opencryptoki-2.3.1+dfsg/0000751000175000017500000000000011336027460012740 5ustar jfjfopencryptoki-2.3.1+dfsg/INSTALL0000640000175000017500000001477411327631345014011 0ustar jfjfBasic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, a file `config.cache' that saves the results of its tests to speed up reconfiguring, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.in' is used to create `configure' by a program called `autoconf'. You only need `configure.in' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `sh ./bootstrap.sh', then type `./configure' to configure the package for your system. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. You can give `configure' initial values for variables by setting them in the environment. Using a Bourne-compatible shell, you can do that on the command line like this: CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure Or on systems that have the `env' program, you can do it like this: env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not supports the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' will install the pkcs11 API in `/usr/lib/pkcs11/', any STDLLs that were built in `/usr/lib/pkcs11/stdll', the config programs in `/usr/lib/pkcs11/methods', and the slot daemon in `/usr/sbin/'. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. Optional Features ================= For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' can not figure out automatically, but needs to determine by the type of host the package will run on. Usually `configure' can figure that out, but if it prints a message saying it can not guess the host type, give it the `--host=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name with three fields: CPU-COMPANY-SYSTEM See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the host type. If you are building compiler tools for cross-compiling, you can also use the `--target=TYPE' option to select the type of system they will produce code for and the `--build=TYPE' option to select the type of system on which you are compiling the package. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Operation Controls ================== `configure' recognizes the following options to control how it operates. `--cache-file=FILE' Use and save the results of the tests in FILE instead of `./config.cache'. Set FILE to `/dev/null' to disable caching, for debugging `configure'. `--help' Print a summary of the options to `configure', and exit. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--version' Print the version of Autoconf used to generate the `configure' script, and exit. `configure' also accepts some other, not widely useful, options. opencryptoki-2.3.1+dfsg/COPYRIGHTS0000640000175000017500000000336611327631345014371 0ustar jfjfBase openCryptoki Code and IBM submissions (C) COPYRIGHT International Business Machines Corp. 2001, 2006 For Code originating from AEP Systems Ltd. * Copyright (c) 1999-2002 AEP Systems Ltd. * Bray Business Park, Southern Cross Route, Bray, Co. Wicklow, Ireland. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of AEP Systems Ltd. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. opencryptoki-2.3.1+dfsg/TODO0000640000175000017500000000341311327631345013434 0ustar jfjf TODO: Proper exit from pkcsslotd. Catch the signal and gracefully shutdown. This should avoid the shared memory failure to shut down. Hardware version and firmware versions are currently hard coded in usr/lib/pkcs11/methods/leeds_slot/pkcs_slot.bash. Query from card if possible in InitSharedMemory in pkcsslotd/shmem.c. [2009-10-05] Refactor build system * Allow installing to non-standard directories * Work /lib & /lib64 confusion with pkcs11_startup * Avoid arch-dependant switches * Use a more standardized and easily-understandable configure/ build process * Create summary screen for configure screen [2009-10-05] usr/sbin/pkcs_slot/pkcs_slot.in: Avoid using `uname -s` for Slot's description and Manufacter, as this identifier varies widly and doesn't bring any useful information. Maybe we should use the opencryptoki version instead? [2009-10-05] Better object-store debugging and tracing. * Dump the object every time a PKCS#11 fetches or pushes it * Create utilities to debug/list/inspect object (this can either be per-token, giving more speciallized details, or be a generalized one using pkcs#11 calls) [2009-10-05] Refactor the testcases * Detect what mechanisms are available and run only the relevant tests * As above, detect relevant limits for each mechanisms (key size, block size etc) and make tests that exercise those limits [2009-10-05] Give human-readable error messages wherever possible, including: * Tooling (pkcsslotd, pkcsconf et al) * Regular log messages and tracing/debug messages [2009-10-05] Better RPM packaging (our .spec file should be the template for distro packaging) * Split in libopencryptoki and -devel packages * Split tokens to have their own (pluggable) packages [2009-10-05] Help/usage message for pkcsslotd opencryptoki-2.3.1+dfsg/README0000640000175000017500000001347411327631345013634 0ustar jfjfopencryptoki README Package version 2.2.4 Authors: Mike Halcrow Kent Yoder Daniel H Jones OVERVIEW openCryptoki version 2.2 implements the PKCS#11 specification version 2.11. This package includes several cryptographic tokens, including the IBM ICA token (requires libICA, which supports zSeries CPACF and LeedsLite hardware) and an OpenSSL-based software token. REQUIREMENTS - SW token: OpenSSL version 0.9.7 or higher - ICA token: libICA version 1.3.6 or higher BUILD PROCESS The simplest way to compile this package is to enter the source code main directory and do the following: 1. Run the bootstrap.sh script by typing: % sh bootstrap.sh 2. Configure the source code by typing: % sh ./configure If you're planning to install the package into your home directory or to a location other than `/usr/local' then add the flag `--prefix=PATH' to `configure'. For example, if your home directory is `/home/luser' you can configure the package to install itself there by invoking: % sh ./configure --prefix=/home/luser If your stdll headers and libraries are not under any standard path, you will need to pass the paths to your files to the configure script. For instance: $ CPPFLAGS="-L/path/lib" LDFLAGS="-I/path/include" ./configure See ./configure --help for info on various options. The default behavior is to build a default token implicitly. For the s390 platform, the default token is ica_s390. For other platforms, the default token is the software token. Other tokens may be enabled using the corresponding --enable- configuration option provided the appropriate libraries are available. While running, `configure' prints some messages telling which features is it checking for. 3. Compile the package by typing: % make 4. Type `make install' to install the programs and any data files and documentation. During installation, the following files go to the following directories: /prefix/sbin/pkcs11_startup /prefix/sbin/pkcs_slot /prefix/sbin/pkcsconf /prefix/sbin/pkcsslotd /prefix/libdir/libopencryptoki.so /prefix/libdir/libopencryptoki.so.0 /prefix/libdir/opencryptoki/libopencryptoki.so /prefix/libdir/opencryptoki/libopencryptoki.so.0 /prefix/libdir/opencryptoki/libopencryptoki.so.0.0.0 /prefix/var/lib/opencryptoki Token objects, which may be optionally built, go to the following locations: /prefix/libdir/opencryptoki/stdll/libpkcs11_ica.so /prefix/libdir/opencryptoki/stdll/libpkcs11_ica.so.0 /prefix/libdir/opencryptoki/stdll/libpkcs11_ica.so.0.0.0 /prefix/libdir/opencryptoki/stdll/libpkcs11_sw.so /prefix/libdir/opencryptoki/stdll/libpkcs11_sw.so.0 /prefix/libdir/opencryptoki/stdll/libpkcs11_sw.so.0.0.0 /prefix/libdir/opencryptoki/stdll/libpkcs11_tpm.so /prefix/libdir/opencryptoki/stdll/libpkcs11_tpm.so.0 /prefix/libdir/opencryptoki/stdll/libpkcs11_tpm.so.0.0.0 where `prefix' is either `/usr/local' or the PATH that you specified in the `--prefix' flag. `libdir' is the name of the library directory; for 32-bit libraries it is usually `lib' and for 64-bit libraries it is usually `lib64'. To maintain backwards compatibility, some additional symlinks are generated (note that these are deprecated, and applications should migrate to use the LSB-compliant names and locations for libraries and executables): /prefix/lib/opencryptoki/PKCS11_API.so - Symlink to /prefix/lib/opencryptoki/libopencryptoki.so /prefix/lib/opencryptoki/stdll/PKCS11_ICA.so - Symlink to /prefix/lib/opencryptoki/stdll/libpkcs11_ica.so /prefix/lib/opencryptoki/stdll/PKCS11_SW.so - Symlink to /prefix/lib/opencryptoki/stdll/libpkcs11_sw.so /prefix/lib/pkcs11/PKCS11_API.so - Symlink to /prefix/lib/opencryptoki/libopencryptoki.so /prefix/lib/pkcs11 - Directory created if non-existent /prefix/lib/pkcs11/methods - Symlink to /prefix/sbin /prefix/lib/pkcs11/stdll - Symlink to /prefix/lib/opencryptoki/stdll /prefix/etc/pkcs11 - Symlink to /prefix/var/lib/opencryptoki If any of these directories do not presently exist, they will be created on demand. Note that if ``prefix'' is ``/usr'', then /prefix/var and /prefix/etc resolve to /var and /etc. On the ``make install'' stage, if content exists in the old /prefix/etc/pkcs11 directory, it will be migrated to the new /prefix/var/lib/opencryptoki location. If you are installing in your home directory make sure that `/home/luser/bin' is in your path. If you're using the bash shell add this line at the end of your .cshrc file: PATH="/home/luser/bin:${PATH}" export PATH If you are using csh or tcsh, then use this line instead: setenv PATH /home/luser/bin:${PATH} By prepending your home directory to the rest of the PATH you can override systemwide installed software with your own custom installation. RUNNING See: http://www-128.ibm.com/developerworks/security/library/s-pkcs/index.html openCryptoki defaults to be usable by anyone who is in the group ``pkcs11''. In this version of openCrypoki, the default SO PIN is 87654321, and the default user PIN is 12345678. These should both be changed to different PIN values before use. You can change the SO PIN by running pkcsconf: % pkcsconf -I You can change the user PIN by typing: % pkcsconf -u You can select the token with the -c command line option; refer to the documentation linked to above for further instructions. opencryptoki-2.3.1+dfsg/COPYING0000640000175000017500000003553111327631345014005 0ustar jfjf Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. opencryptoki-2.3.1+dfsg/rpm/0000751000175000017500000000000011327631345013541 5ustar jfjfopencryptoki-2.3.1+dfsg/rpm/opencryptoki.spec0000640000175000017500000000641211327631345017146 0ustar jfjfName: opencryptoki Version: 2.2.4 Release: 1%{?dist} Summary: An Implementation of PKCS#11 (Cryptoki) v2.11 Group: Applications/Productivity License: CPL URL: http://sourceforge.net/projects/opencryptoki Source0: %{name}-%{version}.tar.bz2 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: autoconf automake libtool openssl-devel Requires: /sbin/chkconfig %description The openCryptoki package implements the PKCS#11 version 2.11: Cryptographic Token Interface Standard (Cryptoki). %package devel Summary: An Implementation of PKCS#11 (Cryptoki) v2.11 Group: Applications/Productivity Requires: opencryptoki = %{version}-%{release}, glibc-devel %description devel The openCryptoki package implements the PKCS#11 version 2.11: Cryptographic Token Interface Standard (Cryptoki). %prep %setup -q -n %{name}-%{version} %build autoreconf --force --install %configure --disable-static make %{?_smp_mflags} %install rm -rf $RPM_BUILD_ROOT make install DESTDIR=$RPM_BUILD_ROOT rm -f $RPM_BUILD_ROOT/%{_libdir}/%{name}/*.la rm -f $RPM_BUILD_ROOT/%{_libdir}/%{name}/stdll/*.la %preun if [ "$1" = "0" ]; then /sbin/service pkcsslotd stop /dev/null 2>&1 /sbin/chkconfig --del pkcsslotd fi %postun -p /sbin/ldconfig %post /sbin/chkconfig --add pkcsslotd /sbin/ldconfig %clean rm -rf $RPM_BUILD_ROOT %pre /usr/sbin/groupadd -r pkcs11 2>/dev/null || true /usr/sbin/usermod -G $(/usr/bin/id --groups --name root | /bin/sed -e ' # add the pkcs group if it is missing /(^| )pkcs11( |$)/!s/$/ pkcs11/ # replace spaces by commas y/ /,/ '),pkcs11 root %files %defattr(-,root,root,-) %doc FAQ LICENSE README doc/* %config(noreplace) %{_sysconfdir}/ld.so.conf.d/%{name}*.conf %dir %attr(770,root,pkcs11) /var/lib/%{name} %attr(755,root,root) %{_sbindir}/pkcsslotd %attr(755,root,root) %{_sbindir}/pkcsconf %attr(755,root,root) %{_sbindir}/pkcs_slot %attr(755,root,root) %{_sbindir}/pkcs11_startup %dir %{_libdir}/%{name} %dir %{_libdir}/%{name}/stdll %{_libdir}/%{name}/libopencryptoki.so %{_libdir}/%{name}/libopencryptoki.so.0 %attr(755,root,root) %{_libdir}/%{name}/libopencryptoki.so.0.0.0 %{_libdir}/%{name}/methods %{_libdir}/%{name}/stdll/libpkcs11_*.so %{_libdir}/%{name}/stdll/libpkcs11_*.so.0 %attr(755,root,root) %{_libdir}/%{name}/stdll/libpkcs11_*.so.0.0.0 %attr(755,root,root) %{_sysconfdir}/init.d/pkcsslotd # symlinks for backward compatibility %dir %{_libdir}/pkcs11 %dir %{_libdir}/pkcs11/stdll %dir %{_libdir}/pkcs11/methods %{_libdir}/pkcs11/PKCS11_API.so %{_libdir}/%{name}/PKCS11_API.so %{_libdir}/pkcs11/libopencryptoki.so %ifarch s390 s390x %{_libdir}/%{name}/stdll/PKCS11_ICA.so %else %{_libdir}/%{name}/stdll/PKCS11_SW.so %endif %files devel %defattr(-,root,root,-) %doc LICENSE %dir %{_includedir}/%{name} %{_includedir}/%{name}/apiclient.h %{_includedir}/%{name}/pkcs11.h %{_includedir}/%{name}/pkcs11types.h %changelog * Thu Aug 7 2006 Daniel H Jones - spec file cleanup * Tue Aug 1 2006 Daniel H Jones - sw token not created for s390 * Tue Jul 25 2006 Daniel H Jones - fixed post section and /var/lib/opencryptoki perms * Thu May 25 2006 Daniel H Jones 2.2.4-1 - initial file created opencryptoki-2.3.1+dfsg/rpm/opencryptoki-libs.spec0000640000175000017500000000362111327631345020074 0ustar jfjf%define base opencryptoki Name: opencryptoki-libs Version: 2.2.4 Release: 1%{?dist} Summary: An Implementation of PKCS#11 (Cryptoki) v2.11 Group: Applications/Productivity License: CPL URL: http://sourceforge.net/projects/opencryptoki Source0: %{base}-%{version}.tar.bz2 BuildRoot: %{_tmppath}/%{base}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: autoconf automake libtool openssl-devel #Requires: %description The openCryptoki package implements the PKCS#11 version 2.11: Cryptographic Token Interface Standard (Cryptoki). %prep %setup -q -n %{base}-%{version} %build autoreconf --force --install %configure --disable-static --disable-daemon make %{?_smp_mflags} %install rm -rf $RPM_BUILD_ROOT make install DESTDIR=$RPM_BUILD_ROOT rm -f $RPM_BUILD_ROOT/%{_libdir}/%{base}/*.la rm -f $RPM_BUILD_ROOT/%{_libdir}/%{base}/stdll/*.la %postun -p /sbin/ldconfig %post -p /sbin/ldconfig %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root,-) %doc LICENSE %config(noreplace) %{_sysconfdir}/ld.so.conf.d/%{base}*.conf %dir %{_libdir}/%{base} %dir %{_libdir}/%{base}/stdll %{_libdir}/%{base}/libopencryptoki.so %{_libdir}/%{base}/libopencryptoki.so.0 %attr(755,root,root) %{_libdir}/%{base}/libopencryptoki.so.0.0.0 %{_libdir}/%{base}/methods %{_libdir}/%{base}/stdll/libpkcs11_*.so %{_libdir}/%{base}/stdll/libpkcs11_*.so.0 %attr(755,root,root) %{_libdir}/%{base}/stdll/libpkcs11_*.so.0.0.0 # symlinks for backward compatibility %dir %{_libdir}/pkcs11 %dir %{_libdir}/pkcs11/stdll %dir %{_libdir}/pkcs11/methods %{_libdir}/pkcs11/PKCS11_API.so %{_libdir}/%{base}/PKCS11_API.so %{_libdir}/pkcs11/libopencryptoki.so %ifarch s390 s390x %{_libdir}/%{base}/stdll/PKCS11_ICA.so %else %{_libdir}/%{base}/stdll/PKCS11_SW.so %endif %changelog * Thu Aug 7 2006 Daniel H Jones - initial file created opencryptoki-2.3.1+dfsg/rpm/opencryptoki-tpmtok.spec0000640000175000017500000000265411327631345020466 0ustar jfjf%define token tpm %define base opencryptoki Name: opencryptoki-%{token}tok Version: 2.2.4 Release: 1%{?dist} Summary: An opencryptoki %{token} token Group: Applications/Productivity License: CPL URL: http://sourceforge.net/projects/opencryptoki Source0: %{base}-%{version}.tar.bz2 BuildRoot: %{_tmppath}/%{base}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: autoconf automake libtool Requires: opencryptoki = %{version}-%{release} %description The opencryptoki-tpmtok package provides an opencryptoki token for the Trusted Computing Platform (TPM) cryptographic device. %prep %setup -q -n %{base}-%{version} %build autoreconf --force --install %configure --disable-static --disable-daemon --disable-swtok --disable-library --enable-%{token}tok make %{?_smp_mflags} %install rm -rf $RPM_BUILD_ROOT make install DESTDIR=$RPM_BUILD_ROOT rm -f $RPM_BUILD_ROOT/%{_libdir}/%{base}/*.la rm -f $RPM_BUILD_ROOT/%{_libdir}/%{base}/stdll/*.la %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root,-) %doc LICENSE %dir %{_libdir}/%{base} %dir %{_libdir}/%{base}/stdll %{_libdir}/%{base}/stdll/libpkcs11_%{token}.so %{_libdir}/%{base}/stdll/libpkcs11_%{token}.so.0 %attr(755,root,root) %{_libdir}/%{base}/stdll/libpkcs11_%{token}.so.0.0.0 %changelog * Tue Aug 7 2006 Daniel H Jones - initial file created opencryptoki-2.3.1+dfsg/LICENSE0000640000175000017500000003553111327631345013757 0ustar jfjf Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. opencryptoki-2.3.1+dfsg/FAQ0000640000175000017500000000460711327631345013304 0ustar jfjf openCryptoki FAQ - Kent Yoder ----------------------------------------------------------------------------- 1. Q. All openCryptoki applications are returning CKR_TOKEN_NOT_PRESENT, even though the token is there, and its STDLL is in the right place. What's the problem? A1. The user who's executing the application is probably not a member of the pkcs11 group. A2. Check that the device driver for your hardware token is loaded. (`lsmod` in Linux). A3. If you're doing development, this error will also be returned of your token's STDLL has unresolved symbols in it. Enable debugging and check the debug log to find out what symbols are undefined. 2. Q. When C_Initialize() gets called by my app, openCryptoki returns CKR_HOST_MEMORY, even though I've got lots of free memory. What's the problem? A1. CKR_HOST_MEMORY is returned also if openCryptoki cannot attach to shared memory. This can happen if: a1. The user who's executing the application is not a member of the pkcs11 group. a2. pkcsslotd is not running. 3. Q. pkcsconf is returning: Error getting token info: 0x2 This is CKR_HOST_MEMORY, see question 2. Error getting token info: 0x3 The slot ID you're providing is invalid. 4. Q. How can I get the complete debug logs from openCryptoki? A. First, for openCryptoki-2.0 forward, define the environment variable PKCS11_API_LOG_DEBUG=1 (in versions of openCryptoki before 2.0, define AIX_PKCS11_API_LOG_DEBUG=1). Also, apparently by default syslogd does not have an entry in /etc/syslogd.conf for debug messages, so even if you have debug messages enabled in your openCryptoki compile, you'll not get them in the system log until you edit /etc/syslogd.conf and restart syslogd. Add an entry in /etc/syslogd.conf such as: # vi /etc/syslogd.conf --- [...] *.debug /var/log/debuglog --- # killall -HUP syslogd Now, when openCryptoki is configured with the --enable-debug option (or if you install the -debug rpms), /var/log/debuglog will receive its debugging messages. 5. Q. My PKCS#11 app is hangs at the point where the PKCS11_API.so tries to log data to the system log. What can I do to fix this? A. Link your application against the pthread library. ----------------------------------------------------------------------------- openCryptoki FAQ opencryptoki-2.3.1+dfsg/configure.in0000640000175000017500000002437111327631506015262 0ustar jfjfdnl Process this file with autoconf to produce a configure script. AC_INIT(openCryptoki, 2.3.1, opencryptoki-tech@lists.sourceforge.net,) dnl Backup CFLAGS so that once the auto tools set it to "-g -O2", dnl (which we want to avoid), we can restore them to whatever the dnl user might have wanted below. cmdline_CFLAGS="$CFLAGS" # Compute $target AC_CANONICAL_TARGET AM_INIT_AUTOMAKE([foreign 1.6]) dnl Checks for programs. dnl Checks for libraries. dnl Checks for header files. AC_DISABLE_STATIC AC_PROG_LIBTOOL AC_HEADER_STDC AC_CHECK_HEADERS(fcntl.h limits.h strings.h sys/file.h syslog.h unistd.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_UID_T AC_TYPE_PID_T AC_TYPE_SIZE_T AC_STRUCT_TM dnl Checks for library functions. AC_FUNC_ALLOCA AC_FUNC_MEMCMP AC_FUNC_STRFTIME AC_FUNC_VPRINTF AC_CHECK_FUNCS([getcwd]) # Used in the init scripts AC_SUBST(ID, /usr/bin/id) AC_SUBST(USERMOD, /usr/sbin/usermod) AC_SUBST(GROUPADD, /usr/sbin/groupadd) dnl i.e., /usr/local or /usr if test "x$prefix" = xNONE; then prefix=$ac_default_prefix fi if test "x$exec_prefix" = xNONE; then exec_prefix='${prefix}' fi CFLAGS="$cmdline_CFLAGS" s390=0 # Arch specific stuff case $target in *64*) lib="lib64" AM_CONDITIONAL(S390, false) ;; *s390x*) s390=1 lib="lib64" AM_CONDITIONAL(S390, true) ;; *s390*) s390=1 lib="lib" AM_CONDITIONAL(S390, true) ;; *) lib="lib" AM_CONDITIONAL(S390, false) ;; esac if test "x$prefix" == x/usr; then AC_SUBST(CONFIG_PATH, /var/lib/opencryptoki) AC_SUBST(CONFIG_PATH_ETC, /etc) AC_SUBST(SBIN_PATH, /usr/sbin) AC_SUBST(DB_PATH, /var/lib/opencryptoki) else AC_SUBST(CONFIG_PATH, $prefix/var/lib/opencryptoki) AC_SUBST(CONFIG_PATH_ETC, $prefix/etc) AC_SUBST(SBIN_PATH, $prefix/sbin) AC_SUBST(DB_PATH, $prefix/var/lib/opencryptoki) fi AC_SUBST(LIB_PATH, $prefix/$lib/opencryptoki) AC_SUBST(STDLL_PATH, $LIB_PATH/stdll) AC_SUBST(CONFIG_FILE, pk_config_data) AC_SUBST(METHOD_PATH, $prefix/sbin) AC_SUBST(HEADER_PATH, $prefix/include) # Debugging support AC_ARG_ENABLE(debug, [ --enable-debug turn on all openCryptoki debugging flags], [ enable_debug="yes"],) if test "x$enable_debug" = xyes; then CFLAGS="$CFLAGS -g -O0 -DDEBUG -DDEBUGON" AC_MSG_RESULT([*** Enabling debugging at user request ***]) else CFLAGS="$CFLAGS -O2" fi # Support for OpenSSL path specification AC_ARG_WITH(openssl, [ --with-openssl[[=DIR]] build with OpenSSL support [[/usr/local/ssl]]], [openssl_prefix=$withval], [openssl_prefix=] ) if test "x$openssl_prefix" != x; then AC_MSG_RESULT([*** Using OpenSSL directory $openssl_prefix ***]) LDFLAGS="-L$openssl_prefix/lib $LDFLAGS" CFLAGS="-I$openssl_prefix/include $CFLAGS" fi # Check if building daemon AC_ARG_ENABLE(daemon, [ --disable-daemon don't build pkcsslotd [default=enabled]], [AM_CONDITIONAL(DAEMON, false)], [AM_CONDITIONAL(DAEMON, true)]) # Check if building library AC_ARG_ENABLE(library, [ --disable-library don't build libopencryptoki [default=enabled]], [AM_CONDITIONAL(LIBRARY, false)], [AM_CONDITIONAL(LIBRARY, true)]) # # s390 tokens # # The ica token is enabled by default on s390 if [[ $s390 -eq 1 ]]; then AM_CONDITIONAL(ICA, false) AC_ARG_ENABLE(ica390tok, [ --disable-ica390tok s390 only: don't build the ICA token [default=enabled]], [AM_CONDITIONAL(DEFAULT_DLL, false)], [enable_ica390tok="yes"]) if test "x$enable_ica390tok" = xyes; then AM_CONDITIONAL(DEFAULT_DLL, true) else AC_MSG_RESULT([*** Disabling the default ICA token at user request ***]) fi else # # non s390 tokens # # The software token is enabled by default on non-s390 platforms AC_ARG_ENABLE(swtok, [ --disable-swtok don't build the software token [default=enabled (except s390)]], [AM_CONDITIONAL(DEFAULT_DLL, false)], [enable_swtok="yes"]) if test "x$enable_swtok" = xyes; then AC_CHECK_LIB(crypto, AES_encrypt, [AM_CONDITIONAL(DEFAULT_DLL, true)], [AM_CONDITIONAL(DEFAULT_DLL, false)]) else AC_MSG_RESULT([*** Disabling the default software token at user request ***]) fi # Support for the IBM Crypto Accelerator (PCICA) token AC_ARG_ENABLE(icatok, [ --enable-icatok build the IBM Crypto Accelerator (PCICA) token [default=disabled]], [enable_icatok="yes"], [enable_icatok="no"]) if test "x$enable_icatok" = xyes; then AC_CHECK_HEADER(ica_api.h, AC_CHECK_LIB(ica, ica_open_adapter, [AM_CONDITIONAL(ICA, true)], [AM_CONDITIONAL(ICA, false)]), [AM_CONDITIONAL(ICA, false)],,) else AM_CONDITIONAL(ICA, false) fi fi # TPM support for the TPM token AC_ARG_ENABLE(tpmtok, [ --enable-tpmtok build the TPM token [default=disabled]], [enable_tpmtok="yes"], [enable_tpmtok="no"]) if test "x$enable_tpmtok" = xyes; then AC_CHECK_HEADER(tss/platform.h, AC_CHECK_LIB(crypto, AES_encrypt, AC_CHECK_LIB(tspi, Tspi_Context_Create, [AM_CONDITIONAL(TPM, true)], [AM_CONDITIONAL(TPM, false)], -lcrypto), [AM_CONDITIONAL(TPM, false)]), [AM_CONDITIONAL(TPM, false)]) else AM_CONDITIONAL(TPM, false) fi # Support for the IBM 4758 (PCICC) token AC_ARG_ENABLE(icctok, [ --enable-icctok build the IBM 4758 (PCICC) token [default=disabled]], [enable_icctok="yes"], [enable_icctok="no"]) if test "x$enable_icctok" = xyes; then AC_CHECK_HEADER(scc_host.h, AC_CHECK_LIB(scc, sccOpenAdapter, [AM_CONDITIONAL(ICC, true)], [AM_CONDITIONAL(ICC, false)]), [AM_CONDITIONAL(ICC, false)],,) else AM_CONDITIONAL(ICC, false) fi # Support for the secure-key (CCA api) token AC_ARG_ENABLE(ccatok, [ --enable-ccatok build the IBM CCA Secure-Key token [default=disabled]], [enable_ccatok="yes"], [enable_ccatok="no"]) if test "x$enable_ccatok" = xyes; then AM_CONDITIONAL(CCA, true) else AM_CONDITIONAL(CCA, false) fi # Support for the AEP Crypto Accelerator AC_ARG_ENABLE(aeptok, [ --enable-aeptok build the AEP Crypto Accelerator token [default=disabled]], [enable_aeptok="no"], [enable_aeptok="yes"]) if test "x$enable_aeptok" = xyes; then AC_CHECK_LIB(aep, AEP_Initialize, [AM_CONDITIONAL(AEP, true)], [AM_CONDITIONAL(AEP, false)]) else AM_CONDITIONAL(AEP, false) fi # Support for the Broadcom Crypto Accelerator AC_ARG_ENABLE(bcomtok, [ --enable-bcomtok build the Broadcom Crypto Accelerator token [default=disabled]], [enable_bcomtok="no"], [enable_bcomtok="yes"]) if test "x$enable_bcomtok" = xyes; then AC_CHECK_HEADER(ubsec.h, AC_CHECK_LIB(ubsec, ubsec_open, [AM_CONDITIONAL(BCOM, true)], [AM_CONDITIONAL(BCOM, false)]), [AM_CONDITIONAL(BCOM, false)],,) else AM_CONDITIONAL(BCOM, false) fi # Support for the Corrent Crypto Accelerator AC_ARG_ENABLE(crtok, [ --enable-crtok build the Corrent Crypto Accelerator token [default=disabled]], [enable_crtok="no"], [enable_crtok="yes"]) if test "x$enable_crtok" = xyes; then AC_CHECK_HEADER(typhoon.h, AC_CHECK_LIB(socketarmor, CR_init_lib, [AM_CONDITIONAL(CR, true)], [AM_CONDITIONAL(CR, false)], -ldl), [AM_CONDITIONAL(CR, false)],,) else AM_CONDITIONAL(CR, false) fi # Check if building tests AC_ARG_ENABLE(testcases, [ --enable-testcases build the test cases [default=disabled]], [AM_CONDITIONAL(TESTS, true)], [AM_CONDITIONAL(TESTS, false)]) CFLAGS="$CFLAGS -DPKCS64 \ -DCONFIG_PATH=\\\"$CONFIG_PATH\\\" \ -DSBIN_PATH=\\\"$SBIN_PATH\\\" \ -DLIB_PATH=\\\"$LIB_PATH\\\" \ -D_XOPEN_SOURCE=500" # At this point, CFLAGS is set to something sensible AC_PROG_CC AC_OUTPUT([Makefile usr/Makefile \ usr/include/Makefile \ usr/include/pkcs11/Makefile \ usr/lib/Makefile \ usr/lib/pkcs11/Makefile \ usr/lib/pkcs11/api/Makefile \ usr/lib/pkcs11/api/shrd_mem.c \ usr/lib/pkcs11/ica_stdll/Makefile \ usr/lib/pkcs11/ica_stdll/tok_struct.h \ usr/lib/pkcs11/ica_s390_stdll/Makefile \ usr/lib/pkcs11/ica_s390_stdll/tok_struct.h \ usr/sbin/Makefile \ usr/sbin/pkcsslotd/Makefile \ usr/sbin/pkcs11_startup/Makefile \ usr/sbin/pkcs11_startup/pkcs11_startup \ usr/sbin/pkcs_slot/Makefile \ usr/sbin/pkcs_slot/pkcs_slot \ usr/sbin/pkcsconf/Makefile \ usr/sbin/pkcscca_migrate/Makefile \ usr/lib/pkcs11/methods/Makefile \ usr/lib/pkcs11/leeds_stdll/Makefile \ usr/lib/pkcs11/soft_stdll/Makefile \ usr/lib/pkcs11/soft_stdll/tok_struct.h \ usr/lib/pkcs11/bcom_stdll/Makefile \ usr/lib/pkcs11/bcom_stdll/tok_struct.h \ usr/lib/pkcs11/cr_stdll/Makefile \ usr/lib/pkcs11/cr_stdll/tok_struct.h \ usr/lib/pkcs11/aep_stdll/Makefile \ usr/lib/pkcs11/aep_stdll/tok_struct.h \ usr/lib/pkcs11/tpm_stdll/Makefile \ usr/lib/pkcs11/tpm_stdll/tok_struct.h \ usr/lib/pkcs11/cca_stdll/Makefile \ usr/lib/pkcs11/cca_stdll/tok_struct.h \ usr/lib/pkcs11/methods/4758_status/Makefile \ misc/Makefile \ misc/pkcsslotd \ testcases/Makefile \ testcases/common/Makefile \ testcases/driver/Makefile \ testcases/init_tok/Makefile \ testcases/mkobj/Makefile \ testcases/oc-digest/Makefile \ testcases/rsa_keygen/Makefile \ testcases/rsa_test/Makefile \ testcases/speed/Makefile \ testcases/test_crypto/Makefile \ testcases/threadmkobj/Makefile \ testcases/tok_obj/Makefile \ testcases/v2.11/Makefile \ testcases/login/Makefile \ man/Makefile \ man/man1/Makefile \ man/man1/pkcsconf.1 \ man/man1/pkcs11_startup.1 \ man/man5/Makefile \ man/man5/pk_config_data.5 \ man/man7/Makefile \ man/man7/opencryptoki.7 \ man/man8/Makefile \ man/man8/pkcsslotd.8]) echo echo "CLFAGS=$CFLAGS" echo opencryptoki-2.3.1+dfsg/bootstrap.sh0000751000175000017500000000012211327631345015312 0ustar jfjf#!/bin/sh set -x aclocal libtoolize --force -c automake --add-missing -c autoconf opencryptoki-2.3.1+dfsg/NEWS0000640000175000017500000000000011327631345013430 0ustar jfjfopencryptoki-2.3.1+dfsg/AUTHORS0000640000175000017500000000062311327631345014014 0ustar jfjf Base function Design and IBM Device support Steven Bade - sbade@us.ibm.com Jimmie Mayfield Dan Rabinovitz - dsrabino@us.ibm.com Shannon Macalpine Kent Yoder - yoder1@us.ibm.com Kapil Sood - kapil@corrent.com, soodkapil@yahoo.com Broadcom capabilitiy Anton Stiglic astiglic@okiok.com AEP capability Carlos Cid carlos.cid@sepsystems.com Corrent capability Kapil Sood kapil.sood@corrent.com opencryptoki-2.3.1+dfsg/misc/0000751000175000017500000000000011327631345013676 5ustar jfjfopencryptoki-2.3.1+dfsg/misc/mech_types.h0000640000175000017500000006761711327631345016230 0ustar jfjf/* COPYRIGHT (c) International Business Machines Corp. 2005 Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ #ifndef _MECH_LIST_TYPES_H #define _MECH_LIST_TYPES_H /** * These defines are copied over from the pkcs11types.h file found in * the openCryptoki package. */ /* An unsigned value, at least 32 bits long */ typedef unsigned long int CK_ULONG; /* A signed value, the same size as a CK_ULONG */ /* CK_LONG is new for v2.0 */ typedef long int CK_LONG; /* At least 32 bits; each bit is a Boolean flag */ typedef CK_ULONG CK_FLAGS; /* CK_MECHANISM_TYPE is a value that identifies a mechanism * type */ typedef CK_ULONG CK_MECHANISM_TYPE; /* The following mechanism types are defined: */ #define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000 #define CKM_RSA_PKCS 0x00000001 #define CKM_RSA_9796 0x00000002 #define CKM_RSA_X_509 0x00000003 /* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS * are new for v2.0. They are mechanisms which hash and sign */ #define CKM_MD2_RSA_PKCS 0x00000004 #define CKM_MD5_RSA_PKCS 0x00000005 #define CKM_SHA1_RSA_PKCS 0x00000006 /* The following are new for v2.11: */ #define CKM_RIPEMD128_RSA_PKCS 0x00000007 #define CKM_RIPEMD160_RSA_PKCS 0x00000008 #define CKM_RSA_PKCS_OAEP 0x00000009 #define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000A #define CKM_RSA_X9_31 0x0000000B #define CKM_SHA1_RSA_X9_31 0x0000000C #define CKM_RSA_PKCS_PSS 0x0000000D #define CKM_SHA1_RSA_PKCS_PSS 0x0000000E #define CKM_DSA_KEY_PAIR_GEN 0x00000010 #define CKM_DSA 0x00000011 #define CKM_DSA_SHA1 0x00000012 #define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020 #define CKM_DH_PKCS_DERIVE 0x00000021 /* The following are new for v2.11 */ #define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030 #define CKM_X9_42_DH_DERIVE 0x00000031 #define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032 #define CKM_X9_42_MQV_DERIVE 0x00000033 #define CKM_RC2_KEY_GEN 0x00000100 #define CKM_RC2_ECB 0x00000101 #define CKM_RC2_CBC 0x00000102 #define CKM_RC2_MAC 0x00000103 /* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */ #define CKM_RC2_MAC_GENERAL 0x00000104 #define CKM_RC2_CBC_PAD 0x00000105 #define CKM_RC4_KEY_GEN 0x00000110 #define CKM_RC4 0x00000111 #define CKM_DES_KEY_GEN 0x00000120 #define CKM_DES_ECB 0x00000121 #define CKM_DES_CBC 0x00000122 #define CKM_DES_MAC 0x00000123 /* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */ #define CKM_DES_MAC_GENERAL 0x00000124 #define CKM_DES_CBC_PAD 0x00000125 #define CKM_DES2_KEY_GEN 0x00000130 #define CKM_DES3_KEY_GEN 0x00000131 #define CKM_DES3_ECB 0x00000132 #define CKM_DES3_CBC 0x00000133 #define CKM_DES3_MAC 0x00000134 /* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN, * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC, * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */ #define CKM_DES3_MAC_GENERAL 0x00000135 #define CKM_DES3_CBC_PAD 0x00000136 #define CKM_CDMF_KEY_GEN 0x00000140 #define CKM_CDMF_ECB 0x00000141 #define CKM_CDMF_CBC 0x00000142 #define CKM_CDMF_MAC 0x00000143 #define CKM_CDMF_MAC_GENERAL 0x00000144 #define CKM_CDMF_CBC_PAD 0x00000145 #define CKM_MD2 0x00000200 /* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */ #define CKM_MD2_HMAC 0x00000201 #define CKM_MD2_HMAC_GENERAL 0x00000202 #define CKM_MD5 0x00000210 /* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */ #define CKM_MD5_HMAC 0x00000211 #define CKM_MD5_HMAC_GENERAL 0x00000212 #define CKM_SHA_1 0x00000220 /* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */ #define CKM_SHA_1_HMAC 0x00000221 #define CKM_SHA_1_HMAC_GENERAL 0x00000222 /* The following are new for v2.11 */ #define CKM_RIPEMD128 0x00000230 #define CKM_RIPEMD128_HMAC 0x00000231 #define CKM_RIPEMD128_HMAC_GENERAL 0x00000232 #define CKM_RIPEMD160 0x00000240 #define CKM_RIPEMD160_HMAC 0x00000241 #define CKM_RIPEMD160_HMAC_GENERAL 0x00000242 /* All of the following mechanisms are new for v2.0 */ /* Note that CAST128 and CAST5 are the same algorithm */ #define CKM_CAST_KEY_GEN 0x00000300 #define CKM_CAST_ECB 0x00000301 #define CKM_CAST_CBC 0x00000302 #define CKM_CAST_MAC 0x00000303 #define CKM_CAST_MAC_GENERAL 0x00000304 #define CKM_CAST_CBC_PAD 0x00000305 #define CKM_CAST3_KEY_GEN 0x00000310 #define CKM_CAST3_ECB 0x00000311 #define CKM_CAST3_CBC 0x00000312 #define CKM_CAST3_MAC 0x00000313 #define CKM_CAST3_MAC_GENERAL 0x00000314 #define CKM_CAST3_CBC_PAD 0x00000315 #define CKM_CAST5_KEY_GEN 0x00000320 #define CKM_CAST128_KEY_GEN 0x00000320 #define CKM_CAST5_ECB 0x00000321 #define CKM_CAST128_ECB 0x00000321 #define CKM_CAST5_CBC 0x00000322 #define CKM_CAST128_CBC 0x00000322 #define CKM_CAST5_MAC 0x00000323 #define CKM_CAST128_MAC 0x00000323 #define CKM_CAST5_MAC_GENERAL 0x00000324 #define CKM_CAST128_MAC_GENERAL 0x00000324 #define CKM_CAST5_CBC_PAD 0x00000325 #define CKM_CAST128_CBC_PAD 0x00000325 #define CKM_RC5_KEY_GEN 0x00000330 #define CKM_RC5_ECB 0x00000331 #define CKM_RC5_CBC 0x00000332 #define CKM_RC5_MAC 0x00000333 #define CKM_RC5_MAC_GENERAL 0x00000334 #define CKM_RC5_CBC_PAD 0x00000335 #define CKM_IDEA_KEY_GEN 0x00000340 #define CKM_IDEA_ECB 0x00000341 #define CKM_IDEA_CBC 0x00000342 #define CKM_IDEA_MAC 0x00000343 #define CKM_IDEA_MAC_GENERAL 0x00000344 #define CKM_IDEA_CBC_PAD 0x00000345 #define CKM_GENERIC_SECRET_KEY_GEN 0x00000350 #define CKM_CONCATENATE_BASE_AND_KEY 0x00000360 #define CKM_CONCATENATE_BASE_AND_DATA 0x00000362 #define CKM_CONCATENATE_DATA_AND_BASE 0x00000363 #define CKM_XOR_BASE_AND_DATA 0x00000364 #define CKM_EXTRACT_KEY_FROM_KEY 0x00000365 #define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370 #define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371 #define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372 /* The following are new for v2.11 */ #define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373 #define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374 #define CKM_TLS_MASTER_KEY_DERIVE 0x00000375 #define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376 #define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377 #define CKM_SSL3_MD5_MAC 0x00000380 #define CKM_SSL3_SHA1_MAC 0x00000381 #define CKM_MD5_KEY_DERIVATION 0x00000390 #define CKM_MD2_KEY_DERIVATION 0x00000391 #define CKM_SHA1_KEY_DERIVATION 0x00000392 #define CKM_PBE_MD2_DES_CBC 0x000003A0 #define CKM_PBE_MD5_DES_CBC 0x000003A1 #define CKM_PBE_MD5_CAST_CBC 0x000003A2 #define CKM_PBE_MD5_CAST3_CBC 0x000003A3 #define CKM_PBE_MD5_CAST5_CBC 0x000003A4 #define CKM_PBE_MD5_CAST128_CBC 0x000003A4 #define CKM_PBE_SHA1_CAST5_CBC 0x000003A5 #define CKM_PBE_SHA1_CAST128_CBC 0x000003A5 #define CKM_PBE_SHA1_RC4_128 0x000003A6 #define CKM_PBE_SHA1_RC4_40 0x000003A7 #define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8 #define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9 #define CKM_PBE_SHA1_RC2_128_CBC 0x000003AA #define CKM_PBE_SHA1_RC2_40_CBC 0x000003AB /* CKM_PKCS5_PBKD2 is new for v2.11 */ #define CKM_PKCS5_PBKD2 0x000003B0 #define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0 #define CKM_KEY_WRAP_LYNKS 0x00000400 #define CKM_KEY_WRAP_SET_OAEP 0x00000401 /* Fortezza mechanisms */ #define CKM_SKIPJACK_KEY_GEN 0x00001000 #define CKM_SKIPJACK_ECB64 0x00001001 #define CKM_SKIPJACK_CBC64 0x00001002 #define CKM_SKIPJACK_OFB64 0x00001003 #define CKM_SKIPJACK_CFB64 0x00001004 #define CKM_SKIPJACK_CFB32 0x00001005 #define CKM_SKIPJACK_CFB16 0x00001006 #define CKM_SKIPJACK_CFB8 0x00001007 #define CKM_SKIPJACK_WRAP 0x00001008 #define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009 #define CKM_SKIPJACK_RELAYX 0x0000100a #define CKM_KEA_KEY_PAIR_GEN 0x00001010 #define CKM_KEA_KEY_DERIVE 0x00001011 #define CKM_FORTEZZA_TIMESTAMP 0x00001020 #define CKM_BATON_KEY_GEN 0x00001030 #define CKM_BATON_ECB128 0x00001031 #define CKM_BATON_ECB96 0x00001032 #define CKM_BATON_CBC128 0x00001033 #define CKM_BATON_COUNTER 0x00001034 #define CKM_BATON_SHUFFLE 0x00001035 #define CKM_BATON_WRAP 0x00001036 /* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11, * CKM_EC_KEY_PAIR_GEN is preferred. */ #define CKM_ECDSA_KEY_PAIR_GEN 0x00001040 #define CKM_EC_KEY_PAIR_GEN 0x00001040 #define CKM_ECDSA 0x00001041 #define CKM_ECDSA_SHA1 0x00001042 /* The following are new for v2.11 */ #define CKM_ECDH1_DERIVE 0x00001050 #define CKM_ECDH1_COFACTOR_DERIVE 0x00001051 #define CKM_ECMQV_DERIVE 0x00001052 #define CKM_JUNIPER_KEY_GEN 0x00001060 #define CKM_JUNIPER_ECB128 0x00001061 #define CKM_JUNIPER_CBC128 0x00001062 #define CKM_JUNIPER_COUNTER 0x00001063 #define CKM_JUNIPER_SHUFFLE 0x00001064 #define CKM_JUNIPER_WRAP 0x00001065 #define CKM_FASTHASH 0x00001070 /* The following are new for v2.11 */ #define CKM_AES_KEY_GEN 0x00001080 #define CKM_AES_ECB 0x00001081 #define CKM_AES_CBC 0x00001082 #define CKM_AES_MAC 0x00001083 #define CKM_AES_MAC_GENERAL 0x00001084 #define CKM_AES_CBC_PAD 0x00001085 #define CKM_DSA_PARAMETER_GEN 0x00002000 #define CKM_DH_PKCS_PARAMETER_GEN 0x00002001 #define CKM_X9_42_DH_PARAMETER_GEN 0x00002002 #define CKM_VENDOR_DEFINED 0x80000000 #define CK_PTR * typedef void CK_PTR CK_VOID_PTR; typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR; /* CK_MECHANISM is a structure that specifies a particular * mechanism */ typedef struct CK_MECHANISM { CK_MECHANISM_TYPE mechanism; CK_VOID_PTR pParameter; CK_ULONG ulParameterLen; /* in bytes */ } CK_MECHANISM; typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR; /* CK_MECHANISM_INFO provides information about a particular * mechanism */ typedef struct CK_MECHANISM_INFO { CK_ULONG ulMinKeySize; CK_ULONG ulMaxKeySize; CK_FLAGS flags; } CK_MECHANISM_INFO; /* The flags are defined as follows: * Bit Flag Mask Meaning */ #define CKF_HW 0x00000001 /* performed by HW */ /* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN, * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER, * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP, * and CKF_DERIVE are new for v2.0. They specify whether or not * a mechanism can be used for a particular task */ #define CKF_ENCRYPT 0x00000100 #define CKF_DECRYPT 0x00000200 #define CKF_DIGEST 0x00000400 #define CKF_SIGN 0x00000800 #define CKF_SIGN_RECOVER 0x00001000 #define CKF_VERIFY 0x00002000 #define CKF_VERIFY_RECOVER 0x00004000 #define CKF_GENERATE 0x00008000 #define CKF_GENERATE_KEY_PAIR 0x00010000 #define CKF_WRAP 0x00020000 #define CKF_UNWRAP 0x00040000 #define CKF_DERIVE 0x00080000 /* The following are new for v2.11 */ #define CKF_EC_F_P 0x00100000 #define CKF_EC_F_2M 0x00200000 #define CKF_EC_ECPARAMETERS 0x00400000 #define CKF_EC_NAMEDCURVE 0x00800000 #define CKF_EC_UNCOMPRESS 0x01000000 #define CKF_EC_COMPRESS 0x02000000 #define CKF_EXTENSION 0x80000000 /* FALSE for 2.01 */ typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR; #define CKR_MECHANISM_INVALID 0x00000070 #define CKR_MECHANISM_PARAM_INVALID 0x00000071 /* From common/c_defs.h in openCryptoki */ typedef struct _MECH_LIST_ELEMENT { CK_MECHANISM_TYPE mech_type; CK_MECHANISM_INFO mech_info; } MECH_LIST_ELEMENT; struct mech_list; struct mech_list { struct mech_list *next; MECH_LIST_ELEMENT element; }; #endif opencryptoki-2.3.1+dfsg/misc/test_mech_list.c0000640000175000017500000003665711327631345017071 0ustar jfjf/* COPYRIGHT (c) International Business Machines Corp. 2005 Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /** * This is something like what you can expect openCryptoki to do when * it requests a mechanism list from your library. */ #include #include "mech_types.h" extern void generate_pkcs11_mech_list(struct mech_list *head); int main(int argc, char *argv[]) { struct mech_list head; struct mech_list *item; generate_pkcs11_mech_list(&head); item = head.next; while (item) { struct mech_list *next; next = item->next; printf("Mechanism type: [%.8x]\n", item->element.mech_type); free(item); item = next; } } opencryptoki-2.3.1+dfsg/misc/mech_list.c0000640000175000017500000004602111327631345016014 0ustar jfjf/* COPYRIGHT (c) International Business Machines Corp. 2005 Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /** * This is an example of how you might convert your library's internal * mechanism descriptors into PKCS#11-compatible descriptors while * generating a mechanism list for openCryptoki. */ #include "mech_types.h" #ifndef NULL #define NULL 0 #endif /** * Bogus internal data descriptors for various mechanisms. */ #define CUSTOM_MECH_TDES 1 #define CUSTOM_MECH_BLOWFISH 2 #define CUSTOM_MECH_RIPEMD160 3 #define CUSTOM_MECH_DSA 4 /** * An example of a library's way of representing a mechanism. */ struct custom_mech_descriptor { int mech_type; int min_key_size; int max_key_size; int is_hw_accelerated; int support_encrypt; int support_decrypt; int support_digest; int support_wrap; int support_unwrap; int support_sign; int support_verify; }; /** * Something like this should actually be filled in by querying the * driver for what is available; if the library supports software * fallback, then the CKF_HW flag should not be set so openCryptoki is * aware of what really is hardware accelerated and what is not. */ struct custom_mech_descriptor library_specific_mechs[] = { {CUSTOM_MECH_TDES, 24, 24, 1, 1, 1, 0, 1, 1, 0, 0}, {CUSTOM_MECH_BLOWFISH, 16, 16, 1, 1, 1, 0, 1, 1, 0, 0}, {CUSTOM_MECH_RIPEMD160, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, {CUSTOM_MECH_DSA, 512, 4096, 1, 0, 0, 0, 0, 0, 1, 1} }; #define CUSTOM_MECH_ARRAY_SIZE 4 /** * Here is an example of how you might map your driver's type * descriptors to the PKCS#11 type descriptors */ struct mech_type_mapping { int internal_mech_type; CK_MECHANISM_TYPE pkcs11_mech_type; }; /** * The mapping from the internal driver type to the PKCS#11 type. */ struct mech_type_mapping mech_type_map[] = { {CUSTOM_MECH_TDES, CKM_DES3_CBC}, {CUSTOM_MECH_BLOWFISH, CKM_VENDOR_DEFINED}, {CUSTOM_MECH_RIPEMD160, CKM_RIPEMD160}, {CUSTOM_MECH_DSA, CKM_DSA} }; #define MECH_TYPE_MAP_SIZE 4 static CK_MECHANISM_TYPE pkcs11_mech_type_for_internal_type(int internal_type) { int i = 0; CK_MECHANISM_TYPE pkcs11_type = CKM_VENDOR_DEFINED; while (i < MECH_TYPE_MAP_SIZE) { if (mech_type_map[i].internal_mech_type == internal_type) { pkcs11_type = mech_type_map[i].pkcs11_mech_type; break; } i++; } return pkcs11_type; } /** * Example method that converts a library's internal mechanism * descriptor into a PKCS#11 mechanism descriptor. Yours may look very * different from this one... */ static void convert_internal_element_to_pkcs11_method_element( MECH_LIST_ELEMENT *element, struct custom_mech_descriptor *internal_mech) { element->mech_type = pkcs11_mech_type_for_internal_type(internal_mech->mech_type); element->mech_info.ulMinKeySize = internal_mech->min_key_size; element->mech_info.ulMaxKeySize = internal_mech->max_key_size; element->mech_info.flags = 0; /* Partial example list of flags that could be set */ if (internal_mech->is_hw_accelerated) { element->mech_info.flags |= CKF_HW; } if (internal_mech->support_encrypt) { element->mech_info.flags |= CKF_ENCRYPT; } if (internal_mech->support_decrypt) { element->mech_info.flags |= CKF_DECRYPT; } if (internal_mech->support_digest) { element->mech_info.flags |= CKF_DIGEST; } if (internal_mech->support_wrap) { element->mech_info.flags |= CKF_WRAP; } if (internal_mech->support_unwrap) { element->mech_info.flags |= CKF_UNWRAP; } if (internal_mech->support_sign) { element->mech_info.flags |= CKF_SIGN; } if (internal_mech->support_verify) { element->mech_info.flags |= CKF_VERIFY; } /* ... */ } /** * Generates a list of supported mechanisms. This is the function that * openCryptoki will be calling directly with a pointer to a * placeholder mech_list struct. * * @param head Pointer to placeholder mech_list struct; this function * fills in the list by tagging on newly malloc'd * mech_list structs off of this struct. */ void generate_pkcs11_mech_list(struct mech_list *head) { struct mech_list *item; int i = 0; item = head; while (i < CUSTOM_MECH_ARRAY_SIZE) { item->next = malloc(sizeof(struct mech_list)); item = item->next; convert_internal_element_to_pkcs11_method_element( &item->element, &library_specific_mechs[i]); i++; } item->next = NULL; return; } opencryptoki-2.3.1+dfsg/misc/pkcsslotd.in0000640000175000017500000000324111327631345016234 0ustar jfjf#!/bin/bash # # pkcsslotd Starts pkcsslotd # # Authors: Kent E. Yoder # Serge E. Hallyn # Daniel H. Jones # # chkconfig: - 50 50 # description: pkcsslotd is a daemon which manages cryptographic hardware \ # tokens for the openCryptoki package. . /etc/init.d/functions PIDFILE=/var/run/pkcsslotd.pid LOCKFILE=/var/lock/subsys/pkcsslotd SLOTDBIN=@METHOD_PATH@/pkcsslotd CONFSTART=@METHOD_PATH@/pkcs11_startup [ -f $SLOTDBIN ] || exit 5 [ -f $CONFSTART ] || exit 5 start() { echo -n $"Starting pkcsslotd: " # Generate the configuration information $CONFSTART ## Start daemon with startproc(8). If this fails ## the echo return value is set appropriate. if [ ! -f $PIDFILE ]; then # pid file does not exist daemon --force $SLOTDBIN elif ! ps -h --pid `cat $PIDFILE` | grep "$SLOTDBIN" 2>&1 >/dev/null; then # pid file exists but named pid not rm -f $PIDFILE daemon --force $SLOTDBIN else # just to have "failed" message daemon $SLOTDBIN fi echo RETVAL=$? [ $RETVAL -eq 0 ] && touch $LOCKFILE return $RETVAL } stop() { echo -n $"Shutting down pkcsslotd:" killproc pkcsslotd -TERM echo RETVAL=$? [ $RETVAL -eq 0 ] && rm -f $LOCKFILE return $RETVAL } restart() { stop start } RETVAL=0 umask 077 case "$1" in start) start ;; stop) stop ;; status) status pkcsslotd $SLOTDBIN ;; restart|reload) restart ;; condrestart) [ -f $LOCKFILE ] && restart || : ;; *) echo $"Usage: $0 {start|stop|status|restart|condrestart}" exit 1 esac exit $? opencryptoki-2.3.1+dfsg/misc/Makefile.am0000640000175000017500000000050011327631345015725 0ustar jfjfif DAEMON initdir = /etc/init.d init_SCRIPTS = pkcsslotd endif install-data-local: mkdir -p $(DESTDIR)/etc/ld.so.conf.d echo "$(libdir)/opencryptoki" \ >$(DESTDIR)/etc/ld.so.conf.d/opencryptoki-$(target_cpu).conf echo "$(libdir)/opencryptoki/stdll" \ >>$(DESTDIR)/etc/ld.so.conf.d/opencryptoki-$(target_cpu).conf opencryptoki-2.3.1+dfsg/misc/migrate_from_2.1_to_2.2.sh0000751000175000017500000000130011327631345020345 0ustar jfjf#!/bin/sh # This script should be run after installing openCryptoki version 2.2.x on a # machine where openCryptoki version 2.1.x has already been installed. # Make sure that no copies of pkcsslotd are running ps -ef | grep pkcsslotd | grep sbin &> /dev/null RES=$? if [ $RES = 0 ]; then killall pkcsslotd fi # Copy files from /etc/pkcs11/ to /var/lib/opencryptoki/ if [ -e "/etc/pkcs11" ]; then mkdir -p /var/lib/opencryptoki cp -aR /etc/pkcs11/* /var/lib/opencryptoki/ cp -a /etc/pkcs11/.slotpid /var/lib/opencryptoki/ fi # Run startup script /usr/sbin/pkcs11_startup # Restart pkcsslotd if it was running before this script was run if [ $RES = 0 ]; then /usr/sbin/pkcsslotd fiopencryptoki-2.3.1+dfsg/ChangeLog0000640000175000017500000000220211327631345014511 0ustar jfjf * openCryptoki-2.2.5 - Fixed bug in comparison of PINs in pkcsconf. - Added code to set the encryption and signature schemes of keys imported into the TPM token. - Added tpm token message to warn when only owner can read the pub SRK. - Fixed return code of function failed when it should be buffer too small in various mech_des.c mech_des3.c and mech_aes.c files. - Moved doc/*.txt to manpage format and integrated them into the build/install - Updated testcases to query env vars for PINs and call a set of common routines for common operations - Added SHA256 support for all tokens - Fixed object cleanup when max number of token objects is hit - Fixed fd exhaustion bug with spin lock fd - Updated TPM stdll for TSS policy handling changes. Trousers 0.2.9+ now required with openCryptoki 2.2.5 - Updated TPM stdll to use TSS_TSPATTRIB_KEYINFO_RSA_MODULUS when retrieving the public modulus - pkcs11_startup fix for use with s/w fallback support in libica on s390 - Added the CCA secure key token and migration utility - Replaced bcopy/bzero with memcpy/memset throughout the code - Removed unused variables throughout the code * openCryptoki-2.2.4 opencryptoki-2.3.1+dfsg/Makefile.am0000640000175000017500000000021411327631345014774 0ustar jfjfif TESTS TESTDIR = testcases endif if LIBRARY MISCDIR = misc endif if DAEMON MISCDIR = misc endif SUBDIRS = usr man $(MISCDIR) $(TESTDIR) opencryptoki-2.3.1+dfsg/man/0000751000175000017500000000000011327631345013516 5ustar jfjfopencryptoki-2.3.1+dfsg/man/man5/0000751000175000017500000000000011327631345014356 5ustar jfjfopencryptoki-2.3.1+dfsg/man/man5/Makefile.am0000640000175000017500000000006511327631345016413 0ustar jfjfman5_MANS=pk_config_data.5 EXTRA_DIST = $(man5_MANS) opencryptoki-2.3.1+dfsg/man/man5/pk_config_data.5.in0000640000175000017500000000101111327631345017772 0ustar jfjf.TH PK_CONFIG_DATA 5 "May 2007" "@PACKAGE_VERSION@" "openCryptoki" .SH NAME pk_config_data \- Configuration file for pkcsslotd. .SH DESCRIPTION This file contains records corresponding to available openCryptoki tokens. At startup, the pkcsslotd daemon parses this file to determine which tokens are available for use. The file should not be manually edited and will be overwritten each time pkcs11_startup is run. .SH "SEE ALSO" .PD 0 .TP \fBopencryptoki\fP(7), .TP \fBpkcsslotd\fP(8), .TP \fBpkcs11_startup\fP(1). .PD opencryptoki-2.3.1+dfsg/man/man7/0000751000175000017500000000000011327631345014360 5ustar jfjfopencryptoki-2.3.1+dfsg/man/man7/opencryptoki.7.in0000640000175000017500000000205011327631345017600 0ustar jfjf.TH OPENCRYPTOKI 7 "May 2007" "@PACKAGE_VERSION@" "openCryptoki" .SH NAME openCryptoki \- A PKCS#11 implementation. .SH DESCRIPTION \fBopenCryptoki\fP is an implementation of the PKCS#11 API standard. It provides an interface to the functions of underlying cryptographic tokens, which may be implemented via software or hardware. The PKCS#11 specification has been released by RSA Labs. More information on PKCS#11 can be found on the RSA labs website: http://www.rsa.com/rsalabs. To use openCryptoki, first run \fIpkcs11_startup\fP to initialize the contents of the pk_config_data file. Then run the \fIpkcsslotd\fP daemon. At this point, openCryptoki is ready to start receiving PKCS#11 requests from user applications. If openCryptoki is included by your distro, its likely that pkcs11_startup is run automatically by an init script. Use the \fIpkcsconf\fP utility to further configure openCryptoki once the daemon is running. .SH "SEE ALSO" .PD 0 .TP \fBpkcsslotd\fP(8), .TP \fBpkcsconf\fP(1), .TP \fBpk_config_data\fP(5), .TP \fBpkcs11_startup\fP(1). .PD opencryptoki-2.3.1+dfsg/man/man7/Makefile.am0000640000175000017500000000006311327631345016413 0ustar jfjfman7_MANS=opencryptoki.7 EXTRA_DIST = $(man7_MANS) opencryptoki-2.3.1+dfsg/man/man8/0000751000175000017500000000000011327631345014361 5ustar jfjfopencryptoki-2.3.1+dfsg/man/man8/Makefile.am0000640000175000017500000000006011327631345016411 0ustar jfjfman8_MANS=pkcsslotd.8 EXTRA_DIST = $(man8_MANS) opencryptoki-2.3.1+dfsg/man/man8/pkcsslotd.8.in0000640000175000017500000000221211327631345017062 0ustar jfjf.TH PKCSSLOTD 8 "May 2007" "@PACKAGE_VERSION@" "openCryptoki" .SH NAME pkcsslotd - shared memory manager for opencryptoki .SH DESCRIPTION The \fBpkcsslotd\fP daemon manages PKCS#11 objects between PKCS#11-enabled applications. When 2 or more processes are accessing the same cryptographic token, the daemon is notified and updates each application when the token's objects change. .SH NOTES Only one instance of the pkcsslotd daemon should be running on any given host. If a prior instance of pkcsslotd did not shut down cleanly, then it may leave an allocated shared memory segment on the system. The allocated memory segment can be identified by its key and can be safely removed once the daemon is stopped with the ipcrm command, such as: \fIipcrm -M 0x6202AB38\fP In order to prevent a denial of service against the daemon, the shared memory segment is created with group ownership by the "pkcs11" group. Any application that requires access to a pkcs11 token must be run by a user who's a member of the "pkcs11" group. .SH "SEE ALSO" .PD 0 .TP \fBopencryptoki\fP(7), .TP \fBpkcsconf\fP(1), .TP \fBpk_config_data\fP(5), .TP \fBpkcs11_startup\fP(1). .PD opencryptoki-2.3.1+dfsg/man/Makefile.am0000640000175000017500000000003711327631345015552 0ustar jfjfSUBDIRS = man1 man5 man7 man8 opencryptoki-2.3.1+dfsg/man/man1/0000751000175000017500000000000011327631345014352 5ustar jfjfopencryptoki-2.3.1+dfsg/man/man1/pkcsconf.1.in0000640000175000017500000000241511327631345016651 0ustar jfjf.TH PKCSCONF 1 "May 2007" "@PACKAGE_VERSION@" "openCryptoki" .SH NAME pkcsconf .SH SYNOPSIS \fBpkcsconf\fP [\fB-itsmMIupP\fP] [\fB-c\fP \fIslotnumber\fP \fB-U\fP \fIuserPIN\fP \fB-S\fP \fISOPin\fP \fB-n\fP \fInewpin\fP] .SH DESCRIPTION The \fBpkcsconf\fP utility displays and configures the state of the pkcsslotd daemon and the tokens managed by the daemon. .SH "COMMAND SUMMARY" .IP "\fB-i\fP" 10 display PKCS11 info .IP "\fB-t\fP" 10 display token info .IP "\fB-s\fP" 10 display slot info .IP "\fB-m\fP" 10 display mechanism list .IP "\fB-I\fP" 10 initialize token .IP "\fB-u\fP" 10 initialize user PIN .IP "\fB-p\fP" 10 set the user PIN .IP "\fB-P\fP" 10 set the SO PIN .IP "\fB-c\fP \fISLOT\fP" 10 specify the token slot for the operation .IP "\fB-U\fP \fIUSERPIN\fP" 10 the current user pin (for use when changing the user pin; -u and -p options); if not specified, user will be prompted .IP "\fB-S\fP \fISOPIN\fP" 10 the current Security Officer (SO) pin (for use when changing the SO pin; -P option); if not specified, user will be prompted .IP "\fB-n\fP \fINEWPIN\fP" 10 the new pin (for use when changing either the user pin or the SO pin; -u, -p and -P options); if not specified, user will be prompted .SH SEE ALSO .PD 0 .TP \fBopencryptoki\fP(7), .TP \fBpkcsslotd\fP(8). .PD opencryptoki-2.3.1+dfsg/man/man1/Makefile.am0000640000175000017500000000010011327631345016375 0ustar jfjfman1_MANS=pkcs11_startup.1 pkcsconf.1 EXTRA_DIST = $(man1_MANS) opencryptoki-2.3.1+dfsg/man/man1/pkcs11_startup.1.in0000640000175000017500000000100011327631345017714 0ustar jfjf.TH PKCS11_STARTUP 1 "May 2007" "@PACKAGE_VERSION@" "openCryptoki" .SH NAME pkcs11_startup .SH DESCRIPTION Script that detects available tokens from installed shared object libraries and writes corresponding records to the pk_config_data file. The pkcsslotd daemon later uses this information when initializing the tokens. The script should be run each time a new token has been installed or uninstalled. .SH "SEE ALSO" .PD 0 .TP \fBopencryptoki\fP(7), .TP \fBpkcsslotd\fP(8), .TP \fBpk_config_data\fP(5). .PD opencryptoki-2.3.1+dfsg/usr/0000751000175000017500000000000011327631345013554 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/lib/0000751000175000017500000000000011327631345014322 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/lib/pkcs11/0000751000175000017500000000000011327631345015424 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/0000751000175000017500000000000011327631465017357 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/csulincl.h0000640000175000017500000015046211327631345021351 0ustar jfjf/******************************************************************************/ /* Licensed Materials Property of IBM */ /* (C) Copyright IBM Corporation, 1997, 2005 */ /* All Rights Reserved */ /* US Government Users Restricted Rights - */ /* Use, duplication or disclosure restricted by */ /* GSA ADP Schedule Contract with IBM Corp. */ /******************************************************************************/ /* */ /* This header file contains the Security API C language */ /* prototypes. See the user publications for more information. */ /* */ /******************************************************************************/ #ifndef __CSULINCL #define __CSULINCL /* * define system linkage macros for the target platform */ #define SECURITYAPI /* * define system linkage to the security API */ #define CSNBCKI CSNBCKI_32 #define CSNBCKM CSNBCKM_32 #define CSNBDKX CSNBDKX_32 #define CSNBDKM CSNBDKM_32 #define CSNBMKP CSNBMKP_32 #define CSNBKEX CSNBKEX_32 #define CSNBKGN CSNBKGN_32 #define CSNBKIM CSNBKIM_32 #define CSNBKPI CSNBKPI_32 #define CSNBKRC CSNBKRC_32 #define CSNBAKRC CSNBAKRC_32 #define CSNBKRD CSNBKRD_32 #define CSNBKRL CSNBKRL_32 #define CSNBKRR CSNBKRR_32 #define CSNBKRW CSNBKRW_32 #define CSNDKRC CSNDKRC_32 #define CSNDKRD CSNDKRD_32 #define CSNDKRL CSNDKRL_32 #define CSNDKRR CSNDKRR_32 #define CSNDKRW CSNDKRW_32 #define CSNBKYT CSNBKYT_32 #define CSNBKSI CSNBKSI_32 #define CSNBKTC CSNBKTC_32 #define CSNBKTR CSNBKTR_32 #define CSNBRNG CSNBRNG_32 #define CSNBDEC CSNBDEC_32 #define CSNBENC CSNBENC_32 #define CSNBMGN CSNBMGN_32 #define CSNBMVR CSNBMVR_32 #define CSNBKTB CSNBKTB_32 #define CSNDPKG CSNDPKG_32 #define CSNDPKB CSNDPKB_32 #define CSNBOWH CSNBOWH_32 #define CSNDPKI CSNDPKI_32 #define CSNDDSG CSNDDSG_32 #define CSNDDSV CSNDDSV_32 #define CSNDKTC CSNDKTC_32 #define CSNDPKX CSNDPKX_32 #define CSNDSYI CSNDSYI_32 #define CSNDSYX CSNDSYX_32 #define CSUACFQ CSUACFQ_32 #define CSUACFC CSUACFC_32 #define CSNDSBC CSNDSBC_32 #define CSNDSBD CSNDSBD_32 #define CSUALCT CSUALCT_32 #define CSUAACM CSUAACM_32 #define CSUAACI CSUAACI_32 #define CSNDPKH CSNDPKH_32 #define CSNDPKR CSNDPKR_32 #define CSUAMKD CSUAMKD_32 #define CSNDRKD CSNDRKD_32 #define CSNDRKL CSNDRKL_32 #define CSNBPTR CSNBPTR_32 #define CSNBCPE CSNBCPE_32 #define CSNBCPA CSNBCPA_32 #define CSNBPGN CSNBPGN_32 #define CSNBPVR CSNBPVR_32 #define CSNDSYG CSNDSYG_32 #define CSNBDKG CSNBDKG_32 #define CSNBEPG CSNBEPG_32 #define CSNBCVE CSNBCVE_32 #define CSNBCSG CSNBCSG_32 #define CSNBCSV CSNBCSV_32 #define CSNBCVG CSNBCVG_32 #define CSNBKTP CSNBKTP_32 #define CSNDPKE CSNDPKE_32 #define CSNDPKD CSNDPKD_32 #define CSNBPEX CSNBPEX_32 #define CSNBPEXX CSNBPEXX_32 #define CSUARNT CSUARNT_32 #define CSNBCVT CSNBCVT_32 #define CSNBMDG CSNBMDG_32 #define CSUACRA CSUACRA_32 #define CSUACRD CSUACRD_32 #define CSNBTRV CSNBTRV_32 #define CSUAPCV CSUAPCV_32 #define CSNBKYTX CSNBKYTX_32 #define CSNBSPN CSNBSPN_32 #define CSNBSKY CSNBSKY_32 #define CSNBPCU CSNBPCU_32 #define CSUAPRB CSUAPRB_32 #define CSUADHK CSUADHK_32 #define CSUADHQ CSUADHQ_32 #define CSNDTBC CSNDTBC_32 #define CSNDRKX CSNDRKX_32 #define CSNBKET CSNBKET_32 #define CSNBSAE CSNBSAE_32 /* * security API prototypes */ /* Clear Key Import */ extern void SECURITYAPI CSNBCKI_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * clear_key, unsigned char * target_key_identifier); /* Clear Key Import Multiple */ extern void SECURITYAPI CSNBCKM_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * clear_key_length, unsigned char * clear_key, unsigned char * target_key_identifier); /* Data Key Export */ extern void SECURITYAPI CSNBDKX_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * source_key_identifier, unsigned char * exporter_key_identifier, unsigned char * target_key_token); /* Data Key Import */ extern void SECURITYAPI CSNBDKM_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * source_key_token, unsigned char * importer_key_identifier, unsigned char * target_key_identifier); /* DES Master Key Process */ extern void SECURITYAPI CSNBMKP_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_part); /* Key Export */ extern void SECURITYAPI CSNBKEX_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_type, unsigned char * source_key_identifier, unsigned char * exporter_key_identifier, unsigned char * target_key_token); /* Key Generate */ extern void SECURITYAPI CSNBKGN_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_form, unsigned char * key_length, unsigned char * key_type_1, unsigned char * key_type_2, unsigned char * KEK_key_identifier_1, unsigned char * KEK_key_identifier_2, unsigned char * generated_key_identifier_1, unsigned char * generated_key_identifier_2); /* Key Import */ extern void SECURITYAPI CSNBKIM_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_type, unsigned char * source_key_token, unsigned char * importer_key_identifier, unsigned char * target_key_identifier); /* Key Part Import */ extern void SECURITYAPI CSNBKPI_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_part, unsigned char * key_identifier); /* Key Storage Initialization */ extern void SECURITYAPI CSNBKSI_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * file_name_length, unsigned char * file_name, long * description_length, unsigned char * description, unsigned char * clear_master_key); /* Key Record Create */ extern void SECURITYAPI CSNBKRC_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_label); /* AES Key Record Create */ extern void SECURITYAPI CSNBAKRC_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_label, long * key_token_length, unsigned char * key_token); /* Key Record Delete */ extern void SECURITYAPI CSNBKRD_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_identifier); /* Key Record List */ extern void SECURITYAPI CSNBKRL_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_label, long * data_set_name_length, unsigned char * data_set_name, unsigned char * security_server_name); /* Key Record Read */ extern void SECURITYAPI CSNBKRR_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_label, unsigned char * key_token); /* Key Record Write */ extern void SECURITYAPI CSNBKRW_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_token, unsigned char * key_label); /* PKA Key Record Create */ extern void SECURITYAPI CSNDKRC_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_label, long * key_token_length, unsigned char * key_token); /* PKA Key Record Delete */ extern void SECURITYAPI CSNDKRD_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_identifier); /* PKA Key Record List */ extern void SECURITYAPI CSNDKRL_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_label, long * data_set_name_length, unsigned char * data_set_name, unsigned char * security_server_name); /* PKA Key Record Read */ extern void SECURITYAPI CSNDKRR_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_label, long * key_token_length, unsigned char * key_token); /* PKA Key Record Write */ extern void SECURITYAPI CSNDKRW_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_label, long * key_token_length, unsigned char * key_token ); /* Key Test */ extern void SECURITYAPI CSNBKYT_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_identifier, unsigned char * random_number, unsigned char * verification_pattern); /* Key Test Extended @b3a*/ extern void SECURITYAPI CSNBKYTX_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_identifier, unsigned char * random_number, unsigned char * verification_pattern, unsigned char * kek_key_identifier); /* Des Key Token Change */ extern void SECURITYAPI CSNBKTC_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_identifier); /* Key Translate */ extern void SECURITYAPI CSNBKTR_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * input_key_token, unsigned char * input_KEK_key_identifier, unsigned char * output_KEK_key_identifier, unsigned char * output_key_token); /* Random Number Generate */ extern void SECURITYAPI CSNBRNG_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * form, unsigned char * random_number); extern void SECURITYAPI CSNBSAE_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * key_identifier_length, unsigned char * key_identifier, long * key_params_length, unsigned char * key_params, long * block_size, long * initialization_vector_length, unsigned char * initialization_vector, long * chaining_vector_length, unsigned char * chaining_vector, long * text_length, unsigned char * text, long * ciphertext_length, unsigned char * ciphertext, long * optional_data_length, unsigned char * optional_data); /* Decipher */ extern void SECURITYAPI CSNBDEC_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_identifier, long * text_length, unsigned char * ciphertext, unsigned char * initialization_vector, long * rule_array_count, unsigned char * rule_array, unsigned char * chaining_vector, unsigned char * plaintext); /* Encipher */ extern void SECURITYAPI CSNBENC_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_identifier, long * text_length, unsigned char * plaintext, unsigned char * initialization_vector, long * rule_array_count, unsigned char * rule_array, long * pad_character, unsigned char * chaining_vector, unsigned char * ciphertext); /* MAC Generate */ extern void SECURITYAPI CSNBMGN_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_identifier, long * text_length, unsigned char * text, long * rule_array_count, unsigned char * rule_array, unsigned char * chaining_vector, unsigned char * MAC); /* MAC Verify */ extern void SECURITYAPI CSNBMVR_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_identifier, long * text_length, unsigned char * text, long * rule_array_count, unsigned char * rule_array, unsigned char * chaining_vector, unsigned char * MAC); /* Key Token Build */ extern void SECURITYAPI CSNBKTB_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_token, unsigned char * key_type, long * rule_array_count, unsigned char * rule_array, unsigned char * key_value, void * reserved_field_1, long * reserved_field_2, unsigned char * reserved_field_3, unsigned char * control_vector, unsigned char * reserved_field_4, long * reserved_field_5, unsigned char * reserved_field_6, unsigned char * master_key_verification_number ); /* PKA Key Generate */ extern void SECURITYAPI CSNDPKG_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * regeneration_data_length, unsigned char * regeneration_data, long * skeleton_key_token_length, unsigned char * skeleton_key_token, unsigned char * transport_key_identifier, long * generated_key_identifier_length, unsigned char * generated_key_identifier); /* PKA Key Token Build */ extern void SECURITYAPI CSNDPKB_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * key_values_structure_length, unsigned char * key_values_structure, long * key_name_ln, unsigned char * key_name, long * reserved_1_length, unsigned char * reserved_1, long * reserved_2_length, unsigned char * reserved_2, long * reserved_3_length, unsigned char * reserved_3, long * reserved_4_length, unsigned char * reserved_4, long * reserved_5_length, unsigned char * reserved_5, long * token_length, unsigned char * token); /* One Way Hash */ extern void SECURITYAPI CSNBOWH_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * text_length, unsigned char * text, long * chaining_vector_length, unsigned char * chaining_vector, long * hash_length, unsigned char * hash); /* PKA Key Import */ extern void SECURITYAPI CSNDPKI_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * source_key_token_length, unsigned char * source_key_token, unsigned char * importer_key_identifier, long * target_key_identifier_length, unsigned char * target_key_identifier); /* Digital Signature Generate */ extern void SECURITYAPI CSNDDSG_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * PKA_private_key_id_length, unsigned char * PKA_private_key_id, long * hash_length, unsigned char * hash, long * signature_field_length, long * signature_bit_length, unsigned char * signature_field); /* Digital Signature Verify */ extern void SECURITYAPI CSNDDSV_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * PKA_public_key_id_length, unsigned char * PKA_public_key_id, long * hash_length, unsigned char * hash, long * signature_field_length, unsigned char * signature_field); /* PKA Key Token Change */ extern void SECURITYAPI CSNDKTC_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * key_id_length, unsigned char * key_id); /* PKA Public Key Extract */ extern void SECURITYAPI CSNDPKX_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * source_key_identifier_length, unsigned char * source_key_identifier, long * target_key_token_length, unsigned char * target_key_token); /* PKA Symmetric Key Import */ extern void SECURITYAPI CSNDSYI_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * RSA_enciphered_key_length, unsigned char * RSA_enciphered_key, long * RSA_private_key_identifier_len, unsigned char * RSA_private_key_identifier, long * target_key_identifier_length, unsigned char * target_key_identifier); /* PKA Symmetric Key Export */ extern void SECURITYAPI CSNDSYX_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * source_key_identifier_length, unsigned char * source_key_identifier, long * RSA_public_key_identifier_len, unsigned char * RSA_public_key_identifier, long * RSA_enciphered_key_length, unsigned char * RSA_enciphered_key); /* Crypto Facility Query */ extern void CSUACFQ_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * verb_data_length, unsigned char * verb_data); /* Crypto Facility Control */ extern void SECURITYAPI CSUACFC_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * verb_data_length, unsigned char * verb_data); /* Compose SET Block */ extern void SECURITYAPI CSNDSBC_32(long * ReturnCode, long * ReasonCode, long * ExitDataLength, unsigned char * ExitData, long * RuleArrayCount, unsigned char * RuleArray, unsigned char * BlockContentsIdentifier, long * XDataStringLength, unsigned char * XDataString, long * DataToEncryptLength, unsigned char * DataToEncrypt, long * DataToHashLength, unsigned char * DataToHash, unsigned char * InitializationVector, long * RSAPublicKeyIdentifierLength, unsigned char * RSAPublicKeyIdentifier, long * DESKeyBLockLength, unsigned char * DESKeyBlock, long * RSAOAEPBlockLength, unsigned char * RSAOAEPBlock, unsigned char * ChainingVector, unsigned char * DESEncryptedDataBlock ); /* Decompose SET Block */ extern void SECURITYAPI CSNDSBD_32(long * ReturnCode, long * ReasonCode, long * ExitDataLength, unsigned char * ExitData, long * RuleArrayCount, unsigned char * RuleArray, long * RSAOAEPBlockLength, unsigned char * RSAOAEPBlock, long * DESEncryptedDataBlockLength, unsigned char * DESEncryptedDataBlock, unsigned char * InitializationVector, long * RSAPrivateKeyIdentifierLength, unsigned char * RSAPrivateKeyIdentifier, long * DESKeyBLockLength, unsigned char * DESKeyBlock, unsigned char * BlockContentsIdentifier, long * XDataStringLength, unsigned char * XDataString, unsigned char * ChainingVector, unsigned char * DataBlock, long * HashBlockLength, unsigned char * HashBlock ); /* Access Control Logon */ extern void SECURITYAPI CSUALCT_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * user_id, long * auth_parm_length, unsigned char * auth_parm, long * auth_data_length, unsigned char * auth_data); /* Access Control Maintenance */ extern void SECURITYAPI CSUAACM_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * name, long * output_data_length, unsigned char * output_data); /* Access Control Initialization */ extern void SECURITYAPI CSUAACI_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * verb_data_1_length, unsigned char * verb_data_1, long * verb_data_2_length, unsigned char * verb_data_2); /* PKA Public Key Hash Register */ extern void SECURITYAPI CSNDPKH_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * public_key_name, long * hash_data_length, unsigned char * hash_data); /* PKA Public Key Register */ extern void SECURITYAPI CSNDPKR_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * public_key_name, long * public_key_certificate_length, unsigned char * public_key_certificate); /* Master Key Distribution */ extern void SECURITYAPI CSUAMKD_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * share_index, unsigned char * private_key_name, unsigned char * certifying_key_name, long * certificate_length, unsigned char * certificate, long * clone_info_encrypting_key_length, unsigned char * clone_info_encrypting_key, long * clone_info_length, unsigned char * clone_info); /* Retained Key Delete */ extern void SECURITYAPI CSNDRKD_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_label); /* Retained Key List */ extern void SECURITYAPI CSNDRKL_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_label_mask, long * retained_keys_count, long * key_labels_count, unsigned char * key_labels); /* Symmetric Key Generate */ extern void SECURITYAPI CSNDSYG_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_encrypting_key, long * rsapub_key_length, unsigned char * rsapub_key, long * locenc_key_length, unsigned char * locenc_key, long * rsaenc_key_length, unsigned char * rsaenc_key); /* Encrypted PIN Translate */ extern void SECURITYAPI CSNBPTR_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * in_PIN_enc_key_id, unsigned char * out_PIN_enc_key_id, unsigned char * in_PIN_profile, unsigned char * in_PAN_data, unsigned char * in_PIN_blk, long * rule_array_count, unsigned char * rule_array, unsigned char * out_PIN_profile, unsigned char * out_PAN_data, long * sequence_number, unsigned char * put_PIN_blk); /* Clear PIN Encrypt */ extern void SECURITYAPI CSNBCPE_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * PIN_enc_key_id, long * rule_array_count, unsigned char * rule_array, unsigned char * clear_PIN, unsigned char * PIN_profile, unsigned char * PAN_data, long * sequence_number, unsigned char * encrypted_PIN_blk); /* Clear PIN Generate Alternate */ extern void SECURITYAPI CSNBCPA_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * PIN_enc_key_id, unsigned char * PIN_gen_key_id, unsigned char * PIN_profile, unsigned char * PAN_data, unsigned char * encrypted_PIN_blk, long * rule_array_count, unsigned char * rule_array, long * PIN_check_length, unsigned char * data_array, unsigned char * returned_result); /* Clear PIN Generate */ extern void SECURITYAPI CSNBPGN_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * PIN_gen_key_id, long * rule_array_count, unsigned char * rule_array, long * PIN_length, long * PIN_check_length, unsigned char * data_array, unsigned char * returned_result); /* Encrypted PIN Verify */ extern void SECURITYAPI CSNBPVR_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * PIN_enc_key_id, unsigned char * PIN_ver_key_id, unsigned char * PIN_profile, unsigned char * PAN_data, unsigned char * encrypted_PIN_blk, long * rule_array_count, unsigned char * rule_array, long * PIN_check_length, unsigned char * data_array); /* Diversified Key Generate */ extern void SECURITYAPI CSNBDKG_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * generating_key_id, long * data_length, unsigned char * data, unsigned char * decrypting_key_id, unsigned char * generated_key_id); /* Encrypted PIN Generate */ extern void SECURITYAPI CSNBEPG_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * PIN_gen_key_id, unsigned char * outPIN_enc_key_id, long * rule_array_count, unsigned char * rule_array, long * PIN_length, unsigned char * data_array, unsigned char * outPIN_profile, unsigned char * PAN_data, long * sequence_number, unsigned char * encrypted_PIN_blk); /* Cryptographic Variable Encipher */ extern void SECURITYAPI CSNBCVE_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * cvarenc_key_id, long * text_length, unsigned char * plain_text, unsigned char * init_vector, unsigned char * cipher_text); /* CVV Generate */ extern void SECURITYAPI CSNBCSG_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * PAN_data, unsigned char * expiration_date, unsigned char * service_code, unsigned char * key_a_id, unsigned char * key_b_id, unsigned char * generated_cvv); /* CVV Verify */ extern void SECURITYAPI CSNBCSV_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * PAN_data, unsigned char * expiration_date, unsigned char * service_code, unsigned char * key_a_id, unsigned char * key_b_id, unsigned char * generated_cvv); /* Control Vector Generate */ extern void SECURITYAPI CSNBCVG_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_type, long * rule_array_count, unsigned char * rule_array, unsigned char * reserved_field_1, unsigned char * control_vector); /* Key Token Parse */ extern void SECURITYAPI CSNBKTP_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_token, unsigned char * key_type, long * rule_array_count, unsigned char * rule_array, unsigned char * key_value, void * master_key_verification_pattern_v03, long * reserved_field_1, unsigned char * reserved_field_2, unsigned char * control_vector, unsigned char * reserved_field_3, long * reserved_field_4, unsigned char * reserved_field_5, unsigned char * master_key_verification_pattern_v00); /* PKA Encrypt */ extern void SECURITYAPI CSNDPKE_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * key_value_length, unsigned char * key_value, long * data_struct_length, unsigned char * data_struct, long * RSA_public_key_length, unsigned char * RSA_public_key, long * RSA_encipher_length, unsigned char * RSA_encipher); /* PKA Decrypt */ extern void SECURITYAPI CSNDPKD_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * enciphered_key_length, unsigned char * enciphered_key, long * data_struct_length, unsigned char * data_struct, long * RSA_private_key_length, unsigned char * RSA_private_key, long * key_value_length, unsigned char * key_value); /* Prohibit Export */ extern void SECURITYAPI CSNBPEX_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_identifier); /* Prohibit Export Extended */ extern void SECURITYAPI CSNBPEXX_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * Source_key_token, unsigned char * Kek_key_identifier); /* Random Number/Known Answer Test */ extern void SECURITYAPI CSUARNT_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array); /* Control Vector Translate */ extern void SECURITYAPI CSNBCVT_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * kek_key_identifier, unsigned char * source_key_token, unsigned char * array_key_left, unsigned char * mask_array_left, unsigned char * array_key_right, unsigned char * mask_array_right, long * rule_array_count, unsigned char * rule_array, unsigned char * target_key_token); /* MDC Generate */ extern void SECURITYAPI CSNBMDG_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * text_length, unsigned char * text_data, long * rule_array_count, unsigned char * rule_array, unsigned char * chaining_vector, unsigned char * MDC); /* Cryptographic Resource Allocate */ extern void SECURITYAPI CSUACRA_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * resource_name_length, unsigned char * resource_name); /* Cryptographic Resource Deallocate */ extern void SECURITYAPI CSUACRD_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * resource_name_length, unsigned char * resource_name); /* Transaction Validation */ extern void SECURITYAPI CSNBTRV_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * transaction_key_length, unsigned char * transaction_key, long * transaction_info_length, unsigned char * transaction_info, long * validation_values_length, unsigned char * validation_values); /* Secure Messaging for Keys */ extern void SECURITYAPI CSNBSKY_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * input_key_indentifier, unsigned char * key_encrypting_key, unsigned char * session_key, long * text_length, unsigned char * clear_text, unsigned char * initialization_vector, long * key_offset, long * key_offset_field_length, unsigned char * cipher_text, unsigned char * output_chaining_value); /* Secure Messaging for PINs */ extern void SECURITYAPI CSNBSPN_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * in_PIN_blk, unsigned char * in_PIN_enc_key_id, unsigned char * in_PIN_profile, unsigned char * in_PAN_data, unsigned char * secmsg_key, unsigned char * out_PIN_profile, unsigned char * out_PAN_data, long * text_length, unsigned char * clear_text, unsigned char * initialization_vector, long * PIN_offset, long * PIN_offset_field_length, unsigned char * cipher_text, unsigned char * output_chaining_value); /* PIN Change/Unblock */ extern void SECURITYAPI CSNBPCU_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * authenticationMasterKeyLength, unsigned char * authenticationMasterKey, long * issuerMasterKeyLength, unsigned char * issuerMasterKey, long * keyGenerationDataLength, unsigned char * keyGenerationData, long * newRefPinKeyLength, unsigned char * newRefPinKey, unsigned char * newRefPinBlock, unsigned char * newRefPinProfile, unsigned char * newRefPanData, long * currentRefPinKeyLength, unsigned char * currentRefPinKey, unsigned char * currentRefPinBlock, unsigned char * currentRefPinProfile, unsigned char * currentRefPanData, long * outputPinDataLength, unsigned char * outputPinData, unsigned char * outputPinProfile, long * outputPinMessageLength, unsigned char * outputPinMessage); /* PCF/CUSP Key Conversion */ extern void SECURITYAPI CSUAPCV_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * KEK_key_identifier_length, unsigned char * KEK_key_identifier, long * PCF_key_list_length, unsigned char * PCF_key_list, long * output_key_list_length, unsigned char * output_key_list); /*Process Request Block*/ extern void SECURITYAPI CSUAPRB_32(long * pReturnCode, long * pReasonCode, long * pExitDataLength, unsigned char * pExitData, long * pRuleArrayCount, unsigned char * pRuleArray, long * pSourceLength, unsigned char * pSource, long * pOutFileNameLength, unsigned char * pOutFileName, long * pReplyLength, unsigned char * pReply); /* Diffie-Hellman Key Load */ extern void SECURITYAPI CSUADHK_32(long * ReturnCode, long * ReasonCode, long * ExitDataLength, unsigned char * ExitData, long * RuleArrayCount, unsigned char * RuleArray, unsigned char * DHModulus, unsigned char * DHGenerator, unsigned char * DHKeyPart, long * TransportKeyHashLength, unsigned char * TransportKeyHash, unsigned char * Reserved1, unsigned char * Reserved2, unsigned char * Reserved3, unsigned char * Reserved4); /* Diffie-Hellman Key Query */ extern void SECURITYAPI CSUADHQ_32(long * ReturnCode, long * ReasonCode, long * ExitDataLength, unsigned char * ExitData, long * RuleArrayCount, unsigned char * RuleArray, unsigned char * DHModulus, unsigned char * DHGenerator, unsigned char * DHKeyPart, long * TransportKeyHashLength, unsigned char * TransportKeyHash, unsigned char * Reserved1, unsigned char * Reserved2, unsigned char * Reserved3, unsigned char * Reserved4); /* Trusted Block Create */ extern void SECURITYAPI CSNDTBC_32 ( long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * input_block_length, unsigned char * input_block_identifier, unsigned char * transport_key_identifier, long * trusted_blokc_length, unsigned char * trusted_blokc_identifier ); /* Remote Key Export */ extern void SECURITYAPI CSNDRKX_32 ( long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * trusted_block_length, unsigned char * trusted_block_identifier, long * certificate_length, unsigned char * certificate, long * certificate_parms_length, unsigned char * certificate_parms, long * transport_key_length, unsigned char * transport_key_identifier, long * rule_id_length, unsigned char * rule_id, long * export_key_kek_length, unsigned char * export_key_kek_identifier, long * export_key_length, unsigned char * export_key_identifier, long * asym_encrypted_key_length, unsigned char * asym_encrypted_key, long * sym_encrypted_key_length, unsigned char * sym_encrypted_key, long * extra_data_length, unsigned char * extra_data, long * key_check_parameters_length, unsigned char * key_check_parameters, long * key_check_length, unsigned char * key_check_value ); /* Key Encryption Translate */ extern void SECURITYAPI CSNBKET_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * kek_identifier_length, unsigned char * kek_identifier, long * key_in_length, unsigned char * key_in, long * key_out_length, unsigned char * key_out); #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/mech_sha.c0000640000175000017500000010273011327631345021272 0ustar jfjf/* * Licensed materials, Property of IBM Corp. * * openCryptoki CCA token * * (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2006 * * Author: Kent E. Yoder * */ // File: mech_sha.c // // Mechanisms for SHA-1 related routines // // The following applies to the software SHA implementation: // Written 2 September 1992, Peter C. Gutmann. // This implementation placed in the public domain. // // Modified 1 June 1993, Colin Plumb. // Modified for the new SHS based on Peter Gutmann's work, // 18 July 1994, Colin Plumb. // Gutmann's work. // Renamed to SHA and comments updated a bit 1 November 1995, Colin Plumb. // These modifications placed in the public domain. // // Comments to pgut1@cs.aukuni.ac.nz // #include #include // for memcmp() et al #include #include #include "cca_stdll.h" #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" #define SHA_HARDWARE_THRESHHOLD 128000 // The SHA f()-functions. The f1 and f3 functions can be optimized to // save one boolean operation each - thanks to Rich Schroeppel, // rcs@cs.arizona.edu for discovering this // #define f1(x,y,z) (z ^ (x & (y ^ z))) // Rounds 0-19 #define f2(x,y,z) (x ^ y ^ z) // Rounds 20-39 #define f3(x,y,z) ((x & y) | (z & (x | y))) // Rounds 40-59 #define f4(x,y,z) (x ^ y ^ z) // Rounds 60-79 // The SHA Mysterious Constants. // K1 = floor(sqrt(2) * 2^30) // K2 = floor(sqrt(3) * 2^30) // K3 = floor(sqrt(5) * 2^30) // K4 = floor(sqrt(10) * 2^30) // #define K1 0x5A827999L // Rounds 0-19 #define K2 0x6ED9EBA1L // Rounds 20-39 #define K3 0x8F1BBCDCL // Rounds 40-59 #define K4 0xCA62C1D6L // Rounds 60-79 // SHA initial values // #define h0init 0x67452301 #define h1init 0xEFCDAB89 #define h2init 0x98BADCFE #define h3init 0x10325476 #define h4init 0xC3D2E1F0 // // Note that it may be necessary to add parentheses to these macros // if they are to be called with expressions as arguments. // // 32-bit rotate left - kludged with shifts // #define ROTL(n,X) ((X << n) | (X >> (32-n))) // The initial expanding function // // The hash function is defined over an 80-word expanded input array W, // where the first 16 are copies of the input data, and the remaining 64 // are defined by W[i] = W[i-16] ^ W[i-14] ^ W[i-8] ^ W[i-3]. This // implementation generates these values on the fly in a circular buffer. // #define expand(W,i) \ (W[i&15] ^= W[(i-14)&15] ^ W[(i-8)&15] ^ W[(i-3)&15], W[i&15] = ROTL(1, W[i&15])) // The prototype SHA sub-round // // The fundamental sub-round is // a' = e + ROTL(5,a) + f(b, c, d) + k + data; // b' = a; // c' = ROTL(30,b); // d' = c; // e' = d; // ... but this is implemented by unrolling the loop 5 times and renaming // the variables (e,a,b,c,d) = (a',b',c',d',e') each iteration. // #define subRound(a, b, c, d, e, f, k, data) \ (e += ROTL(5,a) + f(b, c, d) + k + data, b = ROTL(30, b)) void shaInit( SHA1_CONTEXT *ctx ); void shaUpdate( SHA1_CONTEXT *ctx, CK_BYTE const *buffer, CK_ULONG count); void shaFinal( SHA1_CONTEXT *ctx, CK_BYTE *hash ); void shaTransform( SHA1_CONTEXT *ctx ); // // CK_RV sha1_hash( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { CK_RV rv; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = SHA1_HASH_SIZE; return CKR_OK; } if(ctx->context == NULL) return CKR_HOST_MEMORY; if((rv = ckm_sha1_update(ctx, in_data, in_data_len))) return rv; return ckm_sha1_final( ctx, out_data, out_data_len ); } CK_RV sha2_hash( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { CK_RV rv; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = SHA2_HASH_SIZE; return CKR_OK; } if (ctx->context == NULL) return CKR_HOST_MEMORY; if ((rv = ckm_sha2_update(ctx, in_data, in_data_len))) return rv; return ckm_sha2_final( ctx, out_data, out_data_len ); } CK_RV sha3_hash( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { CK_RV rv; return rv = 0; } CK_RV sha5_hash( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { CK_RV rv; return rv = 0; } // // CK_RV sha1_hash_update( SESSION * sess, DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { if (!sess || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } return ckm_sha1_update( ctx, in_data, in_data_len ); } CK_RV sha2_hash_update( SESSION * sess, DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { if (!sess || !in_data) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } return ckm_sha2_update( ctx, in_data, in_data_len ); } CK_RV sha3_hash_update( SESSION * sess, DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { return CKR_OK; } CK_RV sha5_hash_update( SESSION * sess, DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { return CKR_OK; } // // CK_RV sha1_hash_final( SESSION * sess, CK_BYTE length_only, DIGEST_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ) { if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = SHA1_HASH_SIZE; return CKR_OK; } return ckm_sha1_final( ctx, out_data, out_data_len ); } CK_RV sha2_hash_final( SESSION * sess, CK_BYTE length_only, DIGEST_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ) { if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = SHA2_HASH_SIZE; return CKR_OK; } return ckm_sha2_final( ctx, out_data, out_data_len ); } CK_RV sha3_hash_final( SESSION * sess, CK_BYTE length_only, DIGEST_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ) { return CKR_OK; } CK_RV sha5_hash_final( SESSION * sess, CK_BYTE length_only, DIGEST_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ) { return CKR_OK; } // this routine gets called for two mechanisms actually: // CKM_SHA_1_HMAC // CKM_SHA_1_HMAC_GENERAL // CK_RV sha1_hmac_sign( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE hash[SHA1_HASH_SIZE]; DIGEST_CONTEXT digest_ctx; CK_MECHANISM digest_mech; CK_BYTE k_ipad[SHA1_BLOCK_SIZE]; CK_BYTE k_opad[SHA1_BLOCK_SIZE]; CK_ULONG key_bytes, hash_len, hmac_len; CK_ULONG i; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_SHA_1_HMAC_GENERAL) { hmac_len = *(CK_ULONG *)ctx->mech.pParameter; if (hmac_len == 0) { *out_data_len = 0; return CKR_OK; } } else hmac_len = SHA1_HASH_SIZE; if (length_only == TRUE) { *out_data_len = hmac_len; return CKR_OK; } memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key_obj->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else key_bytes = attr->ulValueLen; // build (K XOR ipad), (K XOR opad) // if (key_bytes > SHA1_BLOCK_SIZE) { digest_mech.mechanism = CKM_SHA_1; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest( sess, FALSE, &digest_ctx, attr->pValue, attr->ulValueLen, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(124, __FILE__, __LINE__); return rc; } digest_mgr_cleanup( &digest_ctx ); memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); for (i=0; i < hash_len; i++) { k_ipad[i] = hash[i] ^ 0x36; k_opad[i] = hash[i] ^ 0x5C; } memset( &k_ipad[i], 0x36, SHA1_BLOCK_SIZE - i); memset( &k_opad[i], 0x5C, SHA1_BLOCK_SIZE - i); } else { CK_BYTE *key = attr->pValue; for (i=0; i < key_bytes; i++) { k_ipad[i] = key[i] ^ 0x36; k_opad[i] = key[i] ^ 0x5C; } memset( &k_ipad[i], 0x36, SHA1_BLOCK_SIZE - key_bytes ); memset( &k_opad[i], 0x5C, SHA1_BLOCK_SIZE - key_bytes ); } digest_mech.mechanism = CKM_SHA_1; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; // inner hash // rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, k_ipad, SHA1_BLOCK_SIZE ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, in_data, in_data_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(126, __FILE__, __LINE__); return rc; } digest_mgr_cleanup( &digest_ctx ); memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); // outer hash // rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, k_opad, SHA1_BLOCK_SIZE ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, hash, hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(126, __FILE__, __LINE__); return rc; } memcpy( out_data, hash, hmac_len ); *out_data_len = hmac_len; digest_mgr_cleanup( &digest_ctx ); return CKR_OK; } /** This routine gets called for two mechanisms actually: * CKM_SHA256_HMAC * CKM_SHA256_HMAC_GENERAL */ CK_RV sha2_hmac_sign( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE hash[SHA2_HASH_SIZE]; DIGEST_CONTEXT digest_ctx; CK_MECHANISM digest_mech; CK_BYTE k_ipad[SHA2_BLOCK_SIZE]; CK_BYTE k_opad[SHA2_BLOCK_SIZE]; CK_ULONG key_bytes, hash_len, hmac_len; CK_ULONG i; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_SHA256_HMAC_GENERAL) { hmac_len = *(CK_ULONG *)ctx->mech.pParameter; if (hmac_len == 0) { *out_data_len = 0; return CKR_OK; } } else hmac_len = SHA2_HASH_SIZE; if (length_only == TRUE) { *out_data_len = hmac_len; return CKR_OK; } memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key_obj->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else key_bytes = attr->ulValueLen; // build (K XOR ipad), (K XOR opad) // if (key_bytes > SHA2_BLOCK_SIZE) { digest_mech.mechanism = CKM_SHA256; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest( sess, FALSE, &digest_ctx, attr->pValue, attr->ulValueLen, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(124, __FILE__, __LINE__); return rc; } digest_mgr_cleanup( &digest_ctx ); memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); for (i=0; i < hash_len; i++) { k_ipad[i] = hash[i] ^ 0x36; k_opad[i] = hash[i] ^ 0x5C; } memset( &k_ipad[i], 0x36, SHA2_BLOCK_SIZE - i); memset( &k_opad[i], 0x5C, SHA2_BLOCK_SIZE - i); } else { CK_BYTE *key = attr->pValue; for (i=0; i < key_bytes; i++) { k_ipad[i] = key[i] ^ 0x36; k_opad[i] = key[i] ^ 0x5C; } memset( &k_ipad[i], 0x36, SHA2_BLOCK_SIZE - key_bytes ); memset( &k_opad[i], 0x5C, SHA2_BLOCK_SIZE - key_bytes ); } digest_mech.mechanism = CKM_SHA256; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; // inner hash // rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, k_ipad, SHA2_BLOCK_SIZE ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, in_data, in_data_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(126, __FILE__, __LINE__); return rc; } digest_mgr_cleanup( &digest_ctx ); memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); // outer hash // rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, k_opad, SHA2_BLOCK_SIZE ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, hash, hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(126, __FILE__, __LINE__); return rc; } memcpy( out_data, hash, hmac_len ); *out_data_len = hmac_len; digest_mgr_cleanup( &digest_ctx ); return CKR_OK; } // // CK_RV sha1_hmac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ) { CK_BYTE hmac[SHA1_HASH_SIZE]; SIGN_VERIFY_CONTEXT hmac_ctx; CK_ULONG hmac_len, len; CK_RV rc; if (!sess || !ctx || !in_data || !signature){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_SHA_1_HMAC_GENERAL) hmac_len = *(CK_ULONG *)ctx->mech.pParameter; else hmac_len = SHA1_HASH_SIZE; memset( &hmac_ctx, 0, sizeof(SIGN_VERIFY_CONTEXT) ); rc = sign_mgr_init( sess, &hmac_ctx, &ctx->mech, FALSE, ctx->key ); if (rc != CKR_OK){ st_err_log(127, __FILE__, __LINE__); goto done; } len = sizeof(hmac); rc = sign_mgr_sign( sess, FALSE, &hmac_ctx, in_data, in_data_len, hmac, &len ); if (rc != CKR_OK){ st_err_log(128, __FILE__, __LINE__); goto done; } if ((len != hmac_len) || (len != sig_len)) { st_err_log(46, __FILE__, __LINE__); rc = CKR_SIGNATURE_LEN_RANGE; goto done; } if (memcmp(hmac, signature, hmac_len) != 0){ st_err_log(47, __FILE__, __LINE__); rc = CKR_SIGNATURE_INVALID; } done: sign_mgr_cleanup( &hmac_ctx ); return rc; } CK_RV sha2_hmac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ) { CK_BYTE hmac[SHA2_HASH_SIZE]; SIGN_VERIFY_CONTEXT hmac_ctx; CK_ULONG hmac_len, len; CK_RV rc; if (!sess || !ctx || !in_data || !signature){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_SHA256_HMAC_GENERAL) hmac_len = *(CK_ULONG *)ctx->mech.pParameter; else hmac_len = SHA2_HASH_SIZE; memset( &hmac_ctx, 0, sizeof(SIGN_VERIFY_CONTEXT) ); rc = sign_mgr_init( sess, &hmac_ctx, &ctx->mech, FALSE, ctx->key ); if (rc != CKR_OK){ st_err_log(127, __FILE__, __LINE__); goto done; } len = sizeof(hmac); rc = sign_mgr_sign( sess, FALSE, &hmac_ctx, in_data, in_data_len, hmac, &len ); if (rc != CKR_OK){ st_err_log(128, __FILE__, __LINE__); goto done; } if ((len != hmac_len) || (len != sig_len)) { st_err_log(46, __FILE__, __LINE__); rc = CKR_SIGNATURE_LEN_RANGE; goto done; } if (memcmp(hmac, signature, hmac_len) != 0){ st_err_log(47, __FILE__, __LINE__); rc = CKR_SIGNATURE_INVALID; } done: sign_mgr_cleanup( &hmac_ctx ); return rc; } // // CKM routines // // // CK_RV ckm_sha1_update( DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { if( token_specific.t_sha_update == NULL ){ if (!ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } shaUpdate( (SHA1_CONTEXT *)ctx->context, in_data, in_data_len ); return CKR_OK; } return token_specific.t_sha_update(ctx, in_data, in_data_len); } CK_RV ckm_sha2_update( DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { if( token_specific.t_sha2_update == NULL ){ /* TODO: Software implementation here */ return CKR_MECHANISM_INVALID; } return token_specific.t_sha2_update(ctx, in_data, in_data_len); } CK_RV ckm_sha3_update( DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { return CKR_OK; } CK_RV ckm_sha5_update( DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { return CKR_OK; } CK_RV ckm_sha3_final( DIGEST_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ) { return CKR_OK; } CK_RV ckm_sha5_final( DIGEST_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ) { return CKR_OK; } // // CK_RV ckm_sha1_final( DIGEST_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ) { if (token_specific.t_sha_final == NULL ){ if (!ctx || !out_data || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < SHA1_HASH_SIZE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } shaFinal( (SHA1_CONTEXT *)ctx->context, out_data ); *out_data_len = SHA1_HASH_SIZE; return CKR_OK; } return token_specific.t_sha_final(ctx, out_data, out_data_len); } CK_RV ckm_sha2_final( DIGEST_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ) { if (token_specific.t_sha2_final == NULL ){ /* TODO: Software implementation here */ return CKR_MECHANISM_INVALID; } return token_specific.t_sha2_final(ctx, out_data, out_data_len); } // // Software SHA-1 implementation // void ckm_sha1_init( DIGEST_CONTEXT * ctx) { // Set the h-vars to their initial values if (token_specific.t_sha_init == NULL ) { SHA1_CONTEXT *sha1_ctx; /* Allocate the context */ ctx->context_len = sizeof(SHA1_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(SHA1_CONTEXT)); if( ctx->context == NULL ) return; sha1_ctx = (SHA1_CONTEXT *)ctx->context; sha1_ctx->hash_value[0] = h0init; sha1_ctx->hash_value[1] = h1init; sha1_ctx->hash_value[2] = h2init; sha1_ctx->hash_value[3] = h3init; sha1_ctx->hash_value[4] = h4init; // Initialise bit count sha1_ctx->bits_lo = sha1_ctx->bits_hi = 0; } else { // SAB XXX call token specific init... the init MUST allocate it's context token_specific.t_sha_init(ctx); } } void ckm_sha2_init( DIGEST_CONTEXT * ctx) { if (token_specific.t_sha2_init == NULL ) { /* TODO: Software implementation here */ return; } else { // SAB XXX call token specific init... the init MUST allocate it's context token_specific.t_sha2_init(ctx); } } void ckm_sha5_init( DIGEST_CONTEXT * ctx) { ctx = NULL; } void ckm_sha3_init( DIGEST_CONTEXT * ctx) { ctx = NULL; } // Perform the SHA transformation. Note that this code, like MD5, seems to // break some optimizing compilers due to the complexity of the expressions // and the size of the basic block. It may be necessary to split it into // sections, e.g. based on the four subrounds // // Note that this corrupts the sha->data area // void shaTransform( SHA1_CONTEXT *ctx ) { register unsigned int A, B, C, D, E; // Set up first buffer // A = ctx->hash_value[0]; B = ctx->hash_value[1]; C = ctx->hash_value[2]; D = ctx->hash_value[3]; E = ctx->hash_value[4]; // Heavy mangling, in 4 sub-rounds of 20 interations each. // subRound( A, B, C, D, E, f1, K1, ctx->buf[ 0] ); subRound( E, A, B, C, D, f1, K1, ctx->buf[ 1] ); subRound( D, E, A, B, C, f1, K1, ctx->buf[ 2] ); subRound( C, D, E, A, B, f1, K1, ctx->buf[ 3] ); subRound( B, C, D, E, A, f1, K1, ctx->buf[ 4] ); subRound( A, B, C, D, E, f1, K1, ctx->buf[ 5] ); subRound( E, A, B, C, D, f1, K1, ctx->buf[ 6] ); subRound( D, E, A, B, C, f1, K1, ctx->buf[ 7] ); subRound( C, D, E, A, B, f1, K1, ctx->buf[ 8] ); subRound( B, C, D, E, A, f1, K1, ctx->buf[ 9] ); subRound( A, B, C, D, E, f1, K1, ctx->buf[10] ); subRound( E, A, B, C, D, f1, K1, ctx->buf[11] ); subRound( D, E, A, B, C, f1, K1, ctx->buf[12] ); subRound( C, D, E, A, B, f1, K1, ctx->buf[13] ); subRound( B, C, D, E, A, f1, K1, ctx->buf[14] ); subRound( A, B, C, D, E, f1, K1, ctx->buf[15] ); subRound( E, A, B, C, D, f1, K1, expand(ctx->buf, 16) ); subRound( D, E, A, B, C, f1, K1, expand(ctx->buf, 17) ); subRound( C, D, E, A, B, f1, K1, expand(ctx->buf, 18) ); subRound( B, C, D, E, A, f1, K1, expand(ctx->buf, 19) ); subRound( A, B, C, D, E, f2, K2, expand(ctx->buf, 20) ); subRound( E, A, B, C, D, f2, K2, expand(ctx->buf, 21) ); subRound( D, E, A, B, C, f2, K2, expand(ctx->buf, 22) ); subRound( C, D, E, A, B, f2, K2, expand(ctx->buf, 23) ); subRound( B, C, D, E, A, f2, K2, expand(ctx->buf, 24) ); subRound( A, B, C, D, E, f2, K2, expand(ctx->buf, 25) ); subRound( E, A, B, C, D, f2, K2, expand(ctx->buf, 26) ); subRound( D, E, A, B, C, f2, K2, expand(ctx->buf, 27) ); subRound( C, D, E, A, B, f2, K2, expand(ctx->buf, 28) ); subRound( B, C, D, E, A, f2, K2, expand(ctx->buf, 29) ); subRound( A, B, C, D, E, f2, K2, expand(ctx->buf, 30) ); subRound( E, A, B, C, D, f2, K2, expand(ctx->buf, 31) ); subRound( D, E, A, B, C, f2, K2, expand(ctx->buf, 32) ); subRound( C, D, E, A, B, f2, K2, expand(ctx->buf, 33) ); subRound( B, C, D, E, A, f2, K2, expand(ctx->buf, 34) ); subRound( A, B, C, D, E, f2, K2, expand(ctx->buf, 35) ); subRound( E, A, B, C, D, f2, K2, expand(ctx->buf, 36) ); subRound( D, E, A, B, C, f2, K2, expand(ctx->buf, 37) ); subRound( C, D, E, A, B, f2, K2, expand(ctx->buf, 38) ); subRound( B, C, D, E, A, f2, K2, expand(ctx->buf, 39) ); subRound( A, B, C, D, E, f3, K3, expand(ctx->buf, 40) ); subRound( E, A, B, C, D, f3, K3, expand(ctx->buf, 41) ); subRound( D, E, A, B, C, f3, K3, expand(ctx->buf, 42) ); subRound( C, D, E, A, B, f3, K3, expand(ctx->buf, 43) ); subRound( B, C, D, E, A, f3, K3, expand(ctx->buf, 44) ); subRound( A, B, C, D, E, f3, K3, expand(ctx->buf, 45) ); subRound( E, A, B, C, D, f3, K3, expand(ctx->buf, 46) ); subRound( D, E, A, B, C, f3, K3, expand(ctx->buf, 47) ); subRound( C, D, E, A, B, f3, K3, expand(ctx->buf, 48) ); subRound( B, C, D, E, A, f3, K3, expand(ctx->buf, 49) ); subRound( A, B, C, D, E, f3, K3, expand(ctx->buf, 50) ); subRound( E, A, B, C, D, f3, K3, expand(ctx->buf, 51) ); subRound( D, E, A, B, C, f3, K3, expand(ctx->buf, 52) ); subRound( C, D, E, A, B, f3, K3, expand(ctx->buf, 53) ); subRound( B, C, D, E, A, f3, K3, expand(ctx->buf, 54) ); subRound( A, B, C, D, E, f3, K3, expand(ctx->buf, 55) ); subRound( E, A, B, C, D, f3, K3, expand(ctx->buf, 56) ); subRound( D, E, A, B, C, f3, K3, expand(ctx->buf, 57) ); subRound( C, D, E, A, B, f3, K3, expand(ctx->buf, 58) ); subRound( B, C, D, E, A, f3, K3, expand(ctx->buf, 59) ); subRound( A, B, C, D, E, f4, K4, expand(ctx->buf, 60) ); subRound( E, A, B, C, D, f4, K4, expand(ctx->buf, 61) ); subRound( D, E, A, B, C, f4, K4, expand(ctx->buf, 62) ); subRound( C, D, E, A, B, f4, K4, expand(ctx->buf, 63) ); subRound( B, C, D, E, A, f4, K4, expand(ctx->buf, 64) ); subRound( A, B, C, D, E, f4, K4, expand(ctx->buf, 65) ); subRound( E, A, B, C, D, f4, K4, expand(ctx->buf, 66) ); subRound( D, E, A, B, C, f4, K4, expand(ctx->buf, 67) ); subRound( C, D, E, A, B, f4, K4, expand(ctx->buf, 68) ); subRound( B, C, D, E, A, f4, K4, expand(ctx->buf, 69) ); subRound( A, B, C, D, E, f4, K4, expand(ctx->buf, 70) ); subRound( E, A, B, C, D, f4, K4, expand(ctx->buf, 71) ); subRound( D, E, A, B, C, f4, K4, expand(ctx->buf, 72) ); subRound( C, D, E, A, B, f4, K4, expand(ctx->buf, 73) ); subRound( B, C, D, E, A, f4, K4, expand(ctx->buf, 74) ); subRound( A, B, C, D, E, f4, K4, expand(ctx->buf, 75) ); subRound( E, A, B, C, D, f4, K4, expand(ctx->buf, 76) ); subRound( D, E, A, B, C, f4, K4, expand(ctx->buf, 77) ); subRound( C, D, E, A, B, f4, K4, expand(ctx->buf, 78) ); subRound( B, C, D, E, A, f4, K4, expand(ctx->buf, 79) ); // Build message digest // ctx->hash_value[0] += A; ctx->hash_value[1] += B; ctx->hash_value[2] += C; ctx->hash_value[3] += D; ctx->hash_value[4] += E; } // SHA is defined in big-endian form, so this converts the buffer from // bytes to words, independent of the machine's native endianness. // // Assuming a consistent byte ordering for the machine, this also // has the magic property of being self-inverse. It is used as // such. // static void byteReverse( unsigned int *buffer, unsigned int byteCount ) { #ifndef __BYTE_ORDER #error "Endianess MUST be defined" #endif #if __BYTE_ORDER == __LITTLE_ENDIAN CK_ULONG value, val; byteCount /= sizeof(CK_ULONG_32); while (byteCount--) { val = *buffer; value = ((0x000000FF & val) << 24) | ((0x0000FF00 & val) << 8 ) | ((0x00FF0000 & val) >> 8 ) | ((0xFF000000 & val) >> 24); *buffer++ = value; } #endif // JRM - this code gives funky results on Linux/Intel. // I assume this is a GCC issue since regression tests passed on NT // // byteCount /= sizeof(CK_ULONG); // while ( byteCount-- ) { // value = (CK_ULONG)((unsigned)((CK_BYTE *)buffer)[0] << 8 | ((CK_BYTE *)buffer)[1]) << 16 | // ((unsigned)((CK_BYTE *)buffer)[2] << 8 | ((CK_BYTE *)buffer)[3]); // *buffer++ = value; // } } void shaUpdate( SHA1_CONTEXT * ctx, CK_BYTE const * buffer, CK_ULONG count) { CK_ULONG t; // Update bitcount // t = ctx->bits_lo; if ((ctx->bits_lo = t + count) < t) ctx->bits_hi++; // Carry from low to high t &= 0x3f; // Bytes already in ctx->buf // Handle any leading odd-sized chunks // if (t) { CK_BYTE *p = (CK_BYTE *)ctx->buf + t; t = 64-t; if (count < t) { memcpy(p, buffer, count); return; } memcpy(p, buffer, t); byteReverse(ctx->buf, SHA1_BLOCK_SIZE); shaTransform(ctx); buffer += t; count -= t; } // Process data in SHA1_BLOCK_SIZE chunks // while (count >= SHA1_BLOCK_SIZE) { memcpy(ctx->buf, buffer, SHA1_BLOCK_SIZE); byteReverse(ctx->buf, SHA1_BLOCK_SIZE); shaTransform(ctx); buffer += SHA1_BLOCK_SIZE; count -= SHA1_BLOCK_SIZE; } // Handle any remaining bytes of data. // memcpy(ctx->buf, buffer, count); } // Final wrapup - pad to 64-byte boundary with the bit pattern // 1 0* (64-bit count of bits processed, MSB-first) // void shaFinal( SHA1_CONTEXT * ctx, CK_BYTE * hash ) { int count; CK_BYTE *p; // Compute number of bytes mod 64 // count = (int)ctx->bits_lo & 0x3F; // Set the first char of padding to 0x80. // This is safe since there is always at least one byte free // p = (CK_BYTE *)ctx->buf + count; *p++ = 0x80; // Bytes of padding needed to make 64 bytes // count = SHA1_BLOCK_SIZE - 1 - count; // Pad out to 56 mod 64 // if (count < 8) { // Two lots of padding: Pad the first block to 64 bytes // memset(p, 0, count); byteReverse(ctx->buf, SHA1_BLOCK_SIZE); shaTransform(ctx); // Now fill the next block with 56 bytes // memset(ctx->buf, 0, SHA1_BLOCK_SIZE-8); } else { // Pad block to 56 bytes // memset(p, 0, count-8); } byteReverse(ctx->buf, SHA1_BLOCK_SIZE-8); // Append length in *bits* and transform // ctx->buf[14] = ctx->bits_hi << 3 | ctx->bits_lo >> 29; ctx->buf[15] = ctx->bits_lo << 3; shaTransform(ctx); // Store output hash in buffer // byteReverse(ctx->hash_value, SHA1_HASH_SIZE); memcpy(hash, ctx->hash_value, SHA1_HASH_SIZE); } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/key.c0000640000175000017500000047022111327631345020316 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: key.c // // Functions contained within: // // key_object_check_required_attributes // key_object_set_default_attributes // key_object_validate_attribute // // publ_key_check_required_attributes // publ_key_set_default_attributes // publ_key_validate_attribute // // priv_key_check_required_attributes // priv_key_set_default_attributes // priv_key_validate_attribute // // secret_key_check_required_attributes // secret_key_set_default_attributes // secret_key_validate_attribute // // rsa_publ_check_required_attributes // rsa_publ_validate_attribute // rsa_priv_check_required_attributes // rsa_priv_validate_attribute // rsa_priv_check_exportability // // dsa_publ_check_required_attributes // dsa_publ_validate_attribute // dsa_priv_check_required_attributes // dsa_priv_validate_attribute // dsa_priv_check_exportability // // ecdsa_publ_check_required_attributes // ecdsa_publ_validate_attribute // ecdsa_priv_checK_required_attributes // ecdsa_priv_validate_attribute // ecdsa_priv_check_exportability // // dh_publ_check_required_attributes // dh_publ_validate_attribute // dh_priv_check_required_attributes // dh_priv_validate_attribute // dh_priv_check_exportability // // kea_publ_check_required_attributes // kea_publ_validate_attribute // kea_priv_check_required_attributes // kea_priv_validate_attribute // kea_priv_check_exportability // // generic_secret_check_required_attributes // generic_secret_validate_attribute // // rc2_check_required_attributes // rc2_validate_attribute // rc2_priv_check_exportability // // rc4_check_required_attributes // rc4_validate_attribute // rc4_priv_check_exportability // // rc5_check_required_attributes // rc5_validate_attribute // rc5_priv_check_exportability // // des_check_required_attributes // des_validate_attribute // des_priv_check_exportability // // des2_check_required_attributes // des2_validate_attribute // des2_priv_check_exportability // // des3_check_required_attributes // des3_validate_attribute // des3_priv_check_exportability // // cast_check_required_attributes // cast_validate_attribute // cast_priv_check_exportability // // cast3_check_required_attributes // cast3_validate_attribute // cast3_priv_check_exportability // // cast5_check_required_attributes // cast5_validate_attribute // cast5_priv_check_exportability // // idea_check_required_attributes // idea_validate_attribute // idea_priv_check_exportability // // cdmf_check_required_attributes // cdmf_validate_attribute // cdmf_priv_check_exportability // // skipjack_check_required_attributes // skipjack_validate_attribute // skipjack_priv_check_exportability // // baton_check_required_attributes // baton_validate_attribute // baton_priv_check_exportability // // juniper_check_required_attributes // juniper_validate_attribute // juniper_priv_check_exportability // #include #include #include // for memcmp() et al #include "pkcs11types.h" #include "defs.h" #include "cca_stdll.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // key_object_check_required_attributes() // // Check required common attributes for key objects // CK_RV key_object_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE * attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_KEY_TYPE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return template_check_required_base_attributes( tmpl, mode ); } // key_object_set_default_attributes() // CK_RV key_object_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE * id_attr = NULL; CK_ATTRIBUTE * sdate_attr = NULL; CK_ATTRIBUTE * edate_attr = NULL; CK_ATTRIBUTE * derive_attr = NULL; CK_ATTRIBUTE * local_attr = NULL; // satisfy the compiler // if (mode) id_attr = NULL; id_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); sdate_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); edate_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); derive_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); local_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!id_attr || !sdate_attr || !edate_attr || !derive_attr || !local_attr) { if (id_attr) free( id_attr ); if (sdate_attr) free( sdate_attr ); if (edate_attr) free( edate_attr ); if (derive_attr) free( derive_attr ); if (local_attr) free( local_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } id_attr->type = CKA_ID; id_attr->ulValueLen = 0; id_attr->pValue = NULL; sdate_attr->type = CKA_START_DATE; sdate_attr->ulValueLen = 0; sdate_attr->pValue = NULL; edate_attr->type = CKA_END_DATE; edate_attr->ulValueLen = 0; edate_attr->pValue = NULL; derive_attr->type = CKA_DERIVE; derive_attr->ulValueLen = sizeof(CK_BBOOL); derive_attr->pValue = (CK_BYTE *)derive_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)derive_attr->pValue = FALSE; local_attr->type = CKA_LOCAL; local_attr->ulValueLen = sizeof(CK_BBOOL); local_attr->pValue = (CK_BYTE *)local_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)local_attr->pValue = FALSE; template_update_attribute( tmpl, id_attr ); template_update_attribute( tmpl, sdate_attr ); template_update_attribute( tmpl, edate_attr ); template_update_attribute( tmpl, derive_attr ); template_update_attribute( tmpl, local_attr ); return CKR_OK; } // key_object_validate_attribute() // CK_RV key_object_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode) { switch (attr->type) { case CKA_KEY_TYPE: if (mode == MODE_CREATE || mode == MODE_DERIVE || mode == MODE_KEYGEN || mode == MODE_UNWRAP) return CKR_OK; else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_ID: case CKA_START_DATE: case CKA_END_DATE: case CKA_DERIVE: return CKR_OK; case CKA_LOCAL: // CKA_LOCAL is only set by the key-generate routine // st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; default: return template_validate_base_attribute( tmpl, attr, mode ); } st_err_log(8, __FILE__, __LINE__); return CKR_ATTRIBUTE_TYPE_INVALID; } // publ_key_check_required_attributes() // CK_RV publ_key_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { // CKO_PUBLIC_KEY has no required attributes // return key_object_check_required_attributes( tmpl, mode ); } // publ_key_set_default_attributes() // // some of the common public key attributes have defaults but none of the specific // public keytypes have default attributes // CK_RV publ_key_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *class_attr = NULL; CK_ATTRIBUTE *subject_attr = NULL; CK_ATTRIBUTE *encrypt_attr = NULL; CK_ATTRIBUTE *verify_attr = NULL; CK_ATTRIBUTE *verify_recover_attr = NULL; CK_ATTRIBUTE *wrap_attr = NULL; CK_OBJECT_CLASS class = CKO_PUBLIC_KEY; CK_RV rc; rc = key_object_set_default_attributes( tmpl, mode ); if (rc != CKR_OK){ st_err_log(172, __FILE__, __LINE__); return rc; } // add the default CKO_PUBLIC_KEY attributes // class_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS) ); subject_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); encrypt_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); verify_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); verify_recover_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); wrap_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!class || !subject_attr || !encrypt_attr || !verify_attr || !verify_recover_attr || !wrap_attr) { if (class_attr) free( class_attr ); if (subject_attr) free( subject_attr ); if (encrypt_attr) free( encrypt_attr ); if (verify_attr) free( verify_attr ); if (verify_recover_attr) free( verify_recover_attr ); if (wrap_attr) free( wrap_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } class_attr->type = CKA_CLASS; class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS); class_attr->pValue = (CK_BYTE *)class_attr + sizeof(CK_ATTRIBUTE); *(CK_OBJECT_CLASS *)class_attr->pValue = CKO_PUBLIC_KEY; subject_attr->type = CKA_SUBJECT; subject_attr->ulValueLen = 0; // empty string subject_attr->pValue = NULL; encrypt_attr->type = CKA_ENCRYPT; encrypt_attr->ulValueLen = sizeof(CK_BBOOL); encrypt_attr->pValue = (CK_BYTE *)encrypt_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)encrypt_attr->pValue = TRUE; verify_attr->type = CKA_VERIFY; verify_attr->ulValueLen = sizeof(CK_BBOOL); verify_attr->pValue = (CK_BYTE *)verify_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)verify_attr->pValue = TRUE; verify_recover_attr->type = CKA_VERIFY_RECOVER; verify_recover_attr->ulValueLen = sizeof(CK_BBOOL); verify_recover_attr->pValue = (CK_BYTE *)verify_recover_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)verify_recover_attr->pValue = TRUE; wrap_attr->type = CKA_WRAP; wrap_attr->ulValueLen = sizeof(CK_BBOOL); wrap_attr->pValue = (CK_BYTE *)wrap_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)wrap_attr->pValue = TRUE; template_update_attribute( tmpl, class_attr ); template_update_attribute( tmpl, subject_attr ); template_update_attribute( tmpl, encrypt_attr ); template_update_attribute( tmpl, verify_attr ); template_update_attribute( tmpl, verify_recover_attr ); template_update_attribute( tmpl, wrap_attr ); return CKR_OK; } // publ_key_validate_attribute // CK_RV publ_key_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_SUBJECT: return CKR_OK; case CKA_ENCRYPT: case CKA_VERIFY: case CKA_VERIFY_RECOVER: case CKA_WRAP: if (mode == MODE_MODIFY) { if (nv_token_data->tweak_vector.allow_key_mods == TRUE) return CKR_OK; st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } return CKR_OK; default: return key_object_validate_attribute( tmpl, attr, mode ); } st_err_log(8, __FILE__, __LINE__); return CKR_ATTRIBUTE_TYPE_INVALID; } // priv_key_check_required_attributes() // CK_RV priv_key_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { // CKO_PRIVATE_KEY has no required attributes // return key_object_check_required_attributes( tmpl, mode ); } // priv_key_set_default_attributes() // // some of the common private key attributes have defaults but none of the specific // private keytypes have default attributes // CK_RV priv_key_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *class_attr = NULL; CK_ATTRIBUTE *subject_attr = NULL; CK_ATTRIBUTE *sensitive_attr = NULL; CK_ATTRIBUTE *decrypt_attr = NULL; CK_ATTRIBUTE *sign_attr = NULL; CK_ATTRIBUTE *sign_recover_attr = NULL; CK_ATTRIBUTE *unwrap_attr = NULL; CK_ATTRIBUTE *extractable_attr = NULL; CK_ATTRIBUTE *never_extr_attr = NULL; CK_ATTRIBUTE *always_sens_attr = NULL; CK_RV rc; rc = key_object_set_default_attributes( tmpl, mode ); if (rc != CKR_OK){ st_err_log(172, __FILE__, __LINE__); return rc; } // add the default CKO_PUBLIC_KEY attributes // class_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS) ); subject_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); sensitive_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); decrypt_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); sign_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); sign_recover_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); unwrap_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); extractable_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); never_extr_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); always_sens_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!class_attr || !subject_attr || !sensitive_attr || !decrypt_attr || !sign_attr || !sign_recover_attr || !unwrap_attr || !extractable_attr || !never_extr_attr || !always_sens_attr ) { if (class_attr) free( class_attr ); if (subject_attr) free( subject_attr ); if (sensitive_attr) free( sensitive_attr ); if (decrypt_attr) free( decrypt_attr ); if (sign_attr) free( sign_attr ); if (sign_recover_attr) free( sign_recover_attr ); if (unwrap_attr) free( unwrap_attr ); if (extractable_attr) free( extractable_attr ); if (always_sens_attr) free( always_sens_attr ); if (never_extr_attr) free( never_extr_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } class_attr->type = CKA_CLASS; class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS); class_attr->pValue = (CK_BYTE *)class_attr + sizeof(CK_ATTRIBUTE); *(CK_OBJECT_CLASS *)class_attr->pValue = CKO_PRIVATE_KEY; subject_attr->type = CKA_SUBJECT; subject_attr->ulValueLen = 0; // empty string subject_attr->pValue = NULL; sensitive_attr->type = CKA_SENSITIVE; sensitive_attr->ulValueLen = sizeof(CK_BBOOL); sensitive_attr->pValue = (CK_BYTE *)sensitive_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)sensitive_attr->pValue = FALSE; decrypt_attr->type = CKA_DECRYPT; decrypt_attr->ulValueLen = sizeof(CK_BBOOL); decrypt_attr->pValue = (CK_BYTE *)decrypt_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)decrypt_attr->pValue = TRUE; sign_attr->type = CKA_SIGN; sign_attr->ulValueLen = sizeof(CK_BBOOL); sign_attr->pValue = (CK_BYTE *)sign_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)sign_attr->pValue = TRUE; sign_recover_attr->type = CKA_SIGN_RECOVER; sign_recover_attr->ulValueLen = sizeof(CK_BBOOL); sign_recover_attr->pValue = (CK_BYTE *)sign_recover_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)sign_recover_attr->pValue = TRUE; unwrap_attr->type = CKA_UNWRAP; unwrap_attr->ulValueLen = sizeof(CK_BBOOL); unwrap_attr->pValue = (CK_BYTE *)unwrap_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)unwrap_attr->pValue = TRUE; extractable_attr->type = CKA_EXTRACTABLE; extractable_attr->ulValueLen = sizeof(CK_BBOOL); extractable_attr->pValue = (CK_BYTE *)extractable_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)extractable_attr->pValue = TRUE; // by default, we'll set NEVER_EXTRACTABLE == FALSE and ALWAYS_SENSITIVE == FALSE // If the key is being created with KEYGEN, it will adjust as necessary. // never_extr_attr->type = CKA_NEVER_EXTRACTABLE; never_extr_attr->ulValueLen = sizeof(CK_BBOOL); never_extr_attr->pValue = (CK_BYTE *)never_extr_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)never_extr_attr->pValue = FALSE; always_sens_attr->type = CKA_ALWAYS_SENSITIVE; always_sens_attr->ulValueLen = sizeof(CK_BBOOL); always_sens_attr->pValue = (CK_BYTE *)always_sens_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)always_sens_attr->pValue = FALSE; template_update_attribute( tmpl, class_attr ); template_update_attribute( tmpl, subject_attr ); template_update_attribute( tmpl, sensitive_attr ); template_update_attribute( tmpl, decrypt_attr ); template_update_attribute( tmpl, sign_attr ); template_update_attribute( tmpl, sign_recover_attr ); template_update_attribute( tmpl, unwrap_attr ); template_update_attribute( tmpl, extractable_attr ); template_update_attribute( tmpl, never_extr_attr ); template_update_attribute( tmpl, always_sens_attr ); return CKR_OK; } // // CK_RV priv_key_unwrap( TEMPLATE *tmpl, CK_ULONG keytype, CK_BYTE *data, CK_ULONG data_len ) { CK_ATTRIBUTE *extractable = NULL; CK_ATTRIBUTE *always_sens = NULL; CK_ATTRIBUTE *never_extract = NULL; CK_ATTRIBUTE *sensitive = NULL; CK_ATTRIBUTE *local = NULL; CK_BBOOL true = TRUE; CK_BBOOL false = FALSE; CK_RV rc; switch (keytype) { case CKK_RSA: rc = rsa_priv_unwrap( tmpl, data, data_len ); break; #if 0 case CKK_DSA: rc = dsa_priv_unwrap( tmpl, data, data_len ); break; #endif default: st_err_log(62, __FILE__, __LINE__); return CKR_WRAPPED_KEY_INVALID; } if (rc != CKR_OK) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return rc; } // make sure // CKA_LOCAL == FALSE // CKA_ALWAYS_SENSITIVE == FALSE // CKA_EXTRACTABLE == TRUE // CKA_NEVER_EXTRACTABLE == FALSE // rc = build_attribute( CKA_LOCAL, &false, 1, &local ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } rc = build_attribute( CKA_ALWAYS_SENSITIVE, &false, 1, &always_sens ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } rc = build_attribute( CKA_SENSITIVE, &false, 1, &sensitive ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } rc = build_attribute( CKA_EXTRACTABLE, &true, 1, &extractable ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } rc = build_attribute( CKA_NEVER_EXTRACTABLE, &false, 1, &never_extract ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } template_update_attribute( tmpl, local ); template_update_attribute( tmpl, always_sens ); template_update_attribute( tmpl, sensitive ); template_update_attribute( tmpl, extractable ); template_update_attribute( tmpl, never_extract ); return CKR_OK; cleanup: if (local) free(local); if (always_sens) free(always_sens); if (extractable) free(extractable); if (never_extract) free(never_extract); return rc; } // priv_key_validate_attribute() // CK_RV priv_key_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_SUBJECT: return CKR_OK; case CKA_DECRYPT: case CKA_SIGN: case CKA_SIGN_RECOVER: case CKA_UNWRAP: // we might want to do this for MODE_COPY too // if (mode == MODE_MODIFY) { if (nv_token_data->tweak_vector.allow_key_mods == TRUE) return CKR_OK; st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } return CKR_OK; // after key creation, CKA_SENSITIVE may only be set to TRUE // case CKA_SENSITIVE: { CK_BBOOL value; if (mode == MODE_CREATE || mode == MODE_KEYGEN) return CKR_OK; value = *(CK_BBOOL *)attr->pValue; if (value != TRUE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } } return CKR_OK; // after key creation, CKA_EXTRACTABLE may only be set to FALSE // case CKA_EXTRACTABLE: { CK_BBOOL value; value = *(CK_BBOOL *)attr->pValue; if ((mode != MODE_CREATE && mode != MODE_KEYGEN) && value != FALSE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } if (value == FALSE) { CK_ATTRIBUTE *attr; attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!attr){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } attr->type = CKA_NEVER_EXTRACTABLE; attr->ulValueLen = sizeof(CK_BBOOL); attr->pValue = (CK_BYTE *)attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)attr->pValue = FALSE; template_update_attribute( tmpl, attr ); } } return CKR_OK; case CKA_ALWAYS_SENSITIVE: case CKA_NEVER_EXTRACTABLE: st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; default: return key_object_validate_attribute( tmpl, attr, mode ); } st_err_log(8, __FILE__, __LINE__); return CKR_ATTRIBUTE_TYPE_INVALID; } // secret_key_check_required_attributes() // CK_RV secret_key_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { return key_object_check_required_attributes( tmpl, mode ); } // secret_key_set_default_attributes() // // some of the common secret key attributes have defaults but none of the specific // secret keytypes have default attributes // CK_RV secret_key_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *class_attr = NULL; CK_ATTRIBUTE *sensitive_attr = NULL; CK_ATTRIBUTE *encrypt_attr = NULL; CK_ATTRIBUTE *decrypt_attr = NULL; CK_ATTRIBUTE *sign_attr = NULL; CK_ATTRIBUTE *verify_attr = NULL; CK_ATTRIBUTE *wrap_attr = NULL; CK_ATTRIBUTE *unwrap_attr = NULL; CK_ATTRIBUTE *extractable_attr = NULL; CK_ATTRIBUTE *never_extr_attr = NULL; CK_ATTRIBUTE *always_sens_attr = NULL; CK_RV rc; rc = key_object_set_default_attributes( tmpl, mode ); if (rc != CKR_OK) return rc; // add the default CKO_DATA attributes // class_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS) ); sensitive_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); encrypt_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); decrypt_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); sign_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); verify_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); wrap_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); unwrap_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); extractable_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); never_extr_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); always_sens_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!class_attr || !sensitive_attr || !encrypt_attr || !decrypt_attr || !sign_attr || !verify_attr || !wrap_attr || !unwrap_attr || !extractable_attr || !never_extr_attr || !always_sens_attr) { if (class_attr) free( class_attr ); if (sensitive_attr) free( sensitive_attr ); if (encrypt_attr) free( encrypt_attr ); if (decrypt_attr) free( decrypt_attr ); if (sign_attr) free( sign_attr ); if (verify_attr) free( verify_attr ); if (wrap_attr) free( wrap_attr ); if (unwrap_attr) free( unwrap_attr ); if (extractable_attr) free( extractable_attr ); if (never_extr_attr) free( never_extr_attr ); if (always_sens_attr) free( always_sens_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } class_attr->type = CKA_CLASS; class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS); class_attr->pValue = (CK_BYTE *)class_attr + sizeof(CK_ATTRIBUTE); *(CK_OBJECT_CLASS *)class_attr->pValue = CKO_SECRET_KEY; sensitive_attr->type = CKA_SENSITIVE; sensitive_attr->ulValueLen = sizeof(CK_BBOOL); sensitive_attr->pValue = (CK_BYTE *)sensitive_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)sensitive_attr->pValue = FALSE; encrypt_attr->type = CKA_ENCRYPT; encrypt_attr->ulValueLen = sizeof(CK_BBOOL); encrypt_attr->pValue = (CK_BYTE *)encrypt_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)encrypt_attr->pValue = TRUE; decrypt_attr->type = CKA_DECRYPT; decrypt_attr->ulValueLen = sizeof(CK_BBOOL); decrypt_attr->pValue = (CK_BYTE *)decrypt_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)decrypt_attr->pValue = TRUE; sign_attr->type = CKA_SIGN; sign_attr->ulValueLen = sizeof(CK_BBOOL); sign_attr->pValue = (CK_BYTE *)sign_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)sign_attr->pValue = TRUE; verify_attr->type = CKA_VERIFY; verify_attr->ulValueLen = sizeof(CK_BBOOL); verify_attr->pValue = (CK_BYTE *)verify_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)verify_attr->pValue = TRUE; wrap_attr->type = CKA_WRAP; wrap_attr->ulValueLen = sizeof(CK_BBOOL); wrap_attr->pValue = (CK_BYTE *)wrap_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)wrap_attr->pValue = TRUE; unwrap_attr->type = CKA_UNWRAP; unwrap_attr->ulValueLen = sizeof(CK_BBOOL); unwrap_attr->pValue = (CK_BYTE *)unwrap_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)unwrap_attr->pValue = TRUE; extractable_attr->type = CKA_EXTRACTABLE; extractable_attr->ulValueLen = sizeof(CK_BBOOL); extractable_attr->pValue = (CK_BYTE *)extractable_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)extractable_attr->pValue = TRUE; // by default, we'll set NEVER_EXTRACTABLE == FALSE and ALWAYS_SENSITIVE == FALSE // If the key is being created with KEYGEN, it will adjust as necessary. // always_sens_attr->type = CKA_ALWAYS_SENSITIVE; always_sens_attr->ulValueLen = sizeof(CK_BBOOL); always_sens_attr->pValue = (CK_BYTE *)always_sens_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)always_sens_attr->pValue = FALSE; never_extr_attr->type = CKA_NEVER_EXTRACTABLE; never_extr_attr->ulValueLen = sizeof(CK_BBOOL); never_extr_attr->pValue = (CK_BYTE *)never_extr_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)never_extr_attr->pValue = FALSE; template_update_attribute( tmpl, class_attr ); template_update_attribute( tmpl, sensitive_attr ); template_update_attribute( tmpl, encrypt_attr ); template_update_attribute( tmpl, decrypt_attr ); template_update_attribute( tmpl, sign_attr ); template_update_attribute( tmpl, verify_attr ); template_update_attribute( tmpl, wrap_attr ); template_update_attribute( tmpl, unwrap_attr ); template_update_attribute( tmpl, extractable_attr ); template_update_attribute( tmpl, never_extr_attr ); template_update_attribute( tmpl, always_sens_attr ); return CKR_OK; } // // CK_RV secret_key_unwrap( TEMPLATE *tmpl, CK_ULONG keytype, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ) { CK_ATTRIBUTE *local = NULL; CK_ATTRIBUTE *always_sens = NULL; CK_ATTRIBUTE *sensitive = NULL; CK_ATTRIBUTE *extractable = NULL; CK_ATTRIBUTE *never_extract = NULL; CK_BBOOL true = TRUE; CK_BBOOL false = FALSE; CK_RV rc; switch (keytype) { #if 0 case CKK_CDMF: case CKK_DES: rc = des_unwrap( tmpl, data, data_len, fromend ); break; case CKK_DES3: rc = des3_unwrap( tmpl, data, data_len, fromend ); break; case CKK_AES: rc = aes_unwrap( tmpl, data, data_len, fromend ); break; #else case CKK_CDMF: case CKK_DES: case CKK_DES3: case CKK_AES: rc = aes_unwrap( tmpl, data, data_len, fromend ); break; #endif case CKK_GENERIC_SECRET: case CKK_RC2: case CKK_RC4: case CKK_RC5: case CKK_CAST: case CKK_CAST3: case CKK_CAST5: rc = generic_secret_unwrap( tmpl, data, data_len, fromend ); break; default: st_err_log(62, __FILE__, __LINE__); return CKR_WRAPPED_KEY_INVALID; } if (rc != CKR_OK) return rc; // make sure // CKA_LOCAL == FALSE // CKA_ALWAYS_SENSITIVE == FALSE // CKA_EXTRACTABLE == TRUE // CKA_NEVER_EXTRACTABLE == FALSE // rc = build_attribute( CKA_LOCAL, &false, 1, &local ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } rc = build_attribute( CKA_ALWAYS_SENSITIVE, &false, 1, &always_sens ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } rc = build_attribute( CKA_SENSITIVE, &false, 1, &sensitive ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } rc = build_attribute( CKA_EXTRACTABLE, &true, 1, &extractable ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } rc = build_attribute( CKA_NEVER_EXTRACTABLE, &false, 1, &never_extract ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } template_update_attribute( tmpl, local ); template_update_attribute( tmpl, always_sens ); template_update_attribute( tmpl, sensitive ); template_update_attribute( tmpl, extractable ); template_update_attribute( tmpl, never_extract ); return CKR_OK; cleanup: if (local) free(local); if (extractable) free(extractable); if (always_sens) free(always_sens); if (never_extract) free(never_extract); return rc; } // secret_key_validate_attribute() // CK_RV secret_key_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_ENCRYPT: case CKA_DECRYPT: case CKA_SIGN: case CKA_VERIFY: case CKA_WRAP: case CKA_UNWRAP: if (mode == MODE_MODIFY) { if (nv_token_data->tweak_vector.allow_key_mods == TRUE) return CKR_OK; st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } return CKR_OK; // after key creation, CKA_SENSITIVE may only be set to TRUE // case CKA_SENSITIVE: { CK_BBOOL value; value = *(CK_BBOOL *)attr->pValue; if ((mode != MODE_CREATE && mode != MODE_DERIVE && mode != MODE_KEYGEN) && (value != TRUE)){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } } return CKR_OK; // after key creation, CKA_EXTRACTABLE may only be set to FALSE // case CKA_EXTRACTABLE: { CK_BBOOL value; // the unwrap routine will automatically set extractable to TRUE // value = *(CK_BBOOL *)attr->pValue; if ((mode != MODE_CREATE && mode != MODE_DERIVE && mode != MODE_KEYGEN) && (value != FALSE)){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } if (value == FALSE) { CK_ATTRIBUTE *attr; attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!attr){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } attr->type = CKA_NEVER_EXTRACTABLE; attr->ulValueLen = sizeof(CK_BBOOL); attr->pValue = (CK_BYTE *)attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)attr->pValue = FALSE; template_update_attribute( tmpl, attr ); } } return CKR_OK; case CKA_ALWAYS_SENSITIVE: case CKA_NEVER_EXTRACTABLE: st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; default: return key_object_validate_attribute( tmpl, attr, mode ); } st_err_log(8, __FILE__, __LINE__); return CKR_ATTRIBUTE_TYPE_INVALID; } // secret_key_check_exportability() // CK_BBOOL secret_key_check_exportability( CK_ATTRIBUTE_TYPE type ) { switch (type) { case CKA_VALUE: st_err_log(86, __FILE__, __LINE__); return FALSE; } return TRUE; } // rsa_publ_check_required_attributes() // CK_RV rsa_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_MODULUS, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_MODULUS_BITS, &attr ); if (!found) { if (mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_PUBLIC_EXPONENT, &attr ); if (!found) { if (mode == MODE_CREATE || mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return publ_key_check_required_attributes( tmpl, mode ); } // rsa_publ_set_default_attributes() // CK_RV rsa_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *type_attr = NULL; CK_ATTRIBUTE *modulus_attr = NULL; CK_ATTRIBUTE *modulus_bits_attr = NULL; CK_ATTRIBUTE *public_exp_attr = NULL; CK_ULONG bits = 0L; publ_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); modulus_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); modulus_bits_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); public_exp_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !modulus_attr || !modulus_bits_attr || !public_exp_attr) { if (type_attr) free( type_attr ); if (modulus_attr) free( modulus_attr ); if (modulus_bits_attr) free( modulus_bits_attr ); if (public_exp_attr) free( public_exp_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_RSA; modulus_attr->type = CKA_MODULUS; modulus_attr->ulValueLen = 0; modulus_attr->pValue = NULL; modulus_bits_attr->type = CKA_MODULUS_BITS; modulus_bits_attr->ulValueLen = sizeof(CK_ULONG); modulus_bits_attr->pValue = (CK_BYTE *)modulus_bits_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)modulus_bits_attr->pValue = bits; public_exp_attr->type = CKA_PUBLIC_EXPONENT; public_exp_attr->ulValueLen = 0; public_exp_attr->pValue = NULL; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, modulus_attr ); template_update_attribute( tmpl, modulus_bits_attr ); template_update_attribute( tmpl, public_exp_attr ); return CKR_OK; } // rsa_publ_validate_attributes() // CK_RV rsa_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_MODULUS_BITS: if (mode == MODE_KEYGEN) { if (attr->ulValueLen != sizeof(CK_ULONG)){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else { CK_ULONG mod_bits = *(CK_ULONG *)attr->pValue; if (mod_bits < 512 || mod_bits > 4096){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } if (mod_bits % 8 != 0){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } return CKR_OK; } } else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_MODULUS: if (mode == MODE_CREATE) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_PUBLIC_EXPONENT: if (mode == MODE_CREATE || mode == MODE_KEYGEN) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } default: return publ_key_validate_attribute( tmpl, attr, mode ); } } // rsa_priv_check_required_attributes() // CK_RV rsa_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_MODULUS, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } // // PKCS #11 is flexible with respect to which attributes must be present // in an RSA key. Keys can be specified in Chinese-Remainder format or // they can be specified in modular-exponent format. Right now, I only // support keys created in Chinese-Remainder format. That is, we return // CKR_TEMPLATE_INCOMPLETE if a modular-exponent key is specified. This // is allowed by PKCS #11. // // In the future, we should allow for creation of keys in modular-exponent // format too. This raises some issues. It's easy enough to recognize // when a key has been specified in modular-exponent format. And it's // easy enough to recognize when all attributes have been specified // (which is what we require right now). What's trickier to handle is // the "middle" cases in which more than the minimum yet less than the // full number of attributes have been specified. Do we revert back to // modular-exponent representation? Do we compute the missing attributes // ourselves? Do we simply return CKR_TEMPLATE_INCOMPLETE? // found = template_attribute_find( tmpl, CKA_PUBLIC_EXPONENT, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_PRIVATE_EXPONENT, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_PRIME_1, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_PRIME_2, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_EXPONENT_1, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_EXPONENT_2, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_COEFFICIENT, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } // we should probably verify that the (e != p) and (e != q). ie. gcd(e,n) == 1 // return priv_key_check_required_attributes( tmpl, mode ); } // rsa_priv_set_default_attributes() // CK_RV rsa_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *modulus_attr = NULL; CK_ATTRIBUTE *public_exp_attr = NULL; CK_ATTRIBUTE *private_exp_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; // satisfy the compiler // if (mode) modulus_attr = NULL; priv_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); modulus_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); public_exp_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); private_exp_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !modulus_attr || !public_exp_attr || !private_exp_attr) { if (type_attr) free( type_attr ); if (modulus_attr) free( modulus_attr ); if (public_exp_attr) free( public_exp_attr ); if (private_exp_attr) free( private_exp_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } modulus_attr->type = CKA_MODULUS; modulus_attr->ulValueLen = 0; modulus_attr->pValue = NULL; public_exp_attr->type = CKA_PUBLIC_EXPONENT; public_exp_attr->ulValueLen = 0; public_exp_attr->pValue = NULL; private_exp_attr->type = CKA_PRIVATE_EXPONENT; private_exp_attr->ulValueLen = 0; private_exp_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_RSA; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, modulus_attr ); template_update_attribute( tmpl, public_exp_attr ); template_update_attribute( tmpl, private_exp_attr ); return CKR_OK; } // rsa_priv_validate_attributes() // CK_RV rsa_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_MODULUS: case CKA_PRIVATE_EXPONENT: if (mode == MODE_CREATE) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_PUBLIC_EXPONENT: case CKA_PRIME_1: case CKA_PRIME_2: case CKA_EXPONENT_1: case CKA_EXPONENT_2: case CKA_COEFFICIENT: if (mode == MODE_CREATE) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } default: return priv_key_validate_attribute( tmpl, attr, mode ); } } // rsa_priv_check_exportability() // CK_BBOOL rsa_priv_check_exportability( CK_ATTRIBUTE_TYPE type ) { switch (type) { case CKA_PRIVATE_EXPONENT: case CKA_PRIME_1: case CKA_PRIME_2: case CKA_EXPONENT_1: case CKA_EXPONENT_2: case CKA_COEFFICIENT: st_err_log(86, __FILE__, __LINE__); return FALSE; } return TRUE; } // create the ASN.1 encoding for the private key for wrapping as defined // in PKCS #8 // // ASN.1 type PrivateKeyInfo ::= SEQUENCE { // version Version // privateKeyAlgorithm PrivateKeyAlgorithmIdentifier // privateKey PrivateKey // attributes OPTIONAL // } // // Where PrivateKey is defined as follows for RSA: // // ASN.1 type RSAPrivateKey // // RSAPrivateKey ::= SEQUENCE { // version Version // modulus INTEGER // publicExponent INTEGER // privateExponent INTEGER // prime1 INTEGER // prime2 INTEGER // exponent1 INTEGER // exponent2 INTEGER // coefficient INTEGER // } // CK_RV rsa_priv_wrap_get_data( TEMPLATE *tmpl, CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ) { CK_ATTRIBUTE *modulus = NULL; CK_ATTRIBUTE *publ_exp = NULL, *opaque = NULL; #if 0 CK_ATTRIBUTE *publ_exp = NULL, *priv_exp = NULL; CK_ATTRIBUTE *prime1 = NULL, *prime2 = NULL; CK_ATTRIBUTE *exponent1 = NULL, *exponent2 = NULL; CK_ATTRIBUTE *coeff = NULL; #endif CK_RV rc; // compute the total length of the BER-encoded data // if (template_attribute_find(tmpl, CKA_MODULUS, &modulus) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (template_attribute_find(tmpl, CKA_PUBLIC_EXPONENT, &publ_exp) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (template_attribute_find(tmpl, CKA_IBM_OPAQUE, &opaque) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } #if 0 if (template_attribute_find(tmpl, CKA_PRIVATE_EXPONENT, &priv_exp) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (template_attribute_find(tmpl, CKA_PRIME_1, &prime1) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (template_attribute_find(tmpl, CKA_PRIME_2, &prime2) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (template_attribute_find(tmpl, CKA_EXPONENT_1, &exponent1) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (template_attribute_find(tmpl, CKA_EXPONENT_2, &exponent2) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (template_attribute_find(tmpl, CKA_COEFFICIENT, &coeff) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = ber_encode_RSAPrivateKey( length_only, data, data_len, modulus, publ_exp, priv_exp, prime1, prime2, exponent1, exponent2, coeff ); #else rc = ber_encode_RSAPrivateKey( length_only, data, data_len, modulus, publ_exp, opaque); #endif if (rc != CKR_OK){ st_err_log(87, __FILE__, __LINE__); } return rc; } // // CK_RV rsa_priv_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG total_length ) { CK_ATTRIBUTE *modulus = NULL; CK_ATTRIBUTE *publ_exp = NULL; #if 0 CK_ATTRIBUTE *priv_exp = NULL; CK_ATTRIBUTE *prime1 = NULL; CK_ATTRIBUTE *prime2 = NULL; CK_ATTRIBUTE *exponent1 = NULL; CK_ATTRIBUTE *exponent2 = NULL; CK_ATTRIBUTE *coeff = NULL; #else CK_ATTRIBUTE *opaque = NULL; #endif CK_RV rc; rc = ber_decode_RSAPrivateKey( data, total_length, &modulus, &publ_exp, #if 0 &priv_exp, &prime1, &prime2, &exponent1, &exponent2, &coeff ); #else &opaque ); #endif if (rc != CKR_OK){ st_err_log(88, __FILE__, __LINE__); return rc; } remove_leading_zeros( modulus ); remove_leading_zeros( publ_exp ); #if 0 remove_leading_zeros( priv_exp ); remove_leading_zeros( prime1 ); remove_leading_zeros( prime2 ); remove_leading_zeros( exponent1 ); remove_leading_zeros( exponent2 ); remove_leading_zeros( coeff ); #else remove_leading_zeros( opaque ); #endif template_update_attribute( tmpl, modulus ); template_update_attribute( tmpl, publ_exp ); #if 0 template_update_attribute( tmpl, priv_exp ); template_update_attribute( tmpl, prime1 ); template_update_attribute( tmpl, prime2 ); template_update_attribute( tmpl, exponent1 ); template_update_attribute( tmpl, exponent2 ); template_update_attribute( tmpl, coeff ); #else template_update_attribute( tmpl, opaque ); #endif return CKR_OK; } // dsa_publ_check_required_attributes() // CK_RV dsa_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_PRIME, &attr ); if (!found) { if (mode == MODE_CREATE || mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_SUBPRIME, &attr ); if (!found) { if (mode == MODE_CREATE || mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_BASE, &attr ); if (!found) { if (mode == MODE_CREATE || mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return publ_key_check_required_attributes( tmpl, mode ); } // dsa_publ_set_default_attributes() // CK_RV dsa_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *prime_attr = NULL; CK_ATTRIBUTE *subprime_attr = NULL; CK_ATTRIBUTE *base_attr = NULL; CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) prime_attr = NULL; publ_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); prime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); subprime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); base_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !prime_attr || !subprime_attr || !base_attr || !value_attr) { if (type_attr) free( type_attr ); if (prime_attr) free( prime_attr ); if (subprime_attr) free( subprime_attr ); if (base_attr) free( base_attr ); if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } prime_attr->type = CKA_PRIME; prime_attr->ulValueLen = 0; prime_attr->pValue = NULL; subprime_attr->type = CKA_SUBPRIME; subprime_attr->ulValueLen = 0; subprime_attr->pValue = NULL; base_attr->type = CKA_BASE; base_attr->ulValueLen = 0; base_attr->pValue = NULL; value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_DSA; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, prime_attr ); template_update_attribute( tmpl, subprime_attr ); template_update_attribute( tmpl, base_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // dsa_publ_validate_attributes() // CK_RV dsa_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_PRIME: { CK_ULONG size; if (mode != MODE_CREATE && mode != MODE_KEYGEN){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } // must be between [512, 1024] bits, and a multiple of 64 bits // size = attr->ulValueLen; if (size < 64 || size > 128 || (size % 8 != 0)){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } return remove_leading_zeros( attr ); } case CKA_SUBPRIME: { if (mode != MODE_CREATE && mode != MODE_KEYGEN){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } // subprime must be 160 bits // if (attr->ulValueLen != 20){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } return remove_leading_zeros( attr ); } case CKA_BASE: if (mode == MODE_CREATE || mode == MODE_KEYGEN) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_VALUE: if (mode == MODE_CREATE) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } default: return publ_key_validate_attribute( tmpl, attr, mode ); } } // dsa_priv_check_required_attributes() // CK_RV dsa_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_PRIME, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_SUBPRIME, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_BASE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return priv_key_check_required_attributes( tmpl, mode ); } // dsa_priv_set_default_attributes() // CK_RV dsa_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *prime_attr = NULL; CK_ATTRIBUTE *subprime_attr = NULL; CK_ATTRIBUTE *base_attr = NULL; CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) prime_attr = NULL; priv_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); prime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); subprime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); base_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !prime_attr || !subprime_attr || !base_attr || !value_attr) { if (type_attr) free( type_attr ); if (prime_attr) free( prime_attr ); if (subprime_attr) free( subprime_attr ); if (base_attr) free( base_attr ); if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } prime_attr->type = CKA_PRIME; prime_attr->ulValueLen = 0; prime_attr->pValue = NULL; subprime_attr->type = CKA_SUBPRIME; subprime_attr->ulValueLen = 0; subprime_attr->pValue = NULL; base_attr->type = CKA_BASE; base_attr->ulValueLen = 0; base_attr->pValue = NULL; value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_DSA; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, prime_attr ); template_update_attribute( tmpl, subprime_attr ); template_update_attribute( tmpl, base_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // dsa_priv_validate_attributes() // CK_RV dsa_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_PRIME: { CK_ULONG size; if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } // must be between [512, 1024] bits, and a multiple of 64 bits // size = attr->ulValueLen; if (size < 64 || size > 128 || (size % 8 != 0)){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } return remove_leading_zeros( attr ); } case CKA_SUBPRIME: { if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } // subprime must be 160 bits // if (attr->ulValueLen != 20){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } return remove_leading_zeros( attr ); } case CKA_BASE: case CKA_VALUE: if (mode == MODE_CREATE) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } default: return priv_key_validate_attribute( tmpl, attr, mode ); } } // dsa_priv_check_exportability() // CK_BBOOL dsa_priv_check_exportability( CK_ATTRIBUTE_TYPE type ) { switch (type) { case CKA_VALUE: return FALSE; } return TRUE; } // create the ASN.1 encoding for the private key for wrapping as defined // in PKCS #8 // // ASN.1 type PrivateKeyInfo ::= SEQUENCE { // version Version // privateKeyAlgorithm PrivateKeyAlgorithmIdentifier // privateKey PrivateKey // attributes OPTIONAL // } // // PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier // // AlgorithmIdentifier ::= SEQUENCE { // algorithm OBJECT IDENTIFIER // parameters ANY DEFINED BY algorithm OPTIONAL // } // // paramters ::= SEQUENCE { // p INTEGER // q INTEGER // g INTEGER // } // // privateKey ::= INTEGER // // CK_RV dsa_priv_wrap_get_data( TEMPLATE *tmpl, CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ) { CK_ATTRIBUTE *prime = NULL; CK_ATTRIBUTE *subprime = NULL; CK_ATTRIBUTE *base = NULL; CK_ATTRIBUTE *value = NULL; CK_RV rc; // compute the total length of the BER-encoded data // if (template_attribute_find(tmpl, CKA_PRIME, &prime) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (template_attribute_find(tmpl, CKA_SUBPRIME, &subprime) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (template_attribute_find(tmpl, CKA_BASE, &base) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (template_attribute_find(tmpl, CKA_VALUE, &value) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = ber_encode_DSAPrivateKey( length_only, data, data_len, prime, subprime, base, value ); if (rc != CKR_OK){ st_err_log(87, __FILE__, __LINE__); } return rc; } #if 0 // // CK_RV dsa_priv_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG total_length ) { CK_ATTRIBUTE *prime = NULL; CK_ATTRIBUTE *subprime = NULL; CK_ATTRIBUTE *base = NULL; CK_ATTRIBUTE *value = NULL; CK_RV rc; rc = ber_decode_DSAPrivateKey( data, total_length, &prime, &subprime, &base, &value ); if (rc != CKR_OK){ st_err_log(88, __FILE__, __LINE__); return rc; } remove_leading_zeros( prime ); remove_leading_zeros( subprime ); remove_leading_zeros( base ); remove_leading_zeros( value ); template_update_attribute( tmpl, prime ); template_update_attribute( tmpl, subprime ); template_update_attribute( tmpl, base ); template_update_attribute( tmpl, value ); return CKR_OK; } #endif // ecdsa_publ_check_required_attributes() // CK_RV ecdsa_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_ECDSA_PARAMS, &attr ); if (!found) { if (mode == MODE_CREATE || mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_EC_POINT, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return publ_key_check_required_attributes( tmpl, mode ); } // ecdsa_publ_set_default_attributes() // CK_RV ecdsa_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *params_attr = NULL; CK_ATTRIBUTE *ec_point_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) params_attr = NULL; publ_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); params_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); ec_point_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !params_attr || !ec_point_attr) { if (type_attr) free( type_attr ); if (params_attr) free( params_attr ); if (ec_point_attr) free( ec_point_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } params_attr->type = CKA_ECDSA_PARAMS; params_attr->ulValueLen = 0; params_attr->pValue = NULL; ec_point_attr->type = CKA_EC_POINT; ec_point_attr->ulValueLen = 0; ec_point_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_ECDSA; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, params_attr ); template_update_attribute( tmpl, ec_point_attr ); return CKR_OK; } // ecdsa_publ_validate_attributes() // CK_RV ecdsa_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_ECDSA_PARAMS: if (mode == MODE_CREATE || mode == MODE_KEYGEN) return CKR_OK; else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_EC_POINT: if (mode == MODE_CREATE) return CKR_OK; else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } default: return publ_key_validate_attribute( tmpl, attr, mode ); } } // ecdsa_priv_check_required_attributes() // CK_RV ecdsa_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_ECDSA_PARAMS, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_EC_POINT, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return priv_key_check_required_attributes( tmpl, mode ); } // ecdsa_priv_set_default_attributes() // CK_RV ecdsa_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *params_attr = NULL; CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) params_attr = NULL; priv_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); params_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !params_attr || !value_attr) { if (type_attr) free( type_attr ); if (params_attr) free( params_attr ); if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } params_attr->type = CKA_ECDSA_PARAMS; params_attr->ulValueLen = 0; params_attr->pValue = NULL; value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_ECDSA; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, params_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // ecdsa_priv_validate_attributes() // CK_RV ecdsa_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_ECDSA_PARAMS: if (mode == MODE_CREATE) return CKR_OK; else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_VALUE: if (mode == MODE_CREATE) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } default: return priv_key_validate_attribute( tmpl, attr, mode ); } } // ecdsa_priv_check_exportability() // CK_BBOOL ecdsa_priv_check_exportability( CK_ATTRIBUTE_TYPE type ) { switch (type) { case CKA_VALUE: return FALSE; } return TRUE; } // dh_publ_check_required_attributes() // CK_RV dh_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_PRIME, &attr ); if (!found) { if (mode == MODE_CREATE || mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_BASE, &attr ); if (!found) { if (mode == MODE_CREATE || mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return publ_key_check_required_attributes( tmpl, mode ); } // dh_publ_set_default_attributes() // CK_RV dh_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *prime_attr = NULL; CK_ATTRIBUTE *base_attr = NULL; CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) prime_attr = NULL; publ_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); prime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); base_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !prime_attr || !base_attr || !value_attr) { if (type_attr) free( type_attr ); if (prime_attr) free( prime_attr ); if (base_attr) free( base_attr ); if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } prime_attr->type = CKA_PRIME; prime_attr->ulValueLen = 0; prime_attr->pValue = NULL; base_attr->type = CKA_BASE; base_attr->ulValueLen = 0; base_attr->pValue = NULL; value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_DH; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, prime_attr ); template_update_attribute( tmpl, base_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // dh_publ_validate_attribute() // CK_RV dh_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_PRIME: case CKA_BASE: if (mode == MODE_CREATE || mode == MODE_KEYGEN) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_VALUE: if (mode == MODE_CREATE) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } default: return publ_key_validate_attribute( tmpl, attr, mode ); } } // dh_priv_check_required_attributes() // CK_RV dh_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_PRIME, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_BASE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE_BITS, &attr ); if (found) { if (mode == MODE_CREATE || mode == MODE_UNWRAP){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } } return priv_key_check_required_attributes( tmpl, mode ); } // dh_priv_set_default_attributes() // CK_RV dh_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *prime_attr = NULL; CK_ATTRIBUTE *base_attr = NULL; CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *value_bits_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; CK_ULONG bits = 0L; priv_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); prime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); base_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_bits_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); if (!type_attr || !prime_attr || !base_attr || !value_attr || !value_bits_attr) { if (type_attr) free( type_attr ); if (prime_attr) free( prime_attr ); if (base_attr) free( base_attr ); if (value_attr) free( value_attr ); if (value_bits_attr) free( value_bits_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } prime_attr->type = CKA_PRIME; prime_attr->ulValueLen = 0; prime_attr->pValue = NULL; base_attr->type = CKA_BASE; base_attr->ulValueLen = 0; base_attr->pValue = NULL; value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; value_bits_attr->type = CKA_VALUE_BITS; value_bits_attr->ulValueLen = sizeof(CK_ULONG); value_bits_attr->pValue = (CK_BYTE *)value_bits_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_bits_attr->pValue = bits; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_DH; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, prime_attr ); template_update_attribute( tmpl, base_attr ); template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, value_bits_attr ); return CKR_OK; } // dh_priv_validate_attribute() // CK_RV dh_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_PRIME: case CKA_BASE: case CKA_VALUE: if (mode == MODE_CREATE || mode == MODE_KEYGEN) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } // I'm not sure what to do about VALUE_BITS...we don't really support // Diffie-Hellman keys other than for storage...when the object is // created, we're supposed to add CKA_VALUE_BITS outselves...which we // don't do at this time. (we'd need to add code in C_CreateObject to // call some sort of objecttype-specific callback) // // kapil 05/08/03 : Commented out error flagging, as CKA_VALUE_BITS is valid // attribute for creating DH priv object. The above is // an older comment. case CKA_VALUE_BITS: // st_err_log(7, __FILE__, __LINE__); // return CKR_ATTRIBUTE_READ_ONLY; return CKR_OK ; break ; default: return priv_key_validate_attribute( tmpl, attr, mode ); } } // dh_priv_check_exportability() // CK_BBOOL dh_priv_check_exportability( CK_ATTRIBUTE_TYPE type ) { switch (type) { case CKA_VALUE: return FALSE; } return TRUE; } // kea_publ_check_required_attributes() // CK_RV kea_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_PRIME, &attr ); if (!found) { if (mode == MODE_CREATE || mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_SUBPRIME, &attr ); if (!found) { if (mode == MODE_CREATE || mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_BASE, &attr ); if (!found) { if (mode == MODE_CREATE || mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return publ_key_check_required_attributes( tmpl, mode ); } // kea_publ_set_default_attributes() // CK_RV kea_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *prime_attr = NULL; CK_ATTRIBUTE *subprime_attr = NULL; CK_ATTRIBUTE *base_attr = NULL; CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) prime_attr = NULL; publ_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); prime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); subprime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); base_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !prime_attr || !subprime_attr || !base_attr || !value_attr) { if (type_attr) free( type_attr ); if (prime_attr) free( prime_attr ); if (subprime_attr) free( subprime_attr ); if (base_attr) free( base_attr ); if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } prime_attr->type = CKA_PRIME; prime_attr->ulValueLen = 0; prime_attr->pValue = NULL; subprime_attr->type = CKA_SUBPRIME; subprime_attr->ulValueLen = 0; subprime_attr->pValue = NULL; base_attr->type = CKA_BASE; base_attr->ulValueLen = 0; base_attr->pValue = NULL; value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_KEA; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, prime_attr ); template_update_attribute( tmpl, subprime_attr ); template_update_attribute( tmpl, base_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // kea_publ_validate_attribute() // CK_RV kea_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_PRIME: case CKA_SUBPRIME: case CKA_BASE: if (mode == MODE_CREATE || mode == MODE_KEYGEN) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_VALUE: if (mode == MODE_CREATE) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } default: return publ_key_validate_attribute( tmpl, attr, mode ); } } // kea_priv_check_required_attributes() // CK_RV kea_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_PRIME, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_SUBPRIME, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_BASE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return priv_key_check_required_attributes( tmpl, mode ); } // kea_priv_set_default_attributes() // CK_RV kea_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *prime_attr = NULL; CK_ATTRIBUTE *subprime_attr = NULL; CK_ATTRIBUTE *base_attr = NULL; CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) prime_attr = NULL; priv_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); prime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); subprime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); base_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !prime_attr || !base_attr || !value_attr || !subprime_attr) { if (prime_attr) free( prime_attr ); if (subprime_attr) free( subprime_attr ); if (base_attr) free( base_attr ); if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } prime_attr->type = CKA_PRIME; prime_attr->ulValueLen = 0; prime_attr->pValue = NULL; subprime_attr->type = CKA_SUBPRIME; subprime_attr->ulValueLen = 0; subprime_attr->pValue = NULL; base_attr->type = CKA_BASE; base_attr->ulValueLen = 0; base_attr->pValue = NULL; value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_KEA; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, prime_attr ); template_update_attribute( tmpl, subprime_attr ); template_update_attribute( tmpl, base_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // kea_priv_validate_attribute() // CK_RV kea_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_PRIME: case CKA_SUBPRIME: case CKA_BASE: case CKA_VALUE: if (mode == MODE_CREATE) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } default: return priv_key_validate_attribute( tmpl, attr, mode ); } } // kea_priv_check_exportability() // CK_BBOOL kea_priv_check_exportability( CK_ATTRIBUTE_TYPE type ) { switch (type) { case CKA_VALUE: return FALSE; } return TRUE; } // generic_secret_check_required_attributes() // CK_RV generic_secret_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE_LEN, &attr ); if (!found) { // here's another place where PKCS #11 deviates from its own specification. // the spec states that VALUE_LEN must be present for KEYGEN but later // it's merely optional if the mechanism is CKM_SSL3_PRE_MASTER_KEY_GEN. // Unfortunately, we can't check the mechanism at this point // //if (mode == MODE_KEYGEN) // return CKR_TEMPLATE_INCOMPLETE; return CKR_OK; } else { // Another contradiction within the spec: When describing the key types // the spec says that VALUE_LEN must not be specified when unwrapping // a key. In the section describing the mechanisms, though, it's allowed for // most unwrapping mechanisms. Netscape DOES does specify this attribute // when unwrapping. // //if (mode == MODE_CREATE || mode == MODE_UNWRAP) if (mode == MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } } return secret_key_check_required_attributes( tmpl, mode ); } // generic_secret_set_default_attributes() // CK_RV generic_secret_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *value_len_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; CK_ULONG len = 0L; if (mode) value_attr = NULL; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_len_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); if (!type_attr || !value_attr || !value_len_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); if (value_len_attr) free( value_len_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; value_len_attr->type = CKA_VALUE_LEN; value_len_attr->ulValueLen = sizeof(CK_ULONG); value_len_attr->pValue = (CK_BYTE *)value_len_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_len_attr->pValue = len; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_GENERIC_SECRET; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, value_len_attr ); return CKR_OK; } // generic_secret_validate_attribute() // CK_RV generic_secret_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_VALUE: if (mode == MODE_CREATE) return CKR_OK; else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } // Another contradiction within the spec: When describing the key types // the spec says that VALUE_LEN must not be specified when unwrapping // a key. In the section describing the mechanisms, though, it's allowed for // most unwrapping mechanisms. Netscape DOES does specify this attribute // when unwrapping. // case CKA_VALUE_LEN: if (mode == MODE_KEYGEN || mode == MODE_DERIVE) return CKR_OK; else { if (mode == MODE_UNWRAP) { if (nv_token_data->tweak_vector.netscape_mods == TRUE) return CKR_OK; } st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // generic_secret_check_exportability() // CK_BBOOL generic_secret_check_exportability( CK_ATTRIBUTE_TYPE type ) { switch (type) { case CKA_VALUE: return FALSE; } return TRUE; } // // CK_RV generic_secret_wrap_get_data( TEMPLATE * tmpl, CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len ) { CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_RV rc; if (!tmpl || !data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } #if 0 rc = template_attribute_find( tmpl, CKA_VALUE, &attr ); #else // In the CCA token we're using the IBM_OPAQUE attribute to store the CCA key rc = template_attribute_find( tmpl, CKA_IBM_OPAQUE, &attr ); #endif if (rc == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } *data_len = attr->ulValueLen; if (length_only == FALSE) { ptr = (CK_BYTE *)malloc( attr->ulValueLen ); if (!ptr){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( ptr, attr->pValue, attr->ulValueLen ); *data = ptr; } return CKR_OK; } // // CK_RV generic_secret_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ) { CK_ATTRIBUTE * attr = NULL; CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * value_len_attr = NULL; CK_BYTE * ptr = NULL; CK_ULONG rc, len; if (fromend == TRUE) ptr = data + data_len; else ptr = data; // it's possible that the user specified CKA_VALUE_LEN in the // template. if so, try to use it. by default, CKA_VALUE_LEN is 0 // rc = template_attribute_find( tmpl, CKA_VALUE_LEN, &attr ); if (rc) { len = *(CK_ULONG *)attr->pValue; if (len > data_len) { st_err_log(9, __FILE__, __LINE__); rc = CKR_ATTRIBUTE_VALUE_INVALID; goto error; } if (len != 0) data_len = len; } if (fromend == TRUE) ptr -= data_len; #if 0 rc = build_attribute( CKA_VALUE, ptr, data_len, &value_attr ); #else rc = build_attribute( CKA_IBM_OPAQUE, ptr, data_len, &value_attr ); #endif if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } if (data_len != len) { rc = build_attribute( CKA_VALUE_LEN, (CK_BYTE *)&data_len, sizeof(CK_ULONG), &value_len_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } } template_update_attribute( tmpl, value_attr ); if (data_len != len) template_update_attribute( tmpl, value_len_attr ); return CKR_OK; error: if (value_attr) free( value_attr ); if (value_len_attr) free( value_len_attr ); return rc; } // rc2_check_required_attributes() // CK_RV rc2_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE_LEN, &attr ); if (!found) { if (mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // rc2_set_default_attributes() // CK_RV rc2_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *value_len_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; CK_ULONG len = 0L; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_len_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); if (!type_attr || !value_attr || !value_len_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); if (value_len_attr) free( value_len_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; value_len_attr->type = CKA_VALUE_LEN; value_len_attr->ulValueLen = sizeof(CK_ULONG); value_len_attr->pValue = (CK_BYTE *)value_len_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_len_attr->pValue = len; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_RC2; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, value_len_attr ); return CKR_OK; } // rc2_validate_attribute() // CK_RV rc2_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_VALUE: if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } // rc2 key length <= 128 bytes // if (attr->ulValueLen > 128) return CKR_ATTRIBUTE_VALUE_INVALID; else return CKR_OK; case CKA_VALUE_LEN: { CK_ULONG len; if (mode != MODE_KEYGEN && mode != MODE_DERIVE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } len = *(CK_ULONG *)attr->pValue; if (len > 128){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // rc4_set_default_attributes() // CK_RV rc4_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *value_len_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; CK_ULONG len = 0L; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_len_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); if (!type_attr || !value_attr || !value_len_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); if (value_len_attr) free( value_len_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; value_len_attr->type = CKA_VALUE_LEN; value_len_attr->ulValueLen = sizeof(CK_ULONG); value_len_attr->pValue = (CK_BYTE *)value_len_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_len_attr->pValue = len; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_RC4; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, value_len_attr ); return CKR_OK; } // rc4_check_required_attributes() // CK_RV rc4_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE_LEN, &attr ); if (!found) { if (mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // rc4_validate_attribute() // CK_RV rc4_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_VALUE: { if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } // key length <= 256 bytes // if (attr->ulValueLen > 256){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } case CKA_VALUE_LEN: { CK_ULONG len; if (mode != MODE_KEYGEN && mode != MODE_DERIVE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } len = *(CK_ULONG *)attr->pValue; if (len > 255){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // rc5_check_required_attributes() // CK_RV rc5_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE_LEN, &attr ); if (!found) { if (mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // rc5_set_default_attributes() // CK_RV rc5_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *value_len_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; CK_ULONG len = 0L; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_len_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); if (!type_attr || !value_attr || !value_len_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); if (value_len_attr) free( value_len_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; value_len_attr->type = CKA_VALUE_LEN; value_len_attr->ulValueLen = sizeof(CK_ULONG); value_len_attr->pValue = (CK_BYTE *)value_len_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_len_attr->pValue = len; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_RC5; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, value_len_attr ); return CKR_OK; } // rc5_validate_attribute() // CK_RV rc5_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_VALUE: { if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } // key length <= 256 bytes // if (attr->ulValueLen > 255){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } case CKA_VALUE_LEN: { CK_ULONG len; if (mode != MODE_KEYGEN && mode != MODE_DERIVE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } len = *(CK_ULONG *)attr->pValue; if (len > 255){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // // CK_RV des_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // // CK_BBOOL des_check_weak_key( CK_BYTE *key ) { CK_ULONG i; for (i=0; i < des_weak_count; i++) { if (memcmp(key, des_weak_keys[i], DES_KEY_SIZE) == 0) return TRUE; } for (i=0; i < des_semi_weak_count; i++) { if (memcmp(key, des_semi_weak_keys[i], DES_KEY_SIZE) == 0) return TRUE; } for (i=0; i < des_possibly_weak_count; i++) { if (memcmp(key, des_possibly_weak_keys[i], DES_KEY_SIZE) == 0) return TRUE; } return FALSE; } // // CK_RV des_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * type_attr = NULL; if (mode) value_attr = NULL; secret_key_set_default_attributes( tmpl, mode ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); if (!value_attr || !type_attr) { if (value_attr) free( value_attr ); if (type_attr) free( type_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_DES; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // // CK_RV des_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ) { CK_ATTRIBUTE * value_attr = NULL; CK_BYTE * ptr = NULL; CK_ULONG i; if (data_len < DES_BLOCK_SIZE){ st_err_log(62, __FILE__, __LINE__); return CKR_WRAPPED_KEY_INVALID; } if (fromend == TRUE) //ptr = data + data_len - DES_BLOCK_SIZE; ptr = data + data_len; else ptr = data; #if 0 if (nv_token_data->tweak_vector.check_des_parity == TRUE) { for (i=0; i < DES_KEY_SIZE; i++) { if (parity_is_odd(ptr[i]) == FALSE){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } } } value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + DES_BLOCK_SIZE ); #else value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + data_len ); #endif if (!value_attr) { st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } #if 0 value_attr->type = CKA_VALUE; value_attr->ulValueLen = DES_BLOCK_SIZE; value_attr->pValue = (CK_BYTE *)value_attr + sizeof(CK_ATTRIBUTE); memcpy( value_attr->pValue, ptr, DES_BLOCK_SIZE ); #else value_attr->type = CKA_IBM_OPAQUE; value_attr->ulValueLen = data_len; value_attr->pValue = (CK_BYTE *)value_attr + sizeof(CK_ATTRIBUTE); memcpy( value_attr->pValue, ptr, data_len ); #endif template_update_attribute( tmpl, value_attr ); return CKR_OK; } // des_validate_attribute() // CK_RV des_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { CK_BYTE * ptr = NULL; CK_ULONG i; switch (attr->type) { case CKA_VALUE: // key length always 8 bytes // if (mode == MODE_CREATE) { if (attr->ulValueLen != DES_KEY_SIZE){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } if (nv_token_data->tweak_vector.check_des_parity == TRUE) { ptr = attr->pValue; for (i=0; i < DES_KEY_SIZE; i++) { if (parity_is_odd(ptr[i]) == FALSE){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } } } return CKR_OK; } else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_VALUE_LEN: // Cryptoki doesn't allow this but Netscape tries uses it // if (nv_token_data->tweak_vector.netscape_mods == TRUE) { if (mode == MODE_CREATE || mode == MODE_DERIVE || mode == MODE_KEYGEN || mode == MODE_UNWRAP) { CK_ULONG len = *(CK_ULONG *)attr->pValue; if (len != DES_KEY_SIZE){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } } else{ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } #if 0 // // CK_RV des_wrap_get_data( TEMPLATE * tmpl, CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len ) { CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_RV rc; if (!tmpl || !data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } *data_len = attr->ulValueLen; if (length_only == FALSE) { ptr = (CK_BYTE *)malloc( attr->ulValueLen ); if (!ptr){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( ptr, attr->pValue, attr->ulValueLen ); *data = ptr; } return CKR_OK; } #endif // des2_check_required_attributes() // CK_RV des2_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // des2_set_default_attributes() // CK_RV des2_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * type_attr = NULL; if (mode) value_attr = NULL; secret_key_set_default_attributes( tmpl, mode ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); if (!value_attr || !type_attr) { if (value_attr) free( value_attr ); if (type_attr) free( type_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_DES2; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // des2_validate_attribute() // CK_RV des2_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { CK_BYTE * ptr = NULL; CK_ULONG i; switch (attr->type) { case CKA_VALUE: // key length always 16 bytes // if (mode == MODE_CREATE) { if (attr->ulValueLen != (2 * DES_KEY_SIZE)){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } if (nv_token_data->tweak_vector.check_des_parity == TRUE) { ptr = attr->pValue; for (i=0; i < 2*DES_KEY_SIZE; i++) { if (parity_is_odd(ptr[i]) == FALSE){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } } } return CKR_OK; } else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_VALUE_LEN: // Cryptoki doesn't allow this but Netscape tries uses it // if (nv_token_data->tweak_vector.netscape_mods == TRUE) { if (mode == MODE_CREATE || mode == MODE_DERIVE || mode == MODE_KEYGEN || mode == MODE_UNWRAP) { CK_ULONG len = *(CK_ULONG *)attr->pValue; if (len != (2 * DES_KEY_SIZE)){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } } else{ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // des3_check_required_attributes() // CK_RV des3_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // des3_set_default_attributes() // CK_RV des3_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * type_attr = NULL; if (mode) value_attr = NULL; secret_key_set_default_attributes( tmpl, mode ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); if (!value_attr || !type_attr) { if (value_attr) free( value_attr ); if (type_attr) free( type_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_DES3; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // // CK_RV des3_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ) { CK_ATTRIBUTE * value_attr = NULL; CK_BYTE * ptr = NULL; CK_ULONG i; if (data_len < 3 * DES_BLOCK_SIZE){ st_err_log(62, __FILE__, __LINE__); return CKR_WRAPPED_KEY_INVALID; } if (fromend == TRUE) //ptr = data + data_len - (3*DES_BLOCK_SIZE); ptr = data + data_len; else ptr = data; #if 0 if (nv_token_data->tweak_vector.check_des_parity == TRUE) { for (i=0; i < 3*DES_KEY_SIZE; i++) { if (parity_is_odd(ptr[i]) == FALSE){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } } } value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + (3 * DES_BLOCK_SIZE) ); #else value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + data_len ); #endif if (!value_attr) { st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } #if 0 value_attr->type = CKA_VALUE; value_attr->ulValueLen = 3 * DES_BLOCK_SIZE; value_attr->pValue = (CK_BYTE *)value_attr + sizeof(CK_ATTRIBUTE); memcpy( value_attr->pValue, ptr, 3 * DES_BLOCK_SIZE ); #else value_attr->type = CKA_IBM_OPAQUE; value_attr->ulValueLen = data_len; value_attr->pValue = (CK_BYTE *)value_attr + sizeof(CK_ATTRIBUTE); memcpy( value_attr->pValue, ptr, data_len ); #endif template_update_attribute( tmpl, value_attr ); return CKR_OK; } // // CK_RV des3_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { CK_BYTE * ptr = NULL; CK_ULONG i; switch (attr->type) { case CKA_VALUE: // key length always 24 bytes // if (mode == MODE_CREATE) { if (attr->ulValueLen != (3 * DES_KEY_SIZE)){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } if (nv_token_data->tweak_vector.check_des_parity == TRUE) { ptr = attr->pValue; for (i=0; i < 3*DES_KEY_SIZE; i++) { if (parity_is_odd(ptr[i]) == FALSE){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } } } return CKR_OK; } else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_VALUE_LEN: // Cryptoki doesn't allow this but Netscape tries uses it // if (nv_token_data->tweak_vector.netscape_mods == TRUE) { if (mode == MODE_CREATE || mode == MODE_DERIVE || mode == MODE_KEYGEN || mode == MODE_UNWRAP) { // CK_ULONG len = *(CK_ULONG *)attr->pValue; // if (len != (3 * DES_KEY_SIZE)) // return CKR_ATTRIBUTE_VALUE_INVALID; // else return CKR_OK; } else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } } else{ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } #if 0 // // CK_RV des3_wrap_get_data( TEMPLATE * tmpl, CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len ) { CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_RV rc; if (!tmpl || !data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } *data_len = attr->ulValueLen; if (length_only == FALSE) { ptr = (CK_BYTE *)malloc( attr->ulValueLen ); if (!ptr){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( ptr, attr->pValue, attr->ulValueLen ); *data = ptr; } return CKR_OK; } #endif // cast_check_required_attributes() // CK_RV cast_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE_LEN, &attr ); if (!found) { if (mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // cast_set_default_attributes() // CK_RV cast_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *value_len_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; CK_ULONG len = 0L; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_len_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); if (!type_attr || !value_attr || !value_len_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); if (value_len_attr) free( value_len_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; value_len_attr->type = CKA_VALUE_LEN; value_len_attr->ulValueLen = sizeof(CK_ULONG); value_len_attr->pValue = (CK_BYTE *)value_len_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_len_attr->pValue = len; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_CAST; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, value_len_attr ); return CKR_OK; } // cast_validate_attribute() // CK_RV cast_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { CK_ULONG len; switch (attr->type) { case CKA_VALUE: { if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } if (attr->ulValueLen > 8 || attr->ulValueLen < 1){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } case CKA_VALUE_LEN: { if (mode != MODE_KEYGEN && mode != MODE_DERIVE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } len = *(CK_ULONG *)attr->pValue; if (len > 8 || len < 1){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // cast3_check_required_attributes() // CK_RV cast3_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE_LEN, &attr ); if (!found) { if (mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // cast3_set_default_attributes() // CK_RV cast3_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *value_len_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; CK_ULONG len = 0L; if (mode) value_attr = NULL; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_len_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); if (!type_attr || !value_attr || !value_len_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); if (value_len_attr) free( value_len_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; value_len_attr->type = CKA_VALUE_LEN; value_len_attr->ulValueLen = sizeof(CK_ULONG); value_len_attr->pValue = (CK_BYTE *)value_len_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_len_attr->pValue = len; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_CAST3; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, value_len_attr ); return CKR_OK; } // cast3_validate_attribute() // CK_RV cast3_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { CK_ULONG len; switch (attr->type) { case CKA_VALUE: { if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } if (attr->ulValueLen > 8 || attr->ulValueLen < 1){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } case CKA_VALUE_LEN: { if (mode != MODE_KEYGEN && mode != MODE_DERIVE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } len = *(CK_ULONG *)attr->pValue; if (len > 8 || len < 1){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // cast5_check_required_attributes() // CK_RV cast5_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE_LEN, &attr ); if (!found) { if (mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // cast5_set_default_attributes() // CK_RV cast5_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *value_len_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; CK_ULONG len = 0L; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_len_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); if (!type_attr || !value_attr || !value_len_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); if (value_len_attr) free( value_len_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; value_len_attr->type = CKA_VALUE_LEN; value_len_attr->ulValueLen = sizeof(CK_ULONG); value_len_attr->pValue = (CK_BYTE *)value_len_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_len_attr->pValue = len; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_CAST5; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, value_len_attr ); return CKR_OK; } // cast5_validate_attribute() // CK_RV cast5_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { CK_ULONG len; switch (attr->type) { case CKA_VALUE: { if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } if (attr->ulValueLen > 16 || attr->ulValueLen < 1){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } case CKA_VALUE_LEN: { if (mode != MODE_KEYGEN && mode != MODE_DERIVE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } len = *(CK_ULONG *)attr->pValue; if (len < 1 || len > 16){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // idea_check_required_attributes() // CK_RV idea_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // idea_set_default_attributes() // CK_RV idea_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) value_attr = NULL; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !value_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_IDEA; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // idea_validate_attribute() // CK_RV idea_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_VALUE: { if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } if (attr->ulValueLen != 16){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // cdmf_check_required_attributes() // CK_RV cdmf_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } #if !(NOCDMF) // cdmf_set_default_attributes() // CK_RV cdmf_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) value_attr = NULL; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !value_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_CDMF; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // cdmf_validate_attribute() // CK_RV cdmf_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { CK_ULONG len; switch (attr->type) { case CKA_VALUE: { #if 0 CDMF_Transform_Args args; #endif CK_ULONG req_len, repl_len; CK_BYTE cdmf_key[DES_KEY_SIZE]; CK_RV rc; if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } if (attr->ulValueLen != DES_KEY_SIZE){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } #if 0 req_len = sizeof(args); repl_len = DES_KEY_SIZE; memcpy( args.des_key, attr->pValue, DES_KEY_SIZE ); rc = communicate( PK_CDMF_TRANSFORM_KEY, &args, req_len, cdmf_key, &repl_len, NULL, 0, NULL, 0 ); if (rc != CKR_OK) return rc; if (rc == CKR_OK) { if (repl_len != DES_KEY_SIZE) return CKR_GENERAL_ERROR; memcpy( attr->pValue, cdmf_key, DES_KEY_SIZE ); } return CKR_OK; #else return tok_cdmf_transform(attr->pValue, DES_KEY_SIZE); #endif } case CKA_VALUE_LEN: { if (nv_token_data->tweak_vector.netscape_mods == TRUE) { if (mode == MODE_CREATE || mode == MODE_KEYGEN) { len = *(CK_ULONG *)attr->pValue; if (len != DES_KEY_SIZE){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } } else{ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } #endif // skipjack_check_required_attributes() // CK_RV skipjack_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // skipjack_set_default_attributes() // CK_RV skipjack_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) value_attr = NULL; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !value_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_SKIPJACK; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // skipjack_validate_attribute() // CK_RV skipjack_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_VALUE: { if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } if (attr->ulValueLen != 20){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // baton_check_required_attributes() // CK_RV baton_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // baton_set_default_attributes() // CK_RV baton_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) value_attr = NULL; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !value_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_BATON; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // baton_validate_attribute() // CK_RV baton_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_VALUE: { if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } if (attr->ulValueLen != 40){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // juniper_check_required_attributes() // CK_RV juniper_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // juniper_set_default_attributes() // CK_RV juniper_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) value_attr = NULL; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !value_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_JUNIPER; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // juniper_validate_attribute() // CK_RV juniper_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_VALUE: { if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } if (attr->ulValueLen != 40){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // aes_set_default_attributes() // CK_RV aes_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * type_attr = NULL; if (mode) value_attr = NULL; secret_key_set_default_attributes( tmpl, mode ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); if (!value_attr || !type_attr) { if (value_attr) free( value_attr ); if (type_attr) free( type_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_AES; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // aes_check_required_attributes() // CK_RV aes_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // // CK_RV aes_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { CK_BYTE * ptr = NULL; CK_ULONG val; switch (attr->type) { case CKA_VALUE: // key length is either 16, 24 or 32 bytes // if (mode == MODE_CREATE) { if (attr->ulValueLen != AES_KEY_SIZE_128 && attr->ulValueLen != AES_KEY_SIZE_192 && attr->ulValueLen != AES_KEY_SIZE_256 ) { st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } return CKR_OK; } else { st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_VALUE_LEN: if (mode == MODE_CREATE || mode == MODE_DERIVE || mode == MODE_KEYGEN || mode == MODE_UNWRAP) { val = *(CK_ULONG *)attr->pValue; if (val != AES_KEY_SIZE_128 && val != AES_KEY_SIZE_192 && val != AES_KEY_SIZE_256 ){ st_err_log(7, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } return CKR_OK; } else{ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // // CK_RV aes_wrap_get_data( TEMPLATE * tmpl, CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len ) { CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_RV rc; if (!tmpl || !data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } *data_len = attr->ulValueLen; if (length_only == FALSE) { ptr = (CK_BYTE *)malloc( attr->ulValueLen ); if (!ptr){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( ptr, attr->pValue, attr->ulValueLen ); *data = ptr; } return CKR_OK; } // // CK_RV aes_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ) { CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * val_len_attr = NULL; CK_BYTE * ptr = NULL; CK_ULONG i; CK_ULONG key_size; CK_BBOOL found = FALSE; /* If the user didn't specify the size of the AES key being * unwrapped, we return. - KEY */ found = template_attribute_find( tmpl, CKA_VALUE_LEN, &val_len_attr ); if (!found){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } key_size = *(CK_ULONG *)val_len_attr->pValue; /* key_size should be one of AES's possible sizes */ if (key_size != AES_KEY_SIZE_128 && key_size != AES_KEY_SIZE_192 && key_size != AES_KEY_SIZE_256){ st_err_log(62, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } if (fromend == TRUE) ptr = data + data_len - key_size; else ptr = data; #if 0 if (nv_token_data->tweak_vector.check_des_parity == TRUE) { for (i=0; i < 3*DES_KEY_SIZE; i++) { if (parity_is_odd(ptr[i]) == FALSE){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } } } #endif value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + CCA_KEY_ID_SIZE ); if (!value_attr) { if (value_attr) free( value_attr ); st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = CCA_KEY_ID_SIZE; value_attr->pValue = (CK_BYTE *)value_attr + sizeof(CK_ATTRIBUTE); memcpy( value_attr->pValue, ptr, CCA_KEY_ID_SIZE ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/cca_specific.c0000640000175000017500000010343111327631345022115 0ustar jfjf /* * Licensed materials, Property of IBM Corp. * * openCryptoki CCA token * * (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2006 * * Author: Kent E. Yoder * */ #include #include #include #include #include #include #include #include #include #include #include #include #include "cca_stdll.h" #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "tok_specific.h" #include "tok_struct.h" #include "h_extern.h" #include "csulincl.h" CK_CHAR manuf[] = "IBM Corp."; CK_CHAR model[] = "IBM CCA Token"; CK_CHAR descr[] = "IBM PKCS#11 CCA Token"; CK_CHAR label[] = "IBM PKCS#11 for CCA"; /* mechanisms provided by this token */ MECH_LIST_ELEMENT mech_list[] = { { CKM_DES_KEY_GEN, { 8, 8, CKF_HW | CKF_GENERATE } }, { CKM_DES3_KEY_GEN, { 24, 24, CKF_HW | CKF_GENERATE } }, { CKM_RSA_PKCS_KEY_PAIR_GEN, { 512, 4096, CKF_HW | CKF_GENERATE_KEY_PAIR } }, { CKM_RSA_PKCS, { 512, 4096, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_SIGN | CKF_VERIFY } }, { CKM_MD2_RSA_PKCS, { 512, 4096, CKF_HW | CKF_SIGN | CKF_VERIFY } }, { CKM_MD5_RSA_PKCS, { 512, 4096, CKF_HW | CKF_SIGN | CKF_VERIFY } }, { CKM_SHA1_RSA_PKCS, { 512, 4096, CKF_HW | CKF_SIGN | CKF_VERIFY } }, { CKM_DES_CBC, { 8, 8, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP } }, { CKM_DES_CBC_PAD, { 8, 8, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP } }, { CKM_DES3_CBC, { 24, 24, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP } }, { CKM_DES3_CBC_PAD, { 24, 24, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP } }, { CKM_AES_KEY_GEN, 16, 32, CKF_HW }, { CKM_AES_ECB, 16, 32, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_AES_CBC, 16, 32, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_AES_MAC, 16, 32, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_AES_MAC_GENERAL, 16, 32, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_AES_CBC_PAD, 16, 32, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_SHA_1, { 0, 0, CKF_DIGEST } }, { CKM_SHA_1_HMAC, { 0, 0, CKF_SIGN | CKF_VERIFY } }, { CKM_SHA_1_HMAC_GENERAL, { 0, 0, CKF_SIGN | CKF_VERIFY } }, { CKM_SHA256, { 0, 0, CKF_HW | CKF_DIGEST } }, { CKM_SHA256_HMAC, { 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY } }, { CKM_SHA256_HMAC_GENERAL, { 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY } }, { CKM_MD5, { 0, 0, CKF_DIGEST } }, { CKM_MD5_HMAC, { 0, 0, CKF_SIGN | CKF_VERIFY } }, { CKM_MD5_HMAC_GENERAL, { 0, 0, CKF_SIGN | CKF_VERIFY } }, { CKM_MD2, { 0, 0, CKF_DIGEST } }, { CKM_MD2_HMAC, { 0, 0, CKF_SIGN | CKF_VERIFY } }, { CKM_MD2_HMAC_GENERAL, { 0, 0, CKF_SIGN | CKF_VERIFY } } }; CK_ULONG mech_list_len = (sizeof(mech_list) / sizeof(MECH_LIST_ELEMENT)); CK_RV token_specific_session(CK_SLOT_ID slotid) { return CKR_OK; } CK_RV token_rng(CK_BYTE *output, CK_ULONG bytes) { long return_code, reason_code; unsigned char form[CCA_KEYWORD_SIZE], random_number[CCA_RNG_SIZE]; CK_ULONG bytes_so_far = 0, bytes_left; CK_RV rv; DBG("Enter"); memcpy(form, "RANDOM ", (size_t)CCA_KEYWORD_SIZE); while (bytes_so_far < bytes) { CSNBRNG(&return_code, &reason_code, NULL, NULL, form, random_number); if (return_code != CCA_SUCCESS) { CCADBG("CSNBRNG", return_code, reason_code); rv = CKR_FUNCTION_FAILED; return rv; } if (bytes_so_far + CCA_RNG_SIZE > bytes) { bytes_left = bytes - bytes_so_far; memcpy(&output[bytes_so_far], random_number, (size_t)bytes_left); bytes_so_far += bytes_left; } else { memcpy(&output[bytes_so_far], random_number, (size_t)CCA_RNG_SIZE); bytes_so_far += CCA_RNG_SIZE; } } return CKR_OK; } // convert pkcs slot number to local representation int tok_slot2local(CK_SLOT_ID snum) { return 1; } CK_RV token_specific_init(char *Correlator, CK_SLOT_ID SlotNumber) { unsigned char rule_array[256] = { 0, }; long return_code, reason_code, rule_array_count, verb_data_length; void *lib_csulcca; lib_csulcca = dlopen("libcsulcca.so", (RTLD_GLOBAL | RTLD_NOW)); if (lib_csulcca == NULL) { syslog(LOG_ERR, "%s: Error loading library: [%s]\n", __FUNCTION__, dlerror()); return CKR_FUNCTION_FAILED; } memcpy(rule_array, "STATCCAE", 8); rule_array_count = 1; verb_data_length = 0; CSUACFQ(&return_code, &reason_code, NULL, NULL, &rule_array_count, rule_array, &verb_data_length, NULL); if (return_code != CCA_SUCCESS) { CCADBG("CSUACFQ (STATUS QUERY)", return_code, reason_code); return CKR_FUNCTION_FAILED; } /* This value should be 2 if the master key is set in the card */ if (memcmp(&rule_array[CCA_STATCCAE_SYM_CMK_OFFSET], "2 ", 8)) { LOG(LOG_WARNING, "Warning: CCA symmetric master key is not yet loaded"); } if (memcmp(&rule_array[CCA_STATCCAE_ASYM_CMK_OFFSET], "2 ", 8)) { LOG(LOG_WARNING, "Warning: CCA asymmetric master key is not yet loaded"); } return CKR_OK; } CK_RV token_specific_final() { return CKR_OK; } CK_RV cca_key_gen(CK_BYTE *key, unsigned char *key_form, unsigned char *key_type_1, CK_ULONG key_size) { long return_code, reason_code; unsigned char key_length[CCA_KEYWORD_SIZE]; unsigned char key_type_2[CCA_KEYWORD_SIZE] = { 0, }; unsigned char kek_key_identifier_1[CCA_KEY_ID_SIZE] = { 0, }; unsigned char kek_key_identifier_2[CCA_KEY_ID_SIZE] = { 0, }; unsigned char *generated_key_identifier_1 = key; unsigned char generated_key_identifier_2[CCA_KEY_ID_SIZE] = { 0, }; switch (key_size) { case 8: memcpy(key_length, "KEYLN8 ", (size_t)CCA_KEYWORD_SIZE); break; #if 0 case 16: memcpy(key_length, "KEYLN16 ", CCA_KEYWORD_SIZE); break; #endif case 24: memcpy(key_length, "KEYLN24 ", (size_t)CCA_KEYWORD_SIZE); break; case 32: memcpy(key_length, " ", (size_t)CCA_KEYWORD_SIZE); break; default: DBG("Invalid key length: %lu", key_size); return CKR_KEY_SIZE_RANGE; } //check if DES 32 bytes keys are supported supported CSNBKGN(&return_code, &reason_code, NULL, NULL, key_form, key_length, key_type_1, key_type_2, kek_key_identifier_1, kek_key_identifier_2, key, generated_key_identifier_2); if (return_code != CCA_SUCCESS) { CCADBG("CSNBKGN (KEYGEN)", return_code, reason_code); return CKR_FUNCTION_FAILED; } // memcpy(key, generated_key_identifier_1, (size_t)CCA_KEY_ID_SIZE); return CKR_OK; } CK_RV token_specific_des_key_gen(CK_BYTE *des_key, CK_ULONG len, CK_ULONG key_size) { long return_code, reason_code; unsigned char key_form[CCA_KEYWORD_SIZE], key_length[CCA_KEYWORD_SIZE]; unsigned char key_type_1[CCA_KEYWORD_SIZE]; DBG("Enter CCA DES keygen"); memcpy(key_form, "OP ", (size_t)CCA_KEYWORD_SIZE); memcpy(key_type_1, "DATA ", (size_t)CCA_KEYWORD_SIZE); return cca_key_gen(des_key, key_form, key_type_1, key_size); } CK_RV token_specific_des_ecb(CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_BYTE encrypt) { DBG("Unsupported function reached."); return CKR_FUNCTION_NOT_SUPPORTED; } CK_RV token_specific_des_cbc(CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_BYTE *init_v, CK_BYTE encrypt) { long return_code, reason_code, rule_array_count, length; long pad_character = 0; //char iv[8] = { 0xfe, 0x43, 0x12, 0xed, 0xaa, 0xbb, 0xdd, 0x90 }; unsigned char chaining_vector[CCA_OCV_SIZE]; unsigned char rule_array[CCA_RULE_ARRAY_SIZE]; CK_BYTE *local_out = out_data; DBG("Enter"); /* We need to have 8 bytes more than the in data length in case CCA * adds some padding, although this extra 8 bytes may not be needed. * If *out_data_len is not 8 bytes larger than in_data_len, then * we'll malloc the needed space and get the data back from CCA in this * malloc'd buffer. If it turns out that the extra 8 bytes wasn't * needed, we just silently copy the data to the user's buffer and * free our malloc'd space, returning as normal. If the space was * needed, we return an error and no memory corruption happens. */ if (*out_data_len < (in_data_len + 8)) { local_out = malloc(in_data_len + 8); if (!local_out) { DBG("Malloc of %lu bytes failed.", in_data_len + 8); return CKR_HOST_MEMORY; } } length = in_data_len; rule_array_count = 1; memcpy(rule_array, "CBC ", (size_t)CCA_KEYWORD_SIZE); if (encrypt) { CSNBENC(&return_code, &reason_code, NULL, NULL, key_value, //id, &length, in_data, //in, init_v, //iv, &rule_array_count, rule_array, &pad_character, chaining_vector, local_out);//out_data); //out); } else { CSNBDEC(&return_code, &reason_code, NULL, NULL, key_value, //id, &length, in_data, //in, init_v, //iv, &rule_array_count, rule_array, chaining_vector, local_out);//out_data); //out); } if (return_code != CCA_SUCCESS) { CCADBG("CSNBENC (DES ENCRYPT)", return_code, reason_code); if (out_data != local_out) free(local_out); #ifdef DEBUG { uint32_t *i = (uint32_t *) key_value, j; DBG("Bad key:"); for ( j = 0; j < 16; j++) DBG("%.8x ", *i++); } #endif return CKR_FUNCTION_FAILED; } /* If we malloc'd a new buffer due to overflow concerns and the data * coming out turned out to be bigger than expected, return an error. * * Else, memcpy the data back to the user's buffer */ if ((local_out != out_data) && ((CK_ULONG)length > *out_data_len)) { DBG("CKR_BUFFER_TOO_SMALL: %ld bytes to write into %ld bytes space", length, *out_data_len); st_err_log(111, __FILE__, __LINE__); free(local_out); return CKR_BUFFER_TOO_SMALL; } else if (local_out != out_data) { memcpy(out_data, local_out, (size_t)length); free(local_out); } *out_data_len = length; return CKR_OK; } CK_RV token_specific_tdes_ecb(CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_BYTE encrypt) { DBG("Unsupported function reached."); return CKR_FUNCTION_NOT_SUPPORTED; } CK_RV token_specific_tdes_cbc(CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_BYTE *init_v, CK_BYTE encrypt) { DBG("Enter"); /* Since keys are opaque objects in this token and there's only * one encipher command to CCA, we can just pass through */ return token_specific_des_cbc(in_data, in_data_len, out_data, out_data_len, key_value, init_v, encrypt); } uint16_t cca_inttok_privkey_get_len(CK_BYTE *tok) { return *(uint16_t *)&tok[CCA_RSA_INTTOK_PRIVKEY_LENGTH_OFFSET]; } /* Given a CCA internal token private key object, get the modulus */ CK_RV cca_inttok_privkey_get_n(CK_BYTE *tok, CK_ULONG *n_len, CK_BYTE *n) { uint16_t privkey_length, n_length; uint32_t privkey_n_offset; privkey_length = *(uint16_t *)&tok[CCA_RSA_INTTOK_PRIVKEY_LENGTH_OFFSET]; n_length = *(uint16_t *)&tok[CCA_RSA_INTTOK_PRIVKEY_N_LENGTH_OFFSET]; if (n_length > (*n_len)) { DBG("Not enough room to return n. (Got %lu, need %hu)", *n_len, n_length); return CKR_FUNCTION_FAILED; } privkey_n_offset = privkey_length - n_length; memcpy(n, &tok[privkey_n_offset], (size_t)n_length); *n_len = n_length; return CKR_OK; } /* Given a CCA internal token pubkey object, get the public exponent */ CK_RV cca_inttok_pubkey_get_e(CK_BYTE *tok, CK_ULONG *e_len, CK_BYTE *e) { uint16_t e_length; e_length = *(uint16_t *)&tok[CCA_RSA_INTTOK_PUBKEY_E_LENGTH_OFFSET]; if (e_length > (*e_len)) { DBG("Not enough room to return e. (Got %lu, need %hu)", *e_len, e_length); return CKR_FUNCTION_FAILED; } memcpy(e, &tok[CCA_RSA_INTTOK_PUBKEY_E_OFFSET], (size_t)e_length); *e_len = (CK_ULONG)e_length; return CKR_OK; } CK_RV token_create_keypair_object(TEMPLATE *tmpl, CK_ULONG tok_len, CK_BYTE *tok) { uint16_t privkey_len, pubkey_offset; CK_BYTE n[CCATOK_MAX_N_LEN], e[CCATOK_MAX_E_LEN]; CK_ULONG n_len = CCATOK_MAX_N_LEN, e_len = CCATOK_MAX_E_LEN; CK_ATTRIBUTE *modulus, *pub_exp, *opaque_key; CK_RV rv; privkey_len = cca_inttok_privkey_get_len(&tok[CCA_RSA_INTTOK_PRIVKEY_OFFSET]); pubkey_offset = privkey_len + CCA_RSA_INTTOK_HDR_LENGTH; /* That's right, n is stored in the private key area. Get it there */ if ((rv = cca_inttok_privkey_get_n(&tok[CCA_RSA_INTTOK_PRIVKEY_OFFSET], &n_len, n))) { DBG("Call to cca_inttok_privkey_get_n() failed. rv=0x%lx", rv); return rv; } /* Get e */ if ((rv = cca_inttok_pubkey_get_e(&tok[pubkey_offset], &e_len, e))) { DBG("Call to cca_inttok_pubkey_get_e() failed. rv=0x%lx", rv); return rv; } /* Add n's value to the template */ if ((rv = build_attribute(CKA_MODULUS, n, n_len, &modulus))) { DBG("build_attribute for n failed. rv=0x%lx", rv); return rv; } template_update_attribute(tmpl, modulus); /* Add e's value to the template */ if ((rv = build_attribute(CKA_PUBLIC_EXPONENT, e, e_len, &pub_exp))) { DBG("build_attribute for e failed. rv=0x%lx", rv); return rv; } template_update_attribute(tmpl, pub_exp); /* Add the opaque key object to the template */ if ((rv = build_attribute(CKA_IBM_OPAQUE, tok, tok_len, &opaque_key))) { DBG("build_attribute for opaque key failed. rv=0x%lx", rv); return rv; } template_update_attribute(tmpl, opaque_key); return CKR_OK; } #if 0 CK_RV token_create_priv_key(TEMPLATE *priv_tmpl, CK_ULONG tok_len, CK_BYTE *tok) { CK_BYTE n[CCATOK_MAX_N_LEN]; CK_ULONG n_len = CCATOK_MAX_N_LEN; CK_RV rv; CK_ATTRIBUTE *opaque_key, *modulus; /* That's right, n is stored in the private key area. Get it there */ if ((rv = cca_inttok_privkey_get_n(&tok[CCA_RSA_INTTOK_PRIVKEY_OFFSET], &n_len, n))) { DBG("Call to cca_inttok_privkey_get_n() failed. rv=0x%lx", rv); return rv; } /* Add n's value to the template. We need to do this for the private * key as well as the public key because openCryptoki checks data * sizes against the size of the CKA_MODULUS attribute of whatever * key object it gets */ if ((rv = build_attribute(CKA_MODULUS, n, n_len, &modulus))) { DBG("build_attribute for n failed. rv=0x%lx", rv); return rv; } template_update_attribute(priv_tmpl, modulus); /* Add the opaque key object to the template */ if ((rv = build_attribute(CKA_IBM_OPAQUE, tok, tok_len, &opaque_key))) { DBG("build_attribute for opaque key failed. rv=0x%lx", rv); return rv; } template_update_attribute(priv_tmpl, opaque_key); return CKR_OK; } #endif CK_RV token_specific_rsa_generate_keypair(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) { long return_code, reason_code, rule_array_count; unsigned char rule_array[CCA_RULE_ARRAY_SIZE] = { 0, }; long key_value_structure_length; long private_key_name_length, key_token_length; unsigned char key_value_structure[CCA_KEY_VALUE_STRUCT_SIZE] = { 0, }; unsigned char private_key_name[CCA_PRIVATE_KEY_NAME_SIZE] = { 0, }; unsigned char key_token[CCA_KEY_TOKEN_SIZE] = { 0, }; long regeneration_data_length, generated_key_token_length; unsigned char regeneration_data[CCA_REGENERATION_DATA_SIZE] = { 0, }; unsigned char transport_key_identifier[CCA_KEY_ID_SIZE] = { 0, }; unsigned char generated_key_token[CCA_KEY_TOKEN_SIZE] = { 0, }; uint16_t size_of_e; uint16_t mod_bits; CK_ATTRIBUTE *pub_exp = NULL, *attr = NULL; CK_RV rv; if (!template_attribute_find(publ_tmpl, CKA_MODULUS_BITS, &attr)) { st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } mod_bits = *(CK_ULONG *)attr->pValue; /* If e is specified in the template, use it */ rv = template_attribute_find(publ_tmpl, CKA_PUBLIC_EXPONENT, &pub_exp); if (rv == TRUE) { if (pub_exp->ulValueLen > SHRT_MAX) return CKR_TEMPLATE_INCONSISTENT; size_of_e = (uint16_t)pub_exp->ulValueLen; memcpy(&key_value_structure[CCA_PKB_E_SIZE_OFFSET], &size_of_e, (size_t)CCA_PKB_E_SIZE); memcpy(&key_value_structure[CCA_PKB_E_OFFSET], pub_exp->pValue, (size_t)pub_exp->ulValueLen); } key_value_structure_length = CCA_KEY_VALUE_STRUCT_SIZE; memcpy(key_value_structure, &mod_bits, sizeof(uint16_t)); rule_array_count = 2; memcpy(rule_array, "RSA-CRT KEY-MGMT", (size_t)(CCA_KEYWORD_SIZE * 2)); private_key_name_length = 0; key_token_length = CCA_KEY_TOKEN_SIZE; CSNDPKB(&return_code, &reason_code, NULL, NULL, &rule_array_count, rule_array, &key_value_structure_length, key_value_structure, &private_key_name_length, private_key_name, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, &key_token_length, key_token); if (return_code != CCA_SUCCESS) { CCADBG("CSNDPKB (RSA KEY TOKEN BUILD)", return_code, reason_code); return CKR_FUNCTION_FAILED; } rule_array_count = 1; memset(rule_array, 0, sizeof(rule_array)); memcpy(rule_array, "MASTER ", (size_t)CCA_KEYWORD_SIZE); generated_key_token_length = CCA_KEY_TOKEN_SIZE; regeneration_data_length = 0; CSNDPKG(&return_code, &reason_code, NULL, NULL, &rule_array_count, rule_array, ®eneration_data_length, regeneration_data, &key_token_length, key_token, transport_key_identifier, &generated_key_token_length, generated_key_token); if (return_code != CCA_SUCCESS) { CCADBG("CSNDPKG (RSA KEY GENERATE)", return_code, reason_code); return CKR_FUNCTION_FAILED; } DBG("RSA secure key token generated. size: %ld", generated_key_token_length); rv = token_create_keypair_object(publ_tmpl, generated_key_token_length, generated_key_token); if (rv != CKR_OK) { DBG("token_create_keypair_object failed. rv: %lu", rv); return rv; } rv = token_create_keypair_object(priv_tmpl, generated_key_token_length, generated_key_token); if (rv != CKR_OK) DBG("token_create_keypair_object failed. rv: %lu", rv); return rv; } CK_RV token_specific_rsa_encrypt(CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, OBJECT *key_obj) { long return_code, reason_code, rule_array_count, data_structure_length; unsigned char rule_array[CCA_RULE_ARRAY_SIZE] = { 0, }; CK_ATTRIBUTE *attr; /* Find the secure key token */ if (!template_attribute_find(key_obj->template, CKA_IBM_OPAQUE, &attr)) { st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } /* The max value allowable by CCA for out_data_len is 256, so cap the incoming value if its * too large. CCA will throw error 8, 72 otherwise. */ if (*out_data_len > 256) *out_data_len = 256; rule_array_count = 1; memcpy(rule_array, "PKCS-1.2", CCA_KEYWORD_SIZE); data_structure_length = 0; CSNDPKE(&return_code, &reason_code, NULL, NULL, &rule_array_count, rule_array, (long *)&in_data_len, in_data, &data_structure_length, // must be 0 NULL, // ignored (long *)&(attr->ulValueLen), attr->pValue, (long *)out_data_len, out_data); if (return_code != CCA_SUCCESS) { CCADBG("CSNDPKE (RSA ENCRYPT)", return_code, reason_code); return CKR_FUNCTION_FAILED; } return CKR_OK; } CK_RV token_specific_rsa_decrypt(CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, OBJECT *key_obj) { long return_code, reason_code, rule_array_count, data_structure_length; unsigned char rule_array[CCA_RULE_ARRAY_SIZE] = { 0, }; CK_ATTRIBUTE *attr; /* Find the secure key token */ if (!template_attribute_find(key_obj->template, CKA_IBM_OPAQUE, &attr)) { st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } /* The max value allowable by CCA for out_data_len is 256, so cap the incoming value if its * too large. CCA will throw error 8, 72 otherwise. */ if (*out_data_len > 256) *out_data_len = 256; rule_array_count = 1; memcpy(rule_array, "PKCS-1.2", CCA_KEYWORD_SIZE); data_structure_length = 0; CSNDPKD(&return_code, &reason_code, NULL, NULL, &rule_array_count, rule_array, (long *)&in_data_len, in_data, &data_structure_length, // must be 0 NULL, // ignored (long *)&(attr->ulValueLen), attr->pValue, (long *)out_data_len, out_data); if (return_code != CCA_SUCCESS) { CCADBG("CSNDPKD (RSA DECRYPT)", return_code, reason_code); return CKR_FUNCTION_FAILED; } return CKR_OK; } CK_RV token_specific_rsa_sign(CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, OBJECT * key_obj ) { long return_code, reason_code, rule_array_count; unsigned char rule_array[CCA_RULE_ARRAY_SIZE] = { 0, }; long signature_bit_length; CK_ATTRIBUTE *attr; /* Find the secure key token */ if (!template_attribute_find(key_obj->template, CKA_IBM_OPAQUE, &attr)) { st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } rule_array_count = 1; memcpy(rule_array, "PKCS-1.1", CCA_KEYWORD_SIZE); CSNDDSG(&return_code, &reason_code, NULL, NULL, &rule_array_count, rule_array, (long *)&(attr->ulValueLen), attr->pValue, (long *)&in_data_len, in_data, (long *)out_data_len, &signature_bit_length, out_data); if (return_code != CCA_SUCCESS) { CCADBG("CSNDDSG (RSA SIGN)", return_code, reason_code); return CKR_FUNCTION_FAILED; } return CKR_OK; } CK_RV token_specific_rsa_verify(CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG out_data_len, OBJECT * key_obj ) { long return_code, reason_code, rule_array_count; unsigned char rule_array[CCA_RULE_ARRAY_SIZE] = { 0, }; CK_ATTRIBUTE *attr; /* Find the secure key token */ if (!template_attribute_find(key_obj->template, CKA_IBM_OPAQUE, &attr)) { st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } rule_array_count = 1; memcpy(rule_array, "PKCS-1.1", CCA_KEYWORD_SIZE); CSNDDSV(&return_code, &reason_code, NULL, NULL, &rule_array_count, rule_array, (long *)&(attr->ulValueLen), attr->pValue, (long *)&in_data_len, in_data, (long *)&out_data_len, out_data); if (return_code == 4 && reason_code == 429) { return CKR_SIGNATURE_INVALID; } else if (return_code != CCA_SUCCESS) { CCADBG("CSNDDSV (RSA VERIFY)", return_code, reason_code); return CKR_FUNCTION_FAILED; } return CKR_OK; } #ifndef NOAES CK_RV token_specific_aes_key_gen(CK_BYTE *aes_key, CK_ULONG key_size) { long return_code, reason_code; unsigned char key_length[CCA_KEYWORD_SIZE]; unsigned char key_token[CCA_KEY_ID_SIZE] = { 0, }; unsigned char key_value[32]; unsigned char key_form[CCA_KEYWORD_SIZE]; unsigned char key_type[CCA_KEYWORD_SIZE]; unsigned char rule_array[CCA_RULE_ARRAY_SIZE] = { 0x20, }; long exit_data_len = 0, rule_array_count; unsigned char exit_data[4] = { 0, }; unsigned char reserved_1[4] = { 0, }; unsigned char point_to_array_of_zeros = 0; unsigned char mkvp[16] = { 0, }; memcpy(rule_array, "INTERNALAES NO-KEY ", (size_t) (CCA_KEYWORD_SIZE*3)); memcpy(key_type, "DATA ", (size_t)CCA_KEYWORD_SIZE); switch (key_size) { case 16: memcpy(rule_array + 3*CCA_KEYWORD_SIZE, "KEYLN16 ", CCA_KEYWORD_SIZE); break; case 24: memcpy(rule_array + 3*CCA_KEYWORD_SIZE, "KEYLN24 ", (size_t)CCA_KEYWORD_SIZE); break; case 32: memcpy(rule_array + 3*CCA_KEYWORD_SIZE, "KEYLN32 ", (size_t)CCA_KEYWORD_SIZE); break; default: DBG("Invalid key length: %lu", key_size); return CKR_KEY_SIZE_RANGE; } #ifdef DEBUG { uint32_t j; DBG("Rule Array:"); for ( j = 0; j < 32; j++) printf("%c", rule_array[j]); printf("\n"); for ( j = 0; j < 8; j++) printf("%c", key_type[j]); } #endif rule_array_count = 4; CSNBKTB(&return_code, &reason_code, &exit_data_len, exit_data, key_token, key_type, &rule_array_count, rule_array, NULL, reserved_1, NULL, &point_to_array_of_zeros, NULL, NULL, NULL, NULL, mkvp); if (return_code != CCA_SUCCESS) { CCADBG("CSNBTKB (TOKEN BUILD)", return_code, reason_code); return CKR_FUNCTION_FAILED; } memcpy(key_form, "OP ", (size_t)CCA_KEYWORD_SIZE); memcpy(key_type, "AESTOKEN", (size_t) CCA_KEYWORD_SIZE); memcpy(aes_key, key_token, (size_t)CCA_KEY_ID_SIZE); return cca_key_gen(aes_key, key_form, key_type, key_size); } CK_RV token_specific_aes_ecb(CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_ULONG key_len, CK_BYTE encrypt) { long return_code, reason_code, rule_array_count, length; long pad_character = 0, block_size = 16; unsigned char chaining_vector[CCA_OCV_SIZE]; unsigned char rule_array[CCA_RULE_ARRAY_SIZE]; long opt_data_len = 0, key_params_len =0, exit_data_len = 0, IV_len = 0, chain_vector_len = 0; char exit_data[0]; CK_BYTE *local_out = out_data; key_len = 64; rule_array_count = 4; memcpy(rule_array, "AES ECB KEYIDENTINITIAL ", rule_array_count*(size_t)CCA_KEYWORD_SIZE); if (encrypt) { CSNBSAE(&return_code, &reason_code, &exit_data_len, exit_data, &rule_array_count, rule_array, &key_len, key_value, &key_params_len, NULL, &block_size, &IV_len, NULL, &chain_vector_len, NULL, &in_data_len, in_data, out_data_len, local_out, &opt_data_len, NULL); } else { CSNBSAD(&return_code, &reason_code, &exit_data_len, exit_data, &rule_array_count, rule_array, &key_len, key_value, &key_params_len, NULL, &block_size, &IV_len, NULL, &chain_vector_len, NULL, &in_data_len, in_data, out_data_len, local_out, &opt_data_len, NULL); } if (return_code != CCA_SUCCESS) { if (encrypt) CCADBG("CSNBSAE (AES ENCRYPT)", return_code, reason_code); else CCADBG("CSNBSAD (AES DECRYPT)", return_code, reason_code); #ifdef DEBUG { uint32_t *i = (uint32_t *) key_value, j; DBG("Bad key:"); // for ( j = 0; j < 16; j++) // DBG("%.8x ", *i++); } #endif (*out_data_len) = 0; return CKR_FUNCTION_FAILED; } return CKR_OK; } CK_RV token_specific_aes_cbc(CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_ULONG key_len, CK_BYTE *init_v, CK_BYTE encrypt) { long return_code, reason_code, rule_array_count, length; long pad_character = 0, block_size = 16; unsigned char IV[8] = { 0xfe, 0x43, 0x12, 0xed, 0xaa, 0xbb, 0xdd, 0x90 }; unsigned char chaining_vector[32]; unsigned char rule_array[CCA_RULE_ARRAY_SIZE]; long opt_data_len = 0, key_params_len =0, exit_data_len = 0, IV_len = 16, chain_vector_len = 32; CK_BYTE *local_out = out_data; char exit_data[0]; if (in_data_len%16 == 0) { rule_array_count = 3; memcpy(rule_array, "AES KEYIDENTINITIAL ", rule_array_count*(size_t)CCA_KEYWORD_SIZE); } else { if ((encrypt) && (*out_data_len < (in_data_len + 16))) { local_out = malloc(in_data_len + 16); if (!local_out) { DBG("Malloc of %lu bytes failed.", in_data_len + 16); return CKR_HOST_MEMORY; } } rule_array_count = 3; memcpy(rule_array, "AES PKCS-PADKEYIDENT", rule_array_count*(size_t)CCA_KEYWORD_SIZE); } length = in_data_len; key_len = 64; if (encrypt) { CSNBSAE(&return_code, &reason_code, &exit_data_len, exit_data, &rule_array_count, rule_array, &key_len, key_value, &key_params_len, exit_data, &block_size, &IV_len, init_v, &chain_vector_len, chaining_vector, &length, in_data, out_data_len, out_data, &opt_data_len, NULL); } else { CSNBSAD(&return_code, &reason_code, &exit_data_len, exit_data, &rule_array_count, rule_array, &key_len, key_value, &key_params_len, NULL, &block_size, &IV_len, init_v, &chain_vector_len, chaining_vector, &length, in_data, out_data_len, out_data, &opt_data_len, NULL); } if (return_code != CCA_SUCCESS) { CCADBG("CSNBENC (AES ENCRYPT)", return_code, reason_code); #ifdef DEBUG { uint32_t *i = (uint32_t *) key_value, j; DBG("Bad key:"); //for ( j = 0; j < 16; j++) // DBG("%.8x ", *i++); } #endif return CKR_FUNCTION_FAILED; } /* If we malloc'd a new buffer due to overflow concerns and the data * coming out turned out to be bigger than expected, return an error. * * Else, memcpy the data back to the user's buffer */ if ((local_out != out_data) && ((CK_ULONG)length > *out_data_len)) { DBG("CKR_BUFFER_TOO_SMALL: %ld bytes to write into %ld bytes space", length, *out_data_len); st_err_log(111, __FILE__, __LINE__); free(local_out); return CKR_BUFFER_TOO_SMALL; } else if (local_out != out_data) { memcpy(out_data, local_out, (size_t)length); free(local_out); } *out_data_len = length; return CKR_OK; } #endif #ifndef NODH /* Begin code contributed by Corrent corp. */ CK_RV token_specific_dh_pkcs_derive(CK_BYTE *z, CK_ULONG *z_len, CK_BYTE *y, CK_ULONG y_len, CK_BYTE *x, CK_ULONG x_len, CK_BYTE *p, CK_ULONG p_len) { DBG("Unsupported function reached."); return CKR_FUNCTION_NOT_SUPPORTED; } CK_RV token_specific_dh_pkcs_key_pair_gen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl ) { DBG("Unsupported function reached."); return CKR_FUNCTION_NOT_SUPPORTED; } /* End code contributed by Corrent corp. */ #endif /* See the top of this file for the declarations of mech_list and * mech_list_len. */ CK_RV token_specific_get_mechanism_list(CK_MECHANISM_TYPE *pMechanismList, CK_ULONG *pulCount) { CK_ULONG i; DBG("Enter"); if (pMechanismList == NULL) { (*pulCount) = mech_list_len; return CKR_OK; } if ((*pulCount) < mech_list_len) { (*pulCount) = mech_list_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } for (i = 0; i < mech_list_len; i++) pMechanismList[i] = mech_list[i].mech_type; (*pulCount) = mech_list_len; return CKR_OK; } CK_RV token_specific_get_mechanism_info(CK_MECHANISM_TYPE type, CK_MECHANISM_INFO *pInfo) { CK_ULONG i; DBG("Enter"); for (i = 0; i < mech_list_len; i++) { if (mech_list[i].mech_type == type) { memcpy(pInfo, &mech_list[i].mech_info, sizeof(CK_MECHANISM_INFO)); return CKR_OK; } } st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } CK_RV sw_des3_cbc(CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *init_v, CK_BYTE *key_value, CK_BYTE encrypt) { des_key_schedule des_key1; des_key_schedule des_key2; des_key_schedule des_key3; const_des_cblock key_SSL1, key_SSL2, key_SSL3; des_cblock ivec; DBG("Enter"); // the des decrypt will only fail if the data length is not evenly divisible // by 8 if (in_data_len % 8) { st_err_log(11, __FILE__, __LINE__); DBG("CKR_DATA_LEN_RANGE"); return CKR_DATA_LEN_RANGE; } // The key as passed in is a 24 byte string containing 3 keys // pick it apart and create the key schedules memcpy(&key_SSL1, key_value, (size_t)8); memcpy(&key_SSL2, key_value+8, (size_t)8); memcpy(&key_SSL3, key_value+16, (size_t)8); des_set_key_unchecked(&key_SSL1, des_key1); des_set_key_unchecked(&key_SSL2, des_key2); des_set_key_unchecked(&key_SSL3, des_key3); memcpy(ivec, init_v, sizeof(ivec)); // Encrypt or decrypt the data if (encrypt) { des_ede3_cbc_encrypt(in_data, out_data, in_data_len, des_key1, des_key2, des_key3, &ivec, DES_ENCRYPT); *out_data_len = in_data_len; } else { des_ede3_cbc_encrypt(in_data, out_data, in_data_len, des_key1, des_key2, des_key3, &ivec, DES_DECRYPT); *out_data_len = in_data_len; } return CKR_OK; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/mech_des3.c0000640000175000017500000013571711327631345021370 0ustar jfjf/* * Licensed materials, Property of IBM Corp. * * openCryptoki CCA token * * (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2006 * */ // File: mech_des3.c // // Mechanisms for DES3 // #include // for memcmp() et al #include #include "cca_stdll.h" #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // // #ifndef NOECB CK_RV des3_ecb_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES3_ECB requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des3_ecb_encrypt( in_data, in_data_len, out_data, out_data_len, key_value ); } // // CK_RV des3_ecb_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES3_ECB requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des3_ecb_decrypt( in_data, in_data_len, out_data, out_data_len, key_value ); } #endif // // CK_RV des3_cbc_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES3_CBC requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des3_cbc_encrypt( in_data, in_data_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); } // // CK_RV des3_cbc_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES3_CBC requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des3_cbc_decrypt( in_data, in_data_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); } // // CK_RV des3_cbc_pad_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE *clear = NULL; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_ULONG padded_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // DES3-CBC-PAD has no input length requirements // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // compute the output length, accounting for padding // padded_len = DES_BLOCK_SIZE * (in_data_len / DES_BLOCK_SIZE + 1); if (length_only == TRUE) { *out_data_len = padded_len; return CKR_OK; } if (*out_data_len < padded_len) { *out_data_len = padded_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } clear = (CK_BYTE *)malloc( padded_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( clear, in_data, in_data_len ); add_pkcs_padding( clear + in_data_len, DES_BLOCK_SIZE, in_data_len, padded_len ); rc = ckm_des3_cbc_encrypt( clear, padded_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); if (rc != CKR_OK) st_err_log(105, __FILE__, __LINE__); free( clear ); return rc; } // // CK_RV des3_cbc_pad_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE *clear = NULL; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_ULONG padded_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // no need to validate the input length since we'll pad as necessary // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // we're decrypting so even with CBC-PAD, we should have an integral // number of block to decrypt // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } // the amount of cleartext after stripping the padding will actually be less // than the input bytes... // padded_len = in_data_len; if (length_only == TRUE) { *out_data_len = padded_len; return CKR_OK; } clear = (CK_BYTE *)malloc( padded_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } rc = ckm_des3_cbc_decrypt( in_data, in_data_len, clear, &padded_len, ctx->mech.pParameter, key_value ); if (rc == CKR_OK) { strip_pkcs_padding( clear, padded_len, out_data_len ); memcpy( out_data, clear, *out_data_len ); } else st_err_log(106, __FILE__, __LINE__); free( clear ); return rc; } #ifndef NOECB // // CK_RV des3_ecb_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % DES_BLOCK_SIZE); out_len = (total - remain); // should always be at least 1 block if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); rc = ckm_des3_ecb_encrypt( clear, out_len, out_data, out_data_len, key_value ); if (rc == CKR_OK) { *out_data_len = out_len; // update the context buffer. we already used the buffer's current // contents so we completely overwrite it // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } free( clear ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // shouldn't reach this } // // CK_RV des3_ecb_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % DES_BLOCK_SIZE); out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_des3_ecb_decrypt( cipher, out_len, out_data, out_data_len, key_value ); if (rc == CKR_OK) { *out_data_len = out_len; // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(105, __FILE__, __LINE__); free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // shouldn't reach this } #endif // // CK_RV des3_cbc_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % DES_BLOCK_SIZE); out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // these buffers need to be longword aligned // clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); rc = ckm_des3_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); if (rc == CKR_OK) { *out_data_len = out_len; // the new init_v is the last encrypted data block // memcpy( ctx->mech.pParameter, out_data + (*out_data_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(105, __FILE__, __LINE__); free( clear ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV des3_cbc_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = context->len + in_data_len; if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = total % DES_BLOCK_SIZE; out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // these buffers need to be longword aligned // cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_des3_cbc_decrypt( cipher, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); if (rc == CKR_OK) { *out_data_len = out_len; // the new init_v is the last input data block // memcpy( ctx->mech.pParameter, cipher + (out_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(106, __FILE__, __LINE__); free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV des3_cbc_pad_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); // note, this is subtly different from the other encrypt update routines // if (total <= DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { remain = (total % DES_BLOCK_SIZE); out_len = total - remain; // out_len is a multiple of DES_BLOCK_SIZE if (remain == 0) { remain = DES_BLOCK_SIZE; out_len -= DES_BLOCK_SIZE; } if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } // at this point, we should have: // 1) remain != 0 // 2) out_len != 0 // rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // these buffers need to be longword aligned // clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); // // we don't do padding during the update // rc = ckm_des3_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); if (rc == CKR_OK) { // the new init_v is the last encrypted data block // memcpy( ctx->mech.pParameter, out_data + (*out_data_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the temporary space // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } free( clear ); return rc; } } // // CK_RV des3_cbc_pad_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); // note, this is subtly different from the other decrypt update routines // if (total <= DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block + 1 byte // remain = total % DES_BLOCK_SIZE; out_len = total - remain; if (remain == 0) { remain = DES_BLOCK_SIZE; out_len -= DES_BLOCK_SIZE; } if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } // at this point, we should have: // 1) remain != 0 // 2) out_len != 0 // rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // these buffers need to be longword aligned // cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_des3_cbc_decrypt( cipher, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); if (rc == CKR_OK) { // the new init_v is the last input data block // memcpy( ctx->mech.pParameter, cipher + (out_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the temporary space // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } #ifndef NOECB // // CK_RV des3_ecb_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES3-ECB does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV des3_ecb_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES3-ECB does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } #endif // // CK_RV des3_cbc_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES3-CBC does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV des3_cbc_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES3-CBC does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV des3_cbc_pad_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE clear[2*DES_BLOCK_SIZE]; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_ULONG out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); context = (DES_CONTEXT *)ctx->context; // there will never be more than one block in the context buffer // so the amount of output is as follows: // if less than 1 block stored, we generate one block of output // if a full block is stored, we generate two blocks of output (one pad block) // if (context->len == DES_BLOCK_SIZE) out_len = 2 * DES_BLOCK_SIZE; else out_len = DES_BLOCK_SIZE; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } else { memcpy( clear, context->data, context->len ); add_pkcs_padding( clear + context->len, DES_BLOCK_SIZE, context->len, out_len ); rc = ckm_des3_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); if (rc != CKR_OK) st_err_log(105, __FILE__, __LINE__); return rc; } } // // CK_RV des3_cbc_pad_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE clear[DES_BLOCK_SIZE]; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_ULONG out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); context = (DES_CONTEXT *)ctx->context; // there had better be a full block in the context buffer // if (context->len != DES_BLOCK_SIZE){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } // we don't know a priori how much data we'll be returning. we won't // know until after we decrypt it and strip the padding. it's possible // that we'll return nothing (the final block might be a padding block). // out_len = DES_BLOCK_SIZE; // upper bound on what we'll return if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } else { rc = ckm_des3_cbc_decrypt( context->data, DES_BLOCK_SIZE, clear, &out_len, ctx->mech.pParameter, key_value ); if (rc == CKR_OK) { strip_pkcs_padding( clear, out_len, &out_len ); if (out_len != 0) memcpy( out_data, clear, out_len ); *out_data_len = out_len; } else st_err_log(106, __FILE__, __LINE__); return rc; } } // // mechanisms // // // CK_RV ckm_des3_key_gen( TEMPLATE *tmpl ) { CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * opaque_attr = NULL; CK_ATTRIBUTE * key_type_attr = NULL; CK_ATTRIBUTE * class_attr = NULL; CK_ATTRIBUTE * local_attr = NULL; CK_BYTE dummy_key[3 * DES_KEY_SIZE] = { 0, }; CK_BYTE des_key[CCA_KEY_ID_SIZE]; CK_ULONG rc; rc = token_specific.t_des_key_gen(des_key, CCA_KEY_ID_SIZE, 3 * DES_KEY_SIZE); if (rc != CKR_OK) return rc; value_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + 3*DES_KEY_SIZE ); opaque_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + CCA_KEY_ID_SIZE ); key_type_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); class_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS) ); local_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!value_attr || !opaque_attr || !key_type_attr || !class_attr || !local_attr) { if (value_attr) free( value_attr ); if (opaque_attr) free( opaque_attr ); if (key_type_attr) free( key_type_attr ); if (class_attr) free( class_attr ); if (local_attr) free( local_attr ); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 3 * DES_KEY_SIZE; value_attr->pValue = (CK_BYTE *)value_attr + sizeof(CK_ATTRIBUTE); memcpy( value_attr->pValue, dummy_key, 3 * DES_KEY_SIZE ); opaque_attr->type = CKA_IBM_OPAQUE; opaque_attr->ulValueLen = CCA_KEY_ID_SIZE; opaque_attr->pValue = (CK_BYTE *)opaque_attr + sizeof(CK_ATTRIBUTE); memcpy( opaque_attr->pValue, des_key, CCA_KEY_ID_SIZE ); key_type_attr->type = CKA_KEY_TYPE; key_type_attr->ulValueLen = sizeof(CK_KEY_TYPE); key_type_attr->pValue = (CK_BYTE *)key_type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)key_type_attr->pValue = CKK_DES3; class_attr->type = CKA_CLASS; class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS); class_attr->pValue = (CK_BYTE *)class_attr + sizeof(CK_ATTRIBUTE); *(CK_OBJECT_CLASS *)class_attr->pValue = CKO_SECRET_KEY; local_attr->type = CKA_LOCAL; local_attr->ulValueLen = sizeof(CK_BBOOL); local_attr->pValue = (CK_BYTE *)local_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)local_attr->pValue = TRUE; template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, opaque_attr ); template_update_attribute( tmpl, key_type_attr ); template_update_attribute( tmpl, class_attr ); template_update_attribute( tmpl, local_attr ); return CKR_OK; } #ifndef NOECB // // CK_RV ckm_des3_ecb_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * key_value ) { CK_ULONG rc; if (!in_data || !out_data || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_tdes_ecb(in_data,in_data_len,out_data, out_data_len, key_value, 1); if (rc != CKR_OK) st_err_log(120, __FILE__, __LINE__); return rc; } // // CK_RV ckm_des3_ecb_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * key_value ) { CK_ULONG rc; if (!in_data || !out_data || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_tdes_ecb(in_data,in_data_len,out_data, out_data_len, key_value, 0); if (rc != CKR_OK) st_err_log(120, __FILE__, __LINE__); return rc; } #endif // // CK_RV ckm_des3_cbc_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * init_v, CK_BYTE * key_value ) { CK_ULONG rc; if (!in_data || !out_data || !init_v || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ #if 0 st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; #else *out_data_len = in_data_len; st_err_log(68, __FILE__, __FUNCTION__); return CKR_BUFFER_TOO_SMALL; #endif } rc = token_specific.t_tdes_cbc(in_data,in_data_len,out_data,out_data_len, key_value,init_v,1); if (rc != CKR_OK) st_err_log(119, __FILE__, __LINE__); return rc; } // // CK_RV ckm_des3_cbc_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * init_v, CK_BYTE * key_value ) { CK_ULONG rc; if (!in_data || !out_data || !init_v || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_tdes_cbc(in_data,in_data_len,out_data,out_data_len, key_value,init_v,0); if (rc != CKR_OK) st_err_log(119, __FILE__, __LINE__); return rc; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/utility.c0000640000175000017500000006153411327631345021234 0ustar jfjf/* * Licensed materials, Property of IBM Corp. * * openCryptoki CCA token * * (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2006 * * Author: Kent E. Yoder * */ #include #include #include #include #include #include #include #include #include #include #include #include "cca_stdll.h" #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" #include "pkcs32.h" #if (SPINXPL) #include #endif // Function: dlist_add_as_first() // // Adds the specified node to the start of the list // // Returns: pointer to the start of the list // DL_NODE * dlist_add_as_first( DL_NODE *list, void *data ) { DL_NODE *node = NULL; if (!data) return list; node = (DL_NODE *)malloc(sizeof(DL_NODE)); if (!node) return NULL; node->data = data; node->prev = NULL; node->next = list; if ( list) list->prev = node; return node; } // Function: dlist_add_as_last() // // Adds the specified node to the end of the list // // Returns: pointer to the start of the list // DL_NODE * dlist_add_as_last( DL_NODE *list, void *data ) { DL_NODE *node = NULL; if (!data) return list; node = (DL_NODE *)malloc(sizeof(DL_NODE)); if (!node) return NULL; node->data = data; node->next = NULL; if (!list) { node->prev = NULL; return node; } else { DL_NODE *temp = dlist_get_last( list ); temp->next = node; node->prev = temp; return list; } } // Function: dlist_find() // DL_NODE * dlist_find( DL_NODE *list, void *data ) { DL_NODE *node = list; while (node && node->data != data) node = node->next; return node; } // Function: dlist_get_first() // // Returns the last node in the list or NULL if list is empty // DL_NODE * dlist_get_first( DL_NODE *list ) { DL_NODE *temp = list; if (!list) return NULL; while (temp->prev != NULL) temp = temp->prev; return temp; } // Function: dlist_get_last() // // Returns the last node in the list or NULL if list is empty // DL_NODE * dlist_get_last( DL_NODE *list ) { DL_NODE *temp = list; if (!list) return NULL; while (temp->next != NULL) temp = temp->next; return temp; } // // CK_ULONG dlist_length( DL_NODE *list ) { DL_NODE *temp = list; CK_ULONG len = 0; while (temp) { len++; temp = temp->next; } return len; } // // DL_NODE * dlist_next( DL_NODE *node ) { if (!node) return NULL; return node->next; } // // DL_NODE * dlist_prev( DL_NODE *node ) { if (!node) return NULL; return node->prev; } // // void dlist_purge( DL_NODE *list ) { DL_NODE *node; if (!list) return; do { node = list->next; free( list ); list = node; } while ( list ); } // Function: dlist_remove_node() // // Attempts to remove the specified node from the list. The caller is // responsible for freeing the data associated with the node prior to // calling this routine // DL_NODE * dlist_remove_node( DL_NODE *list, DL_NODE *node ) { DL_NODE *temp = list; if (!list || !node) return NULL; // special case: removing head of the list // if (list == node) { temp = list->next; if (temp) temp->prev = NULL; free( list ); return temp; } // we have no guarantee that the node is in the list // so search through the list to find it // while ((temp != NULL) && (temp->next != node)) temp = temp->next; if (temp != NULL) { DL_NODE *next = node->next; temp->next = next; if (next) next->prev = temp; free( node ); } return list; } // NOTE about Mutexes and cross process locking.... // // The code uses 2 types of locks... internal locks to prevent threads within the same // process space from stomping on each other (pthread_mutex's suffice for // this).... and Cross Process Locks.... // On AIX we use it's variation of Posix semaphores for this.... Idealy on other // platforms either POSIXSEMaphores or PTHREADXPL (pthreads xprocess lock) would // be used. On Linux unfortunatly neither of these are available so we need to // use the old standby of SYSV semaphores (YECH.... GAG....).... The only // pieces which have been tested are the AIX and SYSV portions although // we expect that the others work correctly. // // we use alot more mutexes in the redesign than we did in the original // design. so instead of just the single global "pkcs_mutex" we have to // deal with a number of mutexes. so we'll make the mutex routines a // bit more generic. // CK_RV _CreateMutex( MUTEX *mutex ) { // on AIX we make this a no-op since we assume that // the mutex was created in the initialization pthread_mutex_init( mutex, NULL ); return CKR_OK; } CK_RV _CreateMsem( sem_t *msem ) { if (!sem_init( msem,0, 1)) // parm 2 non-0 means pshared 1 is unlocked 0 is locked //if (!sem_init( msem,1, 1)) // parm 2 non-0 means pshared 1 is unlocked 0 is locked return CKR_OK; else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } CK_RV _DestroyMutex( MUTEX *mutex ) { // no-op in AIX pthread_mutex_destroy((pthread_mutex_t *)mutex); return CKR_OK; } CK_RV _DestroyMsem( sem_t *msem ) { if (!sem_destroy(msem)) return CKR_OK; else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } CK_RV _LockMutex( MUTEX *mutex ) { pthread_mutex_lock( mutex); return CKR_OK; } CK_RV _LockMsem( sem_t *msem ) { if (!msem){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if(!sem_wait(msem)) // block until the semaphore is free return CKR_OK; else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } CK_RV _UnlockMutex( MUTEX *mutex ) { pthread_mutex_unlock(mutex); return CKR_OK; } CK_RV _UnlockMsem( sem_t *msem ) { if (!msem){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!sem_post(msem)) return CKR_OK; else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } #if SYSVSEM #include // These structures are needed to effect a lock // using SYS V semaphores... static struct sembuf xlock_lock[2]={ 0,0,0, 0,1,SEM_UNDO }; static struct sembuf xlock_unlock[1] = { 0,-1,(IPC_NOWAIT | SEM_UNDO) }; static pthread_mutex_t semmtx = PTHREAD_MUTEX_INITIALIZER; #endif int spinxplfd=-1; int spin_created=0; extern void set_perm(int); CK_RV CreateXProcLock(void *xproc) { #if (SPINXPL) // open the file that we will do the locking on... spinxplfd = open("/tmp/.pkcs11spinloc",O_CREAT|O_APPEND|O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO); if (spinxplfd) { set_perm(spinxplfd); fchmod(spinxplfd,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH | S_IWOTH); spin_created=1; } else { perror("XPROC CREATE file :"); } return CKR_OK; #elif SYSVSEM int semid; int *psem; key_t tok; tok = ftok( pk_dir, 'c' ); //printf("creating semaphore %x \n",tok); psem = (int *)xproc; if ( *psem < 0 ) { if ( (semid = semget(tok,1,IPC_CREAT | 0666)) < 0 ){ if (errno == EEXIST) { if ( (semid = semget(tok,0,0)) < 0) { pthread_mutex_unlock(&semmtx); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } else { pthread_mutex_unlock(&semmtx); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } } psem = (int *)xproc; *psem = semid; //pthread_mutex_unlock(&semmtx); return CKR_OK; // we know that semaphores are created unlocked #elif POSIXSEM return _CreateMsem((sem_t *)xproc); #elif PTHREADXPL pthread_mutex_attr_t mtxattr; pthread_mutexattr_init(&mtxattr); pthread_mutexattr_setpshared(&mtxattr,PTHREAD_PROCESS_SHARED); pthread_mutex_init((pthread_mutex_t *)xproc,&mtxattr); #elif NOXPROCLOCK return CKR_OK; #else #error "Define XPROC LOCKS" #endif } CK_RV DestroyXProcLock(void *xproc) { #if SPINXPL return CKR_OK; #elif SYSVSEM int semid,*psem; //printf("Destroying semaphore %x \n",xproc); pthread_mutex_lock(&semmtx); psem = (int *)xproc; semid = *psem; semctl(semid,1,IPC_RMID,0); pthread_mutex_unlock(&semmtx); return CKR_OK; #elif POSIXSEM return _DestroyMsem((sem_t *)xproc); #elif PTHREADXPL return pthread_mutex_destroy((pthread_mutex_t *)xproc); #elif NOXPROCLOCK return CKR_OK; #else #error "Define XPROC LOCKS" #endif } CK_RV XProcLock(void *xproc) { #if SPINXPL if (!spin_created) { spinxplfd = open("/tmp/.pkcs11spinloc",O_CREAT|O_APPEND|O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO); fchmod(spinxplfd,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH | S_IWOTH); spin_created=1; } if (spinxplfd){ flock(spinxplfd,LOCK_EX); } return CKR_OK; #elif SYSVSEM int semid,*psem; pthread_mutex_lock(&semmtx); return CKR_OK; pthread_mutex_lock(&semmtx); psem = (int *)xproc; semid = *psem; semop(semid,&xlock_lock[0],2); pthread_mutex_unlock(&semmtx); return CKR_OK; #elif POSIXSEM return _LockMsem((sem_t *)xproc); #elif PTHREADXPL return _LockMutex((MUTEX *)xproc); #elif NOXPROCLOCK return CKR_OK; #else #error "Define XPROC LOCKS" #endif } CK_RV XProcUnLock(void *xproc) { #if SPINXPL if (!spin_created) { spinxplfd = open("/tmp/.pkcs11spinloc",O_CREAT|O_APPEND|O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO); fchmod(spinxplfd,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH | S_IWOTH); spin_created=1; } if (spinxplfd) { flock(spinxplfd,LOCK_UN); } return CKR_OK; #elif SYSVSEM int semid,*psem; pthread_mutex_unlock(&semmtx); return CKR_OK; pthread_mutex_lock(&semmtx); psem = (int *)xproc; semid = *psem; semop(semid,&xlock_unlock[0],1); pthread_mutex_unlock(&semmtx); return CKR_OK; #elif POSIXSEM return _UnlockMsem((sem_t *)xproc); #elif PTHREADXPL return _UnlockMutex((MUTEX *)xproc); #elif NOXPROCLOCK return CKR_OK; #else #error "Define XPROC LOCKS" #endif } // // // is_attribute_defined() // // determine whether the specified attribute is defined by Cryptoki // CK_BBOOL is_attribute_defined( CK_ATTRIBUTE_TYPE type ) { if (type >= CKA_VENDOR_DEFINED) return TRUE; switch (type) { case CKA_CLASS: case CKA_TOKEN: case CKA_PRIVATE: case CKA_LABEL: case CKA_APPLICATION: case CKA_VALUE: case CKA_CERTIFICATE_TYPE: case CKA_ISSUER: case CKA_SERIAL_NUMBER: case CKA_KEY_TYPE: case CKA_SUBJECT: case CKA_ID: case CKA_SENSITIVE: case CKA_ENCRYPT: case CKA_DECRYPT: case CKA_WRAP: case CKA_UNWRAP: case CKA_SIGN: case CKA_SIGN_RECOVER: case CKA_VERIFY: case CKA_VERIFY_RECOVER: case CKA_DERIVE: case CKA_START_DATE: case CKA_END_DATE: case CKA_MODULUS: case CKA_MODULUS_BITS: case CKA_PUBLIC_EXPONENT: case CKA_PRIVATE_EXPONENT: case CKA_PRIME_1: case CKA_PRIME_2: case CKA_EXPONENT_1: case CKA_EXPONENT_2: case CKA_COEFFICIENT: case CKA_PRIME: case CKA_SUBPRIME: case CKA_BASE: case CKA_VALUE_BITS: case CKA_VALUE_LEN: case CKA_EXTRACTABLE: case CKA_LOCAL: case CKA_NEVER_EXTRACTABLE: case CKA_ALWAYS_SENSITIVE: case CKA_MODIFIABLE: case CKA_ECDSA_PARAMS: case CKA_EC_POINT: case CKA_HW_FEATURE_TYPE: case CKA_HAS_RESET: case CKA_RESET_ON_INIT: case CKA_KEY_GEN_MECHANISM: case CKA_PRIME_BITS: case CKA_SUBPRIME_BITS: case CKA_OBJECT_ID: case CKA_AC_ISSUER: case CKA_OWNER: case CKA_ATTR_TYPES: case CKA_TRUSTED: return TRUE; } return FALSE; } extern CK_CHAR manuf[]; extern CK_CHAR model[]; extern CK_CHAR descr[]; extern CK_CHAR label[]; // // void init_slotInfo( void ) { memset( &slot_info.slotDescription, ' ', sizeof(slot_info.slotDescription) ); memset( &slot_info.manufacturerID, ' ', sizeof(slot_info.manufacturerID) ); memcpy( &slot_info.slotDescription, descr, strlen((char *)descr) ); memcpy( &slot_info.manufacturerID, manuf, strlen((char *)manuf) ); slot_info.hardwareVersion.major = 1; slot_info.hardwareVersion.minor = 0; slot_info.firmwareVersion.major = 1; slot_info.firmwareVersion.minor = 0; slot_info.flags = CKF_TOKEN_PRESENT | CKF_HW_SLOT; } // // void init_tokenInfo( void ) { CK_TOKEN_INFO_32 *token_info = NULL; token_info = &nv_token_data->token_info; memset( token_info->manufacturerID, ' ', sizeof(token_info->manufacturerID) ); memset( token_info->model, ' ', sizeof(token_info->model) ); memset( token_info->serialNumber, ' ', sizeof(token_info->serialNumber) ); memcpy( token_info->label, nv_token_data->token_info.label, 32 ); memcpy( token_info->manufacturerID, manuf, strlen((char *)manuf) ); memcpy( token_info->model, model, strlen((char *)model) ); // use the 41-xxxxx serial number from the coprocessor // memcpy( token_info->serialNumber, "123" , 3 ); // I don't see any API support for changing the clock so // we will use the system clock for the token's clock. // token_info->flags = CKF_RNG | CKF_LOGIN_REQUIRED | CKF_CLOCK_ON_TOKEN | CKF_SO_PIN_TO_BE_CHANGED; // XXX New in v2.11 - KEY if (memcmp(nv_token_data->user_pin_sha, "00000000000000000000", SHA1_HASH_SIZE) != 0) token_info->flags |= CKF_USER_PIN_INITIALIZED; else token_info->flags |= CKF_USER_PIN_TO_BE_CHANGED; // XXX New in v2.11 - KEY // For the release, we made these // values as CK_UNAVAILABLE_INFORMATION // token_info->ulMaxSessionCount = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->ulSessionCount = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->ulMaxRwSessionCount = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->ulRwSessionCount = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->ulMaxPinLen = MAX_PIN_LEN; token_info->ulMinPinLen = MIN_PIN_LEN; token_info->ulTotalPublicMemory = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->ulFreePublicMemory = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->ulTotalPrivateMemory = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->ulFreePrivateMemory = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->hardwareVersion.major = 1; token_info->hardwareVersion.minor = 0; token_info->firmwareVersion.major = 1; token_info->firmwareVersion.minor = 0; memset( token_info->utcTime, ' ', sizeof(token_info->utcTime) ); } // // CK_RV init_token_data( void ) { CK_RV rc; memset( (char *)nv_token_data, 0, sizeof(nv_token_data) ); // the normal USER pin is not set when the token is initialized // memcpy( nv_token_data->user_pin_sha, "00000000000000000000", SHA1_HASH_SIZE ); memcpy( nv_token_data->so_pin_sha, default_so_pin_sha, SHA1_HASH_SIZE ); memset( user_pin_md5, 0x0, MD5_HASH_SIZE ); memcpy( so_pin_md5, default_so_pin_md5, MD5_HASH_SIZE ); memcpy( nv_token_data->next_token_object_name, "00000000", 8 ); // generate the master key used for signing the Operation State information // ` memset( nv_token_data->token_info.label, ' ', sizeof(nv_token_data->token_info.label) ); memcpy( nv_token_data->token_info.label, label, strlen((char *)label) ); nv_token_data->tweak_vector.allow_weak_des = TRUE; nv_token_data->tweak_vector.check_des_parity = FALSE; nv_token_data->tweak_vector.allow_key_mods = TRUE; nv_token_data->tweak_vector.netscape_mods = TRUE; init_tokenInfo(); // // FIXME: erase the token object index file (and all token objects) // rc = token_specific.t_des_key_gen(master_key, MASTER_KEY_SIZE, 3 * DES_KEY_SIZE); if (rc != CKR_OK){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = save_masterkey_so(); if (rc != CKR_OK){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = save_token_data(); if (rc != CKR_OK) st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return rc; } // Function: compute_next_token_obj_name() // // Given a token object name (8 bytes in the range [0-9A-Z]) increment by one // adjusting as necessary // // This gives us a namespace of 36^8 = 2,821,109,907,456 objects before wrapping around // CK_RV compute_next_token_obj_name( CK_BYTE *current, CK_BYTE *next ) { int val[8]; int i; if (!current || !next){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Convert to integral base 36 // for (i = 0; i < 8; i++) { if (current[i] >= '0' && current[i] <= '9') val[i] = current[i] - '0'; if (current[i] >= 'A' && current[i] <= 'Z') val[i] = current[i] - 'A' + 10; } val[0]++; i=0; while (val[i] > 35) { val[i] = 0; if (i+1 < 8) { val[i+1]++; i++; } else { val[0]++; i = 0; // start pass 2 } } // now, convert back to [0-9A-Z] // for (i = 0; i < 8; i++) { if (val[i] < 10) next[i] = '0' + val[i]; else next[i] = 'A' + val[i] - 10; } return CKR_OK; } // // CK_RV build_attribute( CK_ATTRIBUTE_TYPE type, CK_BYTE *data, CK_ULONG data_len, CK_ATTRIBUTE **attrib ) { CK_ATTRIBUTE *attr = NULL; attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + data_len ); if (!attr){ st_err_log(0, __FILE__, __LINE__); return CKR_DEVICE_MEMORY; } attr->type = type; attr->ulValueLen = data_len; if (data_len > 0) { attr->pValue = (CK_BYTE *)attr + sizeof(CK_ATTRIBUTE); memcpy( attr->pValue, data, data_len ); } else attr->pValue = NULL; *attrib = attr; return CKR_OK; } // // CK_RV add_pkcs_padding( CK_BYTE * ptr, CK_ULONG block_size, CK_ULONG data_len, CK_ULONG total_len ) { CK_ULONG i, pad_len; CK_BYTE pad_value; pad_len = block_size - (data_len % block_size); pad_value = (CK_BYTE)pad_len; if (data_len + pad_len > total_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } for (i = 0; i < pad_len; i++) ptr[i] = pad_value; return CKR_OK; } // // CK_RV strip_pkcs_padding( CK_BYTE * ptr, CK_ULONG total_len, CK_ULONG * data_len ) { CK_BYTE pad_value; pad_value = ptr[total_len - 1]; // thus, we have 'pad_value' bytes of 'pad_value' appended to the end // *data_len = total_len - pad_value; return CKR_OK; } // // CK_RV remove_leading_zeros( CK_ATTRIBUTE *attr ) { CK_BYTE *ptr = NULL; CK_ULONG new_len, i; ptr = attr->pValue; for (i = 0; i < attr->ulValueLen; i++) { if (ptr[i] != 0x0) break; } new_len = attr->ulValueLen - i; memcpy( ptr, ptr + i, new_len ); attr->ulValueLen = new_len; return CKR_OK; } // // CK_BYTE parity_adjust( CK_BYTE b ) { if (parity_is_odd(b) == FALSE) b = (b & 0xFE) | ((~b) & 0x1); return b; } // // CK_RV parity_is_odd( CK_BYTE b ) { b = ((b >> 4) ^ b) & 0x0f; b = ((b >> 2) ^ b) & 0x03; b = ((b >> 1) ^ b) & 0x01; if (b == 1) return TRUE; else return FALSE; } CK_RV attach_shm() { key_t key; int shm_id; struct stat statbuf; CK_BBOOL created = FALSE; #if !(NOSHM) && !(MMAP) // Change TOK_PATH2 to be the directory // of the data store specified. This way we // have a unique key shared memory for each // token object database if (stat(pk_dir, &statbuf) < 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } key = ftok( pk_dir, 'c' ); shm_id = shmget( key, sizeof(LW_SHM_TYPE), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH | IPC_CREAT | IPC_EXCL); if (shm_id < 0) { #if 0 if ((errno != EACCES) && (errno != EEXIST)) { fflush(stdout); fflush(stderr); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } #endif // SAB XXX it appears that in some cases linux does not set // the errno properly on a shmget failure... so if the create // failed we'll just try and attach.... If the basic attach // fails, then we can error out... // SHM segment already exists... // shm_id = shmget( key, sizeof(LW_SHM_TYPE), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ); //if ((errno != EACCES) && (errno != EEXIST)) { if (shm_id < 0) { fflush(stdout); fflush(stderr); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } else created = TRUE; global_shm = (void *)shmat( shm_id, NULL, 0 ); if (!global_shm){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (created == TRUE) { #if !(SYSVSEM) // SYSV sem's are a global that is handled in the // Initialize routine... all others are stored in the // shared memory segment so we have to do // this here after the segment is created // to prevent a core dump CreateXProcLock( &global_shm->mutex ); xproclock = (void *)&global_shm->mutex; // need to do this here #endif XProcLock( xproclock ); global_shm->num_publ_tok_obj = 0; global_shm->num_priv_tok_obj = 0; memset( &global_shm->publ_tok_objs, 0x0, 2048 * sizeof(TOK_OBJ_ENTRY) ); memset( &global_shm->priv_tok_objs, 0x0, 2048 * sizeof(TOK_OBJ_ENTRY) ); XProcUnLock( xproclock ); } else { xproclock = (void *)&global_shm->mutex; } #elif MMAP { #define FILENAME ".stmapfile" #warning "EXPERIMENTAL" char *fname = NULL; char *b2 = NULL; int fd = -1; mode_t mode; CK_RV rc; mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP ); // STAT the file to see if it exists... If not, then create it fname = malloc(strlen(pk_dir)+strlen(FILENAME)+100); if (fname ) { sprintf(fname, "%s/%s", pk_dir, FILENAME); } else { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_HOST_MEMORY; } if (stat(fname, &statbuf) < 0) { // File does not exist Create it fd = open(fname,O_RDWR|O_CREAT,mode); if (fd < 0 ){ LogError("open of %s failed: %s", fname, strerror(errno)); free(fname); return CKR_FUNCTION_FAILED; //Failed } b2 = malloc(sizeof(LW_SHM_TYPE)); memset(b2,'\0',sizeof(LW_SHM_TYPE)); write(fd,b2,sizeof(LW_SHM_TYPE)); free(b2); created=TRUE; } else { fd = open(fname,O_RDWR,mode); if (fd < 0 ){ LogError("open of %s failed: %s", fname, strerror(errno)); free(fname); return CKR_FUNCTION_FAILED; //Failed } } global_shm = (LW_SHM_TYPE *)mmap(NULL,sizeof(LW_SHM_TYPE),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if (created == TRUE) { XProcLock( xproclock ); global_shm->num_publ_tok_obj = 0; global_shm->num_priv_tok_obj = 0; memset( &global_shm->publ_tok_objs, 0x0, 2048 * sizeof(TOK_OBJ_ENTRY) ); memset( &global_shm->priv_tok_objs, 0x0, 2048 * sizeof(TOK_OBJ_ENTRY) ); XProcUnLock( xproclock ); } else { xproclock = (void *)&global_shm->mutex; } rc = CKR_OK; free(fname); close(fd); return rc; } #else global_shm = (void *)malloc(sizeof(LW_SHM_TYPE)); #endif return CKR_OK; } CK_RV detach_shm() { #if !(NOSHM) && !(MMAP) shmdt( global_shm ); #elif MMAP // Detach from memory mapped file munmap((void *)global_shm,sizeof(LW_SHM_TYPE)); #else free(global_shm); #endif return CKR_OK; } //#endif CK_RV compute_sha( CK_BYTE * data, CK_ULONG len, CK_BYTE * hash ) { // XXX KEY DIGEST_CONTEXT ctx; CK_ULONG hash_len = SHA1_HASH_SIZE; CK_RV rv; memset( &ctx, 0x0, sizeof(ctx) ); ckm_sha1_init( &ctx ); if( ctx.context == NULL ) return CKR_HOST_MEMORY; if( (rv = ckm_sha1_update( &ctx, data, len )) != CKR_OK) return rv; return ckm_sha1_final( &ctx, hash, &hash_len ); } CK_RV compute_md5( CK_BYTE * data, CK_ULONG len, CK_BYTE * hash ) { MD5_CONTEXT ctx; memset( &ctx, 0x0, sizeof(ctx) ); ckm_md5_init( &ctx ); ckm_md5_update( &ctx, data, len ); ckm_md5_final( &ctx, hash, MD5_HASH_SIZE ); return CKR_OK; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/host_defs.h0000640000175000017500000002264011327631345021507 0ustar jfjf/* * Licensed materials, Property of IBM Corp. * * openCryptoki CCA token * * (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2006 * * Author: Kent E. Yoder * */ #include #ifndef _HOST_DEFS_H #define _HOST_DEFS_H #include #include #include #include "pkcs32.h" // Both of the strings below have a length of 32 chars and must be // padded with spaces, and non-null terminated. // #define PKW_CRYPTOKI_VERSION_MAJOR 2 #define PKW_CRYPTOKI_VERSION_MINOR 1 #define PKW_CRYPTOKI_MANUFACTURER "IBM Corp. " #define PKW_CRYPTOKI_LIBDESC "PKCS#11 Interface for IBM 4758 " #define PKW_CRYPTOKI_LIB_VERSION_MAJOR 1 #define PKW_CRYPTOKI_LIB_VERSION_MINOR 0 #define PKW_MAX_DEVICES 10 #define MAX_TOK_OBJS 2048 CK_BBOOL pin_expired(CK_SESSION_INFO *, CK_FLAGS); CK_BBOOL pin_locked(CK_SESSION_INFO *, CK_FLAGS); void set_login_flags(CK_USER_TYPE, CK_FLAGS_32 *); // the following enum is for performance measurements. since the server runs // as an NT service, it's difficult (impossible?) to use a standalone performance // probe // enum { PRF_DUMMYFUNCTION = 1, PRF_FCVFUNCTION, PRF_INITIALIZE, PRF_FINALIZE, PRF_GETINFO, PRF_GETFUNCTIONLIST, PRF_GETSLOTLIST, PRF_GETSLOTINFO, PRF_GETTOKENINFO, PRF_GETMECHLIST, PRF_GETMECHINFO, PRF_INITTOKEN, PRF_INITPIN, PRF_SETPIN, PRF_OPENSESSION, PRF_CLOSESESSION, PRF_CLOSEALLSESSIONS, PRF_GETSESSIONINFO, PRF_GETOPERATIONSTATE, PRF_SETOPERATIONSTATE, PRF_LOGIN, PRF_LOGOUT, PRF_CREATEOBJECT, PRF_COPYOBJECT, PRF_DESTROYOBJECT, PRF_GETOBJECTSIZE, PRF_GETATTRIBUTEVALUE, PRF_SETATTRIBUTEVALUE, PRF_FINDOBJECTSINIT, PRF_FINDOBJECTS, PRF_FINDOBJECTSFINAL, PRF_ENCRYPTINIT, PRF_ENCRYPT, PRF_ENCRYPTUPDATE, PRF_ENCRYPTFINAL, PRF_DECRYPTINIT, PRF_DECRYPT, PRF_DECRYPTUPDATE, PRF_DECRYPTFINAL, PRF_DIGESTINIT, PRF_DIGEST, PRF_DIGESTUPDATE, PRF_DIGESTKEY, PRF_DIGESTFINAL, PRF_SIGNINIT, PRF_SIGN, PRF_SIGNUPDATE, PRF_SIGNFINAL, PRF_SIGNRECOVERINIT, PRF_SIGNRECOVER, PRF_VERIFYINIT, PRF_VERIFY, PRF_VERIFYUPDATE, PRF_VERIFYFINAL, PRF_VERIFYRECOVERINIT, PRF_VERIFYRECOVER, PRF_GENKEY, PRF_GENKEYPAIR, PRF_WRAPKEY, PRF_UNWRAPKEY, PRF_DERIVEKEY, PRF_GENRND, PRF_LASTENTRY }; #define TOTAL 1 #define CARD 2 // Endianness-conversion routines. This will be useful for folks trying // to use the coprocessor on a big-endian architecture... // // htocl -- host to card long // ctohl -- card to host long // #ifndef __BYTE_ORDER #error "MUST DEFINE ENDIANESS" #endif #if __BYTE_ORDER == __LITTLE_ENDIAN #define HTOCL(x) (x) #define CTOHL(x) (x) #else #define HTOCL(x) (long_reverse(x)) #define CTOHL(x) (long_reverse(x)) #endif typedef struct _ENCR_DECR_CONTEXT { CK_OBJECT_HANDLE key; CK_MECHANISM mech; CK_BYTE *context; CK_ULONG context_len; CK_BBOOL multi; CK_BBOOL active; } ENCR_DECR_CONTEXT; typedef struct _DIGEST_CONTEXT { CK_MECHANISM mech; CK_BYTE *context; CK_ULONG context_len; CK_BBOOL multi; CK_BBOOL active; } DIGEST_CONTEXT; typedef struct _SIGN_VERIFY_CONTEXT { CK_OBJECT_HANDLE key; CK_MECHANISM mech; // current sign mechanism CK_BYTE *context; // temporary work area CK_ULONG context_len; CK_BBOOL multi; // is this a multi-part operation? CK_BBOOL recover; // are we in recover mode? CK_BBOOL active; } SIGN_VERIFY_CONTEXT; typedef struct _SESSION { CK_SESSION_HANDLE handle; CK_SESSION_INFO session_info; CK_OBJECT_HANDLE *find_list; // array of CK_OBJECT_HANDLE CK_ULONG_32 find_count; // # handles in the list CK_ULONG_32 find_len; // max # of handles in the list CK_ULONG_32 find_idx; // current position CK_BBOOL find_active; ENCR_DECR_CONTEXT encr_ctx; ENCR_DECR_CONTEXT decr_ctx; DIGEST_CONTEXT digest_ctx; SIGN_VERIFY_CONTEXT sign_ctx; SIGN_VERIFY_CONTEXT verify_ctx; } SESSION; typedef struct _DES_CONTEXT { CK_BYTE data[ DES_BLOCK_SIZE ]; CK_ULONG len; CK_BBOOL cbc_pad; // is this a CKM_DES_CBC_PAD operation? } DES_CONTEXT; typedef struct _AES_CONTEXT { CK_BYTE data[ AES_BLOCK_SIZE ]; CK_ULONG len; CK_BBOOL cbc_pad; } AES_CONTEXT; typedef struct _SHA1_CONTEXT { unsigned int buf[16]; unsigned int hash_value[5]; unsigned int bits_hi, bits_lo; // # bits processed so far } SHA1_CONTEXT; typedef SHA1_CONTEXT SHA2_CONTEXT; typedef struct _MD2_CONTEXT { CK_BYTE state[16]; // state CK_BYTE checksum[16]; // checksum CK_ULONG count; // number of bytes, modulo 16 CK_BYTE buffer[16]; // input buffer } MD2_CONTEXT; typedef struct _MD5_CONTEXT { CK_ULONG i[2]; // number of _bits_ handled mod 2^64 CK_ULONG buf[4]; // scratch buffer CK_BYTE in[64]; // input buffer CK_BYTE digest[16]; // actual digest after MD5Final call } MD5_CONTEXT; // linux typedef pthread_mutex_t MUTEX; // This is actualy wrong... XPROC will be with spinlocks #if (SPINXPL) #define XPROCLOCK unsigned int #else #define XPROCLOCK MUTEX #endif typedef struct _TEMPLATE { DL_NODE *attribute_list; } TEMPLATE; typedef struct _OBJECT { CK_OBJECT_CLASS class; CK_BYTE name[8]; // for token objects SESSION *session; // creator; only for session objects TEMPLATE *template; CK_ULONG count_hi; // only significant for token objects CK_ULONG count_lo; // only significant for token objects CK_ULONG index; // SAB Index into the SHM } OBJECT; typedef struct _OBJECT_MAP { CK_OBJECT_HANDLE handle; CK_BBOOL is_private; CK_BBOOL is_session_obj; SESSION * session; OBJECT * ptr; } OBJECT_MAP; typedef struct _ATTRIBUTE_PARSE_LIST { CK_ATTRIBUTE_TYPE type; void *ptr; CK_ULONG len; CK_BBOOL found; } ATTRIBUTE_PARSE_LIST; typedef struct _OP_STATE_DATA { CK_STATE session_state; CK_ULONG active_operation; CK_ULONG data_len; // state data gets appended here // // mechanism parameter gets appended here // } OP_STATE_DATA; // this is our internal "tweak" vector (not the FCV) used to tweak various // aspects of the PKCS #11 implementation. Some of these tweaks deviate from // the PKCS #11 specification but are needed to support Netscape. Others // are left as token-defined values by PKCS #11. // // - whether or not to allow weak/semi-weak DES keys to be imported // - whether to insist imported DES keys have proper parity // - whether the CKA_ENCRYPT/DECRYPT/SIGN/VERIFY attributes are modifiable // after key creation // typedef struct _TWEAK_VEC { int allow_weak_des ; int check_des_parity ; int allow_key_mods ; int netscape_mods ; } TWEAK_VEC; typedef struct _TOKEN_DATA { CK_TOKEN_INFO_32 token_info; CK_BYTE user_pin_sha[3 * DES_BLOCK_SIZE]; CK_BYTE so_pin_sha[3 * DES_BLOCK_SIZE]; CK_BYTE next_token_object_name[8]; TWEAK_VEC tweak_vector; } TOKEN_DATA; typedef struct _SSL3_MAC_CONTEXT { DIGEST_CONTEXT hash_context; CK_BBOOL flag; } SSL3_MAC_CONTEXT; typedef struct _RSA_DIGEST_CONTEXT { DIGEST_CONTEXT hash_context; CK_BBOOL flag; } RSA_DIGEST_CONTEXT; typedef struct _MECH_LIST_ELEMENT { CK_MECHANISM_TYPE mech_type; CK_MECHANISM_INFO mech_info; } MECH_LIST_ELEMENT; struct mech_list_item; struct mech_list_item { struct mech_list_item *next; MECH_LIST_ELEMENT element; }; struct mech_list_item * find_mech_list_item_for_type(CK_MECHANISM_TYPE type, struct mech_list_item *head); /* mech_list.c */ CK_RV ock_generic_get_mechanism_list(CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount); /* mech_list.c */ CK_RV ock_generic_get_mechanism_info(CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo); typedef struct _MASTER_KEY_FILE_T { CK_BYTE key[MASTER_KEY_SIZE]; CK_BYTE sha_hash[SHA1_HASH_SIZE]; } MASTER_KEY_FILE_T; typedef struct _TOK_OBJ_ENTRY { CK_BBOOL deleted; char name[8]; CK_ULONG_32 count_lo; CK_ULONG_32 count_hi; } TOK_OBJ_ENTRY; typedef struct _LW_SHM_TYPE { XPROCLOCK mutex; #if SYSVSEM key_t semtok; #endif TOKEN_DATA nv_token_data; CK_ULONG_32 num_priv_tok_obj; CK_ULONG_32 num_publ_tok_obj; CK_BBOOL priv_loaded; CK_BBOOL publ_loaded; TOK_OBJ_ENTRY publ_tok_objs[ MAX_TOK_OBJS ]; TOK_OBJ_ENTRY priv_tok_objs[ MAX_TOK_OBJS ]; } LW_SHM_TYPE; // These are the same for both AIX and Linux... #define MY_CreateMutex(x) _CreateMutex((MUTEX *)(x)) #define MY_DestroyMutex(x) _DestroyMutex((MUTEX *)(x)) #define MY_LockMutex(x) _LockMutex((MUTEX *)(x)) #define MY_UnlockMutex(x) _UnlockMutex((MUTEX *)(x)) #define MY_CreateMsem(x) CreateXProcLock((void *)(x)) #define MY_DestroyMsem(x) DestroyXProcLock((void *)(x)) #define MY_LockMsem(x) XProcLock((void *)(x)) #define MY_UnlockMsem(x) XProcUnLock((void *)(x)) #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/README-IBM_CCA_users0000640000175000017500000001324711327631345022537 0ustar jfjf openCryptoki CCA Token README Kent Yoder The purpose of this README is to document the differences between setting up the openCryptoki token for the IBM CCA (Common Cryptographic Architecture) and setting up other tokens, such as the ICA (IBM Crypto Accelerator) token. The main difference is that the CCA libraries are available for 64bit s390x only, whereas all other openCryptoki tokens can be used 32 or 64bit. This means that the PKCS#11 setup utility used by openCryptoki, pkcsconf, cannot be used, since its compiled 32bit by default. In order to work around this limitation, a version of pkcsconf has been included in the 64bit openCryptoki package to configure the CCA token. This version is named 'pkcsconf64', and is installed in /usr/sbin, alongside the 32bit pkcsconf. Note that pkcsconf64 can be used to configure any openCryptoki token, since they all support 64bit apps. After installing these RPMs, the setup process is: STEP 1: # /etc/init.d/pkcsslotd start This should start the pkcsslotd daemon. You can check this with: # ps -auwx | grep pkcsslotd You should see something like: root 8914 0.0 0.3 3220 1552 ? Ss 23:31 0:00 /usr/sbin/pkcsslotd STEP 2: Check that all the libraries are in the right places. Do: # /usr/sbin/pkcsconf64 -t You should see: Token #0 Info: Label: IBM ICA PKCS #11 Manufacturer: IBM Corp. Model: IBM ICA Serial Number: 123 Flags: 0x880045 (RNG|LOGIN_REQUIRED|CLOCK_ON_TOKEN|USER_PIN_TO_BE_CHANGED|SO_PIN_TO_BE_CHANGED) Sessions: -1/-1 R/W Sessions: -1/-1 PIN Length: 4-8 Public Memory: 0xFFFFFFFF/0xFFFFFFFF Private Memory: 0xFFFFFFFF/0xFFFFFFFF Hardware Version: 1.0 Firmware Version: 1.0 Token #1 Info: Label: IBM PKCS#11 for CCA Manufacturer: IBM Corp. Model: IBM CCA Token Serial Number: 123 Flags: 0x880045 (RNG|LOGIN_REQUIRED|CLOCK_ON_TOKEN|USER_PIN_TO_BE_CHANGED|SO_PIN_TO_BE_CHANGED) Sessions: -1/-1 R/W Sessions: -1/-1 PIN Length: 4-128 Public Memory: 0xFFFFFFFF/0xFFFFFFFF Private Memory: 0xFFFFFFFF/0xFFFFFFFF Hardware Version: 1.0 Firmware Version: 1.0 Time: 23:33:41 Token #0 is the ICA token, driven by the libica package. If libica or its device driver isn't installed, you may only see Token #1. If you get the following message: C_GetSlotCount returned 0 slots. Check that your tokens are installed correctly. several things could be wrong. Check that: 1) The master keys for the CCA's crypto card have been loaded. If the master keys have not yet been loaded, a message will appear in the system log whenever pkcsconf is run that looks like: openCryptoki(CCA)[5294]: cca_specific.c Warning: CCA master key is not yet loaded Please follow any instructions or procedures you may have been given on loading master keys. 2) The device driver for the CCA hardware is loaded. This module may be called "zsecrypt" or "z90crypt" and may not have been loaded by the /etc/init.d/pkcsslotd script. 3) The CCA libraries are installed correctly. openCryptoki requires the following libraries: library source package ----------------------------------- libcsulcall.so xcryptolinz libcsulsapi.so xcryptolinz libcsulsecy.so xcryptolinz libds30.so xcryptolinz libxcryp.so xcryptolinz libcrypto.so openssl When a token is detected by the startup scripts run by /etc/init.d/pkcsslotd, an entry is made in the /var/lib/opencryptoki/pk_config_data file. This file will contain 1 line per token. STEP 3: Initialize the CCA token. # /usr/sbin/pkcsconf64 -I -c 1 You should see: Enter the SO PIN: - Enter the default SO PIN here, which is "87654321". Enter a unique token label: - Enter any string here, such as "My token init string" Another call to pkcsconf64 should reflect the token label change: # /usr/sbin/pkcsconf64 -t Token #1 Info: Label: My token init string Manufacturer: IBM Corp. Model: IBM CCA Token Serial Number: 123 Flags: 0x880445 (RNG|LOGIN_REQUIRED|CLOCK_ON_TOKEN|TOKEN_INITIALIZED|USER_PIN_TO_BE_CHANGED|SO_PIN_TO_BE_CHANGED) Sessions: -1/-1 R/W Sessions: -1/-1 PIN Length: 4-128 Public Memory: 0xFFFFFFFF/0xFFFFFFFF Private Memory: 0xFFFFFFFF/0xFFFFFFFF Hardware Version: 1.0 Firmware Version: 1.0 Time: 23:38:48 STEP 4: Set the Security Officer's (SO) Password. This should be a secret known only to the system admin. # /usr/sbin/pkcsconf64 -P -c 1 Enter the SO PIN: ******** - This should be the default SO PIN, "87654321" Enter the new SO PIN: ******** Re-enter the new SO PIN: ******** - Enter the new SO PIN here twice for verification STEP 5: Set the PKCS#11 User Password. This will be a secret known to all users/apps of the PKCS#11 interface. # /usr/sbin/pkcsconf64 -u -c 1 Enter the SO PIN: ******** - This should be the SO PIN you set in STEP 4. Enter the new user PIN: ********** Re-enter the new user PIN: ********** - This should be a new secret, known to all users of the token. STEP 6: Make sure applications will have access to PKCS#11. All processes that would like to use PKCS#11 need to be in the 'pkcs11' group. So, if java needs to access PKCS#11, then edit /etc/group: # vim /etc/group Look for the line: pkcs11:!:64:root and add the java uid to that line: pkcs11:!:64:root,java /etc/init.d/pkcsslotd creates the 'pkcs11' group when its first run. Send questions to opencryptoki-users@lists.sourceforge.net. EOF opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/tok_spec_struct.h0000640000175000017500000001143211327631345022741 0ustar jfjf/* * Licensed materials, Property of IBM Corp. * * openCryptoki CCA token * * (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2006 * * Author: Kent E. Yoder * */ /*************************************************************************** Change Log ========== 4/25/03 Kapil Sood (kapil@corrent.com) Added DH key pair generation and DH shared key derivation functions. ****************************************************************************/ #ifndef _TOK_SPECIFIC_STRUCT #define _TOK_SPECIFIC_STRUCT struct token_specific_struct{ CK_BYTE token_directory[2048]; // Used to be in the token_local.h as a #def CK_BYTE token_subdir[2048]; // subdirectory CK_BYTE token_debug_tag[2048]; // debug logging tag CK_RV (*t_init)(char *,CK_SLOT_ID); // Initialization function int (*t_slot2local)(); // convert the PKCS#11 slot to a local index // generaly not used but if a STDLL actually // managed multiple devices, this would conv CK_RV (*t_rng)(CK_BYTE *,CK_ULONG); // Random Number Gen CK_RV (*t_session)(CK_SLOT_ID); //perform anything specific needed by the token takes a slot id CK_RV (*t_final)(); // any specific final code CK_RV (*t_des_key_gen)(CK_BYTE *, CK_ULONG, CK_ULONG); CK_RV (*t_des_ecb)( CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_BYTE); CK_RV (*t_des_cbc)( CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, CK_BYTE *,CK_BYTE *, CK_BYTE); CK_RV (*t_tdes_ecb)( CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_BYTE); CK_RV (*t_tdes_cbc)( CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, CK_BYTE *,CK_BYTE *, CK_BYTE); #if 0 CK_RV (*t_rsa_decrypt)( CK_BYTE *, CK_ULONG, CK_BYTE *, OBJECT *); CK_RV (*t_rsa_encrypt)( CK_BYTE *, CK_ULONG, CK_BYTE *, OBJECT *); #else CK_RV (*t_rsa_decrypt)(CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, OBJECT *); CK_RV (*t_rsa_encrypt)(CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, OBJECT *); CK_RV (*t_rsa_sign)(CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, OBJECT *); CK_RV (*t_rsa_verify)(CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG, OBJECT *); #endif CK_RV (*t_rsa_generate_keypair)(TEMPLATE *, TEMPLATE *); /* Begin code contributed by Corrent corp. */ #ifndef NODH // Token Specific DH functions CK_RV (*t_dh_pkcs_derive) ( CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG ) ; CK_RV (*t_dh_pkcs_key_pair_gen)(TEMPLATE *, TEMPLATE *); #endif /* End code contributed by Corrent corp. */ // Token Specific SHA1 functions CK_RV (*t_sha_init)(DIGEST_CONTEXT *); CK_RV (*t_sha_update)( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG); CK_RV (*t_sha_final)( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG *); // Token Specific SHA256 functions CK_RV (*t_sha2_init)(DIGEST_CONTEXT *); CK_RV (*t_sha2_update)( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG); CK_RV (*t_sha2_final)( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG *); #ifndef NOAES // Token Specific AES functions CK_RV (*t_aes_key_gen)( CK_BYTE *, CK_ULONG); CK_RV (*t_aes_ecb)( CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_ULONG, CK_BYTE); CK_RV (*t_aes_cbc)( CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_ULONG, CK_BYTE *, CK_BYTE); #endif CK_RV (*t_get_mechanism_list)(CK_MECHANISM_TYPE_PTR, CK_ULONG_PTR); CK_RV (*t_get_mechanism_info)(CK_MECHANISM_TYPE, CK_MECHANISM_INFO_PTR); }; typedef struct token_specific_struct token_spec_t; #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/mech_des.c0000640000175000017500000013166111327631345021277 0ustar jfjf/* * Licensed materials, Property of IBM Corp. * * openCryptoki CCA token * * (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2006 * */ // File: mech_des.c // // Mechanisms for DES // #include // for memcmp() et al #include #include "cca_stdll.h" #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" #ifndef NOECB // // CK_RV pk_des_ecb_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES_ECB requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des_ecb_encrypt( in_data, in_data_len, out_data, out_data_len, attr->pValue); } // // CK_RV des_ecb_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES_ECB requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des_ecb_decrypt( in_data, in_data_len, out_data, out_data_len, attr->pValue ); } #endif // // CK_RV pk_des_cbc_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES_CBC requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des_cbc_encrypt( in_data, in_data_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); } // // CK_RV des_cbc_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES_CBC requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des_cbc_decrypt( in_data, in_data_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); } // // CK_RV des_cbc_pad_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE *clear = NULL; CK_ULONG padded_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // DES-CBC-PAD has no input length requirements // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // compute the output length, accounting for padding // padded_len = DES_BLOCK_SIZE * (in_data_len / DES_BLOCK_SIZE + 1); if (length_only == TRUE) { *out_data_len = padded_len; return CKR_OK; } if (*out_data_len < padded_len) { *out_data_len = padded_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } clear = (CK_BYTE *)malloc( padded_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( clear, in_data, in_data_len ); add_pkcs_padding( clear + in_data_len, DES_BLOCK_SIZE, in_data_len, padded_len ); rc = ckm_des_cbc_encrypt( clear, padded_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); if (rc != CKR_OK) st_err_log(113, __FILE__, __LINE__); free( clear ); return rc; } // // CK_RV des_cbc_pad_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE *clear = NULL; CK_ULONG padded_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // no need to validate the input length since we'll pad as necessary // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // we're decrypting so even with CBC-PAD, we should have an integral // number of block to decrypt // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } // the amount of cleartext after stripping the padding will actually be less // than the input bytes... // padded_len = in_data_len; if (length_only == TRUE) { *out_data_len = padded_len; return CKR_OK; } clear = (CK_BYTE *)malloc( padded_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } rc = ckm_des_cbc_decrypt( in_data, in_data_len, clear, &padded_len, ctx->mech.pParameter, attr->pValue ); if (rc == CKR_OK) { strip_pkcs_padding( clear, padded_len, out_data_len ); memcpy( out_data, clear, *out_data_len ); } else st_err_log(114, __FILE__, __LINE__); free( clear ); return rc; } #ifndef NOECB // // CK_RV des_ecb_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % DES_BLOCK_SIZE); out_len = (total - remain); // should always be at least 1 block if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); rc = ckm_des_ecb_encrypt( clear, out_len, out_data, out_data_len, attr->pValue ); if (rc == CKR_OK) { *out_data_len = out_len; // update the context buffer. we already used the buffer's current // contents so we completely overwrite it // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(115, __FILE__, __LINE__); free( clear ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // shouldn't reach this } // // CK_RV des_ecb_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % DES_BLOCK_SIZE); out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_des_ecb_decrypt( cipher, out_len, out_data, out_data_len, attr->pValue ); if (rc == CKR_OK) { *out_data_len = out_len; // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(116, __FILE__, __LINE__); free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // shouldn't reach this } #endif // // CK_RV des_cbc_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % DES_BLOCK_SIZE); out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // these buffers need to be longword aligned // clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); rc = ckm_des_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); if (rc == CKR_OK) { *out_data_len = out_len; // the new init_v is the last encrypted data block // memcpy( ctx->mech.pParameter, out_data + (*out_data_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(113, __FILE__, __LINE__); free( clear ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV des_cbc_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = context->len + in_data_len; if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = total % DES_BLOCK_SIZE; out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // these buffers need to be longword aligned // cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_des_cbc_decrypt( cipher, out_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); if (rc == CKR_OK) { *out_data_len = out_len; // the new init_v is the last decrypted data block // memcpy( ctx->mech.pParameter, cipher + (out_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(114, __FILE__, __LINE__); free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV des_cbc_pad_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); // note, this is subtly different from the other encrypt update routines // if (total <= DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block + 1 byte // remain = total % DES_BLOCK_SIZE; out_len = total - remain; if (remain == 0) { remain = DES_BLOCK_SIZE; out_len -= DES_BLOCK_SIZE; } if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } // at this point, we should have: // 1) remain != 0 // 2) out_len != 0 // rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // these buffers need to be longword aligned // clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); // // we don't do padding during the update // rc = ckm_des_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); if (rc == CKR_OK) { // the new init_v is the last encrypted data block // memcpy( ctx->mech.pParameter, out_data + (*out_data_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the temporary space // memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(113, __FILE__, __LINE__); free( clear ); return rc; } } // // CK_RV des_cbc_pad_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); // note, this is subtly different from the other decrypt update routines // if (total <= DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block + 1 byte // remain = total % DES_BLOCK_SIZE; out_len = total - remain; if (remain == 0) { remain = DES_BLOCK_SIZE; out_len -= DES_BLOCK_SIZE; } if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } // at this point, we should have: // 1) remain != 0 // 2) out_len != 0 // rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // these buffers need to be longword aligned // cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_des_cbc_decrypt( cipher, out_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); if (rc == CKR_OK) { // the new init_v is the last decrypted data block // memcpy( ctx->mech.pParameter, cipher + (out_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the temporary space // memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(114, __FILE__, __LINE__); free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } #ifndef NOECB // // CK_RV des_ecb_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES-ECB does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV des_ecb_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES-ECB does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } #endif // // CK_RV des_cbc_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES-CBC does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV des_cbc_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES-CBC does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV des_cbc_pad_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE clear[2 * DES_BLOCK_SIZE]; CK_ULONG out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; // there will never be more than one block in the context buffer // so the amount of output is as follows: // if less than 1 block stored, we generate one block of output // if a full block is stored, we generate two blocks of output (one pad block) // if (context->len == DES_BLOCK_SIZE) out_len = 2 * DES_BLOCK_SIZE; else out_len = DES_BLOCK_SIZE; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } else { memcpy( clear, context->data, context->len ); add_pkcs_padding( clear + context->len, DES_BLOCK_SIZE, context->len, out_len ); rc = ckm_des_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); if (rc != CKR_OK) st_err_log(113, __FILE__, __LINE__); return rc; } } // // CK_RV des_cbc_pad_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE clear[DES_BLOCK_SIZE]; CK_BYTE cipher[DES_BLOCK_SIZE]; CK_ULONG out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_IBM_OPAQUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; // there had better be a full block in the context buffer // if (context->len != DES_BLOCK_SIZE){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } // we don't know a priori how much data we'll be returning. we won't // know until after we decrypt it and strip the padding. it's possible // that we'll return nothing (the final block might be a padding block). // out_len = DES_BLOCK_SIZE; // upper bound on what we'll return if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } else { memcpy( cipher, context->data, DES_BLOCK_SIZE ); rc = ckm_des_cbc_decrypt( cipher, DES_BLOCK_SIZE, clear, &out_len, ctx->mech.pParameter, attr->pValue ); if (rc == CKR_OK) { strip_pkcs_padding( clear, DES_BLOCK_SIZE, &out_len ); if (out_len != 0) memcpy( out_data, clear, out_len ); *out_data_len = out_len; } else st_err_log(114, __FILE__, __LINE__); return rc; } } // // mechanisms // // // CK_RV ckm_des_key_gen( TEMPLATE *tmpl ) { CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * opaque_attr = NULL; CK_ATTRIBUTE * key_type_attr = NULL; CK_ATTRIBUTE * class_attr = NULL; CK_ATTRIBUTE * local_attr = NULL; CK_BYTE dummy_key[DES_KEY_SIZE] = { 0, }; CK_BYTE des_key[CCA_KEY_ID_SIZE]; CK_ULONG rc; rc = token_specific.t_des_key_gen(des_key, CCA_KEY_ID_SIZE, DES_KEY_SIZE); if (rc != CKR_OK) return rc; value_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + DES_KEY_SIZE ); opaque_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + CCA_KEY_ID_SIZE ); key_type_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); class_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS) ); local_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!value_attr || !opaque_attr || !key_type_attr || !class_attr || !local_attr) { if (value_attr) free( value_attr ); if (opaque_attr) free( opaque_attr ); if (key_type_attr) free( key_type_attr ); if (class_attr) free( class_attr ); if (local_attr) free( local_attr ); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = DES_KEY_SIZE; value_attr->pValue = (CK_BYTE *)value_attr + sizeof(CK_ATTRIBUTE); memcpy( value_attr->pValue, dummy_key, DES_KEY_SIZE ); opaque_attr->type = CKA_IBM_OPAQUE; opaque_attr->ulValueLen = CCA_KEY_ID_SIZE; opaque_attr->pValue = (CK_BYTE *)opaque_attr + sizeof(CK_ATTRIBUTE); memcpy( opaque_attr->pValue, des_key, CCA_KEY_ID_SIZE ); key_type_attr->type = CKA_KEY_TYPE; key_type_attr->ulValueLen = sizeof(CK_KEY_TYPE); key_type_attr->pValue = (CK_BYTE *)key_type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)key_type_attr->pValue = CKK_DES; class_attr->type = CKA_CLASS; class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS); class_attr->pValue = (CK_BYTE *)class_attr + sizeof(CK_ATTRIBUTE); *(CK_OBJECT_CLASS *)class_attr->pValue = CKO_SECRET_KEY; local_attr->type = CKA_LOCAL; local_attr->ulValueLen = sizeof(CK_BBOOL); local_attr->pValue = (CK_BYTE *)local_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)local_attr->pValue = TRUE; template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, opaque_attr ); template_update_attribute( tmpl, key_type_attr ); template_update_attribute( tmpl, class_attr ); template_update_attribute( tmpl, local_attr ); return CKR_OK; } #if !(NOCDMF) // // CK_RV ckm_cdmf_key_gen( TEMPLATE *tmpl ) { CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * key_type_attr = NULL; CK_ATTRIBUTE * class_attr = NULL; CK_ATTRIBUTE * local_attr = NULL; CK_BYTE cdmf_key[DES_KEY_SIZE]; CK_ULONG repl_len, expected_repl_len; CK_ULONG rc; repl_len = expected_repl_len = DES_KEY_SIZE; rc = communicate( PK_CDMF_KEYGEN, NULL, 0, cdmf_key, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK) { if (repl_len != expected_repl_len) return CKR_GENERAL_ERROR; } value_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + DES_KEY_SIZE ); key_type_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); class_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS) ); local_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!value_attr || !key_type_attr || !class_attr || !local_attr) { if (value_attr) free( value_attr ); if (key_type_attr) free( key_type_attr ); if (class_attr) free( class_attr ); if (local_attr) free( local_attr ); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = DES_KEY_SIZE; value_attr->pValue = (CK_BYTE *)value_attr + sizeof(CK_ATTRIBUTE); memcpy( value_attr->pValue, cdmf_key, DES_KEY_SIZE ); key_type_attr->type = CKA_KEY_TYPE; key_type_attr->ulValueLen = sizeof(CK_KEY_TYPE); key_type_attr->pValue = (CK_BYTE *)key_type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)key_type_attr->pValue = CKK_CDMF; class_attr->type = CKA_CLASS; class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS); class_attr->pValue = (CK_BYTE *)class_attr + sizeof(CK_ATTRIBUTE); *(CK_OBJECT_CLASS *)class_attr->pValue = CKO_SECRET_KEY; local_attr->type = CKA_LOCAL; local_attr->ulValueLen = sizeof(CK_BBOOL); local_attr->pValue = (CK_BYTE *)local_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)local_attr->pValue = TRUE; template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, key_type_attr ); template_update_attribute( tmpl, class_attr ); template_update_attribute( tmpl, local_attr ); return CKR_OK; } #endif #ifndef NOECB // // CK_RV ckm_des_ecb_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * key_value ) { CK_ULONG rc; if (!in_data || !out_data || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_des_ecb(in_data,in_data_len,out_data,out_data_len,key_value,1);// token specifics return CKR_ errors ... if (rc != CKR_OK) st_err_log(117, __FILE__, __LINE__); return rc; } // // CK_RV ckm_des_ecb_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * key_value ) { CK_ULONG rc; if (!in_data || !out_data || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_des_ecb(in_data,in_data_len,out_data, out_data_len,key_value,0); // last parm is the encrypt flag if (rc != CKR_OK) st_err_log(117, __FILE__, __LINE__); return rc; } #endif // // CK_RV ckm_des_cbc_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * init_v, CK_BYTE * key_value ) { CK_ULONG rc; if (!in_data || !out_data || !init_v || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ #if 0 st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; #else *out_data_len = in_data_len; st_err_log(68, __FILE__, __FUNCTION__); return CKR_BUFFER_TOO_SMALL; #endif } rc = token_specific.t_des_cbc(in_data,in_data_len,out_data, out_data_len,key_value,init_v,1); // last parm is the encrypt flag if (rc != CKR_OK) st_err_log(118, __FILE__, __LINE__); return rc; } // // CK_RV ckm_des_cbc_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * init_v, CK_BYTE * key_value ) { CK_ULONG rc; if (!in_data || !out_data || !init_v || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_des_cbc(in_data,in_data_len,out_data, out_data_len,key_value,init_v,0); // last parm is the encrypt flag if (rc != CKR_OK) st_err_log(118, __FILE__, __LINE__); return rc; } // we're preparing to wrap a key using DES. need to make sure the // data length is a integral multiple of the DES block size. // // PKCS #11 specifies that the padding shall be in the form of NULL // bytes appended to the data // // this routine works with either DES and 3DES as the wrapping mechanism // CK_RV ckm_des_wrap_format( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len ) { CK_BYTE * ptr = NULL; CK_ULONG len1, len2; len1 = *data_len; // if the input key data isn't a multiple of the blocksize, // we pad with NULLs to the next blocksize multiple. // if (len1 % DES_BLOCK_SIZE != 0) { len2 = DES_BLOCK_SIZE * ((len1 / DES_BLOCK_SIZE) + 1); if (length_only == FALSE) { ptr = (CK_BYTE *)realloc(*data, len2); if (!ptr){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } else memset( ptr + len1, 0x0, (len2 - len1) ); *data = ptr; *data_len = len2; } } return CKR_OK; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/tokenlocal.h0000640000175000017500000000074111327631345021662 0ustar jfjf/* * Licensed materials, Property of IBM Corp. * * openCryptoki CCA token * * (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2006 * * Author: Kent E. Yoder * */ // // to get the variant dependency out #ifndef _TOK_LOCAL_ #define _TOK_LOCAL_ #define PK_LITE_DIR token_specific.token_directory #define PK_DIR PK_LITE_DIR #define SUB_DIR token_specific.token_subdir #define DBGTAG token_specific.token_debug_tag #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/asn1.c0000640000175000017500000014757411327631345020404 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // ASN.1 encoding/decoding routines // // This code is a mess... // //#include #include #include #include // for memcmp() et al #include "pkcs11types.h" #include "defs.h" #include "cca_stdll.h" #include "host_defs.h" #include "h_extern.h" // // CK_ULONG ber_encode_INTEGER( CK_BBOOL length_only, CK_BYTE ** ber_int, CK_ULONG * ber_int_len, CK_BYTE * data, CK_ULONG data_len ) { CK_BYTE *buf = NULL; CK_ULONG len; // if data_len < 127 use short-form length id // if data_len < 256 use long-form length id with 1-byte length field // if data_len < 65536 use long-form length id with 2-byte length field // if data_len < 16777216 use long-form length id with 3-byte length field // if (data_len < 128) len = 1 + 1 + data_len; else if (data_len < 256) len = 1 + (1 + 1) + data_len; else if (data_len < (1 << 16)) len = 1 + (1 + 2) + data_len; else if (data_len < (1 << 24)) len = 1 + (1 + 3) + data_len; else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *ber_int_len = len; return CKR_OK; } buf = (CK_BYTE *)malloc( len ); if (!buf){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } if (data_len < 128) { buf[0] = 0x02; buf[1] = data_len; memcpy( &buf[2], data, data_len ); *ber_int_len = len; *ber_int = buf; return CKR_OK; } if (data_len < 256) { buf[0] = 0x02; buf[1] = 0x81; buf[2] = data_len; memcpy( &buf[3], data, data_len ); *ber_int_len = len; *ber_int = buf; return CKR_OK; } if (data_len < (1 << 16)) { buf[0] = 0x02; buf[1] = 0x82; buf[2] = (data_len >> 8) & 0xFF; buf[3] = (data_len ) & 0xFF; memcpy( &buf[4], data, data_len ); *ber_int_len = len; *ber_int = buf; return CKR_OK; } if (data_len < (1 << 24)) { buf[0] = 0x02; buf[1] = 0x83; buf[2] = (data_len >> 16) & 0xFF; buf[3] = (data_len >> 8) & 0xFF; buf[4] = (data_len ) & 0xFF; memcpy( &buf[5], data, data_len ); *ber_int_len = len; *ber_int = buf; return CKR_OK; } // we should never reach this // free( buf ); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV ber_decode_INTEGER( CK_BYTE * ber_int, CK_BYTE ** data, CK_ULONG * data_len, CK_ULONG * field_len ) { CK_ULONG len, length_octets; if (!ber_int){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ber_int[0] != 0x02){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // short form lengths are easy // if ((ber_int[1] & 0x80) == 0) { len = ber_int[1] & 0x7F; *data = &ber_int[2]; *data_len = len; *field_len = 1 + 1 + len; return CKR_OK; } length_octets = ber_int[1] & 0x7F; if (length_octets == 1) { len = ber_int[2]; *data = &ber_int[3]; *data_len = len; *field_len = 1 + (1 + 1) + len; return CKR_OK; } if (length_octets == 2) { len = ber_int[2]; len = len << 8; len |= ber_int[3]; *data = &ber_int[4]; *data_len = len; *field_len = 1 + (1 + 2) + len; return CKR_OK; } if (length_octets == 3) { len = ber_int[2]; len = len << 8; len |= ber_int[3]; len = len << 8; len |= ber_int[4]; *data = &ber_int[5]; *data_len = len; *field_len = 1 + (1 + 3) + len; return CKR_OK; } // > 3 length octets implies a length > 16MB which isn't possible for // the coprocessor // st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV ber_encode_OCTET_STRING( CK_BBOOL length_only, CK_BYTE ** str, CK_ULONG * str_len, CK_BYTE * data, CK_ULONG data_len ) { CK_BYTE *buf = NULL; CK_ULONG len; // I only support Primitive encoding for OCTET STRINGS // // if data_len < 128 use short-form length id // if data_len < 256 use long-form length id with 1-byte length field // if data_len < 65536 use long-form length id with 2-byte length field // if (data_len < 128) len = 1 + 1 + data_len; else if (data_len < 256) len = 1 + (1 + 1) + data_len; else if (data_len < (1 << 16)) len = 1 + (1 + 2) + data_len; else if (data_len < (1 << 24)) len = 1 + (1 + 3) + data_len; else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *str_len = len; return CKR_OK; } buf = (CK_BYTE *)malloc( len ); if (!buf){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } if (data_len < 128) { buf[0] = 0x04; // primitive, OCTET STRING buf[1] = data_len; memcpy( &buf[2], data, data_len ); *str_len = len; *str = buf; return CKR_OK; } if (data_len < 256) { buf[0] = 0x04; // primitive, OCTET STRING buf[1] = 0x81; // length header -- 1 length octets buf[2] = data_len; memcpy( &buf[3], data, data_len ); *str_len = len; *str = buf; return CKR_OK; } if (data_len < (1 << 16)) { buf[0] = 0x04; // primitive, OCTET STRING buf[1] = 0x82; // length header -- 2 length octets buf[2] = (data_len >> 8) & 0xFF; buf[3] = (data_len ) & 0xFF; memcpy( &buf[4], data, data_len ); *str_len = len; *str = buf; return CKR_OK; } if (data_len < (1 << 24)) { buf[0] = 0x04; // primitive, OCTET STRING buf[1] = 0x83; // length header -- 3 length octets buf[2] = (data_len >> 16) & 0xFF; buf[3] = (data_len >> 8) & 0xFF; buf[4] = (data_len ) & 0xFF; memcpy( &buf[5], data, data_len ); *str_len = len; *str = buf; return CKR_OK; } // we should never reach this // free( buf ); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV ber_decode_OCTET_STRING( CK_BYTE * str, CK_BYTE ** data, CK_ULONG * data_len, CK_ULONG * field_len ) { CK_ULONG len, length_octets; // I only support decoding primitive OCTET STRINGS // if (!str){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (str[0] != 0x04){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // short form lengths are easy // if ((str[1] & 0x80) == 0) { len = str[1] & 0x7F; *data = &str[2]; *data_len = len; *field_len = 1 + (1) + len; return CKR_OK; } length_octets = str[1] & 0x7F; if (length_octets == 1) { len = str[2]; *data = &str[3]; *data_len = len; *field_len = 1 + (1 + 1) + len; return CKR_OK; } if (length_octets == 2) { len = str[2]; len = len << 8; len |= str[3]; *data = &str[4]; *data_len = len; *field_len = 1 + (1 + 2) + len; return CKR_OK; } if (length_octets == 3) { len = str[2]; len = len << 8; len |= str[3]; len = len << 8; len |= str[4]; *data = &str[5]; *data_len = len; *field_len = 1 + (1 + 3) + len; return CKR_OK; } // > 3 length octets implies a length > 16MB // st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV ber_encode_SEQUENCE( CK_BBOOL length_only, CK_BYTE ** seq, CK_ULONG * seq_len, CK_BYTE * data, CK_ULONG data_len ) { CK_BYTE *buf = NULL; CK_ULONG len; // if data_len < 127 use short-form length id // if data_len < 65536 use long-form length id with 2-byte length field // if (data_len < 128) len = 1 + 1 + data_len; else if (data_len < 256) len = 1 + (1 + 1) + data_len; else if (data_len < (1 << 16)) len = 1 + (1 + 2) + data_len; else if (data_len < (1 << 24)) len = 1 + (1 + 3) + data_len; else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *seq_len = len; return CKR_OK; } buf = (CK_BYTE *)malloc( len ); if (!buf){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } if (data_len < 128) { buf[0] = 0x30; // constructed, SEQUENCE buf[1] = data_len; memcpy( &buf[2], data, data_len ); *seq_len = len; *seq = buf; return CKR_OK; } if (data_len < 256) { buf[0] = 0x30; // constructed, SEQUENCE buf[1] = 0x81; // length header -- 1 length octets buf[2] = data_len; memcpy( &buf[3], data, data_len ); *seq_len = len; *seq = buf; return CKR_OK; } if (data_len < (1 << 16)) { buf[0] = 0x30; // constructed, SEQUENCE buf[1] = 0x82; // length header -- 2 length octets buf[2] = (data_len >> 8) & 0xFF; buf[3] = (data_len ) & 0xFF; memcpy( &buf[4], data, data_len ); *seq_len = len; *seq = buf; return CKR_OK; } if (data_len < (1 << 24)) { buf[0] = 0x30; // constructed, SEQUENCE buf[1] = 0x83; // length header -- 3 length octets buf[2] = (data_len >> 16) & 0xFF; buf[3] = (data_len >> 8) & 0xFF; buf[4] = (data_len ) & 0xFF; memcpy( &buf[5], data, data_len ); *seq_len = len; *seq = buf; return CKR_OK; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV ber_decode_SEQUENCE( CK_BYTE * seq, CK_BYTE ** data, CK_ULONG * data_len, CK_ULONG * field_len ) { CK_ULONG len, length_octets; if (!seq){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (seq[0] != 0x30){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // short form lengths are easy // if ((seq[1] & 0x80) == 0) { len = seq[1] & 0x7F; *data = &seq[2]; *data_len = len; *field_len = 1 + (1) + len; return CKR_OK; } length_octets = seq[1] & 0x7F; if (length_octets == 1) { len = seq[2]; *data = &seq[3]; *data_len = len; *field_len = 1 + (1 + 1) + len; return CKR_OK; } if (length_octets == 2) { len = seq[2]; len = len << 8; len |= seq[3]; *data = &seq[4]; *data_len = len; *field_len = 1 + (1 + 2) + len; return CKR_OK; } if (length_octets == 3) { len = seq[2]; len = len << 8; len |= seq[3]; len = len << 8; len |= seq[4]; *data = &seq[5]; *data_len = len; *field_len = 1 + (1 + 3) + len; return CKR_OK; } // > 3 length octets implies a length > 16MB // st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // PrivateKeyInfo ::= SEQUENCE { // version Version -- always '0' for now // privateKeyAlgorithm PrivateKeyAlgorithmIdentifier // privateKey PrivateKey // attributes // } // CK_RV ber_encode_PrivateKeyInfo( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len, CK_BYTE * algorithm_id, CK_ULONG algorithm_id_len, CK_BYTE * priv_key, CK_ULONG priv_key_len ) { CK_BYTE * buf = NULL; CK_BYTE * tmp = NULL; CK_BYTE version[] = { 0 }; CK_BYTE attrib[] = {0x05, 0x00}; CK_ULONG len, total; CK_RV rc; len = 0; rc = ber_encode_INTEGER( TRUE, NULL, &total, version, sizeof(version) ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); return rc; } else len += total; len += algorithm_id_len; rc = ber_encode_OCTET_STRING( TRUE, NULL, &total, priv_key, priv_key_len ); if (rc != CKR_OK){ st_err_log(77, __FILE__, __LINE__); return rc; } else len += total; // for this stuff, attributes are always NULL == 05 00 // len += sizeof(attrib); if (length_only == TRUE) { rc = ber_encode_SEQUENCE( TRUE, NULL, &total, NULL, len ); if (rc == CKR_OK) *data_len = total; if (rc != CKR_OK) st_err_log(78, __FILE__, __LINE__); return rc; } buf = (CK_BYTE *)malloc(len); if (!buf){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } len = 0; rc = ber_encode_INTEGER( FALSE, &tmp, &total, version, sizeof(version) ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+len, tmp, total ); len += total; free( tmp ); memcpy( buf+len, algorithm_id, algorithm_id_len ); len += algorithm_id_len; rc = ber_encode_OCTET_STRING( FALSE, &tmp, &total, priv_key, priv_key_len ); if (rc != CKR_OK){ st_err_log(77, __FILE__, __LINE__); goto error; } memcpy( buf+len, tmp, total ); len += total; free( tmp ); memcpy( buf+len, attrib, sizeof(attrib)); len += sizeof(attrib); rc = ber_encode_SEQUENCE( FALSE, data, data_len, buf, len ); if (rc != CKR_OK) st_err_log(78, __FILE__, __LINE__); error: free( buf ); return rc; } // // CK_RV ber_decode_PrivateKeyInfo( CK_BYTE * data, CK_ULONG data_len, CK_BYTE ** algorithm, CK_ULONG * alg_len, CK_BYTE ** priv_key ) { CK_BYTE *buf = NULL; CK_BYTE *alg = NULL; CK_BYTE *ver = NULL; CK_ULONG buf_len, offset, len, field_len; CK_RV rc; if (!data || (data_len == 0)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = ber_decode_SEQUENCE( data, &buf, &buf_len, &field_len ); if (rc != CKR_OK){ st_err_log(81, __FILE__, __LINE__); return rc; } // version -- we just ignore this // offset = 0; rc = ber_decode_INTEGER( buf+offset, &ver, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); return rc; } offset += field_len; // 'buf' is now pointing to the PrivateKeyAlgorithmIdentifier // rc = ber_decode_SEQUENCE( buf+offset, &alg, &len, &field_len ); if (rc != CKR_OK){ st_err_log(81, __FILE__, __LINE__); return rc; } *algorithm = alg; *alg_len = len; rc = ber_decode_OCTET_STRING( alg + len, priv_key, &buf_len, &field_len ); if (rc != CKR_OK) st_err_log(81, __FILE__, __LINE__); return rc; } // RSAPrivateKey ::= SEQUENCE { // version Version -- always '0' for now // modulus INTEGER // publicExponent INTEGER // } // CK_RV ber_encode_RSAPrivateKey( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len, CK_ATTRIBUTE * modulus, CK_ATTRIBUTE * publ_exp, CK_ATTRIBUTE * opaque ) { CK_BYTE *buf = NULL; CK_BYTE *buf2 = NULL; CK_ULONG len, offset; CK_BYTE version[] = { 0 }; CK_RV rc; offset = 0; rc = 0; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, sizeof(version) ); offset += len; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, modulus->ulValueLen ); offset += len; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, publ_exp->ulValueLen ); offset += len; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, opaque->ulValueLen ); offset += len; #if 0 rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, priv_exp->ulValueLen ); offset += len; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, prime1->ulValueLen ); offset += len; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, prime2->ulValueLen ); offset += len; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, exponent1->ulValueLen ); offset += len; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, exponent2->ulValueLen ); offset += len; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, coeff->ulValueLen ); offset += len; #endif if (rc != CKR_OK){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { rc = ber_encode_SEQUENCE( TRUE, NULL, &len, NULL, offset ); if (rc != CKR_OK){ st_err_log(78, __FILE__, __LINE__); return rc; } rc = ber_encode_PrivateKeyInfo( TRUE, NULL, data_len, NULL, ber_AlgIdRSAEncryptionLen, NULL, len ); if (rc != CKR_OK){ st_err_log(82, __FILE__, __LINE__); return rc; } return rc; } buf = (CK_BYTE *)malloc(offset); if (!buf){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } offset = 0; rc = 0; rc = ber_encode_INTEGER( FALSE, &buf2, &len, version, sizeof(version) ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, buf2, len ); offset += len; free( buf2 ); rc = ber_encode_INTEGER( FALSE, &buf2, &len, (CK_BYTE *)modulus + sizeof(CK_ATTRIBUTE), modulus->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, buf2, len ); offset += len; free( buf2 ); rc = ber_encode_INTEGER( FALSE, &buf2, &len, (CK_BYTE *)publ_exp + sizeof(CK_ATTRIBUTE), publ_exp->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, buf2, len ); offset += len; free( buf2 ); // the CKA_IBM_OPAQUE attrib rc = ber_encode_OCTET_STRING( FALSE, &buf2, &len, (CK_BYTE *)opaque + sizeof(CK_ATTRIBUTE), opaque->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, buf2, len ); offset += len; free( buf2 ); #if 0 rc = ber_encode_INTEGER( FALSE, &buf2, &len, (CK_BYTE *)priv_exp + sizeof(CK_ATTRIBUTE), priv_exp->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, buf2, len ); offset += len; free( buf2 ); rc = ber_encode_INTEGER( FALSE, &buf2, &len, (CK_BYTE *)prime1 + sizeof(CK_ATTRIBUTE), prime1->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, buf2, len ); offset += len; free( buf2 ); rc = ber_encode_INTEGER( FALSE, &buf2, &len, (CK_BYTE *)prime2 + sizeof(CK_ATTRIBUTE), prime2->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, buf2, len ); offset += len; free( buf2 ); rc = ber_encode_INTEGER( FALSE, &buf2, &len, (CK_BYTE *)exponent1 + sizeof(CK_ATTRIBUTE), exponent1->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, buf2, len ); offset += len; free( buf2 ); rc = ber_encode_INTEGER( FALSE, &buf2, &len, (CK_BYTE *)exponent2 + sizeof(CK_ATTRIBUTE), exponent2->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, buf2, len ); offset += len; free( buf2 ); rc = ber_encode_INTEGER( FALSE, &buf2, &len, (CK_BYTE *)coeff + sizeof(CK_ATTRIBUTE), coeff->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, buf2, len ); offset += len; free( buf2 ); #endif rc = ber_encode_SEQUENCE( FALSE, &buf2, &len, buf, offset ); if (rc != CKR_OK){ st_err_log(78, __FILE__, __LINE__); goto error; } rc = ber_encode_PrivateKeyInfo( FALSE, data, data_len, ber_AlgIdRSAEncryption, ber_AlgIdRSAEncryptionLen, buf2, len ); if (rc != CKR_OK) { st_err_log(82, __FILE__, __LINE__); } error: if (buf2) free( buf2 ); if (buf) free( buf ); return rc; } // // CK_RV ber_decode_RSAPrivateKey( CK_BYTE * data, CK_ULONG data_len, CK_ATTRIBUTE ** modulus, CK_ATTRIBUTE ** publ_exp, CK_ATTRIBUTE ** opaque) #if 0 CK_ATTRIBUTE ** priv_exp, CK_ATTRIBUTE ** prime1, CK_ATTRIBUTE ** prime2, CK_ATTRIBUTE ** exponent1, CK_ATTRIBUTE ** exponent2, CK_ATTRIBUTE ** coeff ) #endif { CK_ATTRIBUTE *n_attr = NULL; CK_ATTRIBUTE *e_attr = NULL; CK_ATTRIBUTE *o_attr = NULL; #if 0 CK_ATTRIBUTE *d_attr = NULL; CK_ATTRIBUTE *p_attr = NULL; CK_ATTRIBUTE *q_attr = NULL; CK_ATTRIBUTE *e1_attr = NULL; CK_ATTRIBUTE *e2_attr = NULL; CK_ATTRIBUTE *coeff_attr = NULL; #endif CK_BYTE *alg = NULL; CK_BYTE *rsa_priv_key = NULL; CK_BYTE *buf = NULL; CK_BYTE *tmp = NULL; CK_ULONG offset, buf_len, field_len, len; CK_RV rc; rc = ber_decode_PrivateKeyInfo( data, data_len, &alg, &len, &rsa_priv_key ); if (rc != CKR_OK){ st_err_log(83, __FILE__, __LINE__); return rc; } // make sure we're dealing with an RSA key // if (memcmp(alg, ber_rsaEncryption, ber_rsaEncryptionLen) != 0){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // probably ought to use a different error } rc = ber_decode_SEQUENCE( rsa_priv_key, &buf, &buf_len, &field_len ); if (rc != CKR_OK) return rc; // parse the RSAPrivateKey // offset = 0; // Version // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; // modulus // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; // public exponent // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; // opaque attribute, the CCA key // rc = ber_decode_OCTET_STRING( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; #if 0 // private exponent // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; // prime #1 // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; // prime #2 // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; // exponent #1 // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; // exponent #2 // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; // coefficient // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; if (offset > buf_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } #endif // // it looks okay. build the attributes // offset = 0; // skip the version // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; // modulus // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_MODULUS, tmp, len, &n_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += field_len; } // public exponent // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_PUBLIC_EXPONENT, tmp, len, &e_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += field_len; } // opaque attribute, the CCA key // rc = ber_decode_OCTET_STRING( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_IBM_OPAQUE, tmp, len, &o_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += field_len; } #if 0 // private exponent // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_PRIVATE_EXPONENT, tmp, len, &d_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += field_len; } // prime #1 // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_PRIME_1, tmp, len, &p_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += field_len; } // prime #2 // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_PRIME_2, tmp, len, &q_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += field_len; } // exponent #1 // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_EXPONENT_1, tmp, len, &e1_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += field_len; } // exponent #2 // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_EXPONENT_2, tmp, len, &e2_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += field_len; } // coefficient // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_COEFFICIENT, tmp, len, &coeff_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += len; } #endif *modulus = n_attr; *publ_exp = e_attr; *opaque = o_attr; #if 0 *priv_exp = d_attr; *prime1 = p_attr; *prime2 = q_attr; *exponent1 = e1_attr; *exponent2 = e2_attr; *coeff = coeff_attr; #endif return CKR_OK; cleanup: if (n_attr) free(n_attr); if (e_attr) free(e_attr); if (o_attr) free(o_attr); #if 0 if (d_attr) free(d_attr); if (p_attr) free(p_attr); if (q_attr) free(q_attr); if (e1_attr) free(e1_attr); if (e2_attr) free(e2_attr); if (coeff_attr) free(coeff_attr); #endif return rc; } // DSA is a little different from RSA // // DSAPrivateKey ::= INTEGER // // The 'parameters' field of the AlgorithmIdentifier are as follows: // // DSSParameters ::= SEQUENCE { // prime1 INTEGER // prime2 INTEGER // base INTEGER // } // CK_RV ber_encode_DSAPrivateKey( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len, CK_ATTRIBUTE * prime1, CK_ATTRIBUTE * prime2, CK_ATTRIBUTE * base, CK_ATTRIBUTE * priv_key ) { CK_BYTE *param = NULL; CK_BYTE *buf = NULL; CK_BYTE *tmp = NULL; CK_BYTE *alg = NULL; CK_ULONG offset, len, param_len; CK_ULONG alg_len; CK_RV rc; // build the DSS parameters first // offset = 0; rc = 0; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, prime1->ulValueLen ); offset += len; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, prime2->ulValueLen ); offset += len; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, base->ulValueLen ); offset += len; if (rc != CKR_OK){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { rc = ber_encode_SEQUENCE( TRUE, NULL, ¶m_len, NULL, offset ); if (rc != CKR_OK){ st_err_log(78, __FILE__, __LINE__); return rc; } rc = ber_encode_INTEGER( TRUE, NULL, &len, NULL, priv_key->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); return rc; } rc = ber_encode_PrivateKeyInfo( TRUE, NULL, data_len, NULL, ber_idDSALen + param_len, NULL, len ); if (rc != CKR_OK){ st_err_log(82, __FILE__, __LINE__); } return rc; } // 'buf' will be the sequence data for the AlgorithmIdentifyer::parameter // buf = (CK_BYTE *)malloc(offset); if (!buf){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } len = 0; offset = 0; rc = ber_encode_INTEGER( FALSE, &tmp, &len, (CK_BYTE *)prime1 + sizeof(CK_ATTRIBUTE), prime1->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, tmp, len ); offset += len; free( tmp ); tmp = NULL; rc = ber_encode_INTEGER( FALSE, &tmp, &len, (CK_BYTE *)prime2 + sizeof(CK_ATTRIBUTE), prime2->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, tmp, len ); offset += len; free( tmp ); tmp = NULL; rc = ber_encode_INTEGER( FALSE, &tmp, &len, (CK_BYTE *)base + sizeof(CK_ATTRIBUTE), base->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, tmp, len ); offset += len; free( tmp ); tmp = NULL; rc = ber_encode_SEQUENCE( FALSE, ¶m, ¶m_len, buf, offset ); if (rc != CKR_OK) { st_err_log(78, __FILE__, __LINE__); free(buf); return rc; } free( buf ); buf = NULL; // Build the DSA AlgorithmIdentifier // // AlgorithmIdentifier ::= SEQUENCE { // algorithm OBJECT IDENTIFIER // parameters ANY DEFINED BY algorithm OPTIONAL // } // len = ber_idDSALen + param_len; buf = (CK_BYTE *)malloc( len ); if (!buf){ st_err_log(1, __FILE__, __LINE__); goto error; } memcpy( buf, ber_idDSA, ber_idDSALen ); memcpy( buf + ber_idDSALen, param, param_len ); free( param ); param = NULL; rc = ber_encode_SEQUENCE( FALSE, &alg, &alg_len, buf, len ); if (rc != CKR_OK){ st_err_log(78, __FILE__, __LINE__); goto error; } free( buf ); buf = NULL; // build the private key INTEGER // rc = ber_encode_INTEGER( FALSE, &buf, &len, (CK_BYTE *)priv_key + sizeof(CK_ATTRIBUTE), priv_key->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } rc = ber_encode_PrivateKeyInfo( FALSE, data, data_len, alg, alg_len, buf, len ); if (rc != CKR_OK){ st_err_log(82, __FILE__, __LINE__); goto error; } error: if (alg) free( alg ); if (buf) free( buf ); if (param) free( param ); if (tmp) free( tmp ); return rc; } // // CK_RV ber_decode_DSAPrivateKey( CK_BYTE * data, CK_ULONG data_len, CK_ATTRIBUTE ** prime, CK_ATTRIBUTE ** subprime, CK_ATTRIBUTE ** base, CK_ATTRIBUTE ** priv_key ) { CK_ATTRIBUTE *p_attr = NULL; CK_ATTRIBUTE *q_attr = NULL; CK_ATTRIBUTE *g_attr = NULL; CK_ATTRIBUTE *x_attr = NULL; CK_BYTE *alg = NULL; CK_BYTE *buf = NULL; CK_BYTE *dsakey = NULL; CK_BYTE *tmp = NULL; CK_ULONG buf_len, field_len, len, offset; CK_RV rc; rc = ber_decode_PrivateKeyInfo( data, data_len, &alg, &len, &dsakey ); if (rc != CKR_OK){ st_err_log(82, __FILE__, __LINE__); return rc; } // make sure we're dealing with a DSA key. just compare the OBJECT // IDENTIFIER // if (memcmp(alg, ber_idDSA, ber_idDSALen) != 0){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // extract the parameter data into ATTRIBUTES // rc = ber_decode_SEQUENCE( alg + ber_idDSALen, &buf, &buf_len, &field_len ); if (rc != CKR_OK){ st_err_log(81, __FILE__, __LINE__); return rc; } offset = 0; // prime // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; // subprime // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; // base // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; if (offset > buf_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // it looks okay. build the attributes // offset = 0; // prime // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_PRIME, tmp, len, &p_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += field_len; } // subprime // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_SUBPRIME, tmp, len, &q_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += field_len; } // base // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_BASE, tmp, len, &g_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += field_len; } // now get the private key // rc = ber_decode_INTEGER( dsakey, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_VALUE, tmp, len, &x_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += field_len; } *prime = p_attr; *subprime = q_attr; *base = g_attr; *priv_key = x_attr; return CKR_OK; cleanup: if (p_attr) free(p_attr); if (q_attr) free(q_attr); if (g_attr) free(g_attr); if (x_attr) free(x_attr); return rc; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/LICENSE0000640000175000017500000002653511327631345020374 0ustar jfjfCommon Public License Version 1.0 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, if Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/verify_mgr.c0000640000175000017500000004644711327631345021710 0ustar jfjf/* * Licensed materials, Property of IBM Corp. * * openCryptoki CCA token * * (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2006 * */ // File: verify_mgr.c // // Verify manager routines // #include #include // for memcmp() et al #include #include "cca_stdll.h" #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // // CK_RV verify_mgr_init( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_MECHANISM * mech, CK_BBOOL recover_mode, CK_OBJECT_HANDLE key ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_KEY_TYPE keytype; CK_OBJECT_CLASS class; CK_BBOOL flag; CK_RV rc; if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active != FALSE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } // key usage restrictions // rc = object_mgr_find_in_map1( key, &key_obj ); if (rc != CKR_OK){ st_err_log(18, __FILE__, __LINE__); return CKR_KEY_HANDLE_INVALID; } // is key allowed to verify signatures? // rc = template_attribute_find( key_obj->template, CKA_VERIFY, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { flag = *(CK_BBOOL *)attr->pValue; if (flag != TRUE){ st_err_log(85, __FILE__, __LINE__); return CKR_KEY_FUNCTION_NOT_PERMITTED; } } // is the mechanism supported? is the key type correct? is a // parameter present if required? is the key size allowed? // is the key allowed to generate signatures? // switch (mech->mechanism) { case CKM_RSA_X_509: case CKM_RSA_PKCS: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_RSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // must be a PUBLIC key operation // flag = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else class = *(CK_OBJECT_CLASS *)attr->pValue; if (class != CKO_PUBLIC_KEY){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // PKCS #11 doesn't allow multi-part RSA operations // ctx->context_len = 0; ctx->context = NULL; } break; case CKM_MD2_RSA_PKCS: case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_RSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // must be a PUBLIC key operation // flag = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else class = *(CK_OBJECT_CLASS *)attr->pValue; if (class != CKO_PUBLIC_KEY){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } ctx->context_len = sizeof(RSA_DIGEST_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(RSA_DIGEST_CONTEXT)); if (!ctx->context){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(RSA_DIGEST_CONTEXT)); } break; #if !(NODSA) case CKM_DSA: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // must be a PUBLIC key operation // flag = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else class = *(CK_OBJECT_CLASS *)attr->pValue; if (class != CKO_PUBLIC_KEY){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // PKCS #11 doesn't allow multi-part DSA operations // ctx->context_len = 0; ctx->context = NULL; } break; #endif case CKM_MD2_HMAC: case CKM_MD5_HMAC: case CKM_SHA_1_HMAC: case CKM_SHA256_HMAC: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_GENERIC_SECRET){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // PKCS #11 doesn't allow multi-part HMAC operations // ctx->context_len = 0; ctx->context = NULL; } break; case CKM_MD2_HMAC_GENERAL: case CKM_MD5_HMAC_GENERAL: case CKM_SHA_1_HMAC_GENERAL: case CKM_SHA256_HMAC_GENERAL: { CK_MAC_GENERAL_PARAMS *param = (CK_MAC_GENERAL_PARAMS *)mech->pParameter; if (mech->ulParameterLen != sizeof(CK_MAC_GENERAL_PARAMS)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } if ((mech->mechanism == CKM_MD2_HMAC_GENERAL) && (*param > 16)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } if ((mech->mechanism == CKM_MD5_HMAC_GENERAL) && (*param > 16)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } if ((mech->mechanism == CKM_SHA_1_HMAC_GENERAL) && (*param > 20)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } if ((mech->mechanism == CKM_SHA256_HMAC_GENERAL) && (*param > 32)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_GENERIC_SECRET){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // PKCS #11 doesn't allow multi-part HMAC operations // ctx->context_len = 0; ctx->context = NULL; } break; case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: { CK_MAC_GENERAL_PARAMS *param = (CK_MAC_GENERAL_PARAMS *)mech->pParameter; if (mech->ulParameterLen != sizeof(CK_MAC_GENERAL_PARAMS)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // Netscape sets the parameter == 16. PKCS #11 limit is 8 // if (mech->mechanism == CKM_SSL3_MD5_MAC) { if (*param < 4 || *param > 16){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } } if (mech->mechanism == CKM_SSL3_SHA1_MAC) { if (*param < 4 || *param > 20){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } } rc = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { class = *(CK_OBJECT_CLASS *)attr->pValue; if (class != CKO_SECRET_KEY){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(SSL3_MAC_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(SSL3_MAC_CONTEXT)); if (!ctx->context){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(SSL3_MAC_CONTEXT)); } break; default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } if (mech->ulParameterLen > 0) { ptr = (CK_BYTE *)malloc(mech->ulParameterLen); if (!ptr){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( ptr, mech->pParameter, mech->ulParameterLen ); } ctx->key = key; ctx->mech.ulParameterLen = mech->ulParameterLen; ctx->mech.mechanism = mech->mechanism; ctx->mech.pParameter = ptr; ctx->multi = FALSE; ctx->active = TRUE; ctx->recover = recover_mode; return CKR_OK; } // // CK_RV verify_mgr_cleanup( SIGN_VERIFY_CONTEXT *ctx ) { if (!ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } ctx->key = 0; ctx->mech.ulParameterLen = 0; ctx->mech.mechanism = 0; ctx->multi = FALSE; ctx->active = FALSE; ctx->recover = FALSE; ctx->context_len = 0; if (ctx->mech.pParameter) { free( ctx->mech.pParameter ); ctx->mech.pParameter = NULL; } if (ctx->context) { free( ctx->context ); ctx->context = NULL; } return CKR_OK; } // // CK_RV verify_mgr_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == TRUE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } // if the caller just wants the signature length, there is no reason to // specify the input data. I just need the input data length // if (!in_data || !signature){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->multi == TRUE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } switch (ctx->mech.mechanism) { case CKM_RSA_PKCS: return rsa_pkcs_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); #if 0 case CKM_RSA_X_509: return rsa_x509_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); #endif case CKM_MD2_RSA_PKCS: case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: return rsa_hash_pkcs_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); #if !(NODSA) case CKM_DSA: return dsa_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); #endif #if !(NOMD2) case CKM_MD2_HMAC: case CKM_MD2_HMAC_GENERAL: return md2_hmac_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); #endif case CKM_MD5_HMAC: case CKM_MD5_HMAC_GENERAL: return md5_hmac_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); case CKM_SHA_1_HMAC: case CKM_SHA_1_HMAC_GENERAL: return sha1_hmac_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); case CKM_SHA256_HMAC: case CKM_SHA256_HMAC_GENERAL: return sha2_hmac_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: return ssl3_mac_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV verify_mgr_verify_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { if (!sess || !ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == TRUE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } ctx->multi = TRUE; switch (ctx->mech.mechanism) { case CKM_MD2_RSA_PKCS: case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: return rsa_hash_pkcs_verify_update( sess, ctx, in_data, in_data_len ); case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: return ssl3_mac_verify_update( sess, ctx, in_data, in_data_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // // CK_RV verify_mgr_verify_final( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == TRUE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } switch (ctx->mech.mechanism) { case CKM_MD2_RSA_PKCS: case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: return rsa_hash_pkcs_verify_final( sess, ctx, signature, sig_len ); case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: return ssl3_mac_verify_final( sess, ctx, signature, sig_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // // CK_RV verify_mgr_verify_recover( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len, CK_BYTE * out_data, CK_ULONG * out_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } // if the caller just wants the signature length, there is no reason to // specify the input data. I just need the input data length // if (!signature || !out_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->multi == TRUE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } switch (ctx->mech.mechanism) { case CKM_RSA_PKCS: return rsa_pkcs_verify_recover( sess, length_only, ctx, signature, sig_len, out_data, out_len ); #if 0 case CKM_RSA_X_509: return rsa_x509_verify_recover( sess, length_only, ctx, signature, sig_len, out_data, out_len ); #endif default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/key_mgr.c0000640000175000017500000013237611327631345021171 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ /*************************************************************************** Change Log ========== 4/25/03 Kapil Sood (kapil@corrent.com) Added DH key pair generation and DH shared key derivation functions. ****************************************************************************/ // File: key_mgr.c // #include #include #include // for memcmp() et al #include "pkcs11types.h" #include "defs.h" #include "cca_stdll.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" static CK_BBOOL true = TRUE, false = FALSE; // // CK_RV key_mgr_generate_key( SESSION * sess, CK_MECHANISM * mech, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE * handle ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_ATTRIBUTE * new_attr = NULL; CK_ULONG i, keyclass, subclass = 0; CK_BBOOL flag; CK_RV rc; if (!sess || !mech || !handle){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!pTemplate && (ulCount != 0)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // it's silly but Cryptoki allows the user to specify the CKA_CLASS // in the template. so we have to iterate through the provided template // and make sure that if CKA_CLASS is CKO_SECRET_KEY, if it is present. // // it would have been more logical for Cryptoki to forbid specifying // the CKA_CLASS attribute when generating a key // for (i=0; i < ulCount; i++) { if (pTemplate[i].type == CKA_CLASS) { keyclass = *(CK_OBJECT_CLASS *)pTemplate[i].pValue; if (keyclass != CKO_SECRET_KEY){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } if (pTemplate[i].type == CKA_KEY_TYPE) subclass = *(CK_ULONG *)pTemplate[i].pValue; } switch (mech->mechanism) { case CKM_DES_KEY_GEN: if (subclass != 0 && subclass != CKK_DES){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_DES; break; case CKM_DES3_KEY_GEN: if (subclass != 0 && subclass != CKK_DES3){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_DES3; break; #if !(NOCDMF) case CKM_CDMF_KEY_GEN: if (subclass != 0 && subclass != CKK_CDMF){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_CDMF; break; #endif case CKM_SSL3_PRE_MASTER_KEY_GEN: if (subclass != 0 && subclass != CKK_GENERIC_SECRET){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } if (mech->ulParameterLen != sizeof(CK_VERSION)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } subclass = CKK_GENERIC_SECRET; break; case CKM_AES_KEY_GEN: if (subclass != 0 && subclass != CKK_AES){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_AES; break; default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } rc = object_mgr_create_skel( sess, pTemplate, ulCount, MODE_KEYGEN, CKO_SECRET_KEY, subclass, &key_obj ); if (rc != CKR_OK){ st_err_log(89, __FILE__, __LINE__); goto error; } // at this point, 'key_obj' should contain a skeleton key. depending on // the key type, we may need to extract one or more attributes from // the object prior to generating the key data (ie. variable key length) // switch (mech->mechanism) { case CKM_DES_KEY_GEN: rc = ckm_des_key_gen( key_obj->template ); break; case CKM_DES3_KEY_GEN: rc = ckm_des3_key_gen( key_obj->template ); break; #if !(NOCDMF) case CKM_CDMF_KEY_GEN: rc = ckm_cdmf_key_gen( key_obj->template ); break; #endif case CKM_SSL3_PRE_MASTER_KEY_GEN: rc = ckm_ssl3_pre_master_key_gen( key_obj->template, mech ); break; #ifndef NOAES case CKM_AES_KEY_GEN: rc = ckm_aes_key_gen( key_obj->template ); break; #endif default: st_err_log(28, __FILE__, __LINE__); rc = CKR_MECHANISM_INVALID; } if (rc != CKR_OK){ st_err_log(91, __FILE__, __LINE__); goto error; } // we can now set CKA_ALWAYS_SENSITIVE and CKA_NEVER_EXTRACTABLE // to their appropriate values. this only applies to CKO_SECRET_KEY // and CKO_PRIVATE_KEY objects // flag = template_attribute_find( key_obj->template, CKA_SENSITIVE, &attr ); if (flag == TRUE) { flag = *(CK_BBOOL *)attr->pValue; rc = build_attribute( CKA_ALWAYS_SENSITIVE, &flag, sizeof(CK_BBOOL), &new_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } template_update_attribute( key_obj->template, new_attr ); } else { rc = CKR_FUNCTION_FAILED; st_err_log(4, __FILE__, __LINE__, __FUNCTION__); goto error; } flag = template_attribute_find( key_obj->template, CKA_EXTRACTABLE, &attr ); if (flag == TRUE) { flag = *(CK_BBOOL *)attr->pValue; rc = build_attribute( CKA_NEVER_EXTRACTABLE, &true, sizeof(CK_BBOOL), &new_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } if (flag == TRUE) *(CK_BBOOL *)new_attr->pValue = FALSE; template_update_attribute( key_obj->template, new_attr ); } else { rc = CKR_FUNCTION_FAILED; st_err_log(4, __FILE__, __LINE__, __FUNCTION__); goto error; } // at this point, the key should be fully constructed...assign // an object handle and store the key // rc = object_mgr_create_final( sess, key_obj, handle ); if (rc != CKR_OK){ st_err_log(90, __FILE__, __LINE__); goto error; } return rc; error: if (key_obj) object_free( key_obj ); *handle = 0; return rc; } // // CK_RV key_mgr_generate_key_pair( SESSION * sess, CK_MECHANISM * mech, CK_ATTRIBUTE * publ_tmpl, CK_ULONG publ_count, CK_ATTRIBUTE * priv_tmpl, CK_ULONG priv_count, CK_OBJECT_HANDLE * publ_key_handle, CK_OBJECT_HANDLE * priv_key_handle ) { OBJECT * publ_key_obj = NULL; OBJECT * priv_key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_ATTRIBUTE * new_attr = NULL; CK_ULONG i, keyclass, subclass = 0; CK_BBOOL flag; CK_RV rc; if (!sess || !mech || !publ_key_handle || !priv_key_handle){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!publ_tmpl && (publ_count != 0)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!priv_tmpl && (priv_count != 0)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // it's silly but Cryptoki allows the user to specify the CKA_CLASS // in the template. so we have to iterate through the provided template // and make sure that if CKA_CLASS is valid, if it is present. // // it would have been more logical for Cryptoki to forbid specifying // the CKA_CLASS attribute when generating a key // for (i=0; i < publ_count; i++) { if (publ_tmpl[i].type == CKA_CLASS) { keyclass = *(CK_OBJECT_CLASS *)publ_tmpl[i].pValue; if (keyclass != CKO_PUBLIC_KEY){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } if (publ_tmpl[i].type == CKA_KEY_TYPE) subclass = *(CK_ULONG *)publ_tmpl[i].pValue; } for (i=0; i < priv_count; i++) { if (priv_tmpl[i].type == CKA_CLASS) { keyclass = *(CK_OBJECT_CLASS *)priv_tmpl[i].pValue; if (keyclass != CKO_PRIVATE_KEY){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } if (priv_tmpl[i].type == CKA_KEY_TYPE) { CK_ULONG temp = *(CK_ULONG *)priv_tmpl[i].pValue; if (temp != subclass){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } } switch (mech->mechanism) { case CKM_RSA_PKCS_KEY_PAIR_GEN: if (subclass != 0 && subclass != CKK_RSA){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_RSA; break; #if !(NODSA) case CKM_DSA_KEY_PAIR_GEN: if (subclass != 0 && subclass != CKK_DSA){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_DSA; break; #endif /* Begin code contributed by Corrent corp. */ #if !(NODH) case CKM_DH_PKCS_KEY_PAIR_GEN: if (subclass != 0 && subclass != CKK_DH){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_DH; break; #endif /* End code contributed by Corrent corp. */ default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } rc = object_mgr_create_skel( sess, publ_tmpl, publ_count, MODE_KEYGEN, CKO_PUBLIC_KEY, subclass, &publ_key_obj ); if (rc != CKR_OK){ st_err_log(89, __FILE__, __LINE__); goto error; } rc = object_mgr_create_skel( sess, priv_tmpl, priv_count, MODE_KEYGEN, CKO_PRIVATE_KEY, subclass, &priv_key_obj ); if (rc != CKR_OK){ st_err_log(89, __FILE__, __LINE__); goto error; } // at this point, 'key_obj' should contain a skeleton key. depending on // the key type, we may need to extract one or more attributes from // the object prior to generating the key data (ie. variable key length) // switch (mech->mechanism) { case CKM_RSA_PKCS_KEY_PAIR_GEN: rc = ckm_rsa_key_pair_gen( publ_key_obj->template, priv_key_obj->template ); break; #if !(NODSA) case CKM_DSA_KEY_PAIR_GEN: rc = ckm_dsa_key_pair_gen( publ_key_obj->template, priv_key_obj->template ); break; #endif /* Begin code contributed by Corrent corp. */ #if !(NODH) case CKM_DH_PKCS_KEY_PAIR_GEN: rc = ckm_dh_pkcs_key_pair_gen( publ_key_obj->template, priv_key_obj->template ); break; #endif /* End code contributed by Corrent corp. */ default: st_err_log(28, __FILE__, __LINE__); rc = CKR_MECHANISM_INVALID; break; } if (rc != CKR_OK){ st_err_log(91, __FILE__, __LINE__); goto error; } // we can now set CKA_ALWAYS_SENSITIVE and CKA_NEVER_EXTRACTABLE // to their appropriate values. this only applies to CKO_SECRET_KEY // and CKO_PRIVATE_KEY objects // flag = template_attribute_find( priv_key_obj->template, CKA_SENSITIVE, &attr ); if (flag == TRUE) { flag = *(CK_BBOOL *)attr->pValue; rc = build_attribute( CKA_ALWAYS_SENSITIVE, &flag, sizeof(CK_BBOOL), &new_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } template_update_attribute( priv_key_obj->template, new_attr ); } else { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } flag = template_attribute_find( priv_key_obj->template, CKA_EXTRACTABLE, &attr ); if (flag == TRUE) { flag = *(CK_BBOOL *)attr->pValue; rc = build_attribute( CKA_NEVER_EXTRACTABLE, &true, sizeof(CK_BBOOL), &new_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } if (flag == TRUE) *(CK_BBOOL *)new_attr->pValue = false; template_update_attribute( priv_key_obj->template, new_attr ); } else { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } // at this point, the keys should be fully constructed...assign // object handles and store the keys // rc = object_mgr_create_final( sess, publ_key_obj, publ_key_handle ); if (rc != CKR_OK){ st_err_log(90, __FILE__, __LINE__); goto error; } rc = object_mgr_create_final( sess, priv_key_obj, priv_key_handle ); if (rc != CKR_OK){ st_err_log(90, __FILE__, __LINE__); goto error; } return rc; error: if (publ_key_obj) object_free( publ_key_obj ); if (priv_key_obj) object_free( priv_key_obj ); *publ_key_handle = 0; *priv_key_handle = 0; return rc; } // // CK_RV key_mgr_wrap_key( SESSION * sess, CK_BBOOL length_only, CK_MECHANISM * mech, CK_OBJECT_HANDLE h_wrapping_key, CK_OBJECT_HANDLE h_key, CK_BYTE * wrapped_key, CK_ULONG * wrapped_key_len ) { ENCR_DECR_CONTEXT * ctx = NULL; OBJECT * key1_obj = NULL; OBJECT * key2_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * data = NULL; CK_ULONG data_len; CK_OBJECT_CLASS class; CK_KEY_TYPE keytype; CK_BBOOL flag; CK_RV rc; if (!sess || !wrapped_key_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( h_wrapping_key, &key1_obj ); if (rc != CKR_OK){ st_err_log(62, __FILE__, __LINE__); return CKR_WRAPPING_KEY_HANDLE_INVALID; } rc = object_mgr_find_in_map1( h_key, &key2_obj ); if (rc != CKR_OK){ st_err_log(18, __FILE__, __LINE__); return CKR_KEY_HANDLE_INVALID; } // is the key-to-be-wrapped EXTRACTABLE? // rc = template_attribute_find( key2_obj->template, CKA_EXTRACTABLE, &attr ); if (rc == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; // could happen if user tries to wrap a public key } else { flag = *(CK_BBOOL *)attr->pValue; if (flag == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } } // what kind of key are we trying to wrap? make sure the mechanism is // allowed to wrap this kind of key // rc = template_attribute_find( key2_obj->template, CKA_CLASS, &attr ); if (rc == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } else class = *(CK_OBJECT_CLASS *)attr->pValue; switch (mech->mechanism) { #if !(NOCDMF) case CKM_CDMF_ECB: case CKM_CDMF_CBC: #endif case CKM_DES_ECB: case CKM_DES_CBC: case CKM_DES3_ECB: case CKM_DES3_CBC: case CKM_AES_ECB: case CKM_AES_CBC: if (class != CKO_SECRET_KEY){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } break; #if !(NOCDMF) case CKM_CDMF_CBC_PAD: #endif case CKM_DES_CBC_PAD: case CKM_DES3_CBC_PAD: case CKM_AES_CBC_PAD: // these mechanisms can wrap any type of key // break; case CKM_RSA_PKCS: case CKM_RSA_X_509: if (class != CKO_SECRET_KEY){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } break; default: st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } // extract the secret data to be wrapped // rc = template_attribute_find( key2_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } else keytype = *(CK_KEY_TYPE *)attr->pValue; switch (keytype) { #if 0 #if !(NOCDMF) case CKK_CDMF: #endif case CKK_DES: rc = des_wrap_get_data( key2_obj->template, length_only, &data, &data_len ); if (rc != CKR_OK){ st_err_log(92, __FILE__, __LINE__); return rc; } break; case CKK_DES3: rc = des3_wrap_get_data( key2_obj->template, length_only, &data, &data_len ); if (rc != CKR_OK){ st_err_log(93, __FILE__, __LINE__); return rc; } break; #endif case CKK_RSA: rc = rsa_priv_wrap_get_data( key2_obj->template, length_only, &data, &data_len ); if (rc != CKR_OK){ st_err_log(94, __FILE__, __LINE__); return rc; } break; #if !(NODSA) case CKK_DSA: rc = dsa_priv_wrap_get_data( key2_obj->template, length_only, &data, &data_len ); if (rc != CKR_OK){ st_err_log(95, __FILE__, __LINE__); return rc; } break; #endif case CKK_DES: case CKK_DES3: case CKK_GENERIC_SECRET: rc = generic_secret_wrap_get_data( key2_obj->template, length_only, &data, &data_len ); if (rc != CKR_OK){ st_err_log(96, __FILE__, __LINE__); return rc; } break; #ifndef NOAES case CKK_AES: rc = aes_wrap_get_data( key2_obj->template, length_only, &data, &data_len ); if (rc != CKR_OK){ st_err_log(191, __FILE__, __LINE__); return rc; } break; #endif default: st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } // we might need to format the wrapped data based on the mechanism // switch (mech->mechanism) { #if !(NOCMF) case CKM_CDMF_ECB: case CKM_CDMF_CBC: #endif case CKM_DES_ECB: case CKM_DES_CBC: case CKM_DES3_ECB: case CKM_DES3_CBC: rc = ckm_des_wrap_format( length_only, &data, &data_len ); if (rc != CKR_OK) { st_err_log(97, __FILE__, __LINE__); if (data) free( data ); return rc; } break; #ifndef NOAES case CKM_AES_ECB: case CKM_AES_CBC: rc = ckm_aes_wrap_format( length_only, &data, &data_len ); if (rc != CKR_OK) { st_err_log(192, __FILE__, __LINE__); if (data) free( data ); return rc; } break; #endif #if !(NOCMF) case CKM_CDMF_CBC_PAD: #endif case CKM_DES_CBC_PAD: case CKM_DES3_CBC_PAD: case CKM_AES_CBC_PAD: // these mechanisms pad themselves // break; case CKM_RSA_PKCS: case CKM_RSA_X_509: // rc = ckm_rsa_wrap_format( length_only, &data, &data_len ); // if (rc != CKR_OK) { // free( data ); // return rc; // } break; default: st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } ctx = (ENCR_DECR_CONTEXT *)malloc(sizeof(ENCR_DECR_CONTEXT)); if (!ctx){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx, 0x0, sizeof(ENCR_DECR_CONTEXT) ); // prepare to do the encryption // rc = encr_mgr_init( sess, ctx, OP_WRAP, mech, h_wrapping_key ); if (rc != CKR_OK){ st_err_log(98, __FILE__, __LINE__); return rc; } // do the encryption and clean up. at this point, 'value' may or may not // be NULL depending on 'length_only' // rc = encr_mgr_encrypt( sess, length_only, ctx, data, data_len, wrapped_key, wrapped_key_len ); if (data != NULL){ free( data ); } encr_mgr_cleanup( ctx ); free( ctx ); return rc; } // // CK_RV key_mgr_unwrap_key( SESSION * sess, CK_MECHANISM * mech, CK_ATTRIBUTE * attributes, CK_ULONG attrib_count, CK_BYTE * wrapped_key, CK_ULONG wrapped_key_len, CK_OBJECT_HANDLE h_unwrapping_key, CK_OBJECT_HANDLE * h_unwrapped_key ) { ENCR_DECR_CONTEXT * ctx = NULL; OBJECT * key_obj = NULL; CK_BYTE * data = NULL; CK_ULONG data_len; CK_ULONG keyclass, keytype; CK_ULONG i; CK_BBOOL found_class, found_type, fromend; CK_RV rc; if (!sess || !wrapped_key || !h_unwrapped_key){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( h_unwrapping_key, &key_obj ); if (rc != CKR_OK){ st_err_log(62, __FILE__, __LINE__); return CKR_WRAPPING_KEY_HANDLE_INVALID; } found_class = FALSE; found_type = FALSE; // some mechanisms are restricted to wrapping certain types of keys. // in these cases, the CKA_CLASS attribute is implied and isn't required // to be specified in the template (though it still may appear) // switch (mech->mechanism) { case CKM_RSA_PKCS: case CKM_RSA_X_509: keyclass = CKO_SECRET_KEY; found_class = TRUE; break; #if !(NOCMF) case CKM_CDMF_ECB: case CKM_CDMF_CBC: #endif case CKM_DES_ECB: case CKM_DES_CBC: case CKM_DES3_ECB: case CKM_DES3_CBC: case CKM_AES_ECB: case CKM_AES_CBC: keyclass = CKO_SECRET_KEY; found_class = TRUE; break; #if !(NOCMF) case CKM_CDMF_CBC_PAD: #endif case CKM_DES_CBC_PAD: case CKM_DES3_CBC_PAD: case CKM_AES_CBC_PAD: // these mechanisms can wrap any type of key so nothing is implied // break; } // extract key type and key class from the template if they exist. we // have to scan the entire template in case the CKA_CLASS or CKA_KEY_TYPE // attributes are duplicated // for (i=0; i < attrib_count; i++) { switch (attributes[i].type) { case CKA_CLASS: keyclass = *(CK_OBJECT_CLASS *)attributes[i].pValue; found_class = TRUE; break; case CKA_KEY_TYPE: keytype = *(CK_KEY_TYPE *)attributes[i].pValue; found_type = TRUE; break; } } // if we're unwrapping a private key, we can extract the key type from // the BER-encoded information // if (found_class == FALSE || (found_type == FALSE && keyclass != CKO_PRIVATE_KEY)){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } // final check to see if mechanism is allowed to unwrap such a key // switch (mech->mechanism) { case CKM_RSA_PKCS: case CKM_RSA_X_509: if (keyclass != CKO_SECRET_KEY){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } break; #if !(NOCMF) case CKM_CDMF_ECB: case CKM_CDMF_CBC: #endif case CKM_DES_ECB: case CKM_DES_CBC: case CKM_DES3_ECB: case CKM_DES3_CBC: case CKM_AES_ECB: case CKM_AES_CBC: if (keyclass != CKO_SECRET_KEY){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } break; #if !(NOCMF) case CKM_CDMF_CBC_PAD: #endif case CKM_DES_CBC_PAD: case CKM_DES3_CBC_PAD: case CKM_AES_CBC_PAD: break; default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // looks okay...do the decryption // ctx = (ENCR_DECR_CONTEXT *)malloc(sizeof(ENCR_DECR_CONTEXT)); if (!ctx){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx, 0x0, sizeof(ENCR_DECR_CONTEXT) ); rc = decr_mgr_init( sess, ctx, OP_UNWRAP, mech, h_unwrapping_key ); if (rc != CKR_OK) return rc; rc = decr_mgr_decrypt( sess, TRUE, ctx, wrapped_key, wrapped_key_len, data, &data_len ); if (rc != CKR_OK){ st_err_log(100, __FILE__, __LINE__); goto error; } data = (CK_BYTE *)malloc(data_len); if (!data) { st_err_log(0, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto error; } rc = decr_mgr_decrypt( sess, FALSE, ctx, wrapped_key, wrapped_key_len, data, &data_len ); decr_mgr_cleanup( ctx ); free( ctx ); if (rc != CKR_OK){ st_err_log(100, __FILE__, __LINE__); goto error; } // if we use X.509, the data will be padded from the front with zeros. // PKCS #11 specifies that for this mechanism, CK_VALUE is to be read // from the end of the data. // // Note: the PKCS #11 reference implementation gets this wrong. // if (mech->mechanism == CKM_RSA_X_509) fromend = TRUE; else fromend = FALSE; // extract the key type from the PrivateKeyInfo::AlgorithmIndicator // if (keyclass == CKO_PRIVATE_KEY) { rc = key_mgr_get_private_key_type( data, data_len, &keytype ); if (rc != CKR_OK){ st_err_log(101, __FILE__, __LINE__); goto error; } } // we have decrypted the wrapped key data. we also // know what type of key it is. now we need to construct a new key // object... // rc = object_mgr_create_skel( sess, attributes, attrib_count, MODE_UNWRAP, keyclass, keytype, &key_obj ); if (rc != CKR_OK){ st_err_log(89, __FILE__, __LINE__); goto error; } // at this point, 'key_obj' should contain a skeleton key. depending on // the key type. we're now ready to plug in the decrypted key data. // in some cases, the data will be BER-encoded so we'll need to decode it. // // this routine also ensires that CKA_EXTRACTABLE == FALSE, // CKA_ALWAYS_SENSITIVE == FALSE and CKA_LOCAL == FALSE // switch (keyclass) { case CKO_SECRET_KEY: rc = secret_key_unwrap( key_obj->template, keytype, data, data_len, fromend ); break; case CKO_PRIVATE_KEY: rc = priv_key_unwrap( key_obj->template, keytype, data, data_len ); break; default: rc = CKR_WRAPPED_KEY_INVALID; break; } if (rc != CKR_OK){ st_err_log(173, __FILE__, __LINE__); goto error; } // at this point, the key should be fully constructed...assign // an object handle and store the key // rc = object_mgr_create_final( sess, key_obj, h_unwrapped_key ); if (rc != CKR_OK){ st_err_log(90, __FILE__, __LINE__); goto error; } if (data) free(data); return rc; error: if (key_obj) object_free( key_obj ); if (data) free(data); return rc; } CK_RV key_mgr_get_private_key_type( CK_BYTE *keydata, CK_ULONG keylen, CK_KEY_TYPE *keytype ) { CK_BYTE *alg = NULL; CK_BYTE *priv_key = NULL; CK_ULONG alg_len; CK_RV rc; rc = ber_decode_PrivateKeyInfo( keydata, keylen, &alg, &alg_len, &priv_key ); if (rc != CKR_OK){ st_err_log(102, __FILE__, __LINE__); return rc; } // check the entire AlgorithmIdentifier for RSA // if (alg_len >= ber_rsaEncryptionLen) { if (memcmp(alg, ber_rsaEncryption, ber_rsaEncryptionLen) == 0) { *keytype = CKK_RSA; return CKR_OK; } } // Check only the OBJECT IDENTIFIER for DSA // if (alg_len >= ber_idDSALen) { if (memcmp(alg, ber_idDSA, ber_idDSALen) == 0) { *keytype = CKK_DSA; return CKR_OK; } } st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } // // CK_RV key_mgr_derive_key( SESSION * sess, CK_MECHANISM * mech, CK_OBJECT_HANDLE base_key, CK_OBJECT_HANDLE * derived_key, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ) { if (!sess || !mech){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!pTemplate && (ulCount != 0)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } switch (mech->mechanism) { case CKM_SSL3_MASTER_KEY_DERIVE: { if (!derived_key){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } return ssl3_master_key_derive( sess, mech, base_key, pTemplate, ulCount, derived_key ); } break ; case CKM_SSL3_KEY_AND_MAC_DERIVE: { CK_SSL3_KEY_MAT_PARAMS *params = (CK_SSL3_KEY_MAT_PARAMS *)mech->pParameter; // Check FCV // // if (((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_56_BIT_DES) == 0) && (params->bIsExport == FALSE)) // return CKR_MECHANISM_INVALID; return ssl3_key_and_mac_derive( sess, mech, base_key, pTemplate, ulCount ); } break ; /* Begin code contributed by Corrent corp. */ #ifndef NODH case CKM_DH_PKCS_DERIVE: { if (!derived_key){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } return dh_pkcs_derive( sess, mech, base_key, pTemplate, ulCount, derived_key ); } break ; #endif /* End code contributed by Corrent corp. */ default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/mech_rsa.c0000640000175000017500000006426511327631345021316 0ustar jfjf/* * Licensed materials, Property of IBM Corp. * * openCryptoki CCA token * * (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2006 * */ // File: mech_rsa.c // // Mechanisms for RSA // // Routines contained within: #include #include #include // for memcmp() et al #include #include "cca_stdll.h" #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // // CK_RV rsa_pkcs_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { OBJECT *key_obj = NULL; CK_ATTRIBUTE *attr = NULL; CK_ULONG modulus_bytes; CK_BBOOL flag; CK_RV rc; rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } flag = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else modulus_bytes = attr->ulValueLen; // check input data length restrictions // if (in_data_len > (modulus_bytes - 11)){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } if (length_only == TRUE) { *out_data_len = modulus_bytes; return CKR_OK; } if (*out_data_len < modulus_bytes) { *out_data_len = modulus_bytes; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } rc = ckm_rsa_encrypt( in_data, in_data_len, out_data, out_data_len, key_obj ); if (rc != CKR_OK) st_err_log(132, __FILE__, __LINE__); return rc; } // // CK_RV rsa_pkcs_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { OBJECT *key_obj = NULL; CK_ATTRIBUTE *attr = NULL; CK_ULONG modulus_bytes; CK_BBOOL flag; CK_RV rc; rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } flag = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); if (flag == FALSE) return CKR_FUNCTION_FAILED; else modulus_bytes = attr->ulValueLen; // check input data length restrictions // if (in_data_len != modulus_bytes){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } if (length_only == TRUE) { // this is not exact but it's the upper bound; otherwise we'll need // to do the RSA operation just to get the required length // *out_data_len = modulus_bytes - 11; return CKR_OK; } rc = ckm_rsa_decrypt( in_data, modulus_bytes, out_data, out_data_len, key_obj ); if (rc != CKR_OK) st_err_log(133, __FILE__, __LINE__); if (rc == CKR_DATA_LEN_RANGE){ st_err_log(109, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } return rc; } // // CK_RV rsa_pkcs_sign( SESSION *sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { OBJECT *key_obj = NULL; CK_ATTRIBUTE *attr = NULL; CK_ULONG modulus_bytes; CK_BBOOL flag; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } flag = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); if (flag == FALSE) return CKR_FUNCTION_FAILED; else modulus_bytes = attr->ulValueLen; // check input data length restrictions // if (in_data_len > modulus_bytes - 11) { st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } if (length_only == TRUE) { *out_data_len = modulus_bytes; return CKR_OK; } if (*out_data_len < modulus_bytes) { *out_data_len = modulus_bytes; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } rc = ckm_rsa_sign( in_data, in_data_len, out_data, out_data_len, key_obj ); if (rc != CKR_OK) st_err_log(133, __FILE__, __LINE__); return rc; } // // CK_RV rsa_pkcs_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ) { OBJECT *key_obj = NULL; CK_ATTRIBUTE *attr = NULL; CK_ULONG modulus_bytes; CK_BBOOL flag; CK_RV rc; rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } flag = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else modulus_bytes = attr->ulValueLen; // check input data length restrictions // if (sig_len != modulus_bytes){ st_err_log(46, __FILE__, __LINE__); return CKR_SIGNATURE_LEN_RANGE; } rc = ckm_rsa_verify( in_data, in_data_len, signature, sig_len, key_obj ); if (rc != CKR_OK) st_err_log(132, __FILE__, __LINE__); return rc; } // // CK_RV rsa_pkcs_verify_recover( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len, CK_BYTE * out_data, CK_ULONG * out_data_len ) { OBJECT *key_obj = NULL; CK_ATTRIBUTE *attr = NULL; CK_ULONG modulus_bytes; CK_BBOOL flag; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } flag = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else modulus_bytes = attr->ulValueLen; // check input data length restrictions // if (sig_len != modulus_bytes){ st_err_log(46, __FILE__, __LINE__); return CKR_SIGNATURE_LEN_RANGE; } if (length_only == TRUE) { *out_data_len = modulus_bytes; return CKR_OK; } // verify is a public key operation --> encrypt // rc = ckm_rsa_encrypt( signature, modulus_bytes, out_data, out_data_len, key_obj ); if (rc != CKR_OK) st_err_log(132, __FILE__, __LINE__); return rc; } // // CK_RV rsa_hash_pkcs_sign( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG * sig_len ) { CK_BYTE * ber_data = NULL; CK_BYTE * octet_str = NULL; CK_BYTE * oid = NULL; CK_BYTE * tmp = NULL; CK_ULONG buf1[16]; // 64 bytes is more than enough CK_BYTE hash[SHA1_HASH_SIZE]; // big enough for SHA1, MD5 or MD2 DIGEST_CONTEXT digest_ctx; SIGN_VERIFY_CONTEXT sign_ctx; CK_MECHANISM digest_mech; CK_MECHANISM sign_mech; CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len; CK_RV rc; if (!sess || !ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memset( &digest_ctx, 0x0, sizeof(digest_ctx) ); memset( &sign_ctx, 0x0, sizeof(sign_ctx) ); if (ctx->mech.mechanism == CKM_MD2_RSA_PKCS) { digest_mech.mechanism = CKM_MD2; oid = ber_AlgMd2; oid_len = ber_AlgMd2Len; } else if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) { digest_mech.mechanism = CKM_MD5; oid = ber_AlgMd5; oid_len = ber_AlgMd5Len; } else { digest_mech.mechanism = CKM_SHA_1; oid = ber_AlgSha1; oid_len = ber_AlgSha1Len; } digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } hash_len = sizeof(hash); rc = digest_mgr_digest( sess, length_only, &digest_ctx, in_data, in_data_len, hash, &hash_len ); if (rc != CKR_OK){ st_err_log(124, __FILE__, __LINE__); goto error; } // build the BER-encodings rc = ber_encode_OCTET_STRING( FALSE, &octet_str, &octet_str_len, hash, hash_len ); if (rc != CKR_OK){ st_err_log(77, __FILE__, __LINE__); goto error; } tmp = (CK_BYTE *)buf1; memcpy( tmp, oid, oid_len ); memcpy( tmp + oid_len, octet_str, octet_str_len); rc = ber_encode_SEQUENCE( FALSE, &ber_data, &ber_data_len, tmp, (oid_len + octet_str_len) ); if (rc != CKR_OK){ st_err_log(78, __FILE__, __LINE__); goto error; } // sign the BER-encoded data block sign_mech.mechanism = CKM_RSA_PKCS; sign_mech.ulParameterLen = 0; sign_mech.pParameter = NULL; rc = sign_mgr_init( sess, &sign_ctx, &sign_mech, FALSE, ctx->key ); if (rc != CKR_OK){ st_err_log(127, __FILE__, __LINE__); goto error; } //rc = sign_mgr_sign( sess, length_only, &sign_ctx, hash, hash_len, signature, sig_len ); rc = sign_mgr_sign( sess, length_only, &sign_ctx, ber_data, ber_data_len, signature, sig_len ); if (rc != CKR_OK) st_err_log(128, __FILE__, __LINE__); error: if (octet_str) free( octet_str ); if (ber_data) free( ber_data ); digest_mgr_cleanup( &digest_ctx ); sign_mgr_cleanup( &sign_ctx ); return rc; } // // CK_RV rsa_hash_pkcs_sign_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { RSA_DIGEST_CONTEXT * context = NULL; CK_MECHANISM digest_mech; CK_RV rc; if (!sess || !ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (RSA_DIGEST_CONTEXT *)ctx->context; if (context->flag == FALSE) { if (ctx->mech.mechanism == CKM_MD2_RSA_PKCS) digest_mech.mechanism = CKM_MD2; else if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) digest_mech.mechanism = CKM_MD5; else digest_mech.mechanism = CKM_SHA_1; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &context->hash_context, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } context->flag = TRUE; } rc = digest_mgr_digest_update( sess, &context->hash_context, in_data, in_data_len ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } return CKR_OK; error: digest_mgr_cleanup( &context->hash_context ); return rc; } // // CK_RV rsa_hash_pkcs_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ) { CK_BYTE * ber_data = NULL; CK_BYTE * octet_str = NULL; CK_BYTE * oid = NULL; CK_BYTE * tmp = NULL; CK_ULONG buf1[16]; // 64 bytes is more than enough CK_BYTE hash[SHA1_HASH_SIZE]; DIGEST_CONTEXT digest_ctx; SIGN_VERIFY_CONTEXT verify_ctx; CK_MECHANISM digest_mech; CK_MECHANISM verify_mech; CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len; CK_RV rc; if (!sess || !ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memset( &digest_ctx, 0x0, sizeof(digest_ctx) ); memset( &verify_ctx, 0x0, sizeof(verify_ctx) ); if (ctx->mech.mechanism == CKM_MD2_RSA_PKCS) { digest_mech.mechanism = CKM_MD2; oid = ber_AlgMd2; oid_len = ber_AlgMd2Len; } else if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) { digest_mech.mechanism = CKM_MD5; oid = ber_AlgMd5; oid_len = ber_AlgMd5Len; } else { digest_mech.mechanism = CKM_SHA_1; oid = ber_AlgSha1; oid_len = ber_AlgSha1Len; } digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto done; } hash_len = sizeof(hash); rc = digest_mgr_digest( sess, FALSE, &digest_ctx, in_data, in_data_len, hash, &hash_len ); if (rc != CKR_OK){ st_err_log(124, __FILE__, __LINE__); goto done; } // Build the BER encoding // rc = ber_encode_OCTET_STRING( FALSE, &octet_str, &octet_str_len, hash, hash_len ); if (rc != CKR_OK){ st_err_log(77, __FILE__, __LINE__); goto done; } tmp = (CK_BYTE *)buf1; memcpy( tmp, oid, oid_len ); memcpy( tmp + oid_len, octet_str, octet_str_len ); rc = ber_encode_SEQUENCE( FALSE, &ber_data, &ber_data_len, tmp, (oid_len + octet_str_len) ); if (rc != CKR_OK){ st_err_log(78, __FILE__, __LINE__); goto done; } // Verify the Signed BER-encoded Data block // verify_mech.mechanism = CKM_RSA_PKCS; verify_mech.ulParameterLen = 0; verify_mech.pParameter = NULL; rc = verify_mgr_init( sess, &verify_ctx, &verify_mech, FALSE, ctx->key ); if (rc != CKR_OK){ st_err_log(167, __FILE__, __LINE__); goto done; } //rc = verify_mgr_verify( sess, &verify_ctx, hash, hash_len, signature, sig_len ); rc = verify_mgr_verify( sess, &verify_ctx, ber_data, ber_data_len, signature, sig_len ); if (rc != CKR_OK) st_err_log(168, __FILE__, __LINE__); done: if (octet_str) free( octet_str ); if (ber_data) free( ber_data ); digest_mgr_cleanup( &digest_ctx ); sign_mgr_cleanup( &verify_ctx ); return rc; } // // CK_RV rsa_hash_pkcs_verify_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { RSA_DIGEST_CONTEXT * context = NULL; CK_MECHANISM digest_mech; CK_RV rc; if (!sess || !ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (RSA_DIGEST_CONTEXT *)ctx->context; if (context->flag == FALSE) { if (ctx->mech.mechanism == CKM_MD2_RSA_PKCS) digest_mech.mechanism = CKM_MD2; else if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) digest_mech.mechanism = CKM_MD5; else digest_mech.mechanism = CKM_SHA_1; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &context->hash_context, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } context->flag = TRUE; } rc = digest_mgr_digest_update( sess, &context->hash_context, in_data, in_data_len ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } return CKR_OK; error: digest_mgr_cleanup( &context->hash_context ); return rc; } // // CK_RV rsa_hash_pkcs_sign_final( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG * sig_len ) { CK_BYTE * ber_data = NULL; CK_BYTE * octet_str = NULL; CK_BYTE * oid = NULL; CK_BYTE * tmp = NULL; CK_ULONG buf1[16]; // 64 bytes is more than enough CK_BYTE hash[SHA1_HASH_SIZE]; RSA_DIGEST_CONTEXT * context = NULL; CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len; CK_MECHANISM sign_mech; SIGN_VERIFY_CONTEXT sign_ctx; CK_RV rc; if (!sess || !ctx || !sig_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_MD2_RSA_PKCS) { oid = ber_AlgMd2; oid_len = ber_AlgMd2Len; } else if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) { oid = ber_AlgMd5; oid_len = ber_AlgMd5Len; } else { oid = ber_AlgSha1; oid_len = ber_AlgSha1Len; } memset( &sign_ctx, 0x0, sizeof(sign_ctx)); context = (RSA_DIGEST_CONTEXT *)ctx->context; hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, length_only, &context->hash_context, hash, &hash_len ); if (rc != CKR_OK){ st_err_log(126, __FILE__, __LINE__); goto done; } // Build the BER Encoded Data block // rc = ber_encode_OCTET_STRING( FALSE, &octet_str, &octet_str_len, hash, hash_len ); if (rc != CKR_OK){ st_err_log(77, __FILE__, __LINE__); goto done; } tmp = (CK_BYTE *)buf1; memcpy( tmp, oid, oid_len ); memcpy( tmp + oid_len, octet_str, octet_str_len ); rc = ber_encode_SEQUENCE( FALSE, &ber_data, &ber_data_len, tmp, (oid_len + octet_str_len) ); if (rc != CKR_OK){ st_err_log(78, __FILE__, __LINE__); goto done; } // sign the BER-encoded data block // sign_mech.mechanism = CKM_RSA_PKCS; sign_mech.ulParameterLen = 0; sign_mech.pParameter = NULL; rc = sign_mgr_init( sess, &sign_ctx, &sign_mech, FALSE, ctx->key ); if (rc != CKR_OK){ st_err_log(127, __FILE__, __LINE__); goto done; } //rc = sign_mgr_sign( sess, length_only, &sign_ctx, hash, hash_len, signature, sig_len ); rc = sign_mgr_sign( sess, length_only, &sign_ctx, ber_data, ber_data_len, signature, sig_len ); if (rc != CKR_OK) st_err_log(128, __FILE__, __LINE__); if (length_only == TRUE || rc == CKR_BUFFER_TOO_SMALL) { sign_mgr_cleanup( &sign_ctx ); return rc; } done: if (octet_str) free( octet_str ); if (ber_data) free( ber_data ); digest_mgr_cleanup( &context->hash_context ); sign_mgr_cleanup( &sign_ctx ); return rc; } // // CK_RV rsa_hash_pkcs_verify_final( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len ) { CK_BYTE * ber_data = NULL; CK_BYTE * octet_str = NULL; CK_BYTE * oid = NULL; CK_BYTE * tmp = NULL; CK_ULONG buf1[16]; // 64 bytes is more than enough CK_BYTE hash[SHA1_HASH_SIZE]; RSA_DIGEST_CONTEXT * context = NULL; CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len; CK_MECHANISM verify_mech; SIGN_VERIFY_CONTEXT verify_ctx; CK_RV rc; if (!sess || !ctx || !signature){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_MD2_RSA_PKCS) { oid = ber_AlgMd2; oid_len = ber_AlgMd2Len; } else if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) { oid = ber_AlgMd5; oid_len = ber_AlgMd5Len; } else { oid = ber_AlgSha1; oid_len = ber_AlgSha1Len; } memset( &verify_ctx, 0x0, sizeof(verify_ctx)); context = (RSA_DIGEST_CONTEXT *)ctx->context; hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &context->hash_context, hash, &hash_len ); if (rc != CKR_OK){ st_err_log(126, __FILE__, __LINE__); goto done; } // Build the BER encoding // rc = ber_encode_OCTET_STRING( FALSE, &octet_str, &octet_str_len, hash, hash_len ); if (rc != CKR_OK){ st_err_log(77, __FILE__, __LINE__); goto done; } tmp = (CK_BYTE *)buf1; memcpy( tmp, oid, oid_len ); memcpy( tmp + oid_len, octet_str, octet_str_len ); rc = ber_encode_SEQUENCE( FALSE, &ber_data, &ber_data_len, tmp, (oid_len + octet_str_len) ); if (rc != CKR_OK){ st_err_log(78, __FILE__, __LINE__); goto done; } // verify the signed BER-encoded data block // verify_mech.mechanism = CKM_RSA_PKCS; verify_mech.ulParameterLen = 0; verify_mech.pParameter = NULL; rc = verify_mgr_init( sess, &verify_ctx, &verify_mech, FALSE, ctx->key ); if (rc != CKR_OK){ st_err_log(167, __FILE__, __LINE__); goto done; } //rc = verify_mgr_verify( sess, &verify_ctx, hash, hash_len, signature, sig_len ); rc = verify_mgr_verify( sess, &verify_ctx, ber_data, ber_data_len, signature, sig_len ); if (rc != CKR_OK) st_err_log(168, __FILE__, __LINE__); done: if (octet_str) free( octet_str ); if (ber_data) free( ber_data ); digest_mgr_cleanup( &context->hash_context ); verify_mgr_cleanup( &verify_ctx ); return rc; } // // mechanisms // // // CK_RV ckm_rsa_key_pair_gen( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ) { CK_RV rc; rc = token_specific.t_rsa_generate_keypair(publ_tmpl, priv_tmpl); if (rc != CKR_OK) st_err_log(91, __FILE__, __LINE__); return rc; } // // CK_RV ckm_rsa_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, OBJECT * key_obj ) { CK_ATTRIBUTE * attr = NULL; CK_OBJECT_CLASS keyclass; CK_RV rc; rc = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else keyclass = *(CK_OBJECT_CLASS *)attr->pValue; // this had better be a public key // if (keyclass != CKO_PUBLIC_KEY){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_rsa_encrypt(in_data, in_data_len, out_data, out_data_len, key_obj); if (rc != CKR_OK) st_err_log(134, __FILE__, __LINE__); return rc; } // // CK_RV ckm_rsa_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, OBJECT * key_obj ) { CK_ATTRIBUTE * attr = NULL; CK_OBJECT_CLASS keyclass; CK_RV rc; rc = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else keyclass = *(CK_OBJECT_CLASS *)attr->pValue; // this had better be a private key // if (keyclass != CKO_PRIVATE_KEY){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_rsa_decrypt(in_data, in_data_len, out_data, out_data_len, key_obj); if (rc != CKR_OK) st_err_log(135, __FILE__, __LINE__); return rc; } // // CK_RV ckm_rsa_sign( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, OBJECT * key_obj ) { CK_ATTRIBUTE * attr = NULL; CK_OBJECT_CLASS keyclass; CK_RV rc; rc = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else keyclass = *(CK_OBJECT_CLASS *)attr->pValue; // this had better be a private key // if (keyclass != CKO_PRIVATE_KEY){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_rsa_sign(in_data, in_data_len, out_data, out_data_len, key_obj); if (rc != CKR_OK) st_err_log(135, __FILE__, __LINE__); return rc; } // // CK_RV ckm_rsa_verify( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG out_data_len, OBJECT * key_obj ) { CK_ATTRIBUTE * attr = NULL; CK_OBJECT_CLASS keyclass; CK_RV rc; rc = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else keyclass = *(CK_OBJECT_CLASS *)attr->pValue; // this had better be a private key // if (keyclass != CKO_PUBLIC_KEY){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_rsa_verify(in_data, in_data_len, out_data, out_data_len, key_obj); if (rc != CKR_OK) st_err_log(135, __FILE__, __LINE__); return rc; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/tok_specific.h0000640000175000017500000001257311327631345022177 0ustar jfjf/* * Licensed materials, Property of IBM Corp. * * openCryptoki CCA token * * (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2006 * * Author: Kent E. Yoder * */ /*************************************************************************** Change Log ========== 4/25/03 Kapil Sood (kapil@corrent.com) Added DH key pair generation and DH shared key derivation functions. ****************************************************************************/ // Token specific functions that tokens must implement..... // // Prototypes #ifndef _TOK_SPECIFIC #define _TOK_SPECIFIC CK_RV token_rng(CK_BYTE *, CK_ULONG); int tok_slot2local(CK_SLOT_ID); CK_RV token_specific_init(char *,CK_SLOT_ID ); CK_RV token_specific_session(CK_SLOT_ID); CK_RV token_specific_final(void); CK_RV token_specific_des_key_gen(CK_BYTE *, CK_ULONG, CK_ULONG); CK_RV token_specific_des_ecb(CK_BYTE *, CK_ULONG , CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_BYTE ); CK_RV token_specific_des_cbc(CK_BYTE *, CK_ULONG , CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_BYTE *, CK_BYTE ); CK_RV token_specific_tdes_ecb(CK_BYTE *, CK_ULONG , CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_BYTE ); CK_RV token_specific_tdes_cbc(CK_BYTE *, CK_ULONG , CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_BYTE *, CK_BYTE ); #if 0 CK_RV token_specific_rsa_decrypt( CK_BYTE * , CK_ULONG , CK_BYTE *, OBJECT *); CK_RV token_specific_rsa_encrypt( CK_BYTE * , CK_ULONG , CK_BYTE * , OBJECT * ); #else CK_RV token_specific_rsa_decrypt(CK_BYTE * , CK_ULONG , CK_BYTE * , CK_ULONG * , OBJECT *); CK_RV token_specific_rsa_encrypt(CK_BYTE * , CK_ULONG , CK_BYTE * , CK_ULONG * , OBJECT * ); CK_RV token_specific_rsa_sign(CK_BYTE * , CK_ULONG , CK_BYTE * , CK_ULONG * , OBJECT * ); CK_RV token_specific_rsa_verify(CK_BYTE * , CK_ULONG , CK_BYTE * , CK_ULONG , OBJECT * ); #endif CK_RV token_specific_rsa_generate_keypair( TEMPLATE * , TEMPLATE * ); /* Begin code contributed by Corrent corp. */ #ifndef NODH CK_RV token_specific_dh_pkcs_derive( CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG ) ; CK_RV token_specific_dh_pkcs_key_pair_gen( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ); #endif /* End code contributed by Corrent corp. */ CK_RV tok_cdmv_transform(CK_VOID_PTR, CK_ULONG); CK_RV ckm_dsa_sign( CK_BYTE * , CK_BYTE * , OBJECT * ); CK_RV ckm_dsa_key_pair_gen( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ); CK_RV ckm_dsa_verify( CK_BYTE *, CK_BYTE *, OBJECT * ); CK_RV token_specific_sha_init( DIGEST_CONTEXT * ); CK_RV token_specific_sha_update( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG); CK_RV token_specific_sha_final( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG * ); CK_RV token_specific_sha2_init( DIGEST_CONTEXT * ); CK_RV token_specific_sha2_update( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG); CK_RV token_specific_sha2_final( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG * ); #ifndef NOAES CK_RV token_specific_aes_key_gen( CK_BYTE *, CK_ULONG ); CK_RV token_specific_aes_ecb( CK_BYTE *, CK_ULONG , CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_ULONG , CK_BYTE ); CK_RV token_specific_aes_cbc( CK_BYTE *, CK_ULONG , CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_ULONG , CK_BYTE *, CK_BYTE ); #endif CK_RV token_specific_get_mechanism_list(CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount); CK_RV token_specific_get_mechanism_info(CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo); #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/defs.h0000640000175000017500000001304211327631345020446 0ustar jfjf/* * Licensed materials, Property of IBM Corp. * * openCryptoki CCA token * * (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2006 * * Author: Kent E. Yoder * */ // File: defs.h // // Contains various definitions needed by both the host-side // and coprocessor-side code. // #ifndef _DEFS_H #define _DEFS_H #define MASTER_KEY_SIZE CCA_KEY_ID_SIZE #if (LEEDS) #pragma pack(1) #pragma options align=packed #endif #if (LEEDS) #include #else #define PACK_DATA #endif #define MAX_SESSION_COUNT 64 #define MAX_PIN_LEN 128 #define MIN_PIN_LEN 4 #define MAX_SLOT_ID 10 #define LEEDS_MAX_REQ_LEN 4096 #ifndef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif // the following constants are used for sccSignOn // #define PKCS_11_PRG_ID "pkcs11 2.01" #define PKCS_11_DEVELOPER_ID 0xE #define PKCS_11_VERSION 1 #define PKCS_11_INSTANCE 0 #define PKCS_11_QUEUE 0 #define LEEDS_PRG_ID_PKCS_11 "PKCS11" // the following are "boolean" attributes // #define CKA_IBM_TWEAK_ALLOW_KEYMOD 0x80000001 #define CKA_IBM_TWEAK_ALLOW_WEAK_DES 0x80000002 #define CKA_IBM_TWEAK_DES_PARITY_CHK 0x80000003 #define CKA_IBM_TWEAK_NETSCAPE 0x80000004 #define MODE_COPY (1 << 0) #define MODE_CREATE (1 << 1) #define MODE_KEYGEN (1 << 2) #define MODE_MODIFY (1 << 3) #define MODE_DERIVE (1 << 4) #define MODE_UNWRAP (1 << 5) // RSA block formatting types // #define PKCS_BT_1 1 #define PKCS_BT_2 2 #define OP_ENCRYPT_INIT 1 #define OP_DECRYPT_INIT 2 #define OP_WRAP 3 #define OP_UNWRAP 4 #define OP_SIGN_INIT 5 #define OP_VERIFY_INIT 6 // saved-state identifiers // enum { STATE_INVALID = 0, STATE_ENCR, STATE_DECR, STATE_DIGEST, STATE_SIGN, STATE_VERIFY }; #define AES_KEY_SIZE_256 32 #define AES_KEY_SIZE_192 24 #define AES_KEY_SIZE_128 16 #define AES_BLOCK_SIZE 16 #define AES_INIT_VECTOR_SIZE AES_BLOCK_SIZE #define DES_KEY_SIZE 8 #define DES_BLOCK_SIZE 8 #define SHA1_HASH_SIZE 20 #define SHA1_BLOCK_SIZE 64 typedef struct _sha1_ctx { unsigned char hash[SHA1_HASH_SIZE+1]; unsigned int hash_len, tail_len; int message_part; /* needs to be seen across calls to update and final */ char tail[64]; /* save the last (up to) 64 bytes which may need to be shaved */ void *dev_ctx; } oc_sha1_ctx; #define SHA2_HASH_SIZE 32 #define SHA2_BLOCK_SIZE 64 typedef struct _sha2_ctx { unsigned char hash[SHA2_HASH_SIZE+1]; unsigned int hash_len, tail_len; int message_part; /* needs to be seen across calls to update and * final */ char tail[64]; /* save the last (up to) 64 bytes which may need to * be shaved */ void *dev_ctx; } oc_sha2_ctx; #define MD2_HASH_SIZE 16 #define MD2_BLOCK_SIZE 48 #define MD5_HASH_SIZE 16 #define MD5_BLOCK_SIZE 64 #define DSA_SIGNATURE_SIZE 40 #define DEFAULT_SO_PIN "87654321" typedef enum { ALL = 1, PRIVATE, PUBLIC } SESS_OBJ_TYPE; #if (LEEDS_BUILD) enum cmdconst { FIRST_ENTRY = 0, DUMMYFUNCTION = 1, FCVFUNCTION, UPDATETWEAKVALUES, QUERYTWEAKVALUES, PK_DES_KEYGEN, PK_CDMF_KEYGEN, PK_CDMF_TRANSFORM_KEY, PK_RSA_KEYPAIR_GEN, PK_DSA_KEYPAIR_GEN, PK_GENERATE_RND, PK_DES_ECB_ENCRYPT, PK_DES_ECB_DECRYPT, PK_DES_CBC_ENCRYPT, PK_DES_CBC_DECRYPT, PK_DES3_ECB_ENCRYPT, PK_DES3_ECB_DECRYPT, PK_DES3_CBC_ENCRYPT, PK_DES3_CBC_DECRYPT, PK_RSA_ENCRYPT, PK_RSA_DECRYPT, PK_DSA_SIGN, PK_DSA_VERIFY, PK_SHA1_DIGEST, PK_SHA1_UPDATE, PK_SHA1_FINAL, LAST_ENTRY }; typedef struct _LEEDS_REQUEST { CK_ULONG pid; CK_ULONG req_len; // size of request data CK_ULONG repl_max[4]; // any command-specific request data gets appended here // } PACK_DATA LEEDS_REQUEST; typedef struct _LEEDS_REPLY { CK_RV rc; CK_ULONG repl_len[4]; // size of data // any command-specific reply data gets appended here // } PACK_DATA LEEDS_REPLY; #endif // this is a flattened version of the CK_SSL3_RANDOM_DATA // typedef struct _SSL3_RANDOM_DATA { CK_ULONG client_data_len; CK_ULONG server_data_len; // client data is appended here // server data is appended here // } PACK_DATA SSL3_RANDOM_DATA; // // typedef struct _SSL3_MASTER_KEY_DERIVE_PARAMS { CK_VERSION version; CK_ULONG client_data_len; CK_ULONG server_data_len; // client data is appended here // server data is appended here // } PACK_DATA SSL3_MASTER_KEY_DERIVE_PARAMS; // // typedef struct _SSL3_KEY_MAT_OUT { CK_OBJECT_HANDLE client_mac_secret; CK_OBJECT_HANDLE server_mac_secret; CK_OBJECT_HANDLE client_key; CK_OBJECT_HANDLE server_key; CK_ULONG iv_len; // in bytes // client IV is appended here // server IV is appended here // } PACK_DATA SSL3_KEY_MAT_OUT; // // typedef struct _SSL3_KEY_MAT_PARAMS { CK_ULONG mac_size_bits; CK_ULONG key_size_bits; CK_ULONG iv_size_bits; CK_BBOOL export; CK_ULONG client_data_len; CK_ULONG server_data_len; // client data is appended here // server data is appended here // } PACK_DATA SSL3_KEY_MAT_PARAMS; typedef struct _DL_NODE { struct _DL_NODE *next; struct _DL_NODE *prev; void *data; } DL_NODE; // Abstract this out and include a token specific headerfile #include #define PK_LITE_NV "NVTOK.DAT" #define PK_LITE_OBJ_DIR "TOK_OBJ" #define PK_LITE_OBJ_IDX "OBJ.IDX" #define DEL_CMD "/bin/rm -f" #if (LEEDS) #pragma options align=full #pragma pack() #endif #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/h_extern.h0000640000175000017500000030016611327631345021347 0ustar jfjf/* * Licensed materials, Property of IBM Corp. * * openCryptoki CCA token * * (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2006 * * Author: Kent E. Yoder * */ /*************************************************************************** Change Log ========== 4/25/03 Kapil Sood (kapil@corrent.com) Added DH key pair generation and DH shared key derivation functions. ****************************************************************************/ #ifndef _H_EXTERN_H #define _H_EXTERN_H #include #include "msg.h" #if (LEEDS_BUILD) #pragma options align=packed #endif extern char * pk_dir; // global variables // extern CK_BBOOL initialized; extern char *card_function_names[]; extern char *total_function_names[]; extern MECH_LIST_ELEMENT mech_list[]; extern CK_ULONG mech_list_len; extern pthread_mutex_t native_mutex; #if SYSVSEM extern int xprocsemid; #endif extern void *xproclock; extern MUTEX pkcs_mutex, obj_list_mutex, sess_list_mutex, login_mutex; extern DL_NODE *sess_list; extern DL_NODE *sess_obj_list; extern DL_NODE *publ_token_obj_list; extern DL_NODE *priv_token_obj_list; extern DL_NODE *object_map; extern CK_BYTE master_key[MASTER_KEY_SIZE]; extern CK_BYTE so_pin_md5[MD5_HASH_SIZE]; extern CK_BYTE user_pin_md5[MD5_HASH_SIZE]; extern CK_BYTE default_user_pin_sha[SHA1_HASH_SIZE]; extern CK_BYTE default_so_pin_sha[SHA1_HASH_SIZE]; extern CK_BYTE default_so_pin_md5[MD5_HASH_SIZE]; extern LW_SHM_TYPE *global_shm; extern TOKEN_DATA *nv_token_data; extern CK_SLOT_INFO slot_info; extern CK_ULONG next_object_handle; extern CK_ULONG next_session_handle; // SAB FIXME FIXME extern CK_STATE global_login_state; extern CK_BYTE ber_AlgIdRSAEncryption[]; extern CK_ULONG ber_AlgIdRSAEncryptionLen; extern CK_BYTE ber_rsaEncryption[]; extern CK_ULONG ber_rsaEncryptionLen; extern CK_BYTE ber_idDSA[]; extern CK_ULONG ber_idDSALen; extern CK_BYTE ber_md2WithRSAEncryption[]; extern CK_ULONG ber_md2WithRSAEncryptionLen; extern CK_BYTE ber_md4WithRSAEncryption[]; extern CK_ULONG ber_md4WithRSAEncryptionLen; extern CK_BYTE ber_md5WithRSAEncryption[]; extern CK_ULONG ber_md5WithRSAEncryptionLen; extern CK_BYTE ber_sha1WithRSAEncryption[]; extern CK_ULONG ber_sha1WithRSAEncryptionLen; extern CK_BYTE ber_AlgMd2[]; extern CK_ULONG ber_AlgMd2Len; extern CK_BYTE ber_AlgMd5[]; extern CK_ULONG ber_AlgMd5Len; extern CK_BYTE ber_AlgSha1[]; extern CK_ULONG ber_AlgSha1Len; extern CK_BYTE ber_AlgSha256[]; extern CK_ULONG ber_AlgSha256Len; extern CK_ULONG des_weak_count; extern CK_ULONG des_semi_weak_count; extern CK_ULONG des_possibly_weak_count; extern CK_BYTE des_weak_keys[4][8]; extern CK_BYTE des_semi_weak_keys[12][8]; extern CK_BYTE des_possibly_weak_keys[48][8]; extern struct ST_FCN_LIST function_list; extern CK_C_INITIALIZE_ARGS cinit_args; CK_ULONG long_reverse( CK_ULONG x ); // VACPP C runtime initialization/cleanup entry points // int _CRT_init(void); int _CRT_term(void); CK_RV DummyFunction( CK_SLOT_ID slot_id, int arg ); // General-purpose functions // CK_RV C_Initialize ( CK_VOID_PTR pInitArgs ); CK_RV C_Finalize ( CK_VOID_PTR pReserved ); CK_RV C_GetInfo ( CK_INFO_PTR pInfo ); CK_RV C_GetFunctionList ( CK_FUNCTION_LIST_PTR_PTR ppFunctionList ); // Slot and token management functions // CK_RV C_GetSlotList ( CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount ); CK_RV C_GetSlotInfo ( CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo ); CK_RV C_GetTokenInfo ( CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo ); CK_RV C_WaitForSlotEvent ( CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved ); CK_RV C_GetMechanismList ( CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount ); CK_RV C_GetMechanismInfo ( CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo ); CK_RV C_InitToken ( CK_SLOT_ID slotID, CK_CHAR_PTR pPin, CK_ULONG ulPinLen, CK_CHAR_PTR pLabel ); CK_RV C_InitPIN ( CK_SESSION_HANDLE hSession, CK_CHAR_PTR pPin, CK_ULONG ulPinLen ); CK_RV C_SetPIN ( CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, CK_ULONG ulOldLen, CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen ); // Session management functions // CK_RV C_OpenSession ( CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession ); CK_RV C_CloseSession ( CK_SESSION_HANDLE hSession ); CK_RV C_CloseAllSessions ( CK_SLOT_ID slotID ); CK_RV C_GetSessionInfo ( CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo ); CK_RV C_GetOperationState ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen ); CK_RV C_SetOperationState ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey ); CK_RV C_Login ( CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG uPinLen ); CK_RV C_Logout ( CK_SESSION_HANDLE hSession ); // Object management functions // CK_RV C_CreateObject ( CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject ); CK_RV C_CopyObject ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phNewObject ); CK_RV C_DestroyObject ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject ); CK_RV C_GetObjectSize ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize ); CK_RV C_GetAttributeValue ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ); CK_RV C_SetAttributeValue ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ); CK_RV C_FindObjectsInit ( CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ); CK_RV C_FindObjects ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount ); CK_RV C_FindObjectsFinal ( CK_SESSION_HANDLE hSession ); // Encryption functions // CK_RV C_EncryptInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_Encrypt ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen ); CK_RV C_EncryptUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ); CK_RV C_EncryptFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen); // Decryption functions // CK_RV C_DecryptInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_Decrypt ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen ); CK_RV C_DecryptUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ); CK_RV C_DecryptFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen ); // Message digesting functions // CK_RV C_DigestInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism ); CK_RV C_Digest ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen ); CK_RV C_DigestUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ); CK_RV C_DigestKey ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey ); CK_RV C_DigestFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen ); // Signing and MAC functions // CK_RV C_SignInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_Sign ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ); CK_RV C_SignUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ); CK_RV C_SignFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ); CK_RV C_SignRecoverInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_SignRecover ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ); // Signature/MAC verification functions // CK_RV C_VerifyInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_Verify ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen ); CK_RV C_VerifyUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ); CK_RV C_VerifyFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen ); CK_RV C_VerifyRecoverInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_VerifyRecover ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen ); // Dual-function cryptographics functions // CK_RV C_DigestEncryptUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ); CK_RV C_DecryptDigestUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ); CK_RV C_SignEncryptUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ); CK_RV C_DecryptVerifyUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ); // Key management functions // CK_RV C_GenerateKey ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey ); CK_RV C_GenerateKeyPair ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey ); CK_RV C_WrapKey ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen ); CK_RV C_UnwrapKey ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey ); CK_RV C_DeriveKey ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey ); // Random number generation functions // CK_RV C_SeedRandom ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen ); CK_RV C_GenerateRandom ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen ); // Parallel function management functions // CK_RV C_GetFunctionStatus ( CK_SESSION_HANDLE hSession ); CK_RV C_CancelFunction ( CK_SESSION_HANDLE hSession ); // // internal routines are below this point // CK_RV clock_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV clock_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV clock_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode); CK_RV counter_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV counter_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV counter_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode); CK_RV dp_dsa_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode); CK_RV dp_dsa_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dp_dsa_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode); CK_RV dp_dh_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode); CK_RV dp_dh_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dp_dh_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode); CK_RV dp_x9dh_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode); CK_RV dp_x9dh_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dp_x9dh_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode); CK_RV communicate( CK_ULONG cmd_id, CK_VOID_PTR pReq, CK_ULONG req_len, CK_VOID_PTR pRep, CK_ULONG_PTR repl_len, CK_BYTE_PTR pOut, CK_ULONG out_len, CK_BYTE_PTR pIn, CK_ULONG in_len ); CK_RV compute_next_token_obj_name( CK_BYTE *current, CK_BYTE *next ); CK_RV save_token_object ( OBJECT *obj ); CK_RV save_public_token_object ( OBJECT *obj ); CK_RV save_private_token_object( OBJECT *obj ); CK_RV load_public_token_objects ( void ); CK_RV load_private_token_objects( void ); CK_RV reload_token_object( OBJECT *obj ); CK_RV restore_private_token_object( CK_BYTE * data, CK_ULONG len, OBJECT * pObj ); CK_RV delete_token_object( OBJECT *ptr ); CK_RV init_token_data( void ); CK_RV load_token_data( void ); CK_RV save_token_data( void ); CK_RV load_masterkey_so ( void ); CK_RV load_masterkey_user( void ); CK_RV save_masterkey_so ( void ); CK_RV save_masterkey_user( void ); CK_RV compute_md5( CK_BYTE *data, CK_ULONG len, CK_BYTE *hash ); CK_RV compute_sha( CK_BYTE *data, CK_ULONG len, CK_BYTE *hash ); CK_ULONG long_reverse( CK_ULONG x ); //CK_RV load_FCV( void ); //CK_RV save_FCV( FUNCTION_CTRL_VEC_RECORD *new_FCV ); //CK_RV update_tweak_values( void *attributes, CK_ULONG count ); //CK_RV query_tweak_values( CK_ATTRIBUTE_TYPE * attributes, // CK_ULONG count, // CK_BYTE ** reply, // CK_ULONG * reply_len ); void init_slotInfo(void); void init_tokenInfo(void); CK_BYTE parity_adjust( CK_BYTE b ); CK_RV parity_is_odd( CK_BYTE b ); CK_RV build_attribute( CK_ATTRIBUTE_TYPE type, CK_BYTE *data, CK_ULONG data_len, CK_ATTRIBUTE **attr ); CK_RV add_pkcs_padding( CK_BYTE * ptr, // where to start appending CK_ULONG block_size, CK_ULONG data_len, CK_ULONG total_len ); CK_RV strip_pkcs_padding( CK_BYTE * ptr, CK_ULONG total_len, CK_ULONG * data_len ); CK_RV remove_leading_zeros( CK_ATTRIBUTE *attr ); // RNG routines // CK_RV rng_generate( CK_BYTE *output, CK_ULONG bytes ); // SSL3 routines // CK_RV ssl3_mac_sign( SESSION *sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV ssl3_mac_sign_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ); CK_RV ssl3_mac_sign_final( SESSION *sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV ssl3_mac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); CK_RV ssl3_mac_verify_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ); CK_RV ssl3_mac_verify_final( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len ); CK_RV ssl3_master_key_derive( SESSION * sess, CK_MECHANISM * mech, CK_OBJECT_HANDLE base_key, CK_ATTRIBUTE * attributes, CK_ULONG count, CK_OBJECT_HANDLE * handle ); CK_RV ssl3_key_and_mac_derive( SESSION * sess, CK_MECHANISM * mech, CK_OBJECT_HANDLE base_key, CK_ATTRIBUTE * attributes, CK_ULONG count ); CK_RV ckm_ssl3_pre_master_key_gen( TEMPLATE *tmpl, CK_MECHANISM *mech ); // RSA routines // CK_RV rsa_pkcs_encrypt( SESSION * sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV rsa_pkcs_decrypt( SESSION * sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV rsa_pkcs_sign ( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG * sig_len ); CK_RV rsa_pkcs_verify ( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); CK_RV rsa_pkcs_verify_recover ( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len, CK_BYTE * out_data, CK_ULONG * out_len ); CK_RV rsa_x509_encrypt ( SESSION * sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV rsa_x509_decrypt ( SESSION * sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV rsa_x509_sign ( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG * sig_len ); CK_RV rsa_x509_verify ( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); CK_RV rsa_x509_verify_recover( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len, CK_BYTE * out_data, CK_ULONG * out_len ); CK_RV rsa_hash_pkcs_sign ( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG * sig_len ); CK_RV rsa_hash_pkcs_verify ( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); CK_RV rsa_hash_pkcs_sign_update ( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ); CK_RV rsa_hash_pkcs_verify_update ( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ); CK_RV rsa_hash_pkcs_sign_final ( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG * sig_len ); CK_RV rsa_hash_pkcs_verify_final ( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len ); // RSA mechanisms // CK_RV ckm_rsa_key_pair_gen( TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl ); #if 0 CK_RV ckm_rsa_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, OBJECT * key_obj ); CK_RV ckm_rsa_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, OBJECT * key_obj ); #else CK_RV ckm_rsa_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, OBJECT * key_obj ); CK_RV ckm_rsa_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, OBJECT * key_obj ); CK_RV ckm_rsa_sign( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, OBJECT * key_obj ); CK_RV ckm_rsa_verify( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG out_data_len, OBJECT * key_obj ); #endif CK_RV ckm_rsa_compute_priv_exp( TEMPLATE *tmpl ); #ifndef NODSA // DSA routines // CK_RV dsa_sign ( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG * sig_len ); CK_RV dsa_verify ( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); // DSA mechanisms // CK_RV ckm_dsa_key_pair_gen( TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl ); CK_RV ckm_dsa_sign( CK_BYTE *in_data, // must be 20 bytes CK_BYTE *signature, // must be 40 bytes OBJECT *priv_key ); CK_RV ckm_dsa_verify( CK_BYTE *signature, // must be 40 bytes CK_BYTE *data, // must be 20 bytes OBJECT *publ_key ); #endif /* Begin code contributed by Corrent corp. */ // DH routines // #ifndef NODH CK_RV dh_pkcs_derive( SESSION * sess, CK_MECHANISM * mech, CK_OBJECT_HANDLE base_key, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE * handle ) ; // DH mechanisms // CK_RV ckm_dh_pkcs_derive( CK_VOID_PTR other_pubkey, CK_ULONG other_pubkey_len, CK_OBJECT_HANDLE base_key, CK_BYTE *secret, CK_ULONG *secret_len ) ; CK_RV ckm_dh_key_pair_gen( TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl ); CK_RV ckm_dh_pkcs_key_pair_gen( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ); #endif /* End code contributed by Corrent corp. */ // DES routines - I have to provide two different versions of these // because encryption routines are also used internally // so we can't assume that external-to-external buffering // will be possible and combining them into a single // function is messy. // CK_RV pk_des_ecb_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_ecb_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV pk_des_cbc_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_pad_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_pad_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_ecb_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_ecb_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_pad_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_pad_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_ecb_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_ecb_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_pad_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_pad_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_ecb_wrap_key( SESSION *sess, CK_BBOOL length_only, CK_MECHANISM *mech, OBJECT *key, OBJECT *encr_key, CK_BYTE *data, CK_ULONG *data_len ); // DES mechanisms // CK_RV ckm_des_key_gen ( TEMPLATE *tmpl ); CK_RV ckm_cdmf_key_gen( TEMPLATE *tmpl ); CK_RV ckm_des_ecb_encrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value ); CK_RV ckm_des_ecb_decrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value ); CK_RV ckm_des_cbc_encrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *init_v, CK_BYTE *key_value ); CK_RV ckm_des_cbc_decrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *init_v, CK_BYTE *key_value ); CK_RV ckm_des_wrap_format( CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ); // DES3 routines // CK_RV des3_ecb_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_ecb_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_pad_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_pad_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_ecb_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_ecb_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_pad_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_pad_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_ecb_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_ecb_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_pad_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_pad_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); // DES3 mechanisms // CK_RV ckm_des3_key_gen( TEMPLATE *tmpl ); CK_RV ckm_des3_ecb_encrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value ); CK_RV ckm_des3_ecb_decrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value ); CK_RV ckm_des3_cbc_encrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *init_v, CK_BYTE *key_value ); CK_RV ckm_des3_cbc_decrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *init_v, CK_BYTE *key_value ); // AES routines // CK_RV aes_ecb_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_ecb_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_pad_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_pad_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_ecb_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_ecb_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_pad_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_pad_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_ecb_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_ecb_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_pad_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_pad_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); // AES mechanisms // CK_RV ckm_aes_key_gen( TEMPLATE *tmpl ); CK_RV ckm_aes_ecb_encrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_ULONG key_len ); CK_RV ckm_aes_ecb_decrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_ULONG key_len ); CK_RV ckm_aes_cbc_encrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *init_v, CK_BYTE *key_value, CK_ULONG key_len ); CK_RV ckm_aes_cbc_decrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *init_v, CK_BYTE *key_value, CK_ULONG key_len ); CK_RV ckm_aes_wrap_format( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len ); // SHA-1 mechanisms // CK_RV sha1_hash( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV sha1_hash_update( SESSION *sess, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV sha1_hash_final( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV sha1_hmac_sign( SESSION *sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV sha1_hmac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); void ckm_sha1_init( DIGEST_CONTEXT *ctx ); CK_RV ckm_sha1_update( DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV ckm_sha1_final( DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); // SHA-256 mechanisms // CK_RV sha2_hash( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV sha2_hash_update( SESSION *sess, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV sha2_hash_final( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV sha2_hmac_sign( SESSION *sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV sha2_hmac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); void ckm_sha2_init( DIGEST_CONTEXT *ctx ); CK_RV ckm_sha2_update( DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV ckm_sha2_final( DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); // MD2 mechanisms // CK_RV md2_hash( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV md2_hash_update( SESSION *sess, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV md2_hash_final( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV md2_hmac_sign( SESSION *sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV md2_hmac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); CK_RV ckm_md2_update( MD2_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV ckm_md2_final( MD2_CONTEXT *context, CK_BYTE *out_data, CK_ULONG out_data_len ); void ckm_md2_transform( CK_BYTE *state, CK_BYTE *checksum, CK_BYTE *block ); // MD5 mechanisms // CK_RV md5_hash( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV md5_hash_update( SESSION *sess, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV md5_hash_final( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV md5_hmac_sign( SESSION *sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV md5_hmac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); void ckm_md5_init( MD5_CONTEXT *context ); CK_RV ckm_md5_update( MD5_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV ckm_md5_final( MD5_CONTEXT *context, CK_BYTE *out_data, CK_ULONG out_data_len ); void ckm_md5_transform( CK_ULONG *buf, CK_ULONG *in ); // linked-list routines // DL_NODE * dlist_add_as_first( DL_NODE *list, void *data ); DL_NODE * dlist_add_as_last( DL_NODE *list, void *data ); DL_NODE * dlist_find( DL_NODE *list, void *data ); DL_NODE * dlist_get_first( DL_NODE *list ); DL_NODE * dlist_get_last( DL_NODE *list ); CK_ULONG dlist_length( DL_NODE *list ); DL_NODE * dlist_next( DL_NODE *list ); DL_NODE * dlist_prev( DL_NODE *list ); void dlist_purge( DL_NODE *list ); DL_NODE * dlist_remove_node( DL_NODE *list, DL_NODE *node ); CK_RV _CreateMutex( MUTEX *mutex ); CK_RV _DestroyMutex( MUTEX *mutex ); CK_RV _LockMutex( MUTEX *mutex ); CK_RV _UnlockMutex( MUTEX *mutex ); CK_RV attach_shm(void); CK_RV detach_shm(void); // encryption manager routines // CK_RV encr_mgr_init( SESSION * sess, ENCR_DECR_CONTEXT * ctx, CK_ULONG operation, CK_MECHANISM * mech, CK_OBJECT_HANDLE key_handle ); CK_RV encr_mgr_cleanup( ENCR_DECR_CONTEXT *ctx ); CK_RV encr_mgr_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV encr_mgr_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV encr_mgr_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); // decryption manager routines // CK_RV decr_mgr_init( SESSION * sess, ENCR_DECR_CONTEXT * ctx, CK_ULONG operation, CK_MECHANISM * mech, CK_OBJECT_HANDLE key_handle ); CK_RV decr_mgr_cleanup( ENCR_DECR_CONTEXT * ctx ); CK_RV decr_mgr_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV decr_mgr_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV decr_mgr_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV decr_mgr_update_des_ecb( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV decr_mgr_update_des_cbc( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV decr_mgr_update_des3_ecb( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV decr_mgr_update_des3_cbc( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); // digest manager routines // CK_RV digest_mgr_cleanup( DIGEST_CONTEXT *ctx ); CK_RV digest_mgr_init( SESSION *sess, DIGEST_CONTEXT *ctx, CK_MECHANISM *mech ); CK_RV digest_mgr_digest( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *data, CK_ULONG data_len, CK_BYTE *hash, CK_ULONG *hash_len ); CK_RV digest_mgr_digest_update( SESSION *sess, DIGEST_CONTEXT *ctx, CK_BYTE *data, CK_ULONG data_len ); CK_RV digest_mgr_digest_key( SESSION *sess, DIGEST_CONTEXT *ctx, CK_OBJECT_HANDLE key_handle ); CK_RV digest_mgr_digest_final( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *hash, CK_ULONG *hash_len ); // key manager routines // CK_RV key_mgr_generate_key( SESSION *sess, CK_MECHANISM *mech, CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE *key_handle ); CK_RV key_mgr_generate_key_pair( SESSION *sess, CK_MECHANISM *mech, CK_ATTRIBUTE *publ_tmpl, CK_ULONG publ_count, CK_ATTRIBUTE *priv_tmpl, CK_ULONG priv_count, CK_OBJECT_HANDLE *publ_key_handle, CK_OBJECT_HANDLE *priv_key_handle ); CK_RV key_mgr_get_private_key_type( CK_BYTE *keydata, CK_ULONG keylen, CK_KEY_TYPE *keytype ); CK_RV key_mgr_derive_key( SESSION * sess, CK_MECHANISM * mech, CK_OBJECT_HANDLE base_key, CK_OBJECT_HANDLE * derived_key, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ); CK_RV key_mgr_wrap_key( SESSION *sess, CK_BBOOL length_only, CK_MECHANISM *mech, CK_OBJECT_HANDLE h_wrapping_key, CK_OBJECT_HANDLE h_key, CK_BYTE *wrapped_key, CK_ULONG *wrapped_key_len ); CK_RV key_mgr_unwrap_key( SESSION *sess, CK_MECHANISM *mech, CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount, CK_BYTE *wrapped_key, CK_ULONG wrapped_key_len, CK_OBJECT_HANDLE unwrapping_key, CK_OBJECT_HANDLE *unwrapped_key ); CK_RV key_mgr_derive_prolog( SESSION *sess, CK_ATTRIBUTE *attributes, CK_ULONG attrcount, CK_OBJECT_HANDLE base_key, OBJECT *base_key_obj, CK_BYTE *base_key_value, CK_KEY_TYPE base_key_type, ATTRIBUTE_PARSE_LIST *parselist, CK_ULONG plcount ); // signature manager routines // CK_RV sign_mgr_init( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_MECHANISM * mech, CK_BBOOL recover_mode, CK_OBJECT_HANDLE key_handle ); CK_RV sign_mgr_cleanup( SIGN_VERIFY_CONTEXT *ctx ); CK_RV sign_mgr_sign( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV sign_mgr_sign_recover( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV sign_mgr_sign_final( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV sign_mgr_sign_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ); // signature verify manager routines // CK_RV verify_mgr_init( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_MECHANISM * mech, CK_BBOOL recover_mode, CK_OBJECT_HANDLE key_handle ); CK_RV verify_mgr_cleanup( SIGN_VERIFY_CONTEXT *ctx ); CK_RV verify_mgr_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); CK_RV verify_mgr_verify_recover( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len, CK_BYTE * out_data, CK_ULONG * out_len ); CK_RV verify_mgr_verify_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ); CK_RV verify_mgr_verify_final( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len ); // session manager routines // CK_RV session_mgr_close_all_sessions( void ); CK_RV session_mgr_close_session( SESSION *sess ); SESSION * session_mgr_find( CK_SESSION_HANDLE handle ); CK_RV session_mgr_login_all ( CK_USER_TYPE user_type ); CK_RV session_mgr_logout_all( void ); CK_RV session_mgr_new( CK_ULONG flags, SESSION **sess ); CK_BBOOL session_mgr_readonly_exists( void ); CK_BBOOL session_mgr_so_session_exists ( void ); CK_BBOOL session_mgr_user_session_exists ( void ); CK_BBOOL session_mgr_public_session_exists( void ); CK_RV session_mgr_get_op_state( SESSION *sess, CK_BBOOL length_only, CK_BYTE *data, CK_ULONG *data_len ); CK_RV session_mgr_set_op_state( SESSION *sess, CK_OBJECT_HANDLE encr_key, CK_OBJECT_HANDLE auth_key, CK_BYTE *data, CK_ULONG data_len ); // object manager routines // CK_RV object_mgr_add( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE * handle ); CK_RV object_mgr_add_to_map( SESSION * sess, OBJECT * obj, CK_OBJECT_HANDLE * handle ); CK_RV object_mgr_add_to_shm ( OBJECT *obj ); CK_RV object_mgr_del_from_shm( OBJECT *obj ); CK_RV object_mgr_check_shm ( OBJECT *obj ); CK_RV object_mgr_search_shm_for_obj( TOK_OBJ_ENTRY * list, CK_ULONG lo, CK_ULONG hi, OBJECT * obj, CK_ULONG * index ); CK_RV object_mgr_sort_priv_shm( void ); CK_RV object_mgr_sort_publ_shm( void ); CK_RV object_mgr_update_from_shm( void ); CK_RV object_mgr_update_publ_tok_obj_from_shm(); CK_RV object_mgr_update_priv_tok_obj_from_shm(); CK_RV object_mgr_copy( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE old_obj, CK_OBJECT_HANDLE * new_obj ); CK_RV object_mgr_create_final( SESSION *sess, OBJECT *obj, CK_OBJECT_HANDLE *handle ); CK_RV object_mgr_create_skel( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_ULONG mode, CK_ULONG class, CK_ULONG subclass, OBJECT ** obj ); CK_RV object_mgr_destroy_object( SESSION * sess, CK_OBJECT_HANDLE handle ); CK_RV object_mgr_destroy_token_objects( void ); CK_RV object_mgr_find_in_map_nocache( CK_OBJECT_HANDLE handle, OBJECT ** ptr ); CK_RV object_mgr_find_in_map1( CK_OBJECT_HANDLE handle, OBJECT ** ptr ); CK_RV object_mgr_find_in_map2( OBJECT * ptr, CK_OBJECT_HANDLE * handle ); CK_RV object_mgr_find_init( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ); CK_RV object_mgr_find_build_list( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, DL_NODE * obj_list, CK_BBOOL public_only ); CK_RV object_mgr_find_final( SESSION *sess ); CK_RV object_mgr_get_attribute_values( SESSION * sess, CK_OBJECT_HANDLE handle, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ); CK_RV object_mgr_get_object_size( CK_OBJECT_HANDLE handle, CK_ULONG * size ); CK_BBOOL object_mgr_invalidate_handle1( CK_OBJECT_HANDLE handle ); CK_BBOOL object_mgr_invalidate_handle2( OBJECT *obj ); CK_BBOOL object_mgr_purge_session_objects( SESSION * sess, SESS_OBJ_TYPE type ); CK_BBOOL object_mgr_purge_token_objects( void ); CK_BBOOL object_mgr_purge_private_token_objects( void ); CK_RV object_mgr_remove_from_map( CK_OBJECT_HANDLE handle ); CK_RV object_mgr_restore_obj( CK_BYTE *data, OBJECT *oldObj ); CK_RV object_mgr_set_attribute_values( SESSION * sess, CK_OBJECT_HANDLE handle, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ); // SAB FIXME FIXME CK_BBOOL object_mgr_purge_map( SESSION * sess, SESS_OBJ_TYPE type ); // object routines // CK_RV object_create( CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, OBJECT ** obj ); CK_RV object_create_skel( CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_ULONG mode, CK_ULONG class, CK_ULONG subclass, OBJECT ** key ); CK_RV object_copy( CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, OBJECT * old_obj, OBJECT ** new_obj ); CK_RV object_flatten( OBJECT * obj, CK_BYTE ** data, CK_ULONG * len ); CK_BBOOL object_free( OBJECT *obj ); CK_RV object_get_attribute_values( OBJECT * obj, CK_ATTRIBUTE * pTemplate, CK_ULONG count ); CK_ULONG object_get_size( OBJECT *obj ); CK_RV object_restore( CK_BYTE * data, OBJECT ** obj, CK_BBOOL replace ); CK_RV object_set_attribute_values( OBJECT * obj, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ); CK_BBOOL object_is_modifiable ( OBJECT * obj ); CK_BBOOL object_is_private ( OBJECT * obj ); CK_BBOOL object_is_public ( OBJECT * obj ); CK_BBOOL object_is_token_object ( OBJECT * obj ); CK_BBOOL object_is_session_object( OBJECT * obj ); CK_BBOOL is_attribute_defined( CK_ATTRIBUTE_TYPE type ); // object attribute template routines // CK_RV template_add_attributes( TEMPLATE * tmpl, CK_ATTRIBUTE * attr, CK_ULONG ulCount ); CK_RV template_add_default_attributes( TEMPLATE * tmpl, CK_ULONG class, CK_ULONG subclass, CK_ULONG mode ); CK_BBOOL template_attribute_find( TEMPLATE * tmpl, CK_ATTRIBUTE_TYPE type, CK_ATTRIBUTE ** attr); void template_attribute_find_multiple( TEMPLATE *tmpl, ATTRIBUTE_PARSE_LIST *parselist, CK_ULONG plcount ); CK_BBOOL template_check_exportability( TEMPLATE *tmpl, CK_ATTRIBUTE_TYPE type ); CK_RV template_check_required_attributes( TEMPLATE * tmpl, CK_ULONG class, CK_ULONG subclass, CK_ULONG mode ); CK_RV template_check_required_base_attributes( TEMPLATE * tmpl, CK_ULONG mode ); CK_BBOOL template_compare( CK_ATTRIBUTE * t1, CK_ULONG ulCount, TEMPLATE * t2 ); CK_RV template_copy( TEMPLATE * dest, TEMPLATE * src ); CK_RV template_flatten( TEMPLATE * tmpl, CK_BYTE * dest ); CK_RV template_free( TEMPLATE *tmpl ); CK_BBOOL template_get_class( TEMPLATE * tmpl, CK_ULONG * class, CK_ULONG * subclass ); CK_ULONG template_get_count( TEMPLATE *tmpl ); CK_ULONG template_get_size( TEMPLATE *tmpl ); CK_ULONG template_get_compressed_size( TEMPLATE *tmpl ); CK_RV template_set_default_common_attributes( TEMPLATE *tmpl ); CK_RV template_merge( TEMPLATE *dest, TEMPLATE **src ); CK_RV template_update_attribute( TEMPLATE * tmpl, CK_ATTRIBUTE * attr ); CK_RV template_unflatten( TEMPLATE ** tmpl, CK_BYTE * data, CK_ULONG count ); CK_RV template_validate_attribute( TEMPLATE * tmpl, CK_ATTRIBUTE * attr, CK_ULONG class, CK_ULONG subclass, CK_ULONG mode ); CK_RV template_validate_attributes( TEMPLATE * tmpl, CK_ULONG class, CK_ULONG subclass, CK_ULONG mode ); CK_RV template_validate_base_attribute( TEMPLATE * tmpl, CK_ATTRIBUTE * attr, CK_ULONG mode ); // DATA OBJECT ROUTINES // CK_RV data_object_check_required_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV data_object_set_default_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV data_object_validate_attribute ( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // CERTIFICATE ROUTINES // CK_RV cert_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cert_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV cert_x509_check_required_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cert_x509_set_default_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cert_x509_validate_attribute ( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV cert_vendor_check_required_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cert_vendor_validate_attribute ( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // // KEY ROUTINES // CK_RV key_object_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV key_object_set_default_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV key_object_validate_attribute ( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV publ_key_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV publ_key_set_default_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV publ_key_validate_attribute ( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV priv_key_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV priv_key_set_default_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV priv_key_unwrap( TEMPLATE *tmpl, CK_ULONG keytype, CK_BYTE *data, CK_ULONG data_len ); CK_RV priv_key_validate_attribute ( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_BBOOL secret_key_check_exportability( CK_ATTRIBUTE_TYPE type ); CK_RV secret_key_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV secret_key_set_default_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV secret_key_unwrap( TEMPLATE *tmpl, CK_ULONG keytype, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ); CK_RV secret_key_validate_attribute ( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // rsa routines // CK_RV rsa_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rsa_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV rsa_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_BBOOL rsa_priv_check_exportability( CK_ATTRIBUTE_TYPE type ); CK_RV rsa_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rsa_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rsa_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV rsa_priv_wrap_get_data( TEMPLATE *tmpl, CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ); CK_RV rsa_priv_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len ); // dsa routines // CK_RV dsa_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dsa_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dsa_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_BBOOL dsa_priv_check_exportability( CK_ATTRIBUTE_TYPE type ); CK_RV dsa_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dsa_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dsa_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV dsa_priv_wrap_get_data( TEMPLATE *tmpl, CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ); CK_RV dsa_priv_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len ); // ecdsa routines // CK_RV ecdsa_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV ecdsa_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV ecdsa_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_BBOOL ecdsa_priv_check_exportability( CK_ATTRIBUTE_TYPE type ); CK_RV ecdsa_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV ecdsa_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV ecdsa_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // diffie-hellman routines // CK_RV dh_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dh_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dh_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_BBOOL dh_priv_check_exportability( CK_ATTRIBUTE_TYPE type ); CK_RV dh_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dh_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dh_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // KEA routines // CK_RV kea_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV kea_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV kea_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_BBOOL kea_priv_check_exportability( CK_ATTRIBUTE_TYPE type ); CK_RV kea_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV kea_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV kea_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // Generic secret key routines CK_RV generic_secret_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV generic_secret_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV generic_secret_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV generic_secret_wrap_get_data( TEMPLATE *tmpl, CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ); CK_RV generic_secret_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ); // RC2 routines CK_RV rc2_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rc2_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rc2_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // RC4 routines CK_RV rc4_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rc4_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rc4_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // RC5 routines CK_RV rc5_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rc5_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rc5_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // DES routines CK_RV des_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_BBOOL des_check_weak_key( CK_BYTE *key ); CK_RV des_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV des_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ); CK_RV des_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV des_wrap_get_data( TEMPLATE *tmpl, CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ); // DES2 routines CK_RV des2_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV des2_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV des2_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // DES3 routines CK_RV des3_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV des3_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV des3_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ); CK_RV des3_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV des3_wrap_get_data( TEMPLATE *tmpl, CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ); // AES routines CK_RV aes_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV aes_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV aes_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ); CK_RV aes_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV aes_wrap_get_data( TEMPLATE *tmpl, CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ); // CAST routines CK_RV cast_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cast_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cast_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // CAST3 routines CK_RV cast3_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cast3_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cast3_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // CAST5 routines CK_RV cast5_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cast5_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cast5_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // IDEA routines CK_RV idea_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV idea_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV idea_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // CDMF routines CK_RV cdmf_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cdmf_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cdmf_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // SKIPJACK routines CK_RV skipjack_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV skipjack_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV skipjack_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // BATON routines CK_RV baton_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV baton_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV baton_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // JUNIPER routines CK_RV juniper_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV juniper_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV juniper_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // modular math routines // CK_RV mp_subtract( CK_BYTE *bigint, CK_ULONG val, CK_ULONG len ); CK_RV mp_mult( CK_BYTE *bigint_a, CK_ULONG a_len, CK_BYTE *bigint_b, CK_ULONG b_len, CK_BYTE *bigint_c, CK_ULONG c_len, CK_BYTE *result, CK_ULONG *result_len ); CK_RV mp_exp( CK_BYTE *bigint_a, CK_ULONG a_len, CK_BYTE *bigint_b, CK_ULONG b_len, CK_BYTE *bigint_c, CK_ULONG c_len, CK_BYTE *result, CK_ULONG *result_len ); // ASN.1 routines // CK_ULONG ber_encode_INTEGER( CK_BBOOL length_only, CK_BYTE ** ber_int, CK_ULONG * ber_int_len, CK_BYTE * data, CK_ULONG data_len ); CK_RV ber_decode_INTEGER( CK_BYTE * ber_int, CK_BYTE ** data, CK_ULONG * data_len, CK_ULONG * field_len ); CK_RV ber_encode_OCTET_STRING( CK_BBOOL length_only, CK_BYTE ** str, CK_ULONG * str_len, CK_BYTE * data, CK_ULONG data_len ); CK_RV ber_decode_OCTET_STRING( CK_BYTE * str, CK_BYTE ** data, CK_ULONG * data_len, CK_ULONG * field_len ); CK_RV ber_encode_SEQUENCE( CK_BBOOL length_only, CK_BYTE ** seq, CK_ULONG * seq_len, CK_BYTE * data, CK_ULONG data_len ); CK_RV ber_decode_SEQUENCE( CK_BYTE * seq, CK_BYTE ** data, CK_ULONG * data_len, CK_ULONG * field_len ); CK_RV ber_encode_PrivateKeyInfo( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len, CK_BYTE * algorithm_id, CK_ULONG algorithm_id_len, CK_BYTE * priv_key, CK_ULONG priv_key_len ); CK_RV ber_decode_PrivateKeyInfo( CK_BYTE * data, CK_ULONG data_len, CK_BYTE ** algorithm_id, CK_ULONG * alg_len, CK_BYTE ** priv_key ); CK_RV ber_encode_RSAPrivateKey( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len, CK_ATTRIBUTE * modulus, CK_ATTRIBUTE * publ_exp, #if 0 CK_ATTRIBUTE * priv_exp, CK_ATTRIBUTE * prime1, CK_ATTRIBUTE * prime2, CK_ATTRIBUTE * exponent1, CK_ATTRIBUTE * exponent2, CK_ATTRIBUTE * coeff ); #else CK_ATTRIBUTE * opaque ); #endif CK_RV ber_decode_RSAPrivateKey( CK_BYTE * data, CK_ULONG data_len, CK_ATTRIBUTE ** modulus, CK_ATTRIBUTE ** publ_exp, #if 0 CK_ATTRIBUTE ** priv_exp, CK_ATTRIBUTE ** prime1, CK_ATTRIBUTE ** prime2, CK_ATTRIBUTE ** exponent1, CK_ATTRIBUTE ** exponent2, CK_ATTRIBUTE ** coeff ); #else CK_ATTRIBUTE ** opaque ); #endif CK_RV ber_encode_DSAPrivateKey( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len, CK_ATTRIBUTE * prime1, CK_ATTRIBUTE * prime2, CK_ATTRIBUTE * base, CK_ATTRIBUTE * priv_key ); CK_RV ber_decode_DSAPrivateKey( CK_BYTE * data, CK_ULONG data_len, CK_ATTRIBUTE ** prime, CK_ATTRIBUTE ** subprime, CK_ATTRIBUTE ** base, CK_ATTRIBUTE ** priv_key ); #include "tok_spec_struct.h" extern token_spec_t token_specific; #if (LEEDS_BUILD) #pragma options align=full #endif /* logging */ /* log to stdout */ #define LogMessage(dest, priority, layer, fmt, ...) \ do { \ fprintf(dest, "%s %s %s:%d " fmt "\n", priority, layer, __FILE__, __LINE__, ## __VA_ARGS__); \ } while (0) #define LogMessage1(dest, priority, layer, data) \ do { \ fprintf(dest, "%s %s %s:%d %s\n", priority, layer, __FILE__, __LINE__, data); \ } while (0) /* Debug logging */ #ifdef DEBUG #define LogDebug(fmt, ...) LogMessage(stdout, "LOG_DEBUG", STDLL_NAME, fmt, ##__VA_ARGS__) #define LogDebug1(data) LogMessage1(stdout, "LOG_DEBUG", STDLL_NAME, data) /* Error logging */ #define LogError(fmt, ...) LogMessage(stderr, "LOG_ERR", STDLL_NAME, "ERROR: " fmt, ##__VA_ARGS__) #define LogError1(data) LogMessage1(stderr, "LOG_ERR", STDLL_NAME, "ERROR: " data) /* Warn logging */ #define LogWarn(fmt, ...) LogMessage(stdout, "LOG_WARNING", STDLL_NAME, "WARNING: " fmt, ##__VA_ARGS__) #define LogWarn1(data) LogMessage1(stdout, "LOG_WARNING", STDLL_NAME, "WARNING: " data) /* Info Logging */ #define LogInfo(fmt, ...) LogMessage(stdout, "LOG_INFO", STDLL_NAME, fmt, ##__VA_ARGS__) #define LogInfo1(data) LogMessage1(stdout, "LOG_INFO", STDLL_NAME, data) #define st_err_log(num, ...) LogMessage(stderr, "ERROR", STDLL_NAME, "%s", err_msg[num].msg) #else #define LogDebug(...) do { } while (0) #define LogDebug1(...) do { } while (0) #define LogBlob(...) do { } while (0) #define LogError(...) do { } while (0) #define LogError1(...) do { } while (0) #define LogWarn(...) do { } while (0) #define LogWarn1(...) do { } while (0) #define LogInfo(...) do { } while (0) #define LogInfo1(...) do { } while (0) #define st_err_log(...) do { } while (0) #endif /* CKA_HIDDEN will be used to filter return results on a C_FindObjects call. * Used for objects internal to a token for management of that token */ #define CKA_HIDDEN CKA_VENDOR_DEFINED + 0x01000000 CK_RV sw_des3_cbc(CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_BYTE *, CK_BYTE); #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/mech_aes.c0000640000175000017500000013634311327631345021276 0ustar jfjf/* * Licensed materials, Property of IBM Corp. * * openCryptoki CCA token * * (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2006 * */ // File: mech_aes.c // // Mechanisms for AES // #include // for memcmp() et al #include #include "cca_stdll.h" #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" #ifndef NOAES // // CK_RV aes_ecb_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (in_data_len % AES_BLOCK_SIZE != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // We have to use ulValueLen here, since with AES we don't // know how large the key is. memcpy( key_value, attr->pValue, attr->ulValueLen ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_aes_ecb_encrypt( in_data, in_data_len, out_data, out_data_len, key_value, attr->ulValueLen ); } // // CK_RV aes_ecb_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES3_ECB requires the input data to be an integral // multiple of the block size // if (in_data_len % AES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_aes_ecb_decrypt( in_data, in_data_len, out_data, out_data_len, key_value, attr->ulValueLen ); } // // CK_RV aes_cbc_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES3_CBC requires the input data to be an integral // multiple of the block size // if (in_data_len % AES_BLOCK_SIZE != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_aes_cbc_encrypt( in_data, in_data_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); } // // CK_RV aes_cbc_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES3_CBC requires the input data to be an integral // multiple of the block size // if (in_data_len % AES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_aes_cbc_decrypt( in_data, in_data_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); } // // CK_RV aes_cbc_pad_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE *clear = NULL; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_ULONG padded_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // DES3-CBC-PAD has no input length requirements // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // compute the output length, accounting for padding // padded_len = AES_BLOCK_SIZE * (in_data_len / AES_BLOCK_SIZE + 1); if (length_only == TRUE) { *out_data_len = padded_len; return CKR_OK; } if (*out_data_len < padded_len) { *out_data_len = padded_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } clear = (CK_BYTE *)malloc( padded_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( clear, in_data, in_data_len ); add_pkcs_padding( clear + in_data_len, AES_BLOCK_SIZE, in_data_len, padded_len ); rc = ckm_aes_cbc_encrypt( clear, padded_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc != CKR_OK) st_err_log(105, __FILE__, __LINE__); free( clear ); return rc; } // // CK_RV aes_cbc_pad_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE *clear = NULL; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_ULONG padded_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // no need to validate the input length since we'll pad as necessary // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // we're decrypting so even with CBC-PAD, we should have an integral // number of block to decrypt // if (in_data_len % AES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } // the amount of cleartext after stripping the padding will actually be less // than the input bytes... // padded_len = in_data_len; if (length_only == TRUE) { *out_data_len = padded_len; return CKR_OK; } clear = (CK_BYTE *)malloc( padded_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } rc = ckm_aes_cbc_decrypt( in_data, in_data_len, clear, &padded_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc == CKR_OK) { strip_pkcs_padding( clear, padded_len, out_data_len ); memcpy( out_data, clear, *out_data_len ); } else st_err_log(106, __FILE__, __LINE__); free( clear ); return rc; } // // CK_RV aes_ecb_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (AES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < AES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % AES_BLOCK_SIZE); out_len = (total - remain); // should always be at least 1 block if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); rc = ckm_aes_ecb_encrypt( clear, out_len, out_data, out_data_len, key_value, attr->ulValueLen ); if (rc == CKR_OK) { *out_data_len = out_len; // update the context buffer. we already used the buffer's current // contents so we completely overwrite it // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } free( clear ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // shouldn't reach this } // // CK_RV aes_ecb_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (AES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < AES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % AES_BLOCK_SIZE); out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_aes_ecb_decrypt( cipher, out_len, out_data, out_data_len, key_value, attr->ulValueLen ); if (rc == CKR_OK) { *out_data_len = out_len; // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(105, __FILE__, __LINE__); free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // shouldn't reach this } // // CK_RV aes_cbc_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (AES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < AES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % AES_BLOCK_SIZE); out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // these buffers need to be longword aligned // clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); rc = ckm_aes_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc == CKR_OK) { *out_data_len = out_len; // the new init_v is the last encrypted data block // memcpy( ctx->mech.pParameter, out_data + (*out_data_len - AES_BLOCK_SIZE), AES_BLOCK_SIZE ); // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(105, __FILE__, __LINE__); free( clear ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV aes_cbc_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (AES_CONTEXT *)ctx->context; total = context->len + in_data_len; if (total < AES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = total % AES_BLOCK_SIZE; out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // these buffers need to be longword aligned // cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_aes_cbc_decrypt( cipher, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc == CKR_OK) { *out_data_len = out_len; // the new init_v is the last input data block // memcpy( ctx->mech.pParameter, cipher + (out_len - AES_BLOCK_SIZE), AES_BLOCK_SIZE ); // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(106, __FILE__, __LINE__); free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV aes_cbc_pad_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (AES_CONTEXT *)ctx->context; total = (context->len + in_data_len); // note, this is subtly different from the other encrypt update routines // if (total <= AES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { remain = (total % AES_BLOCK_SIZE); out_len = total - remain; // out_len is a multiple of DES_BLOCK_SIZE if (remain == 0) { remain = AES_BLOCK_SIZE; out_len -= AES_BLOCK_SIZE; } if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } // at this point, we should have: // 1) remain != 0 // 2) out_len != 0 // rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // these buffers need to be longword aligned // clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); // // we don't do padding during the update // rc = ckm_aes_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc == CKR_OK) { // the new init_v is the last encrypted data block // memcpy( ctx->mech.pParameter, out_data + (*out_data_len - AES_BLOCK_SIZE), AES_BLOCK_SIZE ); // copy the remaining 'new' input data to the temporary space // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } free( clear ); return rc; } } // // CK_RV aes_cbc_pad_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (AES_CONTEXT *)ctx->context; total = (context->len + in_data_len); // note, this is subtly different from the other decrypt update routines // if (total <= AES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block + 1 byte // remain = total % AES_BLOCK_SIZE; out_len = total - remain; if (remain == 0) { remain = AES_BLOCK_SIZE; out_len -= AES_BLOCK_SIZE; } if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } // at this point, we should have: // 1) remain != 0 // 2) out_len != 0 // rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // these buffers need to be longword aligned // cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_aes_cbc_decrypt( cipher, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc == CKR_OK) { // the new init_v is the last input data block // memcpy( ctx->mech.pParameter, cipher + (out_len - AES_BLOCK_SIZE), AES_BLOCK_SIZE ); // copy the remaining 'new' input data to the temporary space // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV aes_ecb_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (AES_CONTEXT *)ctx->context; // DES3-ECB does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV aes_ecb_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (AES_CONTEXT *)ctx->context; // DES3-ECB does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV aes_cbc_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (AES_CONTEXT *)ctx->context; // DES3-CBC does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV aes_cbc_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (AES_CONTEXT *)ctx->context; if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV aes_cbc_pad_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT *context = NULL; OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE clear[2*AES_BLOCK_SIZE]; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_ULONG out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); context = (AES_CONTEXT *)ctx->context; // there will never be more than one block in the context buffer // so the amount of output is as follows: // if less than 1 block stored, we generate one block of output // if a full block is stored, we generate two blocks of output (one pad block) // if (context->len == AES_BLOCK_SIZE) out_len = 2 * AES_BLOCK_SIZE; else out_len = AES_BLOCK_SIZE; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } else { memcpy( clear, context->data, context->len ); add_pkcs_padding( clear + context->len, AES_BLOCK_SIZE, context->len, out_len ); rc = ckm_aes_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc != CKR_OK) st_err_log(105, __FILE__, __LINE__); return rc; } } // // CK_RV aes_cbc_pad_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT *context = NULL; OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE clear[AES_BLOCK_SIZE]; CK_BYTE key_value[CCA_KEY_ID_SIZE]; CK_KEY_TYPE keytype; CK_ULONG out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); context = (AES_CONTEXT *)ctx->context; // there had better be a full block in the context buffer // if (context->len != AES_BLOCK_SIZE){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } // we don't know a priori how much data we'll be returning. we won't // know until after we decrypt it and strip the padding. it's possible // that we'll return nothing (the final block might be a padding block). // out_len = AES_BLOCK_SIZE; // upper bound on what we'll return if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } else { rc = ckm_aes_cbc_decrypt( context->data, AES_BLOCK_SIZE, clear, &out_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc == CKR_OK) { strip_pkcs_padding( clear, out_len, &out_len ); if (out_len != 0) memcpy( out_data, clear, out_len ); *out_data_len = out_len; } else st_err_log(106, __FILE__, __LINE__); return rc; } } // // mechanisms // // // CK_RV ckm_aes_key_gen( TEMPLATE *tmpl ) { CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * key_type_attr = NULL; CK_ATTRIBUTE * class_attr = NULL; CK_ATTRIBUTE * local_attr = NULL; CK_ATTRIBUTE * val_len_attr = NULL; CK_BYTE * aes_key = NULL; CK_ULONG rc = CKR_OK; CK_ULONG key_size; CK_BBOOL found = FALSE; found = template_attribute_find( tmpl, CKA_VALUE_LEN, &val_len_attr ); if (found == FALSE) return CKR_TEMPLATE_INCONSISTENT; key_size = *(CK_ULONG *)val_len_attr->pValue; if (key_size != AES_KEY_SIZE_128 && key_size != AES_KEY_SIZE_192 && key_size != AES_KEY_SIZE_256) { return CKR_ATTRIBUTE_VALUE_INVALID; } if ((aes_key = (CK_BYTE *)malloc(CCA_KEY_ID_SIZE)) == NULL) { st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } rc = token_specific.t_aes_key_gen(aes_key, key_size); if (rc != CKR_OK) return rc; value_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + CCA_KEY_ID_SIZE ); key_type_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); class_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS) ); local_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!value_attr || !key_type_attr || !class_attr || !local_attr) { if (value_attr) free( value_attr ); if (key_type_attr) free( key_type_attr ); if (class_attr) free( class_attr ); if (local_attr) free( local_attr ); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = CCA_KEY_ID_SIZE; value_attr->pValue = (CK_BYTE *)value_attr + sizeof(CK_ATTRIBUTE); memcpy( value_attr->pValue, aes_key, CCA_KEY_ID_SIZE ); free(aes_key); key_type_attr->type = CKA_KEY_TYPE; key_type_attr->ulValueLen = sizeof(CK_KEY_TYPE); key_type_attr->pValue = (CK_BYTE *)key_type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)key_type_attr->pValue = CKK_AES; class_attr->type = CKA_CLASS; class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS); class_attr->pValue = (CK_BYTE *)class_attr + sizeof(CK_ATTRIBUTE); *(CK_OBJECT_CLASS *)class_attr->pValue = CKO_SECRET_KEY; local_attr->type = CKA_LOCAL; local_attr->ulValueLen = sizeof(CK_BBOOL); local_attr->pValue = (CK_BYTE *)local_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)local_attr->pValue = TRUE; template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, key_type_attr ); template_update_attribute( tmpl, class_attr ); template_update_attribute( tmpl, local_attr ); return CKR_OK; } // // CK_RV ckm_aes_ecb_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * key_value, CK_ULONG key_len ) { CK_ULONG rc; if (!in_data || !out_data || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_aes_ecb(in_data,in_data_len, out_data,out_data_len, key_value,key_len,1); if (rc != CKR_OK) st_err_log(120, __FILE__, __LINE__); return rc; } // // CK_RV ckm_aes_ecb_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * key_value, CK_ULONG key_len ) { CK_ULONG rc; if (!in_data || !out_data || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_aes_ecb(in_data,in_data_len, out_data,out_data_len, key_value,key_len,0); if (rc != CKR_OK) st_err_log(120, __FILE__, __LINE__); return rc; } // // CK_RV ckm_aes_cbc_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * init_v, CK_BYTE * key_value, CK_ULONG key_len ) { CK_ULONG rc; if (!in_data || !out_data || !init_v || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ #if 0 st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; #else *out_data_len = in_data_len; st_err_log(68, __FILE__, __FUNCTION__); return CKR_BUFFER_TOO_SMALL; #endif } rc = token_specific.t_aes_cbc(in_data, in_data_len, out_data,out_data_len, key_value,key_len, init_v,1); if (rc != CKR_OK) st_err_log(119, __FILE__, __LINE__); return rc; } // // CK_RV ckm_aes_cbc_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * init_v, CK_BYTE * key_value, CK_ULONG key_len ) { CK_ULONG rc; if (!in_data || !out_data || !init_v || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_aes_cbc(in_data, in_data_len, out_data, out_data_len, key_value,key_len, init_v,0); if (rc != CKR_OK) st_err_log(119, __FILE__, __LINE__); return rc; } // // CK_RV ckm_aes_wrap_format( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len ) { CK_BYTE * ptr = NULL; CK_ULONG len1, len2; len1 = *data_len; // if the input key data isn't a multiple of the blocksize, // we pad with NULLs to the next blocksize multiple. // if (len1 % AES_BLOCK_SIZE != 0) { len2 = AES_BLOCK_SIZE * ((len1 / AES_BLOCK_SIZE) + 1); if (length_only == FALSE) { ptr = (CK_BYTE *)realloc(*data, 64); if (!ptr){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } else memset( ptr + len1, 0x0, (len2 - len1) ); *data = ptr; *data_len = len2; } } return CKR_OK; } #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/sign_mgr.c0000640000175000017500000004771111327631345021337 0ustar jfjf/* * Licensed materials, Property of IBM Corp. * * openCryptoki CCA token * * (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2006 * */ // File: sign_mgr.c // // Signature manager routines // #include #include // for memcmp() et al #include #include "cca_stdll.h" #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // // CK_RV sign_mgr_init( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_MECHANISM * mech, CK_BBOOL recover_mode, CK_OBJECT_HANDLE key ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_KEY_TYPE keytype; CK_OBJECT_CLASS class; CK_BBOOL flag; CK_RV rc; if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active != FALSE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } // key usage restrictions // rc = object_mgr_find_in_map1( key, &key_obj ); if (rc != CKR_OK){ st_err_log(18, __FILE__, __LINE__); return CKR_KEY_HANDLE_INVALID; } // is key allowed to generate signatures? // rc = template_attribute_find( key_obj->template, CKA_SIGN, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { flag = *(CK_BBOOL *)attr->pValue; if (flag != TRUE){ st_err_log(85, __FILE__, __LINE__); return CKR_KEY_FUNCTION_NOT_PERMITTED; } } // is the mechanism supported? is the key type correct? is a // parameter present if required? is the key size allowed? // is the key allowed to generate signatures? // switch (mech->mechanism) { case CKM_RSA_X_509: case CKM_RSA_PKCS: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_RSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // must be a PRIVATE key // flag = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (flag == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else class = *(CK_OBJECT_CLASS *)attr->pValue; // if it's not a private RSA key then we have an internal failure...means // that somehow a public key got assigned a CKA_SIGN attribute // if (class != CKO_PRIVATE_KEY){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } // PKCS #11 doesn't allow multi-part RSA operations // ctx->context_len = 0; ctx->context = NULL; } break; #if !(NOMD2) case CKM_MD2_RSA_PKCS: #endif case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_RSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // must be a PRIVATE key operation // flag = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else class = *(CK_OBJECT_CLASS *)attr->pValue; if (class != CKO_PRIVATE_KEY){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } ctx->context_len = sizeof(RSA_DIGEST_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(RSA_DIGEST_CONTEXT)); if (!ctx->context){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(RSA_DIGEST_CONTEXT)); } break; #if !(NODSA) case CKM_DSA: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // must be a PRIVATE key // flag = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (flag == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else class = *(CK_OBJECT_CLASS *)attr->pValue; // if it's not a private RSA key then we have an internal failure...means // that somehow a public key got assigned a CKA_SIGN attribute // if (class != CKO_PRIVATE_KEY){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } // PKCS #11 doesn't allow multi-part DSA operations // ctx->context_len = 0; ctx->context = NULL; } break; #endif #if !(NOMD2) case CKM_MD2_HMAC: #endif case CKM_MD5_HMAC: case CKM_SHA_1_HMAC: case CKM_SHA256_HMAC: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_GENERIC_SECRET){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // PKCS #11 doesn't allow multi-part HMAC operations // ctx->context_len = 0; ctx->context = NULL; } break; #if !(NOMD2) case CKM_MD2_HMAC_GENERAL: #endif case CKM_MD5_HMAC_GENERAL: case CKM_SHA_1_HMAC_GENERAL: case CKM_SHA256_HMAC_GENERAL: { CK_MAC_GENERAL_PARAMS *param = (CK_MAC_GENERAL_PARAMS *)mech->pParameter; if (mech->ulParameterLen != sizeof(CK_MAC_GENERAL_PARAMS)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } #if !(NOMD2) if ((mech->mechanism == CKM_MD2_HMAC_GENERAL) && (*param > 16)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } #endif if ((mech->mechanism == CKM_MD5_HMAC_GENERAL) && (*param > 16)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } if ((mech->mechanism == CKM_SHA_1_HMAC_GENERAL) && (*param > 20)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } if ((mech->mechanism == CKM_SHA256_HMAC_GENERAL) && (*param > 32)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_GENERIC_SECRET){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // PKCS #11 doesn't allow multi-part HMAC operations // ctx->context_len = 0; ctx->context = NULL; } break; case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: { CK_MAC_GENERAL_PARAMS *param = (CK_MAC_GENERAL_PARAMS *)mech->pParameter; if (mech->ulParameterLen != sizeof(CK_MAC_GENERAL_PARAMS)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // FIXME - Netscape sets the parameter == 16. PKCS #11 limit is 8 // if (mech->mechanism == CKM_SSL3_MD5_MAC) { if (*param < 4 || *param > 16){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } } if (mech->mechanism == CKM_SSL3_SHA1_MAC) { if (*param < 4 || *param > 20){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } } rc = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { class = *(CK_OBJECT_CLASS *)attr->pValue; if (class != CKO_SECRET_KEY){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(SSL3_MAC_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(SSL3_MAC_CONTEXT)); if (!ctx->context){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(SSL3_MAC_CONTEXT)); } break; default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } if (mech->ulParameterLen > 0) { ptr = (CK_BYTE *)malloc(mech->ulParameterLen); if (!ptr){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( ptr, mech->pParameter, mech->ulParameterLen ); } ctx->key = key; ctx->mech.ulParameterLen = mech->ulParameterLen; ctx->mech.mechanism = mech->mechanism; ctx->mech.pParameter = ptr; ctx->multi = FALSE; ctx->active = TRUE; ctx->recover = recover_mode; return CKR_OK; } // // CK_RV sign_mgr_cleanup( SIGN_VERIFY_CONTEXT *ctx ) { if (!ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } ctx->key = 0; ctx->mech.ulParameterLen = 0; ctx->mech.mechanism = 0; ctx->multi = FALSE; ctx->active = FALSE; ctx->recover = FALSE; ctx->context_len = 0; if (ctx->mech.pParameter) { free( ctx->mech.pParameter ); ctx->mech.pParameter = NULL; } if (ctx->context) { free( ctx->context ); ctx->context = NULL; } return CKR_OK; } // // CK_RV sign_mgr_sign( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == TRUE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } // if the caller just wants the signature length, there is no reason to // specify the input data. I just need the input data length // if ((length_only == FALSE) && (!in_data || !out_data)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->multi == TRUE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } switch (ctx->mech.mechanism) { case CKM_RSA_PKCS: return rsa_pkcs_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #if 0 case CKM_RSA_X_509: return rsa_x509_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif #if !(NOMD2) case CKM_MD2_RSA_PKCS: #endif case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: return rsa_hash_pkcs_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #if !(NODSA) case CKM_DSA: return dsa_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif #if !(NOMD2) case CKM_MD2_HMAC: case CKM_MD2_HMAC_GENERAL: return md2_hmac_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif case CKM_MD5_HMAC: case CKM_MD5_HMAC_GENERAL: return md5_hmac_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_SHA_1_HMAC: case CKM_SHA_1_HMAC_GENERAL: return sha1_hmac_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_SHA256_HMAC: case CKM_SHA256_HMAC_GENERAL: return sha2_hmac_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: return ssl3_mac_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV sign_mgr_sign_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { if (!sess || !ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == TRUE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } ctx->multi = TRUE; switch (ctx->mech.mechanism) { #if !(NOMD2) case CKM_MD2_RSA_PKCS: #endif case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: return rsa_hash_pkcs_sign_update( sess, ctx, in_data, in_data_len ); case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: return ssl3_mac_sign_update( sess, ctx, in_data, in_data_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // // CK_RV sign_mgr_sign_final( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG * sig_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == TRUE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } switch (ctx->mech.mechanism) { #if !(NOMD2) case CKM_MD2_RSA_PKCS: #endif case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: return rsa_hash_pkcs_sign_final( sess, length_only, ctx, signature, sig_len ); case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: return ssl3_mac_sign_final( sess, length_only, ctx, signature, sig_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // // CK_RV sign_mgr_sign_recover( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } // if the caller just wants the signature length, there is no reason to // specify the input data. I just need the input data length // if ((length_only == FALSE) && (!in_data || !out_data)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->multi == TRUE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } switch (ctx->mech.mechanism) { case CKM_RSA_PKCS: // we can use the same sign mechanism to do sign-recover // return rsa_pkcs_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #if 0 case CKM_RSA_X_509: return rsa_x509_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/README.cca_stdll0000640000175000017500000000157711327631345022175 0ustar jfjf README for the CCA secure-key token Kent Yoder The key used to encrypt private objects on disk is a secure key. The key used to encrypt that secure key is based on the hash of the USER and SO pins. Therefore it is a clear key and software is used to do the encryption/decryption of the secure key. MK_USER: The secure key used for internal on-disk encryption, encrypted under the USER's PIN by software routines MK_SO: The secure key used for internal on-disk encryption, encrypted under the SO's PIN by software routines So, MK_USER and MK_SO contain the same key, encrypted under different PINs PKCS#11 Notes: DES/3DES PKCS#11 key objects have the CCA key identifier stored in the CKA_VALUE attribute. Usually the CKA_VALUE attribute would hold a plaintext key, however in this case, the id used to reference the secure key is stored here. opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/new_host.c0000640000175000017500000030653011327631345021355 0ustar jfjf/* * Licensed materials, Property of IBM Corp. * * openCryptoki CCA token * * (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2006 * * Author: Kent E. Yoder * */ /*************************************************************************** Change Log ========== 4/25/03 Kapil Sood (kapil@corrent.com) Added DH key pair generation and DH shared key derivation functions. ****************************************************************************/ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include "cca_stdll.h" #include "pkcs11types.h" #include "stdll.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" #include "pkcs32.h" #include "../api/apiproto.h" #define UCHAR unsigned char /* Declared in obj_mgr.c */ extern pthread_rwlock_t obj_list_rw_mutex; char *pk_dir; void SC_SetFunctionList(void); #define SESSION_MGR_FIND(x) session_mgr_find(x) /* All these need to * get the lock */ /* Maximum number of supported devices (rather arbitrary) */ #define PKW_MAX_DEVICES 10 // Netscape/SSL is fairly timing-sensitive so can't always use a debugger // // If the CRYPTOKI_DEBUG environment variable is defined, information // about each successful PKCS#11 call made is written to the file named // in that environment variable. // // If the CRYPTOKI_PROFILE environment variable is defined, information // about the amount of time spent in each PKCS#11 API during a "run" // // If the CRYPTOKI_DEBUG environment variable is defined, information // about each successful PKCS#11 call made is written to the file named // in that environment variable. // // If the CRYPTOKI_PROFILE environment variable is defined, information // about the amount of time spent in each PKCS#11 API during a "run" // (i.e., from _DLL_InitTerm init call to _DLL_InitTerm term call) is // appended to the file named in that environment variable. // // If the CRYPTOKI_STATS_FILE environment variable is defined, information // about various internal metrics at the end of a "run" is appended to // the file named in that environment variable. The CRYPTOKI_STATS // environment variable specifies the argument(s) that are passed to // the function that returns the metrics to specify which metric(s) are // returned. // #define MAXFILENAME 1024 static char *debugfilepathbuffer; static int debugon = 1; int debugfile = 0; #define FFLUSH(x) pid_t initedpid=0; // for initialized pid CK_ULONG usage_count = 0; // variable for number of times the DLL has // been used. CK_C_INITIALIZE_ARGS cinit_args = { NULL, NULL, NULL, NULL, 0, NULL }; extern void stlogterm(); extern void stloginit(); extern void stlogit2(int type,char *fmt, ...); CK_BBOOL st_Initialized() { if (initialized == FALSE ) return FALSE; return TRUE; } #ifdef SPINXPL extern int spinxplfd; extern int spin_created; #endif void Fork_Initializer(void) { stlogterm(); stloginit(); // Initialize Logging so we can capture // EVERYTHING #ifdef SPINXPL spinxplfd = -1; spin_created = 0; #endif // Force logout. This cleans out the private session and list // and cleans out the private object map session_mgr_logout_all(); // Clean out the public object map // First parm is no longer used.. object_mgr_purge_map((SESSION *)0xFFFF, PUBLIC); object_mgr_purge_map((SESSION *)0xFFFF, PRIVATE); // This should clear the entire session list out session_mgr_close_all_sessions(); next_session_handle = 1; // Make is so sessions start with 1 next_object_handle = 1; // Clean out the global login state variable // When implemented... Although logout_all should clear this up. // Once the object_map is flushed, the obj_lists (public and // private) are both just linked lists that have to be freed // up... //logit("%s:%d: tokenobj publ 0x%08x priv // 0x%08x",__FILE__,__LINE__,publ_token_obj_list, // priv_token_obj_list); while (priv_token_obj_list) { priv_token_obj_list = dlist_remove_node(priv_token_obj_list, priv_token_obj_list); } while (publ_token_obj_list) { publ_token_obj_list = dlist_remove_node(publ_token_obj_list, publ_token_obj_list); } // Need to do something to prevent the shared memory from // having the objects loaded again.... The most likely place // is in the obj_mgr file where the object is added to shared // memory (object_mgr_add_to_shm) a query should be done to // the appropriate object list.... } #ifdef ALLLOCK #define LOCKIT pthread_mutex_lock(&native_mutex) #define LLOCK #define UNLOCKIT pthread_mutex_unlock(&native_mutex) #else #ifdef DEBLOCK #define LOCKIT #define LLOCK pthread_mutex_lock(&native_mutex) #define UNLOCKIT pthread_mutex_unlock(&native_mutex) #else #define LOCKIT #define LLOCK #define UNLOCKIT #endif #endif int APISlot2Local(snum) CK_SLOT_ID snum; { return(token_specific.t_slot2local(snum)); } #define SLT_CHECK \ CK_SLOT_ID slot_id; \ int sid1; \ \ if ( (sid1 = APISlot2Local(sid)) != -1 ){ \ slot_id = sid1; \ } else { \ return CKR_ARGUMENTS_BAD; \ } #define SESSION_HANDLE sSession.sessionh #define SLOTID APISlot2Local(sSession.slotID) #define SESS_SET \ CK_SESSION_HANDLE hSession; \ \ hSession = sSession.sessionh; // More efficient long reverse inline CK_ULONG long_reverse(CK_ULONG x) { #ifdef _POWER // Power Architecture requires reversal to talk to adapter return ( ((0x000000FF & x)<<24) | ((0x0000FF00 & x)<<8) | ((0x00FF0000 & x)>>8) | ((0xFF000000 & x)>>24) ); #else return (x); // Others don't require reversal. #endif } // verify that the mech specified is in the // mech list for this token... Common code requires this // to be added CK_RV validate_mechanism(CK_MECHANISM_PTR pMechanism) { CK_ULONG i; for (i=0; i< mech_list_len;i++){ if (pMechanism->mechanism == mech_list[i].mech_type) { return CKR_OK; } } st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } #define VALID_MECH(p) \ if ( validate_mechanism(p) != CKR_OK){ \ rc = CKR_MECHANISM_INVALID; \ goto done; \ } \ // Defines to allow NT code to work correctly #define WaitForSingleObject(x,y) pthread_mutex_lock(&(x)) #define ReleaseMutex(x) pthread_mutex_unlock(&(x)) void init_data_store(char *directory) { char *pkdir; if ( (pkdir = getenv("PKCS_APP_STORE")) != NULL){ pk_dir = (char *) malloc(strlen(pkdir)+1024); memset(pk_dir, 0, strlen(pkdir)+1024); sprintf(pk_dir,"%s/%s",pkdir,SUB_DIR); } else { pk_dir = (char *)malloc(strlen(directory)+25); memset(pk_dir, 0, strlen(directory)+25); sprintf(pk_dir,"%s",directory); } } /* In an STDLL this is called once for each card in the system * therefore the initialized only flags certain one time things * However in the case of a lightened accelerator, the cards are all * agregated together in a single token. Therefore the correlator * should be a list of device names which have either the correct clu * or the crypt light adapter... */ CK_RV ST_Initialize(void **FunctionList, CK_SLOT_ID SlotNumber, char *Correlator) { int i; CK_RV rc = CKR_OK; struct passwd *pw,*epw; // SAB XXX XXX uid_t userid,euserid; stlogterm(); stloginit(); // Check for root user or Group PKCS#11 Membershp // Only these are allowed. userid = getuid(); euserid = geteuid(); if (userid != 0 && euserid != 0) { // Root or effective Root // is ok struct group *grp; int rc = 0; gid_t gid,egid; grp = getgrnam("pkcs11"); if (grp) { // Check for member of group.. // SAB get login seems to not work with some // instances of application invocations // (particularly when forked). So we need to // get the group informatiion. Really need to // take the uid and map it to a name. pw = getpwuid(userid); epw = getpwuid(euserid); gid = getgid(); egid = getegid(); if ( gid == grp->gr_gid || egid == grp->gr_gid){ rc = 1; } else { i = 0; while (grp->gr_mem[i]) { if (pw) { if (strncmp(pw->pw_name, grp->gr_mem[i], strlen(pw->pw_name)) == 0 ) { rc = 1; break; } } if (epw) { if (strncmp(epw->pw_name, grp->gr_mem[i], strlen(epw->pw_name)) == 0 ){ rc = 1; break; } } i++; } } if (rc == 0 ){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } else { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } // assume that the upper API prevents multiple calls of initialize // since that only happens on C_Initialize and that is the // resonsibility of the upper layer.. initialized = FALSE; /// So the rest of the code works correctly // If we're not already initialized, grab the mutex and do the // initialization. Check to see if another thread did so while we // were waiting... // // One of the things we do during initialization is create the mutex for // PKCS#11 operations; until we do so, we have to use the native mutex... // WaitForSingleObject( native_mutex, INFINITE ); // SAB need to call Fork_Initializer here // instead of at the end of the loop... // it may also need to call destroy of the following 3 mutexes.. // it may not matter... Fork_Initializer(); MY_CreateMutex( &pkcs_mutex ); MY_CreateMutex( &obj_list_mutex ); if (pthread_rwlock_init(&obj_list_rw_mutex, NULL)) { st_err_log(145, __FILE__, __LINE__); } MY_CreateMutex( &sess_list_mutex ); MY_CreateMutex( &login_mutex ); if ( (debugfilepathbuffer = getenv( "CRYPTOKI_DEBUG")) != NULL) { debugon=1; } init_data_store((char *)PK_DIR); // Handle global initialization issues first if we have not // been initialized. if (st_Initialized() == FALSE){ #if SYSVSEM xproclock = (void *)&xprocsemid; CreateXProcLock(xproclock); #endif if ( (rc = attach_shm()) != CKR_OK) { st_err_log(144, __FILE__, __LINE__); goto done; } nv_token_data = &global_shm->nv_token_data; stloginit(); initialized = TRUE; initedpid = getpid(); SC_SetFunctionList(); // Always call the token_specific_init function.... rc = token_specific.t_init(Correlator,SlotNumber); if (rc != 0) { // Zero means success, right?!? *FunctionList = NULL; st_err_log(145, __FILE__, __LINE__); goto done; } } // SAB XXX FIXME FIXME check return code... for all these... rc = load_token_data(); if (rc != CKR_OK) { *FunctionList = NULL; st_err_log(145, __FILE__, __LINE__); goto done; } load_public_token_objects(); XProcLock( xproclock ); global_shm->publ_loaded = TRUE; XProcUnLock( xproclock ); init_slotInfo(); usage_count++; (*FunctionList) = &function_list; done: ReleaseMutex( native_mutex ); if (rc != 0) st_err_log(145, __FILE__, __LINE__); return rc; } // What does this really have to do in this new token... probably // need to close the adapters that are opened, and clear the other // stuff CK_RV SC_Finalize( CK_SLOT_ID sid ) { CK_RV rc; SLT_CHECK; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } rc = MY_LockMutex( &pkcs_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return rc; } // If somebody else has taken care of things, leave... if (st_Initialized() == FALSE) { MY_UnlockMutex( &pkcs_mutex ); // ? Somebody else has // also destroyed the // mutex... st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } usage_count--; if (usage_count == 0){ initialized = FALSE; } session_mgr_close_all_sessions(); object_mgr_purge_token_objects(); detach_shm(); // close spin lock file if (spin_created) close(spinxplfd); if ( token_specific.t_final != NULL) { token_specific.t_final(); } rc = MY_UnlockMutex( &pkcs_mutex ); if (rc != CKR_OK){ st_err_log(147, __FILE__, __LINE__); return rc; } return CKR_OK; } void copy_token_contents_sensibly(CK_TOKEN_INFO_PTR pInfo, TOKEN_DATA *nv_token_data) { memcpy(pInfo, &nv_token_data->token_info, sizeof(CK_TOKEN_INFO_32)); pInfo->flags = nv_token_data->token_info.flags; if ( nv_token_data->token_info.ulMaxSessionCount == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulMaxSessionCount = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulMaxSessionCount = nv_token_data->token_info.ulMaxSessionCount; } if ( nv_token_data->token_info.ulSessionCount == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulSessionCount = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulSessionCount = nv_token_data->token_info.ulSessionCount; } if ( nv_token_data->token_info.ulMaxRwSessionCount == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulMaxRwSessionCount = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulMaxRwSessionCount = nv_token_data->token_info.ulMaxRwSessionCount; } if ( nv_token_data->token_info.ulRwSessionCount == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulRwSessionCount = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulRwSessionCount = nv_token_data->token_info.ulRwSessionCount; } pInfo->ulMaxPinLen = nv_token_data->token_info.ulMaxPinLen; pInfo->ulMinPinLen = nv_token_data->token_info.ulMinPinLen; if ( nv_token_data->token_info.ulTotalPublicMemory == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulTotalPublicMemory = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulTotalPublicMemory = nv_token_data->token_info.ulTotalPublicMemory; } if ( nv_token_data->token_info.ulFreePublicMemory == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulFreePublicMemory = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulFreePublicMemory = nv_token_data->token_info.ulFreePublicMemory; } if ( nv_token_data->token_info.ulTotalPrivateMemory == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulTotalPrivateMemory = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulTotalPrivateMemory = nv_token_data->token_info.ulTotalPrivateMemory; } if ( nv_token_data->token_info.ulFreePrivateMemory == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulFreePrivateMemory = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulFreePrivateMemory = nv_token_data->token_info.ulFreePrivateMemory; } pInfo->hardwareVersion = nv_token_data->token_info.hardwareVersion; pInfo->firmwareVersion = nv_token_data->token_info.firmwareVersion; pInfo->flags = long_reverse(pInfo->flags); pInfo->ulMaxSessionCount = long_reverse(pInfo->ulMaxSessionCount); pInfo->ulSessionCount = long_reverse(pInfo->ulSessionCount); pInfo->ulMaxRwSessionCount = long_reverse(pInfo->ulMaxRwSessionCount); pInfo->ulRwSessionCount = long_reverse(pInfo->ulRwSessionCount); pInfo->ulMaxPinLen = long_reverse(pInfo->ulMaxPinLen); pInfo->ulMinPinLen = long_reverse(pInfo->ulMinPinLen); pInfo->ulTotalPublicMemory = long_reverse(pInfo->ulTotalPublicMemory); pInfo->ulFreePublicMemory = long_reverse(pInfo->ulFreePublicMemory); pInfo->ulTotalPrivateMemory = long_reverse(pInfo->ulTotalPrivateMemory); pInfo->ulFreePrivateMemory = long_reverse(pInfo->ulFreePrivateMemory); } CK_RV SC_GetTokenInfo( CK_SLOT_ID sid, CK_TOKEN_INFO_PTR pInfo ) { CK_RV rc = CKR_OK; time_t now; SLT_CHECK; LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pInfo) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } if (slot_id > MAX_SLOT_ID) { st_err_log(2, __FILE__, __LINE__); rc = CKR_SLOT_ID_INVALID; goto done; } /* TODO: This should always be enabled; eliminate the PKCS64 flag */ #ifdef PKCS64 copy_token_contents_sensibly(pInfo, nv_token_data); #else memcpy( pInfo, &nv_token_data->token_info, sizeof(CK_TOKEN_INFO) ); #endif // Set the time now = time ((time_t *)NULL); strftime( (char *)pInfo->utcTime, 16, "%X", localtime(&now) ); done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x\n", "C_GetTokenInfo", rc ); } UNLOCKIT; return rc; } CK_RV SC_WaitForSlotEvent( CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved ) { if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } /** * For Netscape we want to not support the SSL3 mechs since the native * ones perform much better. Force those slots to be RSA... it's ugly * but it works. */ static void netscape_hack(CK_MECHANISM_TYPE_PTR mech_arr_ptr, CK_ULONG count) { char *envrn; CK_ULONG i; if ((envrn = getenv("NS_SERVER_HOME")) != NULL) { for (i = 0; i < count; i++){ switch (mech_arr_ptr[i]) { case CKM_SSL3_PRE_MASTER_KEY_GEN: case CKM_SSL3_MASTER_KEY_DERIVE: case CKM_SSL3_KEY_AND_MAC_DERIVE: case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: mech_arr_ptr[i] = CKM_RSA_PKCS; break; } } } } void mechanism_list_transformations(CK_MECHANISM_TYPE_PTR mech_arr_ptr, CK_ULONG_PTR count_ptr) { #ifndef NO_NETSCAPE_HACK netscape_hack(mech_arr_ptr, (*count_ptr)); #endif /* #ifndef NO_NETSCAPE_HACK */ } /** * Get the mechanism type list for the current token. */ CK_RV SC_GetMechanismList(CK_SLOT_ID sid, CK_MECHANISM_TYPE_PTR pMechList, CK_ULONG_PTR count) { CK_RV rc = CKR_OK; SLT_CHECK; LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto out; } if (count == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto out; } if (slot_id > MAX_SLOT_ID) { st_err_log(2, __FILE__, __LINE__); rc = CKR_SLOT_ID_INVALID; goto out; } if (!token_specific.t_get_mechanism_list) { st_err_log(4, __FILE__, __LINE__); rc = CKR_GENERAL_ERROR; goto out; } rc = token_specific.t_get_mechanism_list(pMechList, count); if (rc == CKR_OK) { /* To accomodate certain special cases, we may need to * make adjustments to the token's mechanism list. */ mechanism_list_transformations(pMechList, count); } out: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x, # mechanisms: %d\n", "C_GetMechanismList", rc, *count ); } UNLOCKIT; return rc; } /** * Get the mechanism info for the current type and token. */ CK_RV SC_GetMechanismInfo(CK_SLOT_ID sid, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo) { CK_RV rc = CKR_OK; SLT_CHECK; LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto out; } if (pInfo == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto out; } if (slot_id > MAX_SLOT_ID) { st_err_log(2, __FILE__, __LINE__); rc = CKR_SLOT_ID_INVALID; goto out; } if (!token_specific.t_get_mechanism_info) { st_err_log(4, __FILE__, __LINE__); rc = CKR_GENERAL_ERROR; goto out; } rc = token_specific.t_get_mechanism_info(type, pInfo); out: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x, mech type = 0x%08x\n", "C_GetMechanismInfo", rc, type ); } UNLOCKIT; return rc; } int delete_all_files_in_dir(char *full_dir_path) { return 0; } /* This routine should only be called if no other processes are * attached to the token. we need to somehow check that this is the * only process Meta API should prevent this since it knows session * states in the shared memory. */ CK_RV SC_InitToken( CK_SLOT_ID sid, CK_CHAR_PTR pPin, CK_ULONG ulPinLen, CK_CHAR_PTR pLabel ) { CK_RV rc = CKR_OK; int local_rc = 0; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_SLOT_ID slotID; char *s = NULL; char *pk_full_path = NULL; SLT_CHECK; slotID = slot_id; LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pPin || !pLabel) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } if (nv_token_data->token_info.flags & CKF_SO_PIN_LOCKED) { st_err_log(37, __FILE__, __LINE__); rc = CKR_PIN_LOCKED; goto done; } rc = compute_sha( pPin, ulPinLen, hash_sha ); if (memcmp(nv_token_data->so_pin_sha, hash_sha, SHA1_HASH_SIZE) != 0) { st_err_log(33, __FILE__, __LINE__); rc = CKR_PIN_INCORRECT; goto done; } rc = token_specific.t_des_key_gen( master_key, MASTER_KEY_SIZE, 3 * DES_KEY_SIZE ); if (rc != CKR_OK) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } // Before we reconstruct all the data, we should delete the // token objects from the filesystem. // // Construct a string to delete the token objects. // object_mgr_destroy_token_objects(); #if 0 /* TODO: Implement delete_all_files_in_dir() */ local_rc = asprintf(&pk_full_path, "%s/%s", pk_dir, PK_LITE_OBJ_DIR); if (local_rc == -1) { rc = CKR_HOST_MEMORY; goto out; } local_rc = delete_all_files_in_dir(pk_full_path); if (local_rc == -1) { rc = CKR_FUNCTION_FAILED; goto out; } #endif local_rc = asprintf(&s, "%s %s/%s/* > /dev/null 2>&1", DEL_CMD, pk_dir, PK_LITE_OBJ_DIR); if (local_rc == -1) { rc = CKR_HOST_MEMORY; goto out; } system(s); free(s); s = NULL; // META This should be fine since the open session checking // should occur at the API not the STDLL init_token_data(); init_slotInfo(); memcpy( nv_token_data->token_info.label, pLabel, 32 ); memcpy( nv_token_data->so_pin_sha, hash_sha, SHA1_HASH_SIZE); nv_token_data->token_info.flags |= CKF_TOKEN_INITIALIZED; rc = save_token_data(); if (rc != CKR_OK){ st_err_log(104, __FILE__, __LINE__, __FUNCTION__); goto done; } rc = save_masterkey_so(); if (rc != CKR_OK){ st_err_log(149, __FILE__, __LINE__, __FUNCTION__); goto done; } done: out: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x\n", "C_InitToken", rc ); } UNLOCKIT; if (pk_full_path) { free(pk_full_path); } return rc; } // // CK_RV SC_InitPIN( ST_SESSION_HANDLE sSession, CK_CHAR_PTR pPin, CK_ULONG ulPinLen ) { SESSION * sess = NULL; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_BYTE hash_md5[MD5_HASH_SIZE]; CK_RV rc = CKR_OK; SESS_SET; LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pPin) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_locked(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(37, __FILE__, __LINE__); rc = CKR_PIN_LOCKED; goto done; } if (sess->session_info.state != CKS_RW_SO_FUNCTIONS) { st_err_log(57, __FILE__, __LINE__); rc = CKR_USER_NOT_LOGGED_IN; goto done; } if ((ulPinLen < MIN_PIN_LEN) || (ulPinLen > MAX_PIN_LEN)) { st_err_log(35, __FILE__, __LINE__); rc = CKR_PIN_LEN_RANGE; goto done; } // compute the SHA and MD5 hashes of the user pin rc = compute_sha( pPin, ulPinLen, hash_sha ); rc |= compute_md5( pPin, ulPinLen, hash_md5 ); if (rc != CKR_OK){ st_err_log(148, __FILE__, __LINE__); goto done; } rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto done; } memcpy(nv_token_data->user_pin_sha, hash_sha, SHA1_HASH_SIZE); nv_token_data->token_info.flags |= CKF_USER_PIN_INITIALIZED; nv_token_data->token_info.flags &= ~(CKF_USER_PIN_TO_BE_CHANGED); nv_token_data->token_info.flags &= ~(CKF_USER_PIN_LOCKED); XProcUnLock(xproclock); memcpy( user_pin_md5, hash_md5, MD5_HASH_SIZE ); rc = save_token_data(); if (rc != CKR_OK){ st_err_log(104, __FILE__, __LINE__); goto done; } rc = save_masterkey_user(); if (rc != CKR_OK){ st_err_log(149, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: session = %08x\n", "C_InitPin", rc, hSession); } UNLOCKIT; return rc; } CK_RV SC_SetPIN( ST_SESSION_HANDLE sSession, CK_CHAR_PTR pOldPin, CK_ULONG ulOldLen, CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen ) { SESSION *sess = NULL; CK_BYTE old_hash_sha[SHA1_HASH_SIZE]; CK_BYTE new_hash_sha[SHA1_HASH_SIZE]; CK_BYTE hash_md5[MD5_HASH_SIZE]; CK_RV rc = CKR_OK; SESS_SET; LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_locked(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(37, __FILE__, __LINE__); rc = CKR_PIN_LOCKED; goto done; } if ((ulNewLen < MIN_PIN_LEN) || (ulNewLen > MAX_PIN_LEN)) { st_err_log(35, __FILE__, __LINE__); rc = CKR_PIN_LEN_RANGE; goto done; } rc = compute_sha( pOldPin, ulOldLen, old_hash_sha ); if (rc != CKR_OK){ st_err_log(148, __FILE__, __LINE__); goto done; } /* From the PKCS#11 2.20 spec: "C_SetPIN modifies the PIN of * the user that is currently logged in, or the CKU_USER PIN * if the session is not logged in." A non R/W session fails * with CKR_SESSION_READ_ONLY. */ if ((sess->session_info.state == CKS_RW_USER_FUNCTIONS) || (sess->session_info.state == CKS_RW_PUBLIC_SESSION)) { if (memcmp(nv_token_data->user_pin_sha, old_hash_sha, SHA1_HASH_SIZE) != 0) { st_err_log(33, __FILE__, __LINE__); rc = CKR_PIN_INCORRECT; goto done; } rc = compute_sha( pNewPin, ulNewLen, new_hash_sha ); rc |= compute_md5( pNewPin, ulNewLen, hash_md5 ); if (rc != CKR_OK){ st_err_log(148, __FILE__, __LINE__); goto done; } /* The old PIN matches, now make sure its different * than the new and is not the default. */ if ((memcmp(old_hash_sha, new_hash_sha, SHA1_HASH_SIZE) == 0) || (memcmp(new_hash_sha, default_user_pin_sha, SHA1_HASH_SIZE) == 0)) { st_err_log(34, __FILE__, __LINE__); rc = CKR_PIN_INVALID; goto done; } rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto done; } memcpy(nv_token_data->user_pin_sha, new_hash_sha, SHA1_HASH_SIZE); memcpy(user_pin_md5, hash_md5, MD5_HASH_SIZE); nv_token_data->token_info.flags &= ~(CKF_USER_PIN_TO_BE_CHANGED); XProcUnLock( xproclock ); rc = save_token_data(); if (rc != CKR_OK){ st_err_log(104, __FILE__, __LINE__); goto done; } rc = save_masterkey_user(); } else if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) { if (memcmp(nv_token_data->so_pin_sha, old_hash_sha, SHA1_HASH_SIZE) != 0) { rc = CKR_PIN_INCORRECT; st_err_log(33, __FILE__, __LINE__); goto done; } rc = compute_sha(pNewPin, ulNewLen, new_hash_sha); rc |= compute_md5(pNewPin, ulNewLen, hash_md5); if (rc != CKR_OK){ st_err_log(148, __FILE__, __LINE__); goto done; } /* The old PIN matches, now make sure its different * than the new and is not the default. */ if ((memcmp(old_hash_sha, new_hash_sha, SHA1_HASH_SIZE) == 0) || (memcmp(new_hash_sha, default_so_pin_sha, SHA1_HASH_SIZE) == 0)) { st_err_log(34, __FILE__, __LINE__); rc = CKR_PIN_INVALID; goto done; } rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto done; } memcpy(nv_token_data->so_pin_sha, new_hash_sha, SHA1_HASH_SIZE); memcpy( so_pin_md5, hash_md5, MD5_HASH_SIZE ); nv_token_data->token_info.flags &= ~(CKF_SO_PIN_TO_BE_CHANGED); XProcUnLock( xproclock ); rc = save_token_data(); if (rc != CKR_OK){ st_err_log(104, __FILE__, __LINE__); goto done; } rc = save_masterkey_so(); } else { st_err_log(142, __FILE__, __LINE__); rc = CKR_SESSION_READ_ONLY; } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: session = %08x\n", "C_SetPin", rc, hSession ); } UNLOCKIT; if (rc != CKR_SESSION_READ_ONLY && rc != CKR_OK) st_err_log(149, __FILE__, __LINE__); return rc; } CK_RV SC_OpenSession(CK_SLOT_ID sid, CK_FLAGS flags, CK_SESSION_HANDLE_PTR phSession) { SESSION * sess; CK_BBOOL locked = FALSE; CK_RV rc = CKR_OK; SLT_CHECK; LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (phSession == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } if (slot_id > MAX_SLOT_ID) { st_err_log(2, __FILE__, __LINE__); rc = CKR_SLOT_ID_INVALID; goto done; } flags |= CKF_SERIAL_SESSION; if ((flags & CKF_RW_SESSION) == 0) { if (session_mgr_so_session_exists()) { st_err_log(45, __FILE__, __LINE__); rc = CKR_SESSION_READ_WRITE_SO_EXISTS; goto done; } } // Get the mutex because we may modify the pid_list rc = MY_LockMutex( &pkcs_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); goto done; } locked = TRUE; token_specific.t_session(slot_id); MY_UnlockMutex( &pkcs_mutex ); locked = FALSE; rc = session_mgr_new( flags, &sess ); if (rc != CKR_OK){ st_err_log(152, __FILE__, __LINE__); goto done; } *phSession = sess->handle; // Set the correct slot ID here. Was hard coded to 1. - KEY sess->session_info.slotID = sid; done: if (locked) MY_UnlockMutex( &pkcs_mutex ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x ", "C_OpenSession", rc); if (rc == CKR_OK) stlogit2(debugfile, "sess = %d", ((sess == NULL) ? -1 : (CK_LONG)sess->handle)); stlogit2(debugfile, "\n"); } UNLOCKIT; return rc; } CK_RV SC_CloseSession( ST_SESSION_HANDLE sSession ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET; LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = session_mgr_close_session( sess ); done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x sess = %d\n", "C_CloseSession", rc, hSession ); } UNLOCKIT; return rc; } CK_RV SC_CloseAllSessions( CK_SLOT_ID sid ) { CK_RV rc = CKR_OK; SLT_CHECK; LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } rc = session_mgr_close_all_sessions(); if (rc != CKR_OK){ st_err_log(153, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x slot = %d\n", "C_CloseAllSessions", rc, slot_id ); } UNLOCKIT; return rc; } CK_RV SC_GetSessionInfo( ST_SESSION_HANDLE sSession, CK_SESSION_INFO_PTR pInfo ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET; LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pInfo) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } memcpy( pInfo, &sess->session_info, sizeof(CK_SESSION_INFO) ); done: if (debugfile) { stlogit2(debugfile, "%-25s: session = %08d\n", "C_GetSessionInfo", hSession ); } UNLOCKIT; return rc; } CK_RV SC_GetOperationState( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET; LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pulOperationStateLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } if (!pOperationState) length_only = TRUE; sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = session_mgr_get_op_state( sess, length_only, pOperationState, pulOperationStateLen ); if (rc != CKR_OK){ st_err_log(154, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: session = %08x\n", "C_GetOperationState", rc, hSession ); } UNLOCKIT; return rc; } // // CK_RV SC_SetOperationState( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pOperationState || (ulOperationStateLen == 0)) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = session_mgr_set_op_state( sess, hEncryptionKey, hAuthenticationKey, pOperationState, ulOperationStateLen ); if (rc != CKR_OK){ st_err_log(154, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: session = %08x\n", "C_SetOperationState", rc, hSession ); } UNLOCKIT; return rc; } // // CK_RV SC_Login( ST_SESSION_HANDLE sSession, CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG ulPinLen ) { SESSION * sess = NULL; CK_FLAGS_32 * flags = NULL; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_RV rc = CKR_OK; SESS_SET LOCKIT; // In v2.11, logins should be exclusive, since token // specific flags may need to be set for a bad login. - KEY rc = MY_LockMutex( &login_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } flags = &nv_token_data->token_info.flags; if (!pPin || ulPinLen > MAX_PIN_LEN) { set_login_flags(userType, flags); st_err_log(33, __FILE__, __LINE__); rc = CKR_PIN_INCORRECT; goto done; } // PKCS #11 v2.01 requires that all sessions have the same login status: // --> all sessions are public, all are SO or all are USER // if (userType == CKU_USER) { if (session_mgr_so_session_exists()){ st_err_log(60, __FILE__, __LINE__); rc = CKR_USER_ANOTHER_ALREADY_LOGGED_IN; } if (session_mgr_user_session_exists()){ st_err_log(56, __FILE__, __LINE__); rc = CKR_USER_ALREADY_LOGGED_IN; } } else if (userType == CKU_SO) { if (session_mgr_user_session_exists()){ st_err_log(60, __FILE__, __LINE__); rc = CKR_USER_ANOTHER_ALREADY_LOGGED_IN; } if (session_mgr_so_session_exists()){ st_err_log(56, __FILE__, __LINE__); rc = CKR_USER_ALREADY_LOGGED_IN; } if (session_mgr_readonly_exists()){ st_err_log(142, __FILE__, __LINE__); rc = CKR_SESSION_READ_ONLY_EXISTS; } } else { rc = CKR_USER_TYPE_INVALID; st_err_log(59, __FILE__, __LINE__); } if (rc != CKR_OK) goto done; if (userType == CKU_USER) { if (*flags & CKF_USER_PIN_LOCKED) { st_err_log(37, __FILE__, __LINE__); rc = CKR_PIN_LOCKED; goto done; } if (memcmp(nv_token_data->user_pin_sha, "00000000000000000000", SHA1_HASH_SIZE) == 0) { st_err_log(33, __FILE__, __LINE__); rc = CKR_USER_PIN_NOT_INITIALIZED; goto done; } rc = compute_sha( pPin, ulPinLen, hash_sha ); if (memcmp(nv_token_data->user_pin_sha, hash_sha, SHA1_HASH_SIZE) != 0) { set_login_flags(userType, flags); st_err_log(33, __FILE__, __LINE__); rc = CKR_PIN_INCORRECT; goto done; } /* Successful login, clear flags */ *flags &= ~(CKF_USER_PIN_LOCKED | CKF_USER_PIN_FINAL_TRY | CKF_USER_PIN_COUNT_LOW); compute_md5( pPin, ulPinLen, user_pin_md5 ); memset( so_pin_md5, 0x0, MD5_HASH_SIZE ); rc = load_masterkey_user(); if (rc != CKR_OK){ st_err_log(155, __FILE__, __LINE__); goto done; } rc = load_private_token_objects(); XProcLock( xproclock ); global_shm->priv_loaded = TRUE; XProcUnLock( xproclock ); } else { if (*flags & CKF_SO_PIN_LOCKED) { st_err_log(37, __FILE__, __LINE__); rc = CKR_PIN_LOCKED; goto done; } rc = compute_sha( pPin, ulPinLen, hash_sha ); if (memcmp(nv_token_data->so_pin_sha, hash_sha, SHA1_HASH_SIZE) != 0) { set_login_flags(userType, flags); st_err_log(33, __FILE__, __LINE__); rc = CKR_PIN_INCORRECT; goto done; } /* Successful login, clear flags */ *flags &= ~(CKF_SO_PIN_LOCKED | CKF_SO_PIN_FINAL_TRY | CKF_SO_PIN_COUNT_LOW); compute_md5( pPin, ulPinLen, so_pin_md5 ); memset( user_pin_md5, 0x0, MD5_HASH_SIZE ); rc = load_masterkey_so(); if (rc != CKR_OK) { st_err_log(155, __FILE__, __LINE__); } } rc = session_mgr_login_all( userType ); if (rc != CKR_OK) { st_err_log(174, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x\n", "C_Login", rc ); } UNLOCKIT; save_token_data(); MY_UnlockMutex( &login_mutex ); return rc; } // // CK_RV SC_Logout( ST_SESSION_HANDLE sSession ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } // all sessions have the same state so we just have to check one // if (session_mgr_public_session_exists()) { st_err_log(57, __FILE__, __LINE__); rc = CKR_USER_NOT_LOGGED_IN; goto done; } rc = session_mgr_logout_all(); if (rc != CKR_OK){ st_err_log(57, __FILE__, __LINE__); } memset( user_pin_md5, 0x0, MD5_HASH_SIZE ); memset( so_pin_md5, 0x0, MD5_HASH_SIZE ); object_mgr_purge_private_token_objects(); done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x\n", "C_Logout", rc ); } UNLOCKIT; return rc; } // This is a Leeds-Lite solution so we have to store objects on the host. // CK_RV SC_CreateObject( ST_SESSION_HANDLE sSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject ) { SESSION * sess = NULL; CK_ULONG i; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = object_mgr_add( sess, pTemplate, ulCount, phObject ); if (rc != CKR_OK) { st_err_log(157, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x\n", "C_CreateObject", rc ); for (i = 0; i < ulCount; i++) { if (pTemplate[i].type == CKA_CLASS) stlogit2(debugfile, "%28s: 0x%02x\n", "Object Type", *(CK_ULONG *)pTemplate[i].pValue ); } if (rc == CKR_OK) stlogit2(debugfile, "%28s: %d\n", "Handle", *phObject ); } UNLOCKIT; return rc; } // // CK_RV SC_CopyObject( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phNewObject ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = object_mgr_copy( sess, pTemplate, ulCount, hObject, phNewObject ); if (rc != CKR_OK) { st_err_log(158, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, old handle = %d, new handle = %d\n", "C_CopyObject", rc, hObject, *phNewObject ); } UNLOCKIT; return rc; } // // CK_RV SC_DestroyObject( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = object_mgr_destroy_object( sess, hObject ); if (rc != CKR_OK){ st_err_log(182, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, handle = %d\n", "C_DestroyObject", rc, hObject ); } UNLOCKIT; return rc; } // // CK_RV SC_GetObjectSize( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = object_mgr_get_object_size( hObject, pulSize ); if (rc != CKR_OK){ st_err_log(184, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, handle = %d\n", "C_GetObjectSize", rc, hObject ); } UNLOCKIT; return rc; } // // CK_RV SC_GetAttributeValue( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ) { SESSION * sess = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_ULONG i; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = object_mgr_get_attribute_values( sess, hObject, pTemplate, ulCount ); if (rc != CKR_OK){ st_err_log(159, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, handle = %d\n", "C_GetAttributeValue", rc, hObject ); attr = pTemplate; for (i = 0; i < ulCount; i++, attr++) { ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } } UNLOCKIT; return rc; } // // CK_RV SC_SetAttributeValue( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ) { SESSION * sess = NULL; CK_ATTRIBUTE * attr = NULL; CK_ULONG i; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = object_mgr_set_attribute_values( sess, hObject, pTemplate, ulCount); if (rc != CKR_OK){ st_err_log(161, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, handle = %d\n", "C_SetAttributeValue", rc, hObject ); attr = pTemplate; for (i = 0; i < ulCount; i++, attr++) { CK_BYTE *ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } } UNLOCKIT; return rc; } // // CK_RV SC_FindObjectsInit( ST_SESSION_HANDLE sSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ) { SESSION * sess = NULL; CK_ATTRIBUTE * attr = NULL; CK_ULONG i; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->find_active == TRUE) { st_err_log(31, __FILE__, __LINE__); rc = CKR_OPERATION_ACTIVE; goto done; } rc = object_mgr_find_init( sess, pTemplate, ulCount ); if (rc != CKR_OK){ st_err_log(185, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x\n", "C_FindObjectsInit", rc ); attr = pTemplate; for (i = 0; i < ulCount; i++, attr++) { CK_BYTE *ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } } UNLOCKIT; return rc; } // // CK_RV SC_FindObjects( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount ) { SESSION * sess = NULL; CK_ULONG count = 0; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!phObject || !pulObjectCount) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->find_active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!sess->find_list) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } count = MIN(ulMaxObjectCount, (sess->find_count - sess->find_idx)); memcpy( phObject, sess->find_list + sess->find_idx, count * sizeof(CK_OBJECT_HANDLE) ); *pulObjectCount = count; sess->find_idx += count; rc = CKR_OK; done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, returned %d objects\n", "C_FindObjects", rc, count ); } UNLOCKIT; return rc; } // // CK_RV SC_FindObjectsFinal( ST_SESSION_HANDLE sSession ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->find_active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (sess->find_list) free( sess->find_list ); sess->find_list = NULL; sess->find_len = 0; sess->find_idx = 0; sess->find_active = FALSE; rc = CKR_OK; done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x\n", "C_FindObjectsFinal", rc ); } UNLOCKIT; return rc; } // // CK_RV SC_EncryptInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->encr_ctx.active == TRUE) { st_err_log(31, __FILE__, __LINE__); rc = CKR_OPERATION_ACTIVE; goto done; } rc = encr_mgr_init( sess, &sess->encr_ctx, OP_ENCRYPT_INIT, pMechanism, hKey ); if (rc != CKR_OK) { st_err_log(98, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, key = %d, mech = 0x%x\n", "C_EncryptInit", rc,(sess == NULL)?-1:(CK_LONG)sess->handle, hKey, pMechanism->mechanism ); } UNLOCKIT; return rc; } // // CK_RV SC_Encrypt( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pData || !pulEncryptedDataLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->encr_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pEncryptedData) length_only = TRUE; rc = encr_mgr_encrypt( sess, length_only, &sess->encr_ctx, pData, ulDataLen, pEncryptedData, pulEncryptedDataLen ); if (rc != CKR_OK) { st_err_log(99, __FILE__, __LINE__); } done: LLOCK; if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) encr_mgr_cleanup( &sess->encr_ctx ); if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, amount = %d\n", "C_Encrypt", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulDataLen ); } UNLOCKIT; return rc; } // // CK_RV SC_EncryptUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pPart || !pulEncryptedPartLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->encr_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pEncryptedPart) length_only = TRUE; rc = encr_mgr_encrypt_update( sess, length_only, &sess->encr_ctx, pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen ); if (rc != CKR_OK) { st_err_log(176, __FILE__, __LINE__); } done: LLOCK; if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL) encr_mgr_cleanup( &sess->encr_ctx ); if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, amount = %d\n", "C_EncryptUpdate", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulPartLen ); } UNLOCKIT; return rc; } // I think RSA goofed when designing the specification for C_EncryptFinal. // This function is supposed to follow the Cryptoki standard that if // pLastEncryptedPart == NULL then the user is requesting only the length // of the output. // // But it's quite possible that no output will be returned (say the user // specifies a total of 64 bytes of input data throughout the multi-part // encryption). The same thing can happen during an EncryptUpdate. // // ie: // // 1) user calls C_EncryptFinal to get the needed length // --> we return "0 bytes required" // 2) user passes in a NULL pointer for pLastEncryptedPart // --> we think the user is requesting the length again <-- // // So the user needs to pass in a non-NULL pointer even though we're not // going to return anything in it. It would have been cleaner if RSA would // have simply included a "give-me-the-length-only flag" as an argument. // // CK_RV SC_EncryptFinal( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pulLastEncryptedPartLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->encr_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pLastEncryptedPart) length_only = TRUE; rc = encr_mgr_encrypt_final( sess, length_only, &sess->encr_ctx, pLastEncryptedPart, pulLastEncryptedPartLen ); if (rc != CKR_OK) { st_err_log(177, __FILE__, __LINE__); } done: LLOCK; if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) encr_mgr_cleanup( &sess->encr_ctx ); if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d\n", "C_EncryptFinal", rc, (sess == NULL)?-1:(CK_LONG)sess->handle ); } UNLOCKIT; return rc; } // // CK_RV SC_DecryptInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->decr_ctx.active == TRUE) { st_err_log(31, __FILE__, __LINE__); rc = CKR_OPERATION_ACTIVE; goto done; } rc = decr_mgr_init( sess, &sess->decr_ctx, OP_DECRYPT_INIT, pMechanism, hKey ); if (rc != CKR_OK) { st_err_log(179, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, key = %d, mech = 0x%x\n", "C_DecryptInit", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, hKey, pMechanism->mechanism ); } UNLOCKIT; return rc; } // // CK_RV SC_Decrypt( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pEncryptedData || !pulDataLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->decr_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pData) length_only = TRUE; rc = decr_mgr_decrypt( sess, length_only, &sess->decr_ctx, pEncryptedData, ulEncryptedDataLen, pData, pulDataLen ); if (rc != CKR_OK) { st_err_log(100, __FILE__, __LINE__); } done: LLOCK; if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) decr_mgr_cleanup( &sess->decr_ctx ); if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, amount = %d\n", "C_Decrypt", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulEncryptedDataLen ); } UNLOCKIT; return rc; } // // CK_RV SC_DecryptUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pEncryptedPart || !pulPartLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->decr_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pPart) length_only = TRUE; rc = decr_mgr_decrypt_update( sess, length_only, &sess->decr_ctx, pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen ); if (rc != CKR_OK) { st_err_log(180, __FILE__, __LINE__); } done: LLOCK; if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL) decr_mgr_cleanup( &sess->decr_ctx ); if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, amount = %d\n", "C_DecryptUpdate", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulEncryptedPartLen ); } UNLOCKIT; return rc; } // // CK_RV SC_DecryptFinal( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pulLastPartLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->decr_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pLastPart) length_only = TRUE; rc = decr_mgr_decrypt_final( sess, length_only, &sess->decr_ctx, pLastPart, pulLastPartLen ); if (rc != CKR_OK) { st_err_log(181, __FILE__, __LINE__); } done: LLOCK; if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) decr_mgr_cleanup( &sess->decr_ctx ); if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, amount = %d\n", "C_DecryptFinal", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, *pulLastPartLen ); } UNLOCKIT; return rc; } // // CK_RV SC_DigestInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->digest_ctx.active == TRUE) { st_err_log(31, __FILE__, __LINE__); rc = CKR_OPERATION_ACTIVE; goto done; } rc = digest_mgr_init( sess, &sess->digest_ctx, pMechanism ); if (rc != CKR_OK) { st_err_log(123, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, mech = %x\n", "C_DigestInit", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, pMechanism->mechanism ); } UNLOCKIT; return rc; } // // CK_RV SC_Digest( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } // Netscape has been known to pass a null pData to DigestUpdate // but never for Digest. It doesn't really make sense to allow it here // if (!pData || !pulDigestLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->digest_ctx.active == FALSE) { st_err_log(85, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pDigest) length_only = TRUE; rc = digest_mgr_digest( sess, length_only, &sess->digest_ctx, pData, ulDataLen, pDigest, pulDigestLen ); if (rc != CKR_OK) { st_err_log(124, __FILE__, __LINE__); } done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) digest_mgr_cleanup( &sess->digest_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_Digest", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulDataLen ); } UNLOCKIT; return rc; } // // CK_RV SC_DigestUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } // Netscape has been known to pass a null pPart with ulPartLen == 0... // if (!pPart && ulPartLen != 0) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->digest_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (pPart){ rc = digest_mgr_digest_update( sess, &sess->digest_ctx, pPart, ulPartLen ); if (rc != CKR_OK) { st_err_log(124, __FILE__, __LINE__); } } done: if (rc != CKR_OK) digest_mgr_cleanup( &sess->digest_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_DigestUpdate", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulPartLen ); } UNLOCKIT; return rc; } // // CK_RV SC_DigestKey( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->digest_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } rc = digest_mgr_digest_key( sess, &sess->digest_ctx, hKey ); if (rc != CKR_OK){ st_err_log(124, __FILE__, __LINE__); } done: if (rc != CKR_OK) digest_mgr_cleanup( &sess->digest_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, key = %d\n", "C_DigestKey", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, hKey ); } UNLOCKIT; return rc; } // // CK_RV SC_DigestFinal( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pulDigestLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->digest_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pDigest) length_only = TRUE; rc = digest_mgr_digest_final( sess, length_only, &sess->digest_ctx, pDigest, pulDigestLen ); if (rc != CKR_OK){ st_err_log(126, __FILE__, __LINE__); } done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) digest_mgr_cleanup( &sess->digest_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d\n", "C_DigestFinal", rc, (sess == NULL)?-1:(CK_LONG)sess->handle ); } UNLOCKIT; return rc; } // // CK_RV SC_SignInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } VALID_MECH(pMechanism); if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->sign_ctx.active == TRUE) { rc = CKR_OPERATION_ACTIVE; st_err_log(31, __FILE__, __LINE__); goto done; } rc = sign_mgr_init( sess, &sess->sign_ctx, pMechanism, FALSE, hKey ); if (rc != CKR_OK){ st_err_log(127, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, mech = %x\n", "C_SignInit", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, pMechanism->mechanism ); } UNLOCKIT; return rc; } // // CK_RV SC_Sign( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pData || !pulSignatureLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->sign_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pSignature) length_only = TRUE; rc = sign_mgr_sign( sess, length_only, &sess->sign_ctx, pData, ulDataLen, pSignature, pulSignatureLen ); if (rc != CKR_OK){ st_err_log(171, __FILE__, __LINE__); } done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) sign_mgr_cleanup( &sess->sign_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_Sign", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulDataLen ); } UNLOCKIT; return rc; } // // CK_RV SC_SignUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pPart) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->sign_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } rc = sign_mgr_sign_update( sess, &sess->sign_ctx, pPart, ulPartLen ); if (rc != CKR_OK){ st_err_log(128, __FILE__, __LINE__); } done: if (rc != CKR_OK) sign_mgr_cleanup( &sess->sign_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_SignUpdate", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulPartLen ); } UNLOCKIT; return rc; } // // CK_RV SC_SignFinal( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pulSignatureLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->sign_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pSignature) length_only = TRUE; rc = sign_mgr_sign_final( sess, length_only, &sess->sign_ctx, pSignature, pulSignatureLen ); if (rc != CKR_OK){ st_err_log(129, __FILE__, __LINE__); } done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) sign_mgr_cleanup( &sess->sign_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d\n", "C_SignFinal", rc, (sess == NULL)?-1:(CK_LONG)sess->handle ); } UNLOCKIT; return rc; } // // CK_RV SC_SignRecoverInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->sign_ctx.active == TRUE) { rc = CKR_OPERATION_ACTIVE; st_err_log(31, __FILE__, __LINE__); goto done; } rc = sign_mgr_init( sess, &sess->sign_ctx, pMechanism, TRUE, hKey ); if (rc != CKR_OK){ st_err_log(127, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, mech = %x\n", "C_SignRecoverInit", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, pMechanism->mechanism ); } UNLOCKIT; return rc; } // // CK_RV SC_SignRecover( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); LOCKIT; rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pData || !pulSignatureLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if ((sess->sign_ctx.active == FALSE) || (sess->sign_ctx.recover == FALSE)) { rc = CKR_OPERATION_NOT_INITIALIZED; st_err_log(32, __FILE__, __LINE__); goto done; } if (!pSignature) length_only = TRUE; rc = sign_mgr_sign_recover( sess, length_only, &sess->sign_ctx, pData, ulDataLen, pSignature, pulSignatureLen ); if (rc != CKR_OK){ st_err_log(186, __FILE__, __LINE__); } done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) sign_mgr_cleanup( &sess->sign_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_SignRecover", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulDataLen ); } UNLOCKIT; return rc; } // // CK_RV SC_VerifyInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->verify_ctx.active == TRUE) { rc = CKR_OPERATION_ACTIVE; st_err_log(31, __FILE__, __LINE__); goto done; } rc = verify_mgr_init( sess, &sess->verify_ctx, pMechanism, FALSE, hKey ); if (rc != CKR_OK){ st_err_log(167, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, mech = %x\n", "C_VerifyInit", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, pMechanism->mechanism ); } UNLOCKIT; return rc; } // // CK_RV SC_Verify( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pData || !pSignature) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->verify_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; st_err_log(32, __FILE__, __LINE__); goto done; } rc = verify_mgr_verify( sess, &sess->verify_ctx, pData, ulDataLen, pSignature, ulSignatureLen ); if (rc != CKR_OK){ st_err_log(168, __FILE__, __LINE__); } done: verify_mgr_cleanup( &sess->verify_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_Verify", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulDataLen ); } UNLOCKIT; return rc; } // // CK_RV SC_VerifyUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pPart) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->verify_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; st_err_log(32, __FILE__, __LINE__); goto done; } rc = verify_mgr_verify_update( sess, &sess->verify_ctx, pPart, ulPartLen ); if (rc != CKR_OK){ st_err_log(169, __FILE__, __LINE__); } done: if (rc != CKR_OK) verify_mgr_cleanup( &sess->verify_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_VerifyUpdate", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulPartLen ); } UNLOCKIT; return rc; } // // CK_RV SC_VerifyFinal( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pSignature) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->verify_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; st_err_log(32, __FILE__, __LINE__); goto done; } rc = verify_mgr_verify_final( sess, &sess->verify_ctx, pSignature, ulSignatureLen ); if (rc != CKR_OK){ st_err_log(170, __FILE__, __LINE__); } done: verify_mgr_cleanup( &sess->verify_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d\n", "C_VerifyFinal", rc, (sess == NULL)?-1:(CK_LONG)sess->handle ); } UNLOCKIT; return rc; } // // CK_RV SC_VerifyRecoverInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->verify_ctx.active == TRUE) { rc = CKR_OPERATION_ACTIVE; st_err_log(31, __FILE__, __LINE__); goto done; } rc = verify_mgr_init( sess, &sess->verify_ctx, pMechanism, TRUE, hKey ); if (rc != CKR_OK){ st_err_log(167, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, mech = %x\n", "C_VerifyRecoverInit", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, pMechanism->mechanism ); } UNLOCKIT; return rc; } // // CK_RV SC_VerifyRecover( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pSignature || !pulDataLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if ((sess->verify_ctx.active == FALSE) || (sess->verify_ctx.recover == FALSE)) { rc = CKR_OPERATION_NOT_INITIALIZED; st_err_log(32, __FILE__, __LINE__); goto done; } if (!pData) length_only = TRUE; rc = verify_mgr_verify_recover( sess, length_only, &sess->verify_ctx, pSignature, ulSignatureLen, pData, pulDataLen ); if (rc != CKR_OK){ st_err_log(187, __FILE__, __LINE__); } done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) verify_mgr_cleanup( &sess->verify_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, recover len = %d, length_only = %d\n", "C_VerifyRecover", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, *pulDataLen, length_only ); } UNLOCKIT; return rc; } // // CK_RV SC_DigestEncryptUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ) { SESS_SET if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } // // CK_RV SC_DecryptDigestUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ) { SESS_SET if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } // // CK_RV SC_SignEncryptUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ) { SESS_SET if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } // // CK_RV SC_DecryptVerifyUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ) { SESS_SET if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } // // CK_RV SC_GenerateKey( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism || !phKey || (pTemplate == NULL && ulCount != 0)) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = key_mgr_generate_key( sess, pMechanism, pTemplate, ulCount, phKey ); if (rc != CKR_OK){ st_err_log(91, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { CK_ATTRIBUTE *attr = pTemplate; CK_ULONG i; stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, handle = %d, mech = %x\n", "C_GenerateKey", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, *phKey, pMechanism->mechanism ); for (i = 0; i < ulCount; i++, attr++) { CK_BYTE *ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } } UNLOCKIT; return rc; } // // CK_RV SC_GenerateKeyPair( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism || !phPublicKey || !phPrivateKey || (!pPublicKeyTemplate && (ulPublicKeyAttributeCount != 0)) || (!pPrivateKeyTemplate && (ulPrivateKeyAttributeCount != 0))) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = key_mgr_generate_key_pair( sess, pMechanism, pPublicKeyTemplate, ulPublicKeyAttributeCount, pPrivateKeyTemplate, ulPrivateKeyAttributeCount, phPublicKey, phPrivateKey ); if (rc != CKR_OK){ st_err_log(91, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { CK_ATTRIBUTE *attr = NULL; CK_ULONG i; stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, mech = %x\n", "C_GenerateKeyPair", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, pMechanism->mechanism ); if (rc == CKR_OK) { stlogit2(debugfile, " Public handle: %d\n", *phPublicKey ); stlogit2(debugfile, " Private handle: %d\n", *phPrivateKey ); } stlogit2(debugfile, " Public Template:\n"); attr = pPublicKeyTemplate; for (i = 0; i < ulPublicKeyAttributeCount; i++, attr++) { CK_BYTE *ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } stlogit2(debugfile, " Private Template:\n"); attr = pPrivateKeyTemplate; for (i = 0; i < ulPrivateKeyAttributeCount; i++, attr++) { CK_BYTE *ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } } UNLOCKIT; return rc; } // // CK_RV SC_WrapKey( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism || !pulWrappedKeyLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); if (!pWrappedKey) length_only = TRUE; sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = key_mgr_wrap_key( sess, length_only, pMechanism, hWrappingKey, hKey, pWrappedKey, pulWrappedKeyLen ); if (rc != CKR_OK){ st_err_log(188, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, encrypting key = %d, wrapped key = %d\n", "C_WrapKey", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, hWrappingKey, hKey ); } UNLOCKIT; return rc; } // // CK_RV SC_UnwrapKey( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey ) { SESSION * sess = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_ULONG i; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism || !pWrappedKey || (!pTemplate && ulCount != 0) || !phKey) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = key_mgr_unwrap_key( sess, pMechanism, pTemplate, ulCount, pWrappedKey, ulWrappedKeyLen, hUnwrappingKey, phKey ); if (rc != CKR_OK){ st_err_log(189, __FILE__, __LINE__); } done: // if (rc == CKR_OBJECT_HANDLE_INVALID) brkpt(); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, decrypting key = %d, unwrapped key = %d\n", "C_UnwrapKey", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, hUnwrappingKey, *phKey ); attr = pTemplate; for (i = 0; i < ulCount; i++, attr++) { ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } } UNLOCKIT; return rc; } // // CK_RV SC_DeriveKey( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey ) { SESSION * sess = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_ULONG i; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism || (!pTemplate && ulCount != 0)) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = key_mgr_derive_key( sess, pMechanism, hBaseKey, phKey, pTemplate, ulCount ); if (rc != CKR_OK){ st_err_log(190, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, base key = %d, mech = %x\n", "C_DeriveKey", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, hBaseKey, pMechanism->mechanism ); if (rc == CKR_OK) { switch (pMechanism->mechanism) { case CKM_SSL3_KEY_AND_MAC_DERIVE: { CK_SSL3_KEY_MAT_PARAMS *pReq; CK_SSL3_KEY_MAT_OUT *pPtr; pReq = (CK_SSL3_KEY_MAT_PARAMS *)pMechanism->pParameter; pPtr = pReq->pReturnedKeyMaterial; stlogit2(debugfile, " Client MAC key: %d\n", pPtr->hClientMacSecret ); stlogit2(debugfile, " Server MAC key: %d\n", pPtr->hServerMacSecret ); stlogit2(debugfile, " Client Key: %d\n", pPtr->hClientKey ); stlogit2(debugfile, " Server Key: %d\n", pPtr->hServerKey ); } break; case CKM_DH_PKCS_DERIVE: { stlogit2(debugfile, " DH Shared Secret: \n" ); } break ; default: stlogit2(debugfile, " Derived key: %d\n", *phKey ); } } attr = pTemplate; for (i = 0; i < ulCount; i++, attr++) { ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } } UNLOCKIT; return rc; } // // CK_RV SC_SeedRandom( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen ) { SESS_SET if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } return CKR_OK; } // // CK_RV SC_GenerateRandom( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen ) { SESSION *sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pRandomData && ulRandomLen != 0) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = rng_generate( pRandomData, ulRandomLen ); if (rc != CKR_OK){ st_err_log(130, __FILE__, __LINE__, __FUNCTION__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, %d bytes\n", "C_GenerateRandom", rc, ulRandomLen ); } UNLOCKIT; return rc; } // // CK_RV SC_GetFunctionStatus( ST_SESSION_HANDLE sSession ) { SESS_SET if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } st_err_log(17, __FILE__, __LINE__); return CKR_FUNCTION_NOT_PARALLEL; } // // CK_RV SC_CancelFunction( ST_SESSION_HANDLE sSession ) { SESS_SET if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } st_err_log(17, __FILE__, __LINE__); return CKR_FUNCTION_NOT_PARALLEL; } // // CK_RV QueryTweakValues( void ) { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } // // CK_RV UpdateTweakValues( void ) { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } // Added for AIX work void SC_SetFunctionList(void){ function_list.ST_Initialize = (void *)ST_Initialize; function_list.ST_GetTokenInfo = SC_GetTokenInfo; function_list.ST_GetMechanismList = SC_GetMechanismList; function_list.ST_GetMechanismInfo = SC_GetMechanismInfo; function_list.ST_InitToken = SC_InitToken; function_list.ST_InitPIN = SC_InitPIN; function_list.ST_SetPIN = SC_SetPIN; function_list.ST_OpenSession = SC_OpenSession; function_list.ST_CloseSession = SC_CloseSession; function_list.ST_GetSessionInfo = SC_GetSessionInfo; function_list.ST_GetOperationState = SC_GetOperationState; function_list.ST_SetOperationState = SC_SetOperationState; function_list.ST_Login = SC_Login; function_list.ST_Logout = SC_Logout; function_list.ST_CreateObject = SC_CreateObject; function_list.ST_CopyObject = SC_CopyObject; function_list.ST_DestroyObject = SC_DestroyObject; function_list.ST_GetObjectSize = SC_GetObjectSize; function_list.ST_GetAttributeValue = SC_GetAttributeValue; function_list.ST_SetAttributeValue = SC_SetAttributeValue; function_list.ST_FindObjectsInit = SC_FindObjectsInit; function_list.ST_FindObjects = SC_FindObjects; function_list.ST_FindObjectsFinal = SC_FindObjectsFinal; function_list.ST_EncryptInit = SC_EncryptInit; function_list.ST_Encrypt = SC_Encrypt; function_list.ST_EncryptUpdate = SC_EncryptUpdate; function_list.ST_EncryptFinal = SC_EncryptFinal; function_list.ST_DecryptInit = SC_DecryptInit; function_list.ST_Decrypt = SC_Decrypt; function_list.ST_DecryptUpdate = SC_DecryptUpdate; function_list.ST_DecryptFinal = SC_DecryptFinal; function_list.ST_DigestInit = SC_DigestInit; function_list.ST_Digest = SC_Digest; function_list.ST_DigestUpdate = SC_DigestUpdate; function_list.ST_DigestKey = SC_DigestKey; function_list.ST_DigestFinal = SC_DigestFinal; function_list.ST_SignInit = SC_SignInit; function_list.ST_Sign = SC_Sign; function_list.ST_SignUpdate = SC_SignUpdate; function_list.ST_SignFinal = SC_SignFinal; function_list.ST_SignRecoverInit = SC_SignRecoverInit; function_list.ST_SignRecover = SC_SignRecover; function_list.ST_VerifyInit = SC_VerifyInit; function_list.ST_Verify = SC_Verify; function_list.ST_VerifyUpdate = SC_VerifyUpdate; function_list.ST_VerifyFinal = SC_VerifyFinal; function_list.ST_VerifyRecoverInit = SC_VerifyRecoverInit; function_list.ST_VerifyRecover = SC_VerifyRecover; function_list.ST_DigestEncryptUpdate = NULL; // SC_DigestEncryptUpdate; function_list.ST_DecryptDigestUpdate = NULL; // SC_DecryptDigestUpdate; function_list.ST_SignEncryptUpdate = NULL; //SC_SignEncryptUpdate; function_list.ST_DecryptVerifyUpdate = NULL; // SC_DecryptVerifyUpdate; function_list.ST_GenerateKey = SC_GenerateKey; function_list.ST_GenerateKeyPair = SC_GenerateKeyPair; function_list.ST_WrapKey = SC_WrapKey; function_list.ST_UnwrapKey = SC_UnwrapKey; function_list.ST_DeriveKey = SC_DeriveKey; function_list.ST_SeedRandom = SC_SeedRandom ; function_list.ST_GenerateRandom = SC_GenerateRandom; function_list.ST_GetFunctionStatus = NULL; // SC_GetFunctionStatus; function_list.ST_CancelFunction = NULL; // SC_CancelFunction; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/tok_struct.h.in0000640000175000017500000000246511327631345022342 0ustar jfjf /* * Licensed materials, Property of IBM Corp. * * openCryptoki CCA token * * (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2006 * */ #ifndef __TOK_STRUCT_H #define __TOK_STRUCT_H #include #include "tok_spec_struct.h" token_spec_t token_specific = { "@DB_PATH@/ccatok", "ccatok", "CCA_STDLL_Debug", &token_specific_init, &tok_slot2local, &token_rng, &token_specific_session, &token_specific_final, &token_specific_des_key_gen, &token_specific_des_ecb, &token_specific_des_cbc, &token_specific_tdes_ecb, &token_specific_tdes_cbc, &token_specific_rsa_decrypt, &token_specific_rsa_encrypt, &token_specific_rsa_sign, &token_specific_rsa_verify, &token_specific_rsa_generate_keypair, #ifndef NODH /* Begin code contributed by Corrent corp. */ // DH &token_specific_dh_pkcs_derive, &token_specific_dh_pkcs_key_pair_gen, /* End code contributed by Corrent corp. */ #endif // SHA-1 NULL, NULL, NULL, // SHA-256 NULL, NULL, NULL, #ifndef NOAES // AES &token_specific_aes_key_gen, &token_specific_aes_ecb, &token_specific_aes_cbc, #endif &token_specific_get_mechanism_list, &token_specific_get_mechanism_info }; #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/cca_stdll.h0000640000175000017500000000551211327631345021460 0ustar jfjf /* * Licensed materials, Property of IBM Corp. * * openCryptoki CCA token * * (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2006 * * Author: Kent E. Yoder * */ #ifndef __CCA_STDLL_H__ #define __CCA_STDLL_H__ /* CCA library constants */ #define CCA_PRIVATE_KEY_NAME_SIZE 64 #define CCA_REGENERATION_DATA_SIZE 64 #define CCA_KEY_TOKEN_SIZE 2500 #define CCA_KEY_VALUE_STRUCT_SIZE 2500 #define CCA_RULE_ARRAY_SIZE 256 #define CCA_KEYWORD_SIZE 8 #define CCA_KEY_ID_SIZE 64 #define CCA_RNG_SIZE 8 #define CCA_OCV_SIZE 18 #define CCA_SUCCESS 0 #define CCA_PKB_E_OFFSET 18 #define CCA_PKB_E_SIZE 2 #define CCA_PKB_E_SIZE_OFFSET 4 /* CCA Internal Key Token parsing constants */ /* Size of an RSA internal key token header */ #define CCA_RSA_INTTOK_HDR_LENGTH 8 /* Offset into an RSA internal key token of the private key area */ #define CCA_RSA_INTTOK_PRIVKEY_OFFSET 8 /* Offset into an RSA key area of the total length */ #define CCA_RSA_INTTOK_PRIVKEY_LENGTH_OFFSET 2 #define CCA_RSA_INTTOK_PUBKEY_LENGTH_OFFSET 2 /* Offset into an RSA private key area of the length of n, the modulus */ #define CCA_RSA_INTTOK_PRIVKEY_N_LENGTH_OFFSET 64 /* Offset into an RSA public key area of the length of e, the public exponent */ #define CCA_RSA_INTTOK_PUBKEY_E_LENGTH_OFFSET 6 /* Offset into an RSA public key area of the value of e, the public exponent */ #define CCA_RSA_INTTOK_PUBKEY_E_OFFSET 12 /* Offset into the rule_array returned by the STATCCAE command for the * Current Symmetric Master Key register status */ #define CCA_STATCCAE_SYM_CMK_OFFSET 8 /* Offset into the rule_array returned by the STATCCAE command for the * Current Asymmetric Master Key register status */ #define CCA_STATCCAE_ASYM_CMK_OFFSET 56 /* CCA STDLL constants */ #define CCATOK_MAX_N_LEN 512 #define CCATOK_MAX_E_LEN 256 #define sw_des3_cbc_encrypt(clear, len, cipher, len2, iv, key) \ sw_des3_cbc(clear, len, cipher, len2, iv, key, 1) #define sw_des3_cbc_decrypt(clear, len, cipher, len2, iv, key) \ sw_des3_cbc(clear, len, cipher, len2, iv, key, 0) /* CCA STDLL debug logging definitions */ #ifdef DEBUG #define CCADBG(fn, rc, reason) fprintf(stderr, "CCA_TOK DEBUG %s:%d " fn " failed. " \ "return: %ld, reason: %ld\n", __FUNCTION__, \ __LINE__, rc, reason) #define DBG(fmt, ...) fprintf(stderr, "CCA_TOK DEBUG %s:%d %s " fmt "\n", \ __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__) #else #define CCADBG(...) do { } while (0) #define DBG(...) do { } while (0) #endif #define LOG(priority, fmt, ...) \ do { \ openlog("openCryptoki(CCA)", LOG_NDELAY|LOG_PID, LOG_USER); \ syslog(priority, "%s " fmt, __FILE__, ##__VA_ARGS__); \ } while (0) #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/mech_dh.c0000640000175000017500000001534411327631345021116 0ustar jfjf /************************************************************************ * * * Copyright: Corrent Corporation (c) 2000-2003 * * * * Filename: mech_dh.c * * Created By: Kapil Sood * * Created On: Jan 18, 2003 * * Description: This is the file implementing Diffie-Hellman * * key pair generation and shared key derivation * * operations. * * * ************************************************************************/ // File: mech_dh.c // // Mechanisms for DH // // Routines contained within: #include #include // for memcmp() et al #include #include #include #include "cca_stdll.h" #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" #ifndef NODH // // CK_RV dh_pkcs_derive( SESSION * sess, CK_MECHANISM * mech, CK_OBJECT_HANDLE base_key, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE * handle ) { CK_RV rc; CK_ULONG i, keyclass = 0, keytype = 0 ; CK_ATTRIBUTE *new_attr ; OBJECT *temp_obj = NULL; OBJECT *secret_obj = NULL ; CK_BYTE secret_key_value[256] ; CK_ULONG count, secret_key_value_len = 256 ; CK_ATTRIBUTE *attr ; // Prelim checking of sess, mech, pTemplate, and ulCount was // done in the calling function (key_mgr_derive_key). // Perform DH checking of parameters // Check the existance of the public-value in mechanism if ((!mech->pParameter) || ((mech->ulParameterLen != 64) && (mech->ulParameterLen != 96) && (mech->ulParameterLen != 128) && (mech->ulParameterLen != 192) && (mech->ulParameterLen != 256))) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Check valid object handle on base_key if (&base_key == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Extract the object class and keytype from the supplied template. for (i=0; i < ulCount; i++) { if (pTemplate[i].type == CKA_CLASS) { keyclass = *(CK_OBJECT_CLASS *)pTemplate[i].pValue; if (keyclass != CKO_SECRET_KEY) { st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } if (pTemplate[i].type == CKA_KEY_TYPE) keytype = *(CK_ULONG *)pTemplate[i].pValue; } // Extract public-key from mechanism parameters. base-key contains the // private key, prime, and base. The return value will be in the handle. rc = ckm_dh_pkcs_derive( mech->pParameter, mech->ulParameterLen, base_key, secret_key_value, &secret_key_value_len ); if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED ; } // Build the attribute from the vales that were returned back rc = build_attribute( CKA_VALUE, secret_key_value, secret_key_value_len, &new_attr ); if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED ; } // Create the object that will be passed back as a handle. This will // contain the new (computed) value of the attribute. rc = object_mgr_create_skel( sess, pTemplate, ulCount, MODE_KEYGEN, keyclass, keytype, &temp_obj ); if (rc != CKR_OK){ st_err_log(89, __FILE__, __LINE__); return rc; } // Update the template in the object with the new attribute template_update_attribute( temp_obj->template, new_attr ); // at this point, the derived key is fully constructed...assign an // object handle and store the key // rc = object_mgr_create_final( sess, temp_obj, handle ); if (rc != CKR_OK) { st_err_log(90, __FILE__, __LINE__); object_free( temp_obj ); return rc; } return rc; } // // mechanisms // // // CK_RV ckm_dh_pkcs_derive( CK_VOID_PTR other_pubkey, CK_ULONG other_pubkey_len, CK_OBJECT_HANDLE base_key, CK_BYTE *secret_value, CK_ULONG *secret_value_len ) { CK_RV rc; CK_BYTE p[256] ; CK_ULONG p_len ; CK_BYTE x[256] ; CK_ULONG x_len ; CK_ATTRIBUTE *temp_attr ; OBJECT *base_key_obj = NULL ; CK_ULONG count ; CK_BYTE *p_other_pubkey ; rc = object_mgr_find_in_map1( base_key, &base_key_obj ); if (rc != CKR_OK){ st_err_log(18, __FILE__, __LINE__); return CKR_KEY_HANDLE_INVALID; } // Extract secret (x) from base_key rc = template_attribute_find( base_key_obj->template, CKA_VALUE, &temp_attr ); if (rc == FALSE) { st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { memset(x, 0, sizeof(x)) ; x_len = temp_attr->ulValueLen ; memcpy(x, (CK_BYTE *)temp_attr->pValue, x_len) ; } // Extract prime (p) from base_key rc = template_attribute_find( base_key_obj->template, CKA_PRIME, &temp_attr ); if (rc == FALSE) { st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { memset(p, 0, sizeof(p)) ; p_len = temp_attr->ulValueLen ; memcpy(p, (CK_BYTE *)temp_attr->pValue, p_len) ; } p_other_pubkey = (CK_BYTE *) other_pubkey ; // Perform: z = other_pubkey^x mod p rc = token_specific.t_dh_pkcs_derive(secret_value, secret_value_len, p_other_pubkey, other_pubkey_len, x, x_len, p, p_len ); if (rc != CKR_OK) { st_err_log(191, __FILE__, __LINE__); return CKR_FUNCTION_FAILED ; } return rc; } // // CK_RV ckm_dh_pkcs_key_pair_gen( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ) { CK_RV rc; rc = token_specific.t_dh_pkcs_key_pair_gen(publ_tmpl,priv_tmpl); if (rc != CKR_OK) { st_err_log(91, __FILE__, __LINE__); } return rc; } #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/decr_mgr.c0000640000175000017500000006170011327631345021306 0ustar jfjf/* * Licensed materials, Property of IBM Corp. * * openCryptoki CCA token * * (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2006 * */ // File: decr_mgr.c // // Decryption manager routines // //#include #include #include // for memcmp() et al #include #include "cca_stdll.h" #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // // CK_RV decr_mgr_init( SESSION *sess, ENCR_DECR_CONTEXT *ctx, CK_ULONG operation, CK_MECHANISM *mech, CK_OBJECT_HANDLE key_handle ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_KEY_TYPE keytype; CK_BBOOL flag; CK_RV rc; if (!sess){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active != FALSE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } // key usage restrictions // if (operation == OP_DECRYPT_INIT) { rc = object_mgr_find_in_map1( key_handle, &key_obj ); if (rc != CKR_OK){ st_err_log(18, __FILE__, __LINE__); return CKR_KEY_HANDLE_INVALID; } // is key allowed to do general decryption? // rc = template_attribute_find( key_obj->template, CKA_DECRYPT, &attr ); if (rc == FALSE){ st_err_log(85, __FILE__, __LINE__); return CKR_KEY_FUNCTION_NOT_PERMITTED; } else { flag = *(CK_BBOOL *)attr->pValue; if (flag != TRUE){ st_err_log(85, __FILE__, __LINE__); return CKR_KEY_FUNCTION_NOT_PERMITTED; } } } else if (operation == OP_UNWRAP) { rc = object_mgr_find_in_map1( key_handle, &key_obj ); if (rc != CKR_OK){ st_err_log(62, __FILE__, __LINE__); return CKR_WRAPPING_KEY_HANDLE_INVALID; } // is key allowed to unwrap other keys? // rc = template_attribute_find( key_obj->template, CKA_UNWRAP, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // Cryptoki doesn't define a better return code } else { flag = *(CK_BBOOL *)attr->pValue; if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } } else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // is the mechanism supported? is the key type correct? is a // parameter present if required? is the key size allowed? // does the key support decryption? // // Will the FCV allow the operation? // switch (mech->mechanism) { #ifndef NOECB case CKM_DES_ECB: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_56_BIT_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; #ifndef NOCDMF case CKM_CDMF_ECB: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_CDMF){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_CDMF_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; #endif #endif case CKM_DES_CBC: case CKM_DES_CBC_PAD: { if (mech->ulParameterLen != DES_BLOCK_SIZE){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_56_BIT_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; #ifndef NOCDMF case CKM_CDMF_CBC: case CKM_CDMF_CBC_PAD: { if (mech->ulParameterLen != DES_BLOCK_SIZE){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_CDMF){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; #endif #ifndef NOECB case CKM_DES3_ECB: { if (mech->ulParameterLen != 0) return CKR_MECHANISM_PARAM_INVALID; // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES3 && keytype != CKK_DES2){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_TRIPLE_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; #endif case CKM_DES3_CBC: case CKM_DES3_CBC_PAD: { if (mech->ulParameterLen != DES_BLOCK_SIZE) return CKR_MECHANISM_PARAM_INVALID; // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES3 && keytype != CKK_DES2){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_TRIPLE_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_RSA_X_509: case CKM_RSA_PKCS: { if (mech->ulParameterLen != 0) return CKR_MECHANISM_PARAM_INVALID; rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_RSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // rc = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); // if (rc == FALSE || // nv_FCV.SymmetricModLength/8 < attr->value_length) // return (operation == OP_DECRYPT_INIT ? CKR_KEY_SIZE_RANGE : CKR_UNWRAPPING_KEY_SIZE_RANGE ); // RSA cannot be used for multi-part operations // ctx->context_len = 0; ctx->context = NULL; } break; #ifndef NOAES case CKM_AES_ECB: { // XXX Copied from DES3, should be verified - KEY if (mech->ulParameterLen != 0) return CKR_MECHANISM_PARAM_INVALID; // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_AES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(AES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(AES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(AES_CONTEXT) ); } break; case CKM_AES_CBC: case CKM_AES_CBC_PAD: { // XXX Copied from DES3, should be verified - KEY if (mech->ulParameterLen != AES_INIT_VECTOR_SIZE) return CKR_MECHANISM_PARAM_INVALID; // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_AES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(AES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(AES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(AES_CONTEXT) ); } break; #endif default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } if (mech->ulParameterLen > 0) { ptr = (CK_BYTE *)malloc(mech->ulParameterLen); if (!ptr){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( ptr, mech->pParameter, mech->ulParameterLen ); } ctx->key = key_handle; ctx->mech.ulParameterLen = mech->ulParameterLen; ctx->mech.mechanism = mech->mechanism; ctx->mech.pParameter = ptr; ctx->multi = FALSE; ctx->active = TRUE; return CKR_OK; } // // CK_RV decr_mgr_cleanup( ENCR_DECR_CONTEXT *ctx ) { if (!ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } ctx->key = 0; ctx->mech.ulParameterLen = 0; ctx->mech.mechanism = 0; ctx->multi = FALSE; ctx->active = FALSE; ctx->context_len = 0; if (ctx->mech.pParameter) { free( ctx->mech.pParameter ); ctx->mech.pParameter = NULL; } if (ctx->context) { free( ctx->context ); ctx->context = NULL; } return CKR_OK; } // // CK_RV decr_mgr_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } // if the caller just wants the decrypted length, there is no reason to // specify the input data. I just need the data length // if ((length_only == FALSE) && (!in_data || !out_data)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->multi == TRUE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } switch (ctx->mech.mechanism) { #ifndef NOECB #ifndef NOCDMF case CKM_CDMF_ECB: #endif case CKM_DES_ECB: return des_ecb_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif #ifndef NOCDMF case CKM_CDMF_CBC: #endif case CKM_DES_CBC: return des_cbc_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #ifndef NOCDMF case CKM_CDMF_CBC_PAD: #endif case CKM_DES_CBC_PAD: return des_cbc_pad_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #ifndef NOECB case CKM_DES3_ECB: return des3_ecb_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif case CKM_DES3_CBC: return des3_cbc_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_CBC_PAD: return des3_cbc_pad_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_RSA_PKCS: return rsa_pkcs_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #if 0 case CKM_RSA_X_509: return rsa_x509_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif #ifndef NOAES case CKM_AES_CBC: return aes_cbc_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_ECB: return aes_ecb_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_CBC_PAD: return aes_cbc_pad_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif default: return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV decr_mgr_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { if (!sess || !in_data || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!out_data && !length_only){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } ctx->multi = TRUE; switch (ctx->mech.mechanism) { #ifndef NOECB #ifndef NOCDMF case CKM_CDMF_ECB: #endif case CKM_DES_ECB: return des_ecb_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif #ifndef NOCDMF case CKM_CDMF_CBC: #endif case CKM_DES_CBC: return des_cbc_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #ifndef NOCDMF case CKM_CDMF_CBC_PAD: #endif case CKM_DES_CBC_PAD: return des_cbc_pad_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #ifndef NOECB case CKM_DES3_ECB: return des3_ecb_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif case CKM_DES3_CBC: return des3_cbc_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_CBC_PAD: return des3_cbc_pad_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #ifndef NOAES case CKM_AES_ECB: return aes_ecb_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_CBC: return aes_cbc_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_CBC_PAD: return aes_cbc_pad_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV decr_mgr_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(28, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } switch (ctx->mech.mechanism) { #ifndef NOECB #ifndef NOCDMF case CKM_CDMF_ECB: #endif case CKM_DES_ECB: return des_ecb_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); #endif #ifndef NOCDMF case CKM_CDMF_CBC: #endif case CKM_DES_CBC: return des_cbc_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); #ifndef NOCDMF case CKM_CDMF_CBC_PAD: #endif case CKM_DES_CBC_PAD: return des_cbc_pad_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); #ifndef NOECB case CKM_DES3_ECB: return des3_ecb_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); #endif case CKM_DES3_CBC: return des3_cbc_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_DES3_CBC_PAD: return des3_cbc_pad_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); #ifndef NOAES case CKM_AES_ECB: return aes_ecb_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_AES_CBC: return aes_cbc_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_AES_CBC_PAD: return aes_cbc_pad_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); #endif default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/Makefile.am0000640000175000017500000000372211327631345021414 0ustar jfjf# Makefile.am for common functions for openCryptoki # Michael A. Halcrow # # The PKCS#11 STDLL library # nobase_lib_LTLIBRARIES=opencryptoki/stdll/libpkcs11_cca.la # Not all versions of automake observe libname_CFLAGS opencryptoki_stdll_libpkcs11_cca_la_CFLAGS = -DLINUX -DSPINXPL -DNOCDMF \ -DNODSA -DNODH -DNOECB \ -I. -I../../../include -I../../../include/pkcs11 -I../common \ -DSTDLL_NAME=\"ccatok\" # Not all versions of automake observe libname_CFLAGS AM_CFLAGS = -DLINUX -DSPINXPL -DNOCDMF -DNODSA -DNODH -DNOECB \ -DNODSA -DNODH -DNOECB \ -I. -I../../../include -I../../../include/pkcs11 -I../common \ -DSTDLL_NAME=\"ccatok\" opencryptoki_stdll_libpkcs11_cca_la_LDFLAGS = -shared -Wl,-Bsymbolic \ -lcrypto -lpthread -nostartfiles -Wl,-soname,$@ opencryptoki_stdll_libpkcs11_cca_la_SOURCES = asn1.c \ ../common/dig_mgr.c \ ../common/hwf_obj.c \ ../common/log.c \ key.c \ mech_dh.c \ ../common/mech_rng.c \ new_host.c \ sign_mgr.c \ ../common/cert.c \ ../common/dp_obj.c \ mech_aes.c \ mech_rsa.c \ ../common/obj_mgr.c \ ../common/template.c \ ../common/data_obj.c \ ../common/encr_mgr.c \ key_mgr.c \ ../common/mech_md2.c \ mech_sha.c \ ../common/object.c \ decr_mgr.c \ globals.c \ loadsave.c \ utility.c \ mech_des.c \ mech_des3.c \ ../common/mech_md5.c \ ../common/mech_ssl3.c \ ../common/sess_mgr.c \ verify_mgr.c \ cca_specific.c noinst_HEADERS = h_extern.h tok_spec_struct.h defs.h csulincl.h \ host_defs.h cca_stdll.h tok_specific.h install-data-local: mkdir -p -- "$(DESTDIR)/$(datadir)/opencryptoki" @INSTALL@ README-IBM_CCA_users $(DESTDIR)/$(datadir)/opencryptoki opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/loadsave.c0000640000175000017500000006642211327631345021330 0ustar jfjf/* * Licensed materials, Property of IBM Corp. * * openCryptoki CCA token * * (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2006 * * Author: Kent E. Yoder * */ // loadsave.c // // routines associated with loading/saving files // // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "cca_stdll.h" #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" #include "pkcs32.h" #include "../api/apiproto.h" void set_perm(int file) { struct group *grp; // Set absolute permissions or rw-rw-r-- fchmod(file,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH); grp = getgrnam("pkcs11"); // Obtain the group id if (grp){ fchown(file,getuid(),grp->gr_gid); // set ownership to root, and pkcs11 group } } // // CK_RV load_token_data() { FILE * fp; CK_BYTE fname[PATH_MAX]; TOKEN_DATA td; CK_RV rc; sprintf((char *)fname,"%s/%s",(char *)pk_dir, PK_LITE_NV); rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto out_nolock; } fp = fopen((char *)fname, "r"); if (!fp) { /* Better error checking added */ if (errno == ENOENT) { /* init_token_data may call save_token_data, which graps the * xproclock, so we must release it around this call */ XProcUnLock( xproclock ); init_token_data(); rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto out_nolock; } fp = fopen((char *)fname, "r"); if (!fp) { // were really hosed here since the created // did not occur LogError("failed opening %s for read: %s", fname, strerror(errno)); rc = CKR_FUNCTION_FAILED; goto out_unlock; } } else { /* Could not open file for some unknown reason */ st_err_log(194, __FILE__, __LINE__, PK_LITE_NV, errno); rc = CKR_FUNCTION_FAILED; goto out_unlock; } } set_perm(fileno(fp)); rc = fread( &td, sizeof(TOKEN_DATA), 1, fp ); fclose(fp); if (rc == 0) { rc = CKR_FUNCTION_FAILED; goto out_unlock; } memcpy( nv_token_data, &td, sizeof(TOKEN_DATA) ); rc = CKR_OK; out_unlock: XProcUnLock( xproclock ); out_nolock: return rc; } // // CK_RV save_token_data() { FILE *fp; TOKEN_DATA td; CK_RV rc; CK_BYTE fname[PATH_MAX]; sprintf((char *)fname,"%s/%s",pk_dir, PK_LITE_NV); rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto out_nolock; } fp = fopen((char *)fname, "r+"); if (!fp){ fp = fopen((char *)fname, "w"); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } } set_perm(fileno(fp)); memcpy( &td, nv_token_data, sizeof(TOKEN_DATA) ); (void)fwrite( &td, sizeof(TOKEN_DATA), 1, fp ); fclose(fp); rc = CKR_OK; done: XProcUnLock( xproclock ); out_nolock: return rc; } // // CK_RV save_token_object( OBJECT *obj ) { FILE * fp = NULL; CK_BYTE line[100]; CK_RV rc; CK_BYTE fname[PATH_MAX]; if (object_is_private(obj) == TRUE) rc = save_private_token_object( obj ); else rc = save_public_token_object( obj ); if (rc != CKR_OK){ st_err_log(104, __FILE__, __LINE__); return rc; } // update the index file if it exists // sprintf((char *)fname,"%s/%s/%s",pk_dir,PK_LITE_OBJ_DIR,PK_LITE_OBJ_IDX); fp = fopen( (char *)fname, "r" ); if (fp) { set_perm(fileno(fp)); while (!feof(fp)) { (void)fgets((char *)line, 50, fp ); if (!feof(fp)) { line[ strlen((char *)line)-1 ] = 0; if (strcmp((char *)line,(char *)( obj->name)) == 0) { fclose(fp); return CKR_OK; // object is already in the list } } } fclose(fp); } // we didn't find it...either the index file doesn't exist or this // is a new object... // fp = fopen((char *)fname, "a"); if (!fp){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } set_perm(fileno(fp)); set_perm(fileno(fp)); fprintf( fp, "%s\n", obj->name ); fclose(fp); return CKR_OK; } // this is the same as the old version. public token objects are stored in the // clear // CK_RV save_public_token_object( OBJECT *obj ) { FILE * fp = NULL; CK_BYTE * cleartxt = NULL; CK_BYTE fname[PATH_MAX]; CK_ULONG cleartxt_len; CK_BBOOL flag = FALSE; CK_RV rc; CK_ULONG_32 total_len; sprintf( (char *)fname,"%s/%s/", pk_dir,PK_LITE_OBJ_DIR); strncat( (char *)fname, (char *) obj->name, 8 ); rc = object_flatten( obj, &cleartxt, &cleartxt_len ); if (rc != CKR_OK){ st_err_log(101, __FILE__, __LINE__); goto error; } fp = fopen( (char *)fname, "w" ); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } set_perm(fileno(fp)); total_len = cleartxt_len + sizeof(CK_ULONG_32) + sizeof(CK_BBOOL); (void)fwrite( &total_len, sizeof(CK_ULONG_32), 1, fp ); (void)fwrite( &flag, sizeof(CK_BBOOL), 1, fp ); (void)fwrite( cleartxt, cleartxt_len, 1, fp ); fclose( fp ); free( cleartxt ); return CKR_OK; error: if (fp) fclose( fp ); if (cleartxt) free( cleartxt ); return rc; } // // CK_RV save_private_token_object( OBJECT *obj ) { FILE * fp = NULL; CK_BYTE * obj_data = NULL; CK_BYTE * cleartxt = NULL; CK_BYTE * ciphertxt = NULL; CK_BYTE * ptr = NULL; CK_BYTE fname[100]; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_BYTE des3_key[MASTER_KEY_SIZE]; CK_ULONG obj_data_len,cleartxt_len, ciphertxt_len; CK_ULONG padded_len; CK_BBOOL flag; CK_RV rc; CK_ULONG_32 obj_data_len_32; CK_ULONG_32 total_len; sprintf( (char *)fname,"%s/%s/", pk_dir,PK_LITE_OBJ_DIR); rc = object_flatten( obj, &obj_data, &obj_data_len ); obj_data_len_32 = obj_data_len; if (rc != CKR_OK){ st_err_log(101, __FILE__, __LINE__); goto error; } // // format for the object file: // private flag // ---- begin encrypted part <--+ // length of object data | // object data +---- sensitive part // SHA of (object data) | // ---- end encrypted part <--+ // compute_sha( obj_data, obj_data_len, hash_sha ); // encrypt the sensitive object data. need to be careful. // if I use the normal high-level encryption routines I'll need to // create a tepmorary key object containing the master key, perform the // encryption, then destroy the key object. There is a race condition // here if the application is multithreaded (if a thread-switch occurs, // the other application thread could do a FindObject and be able to access // the master key object. // // So I have to use the low-level encryption routines. // memcpy( des3_key, master_key, MASTER_KEY_SIZE ); cleartxt_len = sizeof(CK_ULONG_32) + obj_data_len_32 + SHA1_HASH_SIZE; padded_len = DES_BLOCK_SIZE * (cleartxt_len / DES_BLOCK_SIZE + 1); cleartxt = (CK_BYTE *)malloc( padded_len ); ciphertxt = (CK_BYTE *)malloc( padded_len ); if (!cleartxt || !ciphertxt) { st_err_log(0, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto error; } ciphertxt_len = padded_len; ptr = cleartxt; memcpy( ptr, &obj_data_len_32, sizeof(CK_ULONG_32) ); ptr += sizeof(CK_ULONG_32); memcpy( ptr, obj_data, obj_data_len_32 ); ptr += obj_data_len_32; memcpy( ptr, hash_sha, SHA1_HASH_SIZE ); add_pkcs_padding( cleartxt + cleartxt_len, DES_BLOCK_SIZE, cleartxt_len, padded_len ); #ifndef CLEARTEXT // SAB XXX some crypto libraries expect to be able to change th einitial vector. // so we will enable that by a local variable { CK_BYTE *initial_vector=NULL; initial_vector = (CK_BYTE *)alloca(strlen("10293847")+5); if (initial_vector) { memcpy(initial_vector, "10293847", strlen("10293847")); rc = ckm_des3_cbc_encrypt( cleartxt, padded_len, ciphertxt, &ciphertxt_len, initial_vector, des3_key ); } else { rc=CKR_FUNCTION_FAILED; } } #else memcpy(ciphertxt, cleartxt, padded_len); rc = CKR_OK; #endif if (rc != CKR_OK){ st_err_log(105, __FILE__, __LINE__); goto error; } strncat( (char *)fname,(char *) obj->name, 8 ); fp = fopen( (char *)fname, "w" ); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } set_perm(fileno(fp)); total_len = sizeof(CK_ULONG_32) + sizeof(CK_BBOOL) + ciphertxt_len; flag = TRUE; (void)fwrite( &total_len, sizeof(CK_ULONG_32), 1, fp ); (void)fwrite( &flag, sizeof(CK_BBOOL), 1, fp ); (void)fwrite( ciphertxt, ciphertxt_len, 1, fp ); fclose( fp ); free( obj_data ); free( cleartxt ); free( ciphertxt ); return CKR_OK; error: if (fp) fclose( fp ); if (obj_data) free( obj_data ); if (cleartxt) free( cleartxt ); if (ciphertxt) free( ciphertxt ); return rc; } // // CK_RV load_public_token_objects( void ) { FILE *fp1 = NULL, *fp2 = NULL; CK_BYTE *buf = NULL; CK_BYTE tmp[PATH_MAX], fname[PATH_MAX],iname[PATH_MAX]; CK_BBOOL priv; CK_ULONG_32 size; sprintf((char *)iname,"%s/%s/%s",pk_dir,PK_LITE_OBJ_DIR, PK_LITE_OBJ_IDX); fp1 = fopen((char *)iname, "r"); if (!fp1) return CKR_OK; // no token objects while (!feof(fp1)) { (void)fgets( (char *)tmp, 50, fp1 ); if (!feof(fp1)) { tmp[ strlen((char *)tmp)-1 ] = 0; sprintf((char *)fname,"%s/%s/",pk_dir, PK_LITE_OBJ_DIR); strcat((char *)fname, (char *)tmp ); fp2 = fopen( (char *)fname, "r" ); if (!fp2) continue; fread( &size, sizeof(CK_ULONG_32), 1, fp2 ); fread( &priv, sizeof(CK_BBOOL), 1, fp2 ); if (priv == TRUE) { fclose( fp2 ); continue; } // size--; size = size -sizeof(CK_ULONG_32) - sizeof(CK_BBOOL); buf = (CK_BYTE *)malloc(size); if (!buf) { fclose(fp1); fclose(fp2); st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } fread( buf, size, 1, fp2 ); // ... grab object mutex here. MY_LockMutex(&obj_list_mutex); object_mgr_restore_obj( buf, NULL ); MY_UnlockMutex(&obj_list_mutex); free( buf ); fclose( fp2 ); } } fclose(fp1); return CKR_OK; } // // CK_RV load_private_token_objects( void ) { FILE *fp1 = NULL, *fp2 = NULL; CK_BYTE *buf = NULL; CK_BYTE tmp[PATH_MAX], fname[PATH_MAX], iname[PATH_MAX]; CK_BBOOL priv; CK_ULONG_32 size; CK_RV rc; sprintf((char *)iname,"%s/%s/%s",pk_dir,PK_LITE_OBJ_DIR, PK_LITE_OBJ_IDX); fp1 = fopen((char *)iname, "r"); if (!fp1) return CKR_OK; // no token objects while (!feof(fp1)) { (void)fgets((char *) tmp, 50, fp1 ); if (!feof(fp1)) { tmp[ strlen((char *)tmp)-1 ] = 0; sprintf((char *)fname,"%s/%s/",pk_dir,PK_LITE_OBJ_DIR); strcat((char *)fname,(char *) tmp ); fp2 = fopen( (char *)fname, "r" ); if (!fp2) continue; fread( &size, sizeof(CK_ULONG_32), 1, fp2 ); fread( &priv, sizeof(CK_BBOOL), 1, fp2 ); if (priv == FALSE) { fclose( fp2 ); continue; } //size--; size = size - sizeof(CK_ULONG_32) - sizeof(CK_BBOOL); buf = (CK_BYTE *)malloc(size); if (!buf) { st_err_log(0, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto error; } rc = fread( (char *)buf, size, 1, fp2 ); if (rc != 1) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } // Grab object list mutex MY_LockMutex(&obj_list_mutex); rc = restore_private_token_object( buf, size, NULL ); MY_UnlockMutex(&obj_list_mutex); if (rc != CKR_OK){ st_err_log(107, __FILE__, __LINE__); goto error; } free( buf ); fclose( fp2 ); } } fclose(fp1); return CKR_OK; error: if (buf) free( buf ); if (fp1) fclose( fp1 ); if (fp2) fclose( fp2 ); return rc; } // // CK_RV restore_private_token_object( CK_BYTE * data, CK_ULONG len, OBJECT * pObj ) { CK_BYTE * cleartxt = NULL; CK_BYTE * obj_data = NULL; CK_BYTE * ciphertxt = NULL; CK_BYTE * ptr = NULL; CK_BYTE des3_key[MASTER_KEY_SIZE]; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_ULONG cleartxt_len, obj_data_len; CK_RV rc; // format for the object data: // (private flag has already been read at this point) // ---- begin encrypted part // length of object data // object data // SHA of object data // ---- end encrypted part // cleartxt_len = len; cleartxt = (CK_BYTE *)malloc(len); if (!cleartxt) { st_err_log(0, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } ciphertxt = data; // decrypt the encrypted chunk // memcpy( des3_key, master_key, MASTER_KEY_SIZE ); #ifndef CLEARTEXT { CK_BYTE *initial_vector=NULL; initial_vector = (CK_BYTE *)alloca(strlen("10293847")+5); if (initial_vector) { memcpy(initial_vector, "10293847", strlen("10293847")); rc = ckm_des3_cbc_decrypt( ciphertxt, len, cleartxt, &len, initial_vector, des3_key ); } else { rc=CKR_FUNCTION_FAILED; } } #else memcpy(cleartxt, ciphertxt, len); rc = CKR_OK; #endif if (rc != CKR_OK){ st_err_log(106, __FILE__, __LINE__); goto done; } strip_pkcs_padding( cleartxt, len, &cleartxt_len ); // if the padding extraction didn't work it means the object was tampered with or // the key was incorrect // if (cleartxt_len > len) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } ptr = cleartxt; obj_data_len = *(CK_ULONG_32 *)ptr; ptr += sizeof(CK_ULONG_32); obj_data = ptr; // check the hash // compute_sha( ptr, obj_data_len, hash_sha ); ptr += obj_data_len; if (memcmp(ptr, hash_sha, SHA1_HASH_SIZE) != 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } // okay. at this point, we're satisfied that nobody has tampered with the // token object... // object_mgr_restore_obj( obj_data, pObj ); rc = CKR_OK; done: if (cleartxt) free( cleartxt ); return rc; } // // CK_RV load_masterkey_so( void ) { FILE * fp = NULL; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_BYTE cipher[sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE clear [sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE des3_key[3 * DES_KEY_SIZE]; MASTER_KEY_FILE_T mk; CK_ULONG cipher_len, clear_len; CK_RV rc; CK_BYTE fname[PATH_MAX]; sprintf((char *)fname,"%s/MK_SO",pk_dir); memset( master_key, 0x0, MASTER_KEY_SIZE ); // this file gets created on C_InitToken so we can assume that it always exists // fp = fopen((char *)fname, "r"); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } set_perm(fileno(fp)); clear_len = cipher_len = (sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE - 1) & ~(DES_BLOCK_SIZE - 1); rc = fread( cipher, cipher_len, 1, fp ); if (rc != 1) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } // decrypt the master key data using the MD5 of the SO key // (we can't use the SHA of the SO key since the SHA of the key is stored // in the token data file). // memcpy( des3_key, so_pin_md5, MD5_HASH_SIZE ); memcpy( des3_key + MD5_HASH_SIZE, so_pin_md5, DES_KEY_SIZE ); #ifndef CLEARTEXT { CK_BYTE *initial_vector=NULL; initial_vector = (CK_BYTE *)alloca(strlen("12345678")+5); if (initial_vector) { memcpy(initial_vector, "12345678", strlen("12345678")); rc = sw_des3_cbc_decrypt( cipher, cipher_len, clear, &clear_len, initial_vector, des3_key ); } else { rc=CKR_FUNCTION_FAILED; } } #else memcpy(clear, cipher, cipher_len); rc = CKR_OK; #endif if (rc != CKR_OK){ st_err_log(106, __FILE__, __LINE__); goto done; } memcpy( (CK_BYTE *)&mk, clear, sizeof(mk) ); // // technically should strip PKCS padding here but since I already know what // the length should be, I don't bother. // // compare the hashes // compute_sha( mk.key, MASTER_KEY_SIZE, hash_sha ); if (memcmp(hash_sha, mk.sha_hash, SHA1_HASH_SIZE) != 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } memcpy( master_key, mk.key, MASTER_KEY_SIZE ); rc = CKR_OK; done: if (fp) fclose(fp); return rc; } // // CK_RV load_masterkey_user( void ) { FILE * fp = NULL; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_BYTE cipher[sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE clear[sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE des3_key[3 * DES_KEY_SIZE]; MASTER_KEY_FILE_T mk; CK_ULONG cipher_len, clear_len; CK_RV rc; CK_BYTE fname[PATH_MAX]; sprintf((char *)fname,"%s/MK_USER",pk_dir); memset( master_key, 0x0, MASTER_KEY_SIZE ); // this file gets created on C_InitToken so we can assume that it always exists // fp = fopen( (char *)fname, "r" ); if (!fp) { LogError("fopen(%s): %s", fname, strerror(errno)); rc = CKR_FUNCTION_FAILED; goto done; } set_perm(fileno(fp)); clear_len = cipher_len = (sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE - 1) & ~(DES_BLOCK_SIZE - 1); rc = fread( cipher, cipher_len, 1, fp ); if (rc != 1) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } // decrypt the master key data using the MD5 of the SO key // (we can't use the SHA of the SO key since the SHA of the key is stored // in the token data file). // memcpy( des3_key, user_pin_md5, MD5_HASH_SIZE ); memcpy( des3_key + MD5_HASH_SIZE, user_pin_md5, DES_KEY_SIZE ); #ifndef CLEARTEXT { CK_BYTE *initial_vector=NULL; initial_vector = (CK_BYTE *)alloca(strlen("12345678")+5); if (initial_vector) { memcpy(initial_vector, "12345678", strlen("12345678")); rc = sw_des3_cbc_decrypt( cipher, cipher_len, clear, &clear_len, initial_vector, des3_key ); } else { rc=CKR_FUNCTION_FAILED; } } #else memcpy(clear, cipher, cipher_len); rc = CKR_OK; #endif if (rc != CKR_OK){ st_err_log(106, __FILE__, __LINE__); goto done; } memcpy( (CK_BYTE *)&mk, clear, sizeof(mk) ); // // technically should strip PKCS padding here but since I already know what // the length should be, I don't bother. // // compare the hashes // compute_sha( mk.key, MASTER_KEY_SIZE, hash_sha ); if (memcmp(hash_sha, mk.sha_hash, SHA1_HASH_SIZE) != 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } memcpy( master_key, mk.key, MASTER_KEY_SIZE ); rc = CKR_OK; done: if (fp) fclose(fp); return rc; } // // CK_RV save_masterkey_so( void ) { FILE * fp = NULL; CK_BYTE cleartxt [sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE ciphertxt[sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE des3_key[3 * DES_KEY_SIZE]; MASTER_KEY_FILE_T mk; CK_ULONG cleartxt_len, ciphertxt_len, padded_len; CK_RV rc; CK_BYTE fname[PATH_MAX]; memcpy( mk.key, master_key, MASTER_KEY_SIZE); compute_sha( master_key, MASTER_KEY_SIZE, mk.sha_hash ); // encrypt the key data // memcpy( des3_key, so_pin_md5, MD5_HASH_SIZE ); memcpy( des3_key + MD5_HASH_SIZE, so_pin_md5, DES_KEY_SIZE ); ciphertxt_len = sizeof(ciphertxt); cleartxt_len = sizeof(mk); memcpy( cleartxt, &mk, cleartxt_len ); padded_len = DES_BLOCK_SIZE * (cleartxt_len / DES_BLOCK_SIZE + 1); add_pkcs_padding( cleartxt + cleartxt_len, DES_BLOCK_SIZE, cleartxt_len, padded_len ); #ifndef CLEARTEXT { CK_BYTE *initial_vector=NULL; initial_vector = (CK_BYTE *)alloca(strlen("12345678")); if (initial_vector) { memcpy(initial_vector, "12345678", strlen("12345678")); rc = sw_des3_cbc_encrypt( cleartxt, padded_len, ciphertxt, &ciphertxt_len, initial_vector, des3_key ); } else { rc=CKR_FUNCTION_FAILED; } } #else memcpy(ciphertxt, cleartxt, padded_len); rc = CKR_OK; #endif if (rc != CKR_OK){ st_err_log(105, __FILE__, __LINE__); goto done; } // write the file // // probably ought to ensure the permissions are correct // sprintf((char *)fname,"%s/MK_SO",pk_dir); fp = fopen( (char *)fname, "w" ); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } set_perm(fileno(fp)); rc = fwrite( ciphertxt, ciphertxt_len, 1, fp ); if (rc != 1) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } rc = CKR_OK; done: if (fp) fclose( fp ); return rc; } // // CK_RV save_masterkey_user( void ) { FILE * fp = NULL; CK_BYTE cleartxt [sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE ciphertxt[sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE des3_key[3 * DES_KEY_SIZE]; MASTER_KEY_FILE_T mk; CK_ULONG cleartxt_len, ciphertxt_len, padded_len; CK_RV rc; CK_BYTE fname[PATH_MAX]; memcpy( mk.key, master_key, MASTER_KEY_SIZE); compute_sha( master_key, MASTER_KEY_SIZE, mk.sha_hash ); // encrypt the key data // memcpy( des3_key, user_pin_md5, MD5_HASH_SIZE ); memcpy( des3_key + MD5_HASH_SIZE, user_pin_md5, DES_KEY_SIZE ); ciphertxt_len = sizeof(ciphertxt); cleartxt_len = sizeof(mk); memcpy( cleartxt, &mk, cleartxt_len ); padded_len = DES_BLOCK_SIZE * (cleartxt_len / DES_BLOCK_SIZE + 1); add_pkcs_padding( cleartxt + cleartxt_len, DES_BLOCK_SIZE, cleartxt_len, padded_len ); #ifndef CLEARTEXT { CK_BYTE *initial_vector=NULL; initial_vector = (CK_BYTE *)alloca(strlen("12345678")+5); if (initial_vector) { memcpy(initial_vector, "12345678", strlen("12345678")); rc = sw_des3_cbc_encrypt( cleartxt, padded_len, ciphertxt, &ciphertxt_len, initial_vector, des3_key ); } else { rc=CKR_FUNCTION_FAILED; } } #else memcpy(ciphertxt, cleartxt, padded_len); rc = CKR_OK; #endif if (rc != CKR_OK){ st_err_log(105, __FILE__, __LINE__); goto done; } // write the file // // probably ought to ensure the permissions are correct // sprintf((char *)fname,"%s/MK_USER", pk_dir); fp = fopen( (char *)fname, "w" ); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } set_perm(fileno(fp)); rc = fwrite( ciphertxt, ciphertxt_len, 1, fp ); if (rc != 1) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } rc = CKR_OK; done: if (fp) fclose( fp ); return rc; } // // CK_RV reload_token_object( OBJECT *obj ) { FILE * fp = NULL; CK_BYTE * buf = NULL; CK_BYTE fname[PATH_MAX]; CK_BBOOL priv; CK_ULONG_32 size; CK_ULONG size_64; CK_RV rc; memset( (char *)fname, 0x0, sizeof(fname) ); sprintf((char *)fname,"%s/%s/",pk_dir, PK_LITE_OBJ_DIR); strncat((char *)fname,(char *) obj->name, 8 ); fp = fopen( (char *)fname, "r" ); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } set_perm(fileno(fp)); fread( &size, sizeof(CK_ULONG_32), 1, fp ); fread( &priv, sizeof(CK_BBOOL), 1, fp ); size = size - sizeof(CK_ULONG_32) - sizeof(CK_BBOOL); // SAB buf = (CK_BYTE *)malloc(size); if (!buf) { st_err_log(0, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } fread( buf, size, 1, fp ); size_64 = size; if (priv){ rc = restore_private_token_object( buf, size_64, obj ); if (rc != CKR_OK) st_err_log(107, __FILE__, __LINE__); } else{ rc = object_mgr_restore_obj( buf, obj ); if (rc != CKR_OK) st_err_log(108, __FILE__, __LINE__); } done: if (fp) fclose( fp ); if (buf) free( buf ); return rc; } extern void set_perm(int) ; // // CK_RV delete_token_object( OBJECT *obj ) { FILE *fp1, *fp2; CK_BYTE line[100]; CK_BYTE objidx[PATH_MAX], idxtmp[PATH_MAX],fname[PATH_MAX]; sprintf((char *)objidx,"%s/%s/%s",pk_dir, PK_LITE_OBJ_DIR,PK_LITE_OBJ_IDX); sprintf((char *)idxtmp,"%s/%s/%s",pk_dir, PK_LITE_OBJ_DIR, "IDX.TMP"); // FIXME: on UNIX, we need to make sure these guys aren't symlinks // before we blindly write to these files... // // remove the object from the index file // fp1 = fopen((char *)objidx, "r"); fp2 = fopen((char *)idxtmp, "w"); if (!fp1 || !fp2) { if (fp1) fclose(fp1); if (fp2) fclose(fp2); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } set_perm(fileno(fp2)); while (!feof(fp1)) { (void)fgets((char *)line, 50, fp1 ); if (!feof(fp1)) { line[ strlen((char *)line)-1 ] = 0; if (strcmp((char *)line, (char *)obj->name) == 0) continue; else fprintf( fp2, "%s\n", line ); } } fclose(fp1); fclose(fp2); fp2 = fopen((char *)objidx, "w"); fp1 = fopen((char *)idxtmp, "r"); if (!fp1 || !fp2) { if (fp1) fclose(fp1); if (fp2) fclose(fp2); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } set_perm(fileno(fp2)); while (!feof(fp1)) { (void)fgets((char *)line, 50, fp1 ); if (!feof(fp1)) fprintf( fp2, "%s",(char *) line ); } fclose(fp1); fclose(fp2); sprintf((char *)fname,"%s/%s/%s",pk_dir, PK_LITE_OBJ_DIR,(char *)obj->name); unlink((char *)fname); return CKR_OK; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/globals.c0000640000175000017500000003500711327631345021150 0ustar jfjf/* * Licensed materials, Property of IBM Corp. * * openCryptoki CCA token * * (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2006 * * Author: Kent E. Yoder * */ /*************************************************************************** Change Log ========== 4/25/03 Kapil Sood (kapil@corrent.com) Added DH key pair generation and DH shared key derivation functions. ****************************************************************************/ #include #include #include "cca_stdll.h" #include "pkcs11types.h" #include "stdll.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" CK_SLOT_INFO slot_info; CK_BBOOL initialized = FALSE; // native_mutex is used to protect C_Initialize. It gets created when the DLL // is attached, it gets destroyed when the DLL is detached // pthread_mutex_t native_mutex ; MUTEX pkcs_mutex, obj_list_mutex, sess_list_mutex, login_mutex; #if SYSVSEM int xprocsemid = -1; #endif void *xproclock; DL_NODE *sess_list = NULL; DL_NODE *sess_obj_list = NULL; DL_NODE *publ_token_obj_list = NULL; DL_NODE *priv_token_obj_list = NULL; DL_NODE *object_map = NULL; CK_STATE global_login_state = 0; LW_SHM_TYPE *global_shm; CK_ULONG next_session_handle = 1; CK_ULONG next_object_handle = 1; TOKEN_DATA *nv_token_data = NULL; struct ST_FCN_LIST function_list ; extern CK_RV LW_Initialize(); /* extern CK_RV SC_Initialize */ extern CK_RV SC_GetFunctionList(); /* extern CK_RV SC_GetFunctionList */ extern CK_RV SC_GetTokenInfo(); /* extern CK_RV SC_GetTokenInfo */ extern CK_RV SC_GetMechanismList(); /* extern CK_RV SC_GetMechanismList */ extern CK_RV SC_GetMechanismInfo(); /* extern CK_RV SC_GetMechanismInfo */ extern CK_RV SC_InitToken(); /* extern CK_RV SC_InitToken */ extern CK_RV SC_InitPIN(); /* extern CK_RV SC_InitPIN */ extern CK_RV SC_SetPIN(); /* extern CK_RV SC_SetPIN */ extern CK_RV SC_OpenSession(); /* extern CK_RV SC_OpenSession */ extern CK_RV SC_CloseSession(); /* extern CK_RV SC_CloseSession */ extern CK_RV SC_CloseAllSessions(); /* extern CK_RV SC_CloseAllSessions */ extern CK_RV SC_GetSessionInfo(); /* extern CK_RV SC_GetSessionInfo */ extern CK_RV SC_GetOperationState(); /* extern CK_RV SC_GetOperationState */ extern CK_RV SC_SetOperationState(); /* extern CK_RV SC_SetOperationState */ extern CK_RV SC_Login(); /* extern CK_RV SC_Login */ extern CK_RV SC_Logout(); /* extern CK_RV SC_Logout */ extern CK_RV SC_CreateObject(); /* extern CK_RV SC_CreateObject */ extern CK_RV SC_CopyObject(); /* extern CK_RV SC_CopyObject */ extern CK_RV SC_DestroyObject(); /* extern CK_RV SC_DestroyObject */ extern CK_RV SC_GetObjectSize(); /* extern CK_RV SC_GetObjectSize */ extern CK_RV SC_GetAttributeValue(); /* extern CK_RV SC_GetAttributeValue */ extern CK_RV SC_SetAttributeValue(); /* extern CK_RV SC_SetAttributeValue */ extern CK_RV SC_FindObjectsInit(); /* extern CK_RV SC_FindObjectsInit */ extern CK_RV SC_FindObjects(); /* extern CK_RV SC_FindObjects */ extern CK_RV SC_FindObjectsFinal(); /* extern CK_RV SC_FindObjectsFinal */ extern CK_RV SC_EncryptInit(); /* extern CK_RV SC_EncryptInit */ extern CK_RV SC_Encrypt(); /* extern CK_RV SC_Encrypt */ extern CK_RV SC_EncryptUpdate(); /* extern CK_RV SC_EncryptUpdate */ extern CK_RV SC_EncryptFinal(); /* extern CK_RV SC_EncryptFinal */ extern CK_RV SC_DecryptInit(); /* extern CK_RV SC_DecryptInit */ extern CK_RV SC_Decrypt(); /* extern CK_RV SC_Decrypt */ extern CK_RV SC_DecryptUpdate(); /* extern CK_RV SC_DecryptUpdate */ extern CK_RV SC_DecryptFinal(); /* extern CK_RV SC_DecryptFinal */ extern CK_RV SC_DigestInit(); /* extern CK_RV SC_DigestInit */ extern CK_RV SC_Digest(); /* extern CK_RV SC_Digest */ extern CK_RV SC_DigestUpdate(); /* extern CK_RV SC_DigestUpdate */ extern CK_RV SC_DigestKey(); /* extern CK_RV SC_DigestKey */ extern CK_RV SC_DigestFinal(); /* extern CK_RV SC_DigestFinal */ extern CK_RV SC_SignInit(); /* extern CK_RV SC_SignInit */ extern CK_RV SC_Sign(); /* extern CK_RV SC_Sign */ extern CK_RV SC_SignUpdate(); /* extern CK_RV SC_SignUpdate */ extern CK_RV SC_SignFinal(); /* extern CK_RV SC_SignFinal */ extern CK_RV SC_SignRecoverInit(); /* extern CK_RV SC_SignRecoverInit */ extern CK_RV SC_SignRecover(); /* extern CK_RV SC_SignRecover */ extern CK_RV SC_VerifyInit(); /* extern CK_RV SC_VerifyInit */ extern CK_RV SC_Verify(); /* extern CK_RV SC_Verify */ extern CK_RV SC_VerifyUpdate(); /* extern CK_RV SC_VerifyUpdate */ extern CK_RV SC_VerifyFinal(); /* extern CK_RV SC_VerifyFinal */ extern CK_RV SC_VerifyRecoverInit(); /* extern CK_RV SC_VerifyRecoverInit */ extern CK_RV SC_VerifyRecover(); /* extern CK_RV SC_VerifyRecover */ extern CK_RV SC_DigestEncryptUpdate(); /* extern CK_RV SC_DigestEncryptUpdate */ extern CK_RV SC_DecryptDigestUpdate(); /* extern CK_RV SC_DecryptDigestUpdate */ extern CK_RV SC_SignEncryptUpdate(); /* extern CK_RV SC_SignEncryptUpdate */ extern CK_RV SC_DecryptVerifyUpdate(); /* extern CK_RV SC_DecryptVerifyUpdate */ extern CK_RV SC_GenerateKey(); /* extern CK_RV SC_GenerateKey */ extern CK_RV SC_GenerateKeyPair(); /* extern CK_RV SC_GenerateKeyPair */ extern CK_RV SC_WrapKey(); /* extern CK_RV SC_WrapKey */ extern CK_RV SC_UnwrapKey(); /* extern CK_RV SC_UnwrapKey */ extern CK_RV SC_DeriveKey(); /* extern CK_RV SC_DeriveKey */ extern CK_RV SC_SeedRandom(); /* extern CK_RV SC_SeedRandom */ extern CK_RV SC_GenerateRandom(); /* extern CK_RV SC_GenerateRandom */ extern CK_RV SC_GetFunctionStatus(); /* extern CK_RV SC_GetFunctionStatus */ extern CK_RV SC_CancelFunction(); /* extern CK_RV SC_CancelFunction */ extern CK_RV SC_WaitForSlotEvent(); /* extern CK_RV SC_WaitForSlotEvent */ // OBJECT IDENTIFIERs // CK_BYTE ber_idDSA[] = { 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01 }; CK_BYTE ber_rsaEncryption[] = { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 }; CK_BYTE ber_md2WithRSAEncryption[] = { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02 }; CK_BYTE ber_md4WithRSAEncryption[] = { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x03 }; CK_BYTE ber_md5WithRSAEncryption[] = { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x04 }; CK_BYTE ber_sha1WithRSAEncryption[] = { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05 }; // Algorithm IDs. (Sequence of OID plus parms, usually NULL) // CK_BYTE ber_AlgMd2[] = { 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x02, 0x05, 0x00 }; CK_BYTE ber_AlgMd5[] = { 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00 }; CK_BYTE ber_AlgSha1[] = { 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00 }; CK_BYTE ber_AlgSha256[] = { 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00 }; CK_BYTE ber_AlgIdRSAEncryption[] = { 0x30, 0x0D, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00 }; // ID Lengths // CK_ULONG ber_idDSALen = sizeof(ber_idDSA); CK_ULONG ber_rsaEncryptionLen = sizeof(ber_rsaEncryption); CK_ULONG ber_md2WithRSAEncryptionLen = sizeof(ber_md2WithRSAEncryption); CK_ULONG ber_md4WithRSAEncryptionLen = sizeof(ber_md4WithRSAEncryption); CK_ULONG ber_md5WithRSAEncryptionLen = sizeof(ber_md5WithRSAEncryption); CK_ULONG ber_sha1WithRSAEncryptionLen= sizeof(ber_sha1WithRSAEncryption); CK_ULONG ber_AlgMd2Len= sizeof(ber_AlgMd2); CK_ULONG ber_AlgMd5Len= sizeof(ber_AlgMd5); CK_ULONG ber_AlgSha1Len= sizeof(ber_AlgSha1); CK_ULONG ber_AlgSha256Len= sizeof(ber_AlgSha256); CK_ULONG ber_AlgIdRSAEncryptionLen = sizeof(ber_AlgIdRSAEncryption); CK_ULONG des_weak_count = 4; CK_ULONG des_semi_weak_count = 12; CK_ULONG des_possibly_weak_count = 48; CK_BYTE des_weak_keys[4][8] = { {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, {0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E}, {0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1}, {0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE} }; CK_BYTE des_semi_weak_keys[12][8] = { {0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE}, {0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01}, {0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1}, {0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E}, {0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1}, {0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01}, {0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE}, {0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E}, {0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E}, {0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01}, {0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE}, {0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1} }; CK_BYTE des_possibly_weak_keys[48][8] = { {0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E, 0x01, 0x01}, {0x01, 0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E, 0x01}, {0x1F, 0x01, 0x01, 0x1F, 0x0E, 0x01, 0x01, 0x0E}, {0x01, 0x01, 0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E}, {0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1, 0x01, 0x01}, {0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01}, {0xFE, 0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E, 0x01}, {0xE0, 0xFE, 0x1F, 0x01, 0xF1, 0xFE, 0x0E, 0x01}, {0xFE, 0xE0, 0x01, 0x1F, 0xFE, 0xF1, 0x01, 0x0E}, {0xE0, 0xFE, 0x01, 0x1F, 0xF1, 0xFE, 0x01, 0x0E}, {0xE0, 0xE0, 0x1F, 0x1F, 0xF1, 0xF1, 0x0E, 0x0E}, {0xFE, 0xFE, 0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E}, {0xFE, 0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1, 0x01}, {0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E, 0xFE, 0x01}, {0xFE, 0x01, 0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E}, {0xE0, 0x01, 0xFE, 0x1F, 0xF1, 0x01, 0xFE, 0x0E}, {0x01, 0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1, 0x01}, {0x1F, 0xFE, 0xE0, 0x01, 0x0E, 0xFE, 0xF0, 0x01}, {0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1, 0xFE, 0x01}, {0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01}, {0x1F, 0xE0, 0xE0, 0x1F, 0x0E, 0xF1, 0xF1, 0x0E}, {0x01, 0xFE, 0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E}, {0x01, 0xE0, 0xFE, 0x1F, 0x01, 0xF1, 0xFE, 0x0E}, {0x1F, 0xFE, 0xFE, 0x1F, 0x0E, 0xFE, 0xFE, 0x0E}, {0xE0, 0x01, 0x01, 0xE0, 0xF1, 0x01, 0x01, 0xF1}, {0xFE, 0x1F, 0x01, 0xE0, 0xFE, 0x0E, 0x01, 0xF1}, {0xFE, 0x01, 0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1}, {0xE0, 0x1F, 0x1F, 0xE0, 0xF1, 0x0E, 0x0E, 0xF1}, {0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE}, {0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E, 0x01, 0xFE}, {0xE0, 0x01, 0x1F, 0xFE, 0xF1, 0x01, 0x0E, 0xFE}, {0xFE, 0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E, 0xFE}, {0x1F, 0xFE, 0x01, 0xE0, 0x0E, 0xFE, 0x01, 0xF1}, {0x01, 0xFE, 0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1}, {0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1, 0x01, 0xFE}, {0x01, 0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E, 0xFE}, {0x01, 0x01, 0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1}, {0x1F, 0x1F, 0xE0, 0xE0, 0x0E, 0x0E, 0xF1, 0xF1}, {0x1F, 0x01, 0xFE, 0xE0, 0x0E, 0x01, 0xFE, 0xF1}, {0x01, 0x1F, 0xFE, 0xE0, 0x01, 0x0E, 0xFE, 0xF1}, {0x1F, 0x01, 0xE0, 0xFE, 0x0E, 0x01, 0xF1, 0xFE}, {0x01, 0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1, 0xFE}, {0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE}, {0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E, 0xFE, 0xFE}, {0xFE, 0xFE, 0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1}, {0xE0, 0xFE, 0xFE, 0xE0, 0xF1, 0xFE, 0xFE, 0xF1}, {0xFE, 0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1, 0xFE}, {0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1, 0xFE, 0xFE} }; // default SO pin hash values // // default SO pin = "87654321" // CK_BYTE default_so_pin_md5[MD5_HASH_SIZE] = { 0x5E, 0x86, 0x67, 0xA4, 0x39, 0xC6, 0x8F, 0x51, 0x45, 0xDD, 0x2F, 0xCB, 0xEC, 0xF0, 0x22, 0x09 }; CK_BYTE default_so_pin_sha[SHA1_HASH_SIZE] = { 0xA7, 0xD5, 0x79, 0xBA, 0x76, 0x39, 0x80, 0x70, 0xEA, 0xE6, 0x54, 0xC3, 0x0F, 0xF1, 0x53, 0xA4, 0xC2, 0x73, 0x27, 0x2A }; /* SHA-1 of "12345678" */ CK_BYTE default_user_pin_sha[SHA1_HASH_SIZE] = { 0x7c, 0x22, 0x2f, 0xb2, 0x92, 0x7d, 0x82, 0x8a, 0xf2, 0x2f, 0x59, 0x21, 0x34, 0xe8, 0x93, 0x24, 0x80, 0x63, 0x7c, 0x0d }; CK_BYTE user_pin_md5[MD5_HASH_SIZE]; CK_BYTE so_pin_md5[MD5_HASH_SIZE]; CK_BYTE master_key[MASTER_KEY_SIZE]; opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cca_stdll/encr_mgr.c0000640000175000017500000006036111327631345021322 0ustar jfjf/* * Licensed materials, Property of IBM Corp. * * openCryptoki CCA token * * (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2006 * */ // File: encr_mgr.c // // Encryption manager routines // //#include #include #include // for memcmp() et al #include #include "cca_stdll.h" #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // // CK_RV encr_mgr_init( SESSION * sess, ENCR_DECR_CONTEXT * ctx, CK_ULONG operation, CK_MECHANISM * mech, CK_OBJECT_HANDLE key_handle ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_KEY_TYPE keytype; CK_BBOOL flag; CK_RV rc; if (!sess || !ctx || !mech){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active != FALSE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } // key usage restrictions // if (operation == OP_ENCRYPT_INIT) { rc = object_mgr_find_in_map1( key_handle, &key_obj ); if (rc != CKR_OK){ st_err_log(18, __FILE__, __LINE__); return CKR_KEY_HANDLE_INVALID; } // is key allowed to do general encryption? // rc = template_attribute_find( key_obj->template, CKA_ENCRYPT, &attr ); if (rc == FALSE){ st_err_log(85, __FILE__, __LINE__); return CKR_KEY_FUNCTION_NOT_PERMITTED; } else { flag = *(CK_BBOOL *)attr->pValue; if (flag != TRUE){ st_err_log(85, __FILE__, __LINE__); return CKR_KEY_FUNCTION_NOT_PERMITTED; } } } else if (operation == OP_WRAP) { rc = object_mgr_find_in_map1( key_handle, &key_obj ); if (rc != CKR_OK){ st_err_log(62, __FILE__, __LINE__); return CKR_WRAPPING_KEY_HANDLE_INVALID; } // is key allowed to wrap other keys? // rc = template_attribute_find( key_obj->template, CKA_WRAP, &attr ); if (rc == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } else { flag = *(CK_BBOOL *)attr->pValue; if (flag == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } } } else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // is the mechanism supported? is the key type correct? is a // parameter present if required? is the key size allowed? // does the key support encryption? // // Will the FCV allow the operation? // switch (mech->mechanism) { #ifndef NOECB case CKM_DES_ECB: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_56_BIT_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; #ifndef NOCDMF case CKM_CDMF_ECB: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_CDMF){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; #endif #endif case CKM_DES_CBC: case CKM_DES_CBC_PAD: { if (mech->ulParameterLen != DES_BLOCK_SIZE){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_56_BIT_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; #ifndef NOCDMF case CKM_CDMF_CBC: case CKM_CDMF_CBC_PAD: { if (mech->ulParameterLen != DES_BLOCK_SIZE){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_CDMF){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; #endif #ifndef NOECB case CKM_DES3_ECB: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES3 && keytype != CKK_DES2){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_TRIPLE_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; #endif case CKM_DES3_CBC: case CKM_DES3_CBC_PAD: { if (mech->ulParameterLen != DES_BLOCK_SIZE){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES3 && keytype != CKK_DES2){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_TRIPLE_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_RSA_X_509: case CKM_RSA_PKCS: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_RSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // rc = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); // if (rc == FALSE || nv_FCV.SymmetricModLength/8 < attr->value_length) // return (operation == OP_DECRYPT_INIT ? CKR_KEY_SIZE_RANGE : CKR_WRAPPING_KEY_SIZE_RANGE ); // RSA cannot be used for multi-part operations // ctx->context_len = 0; ctx->context = NULL; } break; #ifndef NOAES case CKM_AES_ECB: { // XXX Copied in from DES3, should be verified - KEY if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_AES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(AES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(AES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(AES_CONTEXT) ); } break; case CKM_AES_CBC: case CKM_AES_CBC_PAD: { // XXX Copied in from DES3, should be verified - KEY if (mech->ulParameterLen != AES_INIT_VECTOR_SIZE){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_AES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(AES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(AES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(AES_CONTEXT) ); } break; #endif default: st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } if (mech->ulParameterLen > 0) { ptr = (CK_BYTE *)malloc(mech->ulParameterLen); if (!ptr){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( ptr, mech->pParameter, mech->ulParameterLen ); } ctx->key = key_handle; ctx->mech.ulParameterLen = mech->ulParameterLen; ctx->mech.mechanism = mech->mechanism; ctx->mech.pParameter = ptr; ctx->multi = FALSE; ctx->active = TRUE; return CKR_OK; } // // CK_RV encr_mgr_cleanup( ENCR_DECR_CONTEXT *ctx ) { if (!ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } ctx->key = 0; ctx->mech.ulParameterLen = 0; ctx->mech.mechanism = 0; ctx->multi = FALSE; ctx->active = FALSE; ctx->context_len = 0; if (ctx->mech.pParameter) { free( ctx->mech.pParameter ); ctx->mech.pParameter = NULL; } if (ctx->context) { free( ctx->context ); ctx->context = NULL; } return CKR_OK; } // // CK_RV encr_mgr_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } // if the caller just wants the encrypted length, there is no reason to // specify the input data. I just need the data length // if ((length_only == FALSE) && (!in_data || !out_data)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->multi == TRUE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } switch (ctx->mech.mechanism) { #ifndef NOECB #ifndef NOCDMF case CKM_CDMF_ECB: #endif case CKM_DES_ECB: return pk_des_ecb_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif #ifndef NOCDMF case CKM_CDMF_CBC: #endif case CKM_DES_CBC: return pk_des_cbc_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #ifndef NOCDMF case CKM_CDMF_CBC_PAD: #endif case CKM_DES_CBC_PAD: return des_cbc_pad_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #ifndef NOECB case CKM_DES3_ECB: return des3_ecb_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif case CKM_DES3_CBC: return des3_cbc_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_CBC_PAD: return des3_cbc_pad_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_RSA_PKCS: return rsa_pkcs_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #if 0 case CKM_RSA_X_509: return rsa_x509_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif #ifndef NOAES case CKM_AES_CBC: return aes_cbc_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_ECB: return aes_ecb_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_CBC_PAD: return aes_cbc_pad_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif default: st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV encr_mgr_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { if (!sess || !in_data || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!out_data && !length_only){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__, __FUNCTION__); return CKR_OPERATION_NOT_INITIALIZED; } ctx->multi = TRUE; switch (ctx->mech.mechanism) { #ifndef NOECB #ifndef NOCDMF case CKM_CDMF_ECB: #endif case CKM_DES_ECB: return des_ecb_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif #ifndef NOCDMF case CKM_CDMF_CBC: #endif case CKM_DES_CBC: return des_cbc_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #ifndef NOCDMF case CKM_CDMF_CBC_PAD: #endif case CKM_DES_CBC_PAD: return des_cbc_pad_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #ifndef NOECB case CKM_DES3_ECB: return des3_ecb_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif case CKM_DES3_CBC: return des3_cbc_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_CBC_PAD: return des3_cbc_pad_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #ifndef NOAES case CKM_AES_ECB: return aes_ecb_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_CBC: return aes_cbc_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_CBC_PAD: return aes_cbc_pad_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif default: return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV encr_mgr_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__, __FUNCTION__); return CKR_OPERATION_NOT_INITIALIZED; } switch (ctx->mech.mechanism) { #ifndef NOECB #ifndef NOCDMF case CKM_CDMF_ECB: #endif case CKM_DES_ECB: return des_ecb_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); #endif #ifndef NOCDMF case CKM_CDMF_CBC: #endif case CKM_DES_CBC: return des_cbc_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); #ifndef NOCDMF case CKM_CDMF_CBC_PAD: #endif case CKM_DES_CBC_PAD: return des_cbc_pad_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); #ifndef NOECB case CKM_DES3_ECB: return des3_ecb_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); #endif case CKM_DES3_CBC: return des3_cbc_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_DES3_CBC_PAD: return des3_cbc_pad_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); #ifndef NOAES case CKM_AES_ECB: return aes_ecb_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_AES_CBC: return aes_cbc_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_AES_CBC_PAD: return aes_cbc_pad_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); #endif default: return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/api/0000751000175000017500000000000011327631345016175 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/lib/pkcs11/api/apiproto.h0000751000175000017500000003747011327631345020221 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/lib/pkcs11/api/apiproto.h,v 1.2 2006/04/05 20:07:45 kyoder Exp $ */ // /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ // // API local internal function prototypes // // // #ifndef _APIEXT_H #define _APIEXT_H #include "apictl.h" void *attach_shared_memory(); void detach_shared_memory(char *); int API_Initialized(); void Terminate_All_Process_Sessions(); int API_Register(); void API_UnRegister(); int DL_Load_and_Init(API_Slot_t *,CK_SLOT_ID); int XProcLock(void *); int XProcUnLock(void *); void _init(void); void loginit(); void logterm(); void logit( int, char *, ...); void decr_sess_counts(CK_SLOT_ID); void incr_sess_counts(CK_SLOT_ID); void AddToSessionList(Session_Struct_t *); void RemoveFromSessionList(Session_Struct_t *); void DL_UnLoad( API_Slot_t *, CK_SLOT_ID); void DL_Unload(API_Slot_t *); int Valid_Session(Session_Struct_t *, ST_SESSION_T *); int sessions_exist(CK_SLOT_ID); #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/api/apiutil.c0000751000175000017500000010354411327631345020022 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ // // //AIX Pkcs11 Api Utility functions // #if NGPTH #include #else #include #endif #include #include #include #include #include #include #include #include #include #include #include "msg.h" //HACK #include #include // Function prototypes for PKCS11 #include #include #include #if SPINXPL #include #include #include #include static int xplfd=-1; #endif #include #define LIBLOCATION LIB_PATH extern API_Proc_Struct_t *Anchor; /* KEY XXX extern pthread_mutex_t logmutex; */ extern int logging; #include void set_perm(int file) { // Set absolute permissions or rw-rw-r-- fchmod(file,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); } #ifdef DEBUG #define LOGIT logit #else #define LOGIT(...) #endif #define SYSLOG void logit( int, char *, ...); static int enabled=0; // Logging types. Ultimately this will allow // us to log to different log files. The logger will also // handle keeping the files to a decent size. // Much work needs to be done on this capability... // Other logging types need to be implemented void loginit(){ // if (!logging) return; // WE will always log... if (!enabled){ enabled=1; openlog("openCryptokiModule",LOG_PID|LOG_NDELAY,LOG_DAEMON); setlogmask(LOG_UPTO(LOG_DEBUG)); logit(LOG_DEBUG,"Logging enabled %d enabled",enabled); } } void logterm() { enabled = 0; } void logit(int type,char *fmt, ...) { va_list pvar; char buffer[PATH_MAX]; if ( enabled){ // Verify that the requested logging level is less than or // equal to that which is set at compile time. if ( type <= logging ){ va_start(pvar, fmt); vsprintf(buffer,fmt,pvar); va_end(pvar); syslog(type,buffer); } } } #if SYSVSEM #include int Shm_Sem=-1; // system 5 shared memory semaphore... pthread_mutex_t semmtx = PTHREAD_MUTEX_INITIALIZER; // local mutex for semaphore functions... static struct sembuf xlock_lock[2]={ 0,0,0, 0,1,SEM_UNDO }; static struct sembuf xlock_unlock[1] = { 0,-1,(IPC_NOWAIT | SEM_UNDO) }; #endif int XProcLock(void *x) { #if PTHREADXPL return pthread_mutex_lock(x); #elif POSIXSEM #error "posix semaphores need to be defined" #elif SYSVSEM #error "LINUX Code for sysvsem xproc lock needs to be done" #elif NOXPROCLOCK return CKR_OK; #elif SPINXPL if (xplfd == -1 ) { xplfd = open(XPL_FILE,O_CREAT|O_RDWR,S_IRWXU|S_IRWXG|S_IRWXO); } flock(xplfd,LOCK_EX); return CKR_OK; #else #error "XProcess locking needs to be defined" #endif } int XProcUnLock(void *x) { #if PTHREADXPL return pthread_mutex_unlock(x); #elif POSIXSEM #error "posix semaphores need to be defined" #elif SYSVSEM #error "LINUX Code for sysvsem xproc lock needs to be done" #elif NOXPROCLOCK return CKR_OK; #elif SPINXPL flock(xplfd,LOCK_UN); return CKR_OK; #else #error "XProcess locking needs to be definec" #endif } void AddToSessionList(pSess) Session_Struct_t *pSess; { Session_Struct_t *pCur; pthread_mutex_lock(&(Anchor->SessListMutex)); //LOGIT(LOG_DEBUG,"AddToSessionList %x",pSess); pCur = Anchor->SessListBeg; if (!pCur ) { // first time to add //LOGIT(LOG_DEBUG,"\t\tFirst Addition"); pthread_mutex_lock(&(Anchor->ProcMutex)); Anchor->SessListBeg = pSess; pthread_mutex_unlock(&(Anchor->ProcMutex)); pSess->Previous = pSess->Next = NULL; } else { // Go to the end of the list.. while (pCur->Next != NULL ){ //LOGIT(LOG_DEBUG,"\t\tPcur = %x Next = %x",pCur,pCur->Next); pCur = pCur->Next; } // Append this one pCur->Next = pSess; pSess->Previous = pCur; pSess->Next = NULL; } pthread_mutex_unlock(&(Anchor->SessListMutex)); } void RemoveFromSessionList(pSess) Session_Struct_t *pSess; { Session_Struct_t *pCur,*pTmp; pthread_mutex_lock(&(Anchor->SessListMutex)); pCur = Anchor->SessListBeg; // Just in case check that there really is a list although // the call to ValidSession should have caught this already. // But someone may have removed the session already // while we were validating the call. if ( pCur) { // Are we the beginning of the list if (pCur == pSess){ pthread_mutex_lock(&(Anchor->ProcMutex)); pTmp = pSess->Next; Anchor->SessListBeg = pSess->Next; if (pTmp){ pTmp->Previous = NULL; } free(pSess); pthread_mutex_unlock(&(Anchor->ProcMutex)); pCur = NULL; // Force out of the loop } else { // First check for a Null element then check next against // the desired element. This will allow the loop to terminate // at the end of the list even if the desired element is not in // the list (should not happen, but be defensive). while (pCur && pCur->Next != pSess) { pCur = pCur->Next; } // We did not hit the end of the list without finding // our element so we can continue to remove it if (pCur != NULL ){ pTmp = pSess->Next; pCur->Next = pTmp; if (pTmp) { pTmp->Previous = pCur; } free(pSess); } } } pthread_mutex_unlock(&(Anchor->SessListMutex)); } int Valid_Session(pSession,rSession) Session_Struct_t *pSession; ST_SESSION_T *rSession; { int rv=FALSE; // Assume that it is not on the list Session_Struct_t *cSessionp; if ( !pSession ) return FALSE; // Walk the Anchor block session linked list // return TRUE if the pointer is on the list // False if it is not pthread_mutex_lock(&(Anchor->SessListMutex)); cSessionp = Anchor->SessListBeg; while (cSessionp) { if (cSessionp == pSession){ rv = TRUE; rSession->sessionh = pSession->RealHandle; rSession->slotID = pSession->SltId; break; } cSessionp = (Session_Struct_t *)cSessionp->Next; } pthread_mutex_unlock(&(Anchor->SessListMutex)); return rv; } int API_Initialized() { if ( Anchor == NULL ) return FALSE; return TRUE; } int slot_present(id) CK_SLOT_ID id; { Slot_Mgr_Shr_t *shm; #ifdef PKCS64 Slot_Info_t_64 *sinfp; #else Slot_Info_t *sinfp; #endif // Get pointer to shared memory from the anchor block // shm = Anchor->SharedMemP; sinfp = &(shm->slot_info[id]); if ( sinfp->present == FALSE ){ return FALSE; } return TRUE; } void incr_sess_counts(slotID) CK_SLOT_ID slotID; { Slot_Mgr_Shr_t *shm; #ifdef PKCS64 Slot_Info_t_64 *sinfp; Slot_Mgr_Proc_t_64 *procp; #else Slot_Info_t *sinfp; Slot_Mgr_Proc_t *procp; #endif // Get the slot mutex shm = Anchor->SharedMemP; XProcLock(&(shm->slt_mutex)); sinfp = &(shm->slot_info[slotID]); sinfp->global_sessions++; procp = &shm->proc_table[Anchor->MgrProcIndex]; procp->slot_session_count[slotID]++; XProcUnLock(&(shm->slt_mutex)); } void decr_sess_counts(slotID) CK_SLOT_ID slotID; { Slot_Mgr_Shr_t *shm; #ifdef PKCS64 Slot_Info_t_64 *sinfp; Slot_Mgr_Proc_t_64 *procp; #else Slot_Info_t *sinfp; Slot_Mgr_Proc_t *procp; #endif // Get the slot mutex shm = Anchor->SharedMemP; XProcLock(&(shm->slt_mutex)); sinfp = &(shm->slot_info[slotID]); if (sinfp->global_sessions > 0){ sinfp->global_sessions--; } procp = &shm->proc_table[Anchor->MgrProcIndex]; if (procp->slot_session_count[slotID] > 0){ procp->slot_session_count[slotID]++; } XProcUnLock(&(shm->slt_mutex)); } // Check if any sessions from other applicaitons exist on this particular // token.... This will also validate our own sessions as well. // There might be an issue with the fact that a session is created but the // number is not incremented until the session allocation is completed by // the token. The API may need to lock the shared memory prior to creating // the session and then unlock when the stdll has completed its work. // Closing sessions should probably behave the same way. int sessions_exist(slotID) CK_SLOT_ID slotID; { Slot_Mgr_Shr_t *shm; #ifdef PKCS64 Slot_Info_t_64 *sinfp; #else Slot_Info_t *sinfp; #endif // Get the slot mutex shm = Anchor->SharedMemP; #ifdef PKCS64 XProcLock(&(shm->slt_mutex)); sinfp = &(shm->slot_info[slotID]); if (sinfp->global_sessions == 0) { XProcUnLock(&(shm->slt_mutex)); return FALSE; } XProcUnLock(&(shm->slt_mutex)); #else XProcLock(&(shm->slt_mutex)); sinfp = &(shm->slot_info[slotID]); if (sinfp->global_sessions == 0) { XProcUnLock(&(shm->slt_mutex)); return FALSE; } XProcUnLock(&(shm->slt_mutex)); #endif return TRUE; } void unlock_shm() { Slot_Mgr_Shr_t *shm; shm = Anchor->SharedMemP; XProcUnLock(&(shm->slt_mutex)); } void lock_shm() { Slot_Mgr_Shr_t *shm; shm = Anchor->SharedMemP; XProcLock(&(shm->slt_mutex)); } // Terminates all sessions associated with a given process // this cleans up any lingering sessions with the process // and does not // // It is only called from the C_Finalize routine void Terminate_All_Process_Sessions() { CK_SLOT_ID id; CK_RV rv; LOGIT(LOG_DEBUG,"Terminate_All_Process_Sessions"); for (id=0;idSharedMemP; XProcLock(&(shm->slt_mutex)); procp = shm->proc_table; for (indx=0;indx< NUMBER_PROCESSES_ALLOWED; indx++,procp++){ // Is the entry in use if (procp->inuse == TRUE) { // Handle the weird case of the process terminating without // un-registering, and restarting with exactly the same PID // before the slot manager garbage collection can performed. // To eliminate the race condition between garbage collection // the shm-slt_mutex will protect us. // This should be a VERY rare (if ever) occurance, given the // way AIX deals with re-allocation of PID;s, however if this // ever gets ported over to another platform we want to deal // with this accordingly since it may re-use pids differently // (Linux appears to re-use pids more rapidly). if ( procp->proc_id == getpid()) { if ( reuse == -1 ) { reuse = indx; } } }else { //Already found the first free if (free == -1 ) { free = indx; } } } // If we did not find a free entry then we fail the routine if ( (reuse == -1) && (free == -1 ) ){ XProcUnLock(&(shm->slt_mutex)); return FALSE; } // check if we are reusing a control block or taking the first free. // Since th mutex is helt, we don;t have to worry about some other // process grabbing the slot... Garbage collection from // the slotd should not affect this since it will grab the mutex // before doing its thing. if (reuse != -1 ){ procp = &(shm->proc_table[reuse]); indx = reuse; } else { procp = &(shm->proc_table[free]); indx = free; } #ifdef PKCS64 memset((char *)procp, 0, sizeof(Slot_Mgr_Proc_t_64)); #else memset((char *)procp, 0, sizeof(Slot_Mgr_Proc_t)); #endif procp->inuse = TRUE; procp->proc_id = getpid(); procp->reg_time = time(NULL); Anchor->MgrProcIndex=indx; LOGIT(LOG_DEBUG,"API_Register MgrProcIndc %d pid %d \n",procp->proc_id,Anchor->MgrProcIndex); //??? What to do about the Mutex and cond variable //Does initializing them in the slotd allow for them to not be //initialized in the application. XProcUnLock(&(shm->slt_mutex)); return TRUE; } // DeRegister the process with PKCSSLOTD in the // shared memory. // This call must be made with the API Global Mutex Locked // and the Anchor control block initialized with the // shared memory. No checking for shared memory validity is done void API_UnRegister() { Slot_Mgr_Shr_t *shm; #ifdef PKCS64 Slot_Mgr_Proc_t_64 *procp; #else Slot_Mgr_Proc_t *procp; #endif // Grab the Shared Memory MUTEX to prevent other updates to the // SHM Process // The registration is done to allow for future handling of // the Slot Event List. Which is maintained by the Slotd. shm = Anchor->SharedMemP; XProcLock(&(shm->slt_mutex)); procp = &(shm->proc_table[Anchor->MgrProcIndex]); #ifdef PKCS64 memset((char *)procp, 0, sizeof(Slot_Mgr_Proc_t_64)); #else memset((char *)procp, 0, sizeof(Slot_Mgr_Proc_t)); #endif Anchor->MgrProcIndex=0; //??? What to do about the Mutex and cond variable //Does initializing them in the slotd allow for them to not be //initialized in the application. XProcUnLock(&(shm->slt_mutex)); } void DL_UnLoad( sltp,slotID ) API_Slot_t *sltp; CK_SLOT_ID slotID; { Slot_Mgr_Shr_t *shm; #ifdef PKCS64 Slot_Info_t_64 *sinfp; #else Slot_Info_t *sinfp; #endif shm = Anchor->SharedMemP; sinfp = &(shm->slot_info[slotID]); if ( sinfp->present == FALSE ){ return; } if (! sltp->dlop_p ){ return ; } // Call the routine to properly unload the DLL DL_Unload(sltp); return ; } int DL_Loaded( location, dllload) char *location; DLL_Load_t *dllload; { int i; for (i=0;i< NUMBER_SLOTS_MANAGED;i++){ if ( dllload[i].dll_name != NULL){ LOGIT(LOG_DEBUG,"DL_LOADED Looking for index %d name %s",i,dllload[i].dll_name); if (strcmp(location,dllload[i].dll_name)== 0) { return i; // Return the index of the dll } } } return -1; // Indicate failure to find the dll } int DL_Load( sinfp,sltp,dllload) #ifdef PKCS64 Slot_Info_t_64 *sinfp; #else Slot_Info_t *sinfp; #endif API_Slot_t *sltp; DLL_Load_t *dllload; { int i; LOGIT(LOG_DEBUG,"DL_LOAD"); for (i=0;idll_location; // Point to the location dllload[i].dlop_p = dlopen(sinfp->dll_location, (RTLD_GLOBAL | RTLD_LAZY)); if (dllload[i].dlop_p != NULL ){ sltp->dlop_p = dllload[i].dlop_p; sltp->dll_information = &dllload[i]; dllload[i].dll_load_count=1;; } else { syslog(LOG_ERR, "%s: dlopen() failed for [%s]; dlerror = [%s]\n", __FUNCTION__, sinfp->dll_location, dlerror()); LOGIT(LOG_DEBUG,"\tDL_Load of %s failed, dlerror: %s",sinfp->dll_location,dlerror()); sltp->dlop_p = NULL; return 0; } return 1; } void DL_Unload(sltp) API_Slot_t *sltp; { DLL_Load_t *dllload; // Decrement the count of loads. When 0 then unloadthis thing; // dllload = sltp->dll_information; dllload->dll_load_count --; if (dllload->dll_load_count == 0 ){ // bug in 64bit causes crash of system... // check here for 64bit app if (sizeof(long) == 4){ dlclose(dllload->dlop_p); } dllload->dll_name = NULL; } // Clear out the slot information sltp->DLLoaded = FALSE; sltp->dlop_p = NULL; sltp->pSTfini = NULL; sltp->pSTcloseall = NULL; } int DL_Load_and_Init(sltp,slotID ) API_Slot_t *sltp; CK_SLOT_ID slotID; { Slot_Mgr_Shr_t *shm; #ifdef PKCS64 Slot_Info_t_64 *sinfp; #else Slot_Info_t *sinfp; #endif int (*pSTinit)(); void (*pSTfini)(); CK_RV rv; int dll_len,dl_index; DLL_Load_t *dllload; // Get pointer to shared memory from the anchor block // shm = Anchor->SharedMemP; sinfp = &(shm->slot_info[slotID]); dllload = Anchor->DLLs; // list of dll's in the system if ( sinfp->present == FALSE ){ return FALSE; } if ( (dll_len = strlen(sinfp->dll_location))){ // Check if this DLL has been loaded already.. If so, just increment // the counter in the dllload structure and copy the data to // the slot pointer. if ( (dl_index = DL_Loaded(sinfp->dll_location,dllload)) != -1 ){ dllload[dl_index].dll_load_count++; sltp->dll_information = &dllload[dl_index]; sltp->dlop_p = dllload[dl_index].dlop_p; } else { LOGIT(LOG_DEBUG,"DL_Load_and_Init dll_location %s",sinfp->dll_location); DL_Load(sinfp,sltp,dllload); } } else { return FALSE; } if (! sltp->dlop_p ){ LOGIT(LOG_DEBUG,"DL_Load_and_Init pointer %x",sltp->dlop_p); return FALSE; } if (strlen(sinfp->slot_init_fcn)){ pSTinit = (int (*)())dlsym( sltp->dlop_p, sinfp->slot_init_fcn); } else { DL_Unload(sltp); return FALSE; } if (!pSTinit ){ // Unload the DLL DL_Unload(sltp); return FALSE; } // Returns true or false rv = pSTinit(&(sltp->FcnList),slotID,sinfp->correlator); LOGIT(LOG_DEBUG,"return from STDDLL Init = %x",rv); if (rv != CKR_OK ){ // clean up and unload DL_Unload(sltp); sltp->DLLoaded=FALSE; return FALSE; } else { sltp->DLLoaded=TRUE; // Check if a SC_Finalize function has been exported pSTfini = (void (*)())dlsym(sltp->dlop_p,"SC_Finalize"); sltp->pSTfini = pSTfini; sltp->pSTcloseall = (void (*)())dlsym(sltp->dlop_p,"SC_CloseAllSessions"); return TRUE; } return TRUE; } void st_err_log(int num, ...) { va_list pvar; char buffer[4096*4]; if (!enabled) loginit(); if ( enabled ){ va_start(pvar, num); vsprintf(buffer,err_msg[num].msg,pvar); va_end(pvar); syslog(LOG_ERR,buffer); } } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/api/Makefile.am0000640000175000017500000000474411327631345020242 0ustar jfjfnobase_lib_LTLIBRARIES = opencryptoki/libopencryptoki.la SO_CURRENT=0 SO_REVISION=0 SO_AGE=0 opencryptoki_libopencryptoki_la_LDFLAGS = -shared -Wl,-Bsymbolic -lc -ldl \ -lpthread -version-info \ $(SO_CURRENT):$(SO_REVISION):$(SO_AGE) # Not all versions of automake observe libname_CFLAGS opencryptoki_libopencryptoki_la_CFLAGS = -DSPINXPL -DAPI -DDEV -D_THREAD_SAFE \ -fPIC -I../. -I../../../include/pkcs11 # Not all versions of automake observe libname_CFLAGS AM_CFLAGS = -DSPINXPL -DAPI -DDEV -D_THREAD_SAFE \ -fPIC -I../. -I../../../include/pkcs11 opencryptoki_libopencryptoki_la_SOURCES = api_interface.c shrd_mem.c apiutil.c install-data-local: mkdir -p $(DESTDIR)/$(libdir)/opencryptoki cd $(DESTDIR)/$(libdir)/opencryptoki && rm -f PKCS11_API.so && \ ln -sf libopencryptoki.so PKCS11_API.so cd $(DESTDIR)/$(libdir)/opencryptoki && rm -f methods && \ ln -sf ../../sbin/ methods mkdir -p $(DESTDIR)/$(libdir)/pkcs11 cd $(DESTDIR)/$(libdir)/pkcs11 && rm -f methods && \ ln -sf ../../sbin/ methods cd $(DESTDIR)/$(libdir)/pkcs11 && rm -f PKCS11_API.so && \ ln -sf ../opencryptoki/libopencryptoki.so PKCS11_API.so cd $(DESTDIR)/$(libdir)/pkcs11 && rm -f libopencryptoki.so && \ ln -sf ../opencryptoki/libopencryptoki.so libopencryptoki.so mkdir -p $(DESTDIR)/$(libdir)/opencryptoki/stdll cd $(DESTDIR)/$(libdir)/pkcs11 && rm -f stdll && \ ln -sf ../opencryptoki/stdll/ stdll -groupadd pkcs11 if test "x$(prefix)" = "x/usr"; then \ mkdir -p $(DESTDIR)/var/lib/opencryptoki ; \ chown root:pkcs11 $(DESTDIR)/var/lib/opencryptoki ; \ chmod 775 $(DESTDIR)/var/lib/opencryptoki ; \ if [ ! -L $(DESTDIR)/etc/pkcs11 ] ; then \ if [ -e $(DESTDIR)/etc/pkcs11/* ] ; then \ mv $(DESTDIR)/etc/pkcs11/* $(DESTDIR)/var/lib/opencryptoki ; \ fi ; \ fi ;\ mkdir -p $(DESTDIR)/etc \ cd $(DESTDIR)/etc && rm -rf pkcs11 && \ ln -sf $(DESTDIR)/var/lib/opencryptoki pkcs11 ; \ else \ mkdir -p $(DESTDIR)/$(localstatedir)/lib/opencryptoki ; \ chown root:pkcs11 $(DESTDIR)/$(localstatedir)/lib/opencryptoki ; \ chmod 775 $(DESTDIR)/$(localstatedir)/lib/opencryptoki ; \ if [ ! -L $(DESTDIR)/$(sysconfdir)/pkcs11 ] ; then \ if [ -e $(DESTDIR)/$(sysconfdir)/pkcs11/* ] ; then \ mv $(DESTDIR)/$(sysconfdir)/pkcs11/* \ $(DESTDIR)/$(localstatedir)/lib/opencryptoki ; \ fi ; \ fi ; \ mkdir -p $(DESTDIR)/$(sysconfdir) ; \ cd $(DESTDIR)/$(sysconfdir) && rm -rf pkcs11 && \ ln -sf $(DESTDIR)/$(localstatedir)/lib/opencryptoki pkcs11 ; \ fi opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/api/api_interface.c0000751000175000017500000046401311327631345021145 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #if NGPTH #include #else #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include void api_init(); void st_err_log(int, ...); #ifdef DEBUG #define LOG(x) logit(LOG_DEBUG,x) #define LOGIT logit #else #define LOG(...) #define LOGIT(...) #endif // NOTES: // In many cases the specificaiton does not allow returns // of CKR_ARGUMENTSB_BAD. We break the spec, since validation of parameters // to the function are best represented by this return code (where // specific RC's such as CKR_INVALID_SESSION do not exist). // NOTE NOTE NOTE NOTE // The parameter checking on the update operations may need to be // modified (as well as the encrypt/decrypt) to call the stdll // anyway with sanatized parameters since on error, the encrypt/decrypt // sign operations are all supposed to complete. // Therefor the parameter checking here might need to be done in // the STDLL instead of the API. // This would affect ALL the Multipart operations which have // an init followed by one or more operations. // Globals for the API API_Proc_Struct_t *Anchor=NULL; // Initialized to NULL unsigned int Initialized = 0; // Initialized flag pthread_mutex_t GlobMutex; // Global Mutex /* KEY XXX pthread_mutex_t logmutex;*/ // logging mutex ... Keep to a minimum.. int logging=LOG_ERR; // Highest level to log to syslog CK_FUNCTION_LIST FuncList; int slot_loaded[NUMBER_SLOTS_MANAGED]; // Array of flags to indicate // if the STDLL loaded // For linux only at this time... if it works out we can get rid // of the stupid pid tracking.... Linux we kind of have to do this // since new threads are processes also, and we will be hosed void child_fork_initializer() { if ( Anchor ){ free(Anchor); Anchor = NULL; } logterm(); loginit(); // _init is NOT invoked on fork } //------------------------------------------------------------------------ // API function C_CancelFunction //------------------------------------------------------------------------ // This is a legacy function and performs no operations per the // specification. CK_RV C_CancelFunction ( CK_SESSION_HANDLE hSession ) { LOG("C_CancelFunction"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } st_err_log(17, __FILE__, __LINE__); return CKR_FUNCTION_NOT_PARALLEL; // PER Spec pg 170 } //------------------------------------------------------------------------ // API function C_CloseAllSessions //------------------------------------------------------------------------ // Netscape Required // // This is a special one since the API can do this by removing // all active sessions on the slot... The STDLL does not have to implement // this. however this function will fail if any Session removal fails // in the walk. Which could lead to undetermined results. // //------------------------------------------------------------------------ CK_RV C_CloseAllSessions ( CK_SLOT_ID slotID ) { Session_Struct_t *pCur,*pPrev; CK_RV rv; API_Slot_t *sltp; ST_SESSION_T hSession; // Although why does modutil do a close all sessions. It is a single // application it can only close its sessions... // And all sessions should be closed anyhow. LOG("CloseAllSessions"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (slotID >= NUMBER_SLOTS_MANAGED ) { st_err_log(2, __FILE__, __LINE__); return CKR_SLOT_ID_INVALID; } // Proc Mutex is locked when we remove from the seesion list in // Close SEssion. Therefore we don't need to do any locking // the atomic operations are controled when we use the linked list pCur = Anchor->SessListBeg; while (pCur){ //LOGIT(LOG_DEBUG,"Pcur Loop %x Slot %d Pslot %d ",pCur,slotID,pCur->SltId); // Session owned by the slot we are working on // There is a basic problem here. We are using th pCur to point to // the current one, however we delete it from the linked list and // can no longer go Forward. So we have to use the fact that this // is a doubly linked list and get the previous pointer. After // deletion, the next pointer of this block will point to the // next one in the list... // If the value is Null, then this was the first one in the list // and we just set pCur to the SessListBeg. if (pCur->SltId == slotID ){ hSession.sessionh = pCur->RealHandle; // use this since after close session hSession.slotID = pCur->SltId; pPrev = pCur->Previous; rv = C_CloseSession((CK_SESSION_HANDLE)pCur); // Call the local copy if (rv == CKR_OK || rv == CKR_SESSION_CLOSED || rv == CKR_SESSION_HANDLE_INVALID) { if (pPrev == NULL){ //LOGIT(LOG_DEBUG,"Re-wind since we removed the head"); pCur = Anchor->SessListBeg; } else { //LOGIT(LOG_DEBUG,"XXX Prev %x PrevNext %x",pPrev,pPrev->Next); pCur = pPrev->Next; } } else { // We have had a problem deleting a session and // need to abort this operation. This path should not occur // unless LOGIT(LOG_DEBUG,"CloseAllSessions STDLL Problem"); st_err_log(153, __FILE__, __LINE__); return rv; } } else { pCur = pCur->Next; } } sltp = &(Anchor->SltList[slotID]); if (sltp->pSTcloseall) { sltp->pSTcloseall(slotID); // call the terminate function.. } LOG("CloseAllSessions OK"); return CKR_OK; } // end of C_CloseAllSessions //------------------------------------------------------------------------ // API function C_CloseSession //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_CloseSession ( CK_SESSION_HANDLE hSession ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; Session_Struct_t *sessp; ST_SESSION_T rSession; LOG("C_CloseSession"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_CloseSession){ // Map the Session to the slot session rv = fcn->ST_CloseSession(rSession); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); // If the STDLL successfuly closed the session // we can free it.. Otherwise we will have to leave it // lying arround. if (rv == CKR_OK) { sessp = (Session_Struct_t *)hSession; RemoveFromSessionList(sessp); // Need to decrement the global slot session count as well // as the per process slot session count to allow for // proper tracking of the number of sessions on a slot. // This allows things like InitToken to properly work in case // other applications have the token active. decr_sess_counts(slotID); } } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_CloseSession //------------------------------------------------------------------------ // API function C_CopyObject //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_CopyObject ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phNewObject ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_CopyObject"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } if ( !phNewObject ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // null template with a count... will cause the lower layer // to have problems // Template with 0 count is not a problem. we can let // the STDLL handle that... if ( !pTemplate && ulCount ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_CopyObject){ // Map the Session to the slot session rv = fcn->ST_CopyObject(rSession,hObject,pTemplate,ulCount,phNewObject); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_CopyObject //------------------------------------------------------------------------ // API function C_CreateObject //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_CreateObject ( CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_CreateObject"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Null template is invalid... An object needs a minimal // template for creation. if ( !pTemplate ){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } // A 0 count for the template is bad if ( ulCount == 0 ){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } // A Null pointer to return the handle in is also bad // since we could de-reference incorrectly. if (! phObject ) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_CreateObject){ // Map the Session to the slot session rv = fcn->ST_CreateObject(rSession,pTemplate,ulCount,phObject); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_CreateObject //------------------------------------------------------------------------ // API function C_Decrypt //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_Decrypt ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_Decrypt"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Null encrypted data is invalid, null pData buffer is invalid // as is null location to put the response into. if ( !pEncryptedData || !pulDataLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_Decrypt){ // Map the Session to the slot session rv = fcn->ST_Decrypt(rSession,pEncryptedData,ulEncryptedDataLen,pData,pulDataLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_Decrypt //------------------------------------------------------------------------ // API function C_DecryptDigestUpdate //------------------------------------------------------------------------ // Netscape Required CK_RV C_DecryptDigestUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_DecryptDigestUpdate"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // This may have to go to the STDLL for validation if ( !pEncryptedPart || !pulPartLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DecryptDigestUpdate){ // Map the Session to the slot session rv = fcn->ST_DecryptDigestUpdate(rSession,pEncryptedPart,ulEncryptedPartLen,pPart,pulPartLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_DecryptFinal //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_DecryptFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_DecryptFinal"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // This may have to go to the STDLL for validation // It is acceptable to have a Null pointer for the data since // it is trying to get the length of the last part.... // The spec is unclear if a second call to Final is needed // if there is no data in the last part. if (!pulLastPartLen ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DecryptFinal){ // Map the Session to the slot session rv = fcn->ST_DecryptFinal(rSession,pLastPart,pulLastPartLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_DecryptFinal //------------------------------------------------------------------------ // API function C_DecryptInit //------------------------------------------------------------------------ // // // //------------------------------------------------------------------------ CK_RV C_DecryptInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_DecryptInit"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Null mechanism pointer is not good if ( !pMechanism ) { st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DecryptInit){ // Map the Session to the slot session rv = fcn->ST_DecryptInit(rSession,pMechanism,hKey); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_DecryptInit //------------------------------------------------------------------------ // API function C_DecryptUpdate //------------------------------------------------------------------------ // // // //------------------------------------------------------------------------ CK_RV C_DecryptUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_DecryptUpdate"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // May have to let these go through and let the STDLL handle them if ( !pEncryptedPart || !pulPartLen ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DecryptUpdate){ // Map the Session to the slot session rv = fcn->ST_DecryptUpdate(rSession,pEncryptedPart,ulEncryptedPartLen,pPart,pulPartLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_DecryptUpdate //------------------------------------------------------------------------ // API function C_DecryptVerifyUpdate //------------------------------------------------------------------------ CK_RV C_DecryptVerifyUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_DecryptVerifyUpdate"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // May have to let these go through and let the STDLL handle them if ( !pEncryptedPart || !pulPartLen ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DecryptVerifyUpdate){ // Map the Session to the slot session rv = fcn->ST_DecryptVerifyUpdate(rSession,pEncryptedPart,ulEncryptedPartLen,pPart,pulPartLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_DeriveKey //------------------------------------------------------------------------ CK_RV C_DeriveKey ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_DeriveKey"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Null phKey is invalid // Null mechanism pointer is invalid // This is allowed for some SSL3 mechs. the STDLL has to catch this // condition since it validates the mechanism //if (!phKey ) return CKR_ARGUMENTS_BAD; if (!pMechanism ){ st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // Null template with attribute count is bad // but we will let a template with len 0 pass through if (!pTemplate && ulAttributeCount ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DeriveKey){ // Map the Session to the slot session rv = fcn->ST_DeriveKey(rSession,pMechanism,hBaseKey,pTemplate,ulAttributeCount,phKey); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_DestroyObject //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_DestroyObject ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_DestrypObject"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DestroyObject){ // Map the Session to the slot session rv = fcn->ST_DestroyObject(rSession,hObject); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_DestroyObject //------------------------------------------------------------------------ // API function C_Digest //------------------------------------------------------------------------ CK_RV C_Digest ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_Digest"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Null data for digest is bad if (!pData || !pulDigestLen ) return CKR_ARGUMENTS_BAD; // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_Digest){ // Map the Session to the slot session rv = fcn->ST_Digest(rSession,pData,ulDataLen,pDigest,pulDigestLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_DigestEncryptUpdate //------------------------------------------------------------------------ CK_RV C_DigestEncryptUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_DigestEncryptUpdate"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // May have to pass on through to the STDLL if (!pPart || !pulEncryptedPartLen ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DigestEncryptUpdate){ // Map the Session to the slot session rv = fcn->ST_DigestEncryptUpdate(rSession,pPart,ulPartLen,pEncryptedPart,pulEncryptedPartLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_DigestFinal //------------------------------------------------------------------------ CK_RV C_DigestFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_DigestFinal"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pulDigestLen ) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DigestFinal){ // Map the Session to the slot session rv = fcn->ST_DigestFinal(rSession,pDigest,pulDigestLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } //------------------------------------------------------------------------ // API function C_DigestInit //------------------------------------------------------------------------ CK_RV C_DigestInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_DigestInit"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pMechanism ){ st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DigestInit){ // Map the Session to the slot session rv = fcn->ST_DigestInit(rSession,pMechanism); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_DigestKey //------------------------------------------------------------------------ CK_RV C_DigestKey ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_DigestKey"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DigestKey){ // Map the Session to the slot session rv = fcn->ST_DigestKey(rSession,hKey); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_DigestUpdate //------------------------------------------------------------------------ CK_RV C_DigestUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_DigestUpdate"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!ulPartLen){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DigestUpdate){ // Map the Session to the slot session rv = fcn->ST_DigestUpdate(rSession,pPart,ulPartLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_Encrypt //------------------------------------------------------------------------ CK_RV C_Encrypt ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_Encrypt"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pData || !pulEncryptedDataLen){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_Encrypt){ // Map the Session to the slot session rv = fcn->ST_Encrypt(rSession,pData,ulDataLen,pEncryptedData,pulEncryptedDataLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_EncryptFinal //------------------------------------------------------------------------ CK_RV C_EncryptFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_EncryptFinal"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // See comments for DecryptFinal if ( !pulLastEncryptedPartLen){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_EncryptFinal){ // Map the Session to the slot session rv = fcn->ST_EncryptFinal(rSession,pLastEncryptedPart,pulLastEncryptedPartLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_EncryptInit //------------------------------------------------------------------------ CK_RV C_EncryptInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_EncryptInit"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pMechanism){ st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_EncryptInit){ // Map the Session to the slot session rv = fcn->ST_EncryptInit(rSession,pMechanism,hKey); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } //------------------------------------------------------------------------ // API function C_EncryptUpdate //------------------------------------------------------------------------ CK_RV C_EncryptUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_EncryptUpdate"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pPart || !pulEncryptedPartLen){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_EncryptUpdate){ // Map the Session to the slot session rv = fcn->ST_EncryptUpdate(rSession,pPart,ulPartLen,pEncryptedPart,pulEncryptedPartLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_Finalize //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_Finalize ( CK_VOID_PTR pReserved ) { API_Slot_t *sltp; CK_SLOT_ID slotID; LOG("C_Finalize"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (pReserved != NULL) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } pthread_mutex_lock(&GlobMutex); // Grab Process level Global MUTEX Terminate_All_Process_Sessions();// Terminate the sessions // unload all the STDLL's from the application // This is in case the APP decides to do the re-initialize and // continue on // // for (slotID=0;slotIDSltList[slotID]); if (sltp->pSTcloseall) { sltp->pSTcloseall(slotID); // call the terminate function.. } if (sltp->pSTfini){ sltp->pSTfini(slotID); // call the terminate function.. } DL_UnLoad(sltp,slotID); } // Un register from Slot D API_UnRegister(); detach_shared_memory(Anchor->SharedMemP); free(Anchor); // Free API Proc Struct Anchor = NULL; // Unlock pthread_mutex_unlock(&GlobMutex); return CKR_OK; } // end of C_Finalize //------------------------------------------------------------------------ // API function C_FindObjects //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_FindObjects ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_FindObjects"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!phObject || !pulObjectCount ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_FindObjects){ // Map the Session to the slot session rv = fcn->ST_FindObjects(rSession,phObject,ulMaxObjectCount,pulObjectCount); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_FindObjects //------------------------------------------------------------------------ // API function C_FindObjectsFinal //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_FindObjectsFinal ( CK_SESSION_HANDLE hSession ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_FindObjectsFinal"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_FindObjectsFinal){ // Map the Session to the slot session rv = fcn->ST_FindObjectsFinal(rSession); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_FindObjectsFinal //------------------------------------------------------------------------ // API function // C_FindObjectsInit //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_FindObjectsInit ( CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_FindObjectsInit"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // What does a NULL template really mean // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_FindObjectsInit){ // Map the Session to the slot session rv = fcn->ST_FindObjectsInit(rSession,pTemplate,ulCount); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_FindObjectsInit //------------------------------------------------------------------------ // API function C_GenerateKey //------------------------------------------------------------------------ // Netscape Required CK_RV C_GenerateKey ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_GenerateKey"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pMechanism ){ st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } if (!phKey ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_GenerateKey){ // Map the Session to the slot session rv = fcn->ST_GenerateKey(rSession,pMechanism,pTemplate,ulCount,phKey); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_GenerateKeyPair //------------------------------------------------------------------------ // Netscape Required CK_RV C_GenerateKeyPair ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_GenerateKeyPair"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pMechanism){ st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } if (!phPublicKey || !phPrivateKey){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // what other validation of parameters ... What about // template pointers is a Null template pointer valid in generate // key... Are there defaults. // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_GenerateKeyPair){ // Map the Session to the slot session rv = fcn->ST_GenerateKeyPair(rSession,pMechanism,pPublicKeyTemplate, ulPublicKeyAttributeCount,pPrivateKeyTemplate, ulPrivateKeyAttributeCount,phPublicKey,phPrivateKey); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_GenerateRandom //------------------------------------------------------------------------ // Netscape Required CK_RV C_GenerateRandom ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR RandomData, CK_ULONG ulRandomLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_GenerateRandom"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!RandomData) return CKR_ARGUMENTS_BAD; // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_GenerateRandom){ // Map the Session to the slot session rv = fcn->ST_GenerateRandom(rSession,RandomData,ulRandomLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } //------------------------------------------------------------------------ // API function C_GetAttributeValue //------------------------------------------------------------------------ // Netscape Required // // //------------------------------------------------------------------------ CK_RV C_GetAttributeValue ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_GetAttributeValue"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pTemplate){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } if ( ulCount == 0 ){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_GetAttributeValue){ // Map the Session to the slot session rv = fcn->ST_GetAttributeValue(rSession,hObject,pTemplate,ulCount); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_GetAttributeValue //------------------------------------------------------------------------ // API function C_GetFunctionList //------------------------------------------------------------------------ // Netscape Required CK_RV C_GetFunctionList ( CK_FUNCTION_LIST_PTR_PTR ppFunctionList ) { _init(); LOG("C_GetFunctionList"); FuncList.version.major = VERSION_MAJOR; FuncList.version.minor = VERSION_MINOR; FuncList.C_Initialize = C_Initialize; FuncList.C_Finalize = C_Finalize; FuncList.C_GetInfo = C_GetInfo; FuncList.C_GetFunctionList = C_GetFunctionList; FuncList.C_GetSlotList = C_GetSlotList; FuncList.C_GetSlotInfo = C_GetSlotInfo; FuncList.C_GetTokenInfo = C_GetTokenInfo; FuncList.C_GetMechanismList = C_GetMechanismList; FuncList.C_GetMechanismInfo = C_GetMechanismInfo; FuncList.C_InitToken = C_InitToken; FuncList.C_InitPIN = C_InitPIN; FuncList.C_SetPIN = C_SetPIN; FuncList.C_OpenSession = C_OpenSession; FuncList.C_CloseSession = C_CloseSession; FuncList.C_CloseAllSessions = C_CloseAllSessions; FuncList.C_GetSessionInfo = C_GetSessionInfo; FuncList.C_GetOperationState = C_GetOperationState; FuncList.C_SetOperationState = C_SetOperationState; FuncList.C_Login = C_Login; FuncList.C_Logout = C_Logout; FuncList.C_CreateObject = C_CreateObject; FuncList.C_CopyObject = C_CopyObject; FuncList.C_DestroyObject = C_DestroyObject; FuncList.C_GetObjectSize = C_GetObjectSize; FuncList.C_GetAttributeValue = C_GetAttributeValue; FuncList.C_SetAttributeValue = C_SetAttributeValue; FuncList.C_FindObjectsInit = C_FindObjectsInit; FuncList.C_FindObjects = C_FindObjects; FuncList.C_FindObjectsFinal = C_FindObjectsFinal; FuncList.C_EncryptInit = C_EncryptInit; FuncList.C_Encrypt = C_Encrypt; FuncList.C_EncryptUpdate = C_EncryptUpdate; FuncList.C_EncryptFinal = C_EncryptFinal; FuncList.C_DecryptInit = C_DecryptInit; FuncList.C_Decrypt = C_Decrypt; FuncList.C_DecryptUpdate = C_DecryptUpdate; FuncList.C_DecryptFinal = C_DecryptFinal; FuncList.C_DigestInit = C_DigestInit; FuncList.C_Digest = C_Digest; FuncList.C_DigestUpdate = C_DigestUpdate; FuncList.C_DigestKey = C_DigestKey; FuncList.C_DigestFinal = C_DigestFinal; FuncList.C_SignInit = C_SignInit; FuncList.C_Sign = C_Sign; FuncList.C_SignUpdate = C_SignUpdate; FuncList.C_SignFinal = C_SignFinal; FuncList.C_SignRecoverInit = C_SignRecoverInit; FuncList.C_SignRecover = C_SignRecover; FuncList.C_VerifyInit = C_VerifyInit; FuncList.C_Verify = C_Verify; FuncList.C_VerifyUpdate = C_VerifyUpdate; FuncList.C_VerifyFinal = C_VerifyFinal; FuncList.C_VerifyRecoverInit = C_VerifyRecoverInit; FuncList.C_VerifyRecover = C_VerifyRecover; FuncList.C_DigestEncryptUpdate = C_DigestEncryptUpdate; FuncList.C_DecryptDigestUpdate = C_DecryptDigestUpdate; FuncList.C_SignEncryptUpdate = C_SignEncryptUpdate; FuncList.C_DecryptVerifyUpdate = C_DecryptVerifyUpdate; FuncList.C_GenerateKey = C_GenerateKey; FuncList.C_GenerateKeyPair = C_GenerateKeyPair; FuncList.C_WrapKey = C_WrapKey; FuncList.C_UnwrapKey = C_UnwrapKey; FuncList.C_DeriveKey = C_DeriveKey; FuncList.C_SeedRandom = C_SeedRandom; FuncList.C_GenerateRandom = C_GenerateRandom; FuncList.C_GetFunctionStatus = C_GetFunctionStatus; FuncList.C_CancelFunction = C_CancelFunction; FuncList.C_WaitForSlotEvent = C_WaitForSlotEvent; if( ppFunctionList ) { (*ppFunctionList) = &FuncList; return CKR_OK; } else{ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } } //------------------------------------------------------------------------ // API function C_GetFunctionStatus //------------------------------------------------------------------------ CK_RV C_GetFunctionStatus ( CK_SESSION_HANDLE hSession ) { LOG("C_GetFunctionStatus"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } st_err_log(17, __FILE__, __LINE__); return CKR_FUNCTION_NOT_PARALLEL; // PER Specification PG 170 } //------------------------------------------------------------------------ // API function C_GetInfo //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ #ifdef PKCS64 CK_RV C_GetInfo ( CK_INFO_PTR pInfo ) { Slot_Mgr_Shr_t *shm; LOG("C_GetInfo"); if (! API_Initialized() ) { st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if ( !pInfo ) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } shm = Anchor->SharedMemP; memset(pInfo, 0, sizeof(*pInfo)); pInfo->cryptokiVersion = shm->ck_info.cryptokiVersion; memset(pInfo->manufacturerID, '\0', 32); memcpy(pInfo->manufacturerID, &(shm->ck_info.manufacturerID), 32); pInfo->flags = shm->ck_info.flags; memcpy(pInfo->libraryDescription, &(shm->ck_info.libraryDescription), 32); pInfo->libraryVersion = shm->ck_info.libraryVersion; return CKR_OK; } // end of C_GetInfo #else CK_RV C_GetInfo ( CK_INFO_PTR pInfo ) { Slot_Mgr_Shr_t *shm; LOG("C_GetInfo"); if (! API_Initialized() ) { st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if ( !pInfo ) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } shm = Anchor->SharedMemP; memcpy(pInfo, &(shm->ck_info), sizeof(CK_INFO)); return CKR_OK; } // end of C_GetInfo #endif //------------------------------------------------------------------------ // API function C_GetMechanismInfo //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_GetMechanismInfo ( CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; LOGIT(LOG_DEBUG,"C_GetMechansimInfo %d %x %x",slotID,type,pInfo); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if ( slotID >= NUMBER_SLOTS_MANAGED ) { st_err_log(2, __FILE__, __LINE__); return CKR_SLOT_ID_INVALID; } sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_GetMechanismInfo){ rv = fcn->ST_GetMechanismInfo(slotID,type,pInfo); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_GetMechanismInfo //------------------------------------------------------------------------ // API function C_GetMechanismList //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_GetMechanismList ( CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; LOGIT(LOG_DEBUG,"C_GetMechanismList (%d %x %d)",slotID,pMechanismList,*pulCount); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // Always have to have a pulCount if (!pulCount){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Null PMechanism is valid to get a count of mechanisms if (slotID >= NUMBER_SLOTS_MANAGED ) { st_err_log(2, __FILE__, __LINE__); return CKR_SLOT_ID_INVALID; } sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_GetMechanismList){ LOG("Calling STDLL"); rv = fcn->ST_GetMechanismList(slotID,pMechanismList,pulCount); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } LOGIT(LOG_DEBUG,"GetMechanismList RV %x",rv); if (rv == CKR_OK ) { if ( pMechanismList ) { unsigned long i; for (i=0;i< *pulCount;i++){ LOGIT(LOG_DEBUG,"Mechanism[%d] 0x%08X ",i,pMechanismList[i]); } } } return rv; } // end of C_GetMechanismList //------------------------------------------------------------------------ // API function C_GetObjectSize //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_GetObjectSize ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_GetObjectSize"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pulSize){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_GetObjectSize){ // Map the Session to the slot session rv = fcn->ST_GetObjectSize(rSession,hObject,pulSize); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_GetObjectSize //------------------------------------------------------------------------ // API function C_GetOperationState //------------------------------------------------------------------------ CK_RV C_GetOperationState ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_GetOperateionState"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // NULL pOperationState is valid to get buffer // size if (!pulOperationStateLen){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_GetOperationState){ // Map the Session to the slot session rv = fcn->ST_GetOperationState(rSession,pOperationState,pulOperationStateLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_GetSessionInfo //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_GetSessionInfo ( CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOGIT(LOG_DEBUG,"C_GetSessionInfo %x %x",hSession,pInfo); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pInfo){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ) { st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_GetSessionInfo){ // Map the Session to the slot session rv = fcn->ST_GetSessionInfo(rSession,pInfo); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); LOGIT(LOG_DEBUG,"Slot %d State %x Flags %x DevErr %x", pInfo->slotID,pInfo->state, pInfo->flags,pInfo->ulDeviceError); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_GetSessionInfo //------------------------------------------------------------------------ // API function C_GetSlotInfo //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ #ifdef PKCS64 CK_RV C_GetSlotInfo ( CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo ) { uint16 count; Slot_Mgr_Shr_t *shm; Slot_Info_t_64 *sinfp; LOGIT(LOG_DEBUG,"C_GetSlotInfo Slot=%d ptr=%x",slotID,pInfo); //LOGIT(LOG_DEBUG," Slot %d ",slotID); if (API_Initialized() == FALSE ) { st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if ( !pInfo ) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } shm = Anchor->SharedMemP; sinfp = shm->slot_info; sinfp += slotID; count = 0; if (slotID >= NUMBER_SLOTS_MANAGED ) { st_err_log(2, __FILE__, __LINE__); return CKR_SLOT_ID_INVALID; } // Netscape and others appear to call // this for every slot. If the slot does not have // a registered STDLL, then this is a FUnction Failed case if ( sinfp->present == FALSE ){ //LOGIT(LOG_DEBUG," Not present"); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } //LOGIT(LOG_DEBUG," %32s ",sinfp->pk_slot.slotDescription); //LOGIT(LOG_DEBUG," %32s ",sinfp->pk_slot.manufacturerID); #ifdef __64BIT__ memcpy(pInfo, (char *)&(sinfp->pk_slot), sizeof(CK_SLOT_INFO)); #else memcpy((char *)&(pInfo->slotDescription[0]), (char *)&(sinfp->pk_slot.slotDescription[0]), 64); memcpy((char *)&(pInfo->manufacturerID[0]), (char *)&(sinfp->pk_slot.manufacturerID[0]), 32); pInfo->flags = sinfp->pk_slot.flags; pInfo->hardwareVersion = sinfp->pk_slot.hardwareVersion; pInfo->firmwareVersion = sinfp->pk_slot.firmwareVersion; #endif return CKR_OK; } // end of C_GetSlotInfo #else CK_RV C_GetSlotInfo ( CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo ) { uint16 count; uint16 index; uint16 sindx; Slot_Mgr_Shr_t *shm; Slot_Info_t *sinfp; LOGIT(LOG_DEBUG,"C_GetSlotInfo Slot=%d ptr=%x",slotID,pInfo); //LOGIT(LOG_DEBUG," Slot %d ",slotID); if (API_Initialized() == FALSE ) { st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if ( !pInfo ) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } shm = Anchor->SharedMemP; sinfp = shm->slot_info; sinfp += slotID; count = 0; if (slotID >= NUMBER_SLOTS_MANAGED ) { st_err_log(2, __FILE__, __LINE__); return CKR_SLOT_ID_INVALID; } // Netscape and others appear to call // this for every slot. If the slot does not have // a registered STDLL, then this is a FUnction Failed case if ( sinfp->present == FALSE ){ //LOGIT(LOG_DEBUG," Not present"); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } //LOGIT(LOG_DEBUG," %32s ",sinfp->pk_slot.slotDescription); //LOGIT(LOG_DEBUG," %32s ",sinfp->pk_slot.manufacturerID); memcpy(pInfo, (char *)&(sinfp->pk_slot), sizeof(CK_SLOT_INFO)); return CKR_OK; } // end of C_GetSlotInfo #endif //------------------------------------------------------------------------ // API function C_GetSlotList //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_GetSlotList ( CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount ) { //uint16 count; CK_ULONG count; uint16 index; uint16 sindx; Slot_Mgr_Shr_t *shm; #ifdef PKCS64 Slot_Info_t_64 *sinfp; #else Slot_Info_t *sinfp; #endif LOG("C_GetSlotList"); LOGIT(LOG_DEBUG," Pres %d Count %d",tokenPresent,*pulCount); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // Null pSlotList is valid to get count for array allocation if (pulCount == NULL){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } shm = Anchor->SharedMemP; sinfp = shm->slot_info; count = 0; // Count the slots based off the present flag // Go through all the slots and count them up // Remember if the tokenPresent Flag is set do not count the // not present ones. // // ------------------------------------------------------------ // // Present indicates that the slot is managed by the Slot manager // and that an appropriate registration has been made in the DB // // It does not imply that a token is present. // Slots with STDLL's are ALWAYS present in the system wether they // have a token or not is determined from the token functions. // // According to the spec the tokenPresent flag indicates if all // slots are wanted, or those which have tokens present. We will // use this to mean if a STDLL is present or not. All slots // are in the system, if a STDLL is attached to a slot, then it is // present( not to be confused with the Tokens flags indicating // presence). Presence of a STDLL on a slot indicates that there // is a "token reader" available. // // Note: All slots should be named by the slot manager with the // slot id in them... // ------------------------------------------------------------ // // Note: The CK_INFO_STRUCT present flag indicates that a token is present // in the reader located in the slot. Right now we are dealing only // with non-removable tokens, so the slot flags set in the slot DB // are fixed by the STDLL. Ultimately when we get to removable tokens, the // slot manager will have to monitor the device in the slot and set the flag // accordingly. // // This does however change the reporting back of Slot Lists... // // We were using the presence of a STDLL to indicate if a Token is present // or not. however we need to report back based on 2 flags. // // First a stdll must be in the table, second the slot info flags must be // set to present to return. // ---------------------------------------------- // // Also need to validate that the STDLL successfuly loaded. for (index=0;index= NUMBER_SLOTS_MANAGED ) { st_err_log(2, __FILE__, __LINE__); return CKR_SLOT_ID_INVALID; } sltp = &(Anchor->SltList[slotID]); LOGIT(LOG_DEBUG,"Slot p = %x id %d", sltp,slotID); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } // Need to check if the slot is not populated // then we can return the proper return code for a // slot that has no content. shm = Anchor->SharedMemP; sinfp = shm->slot_info; if (sinfp[slotID].present == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_GetTokenInfo){ LOGIT(LOG_DEBUG,"Calling STDLL "); rv = fcn->ST_GetTokenInfo(slotID,pInfo); LOGIT(LOG_DEBUG,"rv %d CK_TOKEN_INFO Flags %x",rv,pInfo->flags); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_GetTokenInfo void Call_Finalize(){ // LOG("Call_Finalize"); C_Finalize(NULL); return; } //------------------------------------------------------------------------ // API function C_Initialize //------------------------------------------------------------------------ // Netscape Required // // //------------------------------------------------------------------------ CK_RV C_Initialize ( CK_VOID_PTR pVoid ) { CK_C_INITIALIZE_ARGS *pArg; char fcnmap = 0; LOGIT(LOG_DEBUG,"C_Initialize"); //if ( API_Proc_Struct NOT allocated ) // allocate Structure // if ( allocation fails ) // return CKR_HOST_MEMORY //else // if ( API_Proc_Struct owned by current process ) // process has called C_Initialize twice Fail routine // return CKR_FUNCTION_FAILED if (!Anchor ) { Anchor = (API_Proc_Struct_t *)malloc(sizeof(API_Proc_Struct_t)); if ( Anchor == NULL ){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } } else { // Linux the atfork routines handle this st_err_log(73, __FILE__, __LINE__); return CKR_CRYPTOKI_ALREADY_INITIALIZED; } memset(slot_loaded, 0, sizeof(int)*NUMBER_SLOTS_MANAGED); // Clear out the load list LOGIT(LOG_DEBUG,"Anchor allocated at %x",(char *)Anchor); // Validation of the parameters passed // if pVoid is NULL, then everything is OK. The applicaiton // will not be doing multi thread accesses. We can use the OS // locks anyhow. // if (pVoid != NULL ){ LOGIT(LOG_DEBUG,"Initialization arg = %x Flags %d", pVoid, ((CK_C_INITIALIZE_ARGS *)pVoid)->flags); pArg = (CK_C_INITIALIZE_ARGS *)pVoid; // Check for a pReserved set if ( pArg->pReserved != NULL ){ free(Anchor); Anchor= NULL; st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; // we only support Native OS locking } // Set up a bit map indicating the presense of the functions. fcnmap = (pArg->CreateMutex?0x01<<0:0); fcnmap |= (pArg->DestroyMutex?0x01<<1:0); fcnmap |= (pArg->LockMutex?0x01<<2:0); fcnmap |= (pArg->UnlockMutex?0x01<<3:0); // Verify that all or none of the functions are set if (fcnmap != 0){ if (fcnmap != 0x0f ) { free(Anchor); Anchor = NULL; logit(LOG_DEBUG,"C_Initialize: Invalid number of functions passed in argument structure"); st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; // we only support Native OS locking } } // If we EVER need to create threads from this library we must // check the Flags for the Can_Create_OS_Threads flag // Right now the library DOES NOT create threads and therefore this // check is irrelavant. if ( pArg->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS ) { LOGIT(LOG_DEBUG,"Can't create OS threads.... This is OK"); } // Since this is an initialization path, we will be verbose in the // code rather than efficient. // // in reality, we only need to check for case 3 since all others // are acceptable to us... for one reason or another. // // Case 1 Flag not set and functiopn pointers NOT supplied if ( !(pArg->flags & CKF_OS_LOCKING_OK) && !(fcnmap) ){ ; // This is COOL. Same as a NUL pointer Locking is irrelavent. } else { // Case 2. Flags set and Fcn pointers NOT supplied. if ( (pArg->flags & CKF_OS_LOCKING_OK) && !(fcnmap)){ ; // This to is COOL since we require native locking } else { // Case 3 Flag Not set and pointers supplied. Can't handle this // one. if ( !(pArg->flags & CKF_OS_LOCKING_OK) && fcnmap ){ free(Anchor); Anchor = NULL; logit(LOG_ERR,"C_Initialize:Application specified that OS locking is invalid "); logit(LOG_ERR,"C_Initialize: PKCS11 Module requires OS locking "); return CKR_CANT_LOCK; // we only support Native OS locking } else { // Case 4 Flag set and fcn pointers set if ( (pArg->flags & CKF_OS_LOCKING_OK) && fcnmap){ ; // This is also cool. } else { // Were really hosed here since this should not have // occured free(Anchor); Anchor=NULL; st_err_log(3, __FILE__, __LINE__); return CKR_GENERAL_ERROR; } } } } //LOGIT(LOG_DEBUG,"Init args Create %x ",((CK_C_INITIALIZE_ARGS *)pVoid)->CreateMutex); //LOGIT(LOG_DEBUG,"Init args Destroy %x ",((CK_C_INITIALIZE_ARGS *)pVoid)->DestroyMutex); //LOGIT(LOG_DEBUG,"Init args Lock %x ",((CK_C_INITIALIZE_ARGS *)pVoid)->LockMutex); //LOGIT(LOG_DEBUG,"Init args unLock %x ",((CK_C_INITIALIZE_ARGS *)pVoid)->UnlockMutex); } else { // Pointer to void... // This is OK we can go on from here. ; } //Zero out API_Proc_Struct //Map Shared Memory Region //if ( Shared Memory Mapped not Successful ) // Free allocated Memory // Return CKR_HOST_MEMORY memset((char *)Anchor, 0, sizeof(API_Proc_Struct_t)); pthread_mutex_init(&(Anchor->ProcMutex),NULL); // This is not shared across apps. pthread_mutex_init(&(Anchor->SessListMutex),NULL); // This is not shared across apps. pthread_mutex_init(&GlobMutex,NULL); /* KEY XXX pthread_mutex_init(&logmutex,NULL); */ pthread_mutex_lock(&GlobMutex); Anchor->Pid = getpid(); if ( (Anchor->SharedMemP = attach_shared_memory()) == NULL ){ // Get shared memory free((void *)Anchor); Anchor = NULL; pthread_mutex_unlock(&GlobMutex); LOGIT(LOG_ERR,"C_Initialize: Module failed to attach to shared memory. Verify that the slot management \ daemon is running %d",errno); st_err_log(144, __FILE__, __LINE__); return CKR_HOST_MEMORY; } LOGIT(LOG_DEBUG,"Shared memory %x ",Anchor->SharedMemP); // Initialize structure values //Register with pkcsslotd if (! API_Register() ) { // free memory allocated // return CKR_FUNCTION_FAILED // return CKR_FUNCTION_NOT_SUPPORTED; detach_shared_memory(Anchor->SharedMemP); free((void *)Anchor); Anchor=NULL; pthread_mutex_unlock(&GlobMutex); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // load al the slot DLL's here { API_Slot_t *sltp; CK_SLOT_ID slotID; for (slotID=0;slotIDSltList[slotID]); // LOGIT(LOG_DEBUG,"Init SLTP = %x ID %d",sltp,slotID); slot_loaded[slotID] = DL_Load_and_Init(sltp,slotID); } } // Attempt to force C_Finalize to be called // This causes Netscape to core dump since it unloads the module //atexit(*Call_Finalize); pthread_mutex_unlock(&GlobMutex); return CKR_OK; // Good return code. } // end of C_Initialize //------------------------------------------------------------------------ // API function C_InitPIN //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_InitPIN ( CK_SESSION_HANDLE hSession, CK_CHAR_PTR pPin, CK_ULONG ulPinLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_InitPin"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // A Null Pin with a Len is invalid // A Null pin with a 0 len is no pin at all? if (!pPin && ulPinLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; // Move this to after the session validation... if (slotID >= NUMBER_SLOTS_MANAGED ) { st_err_log(2, __FILE__, __LINE__); return CKR_SLOT_ID_INVALID; } sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_InitPIN){ // Map the Session to the slot session rv = fcn->ST_InitPIN(rSession,pPin,ulPinLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_InitPIN //------------------------------------------------------------------------ // API function C_InitToken //------------------------------------------------------------------------ //Netscape NEVER Calls this according to the Netscape documentation CK_RV C_InitToken ( CK_SLOT_ID slotID, CK_CHAR_PTR pPin, CK_ULONG ulPinLen, CK_CHAR_PTR pLabel ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; LOG("C_InitToken"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (slotID >= NUMBER_SLOTS_MANAGED ) { st_err_log(2, __FILE__, __LINE__); return CKR_SLOT_ID_INVALID; } // Null pPin and a pinlen is a problem if (!pPin && ulPinLen){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } if (!pLabel ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Prior to invoking the Tokens initialization, the // API needs to verify that NO other applications have any // sessions established with this particular slot // // Hooks into the shared memory to determine how many sessions // on a given token are open need to be added. // When a session is opened, it increments the count. When // closed it decrements the count. Protected by an MUTEX // In the shared memory region the slot_info[slotID].sesscount // variable needs to be checked, and held locked until the operation // is complete. if (sessions_exist(slotID)){ st_err_log(43, __FILE__, __LINE__); return CKR_SESSION_EXISTS; } sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_InitToken){ rv = fcn->ST_InitToken(slotID,pPin,ulPinLen,pLabel); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_Login //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_Login ( CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG ulPinLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_Login"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } #if 0 /* Allow incorrect PIN checks to fall into the SC_Login * function, since v2.11 requires flags to be set. - KEY */ if (!pPin ) { return CKR_PIN_INCORRECT; } #endif // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_Login){ // Map the Session to the slot session rv = fcn->ST_Login(rSession,userType,pPin,ulPinLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_Login //------------------------------------------------------------------------ // API function C_Logout //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_Logout ( CK_SESSION_HANDLE hSession ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_Logout){ // Map the Session to the slot session rv = fcn->ST_Logout(rSession); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_Logout //------------------------------------------------------------------------ // API function C_OpenSession //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ // // Note: Need to worry about handling the Notify and Applicaiton call backs // that are here... STDLL will NEVER deal with these... The // usage of them appears to be optional from the specification // but we may need to do something with them at a later date. // CK_RV C_OpenSession ( CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; Session_Struct_t *apiSessp; LOGIT(LOG_DEBUG,"C_OpenSession %d %x %x %x %x",slotID,flags,pApplication, Notify,phSession); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (slotID >= NUMBER_SLOTS_MANAGED ) { st_err_log(2, __FILE__, __LINE__); return CKR_SLOT_ID_INVALID; } if (!phSession) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // allocate the api session block if ( (apiSessp = (Session_Struct_t *)malloc(sizeof(Session_Struct_t))) == NULL ){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; // // Need to handle the failure of a load here... } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_OpenSession){ rv = fcn->ST_OpenSession(slotID,flags,&(apiSessp->RealHandle)); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); // If the session allocation is successful, then we need to // complete the API session block and return. Otherwise // we free the API session block and exit if ( rv == CKR_OK ){ *phSession = (CK_SESSION_HANDLE)apiSessp; // Set applications session to the // address of the api session // handle this ensures // uniqueness. apiSessp->SltId = slotID; // Add to the linked list AddToSessionList(apiSessp); // NOTE: Need to add Session counter to the shared // memory slot value.... Atomic operation. // sharedmem->slot_info[slotID].sessioncount incremented // when ever a session is attached. // Also increment the per process slot counter to indicate // how many sessions this process owns of the total amount. This // way if the process abends garbage collection in the slot manager // can adequatly clean up the total count value... incr_sess_counts(slotID); } else { free(apiSessp); } } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_OpenSession //------------------------------------------------------------------------ // API function C_SeedRandom //------------------------------------------------------------------------ CK_RV C_SeedRandom ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_SeedRandom"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pSeed && ulSeedLen ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_SeedRandom){ // Map the Session to the slot session rv = fcn->ST_SeedRandom(rSession,pSeed,ulSeedLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } //------------------------------------------------------------------------ // API function C_SetAttributeValue //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_SetAttributeValue ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_SetAttributeValue"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } if (!pTemplate){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } if (!ulCount){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_SetAttributeValue){ // Map the Session to the slot session rv = fcn->ST_SetAttributeValue(rSession,hObject,pTemplate,ulCount); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_SetAttributeValue //------------------------------------------------------------------------ // API function C_SetOperationState //------------------------------------------------------------------------ CK_RV C_SetOperationState ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_SetOperationState"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } if (!pOperationState || ulOperationStateLen == 0 ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_SetOperationState){ // Map the Session to the slot session rv = fcn->ST_SetOperationState(rSession,pOperationState,ulOperationStateLen,hEncryptionKey, hAuthenticationKey); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } //------------------------------------------------------------------------ // API function C_SetPIN //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_SetPIN ( CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, CK_ULONG ulOldLen, CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_SetPIN"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pOldPin || !pNewPin) return CKR_PIN_INVALID; // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ) { st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_SetPIN){ // Map the Session to the slot session rv = fcn->ST_SetPIN(rSession,pOldPin,ulOldLen,pNewPin,ulNewLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_SetPIN //------------------------------------------------------------------------ // API function C_Sign //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_Sign ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_Sign"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pData || !pulSignatureLen){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ) { st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_Sign){ // Map the Session to the slot session rv = fcn->ST_Sign(rSession,pData,ulDataLen,pSignature,pulSignatureLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_Sign //------------------------------------------------------------------------ // API function C_SignEncryptUpdate //------------------------------------------------------------------------ CK_RV C_SignEncryptUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_SignEncryptUpdate"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pPart || !pulEncryptedPartLen){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_SignEncryptUpdate){ // Map the Session to the slot session rv = fcn->ST_SignEncryptUpdate(rSession,pPart,ulPartLen,pEncryptedPart,pulEncryptedPartLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } //------------------------------------------------------------------------ // API function C_SignFinal //------------------------------------------------------------------------ // // // //------------------------------------------------------------------------ CK_RV C_SignFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_SignEncryptUpdate"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pulSignatureLen){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ) { st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_SignFinal){ // Map the Session to the slot session rv = fcn->ST_SignFinal(rSession,pSignature,pulSignatureLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } // end of C_SignFinal //------------------------------------------------------------------------ // API function C_SignInit //------------------------------------------------------------------------ // // // //------------------------------------------------------------------------ CK_RV C_SignInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_SignInit"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pMechanism){ st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ) { st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_SignInit){ // Map the Session to the slot session rv = fcn->ST_SignInit(rSession,pMechanism,hKey); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_SignInit //------------------------------------------------------------------------ // API function C_SignRecover //------------------------------------------------------------------------ CK_RV C_SignRecover ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_SignRecover"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pData || !pulSignatureLen){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_SignRecover){ // Map the Session to the slot session rv = fcn->ST_SignRecover(rSession,pData,ulDataLen,pSignature,pulSignatureLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } //------------------------------------------------------------------------ // API function C_SignRecoverInit //------------------------------------------------------------------------ CK_RV C_SignRecoverInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_SignRecoverInit"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pMechanism){ st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_SignRecoverInit){ // Map the Session to the slot session rv = fcn->ST_SignRecoverInit(rSession,pMechanism,hKey); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } //------------------------------------------------------------------------ // API function C_SignUpdate //------------------------------------------------------------------------ // // // //------------------------------------------------------------------------ CK_RV C_SignUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_SignUpdate"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pPart){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_SignUpdate){ // Map the Session to the slot session rv = fcn->ST_SignUpdate(rSession,pPart,ulPartLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } // end of C_SignUpdate //------------------------------------------------------------------------ // API function C_UnwrapKey //------------------------------------------------------------------------ // Netscape Required CK_RV C_UnwrapKey ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_UnwrapKey"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pMechanism){ st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } if (!phKey){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // what about the other pointers... probably need // to be set correctly // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_UnwrapKey){ // Map the Session to the slot session rv = fcn->ST_UnwrapKey(rSession,pMechanism,hUnwrappingKey,pWrappedKey,ulWrappedKeyLen, pTemplate,ulAttributeCount,phKey); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } //------------------------------------------------------------------------ // API function C_Verify //------------------------------------------------------------------------ // Netscape Required CK_RV C_Verify ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_Verify"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pData || !pSignature){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_Verify){ // Map the Session to the slot session rv = fcn->ST_Verify(rSession,pData,ulDataLen,pSignature,ulSignatureLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_VerifyFinal //------------------------------------------------------------------------ CK_RV C_VerifyFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_VerifyFinal"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pSignature){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_VerifyFinal){ // Map the Session to the slot session rv = fcn->ST_VerifyFinal(rSession,pSignature,ulSignatureLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } //------------------------------------------------------------------------ // API function C_VerifyInit //------------------------------------------------------------------------ CK_RV C_VerifyInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_VerifyInit"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pMechanism){ st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_VerifyInit){ // Map the Session to the slot session rv = fcn->ST_VerifyInit(rSession,pMechanism,hKey); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_VerifyRecover //------------------------------------------------------------------------ // Netscape Required CK_RV C_VerifyRecover ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_VerifyRecover"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pSignature || !pulDataLen){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_VerifyRecover){ // Map the Session to the slot session rv = fcn->ST_VerifyRecover(rSession,pSignature,ulSignatureLen,pData,pulDataLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_VerifyRecoverInit //------------------------------------------------------------------------ CK_RV C_VerifyRecoverInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_VerifyRecoverInit"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pMechanism){ st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_VerifyRecoverInit){ // Map the Session to the slot session rv = fcn->ST_VerifyRecoverInit(rSession,pMechanism,hKey); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_VerifyUpdate //------------------------------------------------------------------------ CK_RV C_VerifyUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_VerifyUpdate"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pPart){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); return CKR_ARGUMENTS_BAD; } // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_VerifyUpdate){ // Map the Session to the slot session rv = fcn->ST_VerifyUpdate(rSession,pPart,ulPartLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_WaitForSlotEvent //------------------------------------------------------------------------ // // //NOTE: We need to implement this one even though Netscape does not //make use of this... // //Standard code template won't work with this. We need to look at //the slot manager and the shared memory indicating the slot bitmap //Blocking needs to be worked out. At the initial release do not //support BLocked calls on wait for slot event. // //Support Note: //This function is really used for removable tokens, and is pretty //inefficient. It may be best to return CKR_FUNCTION_UNSUPPORTED //if it becomes a field issue, until removable token support is fully //implemented. Be forewarned. //------------------------------------------------------------------------ CK_RV C_WaitForSlotEvent ( CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved ) { #ifdef PLUGGABLE_TOKENS_SUPPORTED #ifdef PKCS64 Slot_Mgr_Proc_t_64 *procp; #else Slot_Mgr_Proc_t *procp; #endif #endif LOG("C_WaitForSlotEvent"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } #ifndef PLUGGABLE_TOKENS_SUPPORTED // Since there are no tokens which we support that have the // ability to create slot events, and slotd does not // fully support this (it needs to be aware of the functions exported // by an STDLL to poll the slot for a token event and this // has not been fully implemented at this time, although the // design and structure of the shared memory in slotd do. st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; #else // Get the pointer to the process element.. // This could be done in a single line, but for readability we do it // in 2 steps. shm = Anchor->SharedMemP; procp = &shm->proc_table[Anchor->MgrProcIndex]; // Grab the mutex for the application in shared memory // Check the bit mask for non-zero. If the bit mask is non-zero // find the first slot which is set and set the pSlot value // and return CKR_OK. // for now we will just lock the whole shared memory // REally should be the procp->proc_mutex // but this is such an infrequent thing that we will simply get // the global shared memory lock lock_shm(); if ( procp->slotmap) { // find the first bit set // This will have to change if more than 32 slots ever get supported // including the test for a bit turned on.. for (i=0;NUMBER_SLOTS_MANAGED;i++){ if ( procp->slotmap & (1 << i)) { break; } } *pSlot = i; // set the flag unlock_shm(); return CKR_OK; } else { if ( flags & CKF_DONT_BLOCK ) { unlock_shm(); return CKR_NO_EVENT; } else { // WE need to // 1. Set the blocking variable in the system map to true. // 2. clear the condition variable // // Note: for now we will just poll the bitmap every // second or look for the error field to go to true. // Check first if we are already blocking on another thread // for this process. According to the spec this behavior is undefined. // We will choose to fail the call. if (procp->blocking) { LOGIT(LOG_DEBUG,"WaitForSlot event called by process twice"); unlock_shm(); // Unlock aftersetting st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } procp->error = 0; procp->blocking = 0x01; unlock_shm(); // Unlock aftersetting // NOTE: We need to have an asynchronous mechanism for // the slot manager to wake up anyone blocking on this. // But Since we are not supporting removable tokens, this // call should be almos never made. It might be best to // return CKR_FUNCTION_UNSUPPORTED, but we'll wait and see. while (!procp->slotmap && !procp->error){ sleep(1); // Note This is really bad form. But what the heck } lock_shm(); procp->blocking = 0; if ( procp->error ) { unlock_shm(); st_err_log(3, __FILE__, __LINE__); return CKR_GENERAL_ERROR; // We bailed on this because we were terminating // General error should cause the calling thread to not try anything // else... We need to look at how this holds up in practice. }else { // must have fallen out of loop because of a slot getting an // event for (i=0;NUMBER_SLOTS_MANAGED;i++){ if ( procp->slotmap & (1 << i)) { break; } } *pSlot = i; // set the flag unlock_shm(); return CKR_OK; } } } #endif } // end of C_WaitForSlotEvent //------------------------------------------------------------------------ // API function // C_WrapKey //------------------------------------------------------------------------ // Netscape Required CK_RV C_WrapKey ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen ) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; CK_SLOT_ID slotID; ST_SESSION_T rSession; LOG("C_WrapKey"); if (API_Initialized() == FALSE ){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pMechanism){ st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // other pointers??? // Validate Session if (!Valid_Session((Session_Struct_t *)hSession,&rSession)){ st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } // Get local pointers to session slotID = rSession.slotID; sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if ( (fcn=sltp->FcnList) == NULL ){ st_err_log(50, __FILE__, __LINE__); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_WrapKey){ // Map the Session to the slot session rv = fcn->ST_WrapKey(rSession,pMechanism,hWrappingKey,hKey,pWrappedKey,pulWrappedKeyLen); LOGIT(LOG_DEBUG,"Called STDLL rv = 0x%x",rv); } else { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } void api_init(void) __attribute__((constructor)); void api_init(void) { char *env; // Turn on logging. This can only occure // at the application initialization time.... // Simplify things by using environment variables if ( (env = (char *)getenv("PKCS11_API_LOG_DEBUG")) != NULL ){ logging=LOG_DEBUG; } else { logging = 0; } loginit(); // called once per application... rules for C_Initialize apply // Should only have to do the atfork stuff at load time... if (!Initialized){ pthread_atfork(NULL,NULL,(void(*)())child_fork_initializer); Initialized=1; } } void api_fini(void) __attribute__((destructor)); void api_fini() { logterm(); if ( API_Initialized() == TRUE ) { Call_Finalize(); } } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/api/msg.h0000640000175000017500000005455411327631345017151 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/lib/pkcs11/api/msg.h,v 1.1 2005/01/18 16:09:00 kyoder Exp $ */ // /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ // File: msg.h // Error Messages used by st_err_log struct messages { char * msg; }; struct messages err_msg[]={ {"%s:%d Malloc Failed"}, {"%s:%d Not Enough Memory in Context"}, {"%s:%d Slot Invalid"}, {"%s:%d General Error"}, {"%s:%d %s Function Failed"}, //#5 {"%s:%d %s Bad Arguments"}, {"%s:%d No Event"}, {"%s:%d Attribute Read Only"}, {"%s:%d Attribute Type Invalid"}, {"%s:%d Attribute Value Invalid"}, //#10 {"%s:%d Data Invalid"}, {"%s:%d Data Length out of Range"}, {"%s:%d Device Error"}, {"%s:%d Device Removed"}, {"%s:%d Encrypted Data Invalid"}, //15 {"%s:%d Encrypted Data Length out of Range"}, {"%s:%d Function Cancelled"}, {"%s:%d Function Not Parallel"}, {"%s:%d Key Handle Invalid"}, {"%s:%d Key Size out of Range"}, //20 {"%s:%d Key Type Inconsistent"}, {"%s:%d Key Not Needed"}, {"%s:%d Key Changed"}, {"%s:%d Key Needed"}, {"%s:%d Key Indigestible"}, //25 {"%s:%d Key Function Not Permitted"}, {"%s:%d Key Not Wrappable"}, {"%s:%d Key Unextractable"}, {"%s:%d Mechanism Invalid"}, {"%s:%d Mechanism Param Invalid"}, //30 {"%s:%d Object Handle Invalid"}, {"%s:%d Operation Active"}, {"%s:%d Operation Not Initialized"}, {"%s:%d Pin Incorrect"}, {"%s:%d Pin Invalid"}, //35 {"%s:%d Pin Length out of Range"}, {"%s:%d Pin Expired"}, {"%s:%d Pin Locked"}, {"%s:%d Session Closed"}, {"%s:%d Session Count"}, //40 {"%s:%d Session Handle Invalid"}, {"%s:%d Parallel Session Not Supported"}, {"%s:%d Session Read Only"}, {"%s:%d Session Exists"}, {"%s:%d Session Read only Exists"}, //45 {"%s:%d Session Read Write Exists"}, {"%s:%d Signature Length out of Range"}, {"%s:%d Signature Invalid"}, {"%s:%d Template Incomplete"}, {"%s:%d Template Inconsistent"}, //50 {"%s:%d Token Not Present"}, {"%s:%d Token Not Recognized"}, {"%s:%d Token Write Protected"}, {"%s:%d Unwrapping Key Handle Invalid"}, {"%s:%d Unwrapping Key Size Range Invalid"}, //55 {"%s:%d Unwrapping Key Type Inconsistent"}, {"%s:%d User Already Logged In"}, {"%s:%d User Not Logged In"}, {"%s:%d User PIN Not Initialized"}, {"%s:%d User Type Invalid"}, //60 {"%s:%d Another User Already Logged In"}, {"%s:%d Too Many User Types"}, {"%s:%d Wrapped Key Invalid"}, {"%s:%d Wrapped Key Length Out of Range"}, {"%s:%d Wrapping Key Size out of Range"}, //65 {"%s:%d Wrapping Key Type Inconsistent"}, {"%s:%d Random Seed Not Supported"}, {"%s:%d Random Number Invalid"}, {"%s:%d Buffer Too Small"}, {"%s:%d Saved State Invalid"}, //70 {"%s:%d Information Sensitive"}, {"%s:%d State Unsaveable"}, {"%s:%d API not initialized"}, {"%s:%d API already Initialized"}, {"%s:%d Mutex Bad"}, //75 {"%s:%d Mutex Lock Invalid"}, {"%s:%d Encode Integer Failed"}, {"%s:%d Encode Octet String Failed"}, {"%s:%d Encode Sequence Failed"}, {"%s:%d Decode Integer Failed"}, //80 {"%s:%d Decode Octet String Failed"}, {"%s:%d Decode Sequence Failed"}, {"%s:%d Encode Private Key Failed"}, {"%s:%d Decode Private Key Failed"}, {"%s:%d Build Attribute Failed"}, //85 {"%s:%d Function Not Permitted"}, {"%s:%d Key Not Exportable"}, {"%s:%d Encode Private Key failed"}, {"%s:%d Decode Private Key failed"}, {"%s:%d Object Mgr Create Skeleton failed"}, //90 {"%s:%d Object Mgr Create Final failed"}, {"%s:%d Key Generation failed"}, {"%s:%d DES Wrap Get Data Failed"}, {"%s:%d DES3 Wrap Get Data Failed"}, {"%s:%d RSA Wrap Get Data Failed"}, //95 {"%s:%d DSA Wrap Get Data Failed"}, {"%s:%d Generic Secret Wrap Get Data Failed"}, {"%s:%d DES Wrap Format Failed"}, {"%s:%d Encryption Mgr Init Failed"}, {"%s:%d Encryption Mgr Encrypt Failed"}, //100 {"%s:%d Decryption Mgr Decrypt Failed"}, {"%s:%d Flatten Object Failed"}, {"%s:%d Key Mgr Get Priv Key Type Failed"}, {"%s:%d Decrypt Private Key Info Failed"}, {"%s:%d Save Token Failed"}, //105 {"%s:%d Triple DES CBC Encrypt Failed"}, {"%s:%d Triple DES CBC Decrypt Failed"}, {"%s:%d Restore Private Token Failed"}, {"%s:%d Restore Object Failed"}, {"%s:%d Data Length Out of Range"}, //110 {"%s:%d Object Manager Find in Map Failed"}, {"%s:%d Token Specific RNG Failed"}, {"%s:%d Encrypted Data Length Out of Range"}, {"%s:%d DES CBC Encrypt Failed"}, {"%s:%d DES CBC Decrypt Failed"}, //115 {"%s:%d DES ECB Encrypt Failed"}, {"%s:%d DES ECB Decrypt Failed"}, {"%s:%d Token Specific DES ECB Failed"}, {"%s:%d Token Specific DES CBC Failed"}, {"%s:%d Token Specific 3DES CBC Failed"}, //120 {"%s:%d Token Specific 3DES ECB Failed"}, {"%s:%d DSA Verify Failed"}, {"%s:%d DSA Sign Failed"}, {"%s:%d Digest Init Failed"}, {"%s:%d Digest Failed"}, //125 {"%s:%d Digest Update Failed"}, {"%s:%d Digest Final Failed"}, {"%s:%d Sign Init Failed"}, {"%s:%d Sign Update Failed"}, {"%s:%d Sign Final Failed"}, //130 {"%s:%d Random Number Generate Failed"}, {"%s:%d RSA Format Block Failed"}, {"%s:%d RSA Encrypt Failed"}, {"%s:%d RSA Decrypt Failed"}, {"%s:%d Token Specific RSA Encrypt Failed"}, //135 {"%s:%d Token Specific RSA Decrypt Failed"}, {"%s:%d SSL SHA Failed"}, {"%s:%d SSL3 MD5 Failed"}, {"%s:%d SSL3 Process MAC Keys Failed"}, {"%s:%d SSL3 Process Write Keys Failed"}, //140 {"%s:%d Validate Attribute Failed"}, {"%s:%d SSL3 Process Write Keys Failed"}, {"%s:%d %s Function Not Supported"}, {"%s:%d Token Already Initialized"}, {"%s:%d Cannot Attach to Shared Memory"}, //145 {"%s:%d Token Specific Init Failed"}, {"%s:%d Mutex Lock Failed"}, {"%s:%d Mutex Unlock Failed"}, {"%s:%d Hash Computation Failed"}, {"%s:%d Save Master Key Failed"}, //150 {"%s:%d Process Lock Failed"}, {"%s:%d Process Unlock Failed"}, {"%s:%d Session Mgr New Failed"}, {"%s:%d Close all Sessions Failed"}, {"%s:%d Session Mgr Get Op State Failed"}, //155 {"%s:%d Load Master Key Failed"}, {"%s:%d Object Create Failed"}, {"%s:%d Object Mgr Add to Map Failed"}, {"%s:%d Object Copy Failed"}, {"%s:%d Object Get Attribute Values Failed"}, //160 {"%s:%d Object Restore Data Failed"}, {"%s:%d Object Set Attribute Values Failed"}, {"%s:%d Object Mgr Search for Object Failed"}, {"%s:%d Copy Template Failed"}, {"%s:%d Add Attribute Failed"}, //165 {"%s:%d Check Required Attributes Failed"}, {"%s:%d Unflatten Template Failed"}, {"%s:%d Verify Init Failed"}, {"%s:%d Verify Failed"}, {"%s:%d Verify Update Failed"}, //170 {"%s:%d Verify Final Failed"}, {"%s:%d Sign Failed"}, {"%s:%d Set Default Attributes Failed"}, {"%s:%d Unwrap Key Failed"}, {"%s:%d Session Mgr New Failed"}, //175 {"%s:%d Merge Attributes Failed"}, {"%s:%d Encryption Mgr Encrypt Update Failed"}, {"%s:%d Encryption Mgr Encrypt Final Failed"}, {"%s:%d Update Attribute Failed"}, {"%s:%d Decryption Mgr Init Failed"}, //180 {"%s:%d Decryption Mgr Update Failed"}, {"%s:%d Decryption Mgr Final Failed"}, {"%s:%d Object Mgr Destroy Failed"}, {"%s:%d Attribute Undefined"}, {"%s:%d Object Mgr Get Size Failed"}, //185 {"%s:%d Object Manager Find Init Failed"}, {"%s:%d Sign Recover Failed"}, {"%s:%d Verify Recover Failed"}, {"%s:%d Wrap Key Failed"}, {"%s:%d Unwrap Key Failed"}, //190 {"%s:%d Derive Key Failed"}, {"%s:%d AES Wrap Get Data Failed"}, {"%s:%d AES Wrap Format Failed"}, {"%s:%d Domain Parameter Invalid"}, {"%s:%d File \"%s\" could not be opened, errno=%d"} }; opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/api/shrd_mem.c.in0000640000175000017500000004353211327631345020553 0ustar jfjfstatic const char rcsid[] = "$Header: /cvsroot/opencryptoki/opencryptoki/usr/lib/pkcs11/api/shrd_mem.c.in,v 1.3 2007/09/06 15:40:10 tlendacky Exp $"; // /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ // // Pkcs11 Api Shared Memory Routines // #if NGPTH #include #else #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAPFILENAME "@CONFIG_PATH@/.apimap" extern API_Proc_Struct_t *Anchor; // // Will attach to the shared memory that has been created // by the slot manager daemon. // A NULL pointer will return if the memory region is invalid // for any reason void * attach_shared_memory() { int shmid; char *shmp; struct stat statbuf; struct group *grp; struct passwd *pw, *epw; #if !(MMAP) // Really should fstat the tok_path, since it will be the actual // executable of the slotmgr, however at this time we won't bother // for the prototype. /tmp/slotmgr will have to be an existing file. if (stat(TOK_PATH,&statbuf) < 0 ){ // The Stat token origin file does not work... Kick it out return NULL; } // SAB check for the group id here and membership here as well grp = getgrnam("pkcs11"); if ( grp ) { int i=0; char member=0; pw = getpwuid(getuid()); epw = getpwuid(geteuid()); while( grp->gr_mem[i] ) { if (pw) { if ( strncmp(pw->pw_name, grp->gr_mem[i],strlen(pw->pw_name)) == 0 ){ member = 1; break; } } if (epw) { if ( strncmp(epw->pw_name, grp->gr_mem[i],strlen(epw->pw_name)) == 0 ){ member = 1; break; } } i++; } if ( ! member ) { return NULL; // SAB don't bother even attaching... } } else { return NULL; } Anchor->shm_tok = ftok(TOK_PATH,'b'); // Get the shared memory id. shmid = shmget(Anchor->shm_tok,sizeof(Slot_Mgr_Shr_t), S_IWUSR|S_IWGRP|S_IRGRP|S_IRUSR); if ( shmid < 0 ) { return NULL; } shmp = (void *)shmat(shmid,NULL,0); if ( !shmp ) { return NULL; } return shmp; #else int fd; #warning "EXPERIMENTAL" fd = open(MAPFILENAME,O_RDWR); if (fd < 0 ){ return NULL; //Failed the file should exist and be valid } shmp = (char *)mmap(NULL,sizeof(Slot_Mgr_Shr_t),PROT_READ|PROT_WRITE, MAP_SHARED,fd,0); close(fd); if ( ! shmp ) { return NULL; } return shmp; #endif } // //Detach the shared memory from the api when finished. // void detach_shared_memory( shmp ) char *shmp; { #if !(MMAP) shmdt(shmp); #else munmap(shmp,sizeof(Slot_Mgr_Shr_t)); #endif } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/aep_stdll/0000751000175000017500000000000011327631345017373 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/lib/pkcs11/aep_stdll/aeptok_api.h0000640000175000017500000000525211327631345021664 0ustar jfjf/* * Copyright (c) 1999-2002 AEP Systems Ltd. * Bray Business Park, Southern Cross Route, Bray, Co. Wicklow, Ireland. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of AEP Systems Ltd. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include #include "aep_api.h" #include "openssl/bn.h" #include "openssl/rsa.h" #include "openssl/bio.h" typedef enum{ NotConnected= 0, Connected= 1, InUse= 2 } AEP_CONNECTION_STATE; #define MAX_PROCESS_CONNECTIONS 512 #define RAND_BLK_SIZE 1024 typedef struct AEP_CONNECTION_ENTRY{ AEP_CONNECTION_STATE conn_state; AEP_CONNECTION_HNDL conn_hndl; } AEP_CONNECTION_ENTRY; static AEP_RV GetAEPConnection(AEP_CONNECTION_HNDL *hConnection); static AEP_RV ReturnAEPConnection(AEP_CONNECTION_HNDL hConnection); int AEP_RSA_public_encrypt(unsigned long in_data_len, unsigned char *in_data, unsigned char *out_data, RSA *rsa); int AEP_RSA_private_decrypt(unsigned long in_data_len, unsigned char *in_data, unsigned char *out_data, RSA *rsa); AEP_RV GetBigNumSize(void* ArbBigNum, AEP_U32* BigNumSize); AEP_RV MakeAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize, unsigned char* AEP_BigNum); AEP_RV ConvertAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize, unsigned char* AEP_BigNum); static void invert(unsigned char* dest, unsigned char* orig, int len); opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/aep_stdll/aep_types.h0000640000175000017500000000560411327631345021542 0ustar jfjf/* * Copyright (c) 1999-2002 AEP Systems Ltd. * Bray Business Park, Southern Cross Route, Bray, Co. Wicklow, Ireland. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of AEP Systems Ltd. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /****************************************************************/ /* */ /* Filename: aep_types.h */ /* Description: AEP typedefs */ /* */ /****************************************************************/ #ifndef aep_types_H #define aep_types_H 1 typedef unsigned char AEP_U8; typedef char AEP_CHAR; typedef AEP_U8 AEP_BBOOL; typedef unsigned short AEP_U16; typedef unsigned int AEP_U32; #if defined(AEP_Win32) typedef unsigned _int64 AEP_U64; #elif defined(AEP_GENERIC) typedef unsigned long long AEP_U64; #endif typedef AEP_U32 AEP_FLAGS; typedef AEP_U8 *AEP_U8_PTR; typedef AEP_CHAR *AEP_CHAR_PTR; typedef AEP_U16 *AEP_U16_PTR; typedef AEP_U32 *AEP_U32_PTR; typedef AEP_U64 *AEP_U64_PTR; typedef void *AEP_VOID_PTR; typedef AEP_VOID_PTR *AEP_VOID_PTR_PTR; typedef AEP_U32 AEP_CONNECTION_HNDL; typedef AEP_CONNECTION_HNDL *AEP_CONNECTION_HNDL_PTR; typedef AEP_U64 AEP_TRANSACTION_HNDL; typedef AEP_TRANSACTION_HNDL *AEP_TRANSACTION_HNDL_PTR; typedef AEP_U32 AEP_TRANSACTION_ID; typedef AEP_TRANSACTION_ID *AEP_TRANSACTION_ID_PTR; typedef AEP_U64 AEP_KEY_ID; typedef AEP_U64 AEP_CONTEXT_ID; typedef AEP_U32 AEP_RV; typedef struct AEP_BYTEBLOCK { AEP_U32 Len; AEP_U8_PTR ptr; } AEP_BYTEBLOCK; #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/aep_stdll/aep_api.h0000640000175000017500000000642711327631345021153 0ustar jfjf/* * Copyright (c) 1999-2002 AEP Systems Ltd. * Bray Business Park, Southern Cross Route, Bray, Co. Wicklow, Ireland. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of AEP Systems Ltd. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /****************************************************************/ /* */ /* Filename: aep_api.h */ /* Description: AEP API Include file, fxn prototypes for the */ /* AEP API. */ /* */ /****************************************************************/ #ifndef aep_api_H #define aep_api_H 1 #include "aep_lib.h" #include "aep_defs.h" #include "aep_types.h" AEP_SLIB_CALLING_CONVENTION AEP_RV AEP_Initialize( AEP_VOID_PTR pInitArgs); AEP_SLIB_CALLING_CONVENTION AEP_RV AEP_Finalize( ); AEP_SLIB_CALLING_CONVENTION AEP_RV AEP_SetBNCallBacks( AEP_RV (*GetBigNumSizeFunc)(), AEP_RV (*MakeAEPBigNumFunc)(), AEP_RV (*ConverAEPBigNumFunc)() ); AEP_SLIB_CALLING_CONVENTION AEP_RV AEP_OpenConnection( AEP_CONNECTION_HNDL_PTR phConnection); AEP_SLIB_CALLING_CONVENTION AEP_RV AEP_CloseConnection( AEP_CONNECTION_HNDL hConnection); AEP_SLIB_CALLING_CONVENTION AEP_RV AEP_ModExp( AEP_CONNECTION_HNDL hConnection, AEP_VOID_PTR pA, AEP_VOID_PTR pP, AEP_VOID_PTR pN, AEP_VOID_PTR pResult, AEP_TRANSACTION_ID* pidTransID); AEP_SLIB_CALLING_CONVENTION AEP_RV AEP_ModExpCrt( AEP_CONNECTION_HNDL hConnection, AEP_VOID_PTR pA, AEP_VOID_PTR pP, AEP_VOID_PTR pQ, AEP_VOID_PTR pDmp1, AEP_VOID_PTR pDmq1, AEP_VOID_PTR pIqmp, AEP_VOID_PTR pResult, AEP_TRANSACTION_ID* pidTransId ); AEP_SLIB_CALLING_CONVENTION AEP_RV AEP_GenRandom( AEP_CONNECTION_HNDL hConnection, AEP_U32 Len, AEP_U32 Type, AEP_VOID_PTR pResult, AEP_TRANSACTION_ID* pidTransID ); AEP_SLIB_CALLING_CONVENTION char ** AEP_GetAPIVersion (); #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/aep_stdll/aeptok_api.c0000640000175000017500000001747711327631345021673 0ustar jfjf/* * Copyright (c) 1999-2002 AEP Systems Ltd. * Bray Business Park, Southern Cross Route, Bray, Co. Wicklow, Ireland. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of AEP Systems Ltd. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include #include "aeptok_api.h" extern int cryptoki_aep_avail; static int aep_initialised = FALSE; static AEP_CONNECTION_ENTRY aep_app_conn_table[MAX_PROCESS_CONNECTIONS]; static pid_t recorded_pid = 0; static pthread_mutex_t AEP_ThreadPool_mutex=PTHREAD_MUTEX_INITIALIZER; static AEP_RV GetAEPConnection(AEP_CONNECTION_HNDL *hConnection) { int count; AEP_RV rv = AEP_R_OK; pid_t curr_pid = getpid(); pthread_mutex_lock(&AEP_ThreadPool_mutex); // Check if this is the first time this is being called // from the current process // if (recorded_pid != curr_pid) { if (aep_initialised != TRUE) { aep_initialised = TRUE; recorded_pid = curr_pid; AEP_Finalize(); /*Initialise the AEP API*/ if ( (rv = AEP_Initialize(NULL)) != AEP_R_OK) { aep_initialised = FALSE; recorded_pid = 0; goto end; } /*Set the AEP big num call back functions*/ rv = AEP_SetBNCallBacks(&GetBigNumSize, &MakeAEPBigNum, &ConvertAEPBigNum); if (rv != AEP_R_OK) { aep_initialised = FALSE; recorded_pid = 0; goto end; } /*Init the structures*/ for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++) { aep_app_conn_table[count].conn_state = NotConnected; aep_app_conn_table[count].conn_hndl = 0; } if ( (rv = AEP_OpenConnection(hConnection)) != AEP_R_OK) { /* a problem here, assume AEP subsystem is dead ! */ cryptoki_aep_avail = FALSE; aep_initialised = FALSE; recorded_pid = 0; st_err_log(12, __FILE__, __LINE__); goto end; } aep_app_conn_table[0].conn_state = InUse; aep_app_conn_table[0].conn_hndl = *hConnection; goto end; } for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++) { if (aep_app_conn_table[count].conn_state == Connected) { aep_app_conn_table[count].conn_state = InUse; *hConnection = aep_app_conn_table[count].conn_hndl; goto end; } } /*If no connections available, we try to open a new one*/ for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++) { if (aep_app_conn_table[count].conn_state == NotConnected) { rv = AEP_OpenConnection(hConnection); if ( rv != AEP_R_OK){ // a problem here, assume AEP subsystem is dead ! cryptoki_aep_avail = FALSE; st_err_log(12, __FILE__, __LINE__); goto end; } aep_app_conn_table[count].conn_state = InUse; aep_app_conn_table[count].conn_hndl = *hConnection; goto end; } } rv = AEP_R_GENERAL_ERROR; end: pthread_mutex_unlock(&AEP_ThreadPool_mutex); return rv; } static AEP_RV ReturnAEPConnection(AEP_CONNECTION_HNDL hConnection) { int count; pthread_mutex_lock(&AEP_ThreadPool_mutex); /*Find the connection */ for(count = 0;count < MAX_PROCESS_CONNECTIONS;count ++) { if (aep_app_conn_table[count].conn_hndl == hConnection) { aep_app_conn_table[count].conn_state = Connected; break; } } pthread_mutex_unlock(&AEP_ThreadPool_mutex); return AEP_R_OK; } int AEP_RSA_public_encrypt(unsigned long in_data_len, unsigned char *in_data, unsigned char *out_data, RSA *rsa) { AEP_RV rv; AEP_CONNECTION_HNDL hConnection; BIGNUM rr; BIGNUM *a; if ( GetAEPConnection(&hConnection) != AEP_R_OK) { ReturnAEPConnection(hConnection); return 0; } if ( (a = BN_new()) == NULL) { ReturnAEPConnection(hConnection); return 0; } BN_bin2bn( in_data, in_data_len, a); rv = AEP_ModExp(hConnection, (void*)a, (void*) rsa->e, (void*) rsa->n, (void*)&rr, NULL); if (rv!=AEP_R_OK) { ReturnAEPConnection(hConnection); BN_free(a); return 0; } memset(out_data, 0, in_data_len); if ( rr.top * 4 > in_data_len) { ReturnAEPConnection(hConnection); BN_free(a); return 0; } invert( out_data, (unsigned char*) rr.d, rr.top*4); ReturnAEPConnection(hConnection); BN_free(a); return 1; } int AEP_RSA_private_decrypt(unsigned long in_data_len, unsigned char *in_data, unsigned char *out_data, RSA *rsa) { AEP_RV rv ; AEP_CONNECTION_HNDL hConnection; BIGNUM rr; BIGNUM* a; if ( GetAEPConnection(&hConnection) != AEP_R_OK) { ReturnAEPConnection(hConnection); return 0; } if(!rsa->d || !rsa->n ) { ReturnAEPConnection(hConnection); return 0; } if ( (a = BN_new()) == NULL) { ReturnAEPConnection(hConnection); return 0; } BN_bin2bn( in_data, in_data_len, a); if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { rv = AEP_ModExp(hConnection, (void *)a, (void *)(rsa->d), (void *)(rsa->n), (void *)&rr, NULL); } else { rv = AEP_ModExpCrt(hConnection, (void *)a, (void *)(rsa->p), (void *)(rsa->q), (void *)(rsa->dmp1), (void *)(rsa->dmq1), (void *)(rsa->iqmp), (void *)&rr, NULL); } if (rv!=AEP_R_OK) { ReturnAEPConnection(hConnection); BN_free(a); return 0; } memset(out_data, 0, in_data_len); if ( rr.top * 4 > in_data_len) { ReturnAEPConnection(hConnection); BN_free(a); return 0; } invert( out_data, (unsigned char *) rr.d, rr.top*4); ReturnAEPConnection(hConnection); BN_free(a); return 1; } /* BigNum call back functions, used to convert OpenSSL * bignums into AEP bignums */ AEP_RV GetBigNumSize(void* ArbBigNum, AEP_U32* BigNumSize) { BIGNUM* bn; /*Cast the ArbBigNum pointer to our BIGNUM struct*/ bn = (BIGNUM*) ArbBigNum; /*Size of the bignum in bytes is equal to the bn->top (no of 32 bit words) multiplies by 4*/ *BigNumSize = bn->top << 2; return AEP_R_OK; } AEP_RV MakeAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize, unsigned char* AEP_BigNum) { BIGNUM* bn; unsigned char* buf; int i; /*Cast the ArbBigNum pointer to our BIGNUM struct*/ bn = (BIGNUM*) ArbBigNum; if (BigNumSize != bn->top * 4) return AEP_R_GENERAL_ERROR; memcpy(AEP_BigNum, (unsigned char *) bn->d, BigNumSize); return AEP_R_OK; } AEP_RV ConvertAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize, unsigned char* AEP_BigNum) { BIGNUM* bn; int i; bn = (BIGNUM*)ArbBigNum; /*Make sure big num is a multiple of 4*/ if (BigNumSize & 3 != 0) { exit(1); } bn->top = BigNumSize >> 2; bn->d = (unsigned long*)AEP_malloc(BigNumSize); memcpy( (unsigned char *) bn->d, AEP_BigNum, BigNumSize); return AEP_R_OK; } static void invert(unsigned char* dest, unsigned char* orig, int len) { while (len--) *dest++ = orig[len]; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/aep_stdll/aep_lib.h0000640000175000017500000000537111327631345021145 0ustar jfjf/* * Copyright (c) 1999-2002 AEP Systems Ltd. * Bray Business Park, Southern Cross Route, Bray, Co. Wicklow, Ireland. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of AEP Systems Ltd. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /****************************************************************/ /* */ /* Filename: aep_lib.h */ /* Description: Contains OS specific details */ /* */ /****************************************************************/ #ifndef AEPlib_H #define AEPlib_H 1 #if defined(AEP_Win32) #define AEP_THR_FN_CALLING_CONVENTION DWORD WINAPI # if defined(AEPAPI_DLL_EXPORT) # define AEPAPI_FDEF(rtype,name,params) \ __declspec(dllexport) rtype name params # elif defined(AEPAPI_DLL_LOAD) # define AEPAPI_FDEF(rtype,name,params) \ typedef rtype (*name##_ft)params; \ extern name##_ft name # define AEPAPI_FDEF_INIT(name) name##_ft name = NULL; # define AEPAPI_GETPROCADDRESS(hModule, name) \ name = (name##_ft) GetProcAddress(hModule, #name) extern BOOL AEP_LoadDLL(char *path); # else /* Default to import */ # define AEPAPI_FDEF(rtype,name,params) \ __declspec(dllimport) rtype name params # endif /* if defined(AEP_DLL_EXPORT) */ #elif defined(AEP_GENERIC) #define AEP_SLIB_CALLING_CONVENTION #else #error no OS type defined (needs to be one of AEP_Win32, AEP_Win16, AEP_GENERIC) #endif /* OS Type */ #endif /* ifndef AEPlib_H */ opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/aep_stdll/tok_struct.h.in0000640000175000017500000004034211327631345022355 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2002 */ // SAB FIXME need to figure out a better way... // // to get the variant dependency out #ifndef __TOK_STRUCT_H #define __TOK_STRUCT_H #include #include "tok_spec_struct.h" // #define PK_LITE_DIR "/etc/pkcs11/lite" // // #define PK_DIR PK_LITE_DIR // #define SUB_DIR "lite" // // // #define DBGTAG "ICA_STDLL_Debug" // // // token_spec_t token_specific = { "@DB_PATH@/aep", "aep", "AEP_STDLL_Debug", &token_specific_init, &tok_slot2local, &token_rng, &token_specific_session, &token_specific_final, &token_specific_des_key_gen, &token_specific_des_ecb, &token_specific_des_cbc, &token_specific_tdes_ecb, &token_specific_tdes_cbc, &token_specific_rsa_decrypt, &token_specific_rsa_encrypt, &token_specific_rsa_generate_keypair, // DH &token_specific_dh_pkcs_derive, &token_specific_dh_pkcs_key_pair_gen, // SHA1 NULL, NULL, NULL, /* SHA256 */ NULL, NULL, NULL, /* SHA-384 */ NULL, NULL, NULL, /* SHA-512 */ NULL, NULL, NULL, #ifndef NOAES // AES &token_specific_aes_key_gen, &token_specific_aes_ecb, &token_specific_aes_cbc, #endif &token_specific_get_mechanism_list, &token_specific_get_mechanism_info }; #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/aep_stdll/Makefile.am0000640000175000017500000000320111327631345021423 0ustar jfjfnobase_lib_LTLIBRARIES = opencryptoki/stdll/libpkcs11_aep.la opencryptoki_stdll_libpkcs11_aep_la_LDFLAGS = $(LCRYPTO) \ $(AEP_LIB_DIRS) -nostartfiles -shared -Wl,-soname,PKCS11_AEP.so.1 -lc \ -lpthread -lcrypto -laep # Not all versions of automake observe libname_CFLAGS opencryptoki_stdll_libpkcs11_aep_la_CFLAGS = -DSPINXPL -DDEV \ -D_THREAD_SAFE -fPIC -DSHALLOW=0 -DSWTOK=1 -DLITE=0 -DNOCDMF -DNOMD2 \ -DNODSA -DDEBUGON -DAEP_GENERIC -DNORIPE -DSTDLL_NAME=\"aeptok\" # Not all versions of automake observe libname_CFLAGS AM_CFLAGS = @CFLAGS@ -DSPINXPL -DDEV -D_THREAD_SAFE -fPIC -DSHALLOW=0 \ -DSWTOK=1 -DLITE=0 -DNOCDMF -DNOMD2 -DNODSA -DDEBUGON -DAEP_GENERIC -DNORIPE opencryptoki_stdll_libpkcs11_aep_la_SOURCES = ../common/asn1.c \ ../common/cert.c ../common/hwf_obj.c ../common/dp_obj.c \ ../common/data_obj.c ../common/decr_mgr.c ../common/dig_mgr.c \ ../common/encr_mgr.c ../common/globals.c ../common/loadsave.c \ ../common/key.c ../common/key_mgr.c ../common/mech_des.c \ ../common/mech_des3.c ../common/mech_dh.c ../common/mech_md5.c \ ../common/mech_md2.c ../common/mech_rng.c ../common/mech_rsa.c \ ../common/mech_sha.c ../common/mech_ssl3.c ../common/new_host.c \ ../common/obj_mgr.c ../common/object.c ../common/sess_mgr.c \ ../common/sign_mgr.c ../common/template.c ../common/utility.c \ ../common/verify_mgr.c ../common/log.c ../common/mech_list.c \ aeptok_specific.c aeptok_api.c INCLUDES = -I/usr/include -I. -I../../../include/pkcs11/stdll \ -I../../../include/pkcs11 -I ../common install-data-local: cd $(DESTDIR)/$(libdir)/opencryptoki/stdll && rm -f PKCS11_AEP.so && \ ln -sf libpkcs11_aep.so PKCS11_AEP.so opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/aep_stdll/aep_defs.h0000640000175000017500000000712311327631345021315 0ustar jfjf/* * Copyright (c) 1999-2002 AEP Systems Ltd. * Bray Business Park, Southern Cross Route, Bray, Co. Wicklow, Ireland. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of AEP Systems Ltd. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /****************************************************************/ /* */ /* Filename: aep_defs.h */ /* Description: Contains various constants used in the AEP API */ /* */ /****************************************************************/ #ifndef AEPdefs_H #define AEPdefs_H 1 #define AEP_INVALID_HANDLE 0 /*******Return Values / Error Codes************/ #define AEP_R_OK 0x00000000 #define AEP_R_GENERAL_ERROR 0x10000001 #define AEP_R_HOST_MEMORY 0x10000002 #define AEP_R_FUNCTION_FAILED 0x10000006 #define AEP_R_ARGUMENTS_BAD 0x10020000 #define AEP_R_SIGNATURE_INVALID 0x10020001 #define AEP_R_NO_TARGET_RESOURCES 0x10030000 #define AEP_R_SOCKERROR 0x10000010 #define AEP_R_SOCKEOF 0x10000011 #define AEP_R_CONNECTION_HANDLE_INVALID 0x100000B3 #define AEP_R_TRANSACTION_HANDLE_INVALID 0x10040000 #define AEP_R_TRANSACTION_NOT_READY 0x00010000 #define AEP_R_TRANSACTION_CLAIMED 0x10050000 #define AEP_R_TIMED_OUT 0x10060000 #define AEP_R_FXN_NOT_IMPLEMENTED 0x10070000 #define AEP_R_TARGET_ERROR 0x10080000 #define AEP_R_DAEMON_ERROR 0x10090000 #define AEP_R_KEY_NOT_FOUND 0x100a0000 #define AEP_R_INVALID_CTX_ID 0x10009000 #define AEP_R_NO_KEY_MANAGER 0x1000a000 #define AEP_R_MUTEX_BAD 0x000001A0 #define AEP_R_AEPAPI_NOT_INITIALIZED 0x10000190 #define AEP_R_AEPAPI_ALREADY_INITIALIZED 0x10000191 #define AEP_R_NO_MORE_CONNECTION_HNDLS 0x10000200 #define AEP_R_MISSING_REGISTRY_ENTRY 0x10000201 /*If not defined, define various constants*/ #ifndef NULL_PTR #define NULL_PTR 0 #endif #ifndef NULL #define NULL 0 #endif #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif #define AEP_COND_ATTR_TRUE TRUE #define AEP_COND_ATTR_FALSE FALSE #define SEM_LOCKED 1 #define SEM_UNLOCKED 0 #define AEP_IO_ERROR -1 #define AEP_IO_ERROR_TIMEOUT -2 #define AEP_IO_ERROR_NO_SPACE -3 #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/aep_stdll/aeptok_specific.c0000640000175000017500000011450411327631345022674 0ustar jfjf/*************************************************/ /* AEP Token Implementation. */ /* Currently it uses openssl's libcrypto.so */ /* for DES, 3DES and key generation. */ /* Modular Exponentiation (RSA encrypt/decrypt) */ /* is done in hardware. */ /*************************************************/ #include #include #include #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "args.h" #include "errno.h" #include "tok_specific.h" #include #include #include #include #include #include #ifndef NOAES #include #endif #ifndef NODH #include #endif typedef unsigned int uint32_t; pthread_mutex_t rngmtx = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t nextmutex = PTHREAD_MUTEX_INITIALIZER; unsigned int rnginitialized=0; CK_CHAR manuf[] = "IBM Corp."; CK_CHAR model[] = "IBM AEPToken"; CK_CHAR descr[] = "IBM PKCS#11 AEP token"; CK_CHAR label[] = "AEP OS PKCS#11 "; /* variable indicating if AEP hardware is available */ int cryptoki_aep_avail = TRUE; /* max length of modulae which can be handled by the card */ static int max_key_len = 2176; CK_RV token_specific_session(CK_SLOT_ID slotid) { return CKR_OK; } CK_RV token_rng(CK_BYTE *output, CK_ULONG bytes) { #if 0 int bytes2 = 384; char state[bytes2]; pthread_mutex_lock(&rngmtx); if (!rnginitialized) { RAND_seed(&state, bytes2); rnginitialized=1; } RAND_pseudo_bytes(output, bytes); pthread_mutex_unlock(&rngmtx); #else int ranfd; int rlen,totallen=0; ranfd = open("/dev/urandom",O_RDONLY); if (ranfd >= 0 ){ do { rlen = read(ranfd,output+totallen,bytes-totallen); totallen += rlen; } while( totallen < bytes); return CKR_OK; } else { return CKR_FUNCTION_FAILED; } #endif } // convert pkcs slot number to local representation int tok_slot2local(CK_SLOT_ID snum) { return 1; } CK_RV token_specific_init(char * Correlator,CK_SLOT_ID SlotNumber) { return CKR_OK; } CK_RV token_specific_final() { return CKR_OK; } CK_RV token_specific_des_key_gen(CK_BYTE *des_key,CK_ULONG len) { // Nothing different to do for DES or TDES here as this is just // random data... Validation handles the rest rng_generate(des_key,len); // we really need to validate the key for parity etc... // we should do that here... The caller validates the single des keys // against the known and suspected poor keys.. return CKR_OK; } CK_RV token_specific_des_ecb(CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_BYTE encrypt) { CK_ULONG rc; des_key_schedule des_key2; const_des_cblock key_val_SSL, in_key_data; des_cblock out_key_data; int i,j; int ret; // Create the key schedule memcpy(&key_val_SSL, key_value, 8); des_set_key_unchecked(&key_val_SSL, des_key2); // the des decrypt will only fail if the data length is not // evenly divisible by 8 if (in_data_len % 8 ){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } // Both the encrypt and the decrypt are done 8 bytes at a time if (encrypt) { for (i=0; itemplate, CKA_MODULUS, &modulus ); rc &= template_attribute_find( key_obj->template, CKA_PUBLIC_EXPONENT, &pub_exp ); if (rc == FALSE) { return NULL; } // Create an RSA key struct to return rsa = RSA_new(); if (rsa == NULL) return NULL; RSA_blinding_off(rsa); // Create and init BIGNUM structs to stick in the RSA struct bn_mod = BN_new(); if (bn_mod == NULL) { RSA_free(rsa); return NULL; } bn_exp = BN_new(); if (bn_exp == NULL) { RSA_free(rsa); BN_free(bn_mod); return NULL; } BN_init(bn_mod); BN_init(bn_exp); // Convert from strings to BIGNUMs and stick them in the RSA struct BN_bin2bn((char *)modulus->pValue, modulus->ulValueLen, bn_mod); rsa->n = bn_mod; BN_bin2bn((char *)pub_exp->pValue, pub_exp->ulValueLen, bn_exp); rsa->e = bn_exp; /* get the length of modulus for the modexp operation */ *mLen = BN_num_bits(rsa->n); return (void *)rsa; } void * rsa_convert_private_key(OBJECT *key_obj, int * mLen) { CK_ATTRIBUTE * attr = NULL; CK_ATTRIBUTE * modulus = NULL; CK_ATTRIBUTE * priv_exp = NULL; CK_ATTRIBUTE * prime1 = NULL; CK_ATTRIBUTE * prime2 = NULL; CK_ATTRIBUTE * exp1 = NULL; CK_ATTRIBUTE * exp2 = NULL; CK_ATTRIBUTE * coeff = NULL; CK_BBOOL rc; RSA *rsa; BIGNUM *bn_mod, *bn_priv_exp, *bn_p1, *bn_p2, *bn_e1, *bn_e2, *bn_cf; int tmp; rc = template_attribute_find( key_obj->template, CKA_MODULUS, &modulus ); rc &= template_attribute_find( key_obj->template, CKA_PRIVATE_EXPONENT, &priv_exp ); rc &= template_attribute_find( key_obj->template, CKA_PRIME_1, &prime1 ); rc &= template_attribute_find( key_obj->template, CKA_PRIME_2, &prime2 ); rc &= template_attribute_find( key_obj->template, CKA_EXPONENT_1, &exp1 ); rc &= template_attribute_find( key_obj->template, CKA_EXPONENT_2, &exp2 ); rc &= template_attribute_find( key_obj->template, CKA_COEFFICIENT, &coeff ); if ( !prime2 && !modulus ){ return NULL; } // Create and init all the RSA and BIGNUM structs we need. rsa = RSA_new(); if (rsa == NULL) return NULL; RSA_blinding_off(rsa); bn_mod = BN_new(); bn_priv_exp = BN_new(); bn_p1 = BN_new(); bn_p2 = BN_new(); bn_e1 = BN_new(); bn_e2 = BN_new(); bn_cf = BN_new(); if ((bn_cf == NULL) || (bn_e2 == NULL) || (bn_e1 == NULL) || (bn_p2 == NULL) || (bn_p1 == NULL) || (bn_priv_exp == NULL) || (bn_mod == NULL)) { if (rsa) RSA_free(rsa); if (bn_mod) BN_free(bn_mod); if (bn_priv_exp) BN_free(bn_priv_exp); if (bn_p1) BN_free(bn_p1); if (bn_p2) BN_free(bn_p2); if (bn_e1) BN_free(bn_e1); if (bn_e2) BN_free(bn_e2); if (bn_cf) BN_free(bn_cf); return NULL; } // CRT key? if ( prime1){ if (!prime2 || !exp1 ||!exp2 || !coeff) { return NULL; } // Even though this is CRT key, OpenSSL requires the // modulus and exponents filled in or encrypt and decrypt will // not work BN_bin2bn((char *)modulus->pValue, modulus->ulValueLen, bn_mod); rsa->n = bn_mod; BN_bin2bn((char *)priv_exp->pValue, priv_exp->ulValueLen, bn_priv_exp); rsa->d = bn_priv_exp; BN_bin2bn((char *)prime1->pValue, prime1->ulValueLen, bn_p1); rsa->p = bn_p1; BN_bin2bn((char *)prime2->pValue, prime2->ulValueLen, bn_p2); rsa->q = bn_p2; BN_bin2bn((char *)exp1->pValue, exp1->ulValueLen, bn_e1); rsa->dmp1 = bn_e1; BN_bin2bn((char *)exp2->pValue, exp2->ulValueLen, bn_e2); rsa->dmq1 = bn_e2; BN_bin2bn((char *)coeff->pValue, coeff->ulValueLen, bn_cf); rsa->iqmp = bn_cf; /* get the length of modulus for the modexp operation */ *mLen = BN_num_bits(rsa->p); tmp = BN_num_bits(rsa->q); *mLen = (tmp > *mLen) ? tmp : *mLen; return rsa; } else { // must be a non-CRT key if (!priv_exp) { return NULL; } BN_bin2bn((char *)modulus->pValue, modulus->ulValueLen, bn_mod); rsa->n = bn_mod; BN_bin2bn((char *)priv_exp->pValue, priv_exp->ulValueLen, bn_priv_exp); rsa->d = bn_priv_exp; /* get the length of modulus for the modexp operation */ *mLen = BN_num_bits(rsa->n); } return (void *)rsa; } #define RNG_BUF_SIZE 100 // This function is only required if public key cryptography // has been selected in your variant set up. // Set a mutex in this function and get a cache; // using the ICA device to get random numbers a byte at a // time is VERY slow.. Keygen is gated by this function. unsigned char nextRandom (void) { static unsigned char buffer[RNG_BUF_SIZE]; unsigned char byte; static int used = (RNG_BUF_SIZE); // protected access by the mutex pthread_mutex_lock(&nextmutex); if (used >= RNG_BUF_SIZE){ rng_generate(buffer,sizeof(buffer)); used = 0; } byte = buffer[used++]; pthread_mutex_unlock(&nextmutex); return((unsigned char)byte); } CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) { CK_ATTRIBUTE * publ_exp = NULL; CK_ATTRIBUTE * attr = NULL; CK_ULONG mod_bits; CK_BBOOL flag; CK_RV rc; CK_ULONG BNLength; RSA *rsa; BIGNUM *bignum; CK_BYTE *ssl_ptr; unsigned long three = 3; unsigned char *exp_str; unsigned long exponent; flag = template_attribute_find( publ_tmpl, CKA_MODULUS_BITS, &attr ); if (!flag){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; // should never happen } mod_bits = *(CK_ULONG *)attr->pValue; flag = template_attribute_find( publ_tmpl, CKA_PUBLIC_EXPONENT, &publ_exp ); if (!flag){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } if (mod_bits < 512 || mod_bits > 2048) { st_err_log(19, __FILE__, __LINE__); return CKR_KEY_SIZE_RANGE; } // Because of a limition of OpenSSL, this token only supports // 3 as an exponent in RSA key generation rsa = RSA_new(); if (rsa == NULL) { st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } RSA_blinding_off(rsa); rsa = RSA_generate_key(mod_bits, three, NULL, NULL); if (rsa == NULL) { st_err_log(4, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } // Now fill in the objects.. // // modulus: n // bignum = rsa->n; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_MODULUS, ssl_ptr, BNLength, &attr ); // in bytes if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( publ_tmpl, attr ); free(ssl_ptr); // Public Exponent bignum = rsa->e; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_PUBLIC_EXPONENT, ssl_ptr, BNLength, &attr ); // in bytes if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( publ_tmpl, attr ); free(ssl_ptr); // local = TRUE // flag = TRUE; rc = build_attribute( CKA_LOCAL, &flag, sizeof(CK_BBOOL), &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( publ_tmpl, attr ); // // now, do the private key // // Cheat here and put the whole original key into the CKA_VALUE... // remember to force the system to not return this for RSA keys.. // Add the modulus to the private key information bignum = rsa->n; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_MODULUS, ssl_ptr, BNLength ,&attr ); // in bytes if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); free(ssl_ptr); // Private Exponent bignum = rsa->d; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc( BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_PRIVATE_EXPONENT, ssl_ptr, BNLength, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); free(ssl_ptr); // prime #1: p // bignum = rsa->p; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_PRIME_1, ssl_ptr, BNLength, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); free(ssl_ptr); // prime #2: q // bignum = rsa->q; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_PRIME_2, ssl_ptr, BNLength, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); free(ssl_ptr); // exponent 1: d mod(p-1) // bignum = rsa->dmp1; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_EXPONENT_1, ssl_ptr, BNLength, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); free(ssl_ptr); // exponent 2: d mod(q-1) // bignum = rsa->dmq1; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_EXPONENT_2, ssl_ptr, BNLength, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); free(ssl_ptr); // CRT coefficient: q_inverse mod(p) // bignum = rsa->iqmp; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_COEFFICIENT, ssl_ptr, BNLength, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); free(ssl_ptr); flag = TRUE; rc = build_attribute( CKA_LOCAL, &flag, sizeof(CK_BBOOL), &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); done: RSA_free(rsa); return rc; } CK_RV token_specific_rsa_generate_keypair( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ) { CK_RV rc; rc = os_specific_rsa_keygen(publ_tmpl,priv_tmpl); if (rc != CKR_OK) st_err_log(91, __FILE__, __LINE__); return rc; } CK_RV token_specific_rsa_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, OBJECT * key_obj ) { CK_RV rc; RSA *rsa; int mLen; // Convert the local representation to an RSA representation rsa = (RSA *)rsa_convert_public_key(key_obj, &mLen); if (rsa==NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } if ( cryptoki_aep_avail == TRUE && mLen <= max_key_len) { /* use AEP device */ rc = AEP_RSA_public_encrypt(in_data_len, in_data, out_data, rsa); } // The operation will fall back to software if AEP is not available // or the modulus length is greater than allowed. // We do another "if" instead of "else", as the variable // cryptoki_aep_avail might have just been set to FALSE in the // call of AEP_RSA_public_encrypt above !! if ( cryptoki_aep_avail == FALSE || mLen > max_key_len) { /* do it in software */ rc = RSA_public_encrypt(in_data_len, in_data, out_data, rsa, RSA_NO_PADDING); } if (rc != 0) { rc = CKR_OK; } else { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; } // Clean up after ourselves RSA_free(rsa); done: return rc; } CK_RV token_specific_rsa_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, OBJECT * key_obj ) { CK_RV rc; RSA *rsa; int mLen; // Convert the local key representation to an RSA key representaion rsa = (RSA *)rsa_convert_private_key(key_obj, &mLen); if (rsa == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } if ( cryptoki_aep_avail == TRUE && mLen <= max_key_len) { /* Use AEP device */ rc =AEP_RSA_private_decrypt(in_data_len, in_data, out_data, rsa); } // The operation will fall back to software if AEP is not available // or the modulus length is greater than allowed. // We do another "if" instead of "else", as the variable // cryptoki_aep_avail might have just been set to FALSE in the // call of AEP_RSA_private_decrypt above !! if ( cryptoki_aep_avail == FALSE || mLen > max_key_len) { /* do it in software */ rc = RSA_private_decrypt(in_data_len, in_data, out_data, rsa, RSA_NO_PADDING); } if (rc != 0) { rc = CKR_OK; } else { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; } // Clean up RSA_free(rsa); done: return rc; } #ifndef NOAES CK_RV token_specific_aes_key_gen( CK_BYTE *key, CK_ULONG len ) { return rng_generate(key, len); } CK_RV token_specific_aes_ecb( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_ULONG key_len, CK_BYTE encrypt) { AES_KEY ssl_aes_key; int i; /* There's a previous check that in_data_len % AES_BLOCK_SIZE == 0, * so this is fine */ CK_ULONG loops = (CK_ULONG)(in_data_len/AES_BLOCK_SIZE); memset( &ssl_aes_key, 0, sizeof(AES_KEY)); // AES_ecb_encrypt encrypts only a single block, so we have to break up the // input data here if (encrypt) { AES_set_encrypt_key((unsigned char *)key_value, (key_len*8), &ssl_aes_key); for( i=0; iulValueLen > 256) || (prime_attr->ulValueLen < 64)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } dh = DH_new() ; if (dh == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Create and init BIGNUM structs to stick in the DH struct bn_p = BN_new(); bn_g = BN_new(); if (bn_g == NULL || bn_p == NULL) { if (bn_g) BN_free(bn_g); if (bn_p) BN_free(bn_p); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } BN_init(bn_p); BN_init(bn_g); // Convert from strings to BIGNUMs and stick them in the DH struct BN_bin2bn((char *)prime_attr->pValue, prime_attr->ulValueLen, bn_p); dh->p = bn_p; BN_bin2bn((char *)base_attr->pValue, base_attr->ulValueLen, bn_g); dh->g = bn_g; // Generate the DH Key if (!DH_generate_key(dh)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Extract the public and private key components from the DH struct, // and insert them in the publ_tmpl and priv_tmpl // // pub_key // //temp_bn = BN_new(); temp_bn = dh->pub_key; temp_bn_len = BN_num_bytes(temp_bn); temp_byte = malloc(temp_bn_len); temp_bn_len = BN_bn2bin(temp_bn, temp_byte); rc = build_attribute( CKA_VALUE, temp_byte, temp_bn_len, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( publ_tmpl, temp_attr ); free(temp_byte); // // priv_key // //temp_bn = BN_new(); temp_bn = dh->priv_key; temp_bn_len = BN_num_bytes(temp_bn); temp_byte = malloc(temp_bn_len); temp_bn_len = BN_bn2bin(temp_bn, temp_byte); rc = build_attribute( CKA_VALUE, temp_byte, temp_bn_len, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); free(temp_byte); // Update CKA_VALUE_BITS attribute in the private key value_bits_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); value_bits_attr->type = CKA_VALUE_BITS; value_bits_attr->ulValueLen = sizeof(CK_ULONG); value_bits_attr->pValue = (CK_BYTE *)value_bits_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_bits_attr->pValue = 8*temp_bn_len; template_update_attribute( priv_tmpl, value_bits_attr ); // Add prime and base to the private key template rc = build_attribute( CKA_PRIME,(char *)prime_attr->pValue, prime_attr->ulValueLen, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); rc = build_attribute( CKA_BASE,(char *)base_attr->pValue, base_attr->ulValueLen, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); // Cleanup DH key DH_free(dh) ; return CKR_OK ; } /* end token_specific_dh_key_pair_gen() */ MECH_LIST_ELEMENT mech_list[] = { { CKM_RSA_PKCS_KEY_PAIR_GEN, 512, 2048, CKF_HW | CKF_GENERATE_KEY_PAIR }, #if !(NODSA) { CKM_DSA_KEY_PAIR_GEN, 512, 1024, CKF_HW | CKF_GENERATE_KEY_PAIR }, #endif { CKM_DES_KEY_GEN, 8, 8, CKF_HW | CKF_GENERATE }, { CKM_DES3_KEY_GEN, 24, 24, CKF_HW | CKF_GENERATE }, #if !(NOCDMF) { CKM_CDMF_KEY_GEN, 0, 0, CKF_HW | CKF_GENERATE }, #endif { CKM_RSA_PKCS, 512, 2048, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP | CKF_SIGN | CKF_VERIFY | CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER }, #if !(NOX509) { CKM_RSA_X_509, 512, 2048, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP | CKF_SIGN | CKF_VERIFY | CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER }, #endif #if !(NOMD2) { CKM_MD2_RSA_PKCS, 512, 2048, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NOMD5) { CKM_MD5_RSA_PKCS, 512, 2048, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NOSHA1) { CKM_SHA1_RSA_PKCS, 512, 2048, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NODSA) { CKM_DSA, 512, 1024, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif /* Begin code contributed by Corrent corp. */ #if !(NODH) { CKM_DH_PKCS_DERIVE, 512, 2048, CKF_HW | CKF_DERIVE }, { CKM_DH_PKCS_KEY_PAIR_GEN, 512, 2048, CKF_HW | CKF_GENERATE_KEY_PAIR }, #endif /* End code contributed by Corrent corp. */ { CKM_DES_ECB, 8, 8, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_DES_CBC, 8, 8, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_DES_CBC_PAD, 8, 8, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, #if !(NOCDMF) { CKM_CDMF_ECB, 0, 0, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_CDMF_CBC, 0, 0, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, #endif { CKM_DES3_ECB, 24, 24, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_DES3_CBC, 24, 24, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_DES3_CBC_PAD, 24, 24, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, #if !(NOSHA1) { CKM_SHA_1, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_SHA_1_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SHA_1_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SHA256, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_SHA256_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SHA256_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NOMD2) { CKM_MD2, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_MD2_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_MD2_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NOMD5) { CKM_MD5, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_MD5_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_MD5_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif { CKM_SSL3_PRE_MASTER_KEY_GEN, 48, 48, CKF_HW | CKF_GENERATE }, { CKM_SSL3_MASTER_KEY_DERIVE, 48, 48, CKF_HW | CKF_DERIVE }, { CKM_SSL3_KEY_AND_MAC_DERIVE, 48, 48, CKF_HW | CKF_DERIVE }, { CKM_SSL3_MD5_MAC, 384, 384, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SSL3_SHA1_MAC, 384, 384, CKF_HW | CKF_SIGN | CKF_VERIFY }, #if !(NOAES) { CKM_AES_KEY_GEN, 16, 32, CKF_HW }, { CKM_AES_ECB, 16, 32, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_AES_CBC, 16, 32, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_AES_MAC, 16, 32, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_AES_MAC_GENERAL, 16, 32, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_AES_CBC_PAD, 16, 32, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, #endif #if !(NORIPE) { CKM_RIPEMD128, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_RIPEMD128_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_RIPEMD128_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_RIPEMD160, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_RIPEMD160_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_RIPEMD160_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif }; CK_ULONG mech_list_len = (sizeof(mech_list) / sizeof(MECH_LIST_ELEMENT)); CK_RV token_specific_get_mechanism_list(CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount) { int rc; /* common/mech_list.c */ rc = ock_generic_get_mechanism_list(pMechanismList, pulCount); return rc; } CK_RV token_specific_get_mechanism_info(CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo) { int rc; /* common/mech_list.c */ rc = ock_generic_get_mechanism_info(type, pInfo); return rc; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/aep_stdll/aepmalloc.h0000640000175000017500000000352411327631345021505 0ustar jfjf/* * Copyright (c) 1999-2002 AEP Systems Ltd. * Bray Business Park, Southern Cross Route, Bray, Co. Wicklow, Ireland. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of AEP Systems Ltd. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include #ifdef AEP_ALLOC_ON void AEP_free(void* handle); void *AEP_calloc(size_t nelem, size_t elsize); void *AEP_malloc(size_t size); #else #define AEP_malloc malloc #define AEP_calloc calloc #define AEP_free free #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/0000751000175000017500000000000011327631345017426 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/tpm_specific.c0000640000175000017500000025355411327631345022255 0ustar jfjf /* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */ /* * tpm_specific.c * * Feb 10, 2005 * * Author: Kent Yoder * * Encryption routines are based on ../soft_stdll/soft_specific.c. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef NODH #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include "pkcs11/pkcs11types.h" #include "pkcs11/stdll.h" #include "defs.h" #include "host_defs.h" #include "args.h" #include "h_extern.h" #include "tok_specific.h" #include "tok_spec_struct.h" #include "tok_struct.h" #include "tpm_specific.h" #include "../api/apiproto.h" TSS_RESULT util_set_public_modulus(TSS_HKEY, unsigned long, unsigned char *); CK_CHAR manuf[] = "IBM Corp."; CK_CHAR model[] = "TPM v1.1 Token"; CK_CHAR descr[] = "Token for the Trusted Platform Module"; CK_CHAR label[] = "IBM PKCS#11 TPM Token"; CK_BYTE master_key_private[MK_SIZE]; /* The context we'll use globally to connect to the TSP */ TSS_HCONTEXT tspContext = NULL_HCONTEXT; /* TSP key handles */ TSS_HKEY hSRK = NULL_HKEY; TSS_HKEY hPublicRootKey = NULL_HKEY; TSS_HKEY hPublicLeafKey = NULL_HKEY; TSS_HKEY hPrivateRootKey = NULL_HKEY; TSS_HKEY hPrivateLeafKey = NULL_HKEY; /* TSP policy handles */ TSS_HPOLICY hDefaultPolicy = NULL_HPOLICY; /* PKCS#11 key handles */ CK_OBJECT_HANDLE ckPublicRootKey = 0; CK_OBJECT_HANDLE ckPublicLeafKey = 0; CK_OBJECT_HANDLE ckPrivateRootKey = 0; CK_OBJECT_HANDLE ckPrivateLeafKey = 0; int not_initialized = 0; CK_BYTE current_user_pin_sha[SHA1_HASH_SIZE]; CK_BYTE current_so_pin_sha[SHA1_HASH_SIZE]; CK_RV token_specific_session(CK_SLOT_ID slotid) { return CKR_OK; } CK_RV token_rng(CK_BYTE *output, CK_ULONG bytes) { TSS_RESULT rc; TSS_HTPM hTPM; BYTE *random_bytes = NULL; if ((rc = Tspi_Context_GetTpmObject(tspContext, &hTPM))) { LogError("Tspi_Context_GetTpmObject: %x", rc); return CKR_FUNCTION_FAILED; } if ((rc = Tspi_TPM_GetRandom(hTPM, bytes, &random_bytes))) { LogError("Tspi_TPM_GetRandom failed. rc=0x%x", rc); return CKR_FUNCTION_FAILED; } memcpy(output, random_bytes, bytes); Tspi_Context_FreeMemory(tspContext, random_bytes); return CKR_OK; } int tok_slot2local(CK_SLOT_ID snum) { return 1; } CK_RV token_specific_init(char *Correlator, CK_SLOT_ID SlotNumber) { TSS_RESULT result; if ((result = Tspi_Context_Create(&tspContext))) { LogError("Tspi_Context_Create failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } if ((result = Tspi_Context_Connect(tspContext, NULL))) { LogError("Tspi_Context_Connect failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } if ((result = Tspi_Context_GetDefaultPolicy(tspContext, &hDefaultPolicy))) { LogError("Tspi_Context_GetDefaultPolicy failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } OpenSSL_add_all_algorithms(); return CKR_OK; } CK_RV token_find_key(int key_type, CK_OBJECT_CLASS class, CK_OBJECT_HANDLE *handle) { CK_BYTE *key_id = util_create_id(key_type); CK_RV rc = CKR_OK; CK_BBOOL true = TRUE; CK_ATTRIBUTE tmpl[] = { {CKA_ID, key_id, strlen((char *)key_id)}, {CKA_CLASS, &class, sizeof(class)}, {CKA_HIDDEN, &true, sizeof(CK_BBOOL)} }; CK_OBJECT_HANDLE hObj; CK_ULONG ulObjCount; SESSION dummy_sess; /* init the dummy session state to something that will find any object on * the token */ memset(&dummy_sess, 0, sizeof(SESSION)); dummy_sess.session_info.state = CKS_RO_USER_FUNCTIONS; if ((rc = object_mgr_find_init(&dummy_sess, tmpl, 3))) { goto done; } /* pulled from SC_FindObjects */ ulObjCount = MIN(1, (dummy_sess.find_count - dummy_sess.find_idx)); memcpy( &hObj, dummy_sess.find_list + dummy_sess.find_idx, ulObjCount * sizeof(CK_OBJECT_HANDLE) ); dummy_sess.find_idx += ulObjCount; if (ulObjCount > 1) { LogError1("More than one matching key found in the store!"); rc = CKR_KEY_NOT_FOUND; goto done; } else if (ulObjCount < 1) { LogError("key with ID=\"%s\" not found in the store!", key_id); rc = CKR_KEY_NOT_FOUND; goto done; } *handle = hObj; done: object_mgr_find_final(&dummy_sess); free(key_id); return rc; } CK_RV token_get_key_blob(CK_OBJECT_HANDLE ckKey, CK_ULONG *blob_size, CK_BYTE **ret_blob) { CK_RV rc = CKR_OK; CK_BYTE_PTR blob = NULL; CK_ATTRIBUTE tmpl[] = { {CKA_IBM_OPAQUE, NULL_PTR, 0} }; SESSION dummy_sess; /* set up dummy session */ memset(&dummy_sess, 0, sizeof(SESSION)); dummy_sess.session_info.state = CKS_RO_USER_FUNCTIONS; /* find object the first time to return the size of the buffer needed */ if ((rc = object_mgr_get_attribute_values(&dummy_sess, ckKey, tmpl, 1))) { LogError("object_mgr_get_attribute_values failed. rc=0x%lx", rc); goto done; } blob = malloc(tmpl[0].ulValueLen); if (blob == NULL) { LogError("malloc of %ld bytes failed.", tmpl[0].ulValueLen); rc = CKR_HOST_MEMORY; goto done; } tmpl[0].pValue = blob; /* find object the 2nd time to fill the buffer with data */ if ((rc = object_mgr_get_attribute_values(&dummy_sess, ckKey, tmpl, 1))) { LogError("object_mgr_get_attribute_values failed. rc=0x%lx", rc); goto done; } *ret_blob = blob; *blob_size = tmpl[0].ulValueLen; done: return rc; } CK_RV token_wrap_sw_key(int size_n, unsigned char *n, int size_p, unsigned char *p, TSS_HKEY hParentKey, TSS_FLAG initFlags, TSS_HKEY *phKey) { TSS_RESULT result; TSS_HPOLICY hPolicy; static TSS_BOOL get_srk_pub_key = TRUE; UINT32 key_size; key_size = util_get_keysize_flag(size_n * 8); if (initFlags == 0) { LogError("Invalid key size."); return CKR_FUNCTION_FAILED; } /* create the TSS key object */ result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_RSAKEY, TSS_KEY_MIGRATABLE | initFlags | key_size, phKey); if (result != TSS_SUCCESS) { LogError("Tspi_Context_CreateObject failed: rc=0x%x", result); return result; } result = util_set_public_modulus(*phKey, size_n, n); if (result != TSS_SUCCESS) { LogError("util_set_public_modulus failed: rc=0x%x", result); Tspi_Context_CloseObject(tspContext, *phKey); *phKey = NULL_HKEY; return result; } /* set the private key data in the TSS object */ result = Tspi_SetAttribData(*phKey, TSS_TSPATTRIB_KEY_BLOB, TSS_TSPATTRIB_KEYBLOB_PRIVATE_KEY, size_p, p); if (result != TSS_SUCCESS) { LogError("Tspi_SetAttribData failed: rc=0x%x", result); Tspi_Context_CloseObject(tspContext, *phKey); *phKey = NULL_HKEY; return result; } /* if the parent wrapping key is the SRK, we need to manually pull * out the SRK's pub key, which is not stored in persistent storage * for privacy reasons */ if (hParentKey == hSRK && get_srk_pub_key == TRUE) { UINT32 pubKeySize; BYTE *pubKey; result = Tspi_Key_GetPubKey(hParentKey, &pubKeySize, &pubKey); if (result != TSS_SUCCESS) { if (result == TPM_E_INVALID_KEYHANDLE) { LOG(LOG_WARNING, "Warning: Your TPM is not configured to allow " "reading the public SRK by anyone but the owner. Use " "tpm_restrictsrk -a to allow reading the public SRK"); } else { LogError("Tspi_Key_GetPubKey failed: rc=0x%x", result); } Tspi_Context_CloseObject(tspContext, *phKey); *phKey = NULL_HKEY; return result; } Tspi_Context_FreeMemory(tspContext, pubKey); get_srk_pub_key = FALSE; } result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_MIGRATION, &hPolicy); if (result != TSS_SUCCESS) { LogError("Tspi_Context_CreateObject: 0x%x", result); Tspi_Context_CloseObject(tspContext, *phKey); *phKey = NULL_HKEY; return result; } result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_NONE, 0, NULL); if (result != TSS_SUCCESS) { LogError("Tspi_Policy_SetSecret failed. rc=0x%x", result); Tspi_Context_CloseObject(tspContext, *phKey); Tspi_Context_CloseObject(tspContext, hPolicy); *phKey = NULL_HKEY; return result; } result = Tspi_Policy_AssignToObject(hPolicy, *phKey); if (result != TSS_SUCCESS) { LogError("Tspi_Policy_AssignToObject: 0x%x", result); Tspi_Context_CloseObject(tspContext, *phKey); Tspi_Context_CloseObject(tspContext, hPolicy); *phKey = NULL_HKEY; return result; } if (TPMTOK_TSS_KEY_TYPE(initFlags) == TSS_KEY_TYPE_LEGACY) { if ((result = Tspi_SetAttribUint32(*phKey, TSS_TSPATTRIB_KEY_INFO, TSS_TSPATTRIB_KEYINFO_ENCSCHEME, TSS_ES_RSAESPKCSV15))) { LogError("Tspi_SetAttribUint32 failed. rc=0x%x", result); Tspi_Context_CloseObject(tspContext, *phKey); Tspi_Context_CloseObject(tspContext, hPolicy); return result; } if ((result = Tspi_SetAttribUint32(*phKey, TSS_TSPATTRIB_KEY_INFO, TSS_TSPATTRIB_KEYINFO_SIGSCHEME, TSS_SS_RSASSAPKCS1V15_DER))) { LogError("Tspi_SetAttribUint32 failed. rc=0x%x", result); Tspi_Context_CloseObject(tspContext, *phKey); Tspi_Context_CloseObject(tspContext, hPolicy); return result; } } result = Tspi_Key_WrapKey(*phKey, hParentKey, NULL_HPCRS); if (result != TSS_SUCCESS) { LogError("Tspi_Key_WrapKey failed: rc=0x%x", result); Tspi_Context_CloseObject(tspContext, *phKey); *phKey = NULL_HKEY; } return result; } /* * Create a TPM key blob for an imported key. This function is only called when * a key is in active use, so any failure should trickle through. */ CK_RV token_wrap_key_object( CK_OBJECT_HANDLE ckObject, TSS_HKEY hParentKey, TSS_HKEY *phKey ) { CK_RV rc = CKR_OK; CK_ATTRIBUTE *attr = NULL, *new_attr, *prime_attr; CK_ULONG class, key_type, pub_exp; CK_BBOOL found; OBJECT *obj; TSS_RESULT result; TSS_FLAG initFlags = 0; BYTE *rgbBlob; UINT32 ulBlobLen; if ((rc = object_mgr_find_in_map1(ckObject, &obj))) { LogError("object_mgr_find_in_map1 failed. rc=0x%lx", rc); return rc; } /* if the object isn't a key, fail */ if ((found = template_attribute_find(obj->template, CKA_KEY_TYPE, &attr)) == FALSE) { LogError1("template_attribute_find(CKA_KEY_TYPE) failed."); return CKR_FUNCTION_FAILED; } key_type = *((CK_ULONG *)attr->pValue); if (key_type != CKK_RSA) { LogError("%s: Bad key type!", __FUNCTION__); return CKR_FUNCTION_FAILED; } if ((found = template_attribute_find(obj->template, CKA_CLASS, &attr)) == FALSE) { LogError1("template_attribute_find(CKA_CLASS) failed."); return CKR_FUNCTION_FAILED; } class = *((CK_ULONG *)attr->pValue); if (class == CKO_PRIVATE_KEY) { /* In order to create a full TSS key blob using a PKCS#11 private key * object, we need one of the two primes, the modulus and the private * exponent and we need the public exponent to be correct */ /* check the least likely attribute to exist first, the primes */ if ((found = template_attribute_find(obj->template, CKA_PRIME_1, &prime_attr)) == FALSE) { if ((found = template_attribute_find(obj->template, CKA_PRIME_2, &prime_attr)) == FALSE) { LogError1("Couldn't find prime1 or prime2 of key object to wrap"); return CKR_TEMPLATE_INCONSISTENT; } } /* Make sure the public exponent is usable */ if ((util_check_public_exponent(obj->template))) { LogError("Invalid public exponent"); return CKR_TEMPLATE_INCONSISTENT; } /* get the modulus */ if ((found = template_attribute_find(obj->template, CKA_MODULUS, &attr)) == FALSE) { LogError1("Couldn't find a required attribute of key object"); return CKR_FUNCTION_FAILED; } /* make sure the key size is usable */ initFlags = util_get_keysize_flag(attr->ulValueLen * 8); if (initFlags == 0) { LogError("Invalid key size."); return CKR_TEMPLATE_INCONSISTENT; } /* generate the software based key */ if ((rc = token_wrap_sw_key((int)attr->ulValueLen, attr->pValue, (int)prime_attr->ulValueLen, prime_attr->pValue, hParentKey, TSS_KEY_TYPE_LEGACY | TSS_KEY_NO_AUTHORIZATION, phKey))) { LogError("token_wrap_sw_key failed. rc=0x%lu", rc); return rc; } } else if (class == CKO_PUBLIC_KEY) { /* Make sure the public exponent is usable */ if ((util_check_public_exponent(obj->template))) { LogError("Invalid public exponent"); return CKR_TEMPLATE_INCONSISTENT; } /* grab the modulus to put into the TSS key object */ if ((found = template_attribute_find(obj->template, CKA_MODULUS, &attr)) == FALSE) { LogError1("Couldn't find a required attribute of key object"); return CKR_TEMPLATE_INCONSISTENT; } /* make sure the key size is usable */ initFlags = util_get_keysize_flag(attr->ulValueLen * 8); if (initFlags == 0) { LogError("Invalid key size."); return CKR_TEMPLATE_INCONSISTENT; } initFlags |= TSS_KEY_TYPE_LEGACY | TSS_KEY_MIGRATABLE | TSS_KEY_NO_AUTHORIZATION; if ((result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_RSAKEY, initFlags, phKey))) { LogError("Tspi_Context_CreateObject failed. rc=0x%x", result); return result; } if ((result = util_set_public_modulus(*phKey, attr->ulValueLen, attr->pValue))) { LogError("util_set_public_modulus failed: 0x%x", result); Tspi_Context_CloseObject(tspContext, *phKey); *phKey = NULL_HKEY; return CKR_FUNCTION_FAILED; } } else { LogError("%s: Bad key class!", __FUNCTION__); return CKR_FUNCTION_FAILED; } /* grab the entire key blob to put into the PKCS#11 object */ if ((result = Tspi_GetAttribData(*phKey, TSS_TSPATTRIB_KEY_BLOB, TSS_TSPATTRIB_KEYBLOB_BLOB, &ulBlobLen, &rgbBlob))) { LogError("Tspi_GetAttribData failed with rc: 0x%x", result); return CKR_FUNCTION_FAILED; } /* insert the key blob into the object */ if ((rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob, ulBlobLen, &new_attr))) { st_err_log(84, __FILE__, __LINE__); Tspi_Context_FreeMemory(tspContext, rgbBlob); return rc; } template_update_attribute( obj->template, new_attr ); Tspi_Context_FreeMemory(tspContext, rgbBlob); /* if this is a token object, save it with the new attribute so that we * don't have to go down this path again */ if (!object_is_session_object(obj)) { rc = save_token_object(obj); } return rc; } /* * load a key in the TSS hierarchy from its CK_OBJECT_HANDLE */ CK_RV token_load_key(CK_OBJECT_HANDLE ckKey, TSS_HKEY hParentKey, CK_CHAR_PTR passHash, TSS_HKEY *phKey) { TSS_RESULT result; TSS_HPOLICY hPolicy; CK_BYTE *blob = NULL; CK_ULONG ulBlobSize = 0; CK_RV rc; if ((rc = token_get_key_blob(ckKey, &ulBlobSize, &blob))) { if (rc != CKR_ATTRIBUTE_TYPE_INVALID) { LogError("token_get_key_blob failed. rc=0x%lx", rc); return rc; } /* the key blob wasn't found, so check for a modulus * to load */ LogError1("key blob not found, checking for modulus"); if ((rc = token_wrap_key_object(ckKey, hParentKey, phKey))) { LogError("token_wrap_key_object failed. rc=0x%lx", rc); return rc; } } if (blob != NULL) { /* load the key inside the TSS */ if ((result = Tspi_Context_LoadKeyByBlob(tspContext, hParentKey, ulBlobSize, blob, phKey))) { LogError("Tspi_Context_LoadKeyByBlob: 0x%x", result); goto done; } } #if 0 if ((result = Tspi_GetPolicyObject(*phKey, TSS_POLICY_USAGE, &hPolicy))) { LogError("Tspi_GetPolicyObject: 0x%x", result); goto done; } #else if ((result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hPolicy))) { LogError("Tspi_Context_CreateObject: 0x%x", result); goto done; } #endif if (passHash == NULL) { result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_NONE, 0, NULL); } else { result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1, SHA1_HASH_SIZE, passHash); } if (result != TSS_SUCCESS) { LogError("Tspi_Policy_SetSecret: 0x%x", result); goto done; } if ((result = Tspi_Policy_AssignToObject(hPolicy, *phKey))) { LogError("Tspi_Policy_AssignToObject: 0x%x", result); goto done; } done: free(blob); return result; } TSS_RESULT token_load_srk() { TSS_HPOLICY hPolicy; TSS_RESULT result; TSS_UUID SRK_UUID = TSS_UUID_SRK; if (hSRK != NULL_HKEY) return TSS_SUCCESS; /* load the SRK */ if ((result = Tspi_Context_LoadKeyByUUID(tspContext, TSS_PS_TYPE_SYSTEM, SRK_UUID, &hSRK))) { LogError("Tspi_Context_LoadKeyByUUID failed. rc=0x%x", result); goto done; } #if 0 if ((result = Tspi_GetPolicyObject(hSRK, TSS_POLICY_USAGE, &hPolicy))) { LogError("Tspi_GetPolicyObject failed. rc=0x%x", result); goto done; } #else if ((result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hPolicy))) { LogError("Tspi_Context_CreateObject failed. rc=0x%x", result); goto done; } if ((result = Tspi_Policy_AssignToObject(hPolicy, hSRK))) { LogError("Tspi_Policy_AssignToObject failed. rc=0x%x", result); goto done; } #endif if ((result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_PLAIN, 0, NULL))) { LogError("Tspi_Policy_SetSecret failed. rc=0x%x", result); } done: return result; } TSS_RESULT token_load_public_root_key() { TSS_RESULT result; BYTE *blob; CK_ULONG blob_size; if (hPublicRootKey != NULL_HKEY) return TSS_SUCCESS; if ((result = token_load_srk())) { LogError("token_load_srk failed. rc=0x%x", result); return result; } if ((result = token_find_key(TPMTOK_PUBLIC_ROOT_KEY, CKO_PRIVATE_KEY, &ckPublicRootKey))) { LogError("token_find_key failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } if ((result = token_get_key_blob(ckPublicRootKey, &blob_size, &blob))) { LogError("token_get_key_blob failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } /* load the Public Root Key */ if ((result = Tspi_Context_LoadKeyByBlob(tspContext, hSRK, blob_size, blob, &hPublicRootKey))) { LogError("Tspi_Context_LoadKeyByBlob failed. rc=0x%x", result); free(blob); return CKR_FUNCTION_FAILED; } free(blob); return result; } TSS_RESULT tss_generate_key(TSS_FLAG initFlags, BYTE *passHash, TSS_HKEY hParentKey, TSS_HKEY *phKey) { TSS_RESULT result; TSS_HPOLICY hPolicy, hMigPolicy; if ((result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_RSAKEY, initFlags, phKey))) { LogError("Tspi_Context_CreateObject failed. rc=0x%x", result); return result; } #if 0 if ((result = Tspi_GetPolicyObject(*phKey, TSS_POLICY_USAGE, &hPolicy))) { LogError("Tspi_GetPolicyObject failed. rc=0x%x", result); Tspi_Context_CloseObject(tspContext, *phKey); return result; } #else if ((result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hPolicy))) { LogError("Tspi_Context_CreateObject: 0x%x", result); Tspi_Context_CloseObject(tspContext, *phKey); return result; } #endif if (passHash == NULL) { result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_NONE, 0, NULL); } else { result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1, 20, passHash); } if (result != TSS_SUCCESS) { LogError("Tspi_Policy_SetSecret failed. rc=0x%x", result); Tspi_Context_CloseObject(tspContext, *phKey); Tspi_Context_CloseObject(tspContext, hPolicy); return result; } if ((result = Tspi_Policy_AssignToObject(hPolicy, *phKey))) { LogError("Tspi_Policy_AssignToObject: 0x%x", result); Tspi_Context_CloseObject(tspContext, *phKey); Tspi_Context_CloseObject(tspContext, hPolicy); return result; } if (TPMTOK_TSS_KEY_MIG_TYPE(initFlags) == TSS_KEY_MIGRATABLE) { if ((result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_MIGRATION, &hMigPolicy))) { LogError("Tspi_Context_CreateObject: 0x%x", result); Tspi_Context_CloseObject(tspContext, *phKey); Tspi_Context_CloseObject(tspContext, hPolicy); return result; } if (passHash == NULL) { result = Tspi_Policy_SetSecret(hMigPolicy, TSS_SECRET_MODE_NONE, 0, NULL); } else { result = Tspi_Policy_SetSecret(hMigPolicy, TSS_SECRET_MODE_SHA1, 20, passHash); } if (result != TSS_SUCCESS) { LogError("Tspi_Policy_SetSecret failed. rc=0x%x", result); Tspi_Context_CloseObject(tspContext, *phKey); Tspi_Context_CloseObject(tspContext, hPolicy); Tspi_Context_CloseObject(tspContext, hMigPolicy); return result; } if ((result = Tspi_Policy_AssignToObject(hMigPolicy, *phKey))) { LogError("Tspi_Policy_AssignToObject: 0x%x", result); Tspi_Context_CloseObject(tspContext, *phKey); Tspi_Context_CloseObject(tspContext, hPolicy); Tspi_Context_CloseObject(tspContext, hMigPolicy); return result; } } if (TPMTOK_TSS_KEY_TYPE(initFlags) == TSS_KEY_TYPE_LEGACY) { if ((result = Tspi_SetAttribUint32(*phKey, TSS_TSPATTRIB_KEY_INFO, TSS_TSPATTRIB_KEYINFO_ENCSCHEME, TSS_ES_RSAESPKCSV15))) { LogError("Tspi_SetAttribUint32 failed. rc=0x%x", result); Tspi_Context_CloseObject(tspContext, *phKey); Tspi_Context_CloseObject(tspContext, hPolicy); Tspi_Context_CloseObject(tspContext, hMigPolicy); return result; } if ((result = Tspi_SetAttribUint32(*phKey, TSS_TSPATTRIB_KEY_INFO, TSS_TSPATTRIB_KEYINFO_SIGSCHEME, TSS_SS_RSASSAPKCS1V15_DER))) { LogError("Tspi_SetAttribUint32 failed. rc=0x%x", result); Tspi_Context_CloseObject(tspContext, *phKey); Tspi_Context_CloseObject(tspContext, hPolicy); Tspi_Context_CloseObject(tspContext, hMigPolicy); return result; } } if ((result = Tspi_Key_CreateKey(*phKey, hParentKey, 0))) { LogError("Tspi_Key_CreateKey failed with rc: 0x%x", result); Tspi_Context_CloseObject(tspContext, *phKey); Tspi_Context_CloseObject(tspContext, hPolicy); Tspi_Context_CloseObject(tspContext, hMigPolicy); } return result; } TSS_RESULT tss_change_auth(TSS_HKEY hObjectToChange, TSS_HKEY hParentObject, CK_CHAR *passHash) { TSS_RESULT result; TSS_HPOLICY hPolicy; if ((result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hPolicy))) { LogError("Tspi_Context_CreateObject failed: 0x%x", result); return result; } if ((result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1, SHA1_HASH_SIZE, passHash))) { LogError("Tspi_Policy_SetSecret failed: 0x%x", result); return result; } if ((result = Tspi_ChangeAuth(hObjectToChange, hParentObject, hPolicy))) { LogError("Tspi_ChangeAuth failed: 0x%x", result); } return result; } CK_RV token_store_priv_key(TSS_HKEY hKey, int key_type, CK_OBJECT_HANDLE *ckKey) { CK_ATTRIBUTE *new_attr = NULL; OBJECT *priv_key_obj = NULL; BYTE *rgbBlob = NULL, *rgbPrivBlob = NULL; UINT32 ulBlobLen = 0, ulPrivBlobLen = 0; CK_BBOOL flag; CK_BYTE *key_id = util_create_id(key_type); CK_RV rc; SESSION dummy_sess; /* set up dummy session */ memset(&dummy_sess, 0, sizeof(SESSION)); dummy_sess.session_info.state = CKS_RW_USER_FUNCTIONS; /* grab the entire key blob to put into the PKCS#11 private key object */ if ((rc = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB, TSS_TSPATTRIB_KEYBLOB_BLOB, &ulBlobLen, &rgbBlob))) { LogError("Tspi_GetAttribData failed with rc: 0x%lx", rc); free(key_id); return rc; } /* grab the encrypted provate key to put into the object */ if ((rc = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB, TSS_TSPATTRIB_KEYBLOB_PRIVATE_KEY, &ulPrivBlobLen, &rgbPrivBlob))) { LogError("Tspi_GetAttribData failed with rc: 0x%lx", rc); Tspi_Context_FreeMemory(tspContext, rgbBlob); free(key_id); return rc; } /* create skeleton for the private key object */ if ((rc = object_create_skel(NULL, 0, MODE_KEYGEN, CKO_PRIVATE_KEY, CKK_RSA, &priv_key_obj))) { LogError("objectr_create_skel: 0x%lx", rc); Tspi_Context_FreeMemory(tspContext, rgbBlob); Tspi_Context_FreeMemory(tspContext, rgbPrivBlob); free(key_id); return rc; } /* add the ID attribute */ if ((rc = build_attribute(CKA_ID, key_id, strlen((char *)key_id), &new_attr))) { st_err_log(84, __FILE__, __LINE__); Tspi_Context_FreeMemory(tspContext, rgbBlob); Tspi_Context_FreeMemory(tspContext, rgbPrivBlob); free(key_id); return rc; } template_update_attribute( priv_key_obj->template, new_attr ); free(key_id); /* add the key blob to the PKCS#11 object template */ if ((rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob, ulBlobLen, &new_attr))) { st_err_log(84, __FILE__, __LINE__); Tspi_Context_FreeMemory(tspContext, rgbBlob); Tspi_Context_FreeMemory(tspContext, rgbPrivBlob); return rc; } template_update_attribute( priv_key_obj->template, new_attr ); Tspi_Context_FreeMemory(tspContext, rgbBlob); /* add the private key blob to the PKCS#11 object template */ if ((rc = build_attribute(CKA_MODULUS, rgbPrivBlob, ulPrivBlobLen, &new_attr))) { st_err_log(84, __FILE__, __LINE__); Tspi_Context_FreeMemory(tspContext, rgbPrivBlob); return rc; } template_update_attribute( priv_key_obj->template, new_attr ); Tspi_Context_FreeMemory(tspContext, rgbPrivBlob); /* add the HIDDEN attribute */ flag = TRUE; if ((rc = build_attribute(CKA_HIDDEN, &flag, sizeof(CK_BBOOL), &new_attr))) { st_err_log(84, __FILE__, __LINE__); free(key_id); return rc; } template_update_attribute( priv_key_obj->template, new_attr ); /* set CKA_ALWAYS_SENSITIVE to true */ if ((rc = build_attribute( CKA_ALWAYS_SENSITIVE, &flag, sizeof(CK_BBOOL), &new_attr ))) { st_err_log(84, __FILE__, __LINE__); return rc; } template_update_attribute( priv_key_obj->template, new_attr ); /* set CKA_NEVER_EXTRACTABLE to true */ if ((rc = build_attribute( CKA_NEVER_EXTRACTABLE, &flag, sizeof(CK_BBOOL), &new_attr ))) { st_err_log(84, __FILE__, __LINE__); return rc; } template_update_attribute( priv_key_obj->template, new_attr ); /* make the object reside on the token, as if that were possible */ if ((rc = build_attribute( CKA_TOKEN, &flag, sizeof(CK_BBOOL), &new_attr ))) { st_err_log(84, __FILE__, __LINE__); return rc; } template_update_attribute( priv_key_obj->template, new_attr ); flag = FALSE; if ((rc = build_attribute( CKA_PRIVATE, &flag, sizeof(CK_BBOOL), &new_attr ))) { st_err_log(84, __FILE__, __LINE__); return rc; } template_update_attribute( priv_key_obj->template, new_attr ); if ((rc = object_mgr_create_final(&dummy_sess, priv_key_obj, ckKey))) { st_err_log(90, __FILE__, __LINE__); } return rc; } CK_RV token_store_pub_key(TSS_HKEY hKey, int key_type, CK_OBJECT_HANDLE *ckKey) { CK_RV rc; TSS_RESULT result; CK_ATTRIBUTE *new_attr = NULL; OBJECT *pub_key_obj; CK_BBOOL flag = TRUE; CK_OBJECT_CLASS pub_class = CKO_PUBLIC_KEY; CK_KEY_TYPE type = CKK_RSA; CK_BYTE *key_id = util_create_id(key_type); CK_BYTE pub_exp[] = { 0x1, 0x0, 0x1 }; // 65537 CK_ATTRIBUTE pub_tmpl[] = { {CKA_CLASS, &pub_class, sizeof(pub_class)}, {CKA_KEY_TYPE, &type, sizeof(type)}, {CKA_ID, key_id, strlen((char *)key_id)}, {CKA_PUBLIC_EXPONENT, pub_exp, sizeof(pub_exp)}, {CKA_MODULUS, NULL_PTR, 0} }; BYTE *rgbPubBlob = NULL; UINT32 ulBlobLen = 0; SESSION dummy_sess; /* set up dummy session */ memset(&dummy_sess, 0, sizeof(SESSION)); dummy_sess.session_info.state = CKS_RW_USER_FUNCTIONS; /* grab the public key to put into the PKCS#11 public key object */ if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO, TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &ulBlobLen, &rgbPubBlob))) { LogError("Tspi_GetAttribData failed with rc: 0x%x", result); Tspi_Context_CloseObject(tspContext, hKey); free(key_id); return result; } pub_tmpl[4].pValue = rgbPubBlob; pub_tmpl[4].ulValueLen = ulBlobLen; /* create skeleton for the private key object */ if ((rc = object_create_skel(pub_tmpl, 5, MODE_CREATE, CKO_PUBLIC_KEY, CKK_RSA, &pub_key_obj))) { LogError("object_create_skel: 0x%lx", rc); Tspi_Context_CloseObject(tspContext, hKey); free(key_id); return rc; } Tspi_Context_FreeMemory(tspContext, rgbPubBlob); /* make the object reside on the token, as if that were possible */ if ((rc = build_attribute( CKA_TOKEN, &flag, sizeof(CK_BBOOL), &new_attr ))) { st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( pub_key_obj->template, new_attr ); /* set the object to be hidden */ if ((rc = build_attribute( CKA_HIDDEN, &flag, sizeof(CK_BBOOL), &new_attr ))) { st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( pub_key_obj->template, new_attr ); if ((rc = object_mgr_create_final(&dummy_sess, pub_key_obj, ckKey))) { st_err_log(90, __FILE__, __LINE__); goto done; } done: return rc; } CK_RV token_update_private_key(TSS_HKEY hKey, int key_type) { CK_OBJECT_HANDLE ckHandle; CK_RV rc; SESSION dummy_sess; /* set up dummy session */ memset(&dummy_sess, 0, sizeof(SESSION)); dummy_sess.session_info.state = CKS_RW_USER_FUNCTIONS; /* find the private key portion of the key */ if ((rc = token_find_key(key_type, CKO_PRIVATE_KEY, &ckHandle))) { LogError("token_find_key failed: 0x%lx", rc); return rc; } /* destroy the private key and create a new one */ if ((rc = object_mgr_destroy_object(&dummy_sess, ckHandle))) { LogError("object_mgr_destroy_object failed: 0x%lx", rc); return rc; } if ((rc = token_store_priv_key(hKey, key_type, &ckHandle))) { LogError("token_store_priv_key failed: 0x%lx", rc); } return rc; } CK_RV token_store_tss_key(TSS_HKEY hKey, int key_type, CK_OBJECT_HANDLE *ckKey) { CK_RV rc; /* create a PKCS#11 pub key object for the key */ if ((rc = token_store_pub_key(hKey, key_type, ckKey))) { LogError("token_store_pub_key failed. rc=0x%lx", rc); return rc; } /* create a PKCS#11 private key object for the key */ if ((rc = token_store_priv_key(hKey, key_type, ckKey))) { LogError("token_store_priv_key failed. rc=0x%lx", rc); } return rc; } CK_RV token_generate_leaf_key(int key_type, CK_CHAR_PTR passHash, TSS_HKEY *phKey) { CK_RV rc = CKR_FUNCTION_FAILED; TSS_RESULT result; TSS_HKEY hParentKey; CK_OBJECT_HANDLE *ckKey; TSS_FLAG initFlags = TSS_KEY_MIGRATABLE | TSS_KEY_TYPE_BIND | TSS_KEY_SIZE_2048 | TSS_KEY_AUTHORIZATION; switch (key_type) { case TPMTOK_PUBLIC_LEAF_KEY: hParentKey = hPublicRootKey; ckKey = &ckPublicRootKey; break; case TPMTOK_PRIVATE_LEAF_KEY: hParentKey = hPrivateRootKey; ckKey = &ckPrivateRootKey; break; default: LogError1("Oh NO"); goto done; break; } if ((result = tss_generate_key(initFlags, passHash, hParentKey, phKey))) { LogError("tss_generate_key returned 0x%x", result); return result; } if ((rc = token_store_tss_key(*phKey, key_type, ckKey))) { LogError("token_store_tss_key failed. rc=0x%x", result); } done: return rc; } CK_RV token_verify_pin(TSS_HKEY hKey) { TSS_HENCDATA hEncData; UINT32 ulUnboundDataLen; BYTE *rgbUnboundData; char *rgbData = "CRAPPENFEST"; TSS_RESULT result; CK_RV rc = CKR_FUNCTION_FAILED; if ((result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) { LogError("Tspi_Context_CreateObject failed. rc=0x%x", result); goto done; } if ((result = Tspi_Data_Bind(hEncData, hKey, strlen(rgbData), (BYTE *)rgbData))) { LogError("%s: Bind returned 0x%x", __FUNCTION__, result); goto done; } /* unbind the junk data to test the key's auth data */ result = Tspi_Data_Unbind(hEncData, hKey, &ulUnboundDataLen, &rgbUnboundData); if (result == TCPA_E_AUTHFAIL) { rc = CKR_PIN_INCORRECT; LogError("%s: Unbind returned TCPA_AUTHFAIL", __FUNCTION__); goto done; } else if (result != TSS_SUCCESS) { LogError("%s: Unbind returned 0x%x", __FUNCTION__, result); goto done; } rc = memcmp(rgbUnboundData, rgbData, ulUnboundDataLen); Tspi_Context_FreeMemory(tspContext, rgbUnboundData); done: Tspi_Context_CloseObject(tspContext, hEncData); return rc; } CK_RV token_create_private_tree(CK_BYTE *pinHash, CK_BYTE *pPin) { CK_RV rc; TSS_RESULT result; RSA *rsa; unsigned int size_n, size_p; unsigned char n[256], p[256]; /* all sw generated keys are 2048 bits */ if ((rsa = openssl_gen_key()) == NULL) return CKR_HOST_MEMORY; if (openssl_get_modulus_and_prime(rsa, &size_n, n, &size_p, p) != 0) { LogError1("openssl_get_modulus_and_prime failed"); return CKR_FUNCTION_FAILED; } /* generate the software based user base key */ if ((rc = token_wrap_sw_key(size_n, n, size_p, p, hSRK, TSS_KEY_NO_AUTHORIZATION | TSS_KEY_TYPE_STORAGE, &hPrivateRootKey))) { LogError("token_wrap_sw_key failed. rc=0x%lu", rc); return rc; } if (openssl_write_key(rsa, TPMTOK_PRIV_ROOT_KEY_FILE, pPin)) { LogError1("openssl_write_key"); RSA_free(rsa); return CKR_FUNCTION_FAILED; } RSA_free(rsa); /* store the user base key in a PKCS#11 object internally */ if ((rc = token_store_tss_key(hPrivateRootKey, TPMTOK_PRIVATE_ROOT_KEY, &ckPrivateRootKey))) { LogError("token_store_tss_key failed. rc=0x%lx", rc); return rc; } if ((result = Tspi_Key_LoadKey(hPrivateRootKey, hSRK))) { LogError("Tspi_Key_LoadKey: 0x%x", result); Tspi_Context_CloseObject(tspContext, hPrivateRootKey); hPrivateRootKey = NULL_HKEY; return CKR_FUNCTION_FAILED; } /* generate the private leaf key */ if ((rc = token_generate_leaf_key(TPMTOK_PRIVATE_LEAF_KEY, pinHash, &hPrivateLeafKey))) { LogError("token_generate_leaf_key failed. rc=0x%lx", rc); return rc; } if ((result = Tspi_Key_LoadKey(hPrivateLeafKey, hPrivateRootKey))) { LogError("Tspi_Key_LoadKey: 0x%x", result); Tspi_Context_CloseObject(tspContext, hPrivateRootKey); hPrivateRootKey = NULL_HKEY; Tspi_Context_CloseObject(tspContext, hPrivateLeafKey); hPrivateRootKey = NULL_HKEY; return CKR_FUNCTION_FAILED; } return rc; } CK_RV token_create_public_tree(CK_BYTE *pinHash, CK_BYTE *pPin) { CK_RV rc; TSS_RESULT result; RSA *rsa; unsigned int size_n, size_p; unsigned char n[256], p[256]; /* all sw generated keys are 2048 bits */ if ((rsa = openssl_gen_key()) == NULL) return CKR_HOST_MEMORY; if (openssl_get_modulus_and_prime(rsa, &size_n, n, &size_p, p) != 0) { LogError1("openssl_get_modulus_and_prime failed"); return CKR_FUNCTION_FAILED; } /* create the public root key */ if ((rc = token_wrap_sw_key(size_n, n, size_p, p, hSRK, TSS_KEY_NO_AUTHORIZATION | TSS_KEY_TYPE_STORAGE, &hPublicRootKey))) { LogError("token_wrap_sw_key failed. rc=0x%lx", rc); return rc; } if (openssl_write_key(rsa, TPMTOK_PUB_ROOT_KEY_FILE, pPin)) { LogError1("openssl_write_key"); RSA_free(rsa); return CKR_FUNCTION_FAILED; } RSA_free(rsa); if ((result = Tspi_Key_LoadKey(hPublicRootKey, hSRK))) { LogError("Tspi_Key_LoadKey: 0x%x", result); Tspi_Context_CloseObject(tspContext, hPublicRootKey); hPublicRootKey = NULL_HKEY; return CKR_FUNCTION_FAILED; } if ((rc = token_store_tss_key(hPublicRootKey, TPMTOK_PUBLIC_ROOT_KEY, &ckPublicRootKey))) { LogError("token_store_tss_key failed. rc=0x%lx", rc); return rc; } /* create the SO's leaf key */ if ((rc = token_generate_leaf_key(TPMTOK_PUBLIC_LEAF_KEY, pinHash, &hPublicLeafKey))) { LogError("token_generate_leaf_key failed. rc=0x%lx", rc); return rc; } if ((result = Tspi_Key_LoadKey(hPublicLeafKey, hPublicRootKey))) { LogError("Tspi_Key_LoadKey: 0x%x", result); Tspi_Context_CloseObject(tspContext, hPublicRootKey); hPublicRootKey = NULL_HKEY; Tspi_Context_CloseObject(tspContext, hPublicLeafKey); hPublicLeafKey = NULL_HKEY; return CKR_FUNCTION_FAILED; } return rc; } CK_RV token_migrate(int key_type, CK_BYTE *pin) { RSA *rsa; char *backup_loc; unsigned int size_n, size_p; unsigned char n[256], p[256]; TSS_RESULT result; TSS_HKEY *phKey; CK_RV rc; CK_OBJECT_HANDLE *ckHandle; SESSION dummy_sess; /* set up dummy session */ memset(&dummy_sess, 0, sizeof(SESSION)); dummy_sess.session_info.state = CKS_RW_USER_FUNCTIONS; if (key_type == TPMTOK_PUBLIC_ROOT_KEY) { backup_loc = TPMTOK_PUB_ROOT_KEY_FILE; phKey = &hPublicRootKey; ckHandle = &ckPublicRootKey; } else if (key_type == TPMTOK_PRIVATE_ROOT_KEY) { backup_loc = TPMTOK_PRIV_ROOT_KEY_FILE; phKey = &hPrivateRootKey; ckHandle = &ckPrivateRootKey; } else { LogError1("Invalid key type."); return CKR_FUNCTION_FAILED; } /* read the backup key with the old pin */ if ((rc = openssl_read_key(backup_loc, pin, &rsa))) { LogError1("openssl_read_key failed"); return rc; } /* So, reading the backup openssl key off disk succeeded with the SOs PIN. * We will now try to re-wrap that key with the current SRK */ if (openssl_get_modulus_and_prime(rsa, &size_n, n, &size_p, p) != 0) { LogError1("openssl_get_modulus_and_prime failed"); return CKR_FUNCTION_FAILED; } if ((rc = token_wrap_sw_key(size_n, n, size_p, p, hSRK, TSS_KEY_TYPE_STORAGE | TSS_KEY_NO_AUTHORIZATION, phKey))) { LogError("token_wrap_sw_key failed. rc=0x%lx", rc); RSA_free(rsa); return rc; } RSA_free(rsa); if ((result = Tspi_Key_LoadKey(*phKey, hSRK))) { LogError("Tspi_Key_LoadKey: 0x%x", result); Tspi_Context_CloseObject(tspContext, *phKey); *phKey = NULL_HKEY; return CKR_FUNCTION_FAILED; } /* Loading succeeded, so we need to get rid of the old PKCS#11 objects * and store them anew. */ if ((rc = token_find_key(key_type, CKO_PUBLIC_KEY, ckHandle))) { LogError("token_find_key failed. rc=0x%lx", rc); return CKR_FUNCTION_FAILED; } if ((rc = object_mgr_destroy_object(&dummy_sess, *ckHandle))) { LogError("object_mgr_destroy_object failed: 0x%lx", rc); return rc; } if ((rc = token_find_key(key_type, CKO_PRIVATE_KEY, ckHandle))) { LogError("token_find_key failed. rc=0x%lx", rc); return CKR_FUNCTION_FAILED; } if ((rc = object_mgr_destroy_object(&dummy_sess, *ckHandle))) { LogError("object_mgr_destroy_object failed: 0x%lx", rc); return rc; } if ((rc = token_store_tss_key(*phKey, key_type, ckHandle))) { LogError("token_store_tss_key failed: 0x%lx", rc); return rc; } return CKR_OK; } CK_RV save_masterkey_private() { char fname[PATH_MAX]; struct stat file_stat; int err; FILE *fp = NULL; struct passwd *pw = NULL; TSS_RESULT result; TSS_HENCDATA hEncData; BYTE *encrypted_masterkey; UINT32 encrypted_masterkey_size; if ((pw = getpwuid(getuid())) == NULL) { LogError("getpwuid failed: %s", strerror(errno)); return CKR_FUNCTION_FAILED; } //fp = fopen("/etc/pkcs11/tpm/MK_PRIVATE", "r"); sprintf((char *)fname,"%s/%s/%s", pk_dir, pw->pw_name, TPMTOK_MASTERKEY_PRIVATE); /* if file exists, assume its been written correctly before */ if ((err = stat(fname, &file_stat)) == 0) { return CKR_OK; } else if (errno != ENOENT) { /* some error other than file doesn't exist */ return CKR_FUNCTION_FAILED; } /* encrypt the private masterkey using the private leaf key */ if ((result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) { LogError("Tspi_Context_CreateObject failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } if ((result = Tspi_Data_Bind(hEncData, hPrivateLeafKey, MK_SIZE, master_key_private))) { LogError("Tspi_Data_Bind failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } if ((result = Tspi_GetAttribData(hEncData, TSS_TSPATTRIB_ENCDATA_BLOB, TSS_TSPATTRIB_ENCDATABLOB_BLOB, &encrypted_masterkey_size, &encrypted_masterkey))) { LogError("Tspi_GetAttribData failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } if (encrypted_masterkey_size > 256) { Tspi_Context_FreeMemory(tspContext, encrypted_masterkey); return CKR_DATA_LEN_RANGE; } /* write the encrypted key to disk */ if ((fp = fopen((char *)fname, "w")) == NULL) { LogError("Error opening %s for write: %s", fname, strerror(errno)); Tspi_Context_FreeMemory(tspContext, encrypted_masterkey); return CKR_FUNCTION_FAILED; } if ((err = fwrite(encrypted_masterkey, encrypted_masterkey_size, 1, fp)) == 0) { LogError("Error writing %s: %s", fname, strerror(errno)); Tspi_Context_FreeMemory(tspContext, encrypted_masterkey); fclose(fp); return CKR_FUNCTION_FAILED; } Tspi_Context_FreeMemory(tspContext, encrypted_masterkey); fclose(fp); return CKR_OK; } CK_RV load_masterkey_private() { FILE *fp = NULL; int err; struct stat file_stat; CK_BYTE encrypted_masterkey[256]; char fname[PATH_MAX]; CK_RV rc; struct passwd *pw = NULL; TSS_RESULT result; TSS_HENCDATA hEncData; BYTE *masterkey; UINT32 masterkey_size, encrypted_masterkey_size = 256; if ((pw = getpwuid(getuid())) == NULL) { LogError("getpwuid failed: %s", strerror(errno)); return CKR_FUNCTION_FAILED; } sprintf((char *)fname,"%s/%s/%s", pk_dir, pw->pw_name, TPMTOK_MASTERKEY_PRIVATE); /* if file exists, check its size */ if ((err = stat(fname, &file_stat)) == 0) { if (file_stat.st_size != 256) { LogError1("Private master key has been corrupted"); return CKR_FUNCTION_FAILED; } } else if (errno == ENOENT) { LogError1("Private master key doesn't exist, creating it..."); /* create the private master key, then save */ if ((rc = token_rng(master_key_private, MK_SIZE))) { LogError("token_rng failed. rc=0x%lx", rc); return rc; } return save_masterkey_private(); } else { /* some error other than file doesn't exist */ LogError("stat of private masterkey failed: %s", strerror(errno)); return CKR_FUNCTION_FAILED; } //fp = fopen("/etc/pkcs11/tpm/MK_PUBLIC", "r"); if ((fp = fopen((char *)fname, "r")) == NULL) { LogError("Error opening %s: %s", fname, strerror(errno)); return CKR_FUNCTION_FAILED; } if (fread(encrypted_masterkey, encrypted_masterkey_size, 1, fp) == 0) { LogError("Error reading %s: %s", fname, strerror(errno)); fclose(fp); return CKR_FUNCTION_FAILED; } fclose(fp); /* decrypt the private masterkey using the private leaf key */ if ((result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) { LogError("Tspi_Context_CreateObject failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } if ((result = Tspi_SetAttribData(hEncData, TSS_TSPATTRIB_ENCDATA_BLOB, TSS_TSPATTRIB_ENCDATABLOB_BLOB, encrypted_masterkey_size, encrypted_masterkey))) { LogError("Tspi_SetAttribData failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } if ((result = Tspi_Data_Unbind(hEncData, hPrivateLeafKey, &masterkey_size, &masterkey))) { LogError("Tspi_Data_Unbind failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } if (masterkey_size != MK_SIZE) { LogError("decrypted private master key size is %u, should be %u", masterkey_size, MK_SIZE); Tspi_Context_FreeMemory(tspContext, masterkey); return CKR_FUNCTION_FAILED; } memcpy(master_key_private, masterkey, MK_SIZE); Tspi_Context_FreeMemory(tspContext, masterkey); return CKR_OK; } CK_RV token_specific_login(CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG ulPinLen) { CK_RV rc; CK_BYTE hash_sha[SHA1_HASH_SIZE]; TSS_RESULT result; if ((result = token_load_srk())) { LogError("token_load_srk failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } if ((rc = compute_sha(pPin, ulPinLen, hash_sha))) { LogError("compute_sha failed. rc=0x%lx", rc); return CKR_FUNCTION_FAILED; } if (userType == CKU_USER) { /* If the public root key doesn't exist yet, the SO hasn't init'd the token */ if ((result = token_load_public_root_key())) { LogError("token_load_public_root_key failed. rc=0x%x", result); return CKR_USER_PIN_NOT_INITIALIZED; } /* find, load the private root key */ if ((rc = token_find_key(TPMTOK_PRIVATE_ROOT_KEY, CKO_PRIVATE_KEY, &ckPrivateRootKey))) { /* user's key chain not found, this must be the initial login */ if (memcmp(hash_sha, default_user_pin_sha, SHA1_HASH_SIZE)) { LogError("token_find_key failed and PIN != default"); return CKR_PIN_INCORRECT; } not_initialized = 1; return CKR_OK; } if ((rc = token_load_key(ckPrivateRootKey, hSRK, NULL, &hPrivateRootKey))) { LogError("token_load_key failed. rc=0x%lx", rc); /* Here, we've found the private root key, but its load failed. * This should only happen in a migration path, where we have * the PKCS#11 key store available, but the SRK is now * different. So, we will try to decrypt the PEM backup file * for the private root key using the given password. If that * succeeds, we will assume that we're in a migration path and * re-wrap the private root key to the new SRK. */ if ((token_migrate(TPMTOK_PRIVATE_ROOT_KEY, pPin))) { LogError("token_migrate. rc=0x%lx", rc); return rc; } /* At this point, the public root key has been successfully read * from backup, re-wrapped to the new SRK, loaded and the PKCS#11 * objects have been updated. Proceed with login as normal. */ } /* find, load the user leaf key */ if ((rc = token_find_key(TPMTOK_PRIVATE_LEAF_KEY, CKO_PRIVATE_KEY, &ckPrivateLeafKey))) { LogError("token_find_key failed. rc=0x%lx", rc); return CKR_FUNCTION_FAILED; } if ((rc = token_load_key(ckPrivateLeafKey, hPrivateRootKey, hash_sha, &hPrivateLeafKey))) { LogError("token_load_key failed. rc=0x%lx", rc); return CKR_FUNCTION_FAILED; } if ((rc = token_verify_pin(hPrivateLeafKey))) { LogError("token_verify_pin failed. failed. rc=0x%lx", rc); return rc; } memcpy(current_user_pin_sha, hash_sha, SHA1_HASH_SIZE); /* load private data encryption key here */ if ((rc = load_masterkey_private())) { LogError("load_masterkey_private failed. rc=0x%lx", rc); Tspi_Key_UnloadKey(hPrivateLeafKey); hPrivateLeafKey = NULL_HKEY; return rc; } rc = load_private_token_objects(); XProcLock( xproclock ); global_shm->priv_loaded = TRUE; XProcUnLock( xproclock ); } else { /* SO path -- */ /* find, load the root key */ if ((rc = token_find_key(TPMTOK_PUBLIC_ROOT_KEY, CKO_PRIVATE_KEY, &ckPublicRootKey))) { /* The SO hasn't set her PIN yet, compare the login pin with * the hard-coded value */ if (memcmp(default_so_pin_sha, hash_sha, SHA1_HASH_SIZE)) { LogError("token_find_key failed and PIN != default"); return CKR_PIN_INCORRECT; } not_initialized = 1; return CKR_OK; } /* The SO's key hierarchy has previously been created, so load the key * hierarchy and verify the pin using the TPM. */ if ((rc = token_load_key(ckPublicRootKey, hSRK, NULL, &hPublicRootKey))) { LogError("token_load_key failed. rc=0x%lx", rc); /* Here, we've found the public root key, but its load failed. * This should only happen in a migration path, where we have * the PKCS#11 key store available, but the SRK is now * different. So, we will try to decrypt the PEM backup file * for the public root key using the given password. If that * succeeds, we will assume that we're in a migration path and * re-wrap the public root key to the new SRK. */ if ((token_migrate(TPMTOK_PUBLIC_ROOT_KEY, pPin))) { LogError("token_migrate. rc=0x%lx", rc); return rc; } /* At this point, the public root key has been successfully read * from backup, re-wrapped to the new SRK, loaded and the PKCS#11 * objects have been updated. Proceed with login as normal. */ } /* find, load the public leaf key */ if ((rc = token_find_key(TPMTOK_PUBLIC_LEAF_KEY, CKO_PRIVATE_KEY, &ckPublicLeafKey))) { LogError("token_find_key failed. rc=0x%lx", rc); return CKR_FUNCTION_FAILED; } if ((rc = token_load_key(ckPublicLeafKey, hPublicRootKey, hash_sha, &hPublicLeafKey))) { LogError("token_load_key failed. rc=0x%lx", rc); return CKR_FUNCTION_FAILED; } if ((rc = token_verify_pin(hPublicLeafKey))) { LogError("token_verify_pin failed. rc=0x%lx", rc); return rc; } memcpy(current_so_pin_sha, hash_sha, SHA1_HASH_SIZE); } return rc; } CK_RV token_specific_logout() { if (hPrivateLeafKey != NULL_HKEY) { Tspi_Key_UnloadKey(hPrivateLeafKey); hPrivateLeafKey = NULL_HKEY; } else if (hPublicLeafKey != NULL_HKEY) { Tspi_Key_UnloadKey(hPublicLeafKey); hPublicLeafKey = NULL_HKEY; } memset(master_key_private, 0, MK_SIZE); memset(current_so_pin_sha, 0, SHA1_HASH_SIZE); memset(current_user_pin_sha, 0, SHA1_HASH_SIZE); /* pulled from new_host.c */ object_mgr_purge_private_token_objects(); return CKR_OK; } CK_RV token_specific_init_pin(CK_CHAR_PTR pPin, CK_ULONG ulPinLen) { /* Since the SO must log in before calling C_InitPIN, we will * be able to return CKR_OK automatically here. * This is because the USER key structure is created at the * time of her first login, not at C_InitPIN time. */ return CKR_OK; } CK_RV check_pin_properties(CK_USER_TYPE userType, CK_BYTE *pinHash, CK_ULONG ulPinLen) { /* make sure the new PIN is different */ if (userType == CKU_USER) { if (!memcmp(pinHash, default_user_pin_sha, SHA1_HASH_SIZE)) { LogError("new PIN must not be the default"); return CKR_PIN_INVALID; } } else { if (!memcmp(pinHash, default_so_pin_sha, SHA1_HASH_SIZE)) { LogError("new PIN must not be the default"); return CKR_PIN_INVALID; } } if (ulPinLen > MAX_PIN_LEN || ulPinLen < MIN_PIN_LEN) { LogError("New PIN is out of size range"); return CKR_PIN_LEN_RANGE; } return CKR_OK; } /* use this function call from set_pin only, where a not logged in public * session can provide the user pin which must be verified. This function * assumes that the pin has already been set once, so there's no migration * path option or checking of the default user pin. */ CK_RV verify_user_pin(CK_BYTE *hash_sha) { CK_RV rc; /* find, load the private root key */ if ((rc = token_find_key(TPMTOK_PRIVATE_ROOT_KEY, CKO_PRIVATE_KEY, &ckPrivateRootKey))) { LogError("token_find_key failed. rc=0x%lx", rc); return CKR_FUNCTION_FAILED; } if ((rc = token_load_key(ckPrivateRootKey, hSRK, NULL, &hPrivateRootKey))) { LogError("token_load_key failed. rc=0x%lx", rc); return CKR_FUNCTION_FAILED; } /* find, load the user leaf key */ if ((rc = token_find_key(TPMTOK_PRIVATE_LEAF_KEY, CKO_PRIVATE_KEY, &ckPrivateLeafKey))) { LogError("token_find_key failed. rc=0x%lx", rc); return CKR_FUNCTION_FAILED; } if ((rc = token_load_key(ckPrivateLeafKey, hPrivateRootKey, hash_sha, &hPrivateLeafKey))) { LogError("token_load_key failed. rc=0x%lx", rc); return CKR_FUNCTION_FAILED; } if ((rc = token_verify_pin(hPrivateLeafKey))) { LogError("token_verify_pin failed. failed. rc=0x%lx", rc); return rc; } return CKR_OK; } CK_RV token_specific_set_pin(ST_SESSION_HANDLE session, CK_CHAR_PTR pOldPin, CK_ULONG ulOldPinLen, CK_CHAR_PTR pNewPin, CK_ULONG ulNewPinLen) { SESSION *sess = session_mgr_find( session.sessionh ); CK_BYTE oldpin_hash[SHA1_HASH_SIZE], newpin_hash[SHA1_HASH_SIZE]; CK_RV rc; RSA *rsa_root; TSS_RESULT result; if (!sess) { st_err_log(40, __FILE__, __LINE__); return CKR_SESSION_HANDLE_INVALID; } if ((rc = compute_sha(pOldPin, ulOldPinLen, oldpin_hash))) { LogError("compute_sha failed. rc=0x%lx", rc); return CKR_FUNCTION_FAILED; } if ((rc = compute_sha(pNewPin, ulNewPinLen, newpin_hash))) { LogError("compute_sha failed. rc=0x%lx", rc); return CKR_FUNCTION_FAILED; } if ((result = token_load_srk())) { LogError("token_load_srk failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } /* From the PKCS#11 2.20 spec: "C_SetPIN modifies the PIN of the user that is * currently logged in, or the CKU_USER PIN if the session is not logged in." * A non R/W session fails with CKR_SESSION_READ_ONLY. */ if (sess->session_info.state == CKS_RW_USER_FUNCTIONS || sess->session_info.state == CKS_RW_PUBLIC_SESSION) { if (not_initialized) { if (memcmp(oldpin_hash, default_user_pin_sha, SHA1_HASH_SIZE)) { LogError("old PIN != default for an uninitialized user"); return CKR_PIN_INCORRECT; } if ((rc = check_pin_properties(CKU_USER, newpin_hash, ulNewPinLen))) { return rc; } if ((rc = token_create_private_tree(newpin_hash, pNewPin))) { LogError1("FAILED creating USER tree."); return CKR_FUNCTION_FAILED; } nv_token_data->token_info.flags &= ~(CKF_USER_PIN_TO_BE_CHANGED); nv_token_data->token_info.flags |= CKF_USER_PIN_INITIALIZED; return save_token_data(); } if (sess->session_info.state == CKS_RW_USER_FUNCTIONS) { /* if we're already logged in, just verify the hash */ if (memcmp(current_user_pin_sha, oldpin_hash, SHA1_HASH_SIZE)) { LogError("USER pin incorrect"); return CKR_PIN_INCORRECT; } } else { if ((rc = verify_user_pin(oldpin_hash))) { return rc; } } if ((rc = check_pin_properties(CKU_USER, newpin_hash, ulNewPinLen))) { return rc; } /* change the auth on the TSS object */ if ((result = tss_change_auth(hPrivateLeafKey, hPrivateRootKey, newpin_hash))) { LogError1("tss_change_auth failed"); return CKR_FUNCTION_FAILED; } /* destroy the old PKCS#11 priv key object and create a new one */ if ((rc = token_update_private_key(hPrivateLeafKey, TPMTOK_PRIVATE_LEAF_KEY))) { LogError1("token_update_private_key failed."); return rc; } /* read the backup key with the old pin */ if ((rc = openssl_read_key(TPMTOK_PRIV_ROOT_KEY_FILE, pOldPin, &rsa_root))) { if (rc == CKR_FILE_NOT_FOUND) { /* If the user has moved his backup PEM file off site, allow a * change auth to succeed without updating it. */ return CKR_OK; } LogError1("openssl_read_key failed"); return rc; } /* write it out using the new pin */ if ((rc = openssl_write_key(rsa_root, TPMTOK_PRIV_ROOT_KEY_FILE, pNewPin))) { RSA_free(rsa_root); LogError1("openssl_write_key failed"); return CKR_FUNCTION_FAILED; } RSA_free(rsa_root); } else if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) { if (not_initialized) { if (memcmp(default_so_pin_sha, oldpin_hash, SHA1_HASH_SIZE)) { LogError("old PIN != default for an uninitialized SO"); return CKR_PIN_INCORRECT; } if ((rc = check_pin_properties(CKU_SO, newpin_hash, ulNewPinLen))) { return rc; } if ((rc = token_create_public_tree(newpin_hash, pNewPin))) { LogError1("FAILED creating SO tree."); return CKR_FUNCTION_FAILED; } nv_token_data->token_info.flags &= ~(CKF_SO_PIN_TO_BE_CHANGED); return save_token_data(); } if (memcmp(current_so_pin_sha, oldpin_hash, SHA1_HASH_SIZE)) { LogError("SO PIN incorrect"); return CKR_PIN_INCORRECT; } if ((rc = check_pin_properties(CKU_SO, newpin_hash, ulNewPinLen))) { return rc; } /* change auth on the SO's leaf key */ if ((result = tss_change_auth(hPublicLeafKey, hPublicRootKey, newpin_hash))) { LogError1("tss_change_auth failed"); return CKR_FUNCTION_FAILED; } if ((rc = token_update_private_key(hPublicLeafKey, TPMTOK_PUBLIC_LEAF_KEY))) { LogError1("token_update_private_key failed."); return rc; } /* change auth on the public root key's openssl backup */ if ((rc = openssl_read_key(TPMTOK_PUB_ROOT_KEY_FILE, pOldPin, &rsa_root))) { if (rc == CKR_FILE_NOT_FOUND) { /* If the user has moved his backup PEM file off site, allow a * change auth to succeed without updating it. */ return CKR_OK; } LogError1("openssl_read_key failed"); return rc; } /* write it out using the new pin */ if ((rc = openssl_write_key(rsa_root, TPMTOK_PUB_ROOT_KEY_FILE, pNewPin))) { RSA_free(rsa_root); LogError1("openssl_write_key failed"); return CKR_FUNCTION_FAILED; } RSA_free(rsa_root); } else { st_err_log(142, __FILE__, __LINE__); rc = CKR_SESSION_READ_ONLY; } return rc; } /* only called at token init time */ CK_RV token_specific_verify_so_pin(CK_CHAR_PTR pPin, CK_ULONG ulPinLen) { CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_RV rc; if ((rc = compute_sha(pPin, ulPinLen, hash_sha))) { LogError("compute_sha failed. rc=0x%lx", rc); return CKR_FUNCTION_FAILED; } /* find, load the migratable root key */ if ((rc = token_find_key(TPMTOK_PUBLIC_ROOT_KEY, CKO_PRIVATE_KEY, &ckPublicRootKey))) { /* The SO hasn't set her PIN yet, compare the login pin with * the hard-coded value */ if (memcmp(default_so_pin_sha, hash_sha, SHA1_HASH_SIZE)) { LogError("token_find_key failed and PIN != default"); return CKR_PIN_INCORRECT; } return CKR_OK; } if ((rc = token_load_srk())) { LogError("token_load_srk failed. rc = 0x%lx", rc); return CKR_FUNCTION_FAILED; } /* we found the root key, so check by loading the chain */ if ((rc = token_load_key(ckPublicRootKey, hSRK, NULL, &hPublicRootKey))) { LogError("token_load_key failed. rc=0x%lx", rc); return CKR_FUNCTION_FAILED; } /* find, load the public leaf key */ if ((rc = token_find_key(TPMTOK_PUBLIC_LEAF_KEY, CKO_PRIVATE_KEY, &ckPublicLeafKey))) { LogError("token_find_key failed. rc=0x%lx", rc); return CKR_FUNCTION_FAILED; } if ((rc = token_load_key(ckPublicLeafKey, hPublicRootKey, hash_sha, &hPublicLeafKey))) { LogError1("token_load_key(MigLeafKey) Failed."); return CKR_FUNCTION_FAILED; } if ((rc = token_verify_pin(hPublicLeafKey))) { LogError("token_verify_pin failed. rc=0x%lx", rc); return rc; } return CKR_OK; } CK_RV token_specific_final() { TSS_RESULT result; if ((result = Tspi_Context_Close(tspContext))) { LogError("Tspi_Context_Close failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } return CKR_OK; } CK_RV token_specific_des_key_gen(CK_BYTE *des_key, CK_ULONG len) { // Nothing different to do for DES or TDES here as this is just // random data... Validation handles the rest rng_generate(des_key,len); // we really need to validate the key for parity etc... // we should do that here... The caller validates the single des keys // against the known and suspected poor keys.. return CKR_OK; } CK_RV token_specific_des_ecb(CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_BYTE encrypt) { CK_ULONG rc; des_key_schedule des_key2; const_des_cblock key_val_SSL, in_key_data; des_cblock out_key_data; unsigned int i,j; // Create the key schedule memcpy(&key_val_SSL, key_value, 8); des_set_key_unchecked(&key_val_SSL, des_key2); // the des decrypt will only fail if the data length is not evenly divisible // by 8 if (in_data_len % 8 ){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } // Both the encrypt and the decrypt are done 8 bytes at a time if (encrypt) { for (i=0; itemplate, CKA_MODULUS, &modulus ); if (rc == FALSE) { return NULL; } ret = malloc(modulus->ulValueLen); if (ret == NULL) { LogError("Out of memory."); return NULL; } memcpy(ret, modulus->pValue, modulus->ulValueLen); return ret; } CK_RV token_specific_rsa_generate_keypair( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ) { CK_ATTRIBUTE *publ_exp = NULL; CK_ATTRIBUTE *attr = NULL; CK_ULONG mod_bits = 0; CK_BBOOL flag; CK_RV rc; TSS_FLAG initFlags = 0; BYTE authHash[SHA1_HASH_SIZE]; BYTE *authData = NULL; TSS_HKEY hKey = NULL_HKEY; TSS_HKEY hParentKey = NULL_HKEY; TSS_RESULT result; UINT32 ulBlobLen; BYTE *rgbBlob; /* Make sure the public exponent is usable */ if ((util_check_public_exponent(publ_tmpl))) { LogError("Invalid public exponent"); return CKR_TEMPLATE_INCONSISTENT; } flag = template_attribute_find( publ_tmpl, CKA_MODULUS_BITS, &attr ); if (!flag){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; // should never happen } mod_bits = *(CK_ULONG *)attr->pValue; if ((initFlags = util_get_keysize_flag(mod_bits)) == 0) { st_err_log(19, __FILE__, __LINE__); return CKR_KEY_SIZE_RANGE; } /* If we're not logged in, hPrivateLeafKey and hPublicLeafKey should be NULL */ if ((hPrivateLeafKey == NULL_HKEY) && (hPublicLeafKey == NULL_HKEY)) { /* public session, wrap key with the PRK */ initFlags |= TSS_KEY_TYPE_LEGACY | TSS_KEY_NO_AUTHORIZATION | TSS_KEY_MIGRATABLE; if ((result = token_load_public_root_key())) { LogError("token_load_public_root_key failed. rc=%x", result); return CKR_FUNCTION_FAILED; } hParentKey = hPublicRootKey; } else if (hPrivateLeafKey != NULL_HKEY) { /* logged in USER session */ initFlags |= TSS_KEY_TYPE_LEGACY | TSS_KEY_AUTHORIZATION | TSS_KEY_MIGRATABLE; /* get a random SHA1 hash for the auth data */ if ((rc = token_rng(authHash, SHA1_HASH_SIZE))) { LogError("token_rng failed. rc=%lx", rc); return CKR_FUNCTION_FAILED; } authData = authHash; hParentKey = hPrivateRootKey; } else { /* logged in SO session */ initFlags |= TSS_KEY_TYPE_LEGACY | TSS_KEY_AUTHORIZATION | TSS_KEY_MIGRATABLE; /* get a random SHA1 hash for the auth data */ if ((rc = token_rng(authHash, SHA1_HASH_SIZE))) { LogError("token_rng failed. rc=0x%lx", rc); return CKR_FUNCTION_FAILED; } authData = authHash; hParentKey = hPublicRootKey; } if ((result = tss_generate_key(initFlags, authData, hParentKey, &hKey))) { LogError("tss_generate_key returned 0x%x", result); return result; } if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB, TSS_TSPATTRIB_KEYBLOB_BLOB, &ulBlobLen, &rgbBlob))) { LogError("Tspi_GetAttribData failed with rc: 0x%x", result); return CKR_FUNCTION_FAILED; } if ((rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob, ulBlobLen, &attr))) { st_err_log(84, __FILE__, __LINE__); Tspi_Context_FreeMemory(tspContext, rgbBlob); return rc; } template_update_attribute( priv_tmpl, attr ); if ((rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob, ulBlobLen, &attr))) { st_err_log(84, __FILE__, __LINE__); Tspi_Context_FreeMemory(tspContext, rgbBlob); return rc; } template_update_attribute( publ_tmpl, attr ); Tspi_Context_FreeMemory(tspContext, rgbBlob); /* grab the public key to put into the public key object */ if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO, TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &ulBlobLen, &rgbBlob))) { LogError("Tspi_GetAttribData failed with rc: 0x%x", result); return result; } /* add the public key blob to the object template */ if ((rc = build_attribute(CKA_MODULUS, rgbBlob, ulBlobLen, &attr))) { st_err_log(84, __FILE__, __LINE__); Tspi_Context_FreeMemory(tspContext, rgbBlob); return rc; } template_update_attribute( publ_tmpl, attr ); /* add the public key blob to the object template */ if ((rc = build_attribute(CKA_MODULUS, rgbBlob, ulBlobLen, &attr))) { st_err_log(84, __FILE__, __LINE__); Tspi_Context_FreeMemory(tspContext, rgbBlob); return rc; } template_update_attribute( priv_tmpl, attr ); Tspi_Context_FreeMemory(tspContext, rgbBlob); /* wrap the authdata and put it into an object */ if (authData != NULL) { if ((rc = token_wrap_auth_data(authData, publ_tmpl, priv_tmpl))) { LogError("token_wrap_auth_data failed with rc: 0x%lx", rc); } } return rc; } CK_RV token_rsa_load_key( OBJECT * key_obj, TSS_HKEY * phKey ) { TSS_RESULT result; TSS_HPOLICY hPolicy = NULL_HPOLICY; TSS_HKEY hParentKey; BYTE *authData = NULL; CK_ATTRIBUTE *attr; CK_RV rc; CK_OBJECT_HANDLE handle; if (hPrivateLeafKey != NULL_HKEY) { hParentKey = hPrivateRootKey; } else { if ((result = token_load_public_root_key())) { LogError("token_load_public_root_key failed. rc=%x", result); return CKR_FUNCTION_FAILED; } hParentKey = hPublicRootKey; } if ((rc = template_attribute_find( key_obj->template, CKA_IBM_OPAQUE, &attr )) == FALSE) { /* if the key blob wasn't found, then try to wrap the key */ rc = object_mgr_find_in_map2(key_obj, &handle); if (rc != CKR_OK) return CKR_FUNCTION_FAILED; if ((rc = token_load_key(handle, hParentKey, NULL, phKey))) { LogError("token_load_key failed. rc=0x%lx", rc); return rc; } /* try again to get the CKA_IBM_OPAQUE attr */ if ((rc = template_attribute_find( key_obj->template, CKA_IBM_OPAQUE, &attr )) == FALSE) { LogError("Could not find key blob"); return rc; } } if ((result = Tspi_Context_LoadKeyByBlob(tspContext, hParentKey, attr->ulValueLen, attr->pValue, phKey))) { LogError("Tspi_Context_LoadKeyByBlob failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } /* auth data may be required */ if (template_attribute_find( key_obj->template, CKA_ENC_AUTHDATA, &attr) == TRUE && attr) { if ((hPrivateLeafKey == NULL_HKEY) && (hPublicLeafKey == NULL_HKEY)) { LogError("Shouldn't be in a public session here"); return CKR_FUNCTION_FAILED; } else if (hPublicLeafKey != NULL_HKEY) { hParentKey = hPublicLeafKey; } else { hParentKey = hPrivateLeafKey; } if ((result = token_unwrap_auth_data(attr->pValue, attr->ulValueLen, hParentKey, &authData))) { LogError("token_unwrap_auth_data: 0x%x", result); return CKR_FUNCTION_FAILED; } if ((result = Tspi_GetPolicyObject(*phKey, TSS_POLICY_USAGE, &hPolicy))) { LogError("Tspi_GetPolicyObject: 0x%x", result); return CKR_FUNCTION_FAILED; } /* If the policy handle returned is the same as the context's default policy, then * a new policy must be created and assigned to the key. Otherwise, just set the * secret in the policy */ if (hPolicy == hDefaultPolicy) { if ((result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hPolicy))) { LogError("Tspi_Context_CreateObject: 0x%x", result); return CKR_FUNCTION_FAILED; } if ((result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1, SHA1_HASH_SIZE, authData))) { LogError("Tspi_Policy_SetSecret failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } if ((result = Tspi_Policy_AssignToObject(hPolicy, *phKey))) { LogError("Tspi_Policy_AssignToObject failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } } else if ((result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1, SHA1_HASH_SIZE, authData))) { LogError("Tspi_Policy_SetSecret failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } Tspi_Context_FreeMemory(tspContext, authData); } return CKR_OK; } CK_RV token_specific_rsa_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, OBJECT * key_obj ) { CK_RV rc; TSS_RESULT result; TSS_HKEY hKey; TSS_HENCDATA hEncData = NULL_HENCDATA; UINT32 buf_size = 0; BYTE *buf = NULL; if ((rc = token_rsa_load_key(key_obj, &hKey))) { LogError("token_rsa_load_key failed. rc=0x%lx", rc); return rc; } /* push the data into the encrypted data object */ if ((result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) { LogError("Tspi_Context_CreateObject failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } if ((result = Tspi_SetAttribData(hEncData, TSS_TSPATTRIB_ENCDATA_BLOB, TSS_TSPATTRIB_ENCDATABLOB_BLOB, in_data_len, in_data))) { LogError("Tspi_SetAttribData failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } /* unbind the data, receiving the plaintext back */ LogError("unbinding data with size: %ld", in_data_len); if ((result = Tspi_Data_Unbind(hEncData, hKey, &buf_size, &buf))) { LogError("Tspi_Data_Unbind failed: 0x%x", result); return CKR_FUNCTION_FAILED; } if (*out_data_len < buf_size) { st_err_log(111, __FILE__, __LINE__); Tspi_Context_FreeMemory(tspContext, buf); return CKR_BUFFER_TOO_SMALL; } memcpy(out_data, buf, buf_size); *out_data_len = buf_size; Tspi_Context_FreeMemory(tspContext, buf); return CKR_OK; } CK_RV token_specific_rsa_verify( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * sig, CK_ULONG sig_len, OBJECT * key_obj ) { TSS_RESULT result; TSS_HHASH hHash; TSS_HKEY hKey; CK_RV rc; if ((rc = token_rsa_load_key(key_obj, &hKey))) { LogError("token_rsa_load_key failed. rc=0x%lx", rc); return rc; } /* Create the hash object we'll use to sign */ if ((result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_HASH, TSS_HASH_OTHER, &hHash))) { LogError("Tspi_Context_CreateObject failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } /* Insert the data into the hash object */ if ((result = Tspi_Hash_SetHashValue(hHash, in_data_len, in_data))) { LogError("Tspi_Hash_SetHashValue failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } /* Verify */ result = Tspi_Hash_VerifySignature(hHash, hKey, sig_len, sig); if (result != TSS_SUCCESS && TPMTOK_TSS_ERROR_CODE(result) != TSS_E_FAIL) { LogError("Tspi_Hash_VerifySignature failed. rc=0x%x", result); } if (TPMTOK_TSS_ERROR_CODE(result) == TSS_E_FAIL) { rc = CKR_SIGNATURE_INVALID; } else { rc = CKR_OK; } return rc; } CK_RV token_specific_rsa_sign( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, OBJECT * key_obj ) { TSS_RESULT result; TSS_HHASH hHash; BYTE *sig; UINT32 sig_len; TSS_HKEY hKey; CK_RV rc; if ((rc = token_rsa_load_key(key_obj, &hKey))) { LogError("token_rsa_load_key failed. rc=0x%lx", rc); return rc; } /* Create the hash object we'll use to sign */ if ((result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_HASH, TSS_HASH_OTHER, &hHash))) { LogError("Tspi_Context_CreateObject failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } /* Insert the data into the hash object */ if ((result = Tspi_Hash_SetHashValue(hHash, in_data_len, in_data))) { LogError("Tspi_Hash_SetHashValue failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } /* Sign */ if ((result = Tspi_Hash_Sign(hHash, hKey, &sig_len, &sig))) { LogError("Tspi_Hash_Sign failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } if (sig_len > *out_data_len) { LogError("%s: Error: Buffer too small to hold result.", __FUNCTION__); Tspi_Context_FreeMemory(tspContext, sig); return CKR_BUFFER_TOO_SMALL; } memcpy(out_data, sig, sig_len); *out_data_len = sig_len; Tspi_Context_FreeMemory(tspContext, sig); return CKR_OK; } CK_RV token_specific_rsa_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, OBJECT * key_obj ) { TSS_RESULT result; TSS_HENCDATA hEncData; BYTE *dataBlob; UINT32 dataBlobSize; TSS_HKEY hKey; CK_RV rc; if ((rc = token_rsa_load_key(key_obj, &hKey))) { LogError("token_rsa_load_key failed. rc=0x%lx", rc); return rc; } if ((result = Tspi_Context_CreateObject(tspContext, TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND, &hEncData))) { LogError("Tspi_Context_CreateObject failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } if ((result = Tspi_Data_Bind(hEncData, hKey, in_data_len, in_data))) { LogError("Tspi_Data_Bind failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } if ((result = Tspi_GetAttribData(hEncData, TSS_TSPATTRIB_ENCDATA_BLOB, TSS_TSPATTRIB_ENCDATABLOB_BLOB, &dataBlobSize, &dataBlob))) { LogError("Tspi_SetAttribData failed. rc=0x%x", result); return CKR_FUNCTION_FAILED; } if (dataBlobSize > *out_data_len) { LogError("CKR_DATA_LEN_RANGE"); Tspi_Context_FreeMemory(tspContext, dataBlob); return CKR_DATA_LEN_RANGE; } memcpy(out_data, dataBlob, dataBlobSize); *out_data_len = dataBlobSize; Tspi_Context_FreeMemory(tspContext, dataBlob); return CKR_OK; } CK_RV token_specific_aes_key_gen(CK_BYTE *key, CK_ULONG len) { return token_rng(key, len); } CK_RV token_specific_aes_ecb( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_ULONG key_len, CK_BYTE encrypt) { AES_KEY ssl_aes_key; unsigned int i; /* There's a previous check that in_data_len % AES_BLOCK_SIZE == 0, * so this is fine */ CK_ULONG loops = (CK_ULONG)(in_data_len/AES_BLOCK_SIZE); memset( &ssl_aes_key, 0, sizeof(AES_KEY)); // AES_ecb_encrypt encrypts only a single block, so we have to break up the // input data here if (encrypt) { AES_set_encrypt_key((unsigned char *)key_value, (key_len*8), &ssl_aes_key); for( i=0; iulValueLen > 256) || (prime_attr->ulValueLen < 64)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } dh = DH_new() ; if (dh == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Create and init BIGNUM structs to stick in the DH struct bn_p = BN_new(); bn_g = BN_new(); if (bn_g == NULL || bn_p == NULL) { if (bn_g) BN_free(bn_g); if (bn_p) BN_free(bn_p); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } BN_init(bn_p); BN_init(bn_g); // Convert from strings to BIGNUMs and stick them in the DH struct BN_bin2bn((char *)prime_attr->pValue, prime_attr->ulValueLen, bn_p); dh->p = bn_p; BN_bin2bn((char *)base_attr->pValue, base_attr->ulValueLen, bn_g); dh->g = bn_g; // Generate the DH Key if (!DH_generate_key(dh)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Extract the public and private key components from the DH struct, // and insert them in the publ_tmpl and priv_tmpl // // pub_key // //temp_bn = BN_new(); temp_bn = dh->pub_key; temp_bn_len = BN_num_bytes(temp_bn); temp_byte = malloc(temp_bn_len); temp_bn_len = BN_bn2bin(temp_bn, temp_byte); rc = build_attribute( CKA_VALUE, temp_byte, temp_bn_len, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( publ_tmpl, temp_attr ); free(temp_byte); // // priv_key // //temp_bn = BN_new(); temp_bn = dh->priv_key; temp_bn_len = BN_num_bytes(temp_bn); temp_byte = malloc(temp_bn_len); temp_bn_len = BN_bn2bin(temp_bn, temp_byte); rc = build_attribute( CKA_VALUE, temp_byte, temp_bn_len, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); free(temp_byte); // Update CKA_VALUE_BITS attribute in the private key value_bits_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); value_bits_attr->type = CKA_VALUE_BITS; value_bits_attr->ulValueLen = sizeof(CK_ULONG); value_bits_attr->pValue = (CK_BYTE *)value_bits_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_bits_attr->pValue = 8*temp_bn_len; template_update_attribute( priv_tmpl, value_bits_attr ); // Add prime and base to the private key template rc = build_attribute( CKA_PRIME,(char *)prime_attr->pValue, prime_attr->ulValueLen, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); rc = build_attribute( CKA_BASE,(char *)base_attr->pValue, base_attr->ulValueLen, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); // Cleanup DH key DH_free(dh) ; return CKR_OK ; } #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/mech_sha.c0000640000175000017500000005564111327631345021354 0ustar jfjf /* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */ /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */ // File: mech_sha.c // // Mechanisms for SHA-1 related routines // // The following applies to the software SHA implementation: // Written 2 September 1992, Peter C. Gutmann. // This implementation placed in the public domain. // // Modified 1 June 1993, Colin Plumb. // Modified for the new SHS based on Peter Gutmann's work, // 18 July 1994, Colin Plumb. // Gutmann's work. // Renamed to SHA and comments updated a bit 1 November 1995, Colin Plumb. // These modifications placed in the public domain. // // Comments to pgut1@cs.aukuni.ac.nz // //#include #include #include // for memcmp() et al #include #include #include "pkcs11/pkcs11types.h" #include #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" #define SHA_HARDWARE_THRESHHOLD 128000 // The SHA f()-functions. The f1 and f3 functions can be optimized to // save one boolean operation each - thanks to Rich Schroeppel, // rcs@cs.arizona.edu for discovering this // #define f1(x,y,z) (z ^ (x & (y ^ z))) // Rounds 0-19 #define f2(x,y,z) (x ^ y ^ z) // Rounds 20-39 #define f3(x,y,z) ((x & y) | (z & (x | y))) // Rounds 40-59 #define f4(x,y,z) (x ^ y ^ z) // Rounds 60-79 // The SHA Mysterious Constants. // K1 = floor(sqrt(2) * 2^30) // K2 = floor(sqrt(3) * 2^30) // K3 = floor(sqrt(5) * 2^30) // K4 = floor(sqrt(10) * 2^30) // #define K1 0x5A827999L // Rounds 0-19 #define K2 0x6ED9EBA1L // Rounds 20-39 #define K3 0x8F1BBCDCL // Rounds 40-59 #define K4 0xCA62C1D6L // Rounds 60-79 // SHA initial values // #define h0init 0x67452301 #define h1init 0xEFCDAB89 #define h2init 0x98BADCFE #define h3init 0x10325476 #define h4init 0xC3D2E1F0 // // Note that it may be necessary to add parentheses to these macros // if they are to be called with expressions as arguments. // // 32-bit rotate left - kludged with shifts // #define ROTL(n,X) ((X << n) | (X >> (32-n))) // The initial expanding function // // The hash function is defined over an 80-word expanded input array W, // where the first 16 are copies of the input data, and the remaining 64 // are defined by W[i] = W[i-16] ^ W[i-14] ^ W[i-8] ^ W[i-3]. This // implementation generates these values on the fly in a circular buffer. // #define expand(W,i) \ (W[i&15] ^= W[(i-14)&15] ^ W[(i-8)&15] ^ W[(i-3)&15], W[i&15] = ROTL(1, W[i&15])) // The prototype SHA sub-round // // The fundamental sub-round is // a' = e + ROTL(5,a) + f(b, c, d) + k + data; // b' = a; // c' = ROTL(30,b); // d' = c; // e' = d; // ... but this is implemented by unrolling the loop 5 times and renaming // the variables (e,a,b,c,d) = (a',b',c',d',e') each iteration. // #define subRound(a, b, c, d, e, f, k, data) \ (e += ROTL(5,a) + f(b, c, d) + k + data, b = ROTL(30, b)) void shaInit( SHA1_CONTEXT *ctx ); void shaUpdate( SHA1_CONTEXT *ctx, CK_BYTE const *buffer, CK_ULONG count); void shaFinal( SHA1_CONTEXT *ctx, CK_BYTE *hash ); void shaTransform( SHA1_CONTEXT *ctx ); // // CK_RV sha1_hash( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { CK_RV rv; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = SHA1_HASH_SIZE; return CKR_OK; } if(ctx->context == NULL) return CKR_HOST_MEMORY; if((rv = (ckm_sha1_update(ctx, in_data, in_data_len)))) return rv; return ckm_sha1_final( ctx, out_data, out_data_len ); } // // CK_RV sha1_hash_update( SESSION * sess, DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { if (!sess || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } return ckm_sha1_update( ctx, in_data, in_data_len ); } // // CK_RV sha1_hash_final( SESSION * sess, CK_BYTE length_only, DIGEST_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ) { if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = SHA1_HASH_SIZE; return CKR_OK; } return ckm_sha1_final( ctx, out_data, out_data_len ); } // this routine gets called for two mechanisms actually: // CKM_SHA_1_HMAC // CKM_SHA_1_HMAC_GENERAL // CK_RV sha1_hmac_sign( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE hash[SHA1_HASH_SIZE]; DIGEST_CONTEXT digest_ctx; CK_MECHANISM digest_mech; CK_BYTE k_ipad[SHA1_BLOCK_SIZE]; CK_BYTE k_opad[SHA1_BLOCK_SIZE]; CK_ULONG key_bytes, hash_len, hmac_len; CK_ULONG i; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_SHA_1_HMAC_GENERAL) { hmac_len = *(CK_ULONG *)ctx->mech.pParameter; if (hmac_len == 0) { *out_data_len = 0; return CKR_OK; } } else hmac_len = SHA1_HASH_SIZE; if (length_only == TRUE) { *out_data_len = hmac_len; return CKR_OK; } memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key_obj->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else key_bytes = attr->ulValueLen; // build (K XOR ipad), (K XOR opad) // if (key_bytes > SHA1_BLOCK_SIZE) { digest_mech.mechanism = CKM_SHA_1; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest( sess, FALSE, &digest_ctx, attr->pValue, attr->ulValueLen, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(124, __FILE__, __LINE__); return rc; } digest_mgr_cleanup( &digest_ctx ); memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); for (i=0; i < hash_len; i++) { k_ipad[i] = hash[i] ^ 0x36; k_opad[i] = hash[i] ^ 0x5C; } memset( &k_ipad[i], 0x36, SHA1_BLOCK_SIZE - i); memset( &k_opad[i], 0x5C, SHA1_BLOCK_SIZE - i); } else { CK_BYTE *key = attr->pValue; for (i=0; i < key_bytes; i++) { k_ipad[i] = key[i] ^ 0x36; k_opad[i] = key[i] ^ 0x5C; } memset( &k_ipad[i], 0x36, SHA1_BLOCK_SIZE - key_bytes ); memset( &k_opad[i], 0x5C, SHA1_BLOCK_SIZE - key_bytes ); } digest_mech.mechanism = CKM_SHA_1; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; // inner hash // rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, k_ipad, SHA1_BLOCK_SIZE ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, in_data, in_data_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(126, __FILE__, __LINE__); return rc; } digest_mgr_cleanup( &digest_ctx ); memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); // outer hash // rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, k_opad, SHA1_BLOCK_SIZE ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, hash, hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(126, __FILE__, __LINE__); return rc; } memcpy( out_data, hash, hmac_len ); *out_data_len = hmac_len; digest_mgr_cleanup( &digest_ctx ); return CKR_OK; } // // CK_RV sha1_hmac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ) { CK_BYTE hmac[SHA1_HASH_SIZE]; SIGN_VERIFY_CONTEXT hmac_ctx; CK_ULONG hmac_len, len; CK_RV rc; if (!sess || !ctx || !in_data || !signature){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_SHA_1_HMAC_GENERAL) hmac_len = *(CK_ULONG *)ctx->mech.pParameter; else hmac_len = SHA1_HASH_SIZE; memset( &hmac_ctx, 0, sizeof(SIGN_VERIFY_CONTEXT) ); rc = sign_mgr_init( sess, &hmac_ctx, &ctx->mech, FALSE, ctx->key ); if (rc != CKR_OK){ st_err_log(127, __FILE__, __LINE__); goto done; } len = sizeof(hmac); rc = sign_mgr_sign( sess, FALSE, &hmac_ctx, in_data, in_data_len, hmac, &len ); if (rc != CKR_OK){ st_err_log(128, __FILE__, __LINE__); goto done; } if ((len != hmac_len) || (len != sig_len)) { st_err_log(46, __FILE__, __LINE__); rc = CKR_SIGNATURE_LEN_RANGE; goto done; } if (memcmp(hmac, signature, hmac_len) != 0){ st_err_log(47, __FILE__, __LINE__); rc = CKR_SIGNATURE_INVALID; } done: sign_mgr_cleanup( &hmac_ctx ); return rc; } // // CKM routines // // // CK_RV ckm_sha1_update( DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { if( token_specific.t_sha_update == NULL ){ if (!ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } shaUpdate( (SHA1_CONTEXT *)ctx->context, in_data, in_data_len ); return CKR_OK; } return token_specific.t_sha_update(ctx, in_data, in_data_len); } // // CK_RV ckm_sha1_final( DIGEST_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ) { if (token_specific.t_sha_final == NULL ){ if (!ctx || !out_data || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < SHA1_HASH_SIZE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } shaFinal( (SHA1_CONTEXT *)ctx->context, out_data ); *out_data_len = SHA1_HASH_SIZE; return CKR_OK; } return token_specific.t_sha_final(ctx, out_data, out_data_len); } // // Software SHA-1 implementation // void ckm_sha1_init( DIGEST_CONTEXT * ctx) { // Set the h-vars to their initial values if (token_specific.t_sha_init == NULL ) { SHA1_CONTEXT *sha1_ctx; /* Allocate the context */ ctx->context_len = sizeof(SHA1_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(SHA1_CONTEXT)); if( ctx->context == NULL ) return; sha1_ctx = (SHA1_CONTEXT *)ctx->context; sha1_ctx->hash_value[0] = h0init; sha1_ctx->hash_value[1] = h1init; sha1_ctx->hash_value[2] = h2init; sha1_ctx->hash_value[3] = h3init; sha1_ctx->hash_value[4] = h4init; // Initialise bit count sha1_ctx->bits_lo = sha1_ctx->bits_hi = 0; } else { // SAB XXX call token specific init... the init MUST allocate it's context token_specific.t_sha_init(ctx); } } // Perform the SHA transformation. Note that this code, like MD5, seems to // break some optimizing compilers due to the complexity of the expressions // and the size of the basic block. It may be necessary to split it into // sections, e.g. based on the four subrounds // // Note that this corrupts the sha->data area // void shaTransform( SHA1_CONTEXT *ctx ) { register unsigned int A, B, C, D, E; // Set up first buffer // A = ctx->hash_value[0]; B = ctx->hash_value[1]; C = ctx->hash_value[2]; D = ctx->hash_value[3]; E = ctx->hash_value[4]; // Heavy mangling, in 4 sub-rounds of 20 interations each. // subRound( A, B, C, D, E, f1, K1, ctx->buf[ 0] ); subRound( E, A, B, C, D, f1, K1, ctx->buf[ 1] ); subRound( D, E, A, B, C, f1, K1, ctx->buf[ 2] ); subRound( C, D, E, A, B, f1, K1, ctx->buf[ 3] ); subRound( B, C, D, E, A, f1, K1, ctx->buf[ 4] ); subRound( A, B, C, D, E, f1, K1, ctx->buf[ 5] ); subRound( E, A, B, C, D, f1, K1, ctx->buf[ 6] ); subRound( D, E, A, B, C, f1, K1, ctx->buf[ 7] ); subRound( C, D, E, A, B, f1, K1, ctx->buf[ 8] ); subRound( B, C, D, E, A, f1, K1, ctx->buf[ 9] ); subRound( A, B, C, D, E, f1, K1, ctx->buf[10] ); subRound( E, A, B, C, D, f1, K1, ctx->buf[11] ); subRound( D, E, A, B, C, f1, K1, ctx->buf[12] ); subRound( C, D, E, A, B, f1, K1, ctx->buf[13] ); subRound( B, C, D, E, A, f1, K1, ctx->buf[14] ); subRound( A, B, C, D, E, f1, K1, ctx->buf[15] ); subRound( E, A, B, C, D, f1, K1, expand(ctx->buf, 16) ); subRound( D, E, A, B, C, f1, K1, expand(ctx->buf, 17) ); subRound( C, D, E, A, B, f1, K1, expand(ctx->buf, 18) ); subRound( B, C, D, E, A, f1, K1, expand(ctx->buf, 19) ); subRound( A, B, C, D, E, f2, K2, expand(ctx->buf, 20) ); subRound( E, A, B, C, D, f2, K2, expand(ctx->buf, 21) ); subRound( D, E, A, B, C, f2, K2, expand(ctx->buf, 22) ); subRound( C, D, E, A, B, f2, K2, expand(ctx->buf, 23) ); subRound( B, C, D, E, A, f2, K2, expand(ctx->buf, 24) ); subRound( A, B, C, D, E, f2, K2, expand(ctx->buf, 25) ); subRound( E, A, B, C, D, f2, K2, expand(ctx->buf, 26) ); subRound( D, E, A, B, C, f2, K2, expand(ctx->buf, 27) ); subRound( C, D, E, A, B, f2, K2, expand(ctx->buf, 28) ); subRound( B, C, D, E, A, f2, K2, expand(ctx->buf, 29) ); subRound( A, B, C, D, E, f2, K2, expand(ctx->buf, 30) ); subRound( E, A, B, C, D, f2, K2, expand(ctx->buf, 31) ); subRound( D, E, A, B, C, f2, K2, expand(ctx->buf, 32) ); subRound( C, D, E, A, B, f2, K2, expand(ctx->buf, 33) ); subRound( B, C, D, E, A, f2, K2, expand(ctx->buf, 34) ); subRound( A, B, C, D, E, f2, K2, expand(ctx->buf, 35) ); subRound( E, A, B, C, D, f2, K2, expand(ctx->buf, 36) ); subRound( D, E, A, B, C, f2, K2, expand(ctx->buf, 37) ); subRound( C, D, E, A, B, f2, K2, expand(ctx->buf, 38) ); subRound( B, C, D, E, A, f2, K2, expand(ctx->buf, 39) ); subRound( A, B, C, D, E, f3, K3, expand(ctx->buf, 40) ); subRound( E, A, B, C, D, f3, K3, expand(ctx->buf, 41) ); subRound( D, E, A, B, C, f3, K3, expand(ctx->buf, 42) ); subRound( C, D, E, A, B, f3, K3, expand(ctx->buf, 43) ); subRound( B, C, D, E, A, f3, K3, expand(ctx->buf, 44) ); subRound( A, B, C, D, E, f3, K3, expand(ctx->buf, 45) ); subRound( E, A, B, C, D, f3, K3, expand(ctx->buf, 46) ); subRound( D, E, A, B, C, f3, K3, expand(ctx->buf, 47) ); subRound( C, D, E, A, B, f3, K3, expand(ctx->buf, 48) ); subRound( B, C, D, E, A, f3, K3, expand(ctx->buf, 49) ); subRound( A, B, C, D, E, f3, K3, expand(ctx->buf, 50) ); subRound( E, A, B, C, D, f3, K3, expand(ctx->buf, 51) ); subRound( D, E, A, B, C, f3, K3, expand(ctx->buf, 52) ); subRound( C, D, E, A, B, f3, K3, expand(ctx->buf, 53) ); subRound( B, C, D, E, A, f3, K3, expand(ctx->buf, 54) ); subRound( A, B, C, D, E, f3, K3, expand(ctx->buf, 55) ); subRound( E, A, B, C, D, f3, K3, expand(ctx->buf, 56) ); subRound( D, E, A, B, C, f3, K3, expand(ctx->buf, 57) ); subRound( C, D, E, A, B, f3, K3, expand(ctx->buf, 58) ); subRound( B, C, D, E, A, f3, K3, expand(ctx->buf, 59) ); subRound( A, B, C, D, E, f4, K4, expand(ctx->buf, 60) ); subRound( E, A, B, C, D, f4, K4, expand(ctx->buf, 61) ); subRound( D, E, A, B, C, f4, K4, expand(ctx->buf, 62) ); subRound( C, D, E, A, B, f4, K4, expand(ctx->buf, 63) ); subRound( B, C, D, E, A, f4, K4, expand(ctx->buf, 64) ); subRound( A, B, C, D, E, f4, K4, expand(ctx->buf, 65) ); subRound( E, A, B, C, D, f4, K4, expand(ctx->buf, 66) ); subRound( D, E, A, B, C, f4, K4, expand(ctx->buf, 67) ); subRound( C, D, E, A, B, f4, K4, expand(ctx->buf, 68) ); subRound( B, C, D, E, A, f4, K4, expand(ctx->buf, 69) ); subRound( A, B, C, D, E, f4, K4, expand(ctx->buf, 70) ); subRound( E, A, B, C, D, f4, K4, expand(ctx->buf, 71) ); subRound( D, E, A, B, C, f4, K4, expand(ctx->buf, 72) ); subRound( C, D, E, A, B, f4, K4, expand(ctx->buf, 73) ); subRound( B, C, D, E, A, f4, K4, expand(ctx->buf, 74) ); subRound( A, B, C, D, E, f4, K4, expand(ctx->buf, 75) ); subRound( E, A, B, C, D, f4, K4, expand(ctx->buf, 76) ); subRound( D, E, A, B, C, f4, K4, expand(ctx->buf, 77) ); subRound( C, D, E, A, B, f4, K4, expand(ctx->buf, 78) ); subRound( B, C, D, E, A, f4, K4, expand(ctx->buf, 79) ); // Build message digest // ctx->hash_value[0] += A; ctx->hash_value[1] += B; ctx->hash_value[2] += C; ctx->hash_value[3] += D; ctx->hash_value[4] += E; } // SHA is defined in big-endian form, so this converts the buffer from // bytes to words, independent of the machine's native endianness. // // Assuming a consistent byte ordering for the machine, this also // has the magic property of being self-inverse. It is used as // such. // static void byteReverse( unsigned int *buffer, unsigned int byteCount ) { #ifndef __BYTE_ORDER #error "Endianess MUST be defined" #endif #if __BYTE_ORDER == __LITTLE_ENDIAN CK_ULONG value, val; byteCount /= sizeof(CK_ULONG_32); while (byteCount--) { val = *buffer; value = ((0x000000FF & val) << 24) | ((0x0000FF00 & val) << 8 ) | ((0x00FF0000 & val) >> 8 ) | ((0xFF000000 & val) >> 24); *buffer++ = value; } #endif // JRM - this code gives funky results on Linux/Intel. // I assume this is a GCC issue since regression tests passed on NT // // byteCount /= sizeof(CK_ULONG); // while ( byteCount-- ) { // value = (CK_ULONG)((unsigned)((CK_BYTE *)buffer)[0] << 8 | ((CK_BYTE *)buffer)[1]) << 16 | // ((unsigned)((CK_BYTE *)buffer)[2] << 8 | ((CK_BYTE *)buffer)[3]); // *buffer++ = value; // } } void shaUpdate( SHA1_CONTEXT * ctx, CK_BYTE const * buffer, CK_ULONG count) { CK_ULONG t; // Update bitcount // t = ctx->bits_lo; if ((ctx->bits_lo = t + count) < t) ctx->bits_hi++; // Carry from low to high t &= 0x3f; // Bytes already in ctx->buf // Handle any leading odd-sized chunks // if (t) { CK_BYTE *p = (CK_BYTE *)ctx->buf + t; t = 64-t; if (count < t) { memcpy(p, buffer, count); return; } memcpy(p, buffer, t); byteReverse(ctx->buf, SHA1_BLOCK_SIZE); shaTransform(ctx); buffer += t; count -= t; } // Process data in SHA1_BLOCK_SIZE chunks // while (count >= SHA1_BLOCK_SIZE) { memcpy(ctx->buf, buffer, SHA1_BLOCK_SIZE); byteReverse(ctx->buf, SHA1_BLOCK_SIZE); shaTransform(ctx); buffer += SHA1_BLOCK_SIZE; count -= SHA1_BLOCK_SIZE; } // Handle any remaining bytes of data. // memcpy(ctx->buf, buffer, count); } // Final wrapup - pad to 64-byte boundary with the bit pattern // 1 0* (64-bit count of bits processed, MSB-first) // void shaFinal( SHA1_CONTEXT * ctx, CK_BYTE * hash ) { int count; CK_BYTE *p; // Compute number of bytes mod 64 // count = (int)ctx->bits_lo & 0x3F; // Set the first char of padding to 0x80. // This is safe since there is always at least one byte free // p = (CK_BYTE *)ctx->buf + count; *p++ = 0x80; // Bytes of padding needed to make 64 bytes // count = SHA1_BLOCK_SIZE - 1 - count; // Pad out to 56 mod 64 // if (count < 8) { // Two lots of padding: Pad the first block to 64 bytes // memset(p, 0, count); byteReverse(ctx->buf, SHA1_BLOCK_SIZE); shaTransform(ctx); // Now fill the next block with 56 bytes // memset(ctx->buf, 0, SHA1_BLOCK_SIZE-8); } else { // Pad block to 56 bytes // memset(p, 0, count-8); } byteReverse(ctx->buf, SHA1_BLOCK_SIZE-8); // Append length in *bits* and transform // ctx->buf[14] = ctx->bits_hi << 3 | ctx->bits_lo >> 29; ctx->buf[15] = ctx->bits_lo << 3; shaTransform(ctx); // Store output hash in buffer // byteReverse(ctx->hash_value, SHA1_HASH_SIZE); memcpy(hash, ctx->hash_value, SHA1_HASH_SIZE); } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/mech_des3.c0000640000175000017500000014334511327631345021436 0ustar jfjf /* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */ /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */ // File: mech_des3.c // // Mechanisms for DES3 // //#include #include // for memcmp() et al #include #include "pkcs11/pkcs11types.h" #include #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" //#include "args.h" // // CK_RV des3_ecb_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES3_ECB requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des3_ecb_encrypt( in_data, in_data_len, out_data, out_data_len, key_value ); } // // CK_RV des3_ecb_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES3_ECB requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des3_ecb_decrypt( in_data, in_data_len, out_data, out_data_len, key_value ); } // // CK_RV des3_cbc_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES3_CBC requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des3_cbc_encrypt( in_data, in_data_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); } // // CK_RV des3_cbc_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES3_CBC requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des3_cbc_decrypt( in_data, in_data_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); } // // CK_RV des3_cbc_pad_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE *clear = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_ULONG padded_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // DES3-CBC-PAD has no input length requirements // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); // compute the output length, accounting for padding // padded_len = DES_BLOCK_SIZE * (in_data_len / DES_BLOCK_SIZE + 1); if (length_only == TRUE) { *out_data_len = padded_len; return CKR_OK; } if (*out_data_len < padded_len) { *out_data_len = padded_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } clear = (CK_BYTE *)malloc( padded_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( clear, in_data, in_data_len ); add_pkcs_padding( clear + in_data_len, DES_BLOCK_SIZE, in_data_len, padded_len ); rc = ckm_des3_cbc_encrypt( clear, padded_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); if (rc != CKR_OK) st_err_log(105, __FILE__, __LINE__); free( clear ); return rc; } // // CK_RV des3_cbc_pad_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE *clear = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_ULONG padded_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // no need to validate the input length since we'll pad as necessary // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); // we're decrypting so even with CBC-PAD, we should have an integral // number of block to decrypt // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } // the amount of cleartext after stripping the padding will actually be less // than the input bytes... // padded_len = in_data_len; if (length_only == TRUE) { *out_data_len = padded_len; return CKR_OK; } clear = (CK_BYTE *)malloc( padded_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } rc = ckm_des3_cbc_decrypt( in_data, in_data_len, clear, &padded_len, ctx->mech.pParameter, key_value ); if (rc == CKR_OK) { strip_pkcs_padding( clear, padded_len, out_data_len ); memcpy( out_data, clear, *out_data_len ); } else st_err_log(106, __FILE__, __LINE__); free( clear ); return rc; } // // CK_RV des3_ecb_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % DES_BLOCK_SIZE); out_len = (total - remain); // should always be at least 1 block if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); rc = ckm_des3_ecb_encrypt( clear, out_len, out_data, out_data_len, key_value ); if (rc == CKR_OK) { *out_data_len = out_len; // update the context buffer. we already used the buffer's current // contents so we completely overwrite it // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } free( clear ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // shouldn't reach this } // // CK_RV des3_ecb_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % DES_BLOCK_SIZE); out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_des3_ecb_decrypt( cipher, out_len, out_data, out_data_len, key_value ); if (rc == CKR_OK) { *out_data_len = out_len; // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(105, __FILE__, __LINE__); free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // shouldn't reach this } // // CK_RV des3_cbc_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % DES_BLOCK_SIZE); out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); // these buffers need to be longword aligned // clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); rc = ckm_des3_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); if (rc == CKR_OK) { *out_data_len = out_len; // the new init_v is the last encrypted data block // memcpy( ctx->mech.pParameter, out_data + (*out_data_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(105, __FILE__, __LINE__); free( clear ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV des3_cbc_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = context->len + in_data_len; if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = total % DES_BLOCK_SIZE; out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); // these buffers need to be longword aligned // cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_des3_cbc_decrypt( cipher, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); if (rc == CKR_OK) { *out_data_len = out_len; // the new init_v is the last input data block // memcpy( ctx->mech.pParameter, cipher + (out_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(106, __FILE__, __LINE__); free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV des3_cbc_pad_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); // note, this is subtly different from the other encrypt update routines // if (total <= DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { remain = (total % DES_BLOCK_SIZE); out_len = total - remain; // out_len is a multiple of DES_BLOCK_SIZE if (remain == 0) { remain = DES_BLOCK_SIZE; out_len -= DES_BLOCK_SIZE; } if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } // at this point, we should have: // 1) remain != 0 // 2) out_len != 0 // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); // these buffers need to be longword aligned // clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); // // we don't do padding during the update // rc = ckm_des3_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); if (rc == CKR_OK) { // the new init_v is the last encrypted data block // memcpy( ctx->mech.pParameter, out_data + (*out_data_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the temporary space // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } free( clear ); return rc; } } // // CK_RV des3_cbc_pad_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); // note, this is subtly different from the other decrypt update routines // if (total <= DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block + 1 byte // remain = total % DES_BLOCK_SIZE; out_len = total - remain; if (remain == 0) { remain = DES_BLOCK_SIZE; out_len -= DES_BLOCK_SIZE; } if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } // at this point, we should have: // 1) remain != 0 // 2) out_len != 0 // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); // these buffers need to be longword aligned // cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_des3_cbc_decrypt( cipher, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); if (rc == CKR_OK) { // the new init_v is the last input data block // memcpy( ctx->mech.pParameter, cipher + (out_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the temporary space // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV des3_ecb_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES3-ECB does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV des3_ecb_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES3-ECB does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV des3_cbc_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES3-CBC does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV des3_cbc_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES3-CBC does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV des3_cbc_pad_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE clear[2*DES_BLOCK_SIZE]; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_ULONG out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); context = (DES_CONTEXT *)ctx->context; // there will never be more than one block in the context buffer // so the amount of output is as follows: // if less than 1 block stored, we generate one block of output // if a full block is stored, we generate two blocks of output (one pad block) // if (context->len == DES_BLOCK_SIZE) out_len = 2 * DES_BLOCK_SIZE; else out_len = DES_BLOCK_SIZE; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } else { memcpy( clear, context->data, context->len ); add_pkcs_padding( clear + context->len, DES_BLOCK_SIZE, context->len, out_len ); rc = ckm_des3_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); if (rc != CKR_OK) st_err_log(105, __FILE__, __LINE__); return rc; } } // // CK_RV des3_cbc_pad_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE clear[DES_BLOCK_SIZE]; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_ULONG out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); context = (DES_CONTEXT *)ctx->context; // there had better be a full block in the context buffer // if (context->len != DES_BLOCK_SIZE){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } // we don't know a priori how much data we'll be returning. we won't // know until after we decrypt it and strip the padding. it's possible // that we'll return nothing (the final block might be a padding block). // out_len = DES_BLOCK_SIZE; // upper bound on what we'll return if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } else { rc = ckm_des3_cbc_decrypt( context->data, DES_BLOCK_SIZE, clear, &out_len, ctx->mech.pParameter, key_value ); if (rc == CKR_OK) { strip_pkcs_padding( clear, out_len, &out_len ); if (out_len != 0) memcpy( out_data, clear, out_len ); *out_data_len = out_len; } else st_err_log(106, __FILE__, __LINE__); return rc; } } // // mechanisms // // // CK_RV ckm_des3_key_gen( TEMPLATE *tmpl ) { CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * key_type_attr = NULL; CK_ATTRIBUTE * class_attr = NULL; CK_ATTRIBUTE * local_attr = NULL; CK_BYTE des_key[3 * DES_KEY_SIZE]; CK_ULONG req_len, repl_len, expected_repl_len; CK_ULONG rc; rc = token_specific.t_des_key_gen(des_key, sizeof(des_key)); if (rc != CKR_OK) return rc; value_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + 3*DES_KEY_SIZE ); key_type_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); class_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS) ); local_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!value_attr || !key_type_attr || !class_attr || !local_attr) { if (value_attr) free( value_attr ); if (key_type_attr) free( key_type_attr ); if (class_attr) free( class_attr ); if (local_attr) free( local_attr ); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 3 * DES_KEY_SIZE; value_attr->pValue = (CK_BYTE *)value_attr + sizeof(CK_ATTRIBUTE); memcpy( value_attr->pValue, des_key, 3 * DES_KEY_SIZE ); key_type_attr->type = CKA_KEY_TYPE; key_type_attr->ulValueLen = sizeof(CK_KEY_TYPE); key_type_attr->pValue = (CK_BYTE *)key_type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)key_type_attr->pValue = CKK_DES3; class_attr->type = CKA_CLASS; class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS); class_attr->pValue = (CK_BYTE *)class_attr + sizeof(CK_ATTRIBUTE); *(CK_OBJECT_CLASS *)class_attr->pValue = CKO_SECRET_KEY; local_attr->type = CKA_LOCAL; local_attr->ulValueLen = sizeof(CK_BBOOL); local_attr->pValue = (CK_BYTE *)local_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)local_attr->pValue = TRUE; template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, key_type_attr ); template_update_attribute( tmpl, class_attr ); template_update_attribute( tmpl, local_attr ); return CKR_OK; } // // CK_RV ckm_des3_ecb_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * key_value ) { CK_ULONG req_len, repl_len, expected_repl_len; CK_ULONG rc; if (!in_data || !out_data || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_tdes_ecb(in_data,in_data_len,out_data, out_data_len, key_value, 1); if (rc != CKR_OK) st_err_log(120, __FILE__, __LINE__); return rc; } // // CK_RV ckm_des3_ecb_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * key_value ) { CK_ULONG req_len, repl_len, expected_repl_len; CK_ULONG rc; if (!in_data || !out_data || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_tdes_ecb(in_data,in_data_len,out_data, out_data_len, key_value, 0); if (rc != CKR_OK) st_err_log(120, __FILE__, __LINE__); return rc; } // // CK_RV ckm_des3_cbc_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * init_v, CK_BYTE * key_value ) { CK_ULONG req_len, repl_len, expected_repl_len; CK_ULONG rc; if (!in_data || !out_data || !init_v || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ #if 0 st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; #else *out_data_len = in_data_len; st_err_log(68, __FILE__, __FUNCTION__); return CKR_BUFFER_TOO_SMALL; #endif } rc = token_specific.t_tdes_cbc(in_data,in_data_len,out_data,out_data_len, key_value,init_v,1); if (rc != CKR_OK) st_err_log(119, __FILE__, __LINE__); return rc; } // // CK_RV ckm_des3_cbc_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * init_v, CK_BYTE * key_value ) { CK_ULONG req_len, repl_len, expected_repl_len; CK_ULONG rc; if (!in_data || !out_data || !init_v || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_tdes_cbc(in_data,in_data_len,out_data,out_data_len, key_value,init_v,0); if (rc != CKR_OK) st_err_log(119, __FILE__, __LINE__); return rc; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/tpm_openssl.c0000640000175000017500000001140611327631345022137 0ustar jfjf /* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pkcs11/pkcs11types.h" #include "pkcs11/stdll.h" #include "defs.h" #include "host_defs.h" #include "../common/args.h" #include "h_extern.h" #include "tok_specific.h" #include "tok_spec_struct.h" #include "tpm_specific.h" #ifdef DEBUG void openssl_print_errors() { ERR_load_ERR_strings(); ERR_load_crypto_strings(); ERR_print_errors_fp(stderr); } #endif RSA * openssl_gen_key() { RSA *rsa; int rc, counter = 0; char buf[32]; token_rng((CK_BYTE *)buf, 32); RAND_seed(buf, 32); regen_rsa_key: rsa = RSA_generate_key(2048, 65537, NULL, NULL); if (rsa == NULL) { fprintf(stderr, "Error generating user's RSA key\n"); ERR_load_crypto_strings(); ERR_print_errors_fp(stderr); return NULL; } rc = RSA_check_key(rsa); switch (rc) { case 0: /* rsa is not a valid RSA key */ RSA_free(rsa); counter++; if (counter == KEYGEN_RETRY) { LogDebug("Tried %d times to generate a " "valid RSA key, failed.\n", KEYGEN_RETRY); return NULL; } goto regen_rsa_key; break; case 1: /* success case, rsa is a valid key */ break; case -1: /* fall through */ default: DEBUG_openssl_print_errors(); break; } return rsa; } int openssl_write_key(RSA *rsa, char *filename, CK_BYTE *pPin) { BIO *b = NULL; char loc[PATH_MAX]; struct passwd *pw = NULL; errno = 0; if ((pw = getpwuid(getuid())) == NULL) { LogError("%s: Error getting username: %s", __FUNCTION__, strerror(errno)); return -1; } sprintf(loc, "%s/%s/%s", pk_dir, pw->pw_name, filename); b = BIO_new_file(loc, "w"); if (!b) { LogError("%s: Error opening file for write: %s", __FUNCTION__, loc); return -1; } if (!PEM_write_bio_RSAPrivateKey(b, rsa, EVP_aes_256_cbc(), NULL, 0, 0, pPin)) { BIO_free(b); LogError("Writing key %s to disk failed.", loc); DEBUG_openssl_print_errors(); return -1; } BIO_free(b); if (util_set_file_mode(loc, (S_IRUSR|S_IWUSR))) { LogError("Setting file mode of %s failed", loc); } return 0; } CK_RV openssl_read_key(char *filename, CK_BYTE *pPin, RSA **ret) { BIO *b = NULL; RSA *rsa = NULL; char loc[PATH_MAX]; struct passwd *pw = NULL; CK_RV rc = CKR_FUNCTION_FAILED; errno = 0; if ((pw = getpwuid(getuid())) == NULL) { LogError("%s: Error getting username: %s", __FUNCTION__, strerror(errno)); return CKR_FUNCTION_FAILED; } sprintf(loc, "%s/%s/%s", pk_dir, pw->pw_name, filename); /* we can't allow a pin of NULL here, since openssl will try to prompt * for a password in PEM_read_bio_RSAPrivateKey */ if (pPin == NULL) return CKR_PIN_INCORRECT; b = BIO_new_file(loc, "r+"); if (b == NULL) { LogError("%s: Error opening file for read: %s", __FUNCTION__, loc); return CKR_FILE_NOT_FOUND; } if ((rsa = PEM_read_bio_RSAPrivateKey(b, NULL, 0, pPin)) == NULL) { LogError("Reading key %s from disk failed.", loc); DEBUG_openssl_print_errors(); if (ERR_GET_REASON(ERR_get_error()) == PEM_R_BAD_DECRYPT) { rc = CKR_PIN_INCORRECT; } BIO_free(b); return rc; } BIO_free(b); *ret = rsa; return CKR_OK; } int openssl_get_modulus_and_prime(RSA *rsa, unsigned int *size_n, unsigned char *n, unsigned int *size_p, unsigned char *p) { /* get the modulus from the RSA object */ if ((*size_n = BN_bn2bin(rsa->n, n)) <= 0) { DEBUG_openssl_print_errors(); return -1; } /* get one of the primes from the RSA object */ if ((*size_p = BN_bn2bin(rsa->p, p)) <= 0) { DEBUG_openssl_print_errors(); return -1; } return 0; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/utility.c0000640000175000017500000006372511327631345021312 0ustar jfjf /* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */ /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */ #include #include #include #include #include #include #include #include #include #include #include #include "pkcs11/pkcs11types.h" #include #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" #include "pkcs32.h" #if (SPINXPL) #include #endif // Function: dlist_add_as_first() // // Adds the specified node to the start of the list // // Returns: pointer to the start of the list // DL_NODE * dlist_add_as_first( DL_NODE *list, void *data ) { DL_NODE *node = NULL; if (!data) return list; node = (DL_NODE *)malloc(sizeof(DL_NODE)); if (!node) return NULL; node->data = data; node->prev = NULL; node->next = list; if ( list) list->prev = node; return node; } // Function: dlist_add_as_last() // // Adds the specified node to the end of the list // // Returns: pointer to the start of the list // DL_NODE * dlist_add_as_last( DL_NODE *list, void *data ) { DL_NODE *node = NULL; if (!data) return list; node = (DL_NODE *)malloc(sizeof(DL_NODE)); if (!node) return NULL; node->data = data; node->next = NULL; if (!list) { node->prev = NULL; return node; } else { DL_NODE *temp = dlist_get_last( list ); temp->next = node; node->prev = temp; return list; } } // Function: dlist_find() // DL_NODE * dlist_find( DL_NODE *list, void *data ) { DL_NODE *node = list; while (node && node->data != data) node = node->next; return node; } // Function: dlist_get_first() // // Returns the last node in the list or NULL if list is empty // DL_NODE * dlist_get_first( DL_NODE *list ) { DL_NODE *temp = list; if (!list) return NULL; while (temp->prev != NULL) temp = temp->prev; return temp; } // Function: dlist_get_last() // // Returns the last node in the list or NULL if list is empty // DL_NODE * dlist_get_last( DL_NODE *list ) { DL_NODE *temp = list; if (!list) return NULL; while (temp->next != NULL) temp = temp->next; return temp; } // // CK_ULONG dlist_length( DL_NODE *list ) { DL_NODE *temp = list; CK_ULONG len = 0; while (temp) { len++; temp = temp->next; } return len; } // // DL_NODE * dlist_next( DL_NODE *node ) { if (!node) return NULL; return node->next; } // // DL_NODE * dlist_prev( DL_NODE *node ) { if (!node) return NULL; return node->prev; } // // void dlist_purge( DL_NODE *list ) { DL_NODE *node; if (!list) return; do { node = list->next; free( list ); list = node; } while ( list ); } // Function: dlist_remove_node() // // Attempts to remove the specified node from the list. The caller is // responsible for freeing the data associated with the node prior to // calling this routine // DL_NODE * dlist_remove_node( DL_NODE *list, DL_NODE *node ) { DL_NODE *temp = list; if (!list || !node) return NULL; // special case: removing head of the list // if (list == node) { temp = list->next; if (temp) temp->prev = NULL; free( list ); return temp; } // we have no guarantee that the node is in the list // so search through the list to find it // while ((temp != NULL) && (temp->next != node)) temp = temp->next; if (temp != NULL) { DL_NODE *next = node->next; temp->next = next; if (next) next->prev = temp; free( node ); } return list; } // NOTE about Mutexes and cross process locking.... // // The code uses 2 types of locks... internal locks to prevent threads within the same // process space from stomping on each other (pthread_mutex's suffice for // this).... and Cross Process Locks.... // On AIX we use it's variation of Posix semaphores for this.... Idealy on other // platforms either POSIXSEMaphores or PTHREADXPL (pthreads xprocess lock) would // be used. On Linux unfortunatly neither of these are available so we need to // use the old standby of SYSV semaphores (YECH.... GAG....).... The only // pieces which have been tested are the AIX and SYSV portions although // we expect that the others work correctly. // // we use alot more mutexes in the redesign than we did in the original // design. so instead of just the single global "pkcs_mutex" we have to // deal with a number of mutexes. so we'll make the mutex routines a // bit more generic. // CK_RV _CreateMutex( MUTEX *mutex ) { CK_RV rc; // on AIX we make this a no-op since we assume that // the mutex was created in the initialization pthread_mutex_init( mutex, NULL ); return CKR_OK; } CK_RV _CreateMsem( sem_t *msem ) { if (!sem_init( msem,0, 1)) // parm 2 non-0 means pshared 1 is unlocked 0 is locked //if (!sem_init( msem,1, 1)) // parm 2 non-0 means pshared 1 is unlocked 0 is locked return CKR_OK; else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } CK_RV _DestroyMutex( MUTEX *mutex ) { CK_RV rc; // no-op in AIX pthread_mutex_destroy((pthread_mutex_t *)mutex); return CKR_OK; } CK_RV _DestroyMsem( sem_t *msem ) { if (!sem_destroy(msem)) return CKR_OK; else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } CK_RV _LockMutex( MUTEX *mutex ) { pthread_mutex_lock( mutex); return CKR_OK; } CK_RV _LockMsem( sem_t *msem ) { if (!msem){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if(!sem_wait(msem)) // block until the semaphore is free return CKR_OK; else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } CK_RV _UnlockMutex( MUTEX *mutex ) { pthread_mutex_unlock(mutex); return CKR_OK; } CK_RV _UnlockMsem( sem_t *msem ) { if (!msem){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!sem_post(msem)) return CKR_OK; else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } #if SYSVSEM #include // These structures are needed to effect a lock // using SYS V semaphores... static struct sembuf xlock_lock[2]={ 0,0,0, 0,1,SEM_UNDO }; static struct sembuf xlock_unlock[1] = { 0,-1,(IPC_NOWAIT | SEM_UNDO) }; static pthread_mutex_t semmtx = PTHREAD_MUTEX_INITIALIZER; #endif int spinxplfd=-1; int spin_created=0; extern void set_perm(int); CK_RV CreateXProcLock(void *xproc) { #if (SPINXPL) // open the file that we will do the locking on... spinxplfd = open("/tmp/.pkcs11spinloc",O_CREAT|O_APPEND|O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO); if (spinxplfd) { set_perm(spinxplfd); fchmod(spinxplfd,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH | S_IWOTH); spin_created=1; } else { perror("XPROC CREATE file :"); } return CKR_OK; #elif SYSVSEM int semid; int *psem; key_t tok; tok = ftok( pk_dir, 'c' ); //printf("creating semaphore %x \n",tok); psem = (int *)xproc; if ( *psem < 0 ) { if ( (semid = semget(tok,1,IPC_CREAT | 0666)) < 0 ){ if (errno == EEXIST) { if ( (semid = semget(tok,0,0)) < 0) { pthread_mutex_unlock(&semmtx); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } else { pthread_mutex_unlock(&semmtx); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } } psem = (int *)xproc; *psem = semid; //pthread_mutex_unlock(&semmtx); return CKR_OK; // we know that semaphores are created unlocked #elif POSIXSEM return _CreateMsem((sem_t *)xproc); #elif PTHREADXPL pthread_mutex_attr_t mtxattr; pthread_mutexattr_init(&mtxattr); pthread_mutexattr_setpshared(&mtxattr,PTHREAD_PROCESS_SHARED); pthread_mutex_init((pthread_mutex_t *)xproc,&mtxattr); #elif NOXPROCLOCK return CKR_OK; #else #error "Define XPROC LOCKS" #endif } CK_RV DestroyXProcLock(void *xproc) { #if SPINXPL return CKR_OK; #elif SYSVSEM int semid,*psem; //printf("Destroying semaphore %x \n",xproc); pthread_mutex_lock(&semmtx); psem = (int *)xproc; semid = *psem; semctl(semid,1,IPC_RMID,0); pthread_mutex_unlock(&semmtx); return CKR_OK; #elif POSIXSEM return _DestroyMsem((sem_t *)xproc); #elif PTHREADXPL return pthread_mutex_destroy((pthread_mutex_t *)xproc); #elif NOXPROCLOCK return CKR_OK; #else #error "Define XPROC LOCKS" #endif } CK_RV XProcLock(void *xproc) { #if SPINXPL if (!spin_created) { spinxplfd = open("/tmp/.pkcs11spinloc",O_CREAT|O_APPEND|O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO); fchmod(spinxplfd,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH | S_IWOTH); spin_created=1; } if (spinxplfd){ flock(spinxplfd,LOCK_EX); } return CKR_OK; #elif SYSVSEM int semid,*psem; pthread_mutex_lock(&semmtx); return CKR_OK; pthread_mutex_lock(&semmtx); psem = (int *)xproc; semid = *psem; semop(semid,&xlock_lock[0],2); pthread_mutex_unlock(&semmtx); return CKR_OK; #elif POSIXSEM return _LockMsem((sem_t *)xproc); #elif PTHREADXPL return _LockMutex((MUTEX *)xproc); #elif NOXPROCLOCK return CKR_OK; #else #error "Define XPROC LOCKS" #endif } CK_RV XProcUnLock(void *xproc) { #if SPINXPL if (!spin_created) { spinxplfd = open("/tmp/.pkcs11spinloc",O_CREAT|O_APPEND|O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO); fchmod(spinxplfd,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH | S_IWOTH); spin_created=1; } if (spinxplfd) { flock(spinxplfd,LOCK_UN); } return CKR_OK; #elif SYSVSEM int semid,*psem; pthread_mutex_unlock(&semmtx); return CKR_OK; pthread_mutex_lock(&semmtx); psem = (int *)xproc; semid = *psem; semop(semid,&xlock_unlock[0],1); pthread_mutex_unlock(&semmtx); return CKR_OK; #elif POSIXSEM return _UnlockMsem((sem_t *)xproc); #elif PTHREADXPL return _UnlockMutex((MUTEX *)xproc); #elif NOXPROCLOCK return CKR_OK; #else #error "Define XPROC LOCKS" #endif } // // // is_attribute_defined() // // determine whether the specified attribute is defined by Cryptoki // CK_BBOOL is_attribute_defined( CK_ATTRIBUTE_TYPE type ) { if (type >= CKA_VENDOR_DEFINED) return TRUE; switch (type) { case CKA_CLASS: case CKA_TOKEN: case CKA_PRIVATE: case CKA_LABEL: case CKA_APPLICATION: case CKA_VALUE: case CKA_CERTIFICATE_TYPE: case CKA_ISSUER: case CKA_SERIAL_NUMBER: case CKA_KEY_TYPE: case CKA_SUBJECT: case CKA_ID: case CKA_SENSITIVE: case CKA_ENCRYPT: case CKA_DECRYPT: case CKA_WRAP: case CKA_UNWRAP: case CKA_SIGN: case CKA_SIGN_RECOVER: case CKA_VERIFY: case CKA_VERIFY_RECOVER: case CKA_DERIVE: case CKA_START_DATE: case CKA_END_DATE: case CKA_MODULUS: case CKA_MODULUS_BITS: case CKA_PUBLIC_EXPONENT: case CKA_PRIVATE_EXPONENT: case CKA_PRIME_1: case CKA_PRIME_2: case CKA_EXPONENT_1: case CKA_EXPONENT_2: case CKA_COEFFICIENT: case CKA_PRIME: case CKA_SUBPRIME: case CKA_BASE: case CKA_VALUE_BITS: case CKA_VALUE_LEN: case CKA_EXTRACTABLE: case CKA_LOCAL: case CKA_NEVER_EXTRACTABLE: case CKA_ALWAYS_SENSITIVE: case CKA_MODIFIABLE: case CKA_ECDSA_PARAMS: case CKA_EC_POINT: case CKA_HW_FEATURE_TYPE: case CKA_HAS_RESET: case CKA_RESET_ON_INIT: case CKA_KEY_GEN_MECHANISM: case CKA_PRIME_BITS: case CKA_SUBPRIME_BITS: case CKA_OBJECT_ID: case CKA_AC_ISSUER: case CKA_OWNER: case CKA_ATTR_TYPES: case CKA_TRUSTED: return TRUE; } return FALSE; } extern CK_CHAR manuf[]; extern CK_CHAR model[]; extern CK_CHAR descr[]; extern CK_CHAR label[]; // // void init_slotInfo( void ) { memset( &slot_info.slotDescription, ' ', sizeof(slot_info.slotDescription) ); memset( &slot_info.manufacturerID, ' ', sizeof(slot_info.manufacturerID) ); memcpy( &slot_info.slotDescription, descr, strlen((char *)descr) ); memcpy( &slot_info.manufacturerID, manuf, strlen((char *)manuf) ); slot_info.hardwareVersion.major = 1; slot_info.hardwareVersion.minor = 0; slot_info.firmwareVersion.major = 1; slot_info.firmwareVersion.minor = 0; slot_info.flags = CKF_TOKEN_PRESENT | CKF_HW_SLOT; } // // void init_tokenInfo( void ) { CK_TOKEN_INFO_32 *token_info = NULL; CK_ULONG len; token_info = &nv_token_data->token_info; memset( token_info->manufacturerID, ' ', sizeof(token_info->manufacturerID) ); memset( token_info->model, ' ', sizeof(token_info->model) ); memset( token_info->serialNumber, ' ', sizeof(token_info->serialNumber) ); memcpy( token_info->label, nv_token_data->token_info.label, 32 ); memcpy( token_info->manufacturerID, manuf, strlen((char *)manuf) ); memcpy( token_info->model, model, strlen((char *)model) ); // use the 41-xxxxx serial number from the coprocessor // memcpy( token_info->serialNumber, "123" , 3 ); // I don't see any API support for changing the clock so // we will use the system clock for the token's clock. // token_info->flags = CKF_RNG | CKF_LOGIN_REQUIRED | CKF_CLOCK_ON_TOKEN | CKF_SO_PIN_TO_BE_CHANGED; // XXX New in v2.11 - KEY if (memcmp(nv_token_data->user_pin_sha, "00000000000000000000", SHA1_HASH_SIZE) != 0) token_info->flags |= CKF_USER_PIN_INITIALIZED; else token_info->flags |= CKF_USER_PIN_TO_BE_CHANGED; // XXX New in v2.11 - KEY // For the release, we made these // values as CK_UNAVAILABLE_INFORMATION // token_info->ulMaxSessionCount = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->ulSessionCount = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->ulMaxRwSessionCount = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->ulRwSessionCount = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->ulMaxPinLen = MAX_PIN_LEN; token_info->ulMinPinLen = MIN_PIN_LEN; token_info->ulTotalPublicMemory = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->ulFreePublicMemory = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->ulTotalPrivateMemory = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->ulFreePrivateMemory = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->hardwareVersion.major = 1; token_info->hardwareVersion.minor = 0; token_info->firmwareVersion.major = 1; token_info->firmwareVersion.minor = 0; memset( token_info->utcTime, ' ', sizeof(token_info->utcTime) ); } // // CK_RV init_token_data( void ) { CK_RV rc; memset( (char *)nv_token_data, 0, sizeof(nv_token_data) ); // the normal USER pin is not set when the token is initialized // memcpy( nv_token_data->user_pin_sha, "00000000000000000000", SHA1_HASH_SIZE ); memcpy( nv_token_data->so_pin_sha, default_so_pin_sha, SHA1_HASH_SIZE ); memset( user_pin_md5, 0x0, MD5_HASH_SIZE ); memcpy( so_pin_md5, default_so_pin_md5, MD5_HASH_SIZE ); memcpy( nv_token_data->next_token_object_name, "00000000", 8 ); // generate the master key used for signing the Operation State information // ` memset( nv_token_data->token_info.label, ' ', sizeof(nv_token_data->token_info.label) ); memcpy( nv_token_data->token_info.label, label, strlen((char *)label) ); nv_token_data->tweak_vector.allow_weak_des = TRUE; nv_token_data->tweak_vector.check_des_parity = FALSE; nv_token_data->tweak_vector.allow_key_mods = TRUE; nv_token_data->tweak_vector.netscape_mods = TRUE; init_tokenInfo(); // // FIXME: erase the token object index file (and all token objects) // #if 0 rc = rng_generate( master_key, 3 * DES_KEY_SIZE ); if (rc != CKR_OK){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = save_masterkey_so(); if (rc != CKR_OK){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } #endif rc = save_token_data(); if (rc != CKR_OK) st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return rc; } // Function: compute_next_token_obj_name() // // Given a token object name (8 bytes in the range [0-9A-Z]) increment by one // adjusting as necessary // // This gives us a namespace of 36^8 = 2,821,109,907,456 objects before wrapping around // CK_RV compute_next_token_obj_name( CK_BYTE *current, CK_BYTE *next ) { int val[8]; int i; if (!current || !next){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Convert to integral base 36 // for (i = 0; i < 8; i++) { if (current[i] >= '0' && current[i] <= '9') val[i] = current[i] - '0'; if (current[i] >= 'A' && current[i] <= 'Z') val[i] = current[i] - 'A' + 10; } val[0]++; i=0; while (val[i] > 35) { val[i] = 0; if (i+1 < 8) { val[i+1]++; i++; } else { val[0]++; i = 0; // start pass 2 } } // now, convert back to [0-9A-Z] // for (i = 0; i < 8; i++) { if (val[i] < 10) next[i] = '0' + val[i]; else next[i] = 'A' + val[i] - 10; } return CKR_OK; } // // CK_RV build_attribute( CK_ATTRIBUTE_TYPE type, CK_BYTE *data, CK_ULONG data_len, CK_ATTRIBUTE **attrib ) { CK_ATTRIBUTE *attr = NULL; attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + data_len ); if (!attr){ st_err_log(0, __FILE__, __LINE__); return CKR_DEVICE_MEMORY; } attr->type = type; attr->ulValueLen = data_len; if (data_len > 0) { attr->pValue = (CK_BYTE *)attr + sizeof(CK_ATTRIBUTE); memcpy( attr->pValue, data, data_len ); } else attr->pValue = NULL; *attrib = attr; return CKR_OK; } // // CK_RV add_pkcs_padding( CK_BYTE * ptr, CK_ULONG block_size, CK_ULONG data_len, CK_ULONG total_len ) { CK_ULONG i, pad_len; CK_BYTE pad_value; pad_len = block_size - (data_len % block_size); pad_value = (CK_BYTE)pad_len; if (data_len + pad_len > total_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } for (i = 0; i < pad_len; i++) ptr[i] = pad_value; return CKR_OK; } // // CK_RV strip_pkcs_padding( CK_BYTE * ptr, CK_ULONG total_len, CK_ULONG * data_len ) { CK_BYTE pad_value; pad_value = ptr[total_len - 1]; // thus, we have 'pad_value' bytes of 'pad_value' appended to the end // *data_len = total_len - pad_value; return CKR_OK; } // // CK_RV remove_leading_zeros( CK_ATTRIBUTE *attr ) { CK_BYTE *ptr = NULL; CK_ULONG new_len, i; ptr = attr->pValue; for (i = 0; i < attr->ulValueLen; i++) { if (ptr[i] != 0x0) break; } new_len = attr->ulValueLen - i; memcpy( ptr, ptr + i, new_len ); attr->ulValueLen = new_len; return CKR_OK; } // // CK_BYTE parity_adjust( CK_BYTE b ) { if (parity_is_odd(b) == FALSE) b = (b & 0xFE) | ((~b) & 0x1); return b; } // // CK_RV parity_is_odd( CK_BYTE b ) { b = ((b >> 4) ^ b) & 0x0f; b = ((b >> 2) ^ b) & 0x03; b = ((b >> 1) ^ b) & 0x01; if (b == 1) return TRUE; else return FALSE; } CK_RV attach_shm() { key_t key; int shm_id; struct stat statbuf; CK_BBOOL created = FALSE; void *temp = NULL; #if !(NOSHM) && !(MMAP) // Change TOK_PATH2 to be the directory // of the data store specified. This way we // have a unique key shared memory for each // token object database if (stat(pk_dir, &statbuf) < 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); LogError("pk_dir = \"%s\"", pk_dir); return CKR_FUNCTION_FAILED; } key = ftok( pk_dir, 'c' ); shm_id = shmget( key, sizeof(LW_SHM_TYPE), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH | IPC_CREAT | IPC_EXCL); if (shm_id < 0) { #if 0 if ((errno != EACCES) && (errno != EEXIST)) { fflush(stdout); fflush(stderr); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } #endif // SAB XXX it appears that in some cases linux does not set // the errno properly on a shmget failure... so if the create // failed we'll just try and attach.... If the basic attach // fails, then we can error out... // SHM segment already exists... // shm_id = shmget( key, sizeof(LW_SHM_TYPE), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ); //if ((errno != EACCES) && (errno != EEXIST)) { if (shm_id < 0) { fflush(stdout); fflush(stderr); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } else { created = TRUE; } global_shm = (void *)shmat( shm_id, NULL, 0 ); if (!global_shm){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (created == TRUE) { #if !(SYSVSEM) // SYSV sem's are a global that is handled in the // Initialize routine... all others are stored in the // shared memory segment so we have to do // this here after the segment is created // to prevent a core dump CreateXProcLock( &global_shm->mutex ); xproclock = (void *)&global_shm->mutex; // need to do this here #endif XProcLock( xproclock ); global_shm->num_publ_tok_obj = 0; global_shm->num_priv_tok_obj = 0; memset( &global_shm->publ_tok_objs, 0x0, 2048 * sizeof(TOK_OBJ_ENTRY) ); memset( &global_shm->priv_tok_objs, 0x0, 2048 * sizeof(TOK_OBJ_ENTRY) ); XProcUnLock( xproclock ); } else { xproclock = (void *)&global_shm->mutex; } #elif MMAP { #define FILENAME ".stmapfile" //#define MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) //#define MODE (S_IRUSR|S_IWUSR) //#warning "EXPERIMENTAL" char *fname = NULL, *dirname = NULL; char *b2 = NULL; int fd = -1, i; struct passwd *pw = NULL; mode_t mode = (S_IRUSR | S_IWUSR | S_IXUSR); CK_RV rc; /* manpage decrees that errno must be set to 0 if we want to check it on * error.. */ errno = 0; pw = getpwuid(getuid()); if (pw == NULL) { LogError("getpwuid failed: %s", strerror(errno)); return CKR_FUNCTION_FAILED; } // STAT the directory to see if it exists... If not, then create it dirname = malloc(strlen(pk_dir) + strlen(pw->pw_name) + strlen(PK_LITE_OBJ_DIR) + 2); if (dirname) { sprintf(dirname, "%s/%s", pk_dir, pw->pw_name); } else { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_HOST_MEMORY; } // if the user specific directory doesn't exist, create it and userdir/TOK_OBJ if (stat(dirname, &statbuf) < 0) { if (mkdir(dirname, mode) == -1) { LogError("%s: mkdir(%s): %s", __FUNCTION__, dirname, strerror(errno)); rc = CKR_FUNCTION_FAILED; goto err_out; } fd = open(dirname, O_RDONLY); if (fd < 0) { LogError("%s: open(%s): %s", __FUNCTION__, dirname, strerror(errno)); rc = CKR_FUNCTION_FAILED; goto err_out; } if (fchmod(fd, mode) == -1) { LogError("%s: fchmod(%s): %s", __FUNCTION__, dirname, strerror(errno)); close(fd); rc = CKR_FUNCTION_FAILED; goto err_out; } close(fd); // now create userdir/TOK_OBJ strncat(dirname, "/", 1); strncat(dirname, PK_LITE_OBJ_DIR, strlen(PK_LITE_OBJ_DIR)); if (mkdir(dirname, mode) == -1) { LogError("%s: mkdir \"%s\": %s", __FUNCTION__, dirname, strerror(errno)); rc = CKR_FUNCTION_FAILED; goto err_out; } fd = open(dirname, O_RDONLY); if (fd < 0) { LogError("%s: open(%s): %s", __FUNCTION__, dirname, strerror(errno)); rc = CKR_FUNCTION_FAILED; goto err_out; } if (fchmod(fd, mode) == -1) { LogError("%s: fchmod(%s): %s", __FUNCTION__, dirname, strerror(errno)); close(fd); rc = CKR_FUNCTION_FAILED; goto err_out; } close(fd); } // STAT the file to see if it exists... If not, then create it fname = malloc(strlen(dirname)+strlen(FILENAME)+100); if (fname ) { sprintf(fname, "%s/%s/%s", pk_dir, pw->pw_name, FILENAME); } else { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_HOST_MEMORY; } if (stat(fname, &statbuf) < 0) { // File does not exist Create it fd = open(fname,O_RDWR|O_CREAT,mode); if (fd < 0 ){ LogError("open of %s failed: %s", fname, strerror(errno)); return CKR_FUNCTION_FAILED; //Failed } i = sizeof(LW_SHM_TYPE); b2 = malloc(i); memset(b2,'\0',i); write(fd,b2,i); free(b2); created=TRUE; } else { fd = open(fname,O_RDWR,mode); if (fd < 0 ){ LogError("open of %s failed: %s", fname, strerror(errno)); return CKR_FUNCTION_FAILED; //Failed } } global_shm = (LW_SHM_TYPE *)mmap(NULL,sizeof(LW_SHM_TYPE),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if (created == TRUE) { XProcLock( xproclock ); global_shm->num_publ_tok_obj = 0; global_shm->num_priv_tok_obj = 0; memset( &global_shm->publ_tok_objs, 0x0, 2048 * sizeof(TOK_OBJ_ENTRY) ); memset( &global_shm->priv_tok_objs, 0x0, 2048 * sizeof(TOK_OBJ_ENTRY) ); XProcUnLock( xproclock ); } else { xproclock = (void *)&global_shm->mutex; } rc = CKR_OK; err_out: free(dirname); free(fname); close(fd); return rc; } #else global_shm = (void *)malloc(sizeof(LW_SHM_TYPE)); #endif return CKR_OK; } CK_RV detach_shm() { #if !(NOSHM) && !(MMAP) shmdt( global_shm ); #elif MMAP // Detach from memory mapped file munmap((void *)global_shm,sizeof(LW_SHM_TYPE)); #else free(global_shm); #endif return CKR_OK; } CK_RV compute_sha( CK_BYTE * data, CK_ULONG len, CK_BYTE * hash ) { // XXX KEY DIGEST_CONTEXT ctx; CK_ULONG hash_len = SHA1_HASH_SIZE; CK_RV rv; memset( &ctx, 0x0, sizeof(ctx) ); ckm_sha1_init( &ctx ); if( ctx.context == NULL ) return CKR_HOST_MEMORY; if( (rv = ckm_sha1_update( &ctx, data, len )) != CKR_OK) return rv; return ckm_sha1_final( &ctx, hash, &hash_len ); } CK_RV compute_md5( CK_BYTE * data, CK_ULONG len, CK_BYTE * hash ) { MD5_CONTEXT ctx; memset( &ctx, 0x0, sizeof(ctx) ); ckm_md5_init( &ctx ); ckm_md5_update( &ctx, data, len ); ckm_md5_final( &ctx, hash, MD5_HASH_SIZE ); return CKR_OK; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/host_defs.h0000751000175000017500000002125211327631345021562 0ustar jfjf /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005*/ #include #ifndef _HOST_DEFS_H #define _HOST_DEFS_H #include #include #include #include "pkcs32.h" // Both of the strings below have a length of 32 chars and must be // padded with spaces, and non-null terminated. // #define PKW_CRYPTOKI_VERSION_MAJOR 2 #define PKW_CRYPTOKI_VERSION_MINOR 1 #define PKW_CRYPTOKI_MANUFACTURER "IBM Corp. " #define PKW_CRYPTOKI_LIBDESC "PKCS#11 Interface for IBM 4758 " #define PKW_CRYPTOKI_LIB_VERSION_MAJOR 1 #define PKW_CRYPTOKI_LIB_VERSION_MINOR 0 #define PKW_MAX_DEVICES 10 #define MAX_TOK_OBJS 2048 CK_BBOOL pin_expired(CK_SESSION_INFO *, CK_FLAGS); CK_BBOOL pin_locked(CK_SESSION_INFO *, CK_FLAGS); void set_login_flags(CK_USER_TYPE, CK_FLAGS_32 *); // the following enum is for performance measurements. since the server runs // as an NT service, it's difficult (impossible?) to use a standalone performance // probe // enum { PRF_DUMMYFUNCTION = 1, PRF_FCVFUNCTION, PRF_INITIALIZE, PRF_FINALIZE, PRF_GETINFO, PRF_GETFUNCTIONLIST, PRF_GETSLOTLIST, PRF_GETSLOTINFO, PRF_GETTOKENINFO, PRF_GETMECHLIST, PRF_GETMECHINFO, PRF_INITTOKEN, PRF_INITPIN, PRF_SETPIN, PRF_OPENSESSION, PRF_CLOSESESSION, PRF_CLOSEALLSESSIONS, PRF_GETSESSIONINFO, PRF_GETOPERATIONSTATE, PRF_SETOPERATIONSTATE, PRF_LOGIN, PRF_LOGOUT, PRF_CREATEOBJECT, PRF_COPYOBJECT, PRF_DESTROYOBJECT, PRF_GETOBJECTSIZE, PRF_GETATTRIBUTEVALUE, PRF_SETATTRIBUTEVALUE, PRF_FINDOBJECTSINIT, PRF_FINDOBJECTS, PRF_FINDOBJECTSFINAL, PRF_ENCRYPTINIT, PRF_ENCRYPT, PRF_ENCRYPTUPDATE, PRF_ENCRYPTFINAL, PRF_DECRYPTINIT, PRF_DECRYPT, PRF_DECRYPTUPDATE, PRF_DECRYPTFINAL, PRF_DIGESTINIT, PRF_DIGEST, PRF_DIGESTUPDATE, PRF_DIGESTKEY, PRF_DIGESTFINAL, PRF_SIGNINIT, PRF_SIGN, PRF_SIGNUPDATE, PRF_SIGNFINAL, PRF_SIGNRECOVERINIT, PRF_SIGNRECOVER, PRF_VERIFYINIT, PRF_VERIFY, PRF_VERIFYUPDATE, PRF_VERIFYFINAL, PRF_VERIFYRECOVERINIT, PRF_VERIFYRECOVER, PRF_GENKEY, PRF_GENKEYPAIR, PRF_WRAPKEY, PRF_UNWRAPKEY, PRF_DERIVEKEY, PRF_GENRND, PRF_LASTENTRY }; #define TOTAL 1 #define CARD 2 // Endianness-conversion routines. This will be useful for folks trying // to use the coprocessor on a big-endian architecture... // // htocl -- host to card long // ctohl -- card to host long // #ifndef __BYTE_ORDER #error "MUST DEFINE ENDIANESS" #endif #if __BYTE_ORDER == __LITTLE_ENDIAN #define HTOCL(x) (x) #define CTOHL(x) (x) #else #define HTOCL(x) (long_reverse(x)) #define CTOHL(x) (long_reverse(x)) #endif typedef struct _ENCR_DECR_CONTEXT { CK_OBJECT_HANDLE key; CK_MECHANISM mech; CK_BYTE *context; CK_ULONG context_len; CK_BBOOL multi; CK_BBOOL active; } ENCR_DECR_CONTEXT; typedef struct _DIGEST_CONTEXT { CK_MECHANISM mech; CK_BYTE *context; CK_ULONG context_len; CK_BBOOL multi; CK_BBOOL active; } DIGEST_CONTEXT; typedef struct _SIGN_VERIFY_CONTEXT { CK_OBJECT_HANDLE key; CK_MECHANISM mech; // current sign mechanism CK_BYTE *context; // temporary work area CK_ULONG context_len; CK_BBOOL multi; // is this a multi-part operation? CK_BBOOL recover; // are we in recover mode? CK_BBOOL active; } SIGN_VERIFY_CONTEXT; typedef struct _SESSION { CK_SESSION_HANDLE handle; CK_SESSION_INFO session_info; CK_OBJECT_HANDLE *find_list; // array of CK_OBJECT_HANDLE CK_ULONG_32 find_count; // # handles in the list CK_ULONG_32 find_len; // max # of handles in the list CK_ULONG_32 find_idx; // current position CK_BBOOL find_active; ENCR_DECR_CONTEXT encr_ctx; ENCR_DECR_CONTEXT decr_ctx; DIGEST_CONTEXT digest_ctx; SIGN_VERIFY_CONTEXT sign_ctx; SIGN_VERIFY_CONTEXT verify_ctx; } SESSION; typedef struct _DES_CONTEXT { CK_BYTE data[ DES_BLOCK_SIZE ]; CK_ULONG len; CK_BBOOL cbc_pad; // is this a CKM_DES_CBC_PAD operation? } DES_CONTEXT; typedef struct _AES_CONTEXT { CK_BYTE data[ AES_BLOCK_SIZE ]; CK_ULONG len; CK_BBOOL cbc_pad; } AES_CONTEXT; typedef struct _SHA1_CONTEXT { unsigned int buf[16]; unsigned int hash_value[5]; unsigned int bits_hi, bits_lo; // # bits processed so far } SHA1_CONTEXT; typedef struct _MD2_CONTEXT { CK_BYTE state[16]; // state CK_BYTE checksum[16]; // checksum CK_ULONG count; // number of bytes, modulo 16 CK_BYTE buffer[16]; // input buffer } MD2_CONTEXT; typedef struct _MD5_CONTEXT { CK_ULONG i[2]; // number of _bits_ handled mod 2^64 CK_ULONG buf[4]; // scratch buffer CK_BYTE in[64]; // input buffer CK_BYTE digest[16]; // actual digest after MD5Final call } MD5_CONTEXT; // linux typedef pthread_mutex_t MUTEX; // This is actualy wrong... XPROC will be with spinlocks #if (SPINXPL) #define XPROCLOCK unsigned int #else #define XPROCLOCK MUTEX #endif typedef struct _TEMPLATE { DL_NODE *attribute_list; } TEMPLATE; typedef struct _OBJECT { CK_OBJECT_CLASS class; CK_BYTE name[8]; // for token objects SESSION *session; // creator; only for session objects TEMPLATE *template; CK_ULONG count_hi; // only significant for token objects CK_ULONG count_lo; // only significant for token objects } OBJECT; typedef struct _OBJECT_MAP { CK_OBJECT_HANDLE handle; CK_BBOOL is_private; CK_BBOOL is_session_obj; SESSION * session; OBJECT * ptr; } OBJECT_MAP; typedef struct _ATTRIBUTE_PARSE_LIST { CK_ATTRIBUTE_TYPE type; void *ptr; CK_ULONG len; CK_BBOOL found; } ATTRIBUTE_PARSE_LIST; typedef struct _OP_STATE_DATA { CK_STATE session_state; CK_ULONG active_operation; CK_ULONG data_len; // state data gets appended here // // mechanism parameter gets appended here // } OP_STATE_DATA; // this is our internal "tweak" vector (not the FCV) used to tweak various // aspects of the PKCS #11 implementation. Some of these tweaks deviate from // the PKCS #11 specification but are needed to support Netscape. Others // are left as token-defined values by PKCS #11. // // - whether or not to allow weak/semi-weak DES keys to be imported // - whether to insist imported DES keys have proper parity // - whether the CKA_ENCRYPT/DECRYPT/SIGN/VERIFY attributes are modifiable // after key creation // typedef struct _TWEAK_VEC { int allow_weak_des ; int check_des_parity ; int allow_key_mods ; int netscape_mods ; } TWEAK_VEC; typedef struct _TOKEN_DATA { CK_TOKEN_INFO_32 token_info; CK_BYTE user_pin_sha[3 * DES_BLOCK_SIZE]; CK_BYTE so_pin_sha[3 * DES_BLOCK_SIZE]; CK_BYTE next_token_object_name[8]; TWEAK_VEC tweak_vector; } TOKEN_DATA; typedef struct _SSL3_MAC_CONTEXT { DIGEST_CONTEXT hash_context; CK_BBOOL flag; } SSL3_MAC_CONTEXT; typedef struct _RSA_DIGEST_CONTEXT { DIGEST_CONTEXT hash_context; CK_BBOOL flag; } RSA_DIGEST_CONTEXT; typedef struct _MECH_LIST_ELEMENT { CK_MECHANISM_TYPE mech_type; CK_MECHANISM_INFO mech_info; } MECH_LIST_ELEMENT; typedef struct _MASTER_KEY_FILE_T { CK_BYTE key[3 * DES_KEY_SIZE]; CK_BYTE sha_hash[SHA1_HASH_SIZE]; } MASTER_KEY_FILE_T; typedef struct _TOK_OBJ_ENTRY { CK_BBOOL deleted; char name[8]; CK_ULONG_32 count_lo; CK_ULONG_32 count_hi; } TOK_OBJ_ENTRY; typedef struct _LW_SHM_TYPE { XPROCLOCK mutex; #if SYSVSEM key_t semtok; #endif TOKEN_DATA nv_token_data; CK_ULONG_32 num_priv_tok_obj; CK_ULONG_32 num_publ_tok_obj; CK_BBOOL priv_loaded; CK_BBOOL publ_loaded; TOK_OBJ_ENTRY publ_tok_objs[ MAX_TOK_OBJS ]; TOK_OBJ_ENTRY priv_tok_objs[ MAX_TOK_OBJS ]; } LW_SHM_TYPE; // These are the same for both AIX and Linux... #define MY_CreateMutex(x) _CreateMutex((MUTEX *)(x)) #define MY_DestroyMutex(x) _DestroyMutex((MUTEX *)(x)) #define MY_LockMutex(x) _LockMutex((MUTEX *)(x)) #define MY_UnlockMutex(x) _UnlockMutex((MUTEX *)(x)) #define MY_CreateMsem(x) CreateXProcLock((void *)(x)) #define MY_DestroyMsem(x) DestroyXProcLock((void *)(x)) #define MY_LockMsem(x) XProcLock((void *)(x)) #define MY_UnlockMsem(x) XProcUnLock((void *)(x)) #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/tok_spec_struct.h0000640000175000017500000001124211327631345023012 0ustar jfjf/* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */ /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2002, 2005 */ /*************************************************************************** Change Log ========== 4/25/03 Kapil Sood (kapil@corrent.com) Added DH key pair generation and DH shared key derivation functions. ****************************************************************************/ #ifndef _TOK_SPECIFIC_STRUCT #define _TOK_SPECIFIC_STRUCT struct token_specific_struct{ CK_BYTE token_directory[PATH_MAX]; // Used to be in the token_local.h as a #def CK_BYTE token_subdir[PATH_MAX]; // subdirectory CK_BYTE token_debug_tag[PATH_MAX]; // debug logging tag CK_RV (*t_init)(char *,CK_SLOT_ID); // Initialization function int (*t_slot2local)(); // convert the PKCS#11 slot to a local index // generaly not used but if a STDLL actualy // managed multiple devices, this would conv CK_RV (*t_rng)(CK_BYTE *,CK_ULONG); // Random Number Gen CK_RV (*t_session)(CK_SLOT_ID); //perform anything specific needed by the token takes a slot id CK_RV (*t_final)(); // any specific final code CK_RV (*t_des_key_gen)(CK_BYTE *,CK_ULONG); CK_RV (*t_des_ecb)( CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_BYTE); CK_RV (*t_des_cbc)( CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, CK_BYTE *,CK_BYTE *, CK_BYTE); CK_RV (*t_tdes_ecb)( CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_BYTE); CK_RV (*t_tdes_cbc)( CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, CK_BYTE *,CK_BYTE *, CK_BYTE); CK_RV (*t_rsa_decrypt)(CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, OBJECT *); CK_RV (*t_rsa_encrypt)( CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, OBJECT *); CK_RV (*t_rsa_sign)(CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, OBJECT *); CK_RV (*t_rsa_verify)(CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG, OBJECT *); CK_RV (*t_rsa_generate_keypair)(TEMPLATE *, TEMPLATE *); /* Begin code contributed by Corrent corp. */ #ifndef NODH // Token Specific DH functions CK_RV (*t_dh_pkcs_derive) ( CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG ) ; CK_RV (*t_dh_pkcs_key_pair_gen)(TEMPLATE *, TEMPLATE *); #endif /* End code contributed by Corrent corp. */ // Token Specific SHA1 functions CK_RV (*t_sha_init)(DIGEST_CONTEXT *); CK_RV (*t_sha_update)( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG); CK_RV (*t_sha_final)( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG *); #ifndef NOAES // Token Specific AES functions CK_RV (*t_aes_key_gen)( CK_BYTE *, CK_ULONG); CK_RV (*t_aes_ecb)( CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_ULONG, CK_BYTE); CK_RV (*t_aes_cbc)( CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_ULONG, CK_BYTE *, CK_BYTE); #endif CK_RV (*t_login)(CK_USER_TYPE, CK_CHAR_PTR, CK_ULONG); CK_RV (*t_logout)(); CK_RV (*t_init_pin)(CK_CHAR_PTR, CK_ULONG); CK_RV (*t_set_pin)(ST_SESSION_HANDLE, CK_CHAR_PTR, CK_ULONG, CK_CHAR_PTR, CK_ULONG); CK_RV (*t_verify_so_pin)(CK_CHAR_PTR, CK_ULONG); }; typedef struct token_specific_struct token_spec_t; #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/mech_des.c0000640000175000017500000013353311327631345021351 0ustar jfjf /* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */ /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */ // File: mech_des.c // // Mechanisms for DES // //#include #include // for memcmp() et al #include #include "pkcs11/pkcs11types.h" #include #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" //#include "args.h" // // CK_RV pk_des_ecb_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES_ECB requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des_ecb_encrypt( in_data, in_data_len, out_data, out_data_len, attr->pValue); } // // CK_RV des_ecb_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES_ECB requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des_ecb_decrypt( in_data, in_data_len, out_data, out_data_len, attr->pValue ); } // // CK_RV pk_des_cbc_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES_CBC requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des_cbc_encrypt( in_data, in_data_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); } // // CK_RV des_cbc_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES_CBC requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des_cbc_decrypt( in_data, in_data_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); } // // CK_RV des_cbc_pad_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE *clear = NULL; CK_ULONG padded_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // DES-CBC-PAD has no input length requirements // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // compute the output length, accounting for padding // padded_len = DES_BLOCK_SIZE * (in_data_len / DES_BLOCK_SIZE + 1); if (length_only == TRUE) { *out_data_len = padded_len; return CKR_OK; } if (*out_data_len < padded_len) { *out_data_len = padded_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } clear = (CK_BYTE *)malloc( padded_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( clear, in_data, in_data_len ); add_pkcs_padding( clear + in_data_len, DES_BLOCK_SIZE, in_data_len, padded_len ); rc = ckm_des_cbc_encrypt( clear, padded_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); if (rc != CKR_OK) st_err_log(113, __FILE__, __LINE__); free( clear ); return rc; } // // CK_RV des_cbc_pad_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE *clear = NULL; CK_ULONG padded_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // no need to validate the input length since we'll pad as necessary // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // we're decrypting so even with CBC-PAD, we should have an integral // number of block to decrypt // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } // the amount of cleartext after stripping the padding will actually be less // than the input bytes... // padded_len = in_data_len; if (length_only == TRUE) { *out_data_len = padded_len; return CKR_OK; } clear = (CK_BYTE *)malloc( padded_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } rc = ckm_des_cbc_decrypt( in_data, in_data_len, clear, &padded_len, ctx->mech.pParameter, attr->pValue ); if (rc == CKR_OK) { strip_pkcs_padding( clear, padded_len, out_data_len ); memcpy( out_data, clear, *out_data_len ); } else st_err_log(114, __FILE__, __LINE__); free( clear ); return rc; } // // CK_RV des_ecb_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % DES_BLOCK_SIZE); out_len = (total - remain); // should always be at least 1 block if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); rc = ckm_des_ecb_encrypt( clear, out_len, out_data, out_data_len, attr->pValue ); if (rc == CKR_OK) { *out_data_len = out_len; // update the context buffer. we already used the buffer's current // contents so we completely overwrite it // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(115, __FILE__, __LINE__); free( clear ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // shouldn't reach this } // // CK_RV des_ecb_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % DES_BLOCK_SIZE); out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_des_ecb_decrypt( cipher, out_len, out_data, out_data_len, attr->pValue ); if (rc == CKR_OK) { *out_data_len = out_len; // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(116, __FILE__, __LINE__); free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // shouldn't reach this } // // CK_RV des_cbc_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % DES_BLOCK_SIZE); out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // these buffers need to be longword aligned // clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); rc = ckm_des_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); if (rc == CKR_OK) { *out_data_len = out_len; // the new init_v is the last encrypted data block // memcpy( ctx->mech.pParameter, out_data + (*out_data_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(113, __FILE__, __LINE__); free( clear ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV des_cbc_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = context->len + in_data_len; if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = total % DES_BLOCK_SIZE; out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // these buffers need to be longword aligned // cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_des_cbc_decrypt( cipher, out_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); if (rc == CKR_OK) { *out_data_len = out_len; // the new init_v is the last decrypted data block // memcpy( ctx->mech.pParameter, cipher + (out_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(114, __FILE__, __LINE__); free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV des_cbc_pad_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); // note, this is subtly different from the other encrypt update routines // if (total <= DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block + 1 byte // remain = total % DES_BLOCK_SIZE; out_len = total - remain; if (remain == 0) { remain = DES_BLOCK_SIZE; out_len -= DES_BLOCK_SIZE; } if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } // at this point, we should have: // 1) remain != 0 // 2) out_len != 0 // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // these buffers need to be longword aligned // clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); // // we don't do padding during the update // rc = ckm_des_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); if (rc == CKR_OK) { // the new init_v is the last encrypted data block // memcpy( ctx->mech.pParameter, out_data + (*out_data_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the temporary space // memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(113, __FILE__, __LINE__); free( clear ); return rc; } } // // CK_RV des_cbc_pad_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); // note, this is subtly different from the other decrypt update routines // if (total <= DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block + 1 byte // remain = total % DES_BLOCK_SIZE; out_len = total - remain; if (remain == 0) { remain = DES_BLOCK_SIZE; out_len -= DES_BLOCK_SIZE; } if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } // at this point, we should have: // 1) remain != 0 // 2) out_len != 0 // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // these buffers need to be longword aligned // cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_des_cbc_decrypt( cipher, out_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); if (rc == CKR_OK) { // the new init_v is the last decrypted data block // memcpy( ctx->mech.pParameter, cipher + (out_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the temporary space // memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(114, __FILE__, __LINE__); free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV des_ecb_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES-ECB does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV des_ecb_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES-ECB does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV des_cbc_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES-CBC does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV des_cbc_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES-CBC does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV des_cbc_pad_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE clear[2 * DES_BLOCK_SIZE]; CK_ULONG out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; // there will never be more than one block in the context buffer // so the amount of output is as follows: // if less than 1 block stored, we generate one block of output // if a full block is stored, we generate two blocks of output (one pad block) // if (context->len == DES_BLOCK_SIZE) out_len = 2 * DES_BLOCK_SIZE; else out_len = DES_BLOCK_SIZE; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } else { memcpy( clear, context->data, context->len ); add_pkcs_padding( clear + context->len, DES_BLOCK_SIZE, context->len, out_len ); rc = ckm_des_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); if (rc != CKR_OK) st_err_log(113, __FILE__, __LINE__); return rc; } } // // CK_RV des_cbc_pad_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE clear[DES_BLOCK_SIZE]; CK_BYTE cipher[DES_BLOCK_SIZE]; CK_ULONG out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; // there had better be a full block in the context buffer // if (context->len != DES_BLOCK_SIZE){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } // we don't know a priori how much data we'll be returning. we won't // know until after we decrypt it and strip the padding. it's possible // that we'll return nothing (the final block might be a padding block). // out_len = DES_BLOCK_SIZE; // upper bound on what we'll return if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } else { memcpy( cipher, context->data, DES_BLOCK_SIZE ); rc = ckm_des_cbc_decrypt( cipher, DES_BLOCK_SIZE, clear, &out_len, ctx->mech.pParameter, attr->pValue ); if (rc == CKR_OK) { strip_pkcs_padding( clear, DES_BLOCK_SIZE, &out_len ); if (out_len != 0) memcpy( out_data, clear, out_len ); *out_data_len = out_len; } else st_err_log(114, __FILE__, __LINE__); return rc; } } // // mechanisms // // // CK_RV ckm_des_key_gen( TEMPLATE *tmpl ) { CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * key_type_attr = NULL; CK_ATTRIBUTE * class_attr = NULL; CK_ATTRIBUTE * local_attr = NULL; CK_BYTE des_key[DES_KEY_SIZE]; CK_ULONG req_len, repl_len, expected_repl_len; CK_ULONG rc; // Checking for a weak key is redundant in that the token // specific keygen may already do this // If the key generated is NOT a clear key, then this // needs to be re-worked. // probably by deciding if the key is being created as a private or // public token object. Only token objects are encrypted // The size is passed in to allow the same token specific code to // do both DES and TDES do { rc = token_specific.t_des_key_gen(des_key,DES_KEY_SIZE); } while (des_check_weak_key(des_key) != FALSE && rc != CKR_OK); if (rc != CKR_OK) goto done; value_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + DES_KEY_SIZE ); key_type_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); class_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS) ); local_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!value_attr || !key_type_attr || !class_attr || !local_attr) { if (value_attr) free( value_attr ); if (key_type_attr) free( key_type_attr ); if (class_attr) free( class_attr ); if (local_attr) free( local_attr ); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = DES_KEY_SIZE; value_attr->pValue = (CK_BYTE *)value_attr + sizeof(CK_ATTRIBUTE); memcpy( value_attr->pValue, des_key, DES_KEY_SIZE ); key_type_attr->type = CKA_KEY_TYPE; key_type_attr->ulValueLen = sizeof(CK_KEY_TYPE); key_type_attr->pValue = (CK_BYTE *)key_type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)key_type_attr->pValue = CKK_DES; class_attr->type = CKA_CLASS; class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS); class_attr->pValue = (CK_BYTE *)class_attr + sizeof(CK_ATTRIBUTE); *(CK_OBJECT_CLASS *)class_attr->pValue = CKO_SECRET_KEY; local_attr->type = CKA_LOCAL; local_attr->ulValueLen = sizeof(CK_BBOOL); local_attr->pValue = (CK_BYTE *)local_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)local_attr->pValue = TRUE; template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, key_type_attr ); template_update_attribute( tmpl, class_attr ); template_update_attribute( tmpl, local_attr ); // return CKR_OK; done: return rc; } #if !(NOCDMF) // // CK_RV ckm_cdmf_key_gen( TEMPLATE *tmpl ) { CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * key_type_attr = NULL; CK_ATTRIBUTE * class_attr = NULL; CK_ATTRIBUTE * local_attr = NULL; CK_BYTE cdmf_key[DES_KEY_SIZE]; CK_ULONG repl_len, expected_repl_len; CK_ULONG rc; repl_len = expected_repl_len = DES_KEY_SIZE; rc = communicate( PK_CDMF_KEYGEN, NULL, 0, cdmf_key, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK) { if (repl_len != expected_repl_len) return CKR_GENERAL_ERROR; } value_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + DES_KEY_SIZE ); key_type_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); class_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS) ); local_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!value_attr || !key_type_attr || !class_attr || !local_attr) { if (value_attr) free( value_attr ); if (key_type_attr) free( key_type_attr ); if (class_attr) free( class_attr ); if (local_attr) free( local_attr ); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = DES_KEY_SIZE; value_attr->pValue = (CK_BYTE *)value_attr + sizeof(CK_ATTRIBUTE); memcpy( value_attr->pValue, cdmf_key, DES_KEY_SIZE ); key_type_attr->type = CKA_KEY_TYPE; key_type_attr->ulValueLen = sizeof(CK_KEY_TYPE); key_type_attr->pValue = (CK_BYTE *)key_type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)key_type_attr->pValue = CKK_CDMF; class_attr->type = CKA_CLASS; class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS); class_attr->pValue = (CK_BYTE *)class_attr + sizeof(CK_ATTRIBUTE); *(CK_OBJECT_CLASS *)class_attr->pValue = CKO_SECRET_KEY; local_attr->type = CKA_LOCAL; local_attr->ulValueLen = sizeof(CK_BBOOL); local_attr->pValue = (CK_BYTE *)local_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)local_attr->pValue = TRUE; template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, key_type_attr ); template_update_attribute( tmpl, class_attr ); template_update_attribute( tmpl, local_attr ); return CKR_OK; } #endif // // CK_RV ckm_des_ecb_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * key_value ) { CK_ULONG req_len, repl_len, expected_repl_len; CK_ULONG rc; if (!in_data || !out_data || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_des_ecb(in_data,in_data_len,out_data,out_data_len,key_value,1);// token specifics return CKR_ errors ... if (rc != CKR_OK) st_err_log(117, __FILE__, __LINE__); return rc; } // // CK_RV ckm_des_ecb_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * key_value ) { CK_ULONG req_len, repl_len, expected_repl_len; CK_ULONG rc; if (!in_data || !out_data || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_des_ecb(in_data,in_data_len,out_data, out_data_len,key_value,0); // last parm is the encrypt flag if (rc != CKR_OK) st_err_log(117, __FILE__, __LINE__); return rc; } // // CK_RV ckm_des_cbc_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * init_v, CK_BYTE * key_value ) { CK_ULONG req_len, repl_len, expected_repl_len; CK_ULONG rc; if (!in_data || !out_data || !init_v || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ #if 0 st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; #else *out_data_len = in_data_len; st_err_log(68, __FILE__, __FUNCTION__); return CKR_BUFFER_TOO_SMALL; #endif } rc = token_specific.t_des_cbc(in_data,in_data_len,out_data, out_data_len,key_value,init_v,1); // last parm is the encrypt flag if (rc != CKR_OK) st_err_log(118, __FILE__, __LINE__); return rc; } // // CK_RV ckm_des_cbc_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * init_v, CK_BYTE * key_value ) { CK_ULONG req_len, repl_len, expected_repl_len; CK_ULONG rc; if (!in_data || !out_data || !init_v || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_des_cbc(in_data,in_data_len,out_data, out_data_len,key_value,init_v,0); // last parm is the encrypt flag if (rc != CKR_OK) st_err_log(118, __FILE__, __LINE__); return rc; } // we're preparing to wrap a key using DES. need to make sure the // data length is a integral multiple of the DES block size. // // PKCS #11 specifies that the padding shall be in the form of NULL // bytes appended to the data // // this routine works with either DES and 3DES as the wrapping mechanism // CK_RV ckm_des_wrap_format( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len ) { CK_BYTE * ptr = NULL; CK_ULONG len1, len2; len1 = *data_len; // if the input key data isn't a multiple of the blocksize, // we pad with NULLs to the next blocksize multiple. // if (len1 % DES_BLOCK_SIZE != 0) { len2 = DES_BLOCK_SIZE * ((len1 / DES_BLOCK_SIZE) + 1); if (length_only == FALSE) { ptr = (CK_BYTE *)realloc(*data, len2); if (!ptr){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } else memset( ptr + len1, 0x0, (len2 - len1) ); *data = ptr; *data_len = len2; } } return CKR_OK; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/dig_mgr.c0000640000175000017500000005754411327631345021221 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: dig_mgr.c // // Digest manager routines // #include #include // for memcmp() et al #include #include "pkcs11types.h" #include "pkcs11/stdll.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // // CK_RV digest_mgr_init( SESSION *sess, DIGEST_CONTEXT *ctx, CK_MECHANISM *mech ) { CK_BYTE * ptr = NULL; if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active != FALSE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } // is the mechanism supported? is the parameter present if required? // switch (mech->mechanism) { case CKM_SHA_1: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } ctx->context = NULL; ckm_sha1_init( ctx ); if (!ctx->context) { st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } } break; case CKM_MD2: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } ctx->context_len = sizeof(MD2_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(MD2_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(MD2_CONTEXT) ); } break; case CKM_MD5: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } ctx->context_len = sizeof(MD5_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(MD5_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } ckm_md5_init( (MD5_CONTEXT *)ctx->context ); } break; default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } if (mech->ulParameterLen > 0) { ptr = (CK_BYTE *)malloc(mech->ulParameterLen); if (!ptr){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( ptr, mech->pParameter, mech->ulParameterLen ); } ctx->mech.ulParameterLen = mech->ulParameterLen; ctx->mech.mechanism = mech->mechanism; ctx->mech.pParameter = ptr; ctx->multi = FALSE; ctx->active = TRUE; return CKR_OK; } // // CK_RV digest_mgr_cleanup( DIGEST_CONTEXT *ctx ) { if (!ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } ctx->mech.ulParameterLen = 0; ctx->mech.mechanism = 0; ctx->multi = FALSE; ctx->active = FALSE; ctx->context_len = 0; if (ctx->mech.pParameter) { free( ctx->mech.pParameter ); ctx->mech.pParameter = NULL; } if (ctx->context != NULL) { free( ctx->context ); ctx->context = NULL; } return CKR_OK; } // // CK_RV digest_mgr_digest( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } // if the caller just wants the encrypted length, there is no reason to // specify the input data. I just need the data length // if ((length_only == FALSE) && (!in_data || !out_data)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->multi == TRUE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } switch (ctx->mech.mechanism) { case CKM_SHA_1: return sha1_hash( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #if !(NOMD2 ) case CKM_MD2: return md2_hash( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif case CKM_MD5: return md5_hash( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); default: st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // shouldn't happen } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV digest_mgr_digest_update( SESSION *sess, DIGEST_CONTEXT *ctx, CK_BYTE *data, CK_ULONG data_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } ctx->multi = TRUE; switch (ctx->mech.mechanism) { case CKM_SHA_1: return sha1_hash_update( sess, ctx, data, data_len ); #if !(NOMD2) case CKM_MD2: return md2_hash_update( sess, ctx, data, data_len ); #endif case CKM_MD5: return md5_hash_update( sess, ctx, data, data_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; // shouldn't happen! } // // CK_RV digest_mgr_digest_key( SESSION * sess, DIGEST_CONTEXT * ctx, CK_OBJECT_HANDLE key_handle ) { CK_ATTRIBUTE * attr = NULL; OBJECT * key_obj = NULL; CK_OBJECT_CLASS class; CK_RV rc; if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( key_handle, &key_obj ); if (rc != CKR_OK){ st_err_log(18, __FILE__, __LINE__); return CKR_KEY_HANDLE_INVALID; } // only allow digesting of CKO_SECRET keys // rc = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (rc == FALSE) { st_err_log(24, __FILE__, __LINE__); return CKR_KEY_INDIGESTIBLE; } else class = *(CK_OBJECT_CLASS *)attr->pValue; if (class != CKO_SECRET_KEY){ st_err_log(24, __FILE__, __LINE__); return CKR_KEY_INDIGESTIBLE; } // every secret key has a CKA_VALUE attribute // rc = template_attribute_find( key_obj->template, CKA_VALUE, &attr ); if (!rc){ st_err_log(24, __FILE__, __LINE__); return CKR_KEY_INDIGESTIBLE; } rc = digest_mgr_digest_update( sess, ctx, attr->pValue, attr->ulValueLen ); if (rc != CKR_OK){ st_err_log(24, __FILE__, __LINE__); } return rc; } // // CK_RV digest_mgr_digest_final( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *hash, CK_ULONG *hash_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } /* XXX KEY - Turn off the multi flag to tell the next layer that this * is the final part of a multi part operation. */ ctx->multi = FALSE; switch (ctx->mech.mechanism) { case CKM_SHA_1: return sha1_hash_final( sess, length_only, ctx, hash, hash_len ); #if !(NOMD2) case CKM_MD2: return md2_hash_final( sess, length_only, ctx, hash, hash_len ); #endif case CKM_MD5: return md5_hash_final( sess, length_only, ctx, hash, hash_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; // shouldn't happen } st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/README0000640000175000017500000000415511327631345020313 0ustar jfjf TPM STDLL README Kent Yoder Current architecture: SRK | + User Root Key (URK) | | | + [1..N] User Base Key (UBK) | | | + Migratable Leaf Key (MLK) | | | | | + Auth Data for User Created Keys | | | + [1..N] User Created Keys | + Migratable Root Key (MRK) | + Migratable Leaf Key (MLK) 1. When the SO logs in: A) its verified that she is root (currently commented out) B) the token searches for the User Root Key (URK), and if found, the SO's key chain is loaded, up to the SO's protection key. Some junk data is encrypted and decrypted to challenge the auth data passed in and if that test passes, the SO is logged in C) if the URK isn't found, its assumed that the SO is logging in for the first time, and i. The URK is generated in software ii. The URK's private key is wrapped with the public key of the SRK, and TSS and PKCS#11 objects are created for it, storing it in the PKCS#11 data store D) i and ii are repeated for the Migratable Root Key (MRK) E) The Protection Key is generated by the TPM as a child of the MRK F) Some junk data is encrypted and decrypted to challenge the auth data passed in and if that test passes, the SO is logged in 2. When the USER logs in: A) The URK is searched for and if not found, failure (The SO has not initialized the token) B) If the URK is found, the User's Base Key (UBK) is searched for and if found, the user's key chain is loaded, up to the USER's protection key. Some junk data is encrypted and decrypted to challenge the auth data passed in and if that test passes, the USER is logged in C) if the UBK is not found: i. The UBK is generated in software ii.The UBK's private key is wrapped with the public key of the URK, and TSS and PKCS#11 objects are created for it, storing it in the PKCS#11 data store D) The User's Protection Key is generated by the TPM as a child of the UBK E) Some junk data is encrypted and decrypted to challenge the auth data passed in and if that test passes, the USER is logged in opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/verify_mgr.c0000640000175000017500000004623011327631345021750 0ustar jfjf /* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */ /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */ // File: verify_mgr.c // // Verify manager routines // //#include #include #include // for memcmp() et al #include #include "pkcs11/pkcs11types.h" #include #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // // CK_RV verify_mgr_init( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_MECHANISM * mech, CK_BBOOL recover_mode, CK_OBJECT_HANDLE key ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_KEY_TYPE keytype; CK_OBJECT_CLASS class; CK_BBOOL flag; CK_RV rc; if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active != FALSE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } // key usage restrictions // rc = object_mgr_find_in_map1( key, &key_obj ); if (rc != CKR_OK){ st_err_log(18, __FILE__, __LINE__); return CKR_KEY_HANDLE_INVALID; } // is key allowed to verify signatures? // rc = template_attribute_find( key_obj->template, CKA_VERIFY, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { flag = *(CK_BBOOL *)attr->pValue; if (flag != TRUE){ st_err_log(85, __FILE__, __LINE__); return CKR_KEY_FUNCTION_NOT_PERMITTED; } } // is the mechanism supported? is the key type correct? is a // parameter present if required? is the key size allowed? // is the key allowed to generate signatures? // switch (mech->mechanism) { case CKM_RSA_PKCS: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_RSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // must be a PUBLIC key operation // flag = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else class = *(CK_OBJECT_CLASS *)attr->pValue; if (class != CKO_PUBLIC_KEY){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // PKCS #11 doesn't allow multi-part RSA operations // ctx->context_len = 0; ctx->context = NULL; } break; case CKM_MD2_RSA_PKCS: case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_RSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // must be a PUBLIC key operation // flag = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else class = *(CK_OBJECT_CLASS *)attr->pValue; if (class != CKO_PUBLIC_KEY){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } ctx->context_len = sizeof(RSA_DIGEST_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(RSA_DIGEST_CONTEXT)); if (!ctx->context){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(RSA_DIGEST_CONTEXT)); } break; #if !(NODSA) case CKM_DSA: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // must be a PUBLIC key operation // flag = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else class = *(CK_OBJECT_CLASS *)attr->pValue; if (class != CKO_PUBLIC_KEY){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // PKCS #11 doesn't allow multi-part DSA operations // ctx->context_len = 0; ctx->context = NULL; } break; #endif case CKM_MD2_HMAC: case CKM_MD5_HMAC: case CKM_SHA_1_HMAC: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_GENERIC_SECRET){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // PKCS #11 doesn't allow multi-part HMAC operations // ctx->context_len = 0; ctx->context = NULL; } break; case CKM_MD2_HMAC_GENERAL: case CKM_MD5_HMAC_GENERAL: case CKM_SHA_1_HMAC_GENERAL: { CK_MAC_GENERAL_PARAMS *param = (CK_MAC_GENERAL_PARAMS *)mech->pParameter; if (mech->ulParameterLen != sizeof(CK_MAC_GENERAL_PARAMS)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } if ((mech->mechanism == CKM_MD2_HMAC_GENERAL) && (*param > 16)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } if ((mech->mechanism == CKM_MD5_HMAC_GENERAL) && (*param > 16)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } if ((mech->mechanism == CKM_SHA_1_HMAC_GENERAL) && (*param > 20)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_GENERIC_SECRET){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // PKCS #11 doesn't allow multi-part HMAC operations // ctx->context_len = 0; ctx->context = NULL; } break; case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: { CK_MAC_GENERAL_PARAMS *param = (CK_MAC_GENERAL_PARAMS *)mech->pParameter; if (mech->ulParameterLen != sizeof(CK_MAC_GENERAL_PARAMS)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // Netscape sets the parameter == 16. PKCS #11 limit is 8 // if (mech->mechanism == CKM_SSL3_MD5_MAC) { if (*param < 4 || *param > 16){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } } if (mech->mechanism == CKM_SSL3_SHA1_MAC) { if (*param < 4 || *param > 20){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } } rc = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { class = *(CK_OBJECT_CLASS *)attr->pValue; if (class != CKO_SECRET_KEY){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(SSL3_MAC_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(SSL3_MAC_CONTEXT)); if (!ctx->context){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(SSL3_MAC_CONTEXT)); } break; default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } if (mech->ulParameterLen > 0) { ptr = (CK_BYTE *)malloc(mech->ulParameterLen); if (!ptr){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( ptr, mech->pParameter, mech->ulParameterLen ); } ctx->key = key; ctx->mech.ulParameterLen = mech->ulParameterLen; ctx->mech.mechanism = mech->mechanism; ctx->mech.pParameter = ptr; ctx->multi = FALSE; ctx->active = TRUE; ctx->recover = recover_mode; return CKR_OK; } // // CK_RV verify_mgr_cleanup( SIGN_VERIFY_CONTEXT *ctx ) { if (!ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } ctx->key = 0; ctx->mech.ulParameterLen = 0; ctx->mech.mechanism = 0; ctx->multi = FALSE; ctx->active = FALSE; ctx->recover = FALSE; ctx->context_len = 0; if (ctx->mech.pParameter) { free( ctx->mech.pParameter ); ctx->mech.pParameter = NULL; } if (ctx->context) { free( ctx->context ); ctx->context = NULL; } return CKR_OK; } // // CK_RV verify_mgr_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == TRUE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } // if the caller just wants the signature length, there is no reason to // specify the input data. I just need the input data length // if (!in_data || !signature){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->multi == TRUE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } switch (ctx->mech.mechanism) { case CKM_RSA_PKCS: return rsa_pkcs_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); case CKM_MD2_RSA_PKCS: case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: return rsa_hash_pkcs_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); #if !(NODSA) case CKM_DSA: return dsa_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); #endif #if !(NOMD2) case CKM_MD2_HMAC: case CKM_MD2_HMAC_GENERAL: return md2_hmac_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); #endif case CKM_MD5_HMAC: case CKM_MD5_HMAC_GENERAL: return md5_hmac_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); case CKM_SHA_1_HMAC: case CKM_SHA_1_HMAC_GENERAL: return sha1_hmac_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: return ssl3_mac_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV verify_mgr_verify_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { if (!sess || !ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == TRUE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } ctx->multi = TRUE; switch (ctx->mech.mechanism) { case CKM_MD2_RSA_PKCS: case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: return rsa_hash_pkcs_verify_update( sess, ctx, in_data, in_data_len ); case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: return ssl3_mac_verify_update( sess, ctx, in_data, in_data_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // // CK_RV verify_mgr_verify_final( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == TRUE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } switch (ctx->mech.mechanism) { case CKM_MD2_RSA_PKCS: case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: return rsa_hash_pkcs_verify_final( sess, ctx, signature, sig_len ); case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: return ssl3_mac_verify_final( sess, ctx, signature, sig_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // // CK_RV verify_mgr_verify_recover( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len, CK_BYTE * out_data, CK_ULONG * out_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } // if the caller just wants the signature length, there is no reason to // specify the input data. I just need the input data length // if (!signature || !out_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->multi == TRUE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } switch (ctx->mech.mechanism) { case CKM_RSA_PKCS: return rsa_pkcs_verify_recover( sess, length_only, ctx, signature, sig_len, out_data, out_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/key_mgr.c0000640000175000017500000007664111327631345021245 0ustar jfjf /* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */ /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */ /*************************************************************************** Change Log ========== 4/25/03 Kapil Sood (kapil@corrent.com) Added DH key pair generation and DH shared key derivation functions. ****************************************************************************/ // File: key_mgr.c // //#include #include #include #include // for memcmp() et al #include "pkcs11/pkcs11types.h" #include #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" //#include "args.h" static CK_BBOOL true = TRUE, false = FALSE; // // CK_RV key_mgr_generate_key( SESSION * sess, CK_MECHANISM * mech, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE * handle ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_ATTRIBUTE * new_attr = NULL; CK_ULONG i, keyclass, subclass = 0; CK_BBOOL flag; CK_RV rc; if (!sess || !mech || !handle){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!pTemplate && (ulCount != 0)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // it's silly but Cryptoki allows the user to specify the CKA_CLASS // in the template. so we have to iterate through the provided template // and make sure that if CKA_CLASS is CKO_SECRET_KEY, if it is present. // // it would have been more logical for Cryptoki to forbid specifying // the CKA_CLASS attribute when generating a key // for (i=0; i < ulCount; i++) { if (pTemplate[i].type == CKA_CLASS) { keyclass = *(CK_OBJECT_CLASS *)pTemplate[i].pValue; if (keyclass != CKO_SECRET_KEY){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } if (pTemplate[i].type == CKA_KEY_TYPE) subclass = *(CK_ULONG *)pTemplate[i].pValue; } switch (mech->mechanism) { case CKM_DES_KEY_GEN: if (subclass != 0 && subclass != CKK_DES){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_DES; break; case CKM_DES3_KEY_GEN: if (subclass != 0 && subclass != CKK_DES3){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_DES3; break; #if !(NOCDMF) case CKM_CDMF_KEY_GEN: if (subclass != 0 && subclass != CKK_CDMF){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_CDMF; break; #endif case CKM_SSL3_PRE_MASTER_KEY_GEN: if (subclass != 0 && subclass != CKK_GENERIC_SECRET){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } if (mech->ulParameterLen != sizeof(CK_VERSION)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } subclass = CKK_GENERIC_SECRET; break; case CKM_AES_KEY_GEN: if (subclass != 0 && subclass != CKK_AES){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_AES; break; default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } rc = object_mgr_create_skel( sess, pTemplate, ulCount, MODE_KEYGEN, CKO_SECRET_KEY, subclass, &key_obj ); if (rc != CKR_OK){ st_err_log(89, __FILE__, __LINE__); goto error; } // at this point, 'key_obj' should contain a skeleton key. depending on // the key type, we may need to extract one or more attributes from // the object prior to generating the key data (ie. variable key length) // switch (mech->mechanism) { case CKM_DES_KEY_GEN: rc = ckm_des_key_gen( key_obj->template ); break; case CKM_DES3_KEY_GEN: rc = ckm_des3_key_gen( key_obj->template ); break; #if !(NOCDMF) case CKM_CDMF_KEY_GEN: rc = ckm_cdmf_key_gen( key_obj->template ); break; #endif case CKM_SSL3_PRE_MASTER_KEY_GEN: rc = ckm_ssl3_pre_master_key_gen( key_obj->template, mech ); break; #ifndef NOAES case CKM_AES_KEY_GEN: rc = ckm_aes_key_gen( key_obj->template ); break; #endif default: st_err_log(28, __FILE__, __LINE__); rc = CKR_MECHANISM_INVALID; } if (rc != CKR_OK){ st_err_log(91, __FILE__, __LINE__); goto error; } // we can now set CKA_ALWAYS_SENSITIVE and CKA_NEVER_EXTRACTABLE // to their appropriate values. this only applies to CKO_SECRET_KEY // and CKO_PRIVATE_KEY objects // flag = template_attribute_find( key_obj->template, CKA_SENSITIVE, &attr ); if (flag == TRUE) { flag = *(CK_BBOOL *)attr->pValue; rc = build_attribute( CKA_ALWAYS_SENSITIVE, &flag, sizeof(CK_BBOOL), &new_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } template_update_attribute( key_obj->template, new_attr ); } else { rc = CKR_FUNCTION_FAILED; st_err_log(4, __FILE__, __LINE__, __FUNCTION__); goto error; } flag = template_attribute_find( key_obj->template, CKA_EXTRACTABLE, &attr ); if (flag == TRUE) { flag = *(CK_BBOOL *)attr->pValue; rc = build_attribute( CKA_NEVER_EXTRACTABLE, &true, sizeof(CK_BBOOL), &new_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } if (flag == TRUE) *(CK_BBOOL *)new_attr->pValue = FALSE; template_update_attribute( key_obj->template, new_attr ); } else { rc = CKR_FUNCTION_FAILED; st_err_log(4, __FILE__, __LINE__, __FUNCTION__); goto error; } // at this point, the key should be fully constructed...assign // an object handle and store the key // rc = object_mgr_create_final( sess, key_obj, handle ); if (rc != CKR_OK){ st_err_log(90, __FILE__, __LINE__); goto error; } return rc; error: if (key_obj) object_free( key_obj ); *handle = 0; return rc; } // // CK_RV key_mgr_generate_key_pair( SESSION * sess, CK_MECHANISM * mech, CK_ATTRIBUTE * publ_tmpl, CK_ULONG publ_count, CK_ATTRIBUTE * priv_tmpl, CK_ULONG priv_count, CK_OBJECT_HANDLE * publ_key_handle, CK_OBJECT_HANDLE * priv_key_handle ) { OBJECT * publ_key_obj = NULL; OBJECT * priv_key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_ATTRIBUTE * new_attr = NULL; CK_ULONG i, keyclass, subclass = 0; CK_BBOOL flag; CK_RV rc; if (!sess || !mech || !publ_key_handle || !priv_key_handle){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!publ_tmpl && (publ_count != 0)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!priv_tmpl && (priv_count != 0)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // it's silly but Cryptoki allows the user to specify the CKA_CLASS // in the template. so we have to iterate through the provided template // and make sure that if CKA_CLASS is valid, if it is present. // // it would have been more logical for Cryptoki to forbid specifying // the CKA_CLASS attribute when generating a key // for (i=0; i < publ_count; i++) { if (publ_tmpl[i].type == CKA_CLASS) { keyclass = *(CK_OBJECT_CLASS *)publ_tmpl[i].pValue; if (keyclass != CKO_PUBLIC_KEY){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } if (publ_tmpl[i].type == CKA_KEY_TYPE) subclass = *(CK_ULONG *)publ_tmpl[i].pValue; } for (i=0; i < priv_count; i++) { if (priv_tmpl[i].type == CKA_CLASS) { keyclass = *(CK_OBJECT_CLASS *)priv_tmpl[i].pValue; if (keyclass != CKO_PRIVATE_KEY){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } if (priv_tmpl[i].type == CKA_KEY_TYPE) { CK_ULONG temp = *(CK_ULONG *)priv_tmpl[i].pValue; if (temp != subclass){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } } switch (mech->mechanism) { case CKM_RSA_PKCS_KEY_PAIR_GEN: if (subclass != 0 && subclass != CKK_RSA){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_RSA; break; #if !(NODSA) case CKM_DSA_KEY_PAIR_GEN: if (subclass != 0 && subclass != CKK_DSA){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_DSA; break; #endif /* Begin code contributed by Corrent corp. */ #if !(NODH) case CKM_DH_PKCS_KEY_PAIR_GEN: if (subclass != 0 && subclass != CKK_DH){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_DH; break; #endif /* End code contributed by Corrent corp. */ default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } rc = object_mgr_create_skel( sess, publ_tmpl, publ_count, MODE_KEYGEN, CKO_PUBLIC_KEY, subclass, &publ_key_obj ); if (rc != CKR_OK){ st_err_log(89, __FILE__, __LINE__); goto error; } rc = object_mgr_create_skel( sess, priv_tmpl, priv_count, MODE_KEYGEN, CKO_PRIVATE_KEY, subclass, &priv_key_obj ); if (rc != CKR_OK){ st_err_log(89, __FILE__, __LINE__); goto error; } // at this point, 'key_obj' should contain a skeleton key. depending on // the key type, we may need to extract one or more attributes from // the object prior to generating the key data (ie. variable key length) // switch (mech->mechanism) { case CKM_RSA_PKCS_KEY_PAIR_GEN: rc = ckm_rsa_key_pair_gen( publ_key_obj->template, priv_key_obj->template ); break; #if !(NODSA) case CKM_DSA_KEY_PAIR_GEN: rc = ckm_dsa_key_pair_gen( publ_key_obj->template, priv_key_obj->template ); break; #endif /* Begin code contributed by Corrent corp. */ #if !(NODH) case CKM_DH_PKCS_KEY_PAIR_GEN: rc = ckm_dh_pkcs_key_pair_gen( publ_key_obj->template, priv_key_obj->template ); break; #endif /* End code contributed by Corrent corp. */ default: st_err_log(28, __FILE__, __LINE__); rc = CKR_MECHANISM_INVALID; break; } if (rc != CKR_OK){ st_err_log(91, __FILE__, __LINE__); goto error; } // we can now set CKA_ALWAYS_SENSITIVE and CKA_NEVER_EXTRACTABLE // to their appropriate values. this only applies to CKO_SECRET_KEY // and CKO_PRIVATE_KEY objects // flag = template_attribute_find( priv_key_obj->template, CKA_SENSITIVE, &attr ); if (flag == TRUE) { flag = *(CK_BBOOL *)attr->pValue; rc = build_attribute( CKA_ALWAYS_SENSITIVE, &flag, sizeof(CK_BBOOL), &new_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } template_update_attribute( priv_key_obj->template, new_attr ); } else { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } flag = template_attribute_find( priv_key_obj->template, CKA_EXTRACTABLE, &attr ); if (flag == TRUE) { flag = *(CK_BBOOL *)attr->pValue; rc = build_attribute( CKA_NEVER_EXTRACTABLE, &true, sizeof(CK_BBOOL), &new_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } if (flag == TRUE) *(CK_BBOOL *)new_attr->pValue = false; template_update_attribute( priv_key_obj->template, new_attr ); } else { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } // at this point, the keys should be fully constructed...assign // object handles and store the keys // rc = object_mgr_create_final( sess, publ_key_obj, publ_key_handle ); if (rc != CKR_OK){ st_err_log(90, __FILE__, __LINE__); goto error; } rc = object_mgr_create_final( sess, priv_key_obj, priv_key_handle ); if (rc != CKR_OK){ st_err_log(90, __FILE__, __LINE__); // just calling object_free in the error path below would lead to a double // free error on session close - KEY 09/26/07 object_mgr_destroy_object( sess, *publ_key_handle ); publ_key_obj = NULL; goto error; } return rc; error: if (publ_key_obj) object_free( publ_key_obj ); if (priv_key_obj) object_free( priv_key_obj ); *publ_key_handle = 0; *priv_key_handle = 0; return rc; } // // CK_RV key_mgr_wrap_key( SESSION * sess, CK_BBOOL length_only, CK_MECHANISM * mech, CK_OBJECT_HANDLE h_wrapping_key, CK_OBJECT_HANDLE h_key, CK_BYTE * wrapped_key, CK_ULONG * wrapped_key_len ) { ENCR_DECR_CONTEXT * ctx = NULL; OBJECT * key1_obj = NULL; OBJECT * key2_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * data = NULL; CK_ULONG data_len; CK_OBJECT_CLASS class; CK_KEY_TYPE keytype; CK_BBOOL flag; CK_RV rc; if (!sess || !wrapped_key_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( h_wrapping_key, &key1_obj ); if (rc != CKR_OK){ st_err_log(62, __FILE__, __LINE__); return CKR_WRAPPING_KEY_HANDLE_INVALID; } rc = object_mgr_find_in_map1( h_key, &key2_obj ); if (rc != CKR_OK){ st_err_log(18, __FILE__, __LINE__); return CKR_KEY_HANDLE_INVALID; } // is the key-to-be-wrapped EXTRACTABLE? // rc = template_attribute_find( key2_obj->template, CKA_EXTRACTABLE, &attr ); if (rc == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; // could happen if user tries to wrap a public key } else { flag = *(CK_BBOOL *)attr->pValue; if (flag == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } } // what kind of key are we trying to wrap? make sure the mechanism is // allowed to wrap this kind of key // rc = template_attribute_find( key2_obj->template, CKA_CLASS, &attr ); if (rc == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } else class = *(CK_OBJECT_CLASS *)attr->pValue; switch (mech->mechanism) { #if !(NOCDMF) case CKM_CDMF_ECB: case CKM_CDMF_CBC: #endif case CKM_DES_ECB: case CKM_DES_CBC: case CKM_DES3_ECB: case CKM_DES3_CBC: case CKM_AES_ECB: case CKM_AES_CBC: if (class != CKO_SECRET_KEY){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } break; #if !(NOCDMF) case CKM_CDMF_CBC_PAD: #endif case CKM_DES_CBC_PAD: case CKM_DES3_CBC_PAD: case CKM_AES_CBC_PAD: // these mechanisms can wrap any type of key // break; case CKM_RSA_PKCS: if (class != CKO_SECRET_KEY){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } break; default: st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } // extract the secret data to be wrapped // rc = template_attribute_find( key2_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } else keytype = *(CK_KEY_TYPE *)attr->pValue; switch (keytype) { #if !(NOCDMF) case CKK_CDMF: #endif case CKK_DES: rc = des_wrap_get_data( key2_obj->template, length_only, &data, &data_len ); if (rc != CKR_OK){ st_err_log(92, __FILE__, __LINE__); return rc; } break; case CKK_DES3: rc = des3_wrap_get_data( key2_obj->template, length_only, &data, &data_len ); if (rc != CKR_OK){ st_err_log(93, __FILE__, __LINE__); return rc; } break; case CKK_RSA: rc = rsa_priv_wrap_get_data( key2_obj->template, length_only, &data, &data_len ); if (rc != CKR_OK){ st_err_log(94, __FILE__, __LINE__); return rc; } break; #if !(NODSA) case CKK_DSA: rc = dsa_priv_wrap_get_data( key2_obj->template, length_only, &data, &data_len ); if (rc != CKR_OK){ st_err_log(95, __FILE__, __LINE__); return rc; } break; #endif case CKK_GENERIC_SECRET: rc = generic_secret_wrap_get_data( key2_obj->template, length_only, &data, &data_len ); if (rc != CKR_OK){ st_err_log(96, __FILE__, __LINE__); return rc; } break; #ifndef NOAES case CKK_AES: rc = aes_wrap_get_data( key2_obj->template, length_only, &data, &data_len ); if (rc != CKR_OK){ st_err_log(191, __FILE__, __LINE__); return rc; } break; #endif default: st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } // we might need to format the wrapped data based on the mechanism // switch (mech->mechanism) { #if !(NOCMF) case CKM_CDMF_ECB: case CKM_CDMF_CBC: #endif case CKM_DES_ECB: case CKM_DES_CBC: case CKM_DES3_ECB: case CKM_DES3_CBC: rc = ckm_des_wrap_format( length_only, &data, &data_len ); if (rc != CKR_OK) { st_err_log(97, __FILE__, __LINE__); if (data) free( data ); return rc; } break; #ifndef NOAES case CKM_AES_ECB: case CKM_AES_CBC: rc = ckm_aes_wrap_format( length_only, &data, &data_len ); if (rc != CKR_OK) { st_err_log(192, __FILE__, __LINE__); if (data) free( data ); return rc; } break; #endif #if !(NOCMF) case CKM_CDMF_CBC_PAD: #endif case CKM_DES_CBC_PAD: case CKM_DES3_CBC_PAD: case CKM_AES_CBC_PAD: // these mechanisms pad themselves // break; case CKM_RSA_PKCS: // rc = ckm_rsa_wrap_format( length_only, &data, &data_len ); // if (rc != CKR_OK) { // free( data ); // return rc; // } break; default: st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } ctx = (ENCR_DECR_CONTEXT *)malloc(sizeof(ENCR_DECR_CONTEXT)); if (!ctx){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx, 0x0, sizeof(ENCR_DECR_CONTEXT) ); // prepare to do the encryption // rc = encr_mgr_init( sess, ctx, OP_WRAP, mech, h_wrapping_key ); if (rc != CKR_OK){ st_err_log(98, __FILE__, __LINE__); return rc; } // do the encryption and clean up. at this point, 'value' may or may not // be NULL depending on 'length_only' // rc = encr_mgr_encrypt( sess, length_only, ctx, data, data_len, wrapped_key, wrapped_key_len ); if (data != NULL){ free( data ); } encr_mgr_cleanup( ctx ); free( ctx ); return rc; } // // CK_RV key_mgr_unwrap_key( SESSION * sess, CK_MECHANISM * mech, CK_ATTRIBUTE * attributes, CK_ULONG attrib_count, CK_BYTE * wrapped_key, CK_ULONG wrapped_key_len, CK_OBJECT_HANDLE h_unwrapping_key, CK_OBJECT_HANDLE * h_unwrapped_key ) { ENCR_DECR_CONTEXT * ctx = NULL; OBJECT * key_obj = NULL; CK_BYTE * data = NULL; CK_ULONG data_len; CK_ULONG keyclass, keytype; CK_ULONG i; CK_BBOOL found_class, found_type, fromend; CK_RV rc; if (!sess || !wrapped_key || !h_unwrapped_key){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( h_unwrapping_key, &key_obj ); if (rc != CKR_OK){ st_err_log(62, __FILE__, __LINE__); return CKR_WRAPPING_KEY_HANDLE_INVALID; } found_class = FALSE; found_type = FALSE; // some mechanisms are restricted to wrapping certain types of keys. // in these cases, the CKA_CLASS attribute is implied and isn't required // to be specified in the template (though it still may appear) // switch (mech->mechanism) { case CKM_RSA_PKCS: keyclass = CKO_SECRET_KEY; found_class = TRUE; break; #if !(NOCMF) case CKM_CDMF_ECB: case CKM_CDMF_CBC: #endif case CKM_DES_ECB: case CKM_DES_CBC: case CKM_DES3_ECB: case CKM_DES3_CBC: case CKM_AES_ECB: case CKM_AES_CBC: keyclass = CKO_SECRET_KEY; found_class = TRUE; break; #if !(NOCMF) case CKM_CDMF_CBC_PAD: #endif case CKM_DES_CBC_PAD: case CKM_DES3_CBC_PAD: case CKM_AES_CBC_PAD: // these mechanisms can wrap any type of key so nothing is implied // break; } // extract key type and key class from the template if they exist. we // have to scan the entire template in case the CKA_CLASS or CKA_KEY_TYPE // attributes are duplicated // for (i=0; i < attrib_count; i++) { switch (attributes[i].type) { case CKA_CLASS: keyclass = *(CK_OBJECT_CLASS *)attributes[i].pValue; found_class = TRUE; break; case CKA_KEY_TYPE: keytype = *(CK_KEY_TYPE *)attributes[i].pValue; found_type = TRUE; break; } } // if we're unwrapping a private key, we can extract the key type from // the BER-encoded information // if (found_class == FALSE || (found_type == FALSE && keyclass != CKO_PRIVATE_KEY)){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } // final check to see if mechanism is allowed to unwrap such a key // switch (mech->mechanism) { case CKM_RSA_PKCS: if (keyclass != CKO_SECRET_KEY){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } break; #if !(NOCMF) case CKM_CDMF_ECB: case CKM_CDMF_CBC: #endif case CKM_DES_ECB: case CKM_DES_CBC: case CKM_DES3_ECB: case CKM_DES3_CBC: case CKM_AES_ECB: case CKM_AES_CBC: if (keyclass != CKO_SECRET_KEY){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } break; #if !(NOCMF) case CKM_CDMF_CBC_PAD: #endif case CKM_DES_CBC_PAD: case CKM_DES3_CBC_PAD: case CKM_AES_CBC_PAD: break; default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // looks okay...do the decryption // ctx = (ENCR_DECR_CONTEXT *)malloc(sizeof(ENCR_DECR_CONTEXT)); if (!ctx){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx, 0x0, sizeof(ENCR_DECR_CONTEXT) ); rc = decr_mgr_init( sess, ctx, OP_UNWRAP, mech, h_unwrapping_key ); if (rc != CKR_OK) return rc; rc = decr_mgr_decrypt( sess, TRUE, ctx, wrapped_key, wrapped_key_len, data, &data_len ); if (rc != CKR_OK){ st_err_log(100, __FILE__, __LINE__); goto error; } data = (CK_BYTE *)malloc(data_len); if (!data) { st_err_log(0, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto error; } rc = decr_mgr_decrypt( sess, FALSE, ctx, wrapped_key, wrapped_key_len, data, &data_len ); decr_mgr_cleanup( ctx ); free( ctx ); if (rc != CKR_OK){ st_err_log(100, __FILE__, __LINE__); goto error; } // if we use X.509, the data will be padded from the front with zeros. // PKCS #11 specifies that for this mechanism, CK_VALUE is to be read // from the end of the data. // // Note: the PKCS #11 reference implementation gets this wrong. // if (mech->mechanism == CKM_RSA_X_509) fromend = TRUE; else fromend = FALSE; // extract the key type from the PrivateKeyInfo::AlgorithmIndicator // if (keyclass == CKO_PRIVATE_KEY) { rc = key_mgr_get_private_key_type( data, data_len, &keytype ); if (rc != CKR_OK){ st_err_log(101, __FILE__, __LINE__); goto error; } } // we have decrypted the wrapped key data. we also // know what type of key it is. now we need to construct a new key // object... // rc = object_mgr_create_skel( sess, attributes, attrib_count, MODE_UNWRAP, keyclass, keytype, &key_obj ); if (rc != CKR_OK){ st_err_log(89, __FILE__, __LINE__); goto error; } // at this point, 'key_obj' should contain a skeleton key. depending on // the key type. we're now ready to plug in the decrypted key data. // in some cases, the data will be BER-encoded so we'll need to decode it. // // this routine also ensires that CKA_EXTRACTABLE == FALSE, // CKA_ALWAYS_SENSITIVE == FALSE and CKA_LOCAL == FALSE // switch (keyclass) { case CKO_SECRET_KEY: rc = secret_key_unwrap( key_obj->template, keytype, data, data_len, fromend ); break; case CKO_PRIVATE_KEY: rc = priv_key_unwrap( key_obj->template, keytype, data, data_len ); break; default: rc = CKR_WRAPPED_KEY_INVALID; break; } if (rc != CKR_OK){ st_err_log(173, __FILE__, __LINE__); goto error; } // at this point, the key should be fully constructed...assign // an object handle and store the key // rc = object_mgr_create_final( sess, key_obj, h_unwrapped_key ); if (rc != CKR_OK){ st_err_log(90, __FILE__, __LINE__); goto error; } if (data) free(data); return rc; error: if (key_obj) object_free( key_obj ); if (data) free(data); return rc; } CK_RV key_mgr_get_private_key_type( CK_BYTE *keydata, CK_ULONG keylen, CK_KEY_TYPE *keytype ) { CK_BYTE *alg = NULL; CK_BYTE *priv_key = NULL; CK_ULONG alg_len; CK_RV rc; rc = ber_decode_PrivateKeyInfo( keydata, keylen, &alg, &alg_len, &priv_key ); if (rc != CKR_OK){ st_err_log(102, __FILE__, __LINE__); return rc; } // check the entire AlgorithmIdentifier for RSA // if (alg_len >= ber_rsaEncryptionLen) { if (memcmp(alg, ber_rsaEncryption, ber_rsaEncryptionLen) == 0) { *keytype = CKK_RSA; return CKR_OK; } } // Check only the OBJECT IDENTIFIER for DSA // if (alg_len >= ber_idDSALen) { if (memcmp(alg, ber_idDSA, ber_idDSALen) == 0) { *keytype = CKK_DSA; return CKR_OK; } } st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } // // CK_RV key_mgr_derive_key( SESSION * sess, CK_MECHANISM * mech, CK_OBJECT_HANDLE base_key, CK_OBJECT_HANDLE * derived_key, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ) { if (!sess || !mech){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!pTemplate && (ulCount != 0)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } switch (mech->mechanism) { case CKM_SSL3_MASTER_KEY_DERIVE: { if (!derived_key){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } return ssl3_master_key_derive( sess, mech, base_key, pTemplate, ulCount, derived_key ); } break ; case CKM_SSL3_KEY_AND_MAC_DERIVE: { CK_SSL3_KEY_MAT_PARAMS *params = (CK_SSL3_KEY_MAT_PARAMS *)mech->pParameter; // Check FCV // // if (((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_56_BIT_DES) == 0) && (params->bIsExport == FALSE)) // return CKR_MECHANISM_INVALID; return ssl3_key_and_mac_derive( sess, mech, base_key, pTemplate, ulCount ); } break ; /* Begin code contributed by Corrent corp. */ #ifndef NODH case CKM_DH_PKCS_DERIVE: { if (!derived_key){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } return dh_pkcs_derive( sess, mech, base_key, pTemplate, ulCount, derived_key ); } break ; #endif /* End code contributed by Corrent corp. */ default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/mech_rsa.c0000640000175000017500000006763211327631345021371 0ustar jfjf /* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */ /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */ // File: mech_rsa.c // // Mechanisms for RSA // // Routines contained within: #include #include #include // for memcmp() et al #include #include "pkcs11/pkcs11types.h" #include #include "defs.h" #include "host_defs.h" #include "tok_spec_struct.h" #include "h_extern.h" // // CK_RV ckm_rsa_key_pair_gen( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ) { CK_RV rc; rc = token_specific.t_rsa_generate_keypair(publ_tmpl, priv_tmpl); if (rc != CKR_OK) st_err_log(91, __FILE__, __LINE__); return rc; } // // CK_RV ckm_rsa_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, OBJECT * key_obj ) { CK_ATTRIBUTE * attr = NULL; CK_ATTRIBUTE * modulus = NULL; CK_OBJECT_CLASS keyclass; CK_RV rc; rc = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else keyclass = *(CK_OBJECT_CLASS *)attr->pValue; // this had better be a public key // if (keyclass != CKO_PUBLIC_KEY){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_rsa_encrypt(in_data, in_data_len, out_data, out_data_len, key_obj); if (rc != CKR_OK) st_err_log(134, __FILE__, __LINE__); return rc; } // // CK_RV ckm_rsa_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, OBJECT * key_obj ) { CK_ATTRIBUTE * attr = NULL; CK_OBJECT_CLASS keyclass; CK_RV rc; rc = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else keyclass = *(CK_OBJECT_CLASS *)attr->pValue; // this had better be a private key // if (keyclass != CKO_PRIVATE_KEY){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_rsa_decrypt(in_data, in_data_len, out_data, out_data_len, key_obj); if (rc != CKR_OK) st_err_log(135, __FILE__, __LINE__); return rc; } // // CK_RV ckm_rsa_sign( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, OBJECT * key_obj ) { CK_ATTRIBUTE * attr = NULL; CK_OBJECT_CLASS keyclass; CK_RV rc; rc = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else keyclass = *(CK_OBJECT_CLASS *)attr->pValue; // this had better be a private key // if (keyclass != CKO_PRIVATE_KEY){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_rsa_sign(in_data, in_data_len, out_data, out_data_len, key_obj); if (rc != CKR_OK) st_err_log(135, __FILE__, __LINE__); return rc; } // // CK_RV ckm_rsa_verify( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG out_data_len, OBJECT * key_obj ) { CK_ATTRIBUTE * attr = NULL; CK_OBJECT_CLASS keyclass; CK_RV rc; rc = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else keyclass = *(CK_OBJECT_CLASS *)attr->pValue; // this had better be a private key // if (keyclass != CKO_PUBLIC_KEY){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_rsa_verify(in_data, in_data_len, out_data, out_data_len, key_obj); if (rc != CKR_OK) st_err_log(135, __FILE__, __LINE__); return rc; } // // CK_RV rsa_pkcs_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { OBJECT *key_obj = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE clear[256], cipher[256]; // 2048 bits CK_ULONG modulus_bytes; CK_BBOOL flag; CK_RV rc; rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } flag = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else modulus_bytes = attr->ulValueLen; // check input data length restrictions // if (in_data_len > (modulus_bytes - 11)){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } if (length_only == TRUE) { *out_data_len = modulus_bytes; return CKR_OK; } if (*out_data_len < modulus_bytes) { *out_data_len = modulus_bytes; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } rc = ckm_rsa_encrypt( in_data, in_data_len, out_data, out_data_len, key_obj ); if (rc != CKR_OK) st_err_log(132, __FILE__, __LINE__); return rc; } // // CK_RV rsa_pkcs_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { OBJECT *key_obj = NULL; CK_ATTRIBUTE *attr = NULL; CK_ULONG i, modulus_bytes; CK_BBOOL flag; CK_RV rc; rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } flag = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); if (flag == FALSE) return CKR_FUNCTION_FAILED; else modulus_bytes = attr->ulValueLen; // check input data length restrictions // if (in_data_len != modulus_bytes){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } if (length_only == TRUE) { // this is not exact but it's the upper bound; otherwise we'll need // to do the RSA operation just to get the required length // *out_data_len = modulus_bytes - 11; return CKR_OK; } rc = ckm_rsa_decrypt( in_data, modulus_bytes, out_data, out_data_len, key_obj ); if (rc != CKR_OK) st_err_log(133, __FILE__, __LINE__); if (rc == CKR_DATA_LEN_RANGE){ st_err_log(109, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } return rc; } // // CK_RV rsa_pkcs_sign( SESSION *sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { OBJECT *key_obj = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE data[256], sig[256]; // max size: 256 bytes == 2048 bits CK_ULONG modulus_bytes; CK_BBOOL flag; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } flag = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); if (flag == FALSE) return CKR_FUNCTION_FAILED; else modulus_bytes = attr->ulValueLen; // check input data length restrictions // #if 0 if (in_data_len != modulus_bytes){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } #endif if (in_data_len > modulus_bytes - 11){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } if (length_only == TRUE) { *out_data_len = modulus_bytes; return CKR_OK; } if (*out_data_len < modulus_bytes) { *out_data_len = modulus_bytes; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } #if 0 // signing is a private key operation --> decrypt // rc = ckm_rsa_decrypt( data, in_data_len, out_data, out_data_len, key_obj ); #else rc = ckm_rsa_sign( in_data, in_data_len, out_data, out_data_len, key_obj ); #endif if (rc != CKR_OK) st_err_log(133, __FILE__, __LINE__); return rc; } // // CK_RV rsa_pkcs_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ) { OBJECT *key_obj = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE out[256]; // 2048 bits CK_ULONG i, modulus_bytes, out_len = 256; CK_BBOOL flag; CK_RV rc; rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } flag = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else modulus_bytes = attr->ulValueLen; // check input data length restrictions // if (sig_len != modulus_bytes){ st_err_log(46, __FILE__, __LINE__); return CKR_SIGNATURE_LEN_RANGE; } // verify is a public key operation --> encrypt // #if 0 rc = ckm_rsa_encrypt( signature, modulus_bytes, out, &out_len, key_obj ); if (rc == CKR_OK) { if (out_len != in_data_len){ st_err_log(47, __FILE__, __LINE__); return CKR_SIGNATURE_INVALID; } if (memcmp(in_data, &out, out_len) != 0){ st_err_log(47, __FILE__, __LINE__); return CKR_SIGNATURE_INVALID; } return CKR_OK; } else #else rc = ckm_rsa_verify( in_data, in_data_len, signature, sig_len, key_obj ); if (rc != CKR_OK) #endif st_err_log(132, __FILE__, __LINE__); return rc; } // // CK_RV rsa_pkcs_verify_recover( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len, CK_BYTE * out_data, CK_ULONG * out_data_len ) { OBJECT *key_obj = NULL; CK_ATTRIBUTE *attr = NULL; CK_ULONG i, modulus_bytes; CK_BBOOL flag; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } flag = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else modulus_bytes = attr->ulValueLen; // check input data length restrictions // if (sig_len != modulus_bytes){ st_err_log(46, __FILE__, __LINE__); return CKR_SIGNATURE_LEN_RANGE; } if (length_only == TRUE) { *out_data_len = modulus_bytes; return CKR_OK; } // verify is a public key operation --> encrypt // rc = ckm_rsa_encrypt( signature, modulus_bytes, out_data, out_data_len, key_obj ); if (rc != CKR_OK) st_err_log(132, __FILE__, __LINE__); return rc; } // // CK_RV rsa_hash_pkcs_sign( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG * sig_len ) { CK_BYTE * ber_data = NULL; CK_BYTE * octet_str = NULL; CK_BYTE * oid = NULL; CK_BYTE * tmp = NULL; CK_ULONG buf1[16]; // 64 bytes is more than enough CK_BYTE hash[SHA1_HASH_SIZE]; // big enough for SHA1, MD5 or MD2 DIGEST_CONTEXT digest_ctx; SIGN_VERIFY_CONTEXT sign_ctx; CK_MECHANISM digest_mech; CK_MECHANISM sign_mech; CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len; CK_RV rc; if (!sess || !ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memset( &digest_ctx, 0x0, sizeof(digest_ctx) ); memset( &sign_ctx, 0x0, sizeof(sign_ctx) ); if (ctx->mech.mechanism == CKM_MD2_RSA_PKCS) { digest_mech.mechanism = CKM_MD2; oid = ber_AlgMd2; oid_len = ber_AlgMd2Len; } else if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) { digest_mech.mechanism = CKM_MD5; oid = ber_AlgMd5; oid_len = ber_AlgMd5Len; } else { digest_mech.mechanism = CKM_SHA_1; oid = ber_AlgSha1; oid_len = ber_AlgSha1Len; } digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } hash_len = sizeof(hash); rc = digest_mgr_digest( sess, length_only, &digest_ctx, in_data, in_data_len, hash, &hash_len ); if (rc != CKR_OK){ st_err_log(124, __FILE__, __LINE__); goto error; } // build the BER-encodings rc = ber_encode_OCTET_STRING( FALSE, &octet_str, &octet_str_len, hash, hash_len ); if (rc != CKR_OK){ st_err_log(77, __FILE__, __LINE__); goto error; } tmp = (CK_BYTE *)buf1; memcpy( tmp, oid, oid_len ); memcpy( tmp + oid_len, octet_str, octet_str_len); rc = ber_encode_SEQUENCE( FALSE, &ber_data, &ber_data_len, tmp, (oid_len + octet_str_len) ); if (rc != CKR_OK){ st_err_log(78, __FILE__, __LINE__); goto error; } // sign the BER-encoded data block sign_mech.mechanism = CKM_RSA_PKCS; sign_mech.ulParameterLen = 0; sign_mech.pParameter = NULL; rc = sign_mgr_init( sess, &sign_ctx, &sign_mech, FALSE, ctx->key ); if (rc != CKR_OK){ st_err_log(127, __FILE__, __LINE__); goto error; } //rc = sign_mgr_sign( sess, length_only, &sign_ctx, hash, hash_len, signature, sig_len ); rc = sign_mgr_sign( sess, length_only, &sign_ctx, ber_data, ber_data_len, signature, sig_len ); if (rc != CKR_OK) st_err_log(128, __FILE__, __LINE__); error: if (octet_str) free( octet_str ); if (ber_data) free( ber_data ); digest_mgr_cleanup( &digest_ctx ); sign_mgr_cleanup( &sign_ctx ); return rc; } // // CK_RV rsa_hash_pkcs_sign_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { RSA_DIGEST_CONTEXT * context = NULL; CK_MECHANISM digest_mech; CK_RV rc; if (!sess || !ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (RSA_DIGEST_CONTEXT *)ctx->context; if (context->flag == FALSE) { if (ctx->mech.mechanism == CKM_MD2_RSA_PKCS) digest_mech.mechanism = CKM_MD2; else if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) digest_mech.mechanism = CKM_MD5; else digest_mech.mechanism = CKM_SHA_1; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &context->hash_context, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } context->flag = TRUE; } rc = digest_mgr_digest_update( sess, &context->hash_context, in_data, in_data_len ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } return CKR_OK; error: digest_mgr_cleanup( &context->hash_context ); return rc; } // // CK_RV rsa_hash_pkcs_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ) { CK_BYTE * ber_data = NULL; CK_BYTE * octet_str = NULL; CK_BYTE * oid = NULL; CK_BYTE * tmp = NULL; CK_ULONG buf1[16]; // 64 bytes is more than enough CK_BYTE hash[SHA1_HASH_SIZE]; DIGEST_CONTEXT digest_ctx; SIGN_VERIFY_CONTEXT verify_ctx; CK_MECHANISM digest_mech; CK_MECHANISM verify_mech; CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len; CK_RV rc; if (!sess || !ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memset( &digest_ctx, 0x0, sizeof(digest_ctx) ); memset( &verify_ctx, 0x0, sizeof(verify_ctx) ); if (ctx->mech.mechanism == CKM_MD2_RSA_PKCS) { digest_mech.mechanism = CKM_MD2; oid = ber_AlgMd2; oid_len = ber_AlgMd2Len; } else if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) { digest_mech.mechanism = CKM_MD5; oid = ber_AlgMd5; oid_len = ber_AlgMd5Len; } else { digest_mech.mechanism = CKM_SHA_1; oid = ber_AlgSha1; oid_len = ber_AlgSha1Len; } digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto done; } hash_len = sizeof(hash); rc = digest_mgr_digest( sess, FALSE, &digest_ctx, in_data, in_data_len, hash, &hash_len ); if (rc != CKR_OK){ st_err_log(124, __FILE__, __LINE__); goto done; } // Build the BER encoding // rc = ber_encode_OCTET_STRING( FALSE, &octet_str, &octet_str_len, hash, hash_len ); if (rc != CKR_OK){ st_err_log(77, __FILE__, __LINE__); goto done; } tmp = (CK_BYTE *)buf1; memcpy( tmp, oid, oid_len ); memcpy( tmp + oid_len, octet_str, octet_str_len ); rc = ber_encode_SEQUENCE( FALSE, &ber_data, &ber_data_len, tmp, (oid_len + octet_str_len) ); if (rc != CKR_OK){ st_err_log(78, __FILE__, __LINE__); goto done; } // Verify the Signed BER-encoded Data block // verify_mech.mechanism = CKM_RSA_PKCS; verify_mech.ulParameterLen = 0; verify_mech.pParameter = NULL; rc = verify_mgr_init( sess, &verify_ctx, &verify_mech, FALSE, ctx->key ); if (rc != CKR_OK){ st_err_log(167, __FILE__, __LINE__); goto done; } //rc = verify_mgr_verify( sess, &verify_ctx, hash, hash_len, signature, sig_len ); rc = verify_mgr_verify( sess, &verify_ctx, ber_data, ber_data_len, signature, sig_len ); if (rc != CKR_OK) st_err_log(168, __FILE__, __LINE__); done: if (octet_str) free( octet_str ); if (ber_data) free( ber_data ); digest_mgr_cleanup( &digest_ctx ); sign_mgr_cleanup( &verify_ctx ); return rc; } // // CK_RV rsa_hash_pkcs_verify_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { RSA_DIGEST_CONTEXT * context = NULL; CK_MECHANISM digest_mech; CK_RV rc; if (!sess || !ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (RSA_DIGEST_CONTEXT *)ctx->context; if (context->flag == FALSE) { if (ctx->mech.mechanism == CKM_MD2_RSA_PKCS) digest_mech.mechanism = CKM_MD2; else if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) digest_mech.mechanism = CKM_MD5; else digest_mech.mechanism = CKM_SHA_1; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &context->hash_context, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } context->flag = TRUE; } rc = digest_mgr_digest_update( sess, &context->hash_context, in_data, in_data_len ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } return CKR_OK; error: digest_mgr_cleanup( &context->hash_context ); return rc; } // // CK_RV rsa_hash_pkcs_sign_final( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG * sig_len ) { CK_BYTE * ber_data = NULL; CK_BYTE * octet_str = NULL; CK_BYTE * oid = NULL; CK_BYTE * tmp = NULL; CK_ULONG buf1[16]; // 64 bytes is more than enough CK_BYTE hash[SHA1_HASH_SIZE]; RSA_DIGEST_CONTEXT * context = NULL; CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len; CK_MECHANISM sign_mech; SIGN_VERIFY_CONTEXT sign_ctx; CK_RV rc; if (!sess || !ctx || !sig_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_MD2_RSA_PKCS) { oid = ber_AlgMd2; oid_len = ber_AlgMd2Len; } else if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) { oid = ber_AlgMd5; oid_len = ber_AlgMd5Len; } else { oid = ber_AlgSha1; oid_len = ber_AlgSha1Len; } memset( &sign_ctx, 0x0, sizeof(sign_ctx)); context = (RSA_DIGEST_CONTEXT *)ctx->context; hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, length_only, &context->hash_context, hash, &hash_len ); if (rc != CKR_OK){ st_err_log(126, __FILE__, __LINE__); goto done; } // Build the BER Encoded Data block // rc = ber_encode_OCTET_STRING( FALSE, &octet_str, &octet_str_len, hash, hash_len ); if (rc != CKR_OK){ st_err_log(77, __FILE__, __LINE__); goto done; } tmp = (CK_BYTE *)buf1; memcpy( tmp, oid, oid_len ); memcpy( tmp + oid_len, octet_str, octet_str_len ); rc = ber_encode_SEQUENCE( FALSE, &ber_data, &ber_data_len, tmp, (oid_len + octet_str_len) ); if (rc != CKR_OK){ st_err_log(78, __FILE__, __LINE__); goto done; } // sign the BER-encoded data block // sign_mech.mechanism = CKM_RSA_PKCS; sign_mech.ulParameterLen = 0; sign_mech.pParameter = NULL; rc = sign_mgr_init( sess, &sign_ctx, &sign_mech, FALSE, ctx->key ); if (rc != CKR_OK){ st_err_log(127, __FILE__, __LINE__); goto done; } //rc = sign_mgr_sign( sess, length_only, &sign_ctx, hash, hash_len, signature, sig_len ); rc = sign_mgr_sign( sess, length_only, &sign_ctx, ber_data, ber_data_len, signature, sig_len ); if (rc != CKR_OK) st_err_log(128, __FILE__, __LINE__); if (length_only == TRUE || rc == CKR_BUFFER_TOO_SMALL) { sign_mgr_cleanup( &sign_ctx ); return rc; } done: if (octet_str) free( octet_str ); if (ber_data) free( ber_data ); digest_mgr_cleanup( &context->hash_context ); sign_mgr_cleanup( &sign_ctx ); return rc; } // // CK_RV rsa_hash_pkcs_verify_final( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len ) { CK_BYTE * ber_data = NULL; CK_BYTE * octet_str = NULL; CK_BYTE * oid = NULL; CK_BYTE * tmp = NULL; CK_ULONG buf1[16]; // 64 bytes is more than enough CK_BYTE hash[SHA1_HASH_SIZE]; RSA_DIGEST_CONTEXT * context = NULL; CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len; CK_MECHANISM verify_mech; SIGN_VERIFY_CONTEXT verify_ctx; CK_RV rc; if (!sess || !ctx || !signature){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_MD2_RSA_PKCS) { oid = ber_AlgMd2; oid_len = ber_AlgMd2Len; } else if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) { oid = ber_AlgMd5; oid_len = ber_AlgMd5Len; } else { oid = ber_AlgSha1; oid_len = ber_AlgSha1Len; } memset( &verify_ctx, 0x0, sizeof(verify_ctx)); context = (RSA_DIGEST_CONTEXT *)ctx->context; hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &context->hash_context, hash, &hash_len ); if (rc != CKR_OK){ st_err_log(126, __FILE__, __LINE__); goto done; } // Build the BER encoding // rc = ber_encode_OCTET_STRING( FALSE, &octet_str, &octet_str_len, hash, hash_len ); if (rc != CKR_OK){ st_err_log(77, __FILE__, __LINE__); goto done; } tmp = (CK_BYTE *)buf1; memcpy( tmp, oid, oid_len ); memcpy( tmp + oid_len, octet_str, octet_str_len ); rc = ber_encode_SEQUENCE( FALSE, &ber_data, &ber_data_len, tmp, (oid_len + octet_str_len) ); if (rc != CKR_OK){ st_err_log(78, __FILE__, __LINE__); goto done; } // verify the signed BER-encoded data block // verify_mech.mechanism = CKM_RSA_PKCS; verify_mech.ulParameterLen = 0; verify_mech.pParameter = NULL; rc = verify_mgr_init( sess, &verify_ctx, &verify_mech, FALSE, ctx->key ); if (rc != CKR_OK){ st_err_log(167, __FILE__, __LINE__); goto done; } //rc = verify_mgr_verify( sess, &verify_ctx, hash, hash_len, signature, sig_len ); rc = verify_mgr_verify( sess, &verify_ctx, ber_data, ber_data_len, signature, sig_len ); if (rc != CKR_OK) st_err_log(168, __FILE__, __LINE__); done: if (octet_str) free( octet_str ); if (ber_data) free( ber_data ); digest_mgr_cleanup( &context->hash_context ); verify_mgr_cleanup( &verify_ctx ); return rc; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/tok_specific.h0000640000175000017500000001270411327631345022245 0ustar jfjf/* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */ /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */ /*************************************************************************** Change Log ========== 4/25/03 Kapil Sood (kapil@corrent.com) Added DH key pair generation and DH shared key derivation functions. ****************************************************************************/ // Token specific functions that tokens must implement..... // // Prototypes #ifndef _TOK_SPECIFIC #define _TOK_SPECIFIC CK_RV token_rng(CK_BYTE *, CK_ULONG); int tok_slot2local(CK_SLOT_ID); CK_RV token_specific_init(char *,CK_SLOT_ID ); CK_RV token_specific_session(CK_SLOT_ID); CK_RV token_specific_final(void); CK_RV token_specific_des_key_gen(CK_BYTE *,CK_ULONG) ; CK_RV token_specific_des_ecb(CK_BYTE *, CK_ULONG , CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_BYTE ); CK_RV token_specific_des_cbc(CK_BYTE *, CK_ULONG , CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_BYTE *, CK_BYTE ); CK_RV token_specific_tdes_ecb(CK_BYTE *, CK_ULONG , CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_BYTE ); CK_RV token_specific_tdes_cbc(CK_BYTE *, CK_ULONG , CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_BYTE *, CK_BYTE ); CK_RV token_specific_rsa_decrypt( CK_BYTE * , CK_ULONG , CK_BYTE * , CK_ULONG * , OBJECT *); CK_RV token_specific_rsa_encrypt( CK_BYTE * , CK_ULONG , CK_BYTE * , CK_ULONG * , OBJECT * ); CK_RV token_specific_rsa_sign( CK_BYTE * , CK_ULONG , CK_BYTE * , CK_ULONG * , OBJECT * ); CK_RV token_specific_rsa_verify( CK_BYTE * , CK_ULONG , CK_BYTE * , CK_ULONG , OBJECT * ); CK_RV token_specific_rsa_generate_keypair( TEMPLATE * , TEMPLATE * ); /* Begin code contributed by Corrent corp. */ #ifndef NODH CK_RV token_specific_dh_pkcs_derive( CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG ) ; CK_RV token_specific_dh_pkcs_key_pair_gen( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ); #endif /* End code contributed by Corrent corp. */ CK_RV tok_cdmv_transform(CK_VOID_PTR, CK_ULONG); CK_RV ckm_dsa_sign( CK_BYTE * , CK_BYTE * , OBJECT * ); CK_RV ckm_dsa_key_pair_gen( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ); CK_RV ckm_dsa_verify( CK_BYTE *, CK_BYTE *, OBJECT * ); CK_RV token_specific_sha_init( DIGEST_CONTEXT * ); CK_RV token_specific_sha_update( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG); CK_RV token_specific_sha_final( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG * ); #ifndef NOAES CK_RV token_specific_aes_key_gen( CK_BYTE *, CK_ULONG ); CK_RV token_specific_aes_ecb( CK_BYTE *, CK_ULONG , CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_ULONG , CK_BYTE ); CK_RV token_specific_aes_cbc( CK_BYTE *, CK_ULONG , CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_ULONG , CK_BYTE *, CK_BYTE ); #endif CK_RV token_specific_login(CK_USER_TYPE, CK_CHAR_PTR, CK_ULONG); CK_RV token_specific_logout(); CK_RV token_specific_init_pin(CK_CHAR_PTR, CK_ULONG); CK_RV token_specific_set_pin(ST_SESSION_HANDLE, CK_CHAR_PTR, CK_ULONG, CK_CHAR_PTR, CK_ULONG); CK_RV token_specific_verify_so_pin(CK_CHAR_PTR, CK_ULONG); #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/defs.h0000751000175000017500000000056711327631345020533 0ustar jfjf /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */ // File: defs.h // // Contains various definitions needed by both the host-side // and coprocessor-side code. // #ifndef _TPM_DEFS_H #define _TPM_DEFS_H #include "../common/defs.h" #undef MAX_PIN_LEN #undef MIN_PIN_LEN #define MAX_PIN_LEN 127 #define MIN_PIN_LEN 6 #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/h_extern.h0000640000175000017500000026774111327631345021434 0ustar jfjf/* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */ /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */ /*************************************************************************** Change Log ========== 4/25/03 Kapil Sood (kapil@corrent.com) Added DH key pair generation and DH shared key derivation functions. ****************************************************************************/ #ifndef _H_EXTERN_H #define _H_EXTERN_H #if (LEEDS_BUILD) #pragma options align=packed #endif extern char * pk_dir; // global variables // extern CK_BBOOL initialized; extern char *card_function_names[]; extern char *total_function_names[]; extern MECH_LIST_ELEMENT mech_list[]; extern CK_ULONG mech_list_len; extern pthread_mutex_t native_mutex; #if SYSVSEM extern int xprocsemid; #endif extern void *xproclock; extern MUTEX pkcs_mutex, obj_list_mutex, sess_list_mutex, login_mutex; extern DL_NODE *sess_list; extern DL_NODE *sess_obj_list; extern DL_NODE *publ_token_obj_list; extern DL_NODE *priv_token_obj_list; extern DL_NODE *object_map; #define MK_SIZE (AES_KEY_SIZE_256) extern CK_BYTE master_key_private[MK_SIZE]; extern CK_BYTE so_pin_md5[MD5_HASH_SIZE]; extern CK_BYTE user_pin_md5[MD5_HASH_SIZE]; extern CK_BYTE default_user_pin_sha[SHA1_HASH_SIZE]; extern CK_BYTE default_so_pin_sha[SHA1_HASH_SIZE]; extern CK_BYTE default_so_pin_md5[MD5_HASH_SIZE]; extern LW_SHM_TYPE *global_shm; extern TOKEN_DATA *nv_token_data; extern CK_SLOT_INFO slot_info; extern CK_ULONG next_object_handle; extern CK_ULONG next_session_handle; // SAB FIXME FIXME extern CK_STATE global_login_state; extern CK_BYTE ber_AlgIdRSAEncryption[]; extern CK_ULONG ber_AlgIdRSAEncryptionLen; extern CK_BYTE ber_rsaEncryption[]; extern CK_ULONG ber_rsaEncryptionLen; extern CK_BYTE ber_idDSA[]; extern CK_ULONG ber_idDSALen; extern CK_BYTE ber_md2WithRSAEncryption[]; extern CK_ULONG ber_md2WithRSAEncryptionLen; extern CK_BYTE ber_md4WithRSAEncryption[]; extern CK_ULONG ber_md4WithRSAEncryptionLen; extern CK_BYTE ber_md5WithRSAEncryption[]; extern CK_ULONG ber_md5WithRSAEncryptionLen; extern CK_BYTE ber_sha1WithRSAEncryption[]; extern CK_ULONG ber_sha1WithRSAEncryptionLen; extern CK_BYTE ber_AlgMd2[]; extern CK_ULONG ber_AlgMd2Len; extern CK_BYTE ber_AlgMd5[]; extern CK_ULONG ber_AlgMd5Len; extern CK_BYTE ber_AlgSha1[]; extern CK_ULONG ber_AlgSha1Len; extern CK_BYTE ber_AlgSha256[]; extern CK_ULONG ber_AlgSha256Len; extern CK_ULONG des_weak_count; extern CK_ULONG des_semi_weak_count; extern CK_ULONG des_possibly_weak_count; extern CK_BYTE des_weak_keys[4][8]; extern CK_BYTE des_semi_weak_keys[12][8]; extern CK_BYTE des_possibly_weak_keys[48][8]; extern struct ST_FCN_LIST function_list; extern CK_C_INITIALIZE_ARGS cinit_args; CK_ULONG long_reverse( CK_ULONG x ); // VACPP C runtime initialization/cleanup entry points // int _CRT_init(void); int _CRT_term(void); CK_RV DummyFunction( CK_SLOT_ID slot_id, int arg ); // General-purpose functions // CK_RV C_Initialize ( CK_VOID_PTR pInitArgs ); CK_RV C_Finalize ( CK_VOID_PTR pReserved ); CK_RV C_GetInfo ( CK_INFO_PTR pInfo ); CK_RV C_GetFunctionList ( CK_FUNCTION_LIST_PTR_PTR ppFunctionList ); // Slot and token management functions // CK_RV C_GetSlotList ( CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount ); CK_RV C_GetSlotInfo ( CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo ); CK_RV C_GetTokenInfo ( CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo ); CK_RV C_WaitForSlotEvent ( CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved ); CK_RV C_GetMechanismList ( CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount ); CK_RV C_GetMechanismInfo ( CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo ); CK_RV C_InitToken ( CK_SLOT_ID slotID, CK_CHAR_PTR pPin, CK_ULONG ulPinLen, CK_CHAR_PTR pLabel ); CK_RV C_InitPIN ( CK_SESSION_HANDLE hSession, CK_CHAR_PTR pPin, CK_ULONG ulPinLen ); CK_RV C_SetPIN ( CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, CK_ULONG ulOldLen, CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen ); // Session management functions // CK_RV C_OpenSession ( CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession ); CK_RV C_CloseSession ( CK_SESSION_HANDLE hSession ); CK_RV C_CloseAllSessions ( CK_SLOT_ID slotID ); CK_RV C_GetSessionInfo ( CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo ); CK_RV C_GetOperationState ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen ); CK_RV C_SetOperationState ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey ); CK_RV C_Login ( CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG uPinLen ); CK_RV C_Logout ( CK_SESSION_HANDLE hSession ); // Object management functions // CK_RV C_CreateObject ( CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject ); CK_RV C_CopyObject ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phNewObject ); CK_RV C_DestroyObject ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject ); CK_RV C_GetObjectSize ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize ); CK_RV C_GetAttributeValue ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ); CK_RV C_SetAttributeValue ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ); CK_RV C_FindObjectsInit ( CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ); CK_RV C_FindObjects ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount ); CK_RV C_FindObjectsFinal ( CK_SESSION_HANDLE hSession ); // Encryption functions // CK_RV C_EncryptInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_Encrypt ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen ); CK_RV C_EncryptUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ); CK_RV C_EncryptFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen); // Decryption functions // CK_RV C_DecryptInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_Decrypt ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen ); CK_RV C_DecryptUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ); CK_RV C_DecryptFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen ); // Message digesting functions // CK_RV C_DigestInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism ); CK_RV C_Digest ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen ); CK_RV C_DigestUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ); CK_RV C_DigestKey ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey ); CK_RV C_DigestFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen ); // Signing and MAC functions // CK_RV C_SignInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_Sign ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ); CK_RV C_SignUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ); CK_RV C_SignFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ); CK_RV C_SignRecoverInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_SignRecover ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ); // Signature/MAC verification functions // CK_RV C_VerifyInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_Verify ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen ); CK_RV C_VerifyUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ); CK_RV C_VerifyFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen ); CK_RV C_VerifyRecoverInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_VerifyRecover ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen ); // Dual-function cryptographics functions // CK_RV C_DigestEncryptUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ); CK_RV C_DecryptDigestUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ); CK_RV C_SignEncryptUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ); CK_RV C_DecryptVerifyUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ); // Key management functions // CK_RV C_GenerateKey ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey ); CK_RV C_GenerateKeyPair ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey ); CK_RV C_WrapKey ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen ); CK_RV C_UnwrapKey ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey ); CK_RV C_DeriveKey ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey ); // Random number generation functions // CK_RV C_SeedRandom ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen ); CK_RV C_GenerateRandom ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen ); // Parallel function management functions // CK_RV C_GetFunctionStatus ( CK_SESSION_HANDLE hSession ); CK_RV C_CancelFunction ( CK_SESSION_HANDLE hSession ); // // internal routines are below this point // CK_RV communicate( CK_ULONG cmd_id, CK_VOID_PTR pReq, CK_ULONG req_len, CK_VOID_PTR pRep, CK_ULONG_PTR repl_len, CK_BYTE_PTR pOut, CK_ULONG out_len, CK_BYTE_PTR pIn, CK_ULONG in_len ); CK_RV compute_next_token_obj_name( CK_BYTE *current, CK_BYTE *next ); CK_RV save_token_object ( OBJECT *obj ); CK_RV save_public_token_object ( OBJECT *obj ); CK_RV save_private_token_object( OBJECT *obj ); CK_RV load_public_token_objects ( void ); CK_RV load_private_token_objects( void ); CK_RV reload_token_object( OBJECT *obj ); CK_RV restore_private_token_object( CK_BYTE * data, CK_ULONG len, OBJECT * pObj ); CK_RV delete_token_object( OBJECT *ptr ); CK_RV init_token_data( void ); CK_RV load_token_data( void ); CK_RV save_token_data( void ); #if 0 CK_RV load_masterkey_so ( void ); CK_RV load_masterkey_user( void ); CK_RV save_masterkey_so ( void ); CK_RV save_masterkey_user( void ); #endif CK_RV compute_md5( CK_BYTE *data, CK_ULONG len, CK_BYTE *hash ); CK_RV compute_sha( CK_BYTE *data, CK_ULONG len, CK_BYTE *hash ); CK_ULONG long_reverse( CK_ULONG x ); //CK_RV load_FCV( void ); //CK_RV save_FCV( FUNCTION_CTRL_VEC_RECORD *new_FCV ); //CK_RV update_tweak_values( void *attributes, CK_ULONG count ); //CK_RV query_tweak_values( CK_ATTRIBUTE_TYPE * attributes, // CK_ULONG count, // CK_BYTE ** reply, // CK_ULONG * reply_len ); void init_slotInfo(void); void init_tokenInfo(void); CK_BYTE parity_adjust( CK_BYTE b ); CK_RV parity_is_odd( CK_BYTE b ); CK_RV build_attribute( CK_ATTRIBUTE_TYPE type, CK_BYTE *data, CK_ULONG data_len, CK_ATTRIBUTE **attr ); CK_RV add_pkcs_padding( CK_BYTE * ptr, // where to start appending CK_ULONG block_size, CK_ULONG data_len, CK_ULONG total_len ); CK_RV strip_pkcs_padding( CK_BYTE * ptr, CK_ULONG total_len, CK_ULONG * data_len ); CK_RV remove_leading_zeros( CK_ATTRIBUTE *attr ); // RNG routines // CK_RV rng_generate( CK_BYTE *output, CK_ULONG bytes ); // SSL3 routines // CK_RV ssl3_mac_sign( SESSION *sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV ssl3_mac_sign_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ); CK_RV ssl3_mac_sign_final( SESSION *sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV ssl3_mac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); CK_RV ssl3_mac_verify_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ); CK_RV ssl3_mac_verify_final( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len ); CK_RV ssl3_master_key_derive( SESSION * sess, CK_MECHANISM * mech, CK_OBJECT_HANDLE base_key, CK_ATTRIBUTE * attributes, CK_ULONG count, CK_OBJECT_HANDLE * handle ); CK_RV ssl3_key_and_mac_derive( SESSION * sess, CK_MECHANISM * mech, CK_OBJECT_HANDLE base_key, CK_ATTRIBUTE * attributes, CK_ULONG count ); CK_RV ckm_ssl3_pre_master_key_gen( TEMPLATE *tmpl, CK_MECHANISM *mech ); // RSA routines // CK_RV rsa_pkcs_encrypt( SESSION * sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV rsa_pkcs_decrypt( SESSION * sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV rsa_pkcs_sign ( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG * sig_len ); CK_RV rsa_pkcs_verify ( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); CK_RV rsa_pkcs_verify_recover ( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len, CK_BYTE * out_data, CK_ULONG * out_len ); CK_RV rsa_hash_pkcs_sign ( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG * sig_len ); CK_RV rsa_hash_pkcs_verify ( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); CK_RV rsa_hash_pkcs_sign_update ( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ); CK_RV rsa_hash_pkcs_verify_update ( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ); CK_RV rsa_hash_pkcs_sign_final ( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG * sig_len ); CK_RV rsa_hash_pkcs_verify_final ( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len ); // RSA mechanisms // CK_RV ckm_rsa_key_pair_gen( TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl ); CK_RV ckm_rsa_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, OBJECT * key_obj ); CK_RV ckm_rsa_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, OBJECT * key_obj ); CK_RV ckm_rsa_sign( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, OBJECT * key_obj ); CK_RV ckm_rsa_verify( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG out_data_len, OBJECT * key_obj ); CK_RV ckm_rsa_compute_priv_exp( TEMPLATE *tmpl ); #ifndef NODSA // DSA routines // CK_RV dsa_sign ( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG * sig_len ); CK_RV dsa_verify ( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); // DSA mechanisms // CK_RV ckm_dsa_key_pair_gen( TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl ); CK_RV ckm_dsa_sign( CK_BYTE *in_data, // must be 20 bytes CK_BYTE *signature, // must be 40 bytes OBJECT *priv_key ); CK_RV ckm_dsa_verify( CK_BYTE *signature, // must be 40 bytes CK_BYTE *data, // must be 20 bytes OBJECT *publ_key ); #endif /* Begin code contributed by Corrent corp. */ // DH routines // #ifndef NODH CK_RV dh_pkcs_derive( SESSION * sess, CK_MECHANISM * mech, CK_OBJECT_HANDLE base_key, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE * handle ) ; // DH mechanisms // CK_RV ckm_dh_pkcs_derive( CK_VOID_PTR other_pubkey, CK_ULONG other_pubkey_len, CK_OBJECT_HANDLE base_key, CK_BYTE *secret, CK_ULONG *secret_len ) ; CK_RV ckm_dh_key_pair_gen( TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl ); #endif /* End code contributed by Corrent corp. */ // DES routines - I have to provide two different versions of these // because encryption routines are also used internally // so we can't assume that external-to-external buffering // will be possible and combining them into a single // function is messy. // CK_RV pk_des_ecb_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_ecb_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV pk_des_cbc_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_pad_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_pad_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_ecb_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_ecb_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_pad_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_pad_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_ecb_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_ecb_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_pad_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_pad_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_ecb_wrap_key( SESSION *sess, CK_BBOOL length_only, CK_MECHANISM *mech, OBJECT *key, OBJECT *encr_key, CK_BYTE *data, CK_ULONG *data_len ); // DES mechanisms // CK_RV ckm_des_key_gen ( TEMPLATE *tmpl ); CK_RV ckm_cdmf_key_gen( TEMPLATE *tmpl ); CK_RV ckm_des_ecb_encrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value ); CK_RV ckm_des_ecb_decrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value ); CK_RV ckm_des_cbc_encrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *init_v, CK_BYTE *key_value ); CK_RV ckm_des_cbc_decrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *init_v, CK_BYTE *key_value ); CK_RV ckm_des_wrap_format( CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ); // DES3 routines // CK_RV des3_ecb_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_ecb_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_pad_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_pad_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_ecb_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_ecb_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_pad_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_pad_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_ecb_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_ecb_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_pad_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_pad_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); // DES3 mechanisms // CK_RV ckm_des3_key_gen( TEMPLATE *tmpl ); CK_RV ckm_des3_ecb_encrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value ); CK_RV ckm_des3_ecb_decrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value ); CK_RV ckm_des3_cbc_encrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *init_v, CK_BYTE *key_value ); CK_RV ckm_des3_cbc_decrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *init_v, CK_BYTE *key_value ); // AES routines // CK_RV aes_ecb_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_ecb_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_pad_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_pad_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_ecb_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_ecb_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_pad_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_pad_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_ecb_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_ecb_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_pad_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_pad_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); // AES mechanisms // CK_RV ckm_aes_key_gen( TEMPLATE *tmpl ); CK_RV ckm_aes_ecb_encrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_ULONG key_len ); CK_RV ckm_aes_ecb_decrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_ULONG key_len ); CK_RV ckm_aes_cbc_encrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *init_v, CK_BYTE *key_value, CK_ULONG key_len ); CK_RV ckm_aes_cbc_decrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *init_v, CK_BYTE *key_value, CK_ULONG key_len ); CK_RV ckm_aes_wrap_format( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len ); // SHA-1 mechanisms // CK_RV sha1_hash( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV sha1_hash_update( SESSION *sess, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV sha1_hash_final( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV sha1_hmac_sign( SESSION *sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV sha1_hmac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); void ckm_sha1_init( DIGEST_CONTEXT *ctx ); CK_RV ckm_sha1_update( DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV ckm_sha1_final( DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); // MD2 mechanisms // CK_RV md2_hash( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV md2_hash_update( SESSION *sess, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV md2_hash_final( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV md2_hmac_sign( SESSION *sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV md2_hmac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); CK_RV ckm_md2_update( MD2_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV ckm_md2_final( MD2_CONTEXT *context, CK_BYTE *out_data, CK_ULONG out_data_len ); void ckm_md2_transform( CK_BYTE *state, CK_BYTE *checksum, CK_BYTE *block ); // MD5 mechanisms // CK_RV md5_hash( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV md5_hash_update( SESSION *sess, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV md5_hash_final( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV md5_hmac_sign( SESSION *sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV md5_hmac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); void ckm_md5_init( MD5_CONTEXT *context ); CK_RV ckm_md5_update( MD5_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV ckm_md5_final( MD5_CONTEXT *context, CK_BYTE *out_data, CK_ULONG out_data_len ); void ckm_md5_transform( CK_ULONG *buf, CK_ULONG *in ); // linked-list routines // DL_NODE * dlist_add_as_first( DL_NODE *list, void *data ); DL_NODE * dlist_add_as_last( DL_NODE *list, void *data ); DL_NODE * dlist_find( DL_NODE *list, void *data ); DL_NODE * dlist_get_first( DL_NODE *list ); DL_NODE * dlist_get_last( DL_NODE *list ); CK_ULONG dlist_length( DL_NODE *list ); DL_NODE * dlist_next( DL_NODE *list ); DL_NODE * dlist_prev( DL_NODE *list ); void dlist_purge( DL_NODE *list ); DL_NODE * dlist_remove_node( DL_NODE *list, DL_NODE *node ); CK_RV _CreateMutex( MUTEX *mutex ); CK_RV _DestroyMutex( MUTEX *mutex ); CK_RV _LockMutex( MUTEX *mutex ); CK_RV _UnlockMutex( MUTEX *mutex ); CK_RV attach_shm(void); CK_RV detach_shm(void); // encryption manager routines // CK_RV encr_mgr_init( SESSION * sess, ENCR_DECR_CONTEXT * ctx, CK_ULONG operation, CK_MECHANISM * mech, CK_OBJECT_HANDLE key_handle ); CK_RV encr_mgr_cleanup( ENCR_DECR_CONTEXT *ctx ); CK_RV encr_mgr_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV encr_mgr_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV encr_mgr_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); // decryption manager routines // CK_RV decr_mgr_init( SESSION * sess, ENCR_DECR_CONTEXT * ctx, CK_ULONG operation, CK_MECHANISM * mech, CK_OBJECT_HANDLE key_handle ); CK_RV decr_mgr_cleanup( ENCR_DECR_CONTEXT * ctx ); CK_RV decr_mgr_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV decr_mgr_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV decr_mgr_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV decr_mgr_update_des_ecb( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV decr_mgr_update_des_cbc( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV decr_mgr_update_des3_ecb( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV decr_mgr_update_des3_cbc( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); // digest manager routines // CK_RV digest_mgr_cleanup( DIGEST_CONTEXT *ctx ); CK_RV digest_mgr_init( SESSION *sess, DIGEST_CONTEXT *ctx, CK_MECHANISM *mech ); CK_RV digest_mgr_digest( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *data, CK_ULONG data_len, CK_BYTE *hash, CK_ULONG *hash_len ); CK_RV digest_mgr_digest_update( SESSION *sess, DIGEST_CONTEXT *ctx, CK_BYTE *data, CK_ULONG data_len ); CK_RV digest_mgr_digest_key( SESSION *sess, DIGEST_CONTEXT *ctx, CK_OBJECT_HANDLE key_handle ); CK_RV digest_mgr_digest_final( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *hash, CK_ULONG *hash_len ); // key manager routines // CK_RV key_mgr_generate_key( SESSION *sess, CK_MECHANISM *mech, CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE *key_handle ); CK_RV key_mgr_generate_key_pair( SESSION *sess, CK_MECHANISM *mech, CK_ATTRIBUTE *publ_tmpl, CK_ULONG publ_count, CK_ATTRIBUTE *priv_tmpl, CK_ULONG priv_count, CK_OBJECT_HANDLE *publ_key_handle, CK_OBJECT_HANDLE *priv_key_handle ); CK_RV key_mgr_get_private_key_type( CK_BYTE *keydata, CK_ULONG keylen, CK_KEY_TYPE *keytype ); CK_RV key_mgr_derive_key( SESSION * sess, CK_MECHANISM * mech, CK_OBJECT_HANDLE base_key, CK_OBJECT_HANDLE * derived_key, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ); CK_RV key_mgr_wrap_key( SESSION *sess, CK_BBOOL length_only, CK_MECHANISM *mech, CK_OBJECT_HANDLE h_wrapping_key, CK_OBJECT_HANDLE h_key, CK_BYTE *wrapped_key, CK_ULONG *wrapped_key_len ); CK_RV key_mgr_unwrap_key( SESSION *sess, CK_MECHANISM *mech, CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount, CK_BYTE *wrapped_key, CK_ULONG wrapped_key_len, CK_OBJECT_HANDLE unwrapping_key, CK_OBJECT_HANDLE *unwrapped_key ); CK_RV key_mgr_derive_prolog( SESSION *sess, CK_ATTRIBUTE *attributes, CK_ULONG attrcount, CK_OBJECT_HANDLE base_key, OBJECT *base_key_obj, CK_BYTE *base_key_value, CK_KEY_TYPE base_key_type, ATTRIBUTE_PARSE_LIST *parselist, CK_ULONG plcount ); // signature manager routines // CK_RV sign_mgr_init( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_MECHANISM * mech, CK_BBOOL recover_mode, CK_OBJECT_HANDLE key_handle ); CK_RV sign_mgr_cleanup( SIGN_VERIFY_CONTEXT *ctx ); CK_RV sign_mgr_sign( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV sign_mgr_sign_recover( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV sign_mgr_sign_final( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV sign_mgr_sign_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ); // signature verify manager routines // CK_RV verify_mgr_init( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_MECHANISM * mech, CK_BBOOL recover_mode, CK_OBJECT_HANDLE key_handle ); CK_RV verify_mgr_cleanup( SIGN_VERIFY_CONTEXT *ctx ); CK_RV verify_mgr_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); CK_RV verify_mgr_verify_recover( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len, CK_BYTE * out_data, CK_ULONG * out_len ); CK_RV verify_mgr_verify_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ); CK_RV verify_mgr_verify_final( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len ); // session manager routines // CK_RV session_mgr_close_all_sessions( void ); CK_RV session_mgr_close_session( SESSION *sess ); SESSION * session_mgr_find( CK_SESSION_HANDLE handle ); CK_RV session_mgr_login_all ( CK_USER_TYPE user_type ); CK_RV session_mgr_logout_all( void ); CK_RV session_mgr_new( CK_ULONG flags, SESSION **sess ); CK_BBOOL session_mgr_readonly_exists( void ); CK_BBOOL session_mgr_so_session_exists ( void ); CK_BBOOL session_mgr_user_session_exists ( void ); CK_BBOOL session_mgr_public_session_exists( void ); CK_RV session_mgr_get_op_state( SESSION *sess, CK_BBOOL length_only, CK_BYTE *data, CK_ULONG *data_len ); CK_RV session_mgr_set_op_state( SESSION *sess, CK_OBJECT_HANDLE encr_key, CK_OBJECT_HANDLE auth_key, CK_BYTE *data, CK_ULONG data_len ); // object manager routines // CK_RV object_mgr_add( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE * handle ); CK_RV object_mgr_add_to_map( SESSION * sess, OBJECT * obj, CK_OBJECT_HANDLE * handle ); CK_RV object_mgr_add_to_shm ( OBJECT *obj ); CK_RV object_mgr_del_from_shm( OBJECT *obj ); CK_RV object_mgr_check_shm ( OBJECT *obj ); CK_RV object_mgr_search_shm_for_obj( TOK_OBJ_ENTRY * list, CK_ULONG lo, CK_ULONG hi, OBJECT * obj, CK_ULONG * index ); CK_RV object_mgr_sort_priv_shm( void ); CK_RV object_mgr_sort_publ_shm( void ); CK_RV object_mgr_update_from_shm( void ); CK_RV object_mgr_update_publ_tok_obj_from_shm(); CK_RV object_mgr_update_priv_tok_obj_from_shm(); CK_RV object_mgr_copy( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE old_obj, CK_OBJECT_HANDLE * new_obj ); CK_RV object_mgr_create_final( SESSION *sess, OBJECT *obj, CK_OBJECT_HANDLE *handle ); CK_RV object_mgr_create_skel( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_ULONG mode, CK_ULONG class, CK_ULONG subclass, OBJECT ** obj ); CK_RV object_mgr_destroy_object( SESSION * sess, CK_OBJECT_HANDLE handle ); CK_RV object_mgr_destroy_token_objects( void ); CK_RV object_mgr_find_in_map1( CK_OBJECT_HANDLE handle, OBJECT ** ptr ); CK_RV object_mgr_find_in_map2( OBJECT * ptr, CK_OBJECT_HANDLE * handle ); CK_RV object_mgr_find_init( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ); CK_RV object_mgr_find_build_list( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, DL_NODE * obj_list, CK_BBOOL public_only ); CK_RV object_mgr_find_final( SESSION *sess ); CK_RV object_mgr_get_attribute_values( SESSION * sess, CK_OBJECT_HANDLE handle, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ); CK_RV object_mgr_get_object_size( CK_OBJECT_HANDLE handle, CK_ULONG * size ); CK_BBOOL object_mgr_invalidate_handle1( CK_OBJECT_HANDLE handle ); CK_BBOOL object_mgr_invalidate_handle2( OBJECT *obj ); CK_BBOOL object_mgr_purge_session_objects( SESSION * sess, SESS_OBJ_TYPE type ); CK_BBOOL object_mgr_purge_token_objects( void ); CK_BBOOL object_mgr_purge_private_token_objects( void ); CK_RV object_mgr_remove_from_map( CK_OBJECT_HANDLE handle ); CK_RV object_mgr_restore_obj( CK_BYTE *data, OBJECT *oldObj ); CK_RV object_mgr_set_attribute_values( SESSION * sess, CK_OBJECT_HANDLE handle, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ); // SAB FIXME FIXME CK_BBOOL object_mgr_purge_map( SESSION * sess, SESS_OBJ_TYPE type ); // object routines // CK_RV object_create( CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, OBJECT ** obj ); CK_RV object_create_skel( CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_ULONG mode, CK_ULONG class, CK_ULONG subclass, OBJECT ** key ); CK_RV object_copy( CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, OBJECT * old_obj, OBJECT ** new_obj ); CK_RV object_flatten( OBJECT * obj, CK_BYTE ** data, CK_ULONG * len ); CK_BBOOL object_free( OBJECT *obj ); CK_RV object_get_attribute_values( OBJECT * obj, CK_ATTRIBUTE * pTemplate, CK_ULONG count ); CK_ULONG object_get_size( OBJECT *obj ); CK_RV object_restore( CK_BYTE * data, OBJECT ** obj, CK_BBOOL replace ); CK_RV object_set_attribute_values( OBJECT * obj, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ); CK_BBOOL object_is_modifiable ( OBJECT * obj ); CK_BBOOL object_is_private ( OBJECT * obj ); CK_BBOOL object_is_public ( OBJECT * obj ); CK_BBOOL object_is_token_object ( OBJECT * obj ); CK_BBOOL object_is_session_object( OBJECT * obj ); CK_BBOOL is_attribute_defined( CK_ATTRIBUTE_TYPE type ); // object attribute template routines // CK_RV template_add_attributes( TEMPLATE * tmpl, CK_ATTRIBUTE * attr, CK_ULONG ulCount ); CK_RV template_add_default_attributes( TEMPLATE * tmpl, CK_ULONG class, CK_ULONG subclass, CK_ULONG mode ); CK_BBOOL template_attribute_find( TEMPLATE * tmpl, CK_ATTRIBUTE_TYPE type, CK_ATTRIBUTE ** attr); void template_attribute_find_multiple( TEMPLATE *tmpl, ATTRIBUTE_PARSE_LIST *parselist, CK_ULONG plcount ); CK_BBOOL template_check_exportability( TEMPLATE *tmpl, CK_ATTRIBUTE_TYPE type ); CK_RV template_check_required_attributes( TEMPLATE * tmpl, CK_ULONG class, CK_ULONG subclass, CK_ULONG mode ); CK_RV template_check_required_base_attributes( TEMPLATE * tmpl, CK_ULONG mode ); CK_BBOOL template_compare( CK_ATTRIBUTE * t1, CK_ULONG ulCount, TEMPLATE * t2 ); CK_RV template_copy( TEMPLATE * dest, TEMPLATE * src ); CK_RV template_flatten( TEMPLATE * tmpl, CK_BYTE * dest ); CK_RV template_free( TEMPLATE *tmpl ); CK_BBOOL template_get_class( TEMPLATE * tmpl, CK_ULONG * class, CK_ULONG * subclass ); CK_ULONG template_get_count( TEMPLATE *tmpl ); CK_ULONG template_get_size( TEMPLATE *tmpl ); CK_RV template_set_default_common_attributes( TEMPLATE *tmpl ); CK_RV template_merge( TEMPLATE *dest, TEMPLATE **src ); CK_RV template_update_attribute( TEMPLATE * tmpl, CK_ATTRIBUTE * attr ); CK_RV template_unflatten( TEMPLATE ** tmpl, CK_BYTE * data, CK_ULONG count ); CK_RV template_validate_attribute( TEMPLATE * tmpl, CK_ATTRIBUTE * attr, CK_ULONG class, CK_ULONG subclass, CK_ULONG mode ); CK_RV template_validate_attributes( TEMPLATE * tmpl, CK_ULONG class, CK_ULONG subclass, CK_ULONG mode ); CK_RV template_validate_base_attribute( TEMPLATE * tmpl, CK_ATTRIBUTE * attr, CK_ULONG mode ); // DATA OBJECT ROUTINES // CK_RV data_object_check_required_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV data_object_set_default_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV data_object_validate_attribute ( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // CERTIFICATE ROUTINES // CK_RV cert_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cert_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV cert_x509_check_required_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cert_x509_set_default_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cert_x509_validate_attribute ( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV cert_vendor_check_required_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cert_vendor_validate_attribute ( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // // KEY ROUTINES // CK_RV key_object_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV key_object_set_default_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV key_object_validate_attribute ( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV publ_key_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV publ_key_set_default_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV publ_key_validate_attribute ( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV priv_key_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV priv_key_set_default_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV priv_key_unwrap( TEMPLATE *tmpl, CK_ULONG keytype, CK_BYTE *data, CK_ULONG data_len ); CK_RV priv_key_validate_attribute ( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_BBOOL secret_key_check_exportability( CK_ATTRIBUTE_TYPE type ); CK_RV secret_key_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV secret_key_set_default_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV secret_key_unwrap( TEMPLATE *tmpl, CK_ULONG keytype, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ); CK_RV secret_key_validate_attribute ( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // rsa routines // CK_RV rsa_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rsa_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV rsa_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_BBOOL rsa_priv_check_exportability( CK_ATTRIBUTE_TYPE type ); CK_RV rsa_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rsa_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rsa_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV rsa_priv_wrap_get_data( TEMPLATE *tmpl, CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ); CK_RV rsa_priv_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len ); // dsa routines // CK_RV dsa_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dsa_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dsa_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_BBOOL dsa_priv_check_exportability( CK_ATTRIBUTE_TYPE type ); CK_RV dsa_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dsa_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dsa_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV dsa_priv_wrap_get_data( TEMPLATE *tmpl, CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ); CK_RV dsa_priv_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len ); // ecdsa routines // CK_RV ecdsa_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV ecdsa_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV ecdsa_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_BBOOL ecdsa_priv_check_exportability( CK_ATTRIBUTE_TYPE type ); CK_RV ecdsa_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV ecdsa_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV ecdsa_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // diffie-hellman routines // CK_RV dh_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dh_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dh_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_BBOOL dh_priv_check_exportability( CK_ATTRIBUTE_TYPE type ); CK_RV dh_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dh_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dh_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // KEA routines // CK_RV kea_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV kea_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV kea_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_BBOOL kea_priv_check_exportability( CK_ATTRIBUTE_TYPE type ); CK_RV kea_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV kea_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV kea_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // Generic secret key routines CK_RV generic_secret_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV generic_secret_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV generic_secret_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV generic_secret_wrap_get_data( TEMPLATE *tmpl, CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ); CK_RV generic_secret_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ); // RC2 routines CK_RV rc2_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rc2_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rc2_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // RC4 routines CK_RV rc4_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rc4_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rc4_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // RC5 routines CK_RV rc5_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rc5_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rc5_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // DES routines CK_RV des_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV des_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV des_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ); CK_RV des_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV des_wrap_get_data( TEMPLATE *tmpl, CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ); CK_BBOOL des_check_weak_key( CK_BYTE *key ); // DES2 routines CK_RV des2_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV des2_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV des2_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // DES3 routines CK_RV des3_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV des3_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV des3_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ); CK_RV des3_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV des3_wrap_get_data( TEMPLATE *tmpl, CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ); // AES routines CK_RV aes_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV aes_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV aes_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ); CK_RV aes_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV aes_wrap_get_data( TEMPLATE *tmpl, CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ); // CAST routines CK_RV cast_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cast_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cast_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // CAST3 routines CK_RV cast3_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cast3_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cast3_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // CAST5 routines CK_RV cast5_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cast5_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cast5_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // IDEA routines CK_RV idea_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV idea_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV idea_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // CDMF routines CK_RV cdmf_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cdmf_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cdmf_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // SKIPJACK routines CK_RV skipjack_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV skipjack_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV skipjack_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // BATON routines CK_RV baton_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV baton_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV baton_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // JUNIPER routines CK_RV juniper_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV juniper_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV juniper_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // modular math routines // CK_RV mp_subtract( CK_BYTE *bigint, CK_ULONG val, CK_ULONG len ); CK_RV mp_mult( CK_BYTE *bigint_a, CK_ULONG a_len, CK_BYTE *bigint_b, CK_ULONG b_len, CK_BYTE *bigint_c, CK_ULONG c_len, CK_BYTE *result, CK_ULONG *result_len ); CK_RV mp_exp( CK_BYTE *bigint_a, CK_ULONG a_len, CK_BYTE *bigint_b, CK_ULONG b_len, CK_BYTE *bigint_c, CK_ULONG c_len, CK_BYTE *result, CK_ULONG *result_len ); // ASN.1 routines // CK_ULONG ber_encode_INTEGER( CK_BBOOL length_only, CK_BYTE ** ber_int, CK_ULONG * ber_int_len, CK_BYTE * data, CK_ULONG data_len ); CK_RV ber_decode_INTEGER( CK_BYTE * ber_int, CK_BYTE ** data, CK_ULONG * data_len, CK_ULONG * field_len ); CK_RV ber_encode_OCTET_STRING( CK_BBOOL length_only, CK_BYTE ** str, CK_ULONG * str_len, CK_BYTE * data, CK_ULONG data_len ); CK_RV ber_decode_OCTET_STRING( CK_BYTE * str, CK_BYTE ** data, CK_ULONG * data_len, CK_ULONG * field_len ); CK_RV ber_encode_SEQUENCE( CK_BBOOL length_only, CK_BYTE ** seq, CK_ULONG * seq_len, CK_BYTE * data, CK_ULONG data_len ); CK_RV ber_decode_SEQUENCE( CK_BYTE * seq, CK_BYTE ** data, CK_ULONG * data_len, CK_ULONG * field_len ); CK_RV ber_encode_PrivateKeyInfo( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len, CK_BYTE * algorithm_id, CK_ULONG algorithm_id_len, CK_BYTE * priv_key, CK_ULONG priv_key_len ); CK_RV ber_decode_PrivateKeyInfo( CK_BYTE * data, CK_ULONG data_len, CK_BYTE ** algorithm_id, CK_ULONG * alg_len, CK_BYTE ** priv_key ); CK_RV ber_encode_RSAPrivateKey( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len, CK_ATTRIBUTE * modulus, CK_ATTRIBUTE * publ_exp, CK_ATTRIBUTE * priv_exp, CK_ATTRIBUTE * prime1, CK_ATTRIBUTE * prime2, CK_ATTRIBUTE * exponent1, CK_ATTRIBUTE * exponent2, CK_ATTRIBUTE * coeff ); CK_RV ber_decode_RSAPrivateKey( CK_BYTE * data, CK_ULONG data_len, CK_ATTRIBUTE ** modulus, CK_ATTRIBUTE ** publ_exp, CK_ATTRIBUTE ** priv_exp, CK_ATTRIBUTE ** prime1, CK_ATTRIBUTE ** prime2, CK_ATTRIBUTE ** exponent1, CK_ATTRIBUTE ** exponent2, CK_ATTRIBUTE ** coeff ); CK_RV ber_encode_DSAPrivateKey( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len, CK_ATTRIBUTE * prime1, CK_ATTRIBUTE * prime2, CK_ATTRIBUTE * base, CK_ATTRIBUTE * priv_key ); CK_RV ber_decode_DSAPrivateKey( CK_BYTE * data, CK_ULONG data_len, CK_ATTRIBUTE ** prime, CK_ATTRIBUTE ** subprime, CK_ATTRIBUTE ** base, CK_ATTRIBUTE ** priv_key ); #include "tok_spec_struct.h" extern token_spec_t token_specific; #if (LEEDS_BUILD) #pragma options align=full #endif #include #define APPID "TPM_STDLL" /* log to stdout */ #define LogMessage(dest, priority, layer, fmt, ...) \ do { \ fprintf(dest, "%s %s %s:%d " fmt "\n", priority, layer, __FILE__, __LINE__, ## __VA_ARGS__); \ } while (0) #define LogMessage1(dest, priority, layer, data) \ do { \ fprintf(dest, "%s %s %s:%d %s\n", priority, layer, __FILE__, __LINE__, data); \ } while (0) /* Debug logging */ #ifdef DEBUG #define LogDebug(fmt, ...) LogMessage(stdout, "LOG_DEBUG", APPID, fmt, ##__VA_ARGS__) #define LogDebug1(data) LogMessage1(stdout, "LOG_DEBUG", APPID, data) /* Error logging */ #define LogError(fmt, ...) LogMessage(stderr, "LOG_ERR", APPID, "ERROR: " fmt, ##__VA_ARGS__) #define LogError1(data) LogMessage1(stderr, "LOG_ERR", APPID, "ERROR: " data) /* Warn logging */ #define LogWarn(fmt, ...) LogMessage(stdout, "LOG_WARNING", APPID, "WARNING: " fmt, ##__VA_ARGS__) #define LogWarn1(data) LogMessage1(stdout, "LOG_WARNING", APPID, "WARNING: " data) /* Info Logging */ #define LogInfo(fmt, ...) LogMessage(stdout, "LOG_INFO", APPID, fmt, ##__VA_ARGS__) #define LogInfo1(data) LogMessage1(stdout, "LOG_INFO", APPID, data) #define st_err_log(...) LogMessage(stderr, "ST MSG", APPID, "whammy") #else #define LogDebug(...) do { } while (0) #define LogDebug1(...) do { } while (0) #define LogBlob(...) do { } while (0) #define LogError(...) do { } while (0) #define LogError1(...) do { } while (0) #define LogWarn(...) do { } while (0) #define LogWarn1(...) do { } while (0) #define LogInfo(...) do { } while (0) #define LogInfo1(...) do { } while (0) #define st_err_log(...) do { } while (0) #endif /* custom attributes for the TPM token */ /* CKA_HIDDEN will be used to filter return results on a C_FindObjects call. Used * for objects internal to the TPM token for management */ #define CKA_HIDDEN CKA_VENDOR_DEFINED + 0x01000000 /* CKA_ENC_AUTHDATA will be used to store the encrypted SHA-1 hashes of auth data * passed in for TPM keys. The authdata will be encrypted using either the public * leaf key or the private leaf key */ #define CKA_ENC_AUTHDATA CKA_VENDOR_DEFINED + 0x01000001 #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/tpm_specific.h0000640000175000017500000000700411327631345022245 0ustar jfjf/* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */ #ifndef _TPM_SPECIFIC_H_ #define _TPM_SPECIFIC_H_ #include /* TSS key type helper */ #define TPMTOK_TSS_KEY_TYPE_MASK 0x000000F0 #define TPMTOK_TSS_KEY_TYPE(x) (x & TPMTOK_TSS_KEY_TYPE_MASK) #define TPMTOK_TSS_KEY_MIG_TYPE(x) (x & TSS_KEY_MIGRATABLE) #define TPMTOK_TSS_MAX_ERROR 0x00000FFF #define TPMTOK_TSS_ERROR_CODE(x) (x & TPMTOK_TSS_MAX_ERROR) /* key types in the TPM token */ #define TPMTOK_PRIVATE_ROOT_KEY 1 #define TPMTOK_PRIVATE_LEAF_KEY 2 #define TPMTOK_PUBLIC_ROOT_KEY 3 #define TPMTOK_PUBLIC_LEAF_KEY 4 /* key identifiers for the PKCS#11 objects */ #define TPMTOK_PRIVATE_ROOT_KEY_ID "PRIVATE ROOT KEY" #define TPMTOK_PRIVATE_LEAF_KEY_ID "PRIVATE LEAF KEY" #define TPMTOK_PUBLIC_ROOT_KEY_ID "PUBLIC ROOT KEY" #define TPMTOK_PUBLIC_LEAF_KEY_ID "PUBLIC LEAF KEY" #define TPMTOK_PRIVATE_ROOT_KEY_ID_SIZE strlen(TPMTOK_PRIVATE_ROOT_KEY_ID) #define TPMTOK_PRIVATE_LEAF_KEY_ID_SIZE strlen(TPMTOK_PRIVATE_LEAF_KEY_ID) #define TPMTOK_PUBLIC_ROOT_KEY_ID_SIZE strlen(TPMTOK_PUBLIC_ROOT_KEY_ID) #define TPMTOK_PUBLIC_LEAF_KEY_ID_SIZE strlen(TPMTOK_PUBLIC_LEAF_KEY_ID) #define TPMTOK_PUB_ROOT_KEY_FILE "PUBLIC_ROOT_KEY.pem" #define TPMTOK_PRIV_ROOT_KEY_FILE "PRIVATE_ROOT_KEY.pem" /* TPM token specific return codes */ #define CKR_KEY_NOT_FOUND CKR_VENDOR_DEFINED + 0x0f000000 #define CKR_FILE_NOT_FOUND CKR_VENDOR_DEFINED + 0x0f000001 #define TPMTOK_MASTERKEY_PRIVATE "MK_PRIVATE" #ifdef DEBUG #define DEBUG_openssl_print_errors() openssl_print_errors() #else #define DEBUG_openssl_print_errors() #endif /* retry count for generating software RSA keys */ #define KEYGEN_RETRY 5 RSA *openssl_gen_key(); int openssl_write_key(RSA *, char *, CK_BYTE *); CK_RV openssl_read_key(char *, CK_BYTE *, RSA **); int openssl_get_modulus_and_prime(RSA *, unsigned int *, unsigned char *, unsigned int *, unsigned char *); int util_set_file_mode(char *, mode_t); CK_BYTE *util_create_id(int); CK_RV util_set_username(char **); unsigned int util_get_keysize_flag(CK_ULONG); CK_ULONG util_check_public_exponent(TEMPLATE *); #define NULL_HKEY 0 #define NULL_HENCDATA 0 #define NULL_HPOLICY 0 #define NULL_HCONTEXT 0 #define NULL_HPCRS 0 /* CKA_ENC_AUTHDATA will be used to store the encrypted SHA-1 hashes of auth data * passed in for TPM keys. The authdata will be encrypted using either the public * leaf key or the private leaf key */ #define CKA_ENC_AUTHDATA CKA_VENDOR_DEFINED + 0x01000001 #define MK_SIZE (AES_KEY_SIZE_256) #define LOG(priority, fmt, ...) \ do { \ openlog("openCryptoki(TPM)", LOG_NDELAY|LOG_PID, LOG_USER); \ syslog(priority, "%s " fmt, __FILE__, ##__VA_ARGS__); \ } while (0) #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/mech_aes.c0000640000175000017500000013777111327631345021356 0ustar jfjf /* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */ /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */ // File: mech_aes.c // // Mechanisms for AES // //#include #include // for memcmp() et al #include #include "pkcs11/pkcs11types.h" #include #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" //#include "args.h" // // CK_RV aes_ecb_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (in_data_len % AES_BLOCK_SIZE != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // We have to use ulValueLen here, since with AES we don't // know how large the key is. memcpy( key_value, attr->pValue, attr->ulValueLen ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_aes_ecb_encrypt( in_data, in_data_len, out_data, out_data_len, key_value, attr->ulValueLen ); } // // CK_RV aes_ecb_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES3_ECB requires the input data to be an integral // multiple of the block size // if (in_data_len % AES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_aes_ecb_decrypt( in_data, in_data_len, out_data, out_data_len, key_value, attr->ulValueLen ); } // // CK_RV aes_cbc_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES3_CBC requires the input data to be an integral // multiple of the block size // if (in_data_len % AES_BLOCK_SIZE != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_aes_cbc_encrypt( in_data, in_data_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); } // // CK_RV aes_cbc_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES3_CBC requires the input data to be an integral // multiple of the block size // if (in_data_len % AES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_aes_cbc_decrypt( in_data, in_data_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); } // // CK_RV aes_cbc_pad_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE *clear = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_ULONG padded_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // DES3-CBC-PAD has no input length requirements // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // compute the output length, accounting for padding // padded_len = AES_BLOCK_SIZE * (in_data_len / AES_BLOCK_SIZE + 1); if (length_only == TRUE) { *out_data_len = padded_len; return CKR_OK; } if (*out_data_len < padded_len) { *out_data_len = padded_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } clear = (CK_BYTE *)malloc( padded_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( clear, in_data, in_data_len ); add_pkcs_padding( clear + in_data_len, AES_BLOCK_SIZE, in_data_len, padded_len ); rc = ckm_aes_cbc_encrypt( clear, padded_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc != CKR_OK) st_err_log(105, __FILE__, __LINE__); free( clear ); return rc; } // // CK_RV aes_cbc_pad_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE *clear = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_ULONG padded_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // no need to validate the input length since we'll pad as necessary // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // we're decrypting so even with CBC-PAD, we should have an integral // number of block to decrypt // if (in_data_len % AES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } // the amount of cleartext after stripping the padding will actually be less // than the input bytes... // padded_len = in_data_len; if (length_only == TRUE) { *out_data_len = padded_len; return CKR_OK; } clear = (CK_BYTE *)malloc( padded_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } rc = ckm_aes_cbc_decrypt( in_data, in_data_len, clear, &padded_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc == CKR_OK) { strip_pkcs_padding( clear, padded_len, out_data_len ); memcpy( out_data, clear, *out_data_len ); } else st_err_log(106, __FILE__, __LINE__); free( clear ); return rc; } // // CK_RV aes_ecb_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (AES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < AES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % AES_BLOCK_SIZE); out_len = (total - remain); // should always be at least 1 block if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); rc = ckm_aes_ecb_encrypt( clear, out_len, out_data, out_data_len, key_value, attr->ulValueLen ); if (rc == CKR_OK) { *out_data_len = out_len; // update the context buffer. we already used the buffer's current // contents so we completely overwrite it // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } free( clear ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // shouldn't reach this } // // CK_RV aes_ecb_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (AES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < AES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % AES_BLOCK_SIZE); out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_aes_ecb_decrypt( cipher, out_len, out_data, out_data_len, key_value, attr->ulValueLen ); if (rc == CKR_OK) { *out_data_len = out_len; // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(105, __FILE__, __LINE__); free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // shouldn't reach this } // // CK_RV aes_cbc_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (AES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < AES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % AES_BLOCK_SIZE); out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // these buffers need to be longword aligned // clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); rc = ckm_aes_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc == CKR_OK) { *out_data_len = out_len; // the new init_v is the last encrypted data block // memcpy( ctx->mech.pParameter, out_data + (*out_data_len - AES_BLOCK_SIZE), AES_BLOCK_SIZE ); // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(105, __FILE__, __LINE__); free( clear ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV aes_cbc_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (AES_CONTEXT *)ctx->context; total = context->len + in_data_len; if (total < AES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = total % AES_BLOCK_SIZE; out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // these buffers need to be longword aligned // cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_aes_cbc_decrypt( cipher, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc == CKR_OK) { *out_data_len = out_len; // the new init_v is the last input data block // memcpy( ctx->mech.pParameter, cipher + (out_len - AES_BLOCK_SIZE), AES_BLOCK_SIZE ); // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(106, __FILE__, __LINE__); free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV aes_cbc_pad_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (AES_CONTEXT *)ctx->context; total = (context->len + in_data_len); // note, this is subtly different from the other encrypt update routines // if (total <= AES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { remain = (total % AES_BLOCK_SIZE); out_len = total - remain; // out_len is a multiple of DES_BLOCK_SIZE if (remain == 0) { remain = AES_BLOCK_SIZE; out_len -= AES_BLOCK_SIZE; } if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } // at this point, we should have: // 1) remain != 0 // 2) out_len != 0 // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // these buffers need to be longword aligned // clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); // // we don't do padding during the update // rc = ckm_aes_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc == CKR_OK) { // the new init_v is the last encrypted data block // memcpy( ctx->mech.pParameter, out_data + (*out_data_len - AES_BLOCK_SIZE), AES_BLOCK_SIZE ); // copy the remaining 'new' input data to the temporary space // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } free( clear ); return rc; } } // // CK_RV aes_cbc_pad_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (AES_CONTEXT *)ctx->context; total = (context->len + in_data_len); // note, this is subtly different from the other decrypt update routines // if (total <= AES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block + 1 byte // remain = total % AES_BLOCK_SIZE; out_len = total - remain; if (remain == 0) { remain = AES_BLOCK_SIZE; out_len -= AES_BLOCK_SIZE; } if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } // at this point, we should have: // 1) remain != 0 // 2) out_len != 0 // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // these buffers need to be longword aligned // cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_aes_cbc_decrypt( cipher, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc == CKR_OK) { // the new init_v is the last input data block // memcpy( ctx->mech.pParameter, cipher + (out_len - AES_BLOCK_SIZE), AES_BLOCK_SIZE ); // copy the remaining 'new' input data to the temporary space // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV aes_ecb_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (AES_CONTEXT *)ctx->context; // DES3-ECB does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV aes_ecb_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (AES_CONTEXT *)ctx->context; // DES3-ECB does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV aes_cbc_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (AES_CONTEXT *)ctx->context; // DES3-CBC does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV aes_cbc_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (AES_CONTEXT *)ctx->context; if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV aes_cbc_pad_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT *context = NULL; OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE clear[2*AES_BLOCK_SIZE]; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_ULONG out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); context = (AES_CONTEXT *)ctx->context; // there will never be more than one block in the context buffer // so the amount of output is as follows: // if less than 1 block stored, we generate one block of output // if a full block is stored, we generate two blocks of output (one pad block) // if (context->len == AES_BLOCK_SIZE) out_len = 2 * AES_BLOCK_SIZE; else out_len = AES_BLOCK_SIZE; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } else { memcpy( clear, context->data, context->len ); add_pkcs_padding( clear + context->len, AES_BLOCK_SIZE, context->len, out_len ); rc = ckm_aes_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc != CKR_OK) st_err_log(105, __FILE__, __LINE__); return rc; } } // // CK_RV aes_cbc_pad_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT *context = NULL; OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE clear[AES_BLOCK_SIZE]; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_ULONG out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); context = (AES_CONTEXT *)ctx->context; // there had better be a full block in the context buffer // if (context->len != AES_BLOCK_SIZE){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } // we don't know a priori how much data we'll be returning. we won't // know until after we decrypt it and strip the padding. it's possible // that we'll return nothing (the final block might be a padding block). // out_len = AES_BLOCK_SIZE; // upper bound on what we'll return if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } else { rc = ckm_aes_cbc_decrypt( context->data, AES_BLOCK_SIZE, clear, &out_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc == CKR_OK) { strip_pkcs_padding( clear, out_len, &out_len ); if (out_len != 0) memcpy( out_data, clear, out_len ); *out_data_len = out_len; } else st_err_log(106, __FILE__, __LINE__); return rc; } } // // mechanisms // // // CK_RV ckm_aes_key_gen( TEMPLATE *tmpl ) { CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * key_type_attr = NULL; CK_ATTRIBUTE * class_attr = NULL; CK_ATTRIBUTE * local_attr = NULL; CK_ATTRIBUTE * val_len_attr = NULL; CK_BYTE * aes_key = NULL; CK_ULONG rc = CKR_OK; CK_ULONG key_size; CK_BBOOL found = FALSE; found = template_attribute_find( tmpl, CKA_VALUE_LEN, &val_len_attr ); if (found == FALSE) return CKR_TEMPLATE_INCONSISTENT; key_size = *(CK_ULONG *)val_len_attr->pValue; if (key_size != AES_KEY_SIZE_128 && key_size != AES_KEY_SIZE_192 && key_size != AES_KEY_SIZE_256) { return CKR_ATTRIBUTE_VALUE_INVALID; } if ((aes_key = (CK_BYTE *)malloc(key_size)) == NULL) { st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } rc = token_specific.t_aes_key_gen(aes_key, key_size); if (rc != CKR_OK) return rc; value_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + key_size ); key_type_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); class_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS) ); local_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!value_attr || !key_type_attr || !class_attr || !local_attr) { if (value_attr) free( value_attr ); if (key_type_attr) free( key_type_attr ); if (class_attr) free( class_attr ); if (local_attr) free( local_attr ); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = key_size; value_attr->pValue = (CK_BYTE *)value_attr + sizeof(CK_ATTRIBUTE); memcpy( value_attr->pValue, aes_key, key_size ); free(aes_key); key_type_attr->type = CKA_KEY_TYPE; key_type_attr->ulValueLen = sizeof(CK_KEY_TYPE); key_type_attr->pValue = (CK_BYTE *)key_type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)key_type_attr->pValue = CKK_AES; class_attr->type = CKA_CLASS; class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS); class_attr->pValue = (CK_BYTE *)class_attr + sizeof(CK_ATTRIBUTE); *(CK_OBJECT_CLASS *)class_attr->pValue = CKO_SECRET_KEY; local_attr->type = CKA_LOCAL; local_attr->ulValueLen = sizeof(CK_BBOOL); local_attr->pValue = (CK_BYTE *)local_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)local_attr->pValue = TRUE; template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, key_type_attr ); template_update_attribute( tmpl, class_attr ); template_update_attribute( tmpl, local_attr ); return CKR_OK; } // // CK_RV ckm_aes_ecb_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * key_value, CK_ULONG key_len ) { CK_ULONG rc; if (!in_data || !out_data || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_aes_ecb(in_data,in_data_len, out_data,out_data_len, key_value,key_len,1); if (rc != CKR_OK) st_err_log(120, __FILE__, __LINE__); return rc; } // // CK_RV ckm_aes_ecb_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * key_value, CK_ULONG key_len ) { CK_ULONG rc; if (!in_data || !out_data || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_aes_ecb(in_data,in_data_len, out_data,out_data_len, key_value,key_len,0); if (rc != CKR_OK) st_err_log(120, __FILE__, __LINE__); return rc; } // // CK_RV ckm_aes_cbc_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * init_v, CK_BYTE * key_value, CK_ULONG key_len ) { CK_ULONG rc; if (!in_data || !out_data || !init_v || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ #if 0 st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; #else *out_data_len = in_data_len; st_err_log(68, __FILE__, __FUNCTION__); return CKR_BUFFER_TOO_SMALL; #endif } rc = token_specific.t_aes_cbc(in_data, in_data_len, out_data,out_data_len, key_value,key_len, init_v,1); if (rc != CKR_OK) st_err_log(119, __FILE__, __LINE__); return rc; } // // CK_RV ckm_aes_cbc_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * init_v, CK_BYTE * key_value, CK_ULONG key_len ) { CK_ULONG rc; if (!in_data || !out_data || !init_v || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_aes_cbc(in_data, in_data_len, out_data, out_data_len, key_value,key_len, init_v,0); if (rc != CKR_OK) st_err_log(119, __FILE__, __LINE__); return rc; } // // CK_RV ckm_aes_wrap_format( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len ) { CK_BYTE * ptr = NULL; CK_ULONG len1, len2; len1 = *data_len; // if the input key data isn't a multiple of the blocksize, // we pad with NULLs to the next blocksize multiple. // if (len1 % AES_BLOCK_SIZE != 0) { len2 = AES_BLOCK_SIZE * ((len1 / AES_BLOCK_SIZE) + 1); if (length_only == FALSE) { ptr = (CK_BYTE *)realloc(*data, len2); if (!ptr){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } else memset( ptr + len1, 0x0, (len2 - len1) ); *data = ptr; *data_len = len2; } } return CKR_OK; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/sign_mgr.c0000640000175000017500000004752411327631345021413 0ustar jfjf /* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */ /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */ // File: sign_mgr.c // // Signature manager routines // #include #include // for memcmp() et al #include #include "pkcs11/pkcs11types.h" #include #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // // CK_RV sign_mgr_init( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_MECHANISM * mech, CK_BBOOL recover_mode, CK_OBJECT_HANDLE key ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_KEY_TYPE keytype; CK_OBJECT_CLASS class; CK_BBOOL flag; CK_RV rc; if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active != FALSE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } // key usage restrictions // rc = object_mgr_find_in_map1( key, &key_obj ); if (rc != CKR_OK){ st_err_log(18, __FILE__, __LINE__); return CKR_KEY_HANDLE_INVALID; } // is key allowed to generate signatures? // rc = template_attribute_find( key_obj->template, CKA_SIGN, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { flag = *(CK_BBOOL *)attr->pValue; if (flag != TRUE){ st_err_log(85, __FILE__, __LINE__); return CKR_KEY_FUNCTION_NOT_PERMITTED; } } // is the mechanism supported? is the key type correct? is a // parameter present if required? is the key size allowed? // is the key allowed to generate signatures? // switch (mech->mechanism) { case CKM_RSA_PKCS: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_RSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // must be a PRIVATE key // flag = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (flag == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else class = *(CK_OBJECT_CLASS *)attr->pValue; // if it's not a private RSA key then we have an internal failure...means // that somehow a public key got assigned a CKA_SIGN attribute // if (class != CKO_PRIVATE_KEY){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } // PKCS #11 doesn't allow multi-part RSA operations // ctx->context_len = 0; ctx->context = NULL; } break; #if !(NOMD2) case CKM_MD2_RSA_PKCS: #endif case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_RSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // must be a PRIVATE key operation // flag = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else class = *(CK_OBJECT_CLASS *)attr->pValue; if (class != CKO_PRIVATE_KEY){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } ctx->context_len = sizeof(RSA_DIGEST_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(RSA_DIGEST_CONTEXT)); if (!ctx->context){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(RSA_DIGEST_CONTEXT)); } break; #if !(NODSA) case CKM_DSA: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // must be a PRIVATE key // flag = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (flag == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else class = *(CK_OBJECT_CLASS *)attr->pValue; // if it's not a private RSA key then we have an internal failure...means // that somehow a public key got assigned a CKA_SIGN attribute // if (class != CKO_PRIVATE_KEY){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } // PKCS #11 doesn't allow multi-part DSA operations // ctx->context_len = 0; ctx->context = NULL; } break; #endif #if !(NOMD2) case CKM_MD2_HMAC: #endif case CKM_MD5_HMAC: case CKM_SHA_1_HMAC: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_GENERIC_SECRET){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // PKCS #11 doesn't allow multi-part HMAC operations // ctx->context_len = 0; ctx->context = NULL; } break; #if !(NOMD2) case CKM_MD2_HMAC_GENERAL: #endif case CKM_MD5_HMAC_GENERAL: case CKM_SHA_1_HMAC_GENERAL: { CK_MAC_GENERAL_PARAMS *param = (CK_MAC_GENERAL_PARAMS *)mech->pParameter; if (mech->ulParameterLen != sizeof(CK_MAC_GENERAL_PARAMS)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } #if !(NOMD2) if ((mech->mechanism == CKM_MD2_HMAC_GENERAL) && (*param > 16)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } #endif if ((mech->mechanism == CKM_MD5_HMAC_GENERAL) && (*param > 16)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } if ((mech->mechanism == CKM_SHA_1_HMAC_GENERAL) && (*param > 20)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_GENERIC_SECRET){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // PKCS #11 doesn't allow multi-part HMAC operations // ctx->context_len = 0; ctx->context = NULL; } break; case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: { CK_MAC_GENERAL_PARAMS *param = (CK_MAC_GENERAL_PARAMS *)mech->pParameter; if (mech->ulParameterLen != sizeof(CK_MAC_GENERAL_PARAMS)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // FIXME - Netscape sets the parameter == 16. PKCS #11 limit is 8 // if (mech->mechanism == CKM_SSL3_MD5_MAC) { if (*param < 4 || *param > 16){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } } if (mech->mechanism == CKM_SSL3_SHA1_MAC) { if (*param < 4 || *param > 20){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } } rc = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { class = *(CK_OBJECT_CLASS *)attr->pValue; if (class != CKO_SECRET_KEY){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(SSL3_MAC_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(SSL3_MAC_CONTEXT)); if (!ctx->context){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(SSL3_MAC_CONTEXT)); } break; default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } if (mech->ulParameterLen > 0) { ptr = (CK_BYTE *)malloc(mech->ulParameterLen); if (!ptr){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( ptr, mech->pParameter, mech->ulParameterLen ); } ctx->key = key; ctx->mech.ulParameterLen = mech->ulParameterLen; ctx->mech.mechanism = mech->mechanism; ctx->mech.pParameter = ptr; ctx->multi = FALSE; ctx->active = TRUE; ctx->recover = recover_mode; return CKR_OK; } // // CK_RV sign_mgr_cleanup( SIGN_VERIFY_CONTEXT *ctx ) { if (!ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } ctx->key = 0; ctx->mech.ulParameterLen = 0; ctx->mech.mechanism = 0; ctx->multi = FALSE; ctx->active = FALSE; ctx->recover = FALSE; ctx->context_len = 0; if (ctx->mech.pParameter) { free( ctx->mech.pParameter ); ctx->mech.pParameter = NULL; } if (ctx->context) { free( ctx->context ); ctx->context = NULL; } return CKR_OK; } // // CK_RV sign_mgr_sign( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == TRUE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } // if the caller just wants the signature length, there is no reason to // specify the input data. I just need the input data length // if ((length_only == FALSE) && (!in_data || !out_data)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->multi == TRUE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } switch (ctx->mech.mechanism) { case CKM_RSA_PKCS: return rsa_pkcs_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #if !(NOMD2) case CKM_MD2_RSA_PKCS: #endif case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: return rsa_hash_pkcs_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #if !(NODSA) case CKM_DSA: return dsa_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif #if !(NOMD2) case CKM_MD2_HMAC: case CKM_MD2_HMAC_GENERAL: return md2_hmac_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif case CKM_MD5_HMAC: case CKM_MD5_HMAC_GENERAL: return md5_hmac_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_SHA_1_HMAC: case CKM_SHA_1_HMAC_GENERAL: return sha1_hmac_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: return ssl3_mac_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV sign_mgr_sign_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { if (!sess || !ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == TRUE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } ctx->multi = TRUE; switch (ctx->mech.mechanism) { #if !(NOMD2) case CKM_MD2_RSA_PKCS: #endif case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: return rsa_hash_pkcs_sign_update( sess, ctx, in_data, in_data_len ); case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: return ssl3_mac_sign_update( sess, ctx, in_data, in_data_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // // CK_RV sign_mgr_sign_final( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG * sig_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == TRUE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } switch (ctx->mech.mechanism) { #if !(NOMD2) case CKM_MD2_RSA_PKCS: #endif case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: return rsa_hash_pkcs_sign_final( sess, length_only, ctx, signature, sig_len ); case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: return ssl3_mac_sign_final( sess, length_only, ctx, signature, sig_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // // CK_RV sign_mgr_sign_recover( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } // if the caller just wants the signature length, there is no reason to // specify the input data. I just need the input data length // if ((length_only == FALSE) && (!in_data || !out_data)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->multi == TRUE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } switch (ctx->mech.mechanism) { case CKM_RSA_PKCS: // we can use the same sign mechanism to do sign-recover // return rsa_pkcs_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/new_host.c0000640000175000017500000033724011327631345021431 0ustar jfjf /* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */ /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */ /*************************************************************************** Change Log ========== 4/25/03 Kapil Sood (kapil@corrent.com) Added DH key pair generation and DH shared key derivation functions. ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include "defs.h" #include "host_defs.h" #include "tok_spec_struct.h" #include "h_extern.h" #include #include "tpm_specific.h" #include "../api/apiproto.h" /* Declared in obj_mgr.c */ extern pthread_rwlock_t obj_list_rw_mutex; char *pk_dir; void SC_SetFunctionList(void); //#define SESSION_MGR_FIND(x) session_mgr_find(x,0) // All these need to get the lock #define SESSION_MGR_FIND(x) session_mgr_find(x) // All these need to get the lock // Both of the strings below have a length of 32 chars and must be // padded with spaces, and non-null terminated. // #if 0 #define PKW_CRYPTOKI_VERSION_MAJOR 2 #define PKW_CRYPTOKI_VERSION_MINOR 1 #define PKW_CRYPTOKI_MANUFACTURER "IBM Corp. " #define PKW_CRYPTOKI_LIBDESC "PKCS#11 LIGHTWT for IBM 4758 " #define PKW_CRYPTOKI_LIB_VERSION_MAJOR 1 #define PKW_CRYPTOKI_LIB_VERSION_MINOR 0 #endif // Maximum number of supported devices (rather arbitrary) // #define PKW_MAX_DEVICES 10 // Netscape/SSL is fairly timing-sensitive so can't always use a debugger // // If the CRYPTOKI_DEBUG environment variable is defined, information // about each successful PKCS#11 call made is written to the file named // in that environment variable. // // If the CRYPTOKI_PROFILE environment variable is defined, information // about the amount of time spent in each PKCS#11 API during a "run" // // If the CRYPTOKI_DEBUG environment variable is defined, information // about each successful PKCS#11 call made is written to the file named // in that environment variable. // // If the CRYPTOKI_PROFILE environment variable is defined, information // about the amount of time spent in each PKCS#11 API during a "run" // (i.e., from _DLL_InitTerm init call to _DLL_InitTerm term call) is // appended to the file named in that environment variable. // // If the CRYPTOKI_STATS_FILE environment variable is defined, information // about various internal metrics at the end of a "run" is appended to // the file named in that environment variable. The CRYPTOKI_STATS // environment variable specifies the argument(s) that are passed to // the function that returns the metrics to specify which metric(s) are // returned. // #define MAXFILENAME 1024 static char *debugfilepathbuffer; static int debugon = 1; int debugfile = 0; #define FFLUSH(x) pid_t initedpid=0; // for initialized pid CK_ULONG usage_count = 0; // variable for number of times the DLL has been used. CK_C_INITIALIZE_ARGS cinit_args = { NULL, NULL, NULL, NULL, 0, NULL }; extern void stlogterm(); extern void stloginit(); extern void stlogit2(int type,char *fmt, ...); CK_BBOOL st_Initialized() { if (initialized == FALSE ) return FALSE; #if !(LINUX) if (initedpid != getpid()) return FALSE; #endif return TRUE; } #ifdef SPINXPL extern int spinxplfd; extern int spin_created; #endif // ----------- SAB XXX XXX // void Fork_Initializer(void) { // initialized == FALSE; // Get the initialization to be not true stlogterm(); stloginit(); // Initialize Logging so we can capture EVERYTHING #ifdef SPINXPL spinxplfd = -1; spin_created = 0; #endif // Force logout. This cleans out the private session and list // and cleans out the private object map session_mgr_logout_all(); // Clean out the public object map // First parm is no longer used.. object_mgr_purge_map((SESSION *)0xFFFF, PUBLIC); object_mgr_purge_map((SESSION *)0xFFFF, PRIVATE); // This should clear the entire session list out session_mgr_close_all_sessions(); next_session_handle = 1; // Make is so sessions start with 1 next_object_handle = 1; // Clean out the global login state variable // When implemented... Although logout_all should clear this up. // Once the object_map is flushed, the obj_lists (public and private) are // both just linked lists that have to be freed up... //logit("%s:%d: tokenobj publ 0x%08x priv 0x%08x",__FILE__,__LINE__,publ_token_obj_list, priv_token_obj_list); while (priv_token_obj_list) { priv_token_obj_list = dlist_remove_node(priv_token_obj_list, priv_token_obj_list); } //logit("%s:%d:1 tokenobj publ 0x%08x priv 0x%08x",__FILE__,__LINE__,publ_token_obj_list, priv_token_obj_list); while (publ_token_obj_list) { publ_token_obj_list = dlist_remove_node(publ_token_obj_list,publ_token_obj_list); } //logit("%s:%d:2 tokenobj publ 0x%08x priv 0x%08x",__FILE__,__LINE__,publ_token_obj_list, priv_token_obj_list); // Need to do something to prevent the shared memory from having the // objects loaded again.... The most likely place is in the obj_mgr file // where the object is added to shared memory (object_mgr_add_to_shm) a // query should be done to the appropriate object list.... } // ----------- SAB XXX XXX XXX END #ifdef ALLLOCK #define LOCKIT pthread_mutex_lock(&native_mutex) #define LLOCK #define UNLOCKIT pthread_mutex_unlock(&native_mutex) #else #ifdef DEBLOCK #define LOCKIT #define LLOCK pthread_mutex_lock(&native_mutex) #define UNLOCKIT pthread_mutex_unlock(&native_mutex) #else #define LOCKIT #define LLOCK #define UNLOCKIT #endif #endif int APISlot2Local(snum) CK_SLOT_ID snum; { int i; return(token_specific.t_slot2local(snum)); } #define SLT_CHECK \ CK_SLOT_ID slot_id; \ int sid1; \ \ if ( (sid1 = APISlot2Local(sid)) != -1 ){ \ slot_id = sid1; \ } else { \ return CKR_ARGUMENTS_BAD; \ } #define SESSION_HANDLE sSession.sessionh #define SLOTID APISlot2Local(sSession.slotID) #define SESS_SET \ CK_SESSION_HANDLE hSession; \ \ hSession = sSession.sessionh; // More efficient long reverse CK_ULONG long_reverse( CK_ULONG x ) { #ifdef _POWER // Power Architecture requires reversal to talk to adapter return ( ((0x000000FF & x)<<24) | ((0x0000FF00 & x)<<8) | ((0x00FF0000 & x)>>8) | ((0xFF000000 & x)>>24) ); #else return (x); // Others don't require reversal. #endif } // verify that the mech specified is in the // mech list for this token... Common code requires this // to be added CK_RV validate_mechanism(CK_MECHANISM_PTR pMechanism) { CK_ULONG i; for (i=0; i< mech_list_len;i++){ if ( pMechanism->mechanism == mech_list[i].mech_type){ return CKR_OK; } } st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } #define VALID_MECH(p) \ if ( validate_mechanism(p) != CKR_OK){ \ rc = CKR_MECHANISM_INVALID; \ goto done; \ } \ // Defines to allow NT code to work correctly #define WaitForSingleObject(x,y) pthread_mutex_lock(&(x)) #define ReleaseMutex(x) pthread_mutex_unlock(&(x)) // // // void init_data_store(char *directory) { char *pkdir; if ( (pkdir = getenv("PKCS_APP_STORE")) != NULL) { pk_dir = (char *) malloc(strlen(pkdir)+1024); memset(pk_dir, 0, strlen(pkdir)+1024); sprintf(pk_dir,"%s/%s",pkdir,SUB_DIR); LogError("Using custom data store location: %s", pk_dir); } else { pk_dir = (char *)malloc(strlen(directory)+25); memset(pk_dir, 0, strlen(directory)+25); sprintf(pk_dir,"%s",directory); } } #include // SAB XXX XXX XXX // // //In an STDLL this is called once for each card in the system //therefore the initialized only flags certain one time things //However in the case of a lightened accelerator, the cards //are all agregated together in a single token. Therefore //the correlator should be a list of device names which have //either the correct clu or the crypt light adapter... // CK_RV ST_Initialize( void **FunctionList, CK_SLOT_ID SlotNumber, char *Correlator) { int i, j; CK_RV rc = CKR_OK; char tstr[2048]; char *pkdir; struct passwd *pw,*epw; // SAB XXX XXX uid_t userid,euserid; stlogterm(); stloginit(); // Check for root user or Group PKCS#11 Membershp // Only these are qllowed. userid = getuid(); euserid = geteuid(); if ( userid != 0 && euserid != 0 ) { // Root or effective Root is ok struct group *grp; char *name,*g; int rc = 0; int index = 0; gid_t gid,egid; grp = getgrnam("pkcs11"); if ( grp ) { // Check for member of group.. // SAB get login seems to not work with some instances // of application invocations (particularly when forked). So // we need to get the group informatiion. // Really need to take the uid and map it to a name. pw = getpwuid(userid); epw = getpwuid(euserid); gid = getgid(); egid = getegid(); if ( gid == grp->gr_gid || egid == grp->gr_gid){ rc = 1; } else { i = 0; while (grp->gr_mem[i]) { if (pw) { if ( strncmp(pw->pw_name, grp->gr_mem[i],strlen(pw->pw_name)) == 0 ){ rc = 1; break; } } if (epw) { if ( strncmp(epw->pw_name, grp->gr_mem[i],strlen(epw->pw_name)) == 0 ){ rc = 1; break; } } i++; } } if (rc == 0 ){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } else { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } #if !(LINUX) // Linux we will assume that the upper level has filtered // this and we need to initialize the code // go through this only once for each application if (st_Initialized() == TRUE){ return CKR_OK; } #elif (LINUX) // assume that the upper API prevents multiple calls of initialize // since that only happens on C_Initialize and that is the // resonsibility of the upper layer.. initialized = FALSE; /// So the rest of the code works correctly #endif // If we're not already initialized, grab the mutex and do the // initialization. Check to see if another thread did so while we // were waiting... // // One of the things we do during initialization is create the mutex for // PKCS#11 operations; until we do so, we have to use the native mutex... // WaitForSingleObject( native_mutex, INFINITE ); #if !(LINUX) // check for other completing this before creating mutexes... // make sure that the same process tried to to the init... // thread issues should be caught up above... if (st_Initialized() == TRUE){ st_err_log(143, __FILE__, __LINE__); goto done; } #endif // SAB need to call Fork_Initializer here // instead of at the end of the loop... // it may also need to call destroy of the following 3 mutexes.. // it may not matter... Fork_Initializer(); MY_CreateMutex( &pkcs_mutex ); MY_CreateMutex( &obj_list_mutex ); if (pthread_rwlock_init(&obj_list_rw_mutex, NULL)) { st_err_log(145, __FILE__, __LINE__); } MY_CreateMutex( &sess_list_mutex ); MY_CreateMutex( &login_mutex ); if ( (debugfilepathbuffer = getenv( "CRYPTOKI_DEBUG")) != NULL) { debugon=1; } init_data_store((char *)PK_DIR); // Handle global initialization issues first if we have not // been initialized. if (st_Initialized() == FALSE){ #if SYSVSEM xproclock = (void *)&xprocsemid; CreateXProcLock(xproclock); #endif if ( (rc = attach_shm()) != CKR_OK) { st_err_log(144, __FILE__, __LINE__); goto done; } nv_token_data = &global_shm->nv_token_data; //stloginit(); initialized = TRUE; initedpid = getpid(); SC_SetFunctionList(); // Always call the token_specific_init function.... rc = token_specific.t_init(Correlator,SlotNumber); if (rc != 0) { // Zero means success, right?!? *FunctionList = NULL; st_err_log(145, __FILE__, __LINE__); goto done; } } // SAB XXX FIXME FIXME check return code... for all these... rc = load_token_data(); if (rc != CKR_OK) { *FunctionList = NULL; st_err_log(145, __FILE__, __LINE__); goto done; } load_public_token_objects(); XProcLock( xproclock ); global_shm->publ_loaded = TRUE; XProcUnLock( xproclock ); init_slotInfo(); usage_count++; (*FunctionList) = &function_list; done: ReleaseMutex( native_mutex ); if (rc != 0) st_err_log(145, __FILE__, __LINE__); return rc; } // // What does this really have to do in this new token... // probably need to close the adapters that are opened, and // clear the other stuff CK_RV SC_Finalize( CK_SLOT_ID sid ) { CK_ULONG req_len, repl_len; CK_ULONG i; CK_RV rc, rc2; SLT_CHECK if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } rc = MY_LockMutex( &pkcs_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return rc; } // If somebody else has taken care of things, leave... // if (st_Initialized() == FALSE) { MY_UnlockMutex( &pkcs_mutex ); // ? Somebody else has also destroyed the mutex... st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } usage_count --; if (usage_count == 0){ initialized = FALSE; } session_mgr_close_all_sessions(); object_mgr_purge_token_objects(); detach_shm(); // close spin lock file if (spin_created) close(spinxplfd); if ( token_specific.t_final != NULL) { token_specific.t_final(); } rc = MY_UnlockMutex( &pkcs_mutex ); if (rc != CKR_OK){ st_err_log(147, __FILE__, __LINE__); return rc; } return CKR_OK; } // // CK_RV SC_GetTokenInfo( CK_SLOT_ID sid, CK_TOKEN_INFO_PTR pInfo ) { CK_RV rc = CKR_OK; time_t now; SLT_CHECK LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pInfo) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } if (slot_id > MAX_SLOT_ID) { st_err_log(2, __FILE__, __LINE__); rc = CKR_SLOT_ID_INVALID; goto done; } #ifdef PKCS64 memcpy( pInfo, &nv_token_data->token_info, sizeof(CK_TOKEN_INFO_32)); pInfo->flags = nv_token_data->token_info.flags; if ( nv_token_data->token_info.ulMaxSessionCount == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulMaxSessionCount = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulMaxSessionCount = nv_token_data->token_info.ulMaxSessionCount; } if ( nv_token_data->token_info.ulSessionCount == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulSessionCount = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulSessionCount = nv_token_data->token_info.ulSessionCount; } if ( nv_token_data->token_info.ulMaxRwSessionCount == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulMaxRwSessionCount = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulMaxRwSessionCount = nv_token_data->token_info.ulMaxRwSessionCount; } if ( nv_token_data->token_info.ulRwSessionCount == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulRwSessionCount = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulRwSessionCount = nv_token_data->token_info.ulRwSessionCount; } pInfo->ulMaxPinLen = nv_token_data->token_info.ulMaxPinLen; pInfo->ulMinPinLen = nv_token_data->token_info.ulMinPinLen; if ( nv_token_data->token_info.ulTotalPublicMemory == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulTotalPublicMemory = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulTotalPublicMemory = nv_token_data->token_info.ulTotalPublicMemory; } if ( nv_token_data->token_info.ulFreePublicMemory == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulFreePublicMemory = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulFreePublicMemory = nv_token_data->token_info.ulFreePublicMemory; } if ( nv_token_data->token_info.ulTotalPrivateMemory == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulTotalPrivateMemory = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulTotalPrivateMemory = nv_token_data->token_info.ulTotalPrivateMemory; } if ( nv_token_data->token_info.ulFreePrivateMemory == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulFreePrivateMemory = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulFreePrivateMemory = nv_token_data->token_info.ulFreePrivateMemory; } pInfo->hardwareVersion = nv_token_data->token_info.hardwareVersion; pInfo->firmwareVersion = nv_token_data->token_info.firmwareVersion; // pInfo->utcTime = nv_token_data->token_info.utcTime[16]; pInfo->flags = long_reverse(pInfo->flags); pInfo->ulMaxSessionCount = long_reverse(pInfo->ulMaxSessionCount); pInfo->ulSessionCount = long_reverse(pInfo->ulSessionCount); pInfo->ulMaxRwSessionCount = long_reverse(pInfo->ulMaxRwSessionCount); pInfo->ulRwSessionCount = long_reverse(pInfo->ulRwSessionCount); pInfo->ulMaxPinLen = long_reverse(pInfo->ulMaxPinLen); pInfo->ulMinPinLen = long_reverse(pInfo->ulMinPinLen); pInfo->ulTotalPublicMemory = long_reverse(pInfo->ulTotalPublicMemory); pInfo->ulFreePublicMemory = long_reverse(pInfo->ulFreePublicMemory); pInfo->ulTotalPrivateMemory = long_reverse(pInfo->ulTotalPrivateMemory); pInfo->ulFreePrivateMemory = long_reverse(pInfo->ulFreePrivateMemory); #else memcpy( pInfo, &nv_token_data->token_info, sizeof(CK_TOKEN_INFO) ); #endif // Set the time now = time ((time_t *)NULL); strftime( (char *)pInfo->utcTime, 16, "%X", localtime(&now) ); done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x\n", "C_GetTokenInfo", rc ); } UNLOCKIT; return rc; } // // CK_RV SC_WaitForSlotEvent( CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved ) { if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } // // CK_RV SC_GetMechanismList( CK_SLOT_ID sid, CK_MECHANISM_TYPE_PTR pMechList, CK_ULONG_PTR count ) { CK_ULONG i; CK_RV rc = CKR_OK; char *envrn; SLT_CHECK LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (count == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } if (slot_id > MAX_SLOT_ID) { st_err_log(2, __FILE__, __LINE__); rc = CKR_SLOT_ID_INVALID; goto done; } if (pMechList == NULL) { *count = mech_list_len; rc = CKR_OK; goto done; } if (*count < mech_list_len) { *count = mech_list_len; st_err_log(111, __FILE__, __LINE__); rc = CKR_BUFFER_TOO_SMALL; goto done; } for (i=0; i < mech_list_len; i++) pMechList[i] = mech_list[i].mech_type; #if 1 // For Netscape we want to not support the // SSL3 mechs since the native ones perform much better // Force those slots to be RSA... it's ugly but it works if ( (envrn = getenv("NS_SERVER_HOME"))!= NULL) { for (i=0; i MAX_SLOT_ID) { st_err_log(2, __FILE__, __LINE__); rc = CKR_SLOT_ID_INVALID; goto done; } for (i=0; i < mech_list_len; i++) { if (mech_list[i].mech_type == type) { memcpy( pInfo, &mech_list[i].mech_info, sizeof(CK_MECHANISM_INFO) ); rc = CKR_OK; goto done; } } st_err_log(28, __FILE__, __LINE__); rc = CKR_MECHANISM_INVALID; done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x, mech type = 0x%08x\n", "C_GetMechanismInfo", rc, type ); } UNLOCKIT; return rc; } // this routine should only be called if no other processes are attached to // the token. we need to somehow check that this is the only process // Meta API should prevent this since it knows session states in the shared // memory. // CK_RV SC_InitToken( CK_SLOT_ID sid, CK_CHAR_PTR pPin, CK_ULONG ulPinLen, CK_CHAR_PTR pLabel ) { CK_RV rc = CKR_OK; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_SLOT_ID slotID; char s[2*PATH_MAX]; struct passwd *pw = NULL; SLT_CHECK; slotID = slot_id; LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pPin || !pLabel) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } if (nv_token_data->token_info.flags & CKF_SO_PIN_LOCKED) { st_err_log(37, __FILE__, __LINE__); rc = CKR_PIN_LOCKED; goto done; } rc = token_specific.t_verify_so_pin(pPin, ulPinLen); if (rc != CKR_OK) { st_err_log(33, __FILE__, __LINE__); rc = CKR_PIN_INCORRECT; goto done; } #if 0 rc = compute_sha( pPin, ulPinLen, hash_sha ); if (memcmp(nv_token_data->so_pin_sha, hash_sha, SHA1_HASH_SIZE) != 0) { st_err_log(33, __FILE__, __LINE__); rc = CKR_PIN_INCORRECT; goto done; } rc = rng_generate( master_key, 3 * DES_KEY_SIZE ); if (rc != CKR_OK) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } #endif errno = 0; if ((pw = getpwuid(getuid())) == NULL) { LogError("%s: Error getting username: %s", __FUNCTION__, strerror(errno)); rc = CKR_FUNCTION_FAILED; goto done; } // Before we reconstruct all the data, we should delete the // token objects from the filesystem. // // Construct a string to delete the token objects. // object_mgr_destroy_token_objects(); // delete the TOK_OBJ data files sprintf(s, "%s %s/%s/%s/* > /dev/null 2>&1", DEL_CMD, pk_dir, pw->pw_name, PK_LITE_OBJ_DIR); system(s); // delete the OpenSSL backup keys sprintf(s, "%s %s/%s/%s > /dev/null 2>&1", DEL_CMD, pk_dir, pw->pw_name, TPMTOK_PUB_ROOT_KEY_FILE); system(s); sprintf(s, "%s %s/%s/%s > /dev/null 2>&1", DEL_CMD, pk_dir, pw->pw_name, TPMTOK_PRIV_ROOT_KEY_FILE); system(s); // delete the masterkey sprintf(s, "%s %s/%s/%s > /dev/null 2>&1", DEL_CMD, pk_dir, pw->pw_name, TPMTOK_MASTERKEY_PRIVATE); system(s); // //META This should be fine since the open session checking should occur at //the API not the STDLL init_token_data(); init_slotInfo(); memcpy( nv_token_data->token_info.label, pLabel, 32 ); memcpy( nv_token_data->so_pin_sha, hash_sha, SHA1_HASH_SIZE); // XXX New for v2.11 - KEY nv_token_data->token_info.flags |= CKF_TOKEN_INITIALIZED; rc = save_token_data(); if (rc != CKR_OK){ st_err_log(104, __FILE__, __LINE__, __FUNCTION__); goto done; } #if 0 rc = save_masterkey_so(); if (rc != CKR_OK){ st_err_log(149, __FILE__, __LINE__, __FUNCTION__); goto done; } #endif done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x\n", "C_InitToken", rc ); } UNLOCKIT; return rc; } // // CK_RV SC_InitPIN( ST_SESSION_HANDLE sSession, CK_CHAR_PTR pPin, CK_ULONG ulPinLen ) { SESSION * sess = NULL; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_BYTE hash_md5[MD5_HASH_SIZE]; CK_RV rc = CKR_OK; CK_FLAGS_32 * flags = NULL; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pPin) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_locked(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(37, __FILE__, __LINE__); rc = CKR_PIN_LOCKED; goto done; } if (sess->session_info.state != CKS_RW_SO_FUNCTIONS) { st_err_log(57, __FILE__, __LINE__); rc = CKR_USER_NOT_LOGGED_IN; goto done; } #if 0 if ((ulPinLen < MIN_PIN_LEN) || (ulPinLen > MAX_PIN_LEN)) { st_err_log(35, __FILE__, __LINE__); rc = CKR_PIN_LEN_RANGE; goto done; } #endif rc = token_specific.t_init_pin(pPin, ulPinLen); if (rc == CKR_OK){ flags = &nv_token_data->token_info.flags; *flags &= ~(CKF_USER_PIN_LOCKED | CKF_USER_PIN_FINAL_TRY | CKF_USER_PIN_COUNT_LOW); rc = save_token_data(); if (rc != CKR_OK){ st_err_log(104, __FILE__, __LINE__); goto done; } } #if 0 // compute the SHA and MD5 hashes of the user pin // rc = compute_sha( pPin, ulPinLen, hash_sha ); rc |= compute_md5( pPin, ulPinLen, hash_md5 ); if (rc != CKR_OK){ st_err_log(148, __FILE__, __LINE__); goto done; } rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto done; } memcpy( nv_token_data->user_pin_sha, hash_sha, SHA1_HASH_SIZE ); nv_token_data->token_info.flags |= CKF_USER_PIN_INITIALIZED; XProcUnLock( xproclock ); memcpy( user_pin_md5, hash_md5, MD5_HASH_SIZE ); rc = save_token_data(); if (rc != CKR_OK){ st_err_log(104, __FILE__, __LINE__); goto done; } rc = save_masterkey_user(); if (rc != CKR_OK){ st_err_log(149, __FILE__, __LINE__); } #endif done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: session = %08x\n", "C_InitPin", rc, hSession ); } UNLOCKIT; return rc; } // // CK_RV SC_SetPIN( ST_SESSION_HANDLE sSession, CK_CHAR_PTR pOldPin, CK_ULONG ulOldLen, CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen ) { SESSION * sess = NULL; CK_BYTE old_hash_sha[SHA1_HASH_SIZE]; CK_BYTE new_hash_sha[SHA1_HASH_SIZE]; CK_BYTE hash_md5[MD5_HASH_SIZE]; CK_MECHANISM mech; DIGEST_CONTEXT digest_ctx; CK_ULONG hash_len; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_locked(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(37, __FILE__, __LINE__); rc = CKR_PIN_LOCKED; goto done; } rc = token_specific.t_set_pin(sSession, pOldPin, ulOldLen, pNewPin, ulNewLen); #if 0 if ((ulNewLen < MIN_PIN_LEN) || (ulNewLen > MAX_PIN_LEN)) { st_err_log(35, __FILE__, __LINE__); rc = CKR_PIN_LEN_RANGE; goto done; } rc = compute_sha( pOldPin, ulOldLen, old_hash_sha ); if (rc != CKR_OK){ st_err_log(148, __FILE__, __LINE__); goto done; } if (sess->session_info.state == CKS_RW_USER_FUNCTIONS) { if (memcmp(nv_token_data->user_pin_sha, old_hash_sha, SHA1_HASH_SIZE) != 0) { st_err_log(33, __FILE__, __LINE__); rc = CKR_PIN_INCORRECT; goto done; } rc = compute_sha( pNewPin, ulNewLen, new_hash_sha ); rc |= compute_md5( pNewPin, ulNewLen, hash_md5 ); if (rc != CKR_OK){ st_err_log(148, __FILE__, __LINE__); goto done; } /* The old PIN matches, now make sure its different than the new. * If so, reset the CKF_USER_PIN_TO_BE_CHANGED flag. -KEY */ if (memcmp(old_hash_sha, new_hash_sha, SHA1_HASH_SIZE) == 0) { st_err_log(34, __FILE__, __LINE__); rc = CKR_PIN_INVALID; goto done; } rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto done; } memcpy( nv_token_data->user_pin_sha, new_hash_sha, SHA1_HASH_SIZE ); memcpy( user_pin_md5, hash_md5, MD5_HASH_SIZE ); // New in v2.11 - XXX KEY sess->session_info.flags &= ~(CKF_USER_PIN_TO_BE_CHANGED); XProcUnLock( xproclock ); rc = save_token_data(); if (rc != CKR_OK){ st_err_log(104, __FILE__, __LINE__); goto done; } rc = save_masterkey_user(); } else if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) { if (memcmp(nv_token_data->so_pin_sha, old_hash_sha, SHA1_HASH_SIZE) != 0) { rc = CKR_PIN_INCORRECT; st_err_log(33, __FILE__, __LINE__); goto done; } rc = compute_sha( pNewPin, ulNewLen, new_hash_sha ); rc |= compute_md5( pNewPin, ulNewLen, hash_md5 ); if (rc != CKR_OK){ st_err_log(148, __FILE__, __LINE__); goto done; } /* The old PIN matches, now make sure its different than the new. * If so, reset the CKF_SO_PIN_TO_BE_CHANGED flag. - KEY */ if (memcmp(old_hash_sha, new_hash_sha, SHA1_HASH_SIZE) == 0) { st_err_log(34, __FILE__, __LINE__); rc = CKR_PIN_INVALID; goto done; } rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto done; } memcpy( nv_token_data->so_pin_sha, new_hash_sha, SHA1_HASH_SIZE ); memcpy( so_pin_md5, hash_md5, MD5_HASH_SIZE ); // New in v2.11 - XXX KEY sess->session_info.flags &= ~(CKF_SO_PIN_TO_BE_CHANGED); XProcUnLock( xproclock ); rc = save_token_data(); if (rc != CKR_OK){ st_err_log(104, __FILE__, __LINE__); goto done; } rc = save_masterkey_so(); } else{ st_err_log(142, __FILE__, __LINE__); rc = CKR_SESSION_READ_ONLY; } #endif done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: session = %08x\n", "C_SetPin", rc, hSession ); } UNLOCKIT; if (rc != CKR_SESSION_READ_ONLY && rc != CKR_OK) st_err_log(149, __FILE__, __LINE__); return rc; } // // CK_RV SC_OpenSession( CK_SLOT_ID sid, CK_FLAGS flags, CK_SESSION_HANDLE_PTR phSession ) { SESSION * sess; CK_BBOOL locked = FALSE; CK_RV rc = CKR_OK; SLT_CHECK LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (phSession == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } if (slot_id > MAX_SLOT_ID) { st_err_log(2, __FILE__, __LINE__); rc = CKR_SLOT_ID_INVALID; goto done; } if ((flags & CKF_SERIAL_SESSION) == 0) { st_err_log(41, __FILE__, __LINE__); rc = CKR_SESSION_PARALLEL_NOT_SUPPORTED; goto done; } if ((flags & CKF_RW_SESSION) == 0) { if (session_mgr_so_session_exists()) { st_err_log(45, __FILE__, __LINE__); rc = CKR_SESSION_READ_WRITE_SO_EXISTS; goto done; } } // Get the mutex because we may modify the pid_list // rc = MY_LockMutex( &pkcs_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); goto done; } locked = TRUE; token_specific.t_session(slot_id); MY_UnlockMutex( &pkcs_mutex ); locked = FALSE; rc = session_mgr_new( flags, &sess ); if (rc != CKR_OK){ st_err_log(152, __FILE__, __LINE__); goto done; } *phSession = sess->handle; // Set the correct slot ID here. Was hard coded to 1. - KEY sess->session_info.slotID = sid; done: if (locked) MY_UnlockMutex( &pkcs_mutex ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x ", "C_OpenSession", rc ); if (rc == CKR_OK) stlogit2(debugfile, "sess = %d", (sess == NULL)?-1:(CK_LONG)sess->handle ); stlogit2(debugfile, "\n"); } UNLOCKIT; return rc; } // // CK_RV SC_CloseSession( ST_SESSION_HANDLE sSession ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = session_mgr_close_session( sess ); done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x sess = %d\n", "C_CloseSession", rc, hSession ); } UNLOCKIT; return rc; } // // CK_RV SC_CloseAllSessions( CK_SLOT_ID sid ) { CK_RV rc = CKR_OK; SLT_CHECK LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } rc = session_mgr_close_all_sessions(); if (rc != CKR_OK){ st_err_log(153, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x slot = %d\n", "C_CloseAllSessions", rc, slot_id ); } UNLOCKIT; return rc; } // // CK_RV SC_GetSessionInfo( ST_SESSION_HANDLE sSession, CK_SESSION_INFO_PTR pInfo ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pInfo) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } memcpy( pInfo, &sess->session_info, sizeof(CK_SESSION_INFO) ); done: if (debugfile) { stlogit2(debugfile, "%-25s: session = %08d\n", "C_GetSessionInfo", hSession ); } UNLOCKIT; return rc; } // // CK_RV SC_GetOperationState( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pulOperationStateLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } if (!pOperationState) length_only = TRUE; sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = session_mgr_get_op_state( sess, length_only, pOperationState, pulOperationStateLen ); if (rc != CKR_OK){ st_err_log(154, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: session = %08x\n", "C_GetOperationState", rc, hSession ); } UNLOCKIT; return rc; } // // CK_RV SC_SetOperationState( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pOperationState || (ulOperationStateLen == 0)) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = session_mgr_set_op_state( sess, hEncryptionKey, hAuthenticationKey, pOperationState, ulOperationStateLen ); if (rc != CKR_OK){ st_err_log(154, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: session = %08x\n", "C_SetOperationState", rc, hSession ); } UNLOCKIT; return rc; } // // CK_RV SC_Login( ST_SESSION_HANDLE sSession, CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG ulPinLen ) { SESSION * sess = NULL; CK_FLAGS_32 * flags = NULL; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_RV rc = CKR_OK; SESS_SET LOCKIT; // In v2.11, logins should be exclusive, since token // specific flags may need to be set for a bad login. - KEY rc = MY_LockMutex( &login_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } flags = &nv_token_data->token_info.flags; if (!pPin || ulPinLen > MAX_PIN_LEN) { set_login_flags(userType, flags); st_err_log(33, __FILE__, __LINE__); rc = CKR_PIN_INCORRECT; goto done; } // PKCS #11 v2.01 requires that all sessions have the same login status: // --> all sessions are public, all are SO or all are USER // if (userType == CKU_USER) { if (session_mgr_so_session_exists()){ st_err_log(60, __FILE__, __LINE__); rc = CKR_USER_ANOTHER_ALREADY_LOGGED_IN; } if (session_mgr_user_session_exists()){ st_err_log(56, __FILE__, __LINE__); rc = CKR_USER_ALREADY_LOGGED_IN; } } else if (userType == CKU_SO) { if (session_mgr_user_session_exists()){ st_err_log(60, __FILE__, __LINE__); rc = CKR_USER_ANOTHER_ALREADY_LOGGED_IN; } if (session_mgr_so_session_exists()){ st_err_log(56, __FILE__, __LINE__); rc = CKR_USER_ALREADY_LOGGED_IN; } if (session_mgr_readonly_exists()){ st_err_log(142, __FILE__, __LINE__); rc = CKR_SESSION_READ_ONLY_EXISTS; } } else { rc = CKR_USER_TYPE_INVALID; st_err_log(59, __FILE__, __LINE__); } if (rc != CKR_OK) goto done; if (userType == CKU_USER) { if (*flags & CKF_USER_PIN_LOCKED) { st_err_log(37, __FILE__, __LINE__); rc = CKR_PIN_LOCKED; goto done; } // call the pluggable login function here - KEY rc = token_specific.t_login(userType, pPin, ulPinLen); if (rc == CKR_OK) { *flags &= ~(CKF_USER_PIN_LOCKED | CKF_USER_PIN_FINAL_TRY | CKF_USER_PIN_COUNT_LOW); } else if (rc == CKR_PIN_INCORRECT) { set_login_flags(userType, flags); goto done; } else { goto done; } } else { if (*flags & CKF_SO_PIN_LOCKED) { st_err_log(37, __FILE__, __LINE__); rc = CKR_PIN_LOCKED; goto done; } // call the pluggable login function here - KEY rc = token_specific.t_login(userType, pPin, ulPinLen); if (rc == CKR_OK) { *flags &= ~(CKF_SO_PIN_LOCKED | CKF_SO_PIN_FINAL_TRY | CKF_SO_PIN_COUNT_LOW); } else if (rc == CKR_PIN_INCORRECT) { set_login_flags(userType, flags); goto done; } else { goto done; } } rc = session_mgr_login_all( userType ); if (rc != CKR_OK) { st_err_log(174, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x\n", "C_Login", rc ); } UNLOCKIT; save_token_data(); MY_UnlockMutex( &login_mutex ); return rc; } // // CK_RV SC_Logout( ST_SESSION_HANDLE sSession ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } // all sessions have the same state so we just have to check one // if (session_mgr_public_session_exists()) { st_err_log(57, __FILE__, __LINE__); rc = CKR_USER_NOT_LOGGED_IN; goto done; } rc = session_mgr_logout_all(); if (rc != CKR_OK){ st_err_log(57, __FILE__, __LINE__); } rc = token_specific.t_logout(); #if 0 memset( user_pin_md5, 0x0, MD5_HASH_SIZE ); memset( so_pin_md5, 0x0, MD5_HASH_SIZE ); object_mgr_purge_private_token_objects(); #endif done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x\n", "C_Logout", rc ); } UNLOCKIT; return rc; } // This is a Leeds-Lite solution so we have to store objects on the host. // CK_RV SC_CreateObject( ST_SESSION_HANDLE sSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject ) { SESSION * sess = NULL; CK_ULONG i; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = object_mgr_add( sess, pTemplate, ulCount, phObject ); if (rc != CKR_OK) { st_err_log(157, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x\n", "C_CreateObject", rc ); for (i = 0; i < ulCount; i++) { if (pTemplate[i].type == CKA_CLASS) stlogit2(debugfile, "%28s: 0x%02x\n", "Object Type", *(CK_ULONG *)pTemplate[i].pValue ); } if (rc == CKR_OK) stlogit2(debugfile, "%28s: %d\n", "Handle", *phObject ); } UNLOCKIT; return rc; } // // CK_RV SC_CopyObject( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phNewObject ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = object_mgr_copy( sess, pTemplate, ulCount, hObject, phNewObject ); if (rc != CKR_OK) { st_err_log(158, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, old handle = %d, new handle = %d\n", "C_CopyObject", rc, hObject, *phNewObject ); } UNLOCKIT; return rc; } // // CK_RV SC_DestroyObject( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = object_mgr_destroy_object( sess, hObject ); if (rc != CKR_OK){ st_err_log(182, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, handle = %d\n", "C_DestroyObject", rc, hObject ); } UNLOCKIT; return rc; } // // CK_RV SC_GetObjectSize( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = object_mgr_get_object_size( hObject, pulSize ); if (rc != CKR_OK){ st_err_log(184, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, handle = %d\n", "C_GetObjectSize", rc, hObject ); } UNLOCKIT; return rc; } // // CK_RV SC_GetAttributeValue( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ) { SESSION * sess = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_ULONG i; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = object_mgr_get_attribute_values( sess, hObject, pTemplate, ulCount ); if (rc != CKR_OK){ st_err_log(159, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, handle = %d\n", "C_GetAttributeValue", rc, hObject ); attr = pTemplate; for (i = 0; i < ulCount; i++, attr++) { ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } } UNLOCKIT; return rc; } // // CK_RV SC_SetAttributeValue( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ) { SESSION * sess = NULL; CK_ATTRIBUTE * attr = NULL; CK_ULONG i; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = object_mgr_set_attribute_values( sess, hObject, pTemplate, ulCount); if (rc != CKR_OK){ st_err_log(161, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, handle = %d\n", "C_SetAttributeValue", rc, hObject ); attr = pTemplate; for (i = 0; i < ulCount; i++, attr++) { CK_BYTE *ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } } UNLOCKIT; return rc; } // // CK_RV SC_FindObjectsInit( ST_SESSION_HANDLE sSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ) { SESSION * sess = NULL; CK_ATTRIBUTE * attr = NULL; CK_ULONG i; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->find_active == TRUE) { st_err_log(31, __FILE__, __LINE__); rc = CKR_OPERATION_ACTIVE; goto done; } rc = object_mgr_find_init( sess, pTemplate, ulCount ); if (rc != CKR_OK){ st_err_log(185, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x\n", "C_FindObjectsInit", rc ); attr = pTemplate; for (i = 0; i < ulCount; i++, attr++) { CK_BYTE *ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } } UNLOCKIT; return rc; } // // CK_RV SC_FindObjects( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount ) { SESSION * sess = NULL; CK_ULONG count = 0; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!phObject || !pulObjectCount) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->find_active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!sess->find_list) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } count = MIN(ulMaxObjectCount, (sess->find_count - sess->find_idx)); memcpy( phObject, sess->find_list + sess->find_idx, count * sizeof(CK_OBJECT_HANDLE) ); *pulObjectCount = count; sess->find_idx += count; rc = CKR_OK; done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, returned %d objects\n", "C_FindObjects", rc, count ); } UNLOCKIT; return rc; } // // CK_RV SC_FindObjectsFinal( ST_SESSION_HANDLE sSession ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->find_active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (sess->find_list) free( sess->find_list ); sess->find_list = NULL; sess->find_len = 0; sess->find_idx = 0; sess->find_active = FALSE; rc = CKR_OK; done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x\n", "C_FindObjectsFinal", rc ); } UNLOCKIT; return rc; } // // CK_RV SC_EncryptInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->encr_ctx.active == TRUE) { st_err_log(31, __FILE__, __LINE__); rc = CKR_OPERATION_ACTIVE; goto done; } rc = encr_mgr_init( sess, &sess->encr_ctx, OP_ENCRYPT_INIT, pMechanism, hKey ); if (rc != CKR_OK) { st_err_log(98, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, key = %d, mech = 0x%x\n", "C_EncryptInit", rc,(sess == NULL)?-1:(CK_LONG)sess->handle, hKey, pMechanism->mechanism ); } UNLOCKIT; return rc; } // // CK_RV SC_Encrypt( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pData || !pulEncryptedDataLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->encr_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pEncryptedData) length_only = TRUE; rc = encr_mgr_encrypt( sess, length_only, &sess->encr_ctx, pData, ulDataLen, pEncryptedData, pulEncryptedDataLen ); if (rc != CKR_OK) { st_err_log(99, __FILE__, __LINE__); } done: LLOCK; if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) encr_mgr_cleanup( &sess->encr_ctx ); if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, amount = %d\n", "C_Encrypt", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulDataLen ); } UNLOCKIT; return rc; } // // CK_RV SC_EncryptUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pPart || !pulEncryptedPartLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->encr_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pEncryptedPart) length_only = TRUE; rc = encr_mgr_encrypt_update( sess, length_only, &sess->encr_ctx, pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen ); if (rc != CKR_OK) { st_err_log(176, __FILE__, __LINE__); } done: LLOCK; if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL) encr_mgr_cleanup( &sess->encr_ctx ); if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, amount = %d\n", "C_EncryptUpdate", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulPartLen ); } UNLOCKIT; return rc; } // I think RSA goofed when designing the specification for C_EncryptFinal. // This function is supposed to follow the Cryptoki standard that if // pLastEncryptedPart == NULL then the user is requesting only the length // of the output. // // But it's quite possible that no output will be returned (say the user // specifies a total of 64 bytes of input data throughout the multi-part // encryption). The same thing can happen during an EncryptUpdate. // // ie: // // 1) user calls C_EncryptFinal to get the needed length // --> we return "0 bytes required" // 2) user passes in a NULL pointer for pLastEncryptedPart // --> we think the user is requesting the length again <-- // // So the user needs to pass in a non-NULL pointer even though we're not // going to return anything in it. It would have been cleaner if RSA would // have simply included a "give-me-the-length-only flag" as an argument. // // CK_RV SC_EncryptFinal( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pulLastEncryptedPartLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->encr_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pLastEncryptedPart) length_only = TRUE; rc = encr_mgr_encrypt_final( sess, length_only, &sess->encr_ctx, pLastEncryptedPart, pulLastEncryptedPartLen ); if (rc != CKR_OK) { st_err_log(177, __FILE__, __LINE__); } done: LLOCK; if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) encr_mgr_cleanup( &sess->encr_ctx ); if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d\n", "C_EncryptFinal", rc, (sess == NULL)?-1:(CK_LONG)sess->handle ); } UNLOCKIT; return rc; } // // CK_RV SC_DecryptInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->decr_ctx.active == TRUE) { st_err_log(31, __FILE__, __LINE__); rc = CKR_OPERATION_ACTIVE; goto done; } rc = decr_mgr_init( sess, &sess->decr_ctx, OP_DECRYPT_INIT, pMechanism, hKey ); if (rc != CKR_OK) { st_err_log(179, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, key = %d, mech = 0x%x\n", "C_DecryptInit", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, hKey, pMechanism->mechanism ); } UNLOCKIT; return rc; } // // CK_RV SC_Decrypt( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pEncryptedData || !pulDataLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->decr_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pData) length_only = TRUE; rc = decr_mgr_decrypt( sess, length_only, &sess->decr_ctx, pEncryptedData, ulEncryptedDataLen, pData, pulDataLen ); if (rc != CKR_OK) { st_err_log(100, __FILE__, __LINE__); } done: LLOCK; if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) decr_mgr_cleanup( &sess->decr_ctx ); if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, amount = %d\n", "C_Decrypt", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulEncryptedDataLen ); } UNLOCKIT; return rc; } // // CK_RV SC_DecryptUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pEncryptedPart || !pulPartLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->decr_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pPart) length_only = TRUE; rc = decr_mgr_decrypt_update( sess, length_only, &sess->decr_ctx, pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen ); if (rc != CKR_OK) { st_err_log(180, __FILE__, __LINE__); } done: LLOCK; if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL) decr_mgr_cleanup( &sess->decr_ctx ); if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, amount = %d\n", "C_DecryptUpdate", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulEncryptedPartLen ); } UNLOCKIT; return rc; } // // CK_RV SC_DecryptFinal( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pulLastPartLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->decr_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pLastPart) length_only = TRUE; rc = decr_mgr_decrypt_final( sess, length_only, &sess->decr_ctx, pLastPart, pulLastPartLen ); if (rc != CKR_OK) { st_err_log(181, __FILE__, __LINE__); } done: LLOCK; if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) decr_mgr_cleanup( &sess->decr_ctx ); if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, amount = %d\n", "C_DecryptFinal", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, *pulLastPartLen ); } UNLOCKIT; return rc; } // // CK_RV SC_DigestInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->digest_ctx.active == TRUE) { st_err_log(31, __FILE__, __LINE__); rc = CKR_OPERATION_ACTIVE; goto done; } rc = digest_mgr_init( sess, &sess->digest_ctx, pMechanism ); if (rc != CKR_OK) { st_err_log(123, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, mech = %x\n", "C_DigestInit", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, pMechanism->mechanism ); } UNLOCKIT; return rc; } // // CK_RV SC_Digest( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } // Netscape has been known to pass a null pData to DigestUpdate // but never for Digest. It doesn't really make sense to allow it here // if (!pData || !pulDigestLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->digest_ctx.active == FALSE) { st_err_log(85, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pDigest) length_only = TRUE; rc = digest_mgr_digest( sess, length_only, &sess->digest_ctx, pData, ulDataLen, pDigest, pulDigestLen ); if (rc != CKR_OK) { st_err_log(124, __FILE__, __LINE__); } done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) digest_mgr_cleanup( &sess->digest_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_Digest", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulDataLen ); } UNLOCKIT; return rc; } // // CK_RV SC_DigestUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } // Netscape has been known to pass a null pPart with ulPartLen == 0... // if (!pPart && ulPartLen != 0) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->digest_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (pPart){ rc = digest_mgr_digest_update( sess, &sess->digest_ctx, pPart, ulPartLen ); if (rc != CKR_OK) { st_err_log(124, __FILE__, __LINE__); } } done: if (rc != CKR_OK) digest_mgr_cleanup( &sess->digest_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_DigestUpdate", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulPartLen ); } UNLOCKIT; return rc; } // // CK_RV SC_DigestKey( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->digest_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } rc = digest_mgr_digest_key( sess, &sess->digest_ctx, hKey ); if (rc != CKR_OK){ st_err_log(124, __FILE__, __LINE__); } done: if (rc != CKR_OK) digest_mgr_cleanup( &sess->digest_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, key = %d\n", "C_DigestKey", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, hKey ); } UNLOCKIT; return rc; } // // CK_RV SC_DigestFinal( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pulDigestLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->digest_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pDigest) length_only = TRUE; rc = digest_mgr_digest_final( sess, length_only, &sess->digest_ctx, pDigest, pulDigestLen ); if (rc != CKR_OK){ st_err_log(126, __FILE__, __LINE__); } done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) digest_mgr_cleanup( &sess->digest_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d\n", "C_DigestFinal", rc, (sess == NULL)?-1:(CK_LONG)sess->handle ); } UNLOCKIT; return rc; } // // CK_RV SC_SignInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } VALID_MECH(pMechanism); if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->sign_ctx.active == TRUE) { rc = CKR_OPERATION_ACTIVE; st_err_log(31, __FILE__, __LINE__); goto done; } rc = sign_mgr_init( sess, &sess->sign_ctx, pMechanism, FALSE, hKey ); if (rc != CKR_OK){ st_err_log(127, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, mech = %x\n", "C_SignInit", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, pMechanism->mechanism ); } UNLOCKIT; return rc; } // // CK_RV SC_Sign( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pData || !pulSignatureLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->sign_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pSignature) length_only = TRUE; rc = sign_mgr_sign( sess, length_only, &sess->sign_ctx, pData, ulDataLen, pSignature, pulSignatureLen ); if (rc != CKR_OK){ st_err_log(171, __FILE__, __LINE__); } done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) sign_mgr_cleanup( &sess->sign_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_Sign", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulDataLen ); } UNLOCKIT; return rc; } // // CK_RV SC_SignUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pPart) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->sign_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } rc = sign_mgr_sign_update( sess, &sess->sign_ctx, pPart, ulPartLen ); if (rc != CKR_OK){ st_err_log(128, __FILE__, __LINE__); } done: if (rc != CKR_OK) sign_mgr_cleanup( &sess->sign_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_SignUpdate", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulPartLen ); } UNLOCKIT; return rc; } // // CK_RV SC_SignFinal( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pulSignatureLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->sign_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pSignature) length_only = TRUE; rc = sign_mgr_sign_final( sess, length_only, &sess->sign_ctx, pSignature, pulSignatureLen ); if (rc != CKR_OK){ st_err_log(129, __FILE__, __LINE__); } done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) sign_mgr_cleanup( &sess->sign_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d\n", "C_SignFinal", rc, (sess == NULL)?-1:(CK_LONG)sess->handle ); } UNLOCKIT; return rc; } // // CK_RV SC_SignRecoverInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->sign_ctx.active == TRUE) { rc = CKR_OPERATION_ACTIVE; st_err_log(31, __FILE__, __LINE__); goto done; } rc = sign_mgr_init( sess, &sess->sign_ctx, pMechanism, TRUE, hKey ); if (rc != CKR_OK){ st_err_log(127, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, mech = %x\n", "C_SignRecoverInit", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, pMechanism->mechanism ); } UNLOCKIT; return rc; } // // CK_RV SC_SignRecover( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); LOCKIT; rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pData || !pulSignatureLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if ((sess->sign_ctx.active == FALSE) || (sess->sign_ctx.recover == FALSE)) { rc = CKR_OPERATION_NOT_INITIALIZED; st_err_log(32, __FILE__, __LINE__); goto done; } if (!pSignature) length_only = TRUE; rc = sign_mgr_sign_recover( sess, length_only, &sess->sign_ctx, pData, ulDataLen, pSignature, pulSignatureLen ); if (rc != CKR_OK){ st_err_log(186, __FILE__, __LINE__); } done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) sign_mgr_cleanup( &sess->sign_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_SignRecover", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulDataLen ); } UNLOCKIT; return rc; } // // CK_RV SC_VerifyInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->verify_ctx.active == TRUE) { rc = CKR_OPERATION_ACTIVE; st_err_log(31, __FILE__, __LINE__); goto done; } rc = verify_mgr_init( sess, &sess->verify_ctx, pMechanism, FALSE, hKey ); if (rc != CKR_OK){ st_err_log(167, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, mech = %x\n", "C_VerifyInit", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, pMechanism->mechanism ); } UNLOCKIT; return rc; } // // CK_RV SC_Verify( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pData || !pSignature) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->verify_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; st_err_log(32, __FILE__, __LINE__); goto done; } rc = verify_mgr_verify( sess, &sess->verify_ctx, pData, ulDataLen, pSignature, ulSignatureLen ); if (rc != CKR_OK){ st_err_log(168, __FILE__, __LINE__); } done: verify_mgr_cleanup( &sess->verify_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_Verify", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulDataLen ); } UNLOCKIT; return rc; } // // CK_RV SC_VerifyUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pPart) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->verify_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; st_err_log(32, __FILE__, __LINE__); goto done; } rc = verify_mgr_verify_update( sess, &sess->verify_ctx, pPart, ulPartLen ); if (rc != CKR_OK){ st_err_log(169, __FILE__, __LINE__); } done: if (rc != CKR_OK) verify_mgr_cleanup( &sess->verify_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_VerifyUpdate", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulPartLen ); } UNLOCKIT; return rc; } // // CK_RV SC_VerifyFinal( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pSignature) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->verify_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; st_err_log(32, __FILE__, __LINE__); goto done; } rc = verify_mgr_verify_final( sess, &sess->verify_ctx, pSignature, ulSignatureLen ); if (rc != CKR_OK){ st_err_log(170, __FILE__, __LINE__); } done: verify_mgr_cleanup( &sess->verify_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d\n", "C_VerifyFinal", rc, (sess == NULL)?-1:(CK_LONG)sess->handle ); } UNLOCKIT; return rc; } // // CK_RV SC_VerifyRecoverInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->verify_ctx.active == TRUE) { rc = CKR_OPERATION_ACTIVE; st_err_log(31, __FILE__, __LINE__); goto done; } rc = verify_mgr_init( sess, &sess->verify_ctx, pMechanism, TRUE, hKey ); if (rc != CKR_OK){ st_err_log(167, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, mech = %x\n", "C_VerifyRecoverInit", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, pMechanism->mechanism ); } UNLOCKIT; return rc; } // // CK_RV SC_VerifyRecover( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pSignature || !pulDataLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if ((sess->verify_ctx.active == FALSE) || (sess->verify_ctx.recover == FALSE)) { rc = CKR_OPERATION_NOT_INITIALIZED; st_err_log(32, __FILE__, __LINE__); goto done; } if (!pData) length_only = TRUE; rc = verify_mgr_verify_recover( sess, length_only, &sess->verify_ctx, pSignature, ulSignatureLen, pData, pulDataLen ); if (rc != CKR_OK){ st_err_log(187, __FILE__, __LINE__); } done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) verify_mgr_cleanup( &sess->verify_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, recover len = %d, length_only = %d\n", "C_VerifyRecover", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, *pulDataLen, length_only ); } UNLOCKIT; return rc; } // // CK_RV SC_DigestEncryptUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ) { SESS_SET if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } // // CK_RV SC_DecryptDigestUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ) { SESS_SET if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } // // CK_RV SC_SignEncryptUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ) { SESS_SET if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } // // CK_RV SC_DecryptVerifyUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ) { SESS_SET if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } // // CK_RV SC_GenerateKey( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism || !phKey || (pTemplate == NULL && ulCount != 0)) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = key_mgr_generate_key( sess, pMechanism, pTemplate, ulCount, phKey ); if (rc != CKR_OK){ st_err_log(91, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { CK_ATTRIBUTE *attr = pTemplate; CK_ULONG i; stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, handle = %d, mech = %x\n", "C_GenerateKey", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, *phKey, pMechanism->mechanism ); for (i = 0; i < ulCount; i++, attr++) { CK_BYTE *ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } } UNLOCKIT; return rc; } // // CK_RV SC_GenerateKeyPair( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism || !phPublicKey || !phPrivateKey || (!pPublicKeyTemplate && (ulPublicKeyAttributeCount != 0)) || (!pPrivateKeyTemplate && (ulPrivateKeyAttributeCount != 0))) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = key_mgr_generate_key_pair( sess, pMechanism, pPublicKeyTemplate, ulPublicKeyAttributeCount, pPrivateKeyTemplate, ulPrivateKeyAttributeCount, phPublicKey, phPrivateKey ); if (rc != CKR_OK){ st_err_log(91, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { CK_ATTRIBUTE *attr = NULL; CK_ULONG i; stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, mech = %x\n", "C_GenerateKeyPair", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, pMechanism->mechanism ); if (rc == CKR_OK) { stlogit2(debugfile, " Public handle: %d\n", *phPublicKey ); stlogit2(debugfile, " Private handle: %d\n", *phPrivateKey ); } stlogit2(debugfile, " Public Template:\n"); attr = pPublicKeyTemplate; for (i = 0; i < ulPublicKeyAttributeCount; i++, attr++) { CK_BYTE *ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } stlogit2(debugfile, " Private Template:\n"); attr = pPrivateKeyTemplate; for (i = 0; i < ulPrivateKeyAttributeCount; i++, attr++) { CK_BYTE *ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } } UNLOCKIT; return rc; } // // CK_RV SC_WrapKey( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism || !pulWrappedKeyLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); if (!pWrappedKey) length_only = TRUE; sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = key_mgr_wrap_key( sess, length_only, pMechanism, hWrappingKey, hKey, pWrappedKey, pulWrappedKeyLen ); if (rc != CKR_OK){ st_err_log(188, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, encrypting key = %d, wrapped key = %d\n", "C_WrapKey", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, hWrappingKey, hKey ); } UNLOCKIT; return rc; } // // CK_RV SC_UnwrapKey( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey ) { SESSION * sess = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_ULONG i; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism || !pWrappedKey || (!pTemplate && ulCount != 0) || !phKey) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = key_mgr_unwrap_key( sess, pMechanism, pTemplate, ulCount, pWrappedKey, ulWrappedKeyLen, hUnwrappingKey, phKey ); if (rc != CKR_OK){ st_err_log(189, __FILE__, __LINE__); } done: // if (rc == CKR_OBJECT_HANDLE_INVALID) brkpt(); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, decrypting key = %d, unwrapped key = %d\n", "C_UnwrapKey", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, hUnwrappingKey, *phKey ); attr = pTemplate; for (i = 0; i < ulCount; i++, attr++) { ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } } UNLOCKIT; return rc; } // // CK_RV SC_DeriveKey( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey ) { SESSION * sess = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_ULONG i; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism || (!pTemplate && ulCount != 0)) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = key_mgr_derive_key( sess, pMechanism, hBaseKey, phKey, pTemplate, ulCount ); if (rc != CKR_OK){ st_err_log(190, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, base key = %d, mech = %x\n", "C_DeriveKey", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, hBaseKey, pMechanism->mechanism ); if (rc == CKR_OK) { switch (pMechanism->mechanism) { case CKM_SSL3_KEY_AND_MAC_DERIVE: { CK_SSL3_KEY_MAT_PARAMS *pReq; CK_SSL3_KEY_MAT_OUT *pPtr; pReq = (CK_SSL3_KEY_MAT_PARAMS *)pMechanism->pParameter; pPtr = pReq->pReturnedKeyMaterial; stlogit2(debugfile, " Client MAC key: %d\n", pPtr->hClientMacSecret ); stlogit2(debugfile, " Server MAC key: %d\n", pPtr->hServerMacSecret ); stlogit2(debugfile, " Client Key: %d\n", pPtr->hClientKey ); stlogit2(debugfile, " Server Key: %d\n", pPtr->hServerKey ); } break; case CKM_DH_PKCS_DERIVE: { stlogit2(debugfile, " DH Shared Secret: \n" ); } break ; default: stlogit2(debugfile, " Derived key: %d\n", *phKey ); } } attr = pTemplate; for (i = 0; i < ulCount; i++, attr++) { ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } } UNLOCKIT; return rc; } // // CK_RV SC_SeedRandom( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen ) { SESS_SET if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } return CKR_OK; } // // CK_RV SC_GenerateRandom( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen ) { SESSION *sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pRandomData && ulRandomLen != 0) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = rng_generate( pRandomData, ulRandomLen ); if (rc != CKR_OK){ st_err_log(130, __FILE__, __LINE__, __FUNCTION__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, %d bytes\n", "C_GenerateRandom", rc, ulRandomLen ); } UNLOCKIT; return rc; } // // CK_RV SC_GetFunctionStatus( ST_SESSION_HANDLE sSession ) { SESS_SET if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } st_err_log(17, __FILE__, __LINE__); return CKR_FUNCTION_NOT_PARALLEL; } // // CK_RV SC_CancelFunction( ST_SESSION_HANDLE sSession ) { SESS_SET if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } st_err_log(17, __FILE__, __LINE__); return CKR_FUNCTION_NOT_PARALLEL; } #if (LINUX) #define __cdecl #endif // // CK_RV __cdecl QueryTweakValues( void ) { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } // // CK_RV __cdecl UpdateTweakValues( void ) { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } // Added for AIX work void SC_SetFunctionList(void){ function_list.ST_Initialize = (void *)ST_Initialize; function_list.ST_GetTokenInfo = SC_GetTokenInfo; function_list.ST_GetMechanismList = SC_GetMechanismList; function_list.ST_GetMechanismInfo = SC_GetMechanismInfo; function_list.ST_InitToken = SC_InitToken; function_list.ST_InitPIN = SC_InitPIN; function_list.ST_SetPIN = SC_SetPIN; function_list.ST_OpenSession = SC_OpenSession; function_list.ST_CloseSession = SC_CloseSession; function_list.ST_GetSessionInfo = SC_GetSessionInfo; function_list.ST_GetOperationState = SC_GetOperationState; function_list.ST_SetOperationState = SC_SetOperationState; function_list.ST_Login = SC_Login; function_list.ST_Logout = SC_Logout; function_list.ST_CreateObject = SC_CreateObject; function_list.ST_CopyObject = SC_CopyObject; function_list.ST_DestroyObject = SC_DestroyObject; function_list.ST_GetObjectSize = SC_GetObjectSize; function_list.ST_GetAttributeValue = SC_GetAttributeValue; function_list.ST_SetAttributeValue = SC_SetAttributeValue; function_list.ST_FindObjectsInit = SC_FindObjectsInit; function_list.ST_FindObjects = SC_FindObjects; function_list.ST_FindObjectsFinal = SC_FindObjectsFinal; function_list.ST_EncryptInit = SC_EncryptInit; function_list.ST_Encrypt = SC_Encrypt; function_list.ST_EncryptUpdate = SC_EncryptUpdate; function_list.ST_EncryptFinal = SC_EncryptFinal; function_list.ST_DecryptInit = SC_DecryptInit; function_list.ST_Decrypt = SC_Decrypt; function_list.ST_DecryptUpdate = SC_DecryptUpdate; function_list.ST_DecryptFinal = SC_DecryptFinal; function_list.ST_DigestInit = SC_DigestInit; function_list.ST_Digest = SC_Digest; function_list.ST_DigestUpdate = SC_DigestUpdate; function_list.ST_DigestKey = SC_DigestKey; function_list.ST_DigestFinal = SC_DigestFinal; function_list.ST_SignInit = SC_SignInit; function_list.ST_Sign = SC_Sign; function_list.ST_SignUpdate = SC_SignUpdate; function_list.ST_SignFinal = SC_SignFinal; function_list.ST_SignRecoverInit = SC_SignRecoverInit; function_list.ST_SignRecover = SC_SignRecover; function_list.ST_VerifyInit = SC_VerifyInit; function_list.ST_Verify = SC_Verify; function_list.ST_VerifyUpdate = SC_VerifyUpdate; function_list.ST_VerifyFinal = SC_VerifyFinal; function_list.ST_VerifyRecoverInit = SC_VerifyRecoverInit; function_list.ST_VerifyRecover = SC_VerifyRecover; function_list.ST_DigestEncryptUpdate = NULL; // SC_DigestEncryptUpdate; function_list.ST_DecryptDigestUpdate = NULL; // SC_DecryptDigestUpdate; function_list.ST_SignEncryptUpdate = NULL; //SC_SignEncryptUpdate; function_list.ST_DecryptVerifyUpdate = NULL; // SC_DecryptVerifyUpdate; function_list.ST_GenerateKey = SC_GenerateKey; function_list.ST_GenerateKeyPair = SC_GenerateKeyPair; function_list.ST_WrapKey = SC_WrapKey; function_list.ST_UnwrapKey = SC_UnwrapKey; function_list.ST_DeriveKey = SC_DeriveKey; function_list.ST_SeedRandom = SC_SeedRandom ; function_list.ST_GenerateRandom = SC_GenerateRandom; function_list.ST_GetFunctionStatus = NULL; // SC_GetFunctionStatus; function_list.ST_CancelFunction = NULL; // SC_CancelFunction; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/tok_struct.h.in0000640000175000017500000000357111327631345022413 0ustar jfjf/* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */ #include "tpm_specific.h" struct token_specific_struct token_specific = { "@DB_PATH@/tpm", "tpm", "TPM_STDLL_Debug", &token_specific_init, &tok_slot2local, &token_rng, &token_specific_session, &token_specific_final, &token_specific_des_key_gen, &token_specific_des_ecb, &token_specific_des_cbc, &token_specific_tdes_ecb, &token_specific_tdes_cbc, &token_specific_rsa_decrypt, &token_specific_rsa_encrypt, &token_specific_rsa_sign, &token_specific_rsa_verify, &token_specific_rsa_generate_keypair, #ifndef NODH &token_specific_dh_pkcs_derive, &token_specific_dh_pkcs_key_pair_gen, #endif // SHA-1 - use the internal implementation NULL, NULL, NULL, &token_specific_aes_key_gen, &token_specific_aes_ecb, &token_specific_aes_cbc, &token_specific_login, &token_specific_logout, &token_specific_init_pin, &token_specific_set_pin, &token_specific_verify_so_pin }; opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/mech_dh.c0000640000175000017500000001535011327631345021165 0ustar jfjf /************************************************************************ * * * Copyright: Corrent Corporation (c) 2000-2003 * * * * Filename: mech_dh.c * * Created By: Kapil Sood * * Created On: Jan 18, 2003 * * Description: This is the file implementing Diffie-Hellman * * key pair generation and shared key derivation * * operations. * * * ************************************************************************/ // File: mech_dh.c // // Mechanisms for DH // // Routines contained within: #include #include // for memcmp() et al #include #include #include #include "pkcs11/pkcs11types.h" #include #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" #ifndef NODH // // CK_RV dh_pkcs_derive( SESSION * sess, CK_MECHANISM * mech, CK_OBJECT_HANDLE base_key, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE * handle ) { CK_RV rc; CK_ULONG i, keyclass, keytype = 0 ; CK_ATTRIBUTE *new_attr ; OBJECT *temp_obj = NULL; OBJECT *secret_obj = NULL ; CK_BYTE secret_key_value[256] ; CK_ULONG count, secret_key_value_len = 256 ; CK_ATTRIBUTE *attr ; // Prelim checking of sess, mech, pTemplate, and ulCount was // done in the calling function (key_mgr_derive_key). // Perform DH checking of parameters // Check the existance of the public-value in mechanism if ((!mech->pParameter) || ((mech->ulParameterLen != 64) && (mech->ulParameterLen != 96) && (mech->ulParameterLen != 128) && (mech->ulParameterLen != 192) && (mech->ulParameterLen != 256))) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Check valid object handle on base_key if (&base_key == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Extract the object class and keytype from the supplied template. for (i=0; i < ulCount; i++) { if (pTemplate[i].type == CKA_CLASS) { keyclass = *(CK_OBJECT_CLASS *)pTemplate[i].pValue; if (keyclass != CKO_SECRET_KEY) { st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } if (pTemplate[i].type == CKA_KEY_TYPE) keytype = *(CK_ULONG *)pTemplate[i].pValue; } // Extract public-key from mechanism parameters. base-key contains the // private key, prime, and base. The return value will be in the handle. rc = ckm_dh_pkcs_derive( mech->pParameter, mech->ulParameterLen, base_key, secret_key_value, &secret_key_value_len ); if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED ; } // Build the attribute from the vales that were returned back rc = build_attribute( CKA_VALUE, secret_key_value, secret_key_value_len, &new_attr ); if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED ; } // Create the object that will be passed back as a handle. This will // contain the new (computed) value of the attribute. rc = object_mgr_create_skel( sess, pTemplate, ulCount, MODE_KEYGEN, keyclass, keytype, &temp_obj ); if (rc != CKR_OK){ st_err_log(89, __FILE__, __LINE__); return rc; } // Update the template in the object with the new attribute template_update_attribute( temp_obj->template, new_attr ); // at this point, the derived key is fully constructed...assign an // object handle and store the key // rc = object_mgr_create_final( sess, temp_obj, handle ); if (rc != CKR_OK) { st_err_log(90, __FILE__, __LINE__); object_free( temp_obj ); return rc; } return rc; } // // mechanisms // // // CK_RV ckm_dh_pkcs_derive( CK_VOID_PTR other_pubkey, CK_ULONG other_pubkey_len, CK_OBJECT_HANDLE base_key, CK_BYTE *secret_value, CK_ULONG *secret_value_len ) { CK_RV rc; CK_BYTE p[256] ; CK_ULONG p_len ; CK_BYTE x[256] ; CK_ULONG x_len ; CK_ATTRIBUTE *temp_attr ; OBJECT *base_key_obj = NULL ; CK_ULONG count ; CK_BYTE *p_other_pubkey ; rc = object_mgr_find_in_map1( base_key, &base_key_obj ); if (rc != CKR_OK){ st_err_log(18, __FILE__, __LINE__); return CKR_KEY_HANDLE_INVALID; } // Extract secret (x) from base_key rc = template_attribute_find( base_key_obj->template, CKA_VALUE, &temp_attr ); if (rc == FALSE) { st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { memset(x, 0, sizeof(x)) ; x_len = temp_attr->ulValueLen ; memcpy(x, (CK_BYTE *)temp_attr->pValue, x_len) ; } // Extract prime (p) from base_key rc = template_attribute_find( base_key_obj->template, CKA_PRIME, &temp_attr ); if (rc == FALSE) { st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { memset(p, 0, sizeof(p)) ; p_len = temp_attr->ulValueLen ; memcpy(p, (CK_BYTE *)temp_attr->pValue, p_len) ; } p_other_pubkey = (CK_BYTE *) other_pubkey ; // Perform: z = other_pubkey^x mod p rc = token_specific.t_dh_pkcs_derive(secret_value, secret_value_len, p_other_pubkey, other_pubkey_len, x, x_len, p, p_len ); if (rc != CKR_OK) { st_err_log(191, __FILE__, __LINE__); return CKR_FUNCTION_FAILED ; } return rc; } // // CK_RV ckm_dh_pkcs_key_pair_gen( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ) { CK_RV rc; rc = token_specific.t_dh_pkcs_key_pair_gen(publ_tmpl,priv_tmpl); if (rc != CKR_OK) { st_err_log(91, __FILE__, __LINE__); } return rc; } #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/decr_mgr.c0000640000175000017500000006214211327631345021361 0ustar jfjf /* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */ /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */ // File: decr_mgr.c // // Decryption manager routines // //#include #include #include // for memcmp() et al #include #include "pkcs11/pkcs11types.h" #include #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" //#include "args.h" // // CK_RV decr_mgr_init( SESSION *sess, ENCR_DECR_CONTEXT *ctx, CK_ULONG operation, CK_MECHANISM *mech, CK_OBJECT_HANDLE key_handle ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_KEY_TYPE keytype; CK_BBOOL flag; CK_RV rc; if (!sess){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active != FALSE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } // key usage restrictions // if (operation == OP_DECRYPT_INIT) { rc = object_mgr_find_in_map1( key_handle, &key_obj ); if (rc != CKR_OK){ st_err_log(18, __FILE__, __LINE__); return CKR_KEY_HANDLE_INVALID; } // is key allowed to do general decryption? // rc = template_attribute_find( key_obj->template, CKA_DECRYPT, &attr ); if (rc == FALSE){ st_err_log(85, __FILE__, __LINE__); return CKR_KEY_FUNCTION_NOT_PERMITTED; } else { flag = *(CK_BBOOL *)attr->pValue; if (flag != TRUE){ st_err_log(85, __FILE__, __LINE__); return CKR_KEY_FUNCTION_NOT_PERMITTED; } } } else if (operation == OP_UNWRAP) { rc = object_mgr_find_in_map1( key_handle, &key_obj ); if (rc != CKR_OK){ st_err_log(62, __FILE__, __LINE__); return CKR_WRAPPING_KEY_HANDLE_INVALID; } // is key allowed to unwrap other keys? // rc = template_attribute_find( key_obj->template, CKA_UNWRAP, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // Cryptoki doesn't define a better return code } else { flag = *(CK_BBOOL *)attr->pValue; if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } } else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // is the mechanism supported? is the key type correct? is a // parameter present if required? is the key size allowed? // does the key support decryption? // // Will the FCV allow the operation? // switch (mech->mechanism) { case CKM_DES_ECB: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_56_BIT_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_CDMF_ECB: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_CDMF){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_CDMF_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_DES_CBC: case CKM_DES_CBC_PAD: { if (mech->ulParameterLen != DES_BLOCK_SIZE){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_56_BIT_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_CDMF_CBC: case CKM_CDMF_CBC_PAD: { if (mech->ulParameterLen != DES_BLOCK_SIZE){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_CDMF){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_DES3_ECB: { if (mech->ulParameterLen != 0) return CKR_MECHANISM_PARAM_INVALID; // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES3 && keytype != CKK_DES2){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_TRIPLE_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_DES3_CBC: case CKM_DES3_CBC_PAD: { if (mech->ulParameterLen != DES_BLOCK_SIZE) return CKR_MECHANISM_PARAM_INVALID; // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES3 && keytype != CKK_DES2){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_TRIPLE_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_RSA_PKCS: { if (mech->ulParameterLen != 0) return CKR_MECHANISM_PARAM_INVALID; rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_RSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // rc = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); // if (rc == FALSE || // nv_FCV.SymmetricModLength/8 < attr->value_length) // return (operation == OP_DECRYPT_INIT ? CKR_KEY_SIZE_RANGE : CKR_UNWRAPPING_KEY_SIZE_RANGE ); // RSA cannot be used for multi-part operations // ctx->context_len = 0; ctx->context = NULL; } break; case CKM_AES_ECB: { // XXX Copied from DES3, should be verified - KEY if (mech->ulParameterLen != 0) return CKR_MECHANISM_PARAM_INVALID; // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_AES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(AES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(AES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(AES_CONTEXT) ); } break; case CKM_AES_CBC: case CKM_AES_CBC_PAD: { // XXX Copied from DES3, should be verified - KEY if (mech->ulParameterLen != AES_INIT_VECTOR_SIZE) return CKR_MECHANISM_PARAM_INVALID; // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_AES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(AES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(AES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(AES_CONTEXT) ); } break; default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } if (mech->ulParameterLen > 0) { ptr = (CK_BYTE *)malloc(mech->ulParameterLen); if (!ptr){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( ptr, mech->pParameter, mech->ulParameterLen ); } ctx->key = key_handle; ctx->mech.ulParameterLen = mech->ulParameterLen; ctx->mech.mechanism = mech->mechanism; ctx->mech.pParameter = ptr; ctx->multi = FALSE; ctx->active = TRUE; return CKR_OK; } // // CK_RV decr_mgr_cleanup( ENCR_DECR_CONTEXT *ctx ) { if (!ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } ctx->key = 0; ctx->mech.ulParameterLen = 0; ctx->mech.mechanism = 0; ctx->multi = FALSE; ctx->active = FALSE; ctx->context_len = 0; if (ctx->mech.pParameter) { free( ctx->mech.pParameter ); ctx->mech.pParameter = NULL; } if (ctx->context) { free( ctx->context ); ctx->context = NULL; } return CKR_OK; } // // CK_RV decr_mgr_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } // if the caller just wants the decrypted length, there is no reason to // specify the input data. I just need the data length // if ((length_only == FALSE) && (!in_data || !out_data)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->multi == TRUE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } switch (ctx->mech.mechanism) { case CKM_CDMF_ECB: case CKM_DES_ECB: return des_ecb_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_CDMF_CBC: case CKM_DES_CBC: return des_cbc_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES_CBC_PAD: case CKM_CDMF_CBC_PAD: return des_cbc_pad_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_ECB: return des3_ecb_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_CBC: return des3_cbc_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_CBC_PAD: return des3_cbc_pad_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_RSA_PKCS: return rsa_pkcs_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #ifndef NOAES case CKM_AES_CBC: return aes_cbc_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_ECB: return aes_ecb_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_CBC_PAD: return aes_cbc_pad_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif default: return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV decr_mgr_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { if (!sess || !in_data || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!out_data && !length_only){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } ctx->multi = TRUE; switch (ctx->mech.mechanism) { case CKM_CDMF_ECB: case CKM_DES_ECB: return des_ecb_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_CDMF_CBC: case CKM_DES_CBC: return des_cbc_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES_CBC_PAD: case CKM_CDMF_CBC_PAD: return des_cbc_pad_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_ECB: return des3_ecb_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_CBC: return des3_cbc_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_CBC_PAD: return des3_cbc_pad_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #ifndef NOAES case CKM_AES_ECB: return aes_ecb_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_CBC: return aes_cbc_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_CBC_PAD: return aes_cbc_pad_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV decr_mgr_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(28, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } switch (ctx->mech.mechanism) { case CKM_CDMF_ECB: case CKM_DES_ECB: return des_ecb_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_CDMF_CBC: case CKM_DES_CBC: return des_cbc_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_DES_CBC_PAD: case CKM_CDMF_CBC_PAD: return des_cbc_pad_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_DES3_ECB: return des3_ecb_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_DES3_CBC: return des3_cbc_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_DES3_CBC_PAD: return des3_cbc_pad_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); #ifndef NOAES case CKM_AES_ECB: return aes_ecb_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_AES_CBC: return aes_cbc_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_AES_CBC_PAD: return aes_cbc_pad_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); #endif default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/Makefile.am0000640000175000017500000000606711327631345021473 0ustar jfjf# Makefile.am for common functions for openCryptoki # Michael A. Halcrow nobase_lib_LTLIBRARIES=opencryptoki/stdll/libpkcs11_tpm.la AUTOMAKE_OPTIONS = gnu #VPATH = ../common # TODO: -DLINUX and -DSPINXPL should be controlled via configure.in # Not all versions of automake observe libname_CFLAGS opencryptoki_stdll_libpkcs11_tpm_la_CFLAGS = -DLINUX -DSPINXPL -DNOCDMF \ -DNODSA -DNODH \ -I. -I../../../include \ -I../../../include/pkcs11 \ -I../common -DMMAP \ -DSTDLL_NAME=\"tpmtok\" # Not all versions of automake observe libname_CFLAGS AM_CFLAGS = -DLINUX -DMMAP -DSPINXPL -DNOCDMF -DNODSA -DNODH -I. \ -I../../../include -I../../../include/pkcs11 \ -I../common opencryptoki_stdll_libpkcs11_tpm_la_LDFLAGS = -shared -Wl,-Bsymbolic \ -lcrypto -ltspi -lpthread opencryptoki_stdll_libpkcs11_tpm_la_SOURCES = ../common/asn1.c \ dig_mgr.c \ ../common/hwf_obj.c \ ../common/log.c \ ../common/key.c \ mech_dh.c \ ../common/mech_rng.c \ new_host.c sign_mgr.c \ ../common/cert.c \ ../common/dp_obj.c \ mech_aes.c \ ../common/$(MECH_DSA) \ mech_rsa.c \ ../common/obj_mgr.c \ ../common/template.c \ ../common/data_obj.c \ encr_mgr.c key_mgr.c \ ../common/mech_md2.c \ mech_sha.c \ ../common/object.c \ decr_mgr.c globals.c \ loadsave.c utility.c \ mech_des.c \ mech_des3.c \ ../common/mech_md5.c \ ../common/mech_ssl3.c \ ../common/sess_mgr.c \ verify_mgr.c \ tpm_specific.c \ tpm_openssl.c tpm_util.c noinst_HEADERS = h_extern.h tok_spec_struct.h defs.h \ host_defs.h tpm_specific.h tok_specific.h opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/loadsave.c0000640000175000017500000013550711327631345021403 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // loadsave.c // // routines associated with loading/saving files // // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" #include "pkcs32.h" //#include "args.h" #include "../api/apiproto.h" #define MK_SIZE (AES_KEY_SIZE_256) extern CK_BYTE master_key_private[MK_SIZE]; void set_perm(int file) { #if 0 struct group *grp; // Set absolute permissions of rw-rw-r-- //fchmod(file,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH); #endif /* In the TPM token, with per user data stores, we don't share the token * object amongst a group. In fact, we want to restrict access to a single * user */ fchmod(file,S_IRUSR|S_IWUSR); #if 0 grp = getgrnam("pkcs11"); // Obtain the group id if (grp){ fchown(file,getuid(),grp->gr_gid); // set ownership to root, and pkcs11 group } #endif } // // CK_RV load_token_data() { FILE * fp; CK_BYTE fname[PATH_MAX]; TOKEN_DATA td; CK_BYTE clear[3 * DES_BLOCK_SIZE]; // enough to hold a CBC-encrypted SHA hash CK_BYTE cipher[3 * DES_BLOCK_SIZE]; CK_ULONG clear_len, cipher_len; CK_RV rc; struct passwd *pw = NULL; if ((pw = getpwuid(getuid())) == NULL){ LogError("getpwuid failed: %s", strerror(errno)); return CKR_FUNCTION_FAILED; } sprintf((char *)fname,"%s/%s/%s",(char *)pk_dir, pw->pw_name, PK_LITE_NV); rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto out_nolock; } //sprintf((char *)fname,"%s/%s",(char *)pk_dir, PK_LITE_NV); //fp = fopen("/tmp/NVTOK.DAT", "r"); fp = fopen((char *)fname, "r"); if (!fp) { /* Better error checking added */ if (errno == ENOENT) { /* init_token_data may call save_token_data, which graps the * xproclock, so we must release it around this call */ XProcUnLock( xproclock ); init_token_data(); rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto out_nolock; } //fp = fopen("/tmp/NVTOK.DAT", "r"); fp = fopen((char *)fname, "r"); if (!fp) { // were really hosed here since the created // did not occur //st_err_log(194, __FILE__, __LINE__, PK_LITE_NV, errno); LogError("failed opening %s for read: %s", fname, strerror(errno)); rc = CKR_FUNCTION_FAILED; goto out_unlock; } } else { /* Could not open file for some unknown reason */ st_err_log(194, __FILE__, __LINE__, PK_LITE_NV, errno); rc = CKR_FUNCTION_FAILED; goto out_unlock; } } set_perm(fileno(fp)); rc = fread( &td, sizeof(TOKEN_DATA), 1, fp ); fclose(fp); if (rc == 0) { rc = CKR_FUNCTION_FAILED; goto out_unlock; } // memcpy( cipher, &td.user_pin_sha, 3*DES_BLOCK_SIZE ); // clear_len = cipher_len = 3 * DES_BLOCK_SIZE; // rc = ckm_des3_cbc_decrypt( cipher, cipher_len, clear, &clear_len, "12345678", master_key ); // if (rc != CKR_OK) // return CKR_FUNCTION_FAILED; // // memcpy( &td.user_pin_sha, clear, clear_len ); // // memcpy( cipher, &td.so_pin_sha, 3*DES_BLOCK_SIZE ); // clear_len = cipher_len = 3 * DES_BLOCK_SIZE; // rc = ckm_des3_cbc_decrypt( cipher, cipher_len, clear, &clear_len, "12345678", master_key ); // if (rc != CKR_OK) // return CKR_FUNCTION_FAILED; // // memcpy( &td.so_pin_sha, clear, clear_len ); memcpy( nv_token_data, &td, sizeof(TOKEN_DATA) ); rc = CKR_OK; out_unlock: XProcUnLock( xproclock ); out_nolock: return rc; } // // CK_RV save_token_data() { FILE *fp; TOKEN_DATA td; CK_BYTE clear[3 * DES_BLOCK_SIZE]; CK_BYTE cipher[3 * DES_BLOCK_SIZE]; CK_ULONG clear_len, cipher_len; CK_RV rc; CK_BYTE fname[PATH_MAX]; struct passwd *pw = NULL; if ((pw = getpwuid(getuid())) == NULL){ LogError("getpwuid failed: %s", strerror(errno)); return CKR_FUNCTION_FAILED; } sprintf((char *)fname,"%s/%s/%s",(char *)pk_dir, pw->pw_name, PK_LITE_NV); rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto out_nolock; } //sprintf((char *)fname,"%s/%s",pk_dir, PK_LITE_NV); //fp = fopen("/tmp/NVTOK.DAT", "w"); fp = fopen((char *)fname, "r+"); if (!fp){ fp = fopen((char *)fname, "w"); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } } set_perm(fileno(fp)); memcpy( &td, nv_token_data, sizeof(TOKEN_DATA) ); // memcpy( clear, nv_token_data->user_pin_sha, SHA1_HASH_SIZE ); // memcpy( clear + SHA1_HASH_SIZE, "1234", 4 ); // clear_len = cipher_len = 3 * DES_KEY_SIZE; // rc = ckm_des3_cbc_encrypt( clear, clear_len, cipher, &cipher_len, "12345678", master_key ); // if (rc != CKR_OK) // goto done; // // memcpy( td.user_pin_sha, cipher, 3*DES_BLOCK_SIZE ); // // memcpy( clear, nv_token_data->so_pin_sha, SHA1_HASH_SIZE ); // memcpy( clear + SHA1_HASH_SIZE, "1234", 4 ); // clear_len = cipher_len = 3 * DES_KEY_SIZE; // rc = ckm_des3_cbc_encrypt( clear, clear_len, cipher, &cipher_len, "12345678", master_key ); // if (rc != CKR_OK) // goto done; // // memcpy( td.so_pin_sha, cipher, 3*DES_BLOCK_SIZE ); (void)fwrite( &td, sizeof(TOKEN_DATA), 1, fp ); fclose(fp); rc = CKR_OK; done: XProcUnLock( xproclock ); out_nolock: return rc; } // // CK_RV save_token_object( OBJECT *obj ) { FILE * fp = NULL; CK_BYTE line[100]; CK_RV rc; CK_BYTE fname[PATH_MAX]; struct passwd *pw = NULL; if (object_is_private(obj) == TRUE) rc = save_private_token_object( obj ); else rc = save_public_token_object( obj ); if (rc != CKR_OK){ st_err_log(104, __FILE__, __LINE__); return rc; } // update the index file if it exists // if ((pw = getpwuid(getuid())) == NULL){ LogError("getpwuid failed: %s", strerror(errno)); return CKR_FUNCTION_FAILED; } sprintf((char *)fname,"%s/%s/%s/%s",(char *)pk_dir, pw->pw_name, PK_LITE_OBJ_DIR, PK_LITE_OBJ_IDX); //sprintf((char *)fname,"%s/%s/%s",pk_dir,PK_LITE_OBJ_DIR,PK_LITE_OBJ_IDX); //fp = fopen( "/tmp/TOK_OBJ/OBJ.IDX", "r" ); fp = fopen( (char *)fname, "r" ); if (fp) { set_perm(fileno(fp)); while (!feof(fp)) { (void)fgets((char *)line, 50, fp ); if (!feof(fp)) { line[ strlen((char *)line)-1 ] = 0; if (strcmp((char *)line,(char *)( obj->name)) == 0) { fclose(fp); return CKR_OK; // object is already in the list } } } fclose(fp); } // we didn't find it...either the index file doesn't exist or this // is a new object... // //fp = fopen("/tmp/TOK_OBJ/OBJ.IDX", "a"); fp = fopen((char *)fname, "a"); if (!fp){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } set_perm(fileno(fp)); set_perm(fileno(fp)); fprintf( fp, "%s\n", obj->name ); fclose(fp); return CKR_OK; } // this is the same as the old version. public token objects are stored in the // clear // CK_RV save_public_token_object( OBJECT *obj ) { FILE * fp = NULL; CK_BYTE * cleartxt = NULL; CK_BYTE fname[PATH_MAX]; CK_ULONG cleartxt_len; CK_BBOOL flag = FALSE; CK_RV rc; CK_ULONG_32 total_len; struct passwd *pw = NULL; if ((pw = getpwuid(getuid())) == NULL){ LogError("getpwuid failed: %s", strerror(errno)); return CKR_FUNCTION_FAILED; } sprintf((char *)fname,"%s/%s/%s/",(char *)pk_dir, pw->pw_name, PK_LITE_OBJ_DIR); //strcpy( fname, "/tmp/TOK_OBJ/" ); //sprintf( (char *)fname,"%s/%s/", pk_dir,PK_LITE_OBJ_DIR); strncat( (char *)fname, (char *) obj->name, 8 ); rc = object_flatten( obj, &cleartxt, &cleartxt_len ); if (rc != CKR_OK){ st_err_log(101, __FILE__, __LINE__); goto error; } fp = fopen( (char *)fname, "w" ); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } set_perm(fileno(fp)); total_len = cleartxt_len + sizeof(CK_ULONG_32) + sizeof(CK_BBOOL); (void)fwrite( &total_len, sizeof(CK_ULONG_32), 1, fp ); (void)fwrite( &flag, sizeof(CK_BBOOL), 1, fp ); (void)fwrite( cleartxt, cleartxt_len, 1, fp ); fclose( fp ); free( cleartxt ); return CKR_OK; error: if (fp) fclose( fp ); if (cleartxt) free( cleartxt ); return rc; } // // CK_RV save_private_token_object( OBJECT *obj ) { FILE * fp = NULL; CK_BYTE * obj_data = NULL; CK_BYTE * cleartxt = NULL; CK_BYTE * ciphertxt = NULL; CK_BYTE * ptr = NULL; CK_BYTE fname[100]; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_BYTE hash_md5[MD5_HASH_SIZE]; CK_BYTE aes_key[AES_KEY_SIZE_256]; CK_BYTE aes_iv[AES_BLOCK_SIZE]; CK_ULONG obj_data_len,cleartxt_len, ciphertxt_len, hash_len, tmp, tmp2; CK_ULONG padded_len; CK_BBOOL flag; CK_RV rc; CK_ULONG_32 obj_data_len_32; CK_ULONG_32 total_len; struct passwd * pw = NULL; if ((pw = getpwuid(getuid())) == NULL){ LogError("getpwuid failed: %s", strerror(errno)); return CKR_FUNCTION_FAILED; } sprintf((char *)fname,"%s/%s/%s/",(char *)pk_dir, pw->pw_name, PK_LITE_OBJ_DIR); rc = object_flatten( obj, &obj_data, &obj_data_len ); obj_data_len_32 = obj_data_len; if (rc != CKR_OK){ st_err_log(101, __FILE__, __LINE__); goto error; } // // format for the object file: // private flag // ---- begin encrypted part <--+ // length of object data | // object data +---- sensitive part // SHA of (object data) | // ---- end encrypted part <--+ // compute_sha( obj_data, obj_data_len, hash_sha ); // encrypt the sensitive object data. need to be careful. // if I use the normal high-level encryption routines I'll need to // create a tepmorary key object containing the master key, perform the // encryption, then destroy the key object. There is a race condition // here if the application is multithreaded (if a thread-switch occurs, // the other application thread could do a FindObject and be able to access // the master key object. // // So I have to use the low-level encryption routines. // memcpy( aes_key, master_key_private, AES_KEY_SIZE_256 ); memcpy( aes_iv, ")#%&!*)^!()$&!&N", AES_BLOCK_SIZE ); cleartxt_len = sizeof(CK_ULONG_32) + obj_data_len_32 + SHA1_HASH_SIZE; padded_len = AES_BLOCK_SIZE * (cleartxt_len / AES_BLOCK_SIZE + 1); cleartxt = (CK_BYTE *)malloc( padded_len ); ciphertxt = (CK_BYTE *)malloc( padded_len ); if (!cleartxt || !ciphertxt) { st_err_log(0, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto error; } ciphertxt_len = padded_len; ptr = cleartxt; memcpy( ptr, &obj_data_len_32, sizeof(CK_ULONG_32) ); ptr += sizeof(CK_ULONG_32); memcpy( ptr, obj_data, obj_data_len_32 ); ptr += obj_data_len_32; memcpy( ptr, hash_sha, SHA1_HASH_SIZE ); add_pkcs_padding( cleartxt + cleartxt_len, AES_BLOCK_SIZE, cleartxt_len, padded_len ); #ifndef CLEARTEXT rc = ckm_aes_cbc_encrypt( cleartxt, padded_len, ciphertxt, &ciphertxt_len, aes_iv, (unsigned char *) aes_key, AES_KEY_SIZE_256 ); #else memcpy(ciphertxt, cleartxt, padded_len); rc = CKR_OK; #endif if (rc != CKR_OK){ st_err_log(105, __FILE__, __LINE__); goto error; } //strcpy( (char *)fname, "/tmp/TOK_OBJ/" ); //sprintf( (char *)fname,"%s/%s/", pk_dir,PK_LITE_OBJ_DIR); strncat( (char *)fname,(char *) obj->name, 8 ); fp = fopen( (char *)fname, "w" ); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } set_perm(fileno(fp)); total_len = sizeof(CK_ULONG_32) + sizeof(CK_BBOOL) + ciphertxt_len; flag = TRUE; (void)fwrite( &total_len, sizeof(CK_ULONG_32), 1, fp ); (void)fwrite( &flag, sizeof(CK_BBOOL), 1, fp ); (void)fwrite( ciphertxt, ciphertxt_len, 1, fp ); fclose( fp ); free( obj_data ); free( cleartxt ); free( ciphertxt ); return CKR_OK; error: if (fp) fclose( fp ); if (obj_data) free( obj_data ); if (cleartxt) free( cleartxt ); if (ciphertxt) free( ciphertxt ); return rc; } // // CK_RV load_public_token_objects( void ) { FILE *fp1 = NULL, *fp2 = NULL; CK_BYTE *buf = NULL; CK_BYTE tmp[PATH_MAX], fname[PATH_MAX], iname[PATH_MAX]; CK_BBOOL priv; CK_ULONG_32 size; struct passwd *pw = NULL; if ((pw = getpwuid(getuid())) == NULL){ LogError("getpwuid failed: %s", strerror(errno)); return CKR_FUNCTION_FAILED; } sprintf((char *)iname,"%s/%s/%s/%s",(char *)pk_dir, pw->pw_name, PK_LITE_OBJ_DIR, PK_LITE_OBJ_IDX); //sprintf((char *)iname,"%s/%s/%s",pk_dir,PK_LITE_OBJ_DIR, PK_LITE_OBJ_IDX); //fp1 = fopen("/tmp/TOK_OBJ/OBJ.IDX", "r"); fp1 = fopen((char *)iname, "r"); if (!fp1) return CKR_OK; // no token objects while (!feof(fp1)) { (void)fgets( (char *)tmp, 50, fp1 ); if (!feof(fp1)) { tmp[ strlen((char *)tmp)-1 ] = 0; //strcpy(fname,"/tmp/TOK_OBJ/"); sprintf((char *)fname,"%s/%s/%s/",pk_dir, pw->pw_name, PK_LITE_OBJ_DIR); strcat((char *)fname, (char *)tmp ); fp2 = fopen( (char *)fname, "r" ); if (!fp2) continue; fread( &size, sizeof(CK_ULONG_32), 1, fp2 ); fread( &priv, sizeof(CK_BBOOL), 1, fp2 ); if (priv == TRUE) { fclose( fp2 ); continue; } // size--; size = size -sizeof(CK_ULONG_32) - sizeof(CK_BBOOL); buf = (CK_BYTE *)malloc(size); if (!buf) { fclose(fp1); fclose(fp2); st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } fread( buf, size, 1, fp2 ); // ... grab object mutex here. MY_LockMutex(&obj_list_mutex); object_mgr_restore_obj( buf, NULL ); MY_UnlockMutex(&obj_list_mutex); free( buf ); fclose( fp2 ); } } fclose(fp1); return CKR_OK; } // // CK_RV load_private_token_objects( void ) { FILE *fp1 = NULL, *fp2 = NULL; CK_BYTE *buf = NULL; CK_BYTE tmp[PATH_MAX], fname[PATH_MAX],iname[PATH_MAX]; CK_BYTE sha_hash[SHA1_HASH_SIZE], old_hash[SHA1_HASH_SIZE]; CK_BBOOL priv; CK_ULONG_32 size; CK_RV rc; struct passwd *pw = NULL; if ((pw = getpwuid(getuid())) == NULL){ LogError("getpwuid failed: %s", strerror(errno)); return CKR_FUNCTION_FAILED; } sprintf((char *)iname,"%s/%s/%s/%s",(char *)pk_dir, pw->pw_name, PK_LITE_OBJ_DIR, PK_LITE_OBJ_IDX); //sprintf((char *)iname,"%s/%s/%s",pk_dir,PK_LITE_OBJ_DIR, PK_LITE_OBJ_IDX); //fp1 = fopen("/tmp/TOK_OBJ/OBJ.IDX", "r"); fp1 = fopen((char *)iname, "r"); if (!fp1) return CKR_OK; // no token objects while (!feof(fp1)) { (void)fgets((char *) tmp, 50, fp1 ); if (!feof(fp1)) { tmp[ strlen((char *)tmp)-1 ] = 0; //strcpy(fname,"/tmp/TOK_OBJ/"); sprintf((char *)fname,"%s/%s/%s/",pk_dir, pw->pw_name, PK_LITE_OBJ_DIR); strcat((char *)fname,(char *) tmp ); fp2 = fopen( (char *)fname, "r" ); if (!fp2) continue; fread( &size, sizeof(CK_ULONG_32), 1, fp2 ); fread( &priv, sizeof(CK_BBOOL), 1, fp2 ); if (priv == FALSE) { fclose( fp2 ); continue; } //size--; size = size - sizeof(CK_ULONG_32) - sizeof(CK_BBOOL); buf = (CK_BYTE *)malloc(size); if (!buf) { st_err_log(0, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto error; } rc = fread( (char *)buf, size, 1, fp2 ); if (rc != 1) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } // Grab object list mutex MY_LockMutex(&obj_list_mutex); rc = restore_private_token_object( buf, size, NULL ); MY_UnlockMutex(&obj_list_mutex); if (rc != CKR_OK){ st_err_log(107, __FILE__, __LINE__); goto error; } free( buf ); fclose( fp2 ); } } fclose(fp1); return CKR_OK; error: if (buf) free( buf ); if (fp1) fclose( fp1 ); if (fp2) fclose( fp2 ); return rc; } // // CK_RV restore_private_token_object( CK_BYTE * data, CK_ULONG len, OBJECT * pObj ) { CK_BYTE * cleartxt = NULL; CK_BYTE * obj_data = NULL; CK_BYTE * ciphertxt = NULL; CK_BYTE * ptr = NULL; CK_BYTE aes_key[AES_KEY_SIZE_256]; CK_BYTE aes_iv[AES_BLOCK_SIZE]; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_MECHANISM mech; DIGEST_CONTEXT digest_ctx; ENCR_DECR_CONTEXT encr_ctx; CK_ULONG hash_len, cleartxt_len, obj_data_len; CK_RV rc; // format for the object data: // (private flag has already been read at this point) // ---- begin encrypted part // length of object data // object data // SHA of object data // ---- end encrypted part // cleartxt_len = len; cleartxt = (CK_BYTE *)malloc(len); if (!cleartxt) { st_err_log(0, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } ciphertxt = data; // decrypt the encrypted chunk // memcpy( aes_key, master_key_private, AES_KEY_SIZE_256 ); memcpy( aes_iv, ")#%&!*)^!()$&!&N", AES_BLOCK_SIZE ); #ifndef CLEARTEXT rc = ckm_aes_cbc_decrypt( ciphertxt, len, cleartxt, &len, aes_iv, aes_key, AES_KEY_SIZE_256 ); #else memcpy(cleartxt, ciphertxt, len); rc = CKR_OK; #endif if (rc != CKR_OK){ st_err_log(106, __FILE__, __LINE__); goto done; } strip_pkcs_padding( cleartxt, len, &cleartxt_len ); // if the padding extraction didn't work it means the object was tampered with or // the key was incorrect // if (cleartxt_len > len) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } ptr = cleartxt; obj_data_len = *(CK_ULONG_32 *)ptr; ptr += sizeof(CK_ULONG_32); obj_data = ptr; // check the hash // compute_sha( ptr, obj_data_len, hash_sha ); ptr += obj_data_len; if (memcmp(ptr, hash_sha, SHA1_HASH_SIZE) != 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } // okay. at this point, we're satisfied that nobody has tampered with the // token object... // //object_mgr_restore_obj( obj_data, NULL ); object_mgr_restore_obj( obj_data, pObj ); rc = CKR_OK; done: // if (ciphertxt) free( ciphertxt ); if (cleartxt) free( cleartxt ); return rc; } #if 0 // // CK_RV load_masterkey_so( void ) { FILE * fp = NULL; CK_BYTE * ptr = NULL; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_BYTE cipher[sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE clear [sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE des3_key[3 * DES_KEY_SIZE]; CK_MECHANISM mech; DIGEST_CONTEXT digest_ctx; MASTER_KEY_FILE_T mk; CK_ULONG cipher_len, clear_len, hash_len; CK_RV rc; CK_BYTE fname[PATH_MAX]; memset( master_key, 0x0, 3*DES_KEY_SIZE ); // this file gets created on C_InitToken so we can assume that it always exists // sprintf((char *)fname,"%s/MK_SO",pk_dir); //fp = fopen("/tmp/MK_SO", "r"); fp = fopen((char *)fname, "r"); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } set_perm(fileno(fp)); clear_len = cipher_len = (sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE - 1) & ~(DES_BLOCK_SIZE - 1); rc = fread( cipher, cipher_len, 1, fp ); if (rc != 1) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } // decrypt the master key data using the MD5 of the SO key // (we can't use the SHA of the SO key since the SHA of the key is stored // in the token data file). // memcpy( des3_key, so_pin_md5, MD5_HASH_SIZE ); memcpy( des3_key + MD5_HASH_SIZE, so_pin_md5, DES_KEY_SIZE ); #ifndef CLEARTEXT rc = ckm_des3_cbc_decrypt( cipher, cipher_len, clear, &clear_len, "12345678", des3_key ); #else memcpy(clear, cipher, cipher_len); rc = CKR_OK; #endif if (rc != CKR_OK){ st_err_log(106, __FILE__, __LINE__); goto done; } memcpy( (CK_BYTE *)&mk, clear, sizeof(mk) ); // // technically should strip PKCS padding here but since I already know what // the length should be, I don't bother. // // compare the hashes // compute_sha( mk.key, 3 * DES_KEY_SIZE, hash_sha ); if (memcmp(hash_sha, mk.sha_hash, SHA1_HASH_SIZE) != 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } memcpy( master_key, mk.key, 3*DES_KEY_SIZE ); rc = CKR_OK; done: if (fp) fclose(fp); return rc; } // // CK_RV load_masterkey_user( void ) { FILE * fp = NULL; CK_BYTE * ptr = NULL; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_BYTE cipher[sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE clear[sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE des3_key[3 * DES_KEY_SIZE]; CK_MECHANISM mech; DIGEST_CONTEXT digest_ctx; MASTER_KEY_FILE_T mk; CK_ULONG cipher_len, clear_len, hash_len; CK_RV rc; CK_BYTE fname[PATH_MAX]; memset( master_key, 0x0, 3*DES_KEY_SIZE ); // this file gets created on C_InitToken so we can assume that it always exists // sprintf((char *)fname,"%s/MK_USER",pk_dir); //fp = fopen( "/tmp/MK_USER", "r" ); fp = fopen( (char *)fname, "r" ); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } set_perm(fileno(fp)); clear_len = cipher_len = (sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE - 1) & ~(DES_BLOCK_SIZE - 1); rc = fread( cipher, cipher_len, 1, fp ); if (rc != 1) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } // decrypt the master key data using the MD5 of the SO key // (we can't use the SHA of the SO key since the SHA of the key is stored // in the token data file). // memcpy( des3_key, user_pin_md5, MD5_HASH_SIZE ); memcpy( des3_key + MD5_HASH_SIZE, user_pin_md5, DES_KEY_SIZE ); #ifndef CLEARTEXT rc = ckm_des3_cbc_decrypt( cipher, cipher_len, clear, &clear_len, "12345678", des3_key ); #else memcpy(clear, cipher, cipher_len); rc = CKR_OK; #endif if (rc != CKR_OK){ st_err_log(106, __FILE__, __LINE__); goto done; } memcpy( (CK_BYTE *)&mk, clear, sizeof(mk) ); // // technically should strip PKCS padding here but since I already know what // the length should be, I don't bother. // // compare the hashes // compute_sha( mk.key, 3 * DES_KEY_SIZE, hash_sha ); if (memcmp(hash_sha, mk.sha_hash, SHA1_HASH_SIZE) != 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } memcpy( master_key, mk.key, 3*DES_KEY_SIZE ); rc = CKR_OK; done: if (fp) fclose(fp); return rc; } // // CK_RV save_masterkey_so( void ) { FILE * fp = NULL; CK_BYTE cleartxt [sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE ciphertxt[sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE des3_key[3 * DES_KEY_SIZE]; CK_MECHANISM mech; DIGEST_CONTEXT digest_ctx; MASTER_KEY_FILE_T mk; CK_ULONG hash_len, cleartxt_len, ciphertxt_len, padded_len; CK_RV rc; CK_BYTE fname[PATH_MAX]; memcpy( mk.key, master_key, 3 * DES_KEY_SIZE); compute_sha( master_key, 3 * DES_KEY_SIZE, mk.sha_hash ); // encrypt the key data // memcpy( des3_key, so_pin_md5, MD5_HASH_SIZE ); memcpy( des3_key + MD5_HASH_SIZE, so_pin_md5, DES_KEY_SIZE ); ciphertxt_len = sizeof(ciphertxt); cleartxt_len = sizeof(mk); memcpy( cleartxt, &mk, cleartxt_len ); padded_len = DES_BLOCK_SIZE * (cleartxt_len / DES_BLOCK_SIZE + 1); add_pkcs_padding( cleartxt + cleartxt_len, DES_BLOCK_SIZE, cleartxt_len, padded_len ); #ifndef CLEARTEXT rc = ckm_des3_cbc_encrypt( cleartxt, padded_len, ciphertxt, &ciphertxt_len, "12345678", des3_key ); #else memcpy(ciphertxt, cleartxt, padded_len); rc = CKR_OK; #endif if (rc != CKR_OK){ st_err_log(105, __FILE__, __LINE__); goto done; } // write the file // // probably ought to ensure the permissions are correct // sprintf((char *)fname,"%s/MK_SO",pk_dir); //fp = fopen( "/tmp/MK_SO", "w" ); fp = fopen( (char *)fname, "w" ); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } set_perm(fileno(fp)); rc = fwrite( ciphertxt, ciphertxt_len, 1, fp ); if (rc != 1) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } rc = CKR_OK; done: if (fp) fclose( fp ); return rc; } // // CK_RV save_masterkey_user( void ) { FILE * fp = NULL; CK_BYTE cleartxt [sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE ciphertxt[sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE des3_key[3 * DES_KEY_SIZE]; CK_MECHANISM mech; DIGEST_CONTEXT digest_ctx; MASTER_KEY_FILE_T mk; CK_ULONG hash_len, cleartxt_len, ciphertxt_len, padded_len; CK_RV rc; CK_BYTE fname[PATH_MAX]; memcpy( mk.key, master_key, 3 * DES_KEY_SIZE); compute_sha( master_key, 3 * DES_KEY_SIZE, mk.sha_hash ); // encrypt the key data // memcpy( des3_key, user_pin_md5, MD5_HASH_SIZE ); memcpy( des3_key + MD5_HASH_SIZE, user_pin_md5, DES_KEY_SIZE ); ciphertxt_len = sizeof(ciphertxt); cleartxt_len = sizeof(mk); memcpy( cleartxt, &mk, cleartxt_len ); padded_len = DES_BLOCK_SIZE * (cleartxt_len / DES_BLOCK_SIZE + 1); add_pkcs_padding( cleartxt + cleartxt_len, DES_BLOCK_SIZE, cleartxt_len, padded_len ); #ifndef CLEARTEXT rc = ckm_des3_cbc_encrypt( cleartxt, padded_len, ciphertxt, &ciphertxt_len, "12345678", des3_key ); #else memcpy(ciphertxt, cleartxt, padded_len); rc = CKR_OK; #endif if (rc != CKR_OK){ st_err_log(105, __FILE__, __LINE__); goto done; } // write the file // // probably ought to ensure the permissions are correct // sprintf((char *)fname,"%s/MK_USER", pk_dir); //fp = fopen( "/tmp/MK_USER", "w" ); fp = fopen( (char *)fname, "w" ); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } set_perm(fileno(fp)); rc = fwrite( ciphertxt, ciphertxt_len, 1, fp ); if (rc != 1) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } rc = CKR_OK; done: if (fp) fclose( fp ); return rc; } #endif // // CK_RV reload_token_object( OBJECT *obj ) { FILE * fp = NULL; CK_BYTE * buf = NULL; CK_BYTE fname[PATH_MAX]; CK_BBOOL priv; CK_ULONG_32 size; CK_ULONG size_64; CK_RV rc; struct passwd *pw = NULL; if ((pw = getpwuid(getuid())) == NULL){ LogError("getpwuid failed: %s", strerror(errno)); return CKR_FUNCTION_FAILED; } memset( (char *)fname, 0x0, sizeof(fname) ); sprintf((char *)fname,"%s/%s/%s/",(char *)pk_dir, pw->pw_name, PK_LITE_OBJ_DIR); // strcpy(fname, "/tmp/TOK_OBJ/" ); //sprintf((char *)fname,"%s/%s/",pk_dir, PK_LITE_OBJ_DIR); strncat((char *)fname,(char *) obj->name, 8 ); fp = fopen( (char *)fname, "r" ); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } set_perm(fileno(fp)); fread( &size, sizeof(CK_ULONG_32), 1, fp ); fread( &priv, sizeof(CK_BBOOL), 1, fp ); size = size - sizeof(CK_ULONG_32) - sizeof(CK_BBOOL); // SAB buf = (CK_BYTE *)malloc(size); if (!buf) { st_err_log(0, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } fread( buf, size, 1, fp ); size_64 = size; if (priv){ rc = restore_private_token_object( buf, size_64, obj ); if (rc != CKR_OK) st_err_log(107, __FILE__, __LINE__); } else{ rc = object_mgr_restore_obj( buf, obj ); if (rc != CKR_OK) st_err_log(108, __FILE__, __LINE__); } done: if (fp) fclose( fp ); if (buf) free( buf ); return rc; } extern void set_perm(int) ; // // CK_RV delete_token_object( OBJECT *obj ) { FILE *fp1, *fp2; CK_BYTE line[100]; CK_BYTE objidx[PATH_MAX], idxtmp[PATH_MAX], fname[PATH_MAX]; struct passwd *pw = NULL; if ((pw = getpwuid(getuid())) == NULL){ LogError("getpwuid failed: %s", strerror(errno)); return CKR_FUNCTION_FAILED; } sprintf((char *)objidx,"%s/%s/%s/%s",(char *)pk_dir, pw->pw_name, PK_LITE_OBJ_DIR, PK_LITE_OBJ_IDX); sprintf((char *)idxtmp,"%s/%s/%s/%s",(char *)pk_dir, pw->pw_name, PK_LITE_OBJ_DIR, "IDX.TMP"); // FIXME: on UNIX, we need to make sure these guys aren't symlinks // before we blindly write to these files... // // remove the object from the index file // //sprintf((char *)objidx,"%s/%s/%s",pk_dir, PK_LITE_OBJ_DIR,PK_LITE_OBJ_IDX); //sprintf((char *)idxtmp,"%s/%s/%s",pk_dir, PK_LITE_OBJ_DIR, "IDX.TMP"); //fp1 = fopen("/tmp/TOK_OBJ/OBJ.IDX", "r"); //fp2 = fopen("/tmp/TOK_OBJ/IDX.TMP", "w"); fp1 = fopen((char *)objidx, "r"); fp2 = fopen((char *)idxtmp, "w"); if (!fp1 || !fp2) { if (fp1) fclose(fp1); if (fp2) fclose(fp2); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } set_perm(fileno(fp2)); while (!feof(fp1)) { (void)fgets((char *)line, 50, fp1 ); if (!feof(fp1)) { line[ strlen((char *)line)-1 ] = 0; if (strcmp((char *)line, (char *)obj->name) == 0) continue; else fprintf( fp2, "%s\n", line ); } } fclose(fp1); fclose(fp2); //fp2 = fopen("/tmp/TOK_OBJ/OBJ.IDX", "w"); //fp1 = fopen("/tmp/TOK_OBJ/IDX.TMP", "r"); fp2 = fopen((char *)objidx, "w"); fp1 = fopen((char *)idxtmp, "r"); if (!fp1 || !fp2) { if (fp1) fclose(fp1); if (fp2) fclose(fp2); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } set_perm(fileno(fp2)); while (!feof(fp1)) { (void)fgets((char *)line, 50, fp1 ); if (!feof(fp1)) fprintf( fp2, "%s",(char *) line ); } fclose(fp1); fclose(fp2); sprintf((char *)fname,"%s/%s/%s/%s",pk_dir, pw->pw_name, PK_LITE_OBJ_DIR, (char *)obj->name); //sprintf((char *)fname,"%s/%s/%s",pk_dir, PK_LITE_OBJ_DIR,(char *)obj->name); unlink((char *)fname); return CKR_OK; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/tpm_util.c0000640000175000017500000001247611327631345021441 0ustar jfjf /* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pkcs11/pkcs11types.h" #include "pkcs11/stdll.h" #include "defs.h" #include "host_defs.h" #include "../common/args.h" #include "h_extern.h" #include "tpm_specific.h" extern TSS_HCONTEXT tspContext; UINT32 util_get_keysize_flag(CK_ULONG size) { switch (size) { case 512: return TSS_KEY_SIZE_512; break; case 1024: return TSS_KEY_SIZE_1024; break; case 2048: return TSS_KEY_SIZE_2048; break; default: break; } return 0; } CK_BYTE * util_create_id(int type) { CK_BYTE *ret = NULL; int size = 0; switch (type) { case TPMTOK_PRIVATE_ROOT_KEY: size = TPMTOK_PRIVATE_ROOT_KEY_ID_SIZE + 1; if ((ret = malloc(size)) == NULL) { LogError("malloc of %d bytes failed.", size); break; } sprintf((char *)ret, "%s", TPMTOK_PRIVATE_ROOT_KEY_ID); break; case TPMTOK_PUBLIC_ROOT_KEY: size = TPMTOK_PUBLIC_ROOT_KEY_ID_SIZE + 1; if ((ret = malloc(size)) == NULL) { LogError("malloc of %d bytes failed.", size); break; } sprintf((char *)ret, "%s", TPMTOK_PUBLIC_ROOT_KEY_ID); break; case TPMTOK_PUBLIC_LEAF_KEY: size = TPMTOK_PUBLIC_LEAF_KEY_ID_SIZE + 1; if ((ret = malloc(size)) == NULL) { LogError("malloc of %d bytes failed.", size); break; } sprintf((char *)ret, "%s", TPMTOK_PUBLIC_LEAF_KEY_ID); break; case TPMTOK_PRIVATE_LEAF_KEY: size = TPMTOK_PRIVATE_LEAF_KEY_ID_SIZE + 1; if ((ret = malloc(size)) == NULL) { LogError("malloc of %d bytes failed.", size); break; } sprintf((char *)ret, "%s", TPMTOK_PRIVATE_LEAF_KEY_ID); break; default: LogError("Unknown type passed to %s: %d", __FUNCTION__, type); break; } return ret; } int util_set_file_mode(char *filename, mode_t mode) { struct stat file_stat; if (stat(filename, &file_stat) == -1) { LogError("%s: stat: %s", __FUNCTION__, strerror(errno)); return -1; } else if ((file_stat.st_mode ^ mode) != 0) { if (chmod(filename, mode) == -1) { LogError("chmod(%s) failed: %s", filename, strerror(errno)); return -1; } } return 0; } /* make sure the public exponent attribute is 65537 */ CK_ULONG util_check_public_exponent(TEMPLATE *tmpl) { CK_BBOOL flag; CK_ATTRIBUTE *publ_exp_attr; CK_BYTE pubexp_bytes[] = { 1, 0, 1 }; CK_ULONG publ_exp, rc = 1; flag = template_attribute_find(tmpl, CKA_PUBLIC_EXPONENT, &publ_exp_attr); if (!flag){ LogError("Couldn't find public exponent attribute"); return CKR_TEMPLATE_INCOMPLETE; } switch (publ_exp_attr->ulValueLen) { case 3: rc = memcmp(pubexp_bytes, publ_exp_attr->pValue, 3); break; case sizeof(CK_ULONG): publ_exp = *((CK_ULONG *)publ_exp_attr->pValue); if (publ_exp == 65537) rc = 0; break; default: break; } return rc; } TSS_RESULT util_set_public_modulus(TSS_HKEY hKey, unsigned long size_n, unsigned char *n) { UINT64 offset; UINT32 blob_size; BYTE *blob, pub_blob[1024]; TCPA_PUBKEY pub_key; TSS_RESULT result; /* Get the TCPA_PUBKEY blob from the key object. */ result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB, TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY, &blob_size, &blob); if (result != TSS_SUCCESS) { LogError("Tspi_GetAttribData failed: rc=0x%x", result); return result; } offset = 0; result = Trspi_UnloadBlob_PUBKEY(&offset, blob, &pub_key); if (result != TSS_SUCCESS) { LogError("Tspi_GetAttribData failed: rc=0x%x", result); return result; } Tspi_Context_FreeMemory(tspContext, blob); /* Free the first dangling reference, putting 'n' in its place */ free(pub_key.pubKey.key); pub_key.pubKey.keyLength = size_n; pub_key.pubKey.key = n; offset = 0; Trspi_LoadBlob_PUBKEY(&offset, pub_blob, &pub_key); /* Free the second dangling reference */ free(pub_key.algorithmParms.parms); /* set the public key data in the TSS object */ result = Tspi_SetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB, TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY, (UINT32)offset, pub_blob); if (result != TSS_SUCCESS) { LogError("Tspi_SetAttribData failed: rc=0x%x", result); return result; } return TSS_SUCCESS; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/globals.c0000751000175000017500000004307111327631345021225 0ustar jfjf /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005*/ /*************************************************************************** Change Log ========== 4/25/03 Kapil Sood (kapil@corrent.com) Added DH key pair generation and DH shared key derivation functions. ****************************************************************************/ #include #include #include "pkcs11types.h" #include "stdll.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" CK_SLOT_INFO slot_info; CK_BBOOL initialized = FALSE; // native_mutex is used to protect C_Initialize. It gets created when the DLL // is attached, it gets destroyed when the DLL is detached // pthread_mutex_t native_mutex ; MUTEX pkcs_mutex, obj_list_mutex, sess_list_mutex, login_mutex; #if SYSVSEM int xprocsemid = -1; #endif void *xproclock; DL_NODE *sess_list = NULL; DL_NODE *sess_obj_list = NULL; DL_NODE *publ_token_obj_list = NULL; DL_NODE *priv_token_obj_list = NULL; DL_NODE *object_map = NULL; CK_STATE global_login_state = 0; LW_SHM_TYPE *global_shm; CK_ULONG next_session_handle = 1; CK_ULONG next_object_handle = 1; TOKEN_DATA *nv_token_data = NULL; struct ST_FCN_LIST function_list ; extern CK_RV LW_Initialize(); /* extern CK_RV SC_Initialize */ extern CK_RV SC_GetFunctionList(); /* extern CK_RV SC_GetFunctionList */ extern CK_RV SC_GetTokenInfo(); /* extern CK_RV SC_GetTokenInfo */ extern CK_RV SC_GetMechanismList(); /* extern CK_RV SC_GetMechanismList */ extern CK_RV SC_GetMechanismInfo(); /* extern CK_RV SC_GetMechanismInfo */ extern CK_RV SC_InitToken(); /* extern CK_RV SC_InitToken */ extern CK_RV SC_InitPIN(); /* extern CK_RV SC_InitPIN */ extern CK_RV SC_SetPIN(); /* extern CK_RV SC_SetPIN */ extern CK_RV SC_OpenSession(); /* extern CK_RV SC_OpenSession */ extern CK_RV SC_CloseSession(); /* extern CK_RV SC_CloseSession */ extern CK_RV SC_CloseAllSessions(); /* extern CK_RV SC_CloseAllSessions */ extern CK_RV SC_GetSessionInfo(); /* extern CK_RV SC_GetSessionInfo */ extern CK_RV SC_GetOperationState(); /* extern CK_RV SC_GetOperationState */ extern CK_RV SC_SetOperationState(); /* extern CK_RV SC_SetOperationState */ extern CK_RV SC_Login(); /* extern CK_RV SC_Login */ extern CK_RV SC_Logout(); /* extern CK_RV SC_Logout */ extern CK_RV SC_CreateObject(); /* extern CK_RV SC_CreateObject */ extern CK_RV SC_CopyObject(); /* extern CK_RV SC_CopyObject */ extern CK_RV SC_DestroyObject(); /* extern CK_RV SC_DestroyObject */ extern CK_RV SC_GetObjectSize(); /* extern CK_RV SC_GetObjectSize */ extern CK_RV SC_GetAttributeValue(); /* extern CK_RV SC_GetAttributeValue */ extern CK_RV SC_SetAttributeValue(); /* extern CK_RV SC_SetAttributeValue */ extern CK_RV SC_FindObjectsInit(); /* extern CK_RV SC_FindObjectsInit */ extern CK_RV SC_FindObjects(); /* extern CK_RV SC_FindObjects */ extern CK_RV SC_FindObjectsFinal(); /* extern CK_RV SC_FindObjectsFinal */ extern CK_RV SC_EncryptInit(); /* extern CK_RV SC_EncryptInit */ extern CK_RV SC_Encrypt(); /* extern CK_RV SC_Encrypt */ extern CK_RV SC_EncryptUpdate(); /* extern CK_RV SC_EncryptUpdate */ extern CK_RV SC_EncryptFinal(); /* extern CK_RV SC_EncryptFinal */ extern CK_RV SC_DecryptInit(); /* extern CK_RV SC_DecryptInit */ extern CK_RV SC_Decrypt(); /* extern CK_RV SC_Decrypt */ extern CK_RV SC_DecryptUpdate(); /* extern CK_RV SC_DecryptUpdate */ extern CK_RV SC_DecryptFinal(); /* extern CK_RV SC_DecryptFinal */ extern CK_RV SC_DigestInit(); /* extern CK_RV SC_DigestInit */ extern CK_RV SC_Digest(); /* extern CK_RV SC_Digest */ extern CK_RV SC_DigestUpdate(); /* extern CK_RV SC_DigestUpdate */ extern CK_RV SC_DigestKey(); /* extern CK_RV SC_DigestKey */ extern CK_RV SC_DigestFinal(); /* extern CK_RV SC_DigestFinal */ extern CK_RV SC_SignInit(); /* extern CK_RV SC_SignInit */ extern CK_RV SC_Sign(); /* extern CK_RV SC_Sign */ extern CK_RV SC_SignUpdate(); /* extern CK_RV SC_SignUpdate */ extern CK_RV SC_SignFinal(); /* extern CK_RV SC_SignFinal */ extern CK_RV SC_SignRecoverInit(); /* extern CK_RV SC_SignRecoverInit */ extern CK_RV SC_SignRecover(); /* extern CK_RV SC_SignRecover */ extern CK_RV SC_VerifyInit(); /* extern CK_RV SC_VerifyInit */ extern CK_RV SC_Verify(); /* extern CK_RV SC_Verify */ extern CK_RV SC_VerifyUpdate(); /* extern CK_RV SC_VerifyUpdate */ extern CK_RV SC_VerifyFinal(); /* extern CK_RV SC_VerifyFinal */ extern CK_RV SC_VerifyRecoverInit(); /* extern CK_RV SC_VerifyRecoverInit */ extern CK_RV SC_VerifyRecover(); /* extern CK_RV SC_VerifyRecover */ extern CK_RV SC_DigestEncryptUpdate(); /* extern CK_RV SC_DigestEncryptUpdate */ extern CK_RV SC_DecryptDigestUpdate(); /* extern CK_RV SC_DecryptDigestUpdate */ extern CK_RV SC_SignEncryptUpdate(); /* extern CK_RV SC_SignEncryptUpdate */ extern CK_RV SC_DecryptVerifyUpdate(); /* extern CK_RV SC_DecryptVerifyUpdate */ extern CK_RV SC_GenerateKey(); /* extern CK_RV SC_GenerateKey */ extern CK_RV SC_GenerateKeyPair(); /* extern CK_RV SC_GenerateKeyPair */ extern CK_RV SC_WrapKey(); /* extern CK_RV SC_WrapKey */ extern CK_RV SC_UnwrapKey(); /* extern CK_RV SC_UnwrapKey */ extern CK_RV SC_DeriveKey(); /* extern CK_RV SC_DeriveKey */ extern CK_RV SC_SeedRandom(); /* extern CK_RV SC_SeedRandom */ extern CK_RV SC_GenerateRandom(); /* extern CK_RV SC_GenerateRandom */ extern CK_RV SC_GetFunctionStatus(); /* extern CK_RV SC_GetFunctionStatus */ extern CK_RV SC_CancelFunction(); /* extern CK_RV SC_CancelFunction */ extern CK_RV SC_WaitForSlotEvent(); /* extern CK_RV SC_WaitForSlotEvent */ // OBJECT IDENTIFIERs // CK_BYTE ber_idDSA[] = { 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01 }; CK_BYTE ber_rsaEncryption[] = { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 }; CK_BYTE ber_md2WithRSAEncryption[] = { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02 }; CK_BYTE ber_md4WithRSAEncryption[] = { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x03 }; CK_BYTE ber_md5WithRSAEncryption[] = { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x04 }; CK_BYTE ber_sha1WithRSAEncryption[] = { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05 }; // Algorithm IDs. (Sequence of OID plus parms, usually NULL) // CK_BYTE ber_AlgMd2[] = { 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x02, 0x05, 0x00 }; CK_BYTE ber_AlgMd5[] = { 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00 }; CK_BYTE ber_AlgSha1[] = { 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00 }; CK_BYTE ber_AlgSha256[] = { 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00 }; CK_BYTE ber_AlgIdRSAEncryption[] = { 0x30, 0x0D, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00 }; // ID Lengths // CK_ULONG ber_idDSALen = sizeof(ber_idDSA); CK_ULONG ber_rsaEncryptionLen = sizeof(ber_rsaEncryption); CK_ULONG ber_md2WithRSAEncryptionLen = sizeof(ber_md2WithRSAEncryption); CK_ULONG ber_md4WithRSAEncryptionLen = sizeof(ber_md4WithRSAEncryption); CK_ULONG ber_md5WithRSAEncryptionLen = sizeof(ber_md5WithRSAEncryption); CK_ULONG ber_sha1WithRSAEncryptionLen= sizeof(ber_sha1WithRSAEncryption); CK_ULONG ber_AlgMd2Len= sizeof(ber_AlgMd2); CK_ULONG ber_AlgMd5Len= sizeof(ber_AlgMd5); CK_ULONG ber_AlgSha1Len= sizeof(ber_AlgSha1); CK_ULONG ber_AlgSha256Len= sizeof(ber_AlgSha256); CK_ULONG ber_AlgIdRSAEncryptionLen = sizeof(ber_AlgIdRSAEncryption); CK_ULONG des_weak_count = 4; CK_ULONG des_semi_weak_count = 12; CK_ULONG des_possibly_weak_count = 48; CK_BYTE des_weak_keys[4][8] = { {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, {0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E}, {0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1}, {0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE} }; CK_BYTE des_semi_weak_keys[12][8] = { {0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE}, {0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01}, {0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1}, {0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E}, {0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1}, {0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01}, {0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE}, {0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E}, {0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E}, {0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01}, {0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE}, {0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1} }; CK_BYTE des_possibly_weak_keys[48][8] = { {0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E, 0x01, 0x01}, {0x01, 0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E, 0x01}, {0x1F, 0x01, 0x01, 0x1F, 0x0E, 0x01, 0x01, 0x0E}, {0x01, 0x01, 0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E}, {0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1, 0x01, 0x01}, {0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01}, {0xFE, 0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E, 0x01}, {0xE0, 0xFE, 0x1F, 0x01, 0xF1, 0xFE, 0x0E, 0x01}, {0xFE, 0xE0, 0x01, 0x1F, 0xFE, 0xF1, 0x01, 0x0E}, {0xE0, 0xFE, 0x01, 0x1F, 0xF1, 0xFE, 0x01, 0x0E}, {0xE0, 0xE0, 0x1F, 0x1F, 0xF1, 0xF1, 0x0E, 0x0E}, {0xFE, 0xFE, 0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E}, {0xFE, 0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1, 0x01}, {0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E, 0xFE, 0x01}, {0xFE, 0x01, 0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E}, {0xE0, 0x01, 0xFE, 0x1F, 0xF1, 0x01, 0xFE, 0x0E}, {0x01, 0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1, 0x01}, {0x1F, 0xFE, 0xE0, 0x01, 0x0E, 0xFE, 0xF0, 0x01}, {0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1, 0xFE, 0x01}, {0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01}, {0x1F, 0xE0, 0xE0, 0x1F, 0x0E, 0xF1, 0xF1, 0x0E}, {0x01, 0xFE, 0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E}, {0x01, 0xE0, 0xFE, 0x1F, 0x01, 0xF1, 0xFE, 0x0E}, {0x1F, 0xFE, 0xFE, 0x1F, 0x0E, 0xFE, 0xFE, 0x0E}, {0xE0, 0x01, 0x01, 0xE0, 0xF1, 0x01, 0x01, 0xF1}, {0xFE, 0x1F, 0x01, 0xE0, 0xFE, 0x0E, 0x01, 0xF1}, {0xFE, 0x01, 0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1}, {0xE0, 0x1F, 0x1F, 0xE0, 0xF1, 0x0E, 0x0E, 0xF1}, {0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE}, {0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E, 0x01, 0xFE}, {0xE0, 0x01, 0x1F, 0xFE, 0xF1, 0x01, 0x0E, 0xFE}, {0xFE, 0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E, 0xFE}, {0x1F, 0xFE, 0x01, 0xE0, 0x0E, 0xFE, 0x01, 0xF1}, {0x01, 0xFE, 0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1}, {0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1, 0x01, 0xFE}, {0x01, 0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E, 0xFE}, {0x01, 0x01, 0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1}, {0x1F, 0x1F, 0xE0, 0xE0, 0x0E, 0x0E, 0xF1, 0xF1}, {0x1F, 0x01, 0xFE, 0xE0, 0x0E, 0x01, 0xFE, 0xF1}, {0x01, 0x1F, 0xFE, 0xE0, 0x01, 0x0E, 0xFE, 0xF1}, {0x1F, 0x01, 0xE0, 0xFE, 0x0E, 0x01, 0xF1, 0xFE}, {0x01, 0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1, 0xFE}, {0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE}, {0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E, 0xFE, 0xFE}, {0xFE, 0xFE, 0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1}, {0xE0, 0xFE, 0xFE, 0xE0, 0xF1, 0xFE, 0xFE, 0xF1}, {0xFE, 0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1, 0xFE}, {0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1, 0xFE, 0xFE} }; MECH_LIST_ELEMENT mech_list[] = { { CKM_RSA_PKCS_KEY_PAIR_GEN, {512, 2048, CKF_GENERATE_KEY_PAIR} }, { CKM_DES_KEY_GEN, {0, 0, CKF_GENERATE} }, { CKM_DES3_KEY_GEN, {0, 0, CKF_GENERATE} }, { CKM_RSA_PKCS, {512, 2048, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP | CKF_SIGN | CKF_VERIFY | CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER} }, { CKM_RSA_PKCS_OAEP, {512, 2048, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP | CKF_SIGN | CKF_VERIFY | CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER} }, #if !(NOX509) { CKM_RSA_X_509, {512, 2048, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP | CKF_SIGN | CKF_VERIFY | CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER} }, #endif { CKM_MD5_RSA_PKCS, {512, 2048, CKF_HW | CKF_SIGN | CKF_VERIFY} }, { CKM_SHA1_RSA_PKCS, {512, 2048, CKF_HW | CKF_SIGN | CKF_VERIFY} }, { CKM_DES_ECB, {0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP} }, { CKM_DES_CBC, {0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP} }, { CKM_DES_CBC_PAD, {0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP} }, { CKM_DES3_ECB, {0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP} }, { CKM_DES3_CBC, {0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP} }, { CKM_DES3_CBC_PAD, {0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP} }, { CKM_SHA_1, {0, 0, CKF_DIGEST} }, { CKM_SHA_1_HMAC, {0, 0, CKF_SIGN | CKF_VERIFY} }, { CKM_SHA_1_HMAC_GENERAL, {0, 0, CKF_SIGN | CKF_VERIFY} }, { CKM_MD5, {0, 0, CKF_DIGEST} }, { CKM_MD5_HMAC, {0, 0, CKF_SIGN | CKF_VERIFY} }, { CKM_MD5_HMAC_GENERAL, {0, 0, CKF_SIGN | CKF_VERIFY} }, { CKM_SSL3_PRE_MASTER_KEY_GEN, {48, 48, CKF_GENERATE} }, { CKM_SSL3_MASTER_KEY_DERIVE, {48, 48, CKF_DERIVE} }, { CKM_SSL3_KEY_AND_MAC_DERIVE, {48, 48, CKF_DERIVE} }, { CKM_SSL3_MD5_MAC, {384, 384, CKF_SIGN | CKF_VERIFY} }, { CKM_SSL3_SHA1_MAC, {384, 384, CKF_SIGN | CKF_VERIFY} }, { CKM_AES_KEY_GEN, {16, 32, CKF_GENERATE} }, { CKM_AES_ECB, {16, 32, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP} }, { CKM_AES_CBC, {16, 32, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP} }, { CKM_AES_MAC, {16, 32, CKF_SIGN | CKF_VERIFY} }, { CKM_AES_MAC_GENERAL, {16, 32, CKF_SIGN | CKF_VERIFY} }, { CKM_AES_CBC_PAD, {16, 32, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP} }, }; CK_ULONG mech_list_len = (sizeof(mech_list) / sizeof(MECH_LIST_ELEMENT)); // default SO pin hash values // // default SO pin = "87654321" // CK_BYTE default_so_pin_md5[MD5_HASH_SIZE] = { 0x5E, 0x86, 0x67, 0xA4, 0x39, 0xC6, 0x8F, 0x51, 0x45, 0xDD, 0x2F, 0xCB, 0xEC, 0xF0, 0x22, 0x09 }; CK_BYTE default_so_pin_sha[SHA1_HASH_SIZE] = { 0xA7, 0xD5, 0x79, 0xBA, 0x76, 0x39, 0x80, 0x70, 0xEA, 0xE6, 0x54, 0xC3, 0x0F, 0xF1, 0x53, 0xA4, 0xC2, 0x73, 0x27, 0x2A }; /* SHA-1 of "12345678" */ CK_BYTE default_user_pin_sha[SHA1_HASH_SIZE] = { 0x7c, 0x22, 0x2f, 0xb2, 0x92, 0x7d, 0x82, 0x8a, 0xf2, 0x2f, 0x59, 0x21, 0x34, 0xe8, 0x93, 0x24, 0x80, 0x63, 0x7c, 0x0d }; CK_BYTE user_pin_md5[MD5_HASH_SIZE]; CK_BYTE so_pin_md5[MD5_HASH_SIZE]; opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/tpm_stdll/encr_mgr.c0000640000175000017500000006063211327631345021375 0ustar jfjf /* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */ /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */ // File: encr_mgr.c // // Encryption manager routines // //#include #include #include // for memcmp() et al #include #include "pkcs11/pkcs11types.h" #include #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" //#include "args.h" // // CK_RV encr_mgr_init( SESSION * sess, ENCR_DECR_CONTEXT * ctx, CK_ULONG operation, CK_MECHANISM * mech, CK_OBJECT_HANDLE key_handle ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_KEY_TYPE keytype; CK_BBOOL flag; CK_RV rc; if (!sess || !ctx || !mech){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active != FALSE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } // key usage restrictions // if (operation == OP_ENCRYPT_INIT) { rc = object_mgr_find_in_map1( key_handle, &key_obj ); if (rc != CKR_OK){ st_err_log(18, __FILE__, __LINE__); return CKR_KEY_HANDLE_INVALID; } // is key allowed to do general encryption? // rc = template_attribute_find( key_obj->template, CKA_ENCRYPT, &attr ); if (rc == FALSE){ st_err_log(85, __FILE__, __LINE__); return CKR_KEY_FUNCTION_NOT_PERMITTED; } else { flag = *(CK_BBOOL *)attr->pValue; if (flag != TRUE){ st_err_log(85, __FILE__, __LINE__); return CKR_KEY_FUNCTION_NOT_PERMITTED; } } } else if (operation == OP_WRAP) { rc = object_mgr_find_in_map1( key_handle, &key_obj ); if (rc != CKR_OK){ st_err_log(62, __FILE__, __LINE__); return CKR_WRAPPING_KEY_HANDLE_INVALID; } // is key allowed to wrap other keys? // rc = template_attribute_find( key_obj->template, CKA_WRAP, &attr ); if (rc == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } else { flag = *(CK_BBOOL *)attr->pValue; if (flag == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } } } else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // is the mechanism supported? is the key type correct? is a // parameter present if required? is the key size allowed? // does the key support encryption? // // Will the FCV allow the operation? // switch (mech->mechanism) { case CKM_DES_ECB: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_56_BIT_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_CDMF_ECB: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_CDMF){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_DES_CBC: case CKM_DES_CBC_PAD: { if (mech->ulParameterLen != DES_BLOCK_SIZE){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_56_BIT_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_CDMF_CBC: case CKM_CDMF_CBC_PAD: { if (mech->ulParameterLen != DES_BLOCK_SIZE){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_CDMF){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_DES3_ECB: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES3 && keytype != CKK_DES2){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_TRIPLE_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_DES3_CBC: case CKM_DES3_CBC_PAD: { if (mech->ulParameterLen != DES_BLOCK_SIZE){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES3 && keytype != CKK_DES2){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_TRIPLE_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_RSA_PKCS: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_RSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // rc = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); // if (rc == FALSE || nv_FCV.SymmetricModLength/8 < attr->value_length) // return (operation == OP_DECRYPT_INIT ? CKR_KEY_SIZE_RANGE : CKR_WRAPPING_KEY_SIZE_RANGE ); // RSA cannot be used for multi-part operations // ctx->context_len = 0; ctx->context = NULL; } break; case CKM_AES_ECB: { // XXX Copied in from DES3, should be verified - KEY if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_AES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(AES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(AES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(AES_CONTEXT) ); } break; case CKM_AES_CBC: case CKM_AES_CBC_PAD: { // XXX Copied in from DES3, should be verified - KEY if (mech->ulParameterLen != AES_INIT_VECTOR_SIZE){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_AES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(AES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(AES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(AES_CONTEXT) ); } break; default: st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } if (mech->ulParameterLen > 0) { ptr = (CK_BYTE *)malloc(mech->ulParameterLen); if (!ptr){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( ptr, mech->pParameter, mech->ulParameterLen ); } ctx->key = key_handle; ctx->mech.ulParameterLen = mech->ulParameterLen; ctx->mech.mechanism = mech->mechanism; ctx->mech.pParameter = ptr; ctx->multi = FALSE; ctx->active = TRUE; return CKR_OK; } // // CK_RV encr_mgr_cleanup( ENCR_DECR_CONTEXT *ctx ) { if (!ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } ctx->key = 0; ctx->mech.ulParameterLen = 0; ctx->mech.mechanism = 0; ctx->multi = FALSE; ctx->active = FALSE; ctx->context_len = 0; if (ctx->mech.pParameter) { free( ctx->mech.pParameter ); ctx->mech.pParameter = NULL; } if (ctx->context) { free( ctx->context ); ctx->context = NULL; } return CKR_OK; } // // CK_RV encr_mgr_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } // if the caller just wants the encrypted length, there is no reason to // specify the input data. I just need the data length // if ((length_only == FALSE) && (!in_data || !out_data)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->multi == TRUE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } switch (ctx->mech.mechanism) { case CKM_CDMF_ECB: case CKM_DES_ECB: return pk_des_ecb_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_CDMF_CBC: case CKM_DES_CBC: return pk_des_cbc_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES_CBC_PAD: case CKM_CDMF_CBC_PAD: return des_cbc_pad_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_ECB: return des3_ecb_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_CBC: return des3_cbc_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_CBC_PAD: return des3_cbc_pad_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_RSA_PKCS: return rsa_pkcs_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #ifndef NOAES case CKM_AES_CBC: return aes_cbc_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_ECB: return aes_ecb_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_CBC_PAD: return aes_cbc_pad_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif default: st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV encr_mgr_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { if (!sess || !in_data || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!out_data && !length_only){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__, __FUNCTION__); return CKR_OPERATION_NOT_INITIALIZED; } ctx->multi = TRUE; switch (ctx->mech.mechanism) { case CKM_CDMF_ECB: case CKM_DES_ECB: return des_ecb_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_CDMF_CBC: case CKM_DES_CBC: return des_cbc_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES_CBC_PAD: case CKM_CDMF_CBC_PAD: return des_cbc_pad_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_ECB: return des3_ecb_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_CBC: return des3_cbc_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_CBC_PAD: return des3_cbc_pad_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #ifndef NOAES case CKM_AES_ECB: return aes_ecb_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_CBC: return aes_cbc_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_CBC_PAD: return aes_cbc_pad_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif default: return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV encr_mgr_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__, __FUNCTION__); return CKR_OPERATION_NOT_INITIALIZED; } switch (ctx->mech.mechanism) { case CKM_CDMF_ECB: case CKM_DES_ECB: return des_ecb_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_CDMF_CBC: case CKM_DES_CBC: return des_cbc_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_DES_CBC_PAD: case CKM_CDMF_CBC_PAD: return des_cbc_pad_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_DES3_ECB: return des3_ecb_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_DES3_CBC: return des3_cbc_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_DES3_CBC_PAD: return des3_cbc_pad_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); #ifndef NOAES case CKM_AES_ECB: return aes_ecb_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_AES_CBC: return aes_cbc_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_AES_CBC_PAD: return aes_cbc_pad_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); #endif default: return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cr_stdll/0000751000175000017500000000000011327631345017232 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cr_stdll/typhoon.h0000751000175000017500000015611011327631345021112 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /************************************************************************ * * * Copyright: Corrent Corporation (c) 2001 * * * * Filename: typhoon.h * * Created By: Kapil Sood * * Created On: April 26, 2001 * * Description: This is the main header file of the typhoon * * software library. This file contains all * * function declarations, data structures, type * * definitions, and data declarations that will * * be used in the typhoon software library. * * * * * ************************************************************************/ /* Revision * $Id: typhoon.h,v 1.1 2005/01/18 16:09:03 kyoder Exp $ */ #ifndef TYPHOON_H #define TYPHOON_H #ifdef __cplusplus extern "C" { #endif #include /* Define Error and Warning file names */ #ifdef _UNIX #define ERROR_FILE_NAME "/tmp/error.dat" #define WARNING_FILE_NAME "/tmp/warning.dat" #endif /* Define typedefs for data types used */ typedef unsigned char BYTE ; /* 8-bit byte */ typedef unsigned short INT16 ; /* 16-bit integer */ typedef unsigned int INT32 ; /* 32-bit integer */ /* Define Endian-ness of the library */ typedef enum cr_endian_enum { CR_BIG_ENDIAN=0, CR_LITTLE_ENDIAN, CR_NETWORK_ENDIAN, /* Add all values above this */ CR_MAX_ENDIAN } CR_ENDIAN ; CR_ENDIAN cr_lib_endian ; /* Define Return Code values */ typedef enum RC_enum { SUCCESS = 0, FAILURE = 1, /* Add all values above this */ MAX_RC } RC ; /* Define Crypto Algorithm Code */ typedef enum op_code_enum { CR_NULL_CRYPTO=0, CR_MOD_EXP, CR_MOD_EXP_CRT, CR_RSA_OP, CR_RSA_CRT_OP, CR_DSA_OP, CR_DES_CBC_ENC_OP, CR_DES_CBC_DEC_OP, CR_DES_ECB_ENC_OP, CR_DES_ECB_DEC_OP, CR_TDES_CBC_EDE_ENC_OP, CR_TDES_CBC_EDE_DEC_OP, CR_TDES_ECB_EDE_ENC_OP, CR_TDES_ECB_EDE_DEC_OP, CR_ARCFOUR_ENC_OP, CR_ARCFOUR_DEC_OP, CR_AES128_CBC_ENC_OP, CR_AES128_CBC_DEC_OP, CR_AES192_CBC_ENC_OP, CR_AES192_CBC_DEC_OP, CR_AES256_CBC_ENC_OP, CR_AES256_CBC_DEC_OP, CR_AES128_ECB_ENC_OP, CR_AES128_ECB_DEC_OP, CR_AES192_ECB_ENC_OP, CR_AES192_ECB_DEC_OP, CR_AES256_ECB_ENC_OP, CR_AES256_ECB_DEC_OP, CR_AUTHENTICATE_OP, /* For all HMAC operations */ /* Add all values above this */ CR_MAX_OP_CODE } CR_OP_CODE ; typedef enum authenticate_code_enum { CR_NULL_AUTH=0, CR_SHA1, /* Perform SHA-1 hash */ CR_HMAC_SHA1, /* Perform HMAC_SHA-1 */ CR_HMAC_SHA1_96, /* Perform HMAC_SHA-1-96 */ CR_MD5, /* Perform MD5 hash */ CR_HMAC_MD5, /* Perform HMAC_MD5 hash */ CR_HMAC_MD5_96, /* Perform HMAC_MD5-96 */ CR_MD5_SHA1, /* Perform MD5 and SHA1 hashes separately */ CR_DBL_SHA1, /* Perform SHA1 twice */ CR_DBL_MD5, /* Perform MD5 twice */ CR_DBL_SHA1_MD5, /* Perform MD5 inside and SHA-1 outside */ CR_DBL_MD5_SHA1, /* Perform SHA-1 inside and MD5 outside */ CR_PRF, /* Perform PRF */ /* Add all values above this */ CR_MAX_AUTH_CODE } CR_AUTH_CODE ; /* Define the RSA padding/encryption type */ typedef enum rsa_type_enum { CR_NULL_RSA = 0, CR_PKCS1_1_5 = 1, /* Perform PKCS1_1.5 used in SSLv3/TLS1.0 */ /* Add all values above this */ CR_MAX_RSA_TYPE } CR_RSA_TYPE ; /* Define typedefs for complex data structures used */ typedef struct token_struct { BYTE *p_data ; /* The pointer to actual data */ INT32 data_size ; /* The length (in bytes) of the data */ } token ; typedef struct rsa_key_struct { token *modulus ; /* 'n' */ token *exponent ; /* Can be 'e' or 'd' */ } rsa_key ; typedef struct rsa_crt_key_struct { token *prime_p ; token *prime_q ; token *dmp1 ; /* 'd mod (p-1)' value */ token *dmq1 ; /* 'd mod (q-1)' value */ token *iqmp ; /* 'inv(q) mod p' value */ } rsa_crt_key ; typedef struct dsa_sign_key_struct { token *r ; token *s ; } dsa_sign_key ; typedef struct dsa_key_struct { token *p ; token *q ; token *g ; token *key ; /* sign: server private key(x); verify: client public key(y) */ } dsa_key ; /* The following struct is used as a general purpose structure for DES encryption/decryption operations. Each of the DES keys are 56-bit long, as per DES specifications. However, the last bit of each byte is used for parity checking. Therefore, the total key size for each key is 64-bit. If single/double keys are used, then unused keys must be NULL, and NULL keys must follow the valid keys. The Initialization Vector (iv) is also 64-bit long. */ typedef struct des_key_struct { token *iv ; token *key1 ; token *key2 ; token *key3 ; } des_key ; /* The following struct is used as the key for ARCFOUR. The length of the key * may be between 1 and 256 bytes. However, SSLv3 and TLS1.0 use ARC4 with 128bit * (16 Bytes) key length. Use either the static key, or key token. */ typedef struct arcfour_key_struct { token *key ; unsigned char state[256] ; unsigned char state_x ; unsigned char state_y ; } arcfour_key ; /* The following struct is used as a key for AES. The length of the key must be 128/192/256 bits for AES128/AES192/AES256 respectively. The iv must also be of appropriate sizes */ typedef struct aes_key_struct { token *key ; token *iv ; } aes_key ; /* The following struct is used for defining secret key components for HMAC algorithms. The size of i/odigest component will be 16/20 Bytes, depending on the hash algorithm MD5/SHA1. The I/ODigest values are the 64B extention of the secret key, XORed with ipad/opad, and then hash operated. Alternatively, the application could send the secret into the library, and the Typhoon device will handle the entire computation. If an ordinary MD5 or SHA1 hashing operation is required, there is no need to use this structure. */ typedef struct hmac_key_struct { token *secret ; token *idigest ; token *odigest ; } hmac_key ; /* The following struct is used for defining secret keys for TLS1.0 PRF algorithms. The PRF key components will be either the secret, or the I/ODigest for HMAC_MD5 and HMAC_SHA1. If the secret is NULL, then all other components must contain valid values. If secret is not NULL, then the secret will be used by the library. If the secret is not NULL, then other components must be NULL or will be ignored. */ typedef struct prf_key_struct { token *secret ; BYTE *idigest_md5 ; BYTE *odigest_md5 ; BYTE *idigest_sha1 ; BYTE *odigest_sha1 ; } prf_key ; /* The following structure will be used for passing SSLv3 and TLS1.0 security parameters into the library. These security parameters will be unique for every SSL/TLS connection and direction. The tls_mac_key must be used for TLS1.0 only, and the sslv3_tls_mac_secret for SSLv3. The symmetric keys will either be DES/3DES or ARC4. */ typedef struct sslv3_tls_key_struct { CR_AUTH_CODE auth_code ; CR_OP_CODE crypto_code ; hmac_key *tls_hmac_key ; token *sslv3_mac_secret ; union { des_key *des_sym_key ; arcfour_key *arcfour_sym_key ; } sym_key ; } sslv3_tls_key ; /* The following are the SA flags that will be used with IPSEC processing. * CR_AH_ADDPAD * CR_AH_NEXT_HDR_STRIP - If set for ESP inbound packets the next header byte * will be removed from the packet after decryption. * CR_IV_STRIP - If set for ESP inbound packets the IV is removed * from the IPsec header. * CR_OHDR_STRIP - If set then all bytes up to the data are removed. * CR_MIN_PADEN - If set for outbound packets then the packet is * padded to the multiple of the cipher block size. * For NULL cipher the packet is padded to a multiple * of 4 bytes. * CR_ENCRYPT - Set for outbound ESP packets. Cleared for inbound. */ #define CR_AH_ADDPAD 0x00000001 #define CR_NEXT_HDR_STRIP 0x00000002 #define CR_IV_STRIP 0x00000004 #define CR_OHDR_STRIP 0x00000008 #define CR_MIN_PADEN 0x00000010 #define CR_ENCRYPT 0x00000020 /* Data structure for storing key information for IPsec AH & ESP packets. * auth_code - Authentication type. Must be set for AH. Can be NULL for ESP. * crypto_code - Cipher type for ESP packets. Must be CR_AUTHENTICATE_OP for * AH. * sa_flags - Flags to set in the SA from the list above. * hmac_key - Mac Secret for authentication. Can be NULL if no auth. * sym_key - Union of DES and AES key pointers. crypto_code is checked * to determine which key to use if any. Ignored for AH mode. * NOTE: auth_code and crypto_code cannot both be NULL. */ typedef struct ipsec_key_struct { CR_AUTH_CODE auth_code ; CR_OP_CODE crypto_code ; INT32 sa_flags ; hmac_key *hmac_key ; union { des_key *des_sym_key ; aes_key *aes_sym_key ; } sym_key ; } ipsec_key ; /* Data structures and defines for returning statistics into the library. * The same structure will be passed into the driver. */ #ifndef CR7020_STATS_HDR #define CR7020_STATS_HDR #define CR7020_MAX_STATS 20 #define CR7020_MAX_STAT_NAME_LEN 30 typedef struct cr_key_value_pair { char key[CR7020_MAX_STAT_NAME_LEN] ; unsigned long value ; } cr_key_value_pair; typedef struct cr_stat_table { union { cr_key_value_pair cr7020_stat[CR7020_MAX_STATS] ; } dev ; } cr_stat_table; cr_stat_table cr7020_stat_table ; #endif /* CR7020_STATS_HDR */ #ifndef CR_DEVICE_INFO #define CR_DEVICE_INFO typedef struct cr_device_info_struct { unsigned char driver_version[8]; unsigned int device; unsigned int device_status; unsigned char pci_bus_num; unsigned char pci_dev_num; unsigned char pci_func_num; } cr_device_info; #endif /* CR_DEVICE_INFO */ /* ##################################################################### */ /* Define Function Prototypes */ /* ##################################################################### */ /************************************************************************** Numerical Functions ***************************************************************************/ /* The following function is used for retrieving a random number. The desired length of the random is specified in the size parameter. The random number is returned in result buffer, along with the byte size. */ RC CR_get_random(token *result, INT32 size) ; /* This function will be used for returning strong DES keys, each 8 byte in size. The number of keys is specified in the count parameter. The result token will be filled with the 'count' number of DES keys concatenated in one string. The result size component will contain the length of the DES key string in bytes. */ RC CR_get_des_keys(token *result, INT32 count) ; /* This function is used for returning a prime number of a desired length (in bytes). This length is specified in the size parameter. The prime number is returned in the result buffer, along with the size in bytes */ RC CR_get_prime(token *result, INT32 size) ; /* The following function is used for performing mod operations (a mod n) on the argument, and returns the result. The argument must be in the octet format. */ RC CR_mod(token *result, token *argument, token *modulus) ; /* The following function is used for performing mod exp (a^e mod n) operations on the argument, and returns the result. This uses Montgomery exponentiation method. The argument must be in the octet format and it DOES require a modulo reduction being already done. */ RC CR_mod_exp_mont(token *result, token *argument, token *modulus, token *exponent) ; #ifdef TYPHOON_B /* The following function is used for performing mod exp (a^e mod n) operations on the argument, and returns the result. This uses Montgomery exponentiation method. The argument must be in the octet format and DOES NOT require a modulo reduction. */ RC CR_mod_exp_mont_with_reduction(token *result, token *argument, token *modulus, token *exponent) ; #endif /* TYPHOON_B */ /* The following function is used for performing mod exp (a^e mod n) operations using the Chinese Remainder Theorem. This operation may be used for the RSA private key decrypt, and RSA signing operations. The argument must be in the octet format. */ RC CR_mod_exp_crt(token *result, token *argument, token *prime_p, token *prime_q, token *dmp1, token *dmq1, token *iqmp) ; /* The following function is used for performing mod_add (a+b mod n) operations on the arguments, and returns the result. The argument must be in the octet format. */ RC CR_mod_add(token *result, token *a_arg, token *b_arg, token *modulus) ; /* The following function is used for performing mod_mult (a*b mod n) operations on the arguments, and returns the result. This operation uses Montgomery multiplication method. The argument must be in the octet format. */ RC CR_mod_mult_mont(token *result, token *a_arg, token *b_arg, token *modulus) ; /* The following function will compute 'inv(k) mod n' operation on the argument (k) that is passed in along with the modulus (n). */ RC CR_inv_mod(token *result, token *k, token *modulus) ; /* The following function will be used for computing the value of R^2 mod N, where R^2 = 2^(2*(k+8)) and 'k' is size of N in bytes */ RC CR_r_sqr_mod_n(token *result, token *modulus) ; /************************************************************************** Public-Key Crypto Functions ***************************************************************************/ /* The following function is used for performing RSA encrypt operations on the argument, and returns the result. The 'argument' is in the octet string format. This function performs rsa_type operations to encrypt the argument. The exponent is the public key 'e' component of the recipient. The trans_id is used for debug/error tracking and is optional (can be NULL) */ RC CR_rsa_encrypt(token *ciphertext, BYTE *trans_id, token *argument, CR_RSA_TYPE rsa_type, rsa_key *key) ; /* The following function is used for performing RSA decrypt operations on the argument, and returns the result. The 'argument' is the ciphertext in the octet string format. This function performs rsa_type operations to decrypt the argument. The rsa_key->exponent is the private key 'd' of the recipient. The trans_id is used for debug/error tracking and is optional (can be NULL) */ RC CR_rsa_decrypt(token *plaintext, BYTE *trans_id, token *argument, CR_RSA_TYPE rsa_type, rsa_key *key) ; /* The following function is used for performing RSA decrypt operations on the argument, and returns the result. The 'argument' is the ciphertext in the octet string format. This function performs PKCS#1 operation, specified by rsa_type, to decrypt the argument. The rsa_key->exponent is the private key 'd' of the recipient. The trans_id is used for debug/error tracking and is optional (can be NULL) */ RC CR_rsa_decrypt_crt(token *plaintext, BYTE *trans_id, token *argument, CR_RSA_TYPE rsa_type, rsa_crt_key *key) ; /* The following function is used for performing RSA private key decrypt ops on the argument, and returns the original msg that was encrypted. The 'argument' is in the octet string format. This function does NOT perform any padding ops, and is designed to be used by an external RSA_decrypt() function. The result is of the same size as the modulus, which means that it may have leading zeros. The rsa_key->exponent is the private key 'd' of the recipient. The trans_id is used for debug/error tracking and is optional (can be NULL) */ RC CR_rsa_private_decrypt(token *plaintext, BYTE *trans_id, token *argument, rsa_key *key) ; /* The following function performs RSA private key decrypt operations, using CRT, on the argument, and returns the original msg. The 'argument' is in the octet string format. This function does not perform any padding operations, and will be used by an external RSA_decrypt function. The result is of the same size as the modulus, which means that it may have leading zeros. The trans_id is used for debug/error tracking and is optional (can be NULL) */ RC CR_rsa_private_decrypt_crt(token *plaintext, BYTE *trans_id, token *argument, rsa_crt_key *key) ; /* The following function is used for performing RSA signing operations on the argument, and returns the signature. The 'argument' is in the octet string format. This function performs PKCS#1 encoding operations, as specified by rsa_type to generate the signature. The hash_code value depends on the protocol requesting the signing. The trans_id is used for debug/error tracking and is optional (can be NULL) */ RC CR_rsa_sign(token *signature, BYTE *trans_id, token *argument, CR_RSA_TYPE rsa_type, rsa_key *key, CR_AUTH_CODE hash_code) ; /* The following function uses CRT for performing RSA signing operations on the argument, and returns the signature. The 'argument' is in the octet string format. This function performs PKCS#1 encoding operations, as specified by rsa_type, to generate the signature. The hash_code value depends on the the protocol requesting the signing. The trans_id is used for debug/error tracking and is optional (can be NULL) */ RC CR_rsa_sign_crt(token *signature, BYTE *trans_id, token *argument, CR_RSA_TYPE rsa_type, rsa_crt_key *key, CR_AUTH_CODE hash_code) ; /* The following function is used for performing RSA signature verification operations on the 'signature', and returns the message. The received signature is in the octet string format. This function performs PKCS#1 operation, as specified by rsa_type, to generate the message signed by sender. The rsa_key->exponent is the public key 'e' component of the sender. The computed message is in the octet string format. This function also compares the computed 'message' with the original message to verify the signature. This function returns SUCCESS if the signatures are valid, and FAILURE otherwise. The trans_id is used for debug/error tracking and is optional (can be NULL) */ RC CR_rsa_verify(token *message, BYTE *trans_id, token *signature, CR_RSA_TYPE rsa_type, rsa_key *key, CR_AUTH_CODE hash_code) ; /* The following function is used for performing RSA public key decrypt operation, which will be used by external RSA_verify function. The received signature is in the octet string format. This function performs PKCS#1 mod_exp operation, to generate the original encoded message which was signed by sender. This function returns the PKCS#1 encoded original message in sign_decrypted token. */ RC CR_rsa_public_decrypt(token *sign_decrypted, BYTE *trans_id, token *signature, rsa_key *key) ; /* The following function is used for signing the SHA-1 hashed message. If the passed random number pointer is NULL, then the library internally generates a random number. This function returns the signature components 'r' and 's' in dsa_sign struct. The trans_id is used for debug/error tracking and is optional (can be NULL) */ RC CR_dsa_signature(dsa_sign_key *signature, BYTE *trans_id, token *msg_hash, dsa_key *key, token *random_k) ; /* The following function is used for verifying the DSA signatures on the message (hash_msg_recd). The received signatures that were used to sign this hash_msg_recd must be passed. This returns a value indicating if the signatures match (RC=SUCCESS) or do not match (RC=FAILURE). The trans_id is used for debug/error tracking and is optional (can be NULL) */ RC CR_dsa_verify(BYTE *trans_id, token *msg_hash_recd, dsa_sign_key *signature_recd, dsa_key *key) ; /************************************************************************** Symmetric Crypto Functions ***************************************************************************/ /* The following function is used for performing encryption operations on the data (plaintext). The trans_id identifies key which contains information, internal to the library, about the cipher algorithm. */ RC CR_encrypt(token *ciphertext, BYTE *trans_id, token *plaintext) ; /* The following function is used for performing decryption operations on the data (ciphertext). The trans_id identifies key which contains information, internal to the library, about the cipher algorithm. */ RC CR_decrypt(token *plaintext, BYTE *trans_id, token *ciphertext) ; /* The following function performs entire SSLv3 outbound record layer processing. The processing steps include SSLv3 record layer MAC generation (ignoring version field), padding (for block ciphers only), and encryption. The sequence number is a 64-bit number that the application must pass as an 8-byte string. */ RC CR_encrypt_sslv3_record(token *sslv3_ciphertext, BYTE *trans_id, BYTE *seq_num, token *sslv3_compressed) ; /* The following function performs entire SSLv3 inbound record layer processing. The processing steps include SSLv3 record layer decryption, MAC generation w/o version field and verification, verification and removal of padding (for block ciphers only), and update length field. The sequence number is a 64-bit number that the application must pass as an 8 Byte string. RC=SUCCESS indicates that there was no error in decrypting the record, and RC=FAILURE indicates an error (MAC verify, Seq Number check, Pad verify, or system error) occurred while processing the record. */ RC CR_decrypt_sslv3_record(token *sslv3_compressed, BYTE *trans_id, BYTE *seq_num, token *sslv3_ciphertext) ; /* The following function performs entire TLS1.0 outbound record layer processing. The processing steps include TLS1.0 record layer MAC generation (using HMAC) padding (for block ciphers only), and encryption. The sequence number is a 64-bit number that the application must pass as an 8-byte string. */ RC CR_encrypt_tlsv1_record(token *tlsv1_ciphertext, BYTE *trans_id, BYTE *seq_num, token *tlsv1_compressed) ; /* The following function performs entire TLS1.0 inbound record layer processing. The processing steps include TLS1.0 record layer decryption, MAC generation and verification, verification and removal of padding (for block ciphers only), and update length field. The sequence number is a 64-bit number that the application must pass as an 8 Byte string. RC=SUCCESS indicates that there was no error in decrypting the record, and RC=FAILURE indicates an error (MAC verify, Seq Number check, Pad verify, or system error) occurred while processing the record. */ RC CR_decrypt_tlsv1_record(token *tlsv1_compressed, BYTE *trans_id, BYTE *seq_num, token *tlsv1_ciphertext) ; /* The following function performs entire SSLv3 outbound record layer processing, which has a key passed along with the record. This function is a combination of the CR_insert_sslv3_key() and CR_encrypt_sslv3_record(), which performs these 2 tasks using a single ioctl command. This function will also update the SA and chip numbers in the library. input: trans_id - The transaction identifier that identifies the key and cipher/hash, inside the library sslv3_compressed - The compressed SSL record data and size seq_num - The sequence number with MSB in byte 0 location update_key - Whether the IVs/StateVars for ciphers be read back. For ARCFOUR, the state array, state_x, state_y will be updated. For (T)DES CBC, the original IV will be updated with that read from CR7020 DDR. output: sslv3_ciphertext - The encrypted/HMACed SSLv3 record data and size */ RC CR_encrypt_sslv3_with_key( token *sslv3_ciphertext, BYTE *trans_id, BYTE *seq_num, token *sslv3_compressed, INT32 key_struct_address, BYTE update_key ) ; /* The following function performs entire TLS1.0 outbound record layer processing, which has a key passed along with the record. This function is a combination of the CR_insert_tlsv1_key() and CR_encrypt_tlsv1_record(), which performs these 2 tasks using a single ioctl command. This function will also update the SA and chip numbers in the library. input: trans_id - The transaction identifier that identifies the key and cipher/hash, inside the library tlsv1_compressed - The compressed TLS record data and size seq_num - The sequence number with MSB in byte 0 location update_key - Whether the IVs/StateVars for ciphers be read back. For ARCFOUR, the state array, state_x, state_y will be updated. For (T)DES CBC, the original IV will be updated with that read from CR7020 DDR. output: tlsv1_ciphertext - The encrypted/HMACed SSLv3 record data and size */ RC CR_encrypt_tlsv1_with_key( token *tlsv1_ciphertext, BYTE *trans_id, BYTE *seq_num, token *tlsv1_compressed, INT32 key_struct_address, BYTE update_key ) ; /* Encrypts an IPsec packet using the ESP protocol. The input token * esp_plaintext should contain the outer IP header, followed by 8 bytes * for the SPI & sequence number, followed by the data packet, followed by * the 1 byte for the next header. oheader_len should be set to the length * of the outer IP header in bytes. The returned esp_ciphertext will be * filled with the encrypted packet, padding, and authentication MAC if * used. */ RC CR_encrypt_ipsec_esp( token *esp_ciphertext, BYTE *trans_id, token *esp_plaintext, unsigned int oheader_len ); /* Decrypts an IPsec packet using the ESP protocol. The input token * esp_ciphertext should contain the outer IP header, followed by 8 bytes * for the SPI & sequence number, followed by the IV & encrypted data * packet (including pad & next header bytes), followed by an optional * MAC. The oheader_len should be set to the length of the outer header in * bytes. The MAC, if used, is verified and discarded and the payload * decrypted. The outer header, next header, and IV will be either returned * or stripped depending on the SA flags used when initializing the * transaction. */ RC CR_decrypt_ipsec_esp( token* esp_plaintext, BYTE* trans_id, token* esp_ciphertext, unsigned int oheader_len ); /* Computes the MAC for an IPsec packet using the AH protocol. The input * token ah_plaintext should contain the outer IP header followed by * 8 bytes for the SPI and sequence number followed by the packet. * The oheader_len should contain the length of the outer header in * bytes. The MAC is computed and returned in ah_ciphertext. Note that * the payload data itself is not returned. Also note that any mutable * fields in the outer IP header must be zeroed out before calling this * function. */ RC CR_encrypt_ipsec_ah( token* ah_ciphertext, BYTE* trans_id, token* ah_plaintext, unsigned int oheader_len ); /* Verifies the MAC for an IPsec packet using the AH protocol. The input * token ah_ciphertext should contain the outer IP header followed by 8 * bytes for the SPI and sequence number followed by the MAC followed by * the packet. The oheader_len should contain the length of the outer header * in bytes. The MAC is verified and SUCCESS returned if it is valid. Note * that no data is returned. Also note that any mutable fields in the outer * IP header must be zeroed out before calling this function. */ RC CR_decrypt_ipsec_ah( BYTE* trans_id, token* ah_ciphertext, unsigned int oheader_len ); /* This function is used for performing hash/HMAC operations on the argument. This function requires an algorithm auth_code. The secret key(s) for HMAC were passed in separately, if trans_id is not NULL. If trans_id is NULL, then the secret_key must be valid for HMAC. Definition: HMAC_hash(secret_key, argument) For performing hash operation without secret_key: trans_id will be NULL, and secret_key will be NULL. For hash operation with secret_key, the key must be part of the argument(s), and trans_id must be NULL, and secret_key components must be NULL. inner_argument will be NULL for single hash and HMAC operations. outer_argument will be used for single, double, and HMAC operations. */ RC CR_authenticate(token *digest, BYTE *trans_id, CR_AUTH_CODE auth_code, token *inner_argument, token *outer_argument, hmac_key *secret_key) ; /* The following function will be used for performing the Hash_Init operation for SHA1 and MD5. This function will internally create a context for a new hash operation series and associate it with the given transaction id. input: trans_id - The transaction id. auth_code - The Hash code, either SHA1 or MD5 output: context - Not used. RC must be SUCCESS */ RC CR_HashInit(BYTE *trans_id, void **context, CR_AUTH_CODE auth_code) ; /* The following function will be used for performing incremental hash operations for MD5 and SHA1. The application will pass-in the address to the cr_hash_ctx structure. This function will accumulate the passed-in data until the size exceeds 64 Bytes, in which case, this function will pass all data with a size which is a multiple of 64 to the device for processing. input: trans_id - Transaction id passed to HashInit context - Ignored previous successful call to CR_HashInit arg - The input data and size to be incrementally processed for the hash op specified in the cr_hash_ctx struct. output: RC must be SUCCESS */ RC CR_HashUpdate(BYTE *trans_id, void *context, token *arg) ; /* The following function will be used for performing the final hash operation for MD5 and SHA1. The application will pass-in the address to the cr_hash_ctx structure. This function will add necessary padding to the remaining bytes in the ctx buffer, and perform the final hash processing. This function will also cleanup the ctx data structure and the SA in the device. input: trans_id - Transaction id passed to HashInit context - Ignored output: result - The application must allocate memory (16B for MD5/20B for SHA1) for getting the final digest RC must be SUCCESS */ RC CR_HashFinal(BYTE *result, BYTE *trans_id, void *context) ; /* The following function is used for performing the Pseudo Random Function (PRF) operation on the argument (seed) and label, and setting the desired length in the result parameter. The prf output hash will be placed in result. If the trans_id is NULL, all the components of prf_key: secret, OR, idigest_md5, odigest_md5, idigest_sha1, odigest_sha1 must be valid. If trans_id is not NULL, the secret keys were passed in separately, and if passed in here, they will be ignored. Definition: PRF(secret_key,label,seed)[desired_length] */ RC CR_prf(token *result, BYTE *trans_id, token *seed, token *label, prf_key *secret_key) ; /************************************************************************** Transaction Functions ***************************************************************************/ /* The following function is used for initiating a new transaction. This function returns a pointer to the transaction identifier, if success, or NULL, if failed. */ BYTE *CR_new_transaction(void) ; /* The following function is used for removing a transaction from the system. This function requires that a valid pointer, preferably the same as returned by CR_new_transaction(), is used as the argument. This function will free the memory associated to store the trans_id value. */ RC CR_delete_transaction(BYTE *trans_id) ; /* The following function returns the SA address in Typhoon's DDR memory, corresponding to the transaction identifier that is passed into this function. */ RC CR_get_sa_address(INT32 *sa_address, BYTE *trans_id) ; /* The following function is used to upload a new key into the system. The op_code/auth_code will identify the crypto/hash algorithm for these keys. The library will use these codes to interpret the address pointer of the appropriate crypto/hash struct like des_key, aes_key, and other key structures identified in the header file. Please note that for auth_code to be used, the value of op_code must be AUTHENTICATE_OP, otherwise the value of auth_code will be ignored. Application doesn't create a key for hash operations, the library will generate those keys. The application needs to create the keys for HMAC operations only. Also, the application cannot establish keys for RSA and DSA operations. */ RC CR_insert_cipher_key(BYTE *trans_id, CR_OP_CODE op_code, CR_AUTH_CODE auth_code, INT32 key_struct_address) ; /* The following function will be used for inserting SSLv3 security parameter values into the library. The address pointer will point to the sslv3_tls_key struct. This function will cross verify the input data parameters. This security parameter struct contains all the keys necessary to perform encryption/decryption and MAC operations. */ RC CR_insert_sslv3_key(BYTE *trans_id, INT32 key_struct_address) ; /* The following function will be used for inserting TLS1.0 security parameter values into the library. The address pointer will point to the sslv3_tls_key struct. This function will cross verify the input data parameters. This security parameter struct contains all the keys necessary to perform encryption/decryption and HMAC operations. */ RC CR_insert_tls_key(BYTE *trans_id, INT32 key_struct_address) ; /* Inserts an ipsec_key into the device SA memory. If crypto_code in the * device is set or NULL then the key is inserted as an ESP packet. If * crypto_code is set to CR_AUTHENTICATE_OP then the key is inserted as * an AH packet. */ RC CR_insert_ipsec_key( BYTE* trans_id, INT32 key_struct_address ) ; /* The following function will be used for inserting the PRF keys in the library. The key_struct_address is the address of the structure prf_key */ RC CR_insert_prf_key(BYTE *trans_id, INT32 key_struct_address) ; /* The following function is used to delete a key from the system. */ RC CR_delete_key(BYTE *trans_id) ; /************************************************************************** Administrative Functions ***************************************************************************/ /* The following function will return the version number of the CR702X library. Returns the library version number in lib_ver buffer. Make sure at least 20 bytes are allocated for this buffer. */ RC CR_get_libver(BYTE *lib_ver) ; /* This function will initialize the entire software library. This means cleaning all the on-going operations, deleting all stored data, freeing all allocated memory, and insering intial data (as required). This function also contains (optional) error and warning file pointers. If these are NULL, then the function will create the files identified in this header file */ RC CR_init_lib(FILE *error_file, FILE *warning_file) ; /* This function will be called to close all existing devices that the library is using. In addition, all unused data structures. */ RC CR_close_lib(void) ; /* This function will set the endian-ness of the library to BIG, LITTLE, or NETWORK endian order. This means that the library will accept/interpret data from the application in the order that is set by this function. By default, the library is set to BIG endian. */ void CR_set_endian(CR_ENDIAN endian) ; /* The following function is used for testing the random number generator. The randomizer runs the FIPS tests on a sample of random data, which is generated internally, and returns a SUCCESS if the random data passed the FIPS test, and FAILURE, otherwise. */ RC CR_test_random(void) ; /* This function will be used for resetting the various sub-components of the device driver. */ RC CR_init_random(void) ; /* The following function deletes all on-going transactions in the library, and resets the transaction related data structures */ RC CR_init_transaction(void) ; /* The following function will fill the stats table in the library, and add the key names to the table. This function will be called a single time, as part of the library initialization. The stat table will be updated by the CR_get_stat() function. */ RC CR_init_stat(void) ; /* The following function is used for capturing the stats from the driver, and returning the data to the calling application. The library allocated static memory structure (stat table) at init time (in the function CR_init_stat()), which is cleaned up when program ends. Input: None Output: cr_stat_table: Pointer to the stat table in library memory. Returns NULL pointer on FAILURE. */ cr_stat_table *CR_get_stat(void) ; /* The following function is used for obtaining device information from the driver. Input: None Output: cr_device_info: Pointer to the device info structure in library. memory. Returns NULL pointer on FAILURE. */ cr_device_info *CR_get_device_info(void) ; /* The following function is used to perform a selftest on the CR7020/CR7120 device. Input: None Output: SUCCESS if selftest passed or FAILURE, otherwise. */ RC CR_perform_selftest( void ); /*************************************************************************** END OF APIs ***************************************************************************/ #ifdef __cplusplus } #endif #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cr_stdll/tok_struct.h.in0000640000175000017500000004143011327631345022213 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2002 */ /*************************************************************************** Change Log ========== 8/27/02 Kapil Sood (kapil@corrent.com) Added token interface for the Corrent S2000/S2010/S3500 PCI-X based crypto accelerator cards. 4/25/03 Kapil Sood (kapil@corrent.com) Added DH key pair generation and DH shared key derivation functions. ****************************************************************************/ // SAB FIXME need to figure out a better way... // // to get the variant dependency out #ifndef __TOK_STRUCT_H #define __TOK_STRUCT_H #include #include "tok_spec_struct.h" // #define PK_LITE_DIR "/etc/pkcs11/lite" // // #define PK_DIR PK_LITE_DIR // #define SUB_DIR "lite" // // // #define DBGTAG "ICA_STDLL_Debug" // // // token_spec_t token_specific = { "@DB_PATH@/crtok", "crtok", "CR_STDLL_Debug", &token_specific_init, &tok_slot2local, &token_rng, &token_specific_session, &token_specific_final, &token_specific_des_key_gen, &token_specific_des_ecb, &token_specific_des_cbc, &token_specific_tdes_ecb, &token_specific_tdes_cbc, &token_specific_rsa_decrypt, &token_specific_rsa_encrypt, &token_specific_rsa_generate_keypair, // DH &token_specific_dh_pkcs_derive, &token_specific_dh_pkcs_key_pair_gen, // SHA1 NULL, NULL, NULL, // SHA256 NULL, NULL, NULL, /* SHA-384 */ NULL, NULL, NULL, /* SHA-512 */ NULL, NULL, NULL, #ifndef NOAES // AES &token_specific_aes_key_gen, &token_specific_aes_ecb, &token_specific_aes_cbc, #endif &token_specific_get_mechanism_list, &token_specific_get_mechanism_info }; #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cr_stdll/cr_specific.c0000640000175000017500000016150511327631345021657 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT Corrent Corp. 2002, 2003 */ /*************************************************************************** Change Log ========== 5/19/03 Kapil Sood (kapil@corrent.com) Added support for CKA_VALUE_BITS for DH 4/25/03 Kapil Sood (kapil@corrent.com) Added DH key pair generation and DH shared key derivation functions. 8/27/02 Kapil Sood (kapil@corrent.com) Added token interface for the Corrent S2000/S2010/S3500 PCI-X based crypto accelerator cards. ****************************************************************************/ #include #include // for memcmp() et al #include #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "args.h" #include "errno.h" #include "tok_specific.h" #include #include #include #include #include #include #include #include #include "typhoon.h" #include "tok_struct.h" typedef unsigned int uint32_t; int crfd ; pthread_mutex_t rngmtx = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t nextmutex = PTHREAD_MUTEX_INITIALIZER; unsigned int rnginitialized=0; int CR_MAX_MODULUS_SIZE_BITS = 2048 ; int CR_MAX_MODULUS_SIZE_BYTES = 256 ; CK_CHAR manuf[] = "Corrent Corp."; CK_CHAR model[] = "S3500/S2000" ; CK_CHAR descr[] = "PKCS#11 Corrent token"; CK_CHAR label[] = "Linux PKCS#11 "; CK_RV token_specific_session(CK_SLOT_ID slotid) { return CKR_OK; } CK_RV token_rng(CK_BYTE *output, CK_ULONG bytes) { token rand_num ; RC rc ; rand_num.p_data = (BYTE *) output ; rand_num.data_size = bytes ; rc = CR_get_random(&rand_num, (INT32) bytes) ; if (rc != SUCCESS) { st_err_log(11, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } #if 0 int ranfd; int rlen,totallen=0; ranfd = open("/dev/urandom",O_RDONLY); if (ranfd >= 0 ){ do { rlen = read(ranfd,output+totallen,bytes-totallen); totallen += rlen; } while( totallen < bytes); return CKR_OK; } else { return CKR_FUNCTION_FAILED; } #endif /* if 0 */ } // convert pkcs slot number to local representation int tok_slot2local(CK_SLOT_ID snum) { return 1; } CK_RV token_specific_init(char * Correlator,CK_SLOT_ID SlotNumber) { crfd = CR_init_lib(NULL, NULL); return CKR_OK; } CK_RV token_specific_final() { CR_close_lib(); return CKR_OK; } CK_RV token_specific_des_key_gen(CK_BYTE *des_key,CK_ULONG len) { // Nothing different to do for DES or TDES here as this is just // random data... Validation handles the rest rng_generate(des_key,len); // we really need to validate the key for parity etc... // we should do that here... The caller validates the single des keys // against the known and suspected poor keys.. return CKR_OK; } // convert from the local PKCS11 template representation to // the underlying requirement // returns the pointer to the local key representation // void * rsa_convert_public_key( OBJECT *key_obj ) { CK_BBOOL rc; CK_ATTRIBUTE *modulus = NULL; CK_ATTRIBUTE *pub_exp = NULL; rsa_key *rsa_pub_key; token *t_modulus, *t_exponent ; rc = template_attribute_find( key_obj->template, CKA_MODULUS, &modulus ); rc &= template_attribute_find( key_obj->template, CKA_PUBLIC_EXPONENT, &pub_exp ); if (rc == FALSE) return NULL; rsa_pub_key = (rsa_key *) create_rsa_key(modulus->ulValueLen, pub_exp->ulValueLen); if (rsa_pub_key == NULL) return NULL; memcpy(rsa_pub_key->modulus->p_data, modulus->pValue, modulus->ulValueLen) ; memcpy(rsa_pub_key->exponent->p_data, pub_exp->pValue, pub_exp->ulValueLen) ; rsa_pub_key->modulus->data_size = modulus->ulValueLen; rsa_pub_key->exponent->data_size = pub_exp->ulValueLen; return (void *)rsa_pub_key; } void * rsa_convert_private_key(OBJECT *key_obj) { CK_ATTRIBUTE * modulus = NULL; CK_ATTRIBUTE * priv_exp = NULL; CK_ATTRIBUTE * prime1 = NULL; CK_ATTRIBUTE * prime2 = NULL; CK_ATTRIBUTE * exp1 = NULL; CK_ATTRIBUTE * exp2 = NULL; CK_ATTRIBUTE * coeff = NULL; CK_BBOOL rc; rsa_crt_key *privKey; rsa_key *privKey2 ; rc = template_attribute_find( key_obj->template, CKA_MODULUS, &modulus ); rc &= template_attribute_find( key_obj->template, CKA_PRIVATE_EXPONENT, &priv_exp ); rc &= template_attribute_find( key_obj->template, CKA_PRIME_1, &prime1 ); rc &= template_attribute_find( key_obj->template, CKA_PRIME_2, &prime2 ); rc &= template_attribute_find( key_obj->template, CKA_EXPONENT_1, &exp1 ); rc &= template_attribute_find( key_obj->template, CKA_EXPONENT_2, &exp2 ); rc &= template_attribute_find( key_obj->template, CKA_COEFFICIENT, &coeff ); if ( rc == FALSE) return NULL; /* CRT operations are faster for N>1024 operations. For all other operations, perform non-CRT operations */ if (modulus->ulValueLen > 1024) { privKey = (rsa_crt_key *) create_rsa_crt_key(prime1->ulValueLen, prime2->ulValueLen, exp1->ulValueLen, exp2->ulValueLen, coeff->ulValueLen) ; if (privKey != NULL) { memcpy(privKey->prime_p->p_data, prime1->pValue, prime1->ulValueLen) ; privKey->prime_p->data_size = prime1->ulValueLen; memcpy(privKey->prime_q->p_data, prime2->pValue, prime2->ulValueLen) ; privKey->prime_q->data_size = prime2->ulValueLen; memcpy(privKey->dmp1->p_data, exp1->pValue, exp1->ulValueLen) ; privKey->dmp1->data_size = exp1->ulValueLen; memcpy(privKey->dmq1->p_data, exp2->pValue, exp2->ulValueLen) ; privKey->dmq1->data_size = exp2->ulValueLen; memcpy(privKey->iqmp->p_data, coeff->pValue, coeff->ulValueLen) ; privKey->iqmp->data_size = coeff->ulValueLen; return (void *) privKey ; } else return NULL; } else { privKey2 = (rsa_key *) create_rsa_key(modulus->ulValueLen, priv_exp->ulValueLen) ; if (privKey2 != NULL) { memcpy(privKey2->modulus->p_data, modulus->pValue, modulus->ulValueLen) ; privKey2->modulus->data_size = modulus->ulValueLen; memcpy(privKey2->exponent->p_data, priv_exp->pValue, priv_exp->ulValueLen) ; privKey2->exponent->data_size = priv_exp->ulValueLen; return (void *) privKey2 ; } else return NULL ; } return NULL; } /* end rsa_convert_private_key() */ #define RNG_BUF_SIZE 100 // This function is only required if public key cryptography // has been selected in your variant set up. // Set a mutex in this function and get a cache; // using the ICA device to get random numbers a byte at a // time is VERY slow.. Keygen is gated by this function. unsigned char nextRandom (void) { static unsigned char buffer[RNG_BUF_SIZE]; unsigned char byte; static int used = (RNG_BUF_SIZE); // protected access by the mutex pthread_mutex_lock(&nextmutex); if (used >= RNG_BUF_SIZE) { rng_generate(buffer,sizeof(buffer)); used = 0; } byte = buffer[used++]; pthread_mutex_unlock(&nextmutex); return((unsigned char)byte); } void swapper(char *s, char *d, int size) { int i=0; int j=size; for(i=0;ipValue; flag = template_attribute_find( publ_tmpl, CKA_PUBLIC_EXPONENT, &publ_exp ); if (!flag){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } // we don't support less than 1024 bit keys in the sw if (mod_bits < 512 || mod_bits > 2048) { st_err_log(19, __FILE__, __LINE__); return CKR_KEY_SIZE_RANGE; } // Because of a limition of OpenSSL, this token only supports // 3 as an exponent in RSA key generation rsa = RSA_new(); if (rsa == NULL) { st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } RSA_blinding_off(rsa); rsa = RSA_generate_key(mod_bits, three, NULL, NULL); if (rsa == NULL) { st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // Now fill in the objects.. // // modulus: n // bignum = rsa->n; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_MODULUS, ssl_ptr, BNLength, &attr ); // in bytes if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( publ_tmpl, attr ); free(ssl_ptr); // Public Exponent bignum = rsa->e; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_PUBLIC_EXPONENT, ssl_ptr, BNLength, &attr ); // in bytes if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( publ_tmpl, attr ); free(ssl_ptr); // local = TRUE // flag = TRUE; rc = build_attribute( CKA_LOCAL, &flag, sizeof(CK_BBOOL), &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( publ_tmpl, attr ); // // now, do the private key // // Cheat here and put the whole original key into the CKA_VALUE... remember // to force the system to not return this for RSA keys.. // Add the modulus to the private key information bignum = rsa->n; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_MODULUS, ssl_ptr, BNLength ,&attr ); // in bytes if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); free(ssl_ptr); // Private Exponent bignum = rsa->d; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc( BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_PRIVATE_EXPONENT, ssl_ptr, BNLength, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); free(ssl_ptr); // prime #1: p // bignum = rsa->p; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_PRIME_1, ssl_ptr, BNLength, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); free(ssl_ptr); // prime #2: q // bignum = rsa->q; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_PRIME_2, ssl_ptr, BNLength, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); free(ssl_ptr); // exponent 1: d mod(p-1) // bignum = rsa->dmp1; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_EXPONENT_1, ssl_ptr, BNLength, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); free(ssl_ptr); // exponent 2: d mod(q-1) // bignum = rsa->dmq1; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_EXPONENT_2, ssl_ptr, BNLength, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); free(ssl_ptr); // CRT coefficient: q_inverse mod(p) // bignum = rsa->iqmp; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_COEFFICIENT, ssl_ptr, BNLength, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); free(ssl_ptr); flag = TRUE; rc = build_attribute( CKA_LOCAL, &flag, sizeof(CK_BBOOL), &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); done: RSA_free(rsa); return rc; } CK_RV token_specific_rsa_generate_keypair( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ) { CK_RV rc; rc = os_specific_rsa_keygen(publ_tmpl,priv_tmpl); if (rc != CKR_OK) st_err_log(91, __FILE__, __LINE__); return rc; } CK_RV token_specific_rsa_encrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, OBJECT *key_obj ) { RC rc; CK_RV ret_val ; rsa_key *mexp; token ciphertext, plaintext ; CK_ULONG count ; mexp = (rsa_key *)rsa_convert_public_key(key_obj); if (mexp == NULL) return CKR_FUNCTION_FAILED; /* Setup the input and output Corrent tokens */ plaintext.p_data = in_data ; plaintext.data_size = in_data_len ; ciphertext.p_data = out_data ; ciphertext.data_size = in_data_len ; /* will be updated by the CR lib */ rc = CR_mod_exp_mont(&ciphertext, &plaintext, mexp->modulus, mexp->exponent) ; if ( rc == SUCCESS ) ret_val = CKR_OK; else ret_val = CKR_FUNCTION_FAILED; /* Corrent library may return results after triming leading zeros. Insert the leading zeros back and adjust length below, if necessary */ if (ciphertext.data_size < in_data_len) { memmove(&out_data[in_data_len-ciphertext.data_size], &out_data[0], ciphertext.data_size) ; memset(&out_data[0], 0, in_data_len-ciphertext.data_size) ; ciphertext.data_size = in_data_len ; } /* Free the key storage for CR format */ destroy_rsa_key((rsa_key *) mexp) ; return ret_val ; } /* end token_specific_rsa_encrypt() */ CK_RV token_specific_rsa_decrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, OBJECT *key_obj ) { CK_ATTRIBUTE *modulus ; RC rc ; CK_RV ret_val; rsa_crt_key *privKey = NULL; rsa_key *privKey2 = NULL; token ciphertext, plaintext ; INT32 count ; rc = template_attribute_find( key_obj->template, CKA_MODULUS, &modulus ); if ( rc == FALSE) return CKR_FUNCTION_FAILED; /* CRT operations are faster for N>1024 operations. For all other operations, perform non-CRT operations */ if (modulus->ulValueLen > 1024) privKey = (rsa_crt_key *)rsa_convert_private_key(key_obj); else privKey2 = (rsa_key *)rsa_convert_private_key(key_obj); if ((privKey == NULL) && (privKey2 == NULL)) return CKR_FUNCTION_FAILED; memset(out_data, 0, in_data_len) ; /* Setup the input and output Corrent tokens */ ciphertext.p_data = in_data ; ciphertext.data_size = in_data_len ; plaintext.p_data = out_data ; plaintext.data_size = in_data_len ; /* will be updated by the CR lib */ /* Based on modulus size, invoke CRT or non-CRT */ if (modulus->ulValueLen > 1024) rc = CR_mod_exp_crt(&plaintext, &ciphertext, privKey->prime_p, privKey->prime_q, privKey->dmp1, privKey->dmq1, privKey->iqmp) ; else rc = CR_mod_exp_mont(&plaintext, &ciphertext, privKey2->modulus, privKey2->exponent) ; /* Corrent library returns results after triming leading zeros. Insert the leading zeros back and adjust length below, if necessary */ if (plaintext.data_size < in_data_len) { memmove(&out_data[in_data_len-plaintext.data_size], &out_data[0], plaintext.data_size) ; memset(&out_data[0], 0, in_data_len-plaintext.data_size) ; plaintext.data_size = in_data_len ; } if ( rc == SUCCESS ) ret_val = CKR_OK; else ret_val = CKR_FUNCTION_FAILED; /* Free the key storage for CR format */ if (modulus->ulValueLen > 1024) destroy_rsa_crt_key((rsa_crt_key *) privKey) ; else destroy_rsa_key((rsa_key *) privKey2) ; return ret_val ; } /* end token_specific_rsa_decrypt() */ CK_RV token_specific_des_ecb(CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_BYTE encrypt) { CK_ULONG rc; des_key_schedule des_key2; const_des_cblock key_val_SSL, in_key_data; des_cblock out_key_data; int i,j; int ret; // Create the key schedule memcpy(&key_val_SSL, key_value, 8); des_set_key_unchecked(&key_val_SSL, des_key2); // the des decrypt will only fail if the data length is not evenly divisible // by 8 if (in_data_len % 8 ){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } // Both the encrypt and the decrypt are done 8 bytes at a time if (encrypt) { for (i=0; iulValueLen > CR_MAX_MODULUS_SIZE_BYTES) || (prime_attr->ulValueLen < 64)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Check if the CKA_VALUE_BITS attribute of the private key has been set. // If set, then check value to be less than size of prime, and use that value. // If not set, then use the value dependent on size of prime. rc = template_attribute_find( priv_tmpl, CKA_VALUE_BITS, &temp_value_bits_attr ); if (rc == FALSE) { // Randomly generate private key value priv_key_value_len = prime_attr->ulValueLen ; priv_key_value = malloc(priv_key_value_len) ; token_rng(priv_key_value, priv_key_value_len) ; // Right shift MSB of private to make it smaller than the prime p_temp = (CK_BYTE *)prime_attr->pValue ; while (p_temp[0] < priv_key_value[0]) priv_key_value[0] = priv_key_value[0] >> 1 ; } else { // Randomly generate private key value. Round off the value of CKA_VALUE_BITS // to next higher byte size for added security (and convenience/speed). priv_key_value_len = *(CK_ULONG *)temp_value_bits_attr->pValue ; if (priv_key_value_len > CR_MAX_MODULUS_SIZE_BITS) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Convert to next higher Byte size priv_key_value_len = (priv_key_value_len/8) + 1 ; // If the value set is less than 22 (180 bits), then bump the private-key // value to at least 180 bits (23 bytes)...for additional security if (priv_key_value_len < 22) priv_key_value_len = 23 ; priv_key_value = malloc(priv_key_value_len) ; token_rng(priv_key_value, priv_key_value_len) ; // If private size is same as prime size, make sure that the private // value is less than prime value. if (priv_key_value_len == prime_attr->ulValueLen) { // Right shift MSB of private to make it smaller than the prime p_temp = (CK_BYTE *)prime_attr->pValue ; while (p_temp[0] < priv_key_value[0]) priv_key_value[0] = priv_key_value[0] >> 1 ; } } // Calculate public key using: pub_key = base^priv_key mod prime // Setup the tokens with values from the input params pub_key_t.data_size = CR_MAX_MODULUS_SIZE_BYTES ; pub_key_value = malloc(pub_key_t.data_size) ; pub_key_t.p_data = pub_key_value ; priv_key_t.p_data = priv_key_value ; priv_key_t.data_size = priv_key_value_len ; prime_t.p_data = (char *)prime_attr->pValue ; prime_t.data_size = prime_attr->ulValueLen ; base_t.p_data = (char *)base_attr->pValue ; base_t.data_size = base_attr->ulValueLen ; // Perform mod exp operation rc = CR_mod_exp_mont(&pub_key_t, &base_t, &prime_t, &priv_key_t) ; if ( rc != SUCCESS ) { st_err_log(4, __FILE__, __LINE__); return CKR_FUNCTION_FAILED ; } /* Corrent library may return results after triming leading zeros. Insert the leading zeros back and adjust length below, if necessary */ if (pub_key_t.data_size < prime_t.data_size) { memmove(pub_key_value+(prime_t.data_size-pub_key_t.data_size), pub_key_value, pub_key_t.data_size) ; memset(pub_key_value, 0, prime_t.data_size-pub_key_t.data_size) ; pub_key_t.data_size = prime_t.data_size ; } pub_key_value_len = pub_key_t.data_size ; // Insert the public key component in the publ_tmpl rc = build_attribute( CKA_VALUE, pub_key_value, pub_key_value_len, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( publ_tmpl, temp_attr ); free(pub_key_value); // Insert the private key component in the priv_tmpl rc = build_attribute( CKA_VALUE, priv_key_value, priv_key_value_len, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); free(priv_key_value); // Update CKA_VALUE_BITS attribute in the private key value_bits_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); value_bits_attr->type = CKA_VALUE_BITS; value_bits_attr->ulValueLen = sizeof(CK_ULONG); value_bits_attr->pValue = (CK_BYTE *)value_bits_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_bits_attr->pValue = 8*priv_key_value_len; template_update_attribute( priv_tmpl, value_bits_attr ); // Add prime and base to the private key template rc = build_attribute( CKA_PRIME,(char *)prime_attr->pValue, prime_attr->ulValueLen, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); rc = build_attribute( CKA_BASE,(char *)base_attr->pValue, base_attr->ulValueLen, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); return CKR_OK ; } /* end token_specific_dh_key_pair_gen() */ MECH_LIST_ELEMENT mech_list[] = { { CKM_RSA_PKCS_KEY_PAIR_GEN, 512, 2048, CKF_HW | CKF_GENERATE_KEY_PAIR }, #if !(NODSA) { CKM_DSA_KEY_PAIR_GEN, 512, 1024, CKF_HW | CKF_GENERATE_KEY_PAIR }, #endif { CKM_DES_KEY_GEN, 8, 8, CKF_HW | CKF_GENERATE }, { CKM_DES3_KEY_GEN, 24, 24, CKF_HW | CKF_GENERATE }, #if !(NOCDMF) { CKM_CDMF_KEY_GEN, 0, 0, CKF_HW | CKF_GENERATE }, #endif { CKM_RSA_PKCS, 512, 2048, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP | CKF_SIGN | CKF_VERIFY | CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER }, #if !(NOX509) { CKM_RSA_X_509, 512, 2048, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP | CKF_SIGN | CKF_VERIFY | CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER }, #endif #if !(NOMD2) { CKM_MD2_RSA_PKCS, 512, 2048, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NOMD5) { CKM_MD5_RSA_PKCS, 512, 2048, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NOSHA1) { CKM_SHA1_RSA_PKCS, 512, 2048, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NODSA) { CKM_DSA, 512, 1024, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif /* Begin code contributed by Corrent corp. */ #if !(NODH) { CKM_DH_PKCS_DERIVE, 512, 2048, CKF_HW | CKF_DERIVE }, { CKM_DH_PKCS_KEY_PAIR_GEN, 512, 2048, CKF_HW | CKF_GENERATE_KEY_PAIR }, #endif /* End code contributed by Corrent corp. */ { CKM_DES_ECB, 8, 8, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_DES_CBC, 8, 8, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_DES_CBC_PAD, 8, 8, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, #if !(NOCDMF) { CKM_CDMF_ECB, 0, 0, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_CDMF_CBC, 0, 0, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, #endif { CKM_DES3_ECB, 24, 24, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_DES3_CBC, 24, 24, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_DES3_CBC_PAD, 24, 24, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, #if !(NOSHA1) { CKM_SHA_1, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_SHA_1_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SHA_1_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SHA256, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_SHA256_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SHA256_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NOMD2) { CKM_MD2, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_MD2_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_MD2_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NOMD5) { CKM_MD5, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_MD5_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_MD5_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif { CKM_SSL3_PRE_MASTER_KEY_GEN, 48, 48, CKF_HW | CKF_GENERATE }, { CKM_SSL3_MASTER_KEY_DERIVE, 48, 48, CKF_HW | CKF_DERIVE }, { CKM_SSL3_KEY_AND_MAC_DERIVE, 48, 48, CKF_HW | CKF_DERIVE }, { CKM_SSL3_MD5_MAC, 384, 384, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SSL3_SHA1_MAC, 384, 384, CKF_HW | CKF_SIGN | CKF_VERIFY }, #if !(NOAES) { CKM_AES_KEY_GEN, 16, 32, CKF_HW }, { CKM_AES_ECB, 16, 32, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_AES_CBC, 16, 32, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_AES_MAC, 16, 32, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_AES_MAC_GENERAL, 16, 32, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_AES_CBC_PAD, 16, 32, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, #endif #if !(NORIPE) { CKM_RIPEMD128, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_RIPEMD128_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_RIPEMD128_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_RIPEMD160, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_RIPEMD160_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_RIPEMD160_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif }; CK_ULONG mech_list_len = (sizeof(mech_list) / sizeof(MECH_LIST_ELEMENT)); CK_RV token_specific_get_mechanism_list(CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount) { int rc; /* common/mech_list.c */ rc = ock_generic_get_mechanism_list(pMechanismList, pulCount); return rc; } CK_RV token_specific_get_mechanism_info(CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo) { int rc; /* common/mech_list.c */ rc = ock_generic_get_mechanism_info(type, pInfo); return rc; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/cr_stdll/Makefile.am0000640000175000017500000000322711327631345021272 0ustar jfjfnobase_lib_LTLIBRARIES = opencryptoki/stdll/libpkcs11_cr.la opencryptoki_stdll_libpkcs11_cr_la_LDFLAGS = $(LCRYPTO) $(CR_LIB_DIRS) \ -nostartfiles -shared -Wl,-Bsymbolic -Wl,-soname,PKCS11_BC.so.1 -lc \ -lpthread -lsocketarmor -ldl -lcrypto VARIANT = -DSHALLOW=0 -DSWTOK=1 -DLITE=0 # Not all versions of automake observe libname_CFLAGS opencryptoki_stdll_libpkcs11_cr_la_CFLAGS = -DSPINXPL -DDEV \ -D_THREAD_SAFE -fPIC $(VARIANT) -DNOCDMF -DNOMD2 -DNODSA -DDEBUGON # Not all versions of automake observe libname_CFLAGS AM_CFLAGS = -DSPINXPL -DDEV -D_THREAD_SAFE -fPIC $(VARIANT) -DNOCDMF \ -DNOMD2 -DNODSA -DDEBUGON -DSTDLL_NAME=\"crtok\" opencryptoki_stdll_libpkcs11_cr_la_SOURCES = ../common/asn1.c \ ../common/cert.c ../common/hwf_obj.c ../common/dp_obj.c \ ../common/data_obj.c ../common/decr_mgr.c ../common/dig_mgr.c \ ../common/encr_mgr.c ../common/globals.c ../common/loadsave.c \ ../common/key.c ../common/key_mgr.c ../common/mech_des.c \ ../common/mech_des3.c ../common/mech_dh.c ../common/mech_md5.c \ ../common/mech_md2.c ../common/mech_rng.c ../common/mech_rsa.c \ ../common/mech_sha.c ../common/mech_ssl3.c ../common/new_host.c \ ../common/obj_mgr.c ../common/object.c ../common/sess_mgr.c \ ../common/sign_mgr.c ../common/template.c ../common/utility.c \ ../common/verify_mgr.c ../common/log.c ../common/mech_list.c \ cr_specific.c INCLUDES = $(CR_INC_DIRS) -I/usr/include \ -I. -I../../../include/pkcs11/stdll -I../../../include/pkcs11 \ -I../common -I../../../ica/inc -I../../../../ica/include \ -I.. -I../../../../ica/src/inc install-data-local: cd $(DESTDIR)/$(libdir)/opencryptoki/stdll && rm -f PKCS11_CR.so && \ ln -sf libpkcs11_cr.so PKCS11_CR.so opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/methods/0000751000175000017500000000000011327631345017067 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/lib/pkcs11/methods/4758_status/0000751000175000017500000000000011327631345021101 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/lib/pkcs11/methods/4758_status/4758_status.c0000751000175000017500000005351111327631345023267 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #include #include #include "unistd.h" #include "4758_status.h" #include "pkcs11types.h" #include "defs.h" #include "scc_host.h" CK_ULONG long_reverse( CK_ULONG x ) { CK_ULONG rev; CK_BYTE *p1 = (CK_BYTE *)&x; CK_BYTE *p2 = (CK_BYTE *)&rev; p2[3] = p1[0]; p2[2] = p1[1]; p2[1] = p1[2]; p2[0] = p1[3]; return rev; } #define HTOCL(Z) (Z) #define CTOHL(Z) (Z) CK_RV communicate( CK_ULONG slot_id, CK_ULONG cmd_id, CK_VOID_PTR pReq, CK_ULONG req_len, CK_VOID_PTR pRep, CK_ULONG_PTR repl_len, CK_BYTE_PTR pOut, CK_ULONG out_len, CK_BYTE_PTR pIn, CK_ULONG in_len ) { union { double d; CK_BYTE b[1024]; } alignedBuffers[2]; LEEDS_REQUEST * send_packet = (LEEDS_REQUEST *)&(alignedBuffers[0]); LEEDS_REPLY * recv_packet = (LEEDS_REPLY *)&(alignedBuffers[1]); CK_BYTE * ptr = NULL; CK_BYTE * in_buf = pIn; CK_BYTE * out_buf = pOut; CK_ULONG send_len, recv_len = 0; CK_ULONG in_buf_len = in_len, out_buf_len = out_len; CK_RV rc = CKR_OK; sccAdapterNumber_t num_adapters; sccAgentID_t leeds_id; sccAdapterHandle_t adapter_handle; sccRB_t request_block; memset( &leeds_id, 0, sizeof(leeds_id) ); leeds_id.DeveloperID[0] = PKCS_11_DEVELOPER_ID; leeds_id.DeveloperID[1] = 0x00; memcpy( leeds_id.ProgramID, PKCS_11_PRG_ID, sizeof(leeds_id.ProgramID) ); leeds_id.Version[0] = PKCS_11_VERSION; leeds_id.Instance[0] = PKCS_11_INSTANCE; leeds_id.Queue[0] = PKCS_11_QUEUE; rc = sccOpenAdapter( slot_id, &adapter_handle ); if (rc) exit (SEG2_NOT_RUNABLE); if (repl_len == NULL) return CKR_GENERAL_ERROR; if (pReq == NULL && req_len != 0) return CKR_FUNCTION_FAILED; if (pRep == NULL && *repl_len != 0) return CKR_FUNCTION_FAILED; if (pOut == NULL && out_len != 0) return CKR_FUNCTION_FAILED; if (pIn == NULL && in_len != 0) return CKR_FUNCTION_FAILED; // ensure the buffer lengths are multiples of 4 and that the buffers we // have are big enough // send_len = (sizeof(LEEDS_REQUEST) + req_len + 3) & ~3; recv_len = (sizeof(LEEDS_REPLY) + *repl_len + 3) & ~3; if (send_len > sizeof(alignedBuffers[0])) send_packet = (LEEDS_REQUEST *)malloc( send_len ); if (recv_len > sizeof(alignedBuffers[1])) recv_packet = (LEEDS_REPLY *)malloc( recv_len ); if ((out_len & 3) != 0) { out_buf_len = (out_len + 3) & ~3; out_buf = (CK_BYTE *)malloc( out_buf_len ); memcpy( out_buf, pOut, out_len ); } if ((in_len & 3) != 0) { in_buf_len = (in_len + 3) & ~3; in_buf = (CK_BYTE *)malloc( in_buf_len ); } // If we couldn't allocate something we needed, die // if (send_packet == NULL || recv_packet == NULL || (out_buf == NULL && out_buf_len != 0) || (in_buf == NULL && in_buf_len != 0)) { if (send_len > sizeof(alignedBuffers[0]) && send_packet != NULL) free( send_packet ); if (recv_len > sizeof(alignedBuffers[1]) && recv_packet != NULL) free( recv_packet ); if (out_buf != NULL && out_buf != pOut) free( out_buf ); if (in_buf != NULL && in_buf != pIn) free( in_buf ); return CKR_HOST_MEMORY; } memset( send_packet, 0x0, send_len ); memset( recv_packet, 0x0, recv_len ); memset( &request_block, 0x00, sizeof(request_block) ); memcpy( &request_block.AgentID, &leeds_id, sizeof(leeds_id) ); send_packet->pid = HTOCL( 0); send_packet->req_len = HTOCL( req_len ); send_packet->repl_max[0] = HTOCL( *repl_len ); send_packet->repl_max[1] = HTOCL( in_len ); send_packet->repl_max[2] = 0; // we don't currently use these buffers send_packet->repl_max[3] = 0; // but maybe in the future... // Skip request header // ptr = (CK_BYTE *)send_packet + sizeof(LEEDS_REQUEST); if (pReq != NULL) memcpy( ptr, pReq, req_len ); request_block.pOutBuffer[0] = (unsigned char *)send_packet; request_block.pInBuffer [0] = (unsigned char *)recv_packet; request_block.pOutBuffer[1] = (unsigned char *)out_buf; request_block.pInBuffer [1] = (unsigned char *)in_buf; // I don't know if the following needs to be adjusted for endianness or not // (the device driver could in principle take care of the swapping) // request_block.UserDefined = cmd_id; request_block.OutBufferLength[0] = send_len; request_block.InBufferLength [0] = recv_len; request_block.OutBufferLength[1] = out_buf_len; request_block.InBufferLength [1] = in_buf_len; // send the request synchronously to the adapter // rc = sccRequest( adapter_handle, &request_block ); if (rc != 0) { rc = CKR_FUNCTION_FAILED; goto error; } // handle the replies // if ((CTOHL(recv_packet->repl_len[0]) > *repl_len) || (CTOHL(recv_packet->repl_len[1]) > in_len)) { rc = CKR_FUNCTION_FAILED; goto error; } *repl_len = CTOHL(recv_packet->repl_len[0]); // Skip reply header // ptr = (CK_BYTE *)recv_packet + sizeof(LEEDS_REPLY); if (pRep != NULL) memcpy( pRep, ptr, CTOHL(recv_packet->repl_len[0]) ); if (in_buf != pIn) memcpy( pIn, in_buf, CTOHL(recv_packet->repl_len[1]) ); // This may need to be swapped... // rc = request_block.Status; printf("communicate rc in req block %x \n",rc); error: if (send_len > sizeof(alignedBuffers[0])) free( send_packet ); if (recv_len > sizeof(alignedBuffers[1])) free( recv_packet ); if (in_buf != pIn) free( in_buf ); if (out_buf != pOut) free( out_buf ); return rc; } int main (int argc, char *argv[]){ CK_CHAR_PTR card, tempc; int dev_minor = 0; int c, errflag = 0; while ((c = getopt (argc, argv, "c:")) != (-1)) { switch (c){ case 'c': /* a specific card (slot) is specified */ card = (CK_CHAR_PTR) malloc (strlen(optarg)); memcpy(card, optarg, strlen(optarg)); break; default: errflag++; break; } } if (errflag != 0) return INVALID_PARAMS; if (strlen(card) < 6) return INVALID_PARAMS; else tempc = (char *)malloc(strlen(card)); sscanf(card, "crypto%s", tempc); dev_minor = atoi(tempc); free (tempc); { CK_ULONG data = 0; CK_ULONG req_len, repl_len = 0; int rc; req_len = sizeof(data); if (rc = communicate(dev_minor, CHECK_DEEP, &data, req_len, NULL, &repl_len, NULL, 0, NULL, 0) != CKR_OK) if (rc = communicate(dev_minor, CHECK_SHALLOW, &data, req_len, NULL, &repl_len, NULL, 0, NULL, 0) != CKR_OK) { printf("return from communicate 2 %x \n",rc); return PKCS11_NOT_LOADED; }else return LEEDS2_SHALLOW; else return LEEDS2_DEEP; } } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/methods/4758_status/defs.h0000751000175000017500000004034511327631345022204 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/lib/pkcs11/methods/4758_status/defs.h,v 1.2 2005/02/22 20:48:08 mhalcrow Exp $ */ // /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ // File: defs.h // // Contains various definitions needed by both the host-side // and coprocessor-side code. // #ifndef _DEFS_H #define _DEFS_H #pragma options align=packed #pragma pack(1) #ifndef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif // the following constants are used for sccSignOn // #define PKCS_11_PRG_ID "pkcs11 2.01" #define PKCS_11_DEVELOPER_ID 0xE #define PKCS_11_VERSION 1 #define PKCS_11_INSTANCE 0 #define PKCS_11_QUEUE 0 #define LEEDS_PRG_ID_PKCS_11 "PKCS11" // the following are "boolean" attributes // #define CKA_IBM_TWEAK_ALLOW_KEYMOD 0x80000001 #define CKA_IBM_TWEAK_ALLOW_WEAK_DES 0x80000002 #define CKA_IBM_TWEAK_DES_PARITY_CHK 0x80000003 #define CKA_IBM_TWEAK_NETSCAPE 0x80000004 typedef struct _LEEDS_REQUEST { CK_ULONG pid; CK_ULONG req_len; // size of request data CK_ULONG repl_max[4]; // any command-specific request data gets appended here // } LEEDS_REQUEST; typedef struct _LEEDS_REPLY { CK_RV rc; CK_ULONG repl_len[4]; // size of data // any command-specific reply data gets appended here // } LEEDS_REPLY; #pragma pack() #pragma options align=full #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/methods/4758_status/Makefile.am0000640000175000017500000000063211327631345023136 0ustar jfjfbin_PROGRAMS=4758_status bindir=/tmp 4758_status_LDFLAGS = -ldl -lpthread -lscc 4758_status_CFLAGS = -DDEV -D_THREAD_SAFE -DDEBUG -DAPI SOURCES = 4758_status.c INCLUDES = $(CPPFLAGS) -I. -I../../../../include/pkcs11/ install-data-local: mkdir -p $(INSROOT)/usr/lib/pkcs11/methods; \ if [ $(shell uname -m) != s390x ] ;then cp 4758_status \ $(INSROOT)/usr/lib/pkcs11/methods/; fi; \ rm -f /tmp/4758*; opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/methods/4758_status/4758_status.h0000751000175000017500000003660511327631345023301 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/lib/pkcs11/methods/4758_status/4758_status.h,v 1.1 2005/01/18 16:09:00 kyoder Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #define INVALID_PARAMS 1 #define NOT_CRYPT_DEVICE 2 #define NOT_VALID_DEVICE 3 #define CLU_NOT_FOUND 4 #define SEG2_NOT_RUNABLE 5 #define SEG3_NOT_RUNABLE 6 #define PKCS11_NOT_LOADED 7 #define LEEDS2_DEEP 101 #define LEEDS2_SHALLOW 102 /* COMMUNICATE COMMAND ID's */ #define CHECK_DEEP 99999 #define CHECK_SHALLOW 1 opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/methods/Makefile.am0000640000175000017500000000010011327631345021112 0ustar jfjfif S390 SUBDIRS = else if ICC SUBDIRS = 4758_status endif endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/ica_s390_stdll/0000751000175000017500000000000011327631345020140 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/lib/pkcs11/ica_s390_stdll/ica_specific.c0000751000175000017500000026725511327631345022731 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ /* Modified for S390 by Robert Burroughs */ #include #include // for memcmp() et al #include #include #ifndef NOAES #include #endif #ifndef NODH #include #endif #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_specific.h" #include "tok_struct.h" #include "ica_api.h" // declare the adapter open handle localy ICA_ADAPTER_HANDLE adapter_handle; // Linux really does not need these so we just dummy them up // so the common code across platforms is usable... #define KEYTYPE_MODEXPO 1 #define KEYTYPE_PKCSCRT 2 CK_CHAR manuf[] = "IBM Corp."; CK_CHAR model[] = "IBM ICA "; CK_CHAR descr[] = "IBM PKCS#11 ICA token "; CK_CHAR label[] = "IBM ICA PKCS #11"; pthread_mutex_t rngmtx = PTHREAD_MUTEX_INITIALIZER; unsigned int rnginitialized=0; CK_RV token_rng(CK_BYTE *output, CK_ULONG bytes) { unsigned int rc; pthread_mutex_lock(&rngmtx); rc = ica_random_number_generate( (unsigned int) bytes, output); if (rc != 0) { pthread_mutex_unlock(&rngmtx); return CKR_GENERAL_ERROR; /* report error */ } pthread_mutex_unlock(&rngmtx); return CKR_OK; } int tok_slot2local(CK_SLOT_ID snum) { return 1; } CK_RV token_specific_init(char * Correlator,CK_SLOT_ID SlotNumber) { return ica_open_adapter(&adapter_handle); } CK_RV token_specific_final() { ica_close_adapter(adapter_handle); return CKR_OK; } // count_ones_in_byte: for use in adjust_des_key_parity_bits below CK_BYTE count_ones_in_byte(CK_BYTE byte) { CK_BYTE and_mask, // bit selector number_of_ones = 0; for (and_mask = 1; and_mask != 0; and_mask <<= 1) // for each bit, if (byte & and_mask) // if it's a one, ++number_of_ones; // count it return number_of_ones; } #define EVEN_PARITY TRUE #define ODD_PARITY FALSE // adjust_des_key_parity_bits: to conform to NIST spec for DES and 3DES keys void adjust_des_key_parity_bits(CK_BYTE *des_key, CK_ULONG key_size, CK_BBOOL parity) { CK_BYTE *des_key_byte; for (des_key_byte = des_key; des_key_byte - des_key < key_size; ++des_key_byte) // look at each byte in the key { if ((count_ones_in_byte(*des_key_byte) % 2) ^ (parity == ODD_PARITY)) { // if parity for this byte isn't what it should be, // flip the parity (least significant) bit *des_key_byte ^= 1; } } } CK_RV token_specific_des_key_gen(CK_BYTE *des_key,CK_ULONG len) { // Nothing different to do for DES or TDES here as this is just // random data... Validation handles the rest rng_generate(des_key,len); adjust_des_key_parity_bits(des_key, len, ODD_PARITY); // we really need to validate the key for parity etc... // we should do that here... The caller validates the single des keys // against the known and suspected poor keys..<< return CKR_OK; } CK_RV token_specific_des_ecb(CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_BYTE encrypt) { CK_RV rc; /* * checks for input and output data length and block sizes * are already being carried out in mech_des.c * so we skip those */ if ( encrypt) { rc = ica_des_encrypt(MODE_DES_ECB, (unsigned int) in_data_len, in_data, NULL, (ica_des_key_single_t *) key_value, out_data); } else { rc = ica_des_decrypt(MODE_DES_ECB, (unsigned int) in_data_len, in_data, NULL, (ica_des_key_single_t *) key_value, out_data); } if (rc != 0) { rc = CKR_FUNCTION_FAILED; st_err_log(4, __FILE__, __LINE__, __FUNCTION__); }else { *out_data_len = in_data_len; rc = CKR_OK; } return rc; } CK_RV token_specific_des_cbc(CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_BYTE *init_v, CK_BYTE encrypt) { CK_RV rc; /* * checks for input and output data length and block sizes * are already being carried out in mech_des.c * so we skip those */ if ( encrypt ){ rc = ica_des_encrypt(MODE_DES_CBC, (unsigned int) in_data_len, in_data, (ica_des_vector_t *) init_v, (ica_des_key_single_t *) key_value, out_data); } else { rc = ica_des_decrypt(MODE_DES_CBC, (unsigned int) in_data_len, in_data, (ica_des_vector_t *) init_v, (ica_des_key_single_t *) key_value, out_data); } if (rc != 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; }else { *out_data_len = in_data_len; rc = CKR_OK; } return rc; } CK_RV token_specific_tdes_ecb(CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_BYTE encrypt) { CK_RV rc; /* * checks for input and output data length and block sizes * are already being carried out in mech_des3.c * so we skip those */ if ( encrypt) { rc = ica_3des_encrypt(MODE_DES_ECB, (unsigned int) in_data_len, in_data, NULL, (ica_des_key_triple_t *) key_value, out_data); } else { rc = ica_3des_decrypt(MODE_DES_ECB, (unsigned int) in_data_len, in_data, NULL, (ica_des_key_triple_t *) key_value, out_data); } if (rc != 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; }else { *out_data_len = in_data_len; rc = CKR_OK; } return rc; } CK_RV token_specific_tdes_cbc(CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_BYTE *init_v, CK_BYTE encrypt) { CK_RV rc; /* * checks for input and output data length and block sizes * are already being carried out in mech_des3.c * so we skip those */ if ( encrypt ){ rc = ica_3des_encrypt(MODE_DES_CBC, (unsigned int) in_data_len, in_data, (ica_des_vector_t *) init_v, (ica_des_key_triple_t *) key_value, out_data); } else { rc = ica_3des_decrypt(MODE_DES_CBC, (unsigned int) in_data_len, in_data, (ica_des_vector_t *) init_v, (ica_des_key_triple_t *) key_value, out_data); } if (rc != 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; }else { *out_data_len = in_data_len; rc = CKR_OK; } return rc; } /** * Init SHA data structures */ CK_RV token_specific_sha_generic_init(DIGEST_CONTEXT *ctx, CK_MECHANISM_TYPE sha_type) { unsigned int dev_ctx_size; struct oc_sha_ctx *sc; /* For the C_DigestInit, C_Digest case, we may have already * created ctx->context... - KEY */ if (ctx->context) { sc = (struct oc_sha_ctx *)ctx->context; if(sc->dev_ctx) free(sc->dev_ctx); free(ctx->context); } /* The caller will check to see if ctx->context == NULL */ ctx->context_len = sizeof(struct oc_sha_ctx); ctx->context = malloc(sizeof(struct oc_sha_ctx)); if(ctx->context == NULL) { st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset(ctx->context, 0, ctx->context_len); sc = (struct oc_sha_ctx *)ctx->context; switch (sha_type) { case CKM_SHA_1: sc->hash_len = SHA1_HASH_SIZE; dev_ctx_size = sizeof(sha_context_t); break; case CKM_SHA256: sc->hash_len = SHA2_HASH_SIZE; dev_ctx_size = sizeof(sha256_context_t); break; case CKM_SHA384: sc->hash_len = SHA3_HASH_SIZE; dev_ctx_size = sizeof(sha512_context_t); break; case CKM_SHA512: sc->hash_len = SHA5_HASH_SIZE; dev_ctx_size = sizeof(sha512_context_t); break; default: free(ctx->context); return CKR_MECHANISM_INVALID; } sc->dev_ctx = malloc(dev_ctx_size); if(sc->dev_ctx == NULL){ free(ctx->context); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset(sc->dev_ctx, 0, dev_ctx_size); sc->message_part = SHA_MSG_PART_ONLY; return CKR_OK; } CK_RV token_specific_sha_init(DIGEST_CONTEXT *ctx) { return token_specific_sha_generic_init(ctx, CKM_SHA_1); } CK_RV token_specific_sha2_init(DIGEST_CONTEXT *ctx) { return token_specific_sha_generic_init(ctx, CKM_SHA256); } CK_RV token_specific_sha3_init(DIGEST_CONTEXT *ctx) { return token_specific_sha_generic_init(ctx, CKM_SHA384); } CK_RV token_specific_sha5_init(DIGEST_CONTEXT *ctx) { return token_specific_sha_generic_init(ctx, CKM_SHA512); } CK_RV token_specific_sha_update( DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len ) { unsigned int fill_size = 0; struct oc_sha_ctx *oc_sha_ctx = (struct oc_sha_ctx *)ctx->context; sha_context_t *ica_sha_ctx = (sha_context_t *) oc_sha_ctx->dev_ctx; oc_sha_ctx->hash_len = SHA_HASH_LENGTH; if( !ctx ) return CKR_OPERATION_NOT_INITIALIZED; if( !in_data ) return CKR_FUNCTION_FAILED; if( ctx->multi == TRUE ){ if (oc_sha_ctx->tail_len == 64) { /* Submit the filled out save buffer */ if (ica_sha1( (ica_sha_ctx->runningLength == 0 ? SHA_MSG_PART_FIRST : SHA_MSG_PART_MIDDLE), 64, oc_sha_ctx->tail, ica_sha_ctx, oc_sha_ctx->hash)) return CKR_FUNCTION_FAILED; oc_sha_ctx->tail_len = 0; } /* libICA (and SHA1) demands that if this is a PART_FIRST or a * PART_MIDDLE operation, the amount of data passed in * must be a multiple of 64 bytes. - KEY */ if( ica_sha_ctx->runningLength == 0 && oc_sha_ctx->tail_len == 0) { oc_sha_ctx->message_part = SHA_MSG_PART_FIRST; /* Just copying the last <64 bytes will not work in the case * of a user who SHA's a large chunk of data in 64 byte * pieces because we need to cache the last 64 bytes so that * we're not stuck with 0 bytes when the MSG_PART_FINAL * comes in. - KEY */ if (!(in_data_len % 64)) { oc_sha_ctx->tail_len = 64; memcpy(oc_sha_ctx->tail, in_data + in_data_len - 64, 64); in_data_len -= 64; } else oc_sha_ctx->tail_len = in_data_len & 0x3f; if(oc_sha_ctx->tail_len < 64) { in_data_len &= ~0x3f; memcpy(oc_sha_ctx->tail, in_data + in_data_len, oc_sha_ctx->tail_len); } } else if( ica_sha_ctx->runningLength == 0 && oc_sha_ctx->tail_len > 0 ) { /* Here we need to fill out the temporary tail buffer until * it has 64 bytes in it, then call ica_sha1 on that buffer. * If there weren't enough bytes passed in to fill it out, * just copy in what we can and return success without calling * ica_sha1. - KEY */ fill_size = 64 - oc_sha_ctx->tail_len; if(fill_size < in_data_len) { memcpy(oc_sha_ctx->tail + oc_sha_ctx->tail_len, in_data, fill_size); /* Submit the filled out save buffer */ if (ica_sha1(SHA_MSG_PART_FIRST, 64, oc_sha_ctx->tail, ica_sha_ctx, oc_sha_ctx->hash)) return CKR_FUNCTION_FAILED; } else { memcpy(oc_sha_ctx->tail + oc_sha_ctx->tail_len, in_data, in_data_len); oc_sha_ctx->tail_len += in_data_len; return CKR_OK; } /* We had to use 'fill_size' bytes from in_data to fill out the * empty part of save data, so adjust in_data_len */ in_data_len -= fill_size; oc_sha_ctx->tail_len = in_data_len & 0x3f; if(oc_sha_ctx->tail_len) { memcpy(oc_sha_ctx->tail, in_data + fill_size, oc_sha_ctx->tail_len); in_data_len &= ~0x3f; } } else if( ica_sha_ctx->runningLength > 0 ) { oc_sha_ctx->message_part = SHA_MSG_PART_MIDDLE; if(oc_sha_ctx->tail_len) { fill_size = 64 - oc_sha_ctx->tail_len; if(fill_size < in_data_len) { memcpy(oc_sha_ctx->tail + oc_sha_ctx->tail_len, in_data, fill_size); /* Submit the filled out save buffer */ if (ica_sha1(oc_sha_ctx->message_part, 64, oc_sha_ctx->tail, ica_sha_ctx, oc_sha_ctx->hash)) return CKR_FUNCTION_FAILED; } else { memcpy(oc_sha_ctx->tail + oc_sha_ctx->tail_len, in_data, in_data_len); oc_sha_ctx->tail_len += in_data_len; return CKR_OK; } /* We had to use some of the data from in_data to fill out the * empty part of save data, so adjust in_data_len */ in_data_len -= fill_size; /* Save the _last_ oc_sha_ctx->tail_len bytes from in_data * Rajiv - 2009 */ oc_sha_ctx->tail_len = in_data_len & 0x3f; if(oc_sha_ctx->tail_len) { in_data_len &= ~0x3f; memcpy(oc_sha_ctx->tail, in_data + in_data_len + fill_size, oc_sha_ctx->tail_len); } } else { /* This is the odd case, where we need to go ahead and * send the first X * 64 byte chunks in to be processed * and copy the last <64 byte area into the tail. -KEY */ /* Just copying the last <64 bytes will not work in the case * of a user who SHA's a large chunk of data in 64 byte * pieces because we need to cache the last 64 bytes so that * we're not stuck with 0 bytes when the MSG_PART_FINAL * comes in. - KEY */ if (!(in_data_len % 64)) { oc_sha_ctx->tail_len = 64; memcpy(oc_sha_ctx->tail, in_data + in_data_len - 64, 64); in_data_len -= 64; } else oc_sha_ctx->tail_len = in_data_len & 0x3f; if( oc_sha_ctx->tail_len < 64) { in_data_len &= ~0x3f; memcpy(oc_sha_ctx->tail, in_data + in_data_len, oc_sha_ctx->tail_len); } } } } else { /* ctx->multi == FALSE, but we've run previously. That's * our signal that this is the last part -KEY */ if( ica_sha_ctx->runningLength > 0 ) oc_sha_ctx->message_part = SHA_MSG_PART_FINAL; else oc_sha_ctx->message_part = SHA_MSG_PART_ONLY; } if( in_data_len || oc_sha_ctx->message_part == SHA_MSG_PART_FINAL ) { if (ica_sha1(oc_sha_ctx->message_part, in_data_len, in_data + fill_size,ica_sha_ctx, oc_sha_ctx->hash)) return CKR_FUNCTION_FAILED; } return CKR_OK; } CK_RV token_specific_sha2_update(DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len) { unsigned int fill_size = 0; CK_RV rv = CKR_OK; struct oc_sha_ctx *oc_sha_ctx = (struct oc_sha_ctx *)ctx->context; sha256_context_t *ica_sha2_ctx = (sha256_context_t *) oc_sha_ctx->dev_ctx; oc_sha_ctx->hash_len = SHA256_HASH_LENGTH; if (!ctx) { rv = CKR_OPERATION_NOT_INITIALIZED; goto out; } if (!in_data) { rv = CKR_FUNCTION_FAILED; goto out; } if (ctx->multi == TRUE) { if (oc_sha_ctx->tail_len == 64) { /* Submit the filled out save buffer */ if ((ica_sha256( (ica_sha2_ctx->runningLength == 0 ? SHA_MSG_PART_FIRST : SHA_MSG_PART_MIDDLE), 64, oc_sha_ctx->tail, ica_sha2_ctx, oc_sha_ctx->hash))) { rv = CKR_FUNCTION_FAILED; goto out; } oc_sha_ctx->tail_len = 0; } /* libICA and SHA256 demand that if this is a * PART_FIRST or a PART_MIDDLE operation, the amount * of data passed in must be a multiple of 64 bytes. - * KEY */ if (ica_sha2_ctx->runningLength == 0 && oc_sha_ctx->tail_len == 0) { oc_sha_ctx->message_part = SHA_MSG_PART_FIRST; /* Just copying the last <64 bytes will not * work in the case of a user who SHA's a * large chunk of data in 64 byte pieces * because we need to cache the last 64 bytes * so that we're not stuck with 0 bytes when * the MSG_PART_FINAL comes in. - KEY */ if (!(in_data_len % 64)) { oc_sha_ctx->tail_len = 64; memcpy(oc_sha_ctx->tail, (in_data + in_data_len - 64), 64); in_data_len -= 64; } else { oc_sha_ctx->tail_len = in_data_len & 0x3f; } if (oc_sha_ctx->tail_len < 64) { in_data_len &= ~0x3f; memcpy(oc_sha_ctx->tail, (in_data + in_data_len), oc_sha_ctx->tail_len); } } else if (ica_sha2_ctx->runningLength == 0 && oc_sha_ctx->tail_len > 0) { /* Here we need to fill out the temporary tail * buffer until it has 64 bytes in it, then * call ica_sha256 on that buffer. If there * weren't enough bytes passed in to fill it * out, just copy in what we can and return * success without calling ica_sha256. - KEY */ fill_size = 64 - oc_sha_ctx->tail_len; if (fill_size < in_data_len) { int rc; memcpy((oc_sha_ctx->tail + oc_sha_ctx->tail_len), in_data, fill_size); /* Submit the filled out save buffer */ if ((rc = ica_sha256(SHA_MSG_PART_FIRST, 64, oc_sha_ctx->tail,ica_sha2_ctx, oc_sha_ctx->hash))) { rv = CKR_FUNCTION_FAILED; goto out; } } else { memcpy((oc_sha_ctx->tail + oc_sha_ctx->tail_len), in_data, in_data_len); oc_sha_ctx->tail_len += in_data_len; goto out; } /* We had to use 'fill_size' bytes from * in_data to fill out the empty part of save * data, so adjust in_data_len */ in_data_len -= fill_size; oc_sha_ctx->tail_len = in_data_len & 0x3f; if (oc_sha_ctx->tail_len) { memcpy(oc_sha_ctx->tail, in_data + fill_size, oc_sha_ctx->tail_len); in_data_len &= ~0x3f; } } else if (ica_sha2_ctx->runningLength > 0) { oc_sha_ctx->message_part = SHA_MSG_PART_MIDDLE; if(oc_sha_ctx->tail_len) { fill_size = (64 - oc_sha_ctx->tail_len); if (fill_size < in_data_len) { int rc; memcpy(oc_sha_ctx->tail + oc_sha_ctx->tail_len, in_data, fill_size); /* Submit the filled out save * buffer */ rc = ica_sha256(oc_sha_ctx->message_part, 64, oc_sha_ctx->tail, ica_sha2_ctx, oc_sha_ctx->hash); if (rc) { rv = CKR_FUNCTION_FAILED; goto out; } } else { memcpy((oc_sha_ctx->tail + oc_sha_ctx->tail_len), in_data, in_data_len); oc_sha_ctx->tail_len += in_data_len; goto out; } /* We had to use some of the data from * in_data to fill out the empty part * of save data, so adjust in_data_len */ in_data_len -= fill_size; oc_sha_ctx->tail_len = in_data_len & 0x3f; if(oc_sha_ctx->tail_len) { memcpy(oc_sha_ctx->tail, (in_data + fill_size), oc_sha_ctx->tail_len); in_data_len &= ~0x3f; } } else { /* This is the odd case, where we need * to go ahead and send the first X * * 64 byte chunks in to be processed * and copy the last <64 byte area * into the tail. -KEY */ /* Just copying the last <64 bytes * will not work in the case of a user * who SHA's a large chunk of data in * 64 byte pieces because we need to * cache the last 64 bytes so that * we're not stuck with 0 bytes when * the MSG_PART_FINAL comes in. - KEY */ if (!(in_data_len % 64)) { oc_sha_ctx->tail_len = 64; memcpy(oc_sha_ctx->tail, (in_data + in_data_len - 64), 64); in_data_len -= 64; } else { oc_sha_ctx->tail_len = in_data_len & 0x3f; } if (oc_sha_ctx->tail_len < 64) { in_data_len &= ~0x3f; memcpy(oc_sha_ctx->tail, (in_data + in_data_len), oc_sha_ctx->tail_len); } } } } else { /* ctx->multi == FALSE, but we've run * previously. That's our signal that this is the last * part -KEY */ if (ica_sha2_ctx->runningLength > 0) { oc_sha_ctx->message_part = SHA_MSG_PART_FINAL; } else { oc_sha_ctx->message_part = SHA_MSG_PART_ONLY; } } if (in_data_len || (oc_sha_ctx->message_part == SHA_MSG_PART_FINAL)) { int rc; if ((rc = ica_sha256(oc_sha_ctx->message_part, in_data_len, (in_data + fill_size), ica_sha2_ctx, oc_sha_ctx->hash))) { rv = CKR_FUNCTION_FAILED; goto out; } } out: return rv; } CK_RV token_specific_sha3_update(DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len) { unsigned int fill_size = 0; CK_RV rv = CKR_OK; struct oc_sha_ctx *oc_sha_ctx = (struct oc_sha_ctx *)ctx->context; sha512_context_t *ica_sha3_ctx = (sha512_context_t *) oc_sha_ctx->dev_ctx; oc_sha_ctx->hash_len = SHA384_HASH_LENGTH; if (!ctx) { rv = CKR_OPERATION_NOT_INITIALIZED; goto out; } if (!in_data) { rv = CKR_FUNCTION_FAILED; goto out; } if (ctx->multi == TRUE) { if (oc_sha_ctx->tail_len == SHA3_BLOCK_SIZE) { int rc; /* Submit the filled out save buffer */ if ((rc = ica_sha384(((ica_sha3_ctx->runningLengthLow == 0 && ica_sha3_ctx->runningLengthHigh == 0) ? SHA_MSG_PART_FIRST : SHA_MSG_PART_MIDDLE), SHA3_BLOCK_SIZE, oc_sha_ctx->tail, ica_sha3_ctx, oc_sha_ctx->hash))) { rv = CKR_FUNCTION_FAILED; goto out; } oc_sha_ctx->tail_len = 0; } /* libICA and SHA384 demand that if this is a * PART_FIRST or a PART_MIDDLE operation, the amount * of data passed in must be a multiple of * SHA3_BLOCK_SIZE bytes. */ if (ica_sha3_ctx->runningLengthLow == 0 && ica_sha3_ctx->runningLengthHigh == 0 && oc_sha_ctx->tail_len == 0) { oc_sha_ctx->message_part = SHA_MSG_PART_FIRST; /* Just copying the last tail_len = SHA3_BLOCK_SIZE; memcpy(oc_sha_ctx->tail, (in_data + in_data_len - SHA3_BLOCK_SIZE), SHA3_BLOCK_SIZE); in_data_len -= SHA3_BLOCK_SIZE; } else { oc_sha_ctx->tail_len = (in_data_len & SHA3_BLOCK_SIZE_MASK); } if (oc_sha_ctx->tail_len < SHA3_BLOCK_SIZE) { in_data_len &= ~(SHA3_BLOCK_SIZE_MASK); memcpy(oc_sha_ctx->tail, (in_data + in_data_len), oc_sha_ctx->tail_len); } } else if (ica_sha3_ctx->runningLengthLow == 0 && ica_sha3_ctx->runningLengthHigh == 0 && oc_sha_ctx->tail_len > 0) { /* Here we need to fill out the temporary tail * buffer until it has SHA3_BLOCK_SIZE bytes * in it, then call ica_sha384 on that buffer. * If there weren't enough bytes passed in to * fill it out, just copy in what we can and * return success without calling * ica_sha384. */ fill_size = (SHA3_BLOCK_SIZE - oc_sha_ctx->tail_len); if (fill_size < in_data_len) { int rc; memcpy((oc_sha_ctx->tail + oc_sha_ctx->tail_len), in_data, fill_size); /* Submit the filled out save buffer */ if ((rc = ica_sha384(SHA_MSG_PART_FIRST, SHA3_BLOCK_SIZE, oc_sha_ctx->tail, ica_sha3_ctx, oc_sha_ctx->hash))) { rv = CKR_FUNCTION_FAILED; goto out; } } else { memcpy((oc_sha_ctx->tail + oc_sha_ctx->tail_len), in_data, in_data_len); oc_sha_ctx->tail_len += in_data_len; goto out; } /* We had to use 'fill_size' bytes from * in_data to fill out the empty part of save * data, so adjust in_data_len */ in_data_len -= fill_size; oc_sha_ctx->tail_len = (in_data_len & SHA3_BLOCK_SIZE_MASK); if (oc_sha_ctx->tail_len) { memcpy(oc_sha_ctx->tail, in_data + fill_size, oc_sha_ctx->tail_len); in_data_len &= ~(SHA3_BLOCK_SIZE_MASK); } } else if (ica_sha3_ctx->runningLengthLow > 0 || ica_sha3_ctx->runningLengthHigh > 0) { oc_sha_ctx->message_part = SHA_MSG_PART_MIDDLE; if(oc_sha_ctx->tail_len) { fill_size = (SHA3_BLOCK_SIZE - oc_sha_ctx->tail_len); if (fill_size < in_data_len) { int rc; memcpy((oc_sha_ctx->tail + oc_sha_ctx->tail_len), in_data, fill_size); /* Submit the filled out save * buffer */ rc = ica_sha384(oc_sha_ctx->message_part, SHA3_BLOCK_SIZE, oc_sha_ctx->tail, ica_sha3_ctx, oc_sha_ctx->hash); if (rc) { rv = CKR_FUNCTION_FAILED; goto out; } } else { memcpy((oc_sha_ctx->tail + oc_sha_ctx->tail_len), in_data, in_data_len); oc_sha_ctx->tail_len += in_data_len; goto out; } /* We had to use some of the data from * in_data to fill out the empty part * of save data, so adjust in_data_len */ in_data_len -= fill_size; oc_sha_ctx->tail_len = (in_data_len & SHA3_BLOCK_SIZE_MASK); if(oc_sha_ctx->tail_len) { memcpy(oc_sha_ctx->tail, (in_data + fill_size), oc_sha_ctx->tail_len); in_data_len &= ~(SHA3_BLOCK_SIZE_MASK); } } else { /* This is the odd case, where we need * to go ahead and send the first X * * SHA3_BLOCK_SIZE byte chunks in to * be processed and copy the last * tail_len = SHA3_BLOCK_SIZE; memcpy(oc_sha_ctx->tail, (in_data + in_data_len - SHA3_BLOCK_SIZE), SHA3_BLOCK_SIZE); in_data_len -= SHA3_BLOCK_SIZE; } else { oc_sha_ctx->tail_len = (in_data_len & SHA3_BLOCK_SIZE_MASK); } if (oc_sha_ctx->tail_len < SHA3_BLOCK_SIZE) { in_data_len &= ~(SHA3_BLOCK_SIZE_MASK); memcpy(oc_sha_ctx->tail, (in_data + in_data_len), oc_sha_ctx->tail_len); } } } } else { /* ctx->multi == FALSE, but we've run * previously. That's our signal that this is the last * part -KEY */ if (ica_sha3_ctx->runningLengthLow > 0 || ica_sha3_ctx->runningLengthHigh > 0) { oc_sha_ctx->message_part = SHA_MSG_PART_FINAL; } else { oc_sha_ctx->message_part = SHA_MSG_PART_ONLY; } } if (in_data_len || (oc_sha_ctx->message_part == SHA_MSG_PART_FINAL)) { int rc; if ((rc = ica_sha384(oc_sha_ctx->message_part, in_data_len, (in_data + fill_size), ica_sha3_ctx, oc_sha_ctx->hash))) { rv = CKR_FUNCTION_FAILED; goto out; } } out: return rv; } CK_RV token_specific_sha5_update(DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len) { unsigned int fill_size = 0; CK_RV rv = CKR_OK; struct oc_sha_ctx *oc_sha_ctx = (struct oc_sha_ctx *)ctx->context; SHA512_CONTEXT *ica_sha5_ctx=(SHA512_CONTEXT *)oc_sha_ctx->dev_ctx; oc_sha_ctx->hash_len = SHA512_HASH_LENGTH; if (!ctx) { rv = CKR_OPERATION_NOT_INITIALIZED; goto out; } if (!in_data) { rv = CKR_FUNCTION_FAILED; goto out; } if (ctx->multi == TRUE) { if (oc_sha_ctx->tail_len == SHA5_BLOCK_SIZE) { int rc; /* Submit the filled out save buffer */ if ((rc = ica_sha512(((ica_sha5_ctx->runningLengthLow == 0 && ica_sha5_ctx->runningLengthHigh == 0) ? SHA_MSG_PART_FIRST : SHA_MSG_PART_MIDDLE), SHA5_BLOCK_SIZE, oc_sha_ctx->tail, ica_sha5_ctx, oc_sha_ctx->hash))) { rv = CKR_FUNCTION_FAILED; goto out; } oc_sha_ctx->tail_len = 0; } /* libICA and SHA512 demand that if this is a * PART_FIRST or a PART_MIDDLE operation, the amount * of data passed in must be a multiple of * SHA5_BLOCK_SIZE bytes. */ if (ica_sha5_ctx->runningLengthLow == 0 && ica_sha5_ctx->runningLengthHigh == 0 && oc_sha_ctx->tail_len == 0) { oc_sha_ctx->message_part = SHA_MSG_PART_FIRST; /* Just copying the last tail_len = SHA5_BLOCK_SIZE; memcpy(oc_sha_ctx->tail, (in_data + in_data_len - SHA5_BLOCK_SIZE), SHA5_BLOCK_SIZE); in_data_len -= SHA5_BLOCK_SIZE; } else { oc_sha_ctx->tail_len = (in_data_len & SHA5_BLOCK_SIZE_MASK); } if (oc_sha_ctx->tail_len < SHA5_BLOCK_SIZE) { in_data_len &= ~(SHA5_BLOCK_SIZE_MASK); memcpy(oc_sha_ctx->tail, (in_data + in_data_len), oc_sha_ctx->tail_len); } } else if (ica_sha5_ctx->runningLengthLow == 0 && ica_sha5_ctx->runningLengthHigh == 0 && oc_sha_ctx->tail_len > 0) { /* Here we need to fill out the temporary tail * buffer until it has SHA5_BLOCK_SIZE bytes * in it, then call ica_sha512 on that buffer. * If there weren't enough bytes passed in to * fill it out, just copy in what we can and * return success without calling * ica_sha512. */ fill_size = (SHA5_BLOCK_SIZE - oc_sha_ctx->tail_len); if (fill_size < in_data_len) { int rc; memcpy((oc_sha_ctx->tail + oc_sha_ctx->tail_len), in_data, fill_size); /* Submit the filled out save buffer */ if ((rc = ica_sha512(SHA_MSG_PART_FIRST, SHA5_BLOCK_SIZE, oc_sha_ctx->tail, ica_sha5_ctx, oc_sha_ctx->hash))) { rv = CKR_FUNCTION_FAILED; goto out; } } else { memcpy((oc_sha_ctx->tail + oc_sha_ctx->tail_len), in_data, in_data_len); oc_sha_ctx->tail_len += in_data_len; goto out; } /* We had to use 'fill_size' bytes from * in_data to fill out the empty part of save * data, so adjust in_data_len */ in_data_len -= fill_size; oc_sha_ctx->tail_len = (in_data_len & SHA5_BLOCK_SIZE_MASK); if (oc_sha_ctx->tail_len) { memcpy(oc_sha_ctx->tail, in_data + fill_size, oc_sha_ctx->tail_len); in_data_len &= ~(SHA5_BLOCK_SIZE_MASK); } } else if (ica_sha5_ctx->runningLengthLow > 0 || ica_sha5_ctx->runningLengthHigh > 0) { oc_sha_ctx->message_part = SHA_MSG_PART_MIDDLE; if(oc_sha_ctx->tail_len) { fill_size = (SHA5_BLOCK_SIZE - oc_sha_ctx->tail_len); if (fill_size < in_data_len) { int rc; memcpy((oc_sha_ctx->tail + oc_sha_ctx->tail_len), in_data, fill_size); /* Submit the filled out save * buffer */ rc = ica_sha512(oc_sha_ctx->message_part, SHA5_BLOCK_SIZE, oc_sha_ctx->tail, ica_sha5_ctx, oc_sha_ctx->hash); if (rc) { rv = CKR_FUNCTION_FAILED; goto out; } } else { memcpy((oc_sha_ctx->tail + oc_sha_ctx->tail_len), in_data, in_data_len); oc_sha_ctx->tail_len += in_data_len; goto out; } /* We had to use some of the data from * in_data to fill out the empty part * of save data, so adjust in_data_len */ in_data_len -= fill_size; oc_sha_ctx->tail_len = (in_data_len & SHA5_BLOCK_SIZE_MASK); if(oc_sha_ctx->tail_len) { memcpy(oc_sha_ctx->tail, (in_data + fill_size), oc_sha_ctx->tail_len); in_data_len &= ~(SHA5_BLOCK_SIZE_MASK); } } else { /* This is the odd case, where we need * to go ahead and send the first X * * SHA5_BLOCK_SIZE byte chunks in to * be processed and copy the last * tail_len = SHA5_BLOCK_SIZE; memcpy(oc_sha_ctx->tail, (in_data + in_data_len - SHA5_BLOCK_SIZE), SHA5_BLOCK_SIZE); in_data_len -= SHA5_BLOCK_SIZE; } else { oc_sha_ctx->tail_len = (in_data_len & SHA5_BLOCK_SIZE_MASK); } if (oc_sha_ctx->tail_len < SHA5_BLOCK_SIZE) { in_data_len &= ~(SHA5_BLOCK_SIZE_MASK); memcpy(oc_sha_ctx->tail, (in_data + in_data_len), oc_sha_ctx->tail_len); } } } } else { /* ctx->multi == FALSE, but we've run * previously. That's our signal that this is the last * part -KEY */ if (ica_sha5_ctx->runningLengthLow > 0 || ica_sha5_ctx->runningLengthHigh > 0) { oc_sha_ctx->message_part = SHA_MSG_PART_FINAL; } else { oc_sha_ctx->message_part = SHA_MSG_PART_ONLY; } } if (in_data_len || (oc_sha_ctx->message_part == SHA_MSG_PART_FINAL)) { int rc; if ((rc = ica_sha512(oc_sha_ctx->message_part, in_data_len, (in_data + fill_size), ica_sha5_ctx, oc_sha_ctx->hash))) { rv = CKR_FUNCTION_FAILED; goto out; } } out: return rv; } /** * The update functions have too much type-specific code for it to * make sense to collapse them into a single function. */ CK_RV token_specific_sha_generic_update(DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_MECHANISM_TYPE sha_type) { switch (sha_type) { case CKM_SHA_1: return token_specific_sha_update(ctx, in_data, in_data_len); case CKM_SHA256: return token_specific_sha2_update(ctx, in_data, in_data_len); case CKM_SHA384: return token_specific_sha3_update(ctx, in_data, in_data_len); case CKM_SHA512: return token_specific_sha5_update(ctx, in_data, in_data_len); default: return CKR_MECHANISM_INVALID; } } CK_RV token_specific_sha_generic_final(DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_MECHANISM_TYPE sha_type) { struct oc_sha_ctx *oc_sha_ctx = (struct oc_sha_ctx *)ctx->context; unsigned int copy_len, hash_len; if (!ctx) return CKR_OPERATION_NOT_INITIALIZED; switch (sha_type) { case CKM_SHA_1: hash_len = SHA_HASH_LENGTH; break; case CKM_SHA256: hash_len = SHA256_HASH_LENGTH; break; case CKM_SHA384: hash_len = SHA384_HASH_LENGTH; break; case CKM_SHA512: hash_len = SHA512_HASH_LENGTH; break; default: return CKR_MECHANISM_INVALID; } if(!out_data || (*out_data_len < hash_len)) return CKR_FUNCTION_FAILED; if ((oc_sha_ctx->message_part != SHA_MSG_PART_FINAL) && (oc_sha_ctx->message_part != SHA_MSG_PART_ONLY)) { /* Finalize the SHA operation; tell update that this * multi-part operation is done. -KEY */ ctx->multi = FALSE; token_specific_sha_generic_update(ctx, oc_sha_ctx->tail, oc_sha_ctx->tail_len, sha_type); } copy_len = MIN(*out_data_len, hash_len); memcpy(out_data, oc_sha_ctx->hash, copy_len); *out_data_len = copy_len; /* ctx->context is freed inside digest_mgr_cleanup - KEY */ free(oc_sha_ctx->dev_ctx); return CKR_OK; } CK_RV token_specific_sha_final( DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { return token_specific_sha_generic_final(ctx, out_data, out_data_len, CKM_SHA_1); } CK_RV token_specific_sha2_final(DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len) { return token_specific_sha_generic_final(ctx, out_data, out_data_len, CKM_SHA256); } CK_RV token_specific_sha3_final(DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len) { return token_specific_sha_generic_final(ctx, out_data, out_data_len, CKM_SHA384); } CK_RV token_specific_sha5_final(DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len) { return token_specific_sha_generic_final(ctx, out_data, out_data_len, CKM_SHA512); } #ifndef LITE #define LITE #endif /* Creates a libICA modulus+exponent key representation using * PKCS#11 attributes */ ica_rsa_key_mod_expo_t * rsa_convert_mod_expo_key( CK_ATTRIBUTE * modulus, CK_ATTRIBUTE * mod_bits, CK_ATTRIBUTE * exponent) { CK_BYTE * ptr = NULL; ica_rsa_key_mod_expo_t * modexpokey = NULL; /* We need at least the modulus and a (public|private) exponent */ if (!modulus || !exponent) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return NULL; } modexpokey = (ica_rsa_key_mod_expo_t *) calloc(1, sizeof(ica_rsa_key_mod_expo_t)); if (modexpokey == NULL) { st_err_log(1, __FILE__, __LINE__); goto err; } /* We can't rely solely on CKA_MODULUS_BITS here since Private Keys * using the modulus + private exponent representation may also go * through this path. Use modulus length in bytes as key_length if * no mod_bits is present */ if (mod_bits != NULL) { modexpokey->key_length = ((* (CK_ULONG *) mod_bits->pValue) + 7 ) / 8; } else { modexpokey->key_length = modulus->ulValueLen; } /* maybe I'm over-cautious here */ if ( (modulus->ulValueLen > modexpokey->key_length) || (exponent->ulValueLen > modexpokey->key_length)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); goto err; } modexpokey->modulus = (unsigned char *) calloc(1, modexpokey->key_length); if (modexpokey->modulus == NULL) { st_err_log(1, __FILE__, __LINE__); goto err; } /* right-justified fields */ ptr = modexpokey->modulus + modexpokey->key_length - modulus->ulValueLen; memcpy(ptr, modulus->pValue, modexpokey->key_length); modexpokey->exponent = (unsigned char *) calloc(1, modexpokey->key_length); if (modexpokey->exponent == NULL) { st_err_log(1, __FILE__, __LINE__); goto err; } ptr = modexpokey->exponent + modexpokey->key_length - exponent->ulValueLen; memcpy(ptr, exponent->pValue, exponent->ulValueLen); return modexpokey; err: free(modexpokey->modulus); free(modexpokey->exponent); free(modexpokey); return NULL; } /* Creates a libICA CRT key representation using * PKCS#11 attributes */ ica_rsa_key_crt_t * rsa_convert_crt_key( CK_ATTRIBUTE * modulus, CK_ATTRIBUTE * prime1, CK_ATTRIBUTE * prime2, CK_ATTRIBUTE * exp1, CK_ATTRIBUTE * exp2, CK_ATTRIBUTE * coeff) { CK_BYTE * ptr = NULL; ica_rsa_key_crt_t * crtkey = NULL; /* All the above params are required to build a CRT key * that can be used by libICA. Private Keys with modulus * and private exponent should use rsa_convert_mod_expo_key() */ if (!modulus || !prime1 || !prime2 || !exp1 || !exp2 || !coeff ) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return NULL; } else { crtkey = (ica_rsa_key_crt_t *) calloc(1, sizeof(ica_rsa_key_crt_t)); if (crtkey == NULL) { st_err_log(1, __FILE__, __LINE__); return NULL; } /* use modulus length in bytes as key_length */ crtkey->key_length = modulus->ulValueLen; /* buffers pointed by p, q, dp, dq and qInverse in struct * ica_rsa_key_crt_t must be of size key_legth/2 or larger. * p, dp and qInverse have an additional 8-byte padding. */ /* need to allocate the buffers. Also, all fields are * right-aligned, thus the use for ptr */ /* FIXME: if individual components lengths are bigger then * what we support in libICA then we're in trouble, * but maybe explicitly checking them is being over-zealous? */ if ( (prime1->ulValueLen > (crtkey->key_length/2)) || (prime2->ulValueLen > (crtkey->key_length/2)) || (exp1->ulValueLen > (crtkey->key_length/2)) || (exp2->ulValueLen > (crtkey->key_length/2)) || (coeff->ulValueLen > (crtkey->key_length/2)) ) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); goto err_crtkey; } crtkey->p = (unsigned char *) calloc(1, (crtkey->key_length/2) + 8); if (crtkey->p == NULL) { st_err_log(1, __FILE__, __LINE__); goto err_crtkey; } ptr = crtkey->p + (crtkey->key_length/2) + 8 - prime1->ulValueLen; memcpy(ptr, prime1->pValue, prime1->ulValueLen); crtkey->q = (unsigned char *) calloc(1, crtkey->key_length/2); if (crtkey->q == NULL) { st_err_log(1, __FILE__, __LINE__); goto err_crtkey; } ptr = crtkey->q + (crtkey->key_length/2) - prime2->ulValueLen; memcpy(ptr, prime2->pValue, prime2->ulValueLen); crtkey->dp = (unsigned char *) calloc(1, (crtkey->key_length/2) + 8); if (crtkey->dp == NULL) { st_err_log(1, __FILE__, __LINE__); goto err_crtkey; } ptr = crtkey->dp + (crtkey->key_length/2) + 8 - exp1->ulValueLen; memcpy(ptr, exp1->pValue, exp1->ulValueLen); crtkey->dq = (unsigned char *) calloc(1, crtkey->key_length/2); if (crtkey->dq == NULL) { st_err_log(1, __FILE__, __FILE__); goto err_crtkey; } ptr = crtkey->dq + (crtkey->key_length/2) - exp2->ulValueLen; memcpy(ptr, exp2->pValue, exp2->ulValueLen); crtkey->qInverse = (unsigned char *) calloc(1, (crtkey->key_length/2) + 8); if (crtkey->qInverse == NULL) { st_err_log(1, __FILE__, __LINE__); goto err_crtkey; } ptr = crtkey->qInverse + (crtkey->key_length/2) + 8 - coeff->ulValueLen; memcpy(ptr, coeff->pValue, coeff->ulValueLen); return crtkey; } err_crtkey: free(crtkey->p); free(crtkey->q); free(crtkey->dp); free(crtkey->dq); free(crtkey->qInverse); free(crtkey); return NULL; } // CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) { CK_ATTRIBUTE * publ_exp = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_ULONG mod_bits; CK_BBOOL flag; CK_RV rc; ica_rsa_key_mod_expo_t * publKey = NULL; ica_rsa_key_crt_t * privKey = NULL; flag = template_attribute_find( publ_tmpl, CKA_MODULUS_BITS, &attr ); if (!flag) { st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; // should never happen } mod_bits = *(CK_ULONG *)attr->pValue; flag = template_attribute_find( publ_tmpl, CKA_PUBLIC_EXPONENT, &publ_exp ); if (!flag) { st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } // FIXME: is this check really necessary? if (mod_bits < 512 || mod_bits > 4096) { st_err_log(19, __FILE__, __LINE__); return CKR_KEY_SIZE_RANGE; } /* libICA replicates the openSSL requirement that the public exponent * can't be larger than the size of an unsigned long */ if (publ_exp->ulValueLen > sizeof (unsigned long)) { st_err_log(19, __FILE__, __LINE__); return CKR_KEY_SIZE_RANGE; } /* Build publKey: * The buffers in ica_rsa_key_mod_expo_t must be * allocated by the caller, with key_length size * use calloc() so that memory is zeroed (right alignment) */ publKey = (ica_rsa_key_mod_expo_t *) calloc(1, sizeof(ica_rsa_key_mod_expo_t)); if (publKey == NULL) { st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } /* key_length is in terms of bytes */ publKey->key_length = ((mod_bits + 7) / 8); publKey->modulus = (unsigned char *) calloc(1, publKey->key_length); if (publKey->modulus == NULL) { st_err_log(1, __FILE, __LINE__); rc = CKR_HOST_MEMORY; goto pubkey_cleanup; } publKey->exponent = (unsigned char *) calloc(1, publKey->key_length); if (publKey->exponent == NULL) { st_err_log(1, __FILE, __LINE___); rc = CKR_HOST_MEMORY; goto pubkey_cleanup; } /* Use the provided public exponent: * all fields must be right-aligned, so make * sure we only use the rightmost part */ ptr = publKey->exponent + publKey->key_length - publ_exp->ulValueLen; memcpy(ptr, publ_exp->pValue, publ_exp->ulValueLen); /* Build privKey: * buffers pointed by p, q, dp, dq and qInverse in struct * ica_rsa_key_crt_t must be of size key_legth/2 or larger. * p, dp and qInverse have an additional 8-byte padding */ privKey = (ica_rsa_key_crt_t *) calloc(1, sizeof(ica_rsa_key_crt_t)); if (privKey == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto pubkey_cleanup; } /* modexpo and crt key lengths are always the same */ privKey->key_length = publKey->key_length; privKey->p = (unsigned char *) calloc(1, (privKey->key_length/2) + 8); if (privKey->p == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto privkey_cleanup; } privKey->q = (unsigned char *) calloc(1, privKey->key_length/2); if (privKey->q == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto privkey_cleanup; } privKey->dp = (unsigned char *) calloc(1, (privKey->key_length/2) + 8); if (privKey->dp == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto privkey_cleanup; } privKey->dq = (unsigned char *) calloc(1, privKey->key_length/2); if (privKey->dq == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto privkey_cleanup; } privKey->qInverse = (unsigned char *) calloc(1, (privKey->key_length/2) + 8); if (privKey->qInverse == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto privkey_cleanup; } rc = ica_rsa_key_generate_crt(adapter_handle, (unsigned int)mod_bits, publKey, privKey); if(rc){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto privkey_cleanup; } // modulus: n // rc = build_attribute( CKA_MODULUS, publKey->modulus, publKey->key_length, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto privkey_cleanup; } template_update_attribute( publ_tmpl, attr ); // local = TRUE // flag = TRUE; rc = build_attribute( CKA_LOCAL, &flag, sizeof(CK_BBOOL), &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto privkey_cleanup; } template_update_attribute( publ_tmpl, attr ); // // now, do the private key // // public exponent: e // rc = build_attribute( CKA_PUBLIC_EXPONENT, publ_exp->pValue, publ_exp->ulValueLen, &attr ); if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); goto privkey_cleanup; } template_update_attribute( priv_tmpl, attr ); // modulus: n // rc = build_attribute( CKA_MODULUS, publKey->modulus, publKey->key_length, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); return rc; } template_update_attribute( priv_tmpl, attr ); // exponent 1: d mod(p-1) // rc = build_attribute( CKA_EXPONENT_1, privKey->dp + 8, privKey->key_length/2, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto privkey_cleanup; } template_update_attribute( priv_tmpl, attr ); // exponent 2: d mod(q-1) // rc = build_attribute( CKA_EXPONENT_2, privKey->dq, privKey->key_length/2, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto privkey_cleanup; } template_update_attribute( priv_tmpl, attr ); // prime #1: p // rc = build_attribute( CKA_PRIME_1, privKey->p + 8, privKey->key_length/2, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto privkey_cleanup; } template_update_attribute( priv_tmpl, attr ); // prime #2: q // rc = build_attribute( CKA_PRIME_2, privKey->q, privKey->key_length/2, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto privkey_cleanup; } template_update_attribute( priv_tmpl, attr ); // CRT coefficient: q_inverse mod(p) // rc = build_attribute( CKA_COEFFICIENT, privKey->qInverse + 8, privKey->key_length/2, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto privkey_cleanup; } template_update_attribute( priv_tmpl, attr ); privkey_cleanup: free(privKey->p); free(privKey->q); free(privKey->dp); free(privKey->dq); free(privKey->qInverse); free(privKey); pubkey_cleanup: free(publKey->modulus); free(publKey->exponent); free(publKey); return rc; } CK_RV token_specific_rsa_generate_keypair( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ) { CK_RV rc; rc = os_specific_rsa_keygen(publ_tmpl,priv_tmpl); if (rc != CKR_OK) st_err_log(91, __FILE__, __LINE__); return rc; } // // CK_RV token_specific_rsa_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, OBJECT * key_obj ) { CK_ATTRIBUTE * modulus = NULL; CK_ATTRIBUTE * pub_exp = NULL; CK_ATTRIBUTE * mod_bits = NULL; ica_rsa_key_mod_expo_t * publKey = NULL; CK_RV rc; /* mech_sra.c:ckm_rsa_encrypt accepts only CKO_PUBLIC_KEY */ template_attribute_find( key_obj->template, CKA_MODULUS, &modulus ); template_attribute_find( key_obj->template, CKA_MODULUS_BITS, &mod_bits ); template_attribute_find( key_obj->template, CKA_PUBLIC_EXPONENT, &pub_exp ); publKey = rsa_convert_mod_expo_key(modulus, mod_bits, pub_exp); if (publKey == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } /* in_data must be in big endian format. 'in_data' size in bits must not * exceed the bit length of the key, and size in bytes must * be of the same length of the key */ // FIXME: we're not cheking the size in bits of in_data - but how could we? if (publKey->key_length != in_data_len) { st_err_log(11, __FILE__, __LINE__); rc = CKR_DATA_LEN_RANGE; goto cleanup_pubkey; } rc = ica_rsa_mod_expo(adapter_handle, in_data, publKey, out_data); if (rc != 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; } else { rc = CKR_OK; } cleanup_pubkey: free(publKey->modulus); free(publKey->exponent); free(publKey); done: return rc; } // // CK_RV token_specific_rsa_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, OBJECT * key_obj ) { CK_ATTRIBUTE * modulus = NULL; CK_ATTRIBUTE * prime1 = NULL; CK_ATTRIBUTE * prime2 = NULL; CK_ATTRIBUTE * exp1 = NULL; CK_ATTRIBUTE * exp2 = NULL; CK_ATTRIBUTE * coeff = NULL; CK_ATTRIBUTE * priv_exp = NULL; ica_rsa_key_crt_t * crtKey = NULL; ica_rsa_key_mod_expo_t * modexpoKey = NULL; CK_RV rc; /* mech_rsa.c:ckm_rsa_decrypt accepts only CKO_PRIVATE_KEY, * but Private Key can have 2 representations (see PKCS#1): * - Modulus + private exponent * - p, q, dp, dq and qInv (CRT format) * The former should use ica_rsa_key_mod_expo_t and the latter * ica_rsa_key_crt_t. Detect what representation this * key_obj has and use the proper convert function */ template_attribute_find( key_obj->template, CKA_MODULUS, &modulus ); template_attribute_find( key_obj->template, CKA_PRIVATE_EXPONENT, &priv_exp ); template_attribute_find( key_obj->template, CKA_PRIME_1, &prime1 ); template_attribute_find( key_obj->template, CKA_PRIME_2, &prime2 ); template_attribute_find( key_obj->template, CKA_EXPONENT_1, &exp1 ); template_attribute_find( key_obj->template, CKA_EXPONENT_2, &exp2 ); template_attribute_find( key_obj->template, CKA_COEFFICIENT, &coeff ); /* Need to check for CRT Key format *BEFORE* check for mod_expo key, * that's because opencryptoki *HAS* a CKA_PRIVATE_EXPONENT attribute * even in CRT keys (but with zero length) */ // FIXME: Checking for non-zero lengths anyway (might be overkill) if (modulus && modulus->ulValueLen && prime1 && prime1->ulValueLen && prime2 && prime2->ulValueLen && exp1 && exp1->ulValueLen && exp2 && exp2->ulValueLen && coeff && coeff->ulValueLen ) { /* ica_rsa_key_crt_t representation */ crtKey = rsa_convert_crt_key(modulus, prime1, prime2, exp1, exp2, coeff); if (crtKey == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } /* same check as above */ if (crtKey->key_length != in_data_len) { st_err_log(11, __FILE__, __LINE__); rc = CKR_ENCRYPTED_DATA_LEN_RANGE; goto crt_cleanup; } rc = ica_rsa_crt(adapter_handle, in_data, crtKey, out_data); if (rc != 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; } else { rc = CKR_OK; } goto crt_cleanup; } else if (modulus && modulus->ulValueLen && priv_exp && priv_exp->ulValueLen ) { /* ica_rsa_key_mod_expo_t representation */ modexpoKey = rsa_convert_mod_expo_key(modulus, NULL, priv_exp); if (modexpoKey == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } /* in_data must be in big endian format. Size in bits must not * exceed the bit length of the key, and size in bytes must * be the same */ // FIXME: we're not cheking the size in bits of in_data - but how could we? if (modexpoKey->key_length != in_data_len) { st_err_log(11, __FILE__, __LINE__); rc = CKR_ENCRYPTED_DATA_LEN_RANGE; goto modexpo_cleanup; } rc = ica_rsa_mod_expo(adapter_handle, in_data, modexpoKey, out_data); if (rc != 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; } else { rc = CKR_OK; } goto modexpo_cleanup; } else { /* should never happen */ st_err_log(165, __FILE__, __LINE__); rc = CKR_MECHANISM_PARAM_INVALID; goto done; } crt_cleanup: free(crtKey->p); free(crtKey->q); free(crtKey->dp); free(crtKey->dq); free(crtKey->qInverse); free(crtKey); goto done; modexpo_cleanup: free(modexpoKey->modulus); free(modexpoKey->exponent); free(modexpoKey); done: return rc; } CK_RV token_specific_session(CK_SLOT_ID slotid) { return CKR_OK; } #ifndef NOAES CK_RV token_specific_aes_key_gen(CK_BYTE *key, CK_ULONG len) { return rng_generate(key, len); } CK_RV token_specific_aes_ecb(CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_ULONG key_len, CK_BYTE encrypt) { int rc = CKR_OK; /* * checks for input and output data length and block sizes * are already being carried out in mech_aes.c * so we skip those */ if (encrypt) { rc = ica_aes_encrypt(MODE_AES_ECB, (unsigned int) in_data_len, in_data, NULL, (unsigned int) key_len, key_value, out_data); } else { rc = ica_aes_decrypt(MODE_AES_ECB, (unsigned int) in_data_len, in_data, NULL, (unsigned int) key_len, key_value, out_data); } if (rc != 0) { (*out_data_len) = 0; rc = CKR_FUNCTION_FAILED; } else { (*out_data_len) = in_data_len; rc = CKR_OK; } return rc; } CK_RV token_specific_aes_cbc(CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_ULONG key_len, CK_BYTE *init_v, CK_BYTE encrypt) { CK_RV rc; /* * checks for input and output data length and block sizes * are already being carried out in mech_aes.c * so we skip those */ if (encrypt) { rc = ica_aes_encrypt(MODE_AES_CBC, (unsigned int) in_data_len, in_data, (ica_aes_vector_t *) init_v, (unsigned int) key_len, key_value, out_data); } else { rc = ica_aes_decrypt(MODE_AES_CBC, (unsigned int) in_data_len, in_data, (ica_aes_vector_t *) init_v, (unsigned int) key_len, key_value, out_data); } if (rc != 0) { (*out_data_len) = 0; rc = CKR_FUNCTION_FAILED; } else { (*out_data_len) = in_data_len; rc = CKR_OK; } return rc; } #endif #ifndef NODH // This computes DH shared secret, where: // Output: z is computed shared secret // Input: y is other party's public key // x is private key // p is prime // All length's are in number of bytes. All data comes in as Big Endian. CK_RV token_specific_dh_pkcs_derive( CK_BYTE *z, CK_ULONG *z_len, CK_BYTE *y, CK_ULONG y_len, CK_BYTE *x, CK_ULONG x_len, CK_BYTE *p, CK_ULONG p_len) { CK_RV rc ; BIGNUM *bn_z, *bn_y, *bn_x, *bn_p ; BN_CTX *ctx; // Create and Init the BIGNUM structures. bn_y = BN_new() ; bn_x = BN_new() ; bn_p = BN_new() ; bn_z = BN_new() ; if (bn_z == NULL || bn_p == NULL || bn_x == NULL || bn_y == NULL) { if (bn_y) BN_free(bn_y); if (bn_x) BN_free(bn_x); if (bn_p) BN_free(bn_p); if (bn_z) BN_free(bn_z); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } BN_init(bn_y) ; BN_init(bn_x) ; BN_init(bn_p) ; // Initialize context ctx=BN_CTX_new(); if (ctx == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Add data into these new BN structures BN_bin2bn((char *)y, y_len, bn_y); BN_bin2bn((char *)x, x_len, bn_x); BN_bin2bn((char *)p, p_len, bn_p); rc = BN_mod_exp(bn_z,bn_y,bn_x,bn_p,ctx); if (rc == 0) { BN_free(bn_z); BN_free(bn_y); BN_free(bn_x); BN_free(bn_p); BN_CTX_free(ctx); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } *z_len = BN_num_bytes(bn_z); BN_bn2bin(bn_z, z); BN_free(bn_z); BN_free(bn_y); BN_free(bn_x); BN_free(bn_p); BN_CTX_free(ctx); return CKR_OK; } /* end token_specific_dh_pkcs_derive() */ // This computes DH key pair, where: // Output: priv_tmpl is generated private key // pub_tmpl is computed public key // Input: pub_tmpl is public key (prime and generator) // All length's are in number of bytes. All data comes in as Big Endian. CK_RV token_specific_dh_pkcs_key_pair_gen( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ) { CK_BBOOL rc; CK_ATTRIBUTE *prime_attr = NULL; CK_ATTRIBUTE *base_attr = NULL; CK_ATTRIBUTE *temp_attr = NULL ; CK_ATTRIBUTE *value_bits_attr = NULL; CK_BYTE *temp_byte; CK_ULONG temp_bn_len ; DH *dh ; BIGNUM *bn_p ; BIGNUM *bn_g ; BIGNUM *temp_bn ; rc = template_attribute_find( publ_tmpl, CKA_PRIME, &prime_attr ); rc &= template_attribute_find( publ_tmpl, CKA_BASE, &base_attr ); if (rc == FALSE) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if ((prime_attr->ulValueLen > 256) || (prime_attr->ulValueLen < 64)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } dh = DH_new() ; if (dh == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Create and init BIGNUM structs to stick in the DH struct bn_p = BN_new(); bn_g = BN_new(); if (bn_g == NULL || bn_p == NULL) { if (bn_g) BN_free(bn_g); if (bn_p) BN_free(bn_p); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } BN_init(bn_p); BN_init(bn_g); // Convert from strings to BIGNUMs and stick them in the DH struct BN_bin2bn((char *)prime_attr->pValue, prime_attr->ulValueLen, bn_p); dh->p = bn_p; BN_bin2bn((char *)base_attr->pValue, base_attr->ulValueLen, bn_g); dh->g = bn_g; // Generate the DH Key if (!DH_generate_key(dh)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Extract the public and private key components from the DH struct, // and insert them in the publ_tmpl and priv_tmpl // // pub_key // //temp_bn = BN_new(); temp_bn = dh->pub_key; temp_bn_len = BN_num_bytes(temp_bn); temp_byte = malloc(temp_bn_len); temp_bn_len = BN_bn2bin(temp_bn, temp_byte); rc = build_attribute( CKA_VALUE, temp_byte, temp_bn_len, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( publ_tmpl, temp_attr ); free(temp_byte); // // priv_key // //temp_bn = BN_new(); temp_bn = dh->priv_key; temp_bn_len = BN_num_bytes(temp_bn); temp_byte = malloc(temp_bn_len); temp_bn_len = BN_bn2bin(temp_bn, temp_byte); rc = build_attribute( CKA_VALUE, temp_byte, temp_bn_len, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); free(temp_byte); // Update CKA_VALUE_BITS attribute in the private key value_bits_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); value_bits_attr->type = CKA_VALUE_BITS; value_bits_attr->ulValueLen = sizeof(CK_ULONG); value_bits_attr->pValue = (CK_BYTE *)value_bits_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_bits_attr->pValue = 8*temp_bn_len; template_update_attribute( priv_tmpl, value_bits_attr ); // Add prime and base to the private key template rc = build_attribute( CKA_PRIME,(char *)prime_attr->pValue, prime_attr->ulValueLen, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); rc = build_attribute( CKA_BASE,(char *)base_attr->pValue, base_attr->ulValueLen, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); // Cleanup DH key DH_free(dh) ; return CKR_OK ; } /* end token_specific_dh_key_pair_gen() */ #endif /* #ifndef NODH */ MECH_LIST_ELEMENT mech_list[] = { { CKM_RSA_PKCS_KEY_PAIR_GEN, 512, 4096, CKF_HW | CKF_GENERATE_KEY_PAIR }, #if !(NODSA) { CKM_DSA_KEY_PAIR_GEN, 512, 1024, CKF_HW | CKF_GENERATE_KEY_PAIR }, #endif { CKM_DES_KEY_GEN, 8, 8, CKF_HW | CKF_GENERATE }, { CKM_DES3_KEY_GEN, 24, 24, CKF_HW | CKF_GENERATE }, #if !(NOCDMF) { CKM_CDMF_KEY_GEN, 0, 0, CKF_HW | CKF_GENERATE }, #endif { CKM_RSA_PKCS, 512, 4096, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP | CKF_SIGN | CKF_VERIFY | CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER }, #if !(NOX509) { CKM_RSA_X_509, 512, 4096, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP | CKF_SIGN | CKF_VERIFY | CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER }, #endif #if !(NOMD2) { CKM_MD2_RSA_PKCS, 512, 4096, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NOMD5) { CKM_MD5_RSA_PKCS, 512, 4096, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NOSHA1) { CKM_SHA1_RSA_PKCS, 512, 4096, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NODSA) { CKM_DSA, 512, 1024, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif /* Begin code contributed by Corrent corp. */ #if !(NODH) { CKM_DH_PKCS_DERIVE, 512, 2048, CKF_HW | CKF_DERIVE }, { CKM_DH_PKCS_KEY_PAIR_GEN, 512, 2048, CKF_HW | CKF_GENERATE_KEY_PAIR }, #endif /* End code contributed by Corrent corp. */ { CKM_DES_ECB, 8, 8, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_DES_CBC, 8, 8, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_DES_CBC_PAD, 8, 8, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, #if !(NOCDMF) { CKM_CDMF_ECB, 0, 0, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_CDMF_CBC, 0, 0, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, #endif { CKM_DES3_ECB, 24, 24, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_DES3_CBC, 24, 24, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_DES3_CBC_PAD, 24, 24, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, #if !(NOSHA1) { CKM_SHA_1, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_SHA_1_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SHA_1_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SHA256, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_SHA256_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SHA256_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SHA384, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_SHA384_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SHA384_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SHA512, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_SHA512_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SHA512_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NOMD2) { CKM_MD2, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_MD2_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_MD2_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NOMD5) { CKM_MD5, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_MD5_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_MD5_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif { CKM_SSL3_PRE_MASTER_KEY_GEN, 48, 48, CKF_HW | CKF_GENERATE }, { CKM_SSL3_MASTER_KEY_DERIVE, 48, 48, CKF_HW | CKF_DERIVE }, { CKM_SSL3_KEY_AND_MAC_DERIVE, 48, 48, CKF_HW | CKF_DERIVE }, { CKM_SSL3_MD5_MAC, 384, 384, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SSL3_SHA1_MAC, 384, 384, CKF_HW | CKF_SIGN | CKF_VERIFY }, #if !(NOAES) { CKM_AES_KEY_GEN, 16, 32, CKF_HW }, { CKM_AES_ECB, 16, 32, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_AES_CBC, 16, 32, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_AES_MAC, 16, 32, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_AES_MAC_GENERAL, 16, 32, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_AES_CBC_PAD, 16, 32, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, #endif #if !(NORIPE) { CKM_RIPEMD128, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_RIPEMD128_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_RIPEMD128_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_RIPEMD160, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_RIPEMD160_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_RIPEMD160_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif }; CK_ULONG mech_list_len = (sizeof(mech_list) / sizeof(MECH_LIST_ELEMENT)); /** * Remove/alter mechanisms for whatever reason. */ static void scrub_list(struct mech_list_item *head) { struct mech_list_item *walker; walker = head; while (walker->next) { struct mech_list_item *current; current = walker->next; if (/* remove condition */0) { walker->next = current->next; free(current); } else if (/* alter condition */0) { /* current->element.mech_info.flags = ...; */ } walker = walker->next; } } CK_RV token_specific_get_mechanism_list(CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount) { int rc = CKR_OK; struct mech_list_item head; struct mech_list_item *walker; head.next = NULL; #if 1 rc = ock_generic_get_mechanism_list(pMechanismList, pulCount); if (rc != CKR_OK) { goto out; } #endif /* TODO: Cache this data */ generate_pkcs11_mech_list(&head); scrub_list(&head); #if 1 walker = find_mech_list_item_for_type(CKM_SHA256, &head); if (walker) { if (NULL != pMechanismList) { pMechanismList[(*pulCount)] = CKM_SHA256; } (*pulCount)++; } goto out; #else (*pulCount) = 0; walker = head.next; if (NULL == pMechanismList) { while (walker) { struct mech_list_item *next; next = walker->next; (*pulCount)++; free(walker); walker = next; } goto out; } while (walker) { struct mech_list_item *next; next = walker->next; pMechanismList[(*pulCount)] = walker->element.mech_type; (*pulCount)++; free(walker); walker = next; } #endif out: free_mech_list(&head); return rc; } /* TODO: Remove once proper behavior is determined for duplicate * mechanisms. */ #ifndef OCK_FAIL_ON_DUPLICATE_MECH #define OCK_FAIL_ON_DUPLICATE_MECH 0 #endif CK_RV token_specific_get_mechanism_info(CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo) { int rc = CKR_MECHANISM_INVALID; struct mech_list_item head; struct mech_list_item *walker; head.next = NULL; #if 1 rc = ock_generic_get_mechanism_info(type, pInfo); if (rc == CKR_OK) { /* Match made; info copiedl. We're done. */ goto out; } /* TODO: Remove this hack when the time is right. */ if (type != CKM_SHA256) { goto out; } #endif generate_pkcs11_mech_list(&head); scrub_list(&head); walker = find_mech_list_item_for_type(type, &head); if (walker) { memcpy(pInfo, &walker->element.mech_info, sizeof(CK_MECHANISM_INFO)); rc = CKR_OK; } out: free_mech_list(&head); return rc; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/ica_s390_stdll/tok_struct.h.in0000640000175000017500000004073211327631345023125 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2002 */ // SAB FIXME need to figure out a better way... // // to get the variant dependency out #ifndef __TOK_STRUCT_H #define __TOK_STRUCT_H #include #include "tok_spec_struct.h" // #define PK_LITE_DIR "/etc/pkcs11/lite" // // #define PK_DIR PK_LITE_DIR // #define SUB_DIR "lite" // // // #define DBGTAG "ICA_STDLL_Debug" // // // token_spec_t token_specific = { "@DB_PATH@/lite", "lite", "ICA_STDLL_Debug", &token_specific_init, &tok_slot2local, &token_rng, &token_specific_session, &token_specific_final, &token_specific_des_key_gen, &token_specific_des_ecb, &token_specific_des_cbc, &token_specific_tdes_ecb, &token_specific_tdes_cbc, &token_specific_rsa_decrypt, &token_specific_rsa_encrypt, &token_specific_rsa_generate_keypair, #ifndef NODH // DH &token_specific_dh_pkcs_derive, &token_specific_dh_pkcs_key_pair_gen, #endif // SHA &token_specific_sha_init, &token_specific_sha_update, &token_specific_sha_final, /* SHA-256 */ &token_specific_sha2_init, &token_specific_sha2_update, &token_specific_sha2_final, &token_specific_sha3_init, &token_specific_sha3_update, &token_specific_sha3_final, &token_specific_sha5_init, &token_specific_sha5_update, &token_specific_sha5_final, #ifndef NOAES // AES &token_specific_aes_key_gen, &token_specific_aes_ecb, &token_specific_aes_cbc, #endif &token_specific_get_mechanism_list, &token_specific_get_mechanism_info }; #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/ica_s390_stdll/Makefile.am0000640000175000017500000000330311327631345022173 0ustar jfjfnobase_lib_LTLIBRARIES = opencryptoki/stdll/libpkcs11_ica.la opencryptoki_stdll_libpkcs11_ica_la_LDFLAGS = $(LCRYPTO) \ $(ICA_LIB_DIRS) -nostartfiles -shared -Wl,-Bsymbolic -Wl,-soname,$@ \ -Wl,-Bsymbolic -lc -lpthread -lica -ldl -lcrypto # Not all versions of automake observe libname_CFLAGS opencryptoki_stdll_libpkcs11_ica_la_CFLAGS = -DSPINXPL -DDEV \ -D_THREAD_SAFE -fPIC -DSHALLOW=0 -DSWTOK=0 -DLITE=1 -DNODH \ -DNOCDMF -DNOMD2 -DNODSA -DSTDLL_NAME=\"icatok\" # Not all versions of automake observe libname_CFLAGS AM_CFLAGS = -DSPINXPL -DDEV -D_THREAD_SAFE -fPIC -DSHALLOW=0 -DSWTOK=0 \ -DLITE=1 -DNODH -DNOCDMF -DNOMD2 -DNODSA -DNORIPE opencryptoki_stdll_libpkcs11_ica_la_SOURCES = ../common/asn1.c \ ../common/cert.c ../common/hwf_obj.c ../common/dp_obj.c \ ../common/data_obj.c ../common/decr_mgr.c ../common/dig_mgr.c \ ../common/encr_mgr.c ../common/globals.c ../common/loadsave.c \ ../common/key.c ../common/key_mgr.c ../common/mech_des.c \ ../common/mech_des3.c ../common/mech_aes.c ../common/mech_md5.c \ ../common/mech_md2.c ../common/mech_rng.c ../common/mech_rsa.c \ ../common/mech_sha.c ../common/mech_ssl3.c ../common/new_host.c \ ../common/obj_mgr.c ../common/object.c ../common/sess_mgr.c \ ../common/sign_mgr.c ../common/template.c ../common/utility.c \ ../common/verify_mgr.c ../common/log.c ../common/mech_list.c \ ica_specific.c INCLUDES = $(ICA_INC_DIRS) -I. -I../../../include/pkcs11/stdll \ -I../../../include/pkcs11 -I../common -I../../../ica/inc \ -I../../../../ica/include -I.. -I../../../../ica/src/inc install-data-local: mkdir -p $(DESTDIR)/$(libdir)/opencryptoki/stdll cd $(DESTDIR)/$(libdir)/opencryptoki/stdll && rm -f PKCS11_ICA.so && \ ln -sf libpkcs11_ica.so PKCS11_ICA.so opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/ica_stdll/0000751000175000017500000000000011327631345017362 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/lib/pkcs11/ica_stdll/ica_specific.c0000751000175000017500000017354111327631345022145 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #include #include // for memcmp() et al #include #include #ifndef NOAES #include #endif #ifndef NODH #include #endif #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_specific.h" #include "tok_struct.h" #include "ica_api.h" // declare the adapter open handle localy ICA_ADAPTER_HANDLE adapter_handle; // Linux really does not need these so we just dummy them up // so the common code across platforms is usable... #define KEYTYPE_MODEXPO 1 #define KEYTYPE_PKCSCRT 2 CK_CHAR manuf[] = "IBM Corp."; CK_CHAR model[] = "IBM ICA "; CK_CHAR descr[] = "IBM PKCS#11 ICA token "; CK_CHAR label[] = "IBM ICA PKCS #11"; pthread_mutex_t rngmtx = PTHREAD_MUTEX_INITIALIZER; unsigned int rnginitialized=0; CK_RV token_rng(CK_BYTE *output, CK_ULONG bytes) { unsigned int rc; pthread_mutex_lock(&rngmtx); rc = icaRandomNumberGenerate(adapter_handle, (unsigned int)bytes, output); if (rc != 0) { pthread_mutex_unlock(&rngmtx); st_err_log(3, __FILE__, __LINE__); return CKR_GENERAL_ERROR; /* report error */ } pthread_mutex_unlock(&rngmtx); return CKR_OK; } int tok_slot2local(CK_SLOT_ID snum) { return 1; } CK_RV token_specific_init(char * Correlator,CK_SLOT_ID SlotNumber) { return icaOpenAdapter(0,&adapter_handle); } CK_RV token_specific_final() { icaCloseAdapter(adapter_handle); return CKR_OK; } // count_ones_in_byte: for use in adjust_des_key_parity_bits below CK_BYTE count_ones_in_byte(CK_BYTE byte) { CK_BYTE and_mask, // bit selector number_of_ones = 0; for (and_mask = 1; and_mask != 0; and_mask <<= 1) // for each bit, if (byte & and_mask) // if it's a one, ++number_of_ones; // count it return number_of_ones; } #define EVEN_PARITY TRUE #define ODD_PARITY FALSE // adjust_des_key_parity_bits: to conform to NIST spec for DES and 3DES keys void adjust_des_key_parity_bits(CK_BYTE *des_key, CK_ULONG key_size, CK_BBOOL parity) { CK_BYTE *des_key_byte; for (des_key_byte = des_key; des_key_byte - des_key < key_size; ++des_key_byte) // look at each byte in the key { if ((count_ones_in_byte(*des_key_byte) % 2) ^ (parity == ODD_PARITY)) { // if parity for this byte isn't what it should be, // flip the parity (least significant) bit *des_key_byte ^= 1; } } } CK_RV token_specific_des_key_gen(CK_BYTE *des_key,CK_ULONG len) { // Nothing different to do for DES or TDES here as this is just // random data... Validation handles the rest rng_generate(des_key,len); adjust_des_key_parity_bits(des_key, len, ODD_PARITY); // we really need to validate the key for parity etc... // we should do that here... The caller validates the single des keys // against the known and suspected poor keys..<< return CKR_OK; } CK_RV token_specific_des_ecb(CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_BYTE encrypt) { ICA_DES_VECTOR empty_iv; CK_RV rc; unsigned int _out_data_len = *out_data_len; memset(&empty_iv, 0, sizeof(empty_iv)); if ( encrypt) { rc = icaDesEncrypt(adapter_handle, (unsigned int)MODE_DES_ECB, (unsigned int)in_data_len, in_data, &empty_iv, (ICA_KEY_DES_SINGLE *)key_value, &_out_data_len, out_data); } else { rc = icaDesDecrypt(adapter_handle, (unsigned int)MODE_DES_ECB, (unsigned int)in_data_len, in_data, &empty_iv, (ICA_KEY_DES_SINGLE *)key_value, &_out_data_len, out_data); } if (rc != 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; }else { *out_data_len = in_data_len; rc = CKR_OK; } return rc; } CK_RV token_specific_des_cbc(CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_BYTE *init_v, CK_BYTE encrypt) { CK_RV rc; unsigned int _out_data_len = *out_data_len; if ( encrypt ){ rc = icaDesEncrypt(adapter_handle, (unsigned int)MODE_DES_CBC, (unsigned int)in_data_len, in_data, (ICA_DES_VECTOR *)init_v, (ICA_KEY_DES_SINGLE *)key_value, &_out_data_len, (unsigned char *)out_data); } else { rc = icaDesDecrypt(adapter_handle, (unsigned int)MODE_DES_CBC, (unsigned int)in_data_len, in_data, (ICA_DES_VECTOR *)init_v, (ICA_KEY_DES_SINGLE *)key_value, &_out_data_len, (unsigned char *)out_data); } if (rc != 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; }else { *out_data_len = in_data_len; rc = CKR_OK; } return rc; } CK_RV token_specific_tdes_ecb(CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_BYTE encrypt) { ICA_DES_VECTOR empty_iv; CK_RV rc; unsigned int _out_data_len = *out_data_len; memset(&empty_iv, 0, sizeof(empty_iv)); if ( encrypt) { rc = icaTDesEncrypt(adapter_handle, (unsigned int)MODE_DES_ECB, (unsigned int)in_data_len, in_data, &empty_iv, (ICA_KEY_DES_TRIPLE *)key_value, &_out_data_len, out_data); } else { rc = icaTDesDecrypt(adapter_handle, (unsigned int)MODE_DES_ECB, (unsigned int)in_data_len, in_data, &empty_iv, (ICA_KEY_DES_TRIPLE *)key_value, &_out_data_len, out_data); } if (rc != 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; }else { *out_data_len = in_data_len; rc = CKR_OK; } return rc; } CK_RV token_specific_tdes_cbc(CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_BYTE *init_v, CK_BYTE encrypt) { CK_RV rc; unsigned int _out_data_len = *out_data_len; if ( encrypt ){ rc = icaTDesEncrypt((int)adapter_handle, (unsigned int)MODE_DES_CBC, (unsigned int)in_data_len, in_data, (ICA_DES_VECTOR *)init_v, (ICA_KEY_DES_TRIPLE *)key_value, &_out_data_len, (unsigned char *)out_data); } else { rc = icaTDesDecrypt((int)adapter_handle, (unsigned int)MODE_DES_CBC, (unsigned int)in_data_len, in_data, (ICA_DES_VECTOR *)init_v, (ICA_KEY_DES_TRIPLE *)key_value, &_out_data_len, (unsigned char *)out_data); } if (rc != 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; }else { *out_data_len = in_data_len; rc = CKR_OK; } return rc; } #ifndef LITE #define LITE #endif // convert from the local PKCS11 template representation to // the underlying requirement // returns the pointer to the local key representation void * rsa_convert_public_key( OBJECT * key_obj ) { CK_BBOOL rc; CK_ATTRIBUTE * modulus = NULL; CK_ATTRIBUTE * pub_exp = NULL; ICA_KEY_RSA_MODEXPO *publKey; unsigned char *pkey; unsigned int offset; // So we need to generate the publKey in device specific format every time // we know the modulus is good, and that the pub_exp is good since rc = template_attribute_find( key_obj->template, CKA_MODULUS, &modulus ); rc &= template_attribute_find( key_obj->template, CKA_PUBLIC_EXPONENT, &pub_exp ); if (rc == FALSE) { return NULL; } publKey = (ICA_KEY_RSA_MODEXPO *) malloc(sizeof(ICA_KEY_RSA_MODEXPO)); if (publKey == NULL) { return NULL; } memset(publKey, 0, sizeof(ICA_KEY_RSA_MODEXPO)); // Currently using definition of ICA_KEY_RSA_MODEXPO in NT spec v1.12 publKey->keyType = KEYTYPE_MODEXPO; publKey->keyLength = sizeof(ICA_KEY_RSA_MODEXPO); publKey->modulusBitLength = 8 * modulus->ulValueLen; publKey->nLength = modulus->ulValueLen; publKey->expLength = modulus->ulValueLen; offset = (CK_BYTE_PTR) publKey->keyRecord - (CK_BYTE_PTR) publKey; publKey->expOffset = offset; publKey->nOffset = offset + modulus->ulValueLen; pkey = (CK_BYTE_PTR) publKey->keyRecord; pkey += modulus->ulValueLen - pub_exp->ulValueLen; memcpy(pkey, pub_exp->pValue, pub_exp->ulValueLen); pkey += pub_exp->ulValueLen; memcpy(pkey, modulus->pValue, modulus->ulValueLen); return publKey; } void * rsa_convert_private_key(OBJECT *key_obj) { CK_ATTRIBUTE * attr = NULL; CK_ATTRIBUTE * modulus = NULL; CK_ATTRIBUTE * priv_exp = NULL; CK_ATTRIBUTE * prime1 = NULL; CK_ATTRIBUTE * prime2 = NULL; CK_ATTRIBUTE * exp1 = NULL; CK_ATTRIBUTE * exp2 = NULL; CK_ATTRIBUTE * coeff = NULL; CK_BBOOL rc; CK_BYTE_PTR pkey; ICA_KEY_RSA_CRT *privKey; ICA_KEY_RSA_MODEXPO *privModKey; unsigned int offset, pSize, qSize; rc = template_attribute_find( key_obj->template, CKA_MODULUS, &modulus ); rc &= template_attribute_find( key_obj->template, CKA_PRIVATE_EXPONENT, &priv_exp ); rc &= template_attribute_find( key_obj->template, CKA_PRIME_1, &prime1 ); rc &= template_attribute_find( key_obj->template, CKA_PRIME_2, &prime2 ); rc &= template_attribute_find( key_obj->template, CKA_EXPONENT_1, &exp1 ); rc &= template_attribute_find( key_obj->template, CKA_EXPONENT_2, &exp2 ); rc &= template_attribute_find( key_obj->template, CKA_COEFFICIENT, &coeff ); if ( !prime2 && !modulus ){ return NULL; } // CRT key? if ( prime1){ if (!prime2 || !exp1 ||!exp2 || !coeff) { return NULL; } privKey = (ICA_KEY_RSA_CRT *) malloc(sizeof(ICA_KEY_RSA_CRT)); if (privKey == NULL) { return NULL; } memset(privKey, 0, sizeof(ICA_KEY_RSA_CRT)); // Currently using definition of ICA_KEY_RSA_CRT in NT spec v1.12 // (with nLength and nOffset removed per BEF's e-mail) privKey->keyType = KEYTYPE_PKCSCRT; privKey->keyLength = sizeof(ICA_KEY_RSA_CRT); privKey->modulusBitLength = 8 * modulus->ulValueLen; privKey->pLength = prime1->ulValueLen; privKey->qLength = prime2->ulValueLen; privKey->dpLength = exp1->ulValueLen; privKey->dqLength = exp2->ulValueLen; privKey->qInvLength = coeff->ulValueLen; offset = (CK_BYTE_PTR) privKey->keyRecord - (CK_BYTE_PTR) privKey; qSize = modulus->ulValueLen / 2; pSize = qSize + 8; // 1 QWORD larger privKey->dpOffset = offset; privKey->dqOffset = offset += pSize; privKey->pOffset = offset += qSize; privKey->qOffset = offset += pSize; privKey->qInvOffset = offset + qSize; pkey = (CK_BYTE_PTR) privKey->keyRecord; pkey += pSize - exp1->ulValueLen; memcpy(pkey, exp1->pValue, exp1->ulValueLen); // pkey += exp1->ulValueLen + qSize - exp2->ulValueLen; pkey += exp1->ulValueLen; memcpy(pkey, exp2->pValue, exp2->ulValueLen); // pkey += exp2->ulValueLen + pSize - prime1->ulValueLen; pkey += qSize + pSize - prime1->ulValueLen; memcpy(pkey, prime1->pValue, prime1->ulValueLen); // pkey += prime1->ulValueLen + qSize - prime2->ulValueLen; pkey += prime1->ulValueLen; memcpy(pkey, prime2->pValue, prime2->ulValueLen); // pkey += prime2->ulValueLen + pSize - coeff->ulValueLen; pkey += qSize + pSize - coeff->ulValueLen; memcpy(pkey, coeff->pValue, coeff->ulValueLen); return privKey; // hex_dump_to_file("PRIVATEKEY",(char *)privKey,sizeof(ICA_KEY_RSA_CRT)); } else { // must be a non-CRT key if (!priv_exp) { return NULL; } privModKey = (ICA_KEY_RSA_MODEXPO *) malloc(sizeof(ICA_KEY_RSA_MODEXPO)); if (privModKey == NULL) { return NULL; } memset(privModKey, 0, sizeof(ICA_KEY_RSA_MODEXPO)); // Currently using definition of ICA_KEY_RSA_MODEXPO in NT spec v1.12 privModKey->keyType = KEYTYPE_MODEXPO; privModKey->keyLength = sizeof(ICA_KEY_RSA_MODEXPO); privModKey->modulusBitLength = 8 * modulus->ulValueLen; privModKey->nLength = modulus->ulValueLen; privModKey->expLength = modulus->ulValueLen; offset = (CK_BYTE_PTR) privModKey->keyRecord - (CK_BYTE_PTR) privModKey; privModKey->expOffset = offset; privModKey->nOffset = offset + modulus->ulValueLen; pkey = (CK_BYTE_PTR) privModKey->keyRecord; pkey += modulus->ulValueLen - priv_exp->ulValueLen; memcpy(pkey, priv_exp->pValue, priv_exp->ulValueLen); pkey += priv_exp->ulValueLen; memcpy(pkey, modulus->pValue, modulus->ulValueLen); return privModKey; } } // CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) { CK_ATTRIBUTE * publ_exp = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_BYTE repl_buf[5500]; CK_ULONG req_len, repl_len; CK_ULONG mod_bits; CK_BBOOL flag; CK_RV rc; CK_BYTE_PTR pubExp; CK_BYTE_PTR prdat; // IN format for cryptolite CK_BYTE_PTR pudat; // IN format for cryptolite CK_ULONG keysize; ICA_KEY_RSA_MODEXPO *publKey; ICA_KEY_RSA_CRT *privKey; unsigned int offset, len; unsigned int publKeySize, privKeySize; flag = template_attribute_find( publ_tmpl, CKA_MODULUS_BITS, &attr ); if (!flag){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; // should never happen } mod_bits = *(CK_ULONG *)attr->pValue; flag = template_attribute_find( publ_tmpl, CKA_PUBLIC_EXPONENT, &publ_exp ); if (!flag){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } //jag // we don't support less than 1024 bit keys in the sw if (mod_bits < 256 || mod_bits > 2048) { st_err_log(19, __FILE__, __LINE__); return CKR_KEY_SIZE_RANGE; } if(publ_exp->ulValueLen > (mod_bits * 8)){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } publKey = (ICA_KEY_RSA_MODEXPO *) malloc(sizeof(ICA_KEY_RSA_MODEXPO)); if (publKey == NULL) { st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } privKey = (ICA_KEY_RSA_CRT *) malloc(sizeof(ICA_KEY_RSA_CRT)); if (privKey == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto pubkey_cleanup; } memset(publKey, 0x00, sizeof(ICA_KEY_RSA_MODEXPO)); memset(privKey, 0x00, sizeof(ICA_KEY_RSA_CRT)); // Currently using definition of ICA_KEY_RSA_MODEXPO in NT spec v1.12 keysize = ((mod_bits + 7)/8); /* Linux driver is not using these */ ptr = publKey->keyRecord + keysize - publ_exp->ulValueLen; memcpy(ptr,publ_exp->pValue, publ_exp->ulValueLen); publKeySize = sizeof(ICA_KEY_RSA_MODEXPO); privKeySize = sizeof(ICA_KEY_RSA_CRT); rc = icaRsaKeyGenerateCrt((int)adapter_handle, (unsigned int)mod_bits, (unsigned int)RSA_PUBLIC_FIXED, &publKeySize, (ICA_KEY_RSA_MODEXPO *)publKey, &privKeySize, (ICA_KEY_RSA_CRT *)privKey); if(rc){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto privkey_cleanup; } // modulus: n // ptr = (CK_BYTE *)(publKey->keyRecord + keysize); rc = build_attribute( CKA_MODULUS, ptr, keysize, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto privkey_cleanup; } template_update_attribute( publ_tmpl, attr ); // local = TRUE // flag = TRUE; rc = build_attribute( CKA_LOCAL, &flag, sizeof(CK_BBOOL), &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto privkey_cleanup; } template_update_attribute( publ_tmpl, attr ); // // now, do the private key // // public exponent: e // rc = build_attribute( CKA_PUBLIC_EXPONENT, publ_exp->pValue, publ_exp->ulValueLen, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto privkey_cleanup; } template_update_attribute( priv_tmpl, attr ); // modulus: n // ptr = (CK_BYTE *)(publKey->keyRecord + keysize); rc = build_attribute( CKA_MODULUS, ptr, keysize, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); return rc; } template_update_attribute( priv_tmpl, attr ); /* CRT sizes are smaller */ keysize /= 2; // exponent 1: d mod(p-1) // ptr = (CK_BYTE *)(privKey->keyRecord); rc = build_attribute( CKA_EXPONENT_1, ptr, keysize + 8, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto privkey_cleanup; } template_update_attribute( priv_tmpl, attr ); // exponent 2: d mod(q-1) // ptr += keysize + 8; rc = build_attribute( CKA_EXPONENT_2, ptr, keysize, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto privkey_cleanup; } template_update_attribute( priv_tmpl, attr ); // prime #1: p // ptr += keysize; rc = build_attribute( CKA_PRIME_1, ptr, keysize+8, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto privkey_cleanup; } template_update_attribute( priv_tmpl, attr ); // prime #2: q // ptr += keysize + 8; rc = build_attribute( CKA_PRIME_2, ptr, keysize, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto privkey_cleanup; } template_update_attribute( priv_tmpl, attr ); // CRT coefficient: q_inverse mod(p) // ptr += keysize; rc = build_attribute( CKA_COEFFICIENT, ptr, keysize + 8, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto privkey_cleanup; } template_update_attribute( priv_tmpl, attr ); privkey_cleanup: free(privKey); pubkey_cleanup: free(publKey); return rc; } // SAB FIXME this keygen stuff needs to be reworked.. // // CK_RV token_specific_rsa_generate_keypair( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ) { CK_ATTRIBUTE * publ_exp = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_BYTE repl_buf[5500]; CK_ULONG req_len, repl_len; CK_ULONG mod_bits; CK_BBOOL flag; CK_RV rc; rc = os_specific_rsa_keygen(publ_tmpl,priv_tmpl); if (rc != CKR_OK) st_err_log(91, __FILE__, __LINE__); return rc; } // // CK_RV token_specific_rsa_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, OBJECT * key_obj ) { CK_ATTRIBUTE * attr = NULL; CK_ATTRIBUTE * modulus = NULL; CK_ATTRIBUTE * pub_exp = NULL; CK_BYTE * ptr = NULL; CK_ULONG buffer[80]; // plenty of room... CK_OBJECT_CLASS keyclass; CK_ULONG req_len, repl_len, key_len; CK_RV rc; unsigned int out_data_len; ICA_KEY_RSA_MODEXPO *publKey; publKey = (ICA_KEY_RSA_MODEXPO *) rsa_convert_public_key(key_obj); if (publKey == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } out_data_len = (unsigned int)in_data_len; rc = icaRsaModExpo((int)adapter_handle, (unsigned int)in_data_len, in_data, publKey, &out_data_len, out_data); if (rc != 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; } else { rc = CKR_OK; } free(publKey); goto done; done: return rc; } // // CK_RV token_specific_rsa_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, OBJECT * key_obj ) { CK_ATTRIBUTE * attr = NULL; CK_ATTRIBUTE * modulus = NULL; CK_ATTRIBUTE * pub_exp = NULL; CK_ATTRIBUTE * prime1 = NULL; CK_ATTRIBUTE * prime2 = NULL; CK_ATTRIBUTE * exp1 = NULL; CK_ATTRIBUTE * exp2 = NULL; CK_ATTRIBUTE * coeff = NULL; CK_BYTE * ptr = NULL; CK_ULONG buffer[80]; // plenty of room... CK_OBJECT_CLASS keyclass; CK_ULONG key_size; CK_ULONG req_len, repl_len; CK_RV rc; unsigned int out_data_len; ICA_KEY_RSA_CRT *privKey; privKey = (ICA_KEY_RSA_CRT *) rsa_convert_private_key(key_obj); if (privKey == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } out_data_len = (unsigned int)in_data_len; if (privKey->keyType == KEYTYPE_PKCSCRT) { rc = icaRsaCrt((int)adapter_handle, (unsigned int)in_data_len, in_data, privKey, &out_data_len, out_data); } else if (privKey->keyType == KEYTYPE_MODEXPO) { rc = icaRsaModExpo((int)adapter_handle, (unsigned int)in_data_len, in_data, (ICA_KEY_RSA_MODEXPO *) privKey, &out_data_len, out_data); } else { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; free(privKey); goto done; } if (rc != 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; } else { rc = CKR_OK; } free(privKey); goto done; done: return rc; } CK_RV token_specific_session(CK_SLOT_ID slotid) { return CKR_OK; } CK_RV token_specific_sha_init( DIGEST_CONTEXT * ctx ) { oc_sha1_ctx *sc; /* For the C_DigestInit, C_Digest case, we may have already * created ctx->context... - KEY */ if(ctx->context) { sc = (oc_sha1_ctx *)ctx->context; if(sc->dev_ctx) free(sc->dev_ctx); free(ctx->context); } /* The caller will check to see if ctx->context == NULL */ ctx->context_len = sizeof(oc_sha1_ctx); ctx->context = malloc(sizeof(oc_sha1_ctx)); if(ctx->context == NULL) return CKR_HOST_MEMORY; memset(ctx->context, 0, ctx->context_len); sc = (oc_sha1_ctx *)ctx->context; sc->hash_len = SHA1_HASH_SIZE; sc->message_part = SHA_MSG_PART_ONLY; /* This is libica's LENGTH_SHA_CONTEXT */ sc->dev_ctx = malloc(LENGTH_SHA_CONTEXT); if(sc->dev_ctx == NULL){ free(ctx->context); return CKR_HOST_MEMORY; } memset(sc->dev_ctx, 0, LENGTH_SHA_CONTEXT); return CKR_OK; } CK_RV token_specific_sha_update( DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len ) { unsigned int rc, i, fill_size = 0; oc_sha1_ctx *oc_sha_ctx = (oc_sha1_ctx *)ctx->context; SHA_CONTEXT *ica_sha_ctx = (SHA_CONTEXT *)oc_sha_ctx->dev_ctx; if( !ctx ) return CKR_OPERATION_NOT_INITIALIZED; if( !in_data ) return CKR_FUNCTION_FAILED; if( ctx->multi == TRUE ){ if (oc_sha_ctx->tail_len == 64) { /* Submit the filled out save buffer */ if( icaSha1( adapter_handle, ica_sha_ctx->runningLength == 0 ? SHA_MSG_PART_FIRST : SHA_MSG_PART_MIDDLE, 64, oc_sha_ctx->tail, LENGTH_SHA_CONTEXT, ica_sha_ctx, &oc_sha_ctx->hash_len, oc_sha_ctx->hash)) return CKR_FUNCTION_FAILED; oc_sha_ctx->tail_len = 0; } /* libICA (and SHA1) demands that if this is a PART_FIRST or a * PART_MIDDLE operation, the amount of data passed in * must be a multiple of 64 bytes. - KEY */ if( ica_sha_ctx->runningLength == 0 && oc_sha_ctx->tail_len == 0) { oc_sha_ctx->message_part = SHA_MSG_PART_FIRST; /* Just copying the last <64 bytes will not work in the case * of a user who SHA's a large chunk of data in 64 byte * pieces because we need to cache the last 64 bytes so that * we're not stuck with 0 bytes when the MSG_PART_FINAL * comes in. - KEY */ if (!(in_data_len % 64)) { oc_sha_ctx->tail_len = 64; memcpy(oc_sha_ctx->tail, in_data + in_data_len - 64, 64); in_data_len -= 64; } else oc_sha_ctx->tail_len = in_data_len & 0x3f; if(oc_sha_ctx->tail_len < 64) { in_data_len &= ~0x3f; memcpy(oc_sha_ctx->tail, in_data + in_data_len, oc_sha_ctx->tail_len); } } else if( ica_sha_ctx->runningLength == 0 && oc_sha_ctx->tail_len > 0 ) { /* Here we need to fill out the temporary tail buffer until * it has 64 bytes in it, then call icaSha1 on that buffer. * If there weren't enough bytes passed in to fill it out, * just copy in what we can and return success without calling * icaSha1. - KEY */ fill_size = 64 - oc_sha_ctx->tail_len; if(fill_size < in_data_len) { memcpy(oc_sha_ctx->tail + oc_sha_ctx->tail_len, in_data, fill_size); /* Submit the filled out save buffer */ if( icaSha1( adapter_handle, (unsigned int)SHA_MSG_PART_FIRST, (unsigned int)64, oc_sha_ctx->tail, (unsigned int)LENGTH_SHA_CONTEXT, ica_sha_ctx, &oc_sha_ctx->hash_len, oc_sha_ctx->hash)) return CKR_FUNCTION_FAILED; } else { memcpy(oc_sha_ctx->tail + oc_sha_ctx->tail_len, in_data, in_data_len); oc_sha_ctx->tail_len += in_data_len; return CKR_OK; } /* We had to use 'fill_size' bytes from in_data to fill out the * empty part of save data, so adjust in_data_len */ in_data_len -= fill_size; oc_sha_ctx->tail_len = in_data_len & 0x3f; if(oc_sha_ctx->tail_len) { memcpy(oc_sha_ctx->tail, in_data + fill_size, oc_sha_ctx->tail_len); in_data_len &= ~0x3f; } } else if( ica_sha_ctx->runningLength > 0 ) { oc_sha_ctx->message_part = SHA_MSG_PART_MIDDLE; if(oc_sha_ctx->tail_len) { fill_size = 64 - oc_sha_ctx->tail_len; if(fill_size < in_data_len) { memcpy(oc_sha_ctx->tail + oc_sha_ctx->tail_len, in_data, fill_size); /* Submit the filled out save buffer */ if( icaSha1( adapter_handle, (unsigned int)oc_sha_ctx->message_part, (unsigned int)64, oc_sha_ctx->tail, (unsigned int)LENGTH_SHA_CONTEXT, ica_sha_ctx, &oc_sha_ctx->hash_len, oc_sha_ctx->hash)) return CKR_FUNCTION_FAILED; } else { memcpy(oc_sha_ctx->tail + oc_sha_ctx->tail_len, in_data, in_data_len); oc_sha_ctx->tail_len += in_data_len; return CKR_OK; } /* We had to use some of the data from in_data to fill out the * empty part of save data, so adjust in_data_len */ in_data_len -= fill_size; oc_sha_ctx->tail_len = in_data_len & 0x3f; if(oc_sha_ctx->tail_len) { memcpy(oc_sha_ctx->tail, in_data + fill_size, oc_sha_ctx->tail_len); in_data_len &= ~0x3f; } } else { /* This is the odd case, where we need to go ahead and * send the first X * 64 byte chunks in to be processed * and copy the last <64 byte area into the tail. -KEY */ /* Just copying the last <64 bytes will not work in the case * of a user who SHA's a large chunk of data in 64 byte * pieces because we need to cache the last 64 bytes so that * we're not stuck with 0 bytes when the MSG_PART_FINAL * comes in. - KEY */ if (!(in_data_len % 64)) { oc_sha_ctx->tail_len = 64; memcpy(oc_sha_ctx->tail, in_data + in_data_len - 64, 64); in_data_len -= 64; } else oc_sha_ctx->tail_len = in_data_len & 0x3f; if( oc_sha_ctx->tail_len < 64) { in_data_len &= ~0x3f; memcpy(oc_sha_ctx->tail, in_data + in_data_len, oc_sha_ctx->tail_len); } } } } else { /* ctx->multi == FALSE, but we've run previously. That's * our signal that this is the last part -KEY */ if( ica_sha_ctx->runningLength > 0 ) oc_sha_ctx->message_part = SHA_MSG_PART_FINAL; else oc_sha_ctx->message_part = SHA_MSG_PART_ONLY; } if( in_data_len || oc_sha_ctx->message_part == SHA_MSG_PART_FINAL ) { if( icaSha1( adapter_handle, (unsigned int)oc_sha_ctx->message_part, (unsigned int)in_data_len, in_data + fill_size, (unsigned int)LENGTH_SHA_CONTEXT, ica_sha_ctx, &oc_sha_ctx->hash_len, oc_sha_ctx->hash)) return CKR_FUNCTION_FAILED; } return CKR_OK; } CK_RV token_specific_sha_final( DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { CK_RV rv = CKR_OK; oc_sha1_ctx *oc_sha_ctx = (oc_sha1_ctx *)ctx->context; int copy_len = MIN(*out_data_len, LENGTH_SHA_HASH); if( !ctx ) return CKR_OPERATION_NOT_INITIALIZED; if( !out_data || (*out_data_len < LENGTH_SHA_HASH) ) return CKR_FUNCTION_FAILED; if( oc_sha_ctx->message_part != SHA_MSG_PART_FINAL && oc_sha_ctx->message_part != SHA_MSG_PART_ONLY) { /* Finalize the SHA operation; tell update that this multi-part * operation is done. -KEY */ ctx->multi = FALSE; token_specific_sha_update(ctx, oc_sha_ctx->tail, oc_sha_ctx->tail_len); } memcpy(out_data, oc_sha_ctx->hash, copy_len); *out_data_len = copy_len; /* ctx->context is freed inside digest_mgr_cleanup - KEY */ free(oc_sha_ctx->dev_ctx); return rv; } #ifndef NOAES /* If you'd like openssl AES support, install opensl 0.9.7, edit * usr/lib/pkcs11/ica_stdll/Makefile.am and remove the -DNOAES CFLAG. - KEY */ CK_RV token_specific_aes_key_gen( CK_BYTE *key, CK_ULONG len ) { return rng_generate(key, len); } CK_RV token_specific_aes_ecb( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_ULONG key_len, CK_BYTE encrypt) { AES_KEY ssl_aes_key; int i; /* There's a previous check that in_data_len % AES_BLOCK_SIZE == 0, * so this is fine */ CK_ULONG loops = (CK_ULONG)(in_data_len/AES_BLOCK_SIZE); memset( &ssl_aes_key, 0, sizeof(AES_KEY)); // AES_ecb_encrypt encrypts only a single block, so we have to break up the // input data here if (encrypt) { AES_set_encrypt_key((unsigned char *)key_value, (key_len*8), &ssl_aes_key); for( i=0; iulValueLen > 256) || (prime_attr->ulValueLen < 64)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } dh = DH_new() ; if (dh == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Create and init BIGNUM structs to stick in the DH struct bn_p = BN_new(); bn_g = BN_new(); if (bn_g == NULL || bn_p == NULL) { if (bn_g) BN_free(bn_g); if (bn_p) BN_free(bn_p); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } BN_init(bn_p); BN_init(bn_g); // Convert from strings to BIGNUMs and stick them in the DH struct BN_bin2bn((char *)prime_attr->pValue, prime_attr->ulValueLen, bn_p); dh->p = bn_p; BN_bin2bn((char *)base_attr->pValue, base_attr->ulValueLen, bn_g); dh->g = bn_g; // Generate the DH Key if (!DH_generate_key(dh)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Extract the public and private key components from the DH struct, // and insert them in the publ_tmpl and priv_tmpl // // pub_key // //temp_bn = BN_new(); temp_bn = dh->pub_key; temp_bn_len = BN_num_bytes(temp_bn); temp_byte = malloc(temp_bn_len); temp_bn_len = BN_bn2bin(temp_bn, temp_byte); rc = build_attribute( CKA_VALUE, temp_byte, temp_bn_len, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( publ_tmpl, temp_attr ); free(temp_byte); // // priv_key // //temp_bn = BN_new(); temp_bn = dh->priv_key; temp_bn_len = BN_num_bytes(temp_bn); temp_byte = malloc(temp_bn_len); temp_bn_len = BN_bn2bin(temp_bn, temp_byte); rc = build_attribute( CKA_VALUE, temp_byte, temp_bn_len, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); free(temp_byte); // Update CKA_VALUE_BITS attribute in the private key value_bits_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); value_bits_attr->type = CKA_VALUE_BITS; value_bits_attr->ulValueLen = sizeof(CK_ULONG); value_bits_attr->pValue = (CK_BYTE *)value_bits_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_bits_attr->pValue = 8*temp_bn_len; template_update_attribute( priv_tmpl, value_bits_attr ); // Add prime and base to the private key template rc = build_attribute( CKA_PRIME,(char *)prime_attr->pValue, prime_attr->ulValueLen, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); rc = build_attribute( CKA_BASE,(char *)base_attr->pValue, base_attr->ulValueLen, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); // Cleanup DH key DH_free(dh) ; return CKR_OK ; } /* end token_specific_dh_key_pair_gen() */ #endif /* #ifndef NODH */ MECH_LIST_ELEMENT mech_list[] = { { CKM_RSA_PKCS_KEY_PAIR_GEN, 512, 2048, CKF_HW | CKF_GENERATE_KEY_PAIR }, #if !(NODSA) { CKM_DSA_KEY_PAIR_GEN, 512, 1024, CKF_HW | CKF_GENERATE_KEY_PAIR }, #endif { CKM_DES_KEY_GEN, 8, 8, CKF_HW | CKF_GENERATE }, { CKM_DES3_KEY_GEN, 24, 24, CKF_HW | CKF_GENERATE }, #if !(NOCDMF) { CKM_CDMF_KEY_GEN, 0, 0, CKF_HW | CKF_GENERATE }, #endif { CKM_RSA_PKCS, 512, 2048, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP | CKF_SIGN | CKF_VERIFY | CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER }, #if !(NOX509) { CKM_RSA_X_509, 512, 2048, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP | CKF_SIGN | CKF_VERIFY | CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER }, #endif #if !(NOMD2) { CKM_MD2_RSA_PKCS, 512, 2048, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NOMD5) { CKM_MD5_RSA_PKCS, 512, 2048, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NOSHA1) { CKM_SHA1_RSA_PKCS, 512, 2048, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NODSA) { CKM_DSA, 512, 1024, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif /* Begin code contributed by Corrent corp. */ #if !(NODH) { CKM_DH_PKCS_DERIVE, 512, 2048, CKF_HW | CKF_DERIVE }, { CKM_DH_PKCS_KEY_PAIR_GEN, 512, 2048, CKF_HW | CKF_GENERATE_KEY_PAIR }, #endif /* End code contributed by Corrent corp. */ { CKM_DES_ECB, 8, 8, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_DES_CBC, 8, 8, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_DES_CBC_PAD, 8, 8, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, #if !(NOCDMF) { CKM_CDMF_ECB, 0, 0, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_CDMF_CBC, 0, 0, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, #endif { CKM_DES3_ECB, 24, 24, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_DES3_CBC, 24, 24, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_DES3_CBC_PAD, 24, 24, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, #if !(NOSHA1) { CKM_SHA_1, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_SHA_1_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SHA_1_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SHA256, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_SHA256_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SHA256_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NOMD2) { CKM_MD2, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_MD2_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_MD2_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NOMD5) { CKM_MD5, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_MD5_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_MD5_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif { CKM_SSL3_PRE_MASTER_KEY_GEN, 48, 48, CKF_HW | CKF_GENERATE }, { CKM_SSL3_MASTER_KEY_DERIVE, 48, 48, CKF_HW | CKF_DERIVE }, { CKM_SSL3_KEY_AND_MAC_DERIVE, 48, 48, CKF_HW | CKF_DERIVE }, { CKM_SSL3_MD5_MAC, 384, 384, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SSL3_SHA1_MAC, 384, 384, CKF_HW | CKF_SIGN | CKF_VERIFY }, #if !(NOAES) { CKM_AES_KEY_GEN, 16, 32, CKF_HW }, { CKM_AES_ECB, 16, 32, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_AES_CBC, 16, 32, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_AES_MAC, 16, 32, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_AES_MAC_GENERAL, 16, 32, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_AES_CBC_PAD, 16, 32, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, #endif #if !(NORIPE) { CKM_RIPEMD128, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_RIPEMD128_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_RIPEMD128_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_RIPEMD160, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_RIPEMD160_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_RIPEMD160_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif }; CK_ULONG mech_list_len = (sizeof(mech_list) / sizeof(MECH_LIST_ELEMENT)); CK_RV token_specific_get_mechanism_list(CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount) { int rc; /* common/mech_list.c */ rc = ock_generic_get_mechanism_list(pMechanismList, pulCount); return rc; } CK_RV token_specific_get_mechanism_info(CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo) { int rc; /* common/mech_list.c */ rc = ock_generic_get_mechanism_info(type, pInfo); return rc; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/ica_stdll/tok_struct.h.in0000640000175000017500000004020411327631345022341 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2002 */ // SAB FIXME need to figure out a better way... // // to get the variant dependency out #ifndef __TOK_STRUCT_H #define __TOK_STRUCT_H #include #include "tok_spec_struct.h" token_spec_t token_specific = { "@DB_PATH@/lite", "lite", "ICA_STDLL_Debug", &token_specific_init, &tok_slot2local, &token_rng, &token_specific_session, &token_specific_final, &token_specific_des_key_gen, &token_specific_des_ecb, &token_specific_des_cbc, &token_specific_tdes_ecb, &token_specific_tdes_cbc, &token_specific_rsa_decrypt, &token_specific_rsa_encrypt, &token_specific_rsa_generate_keypair, #ifndef NODH // DH &token_specific_dh_pkcs_derive, &token_specific_dh_pkcs_key_pair_gen, #endif // SHA &token_specific_sha_init, &token_specific_sha_update, &token_specific_sha_final, /* SHA256 */ NULL, NULL, NULL, /* SHA384 */ NULL, NULL, NULL, /* SHA512 */ NULL, NULL, NULL, #ifndef NOAES &token_specific_aes_key_gen, &token_specific_aes_ecb, &token_specific_aes_cbc, #endif &token_specific_get_mechanism_list, &token_specific_get_mechanism_info }; #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/ica_stdll/Makefile.am0000640000175000017500000000330711327631345021421 0ustar jfjfnobase_lib_LTLIBRARIES = opencryptoki/stdll/libpkcs11_ica.la opencryptoki_stdll_libpkcs11_ica_la_LDFLAGS = $(LCRYPTO) \ $(ICA_LIB_DIRS) -nostartfiles -shared -Wl,-Bsymbolic \ -Wl,-soname,PKCS11_ICA.so.1 -lc -lpthread -ldl -lica # Not all versions of automake observe libname_CFLAGS opencryptoki_stdll_libpkcs11_ica_la_CFLAGS = -DSPINXPL -DDEV \ -D_THREAD_SAFE -fPIC -DSHALLOW=0 -DSWTOK=0 -DLITE=1 -DNOCDMF -DNOMD2 \ -DNODSA -DNOAES -DNODH -DNORIPE -DSTDLL_NAME=\"icatok\" # Not all versions of automake observe libname_CFLAGS AM_CFLAGS = -DSPINXPL -DDEV -D_THREAD_SAFE -fPIC -DSHALLOW=0 -DSWTOK=0 \ -DLITE=1 -DNOCDMF -DNOMD2 -DNODSA -DNOAES -DNODH -DNORIPE opencryptoki_stdll_libpkcs11_ica_la_SOURCES= ../common/asn1.c \ ../common/cert.c ../common/hwf_obj.c ../common/dp_obj.c \ ../common/data_obj.c ../common/decr_mgr.c ../common/dig_mgr.c \ ../common/encr_mgr.c ../common/globals.c ../common/loadsave.c \ ../common/key.c ../common/key_mgr.c ../common/mech_des.c \ ../common/mech_des3.c ../common/mech_md5.c ../common/mech_md2.c \ ../common/mech_rng.c ../common/mech_rsa.c ../common/mech_sha.c \ ../common/mech_ssl3.c ../common/new_host.c ../common/obj_mgr.c \ ../common/object.c ../common/sess_mgr.c ../common/sign_mgr.c \ ../common/template.c ../common/utility.c ../common/verify_mgr.c \ ../common/log.c ../common/mech_list.c ica_specific.c INCLUDES = $(ICA_INC_DIRS) -I/usr/include \ -I. -I../../../include/pkcs11/stdll -I../../../include/pkcs11 \ -I../common -I../../../ica/inc -I../../../../ica/include \ -I.. -I../../../../ica/src/inc install-data-local: mkdir -p $(DESTDIR)/$(libdir)/opencryptoki/stdll cd $(DESTDIR)/$(libdir)/opencryptoki/stdll && rm -f PKCS11_ICA.so && \ ln -sf libpkcs11_ica.so PKCS11_ICA.so opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/bcom_stdll/0000751000175000017500000000000011327631345017546 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/lib/pkcs11/bcom_stdll/bcom_specific.c0000640000175000017500000013436011327631345022506 0ustar jfjf#include #include // for memcmp() et al #include #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "args.h" #include "errno.h" #include "tok_specific.h" #include "tok_struct.h" #if 0 #include #include #include #endif #ifndef NOAES #include #endif #ifndef NODH #include #endif #include #include #include // SAB Bcom Add #include "ubsio.h" //#include "unix_wrap.h" #include "ubsec.h" #include "ubsec_lib.h" // SAB end Bcom Add typedef unsigned int U32_t; pthread_mutex_t rngmtx = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t nextmutex = PTHREAD_MUTEX_INITIALIZER; unsigned int rnginitialized=0; CK_CHAR manuf[] = "IBM Corp."; CK_CHAR model[] = "IBM BComHack"; CK_CHAR descr[] = "IBM PKCS#11 Bcom token"; CK_CHAR label[] = "IBM OS PKCS#11 "; /* Broadcom needs a non null pointer even for keys it doesn't use */ unsigned char ZERO_KEY[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; /* Broadcom only implements CBC mode, to do ECB we need a zero IV */ unsigned char ZERO_IV[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; #include int bcomfd; // SAB FIXME Broadcom adapter file descriptor void bignum_swapper(char *s, char *d, int size); void swapper(char *s, char *d, int size); CK_RV token_specific_session(CK_SLOT_ID slotid) { return CKR_OK; } CK_RV token_rng(CK_BYTE *output, CK_ULONG bytes) { #if 1 int bits = 0; int rc = 1; bits = bytes*8; rc = rng_ioctl(bcomfd, UBSEC_RNG_SHA1, output, &bits); if ( rc != 0) { return CKR_FUNCTION_FAILED; } return CKR_OK; #else /* XXX change this to call Broadcom randomness */ int ranfd; int r_len,total_len=0; ranfd = open("/dev/urandom",O_RDONLY); if (ranfd >= 0 ){ do { r_len = read(ranfd,output+total_len,bytes-total_len); total_len += r_len; } while( total_len < bytes); return CKR_OK; } else { return CKR_FUNCTION_FAILED; } #endif } // convert pkcs slot number to local representation int tok_slot2local(CK_SLOT_ID snum) { return 1; } CK_RV token_specific_init(char * Correlator,CK_SLOT_ID SlotNumber) { bcomfd = ubsec_open(UBSEC_KEY_DEVICE); return CKR_OK; } CK_RV token_specific_final() { ubsec_close(bcomfd); return CKR_OK; } CK_RV token_specific_des_key_gen(CK_BYTE *des_key,CK_ULONG _len) { // Nothing different to do for DES or TDES here as this is just // random data... Validation handles the rest rng_generate(des_key,_len); // we really need to validate the key for parity etc... // we should do that here... The caller validates the single des keys // against the known and suspected poor keys.. return CKR_OK; } CK_RV token_specific_des_ecb(CK_BYTE * in_data, CK_ULONG in_data__len, CK_BYTE *out_data, CK_ULONG *out_data__len, CK_BYTE *key_value, CK_BYTE encrypt) { CK_ULONG rc; unsigned char in_block_data[8]; unsigned char out_block_data[8]; int i,j; int ret; ubsec_crypto_context_t ctx; // Initialize the crypto contexte ubsec_crypto_init(key_value, ZERO_KEY, ZERO_KEY, ZERO_KEY, UBSEC_DES, 0, &ctx); // the des decrypt will only fail if the data _length is not evenly divisible // by 8 if (in_data__len % 8 ){ st_err_log(11, __FILE__, __LINE__); rc = CKR_DATA_LEN_RANGE; goto done; } // Do the encryption or decryption // Broadcom only does CBC DES, so to do ECB we need to go DES block // by DES block, with IV = 0 if (encrypt) { for (i=0; i= RNG_BUF_SIZE){ rng_generate(buffer,sizeof(buffer)); used = 0; } byte = buffer[used++]; pthread_mutex_unlock(&nextmutex); return((unsigned char)byte); } void swapper(char *s, char *d, int size) { int i=0; int j=size; for(i=0;in = (U32_t *)malloc(MAX_PUBLIC_KEY_BYTES*sizeof(unsigned char)); memset(rsa_pub->n, 0, MAX_PUBLIC_KEY_BYTES); rsa_pub->n_len = 0; rsa_pub->e = (U32_t *)malloc(MAX_PUBLIC_KEY_BYTES*sizeof(unsigned char)); memset(rsa_pub->e, 0, MAX_PUBLIC_KEY_BYTES); rsa_pub->e_len = 0; if (! (rsa_pub->n && rsa_pub->e)) { goto error; } *out_rsa_pub = rsa_pub; return 0; error: if (rsa_pub) { if (rsa_pub->n) { free(rsa_pub->n); } if (rsa_pub->e) { free(rsa_pub->e); } free (rsa_pub); } return -1; } /* * Convert from the local PKCS11 template representation to * the BCOM representation. * This function allocates memory for a BCOM_RSA_PUB_KEY_t * object, which must be freed by a call to bcom_rsa__pub_free */ int bcom_rsa_pub_from_object(OBJECT *key_obj, BCOM_RSA_PUB_KEY_t **pubKey) { CK_BBOOL rc; CK_ATTRIBUTE *obj_modulus = NULL; CK_ATTRIBUTE *obj_pub_exp = NULL; BCOM_RSA_PUB_KEY_t *mexp; BCOM_RSA_PUB_KEY_t *tPubKey; /* retreive the RSA modulus and public exponent from the PKCS11 template */ rc = template_attribute_find( key_obj->template, CKA_MODULUS, &obj_modulus ); rc &= template_attribute_find( key_obj->template, CKA_PUBLIC_EXPONENT, &obj_pub_exp ); if (rc == FALSE) { return -1; } /* allocate memory for a Broadom representation */ rc = bcom_rsa_pub_new(&tPubKey); if (rc != 0) { pubKey = 0; return -1; } tPubKey->n_len = obj_modulus->ulValueLen; tPubKey->e_len = obj_pub_exp->ulValueLen; bignum_swapper(obj_modulus->pValue, (unsigned char *)tPubKey->n, tPubKey->n_len); bignum_swapper(obj_pub_exp->pValue, (unsigned char *)tPubKey->e, tPubKey->e_len); *pubKey = tPubKey; return 0; } /* XXX revisite this to make sure I got if right */ void bcom_rsa_pub_free(BCOM_RSA_PUB_KEY_t **pubKey) { BCOM_RSA_PUB_KEY_t *tPubKey; if (pubKey) { tPubKey = *pubKey; if (tPubKey) { if (tPubKey->e) { free(tPubKey->e); } if (tPubKey->n) { free(tPubKey->n); } free(tPubKey); } *pubKey = 0; } } int bcom_rsa_crt_new(BCOM_RSA_CRT_KEY_t **out_rsa_priv) { int rc = -1; BCOM_RSA_CRT_KEY_t *rsa_priv; rsa_priv = (BCOM_RSA_CRT_KEY_t *)malloc(sizeof(BCOM_RSA_CRT_KEY_t)); if (! rsa_priv) { goto error; } rsa_priv->n = (U32_t *)malloc(MAX_PUBLIC_KEY_BYTES); memset(rsa_priv->n, 0, MAX_PUBLIC_KEY_BYTES); rsa_priv->d = (U32_t *)malloc(MAX_PUBLIC_KEY_BYTES); memset(rsa_priv->d, 0, MAX_PUBLIC_KEY_BYTES); rsa_priv->d_len = 0; rsa_priv->p = (U32_t *)malloc(MAX_PUBLIC_KEY_BYTES); memset(rsa_priv->p, 0, MAX_PUBLIC_KEY_BYTES); rsa_priv->p_len = 0; rsa_priv->q = (U32_t *)malloc(MAX_PUBLIC_KEY_BYTES); memset(rsa_priv->q, 0, MAX_PUBLIC_KEY_BYTES); rsa_priv->q_len = 0; rsa_priv->dp = (U32_t *)malloc(MAX_PUBLIC_KEY_BYTES); memset(rsa_priv->dp, 0, MAX_PUBLIC_KEY_BYTES); rsa_priv->dp_len = 0; rsa_priv->dq = (U32_t *)malloc(MAX_PUBLIC_KEY_BYTES); memset(rsa_priv->dq, 0, MAX_PUBLIC_KEY_BYTES); rsa_priv->dq_len = 0; rsa_priv->pinv = (U32_t *)malloc(MAX_PUBLIC_KEY_BYTES); memset(rsa_priv->pinv, 0, MAX_PUBLIC_KEY_BYTES); rsa_priv->pinv_len = 0; if (! (rsa_priv->p && rsa_priv->q && rsa_priv->dp && rsa_priv->dq && rsa_priv->pinv)) { goto error; } *out_rsa_priv = rsa_priv; return 0; error: if (rsa_priv) { if (rsa_priv->p) { free(rsa_priv->p); } if (rsa_priv->q) { free(rsa_priv->q); } if (rsa_priv->dp) { free(rsa_priv->dp); } if (rsa_priv->dq) { free(rsa_priv->dq); } if (rsa_priv->pinv) { free(rsa_priv->pinv); } free (rsa_priv); } return -1; } int bcom_rsa_crt_key_from_object(OBJECT *key_obj, BCOM_RSA_CRT_KEY_t **privKey) { CK_ATTRIBUTE *obj_modulus = NULL; CK_ATTRIBUTE *obj_priv_exp = NULL; CK_ATTRIBUTE *obj_prime1 = NULL; CK_ATTRIBUTE *obj_prime2 = NULL; CK_ATTRIBUTE *obj_priv_exp1 = NULL; CK_ATTRIBUTE *obj_priv_exp2 = NULL; CK_ATTRIBUTE *obj_coeff = NULL; CK_BBOOL rc; BCOM_RSA_CRT_KEY_t *tPrivKey; rc = template_attribute_find( key_obj->template, CKA_MODULUS, &obj_modulus ); rc &= template_attribute_find( key_obj->template, CKA_PRIVATE_EXPONENT, &obj_priv_exp ); rc &= template_attribute_find( key_obj->template, CKA_PRIME_1, &obj_prime1 ); rc &= template_attribute_find( key_obj->template, CKA_PRIME_2, &obj_prime2 ); rc &= template_attribute_find( key_obj->template, CKA_EXPONENT_1, &obj_priv_exp1 ); rc &= template_attribute_find( key_obj->template, CKA_EXPONENT_2, &obj_priv_exp2 ); rc &= template_attribute_find( key_obj->template, CKA_COEFFICIENT, &obj_coeff ); if (!obj_prime1 || !obj_prime2 || !obj_priv_exp1 || !obj_priv_exp2 || !obj_coeff || !obj_modulus) { return -1; } rc = bcom_rsa_crt_new(&tPrivKey); if (rc != 0) { return -1; } tPrivKey->n_len = obj_modulus->ulValueLen; bignum_swapper(obj_modulus->pValue, (unsigned char *)tPrivKey->n, tPrivKey->n_len); tPrivKey->d_len = obj_priv_exp->ulValueLen; bignum_swapper(obj_priv_exp->pValue, (unsigned char *)tPrivKey->d, tPrivKey->d_len); tPrivKey->p_len = obj_prime1->ulValueLen; bignum_swapper(obj_prime1->pValue,(unsigned char *) tPrivKey->p, tPrivKey->p_len); tPrivKey->q_len = obj_prime2->ulValueLen; bignum_swapper(obj_prime2->pValue, (unsigned char *)tPrivKey->q, tPrivKey->q_len); tPrivKey->dp_len = obj_priv_exp1->ulValueLen; bignum_swapper(obj_priv_exp1->pValue, (unsigned char *)tPrivKey->dp, tPrivKey->dp_len); tPrivKey->dq_len = obj_priv_exp2->ulValueLen; bignum_swapper(obj_priv_exp2->pValue, (unsigned char *)tPrivKey->dq, tPrivKey->dq_len); tPrivKey->pinv_len = obj_coeff->ulValueLen; bignum_swapper(obj_coeff->pValue, (unsigned char *)tPrivKey->pinv, tPrivKey->pinv_len); *privKey = tPrivKey; return 0; } /* XXX revisite this to make sure I got it right */ void bcom_rsa_crt_free(BCOM_RSA_CRT_KEY_t **crtKey) { BCOM_RSA_CRT_KEY_t *tCrtKey; if (crtKey) { tCrtKey = *crtKey; if (tCrtKey) { if (tCrtKey->d) { free(tCrtKey->d); } if (tCrtKey->p) { free(tCrtKey->p); } if (tCrtKey->q) { free(tCrtKey->q); } if (tCrtKey->dp) { free(tCrtKey->dp); } if (tCrtKey->dq) { free(tCrtKey->dq); } if (tCrtKey->pinv) { free(tCrtKey->pinv); } free(tCrtKey); } *crtKey = 0; } } CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) { CK_ATTRIBUTE * publ_exp = NULL; CK_ATTRIBUTE * attr = NULL; CK_ULONG mod_bits; CK_BBOOL flag; CK_RV rc; CK_ULONG BN_Length; BCOM_RSA_CRT_KEY_t * rsa_priv; BCOM_RSA_PUB_KEY_t * rsa_pub; BCOM_RSA_CRT_KEY_t * swapped_rsa_priv; BCOM_RSA_PUB_KEY_t * swapper_rsa_pub; int ret; CK_ATTRIBUTE * my_pub_exp = NULL; flag = template_attribute_find( publ_tmpl, CKA_MODULUS_BITS, &attr ); if (!flag){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; // should never happen } mod_bits = *(CK_ULONG *)attr->pValue; // we don't support less than 512 bit keys or more than 2048 bit keys if (mod_bits < 512 || mod_bits > 2048) { st_err_log(19, __FILE__, __LINE__); return CKR_KEY_SIZE_RANGE; } ret = bcom_rsa_pub_new(&rsa_pub); if (ret != 0) { st_err_log(40 /* XXX ??? */, __FILE__, __LINE__); rc = CKR_GENERAL_ERROR; goto done; } /* get the value of the public exponent e from the template. if I don't err, Cryptoki states that e should always be given. XXX if not check flag returned to see if attribute exists ? */ flag = template_attribute_find( publ_tmpl, CKA_PUBLIC_EXPONENT, &publ_exp ); if (!flag){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } /* PKCS11 defines big integers in big-endianess, Broadcom uses little-endianess */ swapper(publ_exp->pValue, (unsigned char*)rsa_pub->e, publ_exp->ulValueLen); rsa_pub->e_len = ubsec_bytes_to_bits((unsigned char *)rsa_pub->e, publ_exp->ulValueLen); ret = bcom_rsa_crt_new(&rsa_priv); if (ret != 0) { st_err_log(40 /* XXX ??? */, __FILE__, __LINE__); rc = CKR_GENERAL_ERROR; goto done; } // rsa = foo_RSA_generate_key(mod_bits, three, NULL, NULL); ret = ubsec_rsakeygen(bcomfd, mod_bits, (unsigned char*)rsa_pub->e, &(rsa_pub->e_len), (unsigned char*)rsa_priv->p, &(rsa_priv->p_len), (unsigned char*)rsa_priv->q, &(rsa_priv->q_len), (unsigned char*)rsa_pub->n, &(rsa_pub->n_len), (unsigned char*)rsa_priv->d, &(rsa_priv->d_len), (unsigned char*)rsa_priv->dp, &(rsa_priv->dp_len), (unsigned char*)rsa_priv->dq, &(rsa_priv->dq_len), (unsigned char*)rsa_priv->pinv, &(rsa_priv->pinv_len)); if (ret != 0) { st_err_log(40 /* XXX ??? */, __FILE__, __LINE__); rc = CKR_GENERAL_ERROR; goto done; } #if PRINT_BIGNUM fprintf(stderr, " ========= generated parameters ===========\n"); fprintf(stderr, "e:\n"); PrintNumber(stderr, rsa_pub->e, rsa_pub->e_len, 1); fprintf(stderr, "n:\n"); PrintNumber(stderr, rsa_pub->n, rsa_pub->n_len, 1); fprintf(stderr, "p:\n"); PrintNumber(stderr, rsa_priv->p, rsa_priv->p_len, 1); fprintf(stderr, "q:\n"); PrintNumber(stderr, rsa_priv->q, rsa_priv->q_len, 1); fprintf(stderr, "d:\n"); PrintNumber(stderr, rsa_priv->d, rsa_priv->d_len, 1); fprintf(stderr, "dp:\n"); PrintNumber(stderr, rsa_priv->dp, rsa_priv->dp_len, 1); fprintf(stderr, "dq:\n"); PrintNumber(stderr, rsa_priv->dq, rsa_priv->dq_len, 1); fprintf(stderr, "pinv:\n"); PrintNumber(stderr, rsa_priv->pinv, rsa_priv->pinv_len, 1); fprintf(stderr, " ==========================================\n"); #endif // Now fill in the key objects objects.. // Swapp the big integers from Broadcom's little-endian to PKCS11 big-endian // public key object // modulus n rc = build_swapped_attribute( CKA_MODULUS, (unsigned char *)rsa_pub->n, ubsec_bits_to_bytes(rsa_pub->n_len), &attr); // length in bytes if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( publ_tmpl, attr ); // public exponent rc = build_swapped_attribute( CKA_PUBLIC_EXPONENT, (unsigned char*)rsa_pub->e, ubsec_bits_to_bytes(rsa_pub->e_len), &attr); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( publ_tmpl, attr ); // local = TRUE flag = TRUE; rc = build_attribute( CKA_LOCAL, &flag, sizeof(CK_BBOOL), &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( publ_tmpl, attr ); /* * now, do the private key */ // Add the modulus to the private key information rc = build_swapped_attribute( CKA_MODULUS, (unsigned char*)rsa_pub->n, ubsec_bits_to_bytes(rsa_pub->n_len) ,&attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); // private exponent rc = build_swapped_attribute( CKA_PRIVATE_EXPONENT, (unsigned char*)rsa_priv->d, ubsec_bits_to_bytes(rsa_priv->d_len), &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); // prime #1: p rc = build_swapped_attribute( CKA_PRIME_1, (unsigned char*)rsa_priv->p, ubsec_bits_to_bytes(rsa_priv->p_len), &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); // prime #2: q rc = build_swapped_attribute( CKA_PRIME_2, (unsigned char*)rsa_priv->q, ubsec_bits_to_bytes(rsa_priv->q_len), &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); // exponent 1: d mod(p-1) rc = build_swapped_attribute( CKA_EXPONENT_1, (unsigned char*)rsa_priv->dp, ubsec_bits_to_bytes(rsa_priv->dp_len), &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); // exponent 2: d mod(q-1) rc = build_swapped_attribute( CKA_EXPONENT_2, (unsigned char*)rsa_priv->dq, ubsec_bits_to_bytes(rsa_priv->dq_len), &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); // CRT coefficient: q_inverse mod(p) rc = build_swapped_attribute( CKA_COEFFICIENT, (unsigned char*)rsa_priv->pinv, ubsec_bits_to_bytes(rsa_priv->pinv_len), &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); // flag TRUE flag = TRUE; rc = build_attribute( CKA_LOCAL, &flag, sizeof(CK_BBOOL), &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); done: if (rsa_pub) { bcom_rsa_pub_free(&rsa_pub); } if (rsa_priv) { bcom_rsa_crt_free(&rsa_priv); } return rc; } CK_RV token_specific_rsa_generate_keypair( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ) { CK_RV rc; rc = os_specific_rsa_keygen(publ_tmpl,priv_tmpl); if (rc != CKR_OK) st_err_log(91, __FILE__, __LINE__); return rc; } CK_RV token_specific_rsa_encrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, OBJECT *key_obj ) { CK_RV rc; BCOM_RSA_PUB_KEY_t *pubKey; int out_len_bits; CK_BYTE *tcipher, *tclear; rc = bcom_rsa_pub_from_object(key_obj, &pubKey); if ( rc != 0) { rc = CKR_FUNCTION_FAILED; goto done; } /* * do some verification on size of in_data_len (make sure < size of n) */ if (in_data_len > pubKey->n_len) { rc = CKR_FUNCTION_FAILED; } /* allocate enough memory (size of modulus) for swapped cleartext and for ciphertext */ tcipher = (CK_BYTE *)malloc(pubKey->n_len); memset(tcipher, 0, pubKey->n_len); tclear = (CK_BYTE *)malloc(pubKey->n_len); memset(tcipher, 0, pubKey->n_len); /* swapp the plaintext to get Broadcom representation */ bignum_swapper(in_data, tclear, pubKey->n_len); /* bytes to bits */ out_len_bits = in_data_len*8; #if PRINT_BIGNUM fprintf(stderr, " ===== parameters used for RSA encrypt =====\n"); fprintf(stderr, "e = "); PrintNumber(stderr, pubKey->e, ubsec_bytes_to_bits((unsigned char *)pubKey->e, pubKey->e_len), 1); fprintf(stderr, "n = ", pubKey->n_len); PrintNumber(stderr, pubKey->n, ubsec_bytes_to_bits((unsigned char *)pubKey->n, pubKey->n_len), 1); fprintf(stderr, "msg = "); PrintNumber(stderr, tclear, ubsec_bytes_to_bits(tclear, in_data_len), 1); fprintf(stderr, " ============================================\n"); #endif rc = rsa_mod_exp_ioctl(bcomfd, tclear, ubsec_bytes_to_bits(tclear, in_data_len), (unsigned char *)pubKey->n, ubsec_bytes_to_bits((unsigned char *)pubKey->n, pubKey->n_len), (unsigned char *)pubKey->e, ubsec_bytes_to_bits((unsigned char *)pubKey->e, pubKey->e_len), tcipher, &out_len_bits); if ( rc != 0 ){ rc = CKR_FUNCTION_FAILED; goto done; } #if PRINT_BIGNUM fprintf(stderr, " ===== parameters used for RSA encrypt =====\n"); fprintf(stderr, "cip = "); PrintNumber(stderr, tcipher, ubsec_bytes_to_bits(tcipher, in_data_len), 1); fprintf(stderr, " ============================================\n"); #endif /* swapp to get back PKCS11 representation */ swapper(tcipher, out_data, in_data_len); rc = CKR_OK; done: if (pubKey) { bcom_rsa_pub_free(&pubKey); } if (tcipher) { free(tcipher); } if (tclear) { free(tclear); } return rc; } CK_RV token_specific_rsa_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, OBJECT * key_obj ) { CK_RV rc; CK_ATTRIBUTE *pkey = NULL; CK_BYTE *tcipher, *tclear; BCOM_RSA_CRT_KEY_t *privKey; int out_len; rc = bcom_rsa_crt_key_from_object(key_obj, &privKey); if (rc != 0) { rc = CKR_FUNCTION_FAILED; goto done; } /* we don't decrypt a message which is longer than the modulus */ if (in_data_len > privKey->n_len) { rc = CKR_FUNCTION_FAILED; goto done; } tcipher = (CK_BYTE *)malloc(privKey->n_len); tclear = (CK_BYTE *)malloc(privKey->n_len); if ( ! tcipher || ! tclear) { rc = CKR_FUNCTION_FAILED; goto done; } /* swapp from PKCS11 endianess to Broadcom endianess */ bignum_swapper(in_data, tcipher, privKey->n_len); #if PRINT_BIGNUM fprintf(stderr, " ===== parameters used for RSA decrypt =====\n"); fprintf(stderr, "p = "); PrintNumber(stderr, privKey->p, ubsec_bytes_to_bits((unsigned char *)privKey->p, privKey->p_len), 1); fprintf(stderr, "q = "); PrintNumber(stderr, privKey->q, ubsec_bytes_to_bits((unsigned char *)privKey->q, privKey->q_len), 1); fprintf(stderr, "cipher to decrypt: cip = "); PrintNumber(stderr, tcipher, ubsec_bytes_to_bits(tcipher, in_data_len), 1); fprintf(stderr, " ============================================\n"); #endif /* bytes to bits for output length */ out_len = in_data_len * 8; rc = rsa_mod_exp_crt_ioctl(bcomfd, tcipher, ubsec_bytes_to_bits(tcipher, in_data_len), (unsigned char *)privKey->pinv, ubsec_bytes_to_bits((unsigned char *)privKey->pinv, privKey->pinv_len), (unsigned char *)privKey->dq, ubsec_bytes_to_bits((unsigned char *)privKey->dq, privKey->dq_len), (unsigned char *)privKey->q, ubsec_bytes_to_bits((unsigned char *)privKey->q, privKey->q_len), (unsigned char *)privKey->dp, ubsec_bytes_to_bits((unsigned char *)privKey->dp, privKey->dp_len), (unsigned char *)privKey->p, ubsec_bytes_to_bits((unsigned char *)privKey->p, privKey->p_len), tclear, &out_len); if (rc != 0) { rc = CKR_FUNCTION_FAILED; goto done; } #if PRINT_BIGNUM fprintf(stderr, " ===== parameters used for RSA decrypt =====\n"); fprintf(stderr, "decryption result: msg = "); PrintNumber(stderr, tclear, ubsec_bytes_to_bits(tclear, in_data_len), 1); fprintf(stderr, " ============================================\n"); #endif swapper(tclear, out_data,in_data_len); rc = CKR_OK; done: if (privKey) { // bcom_rsa_crt_free(&privKey); } return rc; } #if PRINT_BIGNUM int PrintNumber(FILE *ofptr, void *num, unsigned int bits, int xct_mode) { int element = ((ROUNDUP_TO_32_BIT(bits)) / 32) -1; int i = 0; if (element < 1) element = 0; for( ; element >= 0; element--, i++) { if (xct_mode) { fprintf(ofptr, "%08X", ((UBS_UINT32 *)num)[element]); } else { if (((i%8) == 7) && element) fprintf(ofptr, "%08X\n", ((UBS_UINT32 *)num)[element]); else fprintf(ofptr, "%08X ", ((UBS_UINT32 *)num)[element]); } } fprintf(ofptr, "\n"); return 0; } #endif #ifndef NOAES CK_RV token_specific_aes_key_gen( CK_BYTE *key, CK_ULONG len ) { return rng_generate(key, len); } CK_RV token_specific_aes_ecb( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_ULONG key_len, CK_BYTE encrypt) { AES_KEY ssl_aes_key; int i; /* There's a previous check that in_data_len % AES_BLOCK_SIZE == 0, * so this is fine */ CK_ULONG loops = (CK_ULONG)(in_data_len/AES_BLOCK_SIZE); memset( &ssl_aes_key, 0, sizeof(AES_KEY)); // AES_ecb_encrypt encrypts only a single block, so we have to break up the // input data here if (encrypt) { AES_set_encrypt_key((unsigned char *)key_value, (key_len*8), &ssl_aes_key); for( i=0; iulValueLen > 256) || (prime_attr->ulValueLen < 64)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } dh = DH_new() ; if (dh == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Create and init BIGNUM structs to stick in the DH struct bn_p = BN_new(); bn_g = BN_new(); if (bn_g == NULL || bn_p == NULL) { if (bn_g) BN_free(bn_g); if (bn_p) BN_free(bn_p); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } BN_init(bn_p); BN_init(bn_g); // Convert from strings to BIGNUMs and stick them in the DH struct BN_bin2bn((char *)prime_attr->pValue, prime_attr->ulValueLen, bn_p); dh->p = bn_p; BN_bin2bn((char *)base_attr->pValue, base_attr->ulValueLen, bn_g); dh->g = bn_g; // Generate the DH Key if (!DH_generate_key(dh)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Extract the public and private key components from the DH struct, // and insert them in the publ_tmpl and priv_tmpl // // pub_key // //temp_bn = BN_new(); temp_bn = dh->pub_key; temp_bn_len = BN_num_bytes(temp_bn); temp_byte = malloc(temp_bn_len); temp_bn_len = BN_bn2bin(temp_bn, temp_byte); rc = build_attribute( CKA_VALUE, temp_byte, temp_bn_len, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( publ_tmpl, temp_attr ); free(temp_byte); // // priv_key // //temp_bn = BN_new(); temp_bn = dh->priv_key; temp_bn_len = BN_num_bytes(temp_bn); temp_byte = malloc(temp_bn_len); temp_bn_len = BN_bn2bin(temp_bn, temp_byte); rc = build_attribute( CKA_VALUE, temp_byte, temp_bn_len, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); free(temp_byte); // Update CKA_VALUE_BITS attribute in the private key value_bits_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); value_bits_attr->type = CKA_VALUE_BITS; value_bits_attr->ulValueLen = sizeof(CK_ULONG); value_bits_attr->pValue = (CK_BYTE *)value_bits_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_bits_attr->pValue = 8*temp_bn_len; template_update_attribute( priv_tmpl, value_bits_attr ); // Add prime and base to the private key template rc = build_attribute( CKA_PRIME,(char *)prime_attr->pValue, prime_attr->ulValueLen, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); rc = build_attribute( CKA_BASE,(char *)base_attr->pValue, base_attr->ulValueLen, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); // Cleanup DH key DH_free(dh) ; return CKR_OK ; } /* end token_specific_dh_key_pair_gen() */ #endif /* #ifndef NODH */ MECH_LIST_ELEMENT mech_list[] = { { CKM_RSA_PKCS_KEY_PAIR_GEN, 512, 2048, CKF_HW | CKF_GENERATE_KEY_PAIR }, #if !(NODSA) { CKM_DSA_KEY_PAIR_GEN, 512, 1024, CKF_HW | CKF_GENERATE_KEY_PAIR }, #endif { CKM_DES_KEY_GEN, 8, 8, CKF_HW | CKF_GENERATE }, { CKM_DES3_KEY_GEN, 24, 24, CKF_HW | CKF_GENERATE }, #if !(NOCDMF) { CKM_CDMF_KEY_GEN, 0, 0, CKF_HW | CKF_GENERATE }, #endif { CKM_RSA_PKCS, 512, 2048, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP | CKF_SIGN | CKF_VERIFY | CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER }, #if !(NOX509) { CKM_RSA_X_509, 512, 2048, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP | CKF_SIGN | CKF_VERIFY | CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER }, #endif #if !(NOMD2) { CKM_MD2_RSA_PKCS, 512, 2048, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NOMD5) { CKM_MD5_RSA_PKCS, 512, 2048, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NOSHA1) { CKM_SHA1_RSA_PKCS, 512, 2048, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NODSA) { CKM_DSA, 512, 1024, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif /* Begin code contributed by Corrent corp. */ #if !(NODH) { CKM_DH_PKCS_DERIVE, 512, 2048, CKF_HW | CKF_DERIVE }, { CKM_DH_PKCS_KEY_PAIR_GEN, 512, 2048, CKF_HW | CKF_GENERATE_KEY_PAIR }, #endif /* End code contributed by Corrent corp. */ { CKM_DES_ECB, 8, 8, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_DES_CBC, 8, 8, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_DES_CBC_PAD, 8, 8, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, #if !(NOCDMF) { CKM_CDMF_ECB, 0, 0, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_CDMF_CBC, 0, 0, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, #endif { CKM_DES3_ECB, 24, 24, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_DES3_CBC, 24, 24, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_DES3_CBC_PAD, 24, 24, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, #if !(NOSHA1) { CKM_SHA_1, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_SHA_1_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SHA_1_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SHA256, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_SHA256_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SHA256_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NOMD2) { CKM_MD2, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_MD2_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_MD2_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif #if !(NOMD5) { CKM_MD5, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_MD5_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_MD5_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif { CKM_SSL3_PRE_MASTER_KEY_GEN, 48, 48, CKF_HW | CKF_GENERATE }, { CKM_SSL3_MASTER_KEY_DERIVE, 48, 48, CKF_HW | CKF_DERIVE }, { CKM_SSL3_KEY_AND_MAC_DERIVE, 48, 48, CKF_HW | CKF_DERIVE }, { CKM_SSL3_MD5_MAC, 384, 384, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_SSL3_SHA1_MAC, 384, 384, CKF_HW | CKF_SIGN | CKF_VERIFY }, #if !(NOAES) { CKM_AES_KEY_GEN, 16, 32, CKF_HW }, { CKM_AES_ECB, 16, 32, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_AES_CBC, 16, 32, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, { CKM_AES_MAC, 16, 32, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_AES_MAC_GENERAL, 16, 32, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_AES_CBC_PAD, 16, 32, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP }, #endif #if !(NORIPE) { CKM_RIPEMD128, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_RIPEMD128_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_RIPEMD128_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_RIPEMD160, 0, 0, CKF_HW | CKF_DIGEST }, { CKM_RIPEMD160_HMAC, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, { CKM_RIPEMD160_HMAC_GENERAL, 0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY }, #endif }; CK_ULONG mech_list_len = (sizeof(mech_list) / sizeof(MECH_LIST_ELEMENT)); CK_RV token_specific_get_mechanism_list(CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount) { int rc; /* common/mech_list.c */ rc = ock_generic_get_mechanism_list(pMechanismList, pulCount); return rc; } CK_RV token_specific_get_mechanism_info(CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo) { int rc; /* common/mech_list.c */ rc = ock_generic_get_mechanism_info(type, pInfo); return rc; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/bcom_stdll/tok_struct.h.in0000640000175000017500000004036611327631345022536 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2002 */ // SAB FIXME need to figure out a better way... // // to get the variant dependency out #ifndef __TOK_STRUCT_H #define __TOK_STRUCT_H #include #include "tok_spec_struct.h" // #define PK_LITE_DIR "/etc/pkcs11/lite" // // #define PK_DIR PK_LITE_DIR // #define SUB_DIR "lite" // // // #define DBGTAG "ICA_STDLL_Debug" // // // token_spec_t token_specific = { "@DB_PATH@/bcom", "bcom", "BC_STDLL_Debug", &token_specific_init, &tok_slot2local, &token_rng, &token_specific_session, &token_specific_final, &token_specific_des_key_gen, &token_specific_des_ecb, &token_specific_des_cbc, &token_specific_tdes_ecb, &token_specific_tdes_cbc, &token_specific_rsa_decrypt, &token_specific_rsa_encrypt, &token_specific_rsa_generate_keypair, #ifndef NODH // DH &token_specific_dh_pkcs_derive, &token_specific_dh_pkcs_key_pair_gen, #endif // SHA1 NULL, NULL, NULL, /* SHA256 */ NULL, NULL, NULL, /* SHA-384 */ NULL, NULL, NULL, /* SHA-512 */ NULL, NULL, NULL, #ifndef NOAES // AES &token_specific_aes_key_gen, &token_specific_aes_ecb, &token_specific_aes_cbc, #endif &token_specific_get_mechanism_list, &token_specific_get_mechanism_info }; #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/bcom_stdll/Makefile.am0000640000175000017500000000327611327631345021612 0ustar jfjfnobase_lib_LTLIBRARIES = opencryptoki/stdll/libpkcs11_bc.la opencryptoki_stdll_libpkcs11_bc_la_LDFLAGS = $(LCRYPTO) $(BC_LIB_DIRS) \ -nostartfiles -shared -Wl,-Bsymbolic -Wl,-soname,PKCS11_BC.so.1 -lc \ -lpthread -lubsec -ldl VARIANT = -DSHALLOW=0 -DSWTOK=1 -DLITE=0 # Not all versions of automake observe libname_CFLAGS opencryptoki_stdll_libpkcs11_bc_la_CFLAGS = -DSPINXPL -DDEV \ -D_THREAD_SAFE -fPIC $(VARIANT) -DNOCDMF -DNOMD2 -DNODSA -DNOAES \ -DNODH -DDEBUGON -DNORIPE -DSTDLL_NAME=\"bcomtok\" # Not all versions of automake observe libname_CFLAGS AM_CFLAGS = -DSPINXPL -DDEV -D_THREAD_SAFE -fPIC $(VARIANT) -DNOCDMF \ -DNOMD2 -DNODSA -DNOAES -DNODH -DDEBUGON -DNORIPE opencryptoki_stdll_libpkcs11_bc_la_SOURCES = ../common/asn1.c \ ../common/cert.c ../common/hwf_obj.c ../common/dp_obj.c \ ../common/data_obj.c ../common/decr_mgr.c ../common/dig_mgr.c \ ../common/encr_mgr.c ../common/globals.c ../common/loadsave.c \ ../common/key.c ../common/key_mgr.c ../common/mech_des.c \ ../common/mech_des3.c ../common/mech_dh.c ../common/mech_md5.c \ ../common/mech_md2.c ../common/mech_rng.c ../common/mech_rsa.c \ ../common/mech_sha.c ../common/mech_ssl3.c ../common/new_host.c \ ../common/obj_mgr.c ../common/object.c ../common/sess_mgr.c \ ../common/sign_mgr.c ../common/template.c ../common/utility.c \ ../common/verify_mgr.c ../common/log.c ../common/mech_list.c \ bcom_specific.c INCLUDES = $(BC_INC_DIRS) -I/usr/include \ -I. -I../../../include/pkcs11/stdll -I../../../include/pkcs11 \ -I../common -I../../../ica/inc -I../../../../ica/include \ -I.. -I../../../../ica/src/inc install-data-local: cd $(DESTDIR)/$(libdir)/opencryptoki/stdll && rm -f PKCS11_BC.so && \ ln -sf libpkcs11_bc.so PKCS11_BC.so opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/leeds_stdll/0000751000175000017500000000000011327631345017722 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/lib/pkcs11/leeds_stdll/util.c0000751000175000017500000004360711327631345021060 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ // File: util.c // // Generic utility routines // * linked-list managment // #include #if defined(LEEDS_BUILD) #include #include #include "pkcs11types.h" #ifdef PKCS64 #include "pkcs32.h" #endif #include "defs.h" #include "h_extern.h" #define CK_ULONG_32 CK_ULONG #define CK_SSL3_MASTER_KEY_DERIVE_PARAMS_32 CK_SSL3_MASTER_KEY_DERIVE_PARAMS #endif // Routine to get the mechanism parameters length properly // adjusted.... Some mechs with structures as parameters need // to have their structures re-cast to 32bit values, but we // will address these if they ever are supported. CK_ULONG_32 get_mech_parameter_len(CK_MECHANISM_PTR pMech) { switch (pMech->mechanism){ // Mechanisms wich have parameters of type CK_MAC_GENERAL_PARAMS case CKM_MD5_HMAC_GENERAL: case CKM_SHA_1_HMAC_GENERAL: case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: { // These are 32 bit numbers really in 64Bit so we // recase the answer. return(sizeof(CK_ULONG_32)); break; } case CKM_SSL3_KEY_AND_MAC_DERIVE: return (sizeof(CK_SSL3_KEY_MAT_PARAMS)); break; case CKM_SSL3_MASTER_KEY_DERIVE: return (sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS_32)); break; default: return (pMech->ulParameterLen); } } #ifdef _BIG_ENDIAN // Routine to adjust mechanism parameters for endianness // Takes the mechanism, and if it needs adjustment then // it will allocate a new parameter block, copy the // data and adjust it for each mechanism. Returning the // adjusted data. User MUST free the memory if the // returned value is not NULL. CK_VOID_PTR adjust_mech_parameter(CK_MECHANISM_PTR pMech) { switch (pMech->mechanism){ // Mechanisms wich have parameters of type CK_MAC_GENERAL_PARAMS case CKM_MD5_HMAC_GENERAL: case CKM_SHA_1_HMAC_GENERAL: case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: { #if __64BIT__ CK_MAC_GENERAL_PARAMS_PTR_32 nptr; #else CK_MAC_GENERAL_PARAMS_PTR nptr; #endif CK_MAC_GENERAL_PARAMS *ptr; ptr = (CK_MAC_GENERAL_PARAMS *)pMech->pParameter; #if __64BIT__ nptr = (CK_MAC_GENERAL_PARAMS_PTR_32)malloc(sizeof(CK_MAC_GENERAL_PARAMS_32)); #else nptr = (CK_MAC_GENERAL_PARAMS_PTR)malloc((long)sizeof(CK_MAC_GENERAL_PARAMS)); #endif // What does one do if malloc fails here.... For now we assume all // is ok. *nptr = long_reverse((CK_ULONG)*ptr); return nptr; break; } #if __64BIT__ case CKM_SSL3_PRE_MASTER_KEY_GEN: { VERSION *nptr; nptr = (VERSION *)malloc(sizeof(VERSION)); return nptr; } break; #endif default: return NULL; // Not one of the mechanisms which needs adjusting } } #else CK_VOID_PTR adjust_mech_parameter(CK_MECHANISM_PTR pMech) { return NULL; // no endian junk going on here } #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/leeds_stdll/stub.c0000751000175000017500000004175311327631345021060 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ // stub.c // #include #if defined(LEEDS_BUILD) #include #include #include #include #include #include "pkcs11types.h" #include "stdll.h" #include "defs.h" #include "args.h" #include "h_extern.h" #endif // // CK_RV SC_WaitForSlotEvent( CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved ) { return CKR_FUNCTION_NOT_SUPPORTED; } // // CK_RV SC_DigestEncryptUpdate( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ) { return CKR_FUNCTION_NOT_SUPPORTED; } // // CK_RV SC_DecryptDigestUpdate( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ) { return CKR_FUNCTION_NOT_SUPPORTED; } // // CK_RV SC_SignEncryptUpdate( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ) { return CKR_FUNCTION_NOT_SUPPORTED; } // // CK_RV SC_DecryptVerifyUpdate( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ) { return CKR_FUNCTION_NOT_SUPPORTED; } CK_RV SC_GetFunctionStatus( CK_SESSION_HANDLE hSession ) { return CKR_FUNCTION_NOT_SUPPORTED; } // // CK_RV SC_CancelFunction( CK_SESSION_HANDLE hSession ) { return CKR_FUNCTION_NOT_SUPPORTED; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/leeds_stdll/host_api.c0000751000175000017500000070265011327631345021711 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ // File: host_api.c // #if defined(LEEDS_BUILD) #include #include #include #include #include #include #include "pkcs11types.h" #ifdef PKCS64 #include "pkcs32.h" #endif #include "stdll.h" #include "defs.h" #include "args.h" #include "h_extern.h" #endif CK_VOID_PTR adjust_mech_parameter(CK_MECHANISM_PTR); // 64 bit needs prototypes #if PKCS64 CK_ULONG_32 get_mech_parameter_len(CK_MECHANISM_PTR); // util.c prototype #else CK_ULONG get_mech_parameter_len(CK_MECHANISM_PTR); // util.c prototype #endif #if (!PKCS64) #define CK_ULONG_32 CK_ULONG #endif #ifdef DEBUGON #include #include #include #include #include #include #ifdef SOCKET #define DBGTAG "Leeds_Socket_Debug" #else #define DBGTAG "Leeds_STDLL_Debug" #endif static int enabled=0; // Logging types. Ultimately this will allow // us to log to different log files. The logger will also // handle keeping the files to a decent size. // Much work needs to be done on this capability... // Other logging types need to be implemented void loginit(){ if (!enabled){ enabled=1; openlog(DBGTAG,LOG_PID|LOG_NDELAY,LOG_DAEMON); setlogmask(LOG_UPTO(LOG_DEBUG)); } } void logit(int type,char *fmt, ...) { int n; va_list pvar; char *env; char buffer[4096*4]; if ( enabled){ va_start(pvar, fmt); vsprintf(buffer,fmt,pvar); va_end(pvar); syslog(LOG_DEBUG,buffer); } } #endif #ifdef SOCKET #include #include #include #include #define PORT 4000 #define HOSTNAME "mayfield.lexington.ibm.com" struct proxy_req { CK_ULONG pid; CK_ULONG cmd_id; CK_ULONG req_len; CK_ULONG repl_len; // (of course this will be the actual replen that I'm looking for dereferenced off *repl_len parameter) CK_ULONG out_len; CK_ULONG in_len; // [Data from pRequest] // [data from pOut] This will not be present if pOut is NULL }; typedef struct proxy_req proxy_req_t; struct proxy_resp{ CK_ULONG return_code; CK_ULONG repl_len; CK_ULONG in_len; //[Reply Data] //[In Data] }; typedef struct proxy_resp proxy_resp_t; #endif #if 0 // BIG BLOCK OF COMMENTS //XXX Development Note Note for 64 bit enablers. The leeds card is a 486 processor with a 32 bit pkcs implementation running on it. All the values will have to be translated to little endian 32 bit values BEFORE being passed into the card. Results will have to be converted to 64 bit values. This is not a trivial task. Notes: session handles - returned values from the adapter are byte swapped because of the way the original code from Lex was implemented. the session create code was modified to swap the value that was returned. Object handles on the other hand are NOT reversed. They have meaning only to the card and to many places would have to be changed to swap the handles. Much of the Lex code originally tried to swap the results without originaly swapping the values. Every effort has been made to properly ifdef the code to correctly handle these situations. #endif // XXX Communicate2 added on 12-09 and following to handle performance // improvements etc with the firmware. The interface to the card had to // change. CK_RV communicate( CK_ULONG cmd_id, CK_SLOT_ID slot_id, CK_VOID_PTR pReq, CK_ULONG req_len, CK_VOID_PTR pRep, CK_ULONG_PTR rep_len, CK_BYTE_PTR pOut, CK_ULONG out_len, CK_BYTE_PTR pIn, CK_ULONG in_len ); CK_BBOOL initialized = FALSE; pid_t initedpid=0; CK_ULONG usage_count = 0; #ifdef PKCS64 CK_ULONG_32 pid_list[ PKW_MAX_DEVICES ] = {0,0,0,0,0,0,0,0,0,0}; #else CK_ULONG pid_list[ PKW_MAX_DEVICES ] = {0,0,0,0,0,0,0,0,0,0}; #endif static sccAdapterNumber_t num_adapters; static sccAgentID_t leeds_id; static sccAdapterHandle_t adapter_handle[MAX_SLOT_ID]; // Need to handle the mutex correctly. for portability purposes // make the NT Wait and Release map to the pthreads code #ifdef PKCS64 pthread_mutex_t pkcs_mutex; #else pthread_mutex_t pkcs_mutex = PTHREAD_MUTEX_INITIALIZER; // Local module lock #endif #ifdef SOCKET pthread_mutex_t smtx = PTHREAD_MUTEX_INITIALIZER; // Local module lock #endif #define WaitForSingleObject( x, y ) pthread_mutex_lock(&x) #define ReleaseMutex( x ) pthread_mutex_unlock(&x) typedef unsigned char UCHAR; #if __64BIT__ #define ADJUSTMECHPTR() \ { \ CK_ULONG_PTR padjust; \ padjust = (CK_ULONG_PTR)adjust_mech_parameter(pMechanism); \ if (padjust ) { \ memcpy((void *) ptr,(void *) padjust, get_mech_parameter_len(pMechanism)); \ free(padjust); \ } else { \ memcpy( ptr, pMechanism->pParameter, pMechanism->ulParameterLen ); \ } \ } #else #define ADJUSTMECHPTR() \ { \ CK_ULONG_PTR padjust; \ padjust = (CK_ULONG_PTR)adjust_mech_parameter(pMechanism); \ if (padjust ) { \ memcpy((void *) ptr,(void *) padjust, pMechanism->ulParameterLen ); \ free(padjust); \ } else { \ memcpy( ptr, pMechanism->pParameter, pMechanism->ulParameterLen ); \ } \ } #endif DL_NODE *session_list = NULL; #ifdef PKCS64 CK_ULONG_32 next_session_handle = 1; #else CK_ULONG next_session_handle = 1; #endif CK_BBOOL Initialized() { if (initialized == FALSE ) return FALSE; if (initedpid != getpid()) return FALSE; return TRUE; } // Global initialized value for each slot indicating if the coorelator // used has been initialized already. struct Cor_init{ unsigned char init; CK_SLOT_ID API_Slotid; } correlator_init[PKW_MAX_DEVICES]; struct ST_FCN_LIST function_list; extern CK_RV SC_Initialize(); /* extern CK_RV SC_Initialize */ extern CK_RV SC_GetTokenInfo(); /* extern CK_RV SC_GetTokenInfo */ extern CK_RV SC_GetMechanismList(); /* extern CK_RV SC_GetMechanismList */ extern CK_RV SC_GetMechanismInfo(); /* extern CK_RV SC_GetMechanismInfo */ extern CK_RV SC_InitToken(); /* extern CK_RV SC_InitToken */ extern CK_RV SC_InitPIN(); /* extern CK_RV SC_InitPIN */ extern CK_RV SC_SetPIN(); /* extern CK_RV SC_SetPIN */ extern CK_RV SC_OpenSession(); /* extern CK_RV SC_OpenSession */ extern CK_RV SC_CloseSession(); /* extern CK_RV SC_CloseSession */ extern CK_RV SC_CloseAllSessions(); /* extern CK_RV SC_CloseAllSessions */ extern CK_RV SC_GetSessionInfo(); /* extern CK_RV SC_GetSessionInfo */ extern CK_RV SC_GetOperationState(); /* extern CK_RV SC_GetOperationState */ extern CK_RV SC_SetOperationState(); /* extern CK_RV SC_SetOperationState */ extern CK_RV SC_Login(); /* extern CK_RV SC_Login */ extern CK_RV SC_Logout(); /* extern CK_RV SC_Logout */ extern CK_RV SC_CreateObject(); /* extern CK_RV SC_CreateObject */ extern CK_RV SC_CopyObject(); /* extern CK_RV SC_CopyObject */ extern CK_RV SC_DestroyObject(); /* extern CK_RV SC_DestroyObject */ extern CK_RV SC_GetObjectSize(); /* extern CK_RV SC_GetObjectSize */ extern CK_RV SC_GetAttributeValue(); /* extern CK_RV SC_GetAttributeValue */ extern CK_RV SC_SetAttributeValue(); /* extern CK_RV SC_SetAttributeValue */ extern CK_RV SC_FindObjectsInit(); /* extern CK_RV SC_FindObjectsInit */ extern CK_RV SC_FindObjects(); /* extern CK_RV SC_FindObjects */ extern CK_RV SC_FindObjectsFinal(); /* extern CK_RV SC_FindObjectsFinal */ extern CK_RV SC_EncryptInit(); /* extern CK_RV SC_EncryptInit */ extern CK_RV SC_Encrypt(); /* extern CK_RV SC_Encrypt */ extern CK_RV SC_EncryptUpdate(); /* extern CK_RV SC_EncryptUpdate */ extern CK_RV SC_EncryptFinal(); /* extern CK_RV SC_EncryptFinal */ extern CK_RV SC_DecryptInit(); /* extern CK_RV SC_DecryptInit */ extern CK_RV SC_Decrypt(); /* extern CK_RV SC_Decrypt */ extern CK_RV SC_DecryptUpdate(); /* extern CK_RV SC_DecryptUpdate */ extern CK_RV SC_DecryptFinal(); /* extern CK_RV SC_DecryptFinal */ extern CK_RV SC_DigestInit(); /* extern CK_RV SC_DigestInit */ extern CK_RV SC_Digest(); /* extern CK_RV SC_Digest */ extern CK_RV SC_DigestUpdate(); /* extern CK_RV SC_DigestUpdate */ extern CK_RV SC_DigestKey(); /* extern CK_RV SC_DigestKey */ extern CK_RV SC_DigestFinal(); /* extern CK_RV SC_DigestFinal */ extern CK_RV SC_SignInit(); /* extern CK_RV SC_SignInit */ extern CK_RV SC_Sign(); /* extern CK_RV SC_Sign */ extern CK_RV SC_SignUpdate(); /* extern CK_RV SC_SignUpdate */ extern CK_RV SC_SignFinal(); /* extern CK_RV SC_SignFinal */ extern CK_RV SC_SignRecoverInit(); /* extern CK_RV SC_SignRecoverInit */ extern CK_RV SC_SignRecover(); /* extern CK_RV SC_SignRecover */ extern CK_RV SC_VerifyInit(); /* extern CK_RV SC_VerifyInit */ extern CK_RV SC_Verify(); /* extern CK_RV SC_Verify */ extern CK_RV SC_VerifyUpdate(); /* extern CK_RV SC_VerifyUpdate */ extern CK_RV SC_VerifyFinal(); /* extern CK_RV SC_VerifyFinal */ extern CK_RV SC_VerifyRecoverInit(); /* extern CK_RV SC_VerifyRecoverInit */ extern CK_RV SC_VerifyRecover(); /* extern CK_RV SC_VerifyRecover */ extern CK_RV SC_DigestEncryptUpdate(); /* extern CK_RV SC_DigestEncryptUpdate */ extern CK_RV SC_DecryptDigestUpdate(); /* extern CK_RV SC_DecryptDigestUpdate */ extern CK_RV SC_SignEncryptUpdate(); /* extern CK_RV SC_SignEncryptUpdate */ extern CK_RV SC_DecryptVerifyUpdate(); /* extern CK_RV SC_DecryptVerifyUpdate */ extern CK_RV SC_GenerateKey(); /* extern CK_RV SC_GenerateKey */ extern CK_RV SC_GenerateKeyPair(); /* extern CK_RV SC_GenerateKeyPair */ extern CK_RV SC_WrapKey(); /* extern CK_RV SC_WrapKey */ extern CK_RV SC_UnwrapKey(); /* extern CK_RV SC_UnwrapKey */ extern CK_RV SC_DeriveKey(); /* extern CK_RV SC_DeriveKey */ extern CK_RV SC_SeedRandom(); /* extern CK_RV SC_SeedRandom */ extern CK_RV SC_GenerateRandom(); /* extern CK_RV SC_GenerateRandom */ extern CK_RV SC_GetFunctionStatus(); /* extern CK_RV SC_GetFunctionStatus */ extern CK_RV SC_CancelFunction(); /* extern CK_RV SC_CancelFunction */ // Added for AIX work void SC_SetFunctionList(void){ function_list.ST_Initialize = SC_Initialize; function_list.ST_GetTokenInfo = SC_GetTokenInfo; function_list.ST_GetMechanismList = SC_GetMechanismList; function_list.ST_GetMechanismInfo = SC_GetMechanismInfo; function_list.ST_InitToken = SC_InitToken; function_list.ST_InitPIN = SC_InitPIN; function_list.ST_SetPIN = SC_SetPIN; function_list.ST_OpenSession = SC_OpenSession; function_list.ST_CloseSession = SC_CloseSession; function_list.ST_GetSessionInfo = SC_GetSessionInfo; function_list.ST_GetOperationState = SC_GetOperationState; function_list.ST_SetOperationState = SC_SetOperationState; function_list.ST_Login = SC_Login; function_list.ST_Logout = SC_Logout; function_list.ST_CreateObject = SC_CreateObject; function_list.ST_CopyObject = SC_CopyObject; function_list.ST_DestroyObject = SC_DestroyObject; function_list.ST_GetObjectSize = SC_GetObjectSize; function_list.ST_GetAttributeValue = SC_GetAttributeValue; function_list.ST_SetAttributeValue = SC_SetAttributeValue; function_list.ST_FindObjectsInit = SC_FindObjectsInit; function_list.ST_FindObjects = SC_FindObjects; function_list.ST_FindObjectsFinal = SC_FindObjectsFinal; function_list.ST_EncryptInit = SC_EncryptInit; function_list.ST_Encrypt = SC_Encrypt; function_list.ST_EncryptUpdate = SC_EncryptUpdate; function_list.ST_EncryptFinal = SC_EncryptFinal; function_list.ST_DecryptInit = SC_DecryptInit; function_list.ST_Decrypt = SC_Decrypt; function_list.ST_DecryptUpdate = SC_DecryptUpdate; function_list.ST_DecryptFinal = SC_DecryptFinal; function_list.ST_DigestInit = SC_DigestInit; function_list.ST_Digest = SC_Digest; function_list.ST_DigestUpdate = SC_DigestUpdate; function_list.ST_DigestKey = SC_DigestKey; function_list.ST_DigestFinal = SC_DigestFinal; function_list.ST_SignInit = SC_SignInit; function_list.ST_Sign = SC_Sign; function_list.ST_SignUpdate = SC_SignUpdate; function_list.ST_SignFinal = SC_SignFinal; function_list.ST_SignRecoverInit = SC_SignRecoverInit; function_list.ST_SignRecover = SC_SignRecover; function_list.ST_VerifyInit = SC_VerifyInit; function_list.ST_Verify = SC_Verify; function_list.ST_VerifyUpdate = SC_VerifyUpdate; function_list.ST_VerifyFinal = SC_VerifyFinal; function_list.ST_VerifyRecoverInit = SC_VerifyRecoverInit; function_list.ST_VerifyRecover = SC_VerifyRecover; function_list.ST_DigestEncryptUpdate = NULL; // SC_DigestEncryptUpdate; function_list.ST_DecryptDigestUpdate = NULL; // SC_DecryptDigestUpdate; function_list.ST_SignEncryptUpdate = NULL; //SC_SignEncryptUpdate; function_list.ST_DecryptVerifyUpdate = NULL; // SC_DecryptVerifyUpdate; function_list.ST_GenerateKey = SC_GenerateKey; function_list.ST_GenerateKeyPair = SC_GenerateKeyPair; function_list.ST_WrapKey = SC_WrapKey; function_list.ST_UnwrapKey = SC_UnwrapKey; function_list.ST_DeriveKey = SC_DeriveKey; function_list.ST_SeedRandom = SC_SeedRandom ; function_list.ST_GenerateRandom = SC_GenerateRandom; function_list.ST_GetFunctionStatus = NULL; // SC_GetFunctionStatus; function_list.ST_CancelFunction = NULL; // SC_CancelFunction; } int APISlot2Local(snum) CK_SLOT_ID snum; { int i; // return snum; /// temp to change this.. for (i=0;i< PKW_MAX_DEVICES; i++){ if (correlator_init[i].init) if (correlator_init[i].API_Slotid == snum) return (i+1); // Slots from Lex code are 1 based not 0... } return -1; } #define SLT_CHECK \ CK_SLOT_ID slot_id; \ int sid1; \ \ if ( (sid1 = APISlot2Local(sid)) != -1 ){ \ slot_id = sid1; \ } else { \ return CKR_ARGUMENTS_BAD; \ } #define SESSION sSession.sessionh #define SLOTID APISlot2Local(sSession.slotID) #define SESS_SET \ CK_SESSION_HANDLE hSession; \ \ hSession = sSession.sessionh; void hex_dump(char *str,CK_BYTE_PTR ptr, int len ) { int lendone=0; int by10 = 0; int i,j; printf("%s Dumping %d bytes \n",str,len); by10 = len/10; for (i=0;i< by10;i++){ for (j=0;j<10;j++){ lendone ++; printf("0x%02X ",*ptr); ptr++; } printf("\n"); } for (j=lendone; j< len;j++){ printf("0x%02X ",*ptr); ptr++; } printf("\n Done Dumping \n"); } CK_RV MY_LockMutex(void) { WaitForSingleObject( pkcs_mutex, INFINITE ); return CKR_OK; } CK_RV MY_UnlockMutex(void) { ReleaseMutex(pkcs_mutex); return CKR_OK; } #ifdef PKCS64 CK_ULONG_32 long_reverse( CK_ULONG_32 x ) #else CK_ULONG long_reverse( CK_ULONG x ) #endif { #ifdef _BIG_ENDIAN // Power Architecture requires reversal to talk to adapter return ( ((0x000000FF & x)<<24) | ((0x0000FF00 & x)<<8) | ((0x00FF0000 & x)>>8) | ((0xFF000000 & x)>>24) ); #else return (x); // Others don't require reversal. #endif } // SAB FIXME Added for 64bit uint32 get_attrib_len(CK_ATTRIBUTE *attr) { switch(attr->type){ case CKA_CLASS: case CKA_KEY_TYPE: case CKA_MODULUS_BITS: case CKA_VALUE_BITS: case CKA_VALUE_LEN: case CKA_CERTIFICATE_TYPE: // SAB FIXME 64bit // These are unsigned longs, which in 64bit need // to be made into 32bit values to be passed to the // card. return(sizeof(unsigned int)); break; default: return (attr->ulValueLen); break; } } void copy_attribute_value(void *source, void *dest, CK_ATTRIBUTE *attr) { #if PKCS64 CK_ULONG_32 d; #else CK_ULONG d; #endif CK_ULONG *p; switch(attr->type){ case CKA_CLASS: case CKA_KEY_TYPE: case CKA_MODULUS_BITS: case CKA_VALUE_BITS: case CKA_VALUE_LEN: case CKA_CERTIFICATE_TYPE: // SAB FIXME 64bit // These are unsigned longs, which in 64bit need // to be made into 32bit values to be passed to the // card. p = (CK_ULONG *)(attr->pValue); d = *p; //printf("copy attribute value d = %x p %x\n",d,*p); *((CK_ULONG_32 *)dest) = d; //*((CK_ULONG_32 *)dest) = *((CK_ULONG *)(attr->pValue)); break; default: memcpy(dest, source, attr->ulValueLen); break; } } // SAB FIXME END Added for 64bit #ifdef _BIG_ENDIAN // Routine to modify a template attribute if necessary void ModifyAttribute(type,val) CK_ATTRIBUTE_TYPE type; #ifdef PKCS64 CK_ULONG_PTR_32 val; { CK_ULONG_32 tval; #else CK_ULONG_PTR val; { CK_ULONG tval; #endif switch (type){ case CKA_CLASS: case CKA_KEY_TYPE: case CKA_MODULUS_BITS: case CKA_VALUE_BITS: case CKA_VALUE_LEN: case CKA_CERTIFICATE_TYPE: // SAB FIXME 64bit // These are the ones which need to be swapped #ifdef PKCS64 tval = HTOCL((CK_ULONG_32)*val); *val = tval; // memcpy(val, &tval, sizeof(CK_ULONG_32)); #else tval = HTOCL((CK_ULONG)*val); memcpy(val, &tval, sizeof(CK_ULONG)); #endif default: break; } } #else // NOTE FIXME intel 64bit systems will have a problem here // and need to be adjusted properly void ModifyAttribute(type,val) CK_ATTRIBUTE_TYPE type; CK_ULONG_PTR val; { // This is a no op function for Intel AIX based systems } #endif #ifndef SOCKET // Function: communicate() // // Specialized communicate routine for use with Encryption/Decryption. The // data to be encrypted/decrypted is sent in a separate buffer. This allows // the mechanisms to take advantage of external-to-external buffer transfers // where possible. Everything else is the same (LEEDS_REQUEST/LEEDS_REPLY // still occurs on buffer #0, etc). // // Args: pReq: the 'normal' request structure // pRep: the 'normal' reply structure // pOut: the cleartext/ciphertext to be sent TO the card // pIn the cleartext/ciphertext to be received FROM the card // // // Assemble a request packet for the 4758, send it across, and unmarshal the // reply. // // cmd_id - Command identifier (specifies which function to invoke) // slot_id - Slot number of 4758 to which request is addressed // pReq - -> buffer containing data (args, etc.) associated with request // req_len - Length in bytes of *pReq // pRep - -> buffer that is to hold the reply // repl_len - -> length in bytes of *pRep // pOut - -> buffer containing additional data to be supplied with the // command (e.g., address of buffer of data to encrypt) // out_len - Length in bytes of *pOut // pIn - -> buffer that is to hold additional data returned by the // coprocessor (e.g., address of buffer to hold encrypted data) // in_len - Length in bytes of *pIn // // Any of the buffer pointers may be NULL (in which case the corresponding // length must be 0). // // cmd_id is sent in the UserDefined field of the sccRequest structure. // The buffers defined by pReq and pOut are passed in pOutBuffer[0] and // pOutBuffer[1], respectively. The buffers defined by pRep and pIn are // passed in pInBuffer[0] and pInBuffer[1], respectively. // // Data in the buffers must be in the proper byte order. Other fields (e.g., // cmd_id) are handled automatically. // // On successful return, *repl_len contains the actual length in bytes of the // reply. // CK_RV communicate( CK_ULONG cmd_id, CK_SLOT_ID slot_id, CK_VOID_PTR pReq, CK_ULONG req_len, CK_VOID_PTR pRep, CK_ULONG_PTR repl_len, CK_BYTE_PTR pOut, CK_ULONG outlen, CK_BYTE_PTR pIn, CK_ULONG inlen ) { union { double d; CK_BYTE b[1024]; } alignedBuffers[2]; LEEDS_REQUEST * send_packet = (LEEDS_REQUEST *)&(alignedBuffers[0]); LEEDS_REPLY * recv_packet = (LEEDS_REPLY *)&(alignedBuffers[1]); CK_BYTE * ptr = NULL; CK_BYTE * in_buf = pIn; CK_BYTE * out_buf = pOut; CK_ULONG send_len, recv_len; CK_ULONG out_len = outlen; CK_ULONG in_len = inlen; CK_ULONG in_buf_len = in_len, out_buf_len = out_len; CK_RV rc; sccRB_t request_block; int i; // XXX WJH //LARGE_INTEGER start,end; if (repl_len == NULL) return CKR_GENERAL_ERROR; if (slot_id > MAX_SLOT_ID) return CKR_FUNCTION_FAILED; if (pReq == NULL && req_len != 0) return CKR_FUNCTION_FAILED; if (pRep == NULL && *repl_len != 0) return CKR_FUNCTION_FAILED; if (pOut == NULL && out_len != 0) { out_len = 0; in_buf_len = in_len, out_buf_len = out_len; //return CKR_FUNCTION_FAILED; } if (pIn == NULL && in_len != 0) { in_len = 0; in_buf_len = in_len, out_buf_len = out_len; //return CKR_FUNCTION_FAILED; } // ensure the buffer lengths are multiples of 4 and that the buffers we // have are big enough // send_len = (sizeof(LEEDS_REQUEST) + req_len + 3) & ~3; recv_len = (sizeof(LEEDS_REPLY) + *repl_len + 3) & ~3; if (send_len > sizeof(alignedBuffers[0])) send_packet = (LEEDS_REQUEST *)malloc( send_len ); if (recv_len > sizeof(alignedBuffers[1])) recv_packet = (LEEDS_REPLY *)malloc( recv_len ); if ((out_len & 3) != 0) { out_buf_len = (out_len + 3) & ~3; out_buf = (CK_BYTE *)malloc( out_buf_len ); memcpy( out_buf, pOut, out_len ); } if ((in_len & 3) != 0) { in_buf_len = (in_len + 3) & ~3; in_buf = (CK_BYTE *)malloc( in_buf_len ); } // If we couldn't allocate something we needed, die // if (send_packet == NULL || recv_packet == NULL || (out_buf == NULL && out_buf_len != 0) || (in_buf == NULL && in_buf_len != 0)) { if (send_len > sizeof(alignedBuffers[0]) && send_packet != NULL) free( send_packet ); if (recv_len > sizeof(alignedBuffers[1]) && recv_packet != NULL) free( recv_packet ); if (out_buf != NULL && out_buf != pOut) free( out_buf ); if (in_buf != NULL && in_buf != pIn) free( in_buf ); return CKR_HOST_MEMORY; } memset( send_packet, 0x0, send_len ); memset( recv_packet, 0x0, recv_len ); memset( &request_block, 0x00, sizeof(request_block) ); memcpy( &request_block.AgentID, &leeds_id, sizeof(leeds_id) ); send_packet->pid = HTOCL( pid_list[slot_id - 1] ); send_packet->req_len = HTOCL( req_len ); send_packet->repl_max[0] = HTOCL( *repl_len ); send_packet->repl_max[1] = HTOCL( in_len ); send_packet->repl_max[2] = 0; // we don't currently use these buffers send_packet->repl_max[3] = 0; // but maybe in the future... // Skip request header // ptr = (CK_BYTE *)send_packet + sizeof(LEEDS_REQUEST); if (pReq != NULL) memcpy( ptr, pReq, req_len ); request_block.pOutBuffer[0] = (UCHAR *)send_packet; request_block.pInBuffer [0] = (UCHAR *)recv_packet; request_block.pOutBuffer[1] = (UCHAR *)out_buf; request_block.pInBuffer [1] = (UCHAR *)in_buf; // I don't know if the following needs to be adjusted for endianness or not // (the device driver could in principle take care of the swapping) // request_block.UserDefined = cmd_id; request_block.OutBufferLength[0] = send_len; request_block.InBufferLength [0] = recv_len; request_block.OutBufferLength[1] = out_buf_len; request_block.InBufferLength [1] = in_buf_len; #if 0 printf("\n\nRequest Block Dump:\n\n"); printf("request_block.AgentID.DeveloperID[0] %X\n", request_block.AgentID.DeveloperID[0]); printf("request_block.AgentID.DeveloperID[1] %X\n", request_block.AgentID.DeveloperID[1]); for ( i=0;i<11;i++) { printf("request_block.AgentID.ProgramID[%X] %X\n", i, request_block.AgentID.ProgramID[i]); } printf("request_block.AgentID.Version[0] %X\n", request_block.AgentID.Version[0]); printf("request_block.AgentID.Instance[0] %X\n", request_block.AgentID.Instance[0]); printf("request_block.AgentID.Queue[0] %X\n", request_block.AgentID.Instance[0]); printf("request_block.reserved %X\n", request_block.reserved); printf("request_block.UserDefined %X\n", request_block.UserDefined); for (i=0;i<4;i++){ printf("request_block.OutBufferLength[%X] %X\n", i, request_block.OutBufferLength[i]); } for (i=0;i<4;i++){ printf("request_block.InBufferLength[%X] %X\n", i, request_block.InBufferLength[i]); } for (i=0;i<4;i++){ printf("request_block.pOutBuffer[%X] %X\n", i, request_block.pOutBuffer[i]); } for (i=0;i<4;i++){ printf("request_block.pInBuffer[%X] %X\n", i, request_block.pInBuffer[i]); } printf("request_block.Status %X\n", request_block.Status); printf("\nLEEDS_REQUEST Dump:\n\n"); printf("send_packet->pid %d\n", send_packet->pid); printf("send_packet->req_len %d\n", send_packet->req_len ); printf("send_packet->repl_max[0] %x\n", send_packet->repl_max[0]); printf("send_packet->repl_max[1] %x\n",send_packet->repl_max[1]); printf("\n\n"); #endif // send the request synchronously to the adapter // rc = sccRequest( adapter_handle[slot_id - 1], &request_block ); if (rc != 0) { rc = CKR_FUNCTION_FAILED; goto error; } // handle the replies // if ((CTOHL(recv_packet->repl_len[0]) > *repl_len) || (CTOHL(recv_packet->repl_len[1]) > in_len)) { #if 0 printf(" rep from card 0 %x \n rep from card 1 %x \n repl_len %x \n in_len %x \n", CTOHL(recv_packet->repl_len[0]),CTOHL(recv_packet->repl_len[1]), *repl_len, in_len); #endif rc = CKR_FUNCTION_FAILED; goto error; } *repl_len = CTOHL(recv_packet->repl_len[0]); // Skip reply header // ptr = (CK_BYTE *)recv_packet + sizeof(LEEDS_REPLY); if (pRep != NULL) memcpy( pRep, ptr, CTOHL(recv_packet->repl_len[0]) ); if (in_buf != pIn) memcpy( pIn, in_buf, CTOHL(recv_packet->repl_len[1]) ); // This may need to be swapped... // rc = request_block.Status; error: if (send_len > sizeof(alignedBuffers[0])) free( send_packet ); if (recv_len > sizeof(alignedBuffers[1])) free( recv_packet ); if (in_buf != pIn) free( in_buf ); if (out_buf != pOut) free( out_buf ); return rc; } #else // Socket CK_RV communicate( CK_ULONG cmd_id, CK_SLOT_ID slot_id, CK_VOID_PTR pReq, CK_ULONG req_len, CK_VOID_PTR pRep, CK_ULONG_PTR repl_len, CK_BYTE_PTR pOut, CK_ULONG out_len, CK_BYTE_PTR pIn, CK_ULONG in_len ) { proxy_req_t * send_packet = NULL; proxy_resp_t * recv_packet = NULL; char *rpkt = NULL; CK_BYTE * ptr = NULL; CK_BYTE * in_buf = NULL; CK_BYTE * out_buf = NULL; CK_ULONG send_len, recv_len; CK_ULONG in_buf_len, out_buf_len; CK_BBOOL alloc_in = FALSE, alloc_out=FALSE; CK_RV rc; long rv; long total_read = 0; sccRB_t request_block; struct hostent *hs,hst; struct sockaddr_in saddr; struct sockaddr_in caddr; int sock; if (!repl_len) return CKR_GENERAL_ERROR; if (slot_id > MAX_SLOT_ID) return CKR_FUNCTION_FAILED; if (pOut == NULL && out_len != 0) return CKR_FUNCTION_FAILED; if (pIn == NULL && in_len != 0) return CKR_FUNCTION_FAILED; #ifdef ALLSOCK // Create the socket here. // pthread_mutex_lock(&smtx); { int j; int count=0; j = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if (j) { sock = j; hs = gethostbyname(HOSTNAME); if (! hs ) { exit(2 ); } hst=*hs; saddr.sin_family = AF_INET; memcpy((char *)&saddr.sin_addr, hs->h_addr, hs->h_length); //saddr.sin_addr.s_addr = htonl(0x0933510c); saddr.sin_port = htons(PORT); if ( connect (sock,(struct sockaddr *)&saddr,sizeof(struct sockaddr_in)) < 0 ){ // XXX FIXME just bail for now. #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: socket failed to connect errno %d \n","communicate",errno); #endif pthread_mutex_unlock(&smtx); return CKR_FUNCTION_FAILED; } else { rc = 0; } } else { pthread_mutex_unlock(&smtx); return CKR_FUNCTION_FAILED; } } pthread_mutex_unlock(&smtx); #else sock = adapter_handle[slot_id-1]; #endif // end socket creation // ensure the buffer lengths are multiples of 4 // Allocate contiguous memory for both send and receive send_len = sizeof(proxy_req_t) + req_len + out_len; recv_len = sizeof(proxy_resp_t) + *repl_len + in_len; #ifdef DEBUGON logit(LOG_DEBUG, "\t\t%-25s: slot_id %d %d, 0x%x \n","communicate",slot_id,slot_id-1,cmd_id); #endif // this probably isn't guaranteed to be longword-aligned... // #if 1 send_packet = (proxy_req_t *)malloc( send_len ); recv_packet = (proxy_resp_t *)malloc( recv_len ); #endif if (!send_packet || !recv_packet) return CKR_HOST_MEMORY; memset( send_packet, 0x0, send_len ); memset( recv_packet, 0x0, recv_len ); ptr = (CK_BYTE *)send_packet + sizeof(proxy_req_t); if (pReq != NULL) memcpy( ptr, pReq, req_len ); ptr = (CK_BYTE *)send_packet + sizeof(proxy_req_t) + req_len; if (pOut != NULL) memcpy(ptr,pOut,out_len); send_packet->pid = HTOCL( pid_list[slot_id - 1] ); send_packet->cmd_id = HTOCL(cmd_id); send_packet->req_len = HTOCL( req_len ); send_packet->repl_len = HTOCL((*repl_len)); // These have to be swapped send_packet->in_len = HTOCL(in_len); send_packet->out_len = HTOCL(out_len); // send the request synchronously to the adapter // // This is actualy send asynchronously to the remote hoset // SAB XXX FIXME this needs to be done... // pthread_mutex_lock(&smtx); #ifdef DEBUGON logit(LOG_DEBUG, "\t\t%-25s: writing \n","communicate"); #endif //rv = write(adapter_handle[slot_id -1 ],send_packet,send_len); rv = write(sock,send_packet,send_len); #ifdef DEBUGON logit(LOG_DEBUG, "\t\t%-25s: wrote %d \n","communicate",rv); #endif if (rv == -1) { #ifdef DEBUGON logit(LOG_DEBUG, "\t\t%-25s: write failed %d errno %d \n","communicate",rv,errno); #endif rc = CKR_FUNCTION_FAILED; // socket failure close(sock); pthread_mutex_unlock(&smtx); goto error; } total_read = 0; rv = 1; //while ( (total_read < recv_len) && ( rv != -1)){ rpkt = (char *)recv_packet; while ( (total_read < sizeof(proxy_resp_t)) && ( rv != -1)){ #ifdef DEBUGON // logit(LOG_DEBUG, "\t\t%-25s: reading header %d \n","communicate",total_read); // logit(LOG_DEBUG, "\t\t%-25s: reading into %x \n","communicate", rpkt + total_read); #endif // rv = read(sock,recv_packet + total_read,recv_len-total_read); rv = read(sock,rpkt + total_read,sizeof(proxy_resp_t)-total_read); #ifdef DEBUGON // logit(LOG_DEBUG, "\t\t%-25s: reading %d \n","communicate",rv); #endif if (rv > 0 ) total_read += rv; if (rv == 0 && total_read < recv_len) { rv = 1; continue; } }; #ifdef DEBUGON // logit(LOG_DEBUG, "\t\t%-25s: second phase read %d resp %d %d \n","communicate", // total_read,(CTOHL(recv_packet->repl_len)),(CTOHL(recv_packet->in_len))); // logit(LOG_DEBUG, "\t\t%-25s: rpkt %x %x \n","communicate", // rpkt,rpkt + total_read); #endif if (total_read == sizeof(proxy_resp_t)) {// && rv != -1){ int local_count=0; rpkt += total_read; while (total_read < (sizeof(proxy_resp_t) + (CTOHL(recv_packet->repl_len)) + (CTOHL(recv_packet->in_len)))) { #ifdef DEBUGON // logit(LOG_DEBUG, "\t\t%-25s: reading rest %d \n","communicate", total_read); // logit(LOG_DEBUG, "\t\t%-25s: reading into %x \n","communicate", rpkt); #endif rv = read(sock,rpkt, ((CTOHL(recv_packet->repl_len)) + (CTOHL(recv_packet->in_len)))-local_count); if (rv > 0 ) { total_read += rv; local_count += rv; rpkt += rv; } #ifdef DEBUGON // logit(LOG_DEBUG, "\t\t%-25s: read %d \n","communicate", rv); // logit(LOG_DEBUG, "\t\t%-25s: total %d \n","communicate", total_read); #endif if (rv == 0 && total_read < (sizeof(proxy_resp_t) + (CTOHL(recv_packet->repl_len)) + (CTOHL(recv_packet->in_len)))) { rv = 1; continue; } } } else { #ifdef DEBUGON logit(LOG_DEBUG, "\t\t%-25s: we are screwed %d \n","communicate",total_read); #endif rc = CKR_FUNCTION_FAILED; pthread_mutex_unlock(&smtx); #ifdef ALLSOCK close(sock); #endif goto error; } if (rv == -1 && total_read == 0) { #ifdef DEBUGON logit(LOG_DEBUG, "\t\t%-25s: eof on socket %d errno %d \n","communicate",rv,errno); #endif rc = CKR_FUNCTION_FAILED; pthread_mutex_unlock(&smtx); #ifdef ALLSOCK close(sock); #endif goto error; } #ifdef ALLSOCK close(sock); #endif pthread_mutex_unlock(&smtx); if ( total_read < sizeof(proxy_resp_t)) { logit(LOG_DEBUG, "\t\t%-25s: Total read not enough %d \n","communicate",total_read); rc = CKR_FUNCTION_FAILED; goto error; } // SAB end XXX FIXME // handle the replies // if ((CTOHL(recv_packet->repl_len) > *repl_len) || (CTOHL(recv_packet->in_len) > in_len)) { #ifdef DEBUGON logit(LOG_DEBUG, "\t\t%-25s: rep length delta %d a %d \n","communicate",*repl_len,CTOHL(recv_packet->repl_len)); logit(LOG_DEBUG, "\t\t%-25s: in length delta %d %d \n","communicate",in_len, CTOHL(recv_packet->in_len)); #endif rc = CKR_FUNCTION_FAILED; goto error; } if (total_read < (CTOHL(recv_packet->repl_len) + CTOHL(recv_packet->in_len))){ logit(LOG_DEBUG, "\t\t%-25s: Total read not enough %d expected %d \n","communicate", total_read,(CTOHL(recv_packet->repl_len) + CTOHL(recv_packet->in_len))); rc = CKR_FUNCTION_FAILED; goto error; } ptr = (CK_BYTE *)recv_packet + sizeof(proxy_resp_t); if (pRep != NULL) memcpy( pRep, ptr, CTOHL(recv_packet->repl_len) ); ptr = (CK_BYTE *)recv_packet + sizeof(proxy_resp_t) + CTOHL(recv_packet->repl_len); if (pIn != NULL) memcpy( pIn, ptr,CTOHL( recv_packet->in_len) ); rc = CTOHL(recv_packet->return_code); #ifdef DEBUGON logit(LOG_DEBUG, "\t\t%-25s: Card returned %d \n","communicate",rc); #endif error: if (send_packet) free( send_packet ); if (recv_packet) free( recv_packet ); if (alloc_in) free( in_buf ); if (alloc_out) free( out_buf ); return rc; } #endif // // CK_RV SC_Initialize( void **FunctionList, CK_SLOT_ID SlotNumber, char *Correlator) { int i, j, bad, rc; #ifdef SOCKET struct hostent *hs,hst; struct sockaddr_in saddr; struct sockaddr_in caddr; #endif #ifdef BRKPT break_point(); #endif WaitForSingleObject( pkcs_mutex, INFINITE ); // Handle global initialization issues first if we have not // been initialized. if (Initialized() == FALSE){ memset( &leeds_id, 0, sizeof(leeds_id) ); leeds_id.DeveloperID[0] = PKCS_11_DEVELOPER_ID; leeds_id.DeveloperID[1] = 0x00; memcpy( leeds_id.ProgramID, PKCS_11_PRG_ID, sizeof(leeds_id.ProgramID) ); leeds_id.Version[0] = PKCS_11_VERSION; leeds_id.Instance[0] = PKCS_11_INSTANCE; leeds_id.Queue[0] = PKCS_11_QUEUE; #ifdef DEBUGON loginit(); #endif // Zero out the adapter handle array // an adapter handle of 0 indicates that the particular adapter has // NOT been initialized memset((char *)adapter_handle, 0, sizeof(sccAdapterHandle_t)*MAX_SLOT_ID); initialized = TRUE; initedpid = getpid(); SC_SetFunctionList(); memset((char *)correlator_init, 0, PKW_MAX_DEVICES * sizeof(struct Cor_init)); { int i; for (i=0;ih_addr, hs->h_length); saddr.sin_port = htons(PORT); if ( connect (adapter_handle[i],(struct sockaddr *)&saddr,sizeof(struct sockaddr_in)) < 0 ){ // XXX FIXME just bail for now. #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: connect errno %d \n","SC_Initialize",errno); #endif ReleaseMutex(pkcs_mutex); return CKR_FUNCTION_FAILED; } else { rc = 0; } } else { #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: open errno %d \n","SC_Initialize",errno); #endif ReleaseMutex(pkcs_mutex); return CKR_FUNCTION_FAILED; } } if (rc == 0 ){ correlator_init[i].init = 1; // Mark in use correlator_init[i].API_Slotid = SlotNumber; } else { (*FunctionList) = NULL; ReleaseMutex(pkcs_mutex); return CKR_FUNCTION_FAILED; } } usage_count++; } #endif // ifdef ALLSOCK #endif (*FunctionList) = &function_list; ReleaseMutex( pkcs_mutex ); return CKR_OK; } // FIXME : This needs to be more fully debugged. // CK_RV SC_Finalize( CK_SLOT_ID sid ) { CK_ULONG req_len, repl_len; CK_ULONG i; SLT_CHECK #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: sid %d slot_id %d, \n","SC_Finalize",sid,slot_id); #endif WaitForSingleObject( pkcs_mutex, INFINITE ); if (Initialized() == FALSE){ ReleaseMutex(pkcs_mutex); return CKR_CRYPTOKI_NOT_INITIALIZED; } #if 0 if (pReserved != NULL){ ReleaseMutex(pkcs_mutex); return CKR_ARGUMENTS_BAD; } #endif { #ifdef DEBUGON logit(LOG_DEBUG, "\t Slot %x pid list %x %x\n",slot_id,pid_list[slot_id],pid_list[slot_id-1]); #endif if (pid_list[slot_id -1 ] != 0){ req_len = 0; repl_len = 0; communicate(C_FINALIZE,slot_id,NULL,req_len, NULL,&repl_len, NULL,0, NULL,0); // need to close the correct adapter handle... } i = slot_id -1; // slot id's are 1 based for leeds, array is zero based if ( adapter_handle[i] != 0 ){ sccCloseAdapter( adapter_handle[i] ); i++; } } // Decrement module usage count // if module usage account is 0 then whack it. // since all instances of the module are cleaned up usage_count --; if (usage_count == 0 ){ initialized = FALSE; } ReleaseMutex( pkcs_mutex ); return CKR_OK; } #ifdef PKCS64 // // CK_RV SC_GetTokenInfo( CK_SLOT_ID sid, CK_TOKEN_INFO_PTR pInfo ) { CK_TOKEN_INFO_32 reply; CK_ULONG req_len; CK_ULONG repl_len; CK_RV rc; SLT_CHECK if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (!pInfo) return CKR_FUNCTION_FAILED; if (slot_id > MAX_SLOT_ID) return CKR_SLOT_ID_INVALID; // no arguments // req_len = 0; repl_len = sizeof(reply); rc = communicate( C_GETTOKENINFO, slot_id, NULL, req_len, &reply, &repl_len, NULL, 0, NULL, 0 ); #ifdef __64BIT__ if (rc == CKR_OK) { // The first 96 bytes are ok since the fields contain no longs: // label, manufacture ID, etc. See CK_TOKEN_INFO for details. memcpy( pInfo, &reply, 96 ); pInfo->flags = reply.flags; pInfo->ulMaxSessionCount = reply.ulMaxSessionCount; pInfo->ulSessionCount = reply.ulSessionCount; pInfo->ulMaxRwSessionCount = reply.ulMaxRwSessionCount; pInfo->ulRwSessionCount = reply.ulRwSessionCount; pInfo->ulMaxPinLen = reply.ulMaxPinLen; pInfo->ulMinPinLen = reply.ulMinPinLen; pInfo->ulTotalPublicMemory = reply.ulTotalPublicMemory; pInfo->ulFreePublicMemory = reply.ulFreePublicMemory; pInfo->ulTotalPrivateMemory = reply.ulTotalPrivateMemory; pInfo->ulFreePrivateMemory = reply.ulFreePrivateMemory; } #else if (rc == CKR_OK) memcpy( pInfo, &reply, sizeof(CK_TOKEN_INFO) ); #endif pInfo->flags = CTOHL( pInfo->flags ); pInfo->ulMaxSessionCount = CTOHL( pInfo->ulMaxSessionCount ); pInfo->ulSessionCount = CTOHL( pInfo->ulSessionCount ); pInfo->ulMaxRwSessionCount = CTOHL( pInfo->ulMaxRwSessionCount ); pInfo->ulRwSessionCount = CTOHL( pInfo->ulRwSessionCount ); pInfo->ulMaxPinLen = CTOHL( pInfo->ulMaxPinLen ); pInfo->ulMinPinLen = CTOHL( pInfo->ulMinPinLen ); pInfo->ulTotalPublicMemory = CTOHL( pInfo->ulTotalPublicMemory ); pInfo->ulFreePublicMemory = CTOHL( pInfo->ulFreePublicMemory ); pInfo->ulTotalPrivateMemory = CTOHL( pInfo->ulTotalPrivateMemory ); pInfo->ulFreePrivateMemory = CTOHL( pInfo->ulFreePrivateMemory ); // These don't need to be swapped at this time. //pInfo->hardwareVersion = long_reverse( pInfo->hardwareVersion ); //pInfo->firmwareVersion = long_reverse( pInfo->firmwareVersion ); // #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x\n", "C_GetTokenInfo", rc ); #endif return rc; } #else // // CK_RV SC_GetTokenInfo( CK_SLOT_ID sid, CK_TOKEN_INFO_PTR pInfo ) { CK_TOKEN_INFO reply; CK_ULONG req_len; CK_ULONG repl_len; CK_RV rc; SLT_CHECK if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (!pInfo) return CKR_FUNCTION_FAILED; if (slot_id > MAX_SLOT_ID) return CKR_SLOT_ID_INVALID; // no arguments // req_len = 0; repl_len = sizeof(reply); rc = communicate( C_GETTOKENINFO, slot_id, NULL, req_len, &reply, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK) memcpy( pInfo, &reply, sizeof(CK_TOKEN_INFO) ); pInfo->flags = CTOHL( pInfo->flags ); pInfo->ulMaxSessionCount = CTOHL( pInfo->ulMaxSessionCount ); pInfo->ulSessionCount = CTOHL( pInfo->ulSessionCount ); pInfo->ulMaxRwSessionCount = CTOHL( pInfo->ulMaxRwSessionCount ); pInfo->ulRwSessionCount = CTOHL( pInfo->ulRwSessionCount ); pInfo->ulMaxPinLen = CTOHL( pInfo->ulMaxPinLen ); pInfo->ulMinPinLen = CTOHL( pInfo->ulMinPinLen ); pInfo->ulTotalPublicMemory = CTOHL( pInfo->ulTotalPublicMemory ); pInfo->ulFreePublicMemory = CTOHL( pInfo->ulFreePublicMemory ); pInfo->ulTotalPrivateMemory = CTOHL( pInfo->ulTotalPrivateMemory ); pInfo->ulFreePrivateMemory = CTOHL( pInfo->ulFreePrivateMemory ); // These don't need to be swapped at this time. //pInfo->hardwareVersion = long_reverse( pInfo->hardwareVersion ); //pInfo->firmwareVersion = long_reverse( pInfo->firmwareVersion ); // #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x\n", "C_GetTokenInfo", rc ); #endif return rc; } #endif #ifdef PKCS64 // // CK_RV SC_GetMechanismList( CK_SLOT_ID sid, CK_MECHANISM_TYPE_PTR pMechList, CK_ULONG_PTR count ) { GetMechList_Args args; CK_BYTE * reply = NULL; CK_ULONG req_len; CK_ULONG repl_len; CK_ULONG i; CK_RV rc; CK_MECHANISM_TYPE_32 *mechp; SLT_CHECK // This is the last in the list of variables. if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (count == NULL) return CKR_FUNCTION_FAILED; req_len = sizeof(args); if (slot_id > MAX_SLOT_ID) return CKR_SLOT_ID_INVALID; if (pMechList != NULL) { args.list_length = HTOCL( *count ); args.length_only = FALSE; repl_len = sizeof(CK_ULONG_32) + (*count * sizeof(CK_MECHANISM_TYPE_32)); } else { args.list_length = 0; args.length_only = TRUE; repl_len = sizeof(CK_ULONG_32); } reply = (CK_BYTE *)malloc(repl_len); if (!reply) return CKR_HOST_MEMORY; rc = communicate( C_GETMECHANISMLIST, slot_id, &args, req_len, reply, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK) { *count = *(CK_ULONG_32 *)reply; // memcpy( count, reply, sizeof(CK_ULONG) ); // Swap the reply length *count = CTOHL( *count ); if (pMechList != NULL) { #if __64BIT__ mechp = (CK_MECHANISM_TYPE_32 *)(reply + sizeof(CK_ULONG_32)); for (i=0; i < *count; i++) { #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: Mechanism[%d] = 0x%08x \n", "C_GetMechanismList", i, pMechList[i] ); #endif printf("%-25s: Mechanism[%d] = 0x%08x \n", "C_GetMechanismList", i, CTOHL(mechp[i]) ); pMechList[i] = CTOHL( mechp[i] ); } #else memcpy( pMechList, reply + sizeof(CK_ULONG), *count * sizeof(CK_MECHANISM_TYPE) ); for (i=0; i < *count; i++) { #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: Mechanism[%d] = 0x%08x \n", "C_GetMechanismList", i, pMechList[i] ); #endif pMechList[i] = CTOHL( pMechList[i] ); } #endif } } free( reply ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, # mechanisms: %d\n", "C_GetMechanismList", rc, *count ); #endif return rc; } #else // // CK_RV SC_GetMechanismList( CK_SLOT_ID sid, CK_MECHANISM_TYPE_PTR pMechList, CK_ULONG_PTR count ) { GetMechList_Args args; CK_BYTE * reply = NULL; CK_ULONG req_len; CK_ULONG repl_len; CK_ULONG i; CK_RV rc; SLT_CHECK // This is the last in the list of variables. if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (count == NULL) return CKR_FUNCTION_FAILED; req_len = sizeof(args); if (slot_id > MAX_SLOT_ID) return CKR_SLOT_ID_INVALID; if (pMechList != NULL) { args.list_length = HTOCL( *count ); args.length_only = FALSE; repl_len = sizeof(CK_ULONG) + (*count * sizeof(CK_MECHANISM_TYPE)); } else { args.list_length = 0; args.length_only = TRUE; repl_len = sizeof(CK_ULONG); } reply = (CK_BYTE *)malloc(repl_len); if (!reply) return CKR_HOST_MEMORY; rc = communicate( C_GETMECHANISMLIST, slot_id, &args, req_len, reply, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK) { memcpy( count, reply, sizeof(CK_ULONG) ); // Swap the reply length *count = CTOHL( *count ); if (pMechList != NULL) { memcpy( pMechList, reply + sizeof(CK_ULONG), *count * sizeof(CK_MECHANISM_TYPE) ); for (i=0; i < *count; i++) { #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: Mechanism[%d] = 0x%08x \n", "C_GetMechanismList", i, pMechList[i] ); #endif pMechList[i] = CTOHL( pMechList[i] ); } } } free( reply ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, # mechanisms: %d\n", "C_GetMechanismList", rc, *count ); #endif return rc; } #endif // // #ifdef PKCS64 CK_RV SC_GetMechanismInfo( CK_SLOT_ID sid, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo ) { GetMechInfo_Args args; CK_ULONG req_len, repl_len; CK_RV rc; CK_MECHANISM_INFO_32 reply; SLT_CHECK if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (pInfo == NULL) return CKR_FUNCTION_FAILED; if (slot_id > MAX_SLOT_ID) return CKR_SLOT_ID_INVALID; req_len = sizeof(args); repl_len = sizeof(reply); args.mech_type = HTOCL( type ); rc = communicate( C_GETMECHANISMINFO, slot_id, &args, req_len, &reply, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK) { #ifdef __64BIT__ pInfo->ulMinKeySize = CTOHL(reply.ulMinKeySize); pInfo->ulMaxKeySize = CTOHL(reply.ulMaxKeySize); pInfo->flags = CTOHL(reply.flags); #else memcpy( pInfo, &reply, sizeof(CK_MECHANISM_INFO) ); pInfo->ulMinKeySize = CTOHL( pInfo->ulMinKeySize ); pInfo->ulMaxKeySize = CTOHL( pInfo->ulMaxKeySize ); pInfo->flags = CTOHL( pInfo->flags ); #endif } #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, mech type = %08x\n", "C_GetMechanismInfo", rc, type ); #endif return rc; } #else CK_RV SC_GetMechanismInfo( CK_SLOT_ID sid, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo ) { GetMechInfo_Args args; CK_ULONG req_len, repl_len; CK_RV rc; CK_MECHANISM_INFO reply; SLT_CHECK if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (pInfo == NULL) return CKR_FUNCTION_FAILED; if (slot_id > MAX_SLOT_ID) return CKR_SLOT_ID_INVALID; req_len = sizeof(args); repl_len = sizeof(reply); args.mech_type = HTOCL( type ); rc = communicate( C_GETMECHANISMINFO, slot_id, &args, req_len, &reply, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK) { memcpy( pInfo, &reply, sizeof(CK_MECHANISM_INFO) ); pInfo->ulMinKeySize = CTOHL( pInfo->ulMinKeySize ); pInfo->ulMaxKeySize = CTOHL( pInfo->ulMaxKeySize ); pInfo->flags = CTOHL( pInfo->flags ); } #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, mech type = %08x\n", "C_GetMechanismInfo", rc, type ); #endif return rc; } #endif // // CK_RV SC_InitPIN( ST_SESSION_HANDLE sSession, CK_CHAR_PTR pPin, CK_ULONG ulPinLen ) { InitPIN_Args args; HOST_SESSION_HANDLE * node = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (pPin == NULL) return CKR_PIN_INVALID; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; if (ulPinLen >MAX_PIN_LEN) return CKR_PIN_LEN_RANGE; slot_id = SLOTID; if (slot_id > MAX_SLOT_ID) return CKR_SLOT_ID_INVALID; req_len = sizeof(args); repl_len = 0; args.session_handle = HTOCL( SESSION ); args.pin_len = HTOCL( ulPinLen ); memcpy( &args.pin, pPin, ulPinLen ); rc = communicate( C_INITPIN, slot_id, &args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); // there is no reply data // #ifdef DEBUGON logit(LOG_DEBUG,"%-25s: rc = %x\n", "C_InitPIN", rc ); #endif return rc; } // // CK_RV SC_SetPIN( ST_SESSION_HANDLE sSession, CK_CHAR_PTR pOldPin, CK_ULONG ulOldLen, CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen ) { SetPIN_Args args; HOST_SESSION_HANDLE * node = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if ((pOldPin == NULL) || (pNewPin == NULL)) return CKR_PIN_INVALID; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; if (ulNewLen >MAX_PIN_LEN) return CKR_PIN_LEN_RANGE; slot_id = SLOTID; if (slot_id > MAX_SLOT_ID) return CKR_SLOT_ID_INVALID; req_len = sizeof(args); repl_len = 0; // no reply args.session_handle = HTOCL( SESSION ); args.old_pin_len = HTOCL( ulOldLen ); args.new_pin_len = HTOCL( ulNewLen ); memcpy( &args.old_pin, pOldPin, ulOldLen ); memcpy( &args.new_pin, pNewPin, ulNewLen ); rc = communicate( C_SETPIN, slot_id, &args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); // there is no reply data // #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x\n", "C_SetPIN", rc ); #endif return rc; } #ifdef PKCS64 // // CK_RV SC_OpenSession( CK_SLOT_ID sid, CK_FLAGS flags, CK_SESSION_HANDLE_PTR phSession ) { OpenSession_Args args; HOST_SESSION_HANDLE * node = NULL; CK_BYTE * reply = NULL; CK_ULONG req_len, repl_len; CK_RV rc; SLT_CHECK #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: sid %d slot_id %d, \n",">SC_OpenSession",sid,slot_id); #endif if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (phSession == NULL) return CKR_FUNCTION_FAILED; if (slot_id > MAX_SLOT_ID) return CKR_SLOT_ID_INVALID; rc = MY_LockMutex(); if (rc != CKR_OK) { #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x sid %d slotid %d\n", "C_OpenSession", rc,sid,slot_id ); #endif return rc; } // do we need a process handle too? // if (pid_list[slot_id - 1] == 0) { repl_len = sizeof(CK_SESSION_HANDLE_32) + sizeof(CK_ULONG_32); args.req_proc_handle = TRUE; } else { repl_len = sizeof(CK_SESSION_HANDLE_32); args.req_proc_handle = FALSE; } reply = (CK_BYTE *)malloc(repl_len); if (!reply) rc = CKR_HOST_MEMORY; else { // allocate the node here instead of inside the CKR_OK processing block // after the call to communcate() because if there is a host memory // error, we want to know before we create a session on the coprocessor // node = (HOST_SESSION_HANDLE *)malloc(sizeof(HOST_SESSION_HANDLE)); if (!node) rc = CKR_HOST_MEMORY; else { args.slot_id = HTOCL( slot_id ); args.flags = HTOCL( flags ); // In the case of a STDLL, nothing is even passed int. args.application_ptr = NULL; // not used args.notify = NULL; // not used args.slot_id = HTOCL( slot_id ); req_len = sizeof(args); rc = communicate( C_OPENSESSION, slot_id, &args, req_len, reply, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK) { node->handle = *(CK_SESSION_HANDLE_32 *)reply; // memcpy( &node->handle, reply, sizeof(CK_SESSION_HANDLE_32) ); node->slot_id = slot_id; node->host_session = next_session_handle++; node->handle = CTOHL(node->handle); // Do this since the all the // code from LEX swaps // this. In reality this // is not necessary, but // rather than change // every location which // uses the node->handle // it is simpler to just // swap it here. if (args.req_proc_handle == TRUE) { pid_list[slot_id - 1] = *(CK_SESSION_HANDLE_32 *)(reply + sizeof(CK_ULONG_32) ); // memcpy( &pid_list[slot_id - 1], reply + // sizeof(CK_SESSION_HANDLE_32), sizeof(CK_ULONG_32) ); pid_list[slot_id - 1] = CTOHL( pid_list[slot_id - 1] ); } *phSession = node->handle; // main api handles the control block free(node); } else free( node ); // only free the node if the OpenSession attempt failed } } if (reply) free( reply ); MY_UnlockMutex(); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x ", "C_OpenSession", rc ); if (rc == CKR_OK) logit(LOG_DEBUG, "sess = %d", *phSession ); #endif return rc; } #else // // CK_RV SC_OpenSession( CK_SLOT_ID sid, CK_FLAGS flags, CK_SESSION_HANDLE_PTR phSession ) { OpenSession_Args args; HOST_SESSION_HANDLE * node = NULL; CK_BYTE * reply = NULL; CK_ULONG req_len, repl_len; CK_RV rc; SLT_CHECK #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: sid %d slot_id %d, \n",">SC_OpenSession",sid,slot_id); #endif if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (phSession == NULL) return CKR_FUNCTION_FAILED; if (slot_id > MAX_SLOT_ID) return CKR_SLOT_ID_INVALID; rc = MY_LockMutex(); if (rc != CKR_OK) { #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x sid %d slotid %d\n", "C_OpenSession", rc,sid,slot_id ); #endif return rc; } // do we need a process handle too? // if (pid_list[slot_id - 1] == 0) { repl_len = sizeof(CK_SESSION_HANDLE) + sizeof(CK_ULONG); args.req_proc_handle = TRUE; } else { repl_len = sizeof(CK_SESSION_HANDLE); args.req_proc_handle = FALSE; } reply = (CK_BYTE *)malloc(repl_len); if (!reply) rc = CKR_HOST_MEMORY; else { // allocate the node here instead of inside the CKR_OK processing block // after the call to communcate() because if there is a host memory // error, we want to know before we create a session on the coprocessor // node = (HOST_SESSION_HANDLE *)malloc(sizeof(HOST_SESSION_HANDLE)); if (!node) rc = CKR_HOST_MEMORY; else { args.slot_id = HTOCL( slot_id ); args.flags = HTOCL( flags ); // In the case of a STDLL, nothing is even passed int. args.application_ptr = NULL; // not used args.notify = NULL; // not used args.slot_id = HTOCL( slot_id ); req_len = sizeof(args); rc = communicate( C_OPENSESSION, slot_id, &args, req_len, reply, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK) { memcpy( &node->handle, reply, sizeof(CK_SESSION_HANDLE) ); node->slot_id = slot_id; node->host_session = next_session_handle++; node->handle = CTOHL(node->handle); // Do this since the all the // code from LEX swaps // this. In reality this // is not necessary, but // rather than change // every location which // uses the node->handle // it is simpler to just // swap it here. if (args.req_proc_handle == TRUE) { memcpy( &pid_list[slot_id - 1], reply + sizeof(CK_SESSION_HANDLE), sizeof(CK_ULONG) ); pid_list[slot_id - 1] = CTOHL( pid_list[slot_id - 1] ); } *phSession = node->handle; // main api handles the control block free(node); } else free( node ); // only free the node if the OpenSession attempt failed } } if (reply) free( reply ); MY_UnlockMutex(); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x ", "C_OpenSession", rc ); if (rc == CKR_OK) logit(LOG_DEBUG, "sess = %d", *phSession ); #endif return rc; } #endif // // // CK_RV SC_CloseSession( ST_SESSION_HANDLE sSession ) { CloseSession_Args args; HOST_SESSION_HANDLE * node = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; args.session_handle = HTOCL( SESSION ); slot_id = SLOTID; req_len = sizeof(args); repl_len = 0; // no reply data rc = communicate( C_CLOSESESSION, slot_id, &args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x sess = %d\n", "C_CloseSession", rc, SESSION ); #endif return rc; } // // CK_RV SC_CloseAllSessions( CK_SLOT_ID sid ) { CK_ULONG req_len, repl_len; CK_RV rc; SLT_CHECK if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; req_len = 0; repl_len = 0; rc = communicate( C_CLOSEALLSESSIONS, slot_id, NULL, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x\n", "C_CloseAllSessions", rc ); #endif return rc; } #ifdef PKCS64 // // CK_RV SC_GetSessionInfo( ST_SESSION_HANDLE sSession, CK_SESSION_INFO_PTR pInfo ) { GetSessionInfo_Args args; HOST_SESSION_HANDLE * node = NULL; CK_SESSION_INFO_32 info; CK_ULONG req_len, repl_len; CK_RV rc; CK_SLOT_ID slot_id; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; if (!pInfo) { return CKR_FUNCTION_FAILED; } args.session_handle = HTOCL( SESSION ); slot_id = SLOTID; req_len = sizeof(args); repl_len = sizeof(info); rc = communicate( C_GETSESSIONINFO, slot_id, &args, req_len, &info, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK) { #ifdef __64BIT__ pInfo->slotID = sSession.slotID; pInfo->state = info->state; pInfo->flags = info->flags; pInfo->ulDeviceError = info->ulDeviceError; #else memcpy( pInfo, &info, sizeof(info) ); #endif // Normalize the session information for STDLL pInfo->slotID = sSession.slotID; pInfo->state = CTOHL( pInfo->state ); pInfo->flags = CTOHL( pInfo->flags ); pInfo->ulDeviceError = CTOHL( pInfo->ulDeviceError ); } #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d\n", "C_GetSessionInfo", rc, SESSION ); #endif return rc; } #else // // CK_RV SC_GetSessionInfo( ST_SESSION_HANDLE sSession, CK_SESSION_INFO_PTR pInfo ) { GetSessionInfo_Args args; HOST_SESSION_HANDLE * node = NULL; CK_SESSION_INFO info; CK_ULONG req_len, repl_len; CK_RV rc; CK_SLOT_ID slot_id; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; if (!pInfo) { return CKR_FUNCTION_FAILED; } args.session_handle = HTOCL( SESSION ); slot_id = SLOTID; req_len = sizeof(args); repl_len = sizeof(info); rc = communicate( C_GETSESSIONINFO, slot_id, &args, req_len, &info, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK) { memcpy( pInfo, &info, sizeof(info) ); // Normalize the session information for STDLL pInfo->slotID = sSession.slotID; pInfo->state = CTOHL( pInfo->state ); pInfo->flags = CTOHL( pInfo->flags ); pInfo->ulDeviceError = CTOHL( pInfo->ulDeviceError ); } #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d\n", "C_GetSessionInfo", rc, SESSION ); #endif return rc; } #endif // // CK_RV SC_Login( ST_SESSION_HANDLE sSession, CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG ulPinLen ) { Login_Args args; HOST_SESSION_HANDLE * node = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (!pPin || ulPinLen > MAX_PIN_LEN) return CKR_PIN_INCORRECT; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; slot_id = SLOTID; args.session_handle = HTOCL( SESSION ); args.user_type = HTOCL( userType ); args.pin_len = HTOCL( ulPinLen ); memcpy( &args.pin, pPin, ulPinLen ); req_len = sizeof(args); repl_len = 0; rc = communicate( C_LOGIN, slot_id, &args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x\n", "C_Login", rc ); #endif return rc; } // // CK_RV SC_Logout( ST_SESSION_HANDLE sSession ) { Logout_Args args; HOST_SESSION_HANDLE * node = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; slot_id = SLOTID; args.session_handle = HTOCL( SESSION ); req_len = sizeof(args); repl_len = 0; rc = communicate( C_LOGOUT, slot_id, &args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x\n", "C_Logout", rc ); #endif return rc; } // // CK_RV SC_CreateObject( ST_SESSION_HANDLE sSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject ) { CreateObject_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; ATTRIBUTE * attrib_block = NULL; CK_BYTE * ptr = NULL; CK_ATTRIBUTE * attr = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_ULONG tmpl_len; CK_ULONG i; CK_RV rc; SESS_SET #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: \n", ">>C_CreateObject" ); #endif if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; if ( !pTemplate ) { return CKR_TEMPLATE_INCOMPLETE; // a template is required } if ( ulCount == 0){ return CKR_TEMPLATE_INCOMPLETE; // this is the best of the choices } slot_id = SLOTID; // compute the total template size // tmpl_len = 0; #if __64BIT__ for (attr = pTemplate, i = 0; i < ulCount; i++, attr++) tmpl_len += sizeof(ATTRIBUTE) + get_attrib_len(attr); // attr->ulValueLen; #else for (attr = pTemplate, i = 0; i < ulCount; i++, attr++) tmpl_len += sizeof(ATTRIBUTE) + attr->ulValueLen; #endif args = (CreateObject_Args *)malloc(sizeof(CreateObject_Args) + tmpl_len); if (!args) return CKR_HOST_MEMORY; args->session_handle = HTOCL( SESSION ); args->attribute_count = HTOCL( ulCount ); args->attribute_block_len = HTOCL( tmpl_len ); // set the attribute block pointer to point to the extra space we allocated // attrib_block = (ATTRIBUTE *)((CK_BYTE*)args + sizeof(CreateObject_Args)); // build the new attribute block // attr = pTemplate; ptr = (CK_BYTE *)attrib_block; for (i = 0; i < ulCount; i++, attr++) { ATTRIBUTE *p_attrib = (ATTRIBUTE *)ptr; unsigned char *pd,*ps; unsigned long *pl; p_attrib->type = HTOCL( attr->type ); #if __64BIT__ p_attrib->value_length = HTOCL(get_attrib_len(attr)); //attr->ulValueLen); #else p_attrib->value_length = HTOCL( attr->ulValueLen ); #endif #ifdef DEBUGON logit(LOG_DEBUG, "\t\t\t>>%-25s: \n", "C_CreateObject -- as passed before endian adjust" ); { CK_BYTE *p; p = (CK_BYTE *)attr->pValue; logit(LOG_DEBUG, "\t\t\t\t>>%3d: Attribute type: 0x%08x\n", i, attr->type ); logit(LOG_DEBUG, "\t\t\t\t>>Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (p != NULL)) logit(LOG_DEBUG, "\t\t\t\t>>First 4 bytes: %02x %02x %02x %02x", p[0], p[1], p[2], p[3] ); logit(LOG_DEBUG, "\n\n"); } #endif // WARNING: on BIG-ENDIAN machines, it is important to ensure that // the value of the attribute has the appropriate endianness if it will // be used by the coprocessor. For instance, CKA_VALUE for a data_object // is ignored. But CKA_KEY_TYPE attribute is used by the coprocessor // so it must be in LITTLE-ENDIAN format before the call to CreateObject. // #ifndef _BIG_ENDIAN memcpy( (ptr + sizeof(ATTRIBUTE)), attr->pValue, attr->ulValueLen ); #else // We need to swap the values. pd = (unsigned char *)(ptr + sizeof(ATTRIBUTE)); #if __64BIT__ copy_attribute_value(attr->pValue,ptr + sizeof(ATTRIBUTE), attr); #else memcpy( (ptr + sizeof(ATTRIBUTE)), attr->pValue, attr->ulValueLen ); #endif #if __64BIT__ if ( attr->ulValueLen == 8 ) { #else if ( attr->ulValueLen == 4 ) { #endif #ifdef PKCS64 ModifyAttribute(attr->type,(CK_ULONG_PTR_32)pd); #else ModifyAttribute(attr->type,(CK_ULONG_PTR)pd); #endif } #endif // This is an error since we have performed byte swapping on // the p_attrib->value_length. This will core dump. //ptr += sizeof(ATTRIBUTE) + p_attrib->value_length; #if __64BIT__ ptr += sizeof(ATTRIBUTE) + get_attrib_len(attr); //attr->ulValueLen; #else ptr += sizeof(ATTRIBUTE) + attr->ulValueLen; #endif } req_len = sizeof(CreateObject_Args) + tmpl_len; repl_len = sizeof(CK_OBJECT_HANDLE); #if __64BIT__ { CK_OBJECT_HANDLE_32 thandle; rc = communicate( C_CREATEOBJECT, slot_id, args, req_len, &thandle, &repl_len, NULL, 0, NULL, 0 ); *phObject = thandle; } #else rc = communicate( C_CREATEOBJECT, slot_id, args, req_len, phObject, &repl_len, NULL, 0, NULL, 0 ); #endif free( args ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x\n", "C_CreateObject", rc ); { int i; for (i=0; i < ulCount; i++) { if (pTemplate[i].type == CKA_CLASS) logit(LOG_DEBUG, "%28s: 0x%02X\n", "Object Type", *(CK_ULONG *)pTemplate[i].pValue ); } } if (rc == CKR_OK) logit(LOG_DEBUG, "%28s: %d\n", "Handle", *phObject ); #endif return rc; } // // CK_RV SC_CopyObject( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phNewObject ) { CopyObject_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; ATTRIBUTE * attrib_block = NULL; CK_BYTE * ptr = NULL; CK_SLOT_ID slot_id; CK_ATTRIBUTE_PTR attr; CK_ULONG req_len, repl_len; CK_ULONG tmpl_len; CK_ULONG i; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; slot_id = SLOTID; // compute the total template size // tmpl_len = 0; #if __64BIT__ for (attr = pTemplate, i = 0; i < ulCount; i++, attr++) tmpl_len += sizeof(ATTRIBUTE) + get_attrib_len(attr); // attr->ulValueLen; #else for (attr = pTemplate, i = 0; i < ulCount; i++, attr++) tmpl_len += sizeof(ATTRIBUTE) + attr->ulValueLen; #endif args = (CopyObject_Args *)malloc(sizeof(CopyObject_Args) + tmpl_len); if (!args) return CKR_HOST_MEMORY; args->session_handle = HTOCL( SESSION ); args->object_handle = ( hObject ); // Object handles have meaning at the // adapter only and are NOT reversed args->attribute_count = HTOCL( ulCount ); args->attribute_block_len = HTOCL( tmpl_len ); // set the attribute block pointer to point to the extra space we allocated // attrib_block = (ATTRIBUTE *)((CK_BYTE*)args + sizeof(CopyObject_Args)); // build the new attribute block // attr = pTemplate; ptr = (CK_BYTE *)attrib_block; for (i = 0; i < ulCount; i++, attr++) { ATTRIBUTE *p_attrib = (ATTRIBUTE *)ptr; unsigned char *pd,*ps; unsigned long *pl; p_attrib->type = HTOCL( attr->type ); #if __64BIT__ p_attrib->value_length = HTOCL(get_attrib_len(attr)); //attr->ulValueLen); #else p_attrib->value_length = HTOCL( attr->ulValueLen ); #endif // WARNING: on BIG-ENDIAN machines, it is important to ensure that // the value of the attribute has the appropriate endianness if it will // be used by the coprocessor. For instance, CKA_VALUE for a data_object // is ignored. But CKA_KEY_TYPE attribute is used by the coprocessor // so it must be in LITTLE-ENDIAN format before the call to CreateObject. // #ifndef _BIG_ENDIAN #if __64BIT__ memcpy( (ptr + sizeof(ATTRIBUTE)), attr->pValue, get_attrib_len(attr)); //attr->ulValueLen ); #else memcpy( (ptr + sizeof(ATTRIBUTE)), attr->pValue, attr->ulValueLen ); #endif #else // We need to swap the values. pd = (unsigned char *)(ptr + sizeof(ATTRIBUTE)); ps = (unsigned char *)(attr->pValue); #if __64BIT__ copy_attribute_value(ps,pd,attr); #else memcpy(pd, ps, attr->ulValueLen); #endif #if __64BIT__ if ( attr->ulValueLen == 8 ) { #else if ( attr->ulValueLen == 4 ) { #endif #ifdef PKCS64 ModifyAttribute(attr->type,(CK_ULONG_PTR_32)pd); #else ModifyAttribute(attr->type,(CK_ULONG_PTR)pd); #endif } #endif ptr += sizeof(ATTRIBUTE) + get_attrib_len(attr); //attr->ulValueLen; // p_attrib->value_length; } req_len = sizeof(CopyObject_Args) + tmpl_len; repl_len = sizeof(CK_OBJECT_HANDLE); #if __64BIT__ { CK_OBJECT_HANDLE_32 nObject; rc = communicate( C_COPYOBJECT, slot_id, args, req_len, &nObject, &repl_len, NULL, 0, NULL, 0 ); *phNewObject = nObject; } #else rc = communicate( C_COPYOBJECT, slot_id, args, req_len, phNewObject, &repl_len, NULL, 0, NULL, 0 ); #endif free( args ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, old handle = %d, new handle = %d\n", "C_CopyObject", rc, hObject, *phNewObject ); #endif return rc; } // // CK_RV SC_DestroyObject( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject ) { DestroyObject_Args args; HOST_SESSION_HANDLE * node = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; slot_id = SLOTID; args.session_handle = HTOCL( SESSION ); args.object_handle = ( hObject ); req_len = sizeof(args); repl_len = 0; rc = communicate( C_DESTROYOBJECT, slot_id, &args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, handle = %d\n", "C_DestroyObject", rc, hObject ); #endif return rc; } // // CK_RV SC_GetObjectSize( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize ) { GetObjectSize_Args args; HOST_SESSION_HANDLE * node = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_ULONG_32 size; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; if (!pulSize) { return CKR_ARGUMENTS_BAD; } slot_id = SLOTID; args.session_handle = HTOCL( SESSION ); args.object_handle = ( hObject ); req_len = sizeof(args); repl_len = sizeof(size); rc = communicate( C_GETOBJECTSIZE, slot_id, &args, req_len, &size, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK) *pulSize = CTOHL( size ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, handle = %d\n", "C_GetObjectSize", rc, hObject ); #endif return rc; } // This routine is just temporary. It will be redesigned after Sept 15 release // #ifdef PKCS64 CK_RV SC_GetAttributeValue( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ) { GetAttributeValue_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; CK_BYTE * buffer = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; #if __64BIT__ CK_ULONG_32 size; // SAB FIXME 64Bit #else CK_ULONG size; #endif CK_ULONG i; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; if ( !pTemplate ){ return CKR_ARGUMENTS_BAD; } if ( ulCount == 0 ){ return CKR_ARGUMENTS_BAD; } slot_id = SLOTID; // request data is GetAttributeValue_Args + array of CK_ATTRIBUTE_TYPE // req_len = sizeof(GetAttributeValue_Args) + (ulCount * sizeof(CK_ATTRIBUTE_TYPE_32)); args = (GetAttributeValue_Args *)malloc( req_len ); if (!args) return CKR_HOST_MEMORY; else { CK_ATTRIBUTE_PTR attr = NULL; CK_ATTRIBUTE_TYPE_32 * attrib_block = NULL; args->session_handle = HTOCL( SESSION ); args->object_handle = ( hObject ); args->attribute_count = HTOCL( ulCount ); args->size_only = TRUE; args->attribute_block_len = HTOCL( ulCount * sizeof(CK_ATTRIBUTE_TYPE_32) ); // set the attribute block pointer to point to the extra space we allocated // attrib_block = (CK_ATTRIBUTE_TYPE_32 *)((CK_BYTE*)args + sizeof(GetAttributeValue_Args)); // build the new attribute block // attr = pTemplate; for (i = 0; i < ulCount; i++, attr++) { CK_ULONG_32 tmp = HTOCL( attr->type ); // We are only dealing with the ATTRIBUTE types memcpy( (CK_BYTE *)attrib_block, &tmp, sizeof(CK_ATTRIBUTE_TYPE_32) ); attrib_block++; } } repl_len = sizeof(size); rc = communicate( C_GETATTRIBUTEVALUE, slot_id, args, req_len, &size, &repl_len, NULL, 0, NULL, 0 ); #ifdef _BIG_ENDIAN // XXX do we really need to reverse this size value... Since we are // I think so, since this is an unsigned long value returned from the Leeds // adapter and therefore it is in Little_endian format size = CTOHL(size); #endif // the coprocessor should never return CKR_BUFFER_TOO_SMALL // if (rc != CKR_OK && rc != CKR_ATTRIBUTE_SENSITIVE && rc != CKR_ATTRIBUTE_TYPE_INVALID) { free( args ); return rc; } // now, allocate the proper-sized reply block and issue the request again // buffer = (CK_BYTE *)malloc(size); if (!buffer) { free( args ); return CKR_HOST_MEMORY; } args->size_only = FALSE; repl_len = size; rc = communicate( C_GETATTRIBUTEVALUE, slot_id, args, req_len, buffer, &repl_len, NULL, 0, NULL, 0 ); // Cryptoki allows for C_GetAttributeValue to return CKR_BUFFER_TOO_SMALL but the // coprocessor should never return that // if (rc == CKR_OK || rc == CKR_ATTRIBUTE_SENSITIVE || rc == CKR_ATTRIBUTE_TYPE_INVALID) { CK_ATTRIBUTE_PTR ck_attr; CK_BYTE * ptr = (CK_BYTE *)buffer; // walk through the reply and update the template. it's safe to assume the // elements in the template and the reply have the same ordering. // ck_attr = pTemplate; // SAB XXX the below handling of attributes for 32bit is probably // wrong.... We really need to only swap the attributes which are of // type CK_ULONG... #if __64BIT__ for (i=0;i< ulCount; i++){ ATTRIBUTE *attr = (ATTRIBUTE *)ptr; // Attribute from the card.. CK_BYTE *val = ptr + sizeof(ATTRIBUTE); // actual value of the attribute CK_ULONG_32 val_len = CTOHL(attr->value_length); // Each attribute needs to bhe handled according // to the type... if (val_len == (CK_ULONG_32)(-1)){ ck_attr->ulValueLen = val_len; } else if ( ck_attr->pValue == NULL) { ck_attr->ulValueLen = val_len; } else if (ck_attr->ulValueLen < val_len){ ck_attr->ulValueLen = (CK_ULONG_32)(-1); if (rc == CKR_OK) rc = CKR_BUFFER_TOO_SMALL; } else { switch(ck_attr->type){ case CKA_CLASS: case CKA_KEY_TYPE: case CKA_MODULUS_BITS: case CKA_VALUE_BITS: case CKA_VALUE_LEN: case CKA_CERTIFICATE_TYPE: // SAB XXX 64bit { CK_ULONG *tval = (CK_ULONG *)(ck_attr->pValue); ck_attr->ulValueLen = sizeof(CK_ULONG); if ( ck_attr->pValue) { *tval = HTOCL((CK_ULONG_32)*val); } } break; default: ck_attr->ulValueLen = val_len; if ( ck_attr->pValue){ memcpy(ck_attr->pValue,val,val_len); } break; } } ck_attr++; // Next attribute in the template from the caler if (val_len == (CK_ULONG_32)(-1)) ptr += sizeof(ATTRIBUTE); else ptr += sizeof(ATTRIBUTE) + val_len; } #else for (i=0; i < ulCount; i++) { ATTRIBUTE * attr = (ATTRIBUTE *)ptr; CK_BYTE * val = ptr + sizeof(ATTRIBUTE); CK_ULONG_32 val_len = CTOHL( attr->value_length ); if (val_len == (CK_ULONG_32)(-1)) { ck_attr->ulValueLen = val_len; } else if (ck_attr->pValue == NULL) { ck_attr->ulValueLen = val_len; } else if (ck_attr->ulValueLen < val_len) { ck_attr->ulValueLen = (CK_ULONG_32)(-1); if (rc == CKR_OK) rc = CKR_BUFFER_TOO_SMALL; } else { ck_attr->ulValueLen = val_len; if ( ck_attr->pValue ){ memcpy( ck_attr->pValue, val, val_len ); #ifdef _BIG_ENDIAN { CK_ULONG_PTR_32 pd; pd = (CK_ULONG_PTR_32)ck_attr->pValue; if ( val_len == sizeof(CK_ULONG_32) ) { ModifyAttribute(ck_attr->type,pd); } } #endif } // check for a valid pointer in the template. } ck_attr++; if (val_len == (CK_ULONG_32)(-1)) ptr += sizeof(ATTRIBUTE); else ptr += sizeof(ATTRIBUTE) + val_len; } #endif } if (args) free( args ); if (buffer) free( buffer ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, handle = %d\n", "C_GetAttributeValue", rc, hObject ); { CK_ATTRIBUTE *attr = NULL; CK_BYTE *ptr = NULL; attr = pTemplate; for (i=0; i < ulCount; i++, attr++) { ptr = (CK_BYTE *)attr->pValue; logit(LOG_DEBUG, " %3d: Attribute type: 0x%08x\n", i, attr->type ); logit(LOG_DEBUG, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) logit(LOG_DEBUG, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); logit(LOG_DEBUG, "\n\n"); } } #endif return rc; } #else CK_RV SC_GetAttributeValue( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ) { GetAttributeValue_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; CK_BYTE * buffer = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_ULONG_32 size; // SAB FIXME 64Bit CK_ULONG i; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; if ( !pTemplate ){ return CKR_ARGUMENTS_BAD; } if ( ulCount == 0 ){ return CKR_ARGUMENTS_BAD; } slot_id = SLOTID; // request data is GetAttributeValue_Args + array of CK_ATTRIBUTE_TYPE // req_len = sizeof(GetAttributeValue_Args) + (ulCount * sizeof(CK_ATTRIBUTE_TYPE)); args = (GetAttributeValue_Args *)malloc( req_len ); if (!args) return CKR_HOST_MEMORY; else { CK_ATTRIBUTE_PTR attr = NULL; CK_ATTRIBUTE_TYPE * attrib_block = NULL; args->session_handle = HTOCL( SESSION ); args->object_handle = ( hObject ); args->attribute_count = HTOCL( ulCount ); args->size_only = TRUE; args->attribute_block_len = HTOCL( ulCount * sizeof(CK_ATTRIBUTE_TYPE) ); // set the attribute block pointer to point to the extra space we allocated // attrib_block = (CK_ATTRIBUTE_TYPE *)((CK_BYTE*)args + sizeof(GetAttributeValue_Args)); // build the new attribute block // attr = pTemplate; for (i = 0; i < ulCount; i++, attr++) { CK_ULONG tmp = HTOCL( attr->type ); // We are only dealing with the ATTRIBUTE types memcpy( (CK_BYTE *)attrib_block, &tmp, sizeof(CK_ATTRIBUTE_TYPE) ); attrib_block++; } } repl_len = sizeof(size); rc = communicate( C_GETATTRIBUTEVALUE, slot_id, args, req_len, &size, &repl_len, NULL, 0, NULL, 0 ); #ifdef _BIG_ENDIAN // XXX do we really need to reverse this size value... Since we are // I think so, since this is an unsigned long value returned from the Leeds // adapter and therefore it is in Little_endian format size = CTOHL(size); #endif // the coprocessor should never return CKR_BUFFER_TOO_SMALL // if (rc != CKR_OK && rc != CKR_ATTRIBUTE_SENSITIVE && rc != CKR_ATTRIBUTE_TYPE_INVALID) { free( args ); return rc; } // now, allocate the proper-sized reply block and issue the request again // buffer = (CK_BYTE *)malloc(size); if (!buffer) { free( args ); return CKR_HOST_MEMORY; } args->size_only = FALSE; repl_len = size; rc = communicate( C_GETATTRIBUTEVALUE, slot_id, args, req_len, buffer, &repl_len, NULL, 0, NULL, 0 ); // Cryptoki allows for C_GetAttributeValue to return CKR_BUFFER_TOO_SMALL but the // coprocessor should never return that // if (rc == CKR_OK || rc == CKR_ATTRIBUTE_SENSITIVE || rc == CKR_ATTRIBUTE_TYPE_INVALID) { CK_ATTRIBUTE_PTR ck_attr; CK_BYTE * ptr = (CK_BYTE *)buffer; // walk through the reply and update the template. it's safe to assume the // elements in the template and the reply have the same ordering. // ck_attr = pTemplate; for (i=0; i < ulCount; i++) { ATTRIBUTE * attr = (ATTRIBUTE *)ptr; CK_BYTE * val = ptr + sizeof(ATTRIBUTE); CK_ULONG val_len = CTOHL( attr->value_length ); if (val_len == (CK_ULONG)(-1)) { ck_attr->ulValueLen = val_len; } else if (ck_attr->pValue == NULL) { ck_attr->ulValueLen = val_len; } else if (ck_attr->ulValueLen < val_len) { ck_attr->ulValueLen = (CK_ULONG)(-1); if (rc == CKR_OK) rc = CKR_BUFFER_TOO_SMALL; } else { ck_attr->ulValueLen = val_len; if ( ck_attr->pValue ){ memcpy( ck_attr->pValue, val, val_len ); #ifdef _BIG_ENDIAN { CK_ULONG_PTR pd; pd = (CK_ULONG_PTR)ck_attr->pValue; if ( val_len == sizeof(CK_ULONG) ) { ModifyAttribute(ck_attr->type,pd); } } #endif } // check for a valid pointer in the template. } ck_attr++; if (val_len == (CK_ULONG)(-1)) ptr += sizeof(ATTRIBUTE); else ptr += sizeof(ATTRIBUTE) + val_len; } } if (args) free( args ); if (buffer) free( buffer ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, handle = %d\n", "C_GetAttributeValue", rc, hObject ); { CK_ATTRIBUTE *attr = NULL; CK_BYTE *ptr = NULL; attr = pTemplate; for (i=0; i < ulCount; i++, attr++) { ptr = (CK_BYTE *)attr->pValue; logit(LOG_DEBUG, " %3d: Attribute type: 0x%08x\n", i, attr->type ); logit(LOG_DEBUG, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) logit(LOG_DEBUG, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); logit(LOG_DEBUG, "\n\n"); } } #endif return rc; } #endif // // CK_RV SC_SetAttributeValue( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ) { SetAttributeValue_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; ATTRIBUTE * attrib_block = NULL; CK_BYTE * ptr = NULL; CK_SLOT_ID slot_id; CK_ATTRIBUTE_PTR attr; CK_ULONG req_len, repl_len; CK_ULONG tmpl_len; CK_ULONG i; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; if ( !pTemplate ){ return CKR_ARGUMENTS_BAD; } if ( ulCount == 0 ){ return CKR_ARGUMENTS_BAD; } slot_id = SLOTID; // compute the total template size // tmpl_len = 0; #if __64BIT__ for (attr = pTemplate, i = 0; i < ulCount; i++, attr++) tmpl_len += sizeof(ATTRIBUTE) + get_attrib_len(attr); // attr->ulValueLen; #else for (attr = pTemplate, i = 0; i < ulCount; i++, attr++) tmpl_len += sizeof(ATTRIBUTE) + attr->ulValueLen; #endif args = (SetAttributeValue_Args *)malloc(sizeof(SetAttributeValue_Args) + tmpl_len); if (!args) return CKR_HOST_MEMORY; args->session_handle = HTOCL( SESSION ); args->object_handle = ( hObject ); args->attribute_count = HTOCL( ulCount ); args->attribute_block_len = HTOCL( tmpl_len ); // set the attribute block pointer to point to the extra space we allocated // attrib_block = (ATTRIBUTE *)((CK_BYTE*)args + sizeof(SetAttributeValue_Args)); // build the new attribute block // attr = pTemplate; ptr = (CK_BYTE *)attrib_block; for (i = 0; i < ulCount; i++, attr++) { ATTRIBUTE *p_attrib = (ATTRIBUTE *)ptr; p_attrib->type = HTOCL( attr->type ); #if __64BIT__ p_attrib->value_length = HTOCL(get_attrib_len(attr)); //attr->ulValueLen); #else p_attrib->value_length = HTOCL( attr->ulValueLen ); #endif // WARNING: on BIG-ENDIAN machines, it is important to ensure that // the value of the attribute has the appropriate endianness if it will // be used by the coprocessor. For instance, CKA_VALUE for a data_object // is ignored. But CKA_KEY_TYPE attribute is used by the coprocessor // so it must be in LITTLE-ENDIAN format before the call to CreateObject. // #ifndef _BIG_ENDIAN memcpy( (ptr + sizeof(ATTRIBUTE)), attr->pValue, attr->ulValueLen ); #else { unsigned char *pd,*ps; unsigned long *pl; // We need to swap the values. pd = (unsigned char *)(ptr + sizeof(ATTRIBUTE)); ps = (unsigned char *)(attr->pValue); #if __64BIT__ copy_attribute_value(ps,pd,attr); #else memcpy(pd, ps, attr->ulValueLen); #endif #if __64BIT__ if ( attr->ulValueLen == 8 ) { #else if ( attr->ulValueLen == 4 ) { #endif pl = (unsigned long *)attr->pValue; pl = (unsigned long *)ps; #ifdef PKCS64 ModifyAttribute(attr->type,(CK_ULONG_PTR_32)pd); #else ModifyAttribute(attr->type,(CK_ULONG_PTR)pd); #endif } } #endif //ptr += sizeof(ATTRIBUTE) + p_attrib->value_length; p_attrib is swapped #if __64BIT__ ptr += sizeof(ATTRIBUTE) + get_attrib_len(attr); //attr->ulValueLen; #else ptr += sizeof(ATTRIBUTE) + attr->ulValueLen; #endif } req_len = sizeof(SetAttributeValue_Args) + tmpl_len; repl_len = 0; rc = communicate( C_SETATTRIBUTEVALUE, slot_id, args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); free( args ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, handle = %d\n", "C_SetAttributeValue", rc, hObject ); attr = pTemplate; for (i=0; i < ulCount; i++, attr++) { ptr = (CK_BYTE *)attr->pValue; logit(LOG_DEBUG, " %3d: Attribute type: 0x%08x\n", i, attr->type ); logit(LOG_DEBUG, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) logit(LOG_DEBUG, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); logit(LOG_DEBUG, "\n\n"); } #endif return rc; } // // CK_RV SC_FindObjectsInit( ST_SESSION_HANDLE sSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ) { FindObjectsInit_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; ATTRIBUTE * attrib_block = NULL; CK_BYTE * ptr = NULL; CK_SLOT_ID slot_id; CK_ATTRIBUTE_PTR attr; CK_ULONG req_len, repl_len; CK_ULONG tmpl_len; CK_ULONG i; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; slot_id = SLOTID; // compute the total template size // tmpl_len = 0; #if __64BIT__ for (attr = pTemplate, i = 0; i < ulCount; i++, attr++) tmpl_len += sizeof(ATTRIBUTE) + get_attrib_len(attr); // attr->ulValueLen; #else for (attr = pTemplate, i = 0; i < ulCount; i++, attr++) tmpl_len += sizeof(ATTRIBUTE) + attr->ulValueLen; #endif args = (FindObjectsInit_Args *)malloc(sizeof(FindObjectsInit_Args) + tmpl_len); if (!args) return CKR_HOST_MEMORY; args->session_handle = HTOCL( SESSION ); args->attribute_count = HTOCL( ulCount ); args->attribute_block_len = HTOCL( tmpl_len ); // set the attribute block pointer to point to the extra space we allocated // attrib_block = (ATTRIBUTE *)((CK_BYTE*)args + sizeof(FindObjectsInit_Args)); // build the new attribute block // attr = pTemplate; ptr = (CK_BYTE *)attrib_block; for (i = 0; i < ulCount; i++, attr++) { ATTRIBUTE *p_attrib = (ATTRIBUTE *)ptr; p_attrib->type = HTOCL( attr->type ); #if __64BIT__ p_attrib->value_length = HTOCL(get_attrib_len(attr)); // attr->ulValueLen ); #else p_attrib->value_length = HTOCL( attr->ulValueLen ); #endif // WARNING: on BIG-ENDIAN machines, it is important to ensure that // the value of the attribute has the appropriate endianness if it will // be used by the coprocessor. For instance, CKA_VALUE for a data_object // is ignored. But CKA_KEY_TYPE attribute is used by the coprocessor // so it must be in LITTLE-ENDIAN format before the call to CreateObject. // #ifndef _BIG_ENDIAN memcpy( (ptr + sizeof(ATTRIBUTE)), attr->pValue, attr->ulValueLen ); #else { unsigned char *pd,*ps; unsigned long *pl; // We need to swap the values. pd = (unsigned char *)(ptr + sizeof(ATTRIBUTE)); ps = (unsigned char *)(attr->pValue); #if __64BIT__ copy_attribute_value(ps,pd,attr); #else memcpy(pd, ps, attr->ulValueLen); #endif #if __64BIT__ if ( attr->ulValueLen == 8 ) { #else if ( attr->ulValueLen == 4 ) { #endif pl = (unsigned long *)attr->pValue; pl = (unsigned long *)ps; #ifdef PKCS64 ModifyAttribute(attr->type,(CK_ULONG_PTR_32)pd); #else ModifyAttribute(attr->type,(CK_ULONG_PTR)pd); #endif } } #endif #if __64BIT__ ptr += sizeof(ATTRIBUTE) + get_attrib_len(attr); #else ptr += sizeof(ATTRIBUTE) + attr->ulValueLen; // Swapped p_attrib->value_length; #endif } req_len = sizeof(FindObjectsInit_Args) + tmpl_len; repl_len = 0; rc = communicate( C_FINDOBJECTSINIT, slot_id, args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); free( args ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x\n", "C_FindObjectsInit", rc ); attr = pTemplate; for (i=0; i < ulCount; i++, attr++) { ptr = (CK_BYTE *)attr->pValue; logit(LOG_DEBUG, " %3d: Attribute type: 0x%08x\n", i, attr->type ); logit(LOG_DEBUG, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) logit(LOG_DEBUG, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); logit(LOG_DEBUG, "\n\n"); } #endif return rc; } #ifdef PKCS64 // // CK_RV SC_FindObjects( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount ) { FindObjects_Args args; HOST_SESSION_HANDLE * node = NULL; CK_BYTE * reply = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_ULONG i; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; if (!phObject || !pulObjectCount) return CKR_ARGUMENTS_BAD; slot_id = SLOTID; args.session_handle = HTOCL( SESSION ); args.max_count = HTOCL( ulMaxObjectCount ); req_len = sizeof(args); repl_len = sizeof(CK_ULONG_32) + (ulMaxObjectCount * sizeof(CK_OBJECT_HANDLE_32)); reply = (CK_BYTE *)malloc(repl_len); if (!reply) return CKR_HOST_MEMORY; rc = communicate( C_FINDOBJECTS, slot_id, &args, req_len, reply, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK) { #if __64BIT__ *pulObjectCount = *(CK_ULONG_32*)reply; #else memcpy( pulObjectCount, reply, sizeof(CK_ULONG) ); #endif *pulObjectCount = CTOHL( *pulObjectCount ); // Failure to swap causes real problems #ifdef __64BIT__ { CK_OBJECT_HANDLE_32 *hp; hp = (CK_OBJECT_HANDLE_32 *)( (char *)reply + sizeof (CK_ULONG_32)); for (i=0; i < *pulObjectCount; i++) phObject[i] = ( hp[i] ); } #else memcpy( phObject, reply + sizeof(CK_ULONG_32), *pulObjectCount * sizeof(CK_OBJECT_HANDLE_32) ); // XXX WJH - Hmmm .... for (i=0; i < *pulObjectCount; i++) phObject[i] = ( phObject[i] ); #endif } free( reply ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, returned %d objects\n", "C_FindObjects", rc, *pulObjectCount ); #endif return rc; } #else // // CK_RV SC_FindObjects( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount ) { FindObjects_Args args; HOST_SESSION_HANDLE * node = NULL; CK_BYTE * reply = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_ULONG i; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; if (!phObject || !pulObjectCount) return CKR_ARGUMENTS_BAD; slot_id = SLOTID; args.session_handle = HTOCL( SESSION ); args.max_count = HTOCL( ulMaxObjectCount ); req_len = sizeof(args); repl_len = sizeof(CK_ULONG) + (ulMaxObjectCount * sizeof(CK_OBJECT_HANDLE)); reply = (CK_BYTE *)malloc(repl_len); if (!reply) return CKR_HOST_MEMORY; rc = communicate( C_FINDOBJECTS, slot_id, &args, req_len, reply, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK) { memcpy( pulObjectCount, reply, sizeof(CK_ULONG) ); *pulObjectCount = CTOHL( *pulObjectCount ); // Failure to swap causes real problems memcpy( phObject, reply + sizeof(CK_ULONG), *pulObjectCount * sizeof(CK_OBJECT_HANDLE) ); for (i=0; i < *pulObjectCount; i++) phObject[i] = ( phObject[i] ); } free( reply ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, returned %d objects\n", "C_FindObjects", rc, *pulObjectCount ); #endif return rc; } #endif // // CK_RV SC_FindObjectsFinal( ST_SESSION_HANDLE sSession ) { FindObjectsFinal_Args args; HOST_SESSION_HANDLE * node = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; slot_id = SLOTID; args.session_handle = HTOCL( SESSION ); req_len = sizeof(args); repl_len = 0; rc = communicate( C_FINDOBJECTSFINAL, slot_id, &args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x\n", "C_FindObjectsFinal", rc ); #endif return rc; } // // CK_RV SC_SeedRandom( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen ) { SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; return CKR_OK; } // // CK_RV SC_GenerateRandom( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen ) { GenerateRandom_Args args; HOST_SESSION_HANDLE * node = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len,len; CK_ULONG total = 0; CK_ULONG amt; CK_ULONG rc = CKR_OK; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; slot_id = SLOTID; // for now, the coprocessor is restricted to returning data in LEEDS_PACKETS // which limits each call to the card to 4096 bytes of random data... // len = ulRandomLen; while (len > 0 && (rc == CKR_OK)) { amt = MIN( len, LEEDS_MAX_REQ_LEN ); args.session_handle = HTOCL( SESSION ); args.num_bytes = HTOCL( amt ); req_len = sizeof(GenerateRandom_Args); repl_len = amt; rc = communicate( C_GENERATERANDOM, slot_id, &args, req_len, pRandomData + total, &repl_len, NULL, 0, NULL, 0 ); if (rc != CKR_OK) return rc; total += amt; len -= amt; } #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, %d bytes\n", "C_GenerateRandom", rc, ulRandomLen ); #endif return rc; } // // CK_RV SC_GenerateKey( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey ) { GenerateKey_Args * args; HOST_SESSION_HANDLE * node = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_ULONG tmpl_len, i; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; if (!pMechanism || !phKey) return CKR_ARGUMENTS_BAD; slot_id = SLOTID; // // figure out how much memory to allocate for the request block // // compute the total template size // tmpl_len = 0; #if __64BIT__ for (attr = pTemplate, i = 0; i < ulCount; i++, attr++) tmpl_len += sizeof(ATTRIBUTE) + get_attrib_len(attr); // attr->ulValueLen; #else for (attr = pTemplate, i = 0; i < ulCount; i++, attr++) tmpl_len += sizeof(ATTRIBUTE) + attr->ulValueLen; #endif #if __64BIT__ req_len = sizeof(GenerateKey_Args) + tmpl_len + get_mech_parameter_len(pMechanism); #else req_len = sizeof(GenerateKey_Args) + pMechanism->ulParameterLen + tmpl_len; #endif args = (GenerateKey_Args *)malloc( req_len ); if (!args) return CKR_HOST_MEMORY; args->session_handle = HTOCL( SESSION ); args->mech_type = HTOCL( pMechanism->mechanism ); #if __64BIT__ args->mech_param_len = HTOCL(get_mech_parameter_len(pMechanism)); // pMechanism->ulParameterLen ); #else args->mech_param_len = HTOCL( pMechanism->ulParameterLen ); #endif args->attribute_count = HTOCL( ulCount ); args->attribute_block_len = HTOCL( tmpl_len ); ptr = (CK_BYTE *)args + sizeof(GenerateKey_Args); if (pMechanism->ulParameterLen != 0) { // WARNING: again, for BIG-ENDIAN machines, it might be necessary // to ensure the parameter has the correct endianness if it is to // be interpretted as something other than a byte array // #ifdef BIG_ENDIAN ADJUSTMECHPTR(); #else memcpy( ptr, pMechanism->pParameter, pMechanism->ulParameterLen ); #endif #if __64BIT__ ptr += get_mech_parameter_len(pMechanism); //->ulParameterLen; #else ptr += pMechanism->ulParameterLen; #endif } // insert the attribute template into the request // attr = pTemplate; for (i=0; i < ulCount; i++, attr++) { ATTRIBUTE *p_attrib = (ATTRIBUTE *)ptr; unsigned char *pd,*ps; unsigned long *pl; p_attrib->type = HTOCL(attr->type); #if __64BIT__ p_attrib->value_length = HTOCL(get_attrib_len(attr)); //attr->ulValueLen); #else p_attrib->value_length = HTOCL(attr->ulValueLen); #endif // BIG-ENDIAN warning. Same here... // #ifndef _BIG_ENDIAN memcpy( (ptr + sizeof(ATTRIBUTE)), attr->pValue, attr->ulValueLen ); #else // We need to swap the values. pd = (unsigned char *)(ptr + sizeof(ATTRIBUTE)); ps = (unsigned char *)(attr->pValue); #if __64BIT__ copy_attribute_value(ps,pd,attr); #else memcpy(pd, ps, attr->ulValueLen); #endif #if __64BIT__ if ( attr->ulValueLen == 8 ) { #else if ( attr->ulValueLen == 4 ) { #endif pl = (unsigned long *)attr->pValue; pl = (unsigned long *)ps; #ifdef PKCS64 ModifyAttribute(attr->type,(CK_ULONG_PTR_32)pd); #else ModifyAttribute(attr->type,(CK_ULONG_PTR)pd); #endif } #endif #if __64BIT__ ptr += sizeof(ATTRIBUTE) + get_attrib_len(attr); //attr->ulValueLen; // p_attrib->value_length; #else ptr += sizeof(ATTRIBUTE) + attr->ulValueLen; // p_attrib->value_length; #endif } #if __64BIT__ repl_len = sizeof(CK_OBJECT_HANDLE_32); #else repl_len = sizeof(CK_OBJECT_HANDLE); #endif //hex_dump("GEN_KEY",(CK_BYTE_PTR)args,req_len); #if __64BIT__ { CK_ULONG_32 val; rc = communicate( C_GENERATEKEY, slot_id, args, req_len, &val, &repl_len, NULL, 0, NULL, 0 ); *phKey = val; } #else rc = communicate( C_GENERATEKEY, slot_id, args, req_len, phKey, &repl_len, NULL, 0, NULL, 0 ); #endif free( args ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, handle = %d, mech = 0x%X\n", "C_GenerateKey", rc, SESSION, *phKey, pMechanism->mechanism ); attr = pTemplate; for (i=0; i < ulCount; i++, attr++) { ptr = (CK_BYTE *)attr->pValue; logit(LOG_DEBUG, " %3d: Attribute type: 0x%08x\n", i, attr->type ); logit(LOG_DEBUG, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) logit(LOG_DEBUG, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); logit(LOG_DEBUG, "\n\n"); } #endif return rc; } // // CK_RV SC_EncryptInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { EncryptInit_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; slot_id = SLOTID; if (pMechanism->ulParameterLen != 0) #if __64BIT__ req_len = sizeof(EncryptInit_Args) + get_mech_parameter_len(pMechanism); //->ulParameterLen; #else req_len = sizeof(EncryptInit_Args) + pMechanism->ulParameterLen; #endif else req_len = sizeof(EncryptInit_Args); args = (EncryptInit_Args *)malloc( req_len ); if (!args) return CKR_HOST_MEMORY; memset( args, 0x0, req_len ); if (pMechanism->ulParameterLen != 0) { CK_BYTE *ptr = (CK_BYTE *)args + sizeof(EncryptInit_Args); #ifdef _BIG_ENDIAN ADJUSTMECHPTR(); #else memcpy( ptr, pMechanism->pParameter, pMechanism->ulParameterLen ); #endif } args->session_handle = HTOCL( SESSION ); args->key = ( hKey ); // Don't swap args->mech_type = HTOCL( pMechanism->mechanism ); #if __64BIT__ args->param_len = HTOCL( get_mech_parameter_len(pMechanism)); //->ulParameterLen ); #else args->param_len = HTOCL( pMechanism->ulParameterLen ); #endif repl_len = 0; rc = communicate( C_ENCRYPTINIT, slot_id, args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); free( args ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, key = %d, mech = 0x%X\n", "C_EncryptInit", rc, SESSION, hKey, pMechanism->mechanism ); #endif return rc; } // 12-09 added because of card/host interface changes CK_RV SC_Encrypt( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen ) { Encrypt_Args args; HOST_SESSION_HANDLE * node = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (!pData || !pulEncryptedDataLen) return CKR_ARGUMENTS_BAD; slot_id = SLOTID; args.session_handle = HTOCL( SESSION ); args.cleartext_len = HTOCL( ulDataLen ); if (pEncryptedData == NULL) args.length_only = TRUE; else args.length_only = FALSE; req_len = sizeof(args); #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32); #else repl_len = sizeof(CK_ULONG); #endif // SAB FIXME changed for 64bit #if __64BIT__ { CK_ULONG_32 tdata; rc = communicate( C_ENCRYPT, slot_id, &args, req_len, &tdata, &repl_len, pData, ulDataLen, pEncryptedData, *pulEncryptedDataLen ); *pulEncryptedDataLen = tdata; } #else rc = communicate( C_ENCRYPT, slot_id, &args, req_len, pulEncryptedDataLen, &repl_len, pData, ulDataLen, pEncryptedData, *pulEncryptedDataLen ); #endif // SAB XXX FIXME really need to swap the pulEncryptedDataLen?? // SAB LOOK // does communicate replace that value. repl_len won't get swapped . #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, amount = %d\n", "C_Encrypt", rc, SESSION, ulDataLen ); #endif #ifdef _BIG_ENDIAN { #ifdef PKCS64 CK_ULONG_32 td; #else CK_ULONG td; #endif td = HTOCL(*pulEncryptedDataLen); *pulEncryptedDataLen = td; } #endif return rc; } // // CK_RV SC_EncryptUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ) { EncryptUpdate_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; CK_BYTE * ptr = NULL; CK_BYTE * reply = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; if (!pPart || !pulEncryptedPartLen) return CKR_ARGUMENTS_BAD; slot_id = SLOTID; req_len = sizeof(EncryptUpdate_Args) + ulPartLen; args = (EncryptUpdate_Args *)malloc( req_len ); if (!args) return CKR_HOST_MEMORY; else { args->session_handle = HTOCL( SESSION ); args->cleartext_len = HTOCL( ulPartLen ); ptr = (CK_BYTE *)args + sizeof(EncryptUpdate_Args); memcpy( ptr, pPart, ulPartLen ); if (pEncryptedPart == NULL) { args->length_only = TRUE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32); #else repl_len = sizeof(CK_ULONG); #endif } else { args->length_only = FALSE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32) + *pulEncryptedPartLen; #else repl_len = sizeof(CK_ULONG) + *pulEncryptedPartLen; #endif } reply = (CK_BYTE *)malloc( repl_len ); if (!reply) rc = CKR_HOST_MEMORY; else { rc = communicate( C_ENCRYPTUPDATE, slot_id, args, req_len, reply, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK || rc == CKR_BUFFER_TOO_SMALL) { #ifdef PKCS64 { CK_ULONG_32 tmp; memcpy( &tmp, reply, sizeof(CK_ULONG_32) ); *pulEncryptedPartLen = CTOHL( tmp ); } #else memcpy( pulEncryptedPartLen, reply, sizeof(CK_ULONG) ); *pulEncryptedPartLen = CTOHL( *pulEncryptedPartLen ); #endif if (rc == CKR_OK && args->length_only == FALSE) #ifdef PKCS64 memcpy( pEncryptedPart, reply + sizeof(CK_ULONG_32), *pulEncryptedPartLen ); #else memcpy( pEncryptedPart, reply + sizeof(CK_ULONG), *pulEncryptedPartLen ); #endif } } } if (args) free( args ); if (reply) free( reply ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, amount = %d\n", "C_EncryptUpdate", rc, SESSION, ulPartLen ); #endif return rc; } // I think RSA goofed when designing the specification for C_EncryptFinal. // This function is supposed to follow the Cryptoki standard that if // pLastEncryptedPart == NULL then the user is requesting only the length // of the output. // // But it's quite possible that no output will be returned (say the user // specifies a total of 64 bytes of input data throughout the multi-part // encryption). The same thing can happen during an EncryptUpdate. // // ie: // // 1) user calls C_EncryptFinal to get the needed length // --> we return "0 bytes required" // 2) user passes in a NULL pointer for pLastEncryptedPart // --> we think the user is requesting the length again <-- // // So the user needs to pass in a non-NULL pointer even though we're not // going to return anything in it. It would have been cleaner if RSA would // have simply included a "give-me-the-length-only flag" as an argument. // CK_RV SC_EncryptFinal( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen ) { EncryptFinal_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; CK_BYTE * reply = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; slot_id = SLOTID; req_len = sizeof(EncryptFinal_Args); args = (EncryptFinal_Args *)malloc( req_len ); if (!args) return CKR_HOST_MEMORY; args->session_handle = HTOCL( SESSION ); if (pLastEncryptedPart == NULL) { args->length_only = TRUE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32); #else repl_len = sizeof(CK_ULONG); #endif } else { args->length_only = FALSE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32) + *pulLastEncryptedPartLen; #else repl_len = sizeof(CK_ULONG) + *pulLastEncryptedPartLen; #endif } reply = (CK_BYTE *)malloc( repl_len ); if (!reply) return CKR_HOST_MEMORY; rc = communicate( C_ENCRYPTFINAL, slot_id, args, req_len, reply, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK) { if (args->length_only == TRUE) { #ifdef PKCS64 *pulLastEncryptedPartLen = *(CK_ULONG_32 *)reply; #else memcpy( pulLastEncryptedPartLen, reply, sizeof(CK_ULONG) ); #endif *pulLastEncryptedPartLen = CTOHL( *pulLastEncryptedPartLen ); } else { #ifdef PKCS64 *pulLastEncryptedPartLen = *(CK_ULONG_32 *)reply; #else memcpy( pulLastEncryptedPartLen, reply, sizeof(CK_ULONG) ); #endif *pulLastEncryptedPartLen = CTOHL( *pulLastEncryptedPartLen ); #ifdef PKCS64 memcpy( pLastEncryptedPart, reply + sizeof(CK_ULONG_32), *pulLastEncryptedPartLen ); #else memcpy( pLastEncryptedPart, reply + sizeof(CK_ULONG), *pulLastEncryptedPartLen ); #endif } } free( args ); free( reply ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d\n", "C_EncryptFinal", rc, SESSION ); #endif return rc; } // // CK_RV SC_DecryptInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { DecryptInit_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; slot_id = SLOTID; if (pMechanism->ulParameterLen != 0) #if __64BIT__ req_len = sizeof(DecryptInit_Args) + get_mech_parameter_len(pMechanism); //->ulParameterLen; #else req_len = sizeof(DecryptInit_Args) + pMechanism->ulParameterLen; #endif else req_len = sizeof(DecryptInit_Args); args = (DecryptInit_Args *)malloc( req_len ); if (!args) return CKR_HOST_MEMORY; memset( args, 0x0, req_len ); if (pMechanism->ulParameterLen != 0) { CK_BYTE *ptr = (CK_BYTE *)args + sizeof(DecryptInit_Args); #ifdef _BIG_ENDIAN ADJUSTMECHPTR(); #else memcpy( ptr, pMechanism->pParameter, pMechanism->ulParameterLen ); #endif } args->session_handle = HTOCL( SESSION ); args->key = ( hKey ); // Don't swap args->mech_type = HTOCL( pMechanism->mechanism ); #if __64BIT__ args->param_len = HTOCL( get_mech_parameter_len(pMechanism)); //->ulParameterLen ); #else args->param_len = HTOCL( pMechanism->ulParameterLen ); #endif repl_len = 0; rc = communicate( C_DECRYPTINIT, slot_id, args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); free( args ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, key = %d, mech = 0x%X\n", "C_DecryptInit", rc, SESSION, hKey, pMechanism->mechanism ); #endif return rc; } // // CK_RV SC_Decrypt( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen ) { Decrypt_Args args; HOST_SESSION_HANDLE * node = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (!pEncryptedData || !pulDataLen) return CKR_ARGUMENTS_BAD; slot_id = SLOTID; args.session_handle = HTOCL( SESSION ); args.ciphertext_len = HTOCL( ulEncryptedDataLen ); if (pData == NULL) args.length_only = TRUE; else args.length_only = FALSE; req_len = sizeof(Decrypt_Args); #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32); #else repl_len = sizeof(CK_ULONG); #endif #if __64BIT__ { CK_ULONG_32 nLen; rc = communicate( C_DECRYPT, slot_id, &args, req_len, &nLen, &repl_len, pEncryptedData, ulEncryptedDataLen, pData, *pulDataLen ); *pulDataLen = nLen; } #else rc = communicate( C_DECRYPT, slot_id, &args, req_len, pulDataLen, &repl_len, pEncryptedData, ulEncryptedDataLen, pData, *pulDataLen ); #endif #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, amount = %d\n", "C_Decrypt", rc, SESSION, ulEncryptedDataLen ); #endif #ifdef _BIG_ENDIAN { *pulDataLen = CTOHL(*pulDataLen); } #endif return rc; } // // CK_RV SC_DecryptUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ) { DecryptUpdate_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; CK_BYTE * ptr = NULL; CK_BYTE * reply = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (!pEncryptedPart || !pulPartLen) return CKR_ARGUMENTS_BAD; slot_id = SLOTID; req_len = sizeof(DecryptUpdate_Args) + ulEncryptedPartLen; args = (DecryptUpdate_Args *)malloc( req_len ); if (!args) return CKR_HOST_MEMORY; else { args->session_handle = HTOCL( SESSION ); args->ciphertext_len = HTOCL( ulEncryptedPartLen ); ptr = (CK_BYTE *)args + sizeof(DecryptUpdate_Args); memcpy( ptr, pEncryptedPart, ulEncryptedPartLen ); if (pPart == NULL) { args->length_only = TRUE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32); #else repl_len = sizeof(CK_ULONG); #endif } else { args->length_only = FALSE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32) + *pulPartLen; #else repl_len = sizeof(CK_ULONG) + *pulPartLen; #endif } reply = (CK_BYTE *)malloc( repl_len ); if (!reply) rc = CKR_HOST_MEMORY; else { rc = communicate( C_DECRYPTUPDATE, slot_id, args, req_len, reply, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK || rc == CKR_BUFFER_TOO_SMALL) { #ifdef PKCS64 *pulPartLen = *(CK_ULONG_32 *)reply; #else memcpy( pulPartLen, reply, sizeof(CK_ULONG) ); #endif *pulPartLen = CTOHL( *pulPartLen ); if (rc == CKR_OK && args->length_only == FALSE) #ifdef PKCS64 memcpy( pPart, reply + sizeof(CK_ULONG_32), *pulPartLen ); #else memcpy( pPart, reply + sizeof(CK_ULONG), *pulPartLen ); #endif } } } if (args) free( args ); if (reply) free( reply ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, amount = %d\n", "C_DecryptUpdate", rc, SESSION, ulEncryptedPartLen ); #endif return rc; } // // CK_RV SC_DecryptFinal( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen ) { DecryptFinal_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; CK_BYTE * reply = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (!pulLastPartLen) return CKR_ARGUMENTS_BAD; slot_id = SLOTID; req_len = sizeof(DecryptFinal_Args); args = (DecryptFinal_Args *)malloc( req_len ); if (!args) return CKR_HOST_MEMORY; else { args->session_handle = HTOCL( SESSION ); if (pLastPart == NULL) { args->length_only = TRUE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32); #else repl_len = sizeof(CK_ULONG); #endif } else { args->length_only = FALSE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32) + *pulLastPartLen; #else repl_len = sizeof(CK_ULONG) + *pulLastPartLen; #endif } reply = (CK_BYTE *)malloc( repl_len ); if (!reply) rc = CKR_HOST_MEMORY; else { rc = communicate( C_DECRYPTFINAL, slot_id, args, req_len, reply, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK || rc == CKR_BUFFER_TOO_SMALL) { #ifdef PKCS64 *pulLastPartLen = *(CK_ULONG_32 *)reply; #else memcpy( pulLastPartLen, reply, sizeof(CK_ULONG) ); #endif *pulLastPartLen = CTOHL( *pulLastPartLen ); if (rc == CKR_OK && args->length_only == FALSE) #ifdef PKCS64 memcpy( pLastPart, reply + sizeof(CK_ULONG_32), *pulLastPartLen ); #else memcpy( pLastPart, reply + sizeof(CK_ULONG), *pulLastPartLen ); #endif } } } if (args) free( args ); if (reply) free( reply ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d\n", "C_DecryptFinal", rc, SESSION ); #endif return rc; } // // CK_RV SC_WrapKey( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen ) { WrapKey_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; CK_BYTE * reply = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (!pulWrappedKeyLen) return CKR_ARGUMENTS_BAD; slot_id = SLOTID; #if __64BIT__ req_len = sizeof(WrapKey_Args) + get_mech_parameter_len(pMechanism); //->ulParameterLen; #else req_len = sizeof(WrapKey_Args) + pMechanism->ulParameterLen; #endif args = (WrapKey_Args *)malloc(req_len); if (!args) return CKR_HOST_MEMORY; else { args->session_handle = HTOCL( SESSION ); args->mech_type = HTOCL( pMechanism->mechanism ); #if __64BIT__ args->mech_param_len = HTOCL( get_mech_parameter_len(pMechanism)); #else args->mech_param_len = HTOCL( pMechanism->ulParameterLen ); #endif args->wrapping_key = ( hWrappingKey ); args->key = ( hKey ); if (pMechanism->ulParameterLen != 0) { CK_BYTE *ptr = (CK_BYTE *)args + sizeof(WrapKey_Args); #ifdef _BIG_ENDIAN ADJUSTMECHPTR(); #else memcpy( ptr, pMechanism->pParameter, pMechanism->ulParameterLen ); #endif } if (!pWrappedKey) { args->length_only = TRUE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32); #else repl_len = sizeof(CK_ULONG); #endif } else { args->length_only = FALSE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32) + *pulWrappedKeyLen; #else repl_len = sizeof(CK_ULONG) + *pulWrappedKeyLen; #endif } reply = (CK_BYTE *)malloc(repl_len); if (!reply) rc = CKR_HOST_MEMORY; else { rc = communicate( C_WRAPKEY, slot_id, args, req_len, reply, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK || rc == CKR_BUFFER_TOO_SMALL) { #ifdef PKCS64 *pulWrappedKeyLen = *(CK_ULONG_32 *) reply; #else memcpy( pulWrappedKeyLen, reply, sizeof(CK_ULONG) ); #endif *pulWrappedKeyLen = CTOHL( *pulWrappedKeyLen ); if (rc == CKR_OK && args->length_only == FALSE) { #ifdef PKCS64 memcpy( pWrappedKey, reply + sizeof(CK_ULONG_32), *pulWrappedKeyLen ); #else memcpy( pWrappedKey, reply + sizeof(CK_ULONG), *pulWrappedKeyLen ); #endif } } } } if (args) free( args ); if (reply) free( reply ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, encrypting key = %d, wrapped key = %d\n", "C_WrapKey", rc, SESSION, hWrappingKey, hKey ); #endif return rc; } // // CK_RV SC_UnwrapKey( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey ) { UnWrapKey_Args * args = NULL; CK_ATTRIBUTE * attr = NULL; HOST_SESSION_HANDLE * node = NULL; CK_BYTE * ptr = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_ULONG tmpl_len; CK_ULONG i; CK_RV rc; SESS_SET if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (hSession == 0) return CKR_SESSION_HANDLE_INVALID; if ((ulWrappedKeyLen == 0) || !phKey || !pWrappedKey) return CKR_ARGUMENTS_BAD; if ((ulAttributeCount != 0) && !pTemplate) return CKR_ARGUMENTS_BAD; slot_id = SLOTID; // compute the total template size // tmpl_len = 0; #if __64BIT__ for (attr = pTemplate, i = 0; i < ulAttributeCount; i++, attr++) tmpl_len += sizeof(ATTRIBUTE) + get_attrib_len(attr); // attr->ulValueLen; #else for (attr = pTemplate, i = 0; i < ulAttributeCount; i++, attr++) tmpl_len += sizeof(ATTRIBUTE) + attr->ulValueLen; #endif #if __64BIT__ req_len = sizeof(UnWrapKey_Args) + get_mech_parameter_len(pMechanism) //->ulParameterLen + ulWrappedKeyLen + tmpl_len; #else req_len = sizeof(UnWrapKey_Args) + pMechanism->ulParameterLen + ulWrappedKeyLen + tmpl_len; #endif args = (UnWrapKey_Args *)malloc(req_len); if (!args) return CKR_HOST_MEMORY; memset( args, 0x0, req_len ); args->session_handle = HTOCL( SESSION ); args->mech_type = HTOCL( pMechanism->mechanism ); #if __64BIT__ args->mech_param_len = HTOCL( get_mech_parameter_len(pMechanism)); #else args->mech_param_len = HTOCL( pMechanism->ulParameterLen ); #endif args->unwrapping_key = ( hUnwrappingKey ); args->wrapped_key_len = HTOCL( ulWrappedKeyLen ); args->attribute_count = HTOCL( ulAttributeCount ); args->attribute_block_len = HTOCL( tmpl_len ); ptr = (CK_BYTE *)args + sizeof(UnWrapKey_Args); if (pMechanism->ulParameterLen != 0) { #ifdef _BIG_ENDIAN ADJUSTMECHPTR(); #else memcpy( ptr, pMechanism->pParameter, pMechanism->ulParameterLen ); #endif #if __64BIT__ ptr += get_mech_parameter_len(pMechanism); //->ulParameterLen; #else ptr += pMechanism->ulParameterLen; #endif } if (ulWrappedKeyLen != 0) { memcpy( ptr, pWrappedKey, ulWrappedKeyLen ); ptr += ulWrappedKeyLen; } // build the attribute block // attr = pTemplate; for (i = 0; i < ulAttributeCount; i++, attr++) { ATTRIBUTE *p_attrib = (ATTRIBUTE *)ptr; p_attrib->type = HTOCL( attr->type ); #if __64BIT__ p_attrib->value_length = HTOCL(get_attrib_len(attr)); //attr->ulValueLen); #else p_attrib->value_length = HTOCL( attr->ulValueLen ); #endif #ifndef _BIG_ENDIAN memcpy( (ptr + sizeof(ATTRIBUTE)), attr->pValue, attr->ulValueLen ); #else { unsigned char *pd,*ps; #ifdef PKCS64 unsigned int *pl; #else unsigned long *pl; #endif // We need to swap the values. pd = (unsigned char *)(ptr + sizeof(ATTRIBUTE)); ps = (unsigned char *)(attr->pValue); #if __64BIT__ copy_attribute_value(ps,pd,attr); #else memcpy(pd, ps, attr->ulValueLen); #endif #if __64BIT__ if ( attr->ulValueLen == 8 ) { #else if ( attr->ulValueLen == 4 ) { #endif pl = (unsigned int *)attr->pValue; pl = (unsigned int *)ps; #ifdef PKCS64 ModifyAttribute(attr->type,(CK_ULONG_PTR_32)pd); #else ModifyAttribute(attr->type,(CK_ULONG_PTR)pd); #endif } } #endif #if __64BIT__ ptr += sizeof(ATTRIBUTE) + get_attrib_len(attr); //attr->ulValueLen; // p_attrib->value_length; #else ptr += sizeof(ATTRIBUTE) + attr->ulValueLen; // p_attrib->value_length; #endif } #ifdef PKCS64 repl_len = sizeof(CK_OBJECT_HANDLE_32); #else repl_len = sizeof(CK_OBJECT_HANDLE); #endif #if __64BIT__ { CK_OBJECT_HANDLE_32 nHandle; rc = communicate( C_UNWRAPKEY, slot_id, args, req_len, &nHandle, &repl_len, NULL, 0, NULL, 0 ); *phKey = nHandle; } #else rc = communicate( C_UNWRAPKEY, slot_id, args, req_len, phKey, &repl_len, NULL, 0, NULL, 0 ); #endif free( args ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, decrypting key = %d, unwrapped key = %d mech 0x%X\n", "C_UnwrapKey", rc, SESSION, hUnwrappingKey, *phKey,pMechanism->mechanism ); attr = pTemplate; for (i=0; i < ulAttributeCount; i++, attr++) { ptr = (CK_BYTE *)attr->pValue; logit(LOG_DEBUG, " %3d: Attribute type: 0x%08x\n", i, attr->type ); logit(LOG_DEBUG, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) logit(LOG_DEBUG, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); logit(LOG_DEBUG, "\n\n"); } #endif return rc; } // // CK_RV SC_DigestInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism ) { DigestInit_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET // this must be at the end of the local variable defs if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; slot_id = SLOTID; if (pMechanism->ulParameterLen != 0) #if __64BIT__ req_len = sizeof(DigestInit_Args) + get_mech_parameter_len(pMechanism); #else req_len = sizeof(DigestInit_Args) + pMechanism->ulParameterLen; #endif else req_len = sizeof(DigestInit_Args); args = (DigestInit_Args *)malloc( req_len ); if (!args) return CKR_HOST_MEMORY; memset( args, 0x0, req_len ); if (pMechanism->ulParameterLen != 0) { CK_BYTE *ptr = (CK_BYTE *)args + sizeof(DigestInit_Args); #ifdef _BIG_ENDIAN ADJUSTMECHPTR(); #else memcpy( ptr, pMechanism->pParameter, pMechanism->ulParameterLen ); #endif } args->session_handle = HTOCL( SESSION ); args->mech_type = HTOCL( pMechanism->mechanism ); #if __64BIT__ args->param_len = HTOCL( get_mech_parameter_len(pMechanism) ); #else args->param_len = HTOCL( pMechanism->ulParameterLen ); #endif repl_len = 0; rc = communicate( C_DIGESTINIT, slot_id, args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); free( args ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, mech = 0x%X\n", "C_DigestInit", rc, SESSION, pMechanism->mechanism ); #endif return rc; } // // CK_RV SC_Digest( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen ) { Digest_Args args; HOST_SESSION_HANDLE * node = NULL; CK_BYTE * reply = NULL; CK_BYTE nullstring[] = { 0 }; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET // this must be at the end of the local variable defs if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (!pData || !pulDigestLen) return CKR_ARGUMENTS_BAD; slot_id = SLOTID; args.session_handle = HTOCL( SESSION ); if (pDigest == NULL) { args.length_only = TRUE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32); #else repl_len = sizeof(CK_ULONG); #endif } else { args.length_only = FALSE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32) + *pulDigestLen; #else repl_len = sizeof(CK_ULONG) + *pulDigestLen; #endif } req_len = sizeof(args); reply = (CK_BYTE *)malloc( repl_len ); if (!reply) return CKR_HOST_MEMORY; if (ulDataLen == 0) { args.data_len = HTOCL( 1 ); rc = communicate( C_DIGEST, slot_id, &args, req_len, reply, &repl_len, nullstring, 1, NULL, 0 ); } else { args.data_len = HTOCL( ulDataLen ); rc = communicate( C_DIGEST, slot_id, &args, req_len, reply, &repl_len, pData, ulDataLen, NULL, 0 ); } if (rc == CKR_OK || rc == CKR_BUFFER_TOO_SMALL) { #ifdef PKCS64 *pulDigestLen = *(CK_ULONG_32 *)reply; #else memcpy( pulDigestLen, reply, sizeof(CK_ULONG) ); #endif *pulDigestLen = CTOHL( *pulDigestLen ); if (rc == CKR_OK && args.length_only == FALSE) #ifdef PKCS64 memcpy( pDigest, reply + sizeof(CK_ULONG_32), *pulDigestLen ); #else memcpy( pDigest, reply + sizeof(CK_ULONG), *pulDigestLen ); #endif } #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_Digest", rc, SESSION, ulDataLen ); #endif return rc; } // // CK_RV SC_DigestUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ) { DigestUpdate_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; CK_BYTE * ptr = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET // this must be at the end of the local variable defs if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; slot_id = SLOTID; req_len = sizeof(DigestUpdate_Args) + ulPartLen; args = (DigestUpdate_Args *)malloc( req_len ); if (!args) return CKR_HOST_MEMORY; args->session_handle = HTOCL( SESSION ); args->data_len = HTOCL( ulPartLen ); if (ulPartLen > 0) { ptr = (CK_BYTE *)args + sizeof(DigestUpdate_Args); memcpy( ptr, pPart, ulPartLen ); } repl_len = 0; rc = communicate( C_DIGESTUPDATE, slot_id, args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); free( args ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_DigestUpdate", rc, SESSION, ulPartLen ); #endif return rc; } // // CK_RV SC_DigestKey( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hKey ) { DigestKey_Args args; HOST_SESSION_HANDLE * node = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET // this must be at the end of the local variable defs if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; slot_id = SLOTID; args.session_handle = HTOCL( SESSION ); args.key = (hKey ); // object handles do not get byte-reversed req_len = sizeof(DigestKey_Args); repl_len = 0; rc = communicate( C_DIGESTKEY, slot_id, &args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, key = %d\n", "C_DigestKey", rc, SESSION, hKey ); #endif return rc; } // // CK_RV SC_DigestFinal( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen ) { DigestFinal_Args args; HOST_SESSION_HANDLE * node = NULL; CK_BYTE * reply = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET // this must be at the end of the local variable defs if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (!pulDigestLen) return CKR_ARGUMENTS_BAD; slot_id = SLOTID; args.session_handle = HTOCL(SESSION); if (!pDigest) { args.length_only = TRUE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32); #else repl_len = sizeof(CK_ULONG); #endif } else { args.length_only = FALSE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32) + *pulDigestLen; #else repl_len = sizeof(CK_ULONG) + *pulDigestLen; #endif } req_len = sizeof(DigestFinal_Args); reply = (CK_BYTE *)malloc(repl_len); if (!reply) return CKR_HOST_MEMORY; rc = communicate( C_DIGESTFINAL, slot_id, &args, req_len, reply, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK || rc == CKR_BUFFER_TOO_SMALL) { #ifdef PKCS64 memcpy( pulDigestLen, reply, sizeof(CK_ULONG_32) ); #else memcpy( pulDigestLen, reply, sizeof(CK_ULONG) ); #endif *pulDigestLen = CTOHL( *pulDigestLen ); if (rc == CKR_OK || rc == CKR_BUFFER_TOO_SMALL) { #ifdef PKCS64 *pulDigestLen = *(CK_ULONG_32 *)reply; #else memcpy( pulDigestLen, reply, sizeof(CK_ULONG) ); #endif *pulDigestLen = CTOHL( *pulDigestLen ); if (rc == CKR_OK && args.length_only == FALSE) #ifdef PKCS64 memcpy( pDigest, reply + sizeof(CK_ULONG_32), *pulDigestLen ); #else memcpy( pDigest, reply + sizeof(CK_ULONG), *pulDigestLen ); #endif } } free( reply ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d\n", "C_DigestFinal", rc, SESSION ); #endif return rc; } // // CK_RV SC_GenerateKeyPair( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey ) { GenKeyPair_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; #ifdef PKCS64 CK_OBJECT_HANDLE_32 reply[2]; #else CK_OBJECT_HANDLE reply[2]; #endif CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_ULONG i, publ_tmpl_len, priv_tmpl_len; CK_RV rc; SESS_SET // this must be at the end of the local variable defs if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (!pMechanism || !phPublicKey || !phPrivateKey) return CKR_ARGUMENTS_BAD; slot_id = SLOTID; // // figure out how much memory to allocate for the request // publ_tmpl_len = 0; #if __64BIT__ for (attr=pPublicKeyTemplate, i=0; i < ulPublicKeyAttributeCount; i++, attr++) publ_tmpl_len += sizeof(ATTRIBUTE) + get_attrib_len(attr); #else for (attr=pPublicKeyTemplate, i=0; i < ulPublicKeyAttributeCount; i++, attr++) publ_tmpl_len += sizeof(ATTRIBUTE) + attr->ulValueLen; #endif priv_tmpl_len = 0; #if __64BIT__ for (attr=pPrivateKeyTemplate, i=0; i < ulPrivateKeyAttributeCount; i++, attr++) priv_tmpl_len += sizeof(ATTRIBUTE) + get_attrib_len(attr); #else for (attr=pPrivateKeyTemplate, i=0; i < ulPrivateKeyAttributeCount; i++, attr++) priv_tmpl_len += sizeof(ATTRIBUTE) + attr->ulValueLen; #endif #if __64BIT__ req_len = sizeof(GenKeyPair_Args) + get_mech_parameter_len(pMechanism); #else req_len = sizeof(GenKeyPair_Args) + pMechanism->ulParameterLen; #endif req_len += publ_tmpl_len + priv_tmpl_len; args = (GenKeyPair_Args *)malloc( req_len ); if (!args) return CKR_HOST_MEMORY; args->session_handle = HTOCL (SESSION); args->mech_type = HTOCL( pMechanism->mechanism ); #if __64BIT__ args->mech_param_len = HTOCL( get_mech_parameter_len(pMechanism)); #else args->mech_param_len = HTOCL( pMechanism->ulParameterLen ); #endif args->publ_key_attr_count = HTOCL( ulPublicKeyAttributeCount ); args->publ_key_tmpl_len = HTOCL( publ_tmpl_len ); args->priv_key_attr_count = HTOCL( ulPrivateKeyAttributeCount ); args->priv_key_tmpl_len = HTOCL( priv_tmpl_len ); // append the variable-length fields to the request // ptr = (CK_BYTE *)args + sizeof(GenKeyPair_Args); if (pMechanism->ulParameterLen != 0) { // WARNING: again, for BIG-ENDIAN machines, it might be necessary // to ensure the parameter has the correct endianness if it is to // be interpretted as something other than a byte array #ifdef _BIG_ENDIAN ADJUSTMECHPTR(); #else memcpy( ptr, pMechanism->pParameter, pMechanism->ulParameterLen ); #endif #if __64BIT__ ptr += get_mech_parameter_len(pMechanism); #else ptr += pMechanism->ulParameterLen; #endif } // append the public key template // attr = pPublicKeyTemplate; for (i=0; i < ulPublicKeyAttributeCount; i++, attr++) { ATTRIBUTE *p_attrib = (ATTRIBUTE *)ptr; unsigned char *pd,*ps; #ifdef PKCS64 unsigned int *pl; #else unsigned long *pl; #endif p_attrib->type = HTOCL( attr->type ); #if __64BIT__ p_attrib->value_length = HTOCL(get_attrib_len(attr)); //attr->ulValueLen); #else p_attrib->value_length = HTOCL( attr->ulValueLen ); #endif // BIG-ENDIAN warning: attribute values #ifndef _BIG_ENDIAN memcpy( (ptr + sizeof(ATTRIBUTE)), attr->pValue, attr->ulValueLen ); #else // We need to swap the values. pd = (unsigned char *)(ptr + sizeof(ATTRIBUTE)); ps = (unsigned char *)(attr->pValue); #if __64BIT__ copy_attribute_value(ps,pd,attr); #else memcpy(pd, ps, attr->ulValueLen); #endif #if __64BIT__ if ( attr->ulValueLen == 8 ) { #else if ( attr->ulValueLen == 4 ) { #endif pl = (unsigned int *)attr->pValue; pl = (unsigned int *)ps; #ifdef PKCS64 ModifyAttribute(attr->type,(CK_ULONG_PTR_32)pd); #else ModifyAttribute(attr->type,(CK_ULONG_PTR)pd); #endif } #endif #if __64BIT__ ptr += sizeof(ATTRIBUTE) + get_attrib_len(attr); // attr->ulValueLen; #else ptr += sizeof(ATTRIBUTE) + attr->ulValueLen; #endif } // append the private key template // attr = pPrivateKeyTemplate; for (i=0; i < ulPrivateKeyAttributeCount; i++, attr++) { ATTRIBUTE *p_attrib = (ATTRIBUTE *)ptr; unsigned char *pd,*ps; #ifdef PKCS64 unsigned int *pl; #else unsigned long *pl; #endif p_attrib->type = HTOCL( attr->type ); #if __64BIT__ p_attrib->value_length = HTOCL(get_attrib_len(attr)); //attr->ulValueLen); #else p_attrib->value_length = HTOCL( attr->ulValueLen ); #endif // BIG-ENDIAN warning: attribute values // #ifndef _BIG_ENDIAN memcpy( (ptr + sizeof(ATTRIBUTE)), attr->pValue, attr->ulValueLen ); #else // We need to swap the values. pd = (unsigned char *)(ptr + sizeof(ATTRIBUTE)); ps = (unsigned char *)(attr->pValue); #if __64BIT__ copy_attribute_value(ps,pd,attr); #else memcpy(pd, ps, attr->ulValueLen); #endif #if __64BIT__ if ( attr->ulValueLen == 8 ) { #else if ( attr->ulValueLen == 4 ) { #endif pl = (unsigned int *)attr->pValue; pl = (unsigned int *)ps; #ifdef PKCS64 ModifyAttribute(attr->type,(CK_ULONG_PTR_32)pd); #else ModifyAttribute(attr->type,(CK_ULONG_PTR)pd); #endif } #endif #if __64BIT__ ptr += sizeof(ATTRIBUTE) + get_attrib_len(attr); // attr->ulValueLen; #else ptr += sizeof(ATTRIBUTE) + attr->ulValueLen; #endif } repl_len = sizeof(reply); rc = communicate( C_GENERATEKEYPAIR, slot_id, args, req_len, reply, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK) { *phPublicKey = reply[0]; *phPrivateKey = reply[1]; } free( args ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, mech = 0x%X\n", "C_GenerateKeyPair", rc, SESSION, pMechanism->mechanism ); if (rc == CKR_OK) { logit(LOG_DEBUG, " Public handle: %d\n", *phPublicKey ); logit(LOG_DEBUG, " Private handle: %d\n", *phPrivateKey ); } logit(LOG_DEBUG, " Public Template:\n"); attr = pPublicKeyTemplate; for (i=0; i < ulPublicKeyAttributeCount; i++, attr++) { ptr = (CK_BYTE *)attr->pValue; logit(LOG_DEBUG, " %3d: Attribute type: 0x%08x\n", i, attr->type ); logit(LOG_DEBUG, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) logit(LOG_DEBUG, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); logit(LOG_DEBUG, "\n\n"); } logit(LOG_DEBUG, " Private Template:\n"); attr = pPrivateKeyTemplate; for (i=0; i < ulPrivateKeyAttributeCount; i++, attr++) { ptr = (CK_BYTE *)attr->pValue; logit(LOG_DEBUG, " %3d: Attribute type: 0x%08x\n", i, attr->type ); logit(LOG_DEBUG, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) logit(LOG_DEBUG, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); logit(LOG_DEBUG, "\n\n"); } #endif return rc; } // // CK_RV SC_SignInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { SignInit_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET // this must be at the end of the local variable defs if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; slot_id = SLOTID; if (pMechanism->ulParameterLen != 0) { #if __64BIT__ req_len = sizeof(SignInit_Args) + get_mech_parameter_len(pMechanism); //->ulParameterLen; #else req_len = sizeof(SignInit_Args) + pMechanism->ulParameterLen; #endif }else req_len = sizeof(SignInit_Args); args = (SignInit_Args *)malloc( req_len ); if (!args) return CKR_HOST_MEMORY; memset( args, 0x0, req_len ); if (pMechanism->ulParameterLen != 0) { CK_BYTE *ptr = (CK_BYTE *)args + sizeof(SignInit_Args); #ifdef _BIG_ENDIAN ADJUSTMECHPTR(); #else // FIXME Intel 64Bit this will not work.. memcpy( ptr, pMechanism->pParameter, pMechanism->ulParameterLen ); #endif } args->session_handle = HTOCL( SESSION ); args->key = ( hKey ); args->mech_type = HTOCL( pMechanism->mechanism ); #if __64BIT__ args->param_len = HTOCL( get_mech_parameter_len(pMechanism)); //->ulParameterLen ); #else args->param_len = HTOCL( pMechanism->ulParameterLen ); #endif repl_len = 0; rc = communicate( C_SIGNINIT, slot_id, args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); free( args ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, mech = 0x%X\n", "C_SignInit", rc, SESSION, pMechanism->mechanism ); logit(LOG_DEBUG, "%-25s: hKey %d \n", "C_SignInit", hKey); #endif return rc; } // // CK_RV SC_Sign( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ) { Sign_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; CK_BYTE * ptr = NULL; CK_BYTE * reply = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET // this must be at the end of the local variable defs if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (!pData || !pulSignatureLen) return CKR_ARGUMENTS_BAD; slot_id = SLOTID; req_len = sizeof(Sign_Args) + ulDataLen; args = (Sign_Args *)malloc( req_len ); if (!args) return CKR_HOST_MEMORY; else { args->session_handle = HTOCL( SESSION ); args->data_len = HTOCL( ulDataLen ); ptr = (CK_BYTE *)args + sizeof(Sign_Args); memcpy( ptr, pData, ulDataLen ); if (pSignature == NULL) { args->length_only = TRUE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32); #else repl_len = sizeof(CK_ULONG); #endif } else { args->length_only = FALSE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32) + *pulSignatureLen; #else repl_len = sizeof(CK_ULONG) + *pulSignatureLen; #endif } reply = (CK_BYTE *)malloc( repl_len ); if (!reply) rc = CKR_HOST_MEMORY; else { rc = communicate( C_SIGN, slot_id, args, req_len, reply, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK || rc == CKR_BUFFER_TOO_SMALL) { #ifdef PKCS64 *pulSignatureLen = *(CK_ULONG_32 *)reply; #else memcpy( pulSignatureLen, reply, sizeof(CK_ULONG) ); #endif *pulSignatureLen = CTOHL( *pulSignatureLen ); if (rc == CKR_OK && args->length_only == FALSE) #ifdef PKCS64 memcpy( pSignature, reply + sizeof(CK_ULONG_32), *pulSignatureLen ); #else memcpy( pSignature, reply + sizeof(CK_ULONG), *pulSignatureLen ); #endif } } } if (args) free( args ); if (reply) free( reply ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_Sign", rc, SESSION, ulDataLen ); #endif return rc; } // // CK_RV SC_SignUpdate ( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ) { SignUpdate_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; CK_BYTE * ptr = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET // this must be at the end of the local variable defs if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (!pPart) return CKR_ARGUMENTS_BAD; slot_id = SLOTID; req_len = sizeof(SignUpdate_Args) + ulPartLen; args = (SignUpdate_Args *)malloc( req_len ); if (!args) return CKR_HOST_MEMORY; args->session_handle = HTOCL( SESSION ); args->data_len = HTOCL( ulPartLen ); ptr = (CK_BYTE *)args + sizeof(SignUpdate_Args); memcpy( ptr, pPart, ulPartLen ); repl_len = 0; rc = communicate( C_SIGNUPDATE, slot_id, args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); free( args ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_SignUpdate", rc, SESSION, ulPartLen ); #endif return rc; } // // CK_RV SC_SignFinal ( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ) { SignFinal_Args args; HOST_SESSION_HANDLE * node = NULL; CK_BYTE * reply = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET // this must be at the end of the local variable defs if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (!pulSignatureLen) return CKR_ARGUMENTS_BAD; slot_id = SLOTID; req_len = sizeof(SignFinal_Args); args.session_handle = HTOCL( SESSION ); if (pSignature == NULL) { args.length_only = TRUE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32); #else repl_len = sizeof(CK_ULONG); #endif } else { args.length_only = FALSE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32) + *pulSignatureLen; #else repl_len = sizeof(CK_ULONG) + *pulSignatureLen; #endif } reply = (CK_BYTE *)malloc( repl_len ); if (!reply) return CKR_HOST_MEMORY; rc = communicate( C_SIGNFINAL, slot_id, &args, req_len, reply, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK || rc == CKR_BUFFER_TOO_SMALL) { #ifdef PKCS64 *pulSignatureLen = *(CK_ULONG_32 *)reply; #else memcpy( pulSignatureLen, reply, sizeof(CK_ULONG) ); #endif *pulSignatureLen = CTOHL( *pulSignatureLen ); if (rc == CKR_OK && args.length_only == FALSE) #ifdef PKCS64 memcpy( pSignature, reply + sizeof(CK_ULONG_32), *pulSignatureLen ); #else memcpy( pSignature, reply + sizeof(CK_ULONG), *pulSignatureLen ); #endif } free( reply ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d\n", "C_SignFinal", rc, SESSION ); #endif return rc; } // // CK_RV SC_VerifyInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { VerifyInit_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET // this must be at the end of the local variable defs if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; slot_id = SLOTID; if (pMechanism->ulParameterLen != 0) #if __64BIT__ req_len = sizeof(VerifyInit_Args) + get_mech_parameter_len(pMechanism); #else req_len = sizeof(VerifyInit_Args) + pMechanism->ulParameterLen; #endif else req_len = sizeof(VerifyInit_Args); args = (VerifyInit_Args *)malloc( req_len ); if (!args) return CKR_HOST_MEMORY; memset( args, 0x0, req_len ); if (pMechanism->ulParameterLen != 0) { CK_BYTE *ptr = (CK_BYTE *)args + sizeof(VerifyInit_Args); #ifdef _BIG_ENDIAN ADJUSTMECHPTR(); #else memcpy( ptr, pMechanism->pParameter, pMechanism->ulParameterLen ); #endif } args->session_handle = HTOCL( SESSION ); args->key = ( hKey ); args->mech_type = HTOCL( pMechanism->mechanism ); #if __64BIT__ args->param_len = HTOCL( get_mech_parameter_len(pMechanism)); #else args->param_len = HTOCL( pMechanism->ulParameterLen ); #endif repl_len = 0; rc = communicate( C_VERIFYINIT, slot_id, args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); free( args ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, mech = 0x%X\n", "C_VerifyInit", rc, SESSION, pMechanism->mechanism ); #endif return rc; } // // CK_RV SC_Verify( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen ) { Verify_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; CK_BYTE * ptr = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET // this must be at the end of the local variable defs if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (!pData || !pSignature) return CKR_ARGUMENTS_BAD; slot_id = SLOTID; req_len = sizeof(Verify_Args) + ulDataLen + ulSignatureLen; args = (Verify_Args *)malloc( req_len ); if (!args) return CKR_HOST_MEMORY; args->session_handle = HTOCL( SESSION ); args->data_len = HTOCL( ulDataLen ); args->signature_len = HTOCL( ulSignatureLen ); ptr = (CK_BYTE *)args + sizeof(Verify_Args); memcpy( ptr, pData, ulDataLen ); ptr += ulDataLen; memcpy( ptr, pSignature, ulSignatureLen ); repl_len = 0; rc = communicate( C_VERIFY, slot_id, args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); free( args ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, datalen = %d, siglen = %d\n", "C_Verify", rc, SESSION, ulDataLen, ulSignatureLen ); #endif return rc; } // // CK_RV SC_VerifyUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ) { VerifyUpdate_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; CK_BYTE * ptr = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET // this must be at the end of the local variable defs if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (!pPart) return CKR_ARGUMENTS_BAD; slot_id = SLOTID; req_len = sizeof(VerifyUpdate_Args) + ulPartLen; args = (VerifyUpdate_Args *)malloc( req_len ); if (!args) return CKR_HOST_MEMORY; args->session_handle = HTOCL( SESSION ); args->data_len = HTOCL( ulPartLen ); ptr = (CK_BYTE *)args + sizeof(VerifyUpdate_Args); memcpy( ptr, pPart, ulPartLen ); repl_len = 0; rc = communicate( C_VERIFYUPDATE, slot_id, args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); free( args ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_VerifyUpdate", rc, SESSION, ulPartLen ); #endif return rc; } // // CK_RV SC_VerifyFinal( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen ) { VerifyFinal_Args * args; HOST_SESSION_HANDLE * node = NULL; CK_BYTE * ptr = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET // this must be at the end of the local variable defs if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (!pSignature) return CKR_ARGUMENTS_BAD; req_len = sizeof(VerifyFinal_Args) + ulSignatureLen; args = (VerifyFinal_Args *)malloc( req_len ); if (!args) return CKR_HOST_MEMORY; slot_id = SLOTID; args->session_handle = HTOCL( SESSION ); args->signature_len = HTOCL( ulSignatureLen ); ptr = (CK_BYTE *)args + sizeof(VerifyFinal_Args); memcpy( ptr, pSignature, ulSignatureLen ); repl_len = 0; rc = communicate( C_VERIFYFINAL, slot_id, args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); free( args ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d\n", "C_VerifyFinal", rc, SESSION ); #endif return rc; } // // CK_RV SC_SignRecoverInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { SignRecoverInit_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET // this must be at the end of the local variable defs if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (pMechanism->ulParameterLen != 0) #if __64BIT__ req_len = sizeof(SignRecoverInit_Args) + get_mech_parameter_len(pMechanism); #else req_len = sizeof(SignRecoverInit_Args) + pMechanism->ulParameterLen; #endif else req_len = sizeof(SignRecoverInit_Args); args = (SignRecoverInit_Args *)malloc( req_len ); if (!args) return CKR_HOST_MEMORY; slot_id = SLOTID; args->session_handle = HTOCL( SESSION ); args->key = ( hKey ); args->mech_type = HTOCL( pMechanism->mechanism ); #if __64BIT__ args->param_len = HTOCL( get_mech_parameter_len(pMechanism)); #else args->param_len = HTOCL( pMechanism->ulParameterLen ); #endif if (pMechanism->ulParameterLen != 0) { CK_BYTE *ptr = (CK_BYTE *)args + sizeof(SignRecoverInit_Args); #ifdef _BIG_ENDIAN ADJUSTMECHPTR(); #else memcpy( ptr, pMechanism->pParameter, pMechanism->ulParameterLen ); #endif } repl_len = 0; rc = communicate( C_SIGNRECOVERINIT, slot_id, args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); free( args ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, mech = 0x%X\n", "C_SignRecoverInit", rc, SESSION, pMechanism->mechanism ); #endif return rc; } // // CK_RV SC_SignRecover( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ) { SignRecover_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; CK_BYTE * ptr = NULL; CK_BYTE * reply = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET // this must be at the end of the local variable defs if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (!pData || !pulSignatureLen) return CKR_ARGUMENTS_BAD; req_len = sizeof(SignRecover_Args) + ulDataLen; args = (SignRecover_Args *)malloc( req_len ); if (!args) return CKR_HOST_MEMORY; slot_id = SLOTID; args->session_handle = HTOCL( SESSION ); args->data_len = HTOCL( ulDataLen ); ptr = (CK_BYTE *)args + sizeof(SignRecover_Args); memcpy( ptr, pData, ulDataLen ); if (pSignature == NULL) { args->length_only = TRUE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32); #else repl_len = sizeof(CK_ULONG); #endif } else { args->length_only = FALSE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32) + *pulSignatureLen; #else repl_len = sizeof(CK_ULONG) + *pulSignatureLen; #endif } reply = (CK_BYTE *)malloc( repl_len ); if (!reply) { rc = CKR_HOST_MEMORY; } else { rc = communicate( C_SIGNRECOVER, slot_id, args, req_len, reply, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK || rc == CKR_BUFFER_TOO_SMALL) { #ifdef PKCS64 *pulSignatureLen = *(CK_ULONG_32 *)reply; #else memcpy( pulSignatureLen, reply, sizeof(CK_ULONG) ); #endif *pulSignatureLen = CTOHL( *pulSignatureLen ); if (rc == CKR_OK && args->length_only == FALSE) #ifdef PKCS64 memcpy( pSignature, reply + sizeof(CK_ULONG_32), *pulSignatureLen ); #else memcpy( pSignature, reply + sizeof(CK_ULONG), *pulSignatureLen ); #endif } } if (args) free( args ); if (reply) free( reply ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_SignRecover", rc, SESSION, ulDataLen ); #endif return rc; } // // CK_RV SC_VerifyRecoverInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { VerifyRecoverInit_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET // this must be at the end of the local variable defs if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (pMechanism->ulParameterLen != 0) #if __64BIT__ req_len = sizeof(VerifyRecoverInit_Args) + get_mech_parameter_len(pMechanism); #else req_len = sizeof(VerifyRecoverInit_Args) + pMechanism->ulParameterLen; #endif else req_len = sizeof(VerifyRecoverInit_Args); args = (VerifyRecoverInit_Args *)malloc( req_len ); if (!args) return CKR_HOST_MEMORY; args->session_handle = HTOCL( SESSION ); args->key = ( hKey ); args->mech_type = HTOCL( pMechanism->mechanism ); #if __64BIT__ args->param_len = HTOCL( get_mech_parameter_len(pMechanism)); #else args->param_len = HTOCL( pMechanism->ulParameterLen ); #endif slot_id = SLOTID; if (pMechanism->ulParameterLen != 0) { CK_BYTE *ptr = (CK_BYTE *)args + sizeof(VerifyRecoverInit_Args); #ifdef _BIG_ENDIAN ADJUSTMECHPTR(); #else memcpy( ptr, pMechanism->pParameter, pMechanism->ulParameterLen ); #endif } repl_len = 0; rc = communicate( C_VERIFYRECOVERINIT, slot_id, args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); free( args ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, mech = 0x%X\n", "C_VerifyRecoverInit", rc, SESSION, pMechanism->mechanism ); #endif return rc; } // // CK_RV SC_VerifyRecover( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen ) { VerifyRecover_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; CK_BYTE * ptr = NULL; CK_BYTE * reply = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET // this must be at the end of the local variable defs if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (!pSignature || !pulDataLen) return CKR_ARGUMENTS_BAD; req_len = sizeof(VerifyRecover_Args) + ulSignatureLen; args = (VerifyRecover_Args *)malloc( req_len ); if (!args) { rc = CKR_HOST_MEMORY; } else { slot_id = SLOTID; args->session_handle = HTOCL( SESSION ); args->signature_len = HTOCL( ulSignatureLen ); ptr = (CK_BYTE *)args + sizeof(VerifyRecover_Args); memcpy( ptr, pSignature, ulSignatureLen ); if (!pData) { args->length_only = TRUE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32); #else repl_len = sizeof(CK_ULONG); #endif } else { args->length_only = FALSE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32) + *pulDataLen; #else repl_len = sizeof(CK_ULONG) + *pulDataLen; #endif } reply = (CK_BYTE *)malloc( repl_len ); if (!reply) { rc = CKR_HOST_MEMORY; } else { rc = communicate( C_VERIFYRECOVER, slot_id, args, req_len, reply, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK || rc == CKR_BUFFER_TOO_SMALL) { #ifdef PKCS64 *pulDataLen = *(CK_ULONG_32 *)reply; #else memcpy( pulDataLen, reply, sizeof(CK_ULONG) ); #endif *pulDataLen = CTOHL( *pulDataLen ); if (rc == CKR_OK && args->length_only == FALSE) #ifdef PKCS64 memcpy( pData, reply + sizeof(CK_ULONG_32), *pulDataLen ); #else memcpy( pData, reply + sizeof(CK_ULONG), *pulDataLen ); #endif } } } if (args) free( args ); if (reply) free( reply ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, recover len = %d\n", "C_VerifyRecover", rc, SESSION, *pulDataLen ); #endif return rc; } // // CK_RV SC_GetOperationState( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen ) { GetOperationState_Args args; HOST_SESSION_HANDLE *node = NULL; CK_BYTE *reply; CK_SLOT_ID slot_id; CK_ULONG req_len; CK_ULONG repl_len; CK_RV rc; SESS_SET // this must be at the end of the local variable defs if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (!pulOperationStateLen) return CKR_ARGUMENTS_BAD; slot_id = SLOTID; args.session_handle = HTOCL( SESSION ); if (pOperationState == NULL) { args.length_only = TRUE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32); #else repl_len = sizeof(CK_ULONG); #endif } else { args.length_only = FALSE; #ifdef PKCS64 repl_len = sizeof(CK_ULONG_32) + *pulOperationStateLen; #else repl_len = sizeof(CK_ULONG) + *pulOperationStateLen; #endif } reply = (CK_BYTE *)malloc(repl_len); if (!reply) return CKR_HOST_MEMORY; req_len = sizeof(args); rc = communicate( C_GETOPERATIONSTATE, slot_id, &args, req_len, reply, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK) { #ifndef _BIG_ENDIAN memcpy( pulOperationStateLen, reply, sizeof(CK_ULONG) ); #else { #ifdef PKCS64 CK_ULONG_32 tLen; tLen = *(CK_ULONG_32 *)reply; #else CK_ULONG tLen; memcpy( &tLen, reply, sizeof(CK_ULONG) ); #endif tLen = CTOHL(tLen); *pulOperationStateLen = tLen; } #endif if (args.length_only == FALSE) #ifdef PKCS64 memcpy( pOperationState, reply + sizeof(CK_ULONG_32), *pulOperationStateLen ); #else memcpy( pOperationState, reply + sizeof(CK_ULONG), *pulOperationStateLen ); #endif } free( reply ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d\n", "C_GetOperationState", rc, SESSION ); #endif return rc; } // // CK_RV SC_SetOperationState( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey ) { SetOperationState_Args *args = NULL; HOST_SESSION_HANDLE *node = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len; CK_RV rc; SESS_SET // this must be at the end of the local variable defs if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (!pOperationState) return CKR_ARGUMENTS_BAD; slot_id = SLOTID; req_len = sizeof(SetOperationState_Args) + ulOperationStateLen; repl_len = 0; args = (SetOperationState_Args *)malloc( req_len ); if (!args) return CKR_HOST_MEMORY; args->session_handle = HTOCL( SESSION ); args->encr_key = (hEncryptionKey); args->auth_key = (hAuthenticationKey); args->data_len = HTOCL( ulOperationStateLen ); memcpy( (CK_BYTE *)args + sizeof(SetOperationState_Args), pOperationState, ulOperationStateLen ); rc = communicate( C_SETOPERATIONSTATE, slot_id, args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); free( args ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d\n", "C_SetOperationState", rc, SESSION ); #endif return rc; } // // CK_RV SC_InitToken( CK_SLOT_ID sid, CK_CHAR_PTR pPin, CK_ULONG ulPinLen, CK_CHAR_PTR pLabel ) { InitToken_Args *args = NULL; CK_ULONG req_len, repl_len; CK_RV rc; // Normalize to stdll slot index CK_SLOT_ID slotID; SLT_CHECK; slotID = slot_id; if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (!pPin || !pLabel) return CKR_FUNCTION_FAILED; req_len = sizeof(InitToken_Args) + ulPinLen; repl_len = 0; args = (InitToken_Args *)malloc(req_len); if (!args) return CKR_HOST_MEMORY; memcpy( args->label, pLabel, 32 ); args->so_pin_len = HTOCL( ulPinLen ); memcpy( (CK_BYTE *)args + sizeof(InitToken_Args), pPin, ulPinLen ); rc = communicate( C_INITTOKEN, slotID, args, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); free( args ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x\n", "C_InitToken", rc ); #endif return rc; } // // //CK_RV C_DeriveKey( CK_SESSION_HANDLE hSession, // CK_MECHANISM_PTR pMechanism, // CK_OBJECT_HANDLE hBaseKey, // CK_ATTRIBUTE_PTR pTemplate, // CK_ULONG ulAttributeCount, // CK_OBJECT_HANDLE_PTR phKey ) //{ // DeriveKey_Args * args; // HOST_SESSION_HANDLE * node = NULL; // CK_ATTRIBUTE * attr = NULL; // CK_BYTE * ptr = NULL; // CK_SLOT_ID slot_id; // CK_ULONG req_len, repl_len; // CK_ULONG tmpl_len, i; // CK_RV rc; // CK_BYTE * reply = NULL; // // // if (Initialized() == FALSE) // return CKR_CRYPTOKI_NOT_INITIALIZED; // // if (!pMechanism || !phKey) // return CKR_ARGUMENTS_BAD; // // node = findSession( hSession ); // if (!node) // return CKR_SESSION_HANDLE_INVALID; // // // slot_id = node->slot_id; // // // // // figure out how much memory to allocate for the request block // // // // // compute the total template size // // // tmpl_len = 0; // for (attr = pTemplate, i = 0; i < ulAttributeCount; i++, attr++) // tmpl_len += sizeof(ATTRIBUTE) + attr->ulValueLen; // // req_len = sizeof(DeriveKey_Args) + pMechanism->ulParameterLen + tmpl_len; // // // The mechanism parameter for certain mechanisms contains pointers to // // other things; in those cases, we have to add those things to the // // request and adjust the request length accordingly, then copy those // // things to the request... // // // // Simlarly, the information returned for certain mechanisms consists of // // more than just a key handle. We have to anticipate this when we // // allocate space to hold the reply... // // // // CKM_SSL3_MASTER_KEY_DERIVE - // // // // Parameter block (CK_SSL3_MASTER_KEY_DERIVE_PARAMS): // // space for remote copy of pClientRandom <-+ // // ulClientRandomLen | // // space for remote copy of pServerRandom +- ulParameterLen // // ulServerRandomLen | // // space for remote copy of pVersion <-+ // // buffer[ulClientRandomLen] (client random data) // // buffer[ulServerRandomLen] (server random data) // // // // Reply block: // // object handle for master key // // updated version information (sizeof(CK_VERSION))// // // // CKM_SSL3_KEY_AND_MAC_DERIVE - // // // // Parameter block (CK_SSL3_KEY_MAT_PARAMS): // // ulMacSizeInBits <-+ // // ulKeySizeInBits | // // ulIVSizeInBits | // // bIsExport | // // space for remote copy of pClientRandom +- ulParameterLen // // ulClientRandomLen | // // space for remote copy of pServerRandom | // // ulServerRandomLen | // // space for remote copy of pReturnedKeyMaterial <-+ // // buffer[ulClientRandomLen] (client random data) // // buffer[ulServerRandomLen] (server random data) // // // // Reply block (CK_SSL3_KEY_MAT_OUT): // // object handle for client MAC secret key // // object handle for server MAC secret key // // object handle for client secret key // // object handle for server secret key // // space for remote copy of pIVClient // // space for remote copy of pIVServer // // buffer[(ulIVSizeInBits + 7)/8] (client IV) // // buffer[(ulIVSizeInBits + 7)/8] (server IV) // // // switch( pMechanism->mechanism ) // { // case CKM_SSL3_MASTER_KEY_DERIVE: // { // CK_SSL3_MASTER_KEY_DERIVE_PARAMS * pPtr = // (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *)pMechanism->pParameter; // // req_len += pPtr->RandomInfo.ulClientRandomLen // + pPtr->RandomInfo.ulServerRandomLen; // // repl_len = sizeof(CK_OBJECT_HANDLE) + sizeof(CK_VERSION); // break; // } // // case CKM_SSL3_KEY_AND_MAC_DERIVE: // { // CK_SSL3_KEY_MAT_PARAMS * pPtr = // (CK_SSL3_KEY_MAT_PARAMS *)pMechanism->pParameter; // // req_len += pPtr->RandomInfo.ulClientRandomLen // + pPtr->RandomInfo.ulServerRandomLen; // // repl_len = 4*sizeof(CK_OBJECT_HANDLE) // + 2*sizeof(CK_BYTE_PTR) // + 2*((pPtr->ulIVSizeInBits + 7)/8); // break; // } // default: // repl_len = sizeof(CK_OBJECT_HANDLE); // break; // } // // args = (DeriveKey_Args *)malloc( req_len ); // if (!args) // return CKR_HOST_MEMORY; // // reply = (CK_BYTE *)malloc( repl_len ); // if (!reply) { // free( args ); // return CKR_HOST_MEMORY; // } // // args->session_handle = HTOCL( node->handle ); // args->mech_type = HTOCL( pMechanism->mechanism ); // args->mech_param_len = HTOCL( pMechanism->ulParameterLen ); // args->base_key = hBaseKey; // args->attribute_count = HTOCL( ulAttributeCount ); // args->attribute_block_len = HTOCL( tmpl_len ); // // ptr = (CK_BYTE *)args + sizeof(DeriveKey_Args); // // if (pMechanism->ulParameterLen != 0) { // // WARNING: again, for BIG-ENDIAN machines, it might be necessary // // to ensure the parameter has the correct endianness if it is to // // be interpretted as something other than a byte array // // // memcpy( ptr, pMechanism->pParameter, pMechanism->ulParameterLen ); // ptr += pMechanism->ulParameterLen; // } // // // Insert mechanism-specific "flattened" pointer info... // // // switch( pMechanism->mechanism ) // { // case CKM_SSL3_MASTER_KEY_DERIVE: // { // CK_SSL3_MASTER_KEY_DERIVE_PARAMS * pPtr = // (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *)pMechanism->pParameter; // // memcpy( ptr, // pPtr->RandomInfo.pClientRandom, // pPtr->RandomInfo.ulClientRandomLen ); // // ptr += pPtr->RandomInfo.ulClientRandomLen; // // memcpy( ptr, // pPtr->RandomInfo.pServerRandom, // pPtr->RandomInfo.ulServerRandomLen ); // // ptr += pPtr->RandomInfo.ulServerRandomLen; // // break; // } // case CKM_SSL3_KEY_AND_MAC_DERIVE: // { // CK_SSL3_KEY_MAT_PARAMS * pPtr = // (CK_SSL3_KEY_MAT_PARAMS *)pMechanism->pParameter; // // memcpy( ptr, // pPtr->RandomInfo.pClientRandom, // pPtr->RandomInfo.ulClientRandomLen ); // // ptr += pPtr->RandomInfo.ulClientRandomLen; // // memcpy( ptr, // pPtr->RandomInfo.pServerRandom, // pPtr->RandomInfo.ulServerRandomLen ); // // ptr += pPtr->RandomInfo.ulServerRandomLen; // // break; // } // default: // break; // } // // // insert the attribute template into the request // // // attr = pTemplate; // // for (i=0; i < ulAttributeCount; i++, attr++) { // ATTRIBUTE *p_attrib = (ATTRIBUTE *)ptr; // // p_attrib->type = HTOCL( attr->type ); // p_attrib->value_length = HTOCL( attr->ulValueLen ); // // // BIG-ENDIAN warning. Same here... // // // memcpy( (ptr + sizeof(ATTRIBUTE)), attr->pValue, attr->ulValueLen ); // // ptr += sizeof(ATTRIBUTE) + attr->ulValueLen; // } // // rc = communicate( C_DERIVEKEY, slot_id, // args, req_len, // reply, &repl_len, // NULL, 0, // NULL, 0 ); // // free( args ); // // // Copy returned information to appropriate destination // // // switch( pMechanism->mechanism ) // { // case CKM_SSL3_MASTER_KEY_DERIVE: // { // CK_SSL3_MASTER_KEY_DERIVE_PARAMS * pPtr = // (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *)pMechanism->pParameter; // // // Update version information in mechanism parameter // // // memcpy( pPtr->pVersion, // reply + sizeof(CK_OBJECT_HANDLE), // sizeof(CK_VERSION) ); // // // Return handle of derived key // // // memcpy( phKey, reply, sizeof(CK_OBJECT_HANDLE) ); // // break; // } // // case CKM_SSL3_KEY_AND_MAC_DERIVE: // { // CK_SSL3_KEY_MAT_OUT *pPtr = // ((CK_SSL3_KEY_MAT_PARAMS *) // (pMechanism->pParameter))->pReturnedKeyMaterial; // // CK_ULONG IVlen = // (repl_len - 2*sizeof(CK_BYTE_PTR) - 4*sizeof(CK_OBJECT_HANDLE))/2; // // // Copy object handles from reply to user's buffer // // // memcpy( pPtr, // reply, // 4*sizeof(CK_OBJECT_HANDLE) ); // // // If IV length was nonzero, copy IVs from reply to // // user's buffer // // // if (IVlen != 0) // { // memcpy( pPtr->pIVClient, // reply + 4*sizeof(CK_OBJECT_HANDLE), // IVlen ); // memcpy( pPtr->pIVServer, // reply + 4*sizeof(CK_OBJECT_HANDLE) + IVlen, // IVlen ); // } // // break; // } // // default: // break; // } // // free( reply ); // //#ifdef DEBUGON // LOG_DEBUG = fopen( DEBUGFILEPATH, "a" ); // logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, handle = %d, mech = %x\n", "C_DeriveKey", rc, node->handle, *phKey, pMechanism->mechanism ); // // attr = pTemplate; // for (i=0; i < ulAttributeCount; i++, attr++) { // ptr = (CK_BYTE *)attr->pValue; // // logit(LOG_DEBUG, " %3d: Attribute type: 0x%08x\n", i, attr->type ); // logit(LOG_DEBUG, " Value Length: %08d\n", attr->ulValueLen ); // // if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) // logit(LOG_DEBUG, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); // // logit(LOG_DEBUG, "\n\n"); // } // // fflush(LOG_DEBUG); // fclose(LOG_DEBUG); //#endif // // return rc; //} CK_RV SC_DeriveKey( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey ) { DeriveKey_Args * args = NULL; HOST_SESSION_HANDLE * node = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * reply = NULL; CK_BYTE * param = NULL; CK_BYTE * ptr = NULL; CK_SLOT_ID slot_id; CK_ULONG req_len, repl_len, param_len; CK_ULONG tmpl_len, i; CK_RV rc; SESS_SET // this must be at the end of the local variable defs if (Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (!pMechanism ) return CKR_ARGUMENTS_BAD; // pHkey can be null if the mechanism is SSL3_KEY_AND_MAC_DERIVE if ( !phKey && (pMechanism->mechanism != CKM_SSL3_KEY_AND_MAC_DERIVE)) return CKR_ARGUMENTS_BAD; slot_id = SLOTID; // compute the total template size // tmpl_len = 0; #if __64BIT__ for (attr = pTemplate, i = 0; i < ulAttributeCount; i++, attr++) tmpl_len += sizeof(ATTRIBUTE) + get_attrib_len(attr); // attr->ulValueLen; #else for (attr = pTemplate, i = 0; i < ulAttributeCount; i++, attr++) tmpl_len += sizeof(ATTRIBUTE) + attr->ulValueLen; #endif // // some of the SSL3 mechanisms have mechanism parameters complicated by // pointers to other structures. we need to flatten these out before we // can send it to the card. we do this in two steps. first step is to // compute the length of the overall request block sent to the card. // second step fills in the mechanism-specific data // // step 1 -- get the request block length and the expected reply block length // switch (pMechanism->mechanism) { #if defined(ENABLE_DH) case CKM_DH_PKCS_DERIVE: { param_len = pMechanism->ulParameterLen; param = (CK_BYTE *)malloc( param_len ); if (!param) { rc = CKR_HOST_MEMORY; goto error; } memcpy( param, pMechanism->pParameter, param_len ); req_len = sizeof(DeriveKey_Args) + param_len + tmpl_len; #ifdef PKCS64 repl_len = sizeof(CK_OBJECT_HANDLE_32); #else repl_len = sizeof(CK_OBJECT_HANDLE); #endif } break; #endif case CKM_MD2_KEY_DERIVATION: case CKM_MD5_KEY_DERIVATION: case CKM_SHA1_KEY_DERIVATION: // no mechanism-specific parameters // param_len = 0; req_len = sizeof(DeriveKey_Args) + tmpl_len; #ifdef PKCS64 repl_len = sizeof(CK_OBJECT_HANDLE_32); #else repl_len = sizeof(CK_OBJECT_HANDLE); #endif break; case CKM_SSL3_MASTER_KEY_DERIVE: { SSL3_MASTER_KEY_DERIVE_PARAMS *p; CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ptr; ptr = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *)pMechanism->pParameter; // SAB XXX XXX 64BIT... // noting special needed since the // Random len is length of a byte string param_len = sizeof(SSL3_MASTER_KEY_DERIVE_PARAMS) + ptr->RandomInfo.ulClientRandomLen + ptr->RandomInfo.ulServerRandomLen; param = (CK_BYTE *)malloc( param_len ); if (!param) { rc = CKR_HOST_MEMORY; goto error; } // XXX 64BIT // No special 64 bit stuff since this is not a CK_ structure // p = (SSL3_MASTER_KEY_DERIVE_PARAMS *)param; p->version.major = 3; // this is ignored by the card p->version.minor = 0; // this is ignored by the card p->client_data_len = HTOCL( ptr->RandomInfo.ulClientRandomLen ); p->server_data_len = HTOCL( ptr->RandomInfo.ulServerRandomLen ); memcpy( param + sizeof(SSL3_MASTER_KEY_DERIVE_PARAMS), ptr->RandomInfo.pClientRandom, ptr->RandomInfo.ulClientRandomLen ); memcpy( param + sizeof(SSL3_MASTER_KEY_DERIVE_PARAMS) + ptr->RandomInfo.ulClientRandomLen, ptr->RandomInfo.pServerRandom, ptr->RandomInfo.ulServerRandomLen ); req_len = sizeof(DeriveKey_Args) + tmpl_len + param_len; #ifdef PKCS64 repl_len = sizeof(CK_OBJECT_HANDLE_32) + sizeof(CK_VERSION); #else repl_len = sizeof(CK_OBJECT_HANDLE) + sizeof(CK_VERSION); #endif } break; case CKM_SSL3_KEY_AND_MAC_DERIVE: { CK_SSL3_KEY_MAT_PARAMS *ptr; SSL3_KEY_MAT_PARAMS *p; CK_ULONG iv_len; ptr = (CK_SSL3_KEY_MAT_PARAMS *)pMechanism->pParameter; param_len = sizeof(SSL3_KEY_MAT_PARAMS) + ptr->RandomInfo.ulClientRandomLen + ptr->RandomInfo.ulServerRandomLen; iv_len = (ptr->ulIVSizeInBits + 7) / 8; param = (CK_BYTE *)malloc( param_len ); if (!param) { rc = CKR_HOST_MEMORY; goto error; } p = (SSL3_KEY_MAT_PARAMS *)param; p->mac_size_bits = HTOCL( ptr->ulMacSizeInBits ); p->key_size_bits = HTOCL( ptr->ulKeySizeInBits ); p->iv_size_bits = HTOCL( ptr->ulIVSizeInBits ); p->export = ptr->bIsExport; p->client_data_len = HTOCL( ptr->RandomInfo.ulClientRandomLen ); p->server_data_len = HTOCL( ptr->RandomInfo.ulServerRandomLen ); memcpy( param + sizeof(SSL3_KEY_MAT_PARAMS), ptr->RandomInfo.pClientRandom, ptr->RandomInfo.ulClientRandomLen); memcpy( param + sizeof(SSL3_KEY_MAT_PARAMS) + ptr->RandomInfo.ulClientRandomLen, ptr->RandomInfo.pServerRandom, ptr->RandomInfo.ulServerRandomLen ); req_len = sizeof(DeriveKey_Args) + tmpl_len + param_len; repl_len = sizeof(SSL3_KEY_MAT_OUT) + (2 * iv_len); } break; default: rc = CKR_MECHANISM_INVALID; goto error; } args = (DeriveKey_Args *)malloc( req_len ); if (!args) { rc = CKR_HOST_MEMORY; goto error; } reply = (CK_BYTE *)malloc( repl_len ); if (!reply) { rc = CKR_HOST_MEMORY; goto error; } args->session_handle = HTOCL( SESSION ); args->mech_type = HTOCL( pMechanism->mechanism ); #if __64BIT__ args->mech_param_len = HTOCL( get_mech_parameter_len(pMechanism)); // XXX 64Bit #else args->mech_param_len = HTOCL( pMechanism->ulParameterLen ); #endif args->base_key = hBaseKey; args->attribute_count = HTOCL( ulAttributeCount ); args->attribute_block_len = HTOCL( tmpl_len ); ptr = (CK_BYTE *)args + sizeof(DeriveKey_Args); // insert the mechanism parameter // memcpy( ptr, param, param_len ); ptr += param_len; free( param ); param = NULL; // insert the attribute template into the request // attr = pTemplate; for (i=0; i < ulAttributeCount; i++, attr++) { ATTRIBUTE *p_attrib = (ATTRIBUTE *)ptr; p_attrib->type = HTOCL( attr->type ); #if __64BIT__ p_attrib->value_length = HTOCL(get_attrib_len(attr)); //attr->ulValueLen); #else p_attrib->value_length = HTOCL( attr->ulValueLen ); #endif // BIG-ENDIAN warning. Same here... // #ifndef _BIG_ENDIAN memcpy( (ptr + sizeof(ATTRIBUTE)), attr->pValue, attr->ulValueLen ); #else { unsigned char *pd,*ps; unsigned long *pl; // We need to swap the values. pd = (unsigned char *)(ptr + sizeof(ATTRIBUTE)); ps = (unsigned char *)(attr->pValue); #if __64BIT__ copy_attribute_value(ps,pd,attr); #else memcpy(pd, ps, attr->ulValueLen); #endif #if __64BIT__ if ( attr->ulValueLen == 8 ) { #else if ( attr->ulValueLen == 4 ) { #endif pl = (unsigned long *)attr->pValue; pl = (unsigned long *)ps; #ifdef PKCS64 ModifyAttribute(attr->type,(CK_ULONG_PTR_32)pd); #else ModifyAttribute(attr->type,(CK_ULONG_PTR)pd); #endif } } #endif #if __64BIT__ ptr += sizeof(ATTRIBUTE) + get_attrib_len(attr); //attr->ulValueLen; #else ptr += sizeof(ATTRIBUTE) + attr->ulValueLen; #endif } rc = communicate( C_DERIVEKEY, slot_id, args, req_len, reply, &repl_len, NULL, 0, NULL, 0 ); free( args ); args = NULL; if (rc != CKR_OK) goto error; // copy returned information to appropriate destination // switch (pMechanism->mechanism) { case CKM_SSL3_MASTER_KEY_DERIVE: { CK_SSL3_MASTER_KEY_DERIVE_PARAMS *pPtr = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *)pMechanism->pParameter; #ifdef PKCS64 #if __64BIT__ *phKey = (CK_ULONG_32)*reply; #else memcpy( phKey, reply, sizeof(CK_OBJECT_HANDLE_32) ); #endif #else memcpy( phKey, reply, sizeof(CK_OBJECT_HANDLE) ); #endif // Netscape's regression tests sometimes set the version pointer // to NULL... // if (pPtr->pVersion != NULL) { memcpy( pPtr->pVersion, #ifdef PKCS64 reply + sizeof(CK_OBJECT_HANDLE_32), #else reply + sizeof(CK_OBJECT_HANDLE), #endif sizeof(CK_VERSION) ); } } break; case CKM_SSL3_KEY_AND_MAC_DERIVE: { CK_SSL3_KEY_MAT_PARAMS *pReq; CK_SSL3_KEY_MAT_OUT *pPtr; SSL3_KEY_MAT_OUT *pReply; #if __64BIT__ CK_ULONG_32 iv_len; #else CK_ULONG iv_len; #endif pReq = (CK_SSL3_KEY_MAT_PARAMS *)pMechanism->pParameter; iv_len = (pReq->ulIVSizeInBits + 7) / 8; pPtr = pReq->pReturnedKeyMaterial; pReply = (SSL3_KEY_MAT_OUT *)reply; // pReply comes from the Card, therefore it MUST // be endian adjusted. pReply->iv_len = CTOHL(pReply->iv_len); if (pReply->iv_len != iv_len) { rc = CKR_FUNCTION_FAILED; goto error; } pPtr->hClientMacSecret = pReply->client_mac_secret; pPtr->hServerMacSecret = pReply->server_mac_secret; pPtr->hClientKey = pReply->client_key; pPtr->hServerKey = pReply->server_key; ptr = (CK_BYTE *)pReply + sizeof(SSL3_KEY_MAT_OUT); if (iv_len) { memcpy( pPtr->pIVClient, ptr, iv_len ); ptr += iv_len; memcpy( pPtr->pIVServer, ptr, iv_len ); } } break; default: // any illegal mechanisms have already been filtered out by now // // JRM - please sanity check this for 64-bit correctness... // #ifdef PKCS64 #if __64BIT__ *phKey = (CK_ULONG_32)*reply; #else memcpy( phKey, reply, sizeof(CK_OBJECT_HANDLE_32) ); #endif #else memcpy( phKey, reply, sizeof(CK_OBJECT_HANDLE) ); #endif break; } free( reply ); reply = NULL; error: if (param) free( param ); if (args) free( args ); if (reply) free( reply ); #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x, sess = %d, base key = %d, mech = %x\n", "C_DeriveKey", rc, SESSION, hBaseKey, pMechanism->mechanism ); logit(LOG_DEBUG, "%-25s: requestlen %d mechparmlen %d sizeof(DeriveKey_Args) %d passedparm %d\n", "C_DeriveKey", req_len,pMechanism->ulParameterLen,sizeof(DeriveKey_Args), param_len); if (rc == CKR_OK) switch (pMechanism->mechanism) { case CKM_SSL3_KEY_AND_MAC_DERIVE: { CK_SSL3_KEY_MAT_PARAMS *pReq; CK_SSL3_KEY_MAT_OUT *pPtr; pReq = (CK_SSL3_KEY_MAT_PARAMS *)pMechanism->pParameter; pPtr = pReq->pReturnedKeyMaterial; logit(LOG_DEBUG, " Client MAC key: %d\n", pPtr->hClientMacSecret ); logit(LOG_DEBUG, " Server MAC key: %d\n", pPtr->hServerMacSecret ); logit(LOG_DEBUG, " Client Key: %d\n", pPtr->hClientKey ); logit(LOG_DEBUG, " Server Key: %d\n", pPtr->hServerKey ); } break; default: logit(LOG_DEBUG, " Derived key: %d\n", *phKey ); } attr = pTemplate; for (i=0; i < ulAttributeCount; i++, attr++) { ptr = (CK_BYTE *)attr->pValue; logit(LOG_DEBUG, " %3d: Attribute type: 0x%08x\n", i, attr->type ); logit(LOG_DEBUG, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) logit(LOG_DEBUG, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); logit(LOG_DEBUG, "\n\n"); } #endif return rc; } #define FCV_ENABLED #ifdef FCV_ENABLED // This function sends a Function Control Vector to the card // CK_RV FCVFunction( CK_SLOT_ID sid, CK_BYTE *FCV, CK_ULONG len ) { CK_ULONG req_len, repl_len, expected_repl_len; CK_RV rc; SLT_CHECK; if (slot_id == 0 && Initialized() == FALSE) return CKR_CRYPTOKI_NOT_INITIALIZED; if (slot_id > MAX_SLOT_ID) return CKR_SLOT_ID_INVALID; req_len = len; repl_len = expected_repl_len = 0; rc = communicate( FCVFUNCTION, slot_id, FCV, req_len, NULL, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK) { if ( repl_len != expected_repl_len ) rc = CKR_GENERAL_ERROR; } #ifdef DEBUGON logit(LOG_DEBUG, "%-25s: rc = %08x\n", "FCVFUNCTION", rc ); #endif return rc; } #endif #if LINUX void _init() { printf("Initialization of leeds STDLL \n"); } #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/leeds_stdll/defs.h0000751000175000017500000005351011327631345021023 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/lib/pkcs11/leeds_stdll/defs.h,v 1.3 2005/11/03 19:38:00 mhalcrow Exp $ */ // /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ // File: defs.h // // Contains various definitions needed by both the host-side // and coprocessor-side code. // #ifndef _DEFS_H #define _DEFS_H #include #if (LEEDS_BUILD) #pragma pack(1) #pragma options align=packed #endif #define MAX_SESSION_COUNT 64 #define MAX_PIN_LEN 8 #define MIN_PIN_LEN 4 #define MAX_SLOT_ID 10 #define LEEDS_MAX_REQ_LEN 4096 #ifndef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif // the following constants are used for sccSignOn // #define PKCS_11_PRG_ID "pkcs11 2.01" #define PKCS_11_DEVELOPER_ID 0xE #define PKCS_11_VERSION 1 #define PKCS_11_INSTANCE 0 #define PKCS_11_QUEUE 0 #define LEEDS_PRG_ID_PKCS_11 "PKCS11" enum { DUMMYFUNCTION = 99999, FCVFUNCTION = 99998, C_INITIALIZE = 1, C_FINALIZE, C_GETINFO, C_GETFUNCTIONLIST, C_GETSLOTLIST, C_GETSLOTINFO, C_GETTOKENINFO, C_WAITFORSLOTEVENT, C_GETMECHANISMLIST, C_GETMECHANISMINFO, C_INITTOKEN, C_INITPIN, C_SETPIN, C_OPENSESSION, C_CLOSESESSION, C_CLOSEALLSESSIONS, C_GETSESSIONINFO, C_GETOPERATIONSTATE, C_SETOPERATIONSTATE, C_LOGIN, C_LOGOUT, C_CREATEOBJECT, C_COPYOBJECT, C_DESTROYOBJECT, C_GETOBJECTSIZE, C_GETATTRIBUTEVALUE, C_SETATTRIBUTEVALUE, C_FINDOBJECTSINIT, C_FINDOBJECTS, C_FINDOBJECTSFINAL, C_ENCRYPTINIT, C_ENCRYPT, C_ENCRYPTUPDATE, C_ENCRYPTFINAL, C_DECRYPTINIT, C_DECRYPT, C_DECRYPTUPDATE, C_DECRYPTFINAL, C_DIGESTINIT, C_DIGEST, C_DIGESTUPDATE, C_DIGESTKEY, C_DIGESTFINAL, C_SIGNINIT, C_SIGN, C_SIGNUPDATE, C_SIGNFINAL, C_SIGNRECOVERINIT, C_SIGNRECOVER, C_VERIFYINIT, C_VERIFY, C_VERIFYUPDATE, C_VERIFYFINAL, C_VERIFYRECOVERINIT, C_VERIFYRECOVER, C_DIGESTENCRYPTUPDATE, C_DECRYPTDIGESTUPDATE, C_SIGNENCRYPTUPDATE, C_DECRYPTVERIFYUPDATE, C_GENERATEKEY, C_GENERATEKEYPAIR, C_WRAPKEY, C_UNWRAPKEY, C_DERIVEKEY, C_SEEDRANDOM, C_GENERATERANDOM, C_GETFUNCTIONSTATUS, C_CANCELFUNCTION }; //typedef struct _LEEDS_PACKET //{ // CK_ULONG cmd_id; // CK_ULONG pid; // CK_RV rc; // CK_ULONG data_len; // CK_BYTE data[4096]; //} LEEDS_PACKET; #ifdef PKCS64 typedef struct _LEEDS_REQUEST { CK_ULONG_32 pid; CK_ULONG_32 req_len; // size of request data CK_ULONG_32 repl_max[4]; // any command-specific request data gets appended here // } LEEDS_REQUEST; typedef struct _LEEDS_REPLY { #ifdef PKCS64 CK_ULONG_32 rc; #else CK_RV rc; #endif CK_ULONG_32 repl_len[4]; // size of data // any command-specific reply data gets appended here // } LEEDS_REPLY; // this is the format of attributes that get passed between 4758 and host // // this is different from the CK_ATTRIBUTE format defined by Cryptoki. // CK_ATTRIBUTE uses a pointer to the data field but we need a flat // structure to pass between the coprocessor and host DLL. Further, we // need the length field to precede the data. // typedef struct _ATTRIBUTE { CK_ATTRIBUTE_TYPE_32 type; CK_ULONG_32 value_length; // the value data is appended here // } ATTRIBUTE; typedef struct _DL_NODE { struct _DL_NODE *next; struct _DL_NODE *prev; void *data; } DL_NODE; // this is a flattened version of the CK_SSL3_RANDOM_DATA // typedef struct _SSL3_RANDOM_DATA { CK_ULONG_32 client_data_len; CK_ULONG_32 server_data_len; // client data is appended here // server data is appended here // } SSL3_RANDOM_DATA; // // typedef struct _SSL3_MASTER_KEY_DERIVE_PARAMS { CK_VERSION version; CK_ULONG_32 client_data_len; CK_ULONG_32 server_data_len; // client data is appended here // server data is appended here // } SSL3_MASTER_KEY_DERIVE_PARAMS; // // typedef struct _SSL3_KEY_MAT_OUT { CK_OBJECT_HANDLE_32 client_mac_secret; CK_OBJECT_HANDLE_32 server_mac_secret; CK_OBJECT_HANDLE_32 client_key; CK_OBJECT_HANDLE_32 server_key; CK_ULONG_32 iv_len; // in bytes // client IV is appended here // server IV is appended here // } SSL3_KEY_MAT_OUT; // // typedef struct _SSL3_KEY_MAT_PARAMS { CK_ULONG_32 mac_size_bits; CK_ULONG_32 key_size_bits; CK_ULONG_32 iv_size_bits; CK_BBOOL export; CK_ULONG_32 client_data_len; CK_ULONG_32 server_data_len; // client data is appended here // server data is appended here // } SSL3_KEY_MAT_PARAMS; // SAB XXX 64Bit /* typedef struct _VERSION { CK_BYTE major; CK_BYTE minor; } VERSION; */ #else // !PKCS11 // WJH Original struct definitions ... typedef struct _LEEDS_REQUEST { CK_ULONG pid; CK_ULONG req_len; // size of request data CK_ULONG repl_max[4]; // any command-specific request data gets appended here // } LEEDS_REQUEST; typedef struct _LEEDS_REPLY { CK_RV rc; CK_ULONG repl_len[4]; // size of data // any command-specific reply data gets appended here // } LEEDS_REPLY; // this is the format of attributes that get passed between 4758 and host // // this is different from the CK_ATTRIBUTE format defined by Cryptoki. // CK_ATTRIBUTE uses a pointer to the data field but we need a flat // structure to pass between the coprocessor and host DLL. Further, we // need the length field to precede the data. // typedef struct _ATTRIBUTE { CK_ATTRIBUTE_TYPE type; CK_ULONG value_length; // the value data is appended here // } ATTRIBUTE; typedef struct _DL_NODE { struct _DL_NODE *next; struct _DL_NODE *prev; void *data; } DL_NODE; // this is a flattened version of the CK_SSL3_RANDOM_DATA // typedef struct _SSL3_RANDOM_DATA { CK_ULONG client_data_len; CK_ULONG server_data_len; // client data is appended here // server data is appended here // } SSL3_RANDOM_DATA; // // typedef struct _SSL3_MASTER_KEY_DERIVE_PARAMS { CK_VERSION version; CK_ULONG client_data_len; CK_ULONG server_data_len; // client data is appended here // server data is appended here // } SSL3_MASTER_KEY_DERIVE_PARAMS; // // typedef struct _SSL3_KEY_MAT_OUT { CK_OBJECT_HANDLE client_mac_secret; CK_OBJECT_HANDLE server_mac_secret; CK_OBJECT_HANDLE client_key; CK_OBJECT_HANDLE server_key; CK_ULONG iv_len; // in bytes // client IV is appended here // server IV is appended here // } SSL3_KEY_MAT_OUT; // // typedef struct _SSL3_KEY_MAT_PARAMS { CK_ULONG mac_size_bits; CK_ULONG key_size_bits; CK_ULONG iv_size_bits; CK_BBOOL export; CK_ULONG client_data_len; CK_ULONG server_data_len; // client data is appended here // server data is appended here // } SSL3_KEY_MAT_PARAMS; #endif // PKCS11 #if (LEEDS_BUILD) #pragma pack( ) #pragma options align=full #endif #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/leeds_stdll/h_extern.h0000751000175000017500000010441411327631345021716 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/lib/pkcs11/leeds_stdll/h_extern.h,v 1.2 2005/02/22 20:48:04 mhalcrow Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #ifndef _H_EXTERN_H #define _H_EXTERN_H #include "pkcs11types.h" #include "defs.h" // Both of the strings below have a length of 32 chars and must be // padded with spaces, and non-null terminated. // #define PKW_CRYPTOKI_VERSION_MAJOR 2 #define PKW_CRYPTOKI_VERSION_MINOR 1 #define PKW_CRYPTOKI_MANUFACTURER "IBM Corp. " #define PKW_CRYPTOKI_LIBDESC "PKCS#11 Interface for IBM 4758 " #define PKW_CRYPTOKI_LIB_VERSION_MAJOR 1 #define PKW_CRYPTOKI_LIB_VERSION_MINOR 0 // Maximum number of supported devices (rather arbitrary) // #define PKW_MAX_DEVICES 10 // Session handles can range anywhere from 0 to sizeof(ULONG). Furthermore, // a single application can open as many sessions as it wants, and the // handles are not guaranteed to be unique between tokens. We therefore // save the slot id and session handle away in a struct, and give the // address of the struct to the application instead of the real session // handle. When it calls us back with that value, we simply dereference // it and once again have the real session handle and the correct slot // number. (This is not 64-bit safe.) // extern CK_BBOOL initialized; #ifdef PKCS64 extern CK_ULONG_32 pid_list[ PKW_MAX_DEVICES ]; #else extern CK_ULONG pid_list[ PKW_MAX_DEVICES ]; #endif typedef struct _HOST_SESSION_HANDLE { CK_SESSION_HANDLE handle; // token-assigned session handle CK_SESSION_HANDLE host_session; // pseudo session handle CK_SLOT_ID slot_id; } HOST_SESSION_HANDLE; // Endianness-conversion routines. This will be useful for folks trying // to use the coprocessor on a big-endian architecture... // // htocl -- host to card long // ctohl -- card to host long // #ifdef PKCS64 CK_ULONG_32 long_reverse( CK_ULONG_32 x ); #else CK_ULONG long_reverse( CK_ULONG x ); #endif #ifdef LITTLE_ENDIAN #define HTOCL(x) (x) #define CTOHL(x) (x) #else #define HTOCL(x) (long_reverse(x)) #define CTOHL(x) (long_reverse(x)) #endif // // PKCS#11 Function Definitions | // ..as per the RSA Labs PKCS#11 documentation, v2.01. | // // General-purpose functions // CK_RV C_Initialize ( CK_VOID_PTR pInitArgs ); CK_RV C_Finalize ( CK_VOID_PTR pReserved ); CK_RV C_GetInfo ( CK_INFO_PTR pInfo ); CK_RV C_GetFunctionList ( CK_FUNCTION_LIST_PTR_PTR ppFunctionList ); // Slot and token management functions // CK_RV C_GetSlotList ( CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount ); CK_RV C_GetSlotInfo ( CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo ); CK_RV C_GetTokenInfo ( CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo ); CK_RV C_WaitForSlotEvent ( CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved ); CK_RV C_GetMechanismList ( CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount ); CK_RV C_GetMechanismInfo ( CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo ); CK_RV C_InitToken ( CK_SLOT_ID slotID, CK_CHAR_PTR pPin, CK_ULONG ulPinLen, CK_CHAR_PTR pLabel ); CK_RV C_InitPIN ( CK_SESSION_HANDLE hSession, CK_CHAR_PTR pPin, CK_ULONG ulPinLen ); CK_RV C_SetPIN ( CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, CK_ULONG ulOldLen, CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen ); // Session management functions // CK_RV C_OpenSession ( CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession ); CK_RV C_CloseSession ( CK_SESSION_HANDLE hSession ); CK_RV C_CloseAllSessions ( CK_SLOT_ID slotID ); CK_RV C_GetSessionInfo ( CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo ); CK_RV C_GetOperationState ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen ); CK_RV C_SetOperationState ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey ); CK_RV C_Login ( CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG uPinLen ); CK_RV C_Logout ( CK_SESSION_HANDLE hSession ); // Object management functions // CK_RV C_CreateObject ( CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject ); CK_RV C_CopyObject ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phNewObject ); CK_RV C_DestroyObject ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject ); CK_RV C_GetObjectSize ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize ); CK_RV C_GetAttributeValue ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ); CK_RV C_SetAttributeValue ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ); CK_RV C_FindObjectsInit ( CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ); CK_RV C_FindObjects ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount ); CK_RV C_FindObjectsFinal ( CK_SESSION_HANDLE hSession ); // Encryption functions // CK_RV C_EncryptInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_Encrypt ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen ); CK_RV C_EncryptUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ); CK_RV C_EncryptFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen); // Decryption functions // CK_RV C_DecryptInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_Decrypt ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen ); CK_RV C_DecryptUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ); CK_RV C_DecryptFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen ); // Message digesting functions // CK_RV C_DigestInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism ); CK_RV C_Digest ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen ); CK_RV C_DigestUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ); CK_RV C_DigestKey ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey ); CK_RV C_DigestFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen ); // Signing and MAC functions // CK_RV C_SignInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_Sign ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ); CK_RV C_SignUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ); CK_RV C_SignFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ); CK_RV C_SignRecoverInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_SignRecover ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ); // Signature/MAC verification functions // CK_RV C_VerifyInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_Verify ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen ); CK_RV C_VerifyUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ); CK_RV C_VerifyFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen ); CK_RV C_VerifyRecoverInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_VerifyRecover ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen ); // Dual-function cryptographics functions // CK_RV C_DigestEncryptUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ); CK_RV C_DecryptDigestUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ); CK_RV C_SignEncryptUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ); CK_RV C_DecryptVerifyUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ); // Key management functions // CK_RV C_GenerateKey ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey ); CK_RV C_GenerateKeyPair ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey ); CK_RV C_WrapKey ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen ); CK_RV C_UnwrapKey ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey ); CK_RV C_DeriveKey ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey ); // Random number generation functions // CK_RV C_SeedRandom ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen ); CK_RV C_GenerateRandom ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen ); // Parallel function management functions // CK_RV C_GetFunctionStatus ( CK_SESSION_HANDLE hSession ); CK_RV C_CancelFunction ( CK_SESSION_HANDLE hSession ); // // Callback functions // // // Misc Routines // DL_NODE *dlist_add_as_first( DL_NODE *list, void *data ); DL_NODE *dlist_find ( DL_NODE *list, void *data ); void dlist_purge ( DL_NODE *list ); DL_NODE *dlist_remove_node ( DL_NODE *list, DL_NODE *node ); HOST_SESSION_HANDLE *findSession( CK_SESSION_HANDLE hSession ); void removeSession( HOST_SESSION_HANDLE *rem ); extern DL_NODE *session_list; #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/leeds_stdll/Makefile.am0000640000175000017500000000130311327631345021753 0ustar jfjflib_LTLIBRARIES=libpkcs11_4758.la libdir = $(exec_prefix)/lib/opencryptoki/stdll libpkcs11_4758_la_LDFLAGS = $(SCC_LIB_DIRS) -nostartfiles -shared \ -Wl,-Bsymbolic -Wl,-soname,$@.1 -lpthread -lscc \ -ldl # Not all versions of automake observe libname_CFLAGS libpkcs11_4758_la_CFLAGS = -DDEV -D_THREAD_SAFE -DLEEDS_BUILD # Not all versions of automake observe libname_CFLAGS AM_CFLAGS = -DDEV -D_THREAD_SAFE -DLEEDS_BUILD libpkcs11_4758_la_SOURCES = host_api.c util.c INCLUDES = $(SCC_INC_DIRS) -I/usr/include -I. -I../../../include/pkcs11/stdll \ -I../../../include/pkcs11 install-data-local: cd $(STDLL_PATH) && rm -f PKCS11_4758.so && \ ln -sf libpkcs11_4758.so PKCS11_4758.so opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/leeds_stdll/args.h0000751000175000017500000011641511327631345021042 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/lib/pkcs11/leeds_stdll/args.h,v 1.2 2005/02/22 20:48:04 mhalcrow Exp $ */ // /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ // File: cardargs.h // // Argument block definitions for coprocessor requests/replies // // This file is required for both host and coprocessor-side code // #ifndef _CARD_ARGS_H #define _CARD_ARGS_H #ifndef _PKCS11TYPES_H_ #include "PKCS11Types.h" #endif #if (LEEDS_BUILD) #pragma pack(1) #pragma options align=packed #endif #ifdef PKCS64 //------------------------------------------------------------------- // typedef struct _GetMechList_Args { CK_ULONG_32 list_length; CK_BBOOL length_only; } GetMechList_Args; // C_GetMechanismList reply: // // +-----------+------------------------------------+ // | CK_ULONG_32 | List of CK_MECHANISM_TYPE_32 elements | // +-----------+------------------------------------+ // typedef struct _GetMechInfo_Args { CK_MECHANISM_TYPE_32 mech_type; } GetMechInfo_Args; typedef struct _InitPIN_Args { CK_SESSION_HANDLE_32 session_handle; CK_BYTE pin[MAX_PIN_LEN]; CK_ULONG_32 pin_len; } InitPIN_Args; typedef struct _SetPIN_Args { CK_SESSION_HANDLE_32 session_handle; CK_BYTE old_pin[MAX_PIN_LEN]; CK_ULONG_32 old_pin_len; CK_BYTE new_pin[MAX_PIN_LEN]; CK_ULONG_32 new_pin_len; } SetPIN_Args; typedef struct _OpenSession_Args { CK_SLOT_ID_32 slot_id; CK_FLAGS_32 flags; CK_ULONG_32 application_ptr; // not used CK_ULONG_32 notify; // not used //CK_VOID_PTR application_ptr; // not used //CK_NOTIFY notify; // not used CK_BBOOL req_proc_handle; } OpenSession_Args; typedef struct _CloseSession_Args { CK_SESSION_HANDLE_32 session_handle; } CloseSession_Args; typedef struct _GetSessionInfo_Args { CK_SESSION_HANDLE_32 session_handle; } GetSessionInfo_Args; typedef struct _Login_Args { CK_SESSION_HANDLE_32 session_handle; CK_USER_TYPE_32 user_type; CK_BYTE pin[MAX_PIN_LEN]; CK_ULONG_32 pin_len; } Login_Args; typedef struct _Logout_Args { CK_SESSION_HANDLE_32 session_handle; } Logout_Args; // CreateObject_Args is a bit different. The attributes themselves // are passed as a datablock immediately following this structure // typedef struct _CreateObject_Args { CK_SESSION_HANDLE_32 session_handle; CK_ULONG_32 attribute_count; CK_ULONG_32 attribute_block_len; // attributes/template gets appended here // } CreateObject_Args; typedef struct _CopyObject_Args { CK_SESSION_HANDLE_32 session_handle; CK_OBJECT_HANDLE_32 object_handle; CK_ULONG_32 attribute_count; CK_ULONG_32 attribute_block_len; // attributes/template gets appended here // } CopyObject_Args; typedef struct _DestroyObject_Args { CK_SESSION_HANDLE_32 session_handle; CK_OBJECT_HANDLE_32 object_handle; } DestroyObject_Args; typedef struct _GetObjectSize_Args { CK_SESSION_HANDLE_32 session_handle; CK_OBJECT_HANDLE_32 object_handle; } GetObjectSize_Args; typedef struct _GetAttributeValue_Args { CK_SESSION_HANDLE_32 session_handle; CK_OBJECT_HANDLE_32 object_handle; CK_ULONG_32 attribute_count; CK_ULONG_32 attribute_block_len; CK_BBOOL size_only; // list of attribute types (CK_ATTRIBUTE_TYPE) gets appended here. // } GetAttributeValue_Args; typedef struct _SetAttributeValue_Args { CK_SESSION_HANDLE_32 session_handle; CK_OBJECT_HANDLE_32 object_handle; CK_ULONG_32 attribute_count; CK_ULONG_32 attribute_block_len; // attribute template gets appended here // } SetAttributeValue_Args; typedef struct _FindObjectsInit_Args { CK_SESSION_HANDLE_32 session_handle; CK_ULONG_32 attribute_count; CK_ULONG_32 attribute_block_len; // attribute template gets appended here // } FindObjectsInit_Args; typedef struct _FindObjects_Args { CK_SESSION_HANDLE_32 session_handle; CK_ULONG_32 max_count; } FindObjects_Args; typedef struct _FindObjectsFinal_Args { CK_SESSION_HANDLE_32 session_handle; } FindObjectsFinal_Args; typedef struct _GenerateRandom_Args { CK_SESSION_HANDLE_32 session_handle; CK_ULONG_32 num_bytes; } GenerateRandom_Args; typedef struct _GenerateKey_Args { CK_SESSION_HANDLE_32 session_handle; CK_MECHANISM_TYPE_32 mech_type; CK_ULONG_32 mech_param_len; CK_ULONG_32 attribute_count; CK_ULONG_32 attribute_block_len; // mechanism parameter gets appended here // attributes get appended here // } GenerateKey_Args; typedef struct _GenKeyPair_Args { CK_SESSION_HANDLE_32 session_handle; CK_MECHANISM_TYPE_32 mech_type; CK_ULONG_32 mech_param_len; CK_ULONG_32 publ_key_attr_count; // # of attributes CK_ULONG_32 publ_key_tmpl_len; // overall template length CK_ULONG_32 priv_key_attr_count; // # of attributes CK_ULONG_32 priv_key_tmpl_len; // overall template length // the mechanism parameter is appended here // the public key template is appended here // the private key template is appended here // } GenKeyPair_Args; typedef struct _EncryptInit_Args { CK_SESSION_HANDLE_32 session_handle; CK_OBJECT_HANDLE_32 key; CK_MECHANISM_TYPE_32 mech_type; CK_ULONG_32 param_len; // length of parameter in bytes // mechanism parameter (if any) is appended here // } EncryptInit_Args; typedef struct _Encrypt_Args { CK_SESSION_HANDLE_32 session_handle; CK_ULONG_32 cleartext_len; CK_BBOOL length_only; // cleartext is appended here // } Encrypt_Args; typedef struct _EncryptUpdate_Args { CK_SESSION_HANDLE_32 session_handle; CK_ULONG_32 cleartext_len; CK_BBOOL length_only; // cleartext is appended here // } EncryptUpdate_Args; typedef struct _EncryptFinal_Args { CK_SESSION_HANDLE_32 session_handle; CK_BBOOL length_only; } EncryptFinal_Args; typedef struct _DecryptInit_Args { CK_SESSION_HANDLE_32 session_handle; CK_OBJECT_HANDLE_32 key; CK_MECHANISM_TYPE_32 mech_type; CK_ULONG_32 param_len; // length of parameter in bytes // mechanism parameter (if any) is appended here // } DecryptInit_Args; typedef struct _Decrypt_Args { CK_SESSION_HANDLE_32 session_handle; CK_ULONG_32 ciphertext_len; CK_BBOOL length_only; // ciphertext is appended here // } Decrypt_Args; typedef struct _DecryptUpdate_Args { CK_SESSION_HANDLE_32 session_handle; CK_ULONG_32 ciphertext_len; CK_BBOOL length_only; // ciphertext is appended here // } DecryptUpdate_Args; typedef struct _DecryptFinal_Args { CK_SESSION_HANDLE_32 session_handle; CK_BBOOL length_only; } DecryptFinal_Args; typedef struct _WrapKey_Args { CK_SESSION_HANDLE_32 session_handle; CK_MECHANISM_TYPE_32 mech_type; CK_ULONG_32 mech_param_len; CK_OBJECT_HANDLE_32 wrapping_key; CK_OBJECT_HANDLE_32 key; // key to be wrapped CK_BBOOL length_only; // mechanism parameter (if any) is appended here // } WrapKey_Args; typedef struct _UnWrapKey_Args { CK_SESSION_HANDLE_32 session_handle; CK_MECHANISM_TYPE_32 mech_type; CK_ULONG_32 mech_param_len; CK_OBJECT_HANDLE_32 unwrapping_key; CK_ULONG_32 wrapped_key_len; CK_ULONG_32 attribute_count; CK_ULONG_32 attribute_block_len; // mechanism parameter appended here (mech_param_len bytes ) // wrapped key appended here (wrapped_key_len bytes ) // attributes appended here (attribute_block_len bytes) // } UnWrapKey_Args; typedef struct _DeriveKey_Args { CK_SESSION_HANDLE_32 session_handle; CK_MECHANISM_TYPE_32 mech_type; CK_ULONG_32 mech_param_len; CK_OBJECT_HANDLE_32 base_key; CK_ULONG_32 attribute_count; CK_ULONG_32 attribute_block_len; // mechanism parameter and things it points to get appended here // attributes get appended here // } DeriveKey_Args; typedef struct _DigestInit_Args { CK_SESSION_HANDLE_32 session_handle; CK_MECHANISM_TYPE_32 mech_type; CK_ULONG_32 param_len; // length of parameter in bytes // mechanism parameter (if any) is appended here // } DigestInit_Args; typedef struct _Digest_Args { CK_SESSION_HANDLE_32 session_handle; CK_ULONG_32 data_len; CK_BBOOL length_only; // data to digest is appended here // } Digest_Args; typedef struct _DigestUpdate_Args { CK_SESSION_HANDLE_32 session_handle; CK_ULONG_32 data_len; // data to digest is appeneded here // } DigestUpdate_Args; typedef struct _DigestKey_Args { CK_SESSION_HANDLE_32 session_handle; CK_OBJECT_HANDLE_32 key; } DigestKey_Args; typedef struct _DigestFinal_Args { CK_SESSION_HANDLE_32 session_handle; CK_BBOOL length_only; } DigestFinal_Args; typedef struct _SignInit_Args { CK_SESSION_HANDLE_32 session_handle; CK_OBJECT_HANDLE_32 key; CK_MECHANISM_TYPE_32 mech_type; CK_ULONG_32 param_len; // length of parameter in bytes // mechanism parameter (if any) is appended here // } SignInit_Args; typedef struct _Sign_Args { CK_SESSION_HANDLE_32 session_handle; CK_ULONG_32 data_len; CK_BBOOL length_only; // data is appended here // } Sign_Args; typedef struct _SignUpdate_Args { CK_SESSION_HANDLE_32 session_handle; CK_ULONG_32 data_len; CK_BBOOL length_only; // data is appended here // } SignUpdate_Args; typedef struct _SignFinal_Args { CK_SESSION_HANDLE_32 session_handle; CK_BBOOL length_only; } SignFinal_Args; typedef struct _VerifyInit_Args { CK_SESSION_HANDLE_32 session_handle; CK_OBJECT_HANDLE_32 key; CK_MECHANISM_TYPE_32 mech_type; CK_ULONG_32 param_len; // length of parameter in bytes // mechanism parameter (if any) is appended here // } VerifyInit_Args; typedef struct _Verify_Args { CK_SESSION_HANDLE_32 session_handle; CK_ULONG_32 data_len; CK_ULONG_32 signature_len; // data is appended here // signature is appended here // } Verify_Args; typedef struct _VerifyUpdate_Args { CK_SESSION_HANDLE_32 session_handle; CK_ULONG_32 data_len; // data is appended here // } VerifyUpdate_Args; typedef struct _VerifyFinal_Args { CK_SESSION_HANDLE_32 session_handle; CK_ULONG_32 signature_len; // signature is appended here // } VerifyFinal_Args; typedef struct _SignRecoverInit_Args { CK_SESSION_HANDLE_32 session_handle; CK_OBJECT_HANDLE_32 key; CK_MECHANISM_TYPE_32 mech_type; CK_ULONG_32 param_len; // length of parameter in bytes // mechanism parameter (if any) is appended here // } SignRecoverInit_Args; typedef struct _SignRecover_Args { CK_SESSION_HANDLE_32 session_handle; CK_ULONG_32 data_len; CK_BBOOL length_only; // data is appended here // } SignRecover_Args; typedef struct _VerifyRecoverInit_Args { CK_SESSION_HANDLE_32 session_handle; CK_OBJECT_HANDLE_32 key; CK_MECHANISM_TYPE_32 mech_type; CK_ULONG_32 param_len; // length of parameter in bytes // mechanism parameter (if any) is appended here // } VerifyRecoverInit_Args; typedef struct _VerifyRecover_Args { CK_SESSION_HANDLE_32 session_handle; CK_BBOOL length_only; CK_ULONG_32 signature_len; // signature is appended here // } VerifyRecover_Args; typedef struct _GetOperationState_Args { CK_SESSION_HANDLE_32 session_handle; CK_BBOOL length_only; } GetOperationState_Args; typedef struct _SetOperationState_Args { CK_SESSION_HANDLE_32 session_handle; CK_OBJECT_HANDLE_32 encr_key; CK_OBJECT_HANDLE_32 auth_key; CK_ULONG_32 data_len; // operation state data is appended here // } SetOperationState_Args; typedef struct _InitToken_Args { CK_BYTE label[32]; // must be 32 bytes CK_ULONG_32 so_pin_len; // SO PIN data is appended here // } InitToken_Args; #else // !PKCS64 // WJH - here is the original content . . . //------------------------------------------------------------------- // typedef struct _GetMechList_Args { CK_ULONG list_length; CK_BBOOL length_only; } GetMechList_Args; // C_GetMechanismList reply: // // +-----------+------------------------------------+ // | CK_ULONG | List of CK_MECHANISM_TYPE elements | // +-----------+------------------------------------+ // typedef struct _GetMechInfo_Args { CK_MECHANISM_TYPE mech_type; } GetMechInfo_Args; typedef struct _InitPIN_Args { CK_SESSION_HANDLE session_handle; CK_BYTE pin[MAX_PIN_LEN]; CK_ULONG pin_len; } InitPIN_Args; typedef struct _SetPIN_Args { CK_SESSION_HANDLE session_handle; CK_BYTE old_pin[MAX_PIN_LEN]; CK_ULONG old_pin_len; CK_BYTE new_pin[MAX_PIN_LEN]; CK_ULONG new_pin_len; } SetPIN_Args; typedef struct _OpenSession_Args { CK_SLOT_ID slot_id; CK_FLAGS flags; CK_ULONG application_ptr; // not used CK_ULONG notify; // not used //CK_VOID_PTR application_ptr; // not used //CK_NOTIFY notify; // not used CK_BBOOL req_proc_handle; } OpenSession_Args; typedef struct _CloseSession_Args { CK_SESSION_HANDLE session_handle; } CloseSession_Args; typedef struct _GetSessionInfo_Args { CK_SESSION_HANDLE session_handle; } GetSessionInfo_Args; typedef struct _Login_Args { CK_SESSION_HANDLE session_handle; CK_USER_TYPE user_type; CK_BYTE pin[MAX_PIN_LEN]; CK_ULONG pin_len; } Login_Args; typedef struct _Logout_Args { CK_SESSION_HANDLE session_handle; } Logout_Args; // CreateObject_Args is a bit different. The attributes themselves // are passed as a datablock immediately following this structure // typedef struct _CreateObject_Args { CK_SESSION_HANDLE session_handle; CK_ULONG attribute_count; CK_ULONG attribute_block_len; // attributes/template gets appended here // } CreateObject_Args; typedef struct _CopyObject_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE object_handle; CK_ULONG attribute_count; CK_ULONG attribute_block_len; // attributes/template gets appended here // } CopyObject_Args; typedef struct _DestroyObject_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE object_handle; } DestroyObject_Args; typedef struct _GetObjectSize_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE object_handle; } GetObjectSize_Args; typedef struct _GetAttributeValue_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE object_handle; CK_ULONG attribute_count; CK_ULONG attribute_block_len; CK_BBOOL size_only; // list of attribute types (CK_ATTRIBUTE_TYPE) gets appended here. // } GetAttributeValue_Args; typedef struct _SetAttributeValue_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE object_handle; CK_ULONG attribute_count; CK_ULONG attribute_block_len; // attribute template gets appended here // } SetAttributeValue_Args; typedef struct _FindObjectsInit_Args { CK_SESSION_HANDLE session_handle; CK_ULONG attribute_count; CK_ULONG attribute_block_len; // attribute template gets appended here // } FindObjectsInit_Args; typedef struct _FindObjects_Args { CK_SESSION_HANDLE session_handle; CK_ULONG max_count; } FindObjects_Args; typedef struct _FindObjectsFinal_Args { CK_SESSION_HANDLE session_handle; } FindObjectsFinal_Args; typedef struct _GenerateRandom_Args { CK_SESSION_HANDLE session_handle; CK_ULONG num_bytes; } GenerateRandom_Args; typedef struct _GenerateKey_Args { CK_SESSION_HANDLE session_handle; CK_MECHANISM_TYPE mech_type; CK_ULONG mech_param_len; CK_ULONG attribute_count; CK_ULONG attribute_block_len; // mechanism parameter gets appended here // attributes get appended here // } GenerateKey_Args; typedef struct _GenKeyPair_Args { CK_SESSION_HANDLE session_handle; CK_MECHANISM_TYPE mech_type; CK_ULONG mech_param_len; CK_ULONG publ_key_attr_count; // # of attributes CK_ULONG publ_key_tmpl_len; // overall template length CK_ULONG priv_key_attr_count; // # of attributes CK_ULONG priv_key_tmpl_len; // overall template length // the mechanism parameter is appended here // the public key template is appended here // the private key template is appended here // } GenKeyPair_Args; typedef struct _EncryptInit_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE key; CK_MECHANISM_TYPE mech_type; CK_ULONG param_len; // length of parameter in bytes // mechanism parameter (if any) is appended here // } EncryptInit_Args; typedef struct _Encrypt_Args { CK_SESSION_HANDLE session_handle; CK_ULONG cleartext_len; CK_BBOOL length_only; // cleartext is appended here // } Encrypt_Args; typedef struct _EncryptUpdate_Args { CK_SESSION_HANDLE session_handle; CK_ULONG cleartext_len; CK_BBOOL length_only; // cleartext is appended here // } EncryptUpdate_Args; typedef struct _EncryptFinal_Args { CK_SESSION_HANDLE session_handle; CK_BBOOL length_only; } EncryptFinal_Args; typedef struct _DecryptInit_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE key; CK_MECHANISM_TYPE mech_type; CK_ULONG param_len; // length of parameter in bytes // mechanism parameter (if any) is appended here // } DecryptInit_Args; typedef struct _Decrypt_Args { CK_SESSION_HANDLE session_handle; CK_ULONG ciphertext_len; CK_BBOOL length_only; // ciphertext is appended here // } Decrypt_Args; typedef struct _DecryptUpdate_Args { CK_SESSION_HANDLE session_handle; CK_ULONG ciphertext_len; CK_BBOOL length_only; // ciphertext is appended here // } DecryptUpdate_Args; typedef struct _DecryptFinal_Args { CK_SESSION_HANDLE session_handle; CK_BBOOL length_only; } DecryptFinal_Args; typedef struct _WrapKey_Args { CK_SESSION_HANDLE session_handle; CK_MECHANISM_TYPE mech_type; CK_ULONG mech_param_len; CK_OBJECT_HANDLE wrapping_key; CK_OBJECT_HANDLE key; // key to be wrapped CK_BBOOL length_only; // mechanism parameter (if any) is appended here // } WrapKey_Args; typedef struct _UnWrapKey_Args { CK_SESSION_HANDLE session_handle; CK_MECHANISM_TYPE mech_type; CK_ULONG mech_param_len; CK_OBJECT_HANDLE unwrapping_key; CK_ULONG wrapped_key_len; CK_ULONG attribute_count; CK_ULONG attribute_block_len; // mechanism parameter appended here (mech_param_len bytes ) // wrapped key appended here (wrapped_key_len bytes ) // attributes appended here (attribute_block_len bytes) // } UnWrapKey_Args; typedef struct _DeriveKey_Args { CK_SESSION_HANDLE session_handle; CK_MECHANISM_TYPE mech_type; CK_ULONG mech_param_len; CK_OBJECT_HANDLE base_key; CK_ULONG attribute_count; CK_ULONG attribute_block_len; // mechanism parameter and things it points to get appended here // attributes get appended here // } DeriveKey_Args; typedef struct _DigestInit_Args { CK_SESSION_HANDLE session_handle; CK_MECHANISM_TYPE mech_type; CK_ULONG param_len; // length of parameter in bytes // mechanism parameter (if any) is appended here // } DigestInit_Args; typedef struct _Digest_Args { CK_SESSION_HANDLE session_handle; CK_ULONG data_len; CK_BBOOL length_only; // data to digest is appended here // } Digest_Args; typedef struct _DigestUpdate_Args { CK_SESSION_HANDLE session_handle; CK_ULONG data_len; // data to digest is appeneded here // } DigestUpdate_Args; typedef struct _DigestKey_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE key; } DigestKey_Args; typedef struct _DigestFinal_Args { CK_SESSION_HANDLE session_handle; CK_BBOOL length_only; } DigestFinal_Args; typedef struct _SignInit_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE key; CK_MECHANISM_TYPE mech_type; CK_ULONG param_len; // length of parameter in bytes // mechanism parameter (if any) is appended here // } SignInit_Args; typedef struct _Sign_Args { CK_SESSION_HANDLE session_handle; CK_ULONG data_len; CK_BBOOL length_only; // data is appended here // } Sign_Args; typedef struct _SignUpdate_Args { CK_SESSION_HANDLE session_handle; CK_ULONG data_len; CK_BBOOL length_only; // data is appended here // } SignUpdate_Args; typedef struct _SignFinal_Args { CK_SESSION_HANDLE session_handle; CK_BBOOL length_only; } SignFinal_Args; typedef struct _VerifyInit_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE key; CK_MECHANISM_TYPE mech_type; CK_ULONG param_len; // length of parameter in bytes // mechanism parameter (if any) is appended here // } VerifyInit_Args; typedef struct _Verify_Args { CK_SESSION_HANDLE session_handle; CK_ULONG data_len; CK_ULONG signature_len; // data is appended here // signature is appended here // } Verify_Args; typedef struct _VerifyUpdate_Args { CK_SESSION_HANDLE session_handle; CK_ULONG data_len; // data is appended here // } VerifyUpdate_Args; typedef struct _VerifyFinal_Args { CK_SESSION_HANDLE session_handle; CK_ULONG signature_len; // signature is appended here // } VerifyFinal_Args; typedef struct _SignRecoverInit_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE key; CK_MECHANISM_TYPE mech_type; CK_ULONG param_len; // length of parameter in bytes // mechanism parameter (if any) is appended here // } SignRecoverInit_Args; typedef struct _SignRecover_Args { CK_SESSION_HANDLE session_handle; CK_ULONG data_len; CK_BBOOL length_only; // data is appended here // } SignRecover_Args; typedef struct _VerifyRecoverInit_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE key; CK_MECHANISM_TYPE mech_type; CK_ULONG param_len; // length of parameter in bytes // mechanism parameter (if any) is appended here // } VerifyRecoverInit_Args; typedef struct _VerifyRecover_Args { CK_SESSION_HANDLE session_handle; CK_BBOOL length_only; CK_ULONG signature_len; // signature is appended here // } VerifyRecover_Args; typedef struct _GetOperationState_Args { CK_SESSION_HANDLE session_handle; CK_BBOOL length_only; } GetOperationState_Args; typedef struct _SetOperationState_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE encr_key; CK_OBJECT_HANDLE auth_key; CK_ULONG data_len; // operation state data is appended here // } SetOperationState_Args; typedef struct _InitToken_Args { CK_BYTE label[32]; // must be 32 bytes CK_ULONG so_pin_len; // SO PIN data is appended here // } InitToken_Args; #endif // PKCS64 #if (LEEDS_BUILD) #pragma pack() #pragma options align=full #endif #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/Makefile.am0000640000175000017500000000075711327631345017471 0ustar jfjfif S390 if DEFAULT_DLL DEFAULT = ica_s390_stdll endif else if DEFAULT_DLL DEFAULT = soft_stdll endif endif if ICA ICA_DLL = ica_stdll endif if TPM TPM_DLL = tpm_stdll endif if ICC LEEDS_DLL= methods leeds_stdll endif if AEP AEP_DLL = aep_stdll endif if BCOM BCOM_DLL = bcom_stdll endif if CR CR_DLL = cr_stdll endif if CCA CCA_DLL = cca_stdll endif if LIBRARY API = api endif SUBDIRS = $(API) $(DEFAULT) $(ICA_DLL) $(TPM_DLL) $(LEEDS_DLL) $(AEP_DLL) $(BCOM_DLL) $(CR_DLL) $(CCA_DLL) opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/soft_stdll/0000751000175000017500000000000011327631345017601 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/lib/pkcs11/soft_stdll/soft_specific.c0000640000175000017500000014612511327631345022576 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ /*************************************************************************** Change Log ========== 4/25/03 Kapil Sood (kapil@corrent.com) Added DH key pair generation and DH shared key derivation functions. ****************************************************************************/ #include #include // for memcmp() et al #include #include #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "args.h" #include "errno.h" #include "tok_specific.h" #include "tok_struct.h" #include #include #include #include #include #include #include #include typedef unsigned int uint32_t; pthread_mutex_t rngmtx = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t nextmutex = PTHREAD_MUTEX_INITIALIZER; unsigned int rnginitialized=0; CK_CHAR manuf[] = "IBM Corp."; CK_CHAR model[] = "IBM SoftTok "; CK_CHAR descr[] = "IBM PKCS#11 Soft token"; CK_CHAR label[] = "IBM OS PKCS#11 "; CK_RV token_specific_session(CK_SLOT_ID slotid) { return CKR_OK; } CK_RV token_rng(CK_BYTE *output, CK_ULONG bytes) { #if 0 int bytes2 = 384; char state[bytes2]; pthread_mutex_lock(&rngmtx); if (!rnginitialized) { RAND_seed(&state, bytes2); rnginitialized=1; } RAND_pseudo_bytes(output, bytes); pthread_mutex_unlock(&rngmtx); #else int ranfd; int rlen; unsigned int totallen=0; ranfd = open("/dev/urandom",O_RDONLY); if (ranfd >= 0 ){ do { rlen = read(ranfd,output+totallen,bytes-totallen); totallen += rlen; } while( totallen < bytes); return CKR_OK; } else { return CKR_FUNCTION_FAILED; } #endif } // convert pkcs slot number to local representation int tok_slot2local(CK_SLOT_ID snum) { return 1; } CK_RV token_specific_init(char * Correlator,CK_SLOT_ID SlotNumber) { return CKR_OK; } CK_RV token_specific_final() { return CKR_OK; } CK_RV token_specific_des_key_gen(CK_BYTE *des_key,CK_ULONG len) { // Nothing different to do for DES or TDES here as this is just // random data... Validation handles the rest rng_generate(des_key,len); // we really need to validate the key for parity etc... // we should do that here... The caller validates the single des keys // against the known and suspected poor keys.. return CKR_OK; } CK_RV token_specific_des_ecb(CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_BYTE encrypt) { CK_ULONG rc; des_key_schedule des_key2; const_des_cblock key_val_SSL, in_key_data; des_cblock out_key_data; unsigned int i,j; // Create the key schedule memcpy(&key_val_SSL, key_value, 8); des_set_key_unchecked(&key_val_SSL, des_key2); // the des decrypt will only fail if the data length is not evenly divisible // by 8 if (in_data_len % 8 ){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } // Both the encrypt and the decrypt are done 8 bytes at a time if (encrypt) { for (i=0; itemplate, CKA_MODULUS, &modulus ); rc &= template_attribute_find( key_obj->template, CKA_PUBLIC_EXPONENT, &pub_exp ); if (rc == FALSE) { return NULL; } // Create an RSA key struct to return rsa = RSA_new(); if (rsa == NULL) return NULL; RSA_blinding_off(rsa); // Create and init BIGNUM structs to stick in the RSA struct bn_mod = BN_new(); bn_exp = BN_new(); if (bn_exp == NULL || bn_mod == NULL) { if (bn_mod) free(bn_mod); if (bn_exp) free(bn_exp); RSA_free(rsa); return NULL; } // Convert from strings to BIGNUMs and stick them in the RSA struct BN_bin2bn((unsigned char *)modulus->pValue, modulus->ulValueLen, bn_mod); rsa->n = bn_mod; BN_bin2bn((unsigned char *)pub_exp->pValue, pub_exp->ulValueLen, bn_exp); rsa->e = bn_exp; return (void *)rsa; } void * rsa_convert_private_key(OBJECT *key_obj) { CK_ATTRIBUTE * modulus = NULL; CK_ATTRIBUTE * priv_exp = NULL; CK_ATTRIBUTE * prime1 = NULL; CK_ATTRIBUTE * prime2 = NULL; CK_ATTRIBUTE * exp1 = NULL; CK_ATTRIBUTE * exp2 = NULL; CK_ATTRIBUTE * coeff = NULL; CK_BBOOL rc; RSA *rsa; BIGNUM *bn_mod, *bn_priv_exp, *bn_p1, *bn_p2, *bn_e1, *bn_e2, *bn_cf; rc = template_attribute_find( key_obj->template, CKA_MODULUS, &modulus ); rc &= template_attribute_find( key_obj->template, CKA_PRIVATE_EXPONENT, &priv_exp ); rc &= template_attribute_find( key_obj->template, CKA_PRIME_1, &prime1 ); rc &= template_attribute_find( key_obj->template, CKA_PRIME_2, &prime2 ); rc &= template_attribute_find( key_obj->template, CKA_EXPONENT_1, &exp1 ); rc &= template_attribute_find( key_obj->template, CKA_EXPONENT_2, &exp2 ); rc &= template_attribute_find( key_obj->template, CKA_COEFFICIENT, &coeff ); if ( !prime2 && !modulus ){ return NULL; } // Create and init all the RSA and BIGNUM structs we need. rsa = RSA_new(); if (rsa == NULL) return NULL; RSA_blinding_off(rsa); bn_mod = BN_new(); bn_priv_exp = BN_new(); bn_p1 = BN_new(); bn_p2 = BN_new(); bn_e1 = BN_new(); bn_e2 = BN_new(); bn_cf = BN_new(); if ((bn_cf == NULL) || (bn_e2 == NULL) || (bn_e1 == NULL) || (bn_p2 == NULL) || (bn_p1 == NULL) || (bn_priv_exp == NULL) || (bn_mod == NULL)) { if (rsa) RSA_free(rsa); if (bn_mod) BN_free(bn_mod); if (bn_priv_exp) BN_free(bn_priv_exp); if (bn_p1) BN_free(bn_p1); if (bn_p2) BN_free(bn_p2); if (bn_e1) BN_free(bn_e1); if (bn_e2) BN_free(bn_e2); if (bn_cf) BN_free(bn_cf); return NULL; } // CRT key? if ( prime1){ if (!prime2 || !exp1 ||!exp2 || !coeff) { return NULL; } // Even though this is CRT key, OpenSSL requires the // modulus and exponents filled in or encrypt and decrypt will // not work BN_bin2bn((unsigned char *)modulus->pValue, modulus->ulValueLen, bn_mod); rsa->n = bn_mod; BN_bin2bn((unsigned char *)priv_exp->pValue, priv_exp->ulValueLen, bn_priv_exp); rsa->d = bn_priv_exp; BN_bin2bn((unsigned char *)prime1->pValue, prime1->ulValueLen, bn_p1); rsa->p = bn_p1; BN_bin2bn((unsigned char *)prime2->pValue, prime2->ulValueLen, bn_p2); rsa->q = bn_p2; BN_bin2bn((unsigned char *)exp1->pValue, exp1->ulValueLen, bn_e1); rsa->dmp1 = bn_e1; BN_bin2bn((unsigned char *)exp2->pValue, exp2->ulValueLen, bn_e2); rsa->dmq1 = bn_e2; BN_bin2bn((unsigned char *)coeff->pValue, coeff->ulValueLen, bn_cf); rsa->iqmp = bn_cf; return rsa; } else { // must be a non-CRT key if (!priv_exp) { return NULL; } BN_bin2bn((unsigned char *)modulus->pValue, modulus->ulValueLen, bn_mod); rsa->n = bn_mod; BN_bin2bn((unsigned char *)priv_exp->pValue, priv_exp->ulValueLen, bn_priv_exp); rsa->d = bn_priv_exp; } return (void *)rsa; } #define RNG_BUF_SIZE 100 // This function is only required if public key cryptography // has been selected in your variant set up. // Set a mutex in this function and get a cache; // using the ICA device to get random numbers a byte at a // time is VERY slow.. Keygen is gated by this function. unsigned char nextRandom (void) { static unsigned char buffer[RNG_BUF_SIZE]; unsigned char byte; static int used = (RNG_BUF_SIZE); // protected access by the mutex pthread_mutex_lock(&nextmutex); if (used >= RNG_BUF_SIZE){ rng_generate(buffer,sizeof(buffer)); used = 0; } byte = buffer[used++]; pthread_mutex_unlock(&nextmutex); return((unsigned char)byte); } CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) { CK_ATTRIBUTE * publ_exp = NULL; CK_ATTRIBUTE * attr = NULL; CK_ULONG mod_bits; CK_BBOOL flag; CK_RV rc; CK_ULONG BNLength; RSA *rsa; BIGNUM *bignum; CK_BYTE *ssl_ptr; void *e = NULL; flag = template_attribute_find( publ_tmpl, CKA_MODULUS_BITS, &attr ); if (!flag){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; // should never happen } mod_bits = *(CK_ULONG *)attr->pValue; if (mod_bits < 512 || mod_bits > 4096) { st_err_log(19, __FILE__, __LINE__); return CKR_KEY_SIZE_RANGE; } flag = template_attribute_find( publ_tmpl, CKA_PUBLIC_EXPONENT, &publ_exp ); if (!flag){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } // Sanity check of public exponent length. if (publ_exp->ulValueLen > sizeof(unsigned long)) { st_err_log(19, __FILE__, __LINE__); return CKR_KEY_SIZE_RANGE; } e = calloc(1, sizeof(unsigned long)); if (e == NULL) { st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } #ifndef __BYTE_ORDER #error "Architecture endianness is not defined." #endif #if __BYTE_ORDER == __LITTLE_ENDIAN memcpy(e, publ_exp->pValue, publ_exp->ulValueLen); #else memcpy(e + (sizeof(unsigned long) - publ_exp->ulValueLen), publ_exp->pValue, publ_exp->ulValueLen); #endif rsa = RSA_generate_key(mod_bits, *(unsigned long *)e, NULL, NULL); free(e); e = NULL; if (rsa == NULL) { st_err_log(4, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } RSA_blinding_off(rsa); // Now fill in the objects.. // // modulus: n // bignum = rsa->n; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_MODULUS, ssl_ptr, BNLength, &attr ); // in bytes if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( publ_tmpl, attr ); free(ssl_ptr); // Public Exponent bignum = rsa->e; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_PUBLIC_EXPONENT, ssl_ptr, BNLength, &attr ); // in bytes if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( publ_tmpl, attr ); free(ssl_ptr); // local = TRUE // flag = TRUE; rc = build_attribute( CKA_LOCAL, &flag, sizeof(CK_BBOOL), &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( publ_tmpl, attr ); // // now, do the private key // // Cheat here and put the whole original key into the CKA_VALUE... remember // to force the system to not return this for RSA keys.. // Add the modulus to the private key information bignum = rsa->n; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_MODULUS, ssl_ptr, BNLength ,&attr ); // in bytes if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); free(ssl_ptr); // Private Exponent bignum = rsa->d; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc( BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_PRIVATE_EXPONENT, ssl_ptr, BNLength, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); free(ssl_ptr); // prime #1: p // bignum = rsa->p; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_PRIME_1, ssl_ptr, BNLength, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); free(ssl_ptr); // prime #2: q // bignum = rsa->q; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_PRIME_2, ssl_ptr, BNLength, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); free(ssl_ptr); // exponent 1: d mod(p-1) // bignum = rsa->dmp1; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_EXPONENT_1, ssl_ptr, BNLength, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); free(ssl_ptr); // exponent 2: d mod(q-1) // bignum = rsa->dmq1; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_EXPONENT_2, ssl_ptr, BNLength, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); free(ssl_ptr); // CRT coefficient: q_inverse mod(p) // bignum = rsa->iqmp; BNLength = BN_num_bytes(bignum); ssl_ptr = malloc(BNLength); if (ssl_ptr == NULL) { st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } BNLength = BN_bn2bin(bignum, ssl_ptr); rc = build_attribute( CKA_COEFFICIENT, ssl_ptr, BNLength, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); free(ssl_ptr); flag = TRUE; rc = build_attribute( CKA_LOCAL, &flag, sizeof(CK_BBOOL), &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto done; } template_update_attribute( priv_tmpl, attr ); done: RSA_free(rsa); return rc; } CK_RV token_specific_rsa_generate_keypair( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ) { CK_RV rc; rc = os_specific_rsa_keygen(publ_tmpl,priv_tmpl); if (rc != CKR_OK) st_err_log(91, __FILE__, __LINE__); return rc; } CK_RV token_specific_rsa_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, OBJECT * key_obj ) { CK_RV rc; RSA *rsa; // Convert the local representation to an RSA representation rsa = (RSA *)rsa_convert_public_key(key_obj); if (rsa==NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } // Do an RSA public encryption rc = RSA_public_encrypt(in_data_len, in_data, out_data, rsa, RSA_NO_PADDING); if (rc != 0) { rc = CKR_OK; } else { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; } // Clean up after ourselves RSA_free(rsa); done: return rc; } CK_RV token_specific_rsa_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, OBJECT * key_obj ) { CK_RV rc; RSA *rsa; // Convert the local key representation to an RSA key representaion rsa = (RSA *)rsa_convert_private_key(key_obj); if (rsa == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } // Do the private decryption rc = RSA_private_decrypt(in_data_len, in_data, out_data, rsa, RSA_NO_PADDING); if (rc != 0) { rc = CKR_OK; } else { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; } // Clean up RSA_free(rsa); done: return rc; } CK_RV token_specific_aes_key_gen( CK_BYTE *key, CK_ULONG len ) { return rng_generate(key, len); } CK_RV token_specific_aes_ecb( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_ULONG key_len, CK_BYTE encrypt) { AES_KEY ssl_aes_key; unsigned int i; /* There's a previous check that in_data_len % AES_BLOCK_SIZE == 0, * so this is fine */ CK_ULONG loops = (CK_ULONG)(in_data_len/AES_BLOCK_SIZE); memset( &ssl_aes_key, 0, sizeof(AES_KEY)); // AES_ecb_encrypt encrypts only a single block, so we have to break up the // input data here if (encrypt) { AES_set_encrypt_key((unsigned char *)key_value, (key_len*8), &ssl_aes_key); for( i=0; iulValueLen > 256) || (prime_attr->ulValueLen < 64)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } dh = DH_new() ; if (dh == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Create and init BIGNUM structs to stick in the DH struct bn_p = BN_new(); bn_g = BN_new(); if (bn_g == NULL || bn_p == NULL) { if (bn_g) BN_free(bn_g); if (bn_p) BN_free(bn_p); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // Convert from strings to BIGNUMs and stick them in the DH struct BN_bin2bn((unsigned char *)prime_attr->pValue, prime_attr->ulValueLen, bn_p); dh->p = bn_p; BN_bin2bn((unsigned char *)base_attr->pValue, base_attr->ulValueLen, bn_g); dh->g = bn_g; // Generate the DH Key if (!DH_generate_key(dh)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Extract the public and private key components from the DH struct, // and insert them in the publ_tmpl and priv_tmpl // // pub_key // //temp_bn = BN_new(); temp_bn = dh->pub_key; temp_bn_len = BN_num_bytes(temp_bn); temp_byte = malloc(temp_bn_len); temp_bn_len = BN_bn2bin(temp_bn, temp_byte); rc = build_attribute( CKA_VALUE, temp_byte, temp_bn_len, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( publ_tmpl, temp_attr ); free(temp_byte); // // priv_key // //temp_bn = BN_new(); temp_bn = dh->priv_key; temp_bn_len = BN_num_bytes(temp_bn); temp_byte = malloc(temp_bn_len); temp_bn_len = BN_bn2bin(temp_bn, temp_byte); rc = build_attribute( CKA_VALUE, temp_byte, temp_bn_len, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); free(temp_byte); // Update CKA_VALUE_BITS attribute in the private key value_bits_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); value_bits_attr->type = CKA_VALUE_BITS; value_bits_attr->ulValueLen = sizeof(CK_ULONG); value_bits_attr->pValue = (CK_BYTE *)value_bits_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_bits_attr->pValue = 8*temp_bn_len; template_update_attribute( priv_tmpl, value_bits_attr ); // Add prime and base to the private key template rc = build_attribute( CKA_PRIME,(unsigned char *)prime_attr->pValue, prime_attr->ulValueLen, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); rc = build_attribute( CKA_BASE,(unsigned char *)base_attr->pValue, base_attr->ulValueLen, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); // Cleanup DH key DH_free(dh) ; return CKR_OK ; } /* end token_specific_dh_key_pair_gen() */ /* End code contributed by Corrent corp. */ MECH_LIST_ELEMENT mech_list[] = { { CKM_RSA_PKCS_KEY_PAIR_GEN, {512, 4096, CKF_HW | CKF_GENERATE_KEY_PAIR} }, #if !(NODSA) { CKM_DSA_KEY_PAIR_GEN, {512, 1024, CKF_HW | CKF_GENERATE_KEY_PAIR} }, #endif { CKM_DES_KEY_GEN, {8, 8, CKF_HW | CKF_GENERATE} }, { CKM_DES3_KEY_GEN, {24, 24, CKF_HW | CKF_GENERATE} }, #if !(NOCDMF) { CKM_CDMF_KEY_GEN, {0, 0, CKF_HW | CKF_GENERATE} }, #endif { CKM_RSA_PKCS, {512, 4096, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP | CKF_SIGN | CKF_VERIFY | CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER} }, #if !(NOX509) { CKM_RSA_X_509, {512, 4096, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP | CKF_SIGN | CKF_VERIFY | CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER} }, #endif #if !(NOMD2) { CKM_MD2_RSA_PKCS, {512, 4096, CKF_HW | CKF_SIGN | CKF_VERIFY} }, #endif #if !(NOMD5) { CKM_MD5_RSA_PKCS, {512, 4096, CKF_HW | CKF_SIGN | CKF_VERIFY} }, #endif #if !(NOSHA1) { CKM_SHA1_RSA_PKCS, {512, 4096, CKF_HW | CKF_SIGN | CKF_VERIFY} }, #endif #if !(NODSA) { CKM_DSA, {512, 1024, CKF_HW | CKF_SIGN | CKF_VERIFY} }, #endif /* Begin code contributed by Corrent corp. */ #if !(NODH) { CKM_DH_PKCS_DERIVE, {512, 2048, CKF_HW | CKF_DERIVE} }, { CKM_DH_PKCS_KEY_PAIR_GEN, {512, 2048, CKF_HW | CKF_GENERATE_KEY_PAIR} }, #endif /* End code contributed by Corrent corp. */ { CKM_DES_ECB, {8, 8, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP} }, { CKM_DES_CBC, {8, 8, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP} }, { CKM_DES_CBC_PAD, {8, 8, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP} }, #if !(NOCDMF) { CKM_CDMF_ECB, {0, 0, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP} }, { CKM_CDMF_CBC, {0, 0, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP} }, #endif { CKM_DES3_ECB, {24, 24, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP} }, { CKM_DES3_CBC, {24, 24, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP} }, { CKM_DES3_CBC_PAD, {24, 24, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP} }, #if !(NOSHA1) { CKM_SHA_1, {0, 0, CKF_HW | CKF_DIGEST} }, { CKM_SHA_1_HMAC, {0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY} }, { CKM_SHA_1_HMAC_GENERAL, {0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY} }, { CKM_SHA256, {0, 0, CKF_HW | CKF_DIGEST} }, { CKM_SHA256_HMAC, {0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY} }, { CKM_SHA256_HMAC_GENERAL, {0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY} }, #endif #if !(NOMD2) { CKM_MD2, {0, 0, CKF_HW | CKF_DIGEST} }, { CKM_MD2_HMAC, {0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY} }, { CKM_MD2_HMAC_GENERAL, {0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY} }, #endif #if !(NOMD5) { CKM_MD5, {0, 0, CKF_HW | CKF_DIGEST} }, { CKM_MD5_HMAC, {0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY} }, { CKM_MD5_HMAC_GENERAL, {0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY} }, #endif { CKM_SSL3_PRE_MASTER_KEY_GEN, {48, 48, CKF_HW | CKF_GENERATE} }, { CKM_SSL3_MASTER_KEY_DERIVE, {48, 48, CKF_HW | CKF_DERIVE} }, { CKM_SSL3_KEY_AND_MAC_DERIVE, {48, 48, CKF_HW | CKF_DERIVE} }, { CKM_SSL3_MD5_MAC, {384, 384, CKF_HW | CKF_SIGN | CKF_VERIFY} }, { CKM_SSL3_SHA1_MAC, {384, 384, CKF_HW | CKF_SIGN | CKF_VERIFY} }, #if !(NOAES) { CKM_AES_KEY_GEN, {16, 32, CKF_HW} }, { CKM_AES_ECB, {16, 32, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP} }, { CKM_AES_CBC, {16, 32, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP} }, { CKM_AES_MAC, {16, 32, CKF_HW | CKF_SIGN | CKF_VERIFY} }, { CKM_AES_MAC_GENERAL, {16, 32, CKF_HW | CKF_SIGN | CKF_VERIFY} }, { CKM_AES_CBC_PAD, {16, 32, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP} }, #endif #if !(NORIPE) { CKM_RIPEMD128, {0, 0, CKF_HW | CKF_DIGEST} }, { CKM_RIPEMD128_HMAC, {0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY} }, { CKM_RIPEMD128_HMAC_GENERAL, {0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY} }, { CKM_RIPEMD160, {0, 0, CKF_HW | CKF_DIGEST} }, { CKM_RIPEMD160_HMAC, {0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY} }, { CKM_RIPEMD160_HMAC_GENERAL, {0, 0, CKF_HW | CKF_SIGN | CKF_VERIFY} }, #endif }; CK_ULONG mech_list_len = (sizeof(mech_list) / sizeof(MECH_LIST_ELEMENT)); CK_RV token_specific_get_mechanism_list(CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount) { int rc; /* common/mech_list.c */ rc = ock_generic_get_mechanism_list(pMechanismList, pulCount); return rc; } CK_RV token_specific_get_mechanism_info(CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo) { int rc; /* common/mech_list.c */ rc = ock_generic_get_mechanism_info(type, pInfo); return rc; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/soft_stdll/tok_struct.h.in0000640000175000017500000004154211327631345022566 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2002 */ /*************************************************************************** Change Log ========== 4/25/03 Kapil Sood (kapil@corrent.com) Added DH key pair generation and DH shared key derivation functions. ****************************************************************************/ // SAB FIXME need to figure out a better way... // // to get the variant dependency out #ifndef __TOK_STRUCT_H #define __TOK_STRUCT_H #include #include "tok_spec_struct.h" // #define PK_LITE_DIR "/etc/pkcs11/lite" // // #define PK_DIR PK_LITE_DIR // #define SUB_DIR "lite" // // // #define DBGTAG "ICA_STDLL_Debug" // // // token_spec_t token_specific = { "@DB_PATH@/swtok", "swtok", "SW_STDLL_Debug", &token_specific_init, &tok_slot2local, &token_rng, &token_specific_session, &token_specific_final, &token_specific_des_key_gen, &token_specific_des_ecb, &token_specific_des_cbc, &token_specific_tdes_ecb, &token_specific_tdes_cbc, &token_specific_rsa_decrypt, &token_specific_rsa_encrypt, &token_specific_rsa_generate_keypair, /* Begin code contributed by Corrent corp. */ // DH &token_specific_dh_pkcs_derive, &token_specific_dh_pkcs_key_pair_gen, /* End code contributed by Corrent corp. */ // SHA-1 NULL, // SHA-1 in the soft token is integrated already, as token NULL, // specific SHA-1 is new. As a TODO, the soft SHA-1 routines NULL, // should probably move to functions plugged in here. /* SHA-256 */ NULL, NULL, NULL, /* SHA-384 */ NULL, NULL, NULL, /* SHA-512 */ NULL, NULL, NULL, // AES &token_specific_aes_key_gen, &token_specific_aes_ecb, &token_specific_aes_cbc, &token_specific_get_mechanism_list, &token_specific_get_mechanism_info }; #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/soft_stdll/Makefile.am0000640000175000017500000000407211327631345021640 0ustar jfjfnobase_lib_LTLIBRARIES = opencryptoki/stdll/libpkcs11_sw.la opencryptoki_stdll_libpkcs11_sw_la_LDFLAGS = -shared -Wl,-Bsymbolic \ -lc -lpthread -lcrypto # Not all versions of automake observe libname_CFLAGS opencryptoki_stdll_libpkcs11_sw_la_CFLAGS = -DSPINXPL -DDEV -D_THREAD_SAFE \ -DSHALLOW=0 -DSWTOK=1 -DLITE=0 \ -DNOCDMF -DNOMD2 -DNODSA -DNORIPE \ -DDEBUGON -fPIC \ -I/usr/include -I. \ -I../../../include/pkcs11/stdll \ -I../../../include/pkcs11 \ -I../common -DSTDLL_NAME=\"swtok\" # Not all versions of automake observe libname_CFLAGS AM_CFLAGS = -DSPINXPL -DDEV -D_THREAD_SAFE -DSHALLOW=0 \ -DSWTOK=1 -DLITE=0 -DNOCDMF -DNOMD2 -DNODSA \ -DDEBUGON -fPIC -I/usr/include -I. \ -I../../../include/pkcs11/stdll \ -I../../../include/pkcs11 -I../common opencryptoki_stdll_libpkcs11_sw_la_SOURCES = ../common/asn1.c \ ../common/cert.c \ ../common/hwf_obj.c \ ../common/dp_obj.c \ ../common/data_obj.c \ ../common/decr_mgr.c \ ../common/dig_mgr.c \ ../common/encr_mgr.c \ ../common/globals.c \ ../common/loadsave.c \ ../common/key.c \ ../common/key_mgr.c \ ../common/mech_aes.c \ ../common/mech_des.c \ ../common/mech_des3.c \ ../common/mech_dh.c \ ../common/mech_md5.c \ ../common/mech_md2.c \ ../common/mech_rng.c \ ../common/mech_rsa.c \ ../common/mech_sha.c \ ../common/mech_ssl3.c \ ../common/new_host.c \ ../common/obj_mgr.c \ ../common/object.c \ ../common/sess_mgr.c \ ../common/sign_mgr.c \ ../common/template.c \ ../common/utility.c \ ../common/verify_mgr.c \ ../common/log.c \ ../common/mech_list.c \ soft_specific.c install-data-local: cd $(DESTDIR)/$(libdir)/opencryptoki/stdll && rm -f PKCS11_SW.so && \ ln -sf libpkcs11_sw.so PKCS11_SW.so opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/0000751000175000017500000000000011327631345016714 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/mech_sha.c0000751000175000017500000020037411327631345020640 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: mech_sha.c // // Mechanisms for SHA-1 related routines // // The following applies to the software SHA implementation: // Written 2 September 1992, Peter C. Gutmann. // This implementation placed in the public domain. // // Modified 1 June 1993, Colin Plumb. // Modified for the new SHS based on Peter Gutmann's work, // 18 July 1994, Colin Plumb. // Gutmann's work. // Renamed to SHA and comments updated a bit 1 November 1995, Colin Plumb. // These modifications placed in the public domain. // // Comments to pgut1@cs.aukuni.ac.nz // #include #include // for memcmp() et al #include #include #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" #define SHA_HARDWARE_THRESHHOLD 128000 // The SHA f()-functions. The f1 and f3 functions can be optimized to // save one boolean operation each - thanks to Rich Schroeppel, // rcs@cs.arizona.edu for discovering this // #define f1(x,y,z) (z ^ (x & (y ^ z))) // Rounds 0-19 #define f2(x,y,z) (x ^ y ^ z) // Rounds 20-39 #define f3(x,y,z) ((x & y) | (z & (x | y))) // Rounds 40-59 #define f4(x,y,z) (x ^ y ^ z) // Rounds 60-79 // The SHA Mysterious Constants. // K1 = floor(sqrt(2) * 2^30) // K2 = floor(sqrt(3) * 2^30) // K3 = floor(sqrt(5) * 2^30) // K4 = floor(sqrt(10) * 2^30) // #define K1 0x5A827999L // Rounds 0-19 #define K2 0x6ED9EBA1L // Rounds 20-39 #define K3 0x8F1BBCDCL // Rounds 40-59 #define K4 0xCA62C1D6L // Rounds 60-79 // SHA initial values // #define h0init 0x67452301 #define h1init 0xEFCDAB89 #define h2init 0x98BADCFE #define h3init 0x10325476 #define h4init 0xC3D2E1F0 // // Note that it may be necessary to add parentheses to these macros // if they are to be called with expressions as arguments. // // 32-bit rotate left - kludged with shifts // #define ROTL(n,X) ((X << n) | (X >> (32-n))) // The initial expanding function // // The hash function is defined over an 80-word expanded input array W, // where the first 16 are copies of the input data, and the remaining 64 // are defined by W[i] = W[i-16] ^ W[i-14] ^ W[i-8] ^ W[i-3]. This // implementation generates these values on the fly in a circular buffer. // #define expand(W,i) \ (W[i&15] ^= W[(i-14)&15] ^ W[(i-8)&15] ^ W[(i-3)&15], W[i&15] = ROTL(1, W[i&15])) // The prototype SHA sub-round // // The fundamental sub-round is // a' = e + ROTL(5,a) + f(b, c, d) + k + data; // b' = a; // c' = ROTL(30,b); // d' = c; // e' = d; // ... but this is implemented by unrolling the loop 5 times and renaming // the variables (e,a,b,c,d) = (a',b',c',d',e') each iteration. // #define subRound(a, b, c, d, e, f, k, data) \ (e += ROTL(5,a) + f(b, c, d) + k + data, b = ROTL(30, b)) void shaInit( SHA1_CONTEXT *ctx ); void shaUpdate( SHA1_CONTEXT *ctx, CK_BYTE const *buffer, CK_ULONG count); void shaFinal( SHA1_CONTEXT *ctx, CK_BYTE *hash ); void shaTransform( SHA1_CONTEXT *ctx ); // // CK_RV sha1_hash( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { CK_RV rv; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = SHA1_HASH_SIZE; return CKR_OK; } if(ctx->context == NULL) return CKR_HOST_MEMORY; if((rv = ckm_sha1_update(ctx, in_data, in_data_len))) return rv; return ckm_sha1_final( ctx, out_data, out_data_len ); } CK_RV sha2_hash( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { CK_RV rv; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = SHA2_HASH_SIZE; return CKR_OK; } if(ctx->context == NULL) return CKR_HOST_MEMORY; if((rv = ckm_sha2_update(ctx, in_data, in_data_len))) return rv; return ckm_sha2_final( ctx, out_data, out_data_len ); } CK_RV sha3_hash( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { CK_RV rv; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = SHA3_HASH_SIZE; return CKR_OK; } if(ctx->context == NULL) return CKR_HOST_MEMORY; if((rv = ckm_sha3_update(ctx, in_data, in_data_len))) return rv; return ckm_sha3_final( ctx, out_data, out_data_len ); } CK_RV sha5_hash( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { CK_RV rv; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = SHA5_HASH_SIZE; return CKR_OK; } if(ctx->context == NULL) return CKR_HOST_MEMORY; if((rv = ckm_sha5_update(ctx, in_data, in_data_len))) return rv; return ckm_sha5_final( ctx, out_data, out_data_len ); } // // CK_RV sha1_hash_update( SESSION * sess, DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { if (!sess || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } return ckm_sha1_update( ctx, in_data, in_data_len ); } CK_RV sha2_hash_update( SESSION * sess, DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { if (!sess || !in_data) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } return ckm_sha2_update( ctx, in_data, in_data_len ); } CK_RV sha3_hash_update( SESSION * sess, DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { if (!sess || !in_data) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } return ckm_sha3_update( ctx, in_data, in_data_len ); } CK_RV sha5_hash_update( SESSION * sess, DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { if (!sess || !in_data) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } return ckm_sha5_update( ctx, in_data, in_data_len ); } // // CK_RV sha1_hash_final( SESSION * sess, CK_BYTE length_only, DIGEST_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ) { if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = SHA1_HASH_SIZE; return CKR_OK; } return ckm_sha1_final( ctx, out_data, out_data_len ); } CK_RV sha2_hash_final( SESSION * sess, CK_BYTE length_only, DIGEST_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ) { if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = SHA2_HASH_SIZE; return CKR_OK; } return ckm_sha2_final( ctx, out_data, out_data_len ); } CK_RV sha3_hash_final( SESSION * sess, CK_BYTE length_only, DIGEST_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ) { if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = SHA3_HASH_SIZE; return CKR_OK; } return ckm_sha3_final( ctx, out_data, out_data_len ); } CK_RV sha5_hash_final( SESSION * sess, CK_BYTE length_only, DIGEST_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ) { if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = SHA5_HASH_SIZE; return CKR_OK; } return ckm_sha5_final( ctx, out_data, out_data_len ); } // this routine gets called for two mechanisms actually: // CKM_SHA_1_HMAC // CKM_SHA_1_HMAC_GENERAL // CK_RV sha1_hmac_sign( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE hash[SHA1_HASH_SIZE]; DIGEST_CONTEXT digest_ctx; CK_MECHANISM digest_mech; CK_BYTE k_ipad[SHA1_BLOCK_SIZE]; CK_BYTE k_opad[SHA1_BLOCK_SIZE]; CK_ULONG key_bytes, hash_len, hmac_len; CK_ULONG i; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_SHA_1_HMAC_GENERAL) { hmac_len = *(CK_ULONG *)ctx->mech.pParameter; if (hmac_len == 0) { *out_data_len = 0; return CKR_OK; } } else hmac_len = SHA1_HASH_SIZE; if (length_only == TRUE) { *out_data_len = hmac_len; return CKR_OK; } memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key_obj->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else key_bytes = attr->ulValueLen; // build (K XOR ipad), (K XOR opad) // if (key_bytes > SHA1_BLOCK_SIZE) { digest_mech.mechanism = CKM_SHA_1; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest( sess, FALSE, &digest_ctx, attr->pValue, attr->ulValueLen, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(124, __FILE__, __LINE__); return rc; } digest_mgr_cleanup( &digest_ctx ); memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); for (i=0; i < hash_len; i++) { k_ipad[i] = hash[i] ^ 0x36; k_opad[i] = hash[i] ^ 0x5C; } memset( &k_ipad[i], 0x36, SHA1_BLOCK_SIZE - i); memset( &k_opad[i], 0x5C, SHA1_BLOCK_SIZE - i); } else { CK_BYTE *key = attr->pValue; for (i=0; i < key_bytes; i++) { k_ipad[i] = key[i] ^ 0x36; k_opad[i] = key[i] ^ 0x5C; } memset( &k_ipad[i], 0x36, SHA1_BLOCK_SIZE - key_bytes ); memset( &k_opad[i], 0x5C, SHA1_BLOCK_SIZE - key_bytes ); } digest_mech.mechanism = CKM_SHA_1; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; // inner hash // rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, k_ipad, SHA1_BLOCK_SIZE ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, in_data, in_data_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(126, __FILE__, __LINE__); return rc; } digest_mgr_cleanup( &digest_ctx ); memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); // outer hash // rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, k_opad, SHA1_BLOCK_SIZE ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, hash, hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(126, __FILE__, __LINE__); return rc; } memcpy( out_data, hash, hmac_len ); *out_data_len = hmac_len; digest_mgr_cleanup( &digest_ctx ); return CKR_OK; } /** This routine gets called for two mechanisms actually: * CKM_SHA256_HMAC * CKM_SHA256_HMAC_GENERAL */ CK_RV sha2_hmac_sign( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE hash[SHA2_HASH_SIZE]; DIGEST_CONTEXT digest_ctx; CK_MECHANISM digest_mech; CK_BYTE k_ipad[SHA2_BLOCK_SIZE]; CK_BYTE k_opad[SHA2_BLOCK_SIZE]; CK_ULONG key_bytes, hash_len, hmac_len; CK_ULONG i; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_SHA256_HMAC_GENERAL) { hmac_len = *(CK_ULONG *)ctx->mech.pParameter; if (hmac_len == 0) { *out_data_len = 0; return CKR_OK; } } else hmac_len = SHA2_HASH_SIZE; if (length_only == TRUE) { *out_data_len = hmac_len; return CKR_OK; } memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key_obj->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else key_bytes = attr->ulValueLen; // build (K XOR ipad), (K XOR opad) // if (key_bytes > SHA2_BLOCK_SIZE) { digest_mech.mechanism = CKM_SHA256; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest( sess, FALSE, &digest_ctx, attr->pValue, attr->ulValueLen, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(124, __FILE__, __LINE__); return rc; } digest_mgr_cleanup( &digest_ctx ); memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); for (i=0; i < hash_len; i++) { k_ipad[i] = hash[i] ^ 0x36; k_opad[i] = hash[i] ^ 0x5C; } memset( &k_ipad[i], 0x36, SHA2_BLOCK_SIZE - i); memset( &k_opad[i], 0x5C, SHA2_BLOCK_SIZE - i); } else { CK_BYTE *key = attr->pValue; for (i=0; i < key_bytes; i++) { k_ipad[i] = key[i] ^ 0x36; k_opad[i] = key[i] ^ 0x5C; } memset( &k_ipad[i], 0x36, SHA2_BLOCK_SIZE - key_bytes ); memset( &k_opad[i], 0x5C, SHA2_BLOCK_SIZE - key_bytes ); } digest_mech.mechanism = CKM_SHA256; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; // inner hash // rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, k_ipad, SHA2_BLOCK_SIZE ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, in_data, in_data_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(126, __FILE__, __LINE__); return rc; } digest_mgr_cleanup( &digest_ctx ); memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); // outer hash // rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, k_opad, SHA2_BLOCK_SIZE ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, hash, hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(126, __FILE__, __LINE__); return rc; } memcpy( out_data, hash, hmac_len ); *out_data_len = hmac_len; digest_mgr_cleanup( &digest_ctx ); return CKR_OK; } /** This routine gets called for two mechanisms actually: * CKM_SHA384_HMAC * CKM_SHA384_HMAC_GENERAL */ CK_RV sha3_hmac_sign( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE hash[SHA3_HASH_SIZE]; DIGEST_CONTEXT digest_ctx; CK_MECHANISM digest_mech; CK_BYTE k_ipad[SHA3_BLOCK_SIZE]; CK_BYTE k_opad[SHA3_BLOCK_SIZE]; CK_ULONG key_bytes, hash_len, hmac_len; CK_ULONG i; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_SHA384_HMAC_GENERAL) { hmac_len = *(CK_ULONG *)ctx->mech.pParameter; if (hmac_len == 0) { *out_data_len = 0; return CKR_OK; } } else hmac_len = SHA3_HASH_SIZE; if (length_only == TRUE) { *out_data_len = hmac_len; return CKR_OK; } memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key_obj->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else key_bytes = attr->ulValueLen; // build (K XOR ipad), (K XOR opad) // if (key_bytes > SHA3_BLOCK_SIZE) { digest_mech.mechanism = CKM_SHA384; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest( sess, FALSE, &digest_ctx, attr->pValue, attr->ulValueLen, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(124, __FILE__, __LINE__); return rc; } digest_mgr_cleanup( &digest_ctx ); memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); for (i=0; i < hash_len; i++) { k_ipad[i] = hash[i] ^ 0x36; k_opad[i] = hash[i] ^ 0x5C; } memset( &k_ipad[i], 0x36, SHA3_BLOCK_SIZE - i); memset( &k_opad[i], 0x5C, SHA3_BLOCK_SIZE - i); } else { CK_BYTE *key = attr->pValue; for (i=0; i < key_bytes; i++) { k_ipad[i] = key[i] ^ 0x36; k_opad[i] = key[i] ^ 0x5C; } memset( &k_ipad[i], 0x36, SHA3_BLOCK_SIZE - key_bytes ); memset( &k_opad[i], 0x5C, SHA3_BLOCK_SIZE - key_bytes ); } digest_mech.mechanism = CKM_SHA384; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; // inner hash // rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, k_ipad, SHA3_BLOCK_SIZE ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, in_data, in_data_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(126, __FILE__, __LINE__); return rc; } digest_mgr_cleanup( &digest_ctx ); memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); // outer hash // rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, k_opad, SHA3_BLOCK_SIZE ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, hash, hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(126, __FILE__, __LINE__); return rc; } memcpy( out_data, hash, hmac_len ); *out_data_len = hmac_len; digest_mgr_cleanup( &digest_ctx ); return CKR_OK; } /** This routine gets called for two mechanisms actually: * CKM_SHA512_HMAC * CKM_SHA512_HMAC_GENERAL */ CK_RV sha5_hmac_sign( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE hash[SHA5_HASH_SIZE]; DIGEST_CONTEXT digest_ctx; CK_MECHANISM digest_mech; CK_BYTE k_ipad[SHA5_BLOCK_SIZE]; CK_BYTE k_opad[SHA5_BLOCK_SIZE]; CK_ULONG key_bytes, hash_len, hmac_len; CK_ULONG i; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_SHA512_HMAC_GENERAL) { hmac_len = *(CK_ULONG *)ctx->mech.pParameter; if (hmac_len == 0) { *out_data_len = 0; return CKR_OK; } } else hmac_len = SHA5_HASH_SIZE; if (length_only == TRUE) { *out_data_len = hmac_len; return CKR_OK; } memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key_obj->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else key_bytes = attr->ulValueLen; // build (K XOR ipad), (K XOR opad) // if (key_bytes > SHA5_BLOCK_SIZE) { digest_mech.mechanism = CKM_SHA512; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest( sess, FALSE, &digest_ctx, attr->pValue, attr->ulValueLen, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(124, __FILE__, __LINE__); return rc; } digest_mgr_cleanup( &digest_ctx ); memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); for (i=0; i < hash_len; i++) { k_ipad[i] = hash[i] ^ 0x36; k_opad[i] = hash[i] ^ 0x5C; } memset( &k_ipad[i], 0x36, SHA5_BLOCK_SIZE - i); memset( &k_opad[i], 0x5C, SHA5_BLOCK_SIZE - i); } else { CK_BYTE *key = attr->pValue; for (i=0; i < key_bytes; i++) { k_ipad[i] = key[i] ^ 0x36; k_opad[i] = key[i] ^ 0x5C; } memset( &k_ipad[i], 0x36, SHA5_BLOCK_SIZE - key_bytes ); memset( &k_opad[i], 0x5C, SHA5_BLOCK_SIZE - key_bytes ); } digest_mech.mechanism = CKM_SHA512; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; // inner hash // rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, k_ipad, SHA5_BLOCK_SIZE ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, in_data, in_data_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(126, __FILE__, __LINE__); return rc; } digest_mgr_cleanup( &digest_ctx ); memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); // outer hash // rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, k_opad, SHA5_BLOCK_SIZE ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, hash, hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(126, __FILE__, __LINE__); return rc; } memcpy( out_data, hash, hmac_len ); *out_data_len = hmac_len; digest_mgr_cleanup( &digest_ctx ); return CKR_OK; } // // CK_RV sha1_hmac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ) { CK_BYTE hmac[SHA1_HASH_SIZE]; SIGN_VERIFY_CONTEXT hmac_ctx; CK_ULONG hmac_len, len; CK_RV rc; if (!sess || !ctx || !in_data || !signature){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_SHA_1_HMAC_GENERAL) hmac_len = *(CK_ULONG *)ctx->mech.pParameter; else hmac_len = SHA1_HASH_SIZE; memset( &hmac_ctx, 0, sizeof(SIGN_VERIFY_CONTEXT) ); rc = sign_mgr_init( sess, &hmac_ctx, &ctx->mech, FALSE, ctx->key ); if (rc != CKR_OK){ st_err_log(127, __FILE__, __LINE__); goto done; } len = sizeof(hmac); rc = sign_mgr_sign( sess, FALSE, &hmac_ctx, in_data, in_data_len, hmac, &len ); if (rc != CKR_OK){ st_err_log(128, __FILE__, __LINE__); goto done; } if ((len != hmac_len) || (len != sig_len)) { st_err_log(46, __FILE__, __LINE__); rc = CKR_SIGNATURE_LEN_RANGE; goto done; } if (memcmp(hmac, signature, hmac_len) != 0){ st_err_log(47, __FILE__, __LINE__); rc = CKR_SIGNATURE_INVALID; } done: sign_mgr_cleanup( &hmac_ctx ); return rc; } CK_RV sha2_hmac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ) { CK_BYTE hmac[SHA2_HASH_SIZE]; SIGN_VERIFY_CONTEXT hmac_ctx; CK_ULONG hmac_len, len; CK_RV rc; if (!sess || !ctx || !in_data || !signature){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_SHA256_HMAC_GENERAL) hmac_len = *(CK_ULONG *)ctx->mech.pParameter; else hmac_len = SHA2_HASH_SIZE; memset( &hmac_ctx, 0, sizeof(SIGN_VERIFY_CONTEXT) ); rc = sign_mgr_init( sess, &hmac_ctx, &ctx->mech, FALSE, ctx->key ); if (rc != CKR_OK){ st_err_log(127, __FILE__, __LINE__); goto done; } len = sizeof(hmac); rc = sign_mgr_sign( sess, FALSE, &hmac_ctx, in_data, in_data_len, hmac, &len ); if (rc != CKR_OK){ st_err_log(128, __FILE__, __LINE__); goto done; } if ((len != hmac_len) || (len != sig_len)) { st_err_log(46, __FILE__, __LINE__); rc = CKR_SIGNATURE_LEN_RANGE; goto done; } if (memcmp(hmac, signature, hmac_len) != 0){ st_err_log(47, __FILE__, __LINE__); rc = CKR_SIGNATURE_INVALID; } done: sign_mgr_cleanup( &hmac_ctx ); return rc; } CK_RV sha3_hmac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ) { CK_BYTE hmac[SHA3_HASH_SIZE]; SIGN_VERIFY_CONTEXT hmac_ctx; CK_ULONG hmac_len, len; CK_RV rc; if (!sess || !ctx || !in_data || !signature){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_SHA384_HMAC_GENERAL) hmac_len = *(CK_ULONG *)ctx->mech.pParameter; else hmac_len = SHA3_HASH_SIZE; memset( &hmac_ctx, 0, sizeof(SIGN_VERIFY_CONTEXT) ); rc = sign_mgr_init( sess, &hmac_ctx, &ctx->mech, FALSE, ctx->key ); if (rc != CKR_OK){ st_err_log(127, __FILE__, __LINE__); goto done; } len = sizeof(hmac); rc = sign_mgr_sign( sess, FALSE, &hmac_ctx, in_data, in_data_len, hmac, &len ); if (rc != CKR_OK){ st_err_log(128, __FILE__, __LINE__); goto done; } if ((len != hmac_len) || (len != sig_len)) { st_err_log(46, __FILE__, __LINE__); rc = CKR_SIGNATURE_LEN_RANGE; goto done; } if (memcmp(hmac, signature, hmac_len) != 0){ st_err_log(47, __FILE__, __LINE__); rc = CKR_SIGNATURE_INVALID; } done: sign_mgr_cleanup( &hmac_ctx ); return rc; } CK_RV sha5_hmac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ) { CK_BYTE hmac[SHA5_HASH_SIZE]; SIGN_VERIFY_CONTEXT hmac_ctx; CK_ULONG hmac_len, len; CK_RV rc; if (!sess || !ctx || !in_data || !signature){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_SHA512_HMAC_GENERAL) hmac_len = *(CK_ULONG *)ctx->mech.pParameter; else hmac_len = SHA5_HASH_SIZE; memset( &hmac_ctx, 0, sizeof(SIGN_VERIFY_CONTEXT) ); rc = sign_mgr_init( sess, &hmac_ctx, &ctx->mech, FALSE, ctx->key ); if (rc != CKR_OK){ st_err_log(127, __FILE__, __LINE__); goto done; } len = sizeof(hmac); rc = sign_mgr_sign( sess, FALSE, &hmac_ctx, in_data, in_data_len, hmac, &len ); if (rc != CKR_OK){ st_err_log(128, __FILE__, __LINE__); goto done; } if ((len != hmac_len) || (len != sig_len)) { st_err_log(46, __FILE__, __LINE__); rc = CKR_SIGNATURE_LEN_RANGE; goto done; } if (memcmp(hmac, signature, hmac_len) != 0){ st_err_log(47, __FILE__, __LINE__); rc = CKR_SIGNATURE_INVALID; } done: sign_mgr_cleanup( &hmac_ctx ); return rc; } // // CKM routines // // // CK_RV ckm_sha1_update( DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { if( token_specific.t_sha_update == NULL ){ if (!ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } shaUpdate( (SHA1_CONTEXT *)ctx->context, in_data, in_data_len ); return CKR_OK; } return token_specific.t_sha_update(ctx, in_data, in_data_len); } CK_RV ckm_sha2_update( DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { if( token_specific.t_sha2_update == NULL ){ /* TODO: Software implementation here */ return CKR_MECHANISM_INVALID; } return token_specific.t_sha2_update(ctx, in_data, in_data_len); } CK_RV ckm_sha3_update( DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { if( token_specific.t_sha3_update == NULL ){ /* TODO: Software implementation here */ return CKR_MECHANISM_INVALID; } return token_specific.t_sha3_update(ctx, in_data, in_data_len); } CK_RV ckm_sha5_update( DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { if( token_specific.t_sha5_update == NULL ){ /* TODO: Software implementation here */ return CKR_MECHANISM_INVALID; } return token_specific.t_sha5_update(ctx, in_data, in_data_len); } // // CK_RV ckm_sha1_final( DIGEST_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ) { if (token_specific.t_sha_final == NULL ){ if (!ctx || !out_data || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < SHA1_HASH_SIZE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } shaFinal( (SHA1_CONTEXT *)ctx->context, out_data ); *out_data_len = SHA1_HASH_SIZE; return CKR_OK; } return token_specific.t_sha_final(ctx, out_data, out_data_len); } CK_RV ckm_sha2_final( DIGEST_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ) { if (token_specific.t_sha2_final == NULL ){ /* TODO: Software implementation here */ return CKR_MECHANISM_INVALID; } return token_specific.t_sha2_final(ctx, out_data, out_data_len); } CK_RV ckm_sha3_final( DIGEST_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ) { if (token_specific.t_sha3_final == NULL ){ /* TODO: Software implementation here */ return CKR_MECHANISM_INVALID; } return token_specific.t_sha3_final(ctx, out_data, out_data_len); } CK_RV ckm_sha5_final( DIGEST_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ) { if (token_specific.t_sha5_final == NULL ){ /* TODO: Software implementation here */ return CKR_MECHANISM_INVALID; } return token_specific.t_sha5_final(ctx, out_data, out_data_len); } // // Software SHA-1 implementation // void ckm_sha1_init( DIGEST_CONTEXT * ctx) { // Set the h-vars to their initial values if (token_specific.t_sha_init == NULL ) { SHA1_CONTEXT *sha1_ctx; /* Allocate the context */ ctx->context_len = sizeof(SHA1_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(SHA1_CONTEXT)); if( ctx->context == NULL ) return; sha1_ctx = (SHA1_CONTEXT *)ctx->context; sha1_ctx->hash_value[0] = h0init; sha1_ctx->hash_value[1] = h1init; sha1_ctx->hash_value[2] = h2init; sha1_ctx->hash_value[3] = h3init; sha1_ctx->hash_value[4] = h4init; // Initialise bit count sha1_ctx->bits_lo = sha1_ctx->bits_hi = 0; } else { // SAB XXX call token specific init... the init MUST allocate it's context token_specific.t_sha_init(ctx); } } void ckm_sha2_init( DIGEST_CONTEXT * ctx) { if (token_specific.t_sha2_init == NULL ) { /* TODO: Software implementation here */ return; } else { // SAB XXX call token specific init... the init MUST allocate it's context token_specific.t_sha2_init(ctx); } } void ckm_sha3_init( DIGEST_CONTEXT * ctx) { if (token_specific.t_sha3_init == NULL ) { /* TODO: Software implementation here */ return; } else { // SAB XXX call token specific init... the init MUST allocate it's context token_specific.t_sha3_init(ctx); } } void ckm_sha5_init( DIGEST_CONTEXT * ctx) { if (token_specific.t_sha5_init == NULL ) { /* TODO: Software implementation here */ return; } else { // SAB XXX call token specific init... the init MUST allocate it's context token_specific.t_sha5_init(ctx); } } // Perform the SHA transformation. Note that this code, like MD5, seems to // break some optimizing compilers due to the complexity of the expressions // and the size of the basic block. It may be necessary to split it into // sections, e.g. based on the four subrounds // // Note that this corrupts the sha->data area // void shaTransform( SHA1_CONTEXT *ctx ) { register unsigned int A, B, C, D, E; // Set up first buffer // A = ctx->hash_value[0]; B = ctx->hash_value[1]; C = ctx->hash_value[2]; D = ctx->hash_value[3]; E = ctx->hash_value[4]; // Heavy mangling, in 4 sub-rounds of 20 interations each. // subRound( A, B, C, D, E, f1, K1, ctx->buf[ 0] ); subRound( E, A, B, C, D, f1, K1, ctx->buf[ 1] ); subRound( D, E, A, B, C, f1, K1, ctx->buf[ 2] ); subRound( C, D, E, A, B, f1, K1, ctx->buf[ 3] ); subRound( B, C, D, E, A, f1, K1, ctx->buf[ 4] ); subRound( A, B, C, D, E, f1, K1, ctx->buf[ 5] ); subRound( E, A, B, C, D, f1, K1, ctx->buf[ 6] ); subRound( D, E, A, B, C, f1, K1, ctx->buf[ 7] ); subRound( C, D, E, A, B, f1, K1, ctx->buf[ 8] ); subRound( B, C, D, E, A, f1, K1, ctx->buf[ 9] ); subRound( A, B, C, D, E, f1, K1, ctx->buf[10] ); subRound( E, A, B, C, D, f1, K1, ctx->buf[11] ); subRound( D, E, A, B, C, f1, K1, ctx->buf[12] ); subRound( C, D, E, A, B, f1, K1, ctx->buf[13] ); subRound( B, C, D, E, A, f1, K1, ctx->buf[14] ); subRound( A, B, C, D, E, f1, K1, ctx->buf[15] ); subRound( E, A, B, C, D, f1, K1, expand(ctx->buf, 16) ); subRound( D, E, A, B, C, f1, K1, expand(ctx->buf, 17) ); subRound( C, D, E, A, B, f1, K1, expand(ctx->buf, 18) ); subRound( B, C, D, E, A, f1, K1, expand(ctx->buf, 19) ); subRound( A, B, C, D, E, f2, K2, expand(ctx->buf, 20) ); subRound( E, A, B, C, D, f2, K2, expand(ctx->buf, 21) ); subRound( D, E, A, B, C, f2, K2, expand(ctx->buf, 22) ); subRound( C, D, E, A, B, f2, K2, expand(ctx->buf, 23) ); subRound( B, C, D, E, A, f2, K2, expand(ctx->buf, 24) ); subRound( A, B, C, D, E, f2, K2, expand(ctx->buf, 25) ); subRound( E, A, B, C, D, f2, K2, expand(ctx->buf, 26) ); subRound( D, E, A, B, C, f2, K2, expand(ctx->buf, 27) ); subRound( C, D, E, A, B, f2, K2, expand(ctx->buf, 28) ); subRound( B, C, D, E, A, f2, K2, expand(ctx->buf, 29) ); subRound( A, B, C, D, E, f2, K2, expand(ctx->buf, 30) ); subRound( E, A, B, C, D, f2, K2, expand(ctx->buf, 31) ); subRound( D, E, A, B, C, f2, K2, expand(ctx->buf, 32) ); subRound( C, D, E, A, B, f2, K2, expand(ctx->buf, 33) ); subRound( B, C, D, E, A, f2, K2, expand(ctx->buf, 34) ); subRound( A, B, C, D, E, f2, K2, expand(ctx->buf, 35) ); subRound( E, A, B, C, D, f2, K2, expand(ctx->buf, 36) ); subRound( D, E, A, B, C, f2, K2, expand(ctx->buf, 37) ); subRound( C, D, E, A, B, f2, K2, expand(ctx->buf, 38) ); subRound( B, C, D, E, A, f2, K2, expand(ctx->buf, 39) ); subRound( A, B, C, D, E, f3, K3, expand(ctx->buf, 40) ); subRound( E, A, B, C, D, f3, K3, expand(ctx->buf, 41) ); subRound( D, E, A, B, C, f3, K3, expand(ctx->buf, 42) ); subRound( C, D, E, A, B, f3, K3, expand(ctx->buf, 43) ); subRound( B, C, D, E, A, f3, K3, expand(ctx->buf, 44) ); subRound( A, B, C, D, E, f3, K3, expand(ctx->buf, 45) ); subRound( E, A, B, C, D, f3, K3, expand(ctx->buf, 46) ); subRound( D, E, A, B, C, f3, K3, expand(ctx->buf, 47) ); subRound( C, D, E, A, B, f3, K3, expand(ctx->buf, 48) ); subRound( B, C, D, E, A, f3, K3, expand(ctx->buf, 49) ); subRound( A, B, C, D, E, f3, K3, expand(ctx->buf, 50) ); subRound( E, A, B, C, D, f3, K3, expand(ctx->buf, 51) ); subRound( D, E, A, B, C, f3, K3, expand(ctx->buf, 52) ); subRound( C, D, E, A, B, f3, K3, expand(ctx->buf, 53) ); subRound( B, C, D, E, A, f3, K3, expand(ctx->buf, 54) ); subRound( A, B, C, D, E, f3, K3, expand(ctx->buf, 55) ); subRound( E, A, B, C, D, f3, K3, expand(ctx->buf, 56) ); subRound( D, E, A, B, C, f3, K3, expand(ctx->buf, 57) ); subRound( C, D, E, A, B, f3, K3, expand(ctx->buf, 58) ); subRound( B, C, D, E, A, f3, K3, expand(ctx->buf, 59) ); subRound( A, B, C, D, E, f4, K4, expand(ctx->buf, 60) ); subRound( E, A, B, C, D, f4, K4, expand(ctx->buf, 61) ); subRound( D, E, A, B, C, f4, K4, expand(ctx->buf, 62) ); subRound( C, D, E, A, B, f4, K4, expand(ctx->buf, 63) ); subRound( B, C, D, E, A, f4, K4, expand(ctx->buf, 64) ); subRound( A, B, C, D, E, f4, K4, expand(ctx->buf, 65) ); subRound( E, A, B, C, D, f4, K4, expand(ctx->buf, 66) ); subRound( D, E, A, B, C, f4, K4, expand(ctx->buf, 67) ); subRound( C, D, E, A, B, f4, K4, expand(ctx->buf, 68) ); subRound( B, C, D, E, A, f4, K4, expand(ctx->buf, 69) ); subRound( A, B, C, D, E, f4, K4, expand(ctx->buf, 70) ); subRound( E, A, B, C, D, f4, K4, expand(ctx->buf, 71) ); subRound( D, E, A, B, C, f4, K4, expand(ctx->buf, 72) ); subRound( C, D, E, A, B, f4, K4, expand(ctx->buf, 73) ); subRound( B, C, D, E, A, f4, K4, expand(ctx->buf, 74) ); subRound( A, B, C, D, E, f4, K4, expand(ctx->buf, 75) ); subRound( E, A, B, C, D, f4, K4, expand(ctx->buf, 76) ); subRound( D, E, A, B, C, f4, K4, expand(ctx->buf, 77) ); subRound( C, D, E, A, B, f4, K4, expand(ctx->buf, 78) ); subRound( B, C, D, E, A, f4, K4, expand(ctx->buf, 79) ); // Build message digest // ctx->hash_value[0] += A; ctx->hash_value[1] += B; ctx->hash_value[2] += C; ctx->hash_value[3] += D; ctx->hash_value[4] += E; } // SHA is defined in big-endian form, so this converts the buffer from // bytes to words, independent of the machine's native endianness. // // Assuming a consistent byte ordering for the machine, this also // has the magic property of being self-inverse. It is used as // such. // static void byteReverse( unsigned int *buffer, unsigned int byteCount ) { #ifndef __BYTE_ORDER #error "Endianess MUST be defined" #endif #if __BYTE_ORDER == __LITTLE_ENDIAN CK_ULONG value, val; byteCount /= sizeof(CK_ULONG_32); while (byteCount--) { val = *buffer; value = ((0x000000FF & val) << 24) | ((0x0000FF00 & val) << 8 ) | ((0x00FF0000 & val) >> 8 ) | ((0xFF000000 & val) >> 24); *buffer++ = value; } #endif // JRM - this code gives funky results on Linux/Intel. // I assume this is a GCC issue since regression tests passed on NT // // byteCount /= sizeof(CK_ULONG); // while ( byteCount-- ) { // value = (CK_ULONG)((unsigned)((CK_BYTE *)buffer)[0] << 8 | ((CK_BYTE *)buffer)[1]) << 16 | // ((unsigned)((CK_BYTE *)buffer)[2] << 8 | ((CK_BYTE *)buffer)[3]); // *buffer++ = value; // } } void shaUpdate( SHA1_CONTEXT * ctx, CK_BYTE const * buffer, CK_ULONG count) { CK_ULONG t; // Update bitcount // t = ctx->bits_lo; if ((ctx->bits_lo = t + count) < t) ctx->bits_hi++; // Carry from low to high t &= 0x3f; // Bytes already in ctx->buf // Handle any leading odd-sized chunks // if (t) { CK_BYTE *p = (CK_BYTE *)ctx->buf + t; t = 64-t; if (count < t) { memcpy(p, buffer, count); return; } memcpy(p, buffer, t); byteReverse(ctx->buf, SHA1_BLOCK_SIZE); shaTransform(ctx); buffer += t; count -= t; } // Process data in SHA1_BLOCK_SIZE chunks // while (count >= SHA1_BLOCK_SIZE) { memcpy(ctx->buf, buffer, SHA1_BLOCK_SIZE); byteReverse(ctx->buf, SHA1_BLOCK_SIZE); shaTransform(ctx); buffer += SHA1_BLOCK_SIZE; count -= SHA1_BLOCK_SIZE; } // Handle any remaining bytes of data. // memcpy(ctx->buf, buffer, count); } // Final wrapup - pad to 64-byte boundary with the bit pattern // 1 0* (64-bit count of bits processed, MSB-first) // void shaFinal( SHA1_CONTEXT * ctx, CK_BYTE * hash ) { int count; CK_BYTE *p; // Compute number of bytes mod 64 // count = (int)ctx->bits_lo & 0x3F; // Set the first char of padding to 0x80. // This is safe since there is always at least one byte free // p = (CK_BYTE *)ctx->buf + count; *p++ = 0x80; // Bytes of padding needed to make 64 bytes // count = SHA1_BLOCK_SIZE - 1 - count; // Pad out to 56 mod 64 // if (count < 8) { // Two lots of padding: Pad the first block to 64 bytes // memset(p, 0, count); byteReverse(ctx->buf, SHA1_BLOCK_SIZE); shaTransform(ctx); // Now fill the next block with 56 bytes // memset(ctx->buf, 0, SHA1_BLOCK_SIZE-8); } else { // Pad block to 56 bytes // memset(p, 0, count-8); } byteReverse(ctx->buf, SHA1_BLOCK_SIZE-8); // Append length in *bits* and transform // ctx->buf[14] = ctx->bits_hi << 3 | ctx->bits_lo >> 29; ctx->buf[15] = ctx->bits_lo << 3; shaTransform(ctx); // Store output hash in buffer // byteReverse(ctx->hash_value, SHA1_HASH_SIZE); memcpy(hash, ctx->hash_value, SHA1_HASH_SIZE); } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/key.c0000751000175000017500000046436411327631345017674 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: key.c // // Functions contained within: // // key_object_check_required_attributes // key_object_set_default_attributes // key_object_validate_attribute // // publ_key_check_required_attributes // publ_key_set_default_attributes // publ_key_validate_attribute // // priv_key_check_required_attributes // priv_key_set_default_attributes // priv_key_validate_attribute // // secret_key_check_required_attributes // secret_key_set_default_attributes // secret_key_validate_attribute // // rsa_publ_check_required_attributes // rsa_publ_validate_attribute // rsa_priv_check_required_attributes // rsa_priv_validate_attribute // rsa_priv_check_exportability // // dsa_publ_check_required_attributes // dsa_publ_validate_attribute // dsa_priv_check_required_attributes // dsa_priv_validate_attribute // dsa_priv_check_exportability // // ecdsa_publ_check_required_attributes // ecdsa_publ_validate_attribute // ecdsa_priv_checK_required_attributes // ecdsa_priv_validate_attribute // ecdsa_priv_check_exportability // // dh_publ_check_required_attributes // dh_publ_validate_attribute // dh_priv_check_required_attributes // dh_priv_validate_attribute // dh_priv_check_exportability // // kea_publ_check_required_attributes // kea_publ_validate_attribute // kea_priv_check_required_attributes // kea_priv_validate_attribute // kea_priv_check_exportability // // generic_secret_check_required_attributes // generic_secret_validate_attribute // // rc2_check_required_attributes // rc2_validate_attribute // rc2_priv_check_exportability // // rc4_check_required_attributes // rc4_validate_attribute // rc4_priv_check_exportability // // rc5_check_required_attributes // rc5_validate_attribute // rc5_priv_check_exportability // // des_check_required_attributes // des_validate_attribute // des_priv_check_exportability // // des2_check_required_attributes // des2_validate_attribute // des2_priv_check_exportability // // des3_check_required_attributes // des3_validate_attribute // des3_priv_check_exportability // // cast_check_required_attributes // cast_validate_attribute // cast_priv_check_exportability // // cast3_check_required_attributes // cast3_validate_attribute // cast3_priv_check_exportability // // cast5_check_required_attributes // cast5_validate_attribute // cast5_priv_check_exportability // // idea_check_required_attributes // idea_validate_attribute // idea_priv_check_exportability // // cdmf_check_required_attributes // cdmf_validate_attribute // cdmf_priv_check_exportability // // skipjack_check_required_attributes // skipjack_validate_attribute // skipjack_priv_check_exportability // // baton_check_required_attributes // baton_validate_attribute // baton_priv_check_exportability // // juniper_check_required_attributes // juniper_validate_attribute // juniper_priv_check_exportability // #include #include #include // for memcmp() et al #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // key_object_check_required_attributes() // // Check required common attributes for key objects // CK_RV key_object_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE * attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_KEY_TYPE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return template_check_required_base_attributes( tmpl, mode ); } // key_object_set_default_attributes() // CK_RV key_object_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE * id_attr = NULL; CK_ATTRIBUTE * sdate_attr = NULL; CK_ATTRIBUTE * edate_attr = NULL; CK_ATTRIBUTE * derive_attr = NULL; CK_ATTRIBUTE * local_attr = NULL; // satisfy the compiler // if (mode) id_attr = NULL; id_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); sdate_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); edate_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); derive_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); local_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!id_attr || !sdate_attr || !edate_attr || !derive_attr || !local_attr) { if (id_attr) free( id_attr ); if (sdate_attr) free( sdate_attr ); if (edate_attr) free( edate_attr ); if (derive_attr) free( derive_attr ); if (local_attr) free( local_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } id_attr->type = CKA_ID; id_attr->ulValueLen = 0; id_attr->pValue = NULL; sdate_attr->type = CKA_START_DATE; sdate_attr->ulValueLen = 0; sdate_attr->pValue = NULL; edate_attr->type = CKA_END_DATE; edate_attr->ulValueLen = 0; edate_attr->pValue = NULL; derive_attr->type = CKA_DERIVE; derive_attr->ulValueLen = sizeof(CK_BBOOL); derive_attr->pValue = (CK_BYTE *)derive_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)derive_attr->pValue = FALSE; local_attr->type = CKA_LOCAL; local_attr->ulValueLen = sizeof(CK_BBOOL); local_attr->pValue = (CK_BYTE *)local_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)local_attr->pValue = FALSE; template_update_attribute( tmpl, id_attr ); template_update_attribute( tmpl, sdate_attr ); template_update_attribute( tmpl, edate_attr ); template_update_attribute( tmpl, derive_attr ); template_update_attribute( tmpl, local_attr ); return CKR_OK; } // key_object_validate_attribute() // CK_RV key_object_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode) { switch (attr->type) { case CKA_KEY_TYPE: if (mode == MODE_CREATE || mode == MODE_DERIVE || mode == MODE_KEYGEN || mode == MODE_UNWRAP) return CKR_OK; else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_ID: case CKA_START_DATE: case CKA_END_DATE: case CKA_DERIVE: return CKR_OK; case CKA_LOCAL: // CKA_LOCAL is only set by the key-generate routine // st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; default: return template_validate_base_attribute( tmpl, attr, mode ); } st_err_log(8, __FILE__, __LINE__); return CKR_ATTRIBUTE_TYPE_INVALID; } // publ_key_check_required_attributes() // CK_RV publ_key_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { // CKO_PUBLIC_KEY has no required attributes // return key_object_check_required_attributes( tmpl, mode ); } // publ_key_set_default_attributes() // // some of the common public key attributes have defaults but none of the specific // public keytypes have default attributes // CK_RV publ_key_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *class_attr = NULL; CK_ATTRIBUTE *subject_attr = NULL; CK_ATTRIBUTE *encrypt_attr = NULL; CK_ATTRIBUTE *verify_attr = NULL; CK_ATTRIBUTE *verify_recover_attr = NULL; CK_ATTRIBUTE *wrap_attr = NULL; CK_OBJECT_CLASS class = CKO_PUBLIC_KEY; CK_RV rc; rc = key_object_set_default_attributes( tmpl, mode ); if (rc != CKR_OK){ st_err_log(172, __FILE__, __LINE__); return rc; } // add the default CKO_PUBLIC_KEY attributes // class_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS) ); subject_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); encrypt_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); verify_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); verify_recover_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); wrap_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!class || !subject_attr || !encrypt_attr || !verify_attr || !verify_recover_attr || !wrap_attr) { if (class_attr) free( class_attr ); if (subject_attr) free( subject_attr ); if (encrypt_attr) free( encrypt_attr ); if (verify_attr) free( verify_attr ); if (verify_recover_attr) free( verify_recover_attr ); if (wrap_attr) free( wrap_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } class_attr->type = CKA_CLASS; class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS); class_attr->pValue = (CK_BYTE *)class_attr + sizeof(CK_ATTRIBUTE); *(CK_OBJECT_CLASS *)class_attr->pValue = CKO_PUBLIC_KEY; subject_attr->type = CKA_SUBJECT; subject_attr->ulValueLen = 0; // empty string subject_attr->pValue = NULL; encrypt_attr->type = CKA_ENCRYPT; encrypt_attr->ulValueLen = sizeof(CK_BBOOL); encrypt_attr->pValue = (CK_BYTE *)encrypt_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)encrypt_attr->pValue = TRUE; verify_attr->type = CKA_VERIFY; verify_attr->ulValueLen = sizeof(CK_BBOOL); verify_attr->pValue = (CK_BYTE *)verify_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)verify_attr->pValue = TRUE; verify_recover_attr->type = CKA_VERIFY_RECOVER; verify_recover_attr->ulValueLen = sizeof(CK_BBOOL); verify_recover_attr->pValue = (CK_BYTE *)verify_recover_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)verify_recover_attr->pValue = TRUE; wrap_attr->type = CKA_WRAP; wrap_attr->ulValueLen = sizeof(CK_BBOOL); wrap_attr->pValue = (CK_BYTE *)wrap_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)wrap_attr->pValue = TRUE; template_update_attribute( tmpl, class_attr ); template_update_attribute( tmpl, subject_attr ); template_update_attribute( tmpl, encrypt_attr ); template_update_attribute( tmpl, verify_attr ); template_update_attribute( tmpl, verify_recover_attr ); template_update_attribute( tmpl, wrap_attr ); return CKR_OK; } // publ_key_validate_attribute // CK_RV publ_key_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_SUBJECT: return CKR_OK; case CKA_ENCRYPT: case CKA_VERIFY: case CKA_VERIFY_RECOVER: case CKA_WRAP: if (mode == MODE_MODIFY) { if (nv_token_data->tweak_vector.allow_key_mods == TRUE) return CKR_OK; st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } return CKR_OK; default: return key_object_validate_attribute( tmpl, attr, mode ); } st_err_log(8, __FILE__, __LINE__); return CKR_ATTRIBUTE_TYPE_INVALID; } // priv_key_check_required_attributes() // CK_RV priv_key_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { // CKO_PRIVATE_KEY has no required attributes // return key_object_check_required_attributes( tmpl, mode ); } // priv_key_set_default_attributes() // // some of the common private key attributes have defaults but none of the specific // private keytypes have default attributes // CK_RV priv_key_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *class_attr = NULL; CK_ATTRIBUTE *subject_attr = NULL; CK_ATTRIBUTE *sensitive_attr = NULL; CK_ATTRIBUTE *decrypt_attr = NULL; CK_ATTRIBUTE *sign_attr = NULL; CK_ATTRIBUTE *sign_recover_attr = NULL; CK_ATTRIBUTE *unwrap_attr = NULL; CK_ATTRIBUTE *extractable_attr = NULL; CK_ATTRIBUTE *never_extr_attr = NULL; CK_ATTRIBUTE *always_sens_attr = NULL; CK_RV rc; rc = key_object_set_default_attributes( tmpl, mode ); if (rc != CKR_OK){ st_err_log(172, __FILE__, __LINE__); return rc; } // add the default CKO_PUBLIC_KEY attributes // class_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS) ); subject_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); sensitive_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); decrypt_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); sign_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); sign_recover_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); unwrap_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); extractable_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); never_extr_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); always_sens_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!class_attr || !subject_attr || !sensitive_attr || !decrypt_attr || !sign_attr || !sign_recover_attr || !unwrap_attr || !extractable_attr || !never_extr_attr || !always_sens_attr ) { if (class_attr) free( class_attr ); if (subject_attr) free( subject_attr ); if (sensitive_attr) free( sensitive_attr ); if (decrypt_attr) free( decrypt_attr ); if (sign_attr) free( sign_attr ); if (sign_recover_attr) free( sign_recover_attr ); if (unwrap_attr) free( unwrap_attr ); if (extractable_attr) free( extractable_attr ); if (always_sens_attr) free( always_sens_attr ); if (never_extr_attr) free( never_extr_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } class_attr->type = CKA_CLASS; class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS); class_attr->pValue = (CK_BYTE *)class_attr + sizeof(CK_ATTRIBUTE); *(CK_OBJECT_CLASS *)class_attr->pValue = CKO_PRIVATE_KEY; subject_attr->type = CKA_SUBJECT; subject_attr->ulValueLen = 0; // empty string subject_attr->pValue = NULL; sensitive_attr->type = CKA_SENSITIVE; sensitive_attr->ulValueLen = sizeof(CK_BBOOL); sensitive_attr->pValue = (CK_BYTE *)sensitive_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)sensitive_attr->pValue = FALSE; decrypt_attr->type = CKA_DECRYPT; decrypt_attr->ulValueLen = sizeof(CK_BBOOL); decrypt_attr->pValue = (CK_BYTE *)decrypt_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)decrypt_attr->pValue = TRUE; sign_attr->type = CKA_SIGN; sign_attr->ulValueLen = sizeof(CK_BBOOL); sign_attr->pValue = (CK_BYTE *)sign_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)sign_attr->pValue = TRUE; sign_recover_attr->type = CKA_SIGN_RECOVER; sign_recover_attr->ulValueLen = sizeof(CK_BBOOL); sign_recover_attr->pValue = (CK_BYTE *)sign_recover_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)sign_recover_attr->pValue = TRUE; unwrap_attr->type = CKA_UNWRAP; unwrap_attr->ulValueLen = sizeof(CK_BBOOL); unwrap_attr->pValue = (CK_BYTE *)unwrap_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)unwrap_attr->pValue = TRUE; extractable_attr->type = CKA_EXTRACTABLE; extractable_attr->ulValueLen = sizeof(CK_BBOOL); extractable_attr->pValue = (CK_BYTE *)extractable_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)extractable_attr->pValue = TRUE; // by default, we'll set NEVER_EXTRACTABLE == FALSE and ALWAYS_SENSITIVE == FALSE // If the key is being created with KEYGEN, it will adjust as necessary. // never_extr_attr->type = CKA_NEVER_EXTRACTABLE; never_extr_attr->ulValueLen = sizeof(CK_BBOOL); never_extr_attr->pValue = (CK_BYTE *)never_extr_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)never_extr_attr->pValue = FALSE; always_sens_attr->type = CKA_ALWAYS_SENSITIVE; always_sens_attr->ulValueLen = sizeof(CK_BBOOL); always_sens_attr->pValue = (CK_BYTE *)always_sens_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)always_sens_attr->pValue = FALSE; template_update_attribute( tmpl, class_attr ); template_update_attribute( tmpl, subject_attr ); template_update_attribute( tmpl, sensitive_attr ); template_update_attribute( tmpl, decrypt_attr ); template_update_attribute( tmpl, sign_attr ); template_update_attribute( tmpl, sign_recover_attr ); template_update_attribute( tmpl, unwrap_attr ); template_update_attribute( tmpl, extractable_attr ); template_update_attribute( tmpl, never_extr_attr ); template_update_attribute( tmpl, always_sens_attr ); return CKR_OK; } // // CK_RV priv_key_unwrap( TEMPLATE *tmpl, CK_ULONG keytype, CK_BYTE *data, CK_ULONG data_len ) { CK_ATTRIBUTE *extractable = NULL; CK_ATTRIBUTE *always_sens = NULL; CK_ATTRIBUTE *never_extract = NULL; CK_ATTRIBUTE *sensitive = NULL; CK_ATTRIBUTE *local = NULL; CK_BBOOL true = TRUE; CK_BBOOL false = FALSE; CK_RV rc; switch (keytype) { case CKK_RSA: rc = rsa_priv_unwrap( tmpl, data, data_len ); break; case CKK_DSA: rc = dsa_priv_unwrap( tmpl, data, data_len ); break; default: st_err_log(62, __FILE__, __LINE__); return CKR_WRAPPED_KEY_INVALID; } if (rc != CKR_OK) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return rc; } // make sure // CKA_LOCAL == FALSE // CKA_ALWAYS_SENSITIVE == FALSE // CKA_EXTRACTABLE == TRUE // CKA_NEVER_EXTRACTABLE == FALSE // rc = build_attribute( CKA_LOCAL, &false, 1, &local ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } rc = build_attribute( CKA_ALWAYS_SENSITIVE, &false, 1, &always_sens ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } rc = build_attribute( CKA_SENSITIVE, &false, 1, &sensitive ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } rc = build_attribute( CKA_EXTRACTABLE, &true, 1, &extractable ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } rc = build_attribute( CKA_NEVER_EXTRACTABLE, &false, 1, &never_extract ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } template_update_attribute( tmpl, local ); template_update_attribute( tmpl, always_sens ); template_update_attribute( tmpl, sensitive ); template_update_attribute( tmpl, extractable ); template_update_attribute( tmpl, never_extract ); return CKR_OK; cleanup: if (local) free(local); if (always_sens) free(always_sens); if (extractable) free(extractable); if (never_extract) free(never_extract); return rc; } // priv_key_validate_attribute() // CK_RV priv_key_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_SUBJECT: return CKR_OK; case CKA_DECRYPT: case CKA_SIGN: case CKA_SIGN_RECOVER: case CKA_UNWRAP: // we might want to do this for MODE_COPY too // if (mode == MODE_MODIFY) { if (nv_token_data->tweak_vector.allow_key_mods == TRUE) return CKR_OK; st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } return CKR_OK; // after key creation, CKA_SENSITIVE may only be set to TRUE // case CKA_SENSITIVE: { CK_BBOOL value; if (mode == MODE_CREATE || mode == MODE_KEYGEN) return CKR_OK; value = *(CK_BBOOL *)attr->pValue; if (value != TRUE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } } return CKR_OK; // after key creation, CKA_EXTRACTABLE may only be set to FALSE // case CKA_EXTRACTABLE: { CK_BBOOL value; value = *(CK_BBOOL *)attr->pValue; if ((mode != MODE_CREATE && mode != MODE_KEYGEN) && value != FALSE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } if (value == FALSE) { CK_ATTRIBUTE *attr; attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!attr){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } attr->type = CKA_NEVER_EXTRACTABLE; attr->ulValueLen = sizeof(CK_BBOOL); attr->pValue = (CK_BYTE *)attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)attr->pValue = FALSE; template_update_attribute( tmpl, attr ); } } return CKR_OK; case CKA_ALWAYS_SENSITIVE: case CKA_NEVER_EXTRACTABLE: st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; default: return key_object_validate_attribute( tmpl, attr, mode ); } st_err_log(8, __FILE__, __LINE__); return CKR_ATTRIBUTE_TYPE_INVALID; } // secret_key_check_required_attributes() // CK_RV secret_key_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { return key_object_check_required_attributes( tmpl, mode ); } // secret_key_set_default_attributes() // // some of the common secret key attributes have defaults but none of the specific // secret keytypes have default attributes // CK_RV secret_key_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *class_attr = NULL; CK_ATTRIBUTE *sensitive_attr = NULL; CK_ATTRIBUTE *encrypt_attr = NULL; CK_ATTRIBUTE *decrypt_attr = NULL; CK_ATTRIBUTE *sign_attr = NULL; CK_ATTRIBUTE *verify_attr = NULL; CK_ATTRIBUTE *wrap_attr = NULL; CK_ATTRIBUTE *unwrap_attr = NULL; CK_ATTRIBUTE *extractable_attr = NULL; CK_ATTRIBUTE *never_extr_attr = NULL; CK_ATTRIBUTE *always_sens_attr = NULL; CK_RV rc; rc = key_object_set_default_attributes( tmpl, mode ); if (rc != CKR_OK) return rc; // add the default CKO_DATA attributes // class_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS) ); sensitive_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); encrypt_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); decrypt_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); sign_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); verify_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); wrap_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); unwrap_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); extractable_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); never_extr_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); always_sens_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!class_attr || !sensitive_attr || !encrypt_attr || !decrypt_attr || !sign_attr || !verify_attr || !wrap_attr || !unwrap_attr || !extractable_attr || !never_extr_attr || !always_sens_attr) { if (class_attr) free( class_attr ); if (sensitive_attr) free( sensitive_attr ); if (encrypt_attr) free( encrypt_attr ); if (decrypt_attr) free( decrypt_attr ); if (sign_attr) free( sign_attr ); if (verify_attr) free( verify_attr ); if (wrap_attr) free( wrap_attr ); if (unwrap_attr) free( unwrap_attr ); if (extractable_attr) free( extractable_attr ); if (never_extr_attr) free( never_extr_attr ); if (always_sens_attr) free( always_sens_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } class_attr->type = CKA_CLASS; class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS); class_attr->pValue = (CK_BYTE *)class_attr + sizeof(CK_ATTRIBUTE); *(CK_OBJECT_CLASS *)class_attr->pValue = CKO_SECRET_KEY; sensitive_attr->type = CKA_SENSITIVE; sensitive_attr->ulValueLen = sizeof(CK_BBOOL); sensitive_attr->pValue = (CK_BYTE *)sensitive_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)sensitive_attr->pValue = FALSE; encrypt_attr->type = CKA_ENCRYPT; encrypt_attr->ulValueLen = sizeof(CK_BBOOL); encrypt_attr->pValue = (CK_BYTE *)encrypt_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)encrypt_attr->pValue = TRUE; decrypt_attr->type = CKA_DECRYPT; decrypt_attr->ulValueLen = sizeof(CK_BBOOL); decrypt_attr->pValue = (CK_BYTE *)decrypt_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)decrypt_attr->pValue = TRUE; sign_attr->type = CKA_SIGN; sign_attr->ulValueLen = sizeof(CK_BBOOL); sign_attr->pValue = (CK_BYTE *)sign_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)sign_attr->pValue = TRUE; verify_attr->type = CKA_VERIFY; verify_attr->ulValueLen = sizeof(CK_BBOOL); verify_attr->pValue = (CK_BYTE *)verify_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)verify_attr->pValue = TRUE; wrap_attr->type = CKA_WRAP; wrap_attr->ulValueLen = sizeof(CK_BBOOL); wrap_attr->pValue = (CK_BYTE *)wrap_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)wrap_attr->pValue = TRUE; unwrap_attr->type = CKA_UNWRAP; unwrap_attr->ulValueLen = sizeof(CK_BBOOL); unwrap_attr->pValue = (CK_BYTE *)unwrap_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)unwrap_attr->pValue = TRUE; extractable_attr->type = CKA_EXTRACTABLE; extractable_attr->ulValueLen = sizeof(CK_BBOOL); extractable_attr->pValue = (CK_BYTE *)extractable_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)extractable_attr->pValue = TRUE; // by default, we'll set NEVER_EXTRACTABLE == FALSE and ALWAYS_SENSITIVE == FALSE // If the key is being created with KEYGEN, it will adjust as necessary. // always_sens_attr->type = CKA_ALWAYS_SENSITIVE; always_sens_attr->ulValueLen = sizeof(CK_BBOOL); always_sens_attr->pValue = (CK_BYTE *)always_sens_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)always_sens_attr->pValue = FALSE; never_extr_attr->type = CKA_NEVER_EXTRACTABLE; never_extr_attr->ulValueLen = sizeof(CK_BBOOL); never_extr_attr->pValue = (CK_BYTE *)never_extr_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)never_extr_attr->pValue = FALSE; template_update_attribute( tmpl, class_attr ); template_update_attribute( tmpl, sensitive_attr ); template_update_attribute( tmpl, encrypt_attr ); template_update_attribute( tmpl, decrypt_attr ); template_update_attribute( tmpl, sign_attr ); template_update_attribute( tmpl, verify_attr ); template_update_attribute( tmpl, wrap_attr ); template_update_attribute( tmpl, unwrap_attr ); template_update_attribute( tmpl, extractable_attr ); template_update_attribute( tmpl, never_extr_attr ); template_update_attribute( tmpl, always_sens_attr ); return CKR_OK; } // // CK_RV secret_key_unwrap( TEMPLATE *tmpl, CK_ULONG keytype, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ) { CK_ATTRIBUTE *local = NULL; CK_ATTRIBUTE *always_sens = NULL; CK_ATTRIBUTE *sensitive = NULL; CK_ATTRIBUTE *extractable = NULL; CK_ATTRIBUTE *never_extract = NULL; CK_BBOOL true = TRUE; CK_BBOOL false = FALSE; CK_RV rc; switch (keytype) { case CKK_CDMF: case CKK_DES: rc = des_unwrap( tmpl, data, data_len, fromend ); break; case CKK_DES3: rc = des3_unwrap( tmpl, data, data_len, fromend ); break; case CKK_AES: rc = aes_unwrap( tmpl, data, data_len, fromend ); break; case CKK_GENERIC_SECRET: case CKK_RC2: case CKK_RC4: case CKK_RC5: case CKK_CAST: case CKK_CAST3: case CKK_CAST5: rc = generic_secret_unwrap( tmpl, data, data_len, fromend ); break; default: st_err_log(62, __FILE__, __LINE__); return CKR_WRAPPED_KEY_INVALID; } if (rc != CKR_OK) return rc; // make sure // CKA_LOCAL == FALSE // CKA_ALWAYS_SENSITIVE == FALSE // CKA_EXTRACTABLE == TRUE // CKA_NEVER_EXTRACTABLE == FALSE // rc = build_attribute( CKA_LOCAL, &false, 1, &local ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } rc = build_attribute( CKA_ALWAYS_SENSITIVE, &false, 1, &always_sens ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } rc = build_attribute( CKA_SENSITIVE, &false, 1, &sensitive ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } rc = build_attribute( CKA_EXTRACTABLE, &true, 1, &extractable ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } rc = build_attribute( CKA_NEVER_EXTRACTABLE, &false, 1, &never_extract ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } template_update_attribute( tmpl, local ); template_update_attribute( tmpl, always_sens ); template_update_attribute( tmpl, sensitive ); template_update_attribute( tmpl, extractable ); template_update_attribute( tmpl, never_extract ); return CKR_OK; cleanup: if (local) free(local); if (extractable) free(extractable); if (always_sens) free(always_sens); if (never_extract) free(never_extract); return rc; } // secret_key_validate_attribute() // CK_RV secret_key_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_ENCRYPT: case CKA_DECRYPT: case CKA_SIGN: case CKA_VERIFY: case CKA_WRAP: case CKA_UNWRAP: if (mode == MODE_MODIFY) { if (nv_token_data->tweak_vector.allow_key_mods == TRUE) return CKR_OK; st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } return CKR_OK; // after key creation, CKA_SENSITIVE may only be set to TRUE // case CKA_SENSITIVE: { CK_BBOOL value; value = *(CK_BBOOL *)attr->pValue; if ((mode != MODE_CREATE && mode != MODE_DERIVE && mode != MODE_KEYGEN) && (value != TRUE)){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } } return CKR_OK; // after key creation, CKA_EXTRACTABLE may only be set to FALSE // case CKA_EXTRACTABLE: { CK_BBOOL value; // the unwrap routine will automatically set extractable to TRUE // value = *(CK_BBOOL *)attr->pValue; if ((mode != MODE_CREATE && mode != MODE_DERIVE && mode != MODE_KEYGEN) && (value != FALSE)){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } if (value == FALSE) { CK_ATTRIBUTE *attr; attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!attr){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } attr->type = CKA_NEVER_EXTRACTABLE; attr->ulValueLen = sizeof(CK_BBOOL); attr->pValue = (CK_BYTE *)attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)attr->pValue = FALSE; template_update_attribute( tmpl, attr ); } } return CKR_OK; case CKA_ALWAYS_SENSITIVE: case CKA_NEVER_EXTRACTABLE: st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; default: return key_object_validate_attribute( tmpl, attr, mode ); } st_err_log(8, __FILE__, __LINE__); return CKR_ATTRIBUTE_TYPE_INVALID; } // secret_key_check_exportability() // CK_BBOOL secret_key_check_exportability( CK_ATTRIBUTE_TYPE type ) { switch (type) { case CKA_VALUE: st_err_log(86, __FILE__, __LINE__); return FALSE; } return TRUE; } // rsa_publ_check_required_attributes() // CK_RV rsa_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_MODULUS, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_MODULUS_BITS, &attr ); if (!found) { if (mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_PUBLIC_EXPONENT, &attr ); if (!found) { if (mode == MODE_CREATE || mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return publ_key_check_required_attributes( tmpl, mode ); } // rsa_publ_set_default_attributes() // CK_RV rsa_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *type_attr = NULL; CK_ATTRIBUTE *modulus_attr = NULL; CK_ATTRIBUTE *modulus_bits_attr = NULL; CK_ATTRIBUTE *public_exp_attr = NULL; CK_ULONG bits = 0L; publ_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); modulus_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); modulus_bits_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); public_exp_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !modulus_attr || !modulus_bits_attr || !public_exp_attr) { if (type_attr) free( type_attr ); if (modulus_attr) free( modulus_attr ); if (modulus_bits_attr) free( modulus_bits_attr ); if (public_exp_attr) free( public_exp_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_RSA; modulus_attr->type = CKA_MODULUS; modulus_attr->ulValueLen = 0; modulus_attr->pValue = NULL; modulus_bits_attr->type = CKA_MODULUS_BITS; modulus_bits_attr->ulValueLen = sizeof(CK_ULONG); modulus_bits_attr->pValue = (CK_BYTE *)modulus_bits_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)modulus_bits_attr->pValue = bits; public_exp_attr->type = CKA_PUBLIC_EXPONENT; public_exp_attr->ulValueLen = 0; public_exp_attr->pValue = NULL; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, modulus_attr ); template_update_attribute( tmpl, modulus_bits_attr ); template_update_attribute( tmpl, public_exp_attr ); return CKR_OK; } // rsa_publ_validate_attributes() // CK_RV rsa_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_MODULUS_BITS: if (mode == MODE_KEYGEN) { if (attr->ulValueLen != sizeof(CK_ULONG)){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else { CK_ULONG mod_bits = *(CK_ULONG *)attr->pValue; if (mod_bits < 512 || mod_bits > 4096){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } if (mod_bits % 8 != 0){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } return CKR_OK; } } else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_MODULUS: if (mode == MODE_CREATE) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_PUBLIC_EXPONENT: if (mode == MODE_CREATE || mode == MODE_KEYGEN) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } default: return publ_key_validate_attribute( tmpl, attr, mode ); } } // rsa_priv_check_required_attributes() // CK_RV rsa_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_MODULUS, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } // // PKCS #11 is flexible with respect to which attributes must be present // in an RSA key. Keys can be specified in Chinese-Remainder format or // they can be specified in modular-exponent format. Right now, I only // support keys created in Chinese-Remainder format. That is, we return // CKR_TEMPLATE_INCOMPLETE if a modular-exponent key is specified. This // is allowed by PKCS #11. // // In the future, we should allow for creation of keys in modular-exponent // format too. This raises some issues. It's easy enough to recognize // when a key has been specified in modular-exponent format. And it's // easy enough to recognize when all attributes have been specified // (which is what we require right now). What's trickier to handle is // the "middle" cases in which more than the minimum yet less than the // full number of attributes have been specified. Do we revert back to // modular-exponent representation? Do we compute the missing attributes // ourselves? Do we simply return CKR_TEMPLATE_INCOMPLETE? // found = template_attribute_find( tmpl, CKA_PUBLIC_EXPONENT, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_PRIVATE_EXPONENT, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_PRIME_1, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_PRIME_2, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_EXPONENT_1, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_EXPONENT_2, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_COEFFICIENT, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } // we should probably verify that the (e != p) and (e != q). ie. gcd(e,n) == 1 // return priv_key_check_required_attributes( tmpl, mode ); } // rsa_priv_set_default_attributes() // CK_RV rsa_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *modulus_attr = NULL; CK_ATTRIBUTE *public_exp_attr = NULL; CK_ATTRIBUTE *private_exp_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; // satisfy the compiler // if (mode) modulus_attr = NULL; priv_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); modulus_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); public_exp_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); private_exp_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !modulus_attr || !public_exp_attr || !private_exp_attr) { if (type_attr) free( type_attr ); if (modulus_attr) free( modulus_attr ); if (public_exp_attr) free( public_exp_attr ); if (private_exp_attr) free( private_exp_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } modulus_attr->type = CKA_MODULUS; modulus_attr->ulValueLen = 0; modulus_attr->pValue = NULL; public_exp_attr->type = CKA_PUBLIC_EXPONENT; public_exp_attr->ulValueLen = 0; public_exp_attr->pValue = NULL; private_exp_attr->type = CKA_PRIVATE_EXPONENT; private_exp_attr->ulValueLen = 0; private_exp_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_RSA; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, modulus_attr ); template_update_attribute( tmpl, public_exp_attr ); template_update_attribute( tmpl, private_exp_attr ); return CKR_OK; } // rsa_priv_validate_attributes() // CK_RV rsa_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_MODULUS: case CKA_PRIVATE_EXPONENT: if (mode == MODE_CREATE) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_PUBLIC_EXPONENT: case CKA_PRIME_1: case CKA_PRIME_2: case CKA_EXPONENT_1: case CKA_EXPONENT_2: case CKA_COEFFICIENT: if (mode == MODE_CREATE) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } default: return priv_key_validate_attribute( tmpl, attr, mode ); } } // rsa_priv_check_exportability() // CK_BBOOL rsa_priv_check_exportability( CK_ATTRIBUTE_TYPE type ) { switch (type) { case CKA_PRIVATE_EXPONENT: case CKA_PRIME_1: case CKA_PRIME_2: case CKA_EXPONENT_1: case CKA_EXPONENT_2: case CKA_COEFFICIENT: st_err_log(86, __FILE__, __LINE__); return FALSE; } return TRUE; } // create the ASN.1 encoding for the private key for wrapping as defined // in PKCS #8 // // ASN.1 type PrivateKeyInfo ::= SEQUENCE { // version Version // privateKeyAlgorithm PrivateKeyAlgorithmIdentifier // privateKey PrivateKey // attributes OPTIONAL // } // // Where PrivateKey is defined as follows for RSA: // // ASN.1 type RSAPrivateKey // // RSAPrivateKey ::= SEQUENCE { // version Version // modulus INTEGER // publicExponent INTEGER // privateExponent INTEGER // prime1 INTEGER // prime2 INTEGER // exponent1 INTEGER // exponent2 INTEGER // coefficient INTEGER // } // CK_RV rsa_priv_wrap_get_data( TEMPLATE *tmpl, CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ) { CK_ATTRIBUTE *modulus = NULL; CK_ATTRIBUTE *publ_exp = NULL, *priv_exp = NULL; CK_ATTRIBUTE *prime1 = NULL, *prime2 = NULL; CK_ATTRIBUTE *exponent1 = NULL, *exponent2 = NULL; CK_ATTRIBUTE *coeff = NULL; CK_RV rc; // compute the total length of the BER-encoded data // if (template_attribute_find(tmpl, CKA_MODULUS, &modulus) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (template_attribute_find(tmpl, CKA_PUBLIC_EXPONENT, &publ_exp) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (template_attribute_find(tmpl, CKA_PRIVATE_EXPONENT, &priv_exp) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (template_attribute_find(tmpl, CKA_PRIME_1, &prime1) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (template_attribute_find(tmpl, CKA_PRIME_2, &prime2) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (template_attribute_find(tmpl, CKA_EXPONENT_1, &exponent1) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (template_attribute_find(tmpl, CKA_EXPONENT_2, &exponent2) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (template_attribute_find(tmpl, CKA_COEFFICIENT, &coeff) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = ber_encode_RSAPrivateKey( length_only, data, data_len, modulus, publ_exp, priv_exp, prime1, prime2, exponent1, exponent2, coeff ); if (rc != CKR_OK){ st_err_log(87, __FILE__, __LINE__); } return rc; } // // CK_RV rsa_priv_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG total_length ) { CK_ATTRIBUTE *modulus = NULL; CK_ATTRIBUTE *publ_exp = NULL; CK_ATTRIBUTE *priv_exp = NULL; CK_ATTRIBUTE *prime1 = NULL; CK_ATTRIBUTE *prime2 = NULL; CK_ATTRIBUTE *exponent1 = NULL; CK_ATTRIBUTE *exponent2 = NULL; CK_ATTRIBUTE *coeff = NULL; CK_RV rc; rc = ber_decode_RSAPrivateKey( data, total_length, &modulus, &publ_exp, &priv_exp, &prime1, &prime2, &exponent1, &exponent2, &coeff ); if (rc != CKR_OK){ st_err_log(88, __FILE__, __LINE__); return rc; } remove_leading_zeros( modulus ); remove_leading_zeros( publ_exp ); remove_leading_zeros( priv_exp ); remove_leading_zeros( prime1 ); remove_leading_zeros( prime2 ); remove_leading_zeros( exponent1 ); remove_leading_zeros( exponent2 ); remove_leading_zeros( coeff ); template_update_attribute( tmpl, modulus ); template_update_attribute( tmpl, publ_exp ); template_update_attribute( tmpl, priv_exp ); template_update_attribute( tmpl, prime1 ); template_update_attribute( tmpl, prime2 ); template_update_attribute( tmpl, exponent1 ); template_update_attribute( tmpl, exponent2 ); template_update_attribute( tmpl, coeff ); return CKR_OK; } // dsa_publ_check_required_attributes() // CK_RV dsa_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_PRIME, &attr ); if (!found) { if (mode == MODE_CREATE || mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_SUBPRIME, &attr ); if (!found) { if (mode == MODE_CREATE || mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_BASE, &attr ); if (!found) { if (mode == MODE_CREATE || mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return publ_key_check_required_attributes( tmpl, mode ); } // dsa_publ_set_default_attributes() // CK_RV dsa_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *prime_attr = NULL; CK_ATTRIBUTE *subprime_attr = NULL; CK_ATTRIBUTE *base_attr = NULL; CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) prime_attr = NULL; publ_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); prime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); subprime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); base_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !prime_attr || !subprime_attr || !base_attr || !value_attr) { if (type_attr) free( type_attr ); if (prime_attr) free( prime_attr ); if (subprime_attr) free( subprime_attr ); if (base_attr) free( base_attr ); if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } prime_attr->type = CKA_PRIME; prime_attr->ulValueLen = 0; prime_attr->pValue = NULL; subprime_attr->type = CKA_SUBPRIME; subprime_attr->ulValueLen = 0; subprime_attr->pValue = NULL; base_attr->type = CKA_BASE; base_attr->ulValueLen = 0; base_attr->pValue = NULL; value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_DSA; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, prime_attr ); template_update_attribute( tmpl, subprime_attr ); template_update_attribute( tmpl, base_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // dsa_publ_validate_attributes() // CK_RV dsa_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_PRIME: { CK_ULONG size; if (mode != MODE_CREATE && mode != MODE_KEYGEN){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } // must be between [512, 1024] bits, and a multiple of 64 bits // size = attr->ulValueLen; if (size < 64 || size > 128 || (size % 8 != 0)){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } return remove_leading_zeros( attr ); } case CKA_SUBPRIME: { if (mode != MODE_CREATE && mode != MODE_KEYGEN){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } // subprime must be 160 bits // if (attr->ulValueLen != 20){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } return remove_leading_zeros( attr ); } case CKA_BASE: if (mode == MODE_CREATE || mode == MODE_KEYGEN) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_VALUE: if (mode == MODE_CREATE) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } default: return publ_key_validate_attribute( tmpl, attr, mode ); } } // dsa_priv_check_required_attributes() // CK_RV dsa_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_PRIME, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_SUBPRIME, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_BASE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return priv_key_check_required_attributes( tmpl, mode ); } // dsa_priv_set_default_attributes() // CK_RV dsa_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *prime_attr = NULL; CK_ATTRIBUTE *subprime_attr = NULL; CK_ATTRIBUTE *base_attr = NULL; CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) prime_attr = NULL; priv_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); prime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); subprime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); base_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !prime_attr || !subprime_attr || !base_attr || !value_attr) { if (type_attr) free( type_attr ); if (prime_attr) free( prime_attr ); if (subprime_attr) free( subprime_attr ); if (base_attr) free( base_attr ); if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } prime_attr->type = CKA_PRIME; prime_attr->ulValueLen = 0; prime_attr->pValue = NULL; subprime_attr->type = CKA_SUBPRIME; subprime_attr->ulValueLen = 0; subprime_attr->pValue = NULL; base_attr->type = CKA_BASE; base_attr->ulValueLen = 0; base_attr->pValue = NULL; value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_DSA; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, prime_attr ); template_update_attribute( tmpl, subprime_attr ); template_update_attribute( tmpl, base_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // dsa_priv_validate_attributes() // CK_RV dsa_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_PRIME: { CK_ULONG size; if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } // must be between [512, 1024] bits, and a multiple of 64 bits // size = attr->ulValueLen; if (size < 64 || size > 128 || (size % 8 != 0)){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } return remove_leading_zeros( attr ); } case CKA_SUBPRIME: { if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } // subprime must be 160 bits // if (attr->ulValueLen != 20){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } return remove_leading_zeros( attr ); } case CKA_BASE: case CKA_VALUE: if (mode == MODE_CREATE) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } default: return priv_key_validate_attribute( tmpl, attr, mode ); } } // dsa_priv_check_exportability() // CK_BBOOL dsa_priv_check_exportability( CK_ATTRIBUTE_TYPE type ) { switch (type) { case CKA_VALUE: return FALSE; } return TRUE; } // create the ASN.1 encoding for the private key for wrapping as defined // in PKCS #8 // // ASN.1 type PrivateKeyInfo ::= SEQUENCE { // version Version // privateKeyAlgorithm PrivateKeyAlgorithmIdentifier // privateKey PrivateKey // attributes OPTIONAL // } // // PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier // // AlgorithmIdentifier ::= SEQUENCE { // algorithm OBJECT IDENTIFIER // parameters ANY DEFINED BY algorithm OPTIONAL // } // // paramters ::= SEQUENCE { // p INTEGER // q INTEGER // g INTEGER // } // // privateKey ::= INTEGER // // CK_RV dsa_priv_wrap_get_data( TEMPLATE *tmpl, CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ) { CK_ATTRIBUTE *prime = NULL; CK_ATTRIBUTE *subprime = NULL; CK_ATTRIBUTE *base = NULL; CK_ATTRIBUTE *value = NULL; CK_RV rc; // compute the total length of the BER-encoded data // if (template_attribute_find(tmpl, CKA_PRIME, &prime) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (template_attribute_find(tmpl, CKA_SUBPRIME, &subprime) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (template_attribute_find(tmpl, CKA_BASE, &base) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (template_attribute_find(tmpl, CKA_VALUE, &value) == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = ber_encode_DSAPrivateKey( length_only, data, data_len, prime, subprime, base, value ); if (rc != CKR_OK){ st_err_log(87, __FILE__, __LINE__); } return rc; } // // CK_RV dsa_priv_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG total_length ) { CK_ATTRIBUTE *prime = NULL; CK_ATTRIBUTE *subprime = NULL; CK_ATTRIBUTE *base = NULL; CK_ATTRIBUTE *value = NULL; CK_RV rc; rc = ber_decode_DSAPrivateKey( data, total_length, &prime, &subprime, &base, &value ); if (rc != CKR_OK){ st_err_log(88, __FILE__, __LINE__); return rc; } remove_leading_zeros( prime ); remove_leading_zeros( subprime ); remove_leading_zeros( base ); remove_leading_zeros( value ); template_update_attribute( tmpl, prime ); template_update_attribute( tmpl, subprime ); template_update_attribute( tmpl, base ); template_update_attribute( tmpl, value ); return CKR_OK; } // ecdsa_publ_check_required_attributes() // CK_RV ecdsa_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_ECDSA_PARAMS, &attr ); if (!found) { if (mode == MODE_CREATE || mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_EC_POINT, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return publ_key_check_required_attributes( tmpl, mode ); } // ecdsa_publ_set_default_attributes() // CK_RV ecdsa_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *params_attr = NULL; CK_ATTRIBUTE *ec_point_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) params_attr = NULL; publ_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); params_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); ec_point_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !params_attr || !ec_point_attr) { if (type_attr) free( type_attr ); if (params_attr) free( params_attr ); if (ec_point_attr) free( ec_point_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } params_attr->type = CKA_ECDSA_PARAMS; params_attr->ulValueLen = 0; params_attr->pValue = NULL; ec_point_attr->type = CKA_EC_POINT; ec_point_attr->ulValueLen = 0; ec_point_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_ECDSA; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, params_attr ); template_update_attribute( tmpl, ec_point_attr ); return CKR_OK; } // ecdsa_publ_validate_attributes() // CK_RV ecdsa_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_ECDSA_PARAMS: if (mode == MODE_CREATE || mode == MODE_KEYGEN) return CKR_OK; else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_EC_POINT: if (mode == MODE_CREATE) return CKR_OK; else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } default: return publ_key_validate_attribute( tmpl, attr, mode ); } } // ecdsa_priv_check_required_attributes() // CK_RV ecdsa_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_ECDSA_PARAMS, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_EC_POINT, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return priv_key_check_required_attributes( tmpl, mode ); } // ecdsa_priv_set_default_attributes() // CK_RV ecdsa_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *params_attr = NULL; CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) params_attr = NULL; priv_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); params_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !params_attr || !value_attr) { if (type_attr) free( type_attr ); if (params_attr) free( params_attr ); if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } params_attr->type = CKA_ECDSA_PARAMS; params_attr->ulValueLen = 0; params_attr->pValue = NULL; value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_ECDSA; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, params_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // ecdsa_priv_validate_attributes() // CK_RV ecdsa_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_ECDSA_PARAMS: if (mode == MODE_CREATE) return CKR_OK; else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_VALUE: if (mode == MODE_CREATE) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } default: return priv_key_validate_attribute( tmpl, attr, mode ); } } // ecdsa_priv_check_exportability() // CK_BBOOL ecdsa_priv_check_exportability( CK_ATTRIBUTE_TYPE type ) { switch (type) { case CKA_VALUE: return FALSE; } return TRUE; } // dh_publ_check_required_attributes() // CK_RV dh_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_PRIME, &attr ); if (!found) { if (mode == MODE_CREATE || mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_BASE, &attr ); if (!found) { if (mode == MODE_CREATE || mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return publ_key_check_required_attributes( tmpl, mode ); } // dh_publ_set_default_attributes() // CK_RV dh_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *prime_attr = NULL; CK_ATTRIBUTE *base_attr = NULL; CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) prime_attr = NULL; publ_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); prime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); base_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !prime_attr || !base_attr || !value_attr) { if (type_attr) free( type_attr ); if (prime_attr) free( prime_attr ); if (base_attr) free( base_attr ); if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } prime_attr->type = CKA_PRIME; prime_attr->ulValueLen = 0; prime_attr->pValue = NULL; base_attr->type = CKA_BASE; base_attr->ulValueLen = 0; base_attr->pValue = NULL; value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_DH; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, prime_attr ); template_update_attribute( tmpl, base_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // dh_publ_validate_attribute() // CK_RV dh_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_PRIME: case CKA_BASE: if (mode == MODE_CREATE || mode == MODE_KEYGEN) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_VALUE: if (mode == MODE_CREATE) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } default: return publ_key_validate_attribute( tmpl, attr, mode ); } } // dh_priv_check_required_attributes() // CK_RV dh_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_PRIME, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_BASE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE_BITS, &attr ); if (found) { if (mode == MODE_CREATE || mode == MODE_UNWRAP){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } } return priv_key_check_required_attributes( tmpl, mode ); } // dh_priv_set_default_attributes() // CK_RV dh_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *prime_attr = NULL; CK_ATTRIBUTE *base_attr = NULL; CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *value_bits_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; CK_ULONG bits = 0L; priv_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); prime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); base_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_bits_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); if (!type_attr || !prime_attr || !base_attr || !value_attr || !value_bits_attr) { if (type_attr) free( type_attr ); if (prime_attr) free( prime_attr ); if (base_attr) free( base_attr ); if (value_attr) free( value_attr ); if (value_bits_attr) free( value_bits_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } prime_attr->type = CKA_PRIME; prime_attr->ulValueLen = 0; prime_attr->pValue = NULL; base_attr->type = CKA_BASE; base_attr->ulValueLen = 0; base_attr->pValue = NULL; value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; value_bits_attr->type = CKA_VALUE_BITS; value_bits_attr->ulValueLen = sizeof(CK_ULONG); value_bits_attr->pValue = (CK_BYTE *)value_bits_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_bits_attr->pValue = bits; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_DH; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, prime_attr ); template_update_attribute( tmpl, base_attr ); template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, value_bits_attr ); return CKR_OK; } // dh_priv_validate_attribute() // CK_RV dh_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_PRIME: case CKA_BASE: case CKA_VALUE: if (mode == MODE_CREATE || mode == MODE_KEYGEN) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } // I'm not sure what to do about VALUE_BITS...we don't really support // Diffie-Hellman keys other than for storage...when the object is // created, we're supposed to add CKA_VALUE_BITS outselves...which we // don't do at this time. (we'd need to add code in C_CreateObject to // call some sort of objecttype-specific callback) // // kapil 05/08/03 : Commented out error flagging, as CKA_VALUE_BITS is valid // attribute for creating DH priv object. The above is // an older comment. case CKA_VALUE_BITS: // st_err_log(7, __FILE__, __LINE__); // return CKR_ATTRIBUTE_READ_ONLY; return CKR_OK ; break ; default: return priv_key_validate_attribute( tmpl, attr, mode ); } } // dh_priv_check_exportability() // CK_BBOOL dh_priv_check_exportability( CK_ATTRIBUTE_TYPE type ) { switch (type) { case CKA_VALUE: return FALSE; } return TRUE; } // kea_publ_check_required_attributes() // CK_RV kea_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_PRIME, &attr ); if (!found) { if (mode == MODE_CREATE || mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_SUBPRIME, &attr ); if (!found) { if (mode == MODE_CREATE || mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_BASE, &attr ); if (!found) { if (mode == MODE_CREATE || mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return publ_key_check_required_attributes( tmpl, mode ); } // kea_publ_set_default_attributes() // CK_RV kea_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *prime_attr = NULL; CK_ATTRIBUTE *subprime_attr = NULL; CK_ATTRIBUTE *base_attr = NULL; CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) prime_attr = NULL; publ_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); prime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); subprime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); base_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !prime_attr || !subprime_attr || !base_attr || !value_attr) { if (type_attr) free( type_attr ); if (prime_attr) free( prime_attr ); if (subprime_attr) free( subprime_attr ); if (base_attr) free( base_attr ); if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } prime_attr->type = CKA_PRIME; prime_attr->ulValueLen = 0; prime_attr->pValue = NULL; subprime_attr->type = CKA_SUBPRIME; subprime_attr->ulValueLen = 0; subprime_attr->pValue = NULL; base_attr->type = CKA_BASE; base_attr->ulValueLen = 0; base_attr->pValue = NULL; value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_KEA; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, prime_attr ); template_update_attribute( tmpl, subprime_attr ); template_update_attribute( tmpl, base_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // kea_publ_validate_attribute() // CK_RV kea_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_PRIME: case CKA_SUBPRIME: case CKA_BASE: if (mode == MODE_CREATE || mode == MODE_KEYGEN) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_VALUE: if (mode == MODE_CREATE) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } default: return publ_key_validate_attribute( tmpl, attr, mode ); } } // kea_priv_check_required_attributes() // CK_RV kea_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_PRIME, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_SUBPRIME, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_BASE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return priv_key_check_required_attributes( tmpl, mode ); } // kea_priv_set_default_attributes() // CK_RV kea_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *prime_attr = NULL; CK_ATTRIBUTE *subprime_attr = NULL; CK_ATTRIBUTE *base_attr = NULL; CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) prime_attr = NULL; priv_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); prime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); subprime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); base_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !prime_attr || !base_attr || !value_attr || !subprime_attr) { if (prime_attr) free( prime_attr ); if (subprime_attr) free( subprime_attr ); if (base_attr) free( base_attr ); if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } prime_attr->type = CKA_PRIME; prime_attr->ulValueLen = 0; prime_attr->pValue = NULL; subprime_attr->type = CKA_SUBPRIME; subprime_attr->ulValueLen = 0; subprime_attr->pValue = NULL; base_attr->type = CKA_BASE; base_attr->ulValueLen = 0; base_attr->pValue = NULL; value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_KEA; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, prime_attr ); template_update_attribute( tmpl, subprime_attr ); template_update_attribute( tmpl, base_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // kea_priv_validate_attribute() // CK_RV kea_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_PRIME: case CKA_SUBPRIME: case CKA_BASE: case CKA_VALUE: if (mode == MODE_CREATE) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } default: return priv_key_validate_attribute( tmpl, attr, mode ); } } // kea_priv_check_exportability() // CK_BBOOL kea_priv_check_exportability( CK_ATTRIBUTE_TYPE type ) { switch (type) { case CKA_VALUE: return FALSE; } return TRUE; } // generic_secret_check_required_attributes() // CK_RV generic_secret_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE_LEN, &attr ); if (!found) { // here's another place where PKCS #11 deviates from its own specification. // the spec states that VALUE_LEN must be present for KEYGEN but later // it's merely optional if the mechanism is CKM_SSL3_PRE_MASTER_KEY_GEN. // Unfortunately, we can't check the mechanism at this point // return CKR_OK; } else { // Another contradiction within the spec: When describing the key types // the spec says that VALUE_LEN must not be specified when unwrapping // a key. In the section describing the mechanisms, though, it's allowed for // most unwrapping mechanisms. Netscape DOES does specify this attribute // when unwrapping. // if (mode == MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } } return secret_key_check_required_attributes( tmpl, mode ); } // generic_secret_set_default_attributes() // CK_RV generic_secret_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *value_len_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; CK_ULONG len = 0L; if (mode) value_attr = NULL; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_len_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); if (!type_attr || !value_attr || !value_len_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); if (value_len_attr) free( value_len_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; value_len_attr->type = CKA_VALUE_LEN; value_len_attr->ulValueLen = sizeof(CK_ULONG); value_len_attr->pValue = (CK_BYTE *)value_len_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_len_attr->pValue = len; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_GENERIC_SECRET; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, value_len_attr ); return CKR_OK; } // generic_secret_validate_attribute() // CK_RV generic_secret_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_VALUE: if (mode == MODE_CREATE) return CKR_OK; else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } // Another contradiction within the spec: When describing the key types // the spec says that VALUE_LEN must not be specified when unwrapping // a key. In the section describing the mechanisms, though, it's allowed for // most unwrapping mechanisms. Netscape DOES does specify this attribute // when unwrapping. // case CKA_VALUE_LEN: if (mode == MODE_KEYGEN || mode == MODE_DERIVE) return CKR_OK; else { if (mode == MODE_UNWRAP) { if (nv_token_data->tweak_vector.netscape_mods == TRUE) return CKR_OK; } st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // generic_secret_check_exportability() // CK_BBOOL generic_secret_check_exportability( CK_ATTRIBUTE_TYPE type ) { switch (type) { case CKA_VALUE: return FALSE; } return TRUE; } // // CK_RV generic_secret_wrap_get_data( TEMPLATE * tmpl, CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len ) { CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_RV rc; if (!tmpl || !data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } *data_len = attr->ulValueLen; if (length_only == FALSE) { ptr = (CK_BYTE *)malloc( attr->ulValueLen ); if (!ptr){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( ptr, attr->pValue, attr->ulValueLen ); *data = ptr; } return CKR_OK; } // // CK_RV generic_secret_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ) { CK_ATTRIBUTE * attr = NULL; CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * value_len_attr = NULL; CK_BYTE * ptr = NULL; CK_ULONG rc, len = 0; if (fromend == TRUE) ptr = data + data_len; else ptr = data; // it's possible that the user specified CKA_VALUE_LEN in the // template. if so, try to use it. by default, CKA_VALUE_LEN is 0 // rc = template_attribute_find( tmpl, CKA_VALUE_LEN, &attr ); if (rc) { len = *(CK_ULONG *)attr->pValue; if (len > data_len) { st_err_log(9, __FILE__, __LINE__); rc = CKR_ATTRIBUTE_VALUE_INVALID; goto error; } if (len != 0) data_len = len; } if (fromend == TRUE) ptr -= data_len; rc = build_attribute( CKA_VALUE, ptr, data_len, &value_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } if (data_len != len) { rc = build_attribute( CKA_VALUE_LEN, (CK_BYTE *)&data_len, sizeof(CK_ULONG), &value_len_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } } template_update_attribute( tmpl, value_attr ); if (data_len != len) template_update_attribute( tmpl, value_len_attr ); return CKR_OK; error: if (value_attr) free( value_attr ); if (value_len_attr) free( value_len_attr ); return rc; } // rc2_check_required_attributes() // CK_RV rc2_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE_LEN, &attr ); if (!found) { if (mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // rc2_set_default_attributes() // CK_RV rc2_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *value_len_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; CK_ULONG len = 0L; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_len_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); if (!type_attr || !value_attr || !value_len_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); if (value_len_attr) free( value_len_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; value_len_attr->type = CKA_VALUE_LEN; value_len_attr->ulValueLen = sizeof(CK_ULONG); value_len_attr->pValue = (CK_BYTE *)value_len_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_len_attr->pValue = len; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_RC2; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, value_len_attr ); return CKR_OK; } // rc2_validate_attribute() // CK_RV rc2_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_VALUE: if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } // rc2 key length <= 128 bytes // if (attr->ulValueLen > 128) return CKR_ATTRIBUTE_VALUE_INVALID; else return CKR_OK; case CKA_VALUE_LEN: { CK_ULONG len; if (mode != MODE_KEYGEN && mode != MODE_DERIVE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } len = *(CK_ULONG *)attr->pValue; if (len > 128){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // rc4_set_default_attributes() // CK_RV rc4_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *value_len_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; CK_ULONG len = 0L; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_len_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); if (!type_attr || !value_attr || !value_len_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); if (value_len_attr) free( value_len_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; value_len_attr->type = CKA_VALUE_LEN; value_len_attr->ulValueLen = sizeof(CK_ULONG); value_len_attr->pValue = (CK_BYTE *)value_len_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_len_attr->pValue = len; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_RC4; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, value_len_attr ); return CKR_OK; } // rc4_check_required_attributes() // CK_RV rc4_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE_LEN, &attr ); if (!found) { if (mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // rc4_validate_attribute() // CK_RV rc4_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_VALUE: { if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } // key length <= 256 bytes // if (attr->ulValueLen > 256){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } case CKA_VALUE_LEN: { CK_ULONG len; if (mode != MODE_KEYGEN && mode != MODE_DERIVE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } len = *(CK_ULONG *)attr->pValue; if (len > 255){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // rc5_check_required_attributes() // CK_RV rc5_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE_LEN, &attr ); if (!found) { if (mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // rc5_set_default_attributes() // CK_RV rc5_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *value_len_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; CK_ULONG len = 0L; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_len_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); if (!type_attr || !value_attr || !value_len_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); if (value_len_attr) free( value_len_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; value_len_attr->type = CKA_VALUE_LEN; value_len_attr->ulValueLen = sizeof(CK_ULONG); value_len_attr->pValue = (CK_BYTE *)value_len_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_len_attr->pValue = len; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_RC5; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, value_len_attr ); return CKR_OK; } // rc5_validate_attribute() // CK_RV rc5_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_VALUE: { if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } // key length <= 256 bytes // if (attr->ulValueLen > 255){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } case CKA_VALUE_LEN: { CK_ULONG len; if (mode != MODE_KEYGEN && mode != MODE_DERIVE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } len = *(CK_ULONG *)attr->pValue; if (len > 255){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // // CK_RV des_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // // CK_BBOOL des_check_weak_key( CK_BYTE *key ) { CK_ULONG i; for (i=0; i < des_weak_count; i++) { if (memcmp(key, des_weak_keys[i], DES_KEY_SIZE) == 0) return TRUE; } for (i=0; i < des_semi_weak_count; i++) { if (memcmp(key, des_semi_weak_keys[i], DES_KEY_SIZE) == 0) return TRUE; } for (i=0; i < des_possibly_weak_count; i++) { if (memcmp(key, des_possibly_weak_keys[i], DES_KEY_SIZE) == 0) return TRUE; } return FALSE; } // // CK_RV des_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * type_attr = NULL; if (mode) value_attr = NULL; secret_key_set_default_attributes( tmpl, mode ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); if (!value_attr || !type_attr) { if (value_attr) free( value_attr ); if (type_attr) free( type_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_DES; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // // CK_RV des_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ) { CK_ATTRIBUTE * value_attr = NULL; CK_BYTE * ptr = NULL; CK_ULONG i; if (data_len < DES_BLOCK_SIZE){ st_err_log(62, __FILE__, __LINE__); return CKR_WRAPPED_KEY_INVALID; } if (fromend == TRUE) ptr = data + data_len - DES_BLOCK_SIZE; else ptr = data; if (nv_token_data->tweak_vector.check_des_parity == TRUE) { for (i=0; i < DES_KEY_SIZE; i++) { if (parity_is_odd(ptr[i]) == FALSE){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } } } value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + DES_BLOCK_SIZE ); if (!value_attr) { if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = DES_BLOCK_SIZE; value_attr->pValue = (CK_BYTE *)value_attr + sizeof(CK_ATTRIBUTE); memcpy( value_attr->pValue, ptr, DES_BLOCK_SIZE ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // des_validate_attribute() // CK_RV des_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { CK_BYTE * ptr = NULL; CK_ULONG i; switch (attr->type) { case CKA_VALUE: // key length always 8 bytes // if (mode == MODE_CREATE) { if (attr->ulValueLen != DES_KEY_SIZE){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } if (nv_token_data->tweak_vector.check_des_parity == TRUE) { ptr = attr->pValue; for (i=0; i < DES_KEY_SIZE; i++) { if (parity_is_odd(ptr[i]) == FALSE){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } } } return CKR_OK; } else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_VALUE_LEN: // Cryptoki doesn't allow this but Netscape tries uses it // if (nv_token_data->tweak_vector.netscape_mods == TRUE) { if (mode == MODE_CREATE || mode == MODE_DERIVE || mode == MODE_KEYGEN || mode == MODE_UNWRAP) { CK_ULONG len = *(CK_ULONG *)attr->pValue; if (len != DES_KEY_SIZE){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } } else{ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // // CK_RV des_wrap_get_data( TEMPLATE * tmpl, CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len ) { CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_RV rc; if (!tmpl || !data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } *data_len = attr->ulValueLen; if (length_only == FALSE) { ptr = (CK_BYTE *)malloc( attr->ulValueLen ); if (!ptr){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( ptr, attr->pValue, attr->ulValueLen ); *data = ptr; } return CKR_OK; } // des2_check_required_attributes() // CK_RV des2_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // des2_set_default_attributes() // CK_RV des2_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * type_attr = NULL; if (mode) value_attr = NULL; secret_key_set_default_attributes( tmpl, mode ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); if (!value_attr || !type_attr) { if (value_attr) free( value_attr ); if (type_attr) free( type_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_DES2; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // des2_validate_attribute() // CK_RV des2_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { CK_BYTE * ptr = NULL; CK_ULONG i; switch (attr->type) { case CKA_VALUE: // key length always 16 bytes // if (mode == MODE_CREATE) { if (attr->ulValueLen != (2 * DES_KEY_SIZE)){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } if (nv_token_data->tweak_vector.check_des_parity == TRUE) { ptr = attr->pValue; for (i=0; i < 2*DES_KEY_SIZE; i++) { if (parity_is_odd(ptr[i]) == FALSE){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } } } return CKR_OK; } else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_VALUE_LEN: // Cryptoki doesn't allow this but Netscape tries uses it // if (nv_token_data->tweak_vector.netscape_mods == TRUE) { if (mode == MODE_CREATE || mode == MODE_DERIVE || mode == MODE_KEYGEN || mode == MODE_UNWRAP) { CK_ULONG len = *(CK_ULONG *)attr->pValue; if (len != (2 * DES_KEY_SIZE)){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } } else{ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // des3_check_required_attributes() // CK_RV des3_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // des3_set_default_attributes() // CK_RV des3_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * type_attr = NULL; if (mode) value_attr = NULL; secret_key_set_default_attributes( tmpl, mode ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); if (!value_attr || !type_attr) { if (value_attr) free( value_attr ); if (type_attr) free( type_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_DES3; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // // CK_RV des3_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ) { CK_ATTRIBUTE * value_attr = NULL; CK_BYTE * ptr = NULL; CK_ULONG i; if (data_len < 3 * DES_BLOCK_SIZE){ st_err_log(62, __FILE__, __LINE__); return CKR_WRAPPED_KEY_INVALID; } if (fromend == TRUE) ptr = data + data_len - (3*DES_BLOCK_SIZE); else ptr = data; if (nv_token_data->tweak_vector.check_des_parity == TRUE) { for (i=0; i < 3*DES_KEY_SIZE; i++) { if (parity_is_odd(ptr[i]) == FALSE){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } } } value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + (3 * DES_BLOCK_SIZE) ); if (!value_attr) { if (value_attr) free( value_attr ); st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 3 * DES_BLOCK_SIZE; value_attr->pValue = (CK_BYTE *)value_attr + sizeof(CK_ATTRIBUTE); memcpy( value_attr->pValue, ptr, 3 * DES_BLOCK_SIZE ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // // CK_RV des3_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { CK_BYTE * ptr = NULL; CK_ULONG i; switch (attr->type) { case CKA_VALUE: // key length always 24 bytes // if (mode == MODE_CREATE) { if (attr->ulValueLen != (3 * DES_KEY_SIZE)){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } if (nv_token_data->tweak_vector.check_des_parity == TRUE) { ptr = attr->pValue; for (i=0; i < 3*DES_KEY_SIZE; i++) { if (parity_is_odd(ptr[i]) == FALSE){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } } } return CKR_OK; } else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_VALUE_LEN: // Cryptoki doesn't allow this but Netscape tries uses it // if (nv_token_data->tweak_vector.netscape_mods == TRUE) { if (mode == MODE_CREATE || mode == MODE_DERIVE || mode == MODE_KEYGEN || mode == MODE_UNWRAP) { return CKR_OK; } else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } } else{ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // // CK_RV des3_wrap_get_data( TEMPLATE * tmpl, CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len ) { CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_RV rc; if (!tmpl || !data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } *data_len = attr->ulValueLen; if (length_only == FALSE) { ptr = (CK_BYTE *)malloc( attr->ulValueLen ); if (!ptr){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( ptr, attr->pValue, attr->ulValueLen ); *data = ptr; } return CKR_OK; } // cast_check_required_attributes() // CK_RV cast_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE_LEN, &attr ); if (!found) { if (mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // cast_set_default_attributes() // CK_RV cast_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *value_len_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; CK_ULONG len = 0L; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_len_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); if (!type_attr || !value_attr || !value_len_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); if (value_len_attr) free( value_len_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; value_len_attr->type = CKA_VALUE_LEN; value_len_attr->ulValueLen = sizeof(CK_ULONG); value_len_attr->pValue = (CK_BYTE *)value_len_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_len_attr->pValue = len; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_CAST; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, value_len_attr ); return CKR_OK; } // cast_validate_attribute() // CK_RV cast_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { CK_ULONG len; switch (attr->type) { case CKA_VALUE: { if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } if (attr->ulValueLen > 8 || attr->ulValueLen < 1){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } case CKA_VALUE_LEN: { if (mode != MODE_KEYGEN && mode != MODE_DERIVE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } len = *(CK_ULONG *)attr->pValue; if (len > 8 || len < 1){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // cast3_check_required_attributes() // CK_RV cast3_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE_LEN, &attr ); if (!found) { if (mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // cast3_set_default_attributes() // CK_RV cast3_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *value_len_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; CK_ULONG len = 0L; if (mode) value_attr = NULL; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_len_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); if (!type_attr || !value_attr || !value_len_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); if (value_len_attr) free( value_len_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; value_len_attr->type = CKA_VALUE_LEN; value_len_attr->ulValueLen = sizeof(CK_ULONG); value_len_attr->pValue = (CK_BYTE *)value_len_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_len_attr->pValue = len; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_CAST3; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, value_len_attr ); return CKR_OK; } // cast3_validate_attribute() // CK_RV cast3_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { CK_ULONG len; switch (attr->type) { case CKA_VALUE: { if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } if (attr->ulValueLen > 8 || attr->ulValueLen < 1){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } case CKA_VALUE_LEN: { if (mode != MODE_KEYGEN && mode != MODE_DERIVE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } len = *(CK_ULONG *)attr->pValue; if (len > 8 || len < 1){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // cast5_check_required_attributes() // CK_RV cast5_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_VALUE_LEN, &attr ); if (!found) { if (mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // cast5_set_default_attributes() // CK_RV cast5_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *value_len_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; CK_ULONG len = 0L; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_len_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); if (!type_attr || !value_attr || !value_len_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); if (value_len_attr) free( value_len_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; value_len_attr->type = CKA_VALUE_LEN; value_len_attr->ulValueLen = sizeof(CK_ULONG); value_len_attr->pValue = (CK_BYTE *)value_len_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_len_attr->pValue = len; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_CAST5; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, value_len_attr ); return CKR_OK; } // cast5_validate_attribute() // CK_RV cast5_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { CK_ULONG len; switch (attr->type) { case CKA_VALUE: { if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } if (attr->ulValueLen > 16 || attr->ulValueLen < 1){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } case CKA_VALUE_LEN: { if (mode != MODE_KEYGEN && mode != MODE_DERIVE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } len = *(CK_ULONG *)attr->pValue; if (len < 1 || len > 16){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // idea_check_required_attributes() // CK_RV idea_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // idea_set_default_attributes() // CK_RV idea_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) value_attr = NULL; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !value_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_IDEA; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // idea_validate_attribute() // CK_RV idea_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_VALUE: { if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } if (attr->ulValueLen != 16){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // cdmf_check_required_attributes() // CK_RV cdmf_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } #if !(NOCDMF) // cdmf_set_default_attributes() // CK_RV cdmf_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) value_attr = NULL; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !value_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_CDMF; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // cdmf_validate_attribute() // CK_RV cdmf_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { CK_ULONG len; switch (attr->type) { case CKA_VALUE: { #if 0 CDMF_Transform_Args args; #endif CK_ULONG req_len, repl_len; CK_BYTE cdmf_key[DES_KEY_SIZE]; CK_RV rc; if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } if (attr->ulValueLen != DES_KEY_SIZE){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } #if 0 req_len = sizeof(args); repl_len = DES_KEY_SIZE; memcpy( args.des_key, attr->pValue, DES_KEY_SIZE ); rc = communicate( PK_CDMF_TRANSFORM_KEY, &args, req_len, cdmf_key, &repl_len, NULL, 0, NULL, 0 ); if (rc != CKR_OK) return rc; if (rc == CKR_OK) { if (repl_len != DES_KEY_SIZE) return CKR_GENERAL_ERROR; memcpy( attr->pValue, cdmf_key, DES_KEY_SIZE ); } return CKR_OK; #else return tok_cdmf_transform(attr->pValue, DES_KEY_SIZE); #endif } case CKA_VALUE_LEN: { if (nv_token_data->tweak_vector.netscape_mods == TRUE) { if (mode == MODE_CREATE || mode == MODE_KEYGEN) { len = *(CK_ULONG *)attr->pValue; if (len != DES_KEY_SIZE){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } } else{ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } #endif // skipjack_check_required_attributes() // CK_RV skipjack_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // skipjack_set_default_attributes() // CK_RV skipjack_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) value_attr = NULL; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !value_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_SKIPJACK; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // skipjack_validate_attribute() // CK_RV skipjack_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_VALUE: { if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } if (attr->ulValueLen != 20){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // baton_check_required_attributes() // CK_RV baton_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // baton_set_default_attributes() // CK_RV baton_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) value_attr = NULL; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !value_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_BATON; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // baton_validate_attribute() // CK_RV baton_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_VALUE: { if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } if (attr->ulValueLen != 40){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // juniper_check_required_attributes() // CK_RV juniper_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // juniper_set_default_attributes() // CK_RV juniper_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *value_attr = NULL; CK_ATTRIBUTE *type_attr = NULL; if (mode) value_attr = NULL; secret_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !value_attr) { if (type_attr) free( type_attr ); if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_JUNIPER; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // juniper_validate_attribute() // CK_RV juniper_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_VALUE: { if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } if (attr->ulValueLen != 40){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else return CKR_OK; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // aes_set_default_attributes() // CK_RV aes_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * type_attr = NULL; if (mode) value_attr = NULL; secret_key_set_default_attributes( tmpl, mode ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); if (!value_attr || !type_attr) { if (value_attr) free( value_attr ); if (type_attr) free( type_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_AES; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // aes_check_required_attributes() // CK_RV aes_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return secret_key_check_required_attributes( tmpl, mode ); } // // CK_RV aes_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { CK_ULONG val; switch (attr->type) { case CKA_VALUE: // key length is either 16, 24 or 32 bytes // if (mode == MODE_CREATE) { if (attr->ulValueLen != AES_KEY_SIZE_128 && attr->ulValueLen != AES_KEY_SIZE_192 && attr->ulValueLen != AES_KEY_SIZE_256 ) { st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } return CKR_OK; } else { st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_VALUE_LEN: if (mode == MODE_CREATE || mode == MODE_DERIVE || mode == MODE_KEYGEN || mode == MODE_UNWRAP) { val = *(CK_ULONG *)attr->pValue; if (val != AES_KEY_SIZE_128 && val != AES_KEY_SIZE_192 && val != AES_KEY_SIZE_256 ){ st_err_log(7, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } return CKR_OK; } else{ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } default: return secret_key_validate_attribute( tmpl, attr, mode ); } } // // CK_RV aes_wrap_get_data( TEMPLATE * tmpl, CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len ) { CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_RV rc; if (!tmpl || !data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } *data_len = attr->ulValueLen; if (length_only == FALSE) { ptr = (CK_BYTE *)malloc( attr->ulValueLen ); if (!ptr){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( ptr, attr->pValue, attr->ulValueLen ); *data = ptr; } return CKR_OK; } // // CK_RV aes_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ) { CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * val_len_attr = NULL; CK_BYTE * ptr = NULL; CK_ULONG key_size; CK_BBOOL found = FALSE; /* * CKA_VALUE_LEN attribute is optional in the key template. Default * is to use AES_BLOCK_SIZE and truncate if no value is specified. --KlausK */ found = template_attribute_find( tmpl, CKA_VALUE_LEN, &val_len_attr ); if (found){ key_size = *(CK_ULONG *)val_len_attr->pValue; } else { key_size = AES_BLOCK_SIZE; /* same as AES_KEY_SIZE_128 */ } /* key_size should be one of AES's possible sizes */ if (key_size != AES_KEY_SIZE_128 && key_size != AES_KEY_SIZE_192 && key_size != AES_KEY_SIZE_256){ st_err_log(62, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } if (fromend == TRUE) ptr = data + data_len - key_size; else ptr = data; #if 0 CK_ULONG i; if (nv_token_data->tweak_vector.check_des_parity == TRUE) { for (i=0; i < 3*DES_KEY_SIZE; i++) { if (parity_is_odd(ptr[i]) == FALSE){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } } } #endif value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + key_size ); if (!value_attr) { if (value_attr) free( value_attr ); st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = key_size; value_attr->pValue = (CK_BYTE *)value_attr + sizeof(CK_ATTRIBUTE); memcpy( value_attr->pValue, ptr, key_size ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/data_obj.c0000751000175000017500000004313511327631345020634 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: data_obj.c // // Functions contained within: // // data_object_check_required_attributes // data_object_set_default_attributes // data_object_validate_attribute // #include #include #include // for memcmp() et al #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" // data_object_check_required_attributes() // CK_RV data_object_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { // CKO_DATA has no required attributes // return template_check_required_base_attributes( tmpl, mode ); } // data_object_set_default_attributes() // // Set the default attributes for data objects: // // CKA_APPLICATION : empty string // CKA_VALUE : empty byte array // CK_RV data_object_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *class_attr = NULL; CK_ATTRIBUTE *app_attr = NULL; CK_ATTRIBUTE *value_attr = NULL; // satisfy the compiler // if (mode) app_attr = NULL; // add the default CKO_DATA attributes // class_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS) ); app_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!class_attr || !app_attr || !value_attr) { if (class_attr) free( class_attr ); if (app_attr) free( app_attr ); if (value_attr) free( value_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } app_attr->type = CKA_APPLICATION; app_attr->ulValueLen = 0; // empty string app_attr->pValue = NULL; value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; // empty byte array value_attr->pValue = NULL; class_attr->type = CKA_CLASS; class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS); class_attr->pValue = (CK_BYTE *)class_attr + sizeof(CK_ATTRIBUTE); *(CK_OBJECT_CLASS *)class_attr->pValue = CKO_DATA; template_update_attribute( tmpl, class_attr ); template_update_attribute( tmpl, app_attr ); template_update_attribute( tmpl, value_attr ); return CKR_OK; } // data_object_validate_attribute() // // Determine whether a CKO_DATA object's attribute are valid. // CK_RV data_object_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { if (!attr){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } switch (attr->type) { case CKA_APPLICATION: case CKA_VALUE: return CKR_OK; default: return template_validate_base_attribute( tmpl, attr, mode ); } return CKR_OK; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/mech_des3.c0000751000175000017500000017655211327631345020735 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: mech_des3.c // // Mechanisms for DES3 // #include // for memcmp() et al #include #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // // CK_RV des3_ecb_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES3_ECB requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des3_ecb_encrypt( in_data, in_data_len, out_data, out_data_len, key_value ); } // // CK_RV des3_ecb_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES3_ECB requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des3_ecb_decrypt( in_data, in_data_len, out_data, out_data_len, key_value ); } // // CK_RV des3_cbc_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES3_CBC requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des3_cbc_encrypt( in_data, in_data_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); } // // CK_RV des3_cbc_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES3_CBC requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des3_cbc_decrypt( in_data, in_data_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); } // // CK_RV des3_cbc_pad_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE *clear = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_ULONG padded_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // DES3-CBC-PAD has no input length requirements // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); // compute the output length, accounting for padding // padded_len = DES_BLOCK_SIZE * (in_data_len / DES_BLOCK_SIZE + 1); if (length_only == TRUE) { *out_data_len = padded_len; return CKR_OK; } if (*out_data_len < padded_len) { *out_data_len = padded_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } clear = (CK_BYTE *)malloc( padded_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( clear, in_data, in_data_len ); add_pkcs_padding( clear + in_data_len, DES_BLOCK_SIZE, in_data_len, padded_len ); rc = ckm_des3_cbc_encrypt( clear, padded_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); if (rc != CKR_OK) st_err_log(105, __FILE__, __LINE__); free( clear ); return rc; } // // CK_RV des3_cbc_pad_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE *clear = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_ULONG padded_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // no need to validate the input length since we'll pad as necessary // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); // we're decrypting so even with CBC-PAD, we should have an integral // number of block to decrypt // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } // the amount of cleartext after stripping the padding will actually be less // than the input bytes... // padded_len = in_data_len; if (length_only == TRUE) { *out_data_len = padded_len; return CKR_OK; } clear = (CK_BYTE *)malloc( padded_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } rc = ckm_des3_cbc_decrypt( in_data, in_data_len, clear, &padded_len, ctx->mech.pParameter, key_value ); if (rc == CKR_OK) { strip_pkcs_padding( clear, padded_len, out_data_len ); memcpy( out_data, clear, *out_data_len ); } else st_err_log(106, __FILE__, __LINE__); free( clear ); return rc; } // // CK_RV des3_ecb_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % DES_BLOCK_SIZE); out_len = (total - remain); // should always be at least 1 block if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); rc = ckm_des3_ecb_encrypt( clear, out_len, out_data, out_data_len, key_value ); if (rc == CKR_OK) { *out_data_len = out_len; // update the context buffer. we already used the buffer's current // contents so we completely overwrite it // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } free( clear ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // shouldn't reach this } // // CK_RV des3_ecb_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % DES_BLOCK_SIZE); out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_des3_ecb_decrypt( cipher, out_len, out_data, out_data_len, key_value ); if (rc == CKR_OK) { *out_data_len = out_len; // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(105, __FILE__, __LINE__); free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // shouldn't reach this } // // CK_RV des3_cbc_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % DES_BLOCK_SIZE); out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); // these buffers need to be longword aligned // clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); rc = ckm_des3_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); if (rc == CKR_OK) { *out_data_len = out_len; // the new init_v is the last encrypted data block // memcpy( ctx->mech.pParameter, out_data + (*out_data_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(105, __FILE__, __LINE__); free( clear ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV des3_cbc_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = context->len + in_data_len; if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = total % DES_BLOCK_SIZE; out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); // these buffers need to be longword aligned // cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_des3_cbc_decrypt( cipher, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); if (rc == CKR_OK) { *out_data_len = out_len; // the new init_v is the last input data block // memcpy( ctx->mech.pParameter, cipher + (out_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(106, __FILE__, __LINE__); free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV des3_cbc_pad_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); // note, this is subtly different from the other encrypt update routines // if (total <= DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { remain = (total % DES_BLOCK_SIZE); out_len = total - remain; // out_len is a multiple of DES_BLOCK_SIZE if (remain == 0) { remain = DES_BLOCK_SIZE; out_len -= DES_BLOCK_SIZE; } if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } // at this point, we should have: // 1) remain != 0 // 2) out_len != 0 // rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); // these buffers need to be longword aligned // clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); // // we don't do padding during the update // rc = ckm_des3_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); if (rc == CKR_OK) { // the new init_v is the last encrypted data block // memcpy( ctx->mech.pParameter, out_data + (*out_data_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the temporary space // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } free( clear ); return rc; } } // // CK_RV des3_cbc_pad_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); // note, this is subtly different from the other decrypt update routines // if (total <= DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block + 1 byte // remain = total % DES_BLOCK_SIZE; out_len = total - remain; if (remain == 0) { remain = DES_BLOCK_SIZE; out_len -= DES_BLOCK_SIZE; } if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } // at this point, we should have: // 1) remain != 0 // 2) out_len != 0 // rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); // these buffers need to be longword aligned // cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_des3_cbc_decrypt( cipher, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); if (rc == CKR_OK) { // the new init_v is the last input data block // memcpy( ctx->mech.pParameter, cipher + (out_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the temporary space // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV des3_ecb_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES3-ECB does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV des3_ecb_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES3-ECB does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV des3_cbc_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES3-CBC does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV des3_cbc_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES3-CBC does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV des3_cbc_pad_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE clear[2*DES_BLOCK_SIZE]; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_ULONG out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); context = (DES_CONTEXT *)ctx->context; // there will never be more than one block in the context buffer // so the amount of output is as follows: // if less than 1 block stored, we generate one block of output // if a full block is stored, we generate two blocks of output (one pad block) // if (context->len == DES_BLOCK_SIZE) out_len = 2 * DES_BLOCK_SIZE; else out_len = DES_BLOCK_SIZE; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } else { memcpy( clear, context->data, context->len ); add_pkcs_padding( clear + context->len, DES_BLOCK_SIZE, context->len, out_len ); rc = ckm_des3_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value ); if (rc != CKR_OK) st_err_log(105, __FILE__, __LINE__); return rc; } } // // CK_RV des3_cbc_pad_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE clear[DES_BLOCK_SIZE]; CK_BYTE key_value[3*DES_KEY_SIZE]; CK_KEY_TYPE keytype; CK_ULONG out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (keytype == CKK_DES2) { memcpy( key_value, attr->pValue, 2*DES_KEY_SIZE ); memcpy( key_value + (2*DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE ); } else memcpy( key_value, attr->pValue, 3*DES_KEY_SIZE ); context = (DES_CONTEXT *)ctx->context; // there had better be a full block in the context buffer // if (context->len != DES_BLOCK_SIZE){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } // we don't know a priori how much data we'll be returning. we won't // know until after we decrypt it and strip the padding. it's possible // that we'll return nothing (the final block might be a padding block). // out_len = DES_BLOCK_SIZE; // upper bound on what we'll return if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } else { rc = ckm_des3_cbc_decrypt( context->data, DES_BLOCK_SIZE, clear, &out_len, ctx->mech.pParameter, key_value ); if (rc == CKR_OK) { strip_pkcs_padding( clear, out_len, &out_len ); if (out_len != 0) memcpy( out_data, clear, out_len ); *out_data_len = out_len; } else st_err_log(106, __FILE__, __LINE__); return rc; } } // // mechanisms // // // CK_RV ckm_des3_key_gen( TEMPLATE *tmpl ) { CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * key_type_attr = NULL; CK_ATTRIBUTE * class_attr = NULL; CK_ATTRIBUTE * local_attr = NULL; CK_BYTE des_key[3 * DES_KEY_SIZE]; CK_ULONG rc; rc = token_specific.t_des_key_gen(des_key, sizeof(des_key)); if (rc != CKR_OK) return rc; value_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + 3*DES_KEY_SIZE ); key_type_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); class_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS) ); local_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!value_attr || !key_type_attr || !class_attr || !local_attr) { if (value_attr) free( value_attr ); if (key_type_attr) free( key_type_attr ); if (class_attr) free( class_attr ); if (local_attr) free( local_attr ); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 3 * DES_KEY_SIZE; value_attr->pValue = (CK_BYTE *)value_attr + sizeof(CK_ATTRIBUTE); memcpy( value_attr->pValue, des_key, 3 * DES_KEY_SIZE ); key_type_attr->type = CKA_KEY_TYPE; key_type_attr->ulValueLen = sizeof(CK_KEY_TYPE); key_type_attr->pValue = (CK_BYTE *)key_type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)key_type_attr->pValue = CKK_DES3; class_attr->type = CKA_CLASS; class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS); class_attr->pValue = (CK_BYTE *)class_attr + sizeof(CK_ATTRIBUTE); *(CK_OBJECT_CLASS *)class_attr->pValue = CKO_SECRET_KEY; local_attr->type = CKA_LOCAL; local_attr->ulValueLen = sizeof(CK_BBOOL); local_attr->pValue = (CK_BYTE *)local_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)local_attr->pValue = TRUE; template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, key_type_attr ); template_update_attribute( tmpl, class_attr ); template_update_attribute( tmpl, local_attr ); return CKR_OK; } // // CK_RV ckm_des3_ecb_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * key_value ) { CK_ULONG rc; if (!in_data || !out_data || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_tdes_ecb(in_data,in_data_len,out_data, out_data_len, key_value, 1); if (rc != CKR_OK) st_err_log(120, __FILE__, __LINE__); return rc; } // // CK_RV ckm_des3_ecb_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * key_value ) { CK_ULONG rc; if (!in_data || !out_data || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_tdes_ecb(in_data,in_data_len,out_data, out_data_len, key_value, 0); if (rc != CKR_OK) st_err_log(120, __FILE__, __LINE__); return rc; } // // CK_RV ckm_des3_cbc_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * init_v, CK_BYTE * key_value ) { CK_ULONG rc; if (!in_data || !out_data || !init_v || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ #if 0 st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; #else *out_data_len = in_data_len; st_err_log(68, __FILE__, __FUNCTION__); return CKR_BUFFER_TOO_SMALL; #endif } rc = token_specific.t_tdes_cbc(in_data,in_data_len,out_data,out_data_len, key_value,init_v,1); if (rc != CKR_OK) st_err_log(119, __FILE__, __LINE__); return rc; } // // CK_RV ckm_des3_cbc_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * init_v, CK_BYTE * key_value ) { CK_ULONG rc; if (!in_data || !out_data || !init_v || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_tdes_cbc(in_data,in_data_len,out_data,out_data_len, key_value,init_v,0); if (rc != CKR_OK) st_err_log(119, __FILE__, __LINE__); return rc; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/utility.c0000751000175000017500000011701011327631345020566 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ #include #include #include #include #include #include #include #include #include #include #include #include #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" #include "pkcs32.h" #if (SPINXPL) #include #endif // Function: dlist_add_as_first() // // Adds the specified node to the start of the list // // Returns: pointer to the start of the list // DL_NODE * dlist_add_as_first( DL_NODE *list, void *data ) { DL_NODE *node = NULL; if (!data) return list; node = (DL_NODE *)malloc(sizeof(DL_NODE)); if (!node) return NULL; node->data = data; node->prev = NULL; node->next = list; if ( list) list->prev = node; return node; } // Function: dlist_add_as_last() // // Adds the specified node to the end of the list // // Returns: pointer to the start of the list // DL_NODE * dlist_add_as_last( DL_NODE *list, void *data ) { DL_NODE *node = NULL; if (!data) return list; node = (DL_NODE *)malloc(sizeof(DL_NODE)); if (!node) return NULL; node->data = data; node->next = NULL; if (!list) { node->prev = NULL; return node; } else { DL_NODE *temp = dlist_get_last( list ); temp->next = node; node->prev = temp; return list; } } // Function: dlist_find() // DL_NODE * dlist_find( DL_NODE *list, void *data ) { DL_NODE *node = list; while (node && node->data != data) node = node->next; return node; } // Function: dlist_get_first() // // Returns the last node in the list or NULL if list is empty // DL_NODE * dlist_get_first( DL_NODE *list ) { DL_NODE *temp = list; if (!list) return NULL; while (temp->prev != NULL) temp = temp->prev; return temp; } // Function: dlist_get_last() // // Returns the last node in the list or NULL if list is empty // DL_NODE * dlist_get_last( DL_NODE *list ) { DL_NODE *temp = list; if (!list) return NULL; while (temp->next != NULL) temp = temp->next; return temp; } // // CK_ULONG dlist_length( DL_NODE *list ) { DL_NODE *temp = list; CK_ULONG len = 0; while (temp) { len++; temp = temp->next; } return len; } // // DL_NODE * dlist_next( DL_NODE *node ) { if (!node) return NULL; return node->next; } // // DL_NODE * dlist_prev( DL_NODE *node ) { if (!node) return NULL; return node->prev; } // // void dlist_purge( DL_NODE *list ) { DL_NODE *node; if (!list) return; do { node = list->next; free( list ); list = node; } while ( list ); } // Function: dlist_remove_node() // // Attempts to remove the specified node from the list. The caller is // responsible for freeing the data associated with the node prior to // calling this routine // DL_NODE * dlist_remove_node( DL_NODE *list, DL_NODE *node ) { DL_NODE *temp = list; if (!list || !node) return NULL; // special case: removing head of the list // if (list == node) { temp = list->next; if (temp) temp->prev = NULL; free( list ); return temp; } // we have no guarantee that the node is in the list // so search through the list to find it // while ((temp != NULL) && (temp->next != node)) temp = temp->next; if (temp != NULL) { DL_NODE *next = node->next; temp->next = next; if (next) next->prev = temp; free( node ); } return list; } // NOTE about Mutexes and cross process locking.... // // The code uses 2 types of locks... internal locks to prevent threads within the same // process space from stomping on each other (pthread_mutex's suffice for // this).... and Cross Process Locks.... // On AIX we use it's variation of Posix semaphores for this.... Idealy on other // platforms either POSIXSEMaphores or PTHREADXPL (pthreads xprocess lock) would // be used. On Linux unfortunatly neither of these are available so we need to // use the old standby of SYSV semaphores (YECH.... GAG....).... The only // pieces which have been tested are the AIX and SYSV portions although // we expect that the others work correctly. // // we use alot more mutexes in the redesign than we did in the original // design. so instead of just the single global "pkcs_mutex" we have to // deal with a number of mutexes. so we'll make the mutex routines a // bit more generic. // CK_RV _CreateMutex( MUTEX *mutex ) { // on AIX we make this a no-op since we assume that // the mutex was created in the initialization pthread_mutex_init( mutex, NULL ); return CKR_OK; } CK_RV _CreateMsem( sem_t *msem ) { if (!sem_init( msem,0, 1)) // parm 2 non-0 means pshared 1 is unlocked 0 is locked //if (!sem_init( msem,1, 1)) // parm 2 non-0 means pshared 1 is unlocked 0 is locked return CKR_OK; else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } CK_RV _DestroyMutex( MUTEX *mutex ) { // no-op in AIX pthread_mutex_destroy((pthread_mutex_t *)mutex); return CKR_OK; } CK_RV _DestroyMsem( sem_t *msem ) { if (!sem_destroy(msem)) return CKR_OK; else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } CK_RV _LockMutex( MUTEX *mutex ) { pthread_mutex_lock( mutex); return CKR_OK; } CK_RV _LockMsem( sem_t *msem ) { if (!msem){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if(!sem_wait(msem)) // block until the semaphore is free return CKR_OK; else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } CK_RV _UnlockMutex( MUTEX *mutex ) { pthread_mutex_unlock(mutex); return CKR_OK; } CK_RV _UnlockMsem( sem_t *msem ) { if (!msem){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!sem_post(msem)) return CKR_OK; else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } #if SYSVSEM #include // These structures are needed to effect a lock // using SYS V semaphores... static struct sembuf xlock_lock[2]={ 0,0,0, 0,1,SEM_UNDO }; static struct sembuf xlock_unlock[1] = { 0,-1,(IPC_NOWAIT | SEM_UNDO) }; static pthread_mutex_t semmtx = PTHREAD_MUTEX_INITIALIZER; #endif int spinxplfd=-1; int spin_created=0; extern void set_perm(int); CK_RV CreateXProcLock(void *xproc) { #if (SPINXPL) // open the file that we will do the locking on... spinxplfd = open("/tmp/.pkcs11spinloc",O_CREAT|O_APPEND|O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO); if (spinxplfd) { set_perm(spinxplfd); fchmod(spinxplfd,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH | S_IWOTH); spin_created=1; } else { perror("XPROC CREATE file :"); } return CKR_OK; #elif SYSVSEM int semid; int *psem; key_t tok; tok = ftok( pk_dir, 'c' ); //printf("creating semaphore %x \n",tok); psem = (int *)xproc; if ( *psem < 0 ) { if ( (semid = semget(tok,1,IPC_CREAT | 0666)) < 0 ){ if (errno == EEXIST) { if ( (semid = semget(tok,0,0)) < 0) { pthread_mutex_unlock(&semmtx); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } else { pthread_mutex_unlock(&semmtx); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } } psem = (int *)xproc; *psem = semid; //pthread_mutex_unlock(&semmtx); return CKR_OK; // we know that semaphores are created unlocked #elif POSIXSEM return _CreateMsem((sem_t *)xproc); #elif PTHREADXPL pthread_mutex_attr_t mtxattr; pthread_mutexattr_init(&mtxattr); pthread_mutexattr_setpshared(&mtxattr,PTHREAD_PROCESS_SHARED); pthread_mutex_init((pthread_mutex_t *)xproc,&mtxattr); #elif NOXPROCLOCK return CKR_OK; #else #error "Define XPROC LOCKS" #endif } CK_RV DestroyXProcLock(void *xproc) { #if SPINXPL return CKR_OK; #elif SYSVSEM int semid,*psem; //printf("Destroying semaphore %x \n",xproc); pthread_mutex_lock(&semmtx); psem = (int *)xproc; semid = *psem; semctl(semid,1,IPC_RMID,0); pthread_mutex_unlock(&semmtx); return CKR_OK; #elif POSIXSEM return _DestroyMsem((sem_t *)xproc); #elif PTHREADXPL return pthread_mutex_destroy((pthread_mutex_t *)xproc); #elif NOXPROCLOCK return CKR_OK; #else #error "Define XPROC LOCKS" #endif } CK_RV XProcLock(void *xproc) { #if SPINXPL if (!spin_created) { spinxplfd = open("/tmp/.pkcs11spinloc",O_CREAT|O_APPEND|O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO); fchmod(spinxplfd,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH | S_IWOTH); spin_created=1; } if (spinxplfd){ flock(spinxplfd,LOCK_EX); } return CKR_OK; #elif SYSVSEM int semid,*psem; pthread_mutex_lock(&semmtx); return CKR_OK; pthread_mutex_lock(&semmtx); psem = (int *)xproc; semid = *psem; semop(semid,&xlock_lock[0],2); pthread_mutex_unlock(&semmtx); return CKR_OK; #elif POSIXSEM return _LockMsem((sem_t *)xproc); #elif PTHREADXPL return _LockMutex((MUTEX *)xproc); #elif NOXPROCLOCK return CKR_OK; #else #error "Define XPROC LOCKS" #endif } CK_RV XProcUnLock(void *xproc) { #if SPINXPL if (!spin_created) { spinxplfd = open("/tmp/.pkcs11spinloc",O_CREAT|O_APPEND|O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO); fchmod(spinxplfd,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH | S_IWOTH); spin_created=1; } if (spinxplfd) { flock(spinxplfd,LOCK_UN); } return CKR_OK; #elif SYSVSEM int semid,*psem; pthread_mutex_unlock(&semmtx); return CKR_OK; pthread_mutex_lock(&semmtx); psem = (int *)xproc; semid = *psem; semop(semid,&xlock_unlock[0],1); pthread_mutex_unlock(&semmtx); return CKR_OK; #elif POSIXSEM return _UnlockMsem((sem_t *)xproc); #elif PTHREADXPL return _UnlockMutex((MUTEX *)xproc); #elif NOXPROCLOCK return CKR_OK; #else #error "Define XPROC LOCKS" #endif } // // // is_attribute_defined() // // determine whether the specified attribute is defined by Cryptoki // CK_BBOOL is_attribute_defined( CK_ATTRIBUTE_TYPE type ) { if (type >= CKA_VENDOR_DEFINED) return TRUE; switch (type) { case CKA_CLASS: case CKA_TOKEN: case CKA_PRIVATE: case CKA_LABEL: case CKA_APPLICATION: case CKA_VALUE: case CKA_CERTIFICATE_TYPE: case CKA_ISSUER: case CKA_SERIAL_NUMBER: case CKA_KEY_TYPE: case CKA_SUBJECT: case CKA_ID: case CKA_SENSITIVE: case CKA_ENCRYPT: case CKA_DECRYPT: case CKA_WRAP: case CKA_UNWRAP: case CKA_SIGN: case CKA_SIGN_RECOVER: case CKA_VERIFY: case CKA_VERIFY_RECOVER: case CKA_DERIVE: case CKA_START_DATE: case CKA_END_DATE: case CKA_MODULUS: case CKA_MODULUS_BITS: case CKA_PUBLIC_EXPONENT: case CKA_PRIVATE_EXPONENT: case CKA_PRIME_1: case CKA_PRIME_2: case CKA_EXPONENT_1: case CKA_EXPONENT_2: case CKA_COEFFICIENT: case CKA_PRIME: case CKA_SUBPRIME: case CKA_BASE: case CKA_VALUE_BITS: case CKA_VALUE_LEN: case CKA_EXTRACTABLE: case CKA_LOCAL: case CKA_NEVER_EXTRACTABLE: case CKA_ALWAYS_SENSITIVE: case CKA_MODIFIABLE: case CKA_ECDSA_PARAMS: case CKA_EC_POINT: case CKA_HW_FEATURE_TYPE: case CKA_HAS_RESET: case CKA_RESET_ON_INIT: case CKA_KEY_GEN_MECHANISM: case CKA_PRIME_BITS: case CKA_SUBPRIME_BITS: case CKA_OBJECT_ID: case CKA_AC_ISSUER: case CKA_OWNER: case CKA_ATTR_TYPES: case CKA_TRUSTED: return TRUE; } return FALSE; } extern CK_CHAR manuf[]; extern CK_CHAR model[]; extern CK_CHAR descr[]; extern CK_CHAR label[]; // // void init_slotInfo( void ) { memset( &slot_info.slotDescription, ' ', sizeof(slot_info.slotDescription) ); memset( &slot_info.manufacturerID, ' ', sizeof(slot_info.manufacturerID) ); memcpy( &slot_info.slotDescription, descr, strlen((char *)descr) ); memcpy( &slot_info.manufacturerID, manuf, strlen((char *)manuf) ); slot_info.hardwareVersion.major = 1; slot_info.hardwareVersion.minor = 0; slot_info.firmwareVersion.major = 1; slot_info.firmwareVersion.minor = 0; slot_info.flags = CKF_TOKEN_PRESENT | CKF_HW_SLOT; } // // void init_tokenInfo( void ) { CK_TOKEN_INFO_32 *token_info = NULL; token_info = &nv_token_data->token_info; memset( token_info->manufacturerID, ' ', sizeof(token_info->manufacturerID) ); memset( token_info->model, ' ', sizeof(token_info->model) ); memset( token_info->serialNumber, ' ', sizeof(token_info->serialNumber) ); memcpy( token_info->label, nv_token_data->token_info.label, 32 ); memcpy( token_info->manufacturerID, manuf, strlen((char *)manuf) ); memcpy( token_info->model, model, strlen((char *)model) ); // use the 41-xxxxx serial number from the coprocessor // memcpy( token_info->serialNumber, "123" , 3 ); // I don't see any API support for changing the clock so // we will use the system clock for the token's clock. // token_info->flags = CKF_RNG | CKF_LOGIN_REQUIRED | CKF_CLOCK_ON_TOKEN | CKF_SO_PIN_TO_BE_CHANGED; // XXX New in v2.11 - KEY if (memcmp(nv_token_data->user_pin_sha, "00000000000000000000", SHA1_HASH_SIZE) != 0) token_info->flags |= CKF_USER_PIN_INITIALIZED; else token_info->flags |= CKF_USER_PIN_TO_BE_CHANGED; // XXX New in v2.11 - KEY // For the release, we made these // values as CK_UNAVAILABLE_INFORMATION // token_info->ulMaxSessionCount = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->ulSessionCount = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->ulMaxRwSessionCount = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->ulRwSessionCount = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->ulMaxPinLen = MAX_PIN_LEN; token_info->ulMinPinLen = MIN_PIN_LEN; token_info->ulTotalPublicMemory = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->ulFreePublicMemory = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->ulTotalPrivateMemory = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->ulFreePrivateMemory = (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION; token_info->hardwareVersion.major = 1; token_info->hardwareVersion.minor = 0; token_info->firmwareVersion.major = 1; token_info->firmwareVersion.minor = 0; memset( token_info->utcTime, ' ', sizeof(token_info->utcTime) ); } // // CK_RV init_token_data( void ) { CK_RV rc; memset( (char *)nv_token_data, 0, sizeof(nv_token_data) ); // the normal USER pin is not set when the token is initialized // memcpy( nv_token_data->user_pin_sha, "00000000000000000000", SHA1_HASH_SIZE ); memcpy( nv_token_data->so_pin_sha, default_so_pin_sha, SHA1_HASH_SIZE ); memset( user_pin_md5, 0x0, MD5_HASH_SIZE ); memcpy( so_pin_md5, default_so_pin_md5, MD5_HASH_SIZE ); memcpy( nv_token_data->next_token_object_name, "00000000", 8 ); // generate the master key used for signing the Operation State information // ` memset( nv_token_data->token_info.label, ' ', sizeof(nv_token_data->token_info.label) ); memcpy( nv_token_data->token_info.label, label, strlen((char *)label) ); nv_token_data->tweak_vector.allow_weak_des = TRUE; nv_token_data->tweak_vector.check_des_parity = FALSE; nv_token_data->tweak_vector.allow_key_mods = TRUE; nv_token_data->tweak_vector.netscape_mods = TRUE; init_tokenInfo(); // // FIXME: erase the token object index file (and all token objects) // rc = rng_generate( master_key, 3 * DES_KEY_SIZE ); if (rc != CKR_OK){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = save_masterkey_so(); if (rc != CKR_OK){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = save_token_data(); if (rc != CKR_OK) st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return rc; } // Function: compute_next_token_obj_name() // // Given a token object name (8 bytes in the range [0-9A-Z]) increment by one // adjusting as necessary // // This gives us a namespace of 36^8 = 2,821,109,907,456 objects before wrapping around // CK_RV compute_next_token_obj_name( CK_BYTE *current, CK_BYTE *next ) { int val[8]; int i; if (!current || !next){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Convert to integral base 36 // for (i = 0; i < 8; i++) { if (current[i] >= '0' && current[i] <= '9') val[i] = current[i] - '0'; if (current[i] >= 'A' && current[i] <= 'Z') val[i] = current[i] - 'A' + 10; } val[0]++; i=0; while (val[i] > 35) { val[i] = 0; if (i+1 < 8) { val[i+1]++; i++; } else { val[0]++; i = 0; // start pass 2 } } // now, convert back to [0-9A-Z] // for (i = 0; i < 8; i++) { if (val[i] < 10) next[i] = '0' + val[i]; else next[i] = 'A' + val[i] - 10; } return CKR_OK; } // // CK_RV build_attribute( CK_ATTRIBUTE_TYPE type, CK_BYTE *data, CK_ULONG data_len, CK_ATTRIBUTE **attrib ) { CK_ATTRIBUTE *attr = NULL; attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + data_len ); if (!attr){ st_err_log(0, __FILE__, __LINE__); return CKR_DEVICE_MEMORY; } attr->type = type; attr->ulValueLen = data_len; if (data_len > 0) { attr->pValue = (CK_BYTE *)attr + sizeof(CK_ATTRIBUTE); memcpy( attr->pValue, data, data_len ); } else attr->pValue = NULL; *attrib = attr; return CKR_OK; } // // CK_RV add_pkcs_padding( CK_BYTE * ptr, CK_ULONG block_size, CK_ULONG data_len, CK_ULONG total_len ) { CK_ULONG i, pad_len; CK_BYTE pad_value; pad_len = block_size - (data_len % block_size); pad_value = (CK_BYTE)pad_len; if (data_len + pad_len > total_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } for (i = 0; i < pad_len; i++) ptr[i] = pad_value; return CKR_OK; } // // CK_RV strip_pkcs_padding( CK_BYTE * ptr, CK_ULONG total_len, CK_ULONG * data_len ) { CK_BYTE pad_value; pad_value = ptr[total_len - 1]; // thus, we have 'pad_value' bytes of 'pad_value' appended to the end // *data_len = total_len - pad_value; return CKR_OK; } // // CK_RV remove_leading_zeros( CK_ATTRIBUTE *attr ) { CK_BYTE *ptr = NULL; CK_ULONG new_len, i; ptr = attr->pValue; for (i = 0; i < attr->ulValueLen; i++) { if (ptr[i] != 0x0) break; } new_len = attr->ulValueLen - i; memcpy( ptr, ptr + i, new_len ); attr->ulValueLen = new_len; return CKR_OK; } // // CK_BYTE parity_adjust( CK_BYTE b ) { if (parity_is_odd(b) == FALSE) b = (b & 0xFE) | ((~b) & 0x1); return b; } // // CK_RV parity_is_odd( CK_BYTE b ) { b = ((b >> 4) ^ b) & 0x0f; b = ((b >> 2) ^ b) & 0x03; b = ((b >> 1) ^ b) & 0x01; if (b == 1) return TRUE; else return FALSE; } CK_RV attach_shm() { key_t key; int shm_id; struct stat statbuf; CK_BBOOL created = FALSE; #if !(NOSHM) && !(MMAP) // Change TOK_PATH2 to be the directory // of the data store specified. This way we // have a unique key shared memory for each // token object database if (stat(pk_dir, &statbuf) < 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } key = ftok( pk_dir, 'c' ); shm_id = shmget( key, sizeof(LW_SHM_TYPE), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH | IPC_CREAT | IPC_EXCL); if (shm_id < 0) { #if 0 if ((errno != EACCES) && (errno != EEXIST)) { fflush(stdout); fflush(stderr); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } #endif // SAB XXX it appears that in some cases linux does not set // the errno properly on a shmget failure... so if the create // failed we'll just try and attach.... If the basic attach // fails, then we can error out... // SHM segment already exists... // shm_id = shmget( key, sizeof(LW_SHM_TYPE), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ); //if ((errno != EACCES) && (errno != EEXIST)) { if (shm_id < 0) { fflush(stdout); fflush(stderr); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } else created = TRUE; global_shm = (void *)shmat( shm_id, NULL, 0 ); if (!global_shm){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (created == TRUE) { #if !(SYSVSEM) // SYSV sem's are a global that is handled in the // Initialize routine... all others are stored in the // shared memory segment so we have to do // this here after the segment is created // to prevent a core dump CreateXProcLock( &global_shm->mutex ); xproclock = (void *)&global_shm->mutex; // need to do this here #endif XProcLock( xproclock ); global_shm->num_publ_tok_obj = 0; global_shm->num_priv_tok_obj = 0; memset( &global_shm->publ_tok_objs, 0x0, 2048 * sizeof(TOK_OBJ_ENTRY) ); memset( &global_shm->priv_tok_objs, 0x0, 2048 * sizeof(TOK_OBJ_ENTRY) ); XProcUnLock( xproclock ); } else { xproclock = (void *)&global_shm->mutex; } #elif MMAP { #define FILENAME ".stmapfile" #warning "EXPERIMENTAL" char *fname = NULL; char *b2 = NULL; int fd = -1; mode_t mode; CK_RV rc; mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP ); // STAT the file to see if it exists... If not, then create it fname = malloc(strlen(pk_dir)+strlen(FILENAME)+100); if (fname ) { sprintf(fname, "%s/%s", pk_dir, FILENAME); } else { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_HOST_MEMORY; } if (stat(fname, &statbuf) < 0) { // File does not exist Create it fd = open(fname,O_RDWR|O_CREAT,mode); if (fd < 0 ){ LogError("open of %s failed: %s", fname, strerror(errno)); free(fname); return CKR_FUNCTION_FAILED; //Failed } b2 = malloc(sizeof(LW_SHM_TYPE)); memset(b2,'\0',sizeof(LW_SHM_TYPE)); write(fd,b2,sizeof(LW_SHM_TYPE)); free(b2); created=TRUE; } else { fd = open(fname,O_RDWR,mode); if (fd < 0 ){ LogError("open of %s failed: %s", fname, strerror(errno)); free(fname); return CKR_FUNCTION_FAILED; //Failed } } global_shm = (LW_SHM_TYPE *)mmap(NULL,sizeof(LW_SHM_TYPE),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if (created == TRUE) { XProcLock( xproclock ); global_shm->num_publ_tok_obj = 0; global_shm->num_priv_tok_obj = 0; memset( &global_shm->publ_tok_objs, 0x0, 2048 * sizeof(TOK_OBJ_ENTRY) ); memset( &global_shm->priv_tok_objs, 0x0, 2048 * sizeof(TOK_OBJ_ENTRY) ); XProcUnLock( xproclock ); } else { xproclock = (void *)&global_shm->mutex; } rc = CKR_OK; free(fname); close(fd); return rc; } #else global_shm = (void *)malloc(sizeof(LW_SHM_TYPE)); #endif return CKR_OK; } CK_RV detach_shm() { #if !(NOSHM) && !(MMAP) shmdt( global_shm ); #elif MMAP // Detach from memory mapped file munmap((void *)global_shm,sizeof(LW_SHM_TYPE)); #else free(global_shm); #endif return CKR_OK; } //#endif CK_RV compute_sha( CK_BYTE * data, CK_ULONG len, CK_BYTE * hash ) { // XXX KEY DIGEST_CONTEXT ctx; CK_ULONG hash_len = SHA1_HASH_SIZE; CK_RV rv; memset( &ctx, 0x0, sizeof(ctx) ); ckm_sha1_init( &ctx ); if( ctx.context == NULL ) return CKR_HOST_MEMORY; if( (rv = ckm_sha1_update( &ctx, data, len )) != CKR_OK) return rv; return ckm_sha1_final( &ctx, hash, &hash_len ); } CK_RV compute_md5( CK_BYTE * data, CK_ULONG len, CK_BYTE * hash ) { MD5_CONTEXT ctx; memset( &ctx, 0x0, sizeof(ctx) ); ckm_md5_init( &ctx ); ckm_md5_update( &ctx, data, len ); ckm_md5_final( &ctx, hash, MD5_HASH_SIZE ); return CKR_OK; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/host_defs.h0000751000175000017500000006036311327631345021056 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/lib/pkcs11/common/host_defs.h,v 1.8 2007/09/06 15:40:12 tlendacky Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ #include #ifndef _HOST_DEFS_H #define _HOST_DEFS_H #include #include #include #include "pkcs32.h" // Both of the strings below have a length of 32 chars and must be // padded with spaces, and non-null terminated. // #define PKW_CRYPTOKI_VERSION_MAJOR 2 #define PKW_CRYPTOKI_VERSION_MINOR 1 #define PKW_CRYPTOKI_MANUFACTURER "IBM Corp. " #define PKW_CRYPTOKI_LIBDESC "PKCS#11 Interface for IBM 4758 " #define PKW_CRYPTOKI_LIB_VERSION_MAJOR 1 #define PKW_CRYPTOKI_LIB_VERSION_MINOR 0 #define PKW_MAX_DEVICES 10 #define MAX_TOK_OBJS 2048 CK_BBOOL pin_expired(CK_SESSION_INFO *, CK_FLAGS); CK_BBOOL pin_locked(CK_SESSION_INFO *, CK_FLAGS); void set_login_flags(CK_USER_TYPE, CK_FLAGS_32 *); // the following enum is for performance measurements. since the server runs // as an NT service, it's difficult (impossible?) to use a standalone performance // probe // enum { PRF_DUMMYFUNCTION = 1, PRF_FCVFUNCTION, PRF_INITIALIZE, PRF_FINALIZE, PRF_GETINFO, PRF_GETFUNCTIONLIST, PRF_GETSLOTLIST, PRF_GETSLOTINFO, PRF_GETTOKENINFO, PRF_GETMECHLIST, PRF_GETMECHINFO, PRF_INITTOKEN, PRF_INITPIN, PRF_SETPIN, PRF_OPENSESSION, PRF_CLOSESESSION, PRF_CLOSEALLSESSIONS, PRF_GETSESSIONINFO, PRF_GETOPERATIONSTATE, PRF_SETOPERATIONSTATE, PRF_LOGIN, PRF_LOGOUT, PRF_CREATEOBJECT, PRF_COPYOBJECT, PRF_DESTROYOBJECT, PRF_GETOBJECTSIZE, PRF_GETATTRIBUTEVALUE, PRF_SETATTRIBUTEVALUE, PRF_FINDOBJECTSINIT, PRF_FINDOBJECTS, PRF_FINDOBJECTSFINAL, PRF_ENCRYPTINIT, PRF_ENCRYPT, PRF_ENCRYPTUPDATE, PRF_ENCRYPTFINAL, PRF_DECRYPTINIT, PRF_DECRYPT, PRF_DECRYPTUPDATE, PRF_DECRYPTFINAL, PRF_DIGESTINIT, PRF_DIGEST, PRF_DIGESTUPDATE, PRF_DIGESTKEY, PRF_DIGESTFINAL, PRF_SIGNINIT, PRF_SIGN, PRF_SIGNUPDATE, PRF_SIGNFINAL, PRF_SIGNRECOVERINIT, PRF_SIGNRECOVER, PRF_VERIFYINIT, PRF_VERIFY, PRF_VERIFYUPDATE, PRF_VERIFYFINAL, PRF_VERIFYRECOVERINIT, PRF_VERIFYRECOVER, PRF_GENKEY, PRF_GENKEYPAIR, PRF_WRAPKEY, PRF_UNWRAPKEY, PRF_DERIVEKEY, PRF_GENRND, PRF_LASTENTRY }; #define TOTAL 1 #define CARD 2 // Endianness-conversion routines. This will be useful for folks trying // to use the coprocessor on a big-endian architecture... // // htocl -- host to card long // ctohl -- card to host long // #ifndef __BYTE_ORDER #error "MUST DEFINE ENDIANESS" #endif #if __BYTE_ORDER == __LITTLE_ENDIAN #define HTOCL(x) (x) #define CTOHL(x) (x) #else #define HTOCL(x) (long_reverse(x)) #define CTOHL(x) (long_reverse(x)) #endif typedef struct _ENCR_DECR_CONTEXT { CK_OBJECT_HANDLE key; CK_MECHANISM mech; CK_BYTE *context; CK_ULONG context_len; CK_BBOOL multi; CK_BBOOL active; } ENCR_DECR_CONTEXT; typedef struct _DIGEST_CONTEXT { CK_MECHANISM mech; CK_BYTE *context; CK_ULONG context_len; CK_BBOOL multi; CK_BBOOL active; } DIGEST_CONTEXT; typedef struct _SIGN_VERIFY_CONTEXT { CK_OBJECT_HANDLE key; CK_MECHANISM mech; // current sign mechanism CK_BYTE *context; // temporary work area CK_ULONG context_len; CK_BBOOL multi; // is this a multi-part operation? CK_BBOOL recover; // are we in recover mode? CK_BBOOL active; } SIGN_VERIFY_CONTEXT; typedef struct _SESSION { CK_SESSION_HANDLE handle; CK_SESSION_INFO session_info; CK_OBJECT_HANDLE *find_list; // array of CK_OBJECT_HANDLE CK_ULONG_32 find_count; // # handles in the list CK_ULONG_32 find_len; // max # of handles in the list CK_ULONG_32 find_idx; // current position CK_BBOOL find_active; ENCR_DECR_CONTEXT encr_ctx; ENCR_DECR_CONTEXT decr_ctx; DIGEST_CONTEXT digest_ctx; SIGN_VERIFY_CONTEXT sign_ctx; SIGN_VERIFY_CONTEXT verify_ctx; } SESSION; typedef struct _DES_CONTEXT { CK_BYTE data[ DES_BLOCK_SIZE ]; CK_ULONG len; CK_BBOOL cbc_pad; // is this a CKM_DES_CBC_PAD operation? } DES_CONTEXT; typedef struct _AES_CONTEXT { CK_BYTE data[ AES_BLOCK_SIZE ]; CK_ULONG len; CK_BBOOL cbc_pad; } AES_CONTEXT; typedef struct _SHA1_CONTEXT { unsigned int buf[16]; unsigned int hash_value[5]; unsigned int bits_hi, bits_lo; // # bits processed so far } SHA1_CONTEXT; typedef SHA1_CONTEXT SHA2_CONTEXT; typedef struct _MD2_CONTEXT { CK_BYTE state[16]; // state CK_BYTE checksum[16]; // checksum CK_ULONG count; // number of bytes, modulo 16 CK_BYTE buffer[16]; // input buffer } MD2_CONTEXT; typedef struct _MD5_CONTEXT { CK_ULONG i[2]; // number of _bits_ handled mod 2^64 CK_ULONG buf[4]; // scratch buffer CK_BYTE in[64]; // input buffer CK_BYTE digest[16]; // actual digest after MD5Final call } MD5_CONTEXT; // linux typedef pthread_mutex_t MUTEX; // This is actualy wrong... XPROC will be with spinlocks #if (SPINXPL) #define XPROCLOCK unsigned int #else #define XPROCLOCK MUTEX #endif typedef struct _TEMPLATE { DL_NODE *attribute_list; } TEMPLATE; typedef struct _OBJECT { CK_OBJECT_CLASS class; CK_BYTE name[8]; // for token objects SESSION *session; // creator; only for session objects TEMPLATE *template; CK_ULONG count_hi; // only significant for token objects CK_ULONG count_lo; // only significant for token objects CK_ULONG index; // SAB Index into the SHM } OBJECT; typedef struct _OBJECT_MAP { CK_OBJECT_HANDLE handle; CK_BBOOL is_private; CK_BBOOL is_session_obj; SESSION * session; OBJECT * ptr; } OBJECT_MAP; typedef struct _ATTRIBUTE_PARSE_LIST { CK_ATTRIBUTE_TYPE type; void *ptr; CK_ULONG len; CK_BBOOL found; } ATTRIBUTE_PARSE_LIST; typedef struct _OP_STATE_DATA { CK_STATE session_state; CK_ULONG active_operation; CK_ULONG data_len; // state data gets appended here // // mechanism parameter gets appended here // } OP_STATE_DATA; // this is our internal "tweak" vector (not the FCV) used to tweak various // aspects of the PKCS #11 implementation. Some of these tweaks deviate from // the PKCS #11 specification but are needed to support Netscape. Others // are left as token-defined values by PKCS #11. // // - whether or not to allow weak/semi-weak DES keys to be imported // - whether to insist imported DES keys have proper parity // - whether the CKA_ENCRYPT/DECRYPT/SIGN/VERIFY attributes are modifiable // after key creation // typedef struct _TWEAK_VEC { int allow_weak_des ; int check_des_parity ; int allow_key_mods ; int netscape_mods ; } TWEAK_VEC; typedef struct _TOKEN_DATA { CK_TOKEN_INFO_32 token_info; CK_BYTE user_pin_sha[3 * DES_BLOCK_SIZE]; CK_BYTE so_pin_sha[3 * DES_BLOCK_SIZE]; CK_BYTE next_token_object_name[8]; TWEAK_VEC tweak_vector; } TOKEN_DATA; typedef struct _SSL3_MAC_CONTEXT { DIGEST_CONTEXT hash_context; CK_BBOOL flag; } SSL3_MAC_CONTEXT; typedef struct _RSA_DIGEST_CONTEXT { DIGEST_CONTEXT hash_context; CK_BBOOL flag; } RSA_DIGEST_CONTEXT; typedef struct _MECH_LIST_ELEMENT { CK_MECHANISM_TYPE mech_type; CK_MECHANISM_INFO mech_info; } MECH_LIST_ELEMENT; struct mech_list_item; struct mech_list_item { struct mech_list_item *next; MECH_LIST_ELEMENT element; }; struct mech_list_item * find_mech_list_item_for_type(CK_MECHANISM_TYPE type, struct mech_list_item *head); /* mech_list.c */ CK_RV ock_generic_get_mechanism_list(CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount); /* mech_list.c */ CK_RV ock_generic_get_mechanism_info(CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo); typedef struct _MASTER_KEY_FILE_T { CK_BYTE key[3 * DES_KEY_SIZE]; CK_BYTE sha_hash[SHA1_HASH_SIZE]; } MASTER_KEY_FILE_T; typedef struct _TOK_OBJ_ENTRY { CK_BBOOL deleted; char name[8]; CK_ULONG_32 count_lo; CK_ULONG_32 count_hi; } TOK_OBJ_ENTRY; typedef struct _LW_SHM_TYPE { XPROCLOCK mutex; #if SYSVSEM key_t semtok; #endif TOKEN_DATA nv_token_data; CK_ULONG_32 num_priv_tok_obj; CK_ULONG_32 num_publ_tok_obj; CK_BBOOL priv_loaded; CK_BBOOL publ_loaded; TOK_OBJ_ENTRY publ_tok_objs[ MAX_TOK_OBJS ]; TOK_OBJ_ENTRY priv_tok_objs[ MAX_TOK_OBJS ]; } LW_SHM_TYPE; // These are the same for both AIX and Linux... #define MY_CreateMutex(x) _CreateMutex((MUTEX *)(x)) #define MY_DestroyMutex(x) _DestroyMutex((MUTEX *)(x)) #define MY_LockMutex(x) _LockMutex((MUTEX *)(x)) #define MY_UnlockMutex(x) _UnlockMutex((MUTEX *)(x)) #define MY_CreateMsem(x) CreateXProcLock((void *)(x)) #define MY_DestroyMsem(x) DestroyXProcLock((void *)(x)) #define MY_LockMsem(x) XProcLock((void *)(x)) #define MY_UnlockMsem(x) XProcUnLock((void *)(x)) #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/tok_spec_struct.h0000751000175000017500000004646011327631345022315 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/lib/pkcs11/common/tok_spec_struct.h,v 1.5 2008/07/16 22:27:48 mhalcrow Exp $ */ // /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002,2002 */ /*************************************************************************** Change Log ========== 4/25/03 Kapil Sood (kapil@corrent.com) Added DH key pair generation and DH shared key derivation functions. ****************************************************************************/ #ifndef _TOK_SPECIFIC_STRUCT #define _TOK_SPECIFIC_STRUCT struct token_specific_struct{ CK_BYTE token_directory[PATH_MAX]; // Used to be in the token_local.h as a #def CK_BYTE token_subdir[PATH_MAX]; // subdirectory CK_BYTE token_debug_tag[PATH_MAX]; // debug logging tag CK_RV (*t_init)(char *,CK_SLOT_ID); // Initialization function int (*t_slot2local)(); // convert the PKCS#11 slot to a local index // generaly not used but if a STDLL actualy // managed multiple devices, this would conv CK_RV (*t_rng)(CK_BYTE *,CK_ULONG); // Random Number Gen CK_RV (*t_session)(CK_SLOT_ID); //perform anything specific needed by the token takes a slot id CK_RV (*t_final)(); // any specific final code CK_RV (*t_des_key_gen)(CK_BYTE *,CK_ULONG); CK_RV (*t_des_ecb)( CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_BYTE); CK_RV (*t_des_cbc)( CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, CK_BYTE *,CK_BYTE *, CK_BYTE); CK_RV (*t_tdes_ecb)( CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_BYTE); CK_RV (*t_tdes_cbc)( CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, CK_BYTE *,CK_BYTE *, CK_BYTE); CK_RV (*t_rsa_decrypt)( CK_BYTE *, CK_ULONG, CK_BYTE *, OBJECT *); CK_RV (*t_rsa_encrypt)( CK_BYTE *, CK_ULONG, CK_BYTE *, OBJECT *); CK_RV (*t_rsa_generate_keypair)(TEMPLATE *, TEMPLATE *); /* Begin code contributed by Corrent corp. */ #ifndef NODH // Token Specific DH functions CK_RV (*t_dh_pkcs_derive) ( CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG ) ; CK_RV (*t_dh_pkcs_key_pair_gen)(TEMPLATE *, TEMPLATE *); #endif /* End code contributed by Corrent corp. */ // Token Specific SHA1 functions CK_RV (*t_sha_init)(DIGEST_CONTEXT *); CK_RV (*t_sha_update)( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG); CK_RV (*t_sha_final)( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG *); // Token Specific SHA256 functions CK_RV (*t_sha2_init)(DIGEST_CONTEXT *); CK_RV (*t_sha2_update)( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG); CK_RV (*t_sha2_final)( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG *); CK_RV (*t_sha3_init)(DIGEST_CONTEXT *); CK_RV (*t_sha3_update)(DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG); CK_RV (*t_sha3_final)(DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG *); CK_RV (*t_sha5_init)(DIGEST_CONTEXT *); CK_RV (*t_sha5_update)(DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG); CK_RV (*t_sha5_final)(DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG *); #ifndef NOAES // Token Specific AES functions CK_RV (*t_aes_key_gen)( CK_BYTE *, CK_ULONG); CK_RV (*t_aes_ecb)( CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_ULONG, CK_BYTE); CK_RV (*t_aes_cbc)( CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_ULONG, CK_BYTE *, CK_BYTE); #endif CK_RV (*t_get_mechanism_list)(CK_MECHANISM_TYPE_PTR, CK_ULONG_PTR); CK_RV (*t_get_mechanism_info)(CK_MECHANISM_TYPE, CK_MECHANISM_INFO_PTR); }; typedef struct token_specific_struct token_spec_t; #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/mech_des.c0000751000175000017500000016671211327631345020647 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: mech_des.c // // Mechanisms for DES // #include // for memcmp() et al #include #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // // CK_RV pk_des_ecb_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES_ECB requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des_ecb_encrypt( in_data, in_data_len, out_data, out_data_len, attr->pValue); } // // CK_RV des_ecb_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES_ECB requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des_ecb_decrypt( in_data, in_data_len, out_data, out_data_len, attr->pValue ); } // // CK_RV pk_des_cbc_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES_CBC requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des_cbc_encrypt( in_data, in_data_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); } // // CK_RV des_cbc_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES_CBC requires the input data to be an integral // multiple of the block size // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_des_cbc_decrypt( in_data, in_data_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); } // // CK_RV des_cbc_pad_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE *clear = NULL; CK_ULONG padded_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // DES-CBC-PAD has no input length requirements // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // compute the output length, accounting for padding // padded_len = DES_BLOCK_SIZE * (in_data_len / DES_BLOCK_SIZE + 1); if (length_only == TRUE) { *out_data_len = padded_len; return CKR_OK; } if (*out_data_len < padded_len) { *out_data_len = padded_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } clear = (CK_BYTE *)malloc( padded_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( clear, in_data, in_data_len ); add_pkcs_padding( clear + in_data_len, DES_BLOCK_SIZE, in_data_len, padded_len ); rc = ckm_des_cbc_encrypt( clear, padded_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); if (rc != CKR_OK) st_err_log(113, __FILE__, __LINE__); free( clear ); return rc; } // // CK_RV des_cbc_pad_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE *clear = NULL; CK_ULONG padded_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // no need to validate the input length since we'll pad as necessary // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // we're decrypting so even with CBC-PAD, we should have an integral // number of block to decrypt // if (in_data_len % DES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } // the amount of cleartext after stripping the padding will actually be less // than the input bytes... // padded_len = in_data_len; if (length_only == TRUE) { *out_data_len = padded_len; return CKR_OK; } clear = (CK_BYTE *)malloc( padded_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } rc = ckm_des_cbc_decrypt( in_data, in_data_len, clear, &padded_len, ctx->mech.pParameter, attr->pValue ); if (rc == CKR_OK) { strip_pkcs_padding( clear, padded_len, out_data_len ); memcpy( out_data, clear, *out_data_len ); } else st_err_log(114, __FILE__, __LINE__); free( clear ); return rc; } // // CK_RV des_ecb_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % DES_BLOCK_SIZE); out_len = (total - remain); // should always be at least 1 block if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); rc = ckm_des_ecb_encrypt( clear, out_len, out_data, out_data_len, attr->pValue ); if (rc == CKR_OK) { *out_data_len = out_len; // update the context buffer. we already used the buffer's current // contents so we completely overwrite it // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(115, __FILE__, __LINE__); free( clear ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // shouldn't reach this } // // CK_RV des_ecb_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % DES_BLOCK_SIZE); out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_des_ecb_decrypt( cipher, out_len, out_data, out_data_len, attr->pValue ); if (rc == CKR_OK) { *out_data_len = out_len; // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(116, __FILE__, __LINE__); free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // shouldn't reach this } // // CK_RV des_cbc_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % DES_BLOCK_SIZE); out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // these buffers need to be longword aligned // clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); rc = ckm_des_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); if (rc == CKR_OK) { *out_data_len = out_len; // the new init_v is the last encrypted data block // memcpy( ctx->mech.pParameter, out_data + (*out_data_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(113, __FILE__, __LINE__); free( clear ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV des_cbc_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = context->len + in_data_len; if (total < DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = total % DES_BLOCK_SIZE; out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // these buffers need to be longword aligned // cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_des_cbc_decrypt( cipher, out_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); if (rc == CKR_OK) { *out_data_len = out_len; // the new init_v is the last decrypted data block // memcpy( ctx->mech.pParameter, cipher + (out_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(114, __FILE__, __LINE__); free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV des_cbc_pad_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); // note, this is subtly different from the other encrypt update routines // if (total <= DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block + 1 byte // remain = total % DES_BLOCK_SIZE; out_len = total - remain; if (remain == 0) { remain = DES_BLOCK_SIZE; out_len -= DES_BLOCK_SIZE; } if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } // at this point, we should have: // 1) remain != 0 // 2) out_len != 0 // rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // these buffers need to be longword aligned // clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); // // we don't do padding during the update // rc = ckm_des_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); if (rc == CKR_OK) { // the new init_v is the last encrypted data block // memcpy( ctx->mech.pParameter, out_data + (*out_data_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the temporary space // memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(113, __FILE__, __LINE__); free( clear ); return rc; } } // // CK_RV des_cbc_pad_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; total = (context->len + in_data_len); // note, this is subtly different from the other decrypt update routines // if (total <= DES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block + 1 byte // remain = total % DES_BLOCK_SIZE; out_len = total - remain; if (remain == 0) { remain = DES_BLOCK_SIZE; out_len -= DES_BLOCK_SIZE; } if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } // at this point, we should have: // 1) remain != 0 // 2) out_len != 0 // rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // these buffers need to be longword aligned // cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_des_cbc_decrypt( cipher, out_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); if (rc == CKR_OK) { // the new init_v is the last decrypted data block // memcpy( ctx->mech.pParameter, cipher + (out_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE ); // copy the remaining 'new' input data to the temporary space // memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(114, __FILE__, __LINE__); free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV des_ecb_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES-ECB does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV des_ecb_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES-ECB does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV des_cbc_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES-CBC does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV des_cbc_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (DES_CONTEXT *)ctx->context; // DES-CBC does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV des_cbc_pad_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE clear[2 * DES_BLOCK_SIZE]; CK_ULONG out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; // there will never be more than one block in the context buffer // so the amount of output is as follows: // if less than 1 block stored, we generate one block of output // if a full block is stored, we generate two blocks of output (one pad block) // if (context->len == DES_BLOCK_SIZE) out_len = 2 * DES_BLOCK_SIZE; else out_len = DES_BLOCK_SIZE; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } else { memcpy( clear, context->data, context->len ); add_pkcs_padding( clear + context->len, DES_BLOCK_SIZE, context->len, out_len ); rc = ckm_des_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, attr->pValue ); if (rc != CKR_OK) st_err_log(113, __FILE__, __LINE__); return rc; } } // // CK_RV des_cbc_pad_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { DES_CONTEXT *context = NULL; OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE clear[DES_BLOCK_SIZE]; CK_BYTE cipher[DES_BLOCK_SIZE]; CK_ULONG out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (DES_CONTEXT *)ctx->context; // there had better be a full block in the context buffer // if (context->len != DES_BLOCK_SIZE){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } // we don't know a priori how much data we'll be returning. we won't // know until after we decrypt it and strip the padding. it's possible // that we'll return nothing (the final block might be a padding block). // out_len = DES_BLOCK_SIZE; // upper bound on what we'll return if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } else { memcpy( cipher, context->data, DES_BLOCK_SIZE ); rc = ckm_des_cbc_decrypt( cipher, DES_BLOCK_SIZE, clear, &out_len, ctx->mech.pParameter, attr->pValue ); if (rc == CKR_OK) { strip_pkcs_padding( clear, DES_BLOCK_SIZE, &out_len ); if (out_len != 0) memcpy( out_data, clear, out_len ); *out_data_len = out_len; } else st_err_log(114, __FILE__, __LINE__); return rc; } } // // mechanisms // // // CK_RV ckm_des_key_gen( TEMPLATE *tmpl ) { CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * key_type_attr = NULL; CK_ATTRIBUTE * class_attr = NULL; CK_ATTRIBUTE * local_attr = NULL; CK_BYTE des_key[DES_KEY_SIZE]; CK_ULONG rc; // Checking for a weak key is redundant in that the token // specific keygen may already do this // If the key generated is NOT a clear key, then this // needs to be re-worked. // probably by deciding if the key is being created as a private or // public token object. Only token objects are encrypted // The size is passed in to allow the same token specific code to // do both DES and TDES do { rc = token_specific.t_des_key_gen(des_key,DES_KEY_SIZE); } while (des_check_weak_key(des_key) != FALSE && rc != CKR_OK); if (rc != CKR_OK) return rc; value_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + DES_KEY_SIZE ); key_type_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); class_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS) ); local_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!value_attr || !key_type_attr || !class_attr || !local_attr) { if (value_attr) free( value_attr ); if (key_type_attr) free( key_type_attr ); if (class_attr) free( class_attr ); if (local_attr) free( local_attr ); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = DES_KEY_SIZE; value_attr->pValue = (CK_BYTE *)value_attr + sizeof(CK_ATTRIBUTE); memcpy( value_attr->pValue, des_key, DES_KEY_SIZE ); key_type_attr->type = CKA_KEY_TYPE; key_type_attr->ulValueLen = sizeof(CK_KEY_TYPE); key_type_attr->pValue = (CK_BYTE *)key_type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)key_type_attr->pValue = CKK_DES; class_attr->type = CKA_CLASS; class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS); class_attr->pValue = (CK_BYTE *)class_attr + sizeof(CK_ATTRIBUTE); *(CK_OBJECT_CLASS *)class_attr->pValue = CKO_SECRET_KEY; local_attr->type = CKA_LOCAL; local_attr->ulValueLen = sizeof(CK_BBOOL); local_attr->pValue = (CK_BYTE *)local_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)local_attr->pValue = TRUE; template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, key_type_attr ); template_update_attribute( tmpl, class_attr ); template_update_attribute( tmpl, local_attr ); return CKR_OK; } #if !(NOCDMF) // // CK_RV ckm_cdmf_key_gen( TEMPLATE *tmpl ) { CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * key_type_attr = NULL; CK_ATTRIBUTE * class_attr = NULL; CK_ATTRIBUTE * local_attr = NULL; CK_BYTE cdmf_key[DES_KEY_SIZE]; CK_ULONG repl_len, expected_repl_len; CK_ULONG rc; repl_len = expected_repl_len = DES_KEY_SIZE; rc = communicate( PK_CDMF_KEYGEN, NULL, 0, cdmf_key, &repl_len, NULL, 0, NULL, 0 ); if (rc == CKR_OK) { if (repl_len != expected_repl_len) return CKR_GENERAL_ERROR; } value_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + DES_KEY_SIZE ); key_type_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); class_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS) ); local_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!value_attr || !key_type_attr || !class_attr || !local_attr) { if (value_attr) free( value_attr ); if (key_type_attr) free( key_type_attr ); if (class_attr) free( class_attr ); if (local_attr) free( local_attr ); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = DES_KEY_SIZE; value_attr->pValue = (CK_BYTE *)value_attr + sizeof(CK_ATTRIBUTE); memcpy( value_attr->pValue, cdmf_key, DES_KEY_SIZE ); key_type_attr->type = CKA_KEY_TYPE; key_type_attr->ulValueLen = sizeof(CK_KEY_TYPE); key_type_attr->pValue = (CK_BYTE *)key_type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)key_type_attr->pValue = CKK_CDMF; class_attr->type = CKA_CLASS; class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS); class_attr->pValue = (CK_BYTE *)class_attr + sizeof(CK_ATTRIBUTE); *(CK_OBJECT_CLASS *)class_attr->pValue = CKO_SECRET_KEY; local_attr->type = CKA_LOCAL; local_attr->ulValueLen = sizeof(CK_BBOOL); local_attr->pValue = (CK_BYTE *)local_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)local_attr->pValue = TRUE; template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, key_type_attr ); template_update_attribute( tmpl, class_attr ); template_update_attribute( tmpl, local_attr ); return CKR_OK; } #endif // // CK_RV ckm_des_ecb_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * key_value ) { CK_ULONG rc; if (!in_data || !out_data || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_des_ecb(in_data,in_data_len,out_data,out_data_len,key_value,1);// token specifics return CKR_ errors ... if (rc != CKR_OK) st_err_log(117, __FILE__, __LINE__); return rc; } // // CK_RV ckm_des_ecb_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * key_value ) { CK_ULONG rc; if (!in_data || !out_data || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_des_ecb(in_data,in_data_len,out_data, out_data_len,key_value,0); // last parm is the encrypt flag if (rc != CKR_OK) st_err_log(117, __FILE__, __LINE__); return rc; } // // CK_RV ckm_des_cbc_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * init_v, CK_BYTE * key_value ) { CK_ULONG rc; if (!in_data || !out_data || !init_v || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ #if 0 st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; #else *out_data_len = in_data_len; st_err_log(68, __FILE__, __FUNCTION__); return CKR_BUFFER_TOO_SMALL; #endif } rc = token_specific.t_des_cbc(in_data,in_data_len,out_data, out_data_len,key_value,init_v,1); // last parm is the encrypt flag if (rc != CKR_OK) st_err_log(118, __FILE__, __LINE__); return rc; } // // CK_RV ckm_des_cbc_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * init_v, CK_BYTE * key_value ) { CK_ULONG rc; if (!in_data || !out_data || !init_v || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_des_cbc(in_data,in_data_len,out_data, out_data_len,key_value,init_v,0); // last parm is the encrypt flag if (rc != CKR_OK) st_err_log(118, __FILE__, __LINE__); return rc; } // we're preparing to wrap a key using DES. need to make sure the // data length is a integral multiple of the DES block size. // // PKCS #11 specifies that the padding shall be in the form of NULL // bytes appended to the data // // this routine works with either DES and 3DES as the wrapping mechanism // CK_RV ckm_des_wrap_format( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len ) { CK_BYTE * ptr = NULL; CK_ULONG len1, len2; len1 = *data_len; // if the input key data isn't a multiple of the blocksize, // we pad with NULLs to the next blocksize multiple. // if (len1 % DES_BLOCK_SIZE != 0) { len2 = DES_BLOCK_SIZE * ((len1 / DES_BLOCK_SIZE) + 1); if (length_only == FALSE) { ptr = (CK_BYTE *)realloc(*data, len2); if (!ptr){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } else memset( ptr + len1, 0x0, (len2 - len1) ); *data = ptr; *data_len = len2; } } return CKR_OK; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/dig_mgr.c0000751000175000017500000006454611327631345020512 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: dig_mgr.c // // Digest manager routines // #include #include // for memcmp() et al #include #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // // CK_RV digest_mgr_init( SESSION *sess, DIGEST_CONTEXT *ctx, CK_MECHANISM *mech ) { CK_BYTE * ptr = NULL; if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active != FALSE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } // is the mechanism supported? is the parameter present if required? // switch (mech->mechanism) { case CKM_SHA_1: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } ctx->context = NULL; ckm_sha1_init( ctx ); if (!ctx->context) { st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } } break; case CKM_SHA256: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } ctx->context = NULL; ckm_sha2_init( ctx ); if (!ctx->context) { st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } } break; case CKM_SHA384: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } ctx->context = NULL; ckm_sha3_init( ctx ); if (!ctx->context) { st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } } break; case CKM_SHA512: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } ctx->context = NULL; ckm_sha5_init( ctx ); if (!ctx->context) { st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } } break; case CKM_MD2: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } ctx->context_len = sizeof(MD2_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(MD2_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(MD2_CONTEXT) ); } break; case CKM_MD5: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } ctx->context_len = sizeof(MD5_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(MD5_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } ckm_md5_init( (MD5_CONTEXT *)ctx->context ); } break; default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } if (mech->ulParameterLen > 0) { ptr = (CK_BYTE *)malloc(mech->ulParameterLen); if (!ptr){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( ptr, mech->pParameter, mech->ulParameterLen ); } ctx->mech.ulParameterLen = mech->ulParameterLen; ctx->mech.mechanism = mech->mechanism; ctx->mech.pParameter = ptr; ctx->multi = FALSE; ctx->active = TRUE; return CKR_OK; } // // CK_RV digest_mgr_cleanup( DIGEST_CONTEXT *ctx ) { if (!ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } ctx->mech.ulParameterLen = 0; ctx->mech.mechanism = 0; ctx->multi = FALSE; ctx->active = FALSE; ctx->context_len = 0; if (ctx->mech.pParameter) { free( ctx->mech.pParameter ); ctx->mech.pParameter = NULL; } if (ctx->context != NULL) { free( ctx->context ); ctx->context = NULL; } return CKR_OK; } // // CK_RV digest_mgr_digest( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } // if the caller just wants the encrypted length, there is no reason to // specify the input data. I just need the data length // if ((length_only == FALSE) && (!in_data || !out_data)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->multi == TRUE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } switch (ctx->mech.mechanism) { case CKM_SHA_1: return sha1_hash( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_SHA256: return sha2_hash( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_SHA384: return sha3_hash( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_SHA512: return sha5_hash( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #if !(NOMD2 ) case CKM_MD2: return md2_hash( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif case CKM_MD5: return md5_hash( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); default: st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // shouldn't happen } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV digest_mgr_digest_update( SESSION *sess, DIGEST_CONTEXT *ctx, CK_BYTE *data, CK_ULONG data_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } ctx->multi = TRUE; switch (ctx->mech.mechanism) { case CKM_SHA_1: return sha1_hash_update( sess, ctx, data, data_len ); case CKM_SHA256: return sha2_hash_update( sess, ctx, data, data_len ); case CKM_SHA384: return sha3_hash_update( sess, ctx, data, data_len ); case CKM_SHA512: return sha5_hash_update( sess, ctx, data, data_len ); #if !(NOMD2) case CKM_MD2: return md2_hash_update( sess, ctx, data, data_len ); #endif case CKM_MD5: return md5_hash_update( sess, ctx, data, data_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; // shouldn't happen! } // // CK_RV digest_mgr_digest_key( SESSION * sess, DIGEST_CONTEXT * ctx, CK_OBJECT_HANDLE key_handle ) { CK_ATTRIBUTE * attr = NULL; OBJECT * key_obj = NULL; CK_OBJECT_CLASS class; CK_RV rc; if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( key_handle, &key_obj ); if (rc != CKR_OK){ st_err_log(18, __FILE__, __LINE__); return CKR_KEY_HANDLE_INVALID; } // only allow digesting of CKO_SECRET keys // rc = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (rc == FALSE) { st_err_log(24, __FILE__, __LINE__); return CKR_KEY_INDIGESTIBLE; } else class = *(CK_OBJECT_CLASS *)attr->pValue; if (class != CKO_SECRET_KEY){ st_err_log(24, __FILE__, __LINE__); return CKR_KEY_INDIGESTIBLE; } // every secret key has a CKA_VALUE attribute // rc = template_attribute_find( key_obj->template, CKA_VALUE, &attr ); if (!rc){ st_err_log(24, __FILE__, __LINE__); return CKR_KEY_INDIGESTIBLE; } rc = digest_mgr_digest_update( sess, ctx, attr->pValue, attr->ulValueLen ); if (rc != CKR_OK){ st_err_log(24, __FILE__, __LINE__); } return rc; } // // CK_RV digest_mgr_digest_final( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *hash, CK_ULONG *hash_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } /* XXX KEY - Turn off the multi flag to tell the next layer that this * is the final part of a multi part operation. */ ctx->multi = FALSE; switch (ctx->mech.mechanism) { case CKM_SHA_1: return sha1_hash_final( sess, length_only, ctx, hash, hash_len ); case CKM_SHA256: return sha2_hash_final( sess, length_only, ctx, hash, hash_len ); case CKM_SHA384: return sha3_hash_final( sess, length_only, ctx, hash, hash_len ); case CKM_SHA512: return sha5_hash_final( sess, length_only, ctx, hash, hash_len ); #if !(NOMD2) case CKM_MD2: return md2_hash_final( sess, length_only, ctx, hash, hash_len ); #endif case CKM_MD5: return md5_hash_final( sess, length_only, ctx, hash, hash_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; // shouldn't happen } st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/dp_obj.c0000640000175000017500000007065511327631345020332 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: dp_obj.c // // Domain Parameter Object functions #include #include #include // for memcmp() et al #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // dp_object_check_required_attributes() // // Check required common attributes for domain parameter objects // CK_RV dp_object_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE * attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_KEY_TYPE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return template_check_required_base_attributes( tmpl, mode ); } CK_RV dp_dsa_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; if (mode == MODE_CREATE){ found = template_attribute_find( tmpl, CKA_PRIME, &attr ); if (!found) { st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } found = template_attribute_find( tmpl, CKA_SUBPRIME, &attr ); if (!found) { st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } found = template_attribute_find( tmpl, CKA_BASE, &attr ); if (!found) { st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } else if (mode == MODE_KEYGEN) { found = template_attribute_find( tmpl, CKA_PRIME_BITS, &attr ); if (!found) { st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return dp_object_check_required_attributes( tmpl, mode ); } CK_RV dp_dh_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; if (mode == MODE_CREATE){ found = template_attribute_find( tmpl, CKA_PRIME, &attr ); if (!found) { st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } found = template_attribute_find( tmpl, CKA_BASE, &attr ); if (!found) { st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } else if (mode == MODE_KEYGEN) { found = template_attribute_find( tmpl, CKA_PRIME_BITS, &attr ); if (!found) { st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return dp_object_check_required_attributes( tmpl, mode ); } CK_RV dp_x9dh_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; if (mode == MODE_CREATE){ found = template_attribute_find( tmpl, CKA_PRIME, &attr ); if (!found) { st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } found = template_attribute_find( tmpl, CKA_SUBPRIME, &attr ); if (!found) { st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } found = template_attribute_find( tmpl, CKA_BASE, &attr ); if (!found) { st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } else if (mode == MODE_KEYGEN) { found = template_attribute_find( tmpl, CKA_PRIME_BITS, &attr ); if (!found) { st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } found = template_attribute_find( tmpl, CKA_SUBPRIME_BITS, &attr ); if (!found) { st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return dp_object_check_required_attributes( tmpl, mode ); } // dp_object_set_default_attributes() // CK_RV dp_object_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE * local_attr = NULL; local_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!local_attr) { st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } local_attr->type = CKA_LOCAL; local_attr->ulValueLen = sizeof(CK_BBOOL); local_attr->pValue = (CK_BYTE *)local_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)local_attr->pValue = FALSE; template_update_attribute( tmpl, local_attr ); return CKR_OK; } // dp_object_validate_attribute() // CK_RV dp_object_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode) { switch (attr->type) { case CKA_KEY_TYPE: if (mode == MODE_CREATE) return CKR_OK; else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_LOCAL: if (mode == MODE_CREATE || mode == MODE_KEYGEN) { st_err_log(8, __FILE__, __LINE__); return CKR_ATTRIBUTE_TYPE_INVALID; } return CKR_OK; default: return template_validate_base_attribute( tmpl, attr, mode ); } } // // CK_RV dp_dsa_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode) { switch (attr->type) { case CKA_PRIME: if (mode == MODE_KEYGEN) { st_err_log(193, __FILE__, __LINE__); return CKR_DOMAIN_PARAMS_INVALID; } return CKR_OK; case CKA_PRIME_BITS: if (mode == MODE_CREATE) { st_err_log(193, __FILE__, __LINE__); return CKR_DOMAIN_PARAMS_INVALID; } return CKR_OK; case CKA_BASE: if (mode == MODE_KEYGEN) { st_err_log(193, __FILE__, __LINE__); return CKR_DOMAIN_PARAMS_INVALID; } return CKR_OK; case CKA_SUBPRIME: if (mode == MODE_KEYGEN) { st_err_log(193, __FILE__, __LINE__); return CKR_DOMAIN_PARAMS_INVALID; } return CKR_OK; default: return dp_object_validate_attribute( tmpl, attr, mode ); } } // // CK_RV dp_dh_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode) { switch (attr->type) { case CKA_PRIME: if (mode == MODE_KEYGEN) { st_err_log(193, __FILE__, __LINE__); return CKR_DOMAIN_PARAMS_INVALID; } return CKR_OK; case CKA_PRIME_BITS: if (mode == MODE_CREATE) { st_err_log(193, __FILE__, __LINE__); return CKR_DOMAIN_PARAMS_INVALID; } return CKR_OK; case CKA_BASE: if (mode == MODE_KEYGEN) { st_err_log(193, __FILE__, __LINE__); return CKR_DOMAIN_PARAMS_INVALID; } return CKR_OK; default: return dp_object_validate_attribute( tmpl, attr, mode ); } } // // CK_RV dp_x9dh_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode) { switch (attr->type) { case CKA_PRIME: if (mode == MODE_KEYGEN) { st_err_log(193, __FILE__, __LINE__); return CKR_DOMAIN_PARAMS_INVALID; } return CKR_OK; case CKA_PRIME_BITS: if (mode == MODE_CREATE) { st_err_log(193, __FILE__, __LINE__); return CKR_DOMAIN_PARAMS_INVALID; } return CKR_OK; case CKA_BASE: if (mode == MODE_KEYGEN) { st_err_log(193, __FILE__, __LINE__); return CKR_DOMAIN_PARAMS_INVALID; } return CKR_OK; case CKA_SUBPRIME: if (mode == MODE_KEYGEN) { st_err_log(193, __FILE__, __LINE__); return CKR_DOMAIN_PARAMS_INVALID; } return CKR_OK; case CKA_SUBPRIME_BITS: if (mode == MODE_CREATE) { st_err_log(193, __FILE__, __LINE__); return CKR_DOMAIN_PARAMS_INVALID; } return CKR_OK; default: return dp_object_validate_attribute( tmpl, attr, mode ); } } CK_RV dp_dsa_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_RV rc; CK_ATTRIBUTE *prime_attr; CK_ATTRIBUTE *subprime_attr; CK_ATTRIBUTE *base_attr; CK_ATTRIBUTE *primebits_attr; CK_ATTRIBUTE *type_attr; rc = dp_object_set_default_attributes( tmpl, mode ); if (rc != CKR_OK) return rc; prime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); subprime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); base_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); primebits_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); if (!prime_attr || !subprime_attr || !base_attr || !primebits_attr || !type_attr) { if (prime_attr) free( prime_attr ); if (subprime_attr) free( subprime_attr ); if (base_attr) free( base_attr ); if (primebits_attr) free( primebits_attr ); if (type_attr) free( type_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } prime_attr->type = CKA_PRIME; prime_attr->ulValueLen = 0; prime_attr->pValue = NULL; subprime_attr->type = CKA_SUBPRIME; subprime_attr->ulValueLen = 0; subprime_attr->pValue = NULL; base_attr->type = CKA_BASE; base_attr->ulValueLen = 0; base_attr->pValue = NULL; primebits_attr->type = CKA_PRIME_BITS; primebits_attr->ulValueLen = 0; primebits_attr->pValue = NULL; #if 0 primebits_attr->ulValueLen = sizeof(CK_ULONG); primebits_attr->pValue = (CK_ULONG *)primebits_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)primebits_attr->pValue = 0; #endif type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_DSA; template_update_attribute( tmpl, prime_attr ); template_update_attribute( tmpl, subprime_attr ); template_update_attribute( tmpl, base_attr ); template_update_attribute( tmpl, primebits_attr ); template_update_attribute( tmpl, type_attr ); return CKR_OK; } CK_RV dp_dh_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_RV rc; CK_ATTRIBUTE *prime_attr; CK_ATTRIBUTE *base_attr; CK_ATTRIBUTE *primebits_attr; CK_ATTRIBUTE *type_attr; rc = dp_object_set_default_attributes( tmpl, mode ); if (rc != CKR_OK) return rc; prime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); base_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); primebits_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); if (!prime_attr || !base_attr || !primebits_attr || !type_attr) { if (prime_attr) free( prime_attr ); if (base_attr) free( base_attr ); if (primebits_attr) free( primebits_attr ); if (type_attr) free( type_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } prime_attr->type = CKA_PRIME; prime_attr->ulValueLen = 0; prime_attr->pValue = NULL; base_attr->type = CKA_BASE; base_attr->ulValueLen = 0; base_attr->pValue = NULL; primebits_attr->type = CKA_PRIME_BITS; primebits_attr->ulValueLen = 0; primebits_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_DH; template_update_attribute( tmpl, prime_attr ); template_update_attribute( tmpl, base_attr ); template_update_attribute( tmpl, primebits_attr ); template_update_attribute( tmpl, type_attr ); return CKR_OK; } CK_RV dp_x9dh_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_RV rc; CK_ATTRIBUTE *prime_attr; CK_ATTRIBUTE *subprime_attr; CK_ATTRIBUTE *base_attr; CK_ATTRIBUTE *primebits_attr; CK_ATTRIBUTE *subprimebits_attr; CK_ATTRIBUTE *type_attr; rc = dp_object_set_default_attributes( tmpl, mode ); if (rc != CKR_OK) return rc; prime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); subprime_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); base_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); primebits_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); subprimebits_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); if (!prime_attr || !subprime_attr || !base_attr || !primebits_attr || !subprimebits_attr || !type_attr) { if (prime_attr) free( prime_attr ); if (subprime_attr) free( subprime_attr ); if (base_attr) free( base_attr ); if (primebits_attr) free( primebits_attr ); if (subprimebits_attr) free( subprimebits_attr ); if (type_attr) free( type_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } prime_attr->type = CKA_PRIME; prime_attr->ulValueLen = 0; prime_attr->pValue = NULL; subprime_attr->type = CKA_SUBPRIME; subprime_attr->ulValueLen = 0; subprime_attr->pValue = NULL; base_attr->type = CKA_BASE; base_attr->ulValueLen = 0; base_attr->pValue = NULL; primebits_attr->type = CKA_PRIME_BITS; primebits_attr->ulValueLen = 0; primebits_attr->pValue = NULL; subprimebits_attr->type = CKA_SUBPRIME_BITS; subprimebits_attr->ulValueLen = 0; subprimebits_attr->pValue = NULL; type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_DSA; template_update_attribute( tmpl, prime_attr ); template_update_attribute( tmpl, subprime_attr ); template_update_attribute( tmpl, base_attr ); template_update_attribute( tmpl, primebits_attr ); template_update_attribute( tmpl, type_attr ); return CKR_OK; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/obj_mgr.c0000751000175000017500000023776711327631345020530 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: obj_mgr.c // // Object manager related functions // #include #include #include #include // for memcmp() et al #include #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" #include "../api/apiproto.h" pthread_rwlock_t obj_list_rw_mutex = PTHREAD_RWLOCK_INITIALIZER; CK_RV object_mgr_add( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE * handle ) { OBJECT * o = NULL; CK_BBOOL priv_obj, sess_obj; CK_BBOOL locked = FALSE; CK_RV rc; if (!sess || !pTemplate || !handle){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = MY_LockMutex( &obj_list_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return rc; } locked = TRUE; rc = object_create( pTemplate, ulCount, &o ); if (rc != CKR_OK){ st_err_log(157, __FILE__, __LINE__); goto done; } // check whether session has permissions to create the object, etc // // Object R/O R/W R/O R/W R/W // Type Public Public User User SO // ------------------------------------------------------------- // Public session R/W R/W R/W R/W R/W // Private session R/W R/W // Public token R/O R/W R/O R/W R/W // Private token R/O R/W // sess_obj = object_is_session_object( o ); priv_obj = object_is_private( o ); if (sess->session_info.state == CKS_RO_PUBLIC_SESSION) { if (priv_obj) { st_err_log(57, __FILE__, __LINE__); rc = CKR_USER_NOT_LOGGED_IN; goto done; } if (!sess_obj) { st_err_log(42, __FILE__, __LINE__); rc = CKR_SESSION_READ_ONLY; goto done; } } if (sess->session_info.state == CKS_RO_USER_FUNCTIONS) { if (!sess_obj) { st_err_log(42, __FILE__, __LINE__); rc = CKR_SESSION_READ_ONLY; goto done; } } if (sess->session_info.state == CKS_RW_PUBLIC_SESSION) { if (priv_obj) { st_err_log(57, __FILE__, __LINE__); rc = CKR_USER_NOT_LOGGED_IN; goto done; } } if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) { if (priv_obj) { st_err_log(57, __FILE__, __LINE__); rc = CKR_USER_NOT_LOGGED_IN; goto done; } } // okay, object is created and the session permissions look okay. // add the object to the appropriate list and assign an object handle // if (sess_obj) { o->session = sess; memset( o->name, 0x00, sizeof(CK_BYTE) * 8 ); sess_obj_list = dlist_add_as_first( sess_obj_list, o ); } else { CK_BYTE current[8]; CK_BYTE next[8]; // we'll be modifying nv_token_data so we should protect this part with // the 'pkcs_mutex' // rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto done; } else { // Determine if we have already reached our Max Token Objects // if (priv_obj) { if (global_shm->num_priv_tok_obj >= MAX_TOK_OBJS) { rc = CKR_HOST_MEMORY; st_err_log(1, __FILE__, __LINE__); XProcUnLock(xproclock); goto done; } } else { if (global_shm->num_publ_tok_obj >= MAX_TOK_OBJS) { rc = CKR_HOST_MEMORY; st_err_log(1, __FILE__, __LINE__); XProcUnLock(xproclock); goto done; } } memcpy( current, &nv_token_data->next_token_object_name, 8 ); o->session = NULL; memcpy( &o->name, current, 8 ); compute_next_token_obj_name( current, next ); memcpy( &nv_token_data->next_token_object_name, next, 8 ); save_token_object( o ); // add the object identifier to the shared memory segment // object_mgr_add_to_shm( o ); XProcUnLock( xproclock ); // save_token_data has to lock the mutex itself because it's used elsewhere // save_token_data(); } // now, store the object in the appropriate local token object list // if (priv_obj) priv_token_obj_list = dlist_add_as_last( priv_token_obj_list, o ); else publ_token_obj_list = dlist_add_as_last( publ_token_obj_list, o ); } rc = object_mgr_add_to_map( sess, o, handle ); if (rc != CKR_OK) { DL_NODE *node = NULL; st_err_log(157, __FILE__, __LINE__); // this is messy but we need to remove the object from whatever // list we just added it to // if (sess_obj) { node = dlist_find( sess_obj_list, o ); if (node) sess_obj_list = dlist_remove_node( sess_obj_list, node ); } else { // we'll want to delete the token object file too! // delete_token_object( o ); if (priv_obj) { node = dlist_find( priv_token_obj_list, o ); if (node) priv_token_obj_list = dlist_remove_node( priv_token_obj_list, node ); } else { node = dlist_find( publ_token_obj_list, o ); if (node) publ_token_obj_list = dlist_remove_node( publ_token_obj_list, node ); } rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto done; } object_mgr_del_from_shm( o ); XProcUnLock( xproclock ); } } done: if (locked) MY_UnlockMutex( &obj_list_mutex ); if ((rc != CKR_OK) && (o != NULL)) object_free( o ); return rc; } // object_mgr_add_to_map() // CK_RV object_mgr_add_to_map( SESSION * sess, OBJECT * obj, CK_OBJECT_HANDLE * handle ) { OBJECT_MAP *map_node = NULL; if (!sess || !obj || !handle){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // this guy doesn't lock a mutex because it's calling routines should have // already locked it // map_node = (OBJECT_MAP *)malloc(sizeof(OBJECT_MAP)); if (!map_node){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } map_node->handle = next_object_handle++; map_node->session = sess; map_node->ptr = obj; if (obj->session != NULL) map_node->is_session_obj = TRUE; else map_node->is_session_obj = FALSE; // add the new map entry to the list if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } object_map = dlist_add_as_first( object_map, map_node ); pthread_rwlock_unlock(&obj_list_rw_mutex); *handle = map_node->handle; return CKR_OK; } // object_mgr_copy() // // algorithm: // 1) find the old object // 2) get the template from the old object // 3) merge in the new object's template // 4) perform class-specific sanity checks // CK_RV object_mgr_copy( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE old_handle, CK_OBJECT_HANDLE * new_handle ) { OBJECT *old_obj = NULL; OBJECT *new_obj = NULL; CK_BBOOL priv_obj; CK_BBOOL sess_obj; CK_BBOOL locked = FALSE; CK_RV rc; if (!sess || !pTemplate || !new_handle){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = MY_LockMutex( &obj_list_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return rc; } locked = TRUE; rc = object_mgr_find_in_map1( old_handle, &old_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); goto done; } rc = object_copy( pTemplate, ulCount, old_obj, &new_obj ); if (rc != CKR_OK){ st_err_log(158, __FILE__, __LINE__); goto done; } // check whether session has permissions to create the object, etc // // Object R/O R/W R/O R/W R/W // Type Public Public User User SO // ------------------------------------------------------------- // Public session R/W R/W R/W R/W R/W // Private session R/W R/W // Public token R/O R/W R/O R/W R/W // Private token R/O R/W // sess_obj = object_is_session_object( new_obj ); priv_obj = object_is_private( new_obj ); if (sess->session_info.state == CKS_RO_PUBLIC_SESSION) { if (priv_obj) { st_err_log(57, __FILE__, __LINE__); rc = CKR_USER_NOT_LOGGED_IN; goto done; } if (!sess_obj) { st_err_log(42, __FILE__, __LINE__); rc = CKR_SESSION_READ_ONLY; goto done; } } if (sess->session_info.state == CKS_RO_USER_FUNCTIONS) { if (!sess_obj) { st_err_log(42, __FILE__, __LINE__); rc = CKR_SESSION_READ_ONLY; goto done; } } if (sess->session_info.state == CKS_RW_PUBLIC_SESSION) { if (priv_obj) { st_err_log(57, __FILE__, __LINE__); rc = CKR_USER_NOT_LOGGED_IN; goto done; } } if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) { if (priv_obj) { st_err_log(57, __FILE__, __LINE__); rc = CKR_USER_NOT_LOGGED_IN; goto done; } } // okay, object is created and the session permissions look okay. // add the object to the appropriate list and assign an object handle // if (sess_obj) { new_obj->session = sess; memset( &new_obj->name, 0x00, sizeof(CK_BYTE) * 8 ); sess_obj_list = dlist_add_as_first( sess_obj_list, new_obj ); } else { CK_BYTE current[8]; CK_BYTE next[8]; // we'll be modifying nv_token_data so we should protect this part // with 'pkcs_mutex' // rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto done; } else { // Determine if we have already reached our Max Token Objects // if (priv_obj) { if (global_shm->num_priv_tok_obj >= MAX_TOK_OBJS) { XProcUnLock(xproclock); st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } } else { if (global_shm->num_publ_tok_obj >= MAX_TOK_OBJS) { XProcUnLock(xproclock); st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } } memcpy( current, &nv_token_data->next_token_object_name, 8 ); new_obj->session = NULL; memcpy( &new_obj->name, current, 8 ); compute_next_token_obj_name( current, next ); memcpy( &nv_token_data->next_token_object_name, next, 8 ); save_token_object( new_obj ); // add the object identifier to the shared memory segment // object_mgr_add_to_shm( new_obj ); XProcUnLock( xproclock ); save_token_data(); } // now, store the object in the token object list in RAM for speed // if (priv_obj) priv_token_obj_list = dlist_add_as_last( priv_token_obj_list, new_obj ); else publ_token_obj_list = dlist_add_as_last( publ_token_obj_list, new_obj ); } rc = object_mgr_add_to_map( sess, new_obj, new_handle ); if (rc != CKR_OK) { DL_NODE *node = NULL; st_err_log(157, __FILE__, __LINE__); // this is messy but we need to remove the object from whatever // list we just added it to // if (sess_obj) { node = dlist_find( sess_obj_list, new_obj ); if (node) sess_obj_list = dlist_remove_node( sess_obj_list, node ); } else { // FIXME - need to destroy the token object file too // delete_token_object( new_obj ); if (priv_obj) { node = dlist_find( priv_token_obj_list, new_obj ); if (node) priv_token_obj_list = dlist_remove_node( priv_token_obj_list, node ); } else { node = dlist_find( publ_token_obj_list, new_obj ); if (node) publ_token_obj_list = dlist_remove_node( publ_token_obj_list, node ); } rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto done; } object_mgr_del_from_shm( new_obj ); XProcUnLock( xproclock ); } } done: if (locked) MY_UnlockMutex( &obj_list_mutex ); if ((rc != CKR_OK) && (new_obj != NULL)) object_free( new_obj ); return rc; } // determines whether the session is allowed to create an object. creates // the object but doesn't add the object to any object lists or to the // process' object map. // CK_RV object_mgr_create_skel( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_ULONG mode, CK_ULONG obj_type, CK_ULONG sub_class, OBJECT ** obj ) { OBJECT *o = NULL; CK_RV rc; CK_BBOOL priv_obj; CK_BBOOL sess_obj; if (!sess || !obj){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!pTemplate && (ulCount != 0)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // we don't need to lock mutex for this routine // rc = object_create_skel( pTemplate, ulCount, mode, obj_type, sub_class, &o ); if (rc != CKR_OK){ st_err_log(89, __FILE__, __LINE__); return rc; } sess_obj = object_is_session_object( o ); priv_obj = object_is_private( o ); if (sess->session_info.state == CKS_RO_PUBLIC_SESSION) { if (priv_obj) { object_free( o ); st_err_log(57, __FILE__, __LINE__); return CKR_USER_NOT_LOGGED_IN; } if (!sess_obj) { object_free( o ); st_err_log(42, __FILE__, __LINE__); return CKR_SESSION_READ_ONLY; } } if (sess->session_info.state == CKS_RO_USER_FUNCTIONS) { if (!sess_obj) { object_free( o ); st_err_log(42, __FILE__, __LINE__); return CKR_SESSION_READ_ONLY; } } if (sess->session_info.state == CKS_RW_PUBLIC_SESSION) { if (priv_obj) { object_free( o ); st_err_log(57, __FILE__, __LINE__); return CKR_USER_NOT_LOGGED_IN; } } if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) { if (priv_obj) { object_free( o ); st_err_log(57, __FILE__, __LINE__); return CKR_USER_NOT_LOGGED_IN; } } *obj = o; return CKR_OK; } CK_RV object_mgr_create_final( SESSION * sess, OBJECT * obj, CK_OBJECT_HANDLE * handle ) { CK_BBOOL sess_obj; CK_BBOOL priv_obj; CK_BBOOL locked = FALSE; CK_RV rc; if (!sess || !obj || !handle){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = MY_LockMutex( &obj_list_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return rc; } locked = TRUE; sess_obj = object_is_session_object( obj ); priv_obj = object_is_private( obj ); if (sess_obj) { obj->session = sess; memset( obj->name, 0x0, sizeof(CK_BYTE) * 8 ); sess_obj_list = dlist_add_as_first( sess_obj_list, obj ); } else { CK_BYTE current[8]; CK_BYTE next[8]; // we'll be modifying nv_token_data so we should protect this part // with 'pkcs_mutex' // rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto done; } else { // Determine if we have already reached our Max Token Objects // if (priv_obj) { if (global_shm->num_priv_tok_obj >= MAX_TOK_OBJS) { XProcUnLock(xproclock); st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } } else { if (global_shm->num_publ_tok_obj >= MAX_TOK_OBJS) { XProcUnLock(xproclock); st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } } memcpy( current, &nv_token_data->next_token_object_name, 8 ); obj->session = NULL; memcpy( &obj->name, current, 8 ); compute_next_token_obj_name( current, next ); memcpy( &nv_token_data->next_token_object_name, next, 8 ); save_token_object( obj ); // add the object identifier to the shared memory segment // object_mgr_add_to_shm( obj ); XProcUnLock( xproclock ); save_token_data(); } // now, store the object in the token object list in RAM for speed // if (priv_obj) priv_token_obj_list = dlist_add_as_last( priv_token_obj_list, obj ); else publ_token_obj_list = dlist_add_as_last( publ_token_obj_list, obj ); } rc = object_mgr_add_to_map( sess, obj, handle ); if (rc != CKR_OK) { DL_NODE *node = NULL; st_err_log(157, __FILE__, __LINE__); // this is messy but we need to remove the object from whatever // list we just added it to // if (sess_obj) { node = dlist_find( sess_obj_list, obj ); if (node) sess_obj_list = dlist_remove_node( sess_obj_list, node ); } else { // FIXME - need to destroy the token object file too // delete_token_object( obj ); if (priv_obj) { node = dlist_find( priv_token_obj_list, obj ); if (node) priv_token_obj_list = dlist_remove_node( priv_token_obj_list, node ); } else { node = dlist_find( publ_token_obj_list, obj ); if (node) publ_token_obj_list = dlist_remove_node( publ_token_obj_list, node ); } rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto done; } object_mgr_del_from_shm( obj ); XProcUnLock( xproclock ); } } done: if (locked) MY_UnlockMutex( &obj_list_mutex ); return rc; } // // CK_RV object_mgr_destroy_object( SESSION * sess, CK_OBJECT_HANDLE handle ) { OBJECT * obj = NULL; CK_BBOOL sess_obj; CK_BBOOL priv_obj; CK_BBOOL locked = FALSE; CK_RV rc; if (!sess){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = MY_LockMutex( &obj_list_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); goto done; } locked = TRUE; rc = object_mgr_find_in_map1( handle, &obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); goto done; } sess_obj = object_is_session_object( obj ); priv_obj = object_is_private( obj ); if (sess_obj) { DL_NODE *node; node = dlist_find( sess_obj_list, obj ); if (node) { object_mgr_remove_from_map( handle ); object_free( obj ); sess_obj_list = dlist_remove_node( sess_obj_list, node ); rc = CKR_OK; goto done; } } else { DL_NODE *node = NULL; delete_token_object( obj ); if (priv_obj) node = dlist_find( priv_token_obj_list, obj ); else node = dlist_find( publ_token_obj_list, obj ); if (node) { rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto done; } object_mgr_del_from_shm( obj ); XProcUnLock( xproclock ); object_mgr_remove_from_map( handle ); object_free( obj ); if (priv_obj) priv_token_obj_list = dlist_remove_node( priv_token_obj_list, node ); else publ_token_obj_list = dlist_remove_node( publ_token_obj_list, node ); rc = CKR_OK; goto done; } } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; done: if (locked) MY_UnlockMutex( &obj_list_mutex ); return rc; } // this routine will destroy all token objects in the system // CK_RV object_mgr_destroy_token_objects( void ) { CK_BBOOL locked1 = FALSE, locked2 = FALSE; CK_RV rc; rc = MY_LockMutex( &obj_list_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); goto done; } else locked1 = TRUE; while (publ_token_obj_list) { OBJECT *obj = (OBJECT *)publ_token_obj_list->data; CK_OBJECT_HANDLE handle; rc = object_mgr_find_in_map2( obj, &handle ); if (rc == CKR_OK) { // only if it's found in the object map. it might not be there // object_mgr_remove_from_map( handle ); } else{ st_err_log(110, __FILE__, __LINE__); } delete_token_object( obj ); object_free( obj ); publ_token_obj_list = dlist_remove_node( publ_token_obj_list, publ_token_obj_list ); } while (priv_token_obj_list) { OBJECT *obj = (OBJECT *)priv_token_obj_list->data; CK_OBJECT_HANDLE handle; rc = object_mgr_find_in_map2( obj, &handle ); if (rc == CKR_OK) { // only if it's found in the object map. it might not be there // object_mgr_remove_from_map( handle ); } else{ st_err_log(110, __FILE__, __LINE__); } delete_token_object( obj ); object_free( obj ); priv_token_obj_list = dlist_remove_node( priv_token_obj_list, priv_token_obj_list ); } // now we want to purge the token object list in shared memory // rc = XProcLock( xproclock ); if (rc == CKR_OK) { locked2 = TRUE; global_shm->num_priv_tok_obj = 0; global_shm->num_publ_tok_obj = 0; memset( &global_shm->publ_tok_objs, 0x0, MAX_TOK_OBJS * sizeof(TOK_OBJ_ENTRY) ); memset( &global_shm->priv_tok_objs, 0x0, MAX_TOK_OBJS * sizeof(TOK_OBJ_ENTRY) ); } else st_err_log(150, __FILE__, __LINE__); done: if (locked1 == TRUE) MY_UnlockMutex( &obj_list_mutex ); if (locked2 == TRUE) XProcUnLock( xproclock ); return rc; } // object_mgr_find_in_map_nocache() // // Locates the specified object in the map // without going and checking for cache update // CK_RV object_mgr_find_in_map_nocache( CK_OBJECT_HANDLE handle, OBJECT ** ptr ) { DL_NODE * node = NULL; OBJECT * obj = NULL; if (!ptr){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // no mutex here. the calling function should have locked the mutex // if (pthread_rwlock_rdlock(&obj_list_rw_mutex)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } node = object_map; while (node) { OBJECT_MAP *map = (OBJECT_MAP *)node->data; if (map->handle == handle) { obj = map->ptr; break; } node = node->next; } pthread_rwlock_unlock(&obj_list_rw_mutex); if (obj == NULL || node == NULL) { st_err_log(30, __FILE__, __LINE__); return CKR_OBJECT_HANDLE_INVALID; } // // if this is a token object, we need to check the shared memory segment // to see if any other processes have updated the object // if (object_is_session_object(obj) == TRUE) { *ptr = obj; return CKR_OK; } *ptr = obj; return CKR_OK; } // object_mgr_find_in_map1() // // Locates the specified object in the map // CK_RV object_mgr_find_in_map1( CK_OBJECT_HANDLE handle, OBJECT ** ptr ) { DL_NODE * node = NULL; OBJECT * obj = NULL; if (!ptr){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // no mutex here. the calling function should have locked the mutex // if (pthread_rwlock_rdlock(&obj_list_rw_mutex)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } node = object_map; while (node) { OBJECT_MAP *map = (OBJECT_MAP *)node->data; if (map->handle == handle) { obj = map->ptr; break; } node = node->next; } pthread_rwlock_unlock(&obj_list_rw_mutex); if (obj == NULL || node == NULL) { st_err_log(30, __FILE__, __LINE__); return CKR_OBJECT_HANDLE_INVALID; } // // if this is a token object, we need to check the shared memory segment // to see if any other processes have updated the object // if (object_is_session_object(obj) == TRUE) { *ptr = obj; return CKR_OK; } // SAB XXX Fix me.. need to make it more efficient than just looking for the object to be changed // set a global flag that contains the ref count to all objects.. if the shm ref count changes, then we update the object // if not object_mgr_check_shm( obj ); *ptr = obj; return CKR_OK; } // object_mgr_find_in_map2() // CK_RV object_mgr_find_in_map2( OBJECT * obj, CK_OBJECT_HANDLE * handle ) { DL_NODE * node = NULL; CK_OBJECT_HANDLE h = (CK_OBJECT_HANDLE)NULL; if (!obj || !handle){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // no mutex here. the calling function should have locked the mutex // if (pthread_rwlock_rdlock(&obj_list_rw_mutex)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } node = object_map; while (node) { OBJECT_MAP *map = (OBJECT_MAP *)node->data; if (map->ptr == obj) { h = map->handle; break; } node = node->next; } pthread_rwlock_unlock(&obj_list_rw_mutex); if (node == NULL) { // st_err_log(30, __FILE__, __LINE__); return CKR_OBJECT_HANDLE_INVALID; } // // if this is a token object, we need to check the shared memory segment // to see if any other processes have updated the object // if (object_is_session_object(obj) == TRUE) { *handle = h; return CKR_OK; } object_mgr_check_shm( obj ); *handle = h; return CKR_OK; } CK_RV object_mgr_find_init( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ) { // it is possible the pTemplate == NULL // if (!sess){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (sess->find_active != FALSE){ return CKR_OPERATION_ACTIVE; st_err_log(31, __FILE__, __LINE__); } // initialize the found object list. if it doesn't exist, allocate // a list big enough for 10 handles. we'll reallocate if we need more // if (sess->find_list != NULL) { memset( sess->find_list, 0x0, sess->find_len * sizeof(CK_OBJECT_HANDLE) ); } else { sess->find_list = (CK_OBJECT_HANDLE *)malloc(10 * sizeof(CK_OBJECT_HANDLE)); if (!sess->find_list){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } else { memset( sess->find_list, 0x0, 10 * sizeof(CK_OBJECT_HANDLE) ); sess->find_len = 10; } } sess->find_count = 0; sess->find_idx = 0; // --- need to grab the object lock here MY_LockMutex(&obj_list_mutex); object_mgr_update_from_shm(); // which objects can be returned: // // Public Session: public session objects, public token objects // User Session: all session objects, all token objects // SO session: public session objects, public token objects // switch (sess->session_info.state) { case CKS_RO_PUBLIC_SESSION: case CKS_RW_PUBLIC_SESSION: case CKS_RW_SO_FUNCTIONS: object_mgr_find_build_list( sess, pTemplate, ulCount, publ_token_obj_list, TRUE ); object_mgr_find_build_list( sess, pTemplate, ulCount, sess_obj_list, TRUE ); break; case CKS_RO_USER_FUNCTIONS: case CKS_RW_USER_FUNCTIONS: object_mgr_find_build_list( sess, pTemplate, ulCount, priv_token_obj_list, FALSE ); object_mgr_find_build_list( sess, pTemplate, ulCount, publ_token_obj_list, FALSE ); object_mgr_find_build_list( sess, pTemplate, ulCount, sess_obj_list, FALSE ); break; } MY_UnlockMutex(&obj_list_mutex); sess->find_active = TRUE; return CKR_OK; } // // CK_RV object_mgr_find_build_list( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, DL_NODE * obj_list, CK_BBOOL public_only ) { OBJECT * obj = NULL; DL_NODE * node = NULL; CK_OBJECT_HANDLE handle; CK_BBOOL is_priv; CK_BBOOL match; CK_BBOOL hw_feature = FALSE; CK_BBOOL hidden_object = FALSE; CK_RV rc; CK_ATTRIBUTE * attr; unsigned int i; // pTemplate == NULL is a legal condition here // if (!sess){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // it's possible that the object list is empty // if (!obj_list) return CKR_OK; // PKCS#11 v2.11 (pg. 79): "When searching using C_FindObjectsInit // and C_FindObjects, hardware feature objects are not returned // unless the CKA_CLASS attribute in the template has the value // CKO_HW_FEATURE." So, we check for CKO_HW_FEATURE and if its set, // we'll find these objects below. - KEY for (i = 0; i < ulCount; i++) { if (pTemplate[i].type == CKA_CLASS) { if (*(CK_ULONG *)pTemplate[i].pValue == CKO_HW_FEATURE) { hw_feature = TRUE; break; } } /* only find CKA_HIDDEN objects if its specified in the template. */ if (pTemplate[i].type == CKA_HIDDEN) { if (*(CK_BBOOL *)pTemplate[i].pValue == TRUE) { hidden_object = TRUE; break; } } } node = obj_list; while (node) { match = FALSE; obj = (OBJECT *)node->data; is_priv = object_is_private( obj ); if ((is_priv == FALSE) || (public_only == FALSE)) { // if the user doesn't specify any template attributes then we return // all objects // if (pTemplate == NULL || ulCount == 0) match = TRUE; else match = template_compare( pTemplate, ulCount, obj->template ); } // if we have a match, find the object in the map (add it if necessary) // then add the object to the list of found objects // if (match) { rc = object_mgr_find_in_map2( obj, &handle ); if (rc != CKR_OK) { //st_err_log(110, __FILE__, __LINE__); rc = object_mgr_add_to_map( sess, obj, &handle ); if (rc != CKR_OK){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } if (rc == CKR_OK) { // If hw_feature is false here, we need to filter out all objects // that have the CKO_HW_FEATURE attribute set. - KEY if ((hw_feature == FALSE) && (template_attribute_find(obj->template, CKA_CLASS, &attr) == TRUE)) { if (*(CK_OBJECT_CLASS *)attr->pValue == CKO_HW_FEATURE) goto next_loop; } /* Don't find objects that have been created with the CKA_HIDDEN * attribute set */ if ((hidden_object == FALSE) && (template_attribute_find(obj->template, CKA_HIDDEN, &attr) == TRUE)) { if (*(CK_BBOOL *)attr->pValue == TRUE) goto next_loop; } sess->find_list[ sess->find_count ] = handle; sess->find_count++; if (sess->find_count >= sess->find_len) { sess->find_len += 15; sess->find_list = (CK_OBJECT_HANDLE *)realloc( sess->find_list, sess->find_len * sizeof(CK_OBJECT_HANDLE) ); if (!sess->find_list){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } } } } next_loop: node = node->next; } return CKR_OK; } // // CK_RV object_mgr_find_final( SESSION *sess ) { if (!sess){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (sess->find_active == FALSE){ st_err_log(32, __FILE__, __LINE__, __FUNCTION__); return CKR_OPERATION_NOT_INITIALIZED; } free( sess->find_list ); sess->find_list = NULL; sess->find_count = 0; sess->find_idx = 0; sess->find_active = FALSE; return CKR_OK; } // // CK_RV object_mgr_get_attribute_values( SESSION * sess, CK_OBJECT_HANDLE handle, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ) { OBJECT * obj; CK_BBOOL priv_obj; CK_BBOOL locked = FALSE; CK_RV rc; if (!pTemplate){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = MY_LockMutex( &obj_list_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return rc; } locked = TRUE; rc = object_mgr_find_in_map1( handle, &obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); goto done; } priv_obj = object_is_private( obj ); if (priv_obj == TRUE) { if (sess->session_info.state == CKS_RO_PUBLIC_SESSION || sess->session_info.state == CKS_RW_PUBLIC_SESSION) { st_err_log(57, __FILE__, __LINE__); rc = CKR_USER_NOT_LOGGED_IN; goto done; } } rc = object_get_attribute_values( obj, pTemplate, ulCount ); if (rc != CKR_OK) st_err_log(159, __FILE__, __LINE__); done: if (locked) MY_UnlockMutex( &obj_list_mutex ); return rc; } // // CK_RV object_mgr_get_object_size( CK_OBJECT_HANDLE handle, CK_ULONG * size ) { OBJECT * obj; CK_RV rc; rc = MY_LockMutex( &obj_list_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return rc; } rc = object_mgr_find_in_map1( handle, &obj ); if (rc != CKR_OK) { st_err_log(30, __FILE__, __LINE__); rc = CKR_OBJECT_HANDLE_INVALID; goto done; } *size = object_get_size( obj ); done: MY_UnlockMutex( &obj_list_mutex ); return rc; } // object_mgr_invalidate_handle1() // // Returns: TRUE if successfully removes the node // FALSE if cannot remove the node (not found, etc) // CK_BBOOL object_mgr_invalidate_handle1( CK_OBJECT_HANDLE handle ) { DL_NODE *node = NULL; // // no mutex stuff here. the calling routine should have locked the mutex // if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } node = object_map; while (node) { OBJECT_MAP *map = (OBJECT_MAP *)node->data; // I think we can do this because even token objects exist in RAM // if (map->handle == handle) { object_map = dlist_remove_node( object_map, node ); free( map ); pthread_rwlock_unlock(&obj_list_rw_mutex); return TRUE; } node = node->next; } pthread_rwlock_unlock(&obj_list_rw_mutex); return FALSE; } // object_mgr_invalidate_handle2() // // Returns: TRUE if successfully removes the node // FALSE if cannot remove the node (not found, etc) // CK_BBOOL object_mgr_invalidate_handle2( OBJECT *obj ) { DL_NODE *node = NULL; if (!obj) return FALSE; // // no mutex stuff here. the calling routine should have locked the mutex // if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } node = object_map; while (node) { OBJECT_MAP *map = (OBJECT_MAP *)node->data; // I think we can do this because even token objects exist in RAM if (map->ptr == obj) { object_map = dlist_remove_node( object_map, node ); free( map ); pthread_rwlock_unlock(&obj_list_rw_mutex); return TRUE; } node = node->next; } pthread_rwlock_unlock(&obj_list_rw_mutex); return FALSE; } // object_mgr_purge_session_objects() // // Args: SESSION * // SESS_OBJ_TYPE: can be ALL, PRIVATE or PUBLIC // // Remove all session objects owned by the specified session satisfying // the 'type' requirements // CK_BBOOL object_mgr_purge_session_objects( SESSION * sess, SESS_OBJ_TYPE type ) { DL_NODE *node = NULL; DL_NODE *next = NULL; OBJECT *obj = NULL; CK_BBOOL del; CK_RV rc; if (!sess) return FALSE; rc = MY_LockMutex( &obj_list_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return FALSE; } node = sess_obj_list; while (node) { obj = (OBJECT *)node->data; del = FALSE; if (obj->session == sess) { if (type == PRIVATE) { if (object_is_private(obj)) del = TRUE; } else if (type == PUBLIC) { if (object_is_public(obj)) del = TRUE; } else if (type == ALL) del = TRUE; } if (del == TRUE) { CK_OBJECT_HANDLE handle; CK_RV rc; rc = object_mgr_find_in_map2( obj, &handle ); if (rc == CKR_OK) { object_mgr_invalidate_handle1( handle ); object_free( obj ); } else st_err_log(110, __FILE__, __LINE__); next = node->next; sess_obj_list = dlist_remove_node( sess_obj_list, node ); node = next; } else node = node->next; } MY_UnlockMutex( &obj_list_mutex ); return TRUE; } // this routine cleans up the list of token objects. in general, we don't // need to do this but when tracing memory leaks, it's best that we free everything // that we've allocated // CK_BBOOL object_mgr_purge_token_objects( ) { DL_NODE *node = NULL; DL_NODE *next = NULL; OBJECT *obj = NULL; CK_RV rc; rc = MY_LockMutex( &obj_list_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return FALSE; } node = publ_token_obj_list; while (publ_token_obj_list) { CK_OBJECT_HANDLE handle; CK_RV rc; obj = (OBJECT *)node->data; rc = object_mgr_find_in_map2( obj, &handle ); if (rc == CKR_OK){ object_mgr_invalidate_handle1( handle ); } object_free( obj ); next = node->next; publ_token_obj_list = dlist_remove_node( publ_token_obj_list, node ); node = next; } node = priv_token_obj_list; while (priv_token_obj_list) { CK_OBJECT_HANDLE handle; CK_RV rc; obj = (OBJECT *)node->data; rc = object_mgr_find_in_map2( obj, &handle ); if (rc == CKR_OK) object_mgr_invalidate_handle1( handle ); else{ st_err_log(110, __FILE__, __LINE__); } object_free( obj ); next = node->next; priv_token_obj_list = dlist_remove_node( priv_token_obj_list, node ); node = next; } MY_UnlockMutex( &obj_list_mutex ); return TRUE; } CK_BBOOL object_mgr_purge_private_token_objects( void ) { OBJECT * obj = NULL; DL_NODE * node = NULL; DL_NODE * next = NULL; CK_RV rc; rc = MY_LockMutex( &obj_list_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return FALSE; } node = priv_token_obj_list; while (priv_token_obj_list) { CK_OBJECT_HANDLE handle; CK_RV rc; obj = (OBJECT *)node->data; rc = object_mgr_find_in_map2( obj, &handle ); if (rc == CKR_OK){ object_mgr_invalidate_handle1( handle ); } else{ st_err_log(110, __FILE__, __LINE__); } object_free( obj ); next = node->next; priv_token_obj_list = dlist_remove_node( priv_token_obj_list, node ); node = next; } MY_UnlockMutex( &obj_list_mutex ); return TRUE; } // object_mgr_remove_from_map() // CK_RV object_mgr_remove_from_map( CK_OBJECT_HANDLE handle ) { DL_NODE *node = NULL; // // no mutex stuff here. the calling routine should have locked the mutex // if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } node = object_map; while (node) { OBJECT_MAP *map = (OBJECT_MAP *)node->data; if (map->handle == handle) { object_map = dlist_remove_node( object_map, node ); free( map ); pthread_rwlock_unlock(&obj_list_rw_mutex); return CKR_OK; } node = node->next; } pthread_rwlock_unlock(&obj_list_rw_mutex); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV object_mgr_restore_obj( CK_BYTE *data, OBJECT *oldObj ) { OBJECT * obj = NULL; CK_BBOOL priv; CK_RV rc; if (!data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // The calling stack MUST have the mutex // to many grab it now. #if 0 rc = MY_LockMutex( &obj_list_mutex ); if (rc != CKR_OK) return rc; #endif if (oldObj != NULL) { obj = oldObj; rc = object_restore( data, &obj, TRUE ); } else { rc = object_restore( data, &obj, FALSE ); if (rc == CKR_OK) { priv = object_is_private( obj ); if (priv) priv_token_obj_list = dlist_add_as_last( priv_token_obj_list, obj ); else publ_token_obj_list = dlist_add_as_last( publ_token_obj_list, obj ); XProcLock( xproclock ); if (priv) { if (global_shm->priv_loaded == FALSE){ if (global_shm->num_priv_tok_obj < MAX_TOK_OBJS) object_mgr_add_to_shm( obj ); else{ st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; } } } else { if (global_shm->publ_loaded == FALSE){ if (global_shm->num_publ_tok_obj < MAX_TOK_OBJS) object_mgr_add_to_shm( obj ); else{ st_err_log(1, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; } } } XProcUnLock( xproclock ); } else { st_err_log(160, __FILE__, __LINE__); } } // make the callers have to have the mutes // to many grab it now. #if 0 MY_UnlockMutex( &obj_list_mutex ); #endif return rc; } // // CK_RV object_mgr_set_attribute_values( SESSION * sess, CK_OBJECT_HANDLE handle, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ) { OBJECT * obj; CK_BBOOL sess_obj, priv_obj; CK_BBOOL modifiable; CK_RV rc; if (!pTemplate){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = MY_LockMutex( &obj_list_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return rc; } rc = object_mgr_find_in_map1( handle, &obj ); MY_UnlockMutex( &obj_list_mutex ); if (rc != CKR_OK) { st_err_log(110, __FILE__, __LINE__); return CKR_OBJECT_HANDLE_INVALID; } // determine whether the session is allowed to modify the object // modifiable = object_is_modifiable( obj ); sess_obj = object_is_session_object( obj ); priv_obj = object_is_private( obj ); // if object is not modifiable, it doesn't matter what kind of session // is issuing the request... // if (!modifiable){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } if (sess->session_info.state == CKS_RO_PUBLIC_SESSION) { if (priv_obj){ st_err_log(57, __FILE__, __LINE__); return CKR_USER_NOT_LOGGED_IN; } if (!sess_obj){ st_err_log(42, __FILE__, __LINE__); return CKR_SESSION_READ_ONLY; } } if (sess->session_info.state == CKS_RO_USER_FUNCTIONS) { if (!sess_obj){ st_err_log(42, __FILE__, __LINE__); return CKR_SESSION_READ_ONLY; } } if (sess->session_info.state == CKS_RW_PUBLIC_SESSION) { if (priv_obj){ st_err_log(57, __FILE__, __LINE__); return CKR_USER_NOT_LOGGED_IN; } } if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) { if (priv_obj){ st_err_log(57, __FILE__, __LINE__); return CKR_USER_NOT_LOGGED_IN; } } rc = object_set_attribute_values( obj, pTemplate, ulCount ); if (rc != CKR_OK){ st_err_log(161, __FILE__, __LINE__); return rc; } // okay. the object has been updated. if it's a session object, // we're finished. if it's a token object, we need to update // non-volatile storage. // if (!sess_obj) { TOK_OBJ_ENTRY *entry = NULL; CK_ULONG index; // I still think there's a race condition here if two processes are // updating the same token object at the same time. I don't know how // to solve this short of assigning each token object it's own mutex... // obj->count_lo++; if (obj->count_lo == 0) obj->count_hi++; save_token_object( obj ); rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); return rc; } if (priv_obj) { rc = object_mgr_search_shm_for_obj( global_shm->priv_tok_objs, 0, global_shm->num_priv_tok_obj-1, obj, &index ); if (rc != CKR_OK) { st_err_log(162, __FILE__, __LINE__); XProcUnLock(xproclock); return rc; } entry = &global_shm->priv_tok_objs[index]; } else { rc = object_mgr_search_shm_for_obj( global_shm->publ_tok_objs, 0, global_shm->num_publ_tok_obj-1, obj, &index ); if (rc != CKR_OK) { st_err_log(162, __FILE__, __LINE__); XProcUnLock(xproclock); return rc; } entry = &global_shm->publ_tok_objs[index]; } entry->count_lo = obj->count_lo; entry->count_hi = obj->count_hi; XProcUnLock( xproclock ); } return rc; } // // CK_RV object_mgr_add_to_shm( OBJECT *obj ) { TOK_OBJ_ENTRY * entry = NULL; CK_BBOOL priv; // the calling routine is responsible for locking the global_shm mutex // priv = object_is_private( obj ); if (priv) entry = &global_shm->priv_tok_objs[global_shm->num_priv_tok_obj]; else entry = &global_shm->publ_tok_objs[global_shm->num_publ_tok_obj]; entry->deleted = FALSE; entry->count_lo = 0; entry->count_hi = 0; memcpy( entry->name, obj->name, 8 ); if (priv) { global_shm->num_priv_tok_obj++; object_mgr_sort_priv_shm(); } else { global_shm->num_publ_tok_obj++; object_mgr_sort_publ_shm(); } return CKR_OK; } // // CK_RV object_mgr_del_from_shm( OBJECT *obj ) { CK_ULONG index, count; CK_BBOOL priv; CK_RV rc; // the calling routine is responsible for locking the global_shm mutex // priv = object_is_private( obj ); if (priv) { rc = object_mgr_search_shm_for_obj( global_shm->priv_tok_objs, 0, global_shm->num_priv_tok_obj-1, obj, &index ); if (rc != CKR_OK){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Since the number of objects starts at 1 and index starts at zero, we // decrement before we get count. This eliminates the need to perform // this operation later as well as decrementing the number of objects. // (i.e. If we have 10 objects, num will be 10 but the last index is 9. // If we want to delete the last object we need to subtract 9 from 9 not // 10 from 9.) // global_shm->num_priv_tok_obj--; #if 1 // XXX SAB when the index is a higher number than the number maintained in shm, the count goes astronomical causing a core dump if (index > global_shm->num_priv_tok_obj) { count = index - global_shm->num_priv_tok_obj; } else { count = global_shm->num_priv_tok_obj - index; } #else count = global_shm->num_priv_tok_obj - index; #endif if (count > 0) { // If we are not deleting the last element in the list // Move up count number of elements effectively deleting the index memcpy((char *)&global_shm->priv_tok_objs[index], (char *)&global_shm->priv_tok_objs[index+1], sizeof(TOK_OBJ_ENTRY) * count ); // We need to zero out the last entry... Since the memcopy // does not zero it out... memset((char *)&global_shm->priv_tok_objs[global_shm->num_priv_tok_obj+1], 0, sizeof(TOK_OBJ_ENTRY)); } else { // We are deleting the last element which is in num_priv_tok_obj memset((char *)&global_shm->priv_tok_objs[global_shm->num_priv_tok_obj], 0, sizeof(TOK_OBJ_ENTRY)); } } else { rc = object_mgr_search_shm_for_obj( global_shm->publ_tok_objs, 0, global_shm->num_publ_tok_obj-1, obj, &index ); if (rc != CKR_OK){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } global_shm->num_publ_tok_obj--; #if 1 // XXX SAB when the index is a higher number than the number maintained in shm, the count goes astronomical causing a core dump if (index > global_shm->num_publ_tok_obj) { count = index - global_shm->num_publ_tok_obj; } else { count = global_shm->num_publ_tok_obj - index; } #else count = global_shm->num_publ_tok_obj - index; #endif if (count > 0) { memcpy((char *)&global_shm->publ_tok_objs[index], (char *)&global_shm->publ_tok_objs[index+1], sizeof(TOK_OBJ_ENTRY) * count); // We need to zero out the last entry... Since the memcopy // does not zero it out... memset((char *)&global_shm->publ_tok_objs[global_shm->num_publ_tok_obj+1], 0, sizeof(TOK_OBJ_ENTRY)); } else { memset((char *)&global_shm->publ_tok_objs[global_shm->num_publ_tok_obj], 0, sizeof(TOK_OBJ_ENTRY)); } } // // object list is still sorted...so no need to re-sort // return CKR_OK; } // // CK_RV object_mgr_check_shm( OBJECT *obj ) { TOK_OBJ_ENTRY * entry = NULL; CK_BBOOL priv; CK_ULONG index; CK_RV rc; // the calling routine is responsible for locking the global_shm mutex // priv = object_is_private( obj ); if (priv) { rc = object_mgr_search_shm_for_obj( global_shm->priv_tok_objs, 0, global_shm->num_priv_tok_obj-1, obj, &index ); if (rc != CKR_OK){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } entry = &global_shm->priv_tok_objs[index]; } else { rc = object_mgr_search_shm_for_obj( global_shm->publ_tok_objs, 0, global_shm->num_publ_tok_obj-1, obj, &index ); if (rc != CKR_OK){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } entry = &global_shm->publ_tok_objs[index]; } if ((obj->count_hi == entry->count_hi) && (obj->count_lo == entry->count_lo)) return CKR_OK; rc = reload_token_object( obj ); return rc; } // I'd use the standard bsearch() routine but I want an index, not a pointer. // Converting the pointer to an index might cause problems when switching // to a 64-bit environment... // CK_RV object_mgr_search_shm_for_obj( TOK_OBJ_ENTRY * obj_list, CK_ULONG lo, CK_ULONG hi, OBJECT * obj, CK_ULONG * index ) { // SAB XXX reduce the search time since this is what seems to be burning cycles CK_ULONG idx; if ( obj->index == 0 ) { for (idx=0;idx<=hi;idx++){ if (memcmp(obj->name, obj_list[idx].name,8) == 0) { *index = idx; obj->index = idx; return CKR_OK ; } } } else { // SAB better double check if ( memcmp(obj->name, obj_list[obj->index].name,8) == 0 ){ *index = obj->index; return CKR_OK ; } else { // something is hosed.. go back to the brute force method for (idx=0;idx<=hi;idx++){ if (memcmp(obj->name, obj_list[idx].name,8) == 0) { *index = idx; obj->index = idx; return CKR_OK ; } } } } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; #if 0 #if 1 CK_ULONG idx; for (idx=0;idx<=hi;idx++){ if (memcmp(obj->name, obj_list[idx].name,8) == 0) { *index = idx; return CKR_OK; } } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; #else if (lo == hi) { if (memcmp(obj->name, obj_list[lo].name, 8) == 0) { *index = lo; return CKR_OK; } else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } mid = (lo + hi) / 2; val = memcmp( obj->name, obj_list[mid].name, 8 ); if (val == 0) { *index = mid; return CKR_OK; } if (val < 0) return object_mgr_search_shm_for_obj( obj_list, lo, mid-1, obj, index ); else return object_mgr_search_shm_for_obj( obj_list, mid+1, hi, obj, index ); #endif #endif } // // CK_RV object_mgr_sort_priv_shm( void ) { // for now, we assume the list is sorted by design. this is not unreasonable // since new object handles are assigned in increasing order. problems // will arise after 36^8 token objects have been created... // return CKR_OK; } // // CK_RV object_mgr_sort_publ_shm( void ) { // for now, we assume the list is sorted by design. this is not unreasonable // since new object handles are assigned in increasing order. problems // will arise after 36^8 token objects have been created... // return CKR_OK; } // this routine scans the local token object lists and updates any objects that // have changed. it also adds any new token objects that have been added by // other processes and deletes any objects that have been deleted by other // processes // CK_RV object_mgr_update_from_shm( void ) { object_mgr_update_publ_tok_obj_from_shm(); object_mgr_update_priv_tok_obj_from_shm(); return CKR_OK; } // // CK_RV object_mgr_update_publ_tok_obj_from_shm() { DL_NODE * node = NULL; DL_NODE * next = NULL; TOK_OBJ_ENTRY * te = NULL; OBJECT * obj = NULL; CK_OBJECT_HANDLE handle; CK_ULONG index; int val; CK_RV rc; node = publ_token_obj_list; index = 0; while ((node != NULL) && (index < global_shm->num_publ_tok_obj)) { te = &global_shm->publ_tok_objs[index]; obj = (OBJECT *)node->data; val = memcmp( obj->name, te->name, 8 ); // 3 cases: // 1) object in local list but not in the global list. need to remove from local list // 2) object in both lists. need to compare counters and update as needed // 3) object in global list but not in the local list. need to add the object here. // if (val < 0) { rc = object_mgr_find_in_map2( obj, &handle ); if (rc == CKR_OK){ st_err_log(110, __FILE__, __LINE__); object_mgr_remove_from_map( handle ); } object_free( obj ); // we don't call delete_token_object since we assume it has been called by // another process already. we just want to remove it from the local list // next = node->next; publ_token_obj_list = dlist_remove_node( publ_token_obj_list, node ); // don't increment the index } else if (val == 0) { if ((te->count_hi != obj->count_hi) || (te->count_lo != obj->count_lo)) { reload_token_object( obj ); obj->count_hi = te->count_hi; obj->count_lo = te->count_lo; } next = node->next; index++; } else { DL_NODE *new_node = NULL; OBJECT *new_obj = NULL; new_obj = (OBJECT *)malloc(sizeof(OBJECT)); memset( new_obj, 0x0, sizeof(OBJECT) ); memcpy( new_obj->name, te->name, 8 ); reload_token_object( new_obj ); // insert the new object into this position in the local list. I don't // like accessing the DL_NODE internals like this but this is the best // way for the time being... // // We really need a dlist_insert() routine! // new_node = (DL_NODE *)malloc(sizeof(DL_NODE)); new_node->data = new_obj; // this won't work if the list doesn't already exist but that's not a problem // here because if it doesn't exist we won't fall through this // new_node->next = node->next; node->next = new_node; new_node->prev = node; next = new_node->next; index++; } node = next; } if ((node == NULL) && (index < global_shm->num_publ_tok_obj)) { OBJECT *new_obj = NULL; unsigned int i; // new items added to the end of the list // for (i=index; i < global_shm->num_publ_tok_obj; i++) { new_obj = (OBJECT *)malloc(sizeof(OBJECT)); memset( new_obj, 0x0, sizeof(OBJECT) ); te = &global_shm->publ_tok_objs[index]; memcpy( new_obj->name, te->name, 8 ); reload_token_object( new_obj ); // insert the new object at the end of the local list // publ_token_obj_list = dlist_add_as_last( publ_token_obj_list, new_obj ); } } else if ((node != NULL) && (index >= global_shm->num_publ_tok_obj)) { while (node) { obj = (OBJECT *)node->data; rc = object_mgr_find_in_map2( obj, &handle ); if (rc == CKR_OK){ st_err_log(110, __FILE__, __LINE__); object_mgr_remove_from_map( handle ); } object_free( obj ); // we don't call delete_token_object since we assume it has been called by // another process already. we just want to remove it from the local list // next = node->next; publ_token_obj_list = dlist_remove_node( publ_token_obj_list, node ); node = next; } } return CKR_OK; } // // CK_RV object_mgr_update_priv_tok_obj_from_shm() { DL_NODE * node = NULL; DL_NODE * next = NULL; TOK_OBJ_ENTRY * te = NULL; OBJECT * obj = NULL; CK_OBJECT_HANDLE handle; CK_ULONG index; int val; CK_RV rc; node = priv_token_obj_list; index = 0; // SAB XXX don't bother doing this call if we are not in the correct // login state if ( !(global_login_state == CKS_RW_USER_FUNCTIONS || global_login_state == CKS_RO_USER_FUNCTIONS)){ return CKR_OK; } while ((node != NULL) && (index < global_shm->num_priv_tok_obj)) { te = &global_shm->priv_tok_objs[index]; obj = (OBJECT *)node->data; val = memcmp( obj->name, te->name, 8 ); // 3 cases: // 1) object in local list but not in the global list. need to remove from local list // 2) object in both lists. need to compare counters and update as needed // 3) object in global list but not in the local list. need to add the object here. // if (val < 0) { rc = object_mgr_find_in_map2( obj, &handle ); if (rc == CKR_OK){ st_err_log(110, __FILE__, __LINE__); object_mgr_remove_from_map( handle ); } object_free( obj ); // we don't call delete_token_object since we assume it has been called by // another process already. we just want to remove it from the local list // next = node->next; priv_token_obj_list = dlist_remove_node( priv_token_obj_list, node ); // don't increment the index } else if (val == 0) { if ((te->count_hi != obj->count_hi) || (te->count_lo != obj->count_lo)){ reload_token_object( obj ); obj->count_hi = te->count_hi; obj->count_lo = te->count_lo; } next = node->next; index++; } else { DL_NODE *new_node = NULL; OBJECT *new_obj = NULL; new_obj = (OBJECT *)malloc(sizeof(OBJECT)); memset( new_obj, 0x0, sizeof(OBJECT) ); memcpy( new_obj->name, te->name, 8 ); reload_token_object( new_obj ); // insert the new object into this position in the local list. I don't // like accessing the DL_NODE internals like this but this is the best // way for the time being... // // We really need a dlist_insert() routine! // new_node = (DL_NODE *)malloc(sizeof(DL_NODE)); new_node->data = new_obj; // this won't work if the list doesn't already exist but that's not a problem // here because if it doesn't exist we won't fall through this // new_node->next = node->next; node->next = new_node; new_node->prev = node; next = new_node->next; index++; } node = next; } if ((node == NULL) && (index < global_shm->num_priv_tok_obj)) { OBJECT *new_obj = NULL; unsigned int i; // new items added to the end of the list // for (i=index; i < global_shm->num_priv_tok_obj; i++) { new_obj = (OBJECT *)malloc(sizeof(OBJECT)); memset( new_obj, 0x0, sizeof(OBJECT) ); te = &global_shm->priv_tok_objs[index]; memcpy( new_obj->name, te->name, 8 ); reload_token_object( new_obj ); // insert the new object at the end of the local list // priv_token_obj_list = dlist_add_as_last( priv_token_obj_list, new_obj ); } } else if ((node != NULL) && (index >= global_shm->num_priv_tok_obj)) { while (node) { obj = (OBJECT *)node->data; rc = object_mgr_find_in_map2( obj, &handle ); if (rc == CKR_OK){ st_err_log(110, __FILE__, __LINE__); object_mgr_remove_from_map( handle ); } object_free( obj ); // we don't call delete_token_object since we assume it has been called by // another process already. we just want to remove it from the local list // next = node->next; priv_token_obj_list = dlist_remove_node( priv_token_obj_list, node ); node = next; } } return CKR_OK; } // SAB FIXME FIXME CK_BBOOL object_mgr_purge_map( SESSION * sess, SESS_OBJ_TYPE type ) { DL_NODE *node = NULL; DL_NODE *next = NULL; // if (!proc || !sess) // return FALSE; if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } node = object_map; while (node) { OBJECT_MAP *map = (OBJECT_MAP *)node->data; OBJECT *obj = (OBJECT *)map->ptr; next = node->next; if (type == PRIVATE) { if (object_is_private(obj)) { object_map = dlist_remove_node( object_map, node ); free( map ); } } if (type == PUBLIC) { if (object_is_public(obj)) { object_map = dlist_remove_node( object_map, node ); free( map ); } } node = next; } pthread_rwlock_unlock(&obj_list_rw_mutex); return TRUE; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/tokenlocal.h0000751000175000017500000003646211327631345021236 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/lib/pkcs11/common/tokenlocal.h,v 1.1 2005/01/18 16:09:02 kyoder Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // // to get the variant dependency out #ifndef _TOK_LOCAL_ #define _TOK_LOCAL_ #define PK_LITE_DIR token_specific.token_directory #define PK_DIR PK_LITE_DIR #define SUB_DIR token_specific.token_subdir #define DBGTAG token_specific.token_debug_tag #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/asn1.c0000751000175000017500000014574511327631345017745 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // ASN.1 encoding/decoding routines // // This code is a mess... // #include #include #include // for memcmp() et al #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" // // CK_ULONG ber_encode_INTEGER( CK_BBOOL length_only, CK_BYTE ** ber_int, CK_ULONG * ber_int_len, CK_BYTE * data, CK_ULONG data_len ) { CK_BYTE *buf = NULL; CK_ULONG len; // if data_len < 127 use short-form length id // if data_len < 256 use long-form length id with 1-byte length field // if data_len < 65536 use long-form length id with 2-byte length field // if data_len < 16777216 use long-form length id with 3-byte length field // if (data_len < 128) len = 1 + 1 + data_len; else if (data_len < 256) len = 1 + (1 + 1) + data_len; else if (data_len < (1 << 16)) len = 1 + (1 + 2) + data_len; else if (data_len < (1 << 24)) len = 1 + (1 + 3) + data_len; else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *ber_int_len = len; return CKR_OK; } buf = (CK_BYTE *)malloc( len ); if (!buf){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } if (data_len < 128) { buf[0] = 0x02; buf[1] = data_len; memcpy( &buf[2], data, data_len ); *ber_int_len = len; *ber_int = buf; return CKR_OK; } if (data_len < 256) { buf[0] = 0x02; buf[1] = 0x81; buf[2] = data_len; memcpy( &buf[3], data, data_len ); *ber_int_len = len; *ber_int = buf; return CKR_OK; } if (data_len < (1 << 16)) { buf[0] = 0x02; buf[1] = 0x82; buf[2] = (data_len >> 8) & 0xFF; buf[3] = (data_len ) & 0xFF; memcpy( &buf[4], data, data_len ); *ber_int_len = len; *ber_int = buf; return CKR_OK; } if (data_len < (1 << 24)) { buf[0] = 0x02; buf[1] = 0x83; buf[2] = (data_len >> 16) & 0xFF; buf[3] = (data_len >> 8) & 0xFF; buf[4] = (data_len ) & 0xFF; memcpy( &buf[5], data, data_len ); *ber_int_len = len; *ber_int = buf; return CKR_OK; } // we should never reach this // free( buf ); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV ber_decode_INTEGER( CK_BYTE * ber_int, CK_BYTE ** data, CK_ULONG * data_len, CK_ULONG * field_len ) { CK_ULONG len, length_octets; if (!ber_int){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ber_int[0] != 0x02){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // short form lengths are easy // if ((ber_int[1] & 0x80) == 0) { len = ber_int[1] & 0x7F; *data = &ber_int[2]; *data_len = len; *field_len = 1 + 1 + len; return CKR_OK; } length_octets = ber_int[1] & 0x7F; if (length_octets == 1) { len = ber_int[2]; *data = &ber_int[3]; *data_len = len; *field_len = 1 + (1 + 1) + len; return CKR_OK; } if (length_octets == 2) { len = ber_int[2]; len = len << 8; len |= ber_int[3]; *data = &ber_int[4]; *data_len = len; *field_len = 1 + (1 + 2) + len; return CKR_OK; } if (length_octets == 3) { len = ber_int[2]; len = len << 8; len |= ber_int[3]; len = len << 8; len |= ber_int[4]; *data = &ber_int[5]; *data_len = len; *field_len = 1 + (1 + 3) + len; return CKR_OK; } // > 3 length octets implies a length > 16MB which isn't possible for // the coprocessor // st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV ber_encode_OCTET_STRING( CK_BBOOL length_only, CK_BYTE ** str, CK_ULONG * str_len, CK_BYTE * data, CK_ULONG data_len ) { CK_BYTE *buf = NULL; CK_ULONG len; // I only support Primitive encoding for OCTET STRINGS // // if data_len < 128 use short-form length id // if data_len < 256 use long-form length id with 1-byte length field // if data_len < 65536 use long-form length id with 2-byte length field // if (data_len < 128) len = 1 + 1 + data_len; else if (data_len < 256) len = 1 + (1 + 1) + data_len; else if (data_len < (1 << 16)) len = 1 + (1 + 2) + data_len; else if (data_len < (1 << 24)) len = 1 + (1 + 3) + data_len; else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *str_len = len; return CKR_OK; } buf = (CK_BYTE *)malloc( len ); if (!buf){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } if (data_len < 128) { buf[0] = 0x04; // primitive, OCTET STRING buf[1] = data_len; memcpy( &buf[2], data, data_len ); *str_len = len; *str = buf; return CKR_OK; } if (data_len < 256) { buf[0] = 0x04; // primitive, OCTET STRING buf[1] = 0x81; // length header -- 1 length octets buf[2] = data_len; memcpy( &buf[3], data, data_len ); *str_len = len; *str = buf; return CKR_OK; } if (data_len < (1 << 16)) { buf[0] = 0x04; // primitive, OCTET STRING buf[1] = 0x82; // length header -- 2 length octets buf[2] = (data_len >> 8) & 0xFF; buf[3] = (data_len ) & 0xFF; memcpy( &buf[4], data, data_len ); *str_len = len; *str = buf; return CKR_OK; } if (data_len < (1 << 24)) { buf[0] = 0x04; // primitive, OCTET STRING buf[1] = 0x83; // length header -- 3 length octets buf[2] = (data_len >> 16) & 0xFF; buf[3] = (data_len >> 8) & 0xFF; buf[4] = (data_len ) & 0xFF; memcpy( &buf[5], data, data_len ); *str_len = len; *str = buf; return CKR_OK; } // we should never reach this // free( buf ); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV ber_decode_OCTET_STRING( CK_BYTE * str, CK_BYTE ** data, CK_ULONG * data_len, CK_ULONG * field_len ) { CK_ULONG len, length_octets; // I only support decoding primitive OCTET STRINGS // if (!str){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (str[0] != 0x04){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // short form lengths are easy // if ((str[1] & 0x80) == 0) { len = str[1] & 0x7F; *data = &str[2]; *data_len = len; *field_len = 1 + (1) + len; return CKR_OK; } length_octets = str[1] & 0x7F; if (length_octets == 1) { len = str[2]; *data = &str[3]; *data_len = len; *field_len = 1 + (1 + 1) + len; return CKR_OK; } if (length_octets == 2) { len = str[2]; len = len << 8; len |= str[3]; *data = &str[4]; *data_len = len; *field_len = 1 + (1 + 2) + len; return CKR_OK; } if (length_octets == 3) { len = str[2]; len = len << 8; len |= str[3]; len = len << 8; len |= str[4]; *data = &str[5]; *data_len = len; *field_len = 1 + (1 + 3) + len; return CKR_OK; } // > 3 length octets implies a length > 16MB // st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV ber_encode_SEQUENCE( CK_BBOOL length_only, CK_BYTE ** seq, CK_ULONG * seq_len, CK_BYTE * data, CK_ULONG data_len ) { CK_BYTE *buf = NULL; CK_ULONG len; // if data_len < 127 use short-form length id // if data_len < 65536 use long-form length id with 2-byte length field // if (data_len < 128) len = 1 + 1 + data_len; else if (data_len < 256) len = 1 + (1 + 1) + data_len; else if (data_len < (1 << 16)) len = 1 + (1 + 2) + data_len; else if (data_len < (1 << 24)) len = 1 + (1 + 3) + data_len; else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *seq_len = len; return CKR_OK; } buf = (CK_BYTE *)malloc( len ); if (!buf){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } if (data_len < 128) { buf[0] = 0x30; // constructed, SEQUENCE buf[1] = data_len; memcpy( &buf[2], data, data_len ); *seq_len = len; *seq = buf; return CKR_OK; } if (data_len < 256) { buf[0] = 0x30; // constructed, SEQUENCE buf[1] = 0x81; // length header -- 1 length octets buf[2] = data_len; memcpy( &buf[3], data, data_len ); *seq_len = len; *seq = buf; return CKR_OK; } if (data_len < (1 << 16)) { buf[0] = 0x30; // constructed, SEQUENCE buf[1] = 0x82; // length header -- 2 length octets buf[2] = (data_len >> 8) & 0xFF; buf[3] = (data_len ) & 0xFF; memcpy( &buf[4], data, data_len ); *seq_len = len; *seq = buf; return CKR_OK; } if (data_len < (1 << 24)) { buf[0] = 0x30; // constructed, SEQUENCE buf[1] = 0x83; // length header -- 3 length octets buf[2] = (data_len >> 16) & 0xFF; buf[3] = (data_len >> 8) & 0xFF; buf[4] = (data_len ) & 0xFF; memcpy( &buf[5], data, data_len ); *seq_len = len; *seq = buf; return CKR_OK; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV ber_decode_SEQUENCE( CK_BYTE * seq, CK_BYTE ** data, CK_ULONG * data_len, CK_ULONG * field_len ) { CK_ULONG len, length_octets; if (!seq){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (seq[0] != 0x30){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // short form lengths are easy // if ((seq[1] & 0x80) == 0) { len = seq[1] & 0x7F; *data = &seq[2]; *data_len = len; *field_len = 1 + (1) + len; return CKR_OK; } length_octets = seq[1] & 0x7F; if (length_octets == 1) { len = seq[2]; *data = &seq[3]; *data_len = len; *field_len = 1 + (1 + 1) + len; return CKR_OK; } if (length_octets == 2) { len = seq[2]; len = len << 8; len |= seq[3]; *data = &seq[4]; *data_len = len; *field_len = 1 + (1 + 2) + len; return CKR_OK; } if (length_octets == 3) { len = seq[2]; len = len << 8; len |= seq[3]; len = len << 8; len |= seq[4]; *data = &seq[5]; *data_len = len; *field_len = 1 + (1 + 3) + len; return CKR_OK; } // > 3 length octets implies a length > 16MB // st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // PrivateKeyInfo ::= SEQUENCE { // version Version -- always '0' for now // privateKeyAlgorithm PrivateKeyAlgorithmIdentifier // privateKey PrivateKey // attributes // } // CK_RV ber_encode_PrivateKeyInfo( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len, CK_BYTE * algorithm_id, CK_ULONG algorithm_id_len, CK_BYTE * priv_key, CK_ULONG priv_key_len ) { CK_BYTE * buf = NULL; CK_BYTE * tmp = NULL; CK_BYTE version[] = { 0 }; CK_BYTE attrib[] = {0x05, 0x00}; CK_ULONG len, total; CK_RV rc; len = 0; rc = ber_encode_INTEGER( TRUE, NULL, &total, version, sizeof(version) ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); return rc; } else len += total; len += algorithm_id_len; rc = ber_encode_OCTET_STRING( TRUE, NULL, &total, priv_key, priv_key_len ); if (rc != CKR_OK){ st_err_log(77, __FILE__, __LINE__); return rc; } else len += total; // for this stuff, attributes are always NULL == 05 00 // len += sizeof(attrib); if (length_only == TRUE) { rc = ber_encode_SEQUENCE( TRUE, NULL, &total, NULL, len ); if (rc == CKR_OK) *data_len = total; if (rc != CKR_OK) st_err_log(78, __FILE__, __LINE__); return rc; } buf = (CK_BYTE *)malloc(len); if (!buf){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } len = 0; rc = ber_encode_INTEGER( FALSE, &tmp, &total, version, sizeof(version) ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+len, tmp, total ); len += total; free( tmp ); memcpy( buf+len, algorithm_id, algorithm_id_len ); len += algorithm_id_len; rc = ber_encode_OCTET_STRING( FALSE, &tmp, &total, priv_key, priv_key_len ); if (rc != CKR_OK){ st_err_log(77, __FILE__, __LINE__); goto error; } memcpy( buf+len, tmp, total ); len += total; free( tmp ); memcpy( buf+len, attrib, sizeof(attrib)); len += sizeof(attrib); rc = ber_encode_SEQUENCE( FALSE, data, data_len, buf, len ); if (rc != CKR_OK) st_err_log(78, __FILE__, __LINE__); error: free( buf ); return rc; } // // CK_RV ber_decode_PrivateKeyInfo( CK_BYTE * data, CK_ULONG data_len, CK_BYTE ** algorithm, CK_ULONG * alg_len, CK_BYTE ** priv_key ) { CK_BYTE *buf = NULL; CK_BYTE *alg = NULL; CK_BYTE *ver = NULL; CK_ULONG buf_len, offset, len, field_len; CK_RV rc; if (!data || (data_len == 0)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = ber_decode_SEQUENCE( data, &buf, &buf_len, &field_len ); if (rc != CKR_OK){ st_err_log(81, __FILE__, __LINE__); return rc; } // version -- we just ignore this // offset = 0; rc = ber_decode_INTEGER( buf+offset, &ver, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); return rc; } offset += field_len; // 'buf' is now pointing to the PrivateKeyAlgorithmIdentifier // rc = ber_decode_SEQUENCE( buf+offset, &alg, &len, &field_len ); if (rc != CKR_OK){ st_err_log(81, __FILE__, __LINE__); return rc; } *algorithm = alg; *alg_len = len; rc = ber_decode_OCTET_STRING( alg + len, priv_key, &buf_len, &field_len ); if (rc != CKR_OK) st_err_log(81, __FILE__, __LINE__); return rc; } // RSAPrivateKey ::= SEQUENCE { // version Version -- always '0' for now // modulus INTEGER // publicExponent INTEGER // privateExponent INTEGER // prime1 INTEGER // prime2 INTEGER // exponent1 INTEGER // exponent2 INTEGER // coefficient INTEGER // } // CK_RV ber_encode_RSAPrivateKey( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len, CK_ATTRIBUTE * modulus, CK_ATTRIBUTE * publ_exp, CK_ATTRIBUTE * priv_exp, CK_ATTRIBUTE * prime1, CK_ATTRIBUTE * prime2, CK_ATTRIBUTE * exponent1, CK_ATTRIBUTE * exponent2, CK_ATTRIBUTE * coeff ) { CK_BYTE *buf = NULL; CK_BYTE *buf2 = NULL; CK_ULONG len, offset; CK_BYTE version[] = { 0 }; CK_RV rc; offset = 0; rc = 0; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, sizeof(version) ); offset += len; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, modulus->ulValueLen ); offset += len; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, publ_exp->ulValueLen ); offset += len; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, priv_exp->ulValueLen ); offset += len; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, prime1->ulValueLen ); offset += len; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, prime2->ulValueLen ); offset += len; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, exponent1->ulValueLen ); offset += len; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, exponent2->ulValueLen ); offset += len; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, coeff->ulValueLen ); offset += len; if (rc != CKR_OK){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { rc = ber_encode_SEQUENCE( TRUE, NULL, &len, NULL, offset ); if (rc != CKR_OK){ st_err_log(78, __FILE__, __LINE__); return rc; } rc = ber_encode_PrivateKeyInfo( TRUE, NULL, data_len, NULL, ber_AlgIdRSAEncryptionLen, NULL, len ); if (rc != CKR_OK){ st_err_log(82, __FILE__, __LINE__); return rc; } return rc; } buf = (CK_BYTE *)malloc(offset); if (!buf){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } offset = 0; rc = 0; rc = ber_encode_INTEGER( FALSE, &buf2, &len, version, sizeof(version) ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, buf2, len ); offset += len; free( buf2 ); rc = ber_encode_INTEGER( FALSE, &buf2, &len, (CK_BYTE *)modulus + sizeof(CK_ATTRIBUTE), modulus->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, buf2, len ); offset += len; free( buf2 ); rc = ber_encode_INTEGER( FALSE, &buf2, &len, (CK_BYTE *)publ_exp + sizeof(CK_ATTRIBUTE), publ_exp->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, buf2, len ); offset += len; free( buf2 ); rc = ber_encode_INTEGER( FALSE, &buf2, &len, (CK_BYTE *)priv_exp + sizeof(CK_ATTRIBUTE), priv_exp->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, buf2, len ); offset += len; free( buf2 ); rc = ber_encode_INTEGER( FALSE, &buf2, &len, (CK_BYTE *)prime1 + sizeof(CK_ATTRIBUTE), prime1->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, buf2, len ); offset += len; free( buf2 ); rc = ber_encode_INTEGER( FALSE, &buf2, &len, (CK_BYTE *)prime2 + sizeof(CK_ATTRIBUTE), prime2->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, buf2, len ); offset += len; free( buf2 ); rc = ber_encode_INTEGER( FALSE, &buf2, &len, (CK_BYTE *)exponent1 + sizeof(CK_ATTRIBUTE), exponent1->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, buf2, len ); offset += len; free( buf2 ); rc = ber_encode_INTEGER( FALSE, &buf2, &len, (CK_BYTE *)exponent2 + sizeof(CK_ATTRIBUTE), exponent2->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, buf2, len ); offset += len; free( buf2 ); rc = ber_encode_INTEGER( FALSE, &buf2, &len, (CK_BYTE *)coeff + sizeof(CK_ATTRIBUTE), coeff->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, buf2, len ); offset += len; free( buf2 ); rc = ber_encode_SEQUENCE( FALSE, &buf2, &len, buf, offset ); if (rc != CKR_OK){ st_err_log(78, __FILE__, __LINE__); goto error; } rc = ber_encode_PrivateKeyInfo( FALSE, data, data_len, ber_AlgIdRSAEncryption, ber_AlgIdRSAEncryptionLen, buf2, len ); if (rc != CKR_OK) { st_err_log(82, __FILE__, __LINE__); } error: if (buf2) free( buf2 ); if (buf) free( buf ); return rc; } // // CK_RV ber_decode_RSAPrivateKey( CK_BYTE * data, CK_ULONG data_len, CK_ATTRIBUTE ** modulus, CK_ATTRIBUTE ** publ_exp, CK_ATTRIBUTE ** priv_exp, CK_ATTRIBUTE ** prime1, CK_ATTRIBUTE ** prime2, CK_ATTRIBUTE ** exponent1, CK_ATTRIBUTE ** exponent2, CK_ATTRIBUTE ** coeff ) { CK_ATTRIBUTE *n_attr = NULL; CK_ATTRIBUTE *e_attr = NULL; CK_ATTRIBUTE *d_attr = NULL; CK_ATTRIBUTE *p_attr = NULL; CK_ATTRIBUTE *q_attr = NULL; CK_ATTRIBUTE *e1_attr = NULL; CK_ATTRIBUTE *e2_attr = NULL; CK_ATTRIBUTE *coeff_attr = NULL; CK_BYTE *alg = NULL; CK_BYTE *rsa_priv_key = NULL; CK_BYTE *buf = NULL; CK_BYTE *tmp = NULL; CK_ULONG offset, buf_len, field_len, len; CK_RV rc; rc = ber_decode_PrivateKeyInfo( data, data_len, &alg, &len, &rsa_priv_key ); if (rc != CKR_OK){ st_err_log(83, __FILE__, __LINE__); return rc; } // make sure we're dealing with an RSA key // if (memcmp(alg, ber_rsaEncryption, ber_rsaEncryptionLen) != 0){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // probably ought to use a different error } rc = ber_decode_SEQUENCE( rsa_priv_key, &buf, &buf_len, &field_len ); if (rc != CKR_OK) return rc; // parse the RSAPrivateKey // offset = 0; // Version // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; // modulus // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; // public exponent // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; // private exponent // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; // prime #1 // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; // prime #2 // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; // exponent #1 // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; // exponent #2 // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; // coefficient // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; if (offset > buf_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // it looks okay. build the attributes // offset = 0; // skip the version // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; // modulus // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_MODULUS, tmp, len, &n_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += field_len; } // public exponent // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_PUBLIC_EXPONENT, tmp, len, &e_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += field_len; } // private exponent // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_PRIVATE_EXPONENT, tmp, len, &d_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += field_len; } // prime #1 // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_PRIME_1, tmp, len, &p_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += field_len; } // prime #2 // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_PRIME_2, tmp, len, &q_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += field_len; } // exponent #1 // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_EXPONENT_1, tmp, len, &e1_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += field_len; } // exponent #2 // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_EXPONENT_2, tmp, len, &e2_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += field_len; } // coefficient // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_COEFFICIENT, tmp, len, &coeff_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += len; } *modulus = n_attr; *publ_exp = e_attr; *priv_exp = d_attr; *prime1 = p_attr; *prime2 = q_attr; *exponent1 = e1_attr; *exponent2 = e2_attr; *coeff = coeff_attr; return CKR_OK; cleanup: if (n_attr) free(n_attr); if (e_attr) free(e_attr); if (d_attr) free(d_attr); if (p_attr) free(p_attr); if (q_attr) free(q_attr); if (e1_attr) free(e1_attr); if (e2_attr) free(e2_attr); if (coeff_attr) free(coeff_attr); return rc; } // DSA is a little different from RSA // // DSAPrivateKey ::= INTEGER // // The 'parameters' field of the AlgorithmIdentifier are as follows: // // DSSParameters ::= SEQUENCE { // prime1 INTEGER // prime2 INTEGER // base INTEGER // } // CK_RV ber_encode_DSAPrivateKey( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len, CK_ATTRIBUTE * prime1, CK_ATTRIBUTE * prime2, CK_ATTRIBUTE * base, CK_ATTRIBUTE * priv_key ) { CK_BYTE *param = NULL; CK_BYTE *buf = NULL; CK_BYTE *tmp = NULL; CK_BYTE *alg = NULL; CK_ULONG offset, len, param_len; CK_ULONG alg_len; CK_RV rc; // build the DSS parameters first // offset = 0; rc = 0; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, prime1->ulValueLen ); offset += len; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, prime2->ulValueLen ); offset += len; rc |= ber_encode_INTEGER( TRUE, NULL, &len, NULL, base->ulValueLen ); offset += len; if (rc != CKR_OK){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { rc = ber_encode_SEQUENCE( TRUE, NULL, ¶m_len, NULL, offset ); if (rc != CKR_OK){ st_err_log(78, __FILE__, __LINE__); return rc; } rc = ber_encode_INTEGER( TRUE, NULL, &len, NULL, priv_key->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); return rc; } rc = ber_encode_PrivateKeyInfo( TRUE, NULL, data_len, NULL, ber_idDSALen + param_len, NULL, len ); if (rc != CKR_OK){ st_err_log(82, __FILE__, __LINE__); } return rc; } // 'buf' will be the sequence data for the AlgorithmIdentifyer::parameter // buf = (CK_BYTE *)malloc(offset); if (!buf){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } len = 0; offset = 0; rc = ber_encode_INTEGER( FALSE, &tmp, &len, (CK_BYTE *)prime1 + sizeof(CK_ATTRIBUTE), prime1->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, tmp, len ); offset += len; free( tmp ); tmp = NULL; rc = ber_encode_INTEGER( FALSE, &tmp, &len, (CK_BYTE *)prime2 + sizeof(CK_ATTRIBUTE), prime2->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, tmp, len ); offset += len; free( tmp ); tmp = NULL; rc = ber_encode_INTEGER( FALSE, &tmp, &len, (CK_BYTE *)base + sizeof(CK_ATTRIBUTE), base->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } memcpy( buf+offset, tmp, len ); offset += len; free( tmp ); tmp = NULL; rc = ber_encode_SEQUENCE( FALSE, ¶m, ¶m_len, buf, offset ); if (rc != CKR_OK) { st_err_log(78, __FILE__, __LINE__); free(buf); return rc; } free( buf ); buf = NULL; // Build the DSA AlgorithmIdentifier // // AlgorithmIdentifier ::= SEQUENCE { // algorithm OBJECT IDENTIFIER // parameters ANY DEFINED BY algorithm OPTIONAL // } // len = ber_idDSALen + param_len; buf = (CK_BYTE *)malloc( len ); if (!buf){ st_err_log(1, __FILE__, __LINE__); goto error; } memcpy( buf, ber_idDSA, ber_idDSALen ); memcpy( buf + ber_idDSALen, param, param_len ); free( param ); param = NULL; rc = ber_encode_SEQUENCE( FALSE, &alg, &alg_len, buf, len ); if (rc != CKR_OK){ st_err_log(78, __FILE__, __LINE__); goto error; } free( buf ); buf = NULL; // build the private key INTEGER // rc = ber_encode_INTEGER( FALSE, &buf, &len, (CK_BYTE *)priv_key + sizeof(CK_ATTRIBUTE), priv_key->ulValueLen ); if (rc != CKR_OK){ st_err_log(76, __FILE__, __LINE__); goto error; } rc = ber_encode_PrivateKeyInfo( FALSE, data, data_len, alg, alg_len, buf, len ); if (rc != CKR_OK){ st_err_log(82, __FILE__, __LINE__); goto error; } error: if (alg) free( alg ); if (buf) free( buf ); if (param) free( param ); if (tmp) free( tmp ); return rc; } // // CK_RV ber_decode_DSAPrivateKey( CK_BYTE * data, CK_ULONG data_len, CK_ATTRIBUTE ** prime, CK_ATTRIBUTE ** subprime, CK_ATTRIBUTE ** base, CK_ATTRIBUTE ** priv_key ) { CK_ATTRIBUTE *p_attr = NULL; CK_ATTRIBUTE *q_attr = NULL; CK_ATTRIBUTE *g_attr = NULL; CK_ATTRIBUTE *x_attr = NULL; CK_BYTE *alg = NULL; CK_BYTE *buf = NULL; CK_BYTE *dsakey = NULL; CK_BYTE *tmp = NULL; CK_ULONG buf_len, field_len, len, offset; CK_RV rc; rc = ber_decode_PrivateKeyInfo( data, data_len, &alg, &len, &dsakey ); if (rc != CKR_OK){ st_err_log(82, __FILE__, __LINE__); return rc; } // make sure we're dealing with a DSA key. just compare the OBJECT // IDENTIFIER // if (memcmp(alg, ber_idDSA, ber_idDSALen) != 0){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // extract the parameter data into ATTRIBUTES // rc = ber_decode_SEQUENCE( alg + ber_idDSALen, &buf, &buf_len, &field_len ); if (rc != CKR_OK){ st_err_log(81, __FILE__, __LINE__); return rc; } offset = 0; // prime // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; // subprime // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; // base // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } offset += field_len; if (offset > buf_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // it looks okay. build the attributes // offset = 0; // prime // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_PRIME, tmp, len, &p_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += field_len; } // subprime // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_SUBPRIME, tmp, len, &q_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += field_len; } // base // rc = ber_decode_INTEGER( buf+offset, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_BASE, tmp, len, &g_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += field_len; } // now get the private key // rc = ber_decode_INTEGER( dsakey, &tmp, &len, &field_len ); if (rc != CKR_OK){ st_err_log(79, __FILE__, __LINE__); goto cleanup; } else { rc = build_attribute( CKA_VALUE, tmp, len, &x_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } offset += field_len; } *prime = p_attr; *subprime = q_attr; *base = g_attr; *priv_key = x_attr; return CKR_OK; cleanup: if (p_attr) free(p_attr); if (q_attr) free(q_attr); if (g_attr) free(g_attr); if (x_attr) free(x_attr); return rc; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/log.c0000751000175000017500000005757011327631345017662 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ #include #include #include #include #include #include #include #include #include #include #include "defs.h" #include "host_defs.h" #include "tok_spec_struct.h" extern token_spec_t token_specific; #include "tokenlocal.h" #include "msg.h" // HACK void stlogit(char *, ...); //extern char **err_msg; #include #include #if 0 extern FILE *debugfile; char lfname[1024]; #else extern int debugfile; #endif pthread_mutex_t lmtx=PTHREAD_MUTEX_INITIALIZER; static int enabled=0; static int logging=0; static int env_log_check=0; // Logging types. Ultimately this will allow // us to log to different log files. The logger will also // handle keeping the files to a decent size. // Much work needs to be done on this capability... // Other logging types need to be implemented void stloginit(){ char *logval; if (!env_log_check){ logval = getenv("PKCS_ERROR_LOG"); env_log_check = 1; if (logval != NULL) logging = 1; else logging = 0; } if (!enabled && logging){ enabled=1; openlog((const char *)DBGTAG,LOG_PID|LOG_NDELAY,LOG_LOCAL6); setlogmask(LOG_UPTO(LOG_DEBUG)); #ifdef DEBUG debugfile = 1; #else debugfile = 0; #endif #if 0 sprintf(lfname,"%s/%s.%d",CONFIG_PATH,DBGTAG,getpid()); debugfile = fopen(lfname,"w+"); if (debugfile) { fchmod(fileno(debugfile), S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); } #endif stlogit("Log initialized"); } } void stlogterm() { enabled = 0; } void stlogit2(int type,char *fmt, ...) { va_list pvar; char buffer[4096*4]; // char buf1[4096]; if (!enabled) stloginit(); if ( enabled && debugfile){ // sprintf(buf1,"Tid %d",pthread_self()); // syslog_r(LOG_DEBUG,&log_data,buf1); va_start(pvar, fmt); vsprintf(buffer,fmt,pvar); va_end(pvar); pthread_mutex_lock(&lmtx); syslog(LOG_DEBUG,buffer); pthread_mutex_unlock(&lmtx); #if 0 if (debugfile) { pthread_mutex_lock(&lmtx); fprintf(debugfile,"[%d]:%s\n",getpid(),buffer); fflush(debugfile); pthread_mutex_unlock(&lmtx); } #endif } } void stlogit(char *fmt, ...) { va_list pvar; char buffer[4096*4]; if (!enabled) stloginit(); if ( enabled && debugfile){ va_start(pvar, fmt); vsprintf(buffer,fmt,pvar); va_end(pvar); pthread_mutex_lock(&lmtx); syslog(LOG_DEBUG,buffer); pthread_mutex_unlock(&lmtx); #if 0 if (debugfile) { pthread_mutex_lock(&lmtx); fprintf(debugfile,"[%d]:%s\n",getpid(),buffer); fflush(debugfile); pthread_mutex_unlock(&lmtx); } #endif } } /* moved in from msg.h */ struct messages err_msg[]={ {"Malloc Failed"}, {"Not Enough Memory in Context"}, {"Slot Invalid"}, {"General Error"}, {"%s Function Failed"}, //#5 {"%s Bad Arguments"}, {"No Event"}, {"Attribute Read Only"}, {"Attribute Type Invalid"}, {"Attribute Value Invalid"}, //#10 {"Data Invalid"}, {"Data Length out of Range"}, {"Device Error"}, {"Device Removed"}, {"Encrypted Data Invalid"}, //15 {"Encrypted Data Length out of Range"}, {"Function Cancelled"}, {"Function Not Parallel"}, {"Key Handle Invalid"}, {"Key Size out of Range"}, //20 {"Key Type Inconsistent"}, {"Key Not Needed"}, {"Key Changed"}, {"Key Needed"}, {"Key Indigestible"}, //25 {"Key Function Not Permitted"}, {"Key Not Wrappable"}, {"Key Unextractable"}, {"Mechanism Invalid"}, {"Mechanism Param Invalid"}, //30 {"Object Handle Invalid"}, {"Operation Active"}, {"Operation Not Initialized"}, {"Pin Incorrect"}, {"Pin Invalid"}, //35 {"Pin Length out of Range"}, {"Pin Expired"}, {"Pin Locked"}, {"Session Closed"}, {"Session Count"}, //40 {"Session Handle Invalid"}, {"Parallel Session Not Supported"}, {"Session Read Only"}, {"Session Exists"}, {"Session Read only Exists"}, //45 {"Session Read Write Exists"}, {"Signature Length out of Range"}, {"Signature Invalid"}, {"Template Incomplete"}, {"Template Inconsistent"}, //50 {"Token Not Present"}, {"Token Not Recognized"}, {"Token Write Protected"}, {"Unwrapping Key Handle Invalid"}, {"Unwrapping Key Size Range Invalid"}, //55 {"Unwrapping Key Type Inconsistent"}, {"User Already Logged In"}, {"User Not Logged In"}, {"User PIN Not Initialized"}, {"User Type Invalid"}, //60 {"Another User Already Logged In"}, {"Too Many User Types"}, {"Wrapped Key Invalid"}, {"Wrapped Key Length Out of Range"}, {"Wrapping Key Size out of Range"}, //65 {"Wrapping Key Type Inconsistent"}, {"Random Seed Not Supported"}, {"Random Number Invalid"}, {"Buffer Too Small"}, {"Saved State Invalid"}, //70 {"Information Sensitive"}, {"State Unsaveable"}, {"API not initialized"}, {"API already Initialized"}, {"Mutex Bad"}, //75 {"Mutex Lock Invalid"}, {"Encode Integer Failed"}, {"Encode Octet String Failed"}, {"Encode Sequence Failed"}, {"Decode Integer Failed"}, //80 {"Decode Octet String Failed"}, {"Decode Sequence Failed"}, {"Encode Private Key Failed"}, {"Decode Private Key Failed"}, {"Build Attribute Failed"}, //85 {"Function Not Permitted"}, {"Key Not Exportable"}, {"Encode Private Key failed"}, {"Decode Private Key failed"}, {"Object Mgr Create Skeleton failed"}, //90 {"Object Mgr Create Final failed"}, {"Key Generation failed"}, {"DES Wrap Get Data Failed"}, {"DES3 Wrap Get Data Failed"}, {"RSA Wrap Get Data Failed"}, //95 {"DSA Wrap Get Data Failed"}, {"Generic Secret Wrap Get Data Failed"}, {"DES Wrap Format Failed"}, {"Encryption Mgr Init Failed"}, {"Encryption Mgr Encrypt Failed"}, //100 {"Decryption Mgr Decrypt Failed"}, {"Flatten Object Failed"}, {"Key Mgr Get Priv Key Type Failed"}, {"Decrypt Private Key Info Failed"}, {"Save Token Failed"}, //105 {"Triple DES CBC Encrypt Failed"}, {"Triple DES CBC Decrypt Failed"}, {"Restore Private Token Failed"}, {"Restore Object Failed"}, {"Data Length Out of Range"}, //110 {"Object Manager Find in Map Failed"}, {"Token Specific RNG Failed"}, {"Encrypted Data Length Out of Range"}, {"DES CBC Encrypt Failed"}, {"DES CBC Decrypt Failed"}, //115 {"DES ECB Encrypt Failed"}, {"DES ECB Decrypt Failed"}, {"Token Specific DES ECB Failed"}, {"Token Specific DES CBC Failed"}, {"Token Specific 3DES CBC Failed"}, //120 {"Token Specific 3DES ECB Failed"}, {"DSA Verify Failed"}, {"DSA Sign Failed"}, {"Digest Init Failed"}, {"Digest Failed"}, //125 {"Digest Update Failed"}, {"Digest Final Failed"}, {"Sign Init Failed"}, {"Sign Update Failed"}, {"Sign Final Failed"}, //130 {"Random Number Generate Failed"}, {"RSA Format Block Failed"}, {"RSA Encrypt Failed"}, {"RSA Decrypt Failed"}, {"Token Specific RSA Encrypt Failed"}, //135 {"Token Specific RSA Decrypt Failed"}, {"SSL SHA Failed"}, {"SSL3 MD5 Failed"}, {"SSL3 Process MAC Keys Failed"}, {"SSL3 Process Write Keys Failed"}, //140 {"Validate Attribute Failed"}, {"SSL3 Process Write Keys Failed"}, {"%s Function Not Supported"}, {"Token Already Initialized"}, {"Cannot Attach to Shared Memory"}, //145 {"Token Specific Init Failed"}, {"Mutex Lock Failed"}, {"Mutex Unlock Failed"}, {"Hash Computation Failed"}, {"Save Master Key Failed"}, //150 {"Process Lock Failed"}, {"Process Unlock Failed"}, {"Session Mgr New Failed"}, {"Close all Sessions Failed"}, {"Session Mgr Get Op State Failed"}, //155 {"Load Master Key Failed"}, {"Object Create Failed"}, {"Object Mgr Add to Map Failed"}, {"Object Copy Failed"}, {"Object Get Attribute Values Failed"}, //160 {"Object Restore Data Failed"}, {"Object Set Attribute Values Failed"}, {"Object Mgr Search for Object Failed"}, {"Copy Template Failed"}, {"Add Attribute Failed"}, //165 {"Check Required Attributes Failed"}, {"Unflatten Template Failed"}, {"Verify Init Failed"}, {"Verify Failed"}, {"Verify Update Failed"}, //170 {"Verify Final Failed"}, {"Sign Failed"}, {"Set Default Attributes Failed"}, {"Unwrap Key Failed"}, {"Session Mgr New Failed"}, //175 {"Merge Attributes Failed"}, {"Encryption Mgr Encrypt Update Failed"}, {"Encryption Mgr Encrypt Final Failed"}, {"Update Attribute Failed"}, {"Decryption Mgr Init Failed"}, //180 {"Decryption Mgr Update Failed"}, {"Decryption Mgr Final Failed"}, {"Object Mgr Destroy Failed"}, {"Attribute Undefined"}, {"Object Mgr Get Size Failed"}, //185 {"Object Manager Find Init Failed"}, {"Sign Recover Failed"}, {"Verify Recover Failed"}, {"Wrap Key Failed"}, {"Unwrap Key Failed"}, //190 {"Derive Key Failed"}, {"AES Wrap Get Data Failed"}, {"AES Wrap Format Failed"}, {"Domain Parameter Invalid"}, {"File \"%s\" could not be opened, errno=%d"} }; opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/verify_mgr.c0000751000175000017500000010376711327631345021252 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: verify_mgr.c // // Verify manager routines // #include #include // for memcmp() et al #include #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // // CK_RV verify_mgr_init( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_MECHANISM * mech, CK_BBOOL recover_mode, CK_OBJECT_HANDLE key ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_KEY_TYPE keytype; CK_OBJECT_CLASS class; CK_BBOOL flag; CK_RV rc; if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active != FALSE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } // key usage restrictions // rc = object_mgr_find_in_map1( key, &key_obj ); if (rc != CKR_OK){ st_err_log(18, __FILE__, __LINE__); return CKR_KEY_HANDLE_INVALID; } // is key allowed to verify signatures? // rc = template_attribute_find( key_obj->template, CKA_VERIFY, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { flag = *(CK_BBOOL *)attr->pValue; if (flag != TRUE){ st_err_log(85, __FILE__, __LINE__); return CKR_KEY_FUNCTION_NOT_PERMITTED; } } // is the mechanism supported? is the key type correct? is a // parameter present if required? is the key size allowed? // is the key allowed to generate signatures? // switch (mech->mechanism) { case CKM_RSA_X_509: case CKM_RSA_PKCS: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_RSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // must be a PUBLIC key operation // flag = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else class = *(CK_OBJECT_CLASS *)attr->pValue; if (class != CKO_PUBLIC_KEY){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // PKCS #11 doesn't allow multi-part RSA operations // ctx->context_len = 0; ctx->context = NULL; } break; case CKM_MD2_RSA_PKCS: case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_RSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // must be a PUBLIC key operation // flag = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else class = *(CK_OBJECT_CLASS *)attr->pValue; if (class != CKO_PUBLIC_KEY){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } ctx->context_len = sizeof(RSA_DIGEST_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(RSA_DIGEST_CONTEXT)); if (!ctx->context){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(RSA_DIGEST_CONTEXT)); } break; #if !(NODSA) case CKM_DSA: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // must be a PUBLIC key operation // flag = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else class = *(CK_OBJECT_CLASS *)attr->pValue; if (class != CKO_PUBLIC_KEY){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // PKCS #11 doesn't allow multi-part DSA operations // ctx->context_len = 0; ctx->context = NULL; } break; #endif case CKM_MD2_HMAC: case CKM_MD5_HMAC: case CKM_SHA_1_HMAC: case CKM_SHA256_HMAC: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_GENERIC_SECRET){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // PKCS #11 doesn't allow multi-part HMAC operations // ctx->context_len = 0; ctx->context = NULL; } break; case CKM_MD2_HMAC_GENERAL: case CKM_MD5_HMAC_GENERAL: case CKM_SHA_1_HMAC_GENERAL: case CKM_SHA256_HMAC_GENERAL: { CK_MAC_GENERAL_PARAMS *param = (CK_MAC_GENERAL_PARAMS *)mech->pParameter; if (mech->ulParameterLen != sizeof(CK_MAC_GENERAL_PARAMS)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } if ((mech->mechanism == CKM_MD2_HMAC_GENERAL) && (*param > 16)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } if ((mech->mechanism == CKM_MD5_HMAC_GENERAL) && (*param > 16)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } if ((mech->mechanism == CKM_SHA_1_HMAC_GENERAL) && (*param > 20)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } if ((mech->mechanism == CKM_SHA256_HMAC_GENERAL) && (*param > 32)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_GENERIC_SECRET){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // PKCS #11 doesn't allow multi-part HMAC operations // ctx->context_len = 0; ctx->context = NULL; } break; case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: { CK_MAC_GENERAL_PARAMS *param = (CK_MAC_GENERAL_PARAMS *)mech->pParameter; if (mech->ulParameterLen != sizeof(CK_MAC_GENERAL_PARAMS)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // Netscape sets the parameter == 16. PKCS #11 limit is 8 // if (mech->mechanism == CKM_SSL3_MD5_MAC) { if (*param < 4 || *param > 16){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } } if (mech->mechanism == CKM_SSL3_SHA1_MAC) { if (*param < 4 || *param > 20){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } } rc = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { class = *(CK_OBJECT_CLASS *)attr->pValue; if (class != CKO_SECRET_KEY){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(SSL3_MAC_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(SSL3_MAC_CONTEXT)); if (!ctx->context){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(SSL3_MAC_CONTEXT)); } break; default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } if (mech->ulParameterLen > 0) { ptr = (CK_BYTE *)malloc(mech->ulParameterLen); if (!ptr){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( ptr, mech->pParameter, mech->ulParameterLen ); } ctx->key = key; ctx->mech.ulParameterLen = mech->ulParameterLen; ctx->mech.mechanism = mech->mechanism; ctx->mech.pParameter = ptr; ctx->multi = FALSE; ctx->active = TRUE; ctx->recover = recover_mode; return CKR_OK; } // // CK_RV verify_mgr_cleanup( SIGN_VERIFY_CONTEXT *ctx ) { if (!ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } ctx->key = 0; ctx->mech.ulParameterLen = 0; ctx->mech.mechanism = 0; ctx->multi = FALSE; ctx->active = FALSE; ctx->recover = FALSE; ctx->context_len = 0; if (ctx->mech.pParameter) { free( ctx->mech.pParameter ); ctx->mech.pParameter = NULL; } if (ctx->context) { free( ctx->context ); ctx->context = NULL; } return CKR_OK; } // // CK_RV verify_mgr_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == TRUE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } // if the caller just wants the signature length, there is no reason to // specify the input data. I just need the input data length // if (!in_data || !signature){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->multi == TRUE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } switch (ctx->mech.mechanism) { case CKM_RSA_PKCS: return rsa_pkcs_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); case CKM_RSA_X_509: return rsa_x509_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); case CKM_MD2_RSA_PKCS: case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: return rsa_hash_pkcs_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); #if !(NODSA) case CKM_DSA: return dsa_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); #endif #if !(NOMD2) case CKM_MD2_HMAC: case CKM_MD2_HMAC_GENERAL: return md2_hmac_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); #endif case CKM_MD5_HMAC: case CKM_MD5_HMAC_GENERAL: return md5_hmac_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); case CKM_SHA_1_HMAC: case CKM_SHA_1_HMAC_GENERAL: return sha1_hmac_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); case CKM_SHA256_HMAC: case CKM_SHA256_HMAC_GENERAL: return sha2_hmac_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: return ssl3_mac_verify( sess, ctx, in_data, in_data_len, signature, sig_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV verify_mgr_verify_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { if (!sess || !ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == TRUE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } ctx->multi = TRUE; switch (ctx->mech.mechanism) { case CKM_MD2_RSA_PKCS: case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: return rsa_hash_pkcs_verify_update( sess, ctx, in_data, in_data_len ); case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: return ssl3_mac_verify_update( sess, ctx, in_data, in_data_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // // CK_RV verify_mgr_verify_final( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == TRUE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } switch (ctx->mech.mechanism) { case CKM_MD2_RSA_PKCS: case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: return rsa_hash_pkcs_verify_final( sess, ctx, signature, sig_len ); case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: return ssl3_mac_verify_final( sess, ctx, signature, sig_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // // CK_RV verify_mgr_verify_recover( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len, CK_BYTE * out_data, CK_ULONG * out_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } // if the caller just wants the signature length, there is no reason to // specify the input data. I just need the input data length // if (!signature || !out_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->multi == TRUE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } switch (ctx->mech.mechanism) { case CKM_RSA_PKCS: return rsa_pkcs_verify_recover( sess, length_only, ctx, signature, sig_len, out_data, out_len ); case CKM_RSA_X_509: return rsa_x509_verify_recover( sess, length_only, ctx, signature, sig_len, out_data, out_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/hwf_obj.c0000640000175000017500000005143211327631345020503 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: hwf_obj.c // // Hardware Feature Object functions #include #include #include // for memcmp() et al #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // hwf_object_check_required_attributes() // // Check required common attributes for hardware feature objects // CK_RV hwf_object_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE * attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_HW_FEATURE_TYPE, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return template_check_required_base_attributes( tmpl, mode ); } CK_RV clock_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; if (mode == MODE_CREATE){ found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return hwf_object_check_required_attributes( tmpl, mode ); } CK_RV counter_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; if (mode == MODE_CREATE){ found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found) { st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } found = template_attribute_find( tmpl, CKA_HAS_RESET, &attr ); if (!found) { st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } found = template_attribute_find( tmpl, CKA_RESET_ON_INIT, &attr ); if (!found) { st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return hwf_object_check_required_attributes( tmpl, mode ); } // hwf_object_set_default_attributes() // CK_RV hwf_object_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { #if 0 CK_ATTRIBUTE * local_attr = NULL; local_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!local_attr) { st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } local_attr->type = CKA_LOCAL; local_attr->ulValueLen = sizeof(CK_BBOOL); local_attr->pValue = (CK_BYTE *)local_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)local_attr->pValue = FALSE; template_update_attribute( tmpl, local_attr ); #endif return CKR_OK; } // hwf_object_validate_attribute() // CK_RV hwf_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode) { switch (attr->type) { case CKA_HW_FEATURE_TYPE: if (mode == MODE_CREATE) return CKR_OK; else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } default: return template_validate_base_attribute( tmpl, attr, mode ); } st_err_log(8, __FILE__, __LINE__); return CKR_ATTRIBUTE_TYPE_INVALID; } // // CK_RV clock_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode) { switch (attr->type) { case CKA_VALUE: return CKR_OK; default: return hwf_validate_attribute( tmpl, attr, mode ); } } // // CK_RV counter_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode) { switch (attr->type) { case CKA_VALUE: /* Fall Through */ case CKA_HAS_RESET: /* Fall Through */ case CKA_RESET_ON_INIT: st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; default: return hwf_validate_attribute( tmpl, attr, mode ); } } CK_RV clock_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_RV rc; CK_ATTRIBUTE *value_attr; rc = hwf_object_set_default_attributes( tmpl, mode ); if (rc != CKR_OK) return rc; value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!value_attr) { st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; template_update_attribute( tmpl, value_attr ); return CKR_OK; } CK_RV counter_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_RV rc; CK_ATTRIBUTE *value_attr; CK_ATTRIBUTE *hasreset_attr; CK_ATTRIBUTE *resetoninit_attr; rc = hwf_object_set_default_attributes( tmpl, mode ); if (rc != CKR_OK) return rc; value_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); hasreset_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL)); resetoninit_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL)); if (!value_attr || !hasreset_attr || !resetoninit_attr) { if (value_attr) free( value_attr ); if (hasreset_attr) free( hasreset_attr ); if (resetoninit_attr) free( resetoninit_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = 0; value_attr->pValue = NULL; hasreset_attr->type = CKA_HAS_RESET; hasreset_attr->ulValueLen = sizeof(CK_BBOOL); hasreset_attr->pValue = (CK_BYTE *)hasreset_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)hasreset_attr->pValue = FALSE; /* Hmm... Not sure if we should be setting this here. */ resetoninit_attr->type = CKA_RESET_ON_INIT; resetoninit_attr->ulValueLen = sizeof(CK_BBOOL); resetoninit_attr->pValue = (CK_BYTE *)resetoninit_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)resetoninit_attr->pValue = FALSE; template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, hasreset_attr ); template_update_attribute( tmpl, resetoninit_attr ); return CKR_OK; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/mech_md5.c0000751000175000017500000013444011327631345020552 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ #include #include // for memcmp() et al #include #include "pkcs11types.h" #include "pkcs32.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // forward declaration // void ckm_md5_transform (); static CK_BYTE PADDING[64] = { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // // CK_RV md5_hash( SESSION * sess, CK_BBOOL length_only, DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ) { CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = MD5_HASH_SIZE; return CKR_OK; } rc = md5_hash_update( sess, ctx, in_data, in_data_len ); if (rc != CKR_OK){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } return md5_hash_final( sess, FALSE, ctx, out_data, out_data_len ); } // // CK_RV md5_hash_update( SESSION * sess, DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { if (!sess || !ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } return ckm_md5_update( (MD5_CONTEXT *)ctx->context, in_data, in_data_len ); } // // CK_RV md5_hash_final( SESSION * sess, CK_BYTE length_only, DIGEST_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ) { CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = MD5_HASH_SIZE; return CKR_OK; } rc = ckm_md5_final( (MD5_CONTEXT *)ctx->context, out_data, MD5_HASH_SIZE ); if (rc == CKR_OK) { *out_data_len = MD5_HASH_SIZE; return rc; } return rc; } // this routine gets called for two mechanisms actually: // CKM_MD5_HMAC // CKM_MD5_HMAC_GENERAL // CK_RV md5_hmac_sign( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE hash[MD5_HASH_SIZE]; DIGEST_CONTEXT digest_ctx; CK_MECHANISM digest_mech; CK_BYTE k_ipad[MD5_BLOCK_SIZE]; CK_BYTE k_opad[MD5_BLOCK_SIZE]; CK_ULONG key_bytes, hash_len, hmac_len; CK_ULONG i; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_MD5_HMAC_GENERAL) { hmac_len = *(CK_ULONG *)ctx->mech.pParameter; if (hmac_len == 0) { *out_data_len = 0; return CKR_OK; } } else hmac_len = MD5_HASH_SIZE; if (length_only == TRUE) { *out_data_len = hmac_len; return CKR_OK; } memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK) return rc; rc = template_attribute_find( key_obj->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else key_bytes = attr->ulValueLen; // build (K XOR ipad), (K XOR opad) // if (key_bytes > MD5_BLOCK_SIZE) { digest_mech.mechanism = CKM_MD5; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest( sess, FALSE, &digest_ctx, attr->pValue, attr->ulValueLen, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); return rc; } digest_mgr_cleanup( &digest_ctx ); memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); for (i=0; i < hash_len; i++) { k_ipad[i] = hash[i] ^ 0x36; k_opad[i] = hash[i] ^ 0x5C; } memset( &k_ipad[i], 0x36, MD5_BLOCK_SIZE - i); memset( &k_opad[i], 0x5C, MD5_BLOCK_SIZE - i); } else { CK_BYTE *key = attr->pValue; for (i=0; i < key_bytes; i++) { k_ipad[i] = key[i] ^ 0x36; k_opad[i] = key[i] ^ 0x5C; } memset( &k_ipad[i], 0x36, MD5_BLOCK_SIZE - key_bytes ); memset( &k_opad[i], 0x5C, MD5_BLOCK_SIZE - key_bytes ); } digest_mech.mechanism = CKM_MD5; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; // inner hash // rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { st_err_log(123, __FILE__, __LINE__); digest_mgr_cleanup( &digest_ctx ); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, k_ipad, MD5_BLOCK_SIZE ); if (rc != CKR_OK) { st_err_log(123, __FILE__, __LINE__); digest_mgr_cleanup( &digest_ctx ); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, in_data, in_data_len ); if (rc != CKR_OK) { st_err_log(123, __FILE__, __LINE__); digest_mgr_cleanup( &digest_ctx ); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &hash_len ); if (rc != CKR_OK) { st_err_log(126, __FILE__, __LINE__); digest_mgr_cleanup( &digest_ctx ); return rc; } digest_mgr_cleanup( &digest_ctx ); memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); // outer hash // rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { st_err_log(123, __FILE__, __LINE__); digest_mgr_cleanup( &digest_ctx ); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, k_opad, MD5_BLOCK_SIZE ); if (rc != CKR_OK) { st_err_log(123, __FILE__, __LINE__); digest_mgr_cleanup( &digest_ctx ); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, hash, hash_len ); if (rc != CKR_OK) { st_err_log(123, __FILE__, __LINE__); digest_mgr_cleanup( &digest_ctx ); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &hash_len ); if (rc != CKR_OK) { st_err_log(126, __FILE__, __LINE__); digest_mgr_cleanup( &digest_ctx ); return rc; } memcpy( out_data, hash, hmac_len ); *out_data_len = hmac_len; digest_mgr_cleanup( &digest_ctx ); return CKR_OK; } // // CK_RV md5_hmac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ) { CK_BYTE hmac[MD5_HASH_SIZE]; SIGN_VERIFY_CONTEXT hmac_ctx; CK_ULONG hmac_len, len; CK_RV rc; if (!sess || !ctx || !in_data || !signature){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_MD5_HMAC_GENERAL) hmac_len = *(CK_ULONG *)ctx->mech.pParameter; else hmac_len = MD5_HASH_SIZE; memset( &hmac_ctx, 0, sizeof(SIGN_VERIFY_CONTEXT) ); rc = sign_mgr_init( sess, &hmac_ctx, &ctx->mech, FALSE, ctx->key ); if (rc != CKR_OK) { sign_mgr_cleanup( &hmac_ctx ); return rc; } len = sizeof(hmac); rc = sign_mgr_sign( sess, FALSE, &hmac_ctx, in_data, in_data_len, hmac, &len ); if (rc != CKR_OK) { sign_mgr_cleanup( &hmac_ctx ); return rc; } if ((len != hmac_len) || (len != sig_len)){ st_err_log(46, __FILE__, __LINE__); return CKR_SIGNATURE_LEN_RANGE; } if (memcmp(hmac, signature, hmac_len) != 0){ st_err_log(47, __FILE__, __LINE__); rc = CKR_SIGNATURE_INVALID; } sign_mgr_cleanup( &hmac_ctx ); return rc; } // // CKM routines // void ckm_md5_init( MD5_CONTEXT *context ) { context->i[0] = context->i[1] = 0; // Load magic initialization constants. // context->buf[0] = (CK_ULONG)0x67452301; context->buf[1] = (CK_ULONG)0xefcdab89; context->buf[2] = (CK_ULONG)0x98badcfe; context->buf[3] = (CK_ULONG)0x10325476; } // // CK_RV ckm_md5_update( MD5_CONTEXT * context, CK_BYTE * in_data, CK_ULONG in_data_len ) { CK_ULONG in[16]; int mdi; CK_ULONG i, ii; // compute number of bytes mod 64 // mdi = (int)((context->i[0] >> 3) & 0x3F); // update number of bits // if ((context->i[0] + (in_data_len << 3)) < context->i[0]) context->i[1]++; context->i[0] += (in_data_len << 3); context->i[1] += (in_data_len >> 29); while (in_data_len--) { // add new character to buffer, increment mdi // context->in[mdi++] = *in_data++; // transform if necessary // if (mdi == 0x40) { for (i = 0, ii = 0; i < 16; i++, ii += 4) in[i] = (((CK_ULONG)context->in[ii+3]) << 24) | (((CK_ULONG)context->in[ii+2]) << 16) | (((CK_ULONG)context->in[ii+1]) << 8) | ((CK_ULONG)context->in[ii]); ckm_md5_transform (context->buf, in); mdi = 0; } } return CKR_OK; } // // CK_RV ckm_md5_final( MD5_CONTEXT *context, CK_BYTE *out_data, CK_ULONG out_data_len ) { CK_ULONG in[16]; int mdi; CK_ULONG i, ii; CK_ULONG padLen; if (!out_data || (out_data_len < MD5_HASH_SIZE)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // save number of bits // in[14] = context->i[0]; in[15] = context->i[1]; // compute number of bytes mod 64 // mdi = (int)((context->i[0] >> 3) & 0x3F); // pad out to 56 mod 64 // padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); ckm_md5_update( context, PADDING, padLen ); // append length in bits and transform // for (i = 0, ii = 0; i < 14; i++, ii += 4) in[i] = (((CK_ULONG)context->in[ii+3]) << 24) | (((CK_ULONG)context->in[ii+2]) << 16) | (((CK_ULONG)context->in[ii+1]) << 8) | ((CK_ULONG)context->in[ii]); ckm_md5_transform (context->buf, in); // store buffer in digest // for (i = 0, ii = 0; i < 4; i++, ii += 4) { context->digest[ii ] = (CK_BYTE) (context->buf[i] & 0xFF); context->digest[ii+1] = (CK_BYTE)((context->buf[i] >> 8) & 0xFF); context->digest[ii+2] = (CK_BYTE)((context->buf[i] >> 16) & 0xFF); context->digest[ii+3] = (CK_BYTE)((context->buf[i] >> 24) & 0xFF); } memcpy( out_data, context->digest, MD5_HASH_SIZE ); return CKR_OK; } // Stuff stolen from CCA (saf_md5.c) /******************************************************************************/ /* Rotate a word (32 bits) left by a specified number of bits. The 32-bit */ /* number invalue is circularly rotated left by num_bits bit positions. The */ /* result is returned as the function result. */ /*----------------------------------------------------------------------------*/ #define rotate_left(Data, bit_cnt) \ (Data = ( (Data << bit_cnt) | \ (Data >> (32 - bit_cnt)) ) ) /******************************************************************************/ /* Implement the MD5 algorithm's "F" function. This function performs a */ /* transform on three input words, designated x, y, and z, producing a */ /* single word output value. The transform is: */ /* */ /* output = ( x AND y ) OR ( (NOT x) AND z ) */ /*----------------------------------------------------------------------------*/ #define F( x, y, z) ( ( x & y ) | ( (~x) & z) ) /******************************************************************************/ /* Implement the MD5 algorithm's "G" function. This function performs a */ /* transform on three input words, designated x, y, and z, producing a */ /* single word output value. The transform is: */ /* */ /* output = ( x AND z ) OR ( y AND (NOT z) ) */ /*----------------------------------------------------------------------------*/ #define G( x, y, z) ( ( x & z ) | ( y & (~z) ) ) /******************************************************************************/ /* Implement the MD5 algorithm's "H" function. This function performs a */ /* transform on three input words, designated x, y, and z, producing a */ /* single word output value. The transform is: */ /* */ /* output = ( x XOR y XOR z ) */ /*----------------------------------------------------------------------------*/ #define H( x, y, z) ( x ^ y ^ z ) /******************************************************************************/ /* Implement the MD5 algorithm's "I" function. This function performs a */ /* transform on three input words, designated x, y, and z, producing a */ /* single word output value. The transform is: */ /* */ /* output = ( y XOR ( x OR (NOT z) ) ) */ /*----------------------------------------------------------------------------*/ #define I( x, y, z) ( y ^ ( x | (~z) ) ) /*----------------------------------------------------------------------------*/ /* */ /* Define the MD5 "T[]" table. This table consists of 64 4-byte (MD5_word) */ /* entries, designated T[1] through T[64]. (Note that this is different from */ /* the way C will index them, from 0..63 instead of 1..64.) */ /* */ /* If the index of each entry is i, where i ranges from 1 to 64, then the */ /* value in each entry is given by the following formula. */ /* */ /* T[i] = int ( 4294967296 * abs ( sin ( i ) ) ) */ /* */ /* where the function sin(i) expects i in radians, and the function int(x) */ /* returns the integer portion of a floating point number x. */ /* */ /*----------------------------------------------------------------------------*/ static CK_ULONG T[64] = { 0xD76AA478, /* T[01] */ 0xE8C7B756, /* T[02] */ 0x242070DB, /* T[03] */ 0xC1BDCEEE, /* T[04] */ 0xF57C0FAF, /* T[05] */ 0x4787C62A, /* T[06] */ 0xA8304613, /* T[07] */ 0xFD469501, /* T[08] */ 0x698098D8, /* T[09] */ 0x8B44F7AF, /* T[10] */ 0xFFFF5BB1, /* T[11] */ 0x895CD7BE, /* T[12] */ 0x6B901122, /* T[13] */ 0xFD987193, /* T[14] */ 0xA679438E, /* T[15] */ 0x49B40821, /* T[16] */ 0xF61E2562, /* T[17] */ 0xC040B340, /* T[18] */ 0x265E5A51, /* T[19] */ 0xE9B6C7AA, /* T[20] */ 0xD62F105D, /* T[21] */ 0x02441453, /* T[22] */ 0xD8A1E681, /* T[23] */ 0xE7D3FBC8, /* T[24] */ 0x21E1CDE6, /* T[25] */ 0xC33707D6, /* T[26] */ 0xF4D50D87, /* T[27] */ 0x455A14ED, /* T[28] */ 0xA9E3E905, /* T[29] */ 0xFCEFA3F8, /* T[30] */ 0x676F02D9, /* T[31] */ 0x8D2A4C8A, /* T[32] */ 0xFFFA3942, /* T[33] */ 0x8771F681, /* T[34] */ 0x6D9D6122, /* T[35] */ 0xFDE5380C, /* T[36] */ 0xA4BEEA44, /* T[37] */ 0x4BDECFA9, /* T[38] */ 0xF6BB4B60, /* T[39] */ 0xBEBFBC70, /* T[40] */ 0x289B7EC6, /* T[41] */ 0xEAA127FA, /* T[42] */ 0xD4EF3085, /* T[43] */ 0x04881D05, /* T[44] */ 0xD9D4D039, /* T[45] */ 0xE6DB99E5, /* T[46] */ 0x1FA27CF8, /* T[47] */ 0xC4AC5665, /* T[48] */ 0xF4292244, /* T[49] */ 0x432AFF97, /* T[50] */ 0xAB9423A7, /* T[51] */ 0xFC93A039, /* T[52] */ 0x655B59C3, /* T[53] */ 0x8F0CCC92, /* T[54] */ 0xFFEFF47D, /* T[55] */ 0x85845DD1, /* T[56] */ 0x6FA87E4F, /* T[57] */ 0xFE2CE6E0, /* T[58] */ 0xA3014314, /* T[59] */ 0x4E0811A1, /* T[60] */ 0xF7537E82, /* T[61] */ 0xBD3AF235, /* T[62] */ 0x2AD7D2BB, /* T[63] */ 0xEB86D391 }; /* T[64] */ // Basic MD5 step. Transform buf based on in. // void ckm_md5_transform( CK_ULONG *long_buf, CK_ULONG *long_in ) { /*-------------------------------------------------------------------------*/ /* The inputs to this function SHOULD be 4 4-byte elements of buf[] and */ /* 16 4-byte elements of in[]. There are architectures, however -- */ /* 64-bit Linux390 among them--in which CK_ULONG translates to an 8-byte */ /* number. Therefore this function must copy inputs to 4-byte temps and */ /* copy the temps back into the 8-byte arrays at the end. */ /*-------------------------------------------------------------------------*/ /* */ /* Macro ROUND_FCN defines the common function that is performed */ /* throughout the MD5 round. Parameters are: */ /* */ /* - The name of the function to be performed on the data for this */ /* round. There are four logical functions, F, G, H, and I, and they */ /* are each used throughout the algorithm. */ /* */ /* - a, b, c, and d are the four md5-word parameters to the functions */ /* F, G, H, and I. They are replaced with varying permutations of the */ /* accumulated hash values in A, B, C, and D. */ /* */ /* - x_index is an index into the in[] array, where in[] is the input */ /* block of message text. */ /* */ /* - t_index is an index into the T[] array, a set of constants. */ /* */ /* - rotate_cnt is the number of bits the result must be rotated. */ /* */ /*-------------------------------------------------------------------------*/ CK_ULONG AA = 0x00000000; /* Temp. save areas for A, B, C, D */ CK_ULONG BB = 0x00000000; /* Temp. save areas for A, B, C, D */ CK_ULONG CC = 0x00000000; /* Temp. save areas for A, B, C, D */ CK_ULONG DD = 0x00000000; /* Temp. save areas for A, B, C, D */ CK_ULONG_32 buf[4]; // temps for long_buf[i] CK_ULONG_32 in[16]; // temps for long_in[i] int i; // loop counter #define ROUND_FCN(FCN, a, b, c, d, x_index, rotate_cnt, t_index) \ { a += FCN(b,c,d) + in[x_index] + T[t_index-1]; \ rotate_left( a, rotate_cnt); \ a += b; \ } /* Save the MD buffer in the temporary locations AA-DD. */ AA = long_buf[0]; BB = long_buf[1]; CC = long_buf[2]; DD = long_buf[3]; // Copy the input long_buf elements into buf and long_in elements into in for (i=0;i<4;i++) { buf[i] = (CK_ULONG_32)long_buf[i]; in[i] = (CK_ULONG_32)long_in[i]; } for (i=4;i<16;i++) in[i] = (CK_ULONG_32)long_in[i]; /*==================================================================*/ /* */ /* Process the four rounds for each 16-word block. */ /* */ /* The function for each of these has the form: */ /* */ /* a = b + (( a + fcn( b, c, d ) + in[k] + T[i] ) <<< s ) */ /* */ /* for a function fcn() which can be F, G, H, or I, and for input */ /* values a, b, c, d, k, i, and s. Array T is the array of */ /* constants, computed from the sin() function. Array in is the */ /* current input block. Value s is the number of bits to rotate */ /* left, where <<< represents a 32-bit left rotation. */ /* */ /* The definitions of these functions are taken directly from the */ /* definition of MD5 in RFC 1321. */ /* */ /*==================================================================*/ /*------------------------------------------------------------------*/ /* */ /* Round 1 */ /* */ /*------------------------------------------------------------------*/ ROUND_FCN(F, buf[0], buf[1], buf[2], buf[3], 0, 7, 1); ROUND_FCN(F, buf[3], buf[0], buf[1], buf[2], 1, 12, 2); ROUND_FCN(F, buf[2], buf[3], buf[0], buf[1], 2, 17, 3); ROUND_FCN(F, buf[1], buf[2], buf[3], buf[0], 3, 22, 4); ROUND_FCN(F, buf[0], buf[1], buf[2], buf[3], 4, 7, 5); ROUND_FCN(F, buf[3], buf[0], buf[1], buf[2], 5, 12, 6); ROUND_FCN(F, buf[2], buf[3], buf[0], buf[1], 6, 17, 7); ROUND_FCN(F, buf[1], buf[2], buf[3], buf[0], 7, 22, 8); ROUND_FCN(F, buf[0], buf[1], buf[2], buf[3], 8, 7, 9); ROUND_FCN(F, buf[3], buf[0], buf[1], buf[2], 9, 12, 10); ROUND_FCN(F, buf[2], buf[3], buf[0], buf[1], 10, 17, 11); ROUND_FCN(F, buf[1], buf[2], buf[3], buf[0], 11, 22, 12); ROUND_FCN(F, buf[0], buf[1], buf[2], buf[3], 12, 7, 13); ROUND_FCN(F, buf[3], buf[0], buf[1], buf[2], 13, 12, 14); ROUND_FCN(F, buf[2], buf[3], buf[0], buf[1], 14, 17, 15); ROUND_FCN(F, buf[1], buf[2], buf[3], buf[0], 15, 22, 16); /*------------------------------------------------------------------*/ /* */ /* Round 2 */ /* */ /*------------------------------------------------------------------*/ ROUND_FCN(G, buf[0], buf[1], buf[2], buf[3], 1, 5, 17); ROUND_FCN(G, buf[3], buf[0], buf[1], buf[2], 6, 9, 18); ROUND_FCN(G, buf[2], buf[3], buf[0], buf[1], 11, 14, 19); ROUND_FCN(G, buf[1], buf[2], buf[3], buf[0], 0, 20, 20); ROUND_FCN(G, buf[0], buf[1], buf[2], buf[3], 5, 5, 21); ROUND_FCN(G, buf[3], buf[0], buf[1], buf[2], 10, 9, 22); ROUND_FCN(G, buf[2], buf[3], buf[0], buf[1], 15, 14, 23); ROUND_FCN(G, buf[1], buf[2], buf[3], buf[0], 4, 20, 24); ROUND_FCN(G, buf[0], buf[1], buf[2], buf[3], 9, 5, 25); ROUND_FCN(G, buf[3], buf[0], buf[1], buf[2], 14, 9, 26); ROUND_FCN(G, buf[2], buf[3], buf[0], buf[1], 3, 14, 27); ROUND_FCN(G, buf[1], buf[2], buf[3], buf[0], 8, 20, 28); ROUND_FCN(G, buf[0], buf[1], buf[2], buf[3], 13, 5, 29); ROUND_FCN(G, buf[3], buf[0], buf[1], buf[2], 2, 9, 30); ROUND_FCN(G, buf[2], buf[3], buf[0], buf[1], 7, 14, 31); ROUND_FCN(G, buf[1], buf[2], buf[3], buf[0], 12, 20, 32); /*------------------------------------------------------------------*/ /* */ /* Round 3 */ /* */ /*------------------------------------------------------------------*/ ROUND_FCN(H, buf[0], buf[1], buf[2], buf[3], 5, 4, 33); ROUND_FCN(H, buf[3], buf[0], buf[1], buf[2], 8, 11, 34); ROUND_FCN(H, buf[2], buf[3], buf[0], buf[1], 11, 16, 35); ROUND_FCN(H, buf[1], buf[2], buf[3], buf[0], 14, 23, 36); ROUND_FCN(H, buf[0], buf[1], buf[2], buf[3], 1, 4, 37); ROUND_FCN(H, buf[3], buf[0], buf[1], buf[2], 4, 11, 38); ROUND_FCN(H, buf[2], buf[3], buf[0], buf[1], 7, 16, 39); ROUND_FCN(H, buf[1], buf[2], buf[3], buf[0], 10, 23, 40); ROUND_FCN(H, buf[0], buf[1], buf[2], buf[3], 13, 4, 41); ROUND_FCN(H, buf[3], buf[0], buf[1], buf[2], 0, 11, 42); ROUND_FCN(H, buf[2], buf[3], buf[0], buf[1], 3, 16, 43); ROUND_FCN(H, buf[1], buf[2], buf[3], buf[0], 6, 23, 44); ROUND_FCN(H, buf[0], buf[1], buf[2], buf[3], 9, 4, 45); ROUND_FCN(H, buf[3], buf[0], buf[1], buf[2], 12, 11, 46); ROUND_FCN(H, buf[2], buf[3], buf[0], buf[1], 15, 16, 47); ROUND_FCN(H, buf[1], buf[2], buf[3], buf[0], 2, 23, 48); /*------------------------------------------------------------------*/ /* */ /* Round 4 */ /* */ /*------------------------------------------------------------------*/ ROUND_FCN(I, buf[0], buf[1], buf[2], buf[3], 0, 6, 49); ROUND_FCN(I, buf[3], buf[0], buf[1], buf[2], 7, 10, 50); ROUND_FCN(I, buf[2], buf[3], buf[0], buf[1], 14, 15, 51); ROUND_FCN(I, buf[1], buf[2], buf[3], buf[0], 5, 21, 52); ROUND_FCN(I, buf[0], buf[1], buf[2], buf[3], 12, 6, 53); ROUND_FCN(I, buf[3], buf[0], buf[1], buf[2], 3, 10, 54); ROUND_FCN(I, buf[2], buf[3], buf[0], buf[1], 10, 15, 55); ROUND_FCN(I, buf[1], buf[2], buf[3], buf[0], 1, 21, 56); ROUND_FCN(I, buf[0], buf[1], buf[2], buf[3], 8, 6, 57); ROUND_FCN(I, buf[3], buf[0], buf[1], buf[2], 15, 10, 58); ROUND_FCN(I, buf[2], buf[3], buf[0], buf[1], 6, 15, 59); ROUND_FCN(I, buf[1], buf[2], buf[3], buf[0], 13, 21, 60); ROUND_FCN(I, buf[0], buf[1], buf[2], buf[3], 4, 6, 61); ROUND_FCN(I, buf[3], buf[0], buf[1], buf[2], 11, 10, 62); ROUND_FCN(I, buf[2], buf[3], buf[0], buf[1], 2, 15, 63); ROUND_FCN(I, buf[1], buf[2], buf[3], buf[0], 9, 21, 64); // Copy the elements of buf into long_buf for (i=0;i<4;i++) long_buf[i] = (CK_ULONG) buf[i]; /* Add to each MD buffer variable the value it had before this block was */ /* started. */ long_buf[0] += AA; long_buf[1] += BB; long_buf[2] += CC; long_buf[3] += DD; /* Undefine the ROUND_FCN macro we used in this function. */ #undef ROUND_FCN } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/mech_md2.c0000751000175000017500000007006411327631345020550 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // #include #include // for memcmp() et al #include #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" //#include "args.h" // Permutation of 0..255 constructed from the digits of pi. It gives a // "random" nonlinear byte substitution operation. // static CK_BYTE S[256] = { 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157, 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27, 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233, 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228, 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237, 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 }; static CK_BYTE *padding[] = { (CK_BYTE *)"", (CK_BYTE *)"\x01", (CK_BYTE *)"\x02\x02", (CK_BYTE *)"\x03\x03\x03", (CK_BYTE *)"\x04\x04\x04\x04", (CK_BYTE *)"\x05\x05\x05\x05\x05", (CK_BYTE *)"\x06\x06\x06\x06\x06\x06", (CK_BYTE *)"\x07\x07\x07\x07\x07\x07\x07", (CK_BYTE *)"\x08\x08\x08\x08\x08\x08\x08\x08", (CK_BYTE *)"\x09\x09\x09\x09\x09\x09\x09\x09\x09", (CK_BYTE *)"\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a", (CK_BYTE *)"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", (CK_BYTE *)"\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", (CK_BYTE *)"\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d\x0d", (CK_BYTE *)"\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e", (CK_BYTE *)"\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f", (CK_BYTE *)"\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" }; // // CK_RV md2_hash( SESSION * sess, CK_BBOOL length_only, DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ) { CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = MD2_HASH_SIZE; return CKR_OK; } rc = md2_hash_update( sess, ctx, in_data, in_data_len ); if (rc != CKR_OK){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } return md2_hash_final( sess, FALSE, ctx, out_data, out_data_len ); } // // CK_RV md2_hash_update( SESSION * sess, DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { if (!sess || !ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } return ckm_md2_update( (MD2_CONTEXT *)ctx->context, in_data, in_data_len ); } // // CK_RV md2_hash_final( SESSION * sess, CK_BYTE length_only, DIGEST_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ) { CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = MD2_HASH_SIZE; return CKR_OK; } rc = ckm_md2_final( (MD2_CONTEXT *)ctx->context, out_data, MD2_HASH_SIZE ); if (rc == CKR_OK) { *out_data_len = MD2_HASH_SIZE; return rc; } return rc; } // this routine gets called for two mechanisms actually: // CKM_MD2_HMAC // CKM_MD2_HMAC_GENERAL // CK_RV md2_hmac_sign( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE hash[MD2_HASH_SIZE]; DIGEST_CONTEXT digest_ctx; CK_MECHANISM digest_mech; CK_BYTE k_ipad[MD2_BLOCK_SIZE]; CK_BYTE k_opad[MD2_BLOCK_SIZE]; CK_ULONG key_bytes, hash_len, hmac_len; CK_ULONG i; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_MD2_HMAC_GENERAL) { hmac_len = *(CK_ULONG *)ctx->mech.pParameter; if (hmac_len == 0) { *out_data_len = 0; return CKR_OK; } } else hmac_len = MD2_HASH_SIZE; if (length_only == TRUE) { *out_data_len = hmac_len; return CKR_OK; } memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key_obj->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else key_bytes = attr->ulValueLen; // build (K XOR ipad), (K XOR opad) // if (key_bytes > MD2_BLOCK_SIZE) { digest_mech.mechanism = CKM_MD2; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest( sess, FALSE, &digest_ctx, attr->pValue, attr->ulValueLen, hash, &hash_len ); if (rc != CKR_OK){ st_err_log(124, __FILE__, __LINE__); return rc; } digest_mgr_cleanup( &digest_ctx ); memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); for (i = 0; i < hash_len; i++) { k_ipad[i] = hash[i] ^ 0x36; k_opad[i] = hash[i] ^ 0x5C; } memset( &k_ipad[i], 0x36, MD2_BLOCK_SIZE - i); memset( &k_opad[i], 0x5C, MD2_BLOCK_SIZE - i); } else { CK_BYTE *key = (CK_BYTE *)attr + sizeof(CK_ATTRIBUTE); for (i = 0; i < key_bytes; i++) { k_ipad[i] = key[i] ^ 0x36; k_opad[i] = key[i] ^ 0x5C; } memset( &k_ipad[i], 0x36, MD2_BLOCK_SIZE - key_bytes ); memset( &k_opad[i], 0x5C, MD2_BLOCK_SIZE - key_bytes ); } digest_mech.mechanism = CKM_MD2; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; // inner hash // rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, k_ipad, MD2_BLOCK_SIZE ); if (rc != CKR_OK){ st_err_log(125, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, in_data, in_data_len ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &hash_len ); if (rc != CKR_OK){ st_err_log(126, __FILE__, __LINE__); return rc; } digest_mgr_cleanup( &digest_ctx ); memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); // outer hash // rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, k_opad, MD2_BLOCK_SIZE ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, hash, hash_len ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &hash_len ); if (rc != CKR_OK){ st_err_log(126, __FILE__, __LINE__); return rc; } memcpy( out_data, hash, hmac_len ); *out_data_len = hmac_len; return CKR_OK; } // // CK_RV md2_hmac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ) { CK_BYTE hmac[MD2_HASH_SIZE]; SIGN_VERIFY_CONTEXT hmac_ctx; CK_ULONG hmac_len, len; CK_RV rc; if (!sess || !ctx || !in_data || !signature){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_MD2_HMAC_GENERAL) hmac_len = *(CK_ULONG *)ctx->mech.pParameter; else hmac_len = MD2_HASH_SIZE; memset( &hmac_ctx, 0, sizeof(SIGN_VERIFY_CONTEXT) ); rc = sign_mgr_init( sess, &hmac_ctx, &ctx->mech, FALSE, ctx->key ); if (rc != CKR_OK){ st_err_log(127, __FILE__, __LINE__); return rc; } len = sizeof(hmac); rc = sign_mgr_sign( sess, FALSE, &hmac_ctx, in_data, in_data_len, hmac, &len ); if (rc != CKR_OK){ st_err_log(128, __FILE__, __LINE__); return rc; } if ((len != hmac_len) || (len != sig_len)){ st_err_log(46, __FILE__, __LINE__); return CKR_SIGNATURE_LEN_RANGE; } if (memcmp(hmac, signature, hmac_len) != 0){ st_err_log(47, __FILE__, __LINE__); return CKR_SIGNATURE_INVALID; } return CKR_OK; } // // CKM routines // // MD2 block update operation. Continues an MD2 message-digest // operation, processing another message block, and updating the // context. // CK_RV ckm_md2_update( MD2_CONTEXT * context, CK_BYTE * input, CK_ULONG inputLen ) { CK_ULONG i, index, partLen; // Update number of bytes mod 16 // index = context->count; context->count = (index + inputLen) & 0xf; partLen = 16 - index; // Process any complete 16-byte blocks // if (inputLen >= partLen) { memcpy( (CK_BYTE *)&context->buffer[index], (CK_BYTE *)input, partLen ); ckm_md2_transform( context->state, context->checksum, context->buffer ); for (i = partLen; i + 15 < inputLen; i += 16) ckm_md2_transform( context->state, context->checksum, &input[i] ); index = 0; } else i = 0; // Buffer remaining input // memcpy( (CK_BYTE *)&context->buffer[index], (CK_BYTE *)&input[i], inputLen-i ); return CKR_OK; } // MD2 finalization. Ends an MD2 message-digest operation, writing the // message digest and zeroizing the context. // CK_RV ckm_md2_final( MD2_CONTEXT * context, CK_BYTE * out_data, CK_ULONG out_data_len ) { CK_ULONG index, padLen; if (!context || !out_data || (out_data_len < MD2_HASH_SIZE)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Pad input to 16-byte multiple (1 - 16 pad bytes) // index = context->count; padLen = 16 - index; ckm_md2_update( context, padding[padLen], padLen ); // Add checksum // ckm_md2_update( context, context->checksum, 16 ); // Store state in digest // memcpy( (CK_BYTE *)out_data, (CK_BYTE *)context->state, 16 ); return CKR_OK; } // MD2 basic transformation. Transforms state and updates checksum // based on block. // void ckm_md2_transform( CK_BYTE * state, CK_BYTE * checksum, CK_BYTE * block ) { CK_ULONG i, j, t; CK_BYTE x[48]; // Form encryption block from state, block, state ^ block. // memcpy( (CK_BYTE *)x, (CK_BYTE *)state, 16 ); memcpy( (CK_BYTE *)x+16, (CK_BYTE *)block, 16 ); for (i = 0; i < 16; i++) x[i+32] = state[i] ^ block[i]; // Encrypt block (18 rounds). // t = 0; for (i = 0; i < 18; i++) { for (j = 0; j < 48; j++) t = x[j] ^= S[t]; t = (t + i) & 0xff; } // Save new state // memcpy( (CK_BYTE *)state, (CK_BYTE *)x, 16 ); // Update checksum. // t = checksum[15]; for (i = 0; i < 16; i++) t = checksum[i] ^= S[block[i] ^ t]; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/sess_mgr.c0000751000175000017500000013100311327631345020703 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: session.c // // Session manager related functions // #include #include #include // for memcmp() et al #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // session_mgr_find() // // search for the specified session. returning a pointer to the session // is dangerous // // Returns: SESSION * or NULL // SESSION * session_mgr_find( CK_SESSION_HANDLE handle ) { DL_NODE * node = NULL; SESSION * result = NULL; CK_RV rc; rc = MY_LockMutex( &sess_list_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return NULL; } node = sess_list; while (node) { SESSION *s = (SESSION *)node->data; if (s->handle == handle) { result = s; break; } node = node->next; } MY_UnlockMutex( &sess_list_mutex ); return result; } // session_mgr_new() // // creates a new session structure and adds it to the process's list // of sessions // // Args: CK_ULONG flags : session flags (INPUT) // SESSION ** sess : new session pointer (OUTPUT) // // Returns: CK_RV // CK_RV session_mgr_new( CK_ULONG flags, SESSION **sess ) { SESSION * new_session = NULL; SESSION * s = NULL; DL_NODE * node = NULL; CK_BBOOL user_session = FALSE; CK_BBOOL so_session = FALSE; CK_BBOOL pkcs_locked = TRUE; CK_BBOOL sess_locked = TRUE; CK_RV rc; new_session = (SESSION *)malloc(sizeof(SESSION)); if (!new_session) { st_err_log(0, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } memset( new_session, 0x0, sizeof(SESSION) ); // find an unused session handle. session handles will wrap // automatically... // rc = MY_LockMutex( &pkcs_mutex ); // this protects next_session_handle if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return rc; } pkcs_locked = TRUE; do { s = session_mgr_find( next_session_handle ); if (s != NULL) next_session_handle++; else new_session->handle = next_session_handle++; } while (s != NULL); MY_UnlockMutex( &pkcs_mutex ); pkcs_locked = FALSE; new_session->session_info.slotID = 1; new_session->session_info.flags = flags; new_session->session_info.ulDeviceError = 0; rc = MY_LockMutex( &sess_list_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return rc; } sess_locked = TRUE; // determine the login/logout status of the new session. PKCS 11 requires // that all sessions belonging to a process have the same login/logout status // node = sess_list; while (node) { SESSION *s = (SESSION *)node->data; if (s->session_info.state == CKS_RW_SO_FUNCTIONS) { so_session = TRUE; break; } if ((s->session_info.state == CKS_RO_USER_FUNCTIONS) || (s->session_info.state == CKS_RW_USER_FUNCTIONS)) { user_session = TRUE; break; } node = node->next; } // SAB XXX login does not drop after all sessions are closed XXX if ( global_login_state == CKS_RW_SO_FUNCTIONS) { so_session = TRUE; } if ((global_login_state == CKS_RO_USER_FUNCTIONS) || (global_login_state == CKS_RW_USER_FUNCTIONS)) { user_session = TRUE; } // END SAB login state carry // we don't have to worry about having a user and SO session at the same time. // that is prevented in the login routine // if (user_session) { if (new_session->session_info.flags & CKF_RW_SESSION) new_session->session_info.state = CKS_RW_USER_FUNCTIONS; else new_session->session_info.state = CKS_RO_USER_FUNCTIONS; } else if (so_session) { new_session->session_info.state = CKS_RW_SO_FUNCTIONS; } else { if (new_session->session_info.flags & CKF_RW_SESSION) new_session->session_info.state = CKS_RW_PUBLIC_SESSION; else new_session->session_info.state = CKS_RO_PUBLIC_SESSION; } sess_list = dlist_add_as_first( sess_list, new_session ); *sess = new_session; done: if (pkcs_locked) MY_UnlockMutex( &pkcs_mutex ); if (sess_locked) MY_UnlockMutex( &sess_list_mutex ); if (rc != CKR_OK && new_session != NULL){ st_err_log(147, __FILE__, __LINE__); free( new_session ); } return rc; } // session_mgr_so_session_exists() // // determines whether a RW_SO session exists for the specified process // // Returns: TRUE or FALSE // CK_BBOOL session_mgr_so_session_exists( void ) { DL_NODE *node = NULL; CK_RV rc; rc = MY_LockMutex( &sess_list_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return rc; } node = sess_list; while (node) { SESSION *s = (SESSION *)node->data; if (s->session_info.state == CKS_RW_SO_FUNCTIONS) { rc = TRUE; goto done; } node = node->next; } rc = FALSE; done: MY_UnlockMutex( &sess_list_mutex ); return rc; } // session_mgr_user_session_exists() // // determines whether a USER session exists for the specified process // // Returns: TRUE or FALSE // CK_BBOOL session_mgr_user_session_exists( void ) { DL_NODE *node = NULL; CK_RV rc; rc = MY_LockMutex( &sess_list_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return rc; } node = sess_list; while (node) { SESSION *s = (SESSION *)node->data; if ((s->session_info.state == CKS_RO_USER_FUNCTIONS) || (s->session_info.state == CKS_RW_USER_FUNCTIONS)) { rc = TRUE; goto done; } node = node->next; } rc = FALSE; done: MY_UnlockMutex( &sess_list_mutex ); return rc; } // session_mgr_public_session_exists() // // determines whether a PUBLIC session exists for the specified process // // Returns: TRUE or FALSE // CK_BBOOL session_mgr_public_session_exists( void ) { DL_NODE *node = NULL; CK_RV rc; rc = MY_LockMutex( &sess_list_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return rc; } node = sess_list; while (node) { SESSION *s = (SESSION *)node->data; if ((s->session_info.state == CKS_RO_PUBLIC_SESSION) || (s->session_info.state == CKS_RW_PUBLIC_SESSION)) { rc = TRUE; goto done; } node = node->next; } rc = FALSE; done: MY_UnlockMutex( &sess_list_mutex ); return rc; } // session_mgr_readonly_exists() // // determines whether the specified process owns any read-only sessions. this is useful // because the SO cannot log in if a read-only session exists. // CK_BBOOL session_mgr_readonly_exists( void ) { DL_NODE *node = NULL; CK_RV rc; rc = MY_LockMutex( &sess_list_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return rc; } node = sess_list; while (node) { SESSION *s = (SESSION *)node->data; if ((s->session_info.flags & CKF_RW_SESSION) == 0) { rc = TRUE; goto done; } node = node->next; } rc = FALSE; done: MY_UnlockMutex( &sess_list_mutex ); return rc; } // session_mgr_close_session() // // removes the specified session from the process' session list // // Args: PROCESS * proc : parent process // SESSION * session : session to remove // // Returns: TRUE on success else FALSE // CK_RV session_mgr_close_session( SESSION *sess ) { DL_NODE * node = NULL; CK_RV rc = CKR_OK; if (!sess) return FALSE; rc = MY_LockMutex( &sess_list_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } node = dlist_find( sess_list, sess ); if (!node) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } object_mgr_purge_session_objects( sess, ALL ); if (sess->find_list) free( sess->find_list ); if (sess->encr_ctx.context) free( sess->encr_ctx.context ); if (sess->encr_ctx.mech.pParameter) free( sess->encr_ctx.mech.pParameter ); if (sess->decr_ctx.context) free( sess->decr_ctx.context ); if (sess->decr_ctx.mech.pParameter) free( sess->decr_ctx.mech.pParameter ); if (sess->digest_ctx.context) free( sess->digest_ctx.context ); if (sess->digest_ctx.mech.pParameter) free( sess->digest_ctx.mech.pParameter ); if (sess->sign_ctx.context) free( sess->sign_ctx.context ); if (sess->sign_ctx.mech.pParameter) free( sess->sign_ctx.mech.pParameter ); if (sess->verify_ctx.context) free( sess->verify_ctx.context ); if (sess->verify_ctx.mech.pParameter) free( sess->verify_ctx.mech.pParameter ); free( sess ); sess_list = dlist_remove_node( sess_list, node ); // XXX XXX Not having this is a problem // for IHS. The spec states that there is an implicit logout // when the last session is closed. Cannonicaly this is what other // implementaitons do. however on linux for some reason IHS can't seem // to keep the session open, which means that they go through the login // path EVERY time, which of course causes a reload of the private // objects EVERY time. If we are logged out, we MUST purge the private // objects from this process.. // if (sess_list == NULL) { // SAB XXX if all sessions are closed. Is this effectivly logging out object_mgr_purge_private_token_objects(); global_login_state = 0; // The objects really need to be purged .. but this impacts the // performance under linux. So we need to make sure that the // login state is valid. I don't really like this. MY_LockMutex( &obj_list_mutex ); object_mgr_purge_map((SESSION *)0xFFFF, PRIVATE); MY_UnlockMutex( &obj_list_mutex ); } done: MY_UnlockMutex( &sess_list_mutex ); return rc; } // session_mgr_close_all_sessions() // // removes all sessions from the specified process // CK_RV session_mgr_close_all_sessions( void ) { CK_RV rc = CKR_OK; rc = MY_LockMutex( &sess_list_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } while (sess_list) { SESSION *sess = (SESSION *)sess_list->data; object_mgr_purge_session_objects( sess, ALL ); if (sess->find_list) free( sess->find_list ); if (sess->encr_ctx.context) free( sess->encr_ctx.context ); if (sess->encr_ctx.mech.pParameter) free( sess->encr_ctx.mech.pParameter); if (sess->decr_ctx.context) free( sess->decr_ctx.context ); if (sess->decr_ctx.mech.pParameter) free( sess->decr_ctx.mech.pParameter); if (sess->digest_ctx.context) free( sess->digest_ctx.context ); if (sess->digest_ctx.mech.pParameter) free( sess->digest_ctx.mech.pParameter); if (sess->sign_ctx.context) free( sess->sign_ctx.context ); if (sess->sign_ctx.mech.pParameter) free( sess->sign_ctx.mech.pParameter); if (sess->verify_ctx.context) free( sess->verify_ctx.context ); if (sess->verify_ctx.mech.pParameter) free( sess->verify_ctx.mech.pParameter); free( sess ); sess_list = dlist_remove_node( sess_list, sess_list ); } MY_UnlockMutex( &sess_list_mutex ); return CKR_OK; } // session_mgr_login_all() // // changes the login status of all sessions in the token // // Arg: CK_USER_TYPE user_type : USER or SO // CK_RV session_mgr_login_all( CK_USER_TYPE user_type ) { DL_NODE * node = NULL; CK_RV rc = CKR_OK; rc = MY_LockMutex( &sess_list_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } node = sess_list; while (node) { SESSION *s = (SESSION *)node->data; if (s->session_info.flags & CKF_RW_SESSION) { if (user_type == CKU_USER) s->session_info.state = CKS_RW_USER_FUNCTIONS; else s->session_info.state = CKS_RW_SO_FUNCTIONS; } else { if (user_type == CKU_USER) s->session_info.state = CKS_RO_USER_FUNCTIONS; } global_login_state = s->session_info.state; // SAB node = node->next; } MY_UnlockMutex( &sess_list_mutex ); return CKR_OK; } // session_mgr_logout_all() // // changes the login status of all sessions in the token // CK_RV session_mgr_logout_all( void ) { DL_NODE * node = NULL; SESSION * s = NULL; CK_RV rc = CKR_OK; rc = MY_LockMutex( &sess_list_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } node = sess_list; while (node) { s = (SESSION *)node->data; // all sessions get logged out so destroy any private objects // public objects are left alone // object_mgr_purge_session_objects( s, PRIVATE ); if (s->session_info.flags & CKF_RW_SESSION) s->session_info.state = CKS_RW_PUBLIC_SESSION; else s->session_info.state = CKS_RO_PUBLIC_SESSION; global_login_state = s->session_info.state; // SAB node = node->next; } MY_UnlockMutex( &sess_list_mutex ); return CKR_OK; } // // CK_RV session_mgr_get_op_state( SESSION *sess, CK_BBOOL length_only, CK_BYTE *data, CK_ULONG *data_len ) { OP_STATE_DATA *op_data = NULL; CK_ULONG op_data_len = 0; CK_ULONG offset; if (!sess){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // ensure that at least one operation is active // if (sess->find_active == TRUE){ st_err_log(71, __FILE__, __LINE__); return CKR_STATE_UNSAVEABLE; } if (sess->encr_ctx.active == TRUE) { if (op_data != NULL){ st_err_log(71, __FILE__, __LINE__); return CKR_STATE_UNSAVEABLE; } op_data_len = sizeof(OP_STATE_DATA) + sizeof(ENCR_DECR_CONTEXT) + sess->encr_ctx.context_len + sess->encr_ctx.mech.ulParameterLen; if (length_only == FALSE) { op_data = (OP_STATE_DATA *)data; op_data->data_len = op_data_len - sizeof(OP_STATE_DATA); op_data->session_state = sess->session_info.state; op_data->active_operation = STATE_ENCR; offset = sizeof(OP_STATE_DATA); memcpy( (CK_BYTE *)op_data + offset, &sess->encr_ctx, sizeof(ENCR_DECR_CONTEXT) ); offset += sizeof(ENCR_DECR_CONTEXT); if (sess->encr_ctx.context_len != 0) { memcpy( (CK_BYTE *)op_data + offset, sess->encr_ctx.context, sess->encr_ctx.context_len ); offset += sess->encr_ctx.context_len; } if (sess->encr_ctx.mech.ulParameterLen != 0) { memcpy( (CK_BYTE *)op_data + offset, sess->encr_ctx.mech.pParameter, sess->encr_ctx.mech.ulParameterLen ); } } } if (sess->decr_ctx.active == TRUE) { if (op_data != NULL){ st_err_log(71, __FILE__, __LINE__); return CKR_STATE_UNSAVEABLE; } op_data_len = sizeof(OP_STATE_DATA) + sizeof(ENCR_DECR_CONTEXT) + sess->decr_ctx.context_len + sess->decr_ctx.mech.ulParameterLen; if (length_only == FALSE) { op_data = (OP_STATE_DATA *)data; op_data->data_len = op_data_len - sizeof(OP_STATE_DATA); op_data->session_state = sess->session_info.state; op_data->active_operation = STATE_DECR; offset = sizeof(OP_STATE_DATA); memcpy( (CK_BYTE *)op_data + offset, &sess->decr_ctx, sizeof(ENCR_DECR_CONTEXT) ); offset += sizeof(ENCR_DECR_CONTEXT); if (sess->decr_ctx.context_len != 0) { memcpy( (CK_BYTE *)op_data + offset, sess->decr_ctx.context, sess->decr_ctx.context_len ); offset += sess->decr_ctx.context_len; } if (sess->decr_ctx.mech.ulParameterLen != 0) { memcpy( (CK_BYTE *)op_data + offset, sess->decr_ctx.mech.pParameter, sess->decr_ctx.mech.ulParameterLen ); } } } if (sess->digest_ctx.active == TRUE) { if (op_data != NULL){ st_err_log(71, __FILE__, __LINE__); return CKR_STATE_UNSAVEABLE; } op_data_len = sizeof(OP_STATE_DATA) + sizeof(DIGEST_CONTEXT) + sess->digest_ctx.context_len + sess->digest_ctx.mech.ulParameterLen; if (length_only == FALSE) { op_data = (OP_STATE_DATA *)data; op_data->data_len = op_data_len - sizeof(OP_STATE_DATA); op_data->session_state = sess->session_info.state; op_data->active_operation = STATE_DIGEST; offset = sizeof(OP_STATE_DATA); memcpy( (CK_BYTE *)op_data + offset, &sess->digest_ctx, sizeof(DIGEST_CONTEXT) ); offset += sizeof(DIGEST_CONTEXT); if (sess->digest_ctx.context_len != 0) { memcpy( (CK_BYTE *)op_data + offset, sess->digest_ctx.context, sess->digest_ctx.context_len ); offset += sess->digest_ctx.context_len; } if (sess->digest_ctx.mech.ulParameterLen != 0) { memcpy( (CK_BYTE *)op_data + offset, sess->digest_ctx.mech.pParameter, sess->digest_ctx.mech.ulParameterLen ); } } } if (sess->sign_ctx.active == TRUE) { if (op_data != NULL){ st_err_log(71, __FILE__, __LINE__); return CKR_STATE_UNSAVEABLE; } op_data_len = sizeof(OP_STATE_DATA) + sizeof(SIGN_VERIFY_CONTEXT) + sess->sign_ctx.context_len + sess->sign_ctx.mech.ulParameterLen; if (length_only == FALSE) { op_data = (OP_STATE_DATA *)data; op_data->data_len = op_data_len - sizeof(OP_STATE_DATA); op_data->session_state = sess->session_info.state; op_data->active_operation = STATE_SIGN; offset = sizeof(OP_STATE_DATA); memcpy( (CK_BYTE *)op_data + offset, &sess->sign_ctx, sizeof(SIGN_VERIFY_CONTEXT) ); offset += sizeof(SIGN_VERIFY_CONTEXT); if (sess->sign_ctx.context_len != 0) { memcpy( (CK_BYTE *)op_data + offset, sess->sign_ctx.context, sess->sign_ctx.context_len ); offset += sess->sign_ctx.context_len; } if (sess->sign_ctx.mech.ulParameterLen != 0) { memcpy( (CK_BYTE *)op_data + offset, sess->sign_ctx.mech.pParameter, sess->sign_ctx.mech.ulParameterLen ); } } } if (sess->verify_ctx.active == TRUE) { if (op_data != NULL){ st_err_log(71, __FILE__, __LINE__); return CKR_STATE_UNSAVEABLE; } op_data_len = sizeof(OP_STATE_DATA) + sizeof(SIGN_VERIFY_CONTEXT) + sess->verify_ctx.context_len + sess->verify_ctx.mech.ulParameterLen; if (length_only == FALSE) { op_data = (OP_STATE_DATA *)data; op_data->data_len = op_data_len - sizeof(OP_STATE_DATA); op_data->session_state = sess->session_info.state; op_data->active_operation = STATE_SIGN; offset = sizeof(OP_STATE_DATA); memcpy( (CK_BYTE *)op_data + offset, &sess->verify_ctx, sizeof(SIGN_VERIFY_CONTEXT) ); offset += sizeof(SIGN_VERIFY_CONTEXT); if (sess->verify_ctx.context_len != 0) { memcpy( (CK_BYTE *)op_data + offset, sess->verify_ctx.context, sess->verify_ctx.context_len ); offset += sess->verify_ctx.context_len; } if (sess->verify_ctx.mech.ulParameterLen != 0) { memcpy( (CK_BYTE *)op_data + offset, sess->verify_ctx.mech.pParameter, sess->verify_ctx.mech.ulParameterLen ); } } } *data_len = op_data_len; return CKR_OK; } // // CK_RV session_mgr_set_op_state( SESSION * sess, CK_OBJECT_HANDLE encr_key, CK_OBJECT_HANDLE auth_key, CK_BYTE * data, CK_ULONG data_len ) { OP_STATE_DATA *op_data = NULL; CK_BYTE *mech_param = NULL; CK_BYTE *context = NULL; CK_BYTE *ptr1 = NULL; CK_BYTE *ptr2 = NULL; CK_BYTE *ptr3 = NULL; CK_ULONG len; if (!sess || !data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } op_data = (OP_STATE_DATA *)data; // make sure the session states are compatible // if (sess->session_info.state != op_data->session_state){ st_err_log(69, __FILE__, __LINE__); return CKR_SAVED_STATE_INVALID; } // validate the new state information. don't touch the session // until the new state is valid. // switch (op_data->active_operation) { case STATE_ENCR: case STATE_DECR: { ENCR_DECR_CONTEXT *ctx = (ENCR_DECR_CONTEXT *)(data + sizeof(OP_STATE_DATA)); len = sizeof(ENCR_DECR_CONTEXT) + ctx->context_len + ctx->mech.ulParameterLen; if (len != op_data->data_len){ st_err_log(69, __FILE__, __LINE__); return CKR_SAVED_STATE_INVALID; } if (auth_key != 0){ st_err_log(21, __FILE__, __LINE__); return CKR_KEY_NOT_NEEDED; } if (encr_key == 0){ st_err_log(23, __FILE__, __LINE__); return CKR_KEY_NEEDED; } ptr1 = (CK_BYTE *)ctx; ptr2 = ptr1 + sizeof(ENCR_DECR_CONTEXT); ptr3 = ptr2 + ctx->context_len; if (ctx->context_len) { context = (CK_BYTE *)malloc( ctx->context_len ); if (!context){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( context, ptr2, ctx->context_len ); } if (ctx->mech.ulParameterLen) { mech_param = (CK_BYTE *)malloc( ctx->mech.ulParameterLen ); if (!mech_param) { if (context) free( context ); st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( mech_param, ptr3, ctx->mech.ulParameterLen ); } } break; case STATE_SIGN: case STATE_VERIFY: { SIGN_VERIFY_CONTEXT *ctx = (SIGN_VERIFY_CONTEXT *)(data + sizeof(OP_STATE_DATA)); len = sizeof(SIGN_VERIFY_CONTEXT) + ctx->context_len + ctx->mech.ulParameterLen; if (len != op_data->data_len){ st_err_log(69, __FILE__, __LINE__); return CKR_SAVED_STATE_INVALID; } if (auth_key == 0){ st_err_log(23, __FILE__, __LINE__); return CKR_KEY_NEEDED; } if (encr_key != 0){ st_err_log(21, __FILE__, __LINE__); return CKR_KEY_NOT_NEEDED; } ptr1 = (CK_BYTE *)ctx; ptr2 = ptr1 + sizeof(SIGN_VERIFY_CONTEXT); ptr3 = ptr2 + ctx->context_len; if (ctx->context_len) { context = (CK_BYTE *)malloc( ctx->context_len ); if (!context){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( context, ptr2, ctx->context_len ); } if (ctx->mech.ulParameterLen) { mech_param = (CK_BYTE *)malloc( ctx->mech.ulParameterLen ); if (!mech_param) { if (context) free( context ); st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( mech_param, ptr3, ctx->mech.ulParameterLen ); } } break; case STATE_DIGEST: { DIGEST_CONTEXT *ctx = (DIGEST_CONTEXT *)(data + sizeof(OP_STATE_DATA)); len = sizeof(DIGEST_CONTEXT) + ctx->context_len + ctx->mech.ulParameterLen; if (len != op_data->data_len){ st_err_log(69, __FILE__, __LINE__); return CKR_SAVED_STATE_INVALID; } if (auth_key != 0){ st_err_log(23, __FILE__, __LINE__); return CKR_KEY_NOT_NEEDED; } if (encr_key != 0){ st_err_log(23, __FILE__, __LINE__); return CKR_KEY_NOT_NEEDED; } ptr1 = (CK_BYTE *)ctx; ptr2 = ptr1 + sizeof(DIGEST_CONTEXT); ptr3 = ptr2 + ctx->context_len; if (ctx->context_len) { context = (CK_BYTE *)malloc( ctx->context_len ); if (!context){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( context, ptr2, ctx->context_len ); } if (ctx->mech.ulParameterLen) { mech_param = (CK_BYTE *)malloc( ctx->mech.ulParameterLen ); if (!mech_param) { if (context) free( context ); st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( mech_param, ptr3, ctx->mech.ulParameterLen ); } } break; default: st_err_log(69, __FILE__, __LINE__); return CKR_SAVED_STATE_INVALID; } // state information looks okay. cleanup the current session state, first // if (sess->encr_ctx.active) encr_mgr_cleanup( &sess->encr_ctx ); if (sess->decr_ctx.active) decr_mgr_cleanup( &sess->decr_ctx ); if (sess->digest_ctx.active) digest_mgr_cleanup( &sess->digest_ctx ); if (sess->sign_ctx.active) sign_mgr_cleanup( &sess->sign_ctx ); if (sess->verify_ctx.active) verify_mgr_cleanup( &sess->verify_ctx ); // copy the new state information // switch (op_data->active_operation) { case STATE_ENCR: memcpy( &sess->encr_ctx, ptr1, sizeof(ENCR_DECR_CONTEXT) ); sess->encr_ctx.key = encr_key; sess->encr_ctx.context = context; sess->encr_ctx.mech.pParameter = mech_param; break; case STATE_DECR: memcpy( &sess->decr_ctx, ptr1, sizeof(ENCR_DECR_CONTEXT) ); sess->decr_ctx.key = encr_key; sess->decr_ctx.context = context; sess->decr_ctx.mech.pParameter = mech_param; break; case STATE_SIGN: memcpy( &sess->sign_ctx, ptr1, sizeof(SIGN_VERIFY_CONTEXT) ); sess->sign_ctx.key = auth_key; sess->sign_ctx.context = context; sess->sign_ctx.mech.pParameter = mech_param; break; case STATE_VERIFY: memcpy( &sess->verify_ctx, ptr1, sizeof(SIGN_VERIFY_CONTEXT) ); sess->verify_ctx.key = auth_key; sess->verify_ctx.context = context; sess->verify_ctx.mech.pParameter = mech_param; break; case STATE_DIGEST: memcpy( &sess->digest_ctx, ptr1, sizeof(DIGEST_CONTEXT) ); sess->digest_ctx.context = context; sess->digest_ctx.mech.pParameter = mech_param; break; } return CKR_OK; } // Return TRUE if the session we're in has its PIN // expired. CK_BBOOL pin_expired(CK_SESSION_INFO *si, CK_FLAGS flags) { // If this is an SO session if ( (flags & CKF_SO_PIN_TO_BE_CHANGED) && (si->state == CKS_RW_SO_FUNCTIONS) ) return TRUE; // Else we're a User session return( (flags & CKF_USER_PIN_TO_BE_CHANGED) && ((si->state == CKS_RO_USER_FUNCTIONS) || (si->state == CKS_RW_USER_FUNCTIONS)) ); } // Return TRUE if the session we're in has its PIN // locked. CK_BBOOL pin_locked(CK_SESSION_INFO *si, CK_FLAGS flags) { // If this is an SO session if ( (flags & CKF_SO_PIN_LOCKED) && (si->state == CKS_RW_SO_FUNCTIONS) ) return TRUE; // Else we're a User session return( (flags & CKF_USER_PIN_LOCKED) && ((si->state == CKS_RO_USER_FUNCTIONS) || (si->state == CKS_RW_USER_FUNCTIONS)) ); } // Increment the login flags after an incorrect password // has been passed to C_Login. New for v2.11. - KEY void set_login_flags(CK_USER_TYPE userType, CK_FLAGS_32 *flags) { if(userType == CKU_USER) { if(*flags & CKF_USER_PIN_FINAL_TRY) { *flags |= CKF_USER_PIN_LOCKED; *flags &= ~(CKF_USER_PIN_FINAL_TRY); } else if (*flags & CKF_USER_PIN_COUNT_LOW) { *flags |= CKF_USER_PIN_FINAL_TRY; *flags &= ~(CKF_USER_PIN_COUNT_LOW); } else { *flags |= CKF_USER_PIN_COUNT_LOW; } } else { if(*flags & CKF_SO_PIN_FINAL_TRY) { *flags |= CKF_SO_PIN_LOCKED; *flags &= ~(CKF_SO_PIN_FINAL_TRY); } else if (*flags & CKF_SO_PIN_COUNT_LOW) { *flags |= CKF_SO_PIN_FINAL_TRY; *flags &= ~(CKF_SO_PIN_COUNT_LOW); } else { *flags |= CKF_SO_PIN_COUNT_LOW; } } } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/key_mgr.c0000751000175000017500000013172111327631345020525 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ /*************************************************************************** Change Log ========== 4/25/03 Kapil Sood (kapil@corrent.com) Added DH key pair generation and DH shared key derivation functions. ****************************************************************************/ // File: key_mgr.c // #include #include #include // for memcmp() et al #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" static CK_BBOOL true = TRUE, false = FALSE; // // CK_RV key_mgr_generate_key( SESSION * sess, CK_MECHANISM * mech, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE * handle ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_ATTRIBUTE * new_attr = NULL; CK_ULONG i, keyclass, subclass = 0; CK_BBOOL flag; CK_RV rc; if (!sess || !mech || !handle){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!pTemplate && (ulCount != 0)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // it's silly but Cryptoki allows the user to specify the CKA_CLASS // in the template. so we have to iterate through the provided template // and make sure that if CKA_CLASS is CKO_SECRET_KEY, if it is present. // // it would have been more logical for Cryptoki to forbid specifying // the CKA_CLASS attribute when generating a key // for (i=0; i < ulCount; i++) { if (pTemplate[i].type == CKA_CLASS) { keyclass = *(CK_OBJECT_CLASS *)pTemplate[i].pValue; if (keyclass != CKO_SECRET_KEY){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } if (pTemplate[i].type == CKA_KEY_TYPE) subclass = *(CK_ULONG *)pTemplate[i].pValue; } switch (mech->mechanism) { case CKM_DES_KEY_GEN: if (subclass != 0 && subclass != CKK_DES){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_DES; break; case CKM_DES3_KEY_GEN: if (subclass != 0 && subclass != CKK_DES3){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_DES3; break; #if !(NOCDMF) case CKM_CDMF_KEY_GEN: if (subclass != 0 && subclass != CKK_CDMF){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_CDMF; break; #endif case CKM_SSL3_PRE_MASTER_KEY_GEN: if (subclass != 0 && subclass != CKK_GENERIC_SECRET){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } if (mech->ulParameterLen != sizeof(CK_VERSION)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } subclass = CKK_GENERIC_SECRET; break; case CKM_AES_KEY_GEN: if (subclass != 0 && subclass != CKK_AES){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_AES; break; default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } rc = object_mgr_create_skel( sess, pTemplate, ulCount, MODE_KEYGEN, CKO_SECRET_KEY, subclass, &key_obj ); if (rc != CKR_OK){ st_err_log(89, __FILE__, __LINE__); goto error; } // at this point, 'key_obj' should contain a skeleton key. depending on // the key type, we may need to extract one or more attributes from // the object prior to generating the key data (ie. variable key length) // switch (mech->mechanism) { case CKM_DES_KEY_GEN: rc = ckm_des_key_gen( key_obj->template ); break; case CKM_DES3_KEY_GEN: rc = ckm_des3_key_gen( key_obj->template ); break; #if !(NOCDMF) case CKM_CDMF_KEY_GEN: rc = ckm_cdmf_key_gen( key_obj->template ); break; #endif case CKM_SSL3_PRE_MASTER_KEY_GEN: rc = ckm_ssl3_pre_master_key_gen( key_obj->template, mech ); break; #ifndef NOAES case CKM_AES_KEY_GEN: rc = ckm_aes_key_gen( key_obj->template ); break; #endif default: st_err_log(28, __FILE__, __LINE__); rc = CKR_MECHANISM_INVALID; } if (rc != CKR_OK){ st_err_log(91, __FILE__, __LINE__); goto error; } // we can now set CKA_ALWAYS_SENSITIVE and CKA_NEVER_EXTRACTABLE // to their appropriate values. this only applies to CKO_SECRET_KEY // and CKO_PRIVATE_KEY objects // flag = template_attribute_find( key_obj->template, CKA_SENSITIVE, &attr ); if (flag == TRUE) { flag = *(CK_BBOOL *)attr->pValue; rc = build_attribute( CKA_ALWAYS_SENSITIVE, &flag, sizeof(CK_BBOOL), &new_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } template_update_attribute( key_obj->template, new_attr ); } else { rc = CKR_FUNCTION_FAILED; st_err_log(4, __FILE__, __LINE__, __FUNCTION__); goto error; } flag = template_attribute_find( key_obj->template, CKA_EXTRACTABLE, &attr ); if (flag == TRUE) { flag = *(CK_BBOOL *)attr->pValue; rc = build_attribute( CKA_NEVER_EXTRACTABLE, &true, sizeof(CK_BBOOL), &new_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } if (flag == TRUE) *(CK_BBOOL *)new_attr->pValue = FALSE; template_update_attribute( key_obj->template, new_attr ); } else { rc = CKR_FUNCTION_FAILED; st_err_log(4, __FILE__, __LINE__, __FUNCTION__); goto error; } // at this point, the key should be fully constructed...assign // an object handle and store the key // rc = object_mgr_create_final( sess, key_obj, handle ); if (rc != CKR_OK){ st_err_log(90, __FILE__, __LINE__); goto error; } return rc; error: if (key_obj) object_free( key_obj ); *handle = 0; return rc; } // // CK_RV key_mgr_generate_key_pair( SESSION * sess, CK_MECHANISM * mech, CK_ATTRIBUTE * publ_tmpl, CK_ULONG publ_count, CK_ATTRIBUTE * priv_tmpl, CK_ULONG priv_count, CK_OBJECT_HANDLE * publ_key_handle, CK_OBJECT_HANDLE * priv_key_handle ) { OBJECT * publ_key_obj = NULL; OBJECT * priv_key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_ATTRIBUTE * new_attr = NULL; CK_ULONG i, keyclass, subclass = 0; CK_BBOOL flag; CK_RV rc; if (!sess || !mech || !publ_key_handle || !priv_key_handle){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!publ_tmpl && (publ_count != 0)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!priv_tmpl && (priv_count != 0)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // it's silly but Cryptoki allows the user to specify the CKA_CLASS // in the template. so we have to iterate through the provided template // and make sure that if CKA_CLASS is valid, if it is present. // // it would have been more logical for Cryptoki to forbid specifying // the CKA_CLASS attribute when generating a key // for (i=0; i < publ_count; i++) { if (publ_tmpl[i].type == CKA_CLASS) { keyclass = *(CK_OBJECT_CLASS *)publ_tmpl[i].pValue; if (keyclass != CKO_PUBLIC_KEY){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } if (publ_tmpl[i].type == CKA_KEY_TYPE) subclass = *(CK_ULONG *)publ_tmpl[i].pValue; } for (i=0; i < priv_count; i++) { if (priv_tmpl[i].type == CKA_CLASS) { keyclass = *(CK_OBJECT_CLASS *)priv_tmpl[i].pValue; if (keyclass != CKO_PRIVATE_KEY){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } if (priv_tmpl[i].type == CKA_KEY_TYPE) { CK_ULONG temp = *(CK_ULONG *)priv_tmpl[i].pValue; if (temp != subclass){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } } switch (mech->mechanism) { case CKM_RSA_PKCS_KEY_PAIR_GEN: if (subclass != 0 && subclass != CKK_RSA){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_RSA; break; #if !(NODSA) case CKM_DSA_KEY_PAIR_GEN: if (subclass != 0 && subclass != CKK_DSA){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_DSA; break; #endif /* Begin code contributed by Corrent corp. */ #if !(NODH) case CKM_DH_PKCS_KEY_PAIR_GEN: if (subclass != 0 && subclass != CKK_DH){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } subclass = CKK_DH; break; #endif /* End code contributed by Corrent corp. */ default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } rc = object_mgr_create_skel( sess, publ_tmpl, publ_count, MODE_KEYGEN, CKO_PUBLIC_KEY, subclass, &publ_key_obj ); if (rc != CKR_OK){ st_err_log(89, __FILE__, __LINE__); goto error; } rc = object_mgr_create_skel( sess, priv_tmpl, priv_count, MODE_KEYGEN, CKO_PRIVATE_KEY, subclass, &priv_key_obj ); if (rc != CKR_OK){ st_err_log(89, __FILE__, __LINE__); goto error; } // at this point, 'key_obj' should contain a skeleton key. depending on // the key type, we may need to extract one or more attributes from // the object prior to generating the key data (ie. variable key length) // switch (mech->mechanism) { case CKM_RSA_PKCS_KEY_PAIR_GEN: rc = ckm_rsa_key_pair_gen( publ_key_obj->template, priv_key_obj->template ); break; #if !(NODSA) case CKM_DSA_KEY_PAIR_GEN: rc = ckm_dsa_key_pair_gen( publ_key_obj->template, priv_key_obj->template ); break; #endif /* Begin code contributed by Corrent corp. */ #if !(NODH) case CKM_DH_PKCS_KEY_PAIR_GEN: rc = ckm_dh_pkcs_key_pair_gen( publ_key_obj->template, priv_key_obj->template ); break; #endif /* End code contributed by Corrent corp. */ default: st_err_log(28, __FILE__, __LINE__); rc = CKR_MECHANISM_INVALID; break; } if (rc != CKR_OK){ st_err_log(91, __FILE__, __LINE__); goto error; } // we can now set CKA_ALWAYS_SENSITIVE and CKA_NEVER_EXTRACTABLE // to their appropriate values. this only applies to CKO_SECRET_KEY // and CKO_PRIVATE_KEY objects // flag = template_attribute_find( priv_key_obj->template, CKA_SENSITIVE, &attr ); if (flag == TRUE) { flag = *(CK_BBOOL *)attr->pValue; rc = build_attribute( CKA_ALWAYS_SENSITIVE, &flag, sizeof(CK_BBOOL), &new_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } template_update_attribute( priv_key_obj->template, new_attr ); } else { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } flag = template_attribute_find( priv_key_obj->template, CKA_EXTRACTABLE, &attr ); if (flag == TRUE) { flag = *(CK_BBOOL *)attr->pValue; rc = build_attribute( CKA_NEVER_EXTRACTABLE, &true, sizeof(CK_BBOOL), &new_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } if (flag == TRUE) *(CK_BBOOL *)new_attr->pValue = false; template_update_attribute( priv_key_obj->template, new_attr ); } else { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } // at this point, the keys should be fully constructed...assign // object handles and store the keys // rc = object_mgr_create_final( sess, publ_key_obj, publ_key_handle ); if (rc != CKR_OK){ st_err_log(90, __FILE__, __LINE__); goto error; } rc = object_mgr_create_final( sess, priv_key_obj, priv_key_handle ); if (rc != CKR_OK){ st_err_log(90, __FILE__, __LINE__); // just calling object_free in the error path below would lead to a double // free error on session close - KEY 09/26/07 object_mgr_destroy_object( sess, *publ_key_handle ); publ_key_obj = NULL; goto error; } return rc; error: if (publ_key_obj) object_free( publ_key_obj ); if (priv_key_obj) object_free( priv_key_obj ); *publ_key_handle = 0; *priv_key_handle = 0; return rc; } // // CK_RV key_mgr_wrap_key( SESSION * sess, CK_BBOOL length_only, CK_MECHANISM * mech, CK_OBJECT_HANDLE h_wrapping_key, CK_OBJECT_HANDLE h_key, CK_BYTE * wrapped_key, CK_ULONG * wrapped_key_len ) { ENCR_DECR_CONTEXT * ctx = NULL; OBJECT * key1_obj = NULL; OBJECT * key2_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * data = NULL; CK_ULONG data_len; CK_OBJECT_CLASS class; CK_KEY_TYPE keytype; CK_BBOOL flag; CK_RV rc; if (!sess || !wrapped_key_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( h_wrapping_key, &key1_obj ); if (rc != CKR_OK){ st_err_log(62, __FILE__, __LINE__); return CKR_WRAPPING_KEY_HANDLE_INVALID; } rc = object_mgr_find_in_map1( h_key, &key2_obj ); if (rc != CKR_OK){ st_err_log(18, __FILE__, __LINE__); return CKR_KEY_HANDLE_INVALID; } // is the key-to-be-wrapped EXTRACTABLE? // rc = template_attribute_find( key2_obj->template, CKA_EXTRACTABLE, &attr ); if (rc == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; // could happen if user tries to wrap a public key } else { flag = *(CK_BBOOL *)attr->pValue; if (flag == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } } // what kind of key are we trying to wrap? make sure the mechanism is // allowed to wrap this kind of key // rc = template_attribute_find( key2_obj->template, CKA_CLASS, &attr ); if (rc == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } else class = *(CK_OBJECT_CLASS *)attr->pValue; switch (mech->mechanism) { #if !(NOCDMF) case CKM_CDMF_ECB: case CKM_CDMF_CBC: #endif case CKM_DES_ECB: case CKM_DES_CBC: case CKM_DES3_ECB: case CKM_DES3_CBC: case CKM_AES_ECB: case CKM_AES_CBC: if (class != CKO_SECRET_KEY){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } break; #if !(NOCDMF) case CKM_CDMF_CBC_PAD: #endif case CKM_DES_CBC_PAD: case CKM_DES3_CBC_PAD: case CKM_AES_CBC_PAD: // these mechanisms can wrap any type of key // break; case CKM_RSA_PKCS: case CKM_RSA_X_509: if (class != CKO_SECRET_KEY){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } break; default: st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } // extract the secret data to be wrapped // rc = template_attribute_find( key2_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } else keytype = *(CK_KEY_TYPE *)attr->pValue; switch (keytype) { #if !(NOCDMF) case CKK_CDMF: #endif case CKK_DES: rc = des_wrap_get_data( key2_obj->template, length_only, &data, &data_len ); if (rc != CKR_OK){ st_err_log(92, __FILE__, __LINE__); return rc; } break; case CKK_DES3: rc = des3_wrap_get_data( key2_obj->template, length_only, &data, &data_len ); if (rc != CKR_OK){ st_err_log(93, __FILE__, __LINE__); return rc; } break; case CKK_RSA: rc = rsa_priv_wrap_get_data( key2_obj->template, length_only, &data, &data_len ); if (rc != CKR_OK){ st_err_log(94, __FILE__, __LINE__); return rc; } break; #if !(NODSA) case CKK_DSA: rc = dsa_priv_wrap_get_data( key2_obj->template, length_only, &data, &data_len ); if (rc != CKR_OK){ st_err_log(95, __FILE__, __LINE__); return rc; } break; #endif case CKK_GENERIC_SECRET: rc = generic_secret_wrap_get_data( key2_obj->template, length_only, &data, &data_len ); if (rc != CKR_OK){ st_err_log(96, __FILE__, __LINE__); return rc; } break; #ifndef NOAES case CKK_AES: rc = aes_wrap_get_data( key2_obj->template, length_only, &data, &data_len ); if (rc != CKR_OK){ st_err_log(191, __FILE__, __LINE__); return rc; } break; #endif default: st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } // we might need to format the wrapped data based on the mechanism // switch (mech->mechanism) { #if !(NOCMF) case CKM_CDMF_ECB: case CKM_CDMF_CBC: #endif case CKM_DES_ECB: case CKM_DES_CBC: case CKM_DES3_ECB: case CKM_DES3_CBC: rc = ckm_des_wrap_format( length_only, &data, &data_len ); if (rc != CKR_OK) { st_err_log(97, __FILE__, __LINE__); if (data) free( data ); return rc; } break; #ifndef NOAES case CKM_AES_ECB: case CKM_AES_CBC: rc = ckm_aes_wrap_format( length_only, &data, &data_len ); if (rc != CKR_OK) { st_err_log(192, __FILE__, __LINE__); if (data) free( data ); return rc; } break; #endif #if !(NOCMF) case CKM_CDMF_CBC_PAD: #endif case CKM_DES_CBC_PAD: case CKM_DES3_CBC_PAD: case CKM_AES_CBC_PAD: // these mechanisms pad themselves // break; case CKM_RSA_PKCS: case CKM_RSA_X_509: break; default: st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } ctx = (ENCR_DECR_CONTEXT *)malloc(sizeof(ENCR_DECR_CONTEXT)); if (!ctx){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx, 0x0, sizeof(ENCR_DECR_CONTEXT) ); // prepare to do the encryption // rc = encr_mgr_init( sess, ctx, OP_WRAP, mech, h_wrapping_key ); if (rc != CKR_OK){ st_err_log(98, __FILE__, __LINE__); return rc; } // do the encryption and clean up. at this point, 'value' may or may not // be NULL depending on 'length_only' // rc = encr_mgr_encrypt( sess, length_only, ctx, data, data_len, wrapped_key, wrapped_key_len ); if (data != NULL){ free( data ); } encr_mgr_cleanup( ctx ); free( ctx ); return rc; } // // CK_RV key_mgr_unwrap_key( SESSION * sess, CK_MECHANISM * mech, CK_ATTRIBUTE * attributes, CK_ULONG attrib_count, CK_BYTE * wrapped_key, CK_ULONG wrapped_key_len, CK_OBJECT_HANDLE h_unwrapping_key, CK_OBJECT_HANDLE * h_unwrapped_key ) { ENCR_DECR_CONTEXT * ctx = NULL; OBJECT * key_obj = NULL; CK_BYTE * data = NULL; CK_ULONG data_len; CK_ULONG keyclass, keytype; CK_ULONG i; CK_BBOOL found_class, found_type, fromend; CK_RV rc; if (!sess || !wrapped_key || !h_unwrapped_key){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( h_unwrapping_key, &key_obj ); if (rc != CKR_OK){ st_err_log(62, __FILE__, __LINE__); return CKR_WRAPPING_KEY_HANDLE_INVALID; } found_class = FALSE; found_type = FALSE; // some mechanisms are restricted to wrapping certain types of keys. // in these cases, the CKA_CLASS attribute is implied and isn't required // to be specified in the template (though it still may appear) // switch (mech->mechanism) { case CKM_RSA_PKCS: case CKM_RSA_X_509: keyclass = CKO_SECRET_KEY; found_class = TRUE; break; #if !(NOCMF) case CKM_CDMF_ECB: case CKM_CDMF_CBC: #endif case CKM_DES_ECB: case CKM_DES_CBC: case CKM_DES3_ECB: case CKM_DES3_CBC: case CKM_AES_ECB: case CKM_AES_CBC: keyclass = CKO_SECRET_KEY; found_class = TRUE; break; #if !(NOCMF) case CKM_CDMF_CBC_PAD: #endif case CKM_DES_CBC_PAD: case CKM_DES3_CBC_PAD: case CKM_AES_CBC_PAD: // these mechanisms can wrap any type of key so nothing is implied // break; } // extract key type and key class from the template if they exist. we // have to scan the entire template in case the CKA_CLASS or CKA_KEY_TYPE // attributes are duplicated // for (i=0; i < attrib_count; i++) { switch (attributes[i].type) { case CKA_CLASS: keyclass = *(CK_OBJECT_CLASS *)attributes[i].pValue; found_class = TRUE; break; case CKA_KEY_TYPE: keytype = *(CK_KEY_TYPE *)attributes[i].pValue; found_type = TRUE; break; } } // if we're unwrapping a private key, we can extract the key type from // the BER-encoded information // if (found_class == FALSE || (found_type == FALSE && keyclass != CKO_PRIVATE_KEY)){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } // final check to see if mechanism is allowed to unwrap such a key // switch (mech->mechanism) { case CKM_RSA_PKCS: case CKM_RSA_X_509: if (keyclass != CKO_SECRET_KEY){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } break; #if !(NOCMF) case CKM_CDMF_ECB: case CKM_CDMF_CBC: #endif case CKM_DES_ECB: case CKM_DES_CBC: case CKM_DES3_ECB: case CKM_DES3_CBC: case CKM_AES_ECB: case CKM_AES_CBC: if (keyclass != CKO_SECRET_KEY){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } break; #if !(NOCMF) case CKM_CDMF_CBC_PAD: #endif case CKM_DES_CBC_PAD: case CKM_DES3_CBC_PAD: case CKM_AES_CBC_PAD: break; default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // looks okay...do the decryption // ctx = (ENCR_DECR_CONTEXT *)malloc(sizeof(ENCR_DECR_CONTEXT)); if (!ctx){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx, 0x0, sizeof(ENCR_DECR_CONTEXT) ); rc = decr_mgr_init( sess, ctx, OP_UNWRAP, mech, h_unwrapping_key ); if (rc != CKR_OK) return rc; rc = decr_mgr_decrypt( sess, TRUE, ctx, wrapped_key, wrapped_key_len, data, &data_len ); if (rc != CKR_OK){ st_err_log(100, __FILE__, __LINE__); goto error; } data = (CK_BYTE *)malloc(data_len); if (!data) { st_err_log(0, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto error; } rc = decr_mgr_decrypt( sess, FALSE, ctx, wrapped_key, wrapped_key_len, data, &data_len ); decr_mgr_cleanup( ctx ); free( ctx ); if (rc != CKR_OK){ st_err_log(100, __FILE__, __LINE__); goto error; } // if we use X.509, the data will be padded from the front with zeros. // PKCS #11 specifies that for this mechanism, CK_VALUE is to be read // from the end of the data. // // Note: the PKCS #11 reference implementation gets this wrong. // if (mech->mechanism == CKM_RSA_X_509) fromend = TRUE; else fromend = FALSE; // extract the key type from the PrivateKeyInfo::AlgorithmIndicator // if (keyclass == CKO_PRIVATE_KEY) { rc = key_mgr_get_private_key_type( data, data_len, &keytype ); if (rc != CKR_OK){ st_err_log(101, __FILE__, __LINE__); goto error; } } // we have decrypted the wrapped key data. we also // know what type of key it is. now we need to construct a new key // object... // rc = object_mgr_create_skel( sess, attributes, attrib_count, MODE_UNWRAP, keyclass, keytype, &key_obj ); if (rc != CKR_OK){ st_err_log(89, __FILE__, __LINE__); goto error; } // at this point, 'key_obj' should contain a skeleton key. depending on // the key type. we're now ready to plug in the decrypted key data. // in some cases, the data will be BER-encoded so we'll need to decode it. // // this routine also ensires that CKA_EXTRACTABLE == FALSE, // CKA_ALWAYS_SENSITIVE == FALSE and CKA_LOCAL == FALSE // switch (keyclass) { case CKO_SECRET_KEY: rc = secret_key_unwrap( key_obj->template, keytype, data, data_len, fromend ); break; case CKO_PRIVATE_KEY: rc = priv_key_unwrap( key_obj->template, keytype, data, data_len ); break; default: rc = CKR_WRAPPED_KEY_INVALID; break; } if (rc != CKR_OK){ st_err_log(173, __FILE__, __LINE__); goto error; } // at this point, the key should be fully constructed...assign // an object handle and store the key // rc = object_mgr_create_final( sess, key_obj, h_unwrapped_key ); if (rc != CKR_OK){ st_err_log(90, __FILE__, __LINE__); goto error; } if (data) free(data); return rc; error: if (key_obj) object_free( key_obj ); if (data) free(data); return rc; } CK_RV key_mgr_get_private_key_type( CK_BYTE *keydata, CK_ULONG keylen, CK_KEY_TYPE *keytype ) { CK_BYTE *alg = NULL; CK_BYTE *priv_key = NULL; CK_ULONG alg_len; CK_RV rc; rc = ber_decode_PrivateKeyInfo( keydata, keylen, &alg, &alg_len, &priv_key ); if (rc != CKR_OK){ st_err_log(102, __FILE__, __LINE__); return rc; } // check the entire AlgorithmIdentifier for RSA // if (alg_len >= ber_rsaEncryptionLen) { if (memcmp(alg, ber_rsaEncryption, ber_rsaEncryptionLen) == 0) { *keytype = CKK_RSA; return CKR_OK; } } // Check only the OBJECT IDENTIFIER for DSA // if (alg_len >= ber_idDSALen) { if (memcmp(alg, ber_idDSA, ber_idDSALen) == 0) { *keytype = CKK_DSA; return CKR_OK; } } st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } // // CK_RV key_mgr_derive_key( SESSION * sess, CK_MECHANISM * mech, CK_OBJECT_HANDLE base_key, CK_OBJECT_HANDLE * derived_key, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ) { if (!sess || !mech){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!pTemplate && (ulCount != 0)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } switch (mech->mechanism) { case CKM_SSL3_MASTER_KEY_DERIVE: { if (!derived_key){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } return ssl3_master_key_derive( sess, mech, base_key, pTemplate, ulCount, derived_key ); } break ; case CKM_SSL3_KEY_AND_MAC_DERIVE: { return ssl3_key_and_mac_derive( sess, mech, base_key, pTemplate, ulCount ); } break ; /* Begin code contributed by Corrent corp. */ #ifndef NODH case CKM_DH_PKCS_DERIVE: { if (!derived_key){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } return dh_pkcs_derive( sess, mech, base_key, pTemplate, ulCount, derived_key ); } break ; #endif /* End code contributed by Corrent corp. */ default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/mech_rsa.c0000751000175000017500000015323011327631345020650 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: mech_rsa.c // // Mechanisms for RSA // // Routines contained within: #include #include #include // for memcmp() et al #include #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // in the Shallow token we have the modulus so we can just get it // from that attribute... in the cryptolite token we have to use the // CK_VALUE cheat // This should only be used with private operations CK_ULONG rsa_get_key_len(OBJECT *keyobj) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL flag; flag = template_attribute_find( keyobj->template, CKA_MODULUS, &attr ); if (flag == FALSE) return 0; else return attr->ulValueLen; } CK_RV rsa_format_block( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG mod_len, CK_ULONG type ) { CK_BYTE buf[512]; CK_BYTE rnd_buf[32]; CK_ULONG i, end, tmp; CK_RV rc; if (!in_data || !out_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // temporary storage // memcpy( buf, in_data, in_data_len ); // PKCS Block Formatting: // // EB == 00 | BT | (K - 3 - DATALEN) bytes of PS | 00 | D // // Block Type 1: PS = 0xFF // Block Type 2: PS = Random Data // if (type == PKCS_BT_1) { out_data[0] = 0x0; out_data[1] = 0x1; tmp = mod_len - 3 - in_data_len; memset( &out_data[2], 0xFF, tmp ); tmp += 2; out_data[tmp] = 0x0; tmp++; memcpy( &out_data[tmp], buf, in_data_len ); } else if (type == PKCS_BT_2) { out_data[0] = 0x0; out_data[1] = 0x2; tmp = 2; end = mod_len - 3 - in_data_len; while (end > 0) { rc = rng_generate( rnd_buf, 32 ); if (rc != CKR_OK){ st_err_log(130, __FILE__, __LINE__); return rc; } for (i=0; (i < 32) && (end > 0); i++) { if (rnd_buf[i] != 0) { out_data[ tmp++ ] = rnd_buf[i]; end--; } } } out_data[tmp] = 0x0; tmp++; memcpy( &out_data[tmp], buf, in_data_len ); } return CKR_OK; } // // CK_RV rsa_pkcs_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { OBJECT *key_obj = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE clear[512], cipher[512]; // 4096 bits CK_ULONG modulus_bytes; CK_BBOOL flag; CK_RV rc; rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } flag = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else modulus_bytes = attr->ulValueLen; // check input data length restrictions // if (in_data_len > (modulus_bytes - 11)){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } if (length_only == TRUE) { *out_data_len = modulus_bytes; return CKR_OK; } if (*out_data_len < modulus_bytes) { *out_data_len = modulus_bytes; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } rc = rsa_format_block( in_data, in_data_len, clear, modulus_bytes, PKCS_BT_2 ); if (rc != CKR_OK){ st_err_log(131, __FILE__, __LINE__); return rc; } rc = ckm_rsa_encrypt( clear, modulus_bytes, cipher, key_obj ); if (rc == CKR_OK) { memcpy( out_data, cipher, modulus_bytes ); *out_data_len = modulus_bytes; } else st_err_log(132, __FILE__, __LINE__); return rc; } // // CK_RV rsa_pkcs_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { OBJECT *key_obj = NULL; CK_BYTE out[512]; // 4096 bits CK_ULONG i, modulus_bytes; CK_RV rc; rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } modulus_bytes = rsa_get_key_len(key_obj); // check input data length restrictions // if (in_data_len != modulus_bytes){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } if (length_only == TRUE) { // this is not exact but it's the upper bound; otherwise we'll need // to do the RSA operation just to get the required length // *out_data_len = modulus_bytes - 11; return CKR_OK; } rc = ckm_rsa_decrypt( in_data, modulus_bytes, out, key_obj ); if (rc == CKR_OK) { CK_ULONG len; // strip off the PKCS block formatting data // // 00 | BT | PADDING | 00 | DATA // for (i=2; i < in_data_len; i++) { if (out[i] == 0x0) { i++; // point i at the first data byte break; } } if (i == in_data_len){ st_err_log(14, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_INVALID; } len = in_data_len - i; if (len > *out_data_len) { *out_data_len = len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } memcpy( out_data, &out[i], len ); *out_data_len = len; } else st_err_log(133, __FILE__, __LINE__); if (rc == CKR_DATA_LEN_RANGE){ st_err_log(109, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } return rc; } // // CK_RV rsa_pkcs_sign( SESSION *sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { OBJECT *key_obj = NULL; CK_BYTE data[512], sig[512]; // max size: 512 bytes == 4096 bits CK_ULONG modulus_bytes; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } modulus_bytes = rsa_get_key_len(key_obj); // check input data length restrictions // if (in_data_len > (modulus_bytes - 11)){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } if (length_only == TRUE) { *out_data_len = modulus_bytes; return CKR_OK; } if (*out_data_len < modulus_bytes) { *out_data_len = modulus_bytes; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } rc = rsa_format_block( in_data, in_data_len, data, modulus_bytes, PKCS_BT_1 ); if (rc != CKR_OK){ st_err_log(131, __FILE__, __LINE__); return rc; } // signing is a private key operation --> decrypt // rc = ckm_rsa_decrypt( data, modulus_bytes, sig, key_obj ); if (rc == CKR_OK) { memcpy( out_data, sig, modulus_bytes ); *out_data_len = modulus_bytes; } else st_err_log(133, __FILE__, __LINE__); return rc; } // // CK_RV rsa_pkcs_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ) { OBJECT *key_obj = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE out[512]; // 4096 bits CK_ULONG i, modulus_bytes; CK_BBOOL flag; CK_RV rc; rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } flag = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else modulus_bytes = attr->ulValueLen; // check input data length restrictions // if (sig_len != modulus_bytes){ st_err_log(46, __FILE__, __LINE__); return CKR_SIGNATURE_LEN_RANGE; } // verifying is a public key operation --> encrypt // rc = ckm_rsa_encrypt( signature, modulus_bytes, out, key_obj ); if (rc == CKR_OK) { CK_ULONG len; // skip past the PKCS block formatting data // // 00 | BT | PADDING | 00 | DATA // for (i=2; i < modulus_bytes; i++) { if (out[i] == 0x0) { i++; // point i at the first data byte break; } } len = modulus_bytes - i; if (len != in_data_len){ st_err_log(47, __FILE__, __LINE__); return CKR_SIGNATURE_INVALID; } if (memcmp(in_data, &out[i], len) != 0){ st_err_log(47, __FILE__, __LINE__); return CKR_SIGNATURE_INVALID; } return CKR_OK; } else st_err_log(132, __FILE__, __LINE__); return rc; } // // CK_RV rsa_pkcs_verify_recover( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len, CK_BYTE * out_data, CK_ULONG * out_data_len ) { OBJECT *key_obj = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE out[512]; // 4096 bits CK_ULONG i, modulus_bytes; CK_BBOOL flag; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } flag = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else modulus_bytes = attr->ulValueLen; // check input data length restrictions // if (sig_len != modulus_bytes){ st_err_log(46, __FILE__, __LINE__); return CKR_SIGNATURE_LEN_RANGE; } if (length_only == TRUE) { *out_data_len = modulus_bytes - 11; return CKR_OK; } // verify is a public key operation --> encrypt // rc = ckm_rsa_encrypt( signature, modulus_bytes, out, key_obj ); if (rc == CKR_OK) { CK_ULONG len; // skip past the PKCS block formatting data // // 00 | BT | PADDING | 00 | DATA // for (i=2; i < modulus_bytes; i++) { if (out[i] == 0x0) { i++; // point i at the first data byte break; } } len = modulus_bytes - i; if (*out_data_len < len) { *out_data_len = len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } memcpy( out_data, &out[i], len ); *out_data_len = len; return CKR_OK; } else st_err_log(132, __FILE__, __LINE__); return rc; } // // CK_RV rsa_x509_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { OBJECT *key_obj = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE clear[512], cipher[512]; // max size: 512 bytes == 4096 bits CK_ULONG modulus_bytes; CK_BBOOL flag; CK_RV rc; rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } flag = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else modulus_bytes = attr->ulValueLen; // CKM_RSA_X_509 requires input data length to be no bigger than the modulus // if (in_data_len > modulus_bytes){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } if (length_only == TRUE) { *out_data_len = modulus_bytes; return CKR_OK; } if (*out_data_len < modulus_bytes) { *out_data_len = modulus_bytes; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } // prepad with zeros // memset( clear, 0x0, modulus_bytes - in_data_len); memcpy( &clear[modulus_bytes - in_data_len], in_data, in_data_len ); rc = ckm_rsa_encrypt( clear, modulus_bytes, cipher, key_obj ); if (rc == CKR_OK) { memcpy( out_data, cipher, modulus_bytes ); *out_data_len = modulus_bytes; } else st_err_log(132, __FILE__, __LINE__); return rc; } // // CK_RV rsa_x509_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { OBJECT *key_obj = NULL; CK_BYTE out[512]; // 4096 bits CK_ULONG modulus_bytes; CK_RV rc; rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } #if 0 flag = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); if (flag == FALSE) return CKR_FUNCTION_FAILED; else modulus_bytes = attr->ulValueLen; #else modulus_bytes = rsa_get_key_len(key_obj); #endif // check input data length restrictions // if (in_data_len != modulus_bytes){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } if (length_only == TRUE) { *out_data_len = modulus_bytes; return CKR_OK; } // Although X.509 prepads with zeros, we don't strip it after // decryption (PKCS #11 specifies that X.509 decryption is supposed // to produce K bytes of cleartext where K is the modulus length) // if (*out_data_len < modulus_bytes) { *out_data_len = modulus_bytes; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } rc = ckm_rsa_decrypt( in_data, modulus_bytes, out, key_obj ); if (rc == CKR_OK) { memcpy( out_data, out, modulus_bytes ); *out_data_len = modulus_bytes; } else st_err_log(133, __FILE__, __LINE__); // ckm_rsa_operation is used for all RSA operations so we need to adjust // the return code accordingly // if (rc == CKR_DATA_LEN_RANGE){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } return rc; } // // CK_RV rsa_x509_sign( SESSION *sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { OBJECT *key_obj = NULL; CK_BYTE data[512], sig[512]; // max size: 512 bytes == 4096 bits CK_ULONG modulus_bytes; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } #if 0 flag = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); if (flag == FALSE) return CKR_FUNCTION_FAILED; else modulus_bytes = attr->ulValueLen; #else modulus_bytes = rsa_get_key_len(key_obj); #endif // check input data length restrictions // if (in_data_len > modulus_bytes){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } if (length_only == TRUE) { *out_data_len = modulus_bytes; return CKR_OK; } if (*out_data_len < modulus_bytes) { *out_data_len = modulus_bytes; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } memset( data, 0x0, modulus_bytes - in_data_len ); memcpy( &data[modulus_bytes - in_data_len], in_data, in_data_len ); // signing is a private key operation --> decrypt // rc = ckm_rsa_decrypt( data, modulus_bytes, sig, key_obj ); if (rc == CKR_OK) { memcpy( out_data, sig, modulus_bytes ); *out_data_len = modulus_bytes; } else st_err_log(133, __FILE__, __LINE__); return rc; } // // CK_RV rsa_x509_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ) { OBJECT *key_obj = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE out[512]; // 4096 bits CK_ULONG modulus_bytes; CK_BBOOL flag; CK_RV rc; rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } flag = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else modulus_bytes = attr->ulValueLen; // check input data length restrictions // if (sig_len != modulus_bytes){ st_err_log(46, __FILE__, __LINE__); return CKR_SIGNATURE_LEN_RANGE; } // verify is a public key operation --> encrypt // rc = ckm_rsa_encrypt( signature, modulus_bytes, out, key_obj ); if (rc == CKR_OK) { CK_ULONG pos1, pos2, len; // it should be noted that in_data_len is not necessarily // the same as the modulus length // for (pos1=0; pos1 < in_data_len; pos1++) if (in_data[pos1] != 0) break; for (pos2=0; pos2 < modulus_bytes; pos2++) if (out[pos2] != 0) break; // at this point, pos1 and pos2 point to the first non-zero bytes // in the input data and the decrypted signature (the recovered data), // respectively. // if ((in_data_len - pos1) != (modulus_bytes - pos2)){ st_err_log(47, __FILE__, __LINE__); return CKR_SIGNATURE_INVALID; } len = in_data_len - pos1; if (memcmp(&in_data[pos1], &out[pos2], len) != 0){ st_err_log(47, __FILE__, __LINE__); return CKR_SIGNATURE_INVALID; } return CKR_OK; } else st_err_log(132, __FILE__, __LINE__); return rc; } // // CK_RV rsa_x509_verify_recover( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len, CK_BYTE * out_data, CK_ULONG * out_data_len ) { OBJECT *key_obj = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE out[512]; // 4096 bits CK_ULONG modulus_bytes; CK_BBOOL flag; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } flag = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else modulus_bytes = attr->ulValueLen; // check input data length restrictions // if (sig_len != modulus_bytes){ st_err_log(46, __FILE__, __LINE__); return CKR_SIGNATURE_LEN_RANGE; } if (length_only == TRUE) { *out_data_len = modulus_bytes; return CKR_OK; } // we perform no stripping of prepended zero bytes here // if (*out_data_len < modulus_bytes) { *out_data_len = modulus_bytes; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } // verify is a public key operation --> encrypt // rc = ckm_rsa_encrypt( signature, modulus_bytes, out, key_obj ); if (rc == CKR_OK) { memcpy( out_data, out, modulus_bytes ); *out_data_len = modulus_bytes; return CKR_OK; } else st_err_log(132, __FILE__, __LINE__); return rc; } // // CK_RV rsa_hash_pkcs_sign( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG * sig_len ) { CK_BYTE * ber_data = NULL; CK_BYTE * octet_str = NULL; CK_BYTE * oid = NULL; CK_BYTE * tmp = NULL; CK_ULONG buf1[16]; // 64 bytes is more than enough CK_BYTE hash[SHA1_HASH_SIZE]; // big enough for SHA1, MD5 or MD2 DIGEST_CONTEXT digest_ctx; SIGN_VERIFY_CONTEXT sign_ctx; CK_MECHANISM digest_mech; CK_MECHANISM sign_mech; CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len; CK_RV rc; if (!sess || !ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memset( &digest_ctx, 0x0, sizeof(digest_ctx) ); memset( &sign_ctx, 0x0, sizeof(sign_ctx) ); if (ctx->mech.mechanism == CKM_MD2_RSA_PKCS) { digest_mech.mechanism = CKM_MD2; oid = ber_AlgMd2; oid_len = ber_AlgMd2Len; } else if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) { digest_mech.mechanism = CKM_MD5; oid = ber_AlgMd5; oid_len = ber_AlgMd5Len; } else { digest_mech.mechanism = CKM_SHA_1; oid = ber_AlgSha1; oid_len = ber_AlgSha1Len; } digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } hash_len = sizeof(hash); rc = digest_mgr_digest( sess, length_only, &digest_ctx, in_data, in_data_len, hash, &hash_len ); if (rc != CKR_OK){ st_err_log(124, __FILE__, __LINE__); goto error; } // build the BER-encodings rc = ber_encode_OCTET_STRING( FALSE, &octet_str, &octet_str_len, hash, hash_len ); if (rc != CKR_OK){ st_err_log(77, __FILE__, __LINE__); goto error; } tmp = (CK_BYTE *)buf1; memcpy( tmp, oid, oid_len ); memcpy( tmp + oid_len, octet_str, octet_str_len); rc = ber_encode_SEQUENCE( FALSE, &ber_data, &ber_data_len, tmp, (oid_len + octet_str_len) ); if (rc != CKR_OK){ st_err_log(78, __FILE__, __LINE__); goto error; } // sign the BER-encoded data block sign_mech.mechanism = CKM_RSA_PKCS; sign_mech.ulParameterLen = 0; sign_mech.pParameter = NULL; rc = sign_mgr_init( sess, &sign_ctx, &sign_mech, FALSE, ctx->key ); if (rc != CKR_OK){ st_err_log(127, __FILE__, __LINE__); goto error; } //rc = sign_mgr_sign( sess, length_only, &sign_ctx, hash, hash_len, signature, sig_len ); rc = sign_mgr_sign( sess, length_only, &sign_ctx, ber_data, ber_data_len, signature, sig_len ); if (rc != CKR_OK) st_err_log(128, __FILE__, __LINE__); error: if (octet_str) free( octet_str ); if (ber_data) free( ber_data ); digest_mgr_cleanup( &digest_ctx ); sign_mgr_cleanup( &sign_ctx ); return rc; } // // CK_RV rsa_hash_pkcs_sign_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { RSA_DIGEST_CONTEXT * context = NULL; CK_MECHANISM digest_mech; CK_RV rc; if (!sess || !ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (RSA_DIGEST_CONTEXT *)ctx->context; if (context->flag == FALSE) { if (ctx->mech.mechanism == CKM_MD2_RSA_PKCS) digest_mech.mechanism = CKM_MD2; else if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) digest_mech.mechanism = CKM_MD5; else digest_mech.mechanism = CKM_SHA_1; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &context->hash_context, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } context->flag = TRUE; } rc = digest_mgr_digest_update( sess, &context->hash_context, in_data, in_data_len ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } return CKR_OK; error: digest_mgr_cleanup( &context->hash_context ); return rc; } // // CK_RV rsa_hash_pkcs_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ) { CK_BYTE * ber_data = NULL; CK_BYTE * octet_str = NULL; CK_BYTE * oid = NULL; CK_BYTE * tmp = NULL; CK_ULONG buf1[16]; // 64 bytes is more than enough CK_BYTE hash[SHA1_HASH_SIZE]; DIGEST_CONTEXT digest_ctx; SIGN_VERIFY_CONTEXT verify_ctx; CK_MECHANISM digest_mech; CK_MECHANISM verify_mech; CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len; CK_RV rc; if (!sess || !ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memset( &digest_ctx, 0x0, sizeof(digest_ctx) ); memset( &verify_ctx, 0x0, sizeof(verify_ctx) ); if (ctx->mech.mechanism == CKM_MD2_RSA_PKCS) { digest_mech.mechanism = CKM_MD2; oid = ber_AlgMd2; oid_len = ber_AlgMd2Len; } else if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) { digest_mech.mechanism = CKM_MD5; oid = ber_AlgMd5; oid_len = ber_AlgMd5Len; } else { digest_mech.mechanism = CKM_SHA_1; oid = ber_AlgSha1; oid_len = ber_AlgSha1Len; } digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto done; } hash_len = sizeof(hash); rc = digest_mgr_digest( sess, FALSE, &digest_ctx, in_data, in_data_len, hash, &hash_len ); if (rc != CKR_OK){ st_err_log(124, __FILE__, __LINE__); goto done; } // Build the BER encoding // rc = ber_encode_OCTET_STRING( FALSE, &octet_str, &octet_str_len, hash, hash_len ); if (rc != CKR_OK){ st_err_log(77, __FILE__, __LINE__); goto done; } tmp = (CK_BYTE *)buf1; memcpy( tmp, oid, oid_len ); memcpy( tmp + oid_len, octet_str, octet_str_len ); rc = ber_encode_SEQUENCE( FALSE, &ber_data, &ber_data_len, tmp, (oid_len + octet_str_len) ); if (rc != CKR_OK){ st_err_log(78, __FILE__, __LINE__); goto done; } // Verify the Signed BER-encoded Data block // verify_mech.mechanism = CKM_RSA_PKCS; verify_mech.ulParameterLen = 0; verify_mech.pParameter = NULL; rc = verify_mgr_init( sess, &verify_ctx, &verify_mech, FALSE, ctx->key ); if (rc != CKR_OK){ st_err_log(167, __FILE__, __LINE__); goto done; } //rc = verify_mgr_verify( sess, &verify_ctx, hash, hash_len, signature, sig_len ); rc = verify_mgr_verify( sess, &verify_ctx, ber_data, ber_data_len, signature, sig_len ); if (rc != CKR_OK) st_err_log(168, __FILE__, __LINE__); done: if (octet_str) free( octet_str ); if (ber_data) free( ber_data ); digest_mgr_cleanup( &digest_ctx ); sign_mgr_cleanup( &verify_ctx ); return rc; } // // CK_RV rsa_hash_pkcs_verify_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { RSA_DIGEST_CONTEXT * context = NULL; CK_MECHANISM digest_mech; CK_RV rc; if (!sess || !ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (RSA_DIGEST_CONTEXT *)ctx->context; if (context->flag == FALSE) { if (ctx->mech.mechanism == CKM_MD2_RSA_PKCS) digest_mech.mechanism = CKM_MD2; else if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) digest_mech.mechanism = CKM_MD5; else digest_mech.mechanism = CKM_SHA_1; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &context->hash_context, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } context->flag = TRUE; } rc = digest_mgr_digest_update( sess, &context->hash_context, in_data, in_data_len ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } return CKR_OK; error: digest_mgr_cleanup( &context->hash_context ); return rc; } // // CK_RV rsa_hash_pkcs_sign_final( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG * sig_len ) { CK_BYTE * ber_data = NULL; CK_BYTE * octet_str = NULL; CK_BYTE * oid = NULL; CK_BYTE * tmp = NULL; CK_ULONG buf1[16]; // 64 bytes is more than enough CK_BYTE hash[SHA1_HASH_SIZE]; RSA_DIGEST_CONTEXT * context = NULL; CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len; CK_MECHANISM sign_mech; SIGN_VERIFY_CONTEXT sign_ctx; CK_RV rc; if (!sess || !ctx || !sig_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_MD2_RSA_PKCS) { oid = ber_AlgMd2; oid_len = ber_AlgMd2Len; } else if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) { oid = ber_AlgMd5; oid_len = ber_AlgMd5Len; } else { oid = ber_AlgSha1; oid_len = ber_AlgSha1Len; } memset( &sign_ctx, 0x0, sizeof(sign_ctx)); context = (RSA_DIGEST_CONTEXT *)ctx->context; hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, length_only, &context->hash_context, hash, &hash_len ); if (rc != CKR_OK){ st_err_log(126, __FILE__, __LINE__); goto done; } // Build the BER Encoded Data block // rc = ber_encode_OCTET_STRING( FALSE, &octet_str, &octet_str_len, hash, hash_len ); if (rc != CKR_OK){ st_err_log(77, __FILE__, __LINE__); goto done; } tmp = (CK_BYTE *)buf1; memcpy( tmp, oid, oid_len ); memcpy( tmp + oid_len, octet_str, octet_str_len ); rc = ber_encode_SEQUENCE( FALSE, &ber_data, &ber_data_len, tmp, (oid_len + octet_str_len) ); if (rc != CKR_OK){ st_err_log(78, __FILE__, __LINE__); goto done; } // sign the BER-encoded data block // sign_mech.mechanism = CKM_RSA_PKCS; sign_mech.ulParameterLen = 0; sign_mech.pParameter = NULL; rc = sign_mgr_init( sess, &sign_ctx, &sign_mech, FALSE, ctx->key ); if (rc != CKR_OK){ st_err_log(127, __FILE__, __LINE__); goto done; } //rc = sign_mgr_sign( sess, length_only, &sign_ctx, hash, hash_len, signature, sig_len ); rc = sign_mgr_sign( sess, length_only, &sign_ctx, ber_data, ber_data_len, signature, sig_len ); if (rc != CKR_OK) st_err_log(128, __FILE__, __LINE__); if (length_only == TRUE || rc == CKR_BUFFER_TOO_SMALL) { sign_mgr_cleanup( &sign_ctx ); return rc; } done: if (octet_str) free( octet_str ); if (ber_data) free( ber_data ); digest_mgr_cleanup( &context->hash_context ); sign_mgr_cleanup( &sign_ctx ); return rc; } // // CK_RV rsa_hash_pkcs_verify_final( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len ) { CK_BYTE * ber_data = NULL; CK_BYTE * octet_str = NULL; CK_BYTE * oid = NULL; CK_BYTE * tmp = NULL; CK_ULONG buf1[16]; // 64 bytes is more than enough CK_BYTE hash[SHA1_HASH_SIZE]; RSA_DIGEST_CONTEXT * context = NULL; CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len; CK_MECHANISM verify_mech; SIGN_VERIFY_CONTEXT verify_ctx; CK_RV rc; if (!sess || !ctx || !signature){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_MD2_RSA_PKCS) { oid = ber_AlgMd2; oid_len = ber_AlgMd2Len; } else if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) { oid = ber_AlgMd5; oid_len = ber_AlgMd5Len; } else { oid = ber_AlgSha1; oid_len = ber_AlgSha1Len; } memset( &verify_ctx, 0x0, sizeof(verify_ctx)); context = (RSA_DIGEST_CONTEXT *)ctx->context; hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &context->hash_context, hash, &hash_len ); if (rc != CKR_OK){ st_err_log(126, __FILE__, __LINE__); goto done; } // Build the BER encoding // rc = ber_encode_OCTET_STRING( FALSE, &octet_str, &octet_str_len, hash, hash_len ); if (rc != CKR_OK){ st_err_log(77, __FILE__, __LINE__); goto done; } tmp = (CK_BYTE *)buf1; memcpy( tmp, oid, oid_len ); memcpy( tmp + oid_len, octet_str, octet_str_len ); rc = ber_encode_SEQUENCE( FALSE, &ber_data, &ber_data_len, tmp, (oid_len + octet_str_len) ); if (rc != CKR_OK){ st_err_log(78, __FILE__, __LINE__); goto done; } // verify the signed BER-encoded data block // verify_mech.mechanism = CKM_RSA_PKCS; verify_mech.ulParameterLen = 0; verify_mech.pParameter = NULL; rc = verify_mgr_init( sess, &verify_ctx, &verify_mech, FALSE, ctx->key ); if (rc != CKR_OK){ st_err_log(167, __FILE__, __LINE__); goto done; } //rc = verify_mgr_verify( sess, &verify_ctx, hash, hash_len, signature, sig_len ); rc = verify_mgr_verify( sess, &verify_ctx, ber_data, ber_data_len, signature, sig_len ); if (rc != CKR_OK) st_err_log(168, __FILE__, __LINE__); done: if (octet_str) free( octet_str ); if (ber_data) free( ber_data ); digest_mgr_cleanup( &context->hash_context ); verify_mgr_cleanup( &verify_ctx ); return rc; } // // mechanisms // // // CK_RV ckm_rsa_key_pair_gen( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ) { CK_ATTRIBUTE * publ_exp = NULL; CK_ATTRIBUTE * attr = NULL; CK_ULONG mod_bits; CK_BBOOL flag; CK_RV rc; flag = template_attribute_find( publ_tmpl, CKA_MODULUS_BITS, &attr ); if (!flag){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; // should never happen } mod_bits = *(CK_ULONG *)attr->pValue; flag = template_attribute_find( publ_tmpl, CKA_PUBLIC_EXPONENT, &publ_exp ); if (!flag){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } // Really want to FIXME to not instantiate the attributes in each token // specific routine. Should return the pieces and instantiate the attributes // once.... SAB.. rc = token_specific.t_rsa_generate_keypair(publ_tmpl, priv_tmpl); if (rc != CKR_OK) st_err_log(91, __FILE__, __LINE__); return rc; } // // CK_RV ckm_rsa_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, OBJECT * key_obj ) { CK_ATTRIBUTE * attr = NULL; CK_OBJECT_CLASS keyclass; CK_RV rc; rc = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else keyclass = *(CK_OBJECT_CLASS *)attr->pValue; // this had better be a public key // if (keyclass != CKO_PUBLIC_KEY){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_rsa_encrypt(in_data,in_data_len,out_data,key_obj); if (rc != CKR_OK) st_err_log(134, __FILE__, __LINE__); return rc; } // // CK_RV ckm_rsa_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, OBJECT * key_obj ) { CK_ATTRIBUTE * attr = NULL; CK_OBJECT_CLASS keyclass; CK_RV rc; rc = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else keyclass = *(CK_OBJECT_CLASS *)attr->pValue; // this had better be a private key // if (keyclass != CKO_PRIVATE_KEY){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_rsa_decrypt(in_data,in_data_len,out_data,key_obj); if (rc != CKR_OK) st_err_log(135, __FILE__, __LINE__); return rc; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/mech_ssl3.c0000751000175000017500000023157511327631345020760 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: mech_ssl3.c // // Mechanisms for SSL v3 support // #include #include // for memcmp() et al #include #include #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" extern FILE *debugfile; extern char *debugfilepathbuffer; CK_RV ssl3_kmd_process_mac_keys( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE * client_handle, CK_BYTE * client_value, CK_OBJECT_HANDLE * server_handle, CK_BYTE * server_value, CK_ULONG mac_len ); CK_RV ssl3_kmd_process_write_keys( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_KEY_TYPE keytype, CK_OBJECT_HANDLE * client_handle, CK_BYTE * client_value, CK_OBJECT_HANDLE * server_handle, CK_BYTE * server_value, CK_ULONG write_len ); // The 'ssl3_mac_*' routines are used with the following mechanisms // // CKM_SSL3_MD5_MAC // CKM_SSL3_SHA1_MAC // // // CK_RV ssl3_mac_sign( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE hash[SHA1_HASH_SIZE]; CK_BYTE * key_data = NULL; CK_BYTE inner[48], outer[48]; DIGEST_CONTEXT digest_ctx; CK_MECHANISM digest_mech; CK_ULONG key_bytes, hash_len, mac_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } mac_len = *(CK_ULONG *)ctx->mech.pParameter; if (length_only == TRUE) { *out_data_len = mac_len; return CKR_OK; } if (*out_data_len < mac_len) { *out_data_len = mac_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key_obj->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else { key_bytes = attr->ulValueLen; key_data = attr->pValue; } // unlike an HMAC operation, we don't XOR the key with the 0x36 or 0x5C. // we just append 48 bytes to the key data // memset( inner, 0x36, 48 ); memset( outer, 0x5C, 48 ); if (ctx->mech.mechanism == CKM_SSL3_MD5_MAC) digest_mech.mechanism = CKM_MD5; else digest_mech.mechanism = CKM_SHA_1; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; // inner hash // rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } rc = digest_mgr_digest_update( sess, &digest_ctx, key_data, key_bytes ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } if (ctx->mech.mechanism == CKM_SSL3_MD5_MAC){ rc = digest_mgr_digest_update( sess, &digest_ctx, inner, 48 ); } else { rc = digest_mgr_digest_update( sess, &digest_ctx, inner, 40 ); } if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } rc = digest_mgr_digest_update( sess, &digest_ctx, in_data, in_data_len ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &hash_len ); if (rc != CKR_OK){ st_err_log(126, __FILE__, __LINE__); goto error; } digest_mgr_cleanup( &digest_ctx ); memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); // outer hash // rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } rc = digest_mgr_digest_update( sess, &digest_ctx, key_data, key_bytes ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } if (ctx->mech.mechanism == CKM_SSL3_MD5_MAC) rc = digest_mgr_digest_update( sess, &digest_ctx, outer, 48 ); else rc = digest_mgr_digest_update( sess, &digest_ctx, outer, 40 ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } rc = digest_mgr_digest_update( sess, &digest_ctx, hash, hash_len ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &hash_len ); if (rc != CKR_OK){ st_err_log(126, __FILE__, __LINE__); goto error; } memcpy( out_data, hash, mac_len ); *out_data_len = mac_len; error: digest_mgr_cleanup( &digest_ctx ); return rc; } // // CK_RV ssl3_mac_sign_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * key_data = NULL; SSL3_MAC_CONTEXT * context = NULL; CK_BYTE inner[48]; CK_MECHANISM digest_mech; CK_ULONG key_bytes; CK_RV rc; if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (SSL3_MAC_CONTEXT *)ctx->context; if (context->flag == FALSE) { rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); goto error; } rc = template_attribute_find( key_obj->template, CKA_VALUE, &attr ); if (rc == FALSE) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } else { key_bytes = attr->ulValueLen; key_data = attr->pValue; } // unlike an HMAC operation, we don't XOR the key with the 0x36 or 0x5C. // we just append 48 bytes to the key data // memset( inner, 0x36, 48 ); if (ctx->mech.mechanism == CKM_SSL3_MD5_MAC) digest_mech.mechanism = CKM_MD5; else digest_mech.mechanism = CKM_SHA_1; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; // inner hash // rc = digest_mgr_init( sess, &context->hash_context, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } rc = digest_mgr_digest_update( sess, &context->hash_context, key_data, key_bytes ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } if (ctx->mech.mechanism == CKM_SSL3_MD5_MAC) rc = digest_mgr_digest_update( sess, &context->hash_context, inner, 48 ); else rc = digest_mgr_digest_update( sess, &context->hash_context, inner, 40 ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } context->flag = TRUE; } rc = digest_mgr_digest_update( sess, &context->hash_context, in_data, in_data_len ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } return CKR_OK; error: digest_mgr_cleanup( &context->hash_context ); return rc; } // // CK_RV ssl3_mac_sign_final( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * key_data = NULL; CK_BYTE hash[SHA1_HASH_SIZE]; SSL3_MAC_CONTEXT * context = NULL; CK_BYTE outer[48]; CK_MECHANISM digest_mech; CK_ULONG key_bytes, hash_len, mac_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } mac_len = *(CK_ULONG *)ctx->mech.pParameter; if (length_only == TRUE) { *out_data_len = mac_len; return CKR_OK; } if (*out_data_len < mac_len) { *out_data_len = mac_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } context = (SSL3_MAC_CONTEXT *)ctx->context; rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); goto error; } rc = template_attribute_find( key_obj->template, CKA_VALUE, &attr ); if (rc == FALSE) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } else { key_bytes = attr->ulValueLen; key_data = attr->pValue; } // finish the inner hash // hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &context->hash_context, hash, &hash_len ); if (rc != CKR_OK){ st_err_log(126, __FILE__, __LINE__); goto error; } // now, do the outer hash // digest_mgr_cleanup( &context->hash_context ); memset( &context->hash_context, 0x0, sizeof(SSL3_MAC_CONTEXT) ); memset( outer, 0x5C, 48 ); if (ctx->mech.mechanism == CKM_SSL3_MD5_MAC) digest_mech.mechanism = CKM_MD5; else digest_mech.mechanism = CKM_SHA_1; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &context->hash_context, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } rc = digest_mgr_digest_update( sess, &context->hash_context, key_data, key_bytes ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } if (ctx->mech.mechanism == CKM_SSL3_MD5_MAC) rc = digest_mgr_digest_update( sess, &context->hash_context, outer, 48 ); else rc = digest_mgr_digest_update( sess, &context->hash_context, outer, 40 ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } rc = digest_mgr_digest_update( sess, &context->hash_context, hash, hash_len ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &context->hash_context, hash, &hash_len ); if (rc != CKR_OK){ st_err_log(126, __FILE__, __LINE__); goto error; } memcpy( out_data, hash, mac_len ); *out_data_len = mac_len; error: digest_mgr_cleanup( &context->hash_context ); return rc; } // This routine could replace the HMAC verification routines // CK_RV ssl3_mac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ) { CK_BYTE mac[SHA1_HASH_SIZE]; SIGN_VERIFY_CONTEXT mac_ctx; CK_ULONG mac_len, len; CK_RV rc; if (!sess || !ctx || !in_data || !signature){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } mac_len = *(CK_ULONG *)ctx->mech.pParameter; memset( &mac_ctx, 0, sizeof(SIGN_VERIFY_CONTEXT) ); rc = sign_mgr_init( sess, &mac_ctx, &ctx->mech, FALSE, ctx->key ); if (rc != CKR_OK){ st_err_log(127, __FILE__, __LINE__); goto error; } len = sizeof(mac); rc = sign_mgr_sign( sess, FALSE, &mac_ctx, in_data, in_data_len, mac, &len ); if (rc != CKR_OK){ st_err_log(128, __FILE__, __LINE__); goto error; } if ((len != mac_len) || (len != sig_len)) { rc = CKR_SIGNATURE_LEN_RANGE; st_err_log(46, __FILE__, __LINE__); goto error; } if (memcmp(mac, signature, mac_len) != 0){ st_err_log(47, __FILE__, __LINE__); rc = CKR_SIGNATURE_INVALID; } error: sign_mgr_cleanup( &mac_ctx ); return rc; } // // CK_RV ssl3_mac_verify_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * key_data = NULL; SSL3_MAC_CONTEXT * context = NULL; CK_BYTE inner[48]; CK_MECHANISM digest_mech; CK_ULONG key_bytes; CK_RV rc; if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (SSL3_MAC_CONTEXT *)ctx->context; if (context->flag == FALSE) { rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); goto error; } rc = template_attribute_find( key_obj->template, CKA_VALUE, &attr ); if (rc == FALSE) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } else { key_bytes = attr->ulValueLen; key_data = attr->pValue; } // unlike an HMAC operation, we don't XOR the key with the 0x36 or 0x5C. // we just append 48 bytes to the key data // memset( inner, 0x36, 48 ); if (ctx->mech.mechanism == CKM_SSL3_MD5_MAC) digest_mech.mechanism = CKM_MD5; else digest_mech.mechanism = CKM_SHA_1; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; // inner hash // rc = digest_mgr_init( sess, &context->hash_context, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } rc = digest_mgr_digest_update( sess, &context->hash_context, key_data, key_bytes ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } if (ctx->mech.mechanism == CKM_SSL3_MD5_MAC) rc = digest_mgr_digest_update( sess, &context->hash_context, inner, 48 ); else rc = digest_mgr_digest_update( sess, &context->hash_context, inner, 40 ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } context->flag = TRUE; } rc = digest_mgr_digest_update( sess, &context->hash_context, in_data, in_data_len ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } return CKR_OK; error: digest_mgr_cleanup( &context->hash_context ); return rc; } // // CK_RV ssl3_mac_verify_final( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * key_data = NULL; SSL3_MAC_CONTEXT * context = NULL; CK_BYTE hash[SHA1_HASH_SIZE]; CK_BYTE outer[48]; CK_MECHANISM digest_mech; CK_ULONG key_bytes, hash_len, mac_len; CK_RV rc; if (!sess || !ctx || !signature){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } mac_len = *(CK_ULONG *)ctx->mech.pParameter; context = (SSL3_MAC_CONTEXT *)ctx->context; rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); goto error; } rc = template_attribute_find( key_obj->template, CKA_VALUE, &attr ); if (rc == FALSE) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } else { key_bytes = attr->ulValueLen; key_data = attr->pValue; } // finish the inner hash // hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &context->hash_context, hash, &hash_len ); if (rc != CKR_OK){ st_err_log(126, __FILE__, __LINE__); goto error; } // now, do the outer hash // digest_mgr_cleanup( &context->hash_context ); memset( &context->hash_context, 0x0, sizeof(SSL3_MAC_CONTEXT) ); memset( outer, 0x5C, 48 ); if (ctx->mech.mechanism == CKM_SSL3_MD5_MAC) digest_mech.mechanism = CKM_MD5; else digest_mech.mechanism = CKM_SHA_1; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &context->hash_context, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } rc = digest_mgr_digest_update( sess, &context->hash_context, key_data, key_bytes ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } if (ctx->mech.mechanism == CKM_SSL3_MD5_MAC) rc = digest_mgr_digest_update( sess, &context->hash_context, outer, 48 ); else rc = digest_mgr_digest_update( sess, &context->hash_context, outer, 40 ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } rc = digest_mgr_digest_update( sess, &context->hash_context, hash, hash_len ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &context->hash_context, hash, &hash_len ); if (rc != CKR_OK){ st_err_log(126, __FILE__, __LINE__); goto error; } if ((mac_len != sig_len) || (mac_len > hash_len)){ st_err_log(47, __FILE__, __LINE__); rc = CKR_SIGNATURE_INVALID; } else if (memcmp(signature, hash, sig_len) != 0){ rc = CKR_SIGNATURE_INVALID; st_err_log(47, __FILE__, __LINE__); } error: digest_mgr_cleanup( &context->hash_context ); return rc; } // // CK_RV ckm_ssl3_pre_master_key_gen( TEMPLATE * tmpl, CK_MECHANISM * mech ) { CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * value_len_attr = NULL; CK_ATTRIBUTE * key_type_attr = NULL; CK_ATTRIBUTE * class_attr = NULL; CK_ATTRIBUTE * local_attr = NULL; CK_ATTRIBUTE * derive_attr = NULL; CK_VERSION * version = NULL; CK_BYTE key[48]; CK_ULONG rc; rc = rng_generate( key, 48 ); if (rc != CKR_OK){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } value_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + 48 ); value_len_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); key_type_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); class_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS) ); local_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); derive_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!value_attr || !value_len_attr || !key_type_attr || !class_attr || !local_attr || !derive_attr) { if (value_attr) free( value_attr ); if (value_len_attr) free( value_len_attr ); if (key_type_attr) free( key_type_attr ); if (class_attr) free( class_attr ); if (local_attr) free( local_attr ); if (derive_attr) free( derive_attr ); st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } version = (CK_VERSION *)mech->pParameter; key[0] = version->major; key[1] = version->minor; value_attr->type = CKA_VALUE; value_attr->ulValueLen = 48; value_attr->pValue = (CK_BYTE *)value_attr + sizeof(CK_ATTRIBUTE); memcpy( value_attr->pValue, key, 48 ); value_len_attr->type = CKA_VALUE_LEN; value_len_attr->ulValueLen = sizeof(CK_ULONG); value_len_attr->pValue = (CK_BYTE *)value_len_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_len_attr->pValue = 48; key_type_attr->type = CKA_KEY_TYPE; key_type_attr->ulValueLen = sizeof(CK_KEY_TYPE); key_type_attr->pValue = (CK_BYTE *)key_type_attr + sizeof(CK_ATTRIBUTE); *(CK_ATTRIBUTE_TYPE *)key_type_attr = CKK_GENERIC_SECRET; class_attr->type = CKA_CLASS; class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS); class_attr->pValue = (CK_BYTE *)class_attr + sizeof(CK_ATTRIBUTE); *(CK_OBJECT_CLASS *)class_attr->pValue = CKO_SECRET_KEY; local_attr->type = CKA_LOCAL; local_attr->ulValueLen = sizeof(CK_BBOOL); local_attr->pValue = (CK_BYTE *)local_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)local_attr->pValue = TRUE; derive_attr->type = CKA_DERIVE; derive_attr->ulValueLen = sizeof(CK_BBOOL); derive_attr->pValue = (CK_BYTE *)derive_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)derive_attr->pValue = TRUE; template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, value_len_attr ); template_update_attribute( tmpl, key_type_attr ); template_update_attribute( tmpl, class_attr ); template_update_attribute( tmpl, local_attr ); template_update_attribute( tmpl, derive_attr ); return CKR_OK; } // // static CK_RV ssl3_sha_then_md5( SESSION * sess, CK_BYTE * secret, CK_BYTE * firstRandom, CK_ULONG firstRandomLen, CK_BYTE * secondRandom, CK_ULONG secondRandomLen, CK_BYTE * variableData, CK_ULONG variableDataLen, CK_BYTE * outBuff ) { DIGEST_CONTEXT digest_ctx; CK_MECHANISM digest_mech; CK_BYTE hash[SHA1_HASH_SIZE]; CK_ULONG len; CK_RV rc; // SHA(variableData + secret + firstRandom + secondRandom) // memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); digest_mech.mechanism = CKM_SHA_1; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } rc = digest_mgr_digest_update( sess, &digest_ctx, variableData, variableDataLen ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } rc = digest_mgr_digest_update( sess, &digest_ctx, secret, 48 ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } rc = digest_mgr_digest_update( sess, &digest_ctx, firstRandom, firstRandomLen ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } rc = digest_mgr_digest_update( sess, &digest_ctx, secondRandom, secondRandomLen ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &len ); if (rc != CKR_OK){ st_err_log(126, __FILE__, __LINE__); goto error; } digest_mgr_cleanup( &digest_ctx ); // MD5(secret + SHA(...)) // memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); digest_mech.mechanism = CKM_MD5; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } rc = digest_mgr_digest_update( sess, &digest_ctx, secret, 48 ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } rc = digest_mgr_digest_update( sess, &digest_ctx, hash, len ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &len ); if (rc == CKR_OK){ memcpy( outBuff, hash, len ); } else st_err_log(126, __FILE__, __LINE__); error: digest_mgr_cleanup( &digest_ctx ); return rc; } // // static CK_RV ssl3_md5_only( SESSION * sess, CK_BYTE * firstString, CK_ULONG firstStringLen, CK_BYTE * secondString, CK_ULONG secondStringLen, CK_BYTE * thirdString, CK_ULONG thirdStringLen, CK_BYTE * outBuff ) { DIGEST_CONTEXT digest_ctx; CK_MECHANISM digest_mech; CK_BYTE hash[MD5_HASH_SIZE]; CK_ULONG len; CK_RV rc; // If firstString is not NULL, // // MD5(firstString + secondString + thirdString) // // If firstString is NULL // // MD5(secondString + thirdString) // memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); digest_mech.mechanism = CKM_MD5; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } if (firstString != NULL) { rc = digest_mgr_digest_update( sess, &digest_ctx, firstString, firstStringLen ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } } rc = digest_mgr_digest_update( sess, &digest_ctx, secondString, secondStringLen ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } rc = digest_mgr_digest_update( sess, &digest_ctx, thirdString, thirdStringLen ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &len ); if (rc == CKR_OK){ st_err_log(126, __FILE__, __LINE__); memcpy( outBuff, hash, len ); } error: digest_mgr_cleanup( &digest_ctx ); return rc; } // // CK_RV ssl3_master_key_derive( SESSION * sess, CK_MECHANISM * mech, CK_OBJECT_HANDLE base_key, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE * handle ) { OBJECT * derived_key_obj = NULL; OBJECT * base_key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * value_len_attr = NULL; CK_ATTRIBUTE * always_sens_attr = NULL; CK_ATTRIBUTE * extract_attr = NULL; CK_BYTE * base_key_value = NULL; CK_BYTE key_data[48]; CK_ULONG i, base_key_len; CK_BBOOL flag; CK_RV rc; CK_SSL3_MASTER_KEY_DERIVE_PARAMS * params = NULL; CK_SSL3_RANDOM_DATA * random_data = NULL; if (!sess || !mech){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } params = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *)mech->pParameter; rc = object_mgr_find_in_map1( base_key, &base_key_obj ); if (rc != CKR_OK){ st_err_log(18, __FILE__, __LINE__); return CKR_KEY_HANDLE_INVALID; } rc = template_attribute_find( base_key_obj->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else { base_key_len = attr->ulValueLen; base_key_value = attr->pValue; if (base_key_len != 48){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } // this mechanism implies the following attributes: // CKA_CLASS : CKO_SECRET_KEY // CKA_KEY_TYPE : CKK_GENERIC_SECRET // CKA_VALUE_LEN : 48 // but we need to make sure the caller didn't specify any // wacky values. it would have been better if Cryptoki had forbidden // these attributes from appearing in the template // for (i=0, attr = pTemplate; i < ulCount; i++, attr++) { CK_OBJECT_CLASS class; CK_KEY_TYPE keytype; CK_ULONG value_len; if (attr->type == CKA_CLASS) { class = *(CK_OBJECT_CLASS *)attr->pValue; if (class != CKO_SECRET_KEY){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } else if (attr->type == CKA_KEY_TYPE) { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_GENERIC_SECRET){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } else if (attr->type == CKA_VALUE_LEN) { value_len = *(CK_ULONG *)attr->pValue; if (value_len != 48){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } } memset( key_data, 0x0, sizeof(key_data) ); random_data = (CK_SSL3_RANDOM_DATA *)(¶ms->RandomInfo); // derive the master key data // rc = ssl3_sha_then_md5( sess, base_key_value, random_data->pClientRandom, random_data->ulClientRandomLen, random_data->pServerRandom, random_data->ulServerRandomLen, (unsigned char *)"A", 1, key_data ); if (rc != CKR_OK){ st_err_log(136, __FILE__, __LINE__); goto error; } rc = ssl3_sha_then_md5( sess, base_key_value, random_data->pClientRandom, random_data->ulClientRandomLen, random_data->pServerRandom, random_data->ulServerRandomLen, (unsigned char *)"BB", 2, &key_data[16] ); if (rc != CKR_OK){ st_err_log(136, __FILE__, __LINE__); goto error; } rc = ssl3_sha_then_md5( sess, base_key_value, random_data->pClientRandom, random_data->ulClientRandomLen, random_data->pServerRandom, random_data->ulServerRandomLen, (unsigned char *)"CCC", 3, &key_data[32] ); if (rc != CKR_OK){ st_err_log(136, __FILE__, __LINE__); goto error; } // build the key skeleton // rc = object_mgr_create_skel( sess, pTemplate, ulCount, MODE_DERIVE, CKO_SECRET_KEY, CKK_GENERIC_SECRET, &derived_key_obj ); if (rc != CKR_OK){ st_err_log(89, __FILE__, __LINE__); goto error; } rc = build_attribute( CKA_VALUE, key_data, 48, &value_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } rc = build_attribute( CKA_VALUE_LEN, (CK_BYTE *)&base_key_len, sizeof(CK_ULONG), &value_len_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } // // now, adjust the CKA_ALWAYS_SENSITIVE and CKA_NEVER_EXTRACTABLE // attributes based on the corresponding values from the base key // // if base key has ALWAYS_SENSITIVE = FALSE, then new key does too // otherwise, the value of CKA_ALWAYS_SENSITIVE = CKA_SENSITIVE // rc = template_attribute_find( base_key_obj->template, CKA_ALWAYS_SENSITIVE, &attr ); if (rc == FALSE) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } flag = *(CK_BBOOL *)attr->pValue; if (flag == TRUE) { rc = template_attribute_find( derived_key_obj->template, CKA_SENSITIVE, &attr ); if (rc == FALSE) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } flag = *(CK_BBOOL *)attr->pValue; } rc = build_attribute( CKA_ALWAYS_SENSITIVE, &flag, sizeof(CK_BBOOL), &always_sens_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } // if base key has NEVER_EXTRACTABLE = FASE, the new key does too // otherwise, the value of CKA_NEVER_EXTRACTABLE = !CKA_EXTRACTABLE // rc = template_attribute_find( base_key_obj->template, CKA_NEVER_EXTRACTABLE, &attr ); if (rc == FALSE) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } flag = *(CK_BBOOL *)attr->pValue; if (flag == TRUE) { rc = template_attribute_find( derived_key_obj->template, CKA_EXTRACTABLE, &attr ); if (rc == FALSE) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } flag = *(CK_BBOOL *)attr->pValue; flag = (~flag) & 0x1; } rc = build_attribute( CKA_NEVER_EXTRACTABLE, &flag, sizeof(CK_BBOOL), &extract_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } template_update_attribute( derived_key_obj->template, value_attr ); template_update_attribute( derived_key_obj->template, value_len_attr ); template_update_attribute( derived_key_obj->template, always_sens_attr ); template_update_attribute( derived_key_obj->template, extract_attr ); // at this point, the derived key is fully constructed...assign an // object handle and store the key // rc = object_mgr_create_final( sess, derived_key_obj, handle ); if (rc != CKR_OK) { st_err_log(90, __FILE__, __LINE__); object_free( derived_key_obj ); return rc; // do NOT goto error } // should we destroy the base key? SSL3 says yes but that might // occur in a separate call to C_DestroyObject // return CKR_OK; error: if (value_attr) free( value_attr ); if (value_len_attr) free( value_len_attr ); if (always_sens_attr) free( always_sens_attr ); if (extract_attr) free( extract_attr ); return rc; } // // CK_RV ssl3_key_and_mac_derive( SESSION * sess, CK_MECHANISM * mech, CK_OBJECT_HANDLE base_key, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ) { OBJECT * base_key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * client_MAC_key_value = NULL; CK_BYTE * server_MAC_key_value = NULL; CK_BYTE * client_write_key_value = NULL; CK_BYTE * server_write_key_value = NULL; CK_BYTE * client_IV = NULL; CK_BYTE * server_IV = NULL; CK_KEY_TYPE keytype = 0xFFFFFFFF; CK_BYTE variable_data[26]; CK_BYTE key_block[(16*26) + (4*16)]; CK_ULONG i, key_material_loop_count; CK_ULONG iv_len = 0, MAC_len, write_len; CK_RV rc; CK_BYTE * base_key_value = NULL; CK_BBOOL base_sensitive; CK_BBOOL base_always_sensitive; CK_BBOOL base_extractable; CK_BBOOL base_never_extractable; CK_OBJECT_HANDLE client_MAC_handle = 0; CK_OBJECT_HANDLE server_MAC_handle = 0; CK_OBJECT_HANDLE client_write_handle = 0; CK_OBJECT_HANDLE server_write_handle = 0; CK_SSL3_KEY_MAT_PARAMS * params = NULL; ATTRIBUTE_PARSE_LIST base_attrs[] = { {CKA_SENSITIVE , &base_sensitive , sizeof(CK_BBOOL), FALSE}, {CKA_EXTRACTABLE , &base_extractable , sizeof(CK_BBOOL), FALSE}, {CKA_ALWAYS_SENSITIVE , &base_always_sensitive , sizeof(CK_BBOOL), FALSE}, {CKA_NEVER_EXTRACTABLE, &base_never_extractable, sizeof(CK_BBOOL), FALSE}, }; if (!sess || !mech){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } params = (CK_SSL3_KEY_MAT_PARAMS *)mech->pParameter; rc = object_mgr_find_in_map1( base_key, &base_key_obj ); if (rc != CKR_OK){ st_err_log(18, __FILE__, __LINE__); return CKR_KEY_HANDLE_INVALID; } rc = template_attribute_find( base_key_obj->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else base_key_value = attr->pValue; template_attribute_find_multiple( base_key_obj->template, base_attrs, 4 ); for (i=0; i < 4; i++) { if (base_attrs[i].found == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } // The SSL3 spec says the IVs are 16 bytes long in the exportable case. // For now, we'll barf if someone asks for an exportable output and asks // for more than 128 bits of IV... // if (params->bIsExport != FALSE && params->ulIVSizeInBits > 128){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // the template must specify the key type for the client and server keys // // also, CKA_SENSITIVE, CKA_ALWAYS_SENSITIVE, CKA_EXTRACTABLE and // CKA_NEVER_EXTRACTABLE, if present, are not allowed to differ from // the base key. We also check for stupid stuff. // for (i=0, attr = pTemplate; i < ulCount; i++, attr++) { CK_BBOOL tmp; if (attr->type == CKA_KEY_TYPE) keytype = *(CK_KEY_TYPE *)attr->pValue; else if (attr->type == CKA_SENSITIVE) { tmp = *(CK_BBOOL *)attr->pValue; if (tmp != base_sensitive){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } else if (attr->type == CKA_ALWAYS_SENSITIVE) { tmp = *(CK_BBOOL *)attr->pValue; if (tmp != base_always_sensitive){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } else if (attr->type == CKA_EXTRACTABLE) { tmp = *(CK_BBOOL *)attr->pValue; if (tmp != base_extractable){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } else if (attr->type == CKA_NEVER_EXTRACTABLE) { tmp = *(CK_BBOOL *)attr->pValue; if (tmp != base_never_extractable){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } else if (attr->type == CKA_CLASS) { CK_OBJECT_CLASS cl = *(CK_OBJECT_CLASS *)attr->pValue; if (cl != CKO_SECRET_KEY){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } } // a key type must be specified for the client and server write keys // if (keytype == 0xFFFFFFFF){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } // figure out how much key material we need to generate // key_material_loop_count = 2 * ((params->ulMacSizeInBits + 7) / 8) + 2 * ((params->ulKeySizeInBits + 7) / 8); if (params->bIsExport == FALSE) key_material_loop_count += 2 * ((params->ulIVSizeInBits + 7) / 8); // we stop at 'ZZZZ....' presumably this is enough for all cases? // if (key_material_loop_count > 26 * 16){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } key_material_loop_count = (key_material_loop_count + 15) / 16; // generate the key material // for (i=0; i < key_material_loop_count; i++) { memset( variable_data, ('A' + i), i+1 ); rc = ssl3_sha_then_md5( sess, base_key_value, params->RandomInfo.pServerRandom, params->RandomInfo.ulServerRandomLen, params->RandomInfo.pClientRandom, params->RandomInfo.ulClientRandomLen, variable_data, i+1, &(key_block[i*16]) ); if (rc != CKR_OK){ st_err_log(136, __FILE__, __LINE__); goto error; } } // Break key material into pieces // MAC_len = (params->ulMacSizeInBits + 7) / 8; write_len = (params->ulKeySizeInBits + 7) / 8; // check this client_MAC_key_value = key_block; server_MAC_key_value = client_MAC_key_value + MAC_len; client_write_key_value = server_MAC_key_value + MAC_len; server_write_key_value = client_write_key_value + (params->ulKeySizeInBits + 7)/8; if (params->ulIVSizeInBits != 0) { iv_len = (params->ulIVSizeInBits + 7) / 8; client_IV = server_write_key_value + write_len; server_IV = client_IV + iv_len; } // Exportable ciphers require additional processing // if (params->bIsExport == TRUE) { rc = ssl3_md5_only( sess, client_write_key_value, (params->ulKeySizeInBits + 7)/8, params->RandomInfo.pClientRandom, params->RandomInfo.ulClientRandomLen, params->RandomInfo.pServerRandom, params->RandomInfo.ulServerRandomLen, &(key_block[16*26]) ); if (rc != CKR_OK){ st_err_log(137, __FILE__, __LINE__); goto error; } client_write_key_value = &(key_block[16*26]); rc = ssl3_md5_only( sess, server_write_key_value, (params->ulKeySizeInBits + 7)/8, params->RandomInfo.pServerRandom, params->RandomInfo.ulServerRandomLen, params->RandomInfo.pClientRandom, params->RandomInfo.ulClientRandomLen, &(key_block[16*26+16]) ); if (rc != CKR_OK){ st_err_log(137, __FILE__, __LINE__); goto error; } server_write_key_value = &(key_block[16*26+16]); if (params->ulIVSizeInBits != 0) { rc = ssl3_md5_only( sess, NULL, 0, params->RandomInfo.pClientRandom, params->RandomInfo.ulClientRandomLen, params->RandomInfo.pServerRandom, params->RandomInfo.ulServerRandomLen, &(key_block[16*26+2*16]) ); if (rc != CKR_OK){ st_err_log(137, __FILE__, __LINE__); goto error; } client_IV = &(key_block[16*26+2*16]); rc = ssl3_md5_only( sess, NULL, 0, params->RandomInfo.pServerRandom, params->RandomInfo.ulServerRandomLen, params->RandomInfo.pClientRandom, params->RandomInfo.ulClientRandomLen, &(key_block[16*26+3*16]) ); if (rc != CKR_OK){ st_err_log(137, __FILE__, __LINE__); goto error; } server_IV = &(key_block[16*26+3*16]); } } rc = ssl3_kmd_process_mac_keys( sess, pTemplate, ulCount, &client_MAC_handle, client_MAC_key_value, &server_MAC_handle, server_MAC_key_value, MAC_len ); if (rc != CKR_OK){ st_err_log(138, __FILE__, __LINE__); goto error; } rc = ssl3_kmd_process_write_keys( sess, pTemplate, ulCount, keytype, &client_write_handle, client_write_key_value, &server_write_handle, server_write_key_value, write_len ); if (rc != CKR_OK){ st_err_log(139, __FILE__, __LINE__); goto error; } params->pReturnedKeyMaterial->hClientMacSecret = client_MAC_handle; params->pReturnedKeyMaterial->hServerMacSecret = server_MAC_handle; params->pReturnedKeyMaterial->hClientKey = client_write_handle; params->pReturnedKeyMaterial->hServerKey = server_write_handle; if (params->ulIVSizeInBits != 0) { if (params->pReturnedKeyMaterial->pIVClient) memcpy( params->pReturnedKeyMaterial->pIVClient, client_IV, iv_len ); if (params->pReturnedKeyMaterial->pIVServer) memcpy( params->pReturnedKeyMaterial->pIVServer, server_IV, iv_len ); #if 0 CK_BYTE *p1, *p2; p1 = (CK_BYTE *)malloc( iv_len ); p2 = (CK_BYTE *)malloc( iv_len ); if (!p1 || !p2) { rc = CKR_HOST_MEMORY; goto error; } memcpy( p1, client_IV, iv_len ); memcpy( p2, server_IV, iv_len ); params->pReturnedKeyMaterial->pIVClient = p1; params->pReturnedKeyMaterial->pIVServer = p2; #endif } return rc; error: if (client_write_handle != 0) object_mgr_remove_from_map( client_write_handle ); if (server_write_handle != 0) object_mgr_remove_from_map( server_write_handle ); return rc; } CK_RV ssl3_kmd_process_mac_keys( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE * client_handle, CK_BYTE * client_value, CK_OBJECT_HANDLE * server_handle, CK_BYTE * server_value, CK_ULONG mac_len ) { OBJECT * client_obj = NULL; OBJECT * server_obj = NULL; CK_ATTRIBUTE * client_val_attr = NULL; CK_ATTRIBUTE * client_val_len_attr = NULL; CK_ATTRIBUTE * server_val_attr = NULL; CK_ATTRIBUTE * server_val_len_attr = NULL; CK_ATTRIBUTE * attr = NULL; CK_ATTRIBUTE * new_attrs = NULL; CK_ULONG i, cnt; CK_ULONG true_vals[] = { CKA_SIGN, CKA_VERIFY, CKA_DERIVE }; CK_ULONG false_vals[] = { CKA_ENCRYPT, CKA_DECRYPT, CKA_WRAP, CKA_UNWRAP }; CK_RV rc = 0; // for the MAC keys, we want the following default values: // CKA_SIGN, CKA_VERIFY, CKA_DERIVE = TRUE // CKA_ENCRYPT, CKA_DECRYPT, CKA_WRAP, CKA_UNWRAP = FALSE // // attributes are added in sequential order so we stick the defaults // at the beginning so that they may be overridden by caller-specified // values. // new_attrs = (CK_ATTRIBUTE *)malloc((ulCount + 7) * (sizeof(CK_ATTRIBUTE))); if (!new_attrs) goto error; // we have to treat these attributes a bit differently. normally, we allocate // the CK_ATTRIBUTE and the value with a single malloc and just point the pValue // member to the extra space. we can't do that here because we have to "emulate" // the way attributes are passed in from the cryptoki application...as an array // of CK_ATTRIBUTEs with no extra space (that is, pValue must be allocated // separately). // attr = new_attrs; for (i=0; i < sizeof(true_vals) / sizeof(CK_ULONG); i++, attr++) { attr->type = true_vals[i]; attr->ulValueLen = sizeof(CK_BBOOL); attr->pValue = (CK_BBOOL *)malloc(sizeof(CK_BBOOL)); if (!attr->pValue) { rc = CKR_HOST_MEMORY; st_err_log(0, __FILE__, __LINE__); goto error; } *(CK_BBOOL *)attr->pValue = TRUE; } for (i=0; i < sizeof(false_vals) / sizeof(CK_ULONG); i++, attr++) { attr->type = false_vals[i]; attr->ulValueLen = sizeof(CK_BBOOL); attr->pValue = (CK_BBOOL *)malloc(sizeof(CK_BBOOL)); if (!attr->pValue) { rc = CKR_HOST_MEMORY; st_err_log(0, __FILE__, __LINE__); goto error; } *(CK_BBOOL *)attr->pValue = FALSE; } for (i=0, cnt=0; i < ulCount; i++) { if (pTemplate[i].type != CKA_KEY_TYPE && pTemplate[i].type != CKA_VALUE && pTemplate[i].type != CKA_VALUE_LEN) { attr->type = pTemplate[i].type; attr->ulValueLen = pTemplate[i].ulValueLen; attr->pValue = (char *)malloc(attr->ulValueLen); if (!attr->pValue) { rc = CKR_HOST_MEMORY; st_err_log(0, __FILE__, __LINE__); goto error; } memcpy( attr->pValue, pTemplate[i].pValue, attr->ulValueLen ); cnt++; attr++; } } ulCount = 7 + cnt; // create the key skeletons // rc = object_mgr_create_skel( sess, new_attrs, ulCount, MODE_DERIVE, CKO_SECRET_KEY, CKK_GENERIC_SECRET, &client_obj ); if (rc != CKR_OK){ st_err_log(89, __FILE__, __LINE__); goto error; } rc = object_mgr_create_skel( sess, new_attrs, ulCount, MODE_DERIVE, CKO_SECRET_KEY, CKK_GENERIC_SECRET, &server_obj ); if (rc != CKR_OK){ st_err_log(89, __FILE__, __LINE__); goto error; } for (i=0; i < ulCount; i++) if (new_attrs[i].pValue) free( new_attrs[i].pValue ); free( new_attrs ); new_attrs = NULL; rc = build_attribute( CKA_VALUE, client_value, mac_len, &client_val_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } rc = build_attribute( CKA_VALUE, server_value, mac_len, &server_val_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } rc = build_attribute( CKA_VALUE_LEN, (CK_BYTE *)&mac_len, sizeof(CK_ULONG), &client_val_len_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } rc = build_attribute( CKA_VALUE_LEN, (CK_BYTE *)&mac_len, sizeof(CK_ULONG), &server_val_len_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } template_update_attribute( client_obj->template, client_val_attr ); template_update_attribute( client_obj->template, client_val_len_attr ); template_update_attribute( server_obj->template, server_val_attr ); template_update_attribute( server_obj->template, server_val_len_attr ); rc = object_mgr_create_final( sess, client_obj, client_handle ); if (rc != CKR_OK){ st_err_log(90, __FILE__, __LINE__); goto error; } rc = object_mgr_create_final( sess, server_obj, server_handle ); if (rc != CKR_OK){ st_err_log(90, __FILE__, __LINE__); goto error; } return CKR_OK; error: if (*client_handle != 0) object_mgr_remove_from_map( *client_handle ); if (*server_handle != 0) object_mgr_remove_from_map( *server_handle ); if (client_obj) { object_free( client_obj ); client_val_attr = NULL; // these get freed with the object client_val_len_attr = NULL; } if (server_obj) { object_free( server_obj ); server_val_attr = NULL; // these get freed with the object server_val_len_attr = NULL; } if (client_val_attr) free( client_val_attr ); if (client_val_len_attr) free( client_val_len_attr ); if (server_val_attr) free( server_val_attr ); if (server_val_len_attr) free( server_val_len_attr ); if (new_attrs) { for (i=0; i < ulCount; i++) { if (new_attrs[i].pValue) free( new_attrs[i].pValue ); } free( new_attrs ); } return rc; } CK_RV ssl3_kmd_process_write_keys( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_KEY_TYPE keytype, CK_OBJECT_HANDLE * client_handle, CK_BYTE * client_value, CK_OBJECT_HANDLE * server_handle, CK_BYTE * server_value, CK_ULONG write_len ) { CK_ATTRIBUTE * client_val_attr = NULL; CK_ATTRIBUTE * client_val_len_attr = NULL; CK_ATTRIBUTE * server_val_attr = NULL; CK_ATTRIBUTE * server_val_len_attr = NULL; CK_ATTRIBUTE * new_attrs = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * client_obj = NULL; OBJECT * server_obj = NULL; CK_ULONG i, cnt; CK_ULONG true_vals[] = { CKA_ENCRYPT, CKA_DECRYPT, CKA_DERIVE }; CK_ULONG false_vals[] = { CKA_SIGN, CKA_VERIFY, CKA_WRAP, CKA_UNWRAP }; CK_RV rc = CKR_HOST_MEMORY; // for the write keys, we want the following default values: // CKA_ENCRYPT, CKA_DECRYPT, CKA_DERIVE = TRUE // CKA_SIGN, CKA_VERIFY, CKA_WRAP, CKA_UNWRAP = FALSE // // attributes are added in sequential order so we stick the defaults // at the beginning so that they may be overridden by caller-specified // values. // new_attrs = (CK_ATTRIBUTE *)malloc((ulCount + 7) * (sizeof(CK_ATTRIBUTE))); if (!new_attrs) goto error; // we have to treat these attributes a bit differently. normally, we allocate // the CK_ATTRIBUTE and the value with a single malloc and just point the pValue // member to the extra space. we can't do that here because we have to "emulate" // the way attributes are passed in from the cryptoki application...as an array // of CK_ATTRIBUTEs with no extra space (that is, pValue must be allocated // separately). // attr = new_attrs; for (i=0; i < sizeof(true_vals) / sizeof(CK_ULONG); i++, attr++) { attr->type = true_vals[i]; attr->ulValueLen = sizeof(CK_BBOOL); attr->pValue = (CK_BBOOL *)malloc(sizeof(CK_BBOOL)); if (!attr->pValue) { st_err_log(0, __FILE__, __LINE__); goto error; } *(CK_BBOOL *)attr->pValue = TRUE; } for (i=0; i < sizeof(false_vals) / sizeof(CK_ULONG); i++, attr++) { attr->type = false_vals[i]; attr->ulValueLen = sizeof(CK_BBOOL); attr->pValue = (CK_BBOOL *)malloc(sizeof(CK_BBOOL)); if (!attr->pValue) { st_err_log(0, __FILE__, __LINE__); goto error; } *(CK_BBOOL *)attr->pValue = FALSE; } for (i=0, cnt=0; i < ulCount; i++) { if (pTemplate[i].type != CKA_KEY_TYPE && pTemplate[i].type != CKA_VALUE && pTemplate[i].type != CKA_VALUE_LEN) { attr->type = pTemplate[i].type; attr->ulValueLen = pTemplate[i].ulValueLen; attr->pValue = (char *)malloc(attr->ulValueLen); if (!attr->pValue) { st_err_log(0, __FILE__, __LINE__); goto error; } memcpy( attr->pValue, pTemplate[i].pValue, attr->ulValueLen ); cnt++; attr++; } } ulCount = 7 + cnt; rc = object_mgr_create_skel( sess, new_attrs, ulCount, MODE_DERIVE, CKO_SECRET_KEY, keytype, &client_obj ); if (rc != CKR_OK){ st_err_log(89, __FILE__, __LINE__); goto error; } rc = object_mgr_create_skel( sess, new_attrs, ulCount, MODE_DERIVE, CKO_SECRET_KEY, keytype, &server_obj ); if (rc != CKR_OK){ st_err_log(89, __FILE__, __LINE__); goto error; } for (i=0; i < ulCount; i++) { if (new_attrs[i].pValue) free( new_attrs[i].pValue ); } free( new_attrs ); new_attrs = NULL; rc = build_attribute( CKA_VALUE, client_value, write_len, &client_val_attr ); rc |= build_attribute( CKA_VALUE, server_value, write_len, &server_val_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } switch (keytype) { case CKK_GENERIC_SECRET: case CKK_DES: case CKK_DES2: case CKK_DES3: case CKK_RC2: case CKK_RC4: case CKK_RC5: case CKK_CAST: case CKK_CAST3: case CKK_CAST5: { rc = build_attribute( CKA_VALUE_LEN, (CK_BYTE *)&write_len, sizeof(CK_ULONG), &client_val_len_attr ); rc |= build_attribute( CKA_VALUE_LEN, (CK_BYTE *)&write_len, sizeof(CK_ULONG), &server_val_len_attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } rc = template_validate_attribute( client_obj->template, client_val_len_attr, CKO_SECRET_KEY, keytype, MODE_DERIVE ); rc |= template_validate_attribute( server_obj->template, server_val_len_attr, CKO_SECRET_KEY, keytype, MODE_DERIVE ); // for these I use MODE_CREATE because I want to validate the value/length. // no othe modes are allowed to mess wiht CKA_VALUE (see for instance, // des_validate_attribute()) // rc |= template_validate_attribute( client_obj->template, client_val_attr, CKO_SECRET_KEY, keytype, MODE_CREATE ); rc |= template_validate_attribute( server_obj->template, server_val_attr, CKO_SECRET_KEY, keytype, MODE_CREATE ); if (rc != CKR_OK){ st_err_log(140, __FILE__, __LINE__); goto error; } template_update_attribute( client_obj->template, client_val_attr ); template_update_attribute( server_obj->template, server_val_attr ); template_update_attribute( client_obj->template, client_val_len_attr ); template_update_attribute( server_obj->template, server_val_len_attr ); // the object owns the attributes now... // client_val_attr = NULL; server_val_attr = NULL; client_val_len_attr = NULL; server_val_len_attr = NULL; } break; default: { rc = template_validate_attribute( client_obj->template, client_val_attr, CKO_SECRET_KEY, keytype, MODE_CREATE ); rc |= template_validate_attribute( server_obj->template, server_val_attr, CKO_SECRET_KEY, keytype, MODE_CREATE ); if (rc != CKR_OK){ st_err_log(140, __FILE__, __LINE__); goto error; } template_update_attribute( client_obj->template, client_val_attr ); template_update_attribute( server_obj->template, server_val_attr ); // the object owns the attributes now... // client_val_attr = NULL; server_val_attr = NULL; } } // finally, assign a handle to each key // rc = object_mgr_create_final( sess, client_obj, client_handle ); if (rc != CKR_OK){ st_err_log(90, __FILE__, __LINE__); goto error; } rc = object_mgr_create_final( sess, server_obj, server_handle ); if (rc != CKR_OK){ st_err_log(90, __FILE__, __LINE__); goto error; } return CKR_OK; error: if (*client_handle != 0) object_mgr_remove_from_map( *client_handle ); if (*server_handle != 0) object_mgr_remove_from_map( *server_handle ); if (client_obj) object_free( client_obj ); if (server_obj) object_free( server_obj ); // the only way these guys are non-NULL is if they were created but // not yet to added to an object // if (client_val_attr) free( client_val_attr ); if (client_val_len_attr) free( client_val_len_attr ); if (server_val_attr) free( server_val_attr ); if (server_val_len_attr) free( server_val_len_attr ); if (new_attrs) { for (i=0; i < ulCount; i++) { if (new_attrs[i].pValue) free( new_attrs[i].pValue ); } free( new_attrs ); } return rc; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/tok_specific.h0000751000175000017500000005113311327631345021535 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/lib/pkcs11/common/tok_specific.h,v 1.4 2007/12/05 22:52:01 mhalcrow Exp $ */ // /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ /*************************************************************************** Change Log ========== 4/25/03 Kapil Sood (kapil@corrent.com) Added DH key pair generation and DH shared key derivation functions. ****************************************************************************/ // Token specific functions that tokens must implement..... // // Prototypes #ifndef _TOK_SPECIFIC #define _TOK_SPECIFIC CK_RV token_rng(CK_BYTE *, CK_ULONG); int tok_slot2local(CK_SLOT_ID); CK_RV token_specific_init(char *,CK_SLOT_ID ); CK_RV token_specific_session(CK_SLOT_ID); CK_RV token_specific_final(void); CK_RV token_specific_des_key_gen(CK_BYTE *,CK_ULONG) ; CK_RV token_specific_des_ecb(CK_BYTE *, CK_ULONG , CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_BYTE ); CK_RV token_specific_des_cbc(CK_BYTE *, CK_ULONG , CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_BYTE *, CK_BYTE ); CK_RV token_specific_tdes_ecb(CK_BYTE *, CK_ULONG , CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_BYTE ); CK_RV token_specific_tdes_cbc(CK_BYTE *, CK_ULONG , CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_BYTE *, CK_BYTE ); CK_RV token_specific_rsa_decrypt( CK_BYTE * , CK_ULONG , CK_BYTE *, OBJECT *); CK_RV token_specific_rsa_encrypt( CK_BYTE * , CK_ULONG , CK_BYTE * , OBJECT * ); CK_RV token_specific_rsa_generate_keypair( TEMPLATE * , TEMPLATE * ); /* Begin code contributed by Corrent corp. */ #ifndef NODH CK_RV token_specific_dh_pkcs_derive( CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG ) ; CK_RV token_specific_dh_pkcs_key_pair_gen( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ); #endif /* End code contributed by Corrent corp. */ CK_RV tok_cdmv_transform(CK_VOID_PTR, CK_ULONG); CK_RV ckm_dsa_sign( CK_BYTE * , CK_BYTE * , OBJECT * ); CK_RV ckm_dsa_key_pair_gen( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ); CK_RV ckm_dsa_verify( CK_BYTE *, CK_BYTE *, OBJECT * ); CK_RV token_specific_sha_generic_init(DIGEST_CONTEXT *ctx, CK_MECHANISM_TYPE sha_type); CK_RV token_specific_sha_generic_update(DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_MECHANISM_TYPE sha_type); CK_RV token_specific_sha_generic_final(DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_MECHANISM_TYPE sha_type); CK_RV token_specific_sha_init( DIGEST_CONTEXT * ); CK_RV token_specific_sha_update( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG); CK_RV token_specific_sha_final( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG * ); CK_RV token_specific_sha2_init( DIGEST_CONTEXT * ); CK_RV token_specific_sha2_update( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG); CK_RV token_specific_sha2_final( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG * ); CK_RV token_specific_sha3_init( DIGEST_CONTEXT * ); CK_RV token_specific_sha3_update( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG); CK_RV token_specific_sha3_final( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG * ); CK_RV token_specific_sha5_init( DIGEST_CONTEXT * ); CK_RV token_specific_sha5_update( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG); CK_RV token_specific_sha5_final( DIGEST_CONTEXT *, CK_BYTE *, CK_ULONG * ); #ifndef NOAES CK_RV token_specific_aes_key_gen( CK_BYTE *, CK_ULONG ); CK_RV token_specific_aes_ecb( CK_BYTE *, CK_ULONG , CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_ULONG , CK_BYTE ); CK_RV token_specific_aes_cbc( CK_BYTE *, CK_ULONG , CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_ULONG , CK_BYTE *, CK_BYTE ); #endif CK_RV token_specific_get_mechanism_list(CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount); CK_RV token_specific_get_mechanism_info(CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo); #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/mech_dsa.c0000751000175000017500000005142511327631345020635 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: mech_dsa.c // // Mechanisms for DSA // // Routines contained within: #include #include // for memcmp() et al #include #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" //#include "tok_spec_struct.h" // // CK_RV dsa_sign( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ) { OBJECT *key_obj = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE sig[DSA_SIGNATURE_SIZE]; CK_OBJECT_CLASS class; CK_BBOOL flag; CK_RV rc; rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(118, __FILE__, __LINE__); return rc; } // must be a PRIVATE key operation // flag = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (flag == FALSE){ st_err_log(118, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } else class = *(CK_OBJECT_CLASS *)attr->pValue; // if it's not a private DSA key then we have an internal failure...means // that somehow a public key got assigned a CKA_SIGN attribute // if (class != CKO_PRIVATE_KEY){ st_err_log(118, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } // check input data length restrictions. Generic DSA works on the SHA-1 // hash of the data so the input to the DSA operation must be 20 bytes // if (in_data_len != 20){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } if (length_only == TRUE) { *out_data_len = DSA_SIGNATURE_SIZE; return CKR_OK; } rc = ckm_dsa_sign( in_data, sig, key_obj ); if (rc == CKR_OK) { memcpy( out_data, sig, DSA_SIGNATURE_SIZE ); *out_data_len = DSA_SIGNATURE_SIZE; } return rc; } // // CK_RV dsa_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ) { OBJECT *key_obj = NULL; CK_ATTRIBUTE *attr = NULL; CK_OBJECT_CLASS class; CK_BBOOL flag; CK_RV rc; rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(118, __FILE__, __LINE__); return rc; } // must be a PUBLIC key operation // flag = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (flag == FALSE){ st_err_log(118, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } else class = *(CK_OBJECT_CLASS *)attr->pValue; if (class != CKO_PUBLIC_KEY){ st_err_log(118, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } // check input data length restrictions // if (sig_len != DSA_SIGNATURE_SIZE){ st_err_log(46, __FILE__, __LINE__); return CKR_SIGNATURE_LEN_RANGE; } if (in_data_len != 20){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } rc = ckm_dsa_verify( signature, in_data, key_obj ); if (rc != CKR_OK) st_err_log(121, __FILE__, __LINE__); return rc; } // // mechanisms // // // CK_RV ckm_dsa_key_pair_gen( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ) { CK_ATTRIBUTE * prime = NULL; CK_ATTRIBUTE * subprime = NULL; CK_ATTRIBUTE * base = NULL; CK_ATTRIBUTE * priv_exp = NULL; CK_ATTRIBUTE * publ_exp = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_BYTE repl_buf[5500]; CK_BBOOL flag; CK_RV rc; rc = token_specific_dsa_generate_keypair(publ_tmpl,priv_tmpl); if (rc != CKR_OK) st_err_log(91, __FILE__, __LINE__); return rc; } // // CK_RV ckm_dsa_sign( CK_BYTE * in_data, CK_BYTE * signature, OBJECT * priv_key ) { CK_ATTRIBUTE * prime = NULL; CK_ATTRIBUTE * subprime = NULL; CK_ATTRIBUTE * base = NULL; CK_ATTRIBUTE * exponent = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_OBJECT_CLASS keyclass; CK_RV rc; rc = template_attribute_find( priv_key->template, CKA_CLASS, &attr ); if (rc == FALSE){ st_err_log(118, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } else keyclass = *(CK_OBJECT_CLASS *)attr->pValue; // this had better be a private key // if (keyclass != CKO_PRIVATE_KEY){ st_err_log(118, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } rc = tok_dsa_sign(in_data, signature, priv_key); if (rc != CKR_OK) st_err_log(122, __FILE__, __LINE__); return rc; } // // CK_RV ckm_dsa_verify( CK_BYTE * signature, CK_BYTE * data, OBJECT * publ_key ) { CK_ATTRIBUTE * prime = NULL; CK_ATTRIBUTE * subprime = NULL; CK_ATTRIBUTE * base = NULL; CK_ATTRIBUTE * exponent = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_OBJECT_CLASS keyclass; CK_RV rc; rc = template_attribute_find( publ_key->template, CKA_CLASS, &attr ); if (rc == FALSE){ st_err_log(118, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } else keyclass = *(CK_OBJECT_CLASS *)attr->pValue; // this had better be a private key // if (keyclass != CKO_PUBLIC_KEY){ st_err_log(118, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } rc = tok_dsa_verify( signature, data, publ_key); if (rc != CKR_OK) st_err_log(121, __FILE__, __LINE__); return rc; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/cert.c0000751000175000017500000005030411327631345020022 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: cert.c // // Functions contained within: // // cert_check_required_attributes // cert_validate_attribute // cert_x509_check_required_attributes // cert_x509_set_default_attributes // cert_x509_validate_attribute // cert_vendor_check_required_attributes // cert_vendor_validate_attribute // #include #include #include // for memcmp() et al #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" // cert_check_required_attributes // // Checks for required attributes for generic CKO_CERTIFICATE objects // // CKA_CERTIFICATE_TYPE : must be present on MODE_CREATE. // CK_RV cert_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE * attr = NULL; CK_BBOOL found; if (!tmpl) return CKR_FUNCTION_FAILED; if (mode == MODE_CREATE) { found = template_attribute_find( tmpl, CKA_CERTIFICATE_TYPE, &attr ); if (found == FALSE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } // don't bother checking the value. it was checked in the 'validate' // routine. } return template_check_required_base_attributes( tmpl, mode ); } // cert_validate_attribute() // CK_RV cert_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { CK_CERTIFICATE_TYPE type; switch (attr->type) { case CKA_CERTIFICATE_TYPE: { if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } type = *(CK_CERTIFICATE_TYPE *)attr->pValue; if (type == CKC_X_509 || type >= CKC_VENDOR_DEFINED) return CKR_OK; else{ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } } break; default: return template_validate_base_attribute( tmpl, attr, mode ); } return template_validate_base_attribute( tmpl, attr, mode ); } // cert_x509_check_required_attributes() // CK_RV cert_x509_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_SUBJECT, &attr ); if (!found){ st_err_log(9, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } found = template_attribute_find( tmpl, CKA_VALUE, &attr ); if (!found){ st_err_log(9, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } return cert_check_required_attributes( tmpl, mode ); } // cert_x509_set_default_attributes() // // Set the default attributes for X.509 certificates // // CKA_ID : empty string // CKA_ISSUER : empty string // CKA_SERIAL_NUMBER : empty string // CK_RV cert_x509_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { CK_ATTRIBUTE * id_attr = NULL; CK_ATTRIBUTE * issuer_attr = NULL; CK_ATTRIBUTE * serial_attr = NULL; // satisfy compiler warning.... // if (mode) id_attr = NULL; id_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); issuer_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); serial_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!id_attr || !issuer_attr || !serial_attr) { if (id_attr) free( id_attr ); if (issuer_attr) free( issuer_attr ); if (serial_attr) free( serial_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } id_attr->type = CKA_ID; id_attr->ulValueLen = 0; // empty string id_attr->pValue = NULL; issuer_attr->type = CKA_ISSUER; issuer_attr->ulValueLen = 0; // empty byte array issuer_attr->pValue = NULL; serial_attr->type = CKA_SERIAL_NUMBER; serial_attr->ulValueLen = 0; // empty byte array serial_attr->pValue = NULL; template_update_attribute( tmpl, id_attr ); template_update_attribute( tmpl, issuer_attr ); template_update_attribute( tmpl, serial_attr ); return CKR_OK; } // cert_x509_validate_attributes() // CK_RV cert_x509_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { switch (attr->type) { case CKA_SUBJECT: if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } else return CKR_OK; case CKA_ID: case CKA_ISSUER: case CKA_SERIAL_NUMBER: return CKR_OK; case CKA_VALUE: if (mode != MODE_CREATE){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } else return CKR_OK; default: return cert_validate_attribute( tmpl, attr, mode ); } } // cert_vendor_check_required_attributes() // CK_RV cert_vendor_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ) { // CKC_VENDOR has no required attributes // return cert_check_required_attributes( tmpl, mode ); } // cert_vendor_validate_attribute() // CK_RV cert_vendor_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ) { // cryptoki specifies no attributes for CKC_VENDOR certificates // return cert_validate_attribute( tmpl, attr, mode ); } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/template.c0000751000175000017500000014510611327631345020705 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: template.c // // Attribute template management routines // // Functions contained in this file: // // template_add_attributes // template_add_default_attributes // template_attribute_find // template_check_required_attributes // template_check_required_base_attributes // template_free // template_set_default_common_attributes // template_update_attribute // template_validate_attribute // template_validate_attributes // template_validate_base_attribute // #include #include #include #include // for memcmp() et al #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" #include "pkcs32.h" // template_add_attributes() // // blindly add the given attributes to the template. do no sanity checking // at this point. sanity checking will occur later. // CK_RV template_add_attributes( TEMPLATE * tmpl, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ) { CK_ATTRIBUTE * attr = NULL; CK_RV rc; unsigned int i; for (i=0; i < ulCount; i++) { if (!is_attribute_defined(pTemplate[i].type)){ st_err_log(183, __FILE__, __LINE__); return CKR_ATTRIBUTE_TYPE_INVALID; } attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + pTemplate[i].ulValueLen); if (!attr){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } attr->type = pTemplate[i].type; attr->ulValueLen = pTemplate[i].ulValueLen; if (attr->ulValueLen != 0) { attr->pValue = (CK_BYTE *)attr + sizeof(CK_ATTRIBUTE); memcpy( attr->pValue, pTemplate[i].pValue, attr->ulValueLen ); } else attr->pValue = NULL; rc = template_update_attribute( tmpl, attr ); if (rc != CKR_OK) { free( attr ); st_err_log(178, __FILE__, __LINE__); return rc; } } return CKR_OK; } // template_add_default_attributes() // CK_RV template_add_default_attributes( TEMPLATE * tmpl, CK_ULONG class, CK_ULONG subclass, CK_ULONG mode ) { CK_RV rc; // first add the default common attributes // rc = template_set_default_common_attributes( tmpl ); if (rc != CKR_OK){ st_err_log(172, __FILE__, __LINE__); return rc; } // set the template class-specific default attributes // switch (class) { case CKO_DATA: return data_object_set_default_attributes( tmpl, mode ); case CKO_CERTIFICATE: if (subclass == CKC_X_509) return cert_x509_set_default_attributes( tmpl, mode ); else return CKR_OK; case CKO_PUBLIC_KEY: switch (subclass) { case CKK_RSA: return rsa_publ_set_default_attributes( tmpl, mode ); case CKK_DSA: return dsa_publ_set_default_attributes( tmpl, mode ); case CKK_ECDSA: return ecdsa_publ_set_default_attributes( tmpl, mode ); case CKK_DH: return dh_publ_set_default_attributes( tmpl, mode ); case CKK_KEA: return kea_publ_set_default_attributes( tmpl, mode ); default: st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; // unknown key type } case CKO_PRIVATE_KEY: switch (subclass) { case CKK_RSA: return rsa_priv_set_default_attributes( tmpl, mode ); case CKK_DSA: return dsa_priv_set_default_attributes( tmpl, mode ); case CKK_ECDSA: return ecdsa_priv_set_default_attributes( tmpl, mode ); case CKK_DH: return dh_priv_set_default_attributes( tmpl, mode ); case CKK_KEA: return kea_priv_set_default_attributes( tmpl, mode ); default: st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; // unknown key type } case CKO_SECRET_KEY: switch (subclass) { case CKK_GENERIC_SECRET: return generic_secret_set_default_attributes( tmpl, mode ); case CKK_RC2: return rc2_set_default_attributes( tmpl, mode ); case CKK_RC4: return rc4_set_default_attributes( tmpl, mode ); case CKK_RC5: return rc5_set_default_attributes( tmpl, mode ); case CKK_DES: return des_set_default_attributes( tmpl, mode ); case CKK_DES2: return des2_set_default_attributes( tmpl, mode ); case CKK_DES3: return des3_set_default_attributes( tmpl, mode ); case CKK_CAST: return cast_set_default_attributes( tmpl, mode ); case CKK_CAST3: return cast3_set_default_attributes( tmpl, mode ); case CKK_CAST5: return cast5_set_default_attributes( tmpl, mode ); case CKK_IDEA: return idea_set_default_attributes( tmpl, mode ); #if !(NOCDMF) case CKK_CDMF: return cdmf_set_default_attributes( tmpl, mode ); #endif case CKK_SKIPJACK: return skipjack_set_default_attributes( tmpl, mode ); case CKK_BATON: return baton_set_default_attributes( tmpl, mode ); case CKK_JUNIPER: return juniper_set_default_attributes( tmpl, mode ); case CKK_AES: return aes_set_default_attributes( tmpl, mode ); default: st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; // unknown key type } case CKO_HW_FEATURE: switch (subclass) { case CKH_CLOCK: return clock_set_default_attributes( tmpl, mode ); case CKH_MONOTONIC_COUNTER: return counter_set_default_attributes( tmpl, mode ); default: st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } case CKO_DOMAIN_PARAMETERS: switch (subclass) { case CKK_DSA: return dp_dsa_set_default_attributes( tmpl, mode ); case CKK_DH: return dp_dh_set_default_attributes( tmpl, mode ); case CKK_X9_42_DH: return dp_x9dh_set_default_attributes( tmpl, mode ); default: st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } default: st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } } // template_attribute_find() // // find the attribute in the list and return its value // CK_BBOOL template_attribute_find( TEMPLATE * tmpl, CK_ATTRIBUTE_TYPE type, CK_ATTRIBUTE ** attr ) { DL_NODE * node = NULL; CK_ATTRIBUTE * a = NULL; if (!tmpl || !attr) return FALSE; node = tmpl->attribute_list; while (node != NULL) { a = (CK_ATTRIBUTE *)node->data; if (type == a->type) { *attr = a; return TRUE; } node = node->next; } *attr = NULL; return FALSE; } // template_attribute_find_multiple() // // find the attributes in the list and return their values // void template_attribute_find_multiple( TEMPLATE * tmpl, ATTRIBUTE_PARSE_LIST * parselist, CK_ULONG plcount ) { CK_ATTRIBUTE * attr = NULL; CK_ULONG i; for (i = 0; i < plcount; i++) { parselist[i].found = template_attribute_find( tmpl, parselist[i].type, &attr ); if (parselist[i].found && parselist[i].ptr != NULL) memcpy(parselist[i].ptr, attr->pValue, parselist[i].len ); } } // template_check_required_attributes() // CK_RV template_check_required_attributes( TEMPLATE * tmpl, CK_ULONG class, CK_ULONG subclass, CK_ULONG mode ) { if (class == CKO_DATA) return data_object_check_required_attributes( tmpl, mode ); else if (class == CKO_CERTIFICATE) { if (subclass == CKC_X_509) return cert_x509_check_required_attributes( tmpl, mode ); else return cert_vendor_check_required_attributes( tmpl, mode ); } else if (class == CKO_PUBLIC_KEY) { switch (subclass) { case CKK_RSA: return rsa_publ_check_required_attributes( tmpl, mode ); case CKK_DSA: return dsa_publ_check_required_attributes( tmpl, mode ); case CKK_ECDSA: return ecdsa_publ_check_required_attributes( tmpl, mode ); case CKK_DH: return dh_publ_check_required_attributes( tmpl, mode ); case CKK_KEA: return kea_publ_check_required_attributes( tmpl, mode ); default: st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; // unknown key type } } else if (class == CKO_PRIVATE_KEY) { switch (subclass) { case CKK_RSA: return rsa_priv_check_required_attributes( tmpl, mode ); case CKK_DSA: return dsa_priv_check_required_attributes( tmpl, mode ); case CKK_ECDSA: return ecdsa_priv_check_required_attributes( tmpl, mode ); case CKK_DH: return dh_priv_check_required_attributes( tmpl, mode ); case CKK_KEA: return kea_priv_check_required_attributes( tmpl, mode ); default: st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; // unknown key type } } else if (class == CKO_SECRET_KEY) { switch (subclass) { case CKK_GENERIC_SECRET: return generic_secret_check_required_attributes( tmpl, mode ); case CKK_RC2: return rc2_check_required_attributes( tmpl, mode ); case CKK_RC4: return rc4_check_required_attributes( tmpl, mode ); case CKK_RC5: return rc5_check_required_attributes( tmpl, mode ); case CKK_DES: return des_check_required_attributes( tmpl, mode ); case CKK_DES2: return des2_check_required_attributes( tmpl, mode ); case CKK_DES3: return des3_check_required_attributes( tmpl, mode ); case CKK_CAST: return cast_check_required_attributes( tmpl, mode ); case CKK_CAST3: return cast3_check_required_attributes( tmpl, mode ); case CKK_CAST5: return cast5_check_required_attributes( tmpl, mode ); case CKK_IDEA: return idea_check_required_attributes( tmpl, mode ); #if !(NOCDMF) case CKK_CDMF: return cdmf_check_required_attributes( tmpl, mode ); #endif case CKK_SKIPJACK: return skipjack_check_required_attributes( tmpl, mode ); case CKK_BATON: return baton_check_required_attributes( tmpl, mode ); case CKK_JUNIPER: return juniper_check_required_attributes( tmpl, mode ); case CKK_AES: return aes_check_required_attributes( tmpl, mode ); default: st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; // unknown key type } } else if (class == CKO_HW_FEATURE) { switch (subclass) { case CKH_CLOCK: return clock_check_required_attributes( tmpl, mode ); case CKH_MONOTONIC_COUNTER: return counter_check_required_attributes( tmpl, mode ); default: st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } } else if (class == CKO_DOMAIN_PARAMETERS) { switch (subclass) { case CKK_DSA: return dp_dsa_check_required_attributes( tmpl, mode ); case CKK_DH: return dp_dh_check_required_attributes( tmpl, mode ); case CKK_X9_42_DH: return dp_x9dh_check_required_attributes( tmpl, mode ); default: st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } } st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; // default fallthru } // template_check_required_base_attributes() // // check to make sure that attributes required by Cryptoki are // present. does not check to see if the attribute makes sense // for the particular object (that is done in the 'validate' routines) // CK_RV template_check_required_base_attributes( TEMPLATE * tmpl, CK_ULONG mode ) { CK_ATTRIBUTE * attr; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_CLASS, &attr ); if (mode == MODE_CREATE && found == FALSE) return CKR_TEMPLATE_INCOMPLETE; return CKR_OK; } // template_compare() // CK_BBOOL template_compare( CK_ATTRIBUTE * t1, CK_ULONG ulCount, TEMPLATE * t2 ) { CK_ATTRIBUTE * attr1 = NULL; CK_ATTRIBUTE * attr2 = NULL; CK_ULONG i; CK_RV rc; if (!t1 || !t2) return FALSE; attr1 = t1; for (i=0; i < ulCount; i++) { rc = template_attribute_find( t2, attr1->type, &attr2 ); if (rc == FALSE) return FALSE; if (attr1->ulValueLen != attr2->ulValueLen) return FALSE; if (memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen) != 0) return FALSE; attr1++; } return TRUE; } // template_copy() // // This doesn't copy the template items verbatim. The new template is in // the reverse order of the old one. This should not have any effect. // // This is very similar to template_merge(). template_merge() can also // be used to copy a list (of unique attributes) but is slower because for // each attribute, it must search through the list. // CK_RV template_copy( TEMPLATE *dest, TEMPLATE *src ) { DL_NODE *node; if (!dest || !src){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } node = src->attribute_list; while (node) { CK_ATTRIBUTE *attr = (CK_ATTRIBUTE *)node->data; CK_ATTRIBUTE *new_attr = NULL; CK_ULONG len; len = sizeof(CK_ATTRIBUTE) + attr->ulValueLen; new_attr = (CK_ATTRIBUTE *)malloc(len); if (!new_attr){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( new_attr, attr, len ); new_attr->pValue = (CK_BYTE *)new_attr + sizeof(CK_ATTRIBUTE); dest->attribute_list = dlist_add_as_first( dest->attribute_list, new_attr ); node = node->next; } return CKR_OK; } // template_flatten() - this still gets used when saving token objects to disk // CK_RV template_flatten( TEMPLATE * tmpl, CK_BYTE * dest ) { DL_NODE * node = NULL; CK_BYTE * ptr = NULL; CK_ULONG_32 long_len; CK_ATTRIBUTE_32 *attr_32 = NULL; CK_ULONG Val; CK_ULONG_32 Val_32; CK_ULONG * pVal; long_len = sizeof(CK_ULONG); if (!tmpl || !dest){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } ptr = dest; node = tmpl->attribute_list; while (node) { CK_ATTRIBUTE *attr = (CK_ATTRIBUTE *)node->data; if (long_len == 4) { memcpy( ptr, attr, sizeof(CK_ATTRIBUTE) + attr->ulValueLen ); ptr += sizeof(CK_ATTRIBUTE) + attr->ulValueLen; } else { attr_32 = malloc(sizeof(CK_ATTRIBUTE_32)); if (!attr_32) { st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } attr_32->type = attr->type; attr_32->pValue = 0x00; if ( ( attr->type == CKA_CLASS || attr->type == CKA_KEY_TYPE || attr->type == CKA_MODULUS_BITS || attr->type == CKA_VALUE_BITS || attr->type == CKA_CERTIFICATE_TYPE || attr->type == CKA_VALUE_LEN ) && attr->ulValueLen != 0 ) { attr_32->ulValueLen = sizeof(CK_ULONG_32); memcpy( ptr, attr_32, sizeof(CK_ATTRIBUTE_32)); ptr += sizeof(CK_ATTRIBUTE_32); pVal = (CK_ULONG *)attr->pValue; Val = *pVal; Val_32 = (CK_ULONG_32)Val; memcpy( ptr, &Val_32, sizeof(CK_ULONG_32)); ptr += sizeof(CK_ULONG_32); } else { attr_32->ulValueLen = attr->ulValueLen; memcpy( ptr, attr_32, sizeof(CK_ATTRIBUTE_32)); ptr += sizeof(CK_ATTRIBUTE_32); if (attr->ulValueLen != 0) { memcpy( ptr, attr->pValue, attr->ulValueLen); ptr += attr->ulValueLen; } } } node = node->next; } if (attr_32) free(attr_32); return CKR_OK; } // // CK_RV template_unflatten( TEMPLATE ** new_tmpl, CK_BYTE * buf, CK_ULONG count ) { TEMPLATE * tmpl = NULL; CK_ATTRIBUTE * a2 = NULL; CK_BYTE * ptr = NULL; CK_ULONG i, len; CK_RV rc; CK_ULONG_32 long_len = sizeof(CK_ULONG); CK_ULONG_32 attr_ulong_32; CK_ULONG attr_ulong; CK_ATTRIBUTE * a1_64 = NULL; CK_ATTRIBUTE_32 * a1 = NULL; if (!new_tmpl || !buf){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } tmpl = (TEMPLATE *)malloc(sizeof(TEMPLATE)); if (!tmpl){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( tmpl, 0x0, sizeof(TEMPLATE) ); ptr = buf; for (i=0; i < count; i++) { if(long_len == 4) { a1_64 = (CK_ATTRIBUTE *)ptr; len = sizeof(CK_ATTRIBUTE) + a1_64->ulValueLen; a2 = (CK_ATTRIBUTE *)malloc(len); if (!a2) { template_free( tmpl ); st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( a2, a1_64, len ); }else{ a1 = (CK_ATTRIBUTE_32 *)ptr; if ( ( a1->type == CKA_CLASS || a1->type == CKA_KEY_TYPE || a1->type == CKA_MODULUS_BITS || a1->type == CKA_VALUE_BITS || a1->type == CKA_CERTIFICATE_TYPE || a1->type == CKA_VALUE_LEN ) && a1->ulValueLen != 0 ) { len = sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG); } else { len = sizeof(CK_ATTRIBUTE) + a1->ulValueLen; } a2 = (CK_ATTRIBUTE *)malloc(len); if (!a2){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } a2->type = a1->type; if ( ( a1->type == CKA_CLASS || a1->type == CKA_KEY_TYPE || a1->type == CKA_MODULUS_BITS || a1->type == CKA_VALUE_BITS || a1->type == CKA_CERTIFICATE_TYPE || a1->type == CKA_VALUE_LEN ) && a1->ulValueLen != 0 ) { a2->ulValueLen = sizeof(CK_ULONG); { CK_ULONG_32 *p32; CK_BYTE *pb2; pb2 = (CK_BYTE *)a1; pb2 += sizeof (CK_ATTRIBUTE_32); p32 = (CK_ULONG_32 *)pb2; attr_ulong_32 = *p32; } attr_ulong = attr_ulong_32; { CK_BYTE *pb2; pb2 = (CK_BYTE *)a2; pb2 += sizeof(CK_ATTRIBUTE); memcpy( pb2 , (CK_BYTE *)&attr_ulong, sizeof(CK_ULONG)); } } else { CK_BYTE *pb2,*pb; a2->ulValueLen = a1->ulValueLen; pb2 = (CK_BYTE *)a2; pb2 += sizeof(CK_ATTRIBUTE); pb = (CK_BYTE *)a1; pb += sizeof(CK_ATTRIBUTE_32); memcpy( pb2, pb, a1->ulValueLen ); } } if (a2->ulValueLen != 0) a2->pValue = (CK_BYTE *)a2 + sizeof(CK_ATTRIBUTE); else a2->pValue = NULL; rc = template_update_attribute( tmpl, a2 ); if (rc != CKR_OK) { free( a2 ); template_free( tmpl ); return rc; } if(long_len == 4) ptr += len; else ptr += sizeof(CK_ATTRIBUTE_32) + a1->ulValueLen; } *new_tmpl = tmpl; return CKR_OK; } // template_free() // CK_RV template_free( TEMPLATE *tmpl ) { if (!tmpl) return CKR_OK; while (tmpl->attribute_list) { CK_ATTRIBUTE *attr = (CK_ATTRIBUTE *)tmpl->attribute_list->data; if (attr) free( attr ); tmpl->attribute_list = dlist_remove_node( tmpl->attribute_list, tmpl->attribute_list ); } free( tmpl ); return CKR_OK; } // template_get_class // CK_BBOOL template_get_class( TEMPLATE * tmpl, CK_ULONG * class, CK_ULONG * subclass ) { DL_NODE * node; CK_BBOOL found; if (!tmpl || !class || !subclass) return FALSE; node = tmpl->attribute_list; // have to iterate through all attributes. no early exits // while (node) { CK_ATTRIBUTE *attr = (CK_ATTRIBUTE *)node->data; if (attr->type == CKA_CLASS) { *class = *(CK_OBJECT_CLASS *)attr->pValue; found = TRUE; } // underneath, these guys are both CK_ULONG so we could combine this // if (attr->type == CKA_CERTIFICATE_TYPE) *subclass = *(CK_CERTIFICATE_TYPE *)attr->pValue; if (attr->type == CKA_KEY_TYPE) *subclass = *(CK_KEY_TYPE *)attr->pValue; node = node->next; } return found; } // // CK_ULONG template_get_count( TEMPLATE *tmpl ) { if (tmpl == NULL) return 0; return dlist_length( tmpl->attribute_list ); } // // CK_ULONG template_get_size( TEMPLATE *tmpl ) { DL_NODE * node; CK_ULONG size = 0; if (tmpl == NULL) return 0; node = tmpl->attribute_list; while (node) { CK_ATTRIBUTE *attr = (CK_ATTRIBUTE *)node->data; size += sizeof(CK_ATTRIBUTE) + attr->ulValueLen; node = node->next; } return size; } // // CK_ULONG template_get_compressed_size( TEMPLATE *tmpl ) { DL_NODE * node; CK_ULONG size = 0; if (tmpl == NULL) return 0; node = tmpl->attribute_list; while (node) { CK_ATTRIBUTE *attr = (CK_ATTRIBUTE *)node->data; size += sizeof(CK_ATTRIBUTE_32); if ( ( attr->type == CKA_CLASS || attr->type == CKA_KEY_TYPE || attr->type == CKA_MODULUS_BITS || attr->type == CKA_VALUE_BITS || attr->type == CKA_CERTIFICATE_TYPE || attr->type == CKA_VALUE_LEN ) && attr->ulValueLen != 0 ) { size += sizeof(CK_ULONG_32); } else { size += attr->ulValueLen; } node = node->next; } return size; } // template_is_okay_to_reveal_attribute() // // determines whether the specified CK_ATTRIBUTE_TYPE is allowed to // be leave the card in the clear. note: the specified template doesn't need // to actually posess an attribute of type 'type'. The template is // provided mainly to determine the object class and subclass // // this routine is called by C_GetAttributeValue which exports the attributes // in the clear. this routine is NOT called when wrapping a key. // CK_BBOOL template_check_exportability( TEMPLATE *tmpl, CK_ATTRIBUTE_TYPE type ) { CK_ATTRIBUTE * attr = NULL; CK_ULONG class; CK_ULONG subclass; CK_BBOOL val; if (!tmpl) return FALSE; // since 'tmpl' belongs to a validated object, it's safe to assume that // the following routine works // template_get_class( tmpl, &class, &subclass ); // Early exits: // 1) CKA_SENSITIVE and CKA_EXTRACTABLE only apply to private key // and secret key objects. If object type is any other, then // by default the attribute is exportable. // // 2) If CKA_SENSITIVE = FALSE then all attributes are exportable // if (class != CKO_PRIVATE_KEY && class != CKO_SECRET_KEY) return TRUE; val = template_attribute_find( tmpl, CKA_SENSITIVE, &attr ); if (val) { val = *(CK_BBOOL *)attr->pValue; if (val == FALSE) return TRUE; } else { // technically, we should throw an error here... // return FALSE; } // at this point, we know the object must have CKA_SENSITIVE = TRUE. // need to determine whether the particular attribute in question is // a "sensitive" attribute. // if (class == CKO_PRIVATE_KEY) { switch (subclass) { case CKK_RSA: return rsa_priv_check_exportability( type ); case CKK_DSA: return dsa_priv_check_exportability( type ); case CKK_ECDSA: return ecdsa_priv_check_exportability( type ); case CKK_DH: return dh_priv_check_exportability( type ); case CKK_KEA: return kea_priv_check_exportability( type ); default: st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; // unknown key type } } else if (class == CKO_SECRET_KEY) { return secret_key_check_exportability( type ); } st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } // template_merge() // // Merge two templates together: dest = dest U src // // src is destroyed in the process // CK_RV template_merge( TEMPLATE *dest, TEMPLATE **src ) { DL_NODE *node; CK_RV rc; if (!dest || !src){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } node = (*src)->attribute_list; while (node) { CK_ATTRIBUTE *attr = (CK_ATTRIBUTE *)node->data; rc = template_update_attribute( dest, attr ); if (rc != CKR_OK){ st_err_log(178, __FILE__, __LINE__); return rc; } // we've assigned the node's data to a node in 'dest' // node->data = NULL; node = node->next; } template_free( *src ); *src = NULL; return CKR_OK; } // template_set_default_common_attributes() // // Set the default attributes common to all objects: // // CKA_TOKEN : FALSE // CKA_PRIVATE : TRUE -- Cryptoki leaves this up to the token to decide // CKA_MODIFIABLE : TRUE // CKA_LABEL : empty string // CK_RV template_set_default_common_attributes( TEMPLATE *tmpl ) { CK_ATTRIBUTE * token_attr; CK_ATTRIBUTE * priv_attr; CK_ATTRIBUTE * mod_attr; CK_ATTRIBUTE * label_attr; // add the default common attributes // token_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); priv_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); mod_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); label_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + 0 ); if (!token_attr || !priv_attr || !mod_attr || !label_attr) { if (token_attr) free( token_attr ); if (priv_attr) free( priv_attr ); if (mod_attr) free( mod_attr ); if (label_attr) free( label_attr); st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } token_attr->type = CKA_TOKEN; token_attr->ulValueLen = sizeof(CK_BBOOL); token_attr->pValue = (CK_BYTE *)token_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)token_attr->pValue = FALSE; priv_attr->type = CKA_PRIVATE; priv_attr->ulValueLen = sizeof(CK_BBOOL); priv_attr->pValue = (CK_BYTE *)priv_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)priv_attr->pValue = FALSE; mod_attr->type = CKA_MODIFIABLE; mod_attr->ulValueLen = sizeof(CK_BBOOL); mod_attr->pValue = (CK_BYTE *)mod_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)mod_attr->pValue = TRUE; label_attr->type = CKA_LABEL; label_attr->ulValueLen = 0; // empty string label_attr->pValue = NULL; template_update_attribute( tmpl, token_attr ); template_update_attribute( tmpl, priv_attr ); template_update_attribute( tmpl, mod_attr ); template_update_attribute( tmpl, label_attr ); // the TEMPLATE 'owns' the attributes now. it is responsible for freeing them // upon deletion... // return CKR_OK; } // template_update_attribute() // // modifies an existing attribute or adds a new attribute to the template // // Returns: TRUE on success, FALSE on failure // CK_RV template_update_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *new_attr ) { DL_NODE * node = NULL; CK_ATTRIBUTE * attr = NULL; if (!tmpl || !new_attr){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } node = tmpl->attribute_list; // if the attribute already exists in the list, remove it. this algorithm will // limit an attribute to appearing at most once in the list // while (node != NULL) { attr = (CK_ATTRIBUTE *)node->data; if (new_attr->type == attr->type) { free( attr ); tmpl->attribute_list = dlist_remove_node( tmpl->attribute_list, node ); break; } node = node->next; } // add the new attribute // tmpl->attribute_list = dlist_add_as_first( tmpl->attribute_list, new_attr ); return CKR_OK; } // template_validate_attribute() // // essentially a group of if-then-else-switch clauses. separated from // template_validate_attributes() to make that routine more readable // CK_RV template_validate_attribute( TEMPLATE * tmpl, CK_ATTRIBUTE * attr, CK_ULONG class, CK_ULONG subclass, CK_ULONG mode ) { if (class == CKO_DATA) return data_object_validate_attribute( tmpl, attr, mode ); else if (class == CKO_CERTIFICATE) { if (subclass == CKC_X_509) return cert_x509_validate_attribute( tmpl, attr, mode ); else return cert_vendor_validate_attribute( tmpl, attr, mode ); } else if (class == CKO_PUBLIC_KEY) { switch (subclass) { case CKK_RSA: return rsa_publ_validate_attribute( tmpl, attr, mode ); case CKK_DSA: return dsa_publ_validate_attribute( tmpl, attr, mode ); case CKK_ECDSA: return ecdsa_publ_validate_attribute( tmpl, attr, mode ); case CKK_DH: return dh_publ_validate_attribute( tmpl, attr, mode ); case CKK_KEA: return kea_publ_validate_attribute( tmpl, attr, mode ); default: st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; // unknown key type } } else if (class == CKO_PRIVATE_KEY) { switch (subclass) { case CKK_RSA: return rsa_priv_validate_attribute( tmpl, attr, mode ); case CKK_DSA: return dsa_priv_validate_attribute( tmpl, attr, mode ); case CKK_ECDSA: return ecdsa_priv_validate_attribute( tmpl, attr, mode ); case CKK_DH: return dh_priv_validate_attribute( tmpl, attr, mode ); case CKK_KEA: return kea_priv_validate_attribute( tmpl, attr, mode ); default: st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; // unknown key type } } else if (class == CKO_SECRET_KEY) { switch (subclass) { case CKK_GENERIC_SECRET: return generic_secret_validate_attribute( tmpl, attr, mode ); case CKK_RC2: return rc2_validate_attribute( tmpl, attr, mode ); case CKK_RC4: return rc4_validate_attribute( tmpl, attr, mode ); case CKK_RC5: return rc5_validate_attribute( tmpl, attr, mode ); case CKK_DES: return des_validate_attribute( tmpl, attr, mode ); case CKK_DES2: return des2_validate_attribute( tmpl, attr, mode ); case CKK_DES3: return des3_validate_attribute( tmpl, attr, mode ); case CKK_CAST: return cast_validate_attribute( tmpl, attr, mode ); case CKK_CAST3: return cast3_validate_attribute( tmpl, attr, mode ); case CKK_CAST5: return cast5_validate_attribute( tmpl, attr, mode ); case CKK_IDEA: return idea_validate_attribute( tmpl, attr, mode ); #if !(NOCDMF) case CKK_CDMF: return cdmf_validate_attribute( tmpl, attr, mode ); #endif case CKK_SKIPJACK: return skipjack_validate_attribute( tmpl, attr, mode ); case CKK_BATON: return baton_validate_attribute( tmpl, attr, mode ); case CKK_JUNIPER: return juniper_validate_attribute( tmpl, attr, mode ); case CKK_AES: return aes_validate_attribute( tmpl, attr, mode ); default: st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; // unknown key type } } else if (class == CKO_HW_FEATURE) { switch (subclass) { case CKH_CLOCK: return clock_validate_attribute( tmpl, attr, mode ); case CKH_MONOTONIC_COUNTER: return counter_validate_attribute( tmpl, attr, mode ); default: st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } } else if (class == CKO_DOMAIN_PARAMETERS) { switch (subclass) { case CKK_DSA: return dp_dsa_validate_attribute( tmpl, attr, mode ); case CKK_DH: return dp_dh_validate_attribute( tmpl, attr, mode ); case CKK_X9_42_DH: return dp_x9dh_validate_attribute( tmpl, attr, mode ); default: st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } } st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; // default fallthru } // template_validate_attributes() // // walk through the list of attributes in the template validating each one // CK_RV template_validate_attributes( TEMPLATE * tmpl, CK_ULONG class, CK_ULONG subclass, CK_ULONG mode ) { DL_NODE *node; CK_RV rc = CKR_OK; node = tmpl->attribute_list; while (node) { CK_ATTRIBUTE *attr = (CK_ATTRIBUTE *)node->data; rc = template_validate_attribute( tmpl, attr, class, subclass, mode ); if (rc != CKR_OK){ st_err_log(140, __FILE__, __LINE__); return rc; } node = node->next; } return CKR_OK; } // template_validate_base_attribute() // CK_RV template_validate_base_attribute( TEMPLATE * tmpl, CK_ATTRIBUTE * attr, CK_ULONG mode ) { if (!tmpl || !attr){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } switch (attr->type) { case CKA_CLASS: if ((mode & (MODE_CREATE|MODE_DERIVE|MODE_KEYGEN|MODE_UNWRAP)) != 0) return CKR_OK; break; case CKA_TOKEN: if ((mode & (MODE_CREATE|MODE_COPY|MODE_DERIVE|MODE_KEYGEN|MODE_UNWRAP)) != 0) return CKR_OK; break; case CKA_PRIVATE: if ((mode & (MODE_CREATE|MODE_COPY|MODE_DERIVE|MODE_KEYGEN|MODE_UNWRAP)) != 0) return CKR_OK; break; case CKA_LABEL: return CKR_OK; case CKA_MODIFIABLE: if ((mode & (MODE_CREATE|MODE_COPY|MODE_DERIVE|MODE_KEYGEN|MODE_UNWRAP)) != 0) return CKR_OK; break; default: st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/mech_rng.c0000751000175000017500000003673311327631345020661 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: mech_rng.c // // Mechanisms for Random Numbers // // PKCS #11 doesn't consider random number generator to be a "mechanism" // #include #include // for memcmp() et al #include #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" #include "tok_specific.h" // // CK_RV rng_generate( CK_BYTE *output, CK_ULONG bytes ) { CK_RV rc; rc = token_rng(output, bytes); if (rc != CKR_OK) st_err_log(111, __FILE__, __LINE__); return rc; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/defs.h0000751000175000017500000005074611327631345020025 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/lib/pkcs11/common/defs.h,v 1.5 2008/07/16 22:27:48 mhalcrow Exp $ */ // /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: defs.h // // Contains various definitions needed by both the host-side // and coprocessor-side code. // #ifndef _DEFS_H #define _DEFS_H #if (LEEDS) #pragma pack(1) #pragma options align=packed #endif #if (LEEDS) #include #else #define PACK_DATA #endif #define MAX_SESSION_COUNT 64 #define MAX_PIN_LEN 8 #define MIN_PIN_LEN 4 #define MAX_SLOT_ID 10 #define LEEDS_MAX_REQ_LEN 4096 #ifndef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif // the following constants are used for sccSignOn // #define PKCS_11_PRG_ID "pkcs11 2.01" #define PKCS_11_DEVELOPER_ID 0xE #define PKCS_11_VERSION 1 #define PKCS_11_INSTANCE 0 #define PKCS_11_QUEUE 0 #define LEEDS_PRG_ID_PKCS_11 "PKCS11" // the following are "boolean" attributes // #define CKA_IBM_TWEAK_ALLOW_KEYMOD 0x80000001 #define CKA_IBM_TWEAK_ALLOW_WEAK_DES 0x80000002 #define CKA_IBM_TWEAK_DES_PARITY_CHK 0x80000003 #define CKA_IBM_TWEAK_NETSCAPE 0x80000004 #define MODE_COPY (1 << 0) #define MODE_CREATE (1 << 1) #define MODE_KEYGEN (1 << 2) #define MODE_MODIFY (1 << 3) #define MODE_DERIVE (1 << 4) #define MODE_UNWRAP (1 << 5) // RSA block formatting types // #define PKCS_BT_1 1 #define PKCS_BT_2 2 #define OP_ENCRYPT_INIT 1 #define OP_DECRYPT_INIT 2 #define OP_WRAP 3 #define OP_UNWRAP 4 #define OP_SIGN_INIT 5 #define OP_VERIFY_INIT 6 // saved-state identifiers // enum { STATE_INVALID = 0, STATE_ENCR, STATE_DECR, STATE_DIGEST, STATE_SIGN, STATE_VERIFY }; #define AES_KEY_SIZE_256 32 #define AES_KEY_SIZE_192 24 #define AES_KEY_SIZE_128 16 #define AES_BLOCK_SIZE 16 #define AES_INIT_VECTOR_SIZE AES_BLOCK_SIZE #define DES_KEY_SIZE 8 #define DES_BLOCK_SIZE 8 #define SHA1_HASH_SIZE 20 #define SHA1_BLOCK_SIZE 64 #define SHA1_BLOCK_SIZE_MASK (SHA1_BLOCK_SIZE - 1) #define SHA2_HASH_SIZE 32 #define SHA2_BLOCK_SIZE 64 #define SHA2_BLOCK_SIZE_MASK (SHA2_BLOCK_SIZE - 1) #define SHA3_HASH_SIZE 48 #define SHA3_BLOCK_SIZE 128 #define SHA3_BLOCK_SIZE_MASK (SHA3_BLOCK_SIZE - 1) #define SHA5_HASH_SIZE 64 #define SHA5_BLOCK_SIZE 128 #define SHA5_BLOCK_SIZE_MASK (SHA5_BLOCK_SIZE - 1) #define MAX_SHA_HASH_SIZE SHA5_HASH_SIZE #define MAX_SHA_BLOCK_SIZE SHA5_BLOCK_SIZE #ifndef PATH_MAX #define PATH_MAX 4096 #endif struct oc_sha_ctx { unsigned char hash[MAX_SHA_HASH_SIZE + 1]; unsigned int hash_len, tail_len; int message_part; /* needs to be seen across calls to update and final */ unsigned char tail[MAX_SHA_BLOCK_SIZE]; /* save the last (up to) block-size * bytes which may need to be shaved */ void *dev_ctx; }; #define MD2_HASH_SIZE 16 #define MD2_BLOCK_SIZE 48 #define MD5_HASH_SIZE 16 #define MD5_BLOCK_SIZE 64 #define DSA_SIGNATURE_SIZE 40 #define DEFAULT_SO_PIN "87654321" typedef enum { ALL = 1, PRIVATE, PUBLIC } SESS_OBJ_TYPE; #if (LEEDS_BUILD) enum cmdconst { FIRST_ENTRY = 0, DUMMYFUNCTION = 1, FCVFUNCTION, UPDATETWEAKVALUES, QUERYTWEAKVALUES, PK_DES_KEYGEN, PK_CDMF_KEYGEN, PK_CDMF_TRANSFORM_KEY, PK_RSA_KEYPAIR_GEN, PK_DSA_KEYPAIR_GEN, PK_GENERATE_RND, PK_DES_ECB_ENCRYPT, PK_DES_ECB_DECRYPT, PK_DES_CBC_ENCRYPT, PK_DES_CBC_DECRYPT, PK_DES3_ECB_ENCRYPT, PK_DES3_ECB_DECRYPT, PK_DES3_CBC_ENCRYPT, PK_DES3_CBC_DECRYPT, PK_RSA_ENCRYPT, PK_RSA_DECRYPT, PK_DSA_SIGN, PK_DSA_VERIFY, PK_SHA1_DIGEST, PK_SHA1_UPDATE, PK_SHA1_FINAL, LAST_ENTRY }; typedef struct _LEEDS_REQUEST { CK_ULONG pid; CK_ULONG req_len; // size of request data CK_ULONG repl_max[4]; // any command-specific request data gets appended here // } PACK_DATA LEEDS_REQUEST; typedef struct _LEEDS_REPLY { CK_RV rc; CK_ULONG repl_len[4]; // size of data // any command-specific reply data gets appended here // } PACK_DATA LEEDS_REPLY; #endif // this is a flattened version of the CK_SSL3_RANDOM_DATA // typedef struct _SSL3_RANDOM_DATA { CK_ULONG client_data_len; CK_ULONG server_data_len; // client data is appended here // server data is appended here // } PACK_DATA SSL3_RANDOM_DATA; // // typedef struct _SSL3_MASTER_KEY_DERIVE_PARAMS { CK_VERSION version; CK_ULONG client_data_len; CK_ULONG server_data_len; // client data is appended here // server data is appended here // } PACK_DATA SSL3_MASTER_KEY_DERIVE_PARAMS; // // typedef struct _SSL3_KEY_MAT_OUT { CK_OBJECT_HANDLE client_mac_secret; CK_OBJECT_HANDLE server_mac_secret; CK_OBJECT_HANDLE client_key; CK_OBJECT_HANDLE server_key; CK_ULONG iv_len; // in bytes // client IV is appended here // server IV is appended here // } PACK_DATA SSL3_KEY_MAT_OUT; // // typedef struct _SSL3_KEY_MAT_PARAMS { CK_ULONG mac_size_bits; CK_ULONG key_size_bits; CK_ULONG iv_size_bits; CK_BBOOL export; CK_ULONG client_data_len; CK_ULONG server_data_len; // client data is appended here // server data is appended here // } PACK_DATA SSL3_KEY_MAT_PARAMS; typedef struct _DL_NODE { struct _DL_NODE *next; struct _DL_NODE *prev; void *data; } DL_NODE; // Abstract this out and include a token specific headerfile #include #define PK_LITE_NV "NVTOK.DAT" #define PK_LITE_OBJ_DIR "TOK_OBJ" #define PK_LITE_OBJ_IDX "OBJ.IDX" #define DEL_CMD "/bin/rm -f" #if (LEEDS) #pragma options align=full #pragma pack() #endif #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/mech_list.c0000640000175000017500000004207311327631345021035 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* COPYRIGHT (c) International Business Machines Corp. 2005 */ #include #include #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" void mech_array_to_list(struct mech_list_item *head, MECH_LIST_ELEMENT mech_list_arr[], int list_len) { int i; struct mech_list_item *current; current = head; for (i = 0; i < list_len; i++) { current->next = malloc(sizeof(struct mech_list_item)); current = current->next; memcpy(¤t->element, &mech_list_arr[i], sizeof(MECH_LIST_ELEMENT)); } } struct mech_list_item * find_mech_list_item_for_type(CK_MECHANISM_TYPE type, struct mech_list_item *head) { struct mech_list_item *res; res = head->next; while (res) { if (res->element.mech_type == type) { goto out; } res = res->next; } out: return res; } void free_mech_list(struct mech_list_item *head) { struct mech_list_item *walker; walker = head->next; while (walker) { struct mech_list_item *next; next = walker->next; free(walker); walker = next; } } /** * If a type exists in the source that is not in the target, copy it * over. If a type exists in both the source and the target, overwrite * the target. */ void merge_mech_lists(struct mech_list_item *head_of_target, struct mech_list_item *head_of_source) { } CK_RV ock_generic_get_mechanism_list(CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount) { int rc = CKR_OK; unsigned int i; if (pMechanismList == NULL) { (*pulCount) = mech_list_len; goto out; } if ((*pulCount) < mech_list_len) { (*pulCount) = mech_list_len; st_err_log(111, __FILE__, __LINE__); rc = CKR_BUFFER_TOO_SMALL; goto out; } for (i=0; i < mech_list_len; i++) pMechanismList[i] = mech_list[i].mech_type; (*pulCount) = mech_list_len; out: return rc; } CK_RV ock_generic_get_mechanism_info(CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo) { int rc = CKR_OK; unsigned int i; for (i=0; i < mech_list_len; i++) { if (mech_list[i].mech_type == type) { memcpy(pInfo, &mech_list[i].mech_info, sizeof(CK_MECHANISM_INFO)); goto out; } } st_err_log(28, __FILE__, __LINE__); rc = CKR_MECHANISM_INVALID; out: return rc; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/h_extern.h0000751000175000017500000033523011327631345020712 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/lib/pkcs11/common/h_extern.h,v 1.10 2007/12/05 22:52:01 mhalcrow Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ /*************************************************************************** Change Log ========== 4/25/03 Kapil Sood (kapil@corrent.com) Added DH key pair generation and DH shared key derivation functions. ****************************************************************************/ #ifndef _H_EXTERN_H #define _H_EXTERN_H #include #include "msg.h" #if (LEEDS_BUILD) #pragma options align=packed #endif extern char * pk_dir; // global variables // extern CK_BBOOL initialized; extern char *card_function_names[]; extern char *total_function_names[]; extern MECH_LIST_ELEMENT mech_list[]; extern CK_ULONG mech_list_len; extern pthread_mutex_t native_mutex; #if SYSVSEM extern int xprocsemid; #endif extern void *xproclock; extern MUTEX pkcs_mutex, obj_list_mutex, sess_list_mutex, login_mutex; extern DL_NODE *sess_list; extern DL_NODE *sess_obj_list; extern DL_NODE *publ_token_obj_list; extern DL_NODE *priv_token_obj_list; extern DL_NODE *object_map; extern CK_BYTE master_key[3*DES_KEY_SIZE]; extern CK_BYTE so_pin_md5[MD5_HASH_SIZE]; extern CK_BYTE user_pin_md5[MD5_HASH_SIZE]; extern CK_BYTE default_user_pin_sha[SHA1_HASH_SIZE]; extern CK_BYTE default_so_pin_sha[SHA1_HASH_SIZE]; extern CK_BYTE default_so_pin_md5[MD5_HASH_SIZE]; extern LW_SHM_TYPE *global_shm; extern TOKEN_DATA *nv_token_data; extern CK_SLOT_INFO slot_info; extern CK_ULONG next_object_handle; extern CK_ULONG next_session_handle; // SAB FIXME FIXME extern CK_STATE global_login_state; extern CK_BYTE ber_AlgIdRSAEncryption[]; extern CK_ULONG ber_AlgIdRSAEncryptionLen; extern CK_BYTE ber_rsaEncryption[]; extern CK_ULONG ber_rsaEncryptionLen; extern CK_BYTE ber_idDSA[]; extern CK_ULONG ber_idDSALen; extern CK_BYTE ber_md2WithRSAEncryption[]; extern CK_ULONG ber_md2WithRSAEncryptionLen; extern CK_BYTE ber_md4WithRSAEncryption[]; extern CK_ULONG ber_md4WithRSAEncryptionLen; extern CK_BYTE ber_md5WithRSAEncryption[]; extern CK_ULONG ber_md5WithRSAEncryptionLen; extern CK_BYTE ber_sha1WithRSAEncryption[]; extern CK_ULONG ber_sha1WithRSAEncryptionLen; extern CK_BYTE ber_AlgMd2[]; extern CK_ULONG ber_AlgMd2Len; extern CK_BYTE ber_AlgMd5[]; extern CK_ULONG ber_AlgMd5Len; extern CK_BYTE ber_AlgSha1[]; extern CK_ULONG ber_AlgSha1Len; extern CK_BYTE ber_AlgSha256[]; extern CK_ULONG ber_AlgSha256Len; extern CK_ULONG des_weak_count; extern CK_ULONG des_semi_weak_count; extern CK_ULONG des_possibly_weak_count; extern CK_BYTE des_weak_keys[4][8]; extern CK_BYTE des_semi_weak_keys[12][8]; extern CK_BYTE des_possibly_weak_keys[48][8]; extern struct ST_FCN_LIST function_list; extern CK_C_INITIALIZE_ARGS cinit_args; CK_ULONG long_reverse( CK_ULONG x ); // VACPP C runtime initialization/cleanup entry points // int _CRT_init(void); int _CRT_term(void); CK_RV DummyFunction( CK_SLOT_ID slot_id, int arg ); // General-purpose functions // CK_RV C_Initialize ( CK_VOID_PTR pInitArgs ); CK_RV C_Finalize ( CK_VOID_PTR pReserved ); CK_RV C_GetInfo ( CK_INFO_PTR pInfo ); CK_RV C_GetFunctionList ( CK_FUNCTION_LIST_PTR_PTR ppFunctionList ); // Slot and token management functions // CK_RV C_GetSlotList ( CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount ); CK_RV C_GetSlotInfo ( CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo ); CK_RV C_GetTokenInfo ( CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo ); CK_RV C_WaitForSlotEvent ( CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved ); CK_RV C_GetMechanismList ( CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount ); CK_RV C_GetMechanismInfo ( CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo ); CK_RV C_InitToken ( CK_SLOT_ID slotID, CK_CHAR_PTR pPin, CK_ULONG ulPinLen, CK_CHAR_PTR pLabel ); CK_RV C_InitPIN ( CK_SESSION_HANDLE hSession, CK_CHAR_PTR pPin, CK_ULONG ulPinLen ); CK_RV C_SetPIN ( CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, CK_ULONG ulOldLen, CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen ); // Session management functions // CK_RV C_OpenSession ( CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession ); CK_RV C_CloseSession ( CK_SESSION_HANDLE hSession ); CK_RV C_CloseAllSessions ( CK_SLOT_ID slotID ); CK_RV C_GetSessionInfo ( CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo ); CK_RV C_GetOperationState ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen ); CK_RV C_SetOperationState ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey ); CK_RV C_Login ( CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG uPinLen ); CK_RV C_Logout ( CK_SESSION_HANDLE hSession ); // Object management functions // CK_RV C_CreateObject ( CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject ); CK_RV C_CopyObject ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phNewObject ); CK_RV C_DestroyObject ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject ); CK_RV C_GetObjectSize ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize ); CK_RV C_GetAttributeValue ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ); CK_RV C_SetAttributeValue ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ); CK_RV C_FindObjectsInit ( CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ); CK_RV C_FindObjects ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount ); CK_RV C_FindObjectsFinal ( CK_SESSION_HANDLE hSession ); // Encryption functions // CK_RV C_EncryptInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_Encrypt ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen ); CK_RV C_EncryptUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ); CK_RV C_EncryptFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen); // Decryption functions // CK_RV C_DecryptInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_Decrypt ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen ); CK_RV C_DecryptUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ); CK_RV C_DecryptFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen ); // Message digesting functions // CK_RV C_DigestInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism ); CK_RV C_Digest ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen ); CK_RV C_DigestUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ); CK_RV C_DigestKey ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey ); CK_RV C_DigestFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen ); // Signing and MAC functions // CK_RV C_SignInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_Sign ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ); CK_RV C_SignUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ); CK_RV C_SignFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ); CK_RV C_SignRecoverInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_SignRecover ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ); // Signature/MAC verification functions // CK_RV C_VerifyInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_Verify ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen ); CK_RV C_VerifyUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ); CK_RV C_VerifyFinal ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen ); CK_RV C_VerifyRecoverInit ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ); CK_RV C_VerifyRecover ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen ); // Dual-function cryptographics functions // CK_RV C_DigestEncryptUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ); CK_RV C_DecryptDigestUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ); CK_RV C_SignEncryptUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ); CK_RV C_DecryptVerifyUpdate ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ); // Key management functions // CK_RV C_GenerateKey ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey ); CK_RV C_GenerateKeyPair ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey ); CK_RV C_WrapKey ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen ); CK_RV C_UnwrapKey ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey ); CK_RV C_DeriveKey ( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey ); // Random number generation functions // CK_RV C_SeedRandom ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen ); CK_RV C_GenerateRandom ( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen ); // Parallel function management functions // CK_RV C_GetFunctionStatus ( CK_SESSION_HANDLE hSession ); CK_RV C_CancelFunction ( CK_SESSION_HANDLE hSession ); // // internal routines are below this point // CK_RV clock_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV clock_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV clock_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode); CK_RV counter_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV counter_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV counter_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode); CK_RV dp_dsa_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode); CK_RV dp_dsa_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dp_dsa_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode); CK_RV dp_dh_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode); CK_RV dp_dh_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dp_dh_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode); CK_RV dp_x9dh_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode); CK_RV dp_x9dh_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dp_x9dh_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode); CK_RV communicate( CK_ULONG cmd_id, CK_VOID_PTR pReq, CK_ULONG req_len, CK_VOID_PTR pRep, CK_ULONG_PTR repl_len, CK_BYTE_PTR pOut, CK_ULONG out_len, CK_BYTE_PTR pIn, CK_ULONG in_len ); CK_RV compute_next_token_obj_name( CK_BYTE *current, CK_BYTE *next ); CK_RV save_token_object ( OBJECT *obj ); CK_RV save_public_token_object ( OBJECT *obj ); CK_RV save_private_token_object( OBJECT *obj ); CK_RV load_public_token_objects ( void ); CK_RV load_private_token_objects( void ); CK_RV reload_token_object( OBJECT *obj ); CK_RV restore_private_token_object( CK_BYTE * data, CK_ULONG len, OBJECT * pObj ); CK_RV delete_token_object( OBJECT *ptr ); CK_RV init_token_data( void ); CK_RV load_token_data( void ); CK_RV save_token_data( void ); CK_RV load_masterkey_so ( void ); CK_RV load_masterkey_user( void ); CK_RV save_masterkey_so ( void ); CK_RV save_masterkey_user( void ); CK_RV compute_md5( CK_BYTE *data, CK_ULONG len, CK_BYTE *hash ); CK_RV compute_sha( CK_BYTE *data, CK_ULONG len, CK_BYTE *hash ); CK_ULONG long_reverse( CK_ULONG x ); //CK_RV load_FCV( void ); //CK_RV save_FCV( FUNCTION_CTRL_VEC_RECORD *new_FCV ); //CK_RV update_tweak_values( void *attributes, CK_ULONG count ); //CK_RV query_tweak_values( CK_ATTRIBUTE_TYPE * attributes, // CK_ULONG count, // CK_BYTE ** reply, // CK_ULONG * reply_len ); void init_slotInfo(void); void init_tokenInfo(void); CK_BYTE parity_adjust( CK_BYTE b ); CK_RV parity_is_odd( CK_BYTE b ); CK_RV build_attribute( CK_ATTRIBUTE_TYPE type, CK_BYTE *data, CK_ULONG data_len, CK_ATTRIBUTE **attr ); CK_RV add_pkcs_padding( CK_BYTE * ptr, // where to start appending CK_ULONG block_size, CK_ULONG data_len, CK_ULONG total_len ); CK_RV strip_pkcs_padding( CK_BYTE * ptr, CK_ULONG total_len, CK_ULONG * data_len ); CK_RV remove_leading_zeros( CK_ATTRIBUTE *attr ); // RNG routines // CK_RV rng_generate( CK_BYTE *output, CK_ULONG bytes ); // SSL3 routines // CK_RV ssl3_mac_sign( SESSION *sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV ssl3_mac_sign_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ); CK_RV ssl3_mac_sign_final( SESSION *sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV ssl3_mac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); CK_RV ssl3_mac_verify_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ); CK_RV ssl3_mac_verify_final( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len ); CK_RV ssl3_master_key_derive( SESSION * sess, CK_MECHANISM * mech, CK_OBJECT_HANDLE base_key, CK_ATTRIBUTE * attributes, CK_ULONG count, CK_OBJECT_HANDLE * handle ); CK_RV ssl3_key_and_mac_derive( SESSION * sess, CK_MECHANISM * mech, CK_OBJECT_HANDLE base_key, CK_ATTRIBUTE * attributes, CK_ULONG count ); CK_RV ckm_ssl3_pre_master_key_gen( TEMPLATE *tmpl, CK_MECHANISM *mech ); // RSA routines // CK_RV rsa_pkcs_encrypt( SESSION * sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV rsa_pkcs_decrypt( SESSION * sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV rsa_pkcs_sign ( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG * sig_len ); CK_RV rsa_pkcs_verify ( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); CK_RV rsa_pkcs_verify_recover ( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len, CK_BYTE * out_data, CK_ULONG * out_len ); CK_RV rsa_x509_encrypt ( SESSION * sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV rsa_x509_decrypt ( SESSION * sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV rsa_x509_sign ( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG * sig_len ); CK_RV rsa_x509_verify ( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); CK_RV rsa_x509_verify_recover( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len, CK_BYTE * out_data, CK_ULONG * out_len ); CK_RV rsa_hash_pkcs_sign ( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG * sig_len ); CK_RV rsa_hash_pkcs_verify ( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); CK_RV rsa_hash_pkcs_sign_update ( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ); CK_RV rsa_hash_pkcs_verify_update ( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ); CK_RV rsa_hash_pkcs_sign_final ( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG * sig_len ); CK_RV rsa_hash_pkcs_verify_final ( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len ); // RSA mechanisms // CK_RV ckm_rsa_key_pair_gen( TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl ); CK_RV ckm_rsa_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, OBJECT * key_obj ); CK_RV ckm_rsa_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, OBJECT * key_obj ); CK_RV ckm_rsa_compute_priv_exp( TEMPLATE *tmpl ); #ifndef NODSA // DSA routines // CK_RV dsa_sign ( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG * sig_len ); CK_RV dsa_verify ( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); // DSA mechanisms // CK_RV ckm_dsa_key_pair_gen( TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl ); CK_RV ckm_dsa_sign( CK_BYTE *in_data, // must be 20 bytes CK_BYTE *signature, // must be 40 bytes OBJECT *priv_key ); CK_RV ckm_dsa_verify( CK_BYTE *signature, // must be 40 bytes CK_BYTE *data, // must be 20 bytes OBJECT *publ_key ); #endif /* Begin code contributed by Corrent corp. */ // DH routines // #ifndef NODH CK_RV dh_pkcs_derive( SESSION * sess, CK_MECHANISM * mech, CK_OBJECT_HANDLE base_key, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE * handle ) ; // DH mechanisms // CK_RV ckm_dh_pkcs_derive( CK_VOID_PTR other_pubkey, CK_ULONG other_pubkey_len, CK_OBJECT_HANDLE base_key, CK_BYTE *secret, CK_ULONG *secret_len ) ; CK_RV ckm_dh_key_pair_gen( TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl ); CK_RV ckm_dh_pkcs_key_pair_gen( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ); #endif /* End code contributed by Corrent corp. */ // DES routines - I have to provide two different versions of these // because encryption routines are also used internally // so we can't assume that external-to-external buffering // will be possible and combining them into a single // function is messy. // CK_RV pk_des_ecb_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_ecb_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV pk_des_cbc_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_pad_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_pad_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_ecb_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_ecb_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_pad_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_pad_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_ecb_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_ecb_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_pad_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_cbc_pad_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des_ecb_wrap_key( SESSION *sess, CK_BBOOL length_only, CK_MECHANISM *mech, OBJECT *key, OBJECT *encr_key, CK_BYTE *data, CK_ULONG *data_len ); // DES mechanisms // CK_RV ckm_des_key_gen ( TEMPLATE *tmpl ); CK_RV ckm_cdmf_key_gen( TEMPLATE *tmpl ); CK_RV ckm_des_ecb_encrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value ); CK_RV ckm_des_ecb_decrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value ); CK_RV ckm_des_cbc_encrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *init_v, CK_BYTE *key_value ); CK_RV ckm_des_cbc_decrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *init_v, CK_BYTE *key_value ); CK_RV ckm_des_wrap_format( CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ); // DES3 routines // CK_RV des3_ecb_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_ecb_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_pad_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_pad_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_ecb_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_ecb_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_pad_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_pad_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_ecb_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_ecb_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_pad_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV des3_cbc_pad_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); // DES3 mechanisms // CK_RV ckm_des3_key_gen( TEMPLATE *tmpl ); CK_RV ckm_des3_ecb_encrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value ); CK_RV ckm_des3_ecb_decrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value ); CK_RV ckm_des3_cbc_encrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *init_v, CK_BYTE *key_value ); CK_RV ckm_des3_cbc_decrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *init_v, CK_BYTE *key_value ); // AES routines // CK_RV aes_ecb_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_ecb_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_pad_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_pad_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_ecb_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_ecb_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_pad_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_pad_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_ecb_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_ecb_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_pad_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV aes_cbc_pad_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *context, CK_BYTE *out_data, CK_ULONG *out_data_len ); // AES mechanisms // CK_RV ckm_aes_key_gen( TEMPLATE *tmpl ); CK_RV ckm_aes_ecb_encrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_ULONG key_len ); CK_RV ckm_aes_ecb_decrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_ULONG key_len ); CK_RV ckm_aes_cbc_encrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *init_v, CK_BYTE *key_value, CK_ULONG key_len ); CK_RV ckm_aes_cbc_decrypt( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *init_v, CK_BYTE *key_value, CK_ULONG key_len ); CK_RV ckm_aes_wrap_format( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len ); // SHA-1 mechanisms // CK_RV sha1_hash( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV sha1_hash_update( SESSION *sess, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV sha1_hash_final( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV sha1_hmac_sign( SESSION *sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV sha1_hmac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); void ckm_sha1_init( DIGEST_CONTEXT *ctx ); CK_RV ckm_sha1_update( DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV ckm_sha1_final( DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); // SHA-256 mechanisms // CK_RV sha2_hash( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV sha2_hash_update( SESSION *sess, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV sha2_hash_final( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV sha2_hmac_sign( SESSION *sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV sha2_hmac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); void ckm_sha2_init( DIGEST_CONTEXT *ctx ); CK_RV ckm_sha2_update( DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV ckm_sha2_final( DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); void ckm_sha3_init( DIGEST_CONTEXT *ctx ); CK_RV ckm_sha3_update( DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV ckm_sha3_final( DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); void ckm_sha5_init( DIGEST_CONTEXT *ctx ); CK_RV ckm_sha5_update( DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV ckm_sha5_final( DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); // MD2 mechanisms // CK_RV md2_hash( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV md2_hash_update( SESSION *sess, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV md2_hash_final( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV md2_hmac_sign( SESSION *sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV md2_hmac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); CK_RV ckm_md2_update( MD2_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV ckm_md2_final( MD2_CONTEXT *context, CK_BYTE *out_data, CK_ULONG out_data_len ); void ckm_md2_transform( CK_BYTE *state, CK_BYTE *checksum, CK_BYTE *block ); // MD5 mechanisms // CK_RV md5_hash( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV md5_hash_update( SESSION *sess, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV md5_hash_final( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV md5_hmac_sign( SESSION *sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV md5_hmac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); void ckm_md5_init( MD5_CONTEXT *context ); CK_RV ckm_md5_update( MD5_CONTEXT *context, CK_BYTE *in_data, CK_ULONG in_data_len ); CK_RV ckm_md5_final( MD5_CONTEXT *context, CK_BYTE *out_data, CK_ULONG out_data_len ); void ckm_md5_transform( CK_ULONG *buf, CK_ULONG *in ); // linked-list routines // DL_NODE * dlist_add_as_first( DL_NODE *list, void *data ); DL_NODE * dlist_add_as_last( DL_NODE *list, void *data ); DL_NODE * dlist_find( DL_NODE *list, void *data ); DL_NODE * dlist_get_first( DL_NODE *list ); DL_NODE * dlist_get_last( DL_NODE *list ); CK_ULONG dlist_length( DL_NODE *list ); DL_NODE * dlist_next( DL_NODE *list ); DL_NODE * dlist_prev( DL_NODE *list ); void dlist_purge( DL_NODE *list ); DL_NODE * dlist_remove_node( DL_NODE *list, DL_NODE *node ); CK_RV _CreateMutex( MUTEX *mutex ); CK_RV _DestroyMutex( MUTEX *mutex ); CK_RV _LockMutex( MUTEX *mutex ); CK_RV _UnlockMutex( MUTEX *mutex ); CK_RV attach_shm(void); CK_RV detach_shm(void); // encryption manager routines // CK_RV encr_mgr_init( SESSION * sess, ENCR_DECR_CONTEXT * ctx, CK_ULONG operation, CK_MECHANISM * mech, CK_OBJECT_HANDLE key_handle ); CK_RV encr_mgr_cleanup( ENCR_DECR_CONTEXT *ctx ); CK_RV encr_mgr_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV encr_mgr_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV encr_mgr_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); // decryption manager routines // CK_RV decr_mgr_init( SESSION * sess, ENCR_DECR_CONTEXT * ctx, CK_ULONG operation, CK_MECHANISM * mech, CK_OBJECT_HANDLE key_handle ); CK_RV decr_mgr_cleanup( ENCR_DECR_CONTEXT * ctx ); CK_RV decr_mgr_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV decr_mgr_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV decr_mgr_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV decr_mgr_update_des_ecb( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV decr_mgr_update_des_cbc( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV decr_mgr_update_des3_ecb( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); CK_RV decr_mgr_update_des3_cbc( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT * ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ); // digest manager routines // CK_RV digest_mgr_cleanup( DIGEST_CONTEXT *ctx ); CK_RV digest_mgr_init( SESSION *sess, DIGEST_CONTEXT *ctx, CK_MECHANISM *mech ); CK_RV digest_mgr_digest( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *data, CK_ULONG data_len, CK_BYTE *hash, CK_ULONG *hash_len ); CK_RV digest_mgr_digest_update( SESSION *sess, DIGEST_CONTEXT *ctx, CK_BYTE *data, CK_ULONG data_len ); CK_RV digest_mgr_digest_key( SESSION *sess, DIGEST_CONTEXT *ctx, CK_OBJECT_HANDLE key_handle ); CK_RV digest_mgr_digest_final( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *hash, CK_ULONG *hash_len ); // key manager routines // CK_RV key_mgr_generate_key( SESSION *sess, CK_MECHANISM *mech, CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE *key_handle ); CK_RV key_mgr_generate_key_pair( SESSION *sess, CK_MECHANISM *mech, CK_ATTRIBUTE *publ_tmpl, CK_ULONG publ_count, CK_ATTRIBUTE *priv_tmpl, CK_ULONG priv_count, CK_OBJECT_HANDLE *publ_key_handle, CK_OBJECT_HANDLE *priv_key_handle ); CK_RV key_mgr_get_private_key_type( CK_BYTE *keydata, CK_ULONG keylen, CK_KEY_TYPE *keytype ); CK_RV key_mgr_derive_key( SESSION * sess, CK_MECHANISM * mech, CK_OBJECT_HANDLE base_key, CK_OBJECT_HANDLE * derived_key, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ); CK_RV key_mgr_wrap_key( SESSION *sess, CK_BBOOL length_only, CK_MECHANISM *mech, CK_OBJECT_HANDLE h_wrapping_key, CK_OBJECT_HANDLE h_key, CK_BYTE *wrapped_key, CK_ULONG *wrapped_key_len ); CK_RV key_mgr_unwrap_key( SESSION *sess, CK_MECHANISM *mech, CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount, CK_BYTE *wrapped_key, CK_ULONG wrapped_key_len, CK_OBJECT_HANDLE unwrapping_key, CK_OBJECT_HANDLE *unwrapped_key ); CK_RV key_mgr_derive_prolog( SESSION *sess, CK_ATTRIBUTE *attributes, CK_ULONG attrcount, CK_OBJECT_HANDLE base_key, OBJECT *base_key_obj, CK_BYTE *base_key_value, CK_KEY_TYPE base_key_type, ATTRIBUTE_PARSE_LIST *parselist, CK_ULONG plcount ); // signature manager routines // CK_RV sign_mgr_init( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_MECHANISM * mech, CK_BBOOL recover_mode, CK_OBJECT_HANDLE key_handle ); CK_RV sign_mgr_cleanup( SIGN_VERIFY_CONTEXT *ctx ); CK_RV sign_mgr_sign( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV sign_mgr_sign_recover( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV sign_mgr_sign_final( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ); CK_RV sign_mgr_sign_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ); // signature verify manager routines // CK_RV verify_mgr_init( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_MECHANISM * mech, CK_BBOOL recover_mode, CK_OBJECT_HANDLE key_handle ); CK_RV verify_mgr_cleanup( SIGN_VERIFY_CONTEXT *ctx ); CK_RV verify_mgr_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ); CK_RV verify_mgr_verify_recover( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len, CK_BYTE * out_data, CK_ULONG * out_len ); CK_RV verify_mgr_verify_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ); CK_RV verify_mgr_verify_final( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len ); // session manager routines // CK_RV session_mgr_close_all_sessions( void ); CK_RV session_mgr_close_session( SESSION *sess ); SESSION * session_mgr_find( CK_SESSION_HANDLE handle ); CK_RV session_mgr_login_all ( CK_USER_TYPE user_type ); CK_RV session_mgr_logout_all( void ); CK_RV session_mgr_new( CK_ULONG flags, SESSION **sess ); CK_BBOOL session_mgr_readonly_exists( void ); CK_BBOOL session_mgr_so_session_exists ( void ); CK_BBOOL session_mgr_user_session_exists ( void ); CK_BBOOL session_mgr_public_session_exists( void ); CK_RV session_mgr_get_op_state( SESSION *sess, CK_BBOOL length_only, CK_BYTE *data, CK_ULONG *data_len ); CK_RV session_mgr_set_op_state( SESSION *sess, CK_OBJECT_HANDLE encr_key, CK_OBJECT_HANDLE auth_key, CK_BYTE *data, CK_ULONG data_len ); // object manager routines // CK_RV object_mgr_add( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE * handle ); CK_RV object_mgr_add_to_map( SESSION * sess, OBJECT * obj, CK_OBJECT_HANDLE * handle ); CK_RV object_mgr_add_to_shm ( OBJECT *obj ); CK_RV object_mgr_del_from_shm( OBJECT *obj ); CK_RV object_mgr_check_shm ( OBJECT *obj ); CK_RV object_mgr_search_shm_for_obj( TOK_OBJ_ENTRY * list, CK_ULONG lo, CK_ULONG hi, OBJECT * obj, CK_ULONG * index ); CK_RV object_mgr_sort_priv_shm( void ); CK_RV object_mgr_sort_publ_shm( void ); CK_RV object_mgr_update_from_shm( void ); CK_RV object_mgr_update_publ_tok_obj_from_shm(); CK_RV object_mgr_update_priv_tok_obj_from_shm(); CK_RV object_mgr_copy( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE old_obj, CK_OBJECT_HANDLE * new_obj ); CK_RV object_mgr_create_final( SESSION *sess, OBJECT *obj, CK_OBJECT_HANDLE *handle ); CK_RV object_mgr_create_skel( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_ULONG mode, CK_ULONG class, CK_ULONG subclass, OBJECT ** obj ); CK_RV object_mgr_destroy_object( SESSION * sess, CK_OBJECT_HANDLE handle ); CK_RV object_mgr_destroy_token_objects( void ); CK_RV object_mgr_find_in_map_nocache( CK_OBJECT_HANDLE handle, OBJECT ** ptr ); CK_RV object_mgr_find_in_map1( CK_OBJECT_HANDLE handle, OBJECT ** ptr ); CK_RV object_mgr_find_in_map2( OBJECT * ptr, CK_OBJECT_HANDLE * handle ); CK_RV object_mgr_find_init( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ); CK_RV object_mgr_find_build_list( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, DL_NODE * obj_list, CK_BBOOL public_only ); CK_RV object_mgr_find_final( SESSION *sess ); CK_RV object_mgr_get_attribute_values( SESSION * sess, CK_OBJECT_HANDLE handle, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ); CK_RV object_mgr_get_object_size( CK_OBJECT_HANDLE handle, CK_ULONG * size ); CK_BBOOL object_mgr_invalidate_handle1( CK_OBJECT_HANDLE handle ); CK_BBOOL object_mgr_invalidate_handle2( OBJECT *obj ); CK_BBOOL object_mgr_purge_session_objects( SESSION * sess, SESS_OBJ_TYPE type ); CK_BBOOL object_mgr_purge_token_objects( void ); CK_BBOOL object_mgr_purge_private_token_objects( void ); CK_RV object_mgr_remove_from_map( CK_OBJECT_HANDLE handle ); CK_RV object_mgr_restore_obj( CK_BYTE *data, OBJECT *oldObj ); CK_RV object_mgr_set_attribute_values( SESSION * sess, CK_OBJECT_HANDLE handle, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ); // SAB FIXME FIXME CK_BBOOL object_mgr_purge_map( SESSION * sess, SESS_OBJ_TYPE type ); // object routines // CK_RV object_create( CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, OBJECT ** obj ); CK_RV object_create_skel( CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_ULONG mode, CK_ULONG class, CK_ULONG subclass, OBJECT ** key ); CK_RV object_copy( CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, OBJECT * old_obj, OBJECT ** new_obj ); CK_RV object_flatten( OBJECT * obj, CK_BYTE ** data, CK_ULONG * len ); CK_BBOOL object_free( OBJECT *obj ); CK_RV object_get_attribute_values( OBJECT * obj, CK_ATTRIBUTE * pTemplate, CK_ULONG count ); CK_ULONG object_get_size( OBJECT *obj ); CK_RV object_restore( CK_BYTE * data, OBJECT ** obj, CK_BBOOL replace ); CK_RV object_set_attribute_values( OBJECT * obj, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ); CK_BBOOL object_is_modifiable ( OBJECT * obj ); CK_BBOOL object_is_private ( OBJECT * obj ); CK_BBOOL object_is_public ( OBJECT * obj ); CK_BBOOL object_is_token_object ( OBJECT * obj ); CK_BBOOL object_is_session_object( OBJECT * obj ); CK_BBOOL is_attribute_defined( CK_ATTRIBUTE_TYPE type ); // object attribute template routines // CK_RV template_add_attributes( TEMPLATE * tmpl, CK_ATTRIBUTE * attr, CK_ULONG ulCount ); CK_RV template_add_default_attributes( TEMPLATE * tmpl, CK_ULONG class, CK_ULONG subclass, CK_ULONG mode ); CK_BBOOL template_attribute_find( TEMPLATE * tmpl, CK_ATTRIBUTE_TYPE type, CK_ATTRIBUTE ** attr); void template_attribute_find_multiple( TEMPLATE *tmpl, ATTRIBUTE_PARSE_LIST *parselist, CK_ULONG plcount ); CK_BBOOL template_check_exportability( TEMPLATE *tmpl, CK_ATTRIBUTE_TYPE type ); CK_RV template_check_required_attributes( TEMPLATE * tmpl, CK_ULONG class, CK_ULONG subclass, CK_ULONG mode ); CK_RV template_check_required_base_attributes( TEMPLATE * tmpl, CK_ULONG mode ); CK_BBOOL template_compare( CK_ATTRIBUTE * t1, CK_ULONG ulCount, TEMPLATE * t2 ); CK_RV template_copy( TEMPLATE * dest, TEMPLATE * src ); CK_RV template_flatten( TEMPLATE * tmpl, CK_BYTE * dest ); CK_RV template_free( TEMPLATE *tmpl ); CK_BBOOL template_get_class( TEMPLATE * tmpl, CK_ULONG * class, CK_ULONG * subclass ); CK_ULONG template_get_count( TEMPLATE *tmpl ); CK_ULONG template_get_size( TEMPLATE *tmpl ); CK_ULONG template_get_compressed_size( TEMPLATE *tmpl ); CK_RV template_set_default_common_attributes( TEMPLATE *tmpl ); CK_RV template_merge( TEMPLATE *dest, TEMPLATE **src ); CK_RV template_update_attribute( TEMPLATE * tmpl, CK_ATTRIBUTE * attr ); CK_RV template_unflatten( TEMPLATE ** tmpl, CK_BYTE * data, CK_ULONG count ); CK_RV template_validate_attribute( TEMPLATE * tmpl, CK_ATTRIBUTE * attr, CK_ULONG class, CK_ULONG subclass, CK_ULONG mode ); CK_RV template_validate_attributes( TEMPLATE * tmpl, CK_ULONG class, CK_ULONG subclass, CK_ULONG mode ); CK_RV template_validate_base_attribute( TEMPLATE * tmpl, CK_ATTRIBUTE * attr, CK_ULONG mode ); // DATA OBJECT ROUTINES // CK_RV data_object_check_required_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV data_object_set_default_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV data_object_validate_attribute ( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // CERTIFICATE ROUTINES // CK_RV cert_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cert_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV cert_x509_check_required_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cert_x509_set_default_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cert_x509_validate_attribute ( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV cert_vendor_check_required_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cert_vendor_validate_attribute ( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // // KEY ROUTINES // CK_RV key_object_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV key_object_set_default_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV key_object_validate_attribute ( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV publ_key_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV publ_key_set_default_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV publ_key_validate_attribute ( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV priv_key_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV priv_key_set_default_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV priv_key_unwrap( TEMPLATE *tmpl, CK_ULONG keytype, CK_BYTE *data, CK_ULONG data_len ); CK_RV priv_key_validate_attribute ( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_BBOOL secret_key_check_exportability( CK_ATTRIBUTE_TYPE type ); CK_RV secret_key_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV secret_key_set_default_attributes ( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV secret_key_unwrap( TEMPLATE *tmpl, CK_ULONG keytype, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ); CK_RV secret_key_validate_attribute ( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // rsa routines // CK_RV rsa_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rsa_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV rsa_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_BBOOL rsa_priv_check_exportability( CK_ATTRIBUTE_TYPE type ); CK_RV rsa_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rsa_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rsa_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV rsa_priv_wrap_get_data( TEMPLATE *tmpl, CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ); CK_RV rsa_priv_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len ); // dsa routines // CK_RV dsa_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dsa_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dsa_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_BBOOL dsa_priv_check_exportability( CK_ATTRIBUTE_TYPE type ); CK_RV dsa_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dsa_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dsa_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV dsa_priv_wrap_get_data( TEMPLATE *tmpl, CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ); CK_RV dsa_priv_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len ); // ecdsa routines // CK_RV ecdsa_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV ecdsa_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV ecdsa_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_BBOOL ecdsa_priv_check_exportability( CK_ATTRIBUTE_TYPE type ); CK_RV ecdsa_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV ecdsa_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV ecdsa_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // diffie-hellman routines // CK_RV dh_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dh_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dh_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_BBOOL dh_priv_check_exportability( CK_ATTRIBUTE_TYPE type ); CK_RV dh_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dh_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV dh_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // KEA routines // CK_RV kea_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV kea_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV kea_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_BBOOL kea_priv_check_exportability( CK_ATTRIBUTE_TYPE type ); CK_RV kea_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV kea_priv_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV kea_priv_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // Generic secret key routines CK_RV generic_secret_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV generic_secret_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV generic_secret_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV generic_secret_wrap_get_data( TEMPLATE *tmpl, CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ); CK_RV generic_secret_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ); // RC2 routines CK_RV rc2_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rc2_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rc2_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // RC4 routines CK_RV rc4_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rc4_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rc4_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // RC5 routines CK_RV rc5_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rc5_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV rc5_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // DES routines CK_RV des_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_BBOOL des_check_weak_key( CK_BYTE *key ); CK_RV des_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV des_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ); CK_RV des_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV des_wrap_get_data( TEMPLATE *tmpl, CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ); // DES2 routines CK_RV des2_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV des2_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV des2_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // DES3 routines CK_RV des3_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV des3_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV des3_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ); CK_RV des3_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV des3_wrap_get_data( TEMPLATE *tmpl, CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ); // AES routines CK_RV aes_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV aes_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV aes_unwrap( TEMPLATE *tmpl, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ); CK_RV aes_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); CK_RV aes_wrap_get_data( TEMPLATE *tmpl, CK_BBOOL length_only, CK_BYTE **data, CK_ULONG *data_len ); // CAST routines CK_RV cast_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cast_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cast_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // CAST3 routines CK_RV cast3_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cast3_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cast3_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // CAST5 routines CK_RV cast5_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cast5_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cast5_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // IDEA routines CK_RV idea_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV idea_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV idea_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // CDMF routines CK_RV cdmf_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cdmf_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV cdmf_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // SKIPJACK routines CK_RV skipjack_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV skipjack_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV skipjack_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // BATON routines CK_RV baton_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV baton_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV baton_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // JUNIPER routines CK_RV juniper_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV juniper_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ); CK_RV juniper_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ); // modular math routines // CK_RV mp_subtract( CK_BYTE *bigint, CK_ULONG val, CK_ULONG len ); CK_RV mp_mult( CK_BYTE *bigint_a, CK_ULONG a_len, CK_BYTE *bigint_b, CK_ULONG b_len, CK_BYTE *bigint_c, CK_ULONG c_len, CK_BYTE *result, CK_ULONG *result_len ); CK_RV mp_exp( CK_BYTE *bigint_a, CK_ULONG a_len, CK_BYTE *bigint_b, CK_ULONG b_len, CK_BYTE *bigint_c, CK_ULONG c_len, CK_BYTE *result, CK_ULONG *result_len ); // ASN.1 routines // CK_ULONG ber_encode_INTEGER( CK_BBOOL length_only, CK_BYTE ** ber_int, CK_ULONG * ber_int_len, CK_BYTE * data, CK_ULONG data_len ); CK_RV ber_decode_INTEGER( CK_BYTE * ber_int, CK_BYTE ** data, CK_ULONG * data_len, CK_ULONG * field_len ); CK_RV ber_encode_OCTET_STRING( CK_BBOOL length_only, CK_BYTE ** str, CK_ULONG * str_len, CK_BYTE * data, CK_ULONG data_len ); CK_RV ber_decode_OCTET_STRING( CK_BYTE * str, CK_BYTE ** data, CK_ULONG * data_len, CK_ULONG * field_len ); CK_RV ber_encode_SEQUENCE( CK_BBOOL length_only, CK_BYTE ** seq, CK_ULONG * seq_len, CK_BYTE * data, CK_ULONG data_len ); CK_RV ber_decode_SEQUENCE( CK_BYTE * seq, CK_BYTE ** data, CK_ULONG * data_len, CK_ULONG * field_len ); CK_RV ber_encode_PrivateKeyInfo( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len, CK_BYTE * algorithm_id, CK_ULONG algorithm_id_len, CK_BYTE * priv_key, CK_ULONG priv_key_len ); CK_RV ber_decode_PrivateKeyInfo( CK_BYTE * data, CK_ULONG data_len, CK_BYTE ** algorithm_id, CK_ULONG * alg_len, CK_BYTE ** priv_key ); CK_RV ber_encode_RSAPrivateKey( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len, CK_ATTRIBUTE * modulus, CK_ATTRIBUTE * publ_exp, CK_ATTRIBUTE * priv_exp, CK_ATTRIBUTE * prime1, CK_ATTRIBUTE * prime2, CK_ATTRIBUTE * exponent1, CK_ATTRIBUTE * exponent2, CK_ATTRIBUTE * coeff ); CK_RV ber_decode_RSAPrivateKey( CK_BYTE * data, CK_ULONG data_len, CK_ATTRIBUTE ** modulus, CK_ATTRIBUTE ** publ_exp, CK_ATTRIBUTE ** priv_exp, CK_ATTRIBUTE ** prime1, CK_ATTRIBUTE ** prime2, CK_ATTRIBUTE ** exponent1, CK_ATTRIBUTE ** exponent2, CK_ATTRIBUTE ** coeff ); CK_RV ber_encode_DSAPrivateKey( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len, CK_ATTRIBUTE * prime1, CK_ATTRIBUTE * prime2, CK_ATTRIBUTE * base, CK_ATTRIBUTE * priv_key ); CK_RV ber_decode_DSAPrivateKey( CK_BYTE * data, CK_ULONG data_len, CK_ATTRIBUTE ** prime, CK_ATTRIBUTE ** subprime, CK_ATTRIBUTE ** base, CK_ATTRIBUTE ** priv_key ); #include "tok_spec_struct.h" extern token_spec_t token_specific; #if (LEEDS_BUILD) #pragma options align=full #endif /* logging */ /* log to stdout */ #define LogMessage(dest, priority, layer, fmt, ...) \ do { \ fprintf(dest, "%s %s %s:%d " fmt "\n", priority, layer, __FILE__, __LINE__, ## __VA_ARGS__); \ } while (0) #define LogMessage1(dest, priority, layer, data) \ do { \ fprintf(dest, "%s %s %s:%d %s\n", priority, layer, __FILE__, __LINE__, data); \ } while (0) /* Debug logging */ #ifdef DEBUG #define LogDebug(fmt, ...) LogMessage(stdout, "LOG_DEBUG", STDLL_NAME, fmt, ##__VA_ARGS__) #define LogDebug1(data) LogMessage1(stdout, "LOG_DEBUG", STDLL_NAME, data) /* Error logging */ #define LogError(fmt, ...) LogMessage(stderr, "LOG_ERR", STDLL_NAME, "ERROR: " fmt, ##__VA_ARGS__) #define LogError1(data) LogMessage1(stderr, "LOG_ERR", STDLL_NAME, "ERROR: " data) /* Warn logging */ #define LogWarn(fmt, ...) LogMessage(stdout, "LOG_WARNING", STDLL_NAME, "WARNING: " fmt, ##__VA_ARGS__) #define LogWarn1(data) LogMessage1(stdout, "LOG_WARNING", STDLL_NAME, "WARNING: " data) /* Info Logging */ #define LogInfo(fmt, ...) LogMessage(stdout, "LOG_INFO", STDLL_NAME, fmt, ##__VA_ARGS__) #define LogInfo1(data) LogMessage1(stdout, "LOG_INFO", STDLL_NAME, data) #define st_err_log(num, ...) LogMessage(stderr, "ERROR", STDLL_NAME, "%s", err_msg[num].msg) #else #define LogDebug(...) do { } while (0) #define LogDebug1(...) do { } while (0) #define LogBlob(...) do { } while (0) #define LogError(...) do { } while (0) #define LogError1(...) do { } while (0) #define LogWarn(...) do { } while (0) #define LogWarn1(...) do { } while (0) #define LogInfo(...) do { } while (0) #define LogInfo1(...) do { } while (0) #define st_err_log(...) do { } while (0) #endif /* CKA_HIDDEN will be used to filter return results on a C_FindObjects call. * Used for objects internal to a token for management of that token */ #define CKA_HIDDEN CKA_VENDOR_DEFINED + 0x01000000 #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/mech_aes.c0000640000175000017500000017365411327631345020644 0ustar jfjf// /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: mech_aes.c // // Mechanisms for AES // #include // for memcmp() et al #include #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // // CK_RV aes_ecb_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (in_data_len % AES_BLOCK_SIZE != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // We have to use ulValueLen here, since with AES we don't // know how large the key is. memcpy( key_value, attr->pValue, attr->ulValueLen ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_aes_ecb_encrypt( in_data, in_data_len, out_data, out_data_len, key_value, attr->ulValueLen ); } // // CK_RV aes_ecb_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES3_ECB requires the input data to be an integral // multiple of the block size // if (in_data_len % AES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_aes_ecb_decrypt( in_data, in_data_len, out_data, out_data_len, key_value, attr->ulValueLen ); } // // CK_RV aes_cbc_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES3_CBC requires the input data to be an integral // multiple of the block size // if (in_data_len % AES_BLOCK_SIZE != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_aes_cbc_encrypt( in_data, in_data_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); } // // CK_RV aes_cbc_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // CKM_DES3_CBC requires the input data to be an integral // multiple of the block size // if (in_data_len % AES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); if (length_only == TRUE) { *out_data_len = in_data_len; return CKR_OK; } if (*out_data_len < in_data_len) { *out_data_len = in_data_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } return ckm_aes_cbc_decrypt( in_data, in_data_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); } // // CK_RV aes_cbc_pad_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE *clear = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_ULONG padded_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // DES3-CBC-PAD has no input length requirements // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // compute the output length, accounting for padding // padded_len = AES_BLOCK_SIZE * (in_data_len / AES_BLOCK_SIZE + 1); if (length_only == TRUE) { *out_data_len = padded_len; return CKR_OK; } if (*out_data_len < padded_len) { *out_data_len = padded_len; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } clear = (CK_BYTE *)malloc( padded_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( clear, in_data, in_data_len ); add_pkcs_padding( clear + in_data_len, AES_BLOCK_SIZE, in_data_len, padded_len ); rc = ckm_aes_cbc_encrypt( clear, padded_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc != CKR_OK) st_err_log(105, __FILE__, __LINE__); free( clear ); return rc; } // // CK_RV aes_cbc_pad_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len) { OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE *clear = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_ULONG padded_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // no need to validate the input length since we'll pad as necessary // rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // we're decrypting so even with CBC-PAD, we should have an integral // number of block to decrypt // if (in_data_len % AES_BLOCK_SIZE != 0){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } // the amount of cleartext after stripping the padding will actually be less // than the input bytes... // padded_len = in_data_len; if (length_only == TRUE) { *out_data_len = padded_len; return CKR_OK; } clear = (CK_BYTE *)malloc( padded_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } rc = ckm_aes_cbc_decrypt( in_data, in_data_len, clear, &padded_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc == CKR_OK) { strip_pkcs_padding( clear, padded_len, out_data_len ); memcpy( out_data, clear, *out_data_len ); } else st_err_log(106, __FILE__, __LINE__); free( clear ); return rc; } // // CK_RV aes_ecb_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (AES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < AES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % AES_BLOCK_SIZE); out_len = (total - remain); // should always be at least 1 block if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); rc = ckm_aes_ecb_encrypt( clear, out_len, out_data, out_data_len, key_value, attr->ulValueLen ); if (rc == CKR_OK) { *out_data_len = out_len; // update the context buffer. we already used the buffer's current // contents so we completely overwrite it // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } free( clear ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // shouldn't reach this } // // CK_RV aes_ecb_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (AES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < AES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % AES_BLOCK_SIZE); out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_aes_ecb_decrypt( cipher, out_len, out_data, out_data_len, key_value, attr->ulValueLen ); if (rc == CKR_OK) { *out_data_len = out_len; // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(105, __FILE__, __LINE__); free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // shouldn't reach this } // // CK_RV aes_cbc_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (AES_CONTEXT *)ctx->context; total = (context->len + in_data_len); if (total < AES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = (total % AES_BLOCK_SIZE); out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // these buffers need to be longword aligned // clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); rc = ckm_aes_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc == CKR_OK) { *out_data_len = out_len; // the new init_v is the last encrypted data block // memcpy( ctx->mech.pParameter, out_data + (*out_data_len - AES_BLOCK_SIZE), AES_BLOCK_SIZE ); // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(105, __FILE__, __LINE__); free( clear ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV aes_cbc_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (AES_CONTEXT *)ctx->context; total = context->len + in_data_len; if (total < AES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block // remain = total % AES_BLOCK_SIZE; out_len = total - remain; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // these buffers need to be longword aligned // cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_aes_cbc_decrypt( cipher, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc == CKR_OK) { *out_data_len = out_len; // the new init_v is the last input data block // memcpy( ctx->mech.pParameter, cipher + (out_len - AES_BLOCK_SIZE), AES_BLOCK_SIZE ); // copy the remaining 'new' input data to the context buffer // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } else st_err_log(106, __FILE__, __LINE__); free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV aes_cbc_pad_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * clear = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (AES_CONTEXT *)ctx->context; total = (context->len + in_data_len); // note, this is subtly different from the other encrypt update routines // if (total <= AES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { remain = (total % AES_BLOCK_SIZE); out_len = total - remain; // out_len is a multiple of DES_BLOCK_SIZE if (remain == 0) { remain = AES_BLOCK_SIZE; out_len -= AES_BLOCK_SIZE; } if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } // at this point, we should have: // 1) remain != 0 // 2) out_len != 0 // rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // these buffers need to be longword aligned // clear = (CK_BYTE *)malloc( out_len ); if (!clear){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous encryption operation first // memcpy( clear, context->data, context->len ); memcpy( clear + context->len, in_data, out_len - context->len ); // // we don't do padding during the update // rc = ckm_aes_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc == CKR_OK) { // the new init_v is the last encrypted data block // memcpy( ctx->mech.pParameter, out_data + (*out_data_len - AES_BLOCK_SIZE), AES_BLOCK_SIZE ); // copy the remaining 'new' input data to the temporary space // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } free( clear ); return rc; } } // // CK_RV aes_cbc_pad_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT * context = NULL; CK_ATTRIBUTE * attr = NULL; OBJECT * key = NULL; CK_BYTE * cipher = NULL; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_ULONG total, remain, out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (AES_CONTEXT *)ctx->context; total = (context->len + in_data_len); // note, this is subtly different from the other decrypt update routines // if (total <= AES_BLOCK_SIZE) { if (length_only == FALSE) { memcpy( context->data + context->len, in_data, in_data_len ); context->len += in_data_len; } *out_data_len = 0; return CKR_OK; } else { // we have at least 1 block + 1 byte // remain = total % AES_BLOCK_SIZE; out_len = total - remain; if (remain == 0) { remain = AES_BLOCK_SIZE; out_len -= AES_BLOCK_SIZE; } if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } // at this point, we should have: // 1) remain != 0 // 2) out_len != 0 // rc = object_mgr_find_in_map_nocache( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); // these buffers need to be longword aligned // cipher = (CK_BYTE *)malloc( out_len ); if (!cipher){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } // copy any data left over from the previous decryption operation first // memcpy( cipher, context->data, context->len ); memcpy( cipher + context->len, in_data, out_len - context->len ); rc = ckm_aes_cbc_decrypt( cipher, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc == CKR_OK) { // the new init_v is the last input data block // memcpy( ctx->mech.pParameter, cipher + (out_len - AES_BLOCK_SIZE), AES_BLOCK_SIZE ); // copy the remaining 'new' input data to the temporary space // if (remain != 0) memcpy( context->data, in_data + (in_data_len - remain), remain ); context->len = remain; } free( cipher ); return rc; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV aes_ecb_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (AES_CONTEXT *)ctx->context; // DES3-ECB does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV aes_ecb_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (AES_CONTEXT *)ctx->context; // DES3-ECB does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV aes_cbc_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (AES_CONTEXT *)ctx->context; // DES3-CBC does no padding so there had better not be // any data in the context buffer. if there is it means // that the overall data length was not a multiple of the blocksize // if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV aes_cbc_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT *context = NULL; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // satisfy the compiler // if (length_only) context = NULL; context = (AES_CONTEXT *)ctx->context; if (context->len != 0){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } *out_data_len = 0; return CKR_OK; } // // CK_RV aes_cbc_pad_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT *context = NULL; OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE clear[2*AES_BLOCK_SIZE]; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_ULONG out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); context = (AES_CONTEXT *)ctx->context; // there will never be more than one block in the context buffer // so the amount of output is as follows: // if less than 1 block stored, we generate one block of output // if a full block is stored, we generate two blocks of output (one pad block) // if (context->len == AES_BLOCK_SIZE) out_len = 2 * AES_BLOCK_SIZE; else out_len = AES_BLOCK_SIZE; if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } else { memcpy( clear, context->data, context->len ); add_pkcs_padding( clear + context->len, AES_BLOCK_SIZE, context->len, out_len ); rc = ckm_aes_cbc_encrypt( clear, out_len, out_data, out_data_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc != CKR_OK) st_err_log(105, __FILE__, __LINE__); return rc; } } // // CK_RV aes_cbc_pad_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { AES_CONTEXT *context = NULL; OBJECT *key = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE clear[AES_BLOCK_SIZE]; CK_BYTE key_value[AES_KEY_SIZE_256]; CK_KEY_TYPE keytype; CK_ULONG out_len; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } keytype = *(CK_KEY_TYPE *)attr->pValue; rc = template_attribute_find( key->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memcpy( key_value, attr->pValue, attr->ulValueLen ); context = (AES_CONTEXT *)ctx->context; // there had better be a full block in the context buffer // if (context->len != AES_BLOCK_SIZE){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } // we don't know a priori how much data we'll be returning. we won't // know until after we decrypt it and strip the padding. it's possible // that we'll return nothing (the final block might be a padding block). // out_len = AES_BLOCK_SIZE; // upper bound on what we'll return if (length_only == TRUE) { *out_data_len = out_len; return CKR_OK; } else { rc = ckm_aes_cbc_decrypt( context->data, AES_BLOCK_SIZE, clear, &out_len, ctx->mech.pParameter, key_value, attr->ulValueLen ); if (rc == CKR_OK) { strip_pkcs_padding( clear, out_len, &out_len ); if (out_len != 0) memcpy( out_data, clear, out_len ); *out_data_len = out_len; } else st_err_log(106, __FILE__, __LINE__); return rc; } } // // mechanisms // // // CK_RV ckm_aes_key_gen( TEMPLATE *tmpl ) { CK_ATTRIBUTE * value_attr = NULL; CK_ATTRIBUTE * key_type_attr = NULL; CK_ATTRIBUTE * class_attr = NULL; CK_ATTRIBUTE * local_attr = NULL; CK_ATTRIBUTE * val_len_attr = NULL; CK_BYTE * aes_key = NULL; CK_ULONG rc = CKR_OK; CK_ULONG key_size; CK_BBOOL found = FALSE; found = template_attribute_find( tmpl, CKA_VALUE_LEN, &val_len_attr ); if (found == FALSE) return CKR_TEMPLATE_INCONSISTENT; key_size = *(CK_ULONG *)val_len_attr->pValue; if (key_size != AES_KEY_SIZE_128 && key_size != AES_KEY_SIZE_192 && key_size != AES_KEY_SIZE_256) { return CKR_ATTRIBUTE_VALUE_INVALID; } if ((aes_key = (CK_BYTE *)malloc(key_size)) == NULL) { st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } rc = token_specific.t_aes_key_gen(aes_key, key_size); if (rc != CKR_OK) return rc; value_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + key_size ); key_type_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); class_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS) ); local_attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!value_attr || !key_type_attr || !class_attr || !local_attr) { if (value_attr) free( value_attr ); if (key_type_attr) free( key_type_attr ); if (class_attr) free( class_attr ); if (local_attr) free( local_attr ); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } value_attr->type = CKA_VALUE; value_attr->ulValueLen = key_size; value_attr->pValue = (CK_BYTE *)value_attr + sizeof(CK_ATTRIBUTE); memcpy( value_attr->pValue, aes_key, key_size ); free(aes_key); key_type_attr->type = CKA_KEY_TYPE; key_type_attr->ulValueLen = sizeof(CK_KEY_TYPE); key_type_attr->pValue = (CK_BYTE *)key_type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)key_type_attr->pValue = CKK_AES; class_attr->type = CKA_CLASS; class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS); class_attr->pValue = (CK_BYTE *)class_attr + sizeof(CK_ATTRIBUTE); *(CK_OBJECT_CLASS *)class_attr->pValue = CKO_SECRET_KEY; local_attr->type = CKA_LOCAL; local_attr->ulValueLen = sizeof(CK_BBOOL); local_attr->pValue = (CK_BYTE *)local_attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)local_attr->pValue = TRUE; template_update_attribute( tmpl, value_attr ); template_update_attribute( tmpl, key_type_attr ); template_update_attribute( tmpl, class_attr ); template_update_attribute( tmpl, local_attr ); return CKR_OK; } // // CK_RV ckm_aes_ecb_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * key_value, CK_ULONG key_len ) { CK_ULONG rc; if (!in_data || !out_data || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_aes_ecb(in_data,in_data_len, out_data,out_data_len, key_value,key_len,1); if (rc != CKR_OK) st_err_log(120, __FILE__, __LINE__); return rc; } // // CK_RV ckm_aes_ecb_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * key_value, CK_ULONG key_len ) { CK_ULONG rc; if (!in_data || !out_data || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_aes_ecb(in_data,in_data_len, out_data,out_data_len, key_value,key_len,0); if (rc != CKR_OK) st_err_log(120, __FILE__, __LINE__); return rc; } // // CK_RV ckm_aes_cbc_encrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * init_v, CK_BYTE * key_value, CK_ULONG key_len ) { CK_ULONG rc; if (!in_data || !out_data || !init_v || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ #if 0 st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; #else *out_data_len = in_data_len; st_err_log(68, __FILE__, __FUNCTION__); return CKR_BUFFER_TOO_SMALL; #endif } rc = token_specific.t_aes_cbc(in_data, in_data_len, out_data,out_data_len, key_value,key_len, init_v,1); if (rc != CKR_OK) st_err_log(119, __FILE__, __LINE__); return rc; } // // CK_RV ckm_aes_cbc_decrypt( CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len, CK_BYTE * init_v, CK_BYTE * key_value, CK_ULONG key_len ) { CK_ULONG rc; if (!in_data || !out_data || !init_v || !key_value){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < in_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = token_specific.t_aes_cbc(in_data, in_data_len, out_data, out_data_len, key_value,key_len, init_v,0); if (rc != CKR_OK) st_err_log(119, __FILE__, __LINE__); return rc; } // // CK_RV ckm_aes_wrap_format( CK_BBOOL length_only, CK_BYTE ** data, CK_ULONG * data_len ) { CK_BYTE * ptr = NULL; CK_ULONG len1, len2; len1 = *data_len; // if the input key data isn't a multiple of the blocksize, // we pad with NULLs to the next blocksize multiple. // if (len1 % AES_BLOCK_SIZE != 0) { len2 = AES_BLOCK_SIZE * ((len1 / AES_BLOCK_SIZE) + 1); if (length_only == FALSE) { ptr = (CK_BYTE *)realloc(*data, len2); if (!ptr){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } else memset( ptr + len1, 0x0, (len2 - len1) ); *data = ptr; *data_len = len2; } } return CKR_OK; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/sign_mgr.c0000751000175000017500000010523111327631345020672 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: sign_mgr.c // // Signature manager routines // #include #include // for memcmp() et al #include #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // // CK_RV sign_mgr_init( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_MECHANISM * mech, CK_BBOOL recover_mode, CK_OBJECT_HANDLE key ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_KEY_TYPE keytype; CK_OBJECT_CLASS class; CK_BBOOL flag; CK_RV rc; if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active != FALSE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } // key usage restrictions // rc = object_mgr_find_in_map1( key, &key_obj ); if (rc != CKR_OK){ st_err_log(18, __FILE__, __LINE__); return CKR_KEY_HANDLE_INVALID; } // is key allowed to generate signatures? // rc = template_attribute_find( key_obj->template, CKA_SIGN, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { flag = *(CK_BBOOL *)attr->pValue; if (flag != TRUE){ st_err_log(85, __FILE__, __LINE__); return CKR_KEY_FUNCTION_NOT_PERMITTED; } } // is the mechanism supported? is the key type correct? is a // parameter present if required? is the key size allowed? // is the key allowed to generate signatures? // switch (mech->mechanism) { case CKM_RSA_X_509: case CKM_RSA_PKCS: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_RSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // must be a PRIVATE key // flag = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (flag == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else class = *(CK_OBJECT_CLASS *)attr->pValue; // if it's not a private RSA key then we have an internal failure...means // that somehow a public key got assigned a CKA_SIGN attribute // if (class != CKO_PRIVATE_KEY){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } // PKCS #11 doesn't allow multi-part RSA operations // ctx->context_len = 0; ctx->context = NULL; } break; #if !(NOMD2) case CKM_MD2_RSA_PKCS: #endif case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_RSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // must be a PRIVATE key operation // flag = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else class = *(CK_OBJECT_CLASS *)attr->pValue; if (class != CKO_PRIVATE_KEY){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } ctx->context_len = sizeof(RSA_DIGEST_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(RSA_DIGEST_CONTEXT)); if (!ctx->context){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(RSA_DIGEST_CONTEXT)); } break; #if !(NODSA) case CKM_DSA: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // must be a PRIVATE key // flag = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (flag == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else class = *(CK_OBJECT_CLASS *)attr->pValue; // if it's not a private RSA key then we have an internal failure...means // that somehow a public key got assigned a CKA_SIGN attribute // if (class != CKO_PRIVATE_KEY){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } // PKCS #11 doesn't allow multi-part DSA operations // ctx->context_len = 0; ctx->context = NULL; } break; #endif #if !(NOMD2) case CKM_MD2_HMAC: #endif case CKM_MD5_HMAC: case CKM_SHA_1_HMAC: case CKM_SHA256_HMAC: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_GENERIC_SECRET){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // PKCS #11 doesn't allow multi-part HMAC operations // ctx->context_len = 0; ctx->context = NULL; } break; #if !(NOMD2) case CKM_MD2_HMAC_GENERAL: #endif case CKM_MD5_HMAC_GENERAL: case CKM_SHA_1_HMAC_GENERAL: case CKM_SHA256_HMAC_GENERAL: { CK_MAC_GENERAL_PARAMS *param = (CK_MAC_GENERAL_PARAMS *)mech->pParameter; if (mech->ulParameterLen != sizeof(CK_MAC_GENERAL_PARAMS)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } #if !(NOMD2) if ((mech->mechanism == CKM_MD2_HMAC_GENERAL) && (*param > 16)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } #endif if ((mech->mechanism == CKM_MD5_HMAC_GENERAL) && (*param > 16)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } if ((mech->mechanism == CKM_SHA_1_HMAC_GENERAL) && (*param > 20)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } if ((mech->mechanism == CKM_SHA256_HMAC_GENERAL) && (*param > 32)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_GENERIC_SECRET){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // PKCS #11 doesn't allow multi-part HMAC operations // ctx->context_len = 0; ctx->context = NULL; } break; case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: { CK_MAC_GENERAL_PARAMS *param = (CK_MAC_GENERAL_PARAMS *)mech->pParameter; if (mech->ulParameterLen != sizeof(CK_MAC_GENERAL_PARAMS)){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // FIXME - Netscape sets the parameter == 16. PKCS #11 limit is 8 // if (mech->mechanism == CKM_SSL3_MD5_MAC) { if (*param < 4 || *param > 16){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } } if (mech->mechanism == CKM_SSL3_SHA1_MAC) { if (*param < 4 || *param > 20){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } } rc = template_attribute_find( key_obj->template, CKA_CLASS, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { class = *(CK_OBJECT_CLASS *)attr->pValue; if (class != CKO_SECRET_KEY){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(SSL3_MAC_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(SSL3_MAC_CONTEXT)); if (!ctx->context){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(SSL3_MAC_CONTEXT)); } break; default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } if (mech->ulParameterLen > 0) { ptr = (CK_BYTE *)malloc(mech->ulParameterLen); if (!ptr){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( ptr, mech->pParameter, mech->ulParameterLen ); } ctx->key = key; ctx->mech.ulParameterLen = mech->ulParameterLen; ctx->mech.mechanism = mech->mechanism; ctx->mech.pParameter = ptr; ctx->multi = FALSE; ctx->active = TRUE; ctx->recover = recover_mode; return CKR_OK; } // // CK_RV sign_mgr_cleanup( SIGN_VERIFY_CONTEXT *ctx ) { if (!ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } ctx->key = 0; ctx->mech.ulParameterLen = 0; ctx->mech.mechanism = 0; ctx->multi = FALSE; ctx->active = FALSE; ctx->recover = FALSE; ctx->context_len = 0; if (ctx->mech.pParameter) { free( ctx->mech.pParameter ); ctx->mech.pParameter = NULL; } if (ctx->context) { free( ctx->context ); ctx->context = NULL; } return CKR_OK; } // // CK_RV sign_mgr_sign( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == TRUE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } // if the caller just wants the signature length, there is no reason to // specify the input data. I just need the input data length // if ((length_only == FALSE) && (!in_data || !out_data)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->multi == TRUE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } switch (ctx->mech.mechanism) { case CKM_RSA_PKCS: return rsa_pkcs_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_RSA_X_509: return rsa_x509_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #if !(NOMD2) case CKM_MD2_RSA_PKCS: #endif case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: return rsa_hash_pkcs_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #if !(NODSA) case CKM_DSA: return dsa_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif #if !(NOMD2) case CKM_MD2_HMAC: case CKM_MD2_HMAC_GENERAL: return md2_hmac_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif case CKM_MD5_HMAC: case CKM_MD5_HMAC_GENERAL: return md5_hmac_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_SHA_1_HMAC: case CKM_SHA_1_HMAC_GENERAL: return sha1_hmac_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_SHA256_HMAC: case CKM_SHA256_HMAC_GENERAL: return sha2_hmac_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: return ssl3_mac_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV sign_mgr_sign_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ) { if (!sess || !ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == TRUE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } ctx->multi = TRUE; switch (ctx->mech.mechanism) { #if !(NOMD2) case CKM_MD2_RSA_PKCS: #endif case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: return rsa_hash_pkcs_sign_update( sess, ctx, in_data, in_data_len ); case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: return ssl3_mac_sign_update( sess, ctx, in_data, in_data_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // // CK_RV sign_mgr_sign_final( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG * sig_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == TRUE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } switch (ctx->mech.mechanism) { #if !(NOMD2) case CKM_MD2_RSA_PKCS: #endif case CKM_MD5_RSA_PKCS: case CKM_SHA1_RSA_PKCS: return rsa_hash_pkcs_sign_final( sess, length_only, ctx, signature, sig_len ); case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: return ssl3_mac_sign_final( sess, length_only, ctx, signature, sig_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } // // CK_RV sign_mgr_sign_recover( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } if (ctx->recover == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } // if the caller just wants the signature length, there is no reason to // specify the input data. I just need the input data length // if ((length_only == FALSE) && (!in_data || !out_data)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->multi == TRUE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } switch (ctx->mech.mechanism) { case CKM_RSA_PKCS: // we can use the same sign mechanism to do sign-recover // return rsa_pkcs_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_RSA_X_509: return rsa_x509_sign( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/linuxdef.h0000751000175000017500000003670711327631345020723 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/lib/pkcs11/common/linuxdef.h,v 1.2 2005/02/22 20:47:46 mhalcrow Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ #ifndef _LINUXDEF_H_ #define _LINUXDEF_H_ #include char *itoa(int value, char *string, int); char *_ltoa(long value, char *string, int); void _splitpath(const char *pathName, char *drive, char *dir, char *fname, char *ext); #define PACK_DATA __attribute__ ((__packed__)) #define _MAX_PATH PATH_MAX #define _MAX_FNAME NAME_MAX #define _MAX_EXT NAME_MAX #endif /*_LINUXDEF_H_ */ opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/c_defs.h0000751000175000017500000004057411327631345020325 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/lib/pkcs11/common/c_defs.h,v 1.3 2005/09/01 22:57:04 mhalcrow Exp $ */ // /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // // Contains definitions that should only be required for the // coprocessor-side code // #ifndef _CARD_H #define _CARD_H #define MODE_COPY (1 << 0) #define MODE_CREATE (1 << 1) #define MODE_KEYGEN (1 << 2) #define MODE_MODIFY (1 << 3) #define MODE_DERIVE (1 << 4) #define MODE_UNWRAP (1 << 5) // RSA block formatting types // #define PKCS_BT_1 1 #define PKCS_BT_2 2 #define OP_ENCRYPT_INIT 1 #define OP_DECRYPT_INIT 2 #define OP_WRAP 3 #define OP_UNWRAP 4 #define OP_SIGN_INIT 5 #define OP_VERIFY_INIT 6 #define DES_KEY_SIZE 8 #define DES_BLOCK_SIZE 8 #define SHA1_HASH_SIZE 20 #define SHA1_BLOCK_SIZE 64 #define SHA2_HASH_SIZE 32 #define SHA2_BLOCK_SIZE 64 #define MD2_HASH_SIZE 16 #define MD2_BLOCK_SIZE 48 #define MD5_HASH_SIZE 16 #define MD5_BLOCK_SIZE 64 #define DSA_SIGNATURE_SIZE 40 #define DEFAULT_SO_PIN "87654321" // saved-state identifiers // enum { STATE_INVALID = 0, STATE_ENCR, STATE_DECR, STATE_DIGEST, STATE_SIGN, STATE_VERIFY }; typedef struct _MECH_LIST_ELEMENT { CK_MECHANISM_TYPE mech_type; CK_MECHANISM_INFO mech_info; } MECH_LIST_ELEMENT; struct mech_list_item; struct mech_list_item { struct mech_list_item *next; MECH_LIST_ELEMENT element; }; typedef struct _TEMPLATE { DL_NODE *attribute_list; } TEMPLATE; #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/new_host.c0000751000175000017500000034375611327631345020733 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ /*************************************************************************** Change Log ========== 4/25/03 Kapil Sood (kapil@corrent.com) Added DH key pair generation and DH shared key derivation functions. ****************************************************************************/ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include "pkcs11types.h" #include "stdll.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" #include "pkcs32.h" #include "../api/apiproto.h" #define UCHAR unsigned char /* Declared in obj_mgr.c */ extern pthread_rwlock_t obj_list_rw_mutex; char *pk_dir; void SC_SetFunctionList(void); #define SESSION_MGR_FIND(x) session_mgr_find(x) /* All these need to * get the lock */ /* Maximum number of supported devices (rather arbitrary) */ #define PKW_MAX_DEVICES 10 // Netscape/SSL is fairly timing-sensitive so can't always use a debugger // // If the CRYPTOKI_DEBUG environment variable is defined, information // about each successful PKCS#11 call made is written to the file named // in that environment variable. // // If the CRYPTOKI_PROFILE environment variable is defined, information // about the amount of time spent in each PKCS#11 API during a "run" // // If the CRYPTOKI_DEBUG environment variable is defined, information // about each successful PKCS#11 call made is written to the file named // in that environment variable. // // If the CRYPTOKI_PROFILE environment variable is defined, information // about the amount of time spent in each PKCS#11 API during a "run" // (i.e., from _DLL_InitTerm init call to _DLL_InitTerm term call) is // appended to the file named in that environment variable. // // If the CRYPTOKI_STATS_FILE environment variable is defined, information // about various internal metrics at the end of a "run" is appended to // the file named in that environment variable. The CRYPTOKI_STATS // environment variable specifies the argument(s) that are passed to // the function that returns the metrics to specify which metric(s) are // returned. // #define MAXFILENAME 1024 static char *debugfilepathbuffer; static int debugon = 1; int debugfile = 0; #define FFLUSH(x) pid_t initedpid=0; // for initialized pid CK_ULONG usage_count = 0; // variable for number of times the DLL has // been used. CK_C_INITIALIZE_ARGS cinit_args = { NULL, NULL, NULL, NULL, 0, NULL }; extern void stlogterm(); extern void stloginit(); extern void stlogit2(int type,char *fmt, ...); CK_BBOOL st_Initialized() { if (initialized == FALSE ) return FALSE; return TRUE; } #ifdef SPINXPL extern int spinxplfd; extern int spin_created; #endif void Fork_Initializer(void) { stlogterm(); stloginit(); // Initialize Logging so we can capture // EVERYTHING #ifdef SPINXPL spinxplfd = -1; spin_created = 0; #endif // Force logout. This cleans out the private session and list // and cleans out the private object map session_mgr_logout_all(); // Clean out the public object map // First parm is no longer used.. object_mgr_purge_map((SESSION *)0xFFFF, PUBLIC); object_mgr_purge_map((SESSION *)0xFFFF, PRIVATE); // This should clear the entire session list out session_mgr_close_all_sessions(); next_session_handle = 1; // Make is so sessions start with 1 next_object_handle = 1; // Clean out the global login state variable // When implemented... Although logout_all should clear this up. // Once the object_map is flushed, the obj_lists (public and // private) are both just linked lists that have to be freed // up... //logit("%s:%d: tokenobj publ 0x%08x priv // 0x%08x",__FILE__,__LINE__,publ_token_obj_list, // priv_token_obj_list); while (priv_token_obj_list) { priv_token_obj_list = dlist_remove_node(priv_token_obj_list, priv_token_obj_list); } while (publ_token_obj_list) { publ_token_obj_list = dlist_remove_node(publ_token_obj_list, publ_token_obj_list); } // Need to do something to prevent the shared memory from // having the objects loaded again.... The most likely place // is in the obj_mgr file where the object is added to shared // memory (object_mgr_add_to_shm) a query should be done to // the appropriate object list.... } #ifdef ALLLOCK #define LOCKIT pthread_mutex_lock(&native_mutex) #define LLOCK #define UNLOCKIT pthread_mutex_unlock(&native_mutex) #else #ifdef DEBLOCK #define LOCKIT #define LLOCK pthread_mutex_lock(&native_mutex) #define UNLOCKIT pthread_mutex_unlock(&native_mutex) #else #define LOCKIT #define LLOCK #define UNLOCKIT #endif #endif int APISlot2Local(snum) CK_SLOT_ID snum; { return(token_specific.t_slot2local(snum)); } #define SLT_CHECK \ CK_SLOT_ID slot_id; \ int sid1; \ \ if ( (sid1 = APISlot2Local(sid)) != -1 ){ \ slot_id = sid1; \ } else { \ return CKR_ARGUMENTS_BAD; \ } #define SESSION_HANDLE sSession.sessionh #define SLOTID APISlot2Local(sSession.slotID) #define SESS_SET \ CK_SESSION_HANDLE hSession; \ \ hSession = sSession.sessionh; // More efficient long reverse inline CK_ULONG long_reverse(CK_ULONG x) { #ifdef _POWER // Power Architecture requires reversal to talk to adapter return ( ((0x000000FF & x)<<24) | ((0x0000FF00 & x)<<8) | ((0x00FF0000 & x)>>8) | ((0xFF000000 & x)>>24) ); #else return (x); // Others don't require reversal. #endif } // verify that the mech specified is in the // mech list for this token... Common code requires this // to be added CK_RV validate_mechanism(CK_MECHANISM_PTR pMechanism) { CK_ULONG i; for (i=0; i< mech_list_len;i++){ if (pMechanism->mechanism == mech_list[i].mech_type) { return CKR_OK; } } st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } #define VALID_MECH(p) \ if ( validate_mechanism(p) != CKR_OK){ \ rc = CKR_MECHANISM_INVALID; \ goto done; \ } \ // Defines to allow NT code to work correctly #define WaitForSingleObject(x,y) pthread_mutex_lock(&(x)) #define ReleaseMutex(x) pthread_mutex_unlock(&(x)) void init_data_store(char *directory) { char *pkdir; if ( (pkdir = getenv("PKCS_APP_STORE")) != NULL){ pk_dir = (char *) malloc(strlen(pkdir)+1024); memset(pk_dir, 0, strlen(pkdir)+1024); sprintf(pk_dir,"%s/%s",pkdir,SUB_DIR); } else { pk_dir = (char *)malloc(strlen(directory)+25); memset(pk_dir, 0, strlen(directory)+25); sprintf(pk_dir,"%s",directory); } } /* In an STDLL this is called once for each card in the system * therefore the initialized only flags certain one time things * However in the case of a lightened accelerator, the cards are all * agregated together in a single token. Therefore the correlator * should be a list of device names which have either the correct clu * or the crypt light adapter... */ CK_RV ST_Initialize(void **FunctionList, CK_SLOT_ID SlotNumber, char *Correlator) { int i; CK_RV rc = CKR_OK; struct passwd *pw,*epw; // SAB XXX XXX uid_t userid,euserid; stlogterm(); stloginit(); // Check for root user or Group PKCS#11 Membershp // Only these are allowed. userid = getuid(); euserid = geteuid(); if (userid != 0 && euserid != 0) { // Root or effective Root // is ok struct group *grp; int rc = 0; gid_t gid,egid; grp = getgrnam("pkcs11"); if (grp) { // Check for member of group.. // SAB get login seems to not work with some // instances of application invocations // (particularly when forked). So we need to // get the group informatiion. Really need to // take the uid and map it to a name. pw = getpwuid(userid); epw = getpwuid(euserid); gid = getgid(); egid = getegid(); if ( gid == grp->gr_gid || egid == grp->gr_gid){ rc = 1; } else { i = 0; while (grp->gr_mem[i]) { if (pw) { if (strncmp(pw->pw_name, grp->gr_mem[i], strlen(pw->pw_name)) == 0 ) { rc = 1; break; } } if (epw) { if (strncmp(epw->pw_name, grp->gr_mem[i], strlen(epw->pw_name)) == 0 ){ rc = 1; break; } } i++; } } if (rc == 0 ){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } else { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } // assume that the upper API prevents multiple calls of initialize // since that only happens on C_Initialize and that is the // resonsibility of the upper layer.. initialized = FALSE; /// So the rest of the code works correctly // If we're not already initialized, grab the mutex and do the // initialization. Check to see if another thread did so while we // were waiting... // // One of the things we do during initialization is create the mutex for // PKCS#11 operations; until we do so, we have to use the native mutex... // WaitForSingleObject( native_mutex, INFINITE ); // SAB need to call Fork_Initializer here // instead of at the end of the loop... // it may also need to call destroy of the following 3 mutexes.. // it may not matter... Fork_Initializer(); MY_CreateMutex( &pkcs_mutex ); MY_CreateMutex( &obj_list_mutex ); if (pthread_rwlock_init(&obj_list_rw_mutex, NULL)) { st_err_log(145, __FILE__, __LINE__); } MY_CreateMutex( &sess_list_mutex ); MY_CreateMutex( &login_mutex ); if ( (debugfilepathbuffer = getenv( "CRYPTOKI_DEBUG")) != NULL) { debugon=1; } init_data_store((char *)PK_DIR); // Handle global initialization issues first if we have not // been initialized. if (st_Initialized() == FALSE){ #if SYSVSEM xproclock = (void *)&xprocsemid; CreateXProcLock(xproclock); #endif if ( (rc = attach_shm()) != CKR_OK) { st_err_log(144, __FILE__, __LINE__); goto done; } nv_token_data = &global_shm->nv_token_data; stloginit(); initialized = TRUE; initedpid = getpid(); SC_SetFunctionList(); // Always call the token_specific_init function.... rc = token_specific.t_init(Correlator,SlotNumber); if (rc != 0) { // Zero means success, right?!? *FunctionList = NULL; st_err_log(145, __FILE__, __LINE__); goto done; } } // SAB XXX FIXME FIXME check return code... for all these... rc = load_token_data(); if (rc != CKR_OK) { *FunctionList = NULL; st_err_log(145, __FILE__, __LINE__); goto done; } load_public_token_objects(); XProcLock( xproclock ); global_shm->publ_loaded = TRUE; XProcUnLock( xproclock ); init_slotInfo(); usage_count++; (*FunctionList) = &function_list; done: ReleaseMutex( native_mutex ); if (rc != 0) st_err_log(145, __FILE__, __LINE__); return rc; } // What does this really have to do in this new token... probably // need to close the adapters that are opened, and clear the other // stuff CK_RV SC_Finalize( CK_SLOT_ID sid ) { CK_RV rc; SLT_CHECK; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } rc = MY_LockMutex( &pkcs_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return rc; } // If somebody else has taken care of things, leave... if (st_Initialized() == FALSE) { MY_UnlockMutex( &pkcs_mutex ); // ? Somebody else has // also destroyed the // mutex... st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } usage_count--; if (usage_count == 0){ initialized = FALSE; } session_mgr_close_all_sessions(); object_mgr_purge_token_objects(); detach_shm(); // close spin lock file if (spin_created) close(spinxplfd); if ( token_specific.t_final != NULL) { token_specific.t_final(); } rc = MY_UnlockMutex( &pkcs_mutex ); if (rc != CKR_OK){ st_err_log(147, __FILE__, __LINE__); return rc; } return CKR_OK; } void copy_token_contents_sensibly(CK_TOKEN_INFO_PTR pInfo, TOKEN_DATA *nv_token_data) { memcpy(pInfo, &nv_token_data->token_info, sizeof(CK_TOKEN_INFO_32)); pInfo->flags = nv_token_data->token_info.flags; if ( nv_token_data->token_info.ulMaxSessionCount == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulMaxSessionCount = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulMaxSessionCount = nv_token_data->token_info.ulMaxSessionCount; } if ( nv_token_data->token_info.ulSessionCount == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulSessionCount = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulSessionCount = nv_token_data->token_info.ulSessionCount; } if ( nv_token_data->token_info.ulMaxRwSessionCount == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulMaxRwSessionCount = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulMaxRwSessionCount = nv_token_data->token_info.ulMaxRwSessionCount; } if ( nv_token_data->token_info.ulRwSessionCount == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulRwSessionCount = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulRwSessionCount = nv_token_data->token_info.ulRwSessionCount; } pInfo->ulMaxPinLen = nv_token_data->token_info.ulMaxPinLen; pInfo->ulMinPinLen = nv_token_data->token_info.ulMinPinLen; if ( nv_token_data->token_info.ulTotalPublicMemory == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulTotalPublicMemory = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulTotalPublicMemory = nv_token_data->token_info.ulTotalPublicMemory; } if ( nv_token_data->token_info.ulFreePublicMemory == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulFreePublicMemory = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulFreePublicMemory = nv_token_data->token_info.ulFreePublicMemory; } if ( nv_token_data->token_info.ulTotalPrivateMemory == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulTotalPrivateMemory = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulTotalPrivateMemory = nv_token_data->token_info.ulTotalPrivateMemory; } if ( nv_token_data->token_info.ulFreePrivateMemory == (CK_ULONG_32)CK_UNAVAILABLE_INFORMATION ) { pInfo->ulFreePrivateMemory = (CK_ULONG)CK_UNAVAILABLE_INFORMATION; } else { pInfo->ulFreePrivateMemory = nv_token_data->token_info.ulFreePrivateMemory; } pInfo->hardwareVersion = nv_token_data->token_info.hardwareVersion; pInfo->firmwareVersion = nv_token_data->token_info.firmwareVersion; pInfo->flags = long_reverse(pInfo->flags); pInfo->ulMaxSessionCount = long_reverse(pInfo->ulMaxSessionCount); pInfo->ulSessionCount = long_reverse(pInfo->ulSessionCount); pInfo->ulMaxRwSessionCount = long_reverse(pInfo->ulMaxRwSessionCount); pInfo->ulRwSessionCount = long_reverse(pInfo->ulRwSessionCount); pInfo->ulMaxPinLen = long_reverse(pInfo->ulMaxPinLen); pInfo->ulMinPinLen = long_reverse(pInfo->ulMinPinLen); pInfo->ulTotalPublicMemory = long_reverse(pInfo->ulTotalPublicMemory); pInfo->ulFreePublicMemory = long_reverse(pInfo->ulFreePublicMemory); pInfo->ulTotalPrivateMemory = long_reverse(pInfo->ulTotalPrivateMemory); pInfo->ulFreePrivateMemory = long_reverse(pInfo->ulFreePrivateMemory); } CK_RV SC_GetTokenInfo( CK_SLOT_ID sid, CK_TOKEN_INFO_PTR pInfo ) { CK_RV rc = CKR_OK; time_t now; SLT_CHECK; LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pInfo) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } if (slot_id > MAX_SLOT_ID) { st_err_log(2, __FILE__, __LINE__); rc = CKR_SLOT_ID_INVALID; goto done; } /* TODO: This should always be enabled; eliminate the PKCS64 flag */ #ifdef PKCS64 copy_token_contents_sensibly(pInfo, nv_token_data); #else memcpy( pInfo, &nv_token_data->token_info, sizeof(CK_TOKEN_INFO) ); #endif // Set the time now = time ((time_t *)NULL); strftime( (char *)pInfo->utcTime, 16, "%X", localtime(&now) ); done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x\n", "C_GetTokenInfo", rc ); } UNLOCKIT; return rc; } CK_RV SC_WaitForSlotEvent( CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved ) { if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } /** * For Netscape we want to not support the SSL3 mechs since the native * ones perform much better. Force those slots to be RSA... it's ugly * but it works. */ static void netscape_hack(CK_MECHANISM_TYPE_PTR mech_arr_ptr, CK_ULONG count) { char *envrn; CK_ULONG i; if ((envrn = getenv("NS_SERVER_HOME")) != NULL) { for (i = 0; i < count; i++){ switch (mech_arr_ptr[i]) { case CKM_SSL3_PRE_MASTER_KEY_GEN: case CKM_SSL3_MASTER_KEY_DERIVE: case CKM_SSL3_KEY_AND_MAC_DERIVE: case CKM_SSL3_MD5_MAC: case CKM_SSL3_SHA1_MAC: mech_arr_ptr[i] = CKM_RSA_PKCS; break; } } } } void mechanism_list_transformations(CK_MECHANISM_TYPE_PTR mech_arr_ptr, CK_ULONG_PTR count_ptr) { #ifndef NO_NETSCAPE_HACK netscape_hack(mech_arr_ptr, (*count_ptr)); #endif /* #ifndef NO_NETSCAPE_HACK */ } /** * Get the mechanism type list for the current token. */ CK_RV SC_GetMechanismList(CK_SLOT_ID sid, CK_MECHANISM_TYPE_PTR pMechList, CK_ULONG_PTR count) { CK_RV rc = CKR_OK; SLT_CHECK; LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto out; } if (count == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto out; } if (slot_id > MAX_SLOT_ID) { st_err_log(2, __FILE__, __LINE__); rc = CKR_SLOT_ID_INVALID; goto out; } if (!token_specific.t_get_mechanism_list) { st_err_log(4, __FILE__, __LINE__); rc = CKR_GENERAL_ERROR; goto out; } rc = token_specific.t_get_mechanism_list(pMechList, count); if (rc == CKR_OK) { /* To accomodate certain special cases, we may need to * make adjustments to the token's mechanism list. */ mechanism_list_transformations(pMechList, count); } out: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x, # mechanisms: %d\n", "C_GetMechanismList", rc, *count ); } UNLOCKIT; return rc; } /** * Get the mechanism info for the current type and token. */ CK_RV SC_GetMechanismInfo(CK_SLOT_ID sid, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo) { CK_RV rc = CKR_OK; SLT_CHECK; LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto out; } if (pInfo == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto out; } if (slot_id > MAX_SLOT_ID) { st_err_log(2, __FILE__, __LINE__); rc = CKR_SLOT_ID_INVALID; goto out; } if (!token_specific.t_get_mechanism_info) { st_err_log(4, __FILE__, __LINE__); rc = CKR_GENERAL_ERROR; goto out; } rc = token_specific.t_get_mechanism_info(type, pInfo); out: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x, mech type = 0x%08x\n", "C_GetMechanismInfo", rc, type ); } UNLOCKIT; return rc; } int delete_all_files_in_dir(char *full_dir_path) { return 0; } /* This routine should only be called if no other processes are * attached to the token. we need to somehow check that this is the * only process Meta API should prevent this since it knows session * states in the shared memory. */ CK_RV SC_InitToken( CK_SLOT_ID sid, CK_CHAR_PTR pPin, CK_ULONG ulPinLen, CK_CHAR_PTR pLabel ) { CK_RV rc = CKR_OK; int local_rc = 0; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_SLOT_ID slotID; char *s = NULL; char *pk_full_path = NULL; SLT_CHECK; slotID = slot_id; LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pPin || !pLabel) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } if (nv_token_data->token_info.flags & CKF_SO_PIN_LOCKED) { st_err_log(37, __FILE__, __LINE__); rc = CKR_PIN_LOCKED; goto done; } rc = compute_sha( pPin, ulPinLen, hash_sha ); if (memcmp(nv_token_data->so_pin_sha, hash_sha, SHA1_HASH_SIZE) != 0) { st_err_log(33, __FILE__, __LINE__); rc = CKR_PIN_INCORRECT; goto done; } rc = rng_generate( master_key, 3 * DES_KEY_SIZE ); if (rc != CKR_OK) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } // Before we reconstruct all the data, we should delete the // token objects from the filesystem. // // Construct a string to delete the token objects. // object_mgr_destroy_token_objects(); #if 0 /* TODO: Implement delete_all_files_in_dir() */ local_rc = asprintf(&pk_full_path, "%s/%s", pk_dir, PK_LITE_OBJ_DIR); if (local_rc == -1) { rc = CKR_HOST_MEMORY; goto out; } local_rc = delete_all_files_in_dir(pk_full_path); if (local_rc == -1) { rc = CKR_FUNCTION_FAILED; goto out; } #endif local_rc = asprintf(&s, "%s %s/%s/* > /dev/null 2>&1", DEL_CMD, pk_dir, PK_LITE_OBJ_DIR); if (local_rc == -1) { rc = CKR_HOST_MEMORY; goto out; } system(s); free(s); s = NULL; // META This should be fine since the open session checking // should occur at the API not the STDLL init_token_data(); init_slotInfo(); memcpy( nv_token_data->token_info.label, pLabel, 32 ); memcpy( nv_token_data->so_pin_sha, hash_sha, SHA1_HASH_SIZE); nv_token_data->token_info.flags |= CKF_TOKEN_INITIALIZED; rc = save_token_data(); if (rc != CKR_OK){ st_err_log(104, __FILE__, __LINE__, __FUNCTION__); goto done; } rc = save_masterkey_so(); if (rc != CKR_OK){ st_err_log(149, __FILE__, __LINE__, __FUNCTION__); goto done; } done: out: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x\n", "C_InitToken", rc ); } UNLOCKIT; if (pk_full_path) { free(pk_full_path); } return rc; } // // CK_RV SC_InitPIN( ST_SESSION_HANDLE sSession, CK_CHAR_PTR pPin, CK_ULONG ulPinLen ) { SESSION * sess = NULL; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_BYTE hash_md5[MD5_HASH_SIZE]; CK_RV rc = CKR_OK; SESS_SET; LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pPin) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_locked(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(37, __FILE__, __LINE__); rc = CKR_PIN_LOCKED; goto done; } if (sess->session_info.state != CKS_RW_SO_FUNCTIONS) { st_err_log(57, __FILE__, __LINE__); rc = CKR_USER_NOT_LOGGED_IN; goto done; } if ((ulPinLen < MIN_PIN_LEN) || (ulPinLen > MAX_PIN_LEN)) { st_err_log(35, __FILE__, __LINE__); rc = CKR_PIN_LEN_RANGE; goto done; } // compute the SHA and MD5 hashes of the user pin rc = compute_sha( pPin, ulPinLen, hash_sha ); rc |= compute_md5( pPin, ulPinLen, hash_md5 ); if (rc != CKR_OK){ st_err_log(148, __FILE__, __LINE__); goto done; } rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto done; } memcpy(nv_token_data->user_pin_sha, hash_sha, SHA1_HASH_SIZE); nv_token_data->token_info.flags |= CKF_USER_PIN_INITIALIZED; nv_token_data->token_info.flags &= ~(CKF_USER_PIN_TO_BE_CHANGED); nv_token_data->token_info.flags &= ~(CKF_USER_PIN_LOCKED); XProcUnLock(xproclock); memcpy( user_pin_md5, hash_md5, MD5_HASH_SIZE ); rc = save_token_data(); if (rc != CKR_OK){ st_err_log(104, __FILE__, __LINE__); goto done; } rc = save_masterkey_user(); if (rc != CKR_OK){ st_err_log(149, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: session = %08x\n", "C_InitPin", rc, hSession); } UNLOCKIT; return rc; } CK_RV SC_SetPIN( ST_SESSION_HANDLE sSession, CK_CHAR_PTR pOldPin, CK_ULONG ulOldLen, CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen ) { SESSION *sess = NULL; CK_BYTE old_hash_sha[SHA1_HASH_SIZE]; CK_BYTE new_hash_sha[SHA1_HASH_SIZE]; CK_BYTE hash_md5[MD5_HASH_SIZE]; CK_RV rc = CKR_OK; SESS_SET; LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_locked(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(37, __FILE__, __LINE__); rc = CKR_PIN_LOCKED; goto done; } if ((ulNewLen < MIN_PIN_LEN) || (ulNewLen > MAX_PIN_LEN)) { st_err_log(35, __FILE__, __LINE__); rc = CKR_PIN_LEN_RANGE; goto done; } rc = compute_sha( pOldPin, ulOldLen, old_hash_sha ); if (rc != CKR_OK){ st_err_log(148, __FILE__, __LINE__); goto done; } /* From the PKCS#11 2.20 spec: "C_SetPIN modifies the PIN of * the user that is currently logged in, or the CKU_USER PIN * if the session is not logged in." A non R/W session fails * with CKR_SESSION_READ_ONLY. */ if ((sess->session_info.state == CKS_RW_USER_FUNCTIONS) || (sess->session_info.state == CKS_RW_PUBLIC_SESSION)) { if (memcmp(nv_token_data->user_pin_sha, old_hash_sha, SHA1_HASH_SIZE) != 0) { st_err_log(33, __FILE__, __LINE__); rc = CKR_PIN_INCORRECT; goto done; } rc = compute_sha( pNewPin, ulNewLen, new_hash_sha ); rc |= compute_md5( pNewPin, ulNewLen, hash_md5 ); if (rc != CKR_OK){ st_err_log(148, __FILE__, __LINE__); goto done; } /* The old PIN matches, now make sure its different * than the new and is not the default. */ if ((memcmp(old_hash_sha, new_hash_sha, SHA1_HASH_SIZE) == 0) || (memcmp(new_hash_sha, default_user_pin_sha, SHA1_HASH_SIZE) == 0)) { st_err_log(34, __FILE__, __LINE__); rc = CKR_PIN_INVALID; goto done; } rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto done; } memcpy(nv_token_data->user_pin_sha, new_hash_sha, SHA1_HASH_SIZE); memcpy(user_pin_md5, hash_md5, MD5_HASH_SIZE); nv_token_data->token_info.flags &= ~(CKF_USER_PIN_TO_BE_CHANGED); XProcUnLock( xproclock ); rc = save_token_data(); if (rc != CKR_OK){ st_err_log(104, __FILE__, __LINE__); goto done; } rc = save_masterkey_user(); } else if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) { if (memcmp(nv_token_data->so_pin_sha, old_hash_sha, SHA1_HASH_SIZE) != 0) { rc = CKR_PIN_INCORRECT; st_err_log(33, __FILE__, __LINE__); goto done; } rc = compute_sha(pNewPin, ulNewLen, new_hash_sha); rc |= compute_md5(pNewPin, ulNewLen, hash_md5); if (rc != CKR_OK){ st_err_log(148, __FILE__, __LINE__); goto done; } /* The old PIN matches, now make sure its different * than the new and is not the default. */ if ((memcmp(old_hash_sha, new_hash_sha, SHA1_HASH_SIZE) == 0) || (memcmp(new_hash_sha, default_so_pin_sha, SHA1_HASH_SIZE) == 0)) { st_err_log(34, __FILE__, __LINE__); rc = CKR_PIN_INVALID; goto done; } rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto done; } memcpy(nv_token_data->so_pin_sha, new_hash_sha, SHA1_HASH_SIZE); memcpy( so_pin_md5, hash_md5, MD5_HASH_SIZE ); nv_token_data->token_info.flags &= ~(CKF_SO_PIN_TO_BE_CHANGED); XProcUnLock( xproclock ); rc = save_token_data(); if (rc != CKR_OK){ st_err_log(104, __FILE__, __LINE__); goto done; } rc = save_masterkey_so(); } else { st_err_log(142, __FILE__, __LINE__); rc = CKR_SESSION_READ_ONLY; } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: session = %08x\n", "C_SetPin", rc, hSession ); } UNLOCKIT; if (rc != CKR_SESSION_READ_ONLY && rc != CKR_OK) st_err_log(149, __FILE__, __LINE__); return rc; } CK_RV SC_OpenSession(CK_SLOT_ID sid, CK_FLAGS flags, CK_SESSION_HANDLE_PTR phSession) { SESSION * sess; CK_BBOOL locked = FALSE; CK_RV rc = CKR_OK; SLT_CHECK; LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (phSession == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } if (slot_id > MAX_SLOT_ID) { st_err_log(2, __FILE__, __LINE__); rc = CKR_SLOT_ID_INVALID; goto done; } flags |= CKF_SERIAL_SESSION; if ((flags & CKF_RW_SESSION) == 0) { if (session_mgr_so_session_exists()) { st_err_log(45, __FILE__, __LINE__); rc = CKR_SESSION_READ_WRITE_SO_EXISTS; goto done; } } // Get the mutex because we may modify the pid_list rc = MY_LockMutex( &pkcs_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); goto done; } locked = TRUE; token_specific.t_session(slot_id); MY_UnlockMutex( &pkcs_mutex ); locked = FALSE; rc = session_mgr_new( flags, &sess ); if (rc != CKR_OK){ st_err_log(152, __FILE__, __LINE__); goto done; } *phSession = sess->handle; // Set the correct slot ID here. Was hard coded to 1. - KEY sess->session_info.slotID = sid; done: if (locked) MY_UnlockMutex( &pkcs_mutex ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x ", "C_OpenSession", rc); if (rc == CKR_OK) stlogit2(debugfile, "sess = %d", ((sess == NULL) ? -1 : (CK_LONG)sess->handle)); stlogit2(debugfile, "\n"); } UNLOCKIT; return rc; } CK_RV SC_CloseSession( ST_SESSION_HANDLE sSession ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET; LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = session_mgr_close_session( sess ); done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x sess = %d\n", "C_CloseSession", rc, hSession ); } UNLOCKIT; return rc; } CK_RV SC_CloseAllSessions( CK_SLOT_ID sid ) { CK_RV rc = CKR_OK; SLT_CHECK; LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } rc = session_mgr_close_all_sessions(); if (rc != CKR_OK){ st_err_log(153, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x slot = %d\n", "C_CloseAllSessions", rc, slot_id ); } UNLOCKIT; return rc; } CK_RV SC_GetSessionInfo( ST_SESSION_HANDLE sSession, CK_SESSION_INFO_PTR pInfo ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET; LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pInfo) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } memcpy( pInfo, &sess->session_info, sizeof(CK_SESSION_INFO) ); done: if (debugfile) { stlogit2(debugfile, "%-25s: session = %08d\n", "C_GetSessionInfo", hSession ); } UNLOCKIT; return rc; } CK_RV SC_GetOperationState( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET; LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pulOperationStateLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } if (!pOperationState) length_only = TRUE; sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = session_mgr_get_op_state( sess, length_only, pOperationState, pulOperationStateLen ); if (rc != CKR_OK){ st_err_log(154, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: session = %08x\n", "C_GetOperationState", rc, hSession ); } UNLOCKIT; return rc; } // // CK_RV SC_SetOperationState( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pOperationState || (ulOperationStateLen == 0)) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = session_mgr_set_op_state( sess, hEncryptionKey, hAuthenticationKey, pOperationState, ulOperationStateLen ); if (rc != CKR_OK){ st_err_log(154, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: session = %08x\n", "C_SetOperationState", rc, hSession ); } UNLOCKIT; return rc; } // // CK_RV SC_Login( ST_SESSION_HANDLE sSession, CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG ulPinLen ) { SESSION * sess = NULL; CK_FLAGS_32 * flags = NULL; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_RV rc = CKR_OK; SESS_SET LOCKIT; // In v2.11, logins should be exclusive, since token // specific flags may need to be set for a bad login. - KEY rc = MY_LockMutex( &login_mutex ); if (rc != CKR_OK){ st_err_log(146, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } flags = &nv_token_data->token_info.flags; if (!pPin || ulPinLen > MAX_PIN_LEN) { set_login_flags(userType, flags); st_err_log(33, __FILE__, __LINE__); rc = CKR_PIN_INCORRECT; goto done; } // PKCS #11 v2.01 requires that all sessions have the same login status: // --> all sessions are public, all are SO or all are USER // if (userType == CKU_USER) { if (session_mgr_so_session_exists()){ st_err_log(60, __FILE__, __LINE__); rc = CKR_USER_ANOTHER_ALREADY_LOGGED_IN; } if (session_mgr_user_session_exists()){ st_err_log(56, __FILE__, __LINE__); rc = CKR_USER_ALREADY_LOGGED_IN; } } else if (userType == CKU_SO) { if (session_mgr_user_session_exists()){ st_err_log(60, __FILE__, __LINE__); rc = CKR_USER_ANOTHER_ALREADY_LOGGED_IN; } if (session_mgr_so_session_exists()){ st_err_log(56, __FILE__, __LINE__); rc = CKR_USER_ALREADY_LOGGED_IN; } if (session_mgr_readonly_exists()){ st_err_log(142, __FILE__, __LINE__); rc = CKR_SESSION_READ_ONLY_EXISTS; } } else { rc = CKR_USER_TYPE_INVALID; st_err_log(59, __FILE__, __LINE__); } if (rc != CKR_OK) goto done; if (userType == CKU_USER) { if (*flags & CKF_USER_PIN_LOCKED) { st_err_log(37, __FILE__, __LINE__); rc = CKR_PIN_LOCKED; goto done; } if (memcmp(nv_token_data->user_pin_sha, "00000000000000000000", SHA1_HASH_SIZE) == 0) { st_err_log(33, __FILE__, __LINE__); rc = CKR_USER_PIN_NOT_INITIALIZED; goto done; } rc = compute_sha( pPin, ulPinLen, hash_sha ); if (memcmp(nv_token_data->user_pin_sha, hash_sha, SHA1_HASH_SIZE) != 0) { set_login_flags(userType, flags); st_err_log(33, __FILE__, __LINE__); rc = CKR_PIN_INCORRECT; goto done; } /* Successful login, clear flags */ *flags &= ~(CKF_USER_PIN_LOCKED | CKF_USER_PIN_FINAL_TRY | CKF_USER_PIN_COUNT_LOW); compute_md5( pPin, ulPinLen, user_pin_md5 ); memset( so_pin_md5, 0x0, MD5_HASH_SIZE ); rc = load_masterkey_user(); if (rc != CKR_OK){ st_err_log(155, __FILE__, __LINE__); goto done; } rc = load_private_token_objects(); XProcLock( xproclock ); global_shm->priv_loaded = TRUE; XProcUnLock( xproclock ); } else { if (*flags & CKF_SO_PIN_LOCKED) { st_err_log(37, __FILE__, __LINE__); rc = CKR_PIN_LOCKED; goto done; } rc = compute_sha( pPin, ulPinLen, hash_sha ); if (memcmp(nv_token_data->so_pin_sha, hash_sha, SHA1_HASH_SIZE) != 0) { set_login_flags(userType, flags); st_err_log(33, __FILE__, __LINE__); rc = CKR_PIN_INCORRECT; goto done; } /* Successful login, clear flags */ *flags &= ~(CKF_SO_PIN_LOCKED | CKF_SO_PIN_FINAL_TRY | CKF_SO_PIN_COUNT_LOW); compute_md5( pPin, ulPinLen, so_pin_md5 ); memset( user_pin_md5, 0x0, MD5_HASH_SIZE ); rc = load_masterkey_so(); if (rc != CKR_OK) { st_err_log(155, __FILE__, __LINE__); } } rc = session_mgr_login_all( userType ); if (rc != CKR_OK) { st_err_log(174, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x\n", "C_Login", rc ); } UNLOCKIT; save_token_data(); MY_UnlockMutex( &login_mutex ); return rc; } // // CK_RV SC_Logout( ST_SESSION_HANDLE sSession ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } // all sessions have the same state so we just have to check one // if (session_mgr_public_session_exists()) { st_err_log(57, __FILE__, __LINE__); rc = CKR_USER_NOT_LOGGED_IN; goto done; } rc = session_mgr_logout_all(); if (rc != CKR_OK){ st_err_log(57, __FILE__, __LINE__); } memset( user_pin_md5, 0x0, MD5_HASH_SIZE ); memset( so_pin_md5, 0x0, MD5_HASH_SIZE ); object_mgr_purge_private_token_objects(); done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = 0x%08x\n", "C_Logout", rc ); } UNLOCKIT; return rc; } // This is a Leeds-Lite solution so we have to store objects on the host. // CK_RV SC_CreateObject( ST_SESSION_HANDLE sSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject ) { SESSION * sess = NULL; CK_ULONG i; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = object_mgr_add( sess, pTemplate, ulCount, phObject ); if (rc != CKR_OK) { st_err_log(157, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x\n", "C_CreateObject", rc ); for (i = 0; i < ulCount; i++) { if (pTemplate[i].type == CKA_CLASS) stlogit2(debugfile, "%28s: 0x%02x\n", "Object Type", *(CK_ULONG *)pTemplate[i].pValue ); } if (rc == CKR_OK) stlogit2(debugfile, "%28s: %d\n", "Handle", *phObject ); } UNLOCKIT; return rc; } // // CK_RV SC_CopyObject( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phNewObject ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = object_mgr_copy( sess, pTemplate, ulCount, hObject, phNewObject ); if (rc != CKR_OK) { st_err_log(158, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, old handle = %d, new handle = %d\n", "C_CopyObject", rc, hObject, *phNewObject ); } UNLOCKIT; return rc; } // // CK_RV SC_DestroyObject( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = object_mgr_destroy_object( sess, hObject ); if (rc != CKR_OK){ st_err_log(182, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, handle = %d\n", "C_DestroyObject", rc, hObject ); } UNLOCKIT; return rc; } // // CK_RV SC_GetObjectSize( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = object_mgr_get_object_size( hObject, pulSize ); if (rc != CKR_OK){ st_err_log(184, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, handle = %d\n", "C_GetObjectSize", rc, hObject ); } UNLOCKIT; return rc; } // // CK_RV SC_GetAttributeValue( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ) { SESSION * sess = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_ULONG i; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = object_mgr_get_attribute_values( sess, hObject, pTemplate, ulCount ); if (rc != CKR_OK){ st_err_log(159, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, handle = %d\n", "C_GetAttributeValue", rc, hObject ); attr = pTemplate; for (i = 0; i < ulCount; i++, attr++) { ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } } UNLOCKIT; return rc; } // // CK_RV SC_SetAttributeValue( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ) { SESSION * sess = NULL; CK_ATTRIBUTE * attr = NULL; CK_ULONG i; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = object_mgr_set_attribute_values( sess, hObject, pTemplate, ulCount); if (rc != CKR_OK){ st_err_log(161, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, handle = %d\n", "C_SetAttributeValue", rc, hObject ); attr = pTemplate; for (i = 0; i < ulCount; i++, attr++) { CK_BYTE *ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } } UNLOCKIT; return rc; } // // CK_RV SC_FindObjectsInit( ST_SESSION_HANDLE sSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ) { SESSION * sess = NULL; CK_ATTRIBUTE * attr = NULL; CK_ULONG i; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->find_active == TRUE) { st_err_log(31, __FILE__, __LINE__); rc = CKR_OPERATION_ACTIVE; goto done; } rc = object_mgr_find_init( sess, pTemplate, ulCount ); if (rc != CKR_OK){ st_err_log(185, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x\n", "C_FindObjectsInit", rc ); attr = pTemplate; for (i = 0; i < ulCount; i++, attr++) { CK_BYTE *ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } } UNLOCKIT; return rc; } // // CK_RV SC_FindObjects( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount ) { SESSION * sess = NULL; CK_ULONG count = 0; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!phObject || !pulObjectCount) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->find_active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!sess->find_list) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } count = MIN(ulMaxObjectCount, (sess->find_count - sess->find_idx)); memcpy( phObject, sess->find_list + sess->find_idx, count * sizeof(CK_OBJECT_HANDLE) ); *pulObjectCount = count; sess->find_idx += count; rc = CKR_OK; done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, returned %d objects\n", "C_FindObjects", rc, count ); } UNLOCKIT; return rc; } // // CK_RV SC_FindObjectsFinal( ST_SESSION_HANDLE sSession ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->find_active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (sess->find_list) free( sess->find_list ); sess->find_list = NULL; sess->find_len = 0; sess->find_idx = 0; sess->find_active = FALSE; rc = CKR_OK; done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x\n", "C_FindObjectsFinal", rc ); } UNLOCKIT; return rc; } // // CK_RV SC_EncryptInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->encr_ctx.active == TRUE) { st_err_log(31, __FILE__, __LINE__); rc = CKR_OPERATION_ACTIVE; goto done; } rc = encr_mgr_init( sess, &sess->encr_ctx, OP_ENCRYPT_INIT, pMechanism, hKey ); if (rc != CKR_OK) { st_err_log(98, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, key = %d, mech = 0x%x\n", "C_EncryptInit", rc,(sess == NULL)?-1:(CK_LONG)sess->handle, hKey, pMechanism->mechanism ); } UNLOCKIT; return rc; } // // CK_RV SC_Encrypt( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pData || !pulEncryptedDataLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->encr_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pEncryptedData) length_only = TRUE; rc = encr_mgr_encrypt( sess, length_only, &sess->encr_ctx, pData, ulDataLen, pEncryptedData, pulEncryptedDataLen ); if (rc != CKR_OK) { st_err_log(99, __FILE__, __LINE__); } done: LLOCK; if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) encr_mgr_cleanup( &sess->encr_ctx ); if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, amount = %d\n", "C_Encrypt", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulDataLen ); } UNLOCKIT; return rc; } // // CK_RV SC_EncryptUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pPart || !pulEncryptedPartLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->encr_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pEncryptedPart) length_only = TRUE; rc = encr_mgr_encrypt_update( sess, length_only, &sess->encr_ctx, pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen ); if (rc != CKR_OK) { st_err_log(176, __FILE__, __LINE__); } done: LLOCK; if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL) encr_mgr_cleanup( &sess->encr_ctx ); if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, amount = %d\n", "C_EncryptUpdate", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulPartLen ); } UNLOCKIT; return rc; } // I think RSA goofed when designing the specification for C_EncryptFinal. // This function is supposed to follow the Cryptoki standard that if // pLastEncryptedPart == NULL then the user is requesting only the length // of the output. // // But it's quite possible that no output will be returned (say the user // specifies a total of 64 bytes of input data throughout the multi-part // encryption). The same thing can happen during an EncryptUpdate. // // ie: // // 1) user calls C_EncryptFinal to get the needed length // --> we return "0 bytes required" // 2) user passes in a NULL pointer for pLastEncryptedPart // --> we think the user is requesting the length again <-- // // So the user needs to pass in a non-NULL pointer even though we're not // going to return anything in it. It would have been cleaner if RSA would // have simply included a "give-me-the-length-only flag" as an argument. // // CK_RV SC_EncryptFinal( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pulLastEncryptedPartLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->encr_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pLastEncryptedPart) length_only = TRUE; rc = encr_mgr_encrypt_final( sess, length_only, &sess->encr_ctx, pLastEncryptedPart, pulLastEncryptedPartLen ); if (rc != CKR_OK) { st_err_log(177, __FILE__, __LINE__); } done: LLOCK; if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) encr_mgr_cleanup( &sess->encr_ctx ); if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d\n", "C_EncryptFinal", rc, (sess == NULL)?-1:(CK_LONG)sess->handle ); } UNLOCKIT; return rc; } // // CK_RV SC_DecryptInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->decr_ctx.active == TRUE) { st_err_log(31, __FILE__, __LINE__); rc = CKR_OPERATION_ACTIVE; goto done; } rc = decr_mgr_init( sess, &sess->decr_ctx, OP_DECRYPT_INIT, pMechanism, hKey ); if (rc != CKR_OK) { st_err_log(179, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, key = %d, mech = 0x%x\n", "C_DecryptInit", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, hKey, pMechanism->mechanism ); } UNLOCKIT; return rc; } // // CK_RV SC_Decrypt( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pEncryptedData || !pulDataLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->decr_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pData) length_only = TRUE; rc = decr_mgr_decrypt( sess, length_only, &sess->decr_ctx, pEncryptedData, ulEncryptedDataLen, pData, pulDataLen ); if (rc != CKR_OK) { st_err_log(100, __FILE__, __LINE__); } done: LLOCK; if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) decr_mgr_cleanup( &sess->decr_ctx ); if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, amount = %d\n", "C_Decrypt", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulEncryptedDataLen ); } UNLOCKIT; return rc; } // // CK_RV SC_DecryptUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pEncryptedPart || !pulPartLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->decr_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pPart) length_only = TRUE; rc = decr_mgr_decrypt_update( sess, length_only, &sess->decr_ctx, pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen ); if (rc != CKR_OK) { st_err_log(180, __FILE__, __LINE__); } done: LLOCK; if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL) decr_mgr_cleanup( &sess->decr_ctx ); if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, amount = %d\n", "C_DecryptUpdate", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulEncryptedPartLen ); } UNLOCKIT; return rc; } // // CK_RV SC_DecryptFinal( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pulLastPartLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->decr_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pLastPart) length_only = TRUE; rc = decr_mgr_decrypt_final( sess, length_only, &sess->decr_ctx, pLastPart, pulLastPartLen ); if (rc != CKR_OK) { st_err_log(181, __FILE__, __LINE__); } done: LLOCK; if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) decr_mgr_cleanup( &sess->decr_ctx ); if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, amount = %d\n", "C_DecryptFinal", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, *pulLastPartLen ); } UNLOCKIT; return rc; } // // CK_RV SC_DigestInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->digest_ctx.active == TRUE) { st_err_log(31, __FILE__, __LINE__); rc = CKR_OPERATION_ACTIVE; goto done; } rc = digest_mgr_init( sess, &sess->digest_ctx, pMechanism ); if (rc != CKR_OK) { st_err_log(123, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, mech = %x\n", "C_DigestInit", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, pMechanism->mechanism ); } UNLOCKIT; return rc; } // // CK_RV SC_Digest( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } // Netscape has been known to pass a null pData to DigestUpdate // but never for Digest. It doesn't really make sense to allow it here // if (!pData || !pulDigestLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->digest_ctx.active == FALSE) { st_err_log(85, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pDigest) length_only = TRUE; rc = digest_mgr_digest( sess, length_only, &sess->digest_ctx, pData, ulDataLen, pDigest, pulDigestLen ); if (rc != CKR_OK) { st_err_log(124, __FILE__, __LINE__); } done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) digest_mgr_cleanup( &sess->digest_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_Digest", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulDataLen ); } UNLOCKIT; return rc; } // // CK_RV SC_DigestUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } // Netscape has been known to pass a null pPart with ulPartLen == 0... // if (!pPart && ulPartLen != 0) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->digest_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (pPart){ rc = digest_mgr_digest_update( sess, &sess->digest_ctx, pPart, ulPartLen ); if (rc != CKR_OK) { st_err_log(124, __FILE__, __LINE__); } } done: if (rc != CKR_OK) digest_mgr_cleanup( &sess->digest_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_DigestUpdate", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulPartLen ); } UNLOCKIT; return rc; } // // CK_RV SC_DigestKey( ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->digest_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } rc = digest_mgr_digest_key( sess, &sess->digest_ctx, hKey ); if (rc != CKR_OK){ st_err_log(124, __FILE__, __LINE__); } done: if (rc != CKR_OK) digest_mgr_cleanup( &sess->digest_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, key = %d\n", "C_DigestKey", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, hKey ); } UNLOCKIT; return rc; } // // CK_RV SC_DigestFinal( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pulDigestLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->digest_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pDigest) length_only = TRUE; rc = digest_mgr_digest_final( sess, length_only, &sess->digest_ctx, pDigest, pulDigestLen ); if (rc != CKR_OK){ st_err_log(126, __FILE__, __LINE__); } done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) digest_mgr_cleanup( &sess->digest_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d\n", "C_DigestFinal", rc, (sess == NULL)?-1:(CK_LONG)sess->handle ); } UNLOCKIT; return rc; } // // CK_RV SC_SignInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } VALID_MECH(pMechanism); if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->sign_ctx.active == TRUE) { rc = CKR_OPERATION_ACTIVE; st_err_log(31, __FILE__, __LINE__); goto done; } rc = sign_mgr_init( sess, &sess->sign_ctx, pMechanism, FALSE, hKey ); if (rc != CKR_OK){ st_err_log(127, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, mech = %x\n", "C_SignInit", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, pMechanism->mechanism ); } UNLOCKIT; return rc; } // // CK_RV SC_Sign( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pData || !pulSignatureLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->sign_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pSignature) length_only = TRUE; rc = sign_mgr_sign( sess, length_only, &sess->sign_ctx, pData, ulDataLen, pSignature, pulSignatureLen ); if (rc != CKR_OK){ st_err_log(171, __FILE__, __LINE__); } done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) sign_mgr_cleanup( &sess->sign_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_Sign", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulDataLen ); } UNLOCKIT; return rc; } // // CK_RV SC_SignUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pPart) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->sign_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } rc = sign_mgr_sign_update( sess, &sess->sign_ctx, pPart, ulPartLen ); if (rc != CKR_OK){ st_err_log(128, __FILE__, __LINE__); } done: if (rc != CKR_OK) sign_mgr_cleanup( &sess->sign_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_SignUpdate", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulPartLen ); } UNLOCKIT; return rc; } // // CK_RV SC_SignFinal( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pulSignatureLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->sign_ctx.active == FALSE) { st_err_log(32, __FILE__, __LINE__); rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (!pSignature) length_only = TRUE; rc = sign_mgr_sign_final( sess, length_only, &sess->sign_ctx, pSignature, pulSignatureLen ); if (rc != CKR_OK){ st_err_log(129, __FILE__, __LINE__); } done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) sign_mgr_cleanup( &sess->sign_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d\n", "C_SignFinal", rc, (sess == NULL)?-1:(CK_LONG)sess->handle ); } UNLOCKIT; return rc; } // // CK_RV SC_SignRecoverInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->sign_ctx.active == TRUE) { rc = CKR_OPERATION_ACTIVE; st_err_log(31, __FILE__, __LINE__); goto done; } rc = sign_mgr_init( sess, &sess->sign_ctx, pMechanism, TRUE, hKey ); if (rc != CKR_OK){ st_err_log(127, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, mech = %x\n", "C_SignRecoverInit", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, pMechanism->mechanism ); } UNLOCKIT; return rc; } // // CK_RV SC_SignRecover( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); LOCKIT; rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pData || !pulSignatureLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if ((sess->sign_ctx.active == FALSE) || (sess->sign_ctx.recover == FALSE)) { rc = CKR_OPERATION_NOT_INITIALIZED; st_err_log(32, __FILE__, __LINE__); goto done; } if (!pSignature) length_only = TRUE; rc = sign_mgr_sign_recover( sess, length_only, &sess->sign_ctx, pData, ulDataLen, pSignature, pulSignatureLen ); if (rc != CKR_OK){ st_err_log(186, __FILE__, __LINE__); } done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) sign_mgr_cleanup( &sess->sign_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_SignRecover", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulDataLen ); } UNLOCKIT; return rc; } // // CK_RV SC_VerifyInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->verify_ctx.active == TRUE) { rc = CKR_OPERATION_ACTIVE; st_err_log(31, __FILE__, __LINE__); goto done; } rc = verify_mgr_init( sess, &sess->verify_ctx, pMechanism, FALSE, hKey ); if (rc != CKR_OK){ st_err_log(167, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, mech = %x\n", "C_VerifyInit", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, pMechanism->mechanism ); } UNLOCKIT; return rc; } // // CK_RV SC_Verify( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pData || !pSignature) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->verify_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; st_err_log(32, __FILE__, __LINE__); goto done; } rc = verify_mgr_verify( sess, &sess->verify_ctx, pData, ulDataLen, pSignature, ulSignatureLen ); if (rc != CKR_OK){ st_err_log(168, __FILE__, __LINE__); } done: verify_mgr_cleanup( &sess->verify_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_Verify", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulDataLen ); } UNLOCKIT; return rc; } // // CK_RV SC_VerifyUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pPart) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->verify_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; st_err_log(32, __FILE__, __LINE__); goto done; } rc = verify_mgr_verify_update( sess, &sess->verify_ctx, pPart, ulPartLen ); if (rc != CKR_OK){ st_err_log(169, __FILE__, __LINE__); } done: if (rc != CKR_OK) verify_mgr_cleanup( &sess->verify_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, datalen = %d\n", "C_VerifyUpdate", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, ulPartLen ); } UNLOCKIT; return rc; } // // CK_RV SC_VerifyFinal( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pSignature) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->verify_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; st_err_log(32, __FILE__, __LINE__); goto done; } rc = verify_mgr_verify_final( sess, &sess->verify_ctx, pSignature, ulSignatureLen ); if (rc != CKR_OK){ st_err_log(170, __FILE__, __LINE__); } done: verify_mgr_cleanup( &sess->verify_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d\n", "C_VerifyFinal", rc, (sess == NULL)?-1:(CK_LONG)sess->handle ); } UNLOCKIT; return rc; } // // CK_RV SC_VerifyRecoverInit( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism ){ st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } if (sess->verify_ctx.active == TRUE) { rc = CKR_OPERATION_ACTIVE; st_err_log(31, __FILE__, __LINE__); goto done; } rc = verify_mgr_init( sess, &sess->verify_ctx, pMechanism, TRUE, hKey ); if (rc != CKR_OK){ st_err_log(167, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, mech = %x\n", "C_VerifyRecoverInit", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, pMechanism->mechanism ); } UNLOCKIT; return rc; } // // CK_RV SC_VerifyRecover( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pSignature || !pulDataLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if ((sess->verify_ctx.active == FALSE) || (sess->verify_ctx.recover == FALSE)) { rc = CKR_OPERATION_NOT_INITIALIZED; st_err_log(32, __FILE__, __LINE__); goto done; } if (!pData) length_only = TRUE; rc = verify_mgr_verify_recover( sess, length_only, &sess->verify_ctx, pSignature, ulSignatureLen, pData, pulDataLen ); if (rc != CKR_OK){ st_err_log(187, __FILE__, __LINE__); } done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) verify_mgr_cleanup( &sess->verify_ctx ); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, recover len = %d, length_only = %d\n", "C_VerifyRecover", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, *pulDataLen, length_only ); } UNLOCKIT; return rc; } // // CK_RV SC_DigestEncryptUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ) { SESS_SET if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } // // CK_RV SC_DecryptDigestUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ) { SESS_SET if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } // // CK_RV SC_SignEncryptUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen ) { SESS_SET if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } // // CK_RV SC_DecryptVerifyUpdate( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen ) { SESS_SET if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } // // CK_RV SC_GenerateKey( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism || !phKey || (pTemplate == NULL && ulCount != 0)) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = key_mgr_generate_key( sess, pMechanism, pTemplate, ulCount, phKey ); if (rc != CKR_OK){ st_err_log(91, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { CK_ATTRIBUTE *attr = pTemplate; CK_ULONG i; stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, handle = %d, mech = %x\n", "C_GenerateKey", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, *phKey, pMechanism->mechanism ); for (i = 0; i < ulCount; i++, attr++) { CK_BYTE *ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } } UNLOCKIT; return rc; } // // CK_RV SC_GenerateKeyPair( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey ) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism || !phPublicKey || !phPrivateKey || (!pPublicKeyTemplate && (ulPublicKeyAttributeCount != 0)) || (!pPrivateKeyTemplate && (ulPrivateKeyAttributeCount != 0))) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = key_mgr_generate_key_pair( sess, pMechanism, pPublicKeyTemplate, ulPublicKeyAttributeCount, pPrivateKeyTemplate, ulPrivateKeyAttributeCount, phPublicKey, phPrivateKey ); if (rc != CKR_OK){ st_err_log(91, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { CK_ATTRIBUTE *attr = NULL; CK_ULONG i; stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, mech = %x\n", "C_GenerateKeyPair", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, pMechanism->mechanism ); if (rc == CKR_OK) { stlogit2(debugfile, " Public handle: %d\n", *phPublicKey ); stlogit2(debugfile, " Private handle: %d\n", *phPrivateKey ); } stlogit2(debugfile, " Public Template:\n"); attr = pPublicKeyTemplate; for (i = 0; i < ulPublicKeyAttributeCount; i++, attr++) { CK_BYTE *ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } stlogit2(debugfile, " Private Template:\n"); attr = pPrivateKeyTemplate; for (i = 0; i < ulPrivateKeyAttributeCount; i++, attr++) { CK_BYTE *ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } } UNLOCKIT; return rc; } // // CK_RV SC_WrapKey( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen ) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism || !pulWrappedKeyLen) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); if (!pWrappedKey) length_only = TRUE; sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = key_mgr_wrap_key( sess, length_only, pMechanism, hWrappingKey, hKey, pWrappedKey, pulWrappedKeyLen ); if (rc != CKR_OK){ st_err_log(188, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, encrypting key = %d, wrapped key = %d\n", "C_WrapKey", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, hWrappingKey, hKey ); } UNLOCKIT; return rc; } // // CK_RV SC_UnwrapKey( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey ) { SESSION * sess = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_ULONG i; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism || !pWrappedKey || (!pTemplate && ulCount != 0) || !phKey) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = key_mgr_unwrap_key( sess, pMechanism, pTemplate, ulCount, pWrappedKey, ulWrappedKeyLen, hUnwrappingKey, phKey ); if (rc != CKR_OK){ st_err_log(189, __FILE__, __LINE__); } done: // if (rc == CKR_OBJECT_HANDLE_INVALID) brkpt(); LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, decrypting key = %d, unwrapped key = %d\n", "C_UnwrapKey", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, hUnwrappingKey, *phKey ); attr = pTemplate; for (i = 0; i < ulCount; i++, attr++) { ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } } UNLOCKIT; return rc; } // // CK_RV SC_DeriveKey( ST_SESSION_HANDLE sSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey ) { SESSION * sess = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_ULONG i; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pMechanism || (!pTemplate && ulCount != 0)) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } VALID_MECH(pMechanism); sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (pin_expired(&sess->session_info, nv_token_data->token_info.flags) == TRUE) { st_err_log(36, __FILE__, __LINE__); rc = CKR_PIN_EXPIRED; goto done; } rc = key_mgr_derive_key( sess, pMechanism, hBaseKey, phKey, pTemplate, ulCount ); if (rc != CKR_OK){ st_err_log(190, __FILE__, __LINE__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, sess = %d, base key = %d, mech = %x\n", "C_DeriveKey", rc, (sess == NULL)?-1:(CK_LONG)sess->handle, hBaseKey, pMechanism->mechanism ); if (rc == CKR_OK) { switch (pMechanism->mechanism) { case CKM_SSL3_KEY_AND_MAC_DERIVE: { CK_SSL3_KEY_MAT_PARAMS *pReq; CK_SSL3_KEY_MAT_OUT *pPtr; pReq = (CK_SSL3_KEY_MAT_PARAMS *)pMechanism->pParameter; pPtr = pReq->pReturnedKeyMaterial; stlogit2(debugfile, " Client MAC key: %d\n", pPtr->hClientMacSecret ); stlogit2(debugfile, " Server MAC key: %d\n", pPtr->hServerMacSecret ); stlogit2(debugfile, " Client Key: %d\n", pPtr->hClientKey ); stlogit2(debugfile, " Server Key: %d\n", pPtr->hServerKey ); } break; case CKM_DH_PKCS_DERIVE: { stlogit2(debugfile, " DH Shared Secret: \n" ); } break ; default: stlogit2(debugfile, " Derived key: %d\n", *phKey ); } } attr = pTemplate; for (i = 0; i < ulCount; i++, attr++) { ptr = (CK_BYTE *)attr->pValue; stlogit2(debugfile, " %3d: Attribute type: 0x%08x\n", i, attr->type ); stlogit2(debugfile, " Value Length: %08d\n", attr->ulValueLen ); if (attr->ulValueLen != (CK_ULONG)(-1) && (ptr != NULL)) stlogit2(debugfile, " First 4 bytes: %02x %02x %02x %02x", ptr[0], ptr[1], ptr[2], ptr[3] ); stlogit2(debugfile, "\n\n"); } } UNLOCKIT; return rc; } // // CK_RV SC_SeedRandom( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen ) { SESS_SET if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } return CKR_OK; } // // CK_RV SC_GenerateRandom( ST_SESSION_HANDLE sSession, CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen ) { SESSION *sess = NULL; CK_RV rc = CKR_OK; SESS_SET LOCKIT; if (st_Initialized() == FALSE) { st_err_log(72, __FILE__, __LINE__); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (!pRandomData && ulRandomLen != 0) { st_err_log(5, __FILE__, __LINE__, __FUNCTION__); rc = CKR_ARGUMENTS_BAD; goto done; } sess = SESSION_MGR_FIND( hSession ); if (!sess) { st_err_log(40, __FILE__, __LINE__); rc = CKR_SESSION_HANDLE_INVALID; goto done; } rc = rng_generate( pRandomData, ulRandomLen ); if (rc != CKR_OK){ st_err_log(130, __FILE__, __LINE__, __FUNCTION__); } done: LLOCK; if (debugfile) { stlogit2(debugfile, "%-25s: rc = %08x, %d bytes\n", "C_GenerateRandom", rc, ulRandomLen ); } UNLOCKIT; return rc; } // // CK_RV SC_GetFunctionStatus( ST_SESSION_HANDLE sSession ) { SESS_SET if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } st_err_log(17, __FILE__, __LINE__); return CKR_FUNCTION_NOT_PARALLEL; } // // CK_RV SC_CancelFunction( ST_SESSION_HANDLE sSession ) { SESS_SET if (st_Initialized() == FALSE){ st_err_log(72, __FILE__, __LINE__); return CKR_CRYPTOKI_NOT_INITIALIZED; } st_err_log(17, __FILE__, __LINE__); return CKR_FUNCTION_NOT_PARALLEL; } // // CK_RV QueryTweakValues( void ) { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } // // CK_RV UpdateTweakValues( void ) { st_err_log(142, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_NOT_SUPPORTED; } // Added for AIX work void SC_SetFunctionList(void){ function_list.ST_Initialize = (void *)ST_Initialize; function_list.ST_GetTokenInfo = SC_GetTokenInfo; function_list.ST_GetMechanismList = SC_GetMechanismList; function_list.ST_GetMechanismInfo = SC_GetMechanismInfo; function_list.ST_InitToken = SC_InitToken; function_list.ST_InitPIN = SC_InitPIN; function_list.ST_SetPIN = SC_SetPIN; function_list.ST_OpenSession = SC_OpenSession; function_list.ST_CloseSession = SC_CloseSession; function_list.ST_GetSessionInfo = SC_GetSessionInfo; function_list.ST_GetOperationState = SC_GetOperationState; function_list.ST_SetOperationState = SC_SetOperationState; function_list.ST_Login = SC_Login; function_list.ST_Logout = SC_Logout; function_list.ST_CreateObject = SC_CreateObject; function_list.ST_CopyObject = SC_CopyObject; function_list.ST_DestroyObject = SC_DestroyObject; function_list.ST_GetObjectSize = SC_GetObjectSize; function_list.ST_GetAttributeValue = SC_GetAttributeValue; function_list.ST_SetAttributeValue = SC_SetAttributeValue; function_list.ST_FindObjectsInit = SC_FindObjectsInit; function_list.ST_FindObjects = SC_FindObjects; function_list.ST_FindObjectsFinal = SC_FindObjectsFinal; function_list.ST_EncryptInit = SC_EncryptInit; function_list.ST_Encrypt = SC_Encrypt; function_list.ST_EncryptUpdate = SC_EncryptUpdate; function_list.ST_EncryptFinal = SC_EncryptFinal; function_list.ST_DecryptInit = SC_DecryptInit; function_list.ST_Decrypt = SC_Decrypt; function_list.ST_DecryptUpdate = SC_DecryptUpdate; function_list.ST_DecryptFinal = SC_DecryptFinal; function_list.ST_DigestInit = SC_DigestInit; function_list.ST_Digest = SC_Digest; function_list.ST_DigestUpdate = SC_DigestUpdate; function_list.ST_DigestKey = SC_DigestKey; function_list.ST_DigestFinal = SC_DigestFinal; function_list.ST_SignInit = SC_SignInit; function_list.ST_Sign = SC_Sign; function_list.ST_SignUpdate = SC_SignUpdate; function_list.ST_SignFinal = SC_SignFinal; function_list.ST_SignRecoverInit = SC_SignRecoverInit; function_list.ST_SignRecover = SC_SignRecover; function_list.ST_VerifyInit = SC_VerifyInit; function_list.ST_Verify = SC_Verify; function_list.ST_VerifyUpdate = SC_VerifyUpdate; function_list.ST_VerifyFinal = SC_VerifyFinal; function_list.ST_VerifyRecoverInit = SC_VerifyRecoverInit; function_list.ST_VerifyRecover = SC_VerifyRecover; function_list.ST_DigestEncryptUpdate = NULL; // SC_DigestEncryptUpdate; function_list.ST_DecryptDigestUpdate = NULL; // SC_DecryptDigestUpdate; function_list.ST_SignEncryptUpdate = NULL; //SC_SignEncryptUpdate; function_list.ST_DecryptVerifyUpdate = NULL; // SC_DecryptVerifyUpdate; function_list.ST_GenerateKey = SC_GenerateKey; function_list.ST_GenerateKeyPair = SC_GenerateKeyPair; function_list.ST_WrapKey = SC_WrapKey; function_list.ST_UnwrapKey = SC_UnwrapKey; function_list.ST_DeriveKey = SC_DeriveKey; function_list.ST_SeedRandom = SC_SeedRandom ; function_list.ST_GenerateRandom = SC_GenerateRandom; function_list.ST_GetFunctionStatus = NULL; // SC_GetFunctionStatus; function_list.ST_CancelFunction = NULL; // SC_CancelFunction; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/mech_dh.c0000640000175000017500000005265711327631345020466 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /************************************************************************ * * * Copyright: Corrent Corporation (c) 2000-2003 * * * * Filename: mech_dh.c * * Created By: Kapil Sood * * Created On: Jan 18, 2003 * * Description: This is the file implementing Diffie-Hellman * * key pair generation and shared key derivation * * operations. * * * ************************************************************************/ // File: mech_dh.c // // Mechanisms for DH // // Routines contained within: #include #include // for memcmp() et al #include #include #include #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" #ifndef NODH // // CK_RV dh_pkcs_derive( SESSION * sess, CK_MECHANISM * mech, CK_OBJECT_HANDLE base_key, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE * handle ) { CK_RV rc; CK_ULONG i, keyclass = 0, keytype = 0 ; CK_ATTRIBUTE *new_attr ; OBJECT *temp_obj = NULL; CK_BYTE secret_key_value[256] ; CK_ULONG secret_key_value_len = 256 ; // Prelim checking of sess, mech, pTemplate, and ulCount was // done in the calling function (key_mgr_derive_key). // Perform DH checking of parameters // Check the existance of the public-value in mechanism if ((!mech->pParameter) || ((mech->ulParameterLen != 64) && (mech->ulParameterLen != 96) && (mech->ulParameterLen != 128) && (mech->ulParameterLen != 192) && (mech->ulParameterLen != 256))) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Check valid object handle on base_key if (&base_key == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Extract the object class and keytype from the supplied template. for (i=0; i < ulCount; i++) { if (pTemplate[i].type == CKA_CLASS) { keyclass = *(CK_OBJECT_CLASS *)pTemplate[i].pValue; if (keyclass != CKO_SECRET_KEY) { st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } if (pTemplate[i].type == CKA_KEY_TYPE) keytype = *(CK_ULONG *)pTemplate[i].pValue; } // Extract public-key from mechanism parameters. base-key contains the // private key, prime, and base. The return value will be in the handle. rc = ckm_dh_pkcs_derive( mech->pParameter, mech->ulParameterLen, base_key, secret_key_value, &secret_key_value_len ); if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED ; } // Build the attribute from the vales that were returned back rc = build_attribute( CKA_VALUE, secret_key_value, secret_key_value_len, &new_attr ); if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED ; } // Create the object that will be passed back as a handle. This will // contain the new (computed) value of the attribute. rc = object_mgr_create_skel( sess, pTemplate, ulCount, MODE_KEYGEN, keyclass, keytype, &temp_obj ); if (rc != CKR_OK){ st_err_log(89, __FILE__, __LINE__); return rc; } // Update the template in the object with the new attribute template_update_attribute( temp_obj->template, new_attr ); // at this point, the derived key is fully constructed...assign an // object handle and store the key // rc = object_mgr_create_final( sess, temp_obj, handle ); if (rc != CKR_OK) { st_err_log(90, __FILE__, __LINE__); object_free( temp_obj ); return rc; } return rc; } // // mechanisms // // // CK_RV ckm_dh_pkcs_derive( CK_VOID_PTR other_pubkey, CK_ULONG other_pubkey_len, CK_OBJECT_HANDLE base_key, CK_BYTE *secret_value, CK_ULONG *secret_value_len ) { CK_RV rc; CK_BYTE p[256] ; CK_ULONG p_len ; CK_BYTE x[256] ; CK_ULONG x_len ; CK_ATTRIBUTE *temp_attr ; OBJECT *base_key_obj = NULL ; CK_BYTE *p_other_pubkey ; rc = object_mgr_find_in_map1( base_key, &base_key_obj ); if (rc != CKR_OK){ st_err_log(18, __FILE__, __LINE__); return CKR_KEY_HANDLE_INVALID; } // Extract secret (x) from base_key rc = template_attribute_find( base_key_obj->template, CKA_VALUE, &temp_attr ); if (rc == FALSE) { st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { memset(x, 0, sizeof(x)) ; x_len = temp_attr->ulValueLen ; memcpy(x, (CK_BYTE *)temp_attr->pValue, x_len) ; } // Extract prime (p) from base_key rc = template_attribute_find( base_key_obj->template, CKA_PRIME, &temp_attr ); if (rc == FALSE) { st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { memset(p, 0, sizeof(p)) ; p_len = temp_attr->ulValueLen ; memcpy(p, (CK_BYTE *)temp_attr->pValue, p_len) ; } p_other_pubkey = (CK_BYTE *) other_pubkey ; // Perform: z = other_pubkey^x mod p rc = token_specific.t_dh_pkcs_derive(secret_value, secret_value_len, p_other_pubkey, other_pubkey_len, x, x_len, p, p_len ); if (rc != CKR_OK) { st_err_log(191, __FILE__, __LINE__); return CKR_FUNCTION_FAILED ; } return rc; } // // CK_RV ckm_dh_pkcs_key_pair_gen( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ) { CK_RV rc; rc = token_specific.t_dh_pkcs_key_pair_gen(publ_tmpl,priv_tmpl); if (rc != CKR_OK) { st_err_log(91, __FILE__, __LINE__); } return rc; } #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/decr_mgr.c0000751000175000017500000011635511327631345020660 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: decr_mgr.c // // Decryption manager routines // #include #include // for memcmp() et al #include #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // // CK_RV decr_mgr_init( SESSION *sess, ENCR_DECR_CONTEXT *ctx, CK_ULONG operation, CK_MECHANISM *mech, CK_OBJECT_HANDLE key_handle ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_KEY_TYPE keytype; CK_BBOOL flag; CK_RV rc; if (!sess){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active != FALSE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } // key usage restrictions // if (operation == OP_DECRYPT_INIT) { rc = object_mgr_find_in_map1( key_handle, &key_obj ); if (rc != CKR_OK){ st_err_log(18, __FILE__, __LINE__); return CKR_KEY_HANDLE_INVALID; } // is key allowed to do general decryption? // rc = template_attribute_find( key_obj->template, CKA_DECRYPT, &attr ); if (rc == FALSE){ st_err_log(85, __FILE__, __LINE__); return CKR_KEY_FUNCTION_NOT_PERMITTED; } else { flag = *(CK_BBOOL *)attr->pValue; if (flag != TRUE){ st_err_log(85, __FILE__, __LINE__); return CKR_KEY_FUNCTION_NOT_PERMITTED; } } } else if (operation == OP_UNWRAP) { rc = object_mgr_find_in_map1( key_handle, &key_obj ); if (rc != CKR_OK){ st_err_log(62, __FILE__, __LINE__); return CKR_WRAPPING_KEY_HANDLE_INVALID; } // is key allowed to unwrap other keys? // rc = template_attribute_find( key_obj->template, CKA_UNWRAP, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; // Cryptoki doesn't define a better return code } else { flag = *(CK_BBOOL *)attr->pValue; if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } } else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // is the mechanism supported? is the key type correct? is a // parameter present if required? is the key size allowed? // does the key support decryption? // // Will the FCV allow the operation? // switch (mech->mechanism) { case CKM_DES_ECB: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_56_BIT_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_CDMF_ECB: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_CDMF){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_CDMF_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_DES_CBC: case CKM_DES_CBC_PAD: { if (mech->ulParameterLen != DES_BLOCK_SIZE){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_56_BIT_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_CDMF_CBC: case CKM_CDMF_CBC_PAD: { if (mech->ulParameterLen != DES_BLOCK_SIZE){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_CDMF){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_DES3_ECB: { if (mech->ulParameterLen != 0) return CKR_MECHANISM_PARAM_INVALID; // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES3 && keytype != CKK_DES2){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_TRIPLE_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_DES3_CBC: case CKM_DES3_CBC_PAD: { if (mech->ulParameterLen != DES_BLOCK_SIZE) return CKR_MECHANISM_PARAM_INVALID; // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES3 && keytype != CKK_DES2){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_TRIPLE_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_RSA_X_509: case CKM_RSA_PKCS: { if (mech->ulParameterLen != 0) return CKR_MECHANISM_PARAM_INVALID; rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_RSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // rc = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); // if (rc == FALSE || // nv_FCV.SymmetricModLength/8 < attr->value_length) // return (operation == OP_DECRYPT_INIT ? CKR_KEY_SIZE_RANGE : CKR_UNWRAPPING_KEY_SIZE_RANGE ); // RSA cannot be used for multi-part operations // ctx->context_len = 0; ctx->context = NULL; } break; case CKM_AES_ECB: { // XXX Copied from DES3, should be verified - KEY if (mech->ulParameterLen != 0) return CKR_MECHANISM_PARAM_INVALID; // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_AES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(AES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(AES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(AES_CONTEXT) ); } break; case CKM_AES_CBC: case CKM_AES_CBC_PAD: { // XXX Copied from DES3, should be verified - KEY if (mech->ulParameterLen != AES_INIT_VECTOR_SIZE) return CKR_MECHANISM_PARAM_INVALID; // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_AES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(AES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(AES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(AES_CONTEXT) ); } break; default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } if (mech->ulParameterLen > 0) { ptr = (CK_BYTE *)malloc(mech->ulParameterLen); if (!ptr){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( ptr, mech->pParameter, mech->ulParameterLen ); } ctx->key = key_handle; ctx->mech.ulParameterLen = mech->ulParameterLen; ctx->mech.mechanism = mech->mechanism; ctx->mech.pParameter = ptr; ctx->multi = FALSE; ctx->active = TRUE; return CKR_OK; } // // CK_RV decr_mgr_cleanup( ENCR_DECR_CONTEXT *ctx ) { if (!ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } ctx->key = 0; ctx->mech.ulParameterLen = 0; ctx->mech.mechanism = 0; ctx->multi = FALSE; ctx->active = FALSE; ctx->context_len = 0; if (ctx->mech.pParameter) { free( ctx->mech.pParameter ); ctx->mech.pParameter = NULL; } if (ctx->context) { free( ctx->context ); ctx->context = NULL; } return CKR_OK; } // // CK_RV decr_mgr_decrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } // if the caller just wants the decrypted length, there is no reason to // specify the input data. I just need the data length // if ((length_only == FALSE) && (!in_data || !out_data)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->multi == TRUE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } switch (ctx->mech.mechanism) { case CKM_CDMF_ECB: case CKM_DES_ECB: return des_ecb_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_CDMF_CBC: case CKM_DES_CBC: return des_cbc_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES_CBC_PAD: case CKM_CDMF_CBC_PAD: return des_cbc_pad_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_ECB: return des3_ecb_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_CBC: return des3_cbc_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_CBC_PAD: return des3_cbc_pad_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_RSA_PKCS: return rsa_pkcs_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_RSA_X_509: return rsa_x509_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #ifndef NOAES case CKM_AES_CBC: return aes_cbc_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_ECB: return aes_ecb_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_CBC_PAD: return aes_cbc_pad_decrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif default: return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV decr_mgr_decrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { if (!sess || !in_data || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!out_data && !length_only){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } ctx->multi = TRUE; switch (ctx->mech.mechanism) { case CKM_CDMF_ECB: case CKM_DES_ECB: return des_ecb_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_CDMF_CBC: case CKM_DES_CBC: return des_cbc_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES_CBC_PAD: case CKM_CDMF_CBC_PAD: return des_cbc_pad_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_ECB: return des3_ecb_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_CBC: return des3_cbc_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_CBC_PAD: return des3_cbc_pad_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #ifndef NOAES case CKM_AES_ECB: return aes_ecb_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_CBC: return aes_cbc_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_CBC_PAD: return aes_cbc_pad_decrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV decr_mgr_decrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(28, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } switch (ctx->mech.mechanism) { case CKM_CDMF_ECB: case CKM_DES_ECB: return des_ecb_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_CDMF_CBC: case CKM_DES_CBC: return des_cbc_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_DES_CBC_PAD: case CKM_CDMF_CBC_PAD: return des_cbc_pad_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_DES3_ECB: return des3_ecb_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_DES3_CBC: return des3_cbc_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_DES3_CBC_PAD: return des3_cbc_pad_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); #ifndef NOAES case CKM_AES_ECB: return aes_ecb_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_AES_CBC: return aes_cbc_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_AES_CBC_PAD: return aes_cbc_pad_decrypt_final( sess, length_only, ctx, out_data, out_data_len ); #endif default: st_err_log(28, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/c_extern.h0000751000175000017500000004471711327631345020714 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/lib/pkcs11/common/c_extern.h,v 1.1 2005/01/18 16:09:01 kyoder Exp $ */ // /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: extern.h // // Lists extern (global) variables for the coprocessor-side code // #ifndef _EXTERN_H #define _EXTERN_H #define malloc(x) newmalloc(x) #define free(x) newfree(x) #define realloc(x,y) newrealloc(x,y) _prelinkc_ void _postlinkc_ newfree(void *); _prelinkc_ void * _postlinkc_ newmalloc(size_t); _prelinkc_ void * _postlinkc_ newrealloc(void *,size_t); CK_RV api_DummyFunction ( sccRequestHeader_t *req, LEEDS_REQUEST *request, LEEDS_REPLY *reply ); CK_RV do_RND_Generate ( sccRequestHeader_t *req, LEEDS_REQUEST *request, LEEDS_REPLY *reply ); CK_RV do_DES_KeyGen ( sccRequestHeader_t *req, LEEDS_REQUEST *request, LEEDS_REPLY *reply ); CK_RV do_CDMF_KeyGen ( sccRequestHeader_t *req, LEEDS_REQUEST *request, LEEDS_REPLY *reply ); CK_RV do_Encrypt_DES_ECB ( sccRequestHeader_t *req, LEEDS_REQUEST *request, LEEDS_REPLY *reply ); CK_RV do_Decrypt_DES_ECB ( sccRequestHeader_t *req, LEEDS_REQUEST *request, LEEDS_REPLY *reply ); CK_RV do_Encrypt_DES_CBC ( sccRequestHeader_t *req, LEEDS_REQUEST *request, LEEDS_REPLY *reply ); CK_RV do_Decrypt_DES_CBC ( sccRequestHeader_t *req, LEEDS_REQUEST *request, LEEDS_REPLY *reply ); CK_RV do_Encrypt_DES3_ECB( sccRequestHeader_t *req, LEEDS_REQUEST *request, LEEDS_REPLY *reply ); CK_RV do_Decrypt_DES3_ECB( sccRequestHeader_t *req, LEEDS_REQUEST *request, LEEDS_REPLY *reply ); CK_RV do_Encrypt_DES3_CBC( sccRequestHeader_t *req, LEEDS_REQUEST *request, LEEDS_REPLY *reply ); CK_RV do_Decrypt_DES3_CBC( sccRequestHeader_t *req, LEEDS_REQUEST *request, LEEDS_REPLY *reply ); CK_RV do_SHA1_Hash ( sccRequestHeader_t *req, LEEDS_REQUEST *request, LEEDS_REPLY *reply ); CK_RV do_SHA1_Update ( sccRequestHeader_t *req, LEEDS_REQUEST *request, LEEDS_REPLY *reply ); CK_RV do_SHA1_Final ( sccRequestHeader_t *req, LEEDS_REQUEST *request, LEEDS_REPLY *reply ); CK_RV do_RSA_KeyPairGen ( sccRequestHeader_t *req, LEEDS_REQUEST *request, LEEDS_REPLY *reply ); CK_RV do_RSA_Encrypt ( sccRequestHeader_t *req, LEEDS_REQUEST *request, LEEDS_REPLY *reply ); CK_RV do_RSA_Decrypt ( sccRequestHeader_t *req, LEEDS_REQUEST *request, LEEDS_REPLY *reply ); CK_RV do_DSA_KeyPairGen ( sccRequestHeader_t *req, LEEDS_REQUEST *request, LEEDS_REPLY *reply ); CK_RV do_DSA_Sign ( sccRequestHeader_t *req, LEEDS_REQUEST *request, LEEDS_REPLY *reply ); CK_RV do_DSA_Verify ( sccRequestHeader_t *req, LEEDS_REQUEST *request, LEEDS_REPLY *reply ); CK_RV mp_subtract( CK_BYTE *bigint, CK_ULONG val, CK_ULONG len ); CK_RV mp_mult( CK_BYTE *bigint_a, CK_ULONG a_len, CK_BYTE *bigint_b, CK_ULONG b_len, CK_BYTE *bigint_n, CK_ULONG n_len, CK_BYTE *result, CK_ULONG *result_len ); CK_RV mp_exp( CK_BYTE *bigint_a, CK_ULONG a_len, CK_BYTE *bigint_b, CK_ULONG b_len, CK_BYTE *bigint_n, CK_ULONG n_len, CK_BYTE *result, CK_ULONG *result_len ); CK_BYTE parity_adjust( CK_BYTE b ); CK_RV parity_is_odd( CK_BYTE b ); CK_RV ckm_rsa_compute_priv_exp( sccPKCSKeyToken_t * key_token, CK_BYTE * dest, CK_ULONG * exp_len ); unsigned long treeCheck(int treeIdx); void *newmalloc(size_t size); void newfree(void *ptr); void *newrealloc(void *oldptr,size_t size); #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/object.c0000751000175000017500000010244211327631345020334 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: object.c // // Object manager related functions // // Functions contained within: // // object_create // object_free // object_is_modifiable // object_is_private // object_is_token_object // object_is_session_object // #include #include #include #include #ifdef LEEDS_BUILD #include // for memcmp() et al #endif #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" #include "pkcs32.h" // object_create() // // Args: void * attributes : (INPUT) pointer to data block containing ATTRIBUTEs // OBJECT * obj : (OUTPUT) destination object // // Creates an object with the specified attributes. Verifies that all required // attributes are present and adds any missing attributes that have Cryptoki-defined // default values. This routine does not check whether the session is authorized // to create the object. That is done elsewhere (see object_mgr_create()) // CK_RV object_create( CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, OBJECT ** obj ) { OBJECT * o = NULL; CK_ATTRIBUTE * attr = NULL; CK_ATTRIBUTE * sensitive = NULL; CK_ATTRIBUTE * extractable = NULL; CK_ATTRIBUTE * local = NULL; CK_BBOOL class_given = FALSE; CK_BBOOL subclass_given = FALSE; CK_BBOOL flag; CK_ULONG class = 0xFFFFFFFF, subclass = 0xFFFFFFFF; CK_RV rc; unsigned int i; if (!pTemplate){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // extract the object class and subclass // attr = pTemplate; for (i=0; i < ulCount; i++, attr++) { if (attr->type == CKA_CLASS) { class = *(CK_OBJECT_CLASS *)attr->pValue; class_given = TRUE; } if (attr->type == CKA_CERTIFICATE_TYPE) { subclass = *(CK_CERTIFICATE_TYPE *)attr->pValue; subclass_given = TRUE; } if (attr->type == CKA_KEY_TYPE) { subclass = *(CK_KEY_TYPE *)attr->pValue; subclass_given = TRUE; } if (attr->type == CKA_HW_FEATURE_TYPE) { subclass = *(CK_HW_FEATURE_TYPE *)attr->pValue; subclass_given = TRUE; } } if (class_given == FALSE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } // Return CKR_ATTRIBUTE_TYPE_INVALID when trying to create a // vendor-defined object. if (class >= CKO_VENDOR_DEFINED) { st_err_log(8, __FILE__, __LINE__); return CKR_ATTRIBUTE_TYPE_INVALID; } if (class != CKO_DATA && subclass_given != TRUE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } rc = object_create_skel( pTemplate, ulCount, MODE_CREATE, class, subclass, &o ); if (rc != CKR_OK){ st_err_log(89, __FILE__, __LINE__); return rc; } // for key objects, we need be careful... // // note: I would think that keys loaded with C_CreateObject should // have their CKA_NEVER_EXTRACTABLE == FALSE and // CKA_ALWAYS_SENSITIVE == FALSE since the key data was presumably // stored in the clear prior to the call to C_CreateObject. The // PKCS #11 spec doesn't impose this restriction however. // if (class == CKO_PRIVATE_KEY || class == CKO_SECRET_KEY) { rc = template_attribute_find( o->template, CKA_SENSITIVE, &attr ); if (rc == FALSE) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } flag = *(CK_BBOOL *)attr->pValue; rc = build_attribute( CKA_ALWAYS_SENSITIVE, &flag, sizeof(CK_BYTE), &sensitive ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } rc = template_attribute_find( o->template, CKA_EXTRACTABLE, &attr ); if (rc == FALSE) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } flag = *(CK_BBOOL *)attr->pValue; flag = (~flag) & 0x1; rc = build_attribute( CKA_NEVER_EXTRACTABLE, &flag, sizeof(CK_BYTE), &extractable ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto error; } template_update_attribute( o->template, sensitive ); template_update_attribute( o->template, extractable ); } *obj = o; return CKR_OK; error: if (sensitive) free( sensitive ); if (extractable) free( extractable ); if (local) free( local ); object_free( o ); return rc; } // object_copy() // // Args: OBJECT * old_obj : (INPUT) pointer to the source object // void * attributes : (INPUT) pointer to data block containing additional ATTRIBUTEs // CK_ULONG count : (INPUT) number of new attributes // OBJECT ** new_obj : (OUTPUT) destination object // // Builds a copy of the specified object. The new object gets the original // object's attribute template plus any additional attributes that are specified. // Verifies that all required attributes are present. This routine does not // check whether the session is authorized to copy the object -- routines at // the individual object level don't have the concept of "session". These checks // are done by the object manager. // CK_RV object_copy( CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, OBJECT * old_obj, OBJECT ** new_obj ) { TEMPLATE * tmpl = NULL; TEMPLATE * new_tmpl = NULL; OBJECT * o = NULL; CK_BBOOL found; CK_ULONG class, subclass; CK_RV rc; if (!old_obj || !pTemplate || !new_obj){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } o = (OBJECT *)malloc(sizeof(OBJECT)); tmpl = (TEMPLATE *)malloc(sizeof(TEMPLATE)); new_tmpl = (TEMPLATE *)malloc(sizeof(TEMPLATE)); if (!o || !tmpl || !new_tmpl) { rc = CKR_HOST_MEMORY; st_err_log(0, __FILE__, __LINE__); goto error; } memset( o, 0x0, sizeof(OBJECT) ); memset( tmpl, 0x0, sizeof(TEMPLATE) ); memset( new_tmpl, 0x0, sizeof(TEMPLATE) ); // copy the original object's attribute template // rc = template_copy( tmpl, old_obj->template ); if (rc != CKR_OK){ st_err_log(163, __FILE__, __LINE__); goto error; } rc = template_add_attributes( new_tmpl, pTemplate, ulCount ); if (rc != CKR_OK){ st_err_log(164, __FILE__, __LINE__); goto error; } // at this point, the new object has the list of attributes. we need // to do some more checking now: // 1) invalid attribute values // 2) missing required attributes // 3) attributes inappropriate for the object class // 4) conflicting attributes/values // found = template_get_class( tmpl, &class, &subclass ); if (found == FALSE) { st_err_log(49, __FILE__, __LINE__); rc = CKR_TEMPLATE_INCONSISTENT; goto error; } // the user cannot change object classes so we assume the existing // object attributes are valid. we still need to check the new attributes. // we cannot merge the new attributes in with the old ones and then check // for validity because some attributes are added internally and are not // allowed to be specified by the user (ie. CKA_LOCAL for key types) but // may still be part of the old template. // rc = template_validate_attributes( new_tmpl, class, subclass, MODE_COPY ); if (rc != CKR_OK){ st_err_log(165, __FILE__, __LINE__); goto error; } // merge in the new attributes // rc = template_merge( tmpl, &new_tmpl ); if (rc != CKR_OK){ st_err_log(165, __FILE__, __LINE__); goto error; } // do we need this? since an attribute cannot be removed, the original // object's template (contained in tmpl) already has the required attributes // present // rc = template_check_required_attributes( tmpl, class, subclass, MODE_COPY ); if (rc != CKR_OK){ st_err_log(166, __FILE__, __LINE__); goto error; } // at this point, we should have a valid object with correct attributes // o->template = tmpl; *new_obj = o; return CKR_OK; error: if (tmpl) template_free( tmpl ); if (new_tmpl) template_free( new_tmpl ); if (o) object_free( o ); return rc; } // object_flatten() - this is still used when saving token objects // CK_RV object_flatten( OBJECT * obj, CK_BYTE ** data, CK_ULONG * len ) { CK_BYTE * buf = NULL; CK_ULONG tmpl_len, total_len; CK_ULONG offset; CK_ULONG_32 count; long rc; if (!obj){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } count = template_get_count( obj->template ); tmpl_len = template_get_compressed_size ( obj->template ); total_len = tmpl_len + sizeof(CK_OBJECT_CLASS_32) + sizeof(CK_ULONG_32) + 8; buf = (CK_BYTE *)malloc(total_len); if (!buf){ // SAB XXX FIXME This was DATA st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( (CK_BYTE *)buf,0x0,total_len); offset = 0; memcpy( buf + offset, &obj->class, sizeof(CK_OBJECT_CLASS_32) ); offset += sizeof(CK_OBJECT_CLASS_32); memcpy( buf + offset, &count, sizeof(CK_ULONG_32) ); offset += sizeof(CK_ULONG_32); memcpy( buf + offset, &obj->name, sizeof(CK_BYTE) * 8 ); offset += 8; rc = template_flatten( obj->template, buf + offset ); if (rc != CKR_OK) { free( buf ); return rc; } *data = buf; *len = total_len; return CKR_OK; } // object_free() // // does what it says... // CK_BBOOL object_free( OBJECT *obj ) { template_free( obj->template ); free( obj ); return TRUE; } // object_is_modifiable() // CK_BBOOL object_is_modifiable( OBJECT *obj ) { CK_ATTRIBUTE * attr = NULL; CK_BBOOL modifiable; CK_BBOOL found; found = template_attribute_find( obj->template, CKA_MODIFIABLE, &attr ); if (found == FALSE) return TRUE; // should always be found but we default to TRUE modifiable = *(CK_BBOOL *)attr->pValue; return modifiable; } // object_is_private() // // an is_private member should probably be added to OBJECT // CK_BBOOL object_is_private( OBJECT *obj ) { CK_ATTRIBUTE * attr = NULL; CK_BBOOL priv; CK_BBOOL found; found = template_attribute_find( obj->template, CKA_PRIVATE, &attr ); if (found == FALSE){ return TRUE; // should always be found but we default to TRUE } if ( attr == NULL) return TRUE; priv = *((CK_BBOOL *)attr->pValue); return priv; } // object_is_public() // CK_BBOOL object_is_public( OBJECT *obj ) { CK_BBOOL rc; rc = object_is_private( obj ); if (rc) return FALSE; return TRUE; } // object_is_token_object() // CK_BBOOL object_is_token_object( OBJECT *obj ) { CK_ATTRIBUTE * attr = NULL; CK_BBOOL is_token; CK_BBOOL found; found = template_attribute_find( obj->template, CKA_TOKEN, &attr ); if (found == FALSE) return FALSE; is_token = *(CK_BBOOL *)attr->pValue; return is_token; } // object_is_session_object() // CK_BBOOL object_is_session_object( OBJECT *obj ) { CK_BBOOL rc; rc = object_is_token_object( obj ); if (rc) return FALSE; else return TRUE; } // object_get_size() // CK_ULONG object_get_size( OBJECT *obj ) { CK_ULONG size; size = sizeof(OBJECT) + template_get_size(obj->template); return size; } // // CK_RV object_get_attribute_values( OBJECT * obj, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ) { TEMPLATE *obj_tmpl = NULL; CK_ATTRIBUTE *attr = NULL; CK_ULONG i; CK_BBOOL flag; CK_RV rc; rc = CKR_OK; obj_tmpl = obj->template; for (i=0; i < ulCount; i++) { flag = template_check_exportability( obj_tmpl, pTemplate[i].type); if (flag == FALSE) { st_err_log(70, __FILE__, __LINE__); rc = CKR_ATTRIBUTE_SENSITIVE; pTemplate[i].ulValueLen = (CK_ULONG)-1; continue; } flag = template_attribute_find( obj_tmpl, pTemplate[i].type, &attr ); if (flag == FALSE) { st_err_log(8, __FILE__, __LINE__); rc = CKR_ATTRIBUTE_TYPE_INVALID; pTemplate[i].ulValueLen = (CK_ULONG)-1; continue; } if (pTemplate[i].pValue == NULL) { pTemplate[i].ulValueLen = attr->ulValueLen; } else if (pTemplate[i].ulValueLen >= attr->ulValueLen) { memcpy( pTemplate[i].pValue, attr->pValue, attr->ulValueLen ); pTemplate[i].ulValueLen = attr->ulValueLen; } else { st_err_log(111, __FILE__, __LINE__); rc = CKR_BUFFER_TOO_SMALL; pTemplate[i].ulValueLen = (CK_ULONG)-1; } } return rc; } // object_set_attribute_values() // CK_RV object_set_attribute_values( OBJECT * obj, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount ) { TEMPLATE * new_tmpl; CK_BBOOL found; CK_ULONG class, subclass; CK_RV rc; if (!obj || !pTemplate){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } found = template_get_class( obj->template, &class, &subclass ); if (found == FALSE) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } new_tmpl = (TEMPLATE *)malloc(sizeof(TEMPLATE)); if (!new_tmpl){ st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( new_tmpl, 0x0, sizeof(TEMPLATE) ); rc = template_add_attributes( new_tmpl, pTemplate, ulCount ); if (rc != CKR_OK){ st_err_log(164, __FILE__, __LINE__); goto error; } // the user cannot change object classes so we assume the existing // object attributes are valid. we still need to check the new attributes. // we cannot merge the new attributes in with the old ones and then check // for validity because some attributes are added internally and are not // allowed to be specified by the user (ie. CKA_LOCAL for key types) but // may still be part of the old template. // rc = template_validate_attributes( new_tmpl, class, subclass, MODE_MODIFY ); if (rc != CKR_OK){ st_err_log(165, __FILE__, __LINE__); goto error; } // merge in the new attributes // rc = template_merge( obj->template, &new_tmpl ); if (rc != CKR_OK){ st_err_log(165, __FILE__, __LINE__); return rc; } return CKR_OK; error: // we only free the template if there was an error...otherwise the // object "owns" the template // if (new_tmpl) template_free( new_tmpl ); return rc; } // // CK_RV object_restore( CK_BYTE *data, OBJECT **new_obj, CK_BBOOL replace ) { TEMPLATE * tmpl = NULL; OBJECT * obj = NULL; CK_ULONG offset = 0; CK_ULONG_32 count = 0; CK_RV rc; if (!data || !new_obj){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } obj = (OBJECT *)malloc(sizeof(OBJECT)); if (!obj) { st_err_log(0, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto error; } memset( obj, 0x0, sizeof(OBJECT) ); memcpy( &obj->class, data + offset, sizeof(CK_OBJECT_CLASS_32) ); offset += sizeof(CK_OBJECT_CLASS_32); memcpy( &count, data + offset, sizeof(CK_ULONG_32) ); offset += sizeof(CK_ULONG_32); memcpy( &obj->name, data + offset, 8 ); offset += 8; rc = template_unflatten( &tmpl, data + offset, count ); if (rc != CKR_OK){ st_err_log(166, __FILE__, __LINE__); goto error; } obj->template = tmpl; if (replace == FALSE) { *new_obj = obj; } else { template_free( (*new_obj)->template ); memcpy( *new_obj, obj, sizeof(OBJECT) ); free( obj ); // don't want to do object_free() here! } return CKR_OK; error: if (obj) object_free( obj ); if (tmpl) template_free( tmpl ); return rc; } // // CK_RV object_create_skel( CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_ULONG mode, CK_ULONG class, CK_ULONG subclass, OBJECT ** obj ) { TEMPLATE * tmpl = NULL; TEMPLATE * tmpl2 = NULL; OBJECT * o = NULL; CK_RV rc; if (!obj){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!pTemplate && (ulCount != 0)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } o = (OBJECT *)malloc(sizeof(OBJECT)); tmpl = (TEMPLATE *)malloc(sizeof(TEMPLATE)); tmpl2 = (TEMPLATE *)malloc(sizeof(TEMPLATE)); if (!o || !tmpl || !tmpl2) { st_err_log(0, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } memset( o, 0x0, sizeof(OBJECT) ); memset( tmpl, 0x0, sizeof(TEMPLATE) ); memset( tmpl2, 0x0, sizeof(TEMPLATE) ); rc = template_add_default_attributes( tmpl, class, subclass, mode ); if (rc != CKR_OK) goto done; rc = template_add_attributes( tmpl2, pTemplate, ulCount ); if (rc != CKR_OK) goto done; // at this point, the new template has the list of attributes. we need // to do some more checking now: // 1) invalid attribute values // 2) missing required attributes // 3) attributes inappropriate for the object class // 4) conflicting attributes/values // rc = template_validate_attributes( tmpl2, class, subclass, mode ); if (rc != CKR_OK){ st_err_log(165, __FILE__, __LINE__); goto done; } rc = template_check_required_attributes( tmpl2, class, subclass, mode ); if (rc != CKR_OK){ st_err_log(166, __FILE__, __LINE__); goto done; } rc = template_merge( tmpl, &tmpl2 ); if (rc != CKR_OK){ st_err_log(165, __FILE__, __LINE__); goto done; } // at this point, we should have a valid object with correct attributes // o->template = tmpl; *obj = o; return CKR_OK; done: if (o) free( o ); if (tmpl) template_free( tmpl ); if (tmpl2) template_free( tmpl2 ); return rc; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/msg.h0000640000175000017500000003631011327631345017656 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/lib/pkcs11/common/msg.h,v 1.2 2005/08/04 22:11:46 kyoder Exp $ */ // /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: msg.h // Error messages reported by st_err_log #ifndef __MSG_H__ #define __MSG_H__ struct messages { char * msg; }; extern struct messages err_msg[]; #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/loadsave.c0000751000175000017500000012437211327631345020672 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // loadsave.c // // routines associated with loading/saving files // // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" #include "pkcs32.h" #include "../api/apiproto.h" void set_perm(int file) { struct group *grp; // Set absolute permissions or rw-rw-r-- fchmod(file,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH); grp = getgrnam("pkcs11"); // Obtain the group id if (grp){ fchown(file,getuid(),grp->gr_gid); // set ownership to root, and pkcs11 group } } // // CK_RV load_token_data() { FILE * fp; CK_BYTE fname[PATH_MAX]; TOKEN_DATA td; CK_RV rc; sprintf((char *)fname,"%s/%s",(char *)pk_dir, PK_LITE_NV); rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto out_nolock; } fp = fopen((char *)fname, "r"); if (!fp) { /* Better error checking added */ if (errno == ENOENT) { /* init_token_data may call save_token_data, which graps the * xproclock, so we must release it around this call */ XProcUnLock( xproclock ); init_token_data(); rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto out_nolock; } fp = fopen((char *)fname, "r"); if (!fp) { // were really hosed here since the created // did not occur LogError("failed opening %s for read: %s", fname, strerror(errno)); rc = CKR_FUNCTION_FAILED; goto out_unlock; } } else { /* Could not open file for some unknown reason */ st_err_log(194, __FILE__, __LINE__, PK_LITE_NV, errno); rc = CKR_FUNCTION_FAILED; goto out_unlock; } } set_perm(fileno(fp)); rc = fread( &td, sizeof(TOKEN_DATA), 1, fp ); fclose(fp); if (rc == 0) { rc = CKR_FUNCTION_FAILED; goto out_unlock; } memcpy(nv_token_data, &td, sizeof(TOKEN_DATA) ); rc = CKR_OK; out_unlock: XProcUnLock( xproclock ); out_nolock: return rc; } // // CK_RV save_token_data() { FILE *fp; TOKEN_DATA td; CK_RV rc; CK_BYTE fname[PATH_MAX]; fpos_t fpos; sprintf((char *)fname,"%s/%s",pk_dir, PK_LITE_NV); rc = XProcLock( xproclock ); if (rc != CKR_OK){ st_err_log(150, __FILE__, __LINE__); goto out_nolock; } fp = fopen((char *)fname, "r+"); if (!fp){ fp = fopen((char *)fname, "w"); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } } set_perm(fileno(fp)); memcpy( &td, nv_token_data, sizeof(TOKEN_DATA) ); (void)fwrite( &td, sizeof(TOKEN_DATA), 1, fp ); fclose(fp); rc = CKR_OK; done: XProcUnLock( xproclock ); out_nolock: return rc; } // // CK_RV save_token_object( OBJECT *obj ) { FILE * fp = NULL; CK_BYTE line[100]; CK_RV rc; CK_BYTE fname[PATH_MAX]; if (object_is_private(obj) == TRUE) rc = save_private_token_object( obj ); else rc = save_public_token_object( obj ); if (rc != CKR_OK){ st_err_log(104, __FILE__, __LINE__); return rc; } // update the index file if it exists // sprintf((char *)fname,"%s/%s/%s",pk_dir,PK_LITE_OBJ_DIR,PK_LITE_OBJ_IDX); fp = fopen( (char *)fname, "r" ); if (fp) { set_perm(fileno(fp)); while (!feof(fp)) { (void)fgets((char *)line, 50, fp ); if (!feof(fp)) { line[ strlen((char *)line)-1 ] = 0; if (strcmp((char *)line,(char *)( obj->name)) == 0) { fclose(fp); return CKR_OK; // object is already in the list } } } fclose(fp); } // we didn't find it...either the index file doesn't exist or this // is a new object... // fp = fopen((char *)fname, "a"); if (!fp){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } set_perm(fileno(fp)); set_perm(fileno(fp)); fprintf( fp, "%s\n", obj->name ); fclose(fp); return CKR_OK; } // this is the same as the old version. public token objects are stored in the // clear // CK_RV save_public_token_object( OBJECT *obj ) { FILE * fp = NULL; CK_BYTE * cleartxt = NULL; CK_BYTE fname[PATH_MAX]; CK_ULONG cleartxt_len; CK_BBOOL flag = FALSE; CK_RV rc; CK_ULONG_32 total_len; sprintf( (char *)fname,"%s/%s/", pk_dir,PK_LITE_OBJ_DIR); strncat( (char *)fname, (char *) obj->name, 8 ); rc = object_flatten( obj, &cleartxt, &cleartxt_len ); if (rc != CKR_OK){ st_err_log(101, __FILE__, __LINE__); goto error; } fp = fopen( (char *)fname, "w" ); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } set_perm(fileno(fp)); total_len = cleartxt_len + sizeof(CK_ULONG_32) + sizeof(CK_BBOOL); (void)fwrite( &total_len, sizeof(CK_ULONG_32), 1, fp ); (void)fwrite( &flag, sizeof(CK_BBOOL), 1, fp ); (void)fwrite( cleartxt, cleartxt_len, 1, fp ); fclose( fp ); free( cleartxt ); return CKR_OK; error: if (fp) fclose( fp ); if (cleartxt) free( cleartxt ); return rc; } // // CK_RV save_private_token_object( OBJECT *obj ) { FILE * fp = NULL; CK_BYTE * obj_data = NULL; CK_BYTE * cleartxt = NULL; CK_BYTE * ciphertxt = NULL; CK_BYTE * ptr = NULL; CK_BYTE fname[100]; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_BYTE des3_key[3 * DES_KEY_SIZE]; CK_ULONG obj_data_len,cleartxt_len, ciphertxt_len; CK_ULONG padded_len; CK_BBOOL flag; CK_RV rc; CK_ULONG_32 obj_data_len_32; CK_ULONG_32 total_len; sprintf( (char *)fname,"%s/%s/", pk_dir,PK_LITE_OBJ_DIR); rc = object_flatten( obj, &obj_data, &obj_data_len ); obj_data_len_32 = obj_data_len; if (rc != CKR_OK){ st_err_log(101, __FILE__, __LINE__); goto error; } // // format for the object file: // private flag // ---- begin encrypted part <--+ // length of object data | // object data +---- sensitive part // SHA of (object data) | // ---- end encrypted part <--+ // compute_sha( obj_data, obj_data_len, hash_sha ); // encrypt the sensitive object data. need to be careful. // if I use the normal high-level encryption routines I'll need to // create a tepmorary key object containing the master key, perform the // encryption, then destroy the key object. There is a race condition // here if the application is multithreaded (if a thread-switch occurs, // the other application thread could do a FindObject and be able to access // the master key object. // // So I have to use the low-level encryption routines. // memcpy( des3_key, master_key, 3*DES_KEY_SIZE ); cleartxt_len = sizeof(CK_ULONG_32) + obj_data_len_32 + SHA1_HASH_SIZE; padded_len = DES_BLOCK_SIZE * (cleartxt_len / DES_BLOCK_SIZE + 1); cleartxt = (CK_BYTE *)malloc( padded_len ); ciphertxt = (CK_BYTE *)malloc( padded_len ); if (!cleartxt || !ciphertxt) { st_err_log(0, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto error; } ciphertxt_len = padded_len; ptr = cleartxt; memcpy( ptr, &obj_data_len_32, sizeof(CK_ULONG_32) ); ptr += sizeof(CK_ULONG_32); memcpy( ptr, obj_data, obj_data_len_32 ); ptr += obj_data_len_32; memcpy( ptr, hash_sha, SHA1_HASH_SIZE ); add_pkcs_padding( cleartxt + cleartxt_len, DES_BLOCK_SIZE, cleartxt_len, padded_len ); #ifndef CLEARTEXT // SAB XXX some crypto libraries expect to be able to change th einitial vector. // so we will enable that by a local variable { CK_BYTE *initial_vector=NULL; initial_vector = (CK_BYTE *)alloca(strlen("10293847")+5); if (initial_vector) { memcpy(initial_vector, "10293847", strlen("10293847")); rc = ckm_des3_cbc_encrypt( cleartxt, padded_len, ciphertxt, &ciphertxt_len, initial_vector, des3_key ); } else { rc=CKR_FUNCTION_FAILED; } } #else memcpy(ciphertxt, cleartxt, padded_len); rc = CKR_OK; #endif if (rc != CKR_OK){ st_err_log(105, __FILE__, __LINE__); goto error; } strncat( (char *)fname,(char *) obj->name, 8 ); fp = fopen( (char *)fname, "w" ); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } set_perm(fileno(fp)); total_len = sizeof(CK_ULONG_32) + sizeof(CK_BBOOL) + ciphertxt_len; flag = TRUE; (void)fwrite( &total_len, sizeof(CK_ULONG_32), 1, fp ); (void)fwrite( &flag, sizeof(CK_BBOOL), 1, fp ); (void)fwrite( ciphertxt, ciphertxt_len, 1, fp ); fclose( fp ); free( obj_data ); free( cleartxt ); free( ciphertxt ); return CKR_OK; error: if (fp) fclose( fp ); if (obj_data) free( obj_data ); if (cleartxt) free( cleartxt ); if (ciphertxt) free( ciphertxt ); return rc; } // // CK_RV load_public_token_objects( void ) { FILE *fp1 = NULL, *fp2 = NULL; CK_BYTE *buf = NULL; CK_BYTE tmp[PATH_MAX], fname[PATH_MAX], iname[PATH_MAX]; CK_BBOOL priv; CK_ULONG_32 size; sprintf((char *)iname,"%s/%s/%s",pk_dir,PK_LITE_OBJ_DIR, PK_LITE_OBJ_IDX); fp1 = fopen((char *)iname, "r"); if (!fp1) return CKR_OK; // no token objects while (!feof(fp1)) { (void)fgets( (char *)tmp, 50, fp1 ); if (!feof(fp1)) { tmp[ strlen((char *)tmp)-1 ] = 0; sprintf((char *)fname,"%s/%s/",pk_dir, PK_LITE_OBJ_DIR); strcat((char *)fname, (char *)tmp ); fp2 = fopen( (char *)fname, "r" ); if (!fp2) continue; fread( &size, sizeof(CK_ULONG_32), 1, fp2 ); fread( &priv, sizeof(CK_BBOOL), 1, fp2 ); if (priv == TRUE) { fclose( fp2 ); continue; } // size--; size = size -sizeof(CK_ULONG_32) - sizeof(CK_BBOOL); buf = (CK_BYTE *)malloc(size); if (!buf) { fclose(fp1); fclose(fp2); st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } fread( buf, size, 1, fp2 ); // ... grab object mutex here. MY_LockMutex(&obj_list_mutex); object_mgr_restore_obj( buf, NULL ); MY_UnlockMutex(&obj_list_mutex); free( buf ); fclose( fp2 ); } } fclose(fp1); return CKR_OK; } // // CK_RV load_private_token_objects( void ) { FILE *fp1 = NULL, *fp2 = NULL; CK_BYTE *buf = NULL; CK_BYTE tmp[PATH_MAX], fname[PATH_MAX], iname[PATH_MAX]; CK_BBOOL priv; CK_ULONG_32 size; CK_RV rc; sprintf((char *)iname,"%s/%s/%s",pk_dir,PK_LITE_OBJ_DIR, PK_LITE_OBJ_IDX); fp1 = fopen((char *)iname, "r"); if (!fp1) return CKR_OK; // no token objects while (!feof(fp1)) { (void)fgets((char *) tmp, 50, fp1 ); if (!feof(fp1)) { tmp[ strlen((char *)tmp)-1 ] = 0; sprintf((char *)fname,"%s/%s/",pk_dir,PK_LITE_OBJ_DIR); strcat((char *)fname,(char *) tmp ); fp2 = fopen( (char *)fname, "r" ); if (!fp2) continue; fread( &size, sizeof(CK_ULONG_32), 1, fp2 ); fread( &priv, sizeof(CK_BBOOL), 1, fp2 ); if (priv == FALSE) { fclose( fp2 ); continue; } //size--; size = size - sizeof(CK_ULONG_32) - sizeof(CK_BBOOL); buf = (CK_BYTE *)malloc(size); if (!buf) { st_err_log(0, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto error; } rc = fread( (char *)buf, size, 1, fp2 ); if (rc != 1) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } // Grab object list mutex MY_LockMutex(&obj_list_mutex); rc = restore_private_token_object( buf, size, NULL ); MY_UnlockMutex(&obj_list_mutex); if (rc != CKR_OK){ st_err_log(107, __FILE__, __LINE__); goto error; } free( buf ); fclose( fp2 ); } } fclose(fp1); return CKR_OK; error: if (buf) free( buf ); if (fp1) fclose( fp1 ); if (fp2) fclose( fp2 ); return rc; } // // CK_RV restore_private_token_object( CK_BYTE * data, CK_ULONG len, OBJECT * pObj ) { CK_BYTE * cleartxt = NULL; CK_BYTE * obj_data = NULL; CK_BYTE * ciphertxt = NULL; CK_BYTE * ptr = NULL; CK_BYTE des3_key[3 * DES_KEY_SIZE]; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_ULONG cleartxt_len, obj_data_len; CK_RV rc; // format for the object data: // (private flag has already been read at this point) // ---- begin encrypted part // length of object data // object data // SHA of object data // ---- end encrypted part // cleartxt_len = len; cleartxt = (CK_BYTE *)malloc(len); if (!cleartxt) { st_err_log(0, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } ciphertxt = data; // decrypt the encrypted chunk // memcpy( des3_key, master_key, 3*DES_KEY_SIZE ); #ifndef CLEARTEXT { CK_BYTE *initial_vector=NULL; initial_vector = (CK_BYTE *)alloca(strlen("10293847")+5); if (initial_vector) { memcpy(initial_vector, "10293847", strlen("10293847")); rc = ckm_des3_cbc_decrypt( ciphertxt, len, cleartxt, &len, initial_vector, des3_key ); } else { rc=CKR_FUNCTION_FAILED; } } #else memcpy(cleartxt, ciphertxt, len); rc = CKR_OK; #endif if (rc != CKR_OK){ st_err_log(106, __FILE__, __LINE__); goto done; } strip_pkcs_padding( cleartxt, len, &cleartxt_len ); // if the padding extraction didn't work it means the object was tampered with or // the key was incorrect // if (cleartxt_len > len) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } ptr = cleartxt; obj_data_len = *(CK_ULONG_32 *)ptr; ptr += sizeof(CK_ULONG_32); obj_data = ptr; // check the hash // compute_sha( ptr, obj_data_len, hash_sha ); ptr += obj_data_len; if (memcmp(ptr, hash_sha, SHA1_HASH_SIZE) != 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } // okay. at this point, we're satisfied that nobody has tampered with the // token object... // object_mgr_restore_obj( obj_data, pObj ); rc = CKR_OK; done: if (cleartxt) free( cleartxt ); return rc; } // // CK_RV load_masterkey_so( void ) { FILE * fp = NULL; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_BYTE cipher[sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE clear [sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE des3_key[3 * DES_KEY_SIZE]; MASTER_KEY_FILE_T mk; CK_ULONG cipher_len, clear_len; CK_RV rc; CK_BYTE fname[PATH_MAX]; sprintf((char *)fname,"%s/MK_SO",pk_dir); memset( master_key, 0x0, 3*DES_KEY_SIZE ); // this file gets created on C_InitToken so we can assume that it always exists // fp = fopen((char *)fname, "r"); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } set_perm(fileno(fp)); clear_len = cipher_len = (sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE - 1) & ~(DES_BLOCK_SIZE - 1); rc = fread( cipher, cipher_len, 1, fp ); if (rc != 1) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } // decrypt the master key data using the MD5 of the SO key // (we can't use the SHA of the SO key since the SHA of the key is stored // in the token data file). // memcpy( des3_key, so_pin_md5, MD5_HASH_SIZE ); memcpy( des3_key + MD5_HASH_SIZE, so_pin_md5, DES_KEY_SIZE ); #ifndef CLEARTEXT { CK_BYTE *initial_vector=NULL; initial_vector = (CK_BYTE *)alloca(strlen("12345678")+5); if (initial_vector) { memcpy(initial_vector, "12345678", strlen("12345678")); rc = ckm_des3_cbc_decrypt( cipher, cipher_len, clear, &clear_len, initial_vector, des3_key ); } else { rc=CKR_FUNCTION_FAILED; } } #else memcpy(clear, cipher, cipher_len); rc = CKR_OK; #endif if (rc != CKR_OK){ st_err_log(106, __FILE__, __LINE__); goto done; } memcpy( (CK_BYTE *)&mk, clear, sizeof(mk) ); // // technically should strip PKCS padding here but since I already know what // the length should be, I don't bother. // // compare the hashes // compute_sha( mk.key, 3 * DES_KEY_SIZE, hash_sha ); if (memcmp(hash_sha, mk.sha_hash, SHA1_HASH_SIZE) != 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } memcpy( master_key, mk.key, 3*DES_KEY_SIZE ); rc = CKR_OK; done: if (fp) fclose(fp); return rc; } // // CK_RV load_masterkey_user( void ) { FILE * fp = NULL; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_BYTE cipher[sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE clear[sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE des3_key[3 * DES_KEY_SIZE]; MASTER_KEY_FILE_T mk; CK_ULONG cipher_len, clear_len; CK_RV rc; CK_BYTE fname[PATH_MAX]; sprintf((char *)fname,"%s/MK_USER",pk_dir); memset( master_key, 0x0, 3*DES_KEY_SIZE ); // this file gets created on C_InitToken so we can assume that it always exists // fp = fopen( (char *)fname, "r" ); if (!fp) { LogError("fopen(%s): %s", fname, strerror(errno)); rc = CKR_FUNCTION_FAILED; goto done; } set_perm(fileno(fp)); clear_len = cipher_len = (sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE - 1) & ~(DES_BLOCK_SIZE - 1); rc = fread( cipher, cipher_len, 1, fp ); if (rc != 1) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } // decrypt the master key data using the MD5 of the SO key // (we can't use the SHA of the SO key since the SHA of the key is stored // in the token data file). // memcpy( des3_key, user_pin_md5, MD5_HASH_SIZE ); memcpy( des3_key + MD5_HASH_SIZE, user_pin_md5, DES_KEY_SIZE ); #ifndef CLEARTEXT { CK_BYTE *initial_vector=NULL; initial_vector = (CK_BYTE *)alloca(strlen("12345678")+5); if (initial_vector) { memcpy(initial_vector, "12345678", strlen("12345678")); rc = ckm_des3_cbc_decrypt( cipher, cipher_len, clear, &clear_len, initial_vector, des3_key ); } else { rc=CKR_FUNCTION_FAILED; } } #else memcpy(clear, cipher, cipher_len); rc = CKR_OK; #endif if (rc != CKR_OK){ st_err_log(106, __FILE__, __LINE__); goto done; } memcpy( (CK_BYTE *)&mk, clear, sizeof(mk) ); // // technically should strip PKCS padding here but since I already know what // the length should be, I don't bother. // // compare the hashes // compute_sha( mk.key, 3 * DES_KEY_SIZE, hash_sha ); if (memcmp(hash_sha, mk.sha_hash, SHA1_HASH_SIZE) != 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } memcpy( master_key, mk.key, 3*DES_KEY_SIZE ); rc = CKR_OK; done: if (fp) fclose(fp); return rc; } // // CK_RV save_masterkey_so( void ) { FILE * fp = NULL; CK_BYTE cleartxt [sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE ciphertxt[sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE des3_key[3 * DES_KEY_SIZE]; MASTER_KEY_FILE_T mk; CK_ULONG cleartxt_len, ciphertxt_len, padded_len; CK_RV rc; CK_BYTE fname[PATH_MAX]; memcpy( mk.key, master_key, 3 * DES_KEY_SIZE); compute_sha( master_key, 3 * DES_KEY_SIZE, mk.sha_hash ); // encrypt the key data // memcpy( des3_key, so_pin_md5, MD5_HASH_SIZE ); memcpy( des3_key + MD5_HASH_SIZE, so_pin_md5, DES_KEY_SIZE ); ciphertxt_len = sizeof(ciphertxt); cleartxt_len = sizeof(mk); memcpy( cleartxt, &mk, cleartxt_len ); padded_len = DES_BLOCK_SIZE * (cleartxt_len / DES_BLOCK_SIZE + 1); add_pkcs_padding( cleartxt + cleartxt_len, DES_BLOCK_SIZE, cleartxt_len, padded_len ); #ifndef CLEARTEXT { CK_BYTE *initial_vector=NULL; initial_vector = (CK_BYTE *)alloca(strlen("12345678")); if (initial_vector) { memcpy(initial_vector, "12345678", strlen("12345678")); rc = ckm_des3_cbc_encrypt( cleartxt, padded_len, ciphertxt, &ciphertxt_len, initial_vector, des3_key ); } else { rc=CKR_FUNCTION_FAILED; } } #else memcpy(ciphertxt, cleartxt, padded_len); rc = CKR_OK; #endif if (rc != CKR_OK){ st_err_log(105, __FILE__, __LINE__); goto done; } // write the file // // probably ought to ensure the permissions are correct // sprintf((char *)fname,"%s/MK_SO",pk_dir); fp = fopen( (char *)fname, "w" ); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } set_perm(fileno(fp)); rc = fwrite( ciphertxt, ciphertxt_len, 1, fp ); if (rc != 1) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } rc = CKR_OK; done: if (fp) fclose( fp ); return rc; } // // CK_RV save_masterkey_user( void ) { FILE * fp = NULL; CK_BYTE cleartxt [sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE ciphertxt[sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE des3_key[3 * DES_KEY_SIZE]; MASTER_KEY_FILE_T mk; CK_ULONG cleartxt_len, ciphertxt_len, padded_len; CK_RV rc; CK_BYTE fname[PATH_MAX]; memcpy( mk.key, master_key, 3 * DES_KEY_SIZE); compute_sha( master_key, 3 * DES_KEY_SIZE, mk.sha_hash ); // encrypt the key data // memcpy( des3_key, user_pin_md5, MD5_HASH_SIZE ); memcpy( des3_key + MD5_HASH_SIZE, user_pin_md5, DES_KEY_SIZE ); ciphertxt_len = sizeof(ciphertxt); cleartxt_len = sizeof(mk); memcpy( cleartxt, &mk, cleartxt_len ); padded_len = DES_BLOCK_SIZE * (cleartxt_len / DES_BLOCK_SIZE + 1); add_pkcs_padding( cleartxt + cleartxt_len, DES_BLOCK_SIZE, cleartxt_len, padded_len ); #ifndef CLEARTEXT { CK_BYTE *initial_vector=NULL; initial_vector = (CK_BYTE *)alloca(strlen("12345678")+5); if (initial_vector) { memcpy(initial_vector, "12345678", strlen("12345678")); rc = ckm_des3_cbc_encrypt( cleartxt, padded_len, ciphertxt, &ciphertxt_len, initial_vector, des3_key ); } else { rc=CKR_FUNCTION_FAILED; } } #else memcpy(ciphertxt, cleartxt, padded_len); rc = CKR_OK; #endif if (rc != CKR_OK){ st_err_log(105, __FILE__, __LINE__); goto done; } // write the file // // probably ought to ensure the permissions are correct // sprintf((char *)fname,"%s/MK_USER", pk_dir); fp = fopen( (char *)fname, "w" ); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } set_perm(fileno(fp)); rc = fwrite( ciphertxt, ciphertxt_len, 1, fp ); if (rc != 1) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } rc = CKR_OK; done: if (fp) fclose( fp ); return rc; } // // CK_RV reload_token_object( OBJECT *obj ) { FILE * fp = NULL; CK_BYTE * buf = NULL; CK_BYTE fname[PATH_MAX]; CK_BBOOL priv; CK_ULONG_32 size; CK_ULONG size_64; CK_RV rc; memset( (char *)fname, 0x0, sizeof(fname) ); sprintf((char *)fname,"%s/%s/",pk_dir, PK_LITE_OBJ_DIR); strncat((char *)fname,(char *) obj->name, 8 ); fp = fopen( (char *)fname, "r" ); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } set_perm(fileno(fp)); fread( &size, sizeof(CK_ULONG_32), 1, fp ); fread( &priv, sizeof(CK_BBOOL), 1, fp ); size = size - sizeof(CK_ULONG_32) - sizeof(CK_BBOOL); // SAB buf = (CK_BYTE *)malloc(size); if (!buf) { st_err_log(0, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } fread( buf, size, 1, fp ); size_64 = size; if (priv){ rc = restore_private_token_object( buf, size_64, obj ); if (rc != CKR_OK) st_err_log(107, __FILE__, __LINE__); } else{ rc = object_mgr_restore_obj( buf, obj ); if (rc != CKR_OK) st_err_log(108, __FILE__, __LINE__); } done: if (fp) fclose( fp ); if (buf) free( buf ); return rc; } extern void set_perm(int) ; // // CK_RV delete_token_object( OBJECT *obj ) { FILE *fp1, *fp2; CK_BYTE line[100]; CK_BYTE objidx[PATH_MAX], idxtmp[PATH_MAX], fname[PATH_MAX]; sprintf((char *)objidx,"%s/%s/%s",pk_dir, PK_LITE_OBJ_DIR,PK_LITE_OBJ_IDX); sprintf((char *)idxtmp,"%s/%s/%s",pk_dir, PK_LITE_OBJ_DIR, "IDX.TMP"); // FIXME: on UNIX, we need to make sure these guys aren't symlinks // before we blindly write to these files... // // remove the object from the index file // fp1 = fopen((char *)objidx, "r"); fp2 = fopen((char *)idxtmp, "w"); if (!fp1 || !fp2) { if (fp1) fclose(fp1); if (fp2) fclose(fp2); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } set_perm(fileno(fp2)); while (!feof(fp1)) { (void)fgets((char *)line, 50, fp1 ); if (!feof(fp1)) { line[ strlen((char *)line)-1 ] = 0; if (strcmp((char *)line, (char *)obj->name) == 0) continue; else fprintf( fp2, "%s\n", line ); } } fclose(fp1); fclose(fp2); fp2 = fopen((char *)objidx, "w"); fp1 = fopen((char *)idxtmp, "r"); if (!fp1 || !fp2) { if (fp1) fclose(fp1); if (fp2) fclose(fp2); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } set_perm(fileno(fp2)); while (!feof(fp1)) { (void)fgets((char *)line, 50, fp1 ); if (!feof(fp1)) fprintf( fp2, "%s",(char *) line ); } fclose(fp1); fclose(fp2); sprintf((char *)fname,"%s/%s/%s",pk_dir, PK_LITE_OBJ_DIR,(char *)obj->name); unlink((char *)fname); return CKR_OK; } opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/args.h0000751000175000017500000007745311327631345020044 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/lib/pkcs11/common/args.h,v 1.4 2006/08/01 15:56:51 mhalcrow Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ #ifndef _CARD_ARGS_H #define _CARD_ARGS_H #ifndef _PKCS11TYPES_H_ #include "pkcs11types.h" #endif #if (LEEDS_BUILD) #pragma pack(1) #pragma options align=packed #include "linuxdef.h" #ifdef _NT_ON_I386 #pragma pack(1) #endif #else #define PACK_DATA #endif // C_Initialize // C_Finalize // C_GetInfo // C_GetFunctionList // C_GetSlotList // C_GetSlotInfo // C_GetTokenInfo // C_WaitForSlotEvent // // REQUEST_PID // no request struct // // PURGE_SESSION_OBJECTS // typedef struct _PurgeSessionObjects_Args { CK_SESSION_HANDLE session; CK_BYTE flag; // just the private objects or all? }PACK_DATA PurgeSessionObjects_Args; // C_LOGIN // typedef struct _VerifyPIN_Args { CK_USER_TYPE user_type; CK_BYTE pin[MAX_PIN_LEN]; CK_ULONG pin_len; } PACK_DATA VerifyPIN_Args; // DES_ECB_ENCRYPT // typedef struct _DES_ECB_ARGS { CK_ULONG data_len; CK_BYTE key[DES_KEY_SIZE]; } PACK_DATA DES_ECB_Args; typedef struct _DES_CBC_ARGS { CK_ULONG data_len; CK_BYTE key[DES_KEY_SIZE]; CK_BYTE init_v[DES_BLOCK_SIZE]; } PACK_DATA DES_CBC_Args; typedef struct _DES3_ECB_ARGS { CK_ULONG data_len; CK_BYTE key[3*DES_KEY_SIZE]; } PACK_DATA DES3_ECB_Args; typedef struct _DES3_CBC_ARGS { CK_ULONG data_len; CK_BYTE key[3*DES_KEY_SIZE]; CK_BYTE init_v[DES_BLOCK_SIZE]; } PACK_DATA DES3_CBC_Args; // // GENERATE_RANDOM typedef struct _RNG_Args { CK_ULONG bytes; } PACK_DATA RNG_Args; // SHA1_DIGEST // typedef struct _SHA_Digest_Args { CK_ULONG bytes; CK_BYTE last_bytes[4]; // last (total_bytes % 4) of input data // data to be hashed will be sent via external buffer transfer // } PACK_DATA SHA_Digest_Args; // SHA1_UPDATE // typedef struct _SHA_Update_Args { CK_ULONG bytes; CK_ULONG running_length; CK_BYTE context[SHA1_HASH_SIZE]; // data to be hashed will be sent via external buffer transfer // } PACK_DATA SHA_Update_Args; // SHA1_FINAL // typedef struct _SHA_Final_Args { CK_ULONG bytes; CK_ULONG running_length; CK_BYTE context[SHA1_HASH_SIZE]; CK_BYTE last_bytes[4]; // data to be hashed will be sent via external buffer transfer // } PACK_DATA SHA_Final_Args; // DES_KEYGEN // typedef struct _DES_KeyGen_Args { CK_ULONG bytes; // 8, 16 or 24 } PACK_DATA DES_KeyGen_Args; // CDMF_KEYGEN // typedef struct _CDMF_Transform_Args { CK_BYTE des_key[DES_KEY_SIZE]; } PACK_DATA CDMF_Transform_Args; // DSA_KEYPAIR_GEN // typedef struct _DSA_KeyGen_Args { CK_ULONG prime_len; CK_ULONG subprime_len; CK_ULONG base_len; // CKA_PRIME value is appended here // // CKA_SUBPRIME value is appended here // // CKA_BASE value is appended here // } PACK_DATA DSA_KeyGen_Args; typedef struct _DSA_KeyGen_Reply { CK_ULONG publ_exp_len; CK_ULONG priv_exp_len; // public is appended here // private is appended here // } PACK_DATA DSA_KeyGen_Reply; typedef struct _DSA_Sign_Args { CK_BYTE data[SHA1_HASH_SIZE]; CK_ULONG prime_len; CK_ULONG subprime_len; CK_ULONG base_len; CK_ULONG exp_len; // prime is appended here // subprime is appended here // base is appended here // exponent is appended here (private) // } PACK_DATA DSA_Sign_Args; typedef struct _DSA_Verify_Args { CK_BYTE data[SHA1_HASH_SIZE]; CK_BYTE sig[DSA_SIGNATURE_SIZE]; CK_ULONG prime_len; CK_ULONG subprime_len; CK_ULONG base_len; CK_ULONG exp_len; // prime is appended here // subprime is appended here // base is appended here // exponent is appended here (public) // } PACK_DATA DSA_Verify_Args; // RSA_KEYPAIR_GEN // typedef struct _RSA_KeyGen_Args { CK_ULONG modulus_bits; CK_ULONG publ_exp_len; // public exponent is appended here // } PACK_DATA RSA_KeyGen_Args; typedef struct _RSA_KeyGen_Reply { CK_ULONG modulus_len; CK_ULONG prime1_len; CK_ULONG prime2_len; CK_ULONG exp1_len; CK_ULONG exp2_len; CK_ULONG coeff_len; CK_ULONG priv_exp_len; // modulus is appended here // prime1 is appended here // prime2 is appended here // exp1 is appended here // exp2 is appended here // coeff is appended here // private exponent is appended here } PACK_DATA RSA_KeyGen_Reply; typedef struct _RSA_Encrypt_Args { CK_ULONG data_len; CK_ULONG modulus_len; CK_ULONG publ_exp_len; // key data is appended here in the order listed // // cleartext is appended here // } PACK_DATA RSA_Encrypt_Args; typedef struct _RSA_Encrypt_Reply { CK_ULONG data_len; // ciphertext is appended here // } PACK_DATA RSA_Encrypt_Reply; typedef struct _RSA_Decrypt_Args { CK_ULONG data_len; CK_ULONG modulus_len; CK_ULONG publ_exp_len; CK_ULONG prime1_len; CK_ULONG prime2_len; CK_ULONG exp1_len; CK_ULONG exp2_len; CK_ULONG coeff_len; // key data is appended here in the order listed // // ciphertext is appended here // } PACK_DATA RSA_Decrypt_Args; typedef struct _RSA_Decrypt_Reply { CK_ULONG data_len; // cleartext is appended here // } PACK_DATA RSA_Decrypt_Reply; // // // #if 0 typedef struct _InitPIN_Args { CK_SESSION_HANDLE session_handle; CK_BYTE pin[MAX_PIN_LEN]; CK_ULONG pin_len; } InitPIN_Args; typedef struct _SetPIN_Args { CK_SESSION_HANDLE session_handle; CK_BYTE old_pin[MAX_PIN_LEN]; CK_ULONG old_pin_len; CK_BYTE new_pin[MAX_PIN_LEN]; CK_ULONG new_pin_len; } SetPIN_Args; typedef struct _OpenSession_Args { CK_SLOT_ID slot_id; CK_FLAGS flags; CK_VOID_PTR application_ptr; // not used CK_NOTIFY notify; // not used CK_BBOOL req_proc_handle; } OpenSession_Args; typedef struct _CloseSession_Args { CK_SESSION_HANDLE session_handle; } CloseSession_Args; typedef struct _GetSessionInfo_Args { CK_SESSION_HANDLE session_handle; } GetSessionInfo_Args; typedef struct _Login_Args { CK_SESSION_HANDLE session_handle; CK_USER_TYPE user_type; CK_BYTE pin[MAX_PIN_LEN]; CK_ULONG pin_len; } Login_Args; typedef struct _Logout_Args { CK_SESSION_HANDLE session_handle; } Logout_Args; // CreateObject_Args is a bit different. The attributes themselves // are passed as a datablock immediately following this structure // typedef struct _CreateObject_Args { CK_SESSION_HANDLE session_handle; CK_ULONG attribute_count; CK_ULONG attribute_block_len; // attributes/template gets appended here // } CreateObject_Args; typedef struct _CopyObject_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE object_handle; CK_ULONG attribute_count; CK_ULONG attribute_block_len; // attributes/template gets appended here // } CopyObject_Args; typedef struct _DestroyObject_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE object_handle; } DestroyObject_Args; typedef struct _GetObjectSize_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE object_handle; } GetObjectSize_Args; typedef struct _GetAttributeValue_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE object_handle; CK_ULONG attribute_count; CK_ULONG attribute_block_len; CK_BBOOL size_only; // list of attribute types (CK_ATTRIBUTE_TYPE) gets appended here. // } GetAttributeValue_Args; typedef struct _SetAttributeValue_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE object_handle; CK_ULONG attribute_count; CK_ULONG attribute_block_len; // attribute template gets appended here // } SetAttributeValue_Args; typedef struct _FindObjectsInit_Args { CK_SESSION_HANDLE session_handle; CK_ULONG attribute_count; CK_ULONG attribute_block_len; // attribute template gets appended here // } FindObjectsInit_Args; typedef struct _FindObjects_Args { CK_SESSION_HANDLE session_handle; CK_ULONG max_count; } FindObjects_Args; typedef struct _FindObjectsFinal_Args { CK_SESSION_HANDLE session_handle; } FindObjectsFinal_Args; typedef struct _GenerateRandom_Args { CK_SESSION_HANDLE session_handle; CK_ULONG num_bytes; } GenerateRandom_Args; typedef struct _GenerateKey_Args { CK_SESSION_HANDLE session_handle; CK_MECHANISM_TYPE mech_type; CK_ULONG mech_param_len; CK_ULONG attribute_count; CK_ULONG attribute_block_len; // mechanism parameter gets appended here // attributes get appended here // } GenerateKey_Args; typedef struct _GenKeyPair_Args { CK_SESSION_HANDLE session_handle; CK_MECHANISM_TYPE mech_type; CK_ULONG mech_param_len; CK_ULONG publ_key_attr_count; // # of attributes CK_ULONG publ_key_tmpl_len; // overall template length CK_ULONG priv_key_attr_count; // # of attributes CK_ULONG priv_key_tmpl_len; // overall template length // the mechanism parameter is appended here // the public key template is appended here // the private key template is appended here // } GenKeyPair_Args; typedef struct _EncryptInit_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE key; CK_MECHANISM_TYPE mech_type; CK_ULONG param_len; // length of parameter in bytes // mechanism parameter (if any) is appended here // } EncryptInit_Args; typedef struct _Encrypt_Args { CK_SESSION_HANDLE session_handle; CK_ULONG cleartext_len; CK_BBOOL length_only; // cleartext is sent in a CPQ buffer #1 // } Encrypt_Args; typedef struct _EncryptUpdate_Args { CK_SESSION_HANDLE session_handle; CK_ULONG cleartext_len; CK_BBOOL length_only; // cleartext is appended here // } EncryptUpdate_Args; typedef struct _EncryptFinal_Args { CK_SESSION_HANDLE session_handle; CK_BBOOL length_only; } EncryptFinal_Args; typedef struct _DecryptInit_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE key; CK_MECHANISM_TYPE mech_type; CK_ULONG param_len; // length of parameter in bytes // mechanism parameter (if any) is appended here // } DecryptInit_Args; typedef struct _Decrypt_Args { CK_SESSION_HANDLE session_handle; CK_ULONG ciphertext_len; CK_BBOOL length_only; // ciphertext is sent in CPQ buffer #1 // } Decrypt_Args; typedef struct _DecryptUpdate_Args { CK_SESSION_HANDLE session_handle; CK_ULONG ciphertext_len; CK_BBOOL length_only; // ciphertext is appended here // } DecryptUpdate_Args; typedef struct _DecryptFinal_Args { CK_SESSION_HANDLE session_handle; CK_BBOOL length_only; } DecryptFinal_Args; typedef struct _WrapKey_Args { CK_SESSION_HANDLE session_handle; CK_MECHANISM_TYPE mech_type; CK_ULONG mech_param_len; CK_OBJECT_HANDLE wrapping_key; CK_OBJECT_HANDLE key; // key to be wrapped CK_BBOOL length_only; // mechanism parameter (if any) is appended here // } WrapKey_Args; typedef struct _UnWrapKey_Args { CK_SESSION_HANDLE session_handle; CK_MECHANISM_TYPE mech_type; CK_ULONG mech_param_len; CK_OBJECT_HANDLE unwrapping_key; CK_ULONG wrapped_key_len; CK_ULONG attribute_count; CK_ULONG attribute_block_len; // mechanism parameter appended here (mech_param_len bytes ) // wrapped key appended here (wrapped_key_len bytes ) // attributes appended here (attribute_block_len bytes) // } UnWrapKey_Args; typedef struct _DeriveKey_Args { CK_SESSION_HANDLE session_handle; CK_MECHANISM_TYPE mech_type; CK_ULONG mech_param_len; CK_OBJECT_HANDLE base_key; CK_ULONG attribute_count; CK_ULONG attribute_block_len; // mechanism parameter and things it points to get appended here // attributes get appended here // } DeriveKey_Args; typedef struct _DigestInit_Args { CK_SESSION_HANDLE session_handle; CK_MECHANISM_TYPE mech_type; CK_ULONG param_len; // length of parameter in bytes // mechanism parameter (if any) is appended here // } DigestInit_Args; typedef struct _Digest_Args { CK_SESSION_HANDLE session_handle; CK_ULONG data_len; CK_BBOOL length_only; // data to digest is now sent in buffer #1 // } Digest_Args; typedef struct _DigestUpdate_Args { CK_SESSION_HANDLE session_handle; CK_ULONG data_len; // data to digest is appeneded here // } DigestUpdate_Args; typedef struct _DigestKey_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE key; } DigestKey_Args; typedef struct _DigestFinal_Args { CK_SESSION_HANDLE session_handle; CK_BBOOL length_only; } DigestFinal_Args; typedef struct _SignInit_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE key; CK_MECHANISM_TYPE mech_type; CK_ULONG param_len; // length of parameter in bytes // mechanism parameter (if any) is appended here // } SignInit_Args; typedef struct _Sign_Args { CK_SESSION_HANDLE session_handle; CK_ULONG data_len; CK_BBOOL length_only; // data is appended here // } Sign_Args; typedef struct _SignUpdate_Args { CK_SESSION_HANDLE session_handle; CK_ULONG data_len; CK_BBOOL length_only; // data is appended here // } SignUpdate_Args; typedef struct _SignFinal_Args { CK_SESSION_HANDLE session_handle; CK_BBOOL length_only; } SignFinal_Args; typedef struct _VerifyInit_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE key; CK_MECHANISM_TYPE mech_type; CK_ULONG param_len; // length of parameter in bytes // mechanism parameter (if any) is appended here // } VerifyInit_Args; typedef struct _Verify_Args { CK_SESSION_HANDLE session_handle; CK_ULONG data_len; CK_ULONG signature_len; // data is appended here // signature is appended here // } Verify_Args; typedef struct _VerifyUpdate_Args { CK_SESSION_HANDLE session_handle; CK_ULONG data_len; // data is appended here // } VerifyUpdate_Args; typedef struct _VerifyFinal_Args { CK_SESSION_HANDLE session_handle; CK_ULONG signature_len; // signature is appended here // } VerifyFinal_Args; typedef struct _SignRecoverInit_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE key; CK_MECHANISM_TYPE mech_type; CK_ULONG param_len; // length of parameter in bytes // mechanism parameter (if any) is appended here // } SignRecoverInit_Args; typedef struct _SignRecover_Args { CK_SESSION_HANDLE session_handle; CK_ULONG data_len; CK_BBOOL length_only; // data is appended here // } SignRecover_Args; typedef struct _VerifyRecoverInit_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE key; CK_MECHANISM_TYPE mech_type; CK_ULONG param_len; // length of parameter in bytes // mechanism parameter (if any) is appended here // } VerifyRecoverInit_Args; typedef struct _VerifyRecover_Args { CK_SESSION_HANDLE session_handle; CK_BBOOL length_only; CK_ULONG signature_len; // signature is appended here // } VerifyRecover_Args; typedef struct _GetOperationState_Args { CK_SESSION_HANDLE session_handle; CK_BBOOL length_only; } GetOperationState_Args; typedef struct _SetOperationState_Args { CK_SESSION_HANDLE session_handle; CK_OBJECT_HANDLE encr_key; CK_OBJECT_HANDLE auth_key; CK_ULONG data_len; // operation state data is appended here // } SetOperationState_Args; typedef struct _UpdateTweakValues_Args { CK_ULONG attribute_count; CK_ULONG attribute_block_len; CK_ULONG so_pin_len; // SO PIN gets appended here // // attribute template gets appended here // } UpdateTweakValues_Args; typedef struct _QueryTweakValues_Args { CK_ULONG attribute_count; CK_ULONG attribute_block_len; CK_BBOOL size_only; // list of attribute types (CK_ATTRIBUTE_TYPE) gets appended here. // } QueryTweakValues_Args; #endif #if (LEEDS_BUILD) #ifdef _NT_ON_I386 #pragma pack() #endif #pragma pack() #pragma options align=full #endif #endif opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/globals.c0000751000175000017500000007227511327631345020523 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ /*************************************************************************** Change Log ========== 4/25/03 Kapil Sood (kapil@corrent.com) Added DH key pair generation and DH shared key derivation functions. ****************************************************************************/ #include #include #include "pkcs11types.h" #include "stdll.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" CK_SLOT_INFO slot_info; CK_BBOOL initialized = FALSE; // native_mutex is used to protect C_Initialize. It gets created when the DLL // is attached, it gets destroyed when the DLL is detached // pthread_mutex_t native_mutex ; MUTEX pkcs_mutex, obj_list_mutex, sess_list_mutex, login_mutex; #if SYSVSEM int xprocsemid = -1; #endif void *xproclock; DL_NODE *sess_list = NULL; DL_NODE *sess_obj_list = NULL; DL_NODE *publ_token_obj_list = NULL; DL_NODE *priv_token_obj_list = NULL; DL_NODE *object_map = NULL; CK_STATE global_login_state = 0; LW_SHM_TYPE *global_shm; CK_ULONG next_session_handle = 1; CK_ULONG next_object_handle = 1; TOKEN_DATA *nv_token_data = NULL; struct ST_FCN_LIST function_list ; extern CK_RV LW_Initialize(); /* extern CK_RV SC_Initialize */ extern CK_RV SC_GetFunctionList(); /* extern CK_RV SC_GetFunctionList */ extern CK_RV SC_GetTokenInfo(); /* extern CK_RV SC_GetTokenInfo */ extern CK_RV SC_GetMechanismList(); /* extern CK_RV SC_GetMechanismList */ extern CK_RV SC_GetMechanismInfo(); /* extern CK_RV SC_GetMechanismInfo */ extern CK_RV SC_InitToken(); /* extern CK_RV SC_InitToken */ extern CK_RV SC_InitPIN(); /* extern CK_RV SC_InitPIN */ extern CK_RV SC_SetPIN(); /* extern CK_RV SC_SetPIN */ extern CK_RV SC_OpenSession(); /* extern CK_RV SC_OpenSession */ extern CK_RV SC_CloseSession(); /* extern CK_RV SC_CloseSession */ extern CK_RV SC_CloseAllSessions(); /* extern CK_RV SC_CloseAllSessions */ extern CK_RV SC_GetSessionInfo(); /* extern CK_RV SC_GetSessionInfo */ extern CK_RV SC_GetOperationState(); /* extern CK_RV SC_GetOperationState */ extern CK_RV SC_SetOperationState(); /* extern CK_RV SC_SetOperationState */ extern CK_RV SC_Login(); /* extern CK_RV SC_Login */ extern CK_RV SC_Logout(); /* extern CK_RV SC_Logout */ extern CK_RV SC_CreateObject(); /* extern CK_RV SC_CreateObject */ extern CK_RV SC_CopyObject(); /* extern CK_RV SC_CopyObject */ extern CK_RV SC_DestroyObject(); /* extern CK_RV SC_DestroyObject */ extern CK_RV SC_GetObjectSize(); /* extern CK_RV SC_GetObjectSize */ extern CK_RV SC_GetAttributeValue(); /* extern CK_RV SC_GetAttributeValue */ extern CK_RV SC_SetAttributeValue(); /* extern CK_RV SC_SetAttributeValue */ extern CK_RV SC_FindObjectsInit(); /* extern CK_RV SC_FindObjectsInit */ extern CK_RV SC_FindObjects(); /* extern CK_RV SC_FindObjects */ extern CK_RV SC_FindObjectsFinal(); /* extern CK_RV SC_FindObjectsFinal */ extern CK_RV SC_EncryptInit(); /* extern CK_RV SC_EncryptInit */ extern CK_RV SC_Encrypt(); /* extern CK_RV SC_Encrypt */ extern CK_RV SC_EncryptUpdate(); /* extern CK_RV SC_EncryptUpdate */ extern CK_RV SC_EncryptFinal(); /* extern CK_RV SC_EncryptFinal */ extern CK_RV SC_DecryptInit(); /* extern CK_RV SC_DecryptInit */ extern CK_RV SC_Decrypt(); /* extern CK_RV SC_Decrypt */ extern CK_RV SC_DecryptUpdate(); /* extern CK_RV SC_DecryptUpdate */ extern CK_RV SC_DecryptFinal(); /* extern CK_RV SC_DecryptFinal */ extern CK_RV SC_DigestInit(); /* extern CK_RV SC_DigestInit */ extern CK_RV SC_Digest(); /* extern CK_RV SC_Digest */ extern CK_RV SC_DigestUpdate(); /* extern CK_RV SC_DigestUpdate */ extern CK_RV SC_DigestKey(); /* extern CK_RV SC_DigestKey */ extern CK_RV SC_DigestFinal(); /* extern CK_RV SC_DigestFinal */ extern CK_RV SC_SignInit(); /* extern CK_RV SC_SignInit */ extern CK_RV SC_Sign(); /* extern CK_RV SC_Sign */ extern CK_RV SC_SignUpdate(); /* extern CK_RV SC_SignUpdate */ extern CK_RV SC_SignFinal(); /* extern CK_RV SC_SignFinal */ extern CK_RV SC_SignRecoverInit(); /* extern CK_RV SC_SignRecoverInit */ extern CK_RV SC_SignRecover(); /* extern CK_RV SC_SignRecover */ extern CK_RV SC_VerifyInit(); /* extern CK_RV SC_VerifyInit */ extern CK_RV SC_Verify(); /* extern CK_RV SC_Verify */ extern CK_RV SC_VerifyUpdate(); /* extern CK_RV SC_VerifyUpdate */ extern CK_RV SC_VerifyFinal(); /* extern CK_RV SC_VerifyFinal */ extern CK_RV SC_VerifyRecoverInit(); /* extern CK_RV SC_VerifyRecoverInit */ extern CK_RV SC_VerifyRecover(); /* extern CK_RV SC_VerifyRecover */ extern CK_RV SC_DigestEncryptUpdate(); /* extern CK_RV SC_DigestEncryptUpdate */ extern CK_RV SC_DecryptDigestUpdate(); /* extern CK_RV SC_DecryptDigestUpdate */ extern CK_RV SC_SignEncryptUpdate(); /* extern CK_RV SC_SignEncryptUpdate */ extern CK_RV SC_DecryptVerifyUpdate(); /* extern CK_RV SC_DecryptVerifyUpdate */ extern CK_RV SC_GenerateKey(); /* extern CK_RV SC_GenerateKey */ extern CK_RV SC_GenerateKeyPair(); /* extern CK_RV SC_GenerateKeyPair */ extern CK_RV SC_WrapKey(); /* extern CK_RV SC_WrapKey */ extern CK_RV SC_UnwrapKey(); /* extern CK_RV SC_UnwrapKey */ extern CK_RV SC_DeriveKey(); /* extern CK_RV SC_DeriveKey */ extern CK_RV SC_SeedRandom(); /* extern CK_RV SC_SeedRandom */ extern CK_RV SC_GenerateRandom(); /* extern CK_RV SC_GenerateRandom */ extern CK_RV SC_GetFunctionStatus(); /* extern CK_RV SC_GetFunctionStatus */ extern CK_RV SC_CancelFunction(); /* extern CK_RV SC_CancelFunction */ extern CK_RV SC_WaitForSlotEvent(); /* extern CK_RV SC_WaitForSlotEvent */ // OBJECT IDENTIFIERs // CK_BYTE ber_idDSA[] = { 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01 }; CK_BYTE ber_rsaEncryption[] = { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 }; CK_BYTE ber_md2WithRSAEncryption[] = { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02 }; CK_BYTE ber_md4WithRSAEncryption[] = { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x03 }; CK_BYTE ber_md5WithRSAEncryption[] = { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x04 }; CK_BYTE ber_sha1WithRSAEncryption[] = { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05 }; // Algorithm IDs. (Sequence of OID plus parms, usually NULL) // CK_BYTE ber_AlgMd2[] = { 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x02, 0x05, 0x00 }; CK_BYTE ber_AlgMd5[] = { 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00 }; CK_BYTE ber_AlgSha1[] = { 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00 }; CK_BYTE ber_AlgSha256[] = { 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00 }; CK_BYTE ber_AlgIdRSAEncryption[] = { 0x30, 0x0D, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00 }; // ID Lengths // CK_ULONG ber_idDSALen = sizeof(ber_idDSA); CK_ULONG ber_rsaEncryptionLen = sizeof(ber_rsaEncryption); CK_ULONG ber_md2WithRSAEncryptionLen = sizeof(ber_md2WithRSAEncryption); CK_ULONG ber_md4WithRSAEncryptionLen = sizeof(ber_md4WithRSAEncryption); CK_ULONG ber_md5WithRSAEncryptionLen = sizeof(ber_md5WithRSAEncryption); CK_ULONG ber_sha1WithRSAEncryptionLen= sizeof(ber_sha1WithRSAEncryption); CK_ULONG ber_AlgMd2Len= sizeof(ber_AlgMd2); CK_ULONG ber_AlgMd5Len= sizeof(ber_AlgMd5); CK_ULONG ber_AlgSha1Len= sizeof(ber_AlgSha1); CK_ULONG ber_AlgSha256Len= sizeof(ber_AlgSha256); CK_ULONG ber_AlgIdRSAEncryptionLen = sizeof(ber_AlgIdRSAEncryption); CK_ULONG des_weak_count = 4; CK_ULONG des_semi_weak_count = 12; CK_ULONG des_possibly_weak_count = 48; CK_BYTE des_weak_keys[4][8] = { {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, {0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E}, {0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1}, {0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE} }; CK_BYTE des_semi_weak_keys[12][8] = { {0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE}, {0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01}, {0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1}, {0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E}, {0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1}, {0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01}, {0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE}, {0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E}, {0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E}, {0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01}, {0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE}, {0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1} }; CK_BYTE des_possibly_weak_keys[48][8] = { {0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E, 0x01, 0x01}, {0x01, 0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E, 0x01}, {0x1F, 0x01, 0x01, 0x1F, 0x0E, 0x01, 0x01, 0x0E}, {0x01, 0x01, 0x1F, 0x1F, 0x01, 0x01, 0x0E, 0x0E}, {0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1, 0x01, 0x01}, {0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01}, {0xFE, 0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E, 0x01}, {0xE0, 0xFE, 0x1F, 0x01, 0xF1, 0xFE, 0x0E, 0x01}, {0xFE, 0xE0, 0x01, 0x1F, 0xFE, 0xF1, 0x01, 0x0E}, {0xE0, 0xFE, 0x01, 0x1F, 0xF1, 0xFE, 0x01, 0x0E}, {0xE0, 0xE0, 0x1F, 0x1F, 0xF1, 0xF1, 0x0E, 0x0E}, {0xFE, 0xFE, 0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E}, {0xFE, 0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1, 0x01}, {0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E, 0xFE, 0x01}, {0xFE, 0x01, 0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E}, {0xE0, 0x01, 0xFE, 0x1F, 0xF1, 0x01, 0xFE, 0x0E}, {0x01, 0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1, 0x01}, {0x1F, 0xFE, 0xE0, 0x01, 0x0E, 0xFE, 0xF0, 0x01}, {0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1, 0xFE, 0x01}, {0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01}, {0x1F, 0xE0, 0xE0, 0x1F, 0x0E, 0xF1, 0xF1, 0x0E}, {0x01, 0xFE, 0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E}, {0x01, 0xE0, 0xFE, 0x1F, 0x01, 0xF1, 0xFE, 0x0E}, {0x1F, 0xFE, 0xFE, 0x1F, 0x0E, 0xFE, 0xFE, 0x0E}, {0xE0, 0x01, 0x01, 0xE0, 0xF1, 0x01, 0x01, 0xF1}, {0xFE, 0x1F, 0x01, 0xE0, 0xFE, 0x0E, 0x01, 0xF1}, {0xFE, 0x01, 0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1}, {0xE0, 0x1F, 0x1F, 0xE0, 0xF1, 0x0E, 0x0E, 0xF1}, {0xFE, 0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE}, {0xE0, 0x1F, 0x01, 0xFE, 0xF1, 0x0E, 0x01, 0xFE}, {0xE0, 0x01, 0x1F, 0xFE, 0xF1, 0x01, 0x0E, 0xFE}, {0xFE, 0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E, 0xFE}, {0x1F, 0xFE, 0x01, 0xE0, 0x0E, 0xFE, 0x01, 0xF1}, {0x01, 0xFE, 0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1}, {0x1F, 0xE0, 0x01, 0xFE, 0x0E, 0xF1, 0x01, 0xFE}, {0x01, 0xE0, 0x1F, 0xFE, 0x01, 0xF1, 0x0E, 0xFE}, {0x01, 0x01, 0xE0, 0xE0, 0x01, 0x01, 0xF1, 0xF1}, {0x1F, 0x1F, 0xE0, 0xE0, 0x0E, 0x0E, 0xF1, 0xF1}, {0x1F, 0x01, 0xFE, 0xE0, 0x0E, 0x01, 0xFE, 0xF1}, {0x01, 0x1F, 0xFE, 0xE0, 0x01, 0x0E, 0xFE, 0xF1}, {0x1F, 0x01, 0xE0, 0xFE, 0x0E, 0x01, 0xF1, 0xFE}, {0x01, 0x1F, 0xE0, 0xFE, 0x01, 0x0E, 0xF1, 0xFE}, {0x01, 0x01, 0xFE, 0xFE, 0x01, 0x01, 0xFE, 0xFE}, {0x1F, 0x1F, 0xFE, 0xFE, 0x0E, 0x0E, 0xFE, 0xFE}, {0xFE, 0xFE, 0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1}, {0xE0, 0xFE, 0xFE, 0xE0, 0xF1, 0xFE, 0xFE, 0xF1}, {0xFE, 0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1, 0xFE}, {0xE0, 0xE0, 0xFE, 0xFE, 0xF1, 0xF1, 0xFE, 0xFE} }; // default SO pin hash values // // default SO pin = "87654321" // CK_BYTE default_so_pin_md5[MD5_HASH_SIZE] = { 0x5E, 0x86, 0x67, 0xA4, 0x39, 0xC6, 0x8F, 0x51, 0x45, 0xDD, 0x2F, 0xCB, 0xEC, 0xF0, 0x22, 0x09 }; CK_BYTE default_so_pin_sha[SHA1_HASH_SIZE] = { 0xA7, 0xD5, 0x79, 0xBA, 0x76, 0x39, 0x80, 0x70, 0xEA, 0xE6, 0x54, 0xC3, 0x0F, 0xF1, 0x53, 0xA4, 0xC2, 0x73, 0x27, 0x2A }; /* SHA-1 of "12345678" */ CK_BYTE default_user_pin_sha[SHA1_HASH_SIZE] = { 0x7c, 0x22, 0x2f, 0xb2, 0x92, 0x7d, 0x82, 0x8a, 0xf2, 0x2f, 0x59, 0x21, 0x34, 0xe8, 0x93, 0x24, 0x80, 0x63, 0x7c, 0x0d }; CK_BYTE user_pin_md5[MD5_HASH_SIZE]; CK_BYTE so_pin_md5[MD5_HASH_SIZE]; CK_BYTE master_key[3 * DES_KEY_SIZE]; opencryptoki-2.3.1+dfsg/usr/lib/pkcs11/common/encr_mgr.c0000751000175000017500000011504511327631345020665 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001,2002 */ // File: encr_mgr.c // // Encryption manager routines // #include #include // for memcmp() et al #include #include "pkcs11types.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" #include "tok_spec_struct.h" // // CK_RV encr_mgr_init( SESSION * sess, ENCR_DECR_CONTEXT * ctx, CK_ULONG operation, CK_MECHANISM * mech, CK_OBJECT_HANDLE key_handle ) { OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE * ptr = NULL; CK_KEY_TYPE keytype; CK_BBOOL flag; CK_RV rc; if (!sess || !ctx || !mech){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active != FALSE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } // key usage restrictions // if (operation == OP_ENCRYPT_INIT) { rc = object_mgr_find_in_map1( key_handle, &key_obj ); if (rc != CKR_OK){ st_err_log(18, __FILE__, __LINE__); return CKR_KEY_HANDLE_INVALID; } // is key allowed to do general encryption? // rc = template_attribute_find( key_obj->template, CKA_ENCRYPT, &attr ); if (rc == FALSE){ st_err_log(85, __FILE__, __LINE__); return CKR_KEY_FUNCTION_NOT_PERMITTED; } else { flag = *(CK_BBOOL *)attr->pValue; if (flag != TRUE){ st_err_log(85, __FILE__, __LINE__); return CKR_KEY_FUNCTION_NOT_PERMITTED; } } } else if (operation == OP_WRAP) { rc = object_mgr_find_in_map1( key_handle, &key_obj ); if (rc != CKR_OK){ st_err_log(62, __FILE__, __LINE__); return CKR_WRAPPING_KEY_HANDLE_INVALID; } // is key allowed to wrap other keys? // rc = template_attribute_find( key_obj->template, CKA_WRAP, &attr ); if (rc == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } else { flag = *(CK_BBOOL *)attr->pValue; if (flag == FALSE){ st_err_log(26, __FILE__, __LINE__); return CKR_KEY_NOT_WRAPPABLE; } } } else{ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // is the mechanism supported? is the key type correct? is a // parameter present if required? is the key size allowed? // does the key support encryption? // // Will the FCV allow the operation? // switch (mech->mechanism) { case CKM_DES_ECB: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_56_BIT_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_CDMF_ECB: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_CDMF){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_DES_CBC: case CKM_DES_CBC_PAD: { if (mech->ulParameterLen != DES_BLOCK_SIZE){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_56_BIT_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_CDMF_CBC: case CKM_CDMF_CBC_PAD: { if (mech->ulParameterLen != DES_BLOCK_SIZE){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_CDMF){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_DES3_ECB: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES3 && keytype != CKK_DES2){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_TRIPLE_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_DES3_CBC: case CKM_DES3_CBC_PAD: { if (mech->ulParameterLen != DES_BLOCK_SIZE){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_DES3 && keytype != CKK_DES2){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // if ((nv_FCV.FunctionCntlBytes[DES_FUNCTION_BYTE] & FCV_TRIPLE_DES) == 0) // return CKR_MECHANISM_INVALID; ctx->context_len = sizeof(DES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(DES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(DES_CONTEXT) ); } break; case CKM_RSA_X_509: case CKM_RSA_PKCS: { if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_RSA){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } // Check FCV // // rc = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); // if (rc == FALSE || nv_FCV.SymmetricModLength/8 < attr->value_length) // return (operation == OP_DECRYPT_INIT ? CKR_KEY_SIZE_RANGE : CKR_WRAPPING_KEY_SIZE_RANGE ); // RSA cannot be used for multi-part operations // ctx->context_len = 0; ctx->context = NULL; } break; case CKM_AES_ECB: { // XXX Copied in from DES3, should be verified - KEY if (mech->ulParameterLen != 0){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_AES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(AES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(AES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(AES_CONTEXT) ); } break; case CKM_AES_CBC: case CKM_AES_CBC_PAD: { // XXX Copied in from DES3, should be verified - KEY if (mech->ulParameterLen != AES_INIT_VECTOR_SIZE){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // is the key type correct? // rc = template_attribute_find( key_obj->template, CKA_KEY_TYPE, &attr ); if (rc == FALSE){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } else { keytype = *(CK_KEY_TYPE *)attr->pValue; if (keytype != CKK_AES){ st_err_log(20, __FILE__, __LINE__); return CKR_KEY_TYPE_INCONSISTENT; } } ctx->context_len = sizeof(AES_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(AES_CONTEXT)); if (!ctx->context){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(AES_CONTEXT) ); } break; default: st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } if (mech->ulParameterLen > 0) { ptr = (CK_BYTE *)malloc(mech->ulParameterLen); if (!ptr){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } memcpy( ptr, mech->pParameter, mech->ulParameterLen ); } ctx->key = key_handle; ctx->mech.ulParameterLen = mech->ulParameterLen; ctx->mech.mechanism = mech->mechanism; ctx->mech.pParameter = ptr; ctx->multi = FALSE; ctx->active = TRUE; return CKR_OK; } // // CK_RV encr_mgr_cleanup( ENCR_DECR_CONTEXT *ctx ) { if (!ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } ctx->key = 0; ctx->mech.ulParameterLen = 0; ctx->mech.mechanism = 0; ctx->multi = FALSE; ctx->active = FALSE; ctx->context_len = 0; if (ctx->mech.pParameter) { free( ctx->mech.pParameter ); ctx->mech.pParameter = NULL; } if (ctx->context) { free( ctx->context ); ctx->context = NULL; } return CKR_OK; } // // CK_RV encr_mgr_encrypt( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__); return CKR_OPERATION_NOT_INITIALIZED; } // if the caller just wants the encrypted length, there is no reason to // specify the input data. I just need the data length // if ((length_only == FALSE) && (!in_data || !out_data)){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->multi == TRUE){ st_err_log(31, __FILE__, __LINE__); return CKR_OPERATION_ACTIVE; } switch (ctx->mech.mechanism) { case CKM_CDMF_ECB: case CKM_DES_ECB: return pk_des_ecb_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_CDMF_CBC: case CKM_DES_CBC: return pk_des_cbc_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES_CBC_PAD: case CKM_CDMF_CBC_PAD: return des_cbc_pad_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_ECB: return des3_ecb_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_CBC: return des3_cbc_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_CBC_PAD: return des3_cbc_pad_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_RSA_PKCS: return rsa_pkcs_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_RSA_X_509: return rsa_x509_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #ifndef NOAES case CKM_AES_CBC: return aes_cbc_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_ECB: return aes_ecb_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_CBC_PAD: return aes_cbc_pad_encrypt( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif default: st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV encr_mgr_encrypt_update( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { if (!sess || !in_data || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (!out_data && !length_only){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__, __FUNCTION__); return CKR_OPERATION_NOT_INITIALIZED; } ctx->multi = TRUE; switch (ctx->mech.mechanism) { case CKM_CDMF_ECB: case CKM_DES_ECB: return des_ecb_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_CDMF_CBC: case CKM_DES_CBC: return des_cbc_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES_CBC_PAD: case CKM_CDMF_CBC_PAD: return des_cbc_pad_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_ECB: return des3_ecb_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_CBC: return des3_cbc_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_DES3_CBC_PAD: return des3_cbc_pad_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #ifndef NOAES case CKM_AES_ECB: return aes_ecb_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_CBC: return aes_cbc_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); case CKM_AES_CBC_PAD: return aes_cbc_pad_encrypt_update( sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); #endif default: return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // // CK_RV encr_mgr_encrypt_final( SESSION *sess, CK_BBOOL length_only, ENCR_DECR_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ) { if (!sess || !ctx){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ st_err_log(32, __FILE__, __LINE__, __FUNCTION__); return CKR_OPERATION_NOT_INITIALIZED; } switch (ctx->mech.mechanism) { case CKM_CDMF_ECB: case CKM_DES_ECB: return des_ecb_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_CDMF_CBC: case CKM_DES_CBC: return des_cbc_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_DES_CBC_PAD: case CKM_CDMF_CBC_PAD: return des_cbc_pad_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_DES3_ECB: return des3_ecb_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_DES3_CBC: return des3_cbc_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_DES3_CBC_PAD: return des3_cbc_pad_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); #ifndef NOAES case CKM_AES_ECB: return aes_ecb_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_AES_CBC: return aes_cbc_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); case CKM_AES_CBC_PAD: return aes_cbc_pad_encrypt_final( sess, length_only, ctx, out_data, out_data_len ); #endif default: return CKR_MECHANISM_INVALID; } st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } opencryptoki-2.3.1+dfsg/usr/lib/Makefile.am0000640000175000017500000000002111327631345016347 0ustar jfjfSUBDIRS = pkcs11 opencryptoki-2.3.1+dfsg/usr/sbin/0000751000175000017500000000000011327631345014507 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/sbin/pkcsslotd/0000751000175000017500000000000011327631345016515 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/sbin/pkcsslotd/slotmgr.c0000751000175000017500000005576111327631345020371 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ /***************************************** * AIX PKCS11 Slot manager Daemon *****************************************/ #include "pthread.h" #define SLOTD_DECLARE_VARS 1 #include "pkcsslotd.h" #include /* We make main() able to modify Daemon so that we can daemonize or not based on a command-line argument */ extern BOOL Daemon; extern BOOL IveDaemonized; #if !(THREADED) extern void *GCMain ( void *Ptr); #endif void DumpSharedMemory ( void ); /***************************************** * main() - * You know what main does. * Comment block for ease of spotting * it when paging through file * *****************************************/ int main ( int argc, char *argv[], char *envp[]) { setlocale(LC_ALL, ""); catd = catopen(MF_SLOTD,0); /**********************************/ /* Read in command-line arguments */ /**********************************/ /* FIXME: Argument for daemonizing or not */ /* FIXME: Argument for debug level */ /* FIXME: Arguments affecting the log files, whether to use syslog, etc. (Read conf file?) */ /* Report our debug level */ if ( GetDebugLevel() > DEBUG_NONE) { DbgLog(GetDebugLevel(), "Starting with debugging messages logged at level %d (%d = No messages; %d = few; %d = more, etc.)", GetDebugLevel(), DEBUG_NONE, DEBUG_LEVEL0, DEBUG_LEVEL1); } /* Save our startup directory */ SaveStartupDirectory( argv[0] ); /* Would help to do this before initializing the rest of the data structures */ // SAB XXX this needs to be modified to eliminate the need // for ODM... Currently for ODM based systems this is in odm.c // and the coresponding odm.h..... // for Non-ODM system create a no_odm.h and no_odm.c that // contains this function and does the proper work. if ( ! ReadSlotInfoDB() ) { ErrLog(SLOTD_MSG(SLOTFAIL, "Failed to read slot database.\n")); return 1; } else { DbgLog (DL0, "ReadSlotInfoDB succeeded.\n"); } /* Allocate and Attach the shared memory region */ if ( ! CreateSharedMemory() ) { /* CreateSharedMemory() does it's own error logging */ return 1; } DbgLog(DL0,"SHMID %d token %#X \n", shmid, tok); /* Now that we've created the shared memory segment, we attach to it */ if ( ! AttachToSharedMemeory() ) { /* AttachToSharedMemory() does it's own error logging */ DestroySharedMemory(); return 2; } /* Initialize the global shared memory mutex (and the attribute used to create the per-process mutexes */ if ( ! InitializeMutexes() ) { DetachFromSharedMemory(); DestroySharedMemory(); return 3; } /* Get the global shared memory mutex */ #if 1 XProcLock(&(shmp->slt_mutex)); #else #ifdef PKCS64 msem_lock(&(shmp->slt_mutex),0); #else pthread_mutex_lock(&(shmp->slt_mutex)); #endif #endif /* Populate the Shared Memory Region */ if ( ! InitSharedMemory(shmp) ) { #if 1 XProcUnLock(&(shmp->slt_mutex)); #else #ifdef PKCS64 msem_unlock(&(shmp->slt_mutex),0); #else pthread_mutex_unlock(&(shmp->slt_mutex)); #endif #endif DetachFromSharedMemory(); DestroySharedMemory(); return 4; } /* Release the global shared memory mutex */ #if 1 XProcUnLock(&(shmp->slt_mutex)); #else #ifdef PKCS64 msem_unlock(&(shmp->slt_mutex),0); #else pthread_mutex_unlock(&(shmp->slt_mutex)); #endif #endif #if TEST_MUTEXES DumpSharedMemory(); #endif /* TEST_MUTEXES */ /* * Become a Daemon, if called for */ if ( Daemon ) { // SAB XXX Here we need to remove the dependency on libdae // since we don't want to port that over to Linux... // #ifdef NODAE { pid_t pid; if ( (pid = fork()) < 0 ){ DestroyMutexes(); DetachFromSharedMemory(); DestroySharedMemory(); return 5; } else { if ( pid != 0) { exit(0); // Terminate the parent } else { setsid(); // Session leader #ifndef DEV fclose(stderr); fclose(stdout); fclose(stdin); #endif } } } #else dae_parent_t parent = DAE_P_OTHER; /* Something other than SRC or inetd */ dae_error_detail_t err_detail; int dae_error = DAE_E_OK; pid_t OldPid = getpid(); dae_init_prevent_zombies( parent, RESTART_SYS_CALLS ); if ( (dae_error = dae_init( &parent, &err_detail )) != DAE_E_OK ) { #ifdef DEV // Only log this information in development builds fprintf(stderr, "Failed to daemonize! dae_init returned %s (%d)\n", DAEConst(dae_error), dae_error); fprintf(stderr, "the routine \"%s\" returned the following information:\n", err_detail.dae_routine); fprintf(stderr, "\"%s\"\n", err_detail.dae_error_string); #endif DestroyMutexes(); DetachFromSharedMemory(); DestroySharedMemory(); return 5; } IveDaemonized = TRUE; #ifdef DEV // Log only on development builds LogLog("DAEMON: Process %d spawned daemon process %d", OldPid, getpid()); #endif #endif } else { #ifdef DEV // Log only on development builds LogLog("Not becoming a daemon...\n"); #endif } /***************************************** * * Register Signal Handlers * Daemon probably should ignore ALL signals possible, since termination * while active is a bad thing... however one could check for * any processes active in the shared memory, and destroy the shm if * the process wishes to terminate. * *****************************************/ /* * We have to set up the signal handlers after we daemonize because * the daemonization process redefines our handler for (at least) SIGTERM */ if ( ! SetupSignalHandlers() ) { DestroyMutexes(); DetachFromSharedMemory(); DestroySharedMemory(); return 6; } /* ultimatly we will create a couple of threads which monitor the slot db and handle the insertion and removal of tokens from the slot. */ /* For Testing the Garbage collection routines */ /* shmp->proc_table[3].inuse = TRUE; shmp->proc_table[3].proc_id = 24328; */ #if !defined(NOGARBAGE) printf("Start garbage \n"); /* start garbage collection thread */ if ( ! StartGCThread(shmp) ) { DestroyMutexes(); DetachFromSharedMemory(); DestroySharedMemory(); return 7; } #endif #if TEST_MUTEXES /* Get the global shared memory mutex */ LogLog ("Grabbing the shared memory mutex"); pthread_mutex_lock(&(shmp->slt_mutex)); #endif /* TEST_MUTEXES */ #if TEST_COND_VARS DumpSharedMemory(); LogLog("Send this process a SIGUSR1 to get it to signal on the condition variable"); #endif /* TEST_COND_VARS */ // We've fully become a daemon. Now create the PID file { FILE *pidfile; pidfile = fopen(PID_FILE_PATH,"w"); if (pidfile) { fprintf(pidfile,"%d",getpid()); fclose(pidfile); } } while (1) { #if !(THREADED) && !(NOGARBAGE) GCMain(shmp); #else sleep(10); #endif } /************************************************************* * * Here we need to actualy go through the processes and verify that thye * still exist. If not, then they terminated with out properly calling * C_Finalize and therefore need to be removed from the system. * Look for a system routine to determine if the shared memory is held by * the process to further verify that the proper processes are in the * table. * *************************************************************/ } /* end main */ #if TEST_MUTEXES || TEST_COND_VARS void DumpSharedMemory ( void ) { u_int32 *p; char Buf[PATH_MAX]; u_int32 i; p = (u_int32 *) shmp; for ( i = 0; i < 15; i++ ) { sprintf(Buf, "%08X %08X %08X %08X", p[0+(i*4)], p[1+(i*4)], p[2+(i*4)], p[3+(i*4)]); LogLog(Buf); } return; } #endif /* TEST_MUTEXES || TEST_COND_VARS */ opencryptoki-2.3.1+dfsg/usr/sbin/pkcsslotd/signal.c0000751000175000017500000005143511327631345020151 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #include "pthread.h" #include "pkcsslotd.h" #include "err.h" #ifdef PKCS64 extern BOOL IsValidProcessEntry ( pid_t_64 pid, time_t_64 RegTime ); #else extern BOOL IsValidProcessEntry ( pid_t pid, time_t RegTime ); #endif static int SigsToIntercept[] = { SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGTSTP, SIGTTIN, SIGTTOU, SIGUSR1, SIGUSR2, SIGPROF }; /* SIGCONT - Don't want to exit on SIGCONT; it'll in fact mask other signals - kill -HUP actually sends SIGCONT before SIGHUP */ /* SIGCHLD - Don't want to exit. Should never receive, but we do, apparently when something tries to cancel the GC Thread */ static int SigsToIgnore[] = { SIGCHLD, }; /************************************************** * slotdGenericSignalHandler * * Main signal handler for the daemon. Doesn't * allow the daemon to be killed unless we're * not in use ***************************************************/ void slotdGenericSignalHandler( int Signal ) { int procindex; BOOL OkToExit = TRUE; /******************************************************** * DbgLog calls (possibly) printf, syslog_r, etc. * The behavior of these functions is "undefined" * when called from a signal handler according to * the sigaction man page. * * Thus, they're only called in development * versions of the code. ********************************************************/ #ifdef DEV DbgLog(DL2, "slotdGenericSignalHandler got %s (%d; %#x)", SignalConst(Signal), Signal, Signal); #endif /* DEV */ #if !defined(NOGARBAGE) StopGCThread(shmp); CheckForGarbage(shmp); #endif for ( procindex = 0; (procindex < NUMBER_PROCESSES_ALLOWED); procindex++ ) { #ifdef PKCS64 Slot_Mgr_Proc_t_64 *pProc = &(shmp->proc_table[procindex]); #else Slot_Mgr_Proc_t *pProc = &(shmp->proc_table[procindex]); #endif if ( shmp == NULL ) { break; } if ( ( pProc->inuse ) #if !(NOGARBAGE) && ( IsValidProcessEntry( pProc->proc_id, pProc->reg_time)) #endif ) { /* Someone's still using us... Log it */ OkToExit = FALSE; #ifdef DEV WarnLog("Process %d is still registered", pProc->proc_id); #endif } } if ( !OkToExit ) { DbgLog(DL1,"Continuing execution"); #if !defined(NOGARBAGE) StartGCThread(shmp); #endif return; } InfoLog("Exiting on %s (%d; %#x)", SignalConst(Signal), Signal, Signal); DestroyMutexes(); DetachFromSharedMemory(); DestroySharedMemory(); exit(0); } #if TEST_MUTEXES || TEST_COND_VARS void TestSig ( int Signal ) { int err; LogLog ( "TestSig got %s (%d; %#x)", SignalConst(Signal), Signal, Signal); #if TEST_MUTEXES /* Release the global shared memory mutex */ pthread_mutex_unlock(&(shmp->slt_mutex)); LogLog("TestSig unlocked the mutex"); #endif /* TEST_MUTEXES */ #if TEST_COND_VARS LogLog("Locking the CV Mutex"); if ( (err = pthread_mutex_lock( &(shmp->shmem_cv_mutex) )) != 0 ) { DbgLog(DL0,"TestSig: pthread_mutex_lock returned %s (%d; %#x)\n", SysConst(err), err, err ); return; } /* Manipulate the variable */ LogLog("Locked the CV Mutex"); /* Signal one app/thread */ if ( (err = pthread_cond_signal( &(shmp->shmem_cv) ) ) != 0 ) { DbgLog(DL0,"TestSig: pthread_cond_signal returned %s (%d; %#x)\n", SysConst(err), err, err ); return; } LogLog("Releasing the CV Mutex"); if ( (err = pthread_mutex_unlock ( &(shmp->shmem_cv_mutex) ) ) != 0 ) { DbgLog(DL0,"TestSig: pthread_mutex_unlock returned %s (%d; %#x)\n", SysConst(err), err, err ); return; } LogLog("CV Mutex released"); #endif /* TEST_COND_VARS */ return; } #endif /* TEST_MUTEXES || TEST_COND_VARS*/ /*************************************************** * SetupSignalHandlers - * * Installs slotdGenericSignalHandler for the listed signals * ***************************************************/ int SetupSignalHandlers ( void ) { unsigned int i; struct sigaction new_action; new_action.sa_handler = slotdGenericSignalHandler; sigemptyset(&(new_action.sa_mask)); sigaddset(&(new_action.sa_mask), SIGCHLD); /* sigaddset(&(new_action.sa_mask), SA_NOCLDWAIT); */ /* sigaddset(&(new_action.sa_mask), SA_NOCLDSTOP); */ new_action.sa_flags = (RESTART_SYS_CALLS ? SA_RESTART : 0); for ( i = 0; i < (sizeof(SigsToIntercept) / sizeof(SigsToIntercept[0])); i++ ) { if ( sigaction ( SigsToIntercept[i], &new_action, NULL ) != 0 ) { //DbgLog("SetupSignalHandlers - sigaction failed for %s (%d; %#x)", SignalConst(SigsToIntercept[i]), SigsToIntercept[i], SigsToIntercept[i]); return FALSE; } } new_action.sa_handler = SIG_IGN; sigemptyset(&(new_action.sa_mask)); for ( i = 0; i < (sizeof ( SigsToIgnore ) / sizeof (SigsToIgnore[0]) ); i++ ) { if ( sigaction ( SigsToIgnore[i], &new_action, NULL ) != 0 ) { //DbgLog ( "Failed to ignore signal."); return FALSE; } } #if TEST_MUTEXES || TEST_COND_VARS new_action.sa_handler = TestSig; if ( sigaction ( SIGUSR1, &new_action, NULL ) != 0 ) { DbgLog(DL0,"Failed to set TestSig for SIGUSR1"); return FALSE; } #endif /* TEST_MUTEXES || TEST_COND_VARS */ return TRUE; } /*********************************************************************** * GCBlockSignals - * * Garbage collector calls this to prevent signals from getting * sent to the GC thread. * ***********************************************************************/ BOOL GCBlockSignals (void) { unsigned int i; int ret; sigset_t SigSet; sigemptyset(&SigSet); for ( i = 0; i < (sizeof(SigsToIntercept) / sizeof(SigsToIntercept[0]) ); i++ ) { sigaddset(&SigSet, SigsToIntercept[i]); } ret = pthread_sigmask(SIG_SETMASK, &SigSet, NULL); return ret; } opencryptoki-2.3.1+dfsg/usr/sbin/pkcsslotd/no_odm.c0000751000175000017500000007045111327631345020146 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #include "pthread.h" #include "pkcsslotd.h" #include #include #define ODM_DIRECTORY CONFIG_PATH /***************************** * Function Prototypes * *****************************/ static BOOL BlankPadNoNull ( char *Dest, char *Src, u_int32 SrcLen ); #ifdef PKCS64 static void PrintSlotInfo ( Slot_Info_t_64 *P ); #else static void PrintSlotInfo ( Slot_Info_t *P ); #endif BOOL BooleanVal ( char *ptr, int length, BOOL *result ) { int i; char *p = ptr; /* Takes a text-based way of entering Yes/No and converts it to 1 or 0 */ if ( ptr == NULL ) return FALSE; /* skip over leading whitespace */ i = 0; while ( (i < length) && (isspace(ptr[i])) ) { i++; } if ( i >= length ) { *result = FALSE; return TRUE; } /* p points to the 1st non-space character */ p = &(ptr[i]); /* Does p start with Y|T|1 (yes, True, 1)? */ if ( p[0] == 'y' || p[0] == 'Y' || p[0] == 'T' || p[0] == 't' ) { *result = TRUE; return TRUE; } /* What about N|F|0 (zero)? */ if ( p[0] == 'n' || p[0] == 'N' || p[0] == '0' || p[0] == 'F' || p[0] == 'f' ) { *result = FALSE; return TRUE; } /* 0 is checked for above. Any other number is TRUE */ if ( isdigit( p[0] ) ) { *result = TRUE; return TRUE; } /* We've got unrecognized data */ return FALSE; } #ifdef PKCS64 void PrintSlotInfo ( Slot_Info_t_64 *P ) { #else void PrintSlotInfo ( Slot_Info_t *P ) { #endif #ifdef PKCS64 CK_SLOT_INFO_64 *ck = NULL; #else CK_SLOT_INFO *ck = NULL; #endif ck = &(P->pk_slot); if (! P->present) return; DbgLog(DL3, "slot_number: %d", P->slot_number); DbgLog(DL3, "present : %d", P->present); DbgLog(DL3, "pk_slot :"); DbgLog(DL3, " slotDescription: '%.64s'", ck->slotDescription); DbgLog(DL3, " manufacturerID : '%.32s'", ck->manufacturerID); DbgLog(DL3, " flags : %#x", ck->flags); DbgLog(DL3, " hardwareVersion: %d.%d", ck->hardwareVersion.major, ck->hardwareVersion.minor); DbgLog(DL3, " firmwareVersion: %d.%d", ck->firmwareVersion.major, ck->firmwareVersion.minor); DbgLog(DL3, "dll_location: '%s'", P->dll_location); DbgLog(DL3, "slot_init_fcn: '%s'", P->slot_init_fcn); DbgLog(DL3, "correlator: '%s'", P->correlator); DbgLog(DL3, "global_sessions: %#X", P->global_sessions); DbgLog(DL3, "************************************************"); return; } static BOOL BlankPadNoNull ( char *Dest, char *Src, u_int32 Len ) { char *s = NULL; /* Allocate Len bytes */ if ( (s = (char *) malloc(Len)) == NULL ) { return FALSE; } /* Fill with blanks */ memset(s, ' ', Len); /* Copy the string, but not the trailing NULL */ memcpy(s, Src, ( ( strlen(Src) < Len ) ? strlen(Src) : Len ) ); /* Copy Len bytes into Dest */ memcpy(Dest, s, Len); /* Free storage */ free(s); return TRUE; } // Need to eliminate need for ODM here... BOOL ReadSlotInfoDB ( void ) { unsigned char Index = 0; char StartDir[PATH_MAX + 1]; enum element_type { Present = 1, SlotNumber, SlotDescription, ManufacturerID, TokenPresent, RemovableToken, HardwareSlot, HwVersionMajor, HwVersionMinor, FwVersionMajor, FwVersionMinor, Correlator, DLLLocation, SlotInitFcn }; enum element_type element_num; char slot_entry[PATH_MAX], *slot_element; char separator[] = "|\n"; //char separator[] = "|"; BOOL Res = FALSE; #ifdef PKCS64 CK_SLOT_INFO_64 *pSlot = NULL; #else CK_SLOT_INFO *pSlot = NULL; #endif #ifdef PKCS64 Slot_Info_t_64 sinfo_struct; #else Slot_Info_t sinfo_struct; #endif FILE *fp; sprintf(StartDir,"%s/%s", ODM_DIRECTORY, "pk_config_data"); fp=fopen(StartDir, "r"); if (fp == NULL) { fprintf(stderr, "\nCannot open file %s\n", StartDir); fprintf(stderr, "Please run %s/pkcs11_startup\n", SBIN_PATH); return FALSE; } /* first checking if the end of file hasn't been reached */ // For some reason (strange) on linux the FP gets nulled when the end of the file // is reached....SO, we just check for a valid FP first.. while( fp && !feof(fp) ) { if( Index >= NUMBER_SLOTS_MANAGED ) // making sure all slots aren't filled in the sinfo array break; #ifdef ALLOCATE slot_entry = (char *)malloc(sizeof(char)*(PATH_MAX)); #else memset(slot_entry, 0, PATH_MAX); #endif fgets(slot_entry, PATH_MAX, fp); while( ( (slot_entry[0] == '#') || (slot_entry[0] == '\n') || (slot_entry[0] == (char)NULL) ) && (!feof(fp)) ) { // skipping all blank lines, and lines beginning with a #, at all times // AM I FORGETTING ANY OTHER CONDITIONS FOR BLANK LINES ?? // SAB XXX Any one of these causes an abort fgets(slot_entry, PATH_MAX, fp); } // Check for null string... if ( slot_entry[0] == '\0') break; // if( feof(fp) ) // break; memset(&sinfo_struct, 0, sizeof(sinfo_struct)); // for good measure zero it out before use each time sinfo_struct.global_sessions = 0; // initializing to zero element_num = Present; /* Present */ slot_element = strtok(slot_entry, separator); if ( ! BooleanVal( slot_element, strlen(slot_element), &Res ) ) // BooleanVal(), correct value for 2nd parameter ?? continue; if (Res) sinfo_struct.present = (CK_BOOL) Res; else break; // skipping this entry if it's not "Present" ?? element_num++; while( (slot_element = strtok(NULL, separator)) != NULL ) { // continually parsing line, extracting the tokens separated by | // in variable string, slot_entry, and putting them in their // appropriate fields in the Slot_Info_t(_64) struct, sinfo_struct pSlot = &(sinfo_struct.pk_slot); switch(element_num) { /* Switch Statement to deal with each element of the slot, placing the elements in appropriate member of sinfo_struct */ /* SlotNumber */ case SlotNumber: #if 0 #ifdef PKCS64 sinfo_struct.slot_number = (CK_SLOT_ID_64) atoi(slot_element); #else sinfo_struct.slot_number = (CK_SLOT_ID) atoi(slot_element); #endif #else sinfo_struct.slot_number = Index; // slot_element in config file is deprecated #endif element_num++; break; /* SlotDescription */ case SlotDescription: strncpy( (char *)(pSlot->slotDescription), slot_element, ( (strlen(slot_element) > sizeof(pSlot->slotDescription)) ? sizeof(pSlot->slotDescription) : (strlen(slot_element) ) ) ); /* Set the last character in string to NULL since strncpy may mor may not copy the trailing NULL */ pSlot->slotDescription[sizeof(pSlot->slotDescription) - 1] = (CK_CHAR)NULL; element_num++; break; /* ManufacturerID */ case ManufacturerID: strncpy( (char *)(pSlot->manufacturerID), slot_element, ( (strlen(slot_element) > sizeof(pSlot->manufacturerID)) ? (sizeof(pSlot->manufacturerID)) : (strlen(slot_element) ) ) ); /* Set the last character in string to NULL since strncpy may mor may not copy the trailing NULL */ pSlot->manufacturerID[sizeof(pSlot->manufacturerID) - 1] = (CK_CHAR)NULL; element_num++; break; /* TokenPresent */ case TokenPresent: pSlot->flags = 0x0; //NULL; // initially setting to NULL Res = FALSE; // resetting Res to FALSE before determining token type using BooleanVal() function if( BooleanVal(slot_element, strlen(slot_element), &Res) ) if(Res == TRUE) pSlot->flags |= (CKF_TOKEN_PRESENT); #if 0 // SAB XXX Since tokens can be removable, it is concievable that an // entry exists but the token is not present.... So the else clause is // not needed Also all over the code you are changing the present // flag... probably not what you intended else sinfo_struct.present = (CK_BOOL) FALSE; #endif /* fprintf(stderr, "\nUnrecognized data\n"); // not exactly sure about this. */ element_num++; break; /* RemovableToken */ case RemovableToken: if( BooleanVal(slot_element, strlen(slot_element), &Res) ) if(Res == TRUE) pSlot->flags |= (CKF_REMOVABLE_DEVICE); #if 0 // SAB XXX Since tokens can be removable, it is concievable that an // entry exists but the token is not present.... So the else clause is // not needed else sinfo_struct.present = (CK_BOOL) FALSE; /* fprintf(stderr, "\nUnrecognized data\n"); // not exactly sure about this. */ #endif element_num++; break; /* HardwareSlot */ case HardwareSlot: if( BooleanVal(slot_element, strlen(slot_element), &Res) ) if(Res == TRUE) pSlot->flags |= (CKF_HW_SLOT); #if 0 else // SAB XXX Since tokens can be removable, it is concievable that an // entry exists but the token is not present.... So the else clause is // not needed sinfo_struct.present = (CK_BOOL) FALSE; #endif /* fprintf(stderr, "\nUnrecognized data\n"); // not exactly sure about this. */ if(pSlot->flags == 0x0 /*NULL*/ ) // making sure after all possible types have flags have been checked for fprintf(stderr, "\nUnrecognized token flag\n"); // the token has been labeled as one of them element_num++; break; /* HardwareVersion major and minor */ case HwVersionMajor: pSlot->hardwareVersion.major = (CK_BYTE) atoi(slot_element); element_num++; break; case HwVersionMinor: pSlot->hardwareVersion.minor = (CK_BYTE) atoi(slot_element); element_num++; break; /*FirmwareVersion major and minor */ case FwVersionMajor: pSlot->firmwareVersion.major = (CK_BYTE) atoi(slot_element); element_num++; break; case FwVersionMinor: pSlot->firmwareVersion.minor = (CK_BYTE) atoi(slot_element); element_num++; break; /* Correlator */ case Correlator: // SAB XXX FIXME... be able to handle NULL correlator // for tokens which don't need this... XXX if(slot_element[0] == 0x0 /*NULL */ ) { sinfo_struct.correlator[0] = '\0'; } else { strncpy( (sinfo_struct.correlator), slot_element, ( (strlen(slot_element) > sizeof(sinfo_struct.correlator)) ? (sizeof(sinfo_struct.correlator)) : (strlen(slot_element)) ) ); /* Set the last character in string to NULL since strncpy may mor may not copy the trailing NULL */ sinfo_struct.correlator[sizeof(sinfo_struct.correlator) - 1] = (char) NULL; } element_num++; break; /* DLLLocation */ case DLLLocation: if(slot_element[0] == 0x0 /*NULL */) { //finish later... sinfo_struct.dll_location[0] = (char)NULL; } else { strncpy( (sinfo_struct.dll_location), slot_element, ( (strlen(slot_element) > sizeof(sinfo_struct.dll_location)) ? (sizeof(sinfo_struct.dll_location)) : (strlen(slot_element)) ) ); // took away an ")" /* Set the last character in string to NULL since strncpy may mor may not copy the trailing NULL */ sinfo_struct.dll_location[sizeof(sinfo_struct.dll_location) - 1] = (char) NULL; } element_num++; break; /* SlotInitFcn */ case SlotInitFcn: if(slot_element[0] == 0x0 /*NULL */) { // finish later... sinfo_struct.slot_init_fcn[0] = (char)NULL; } else { // SAB if there is not an initfcn then this entry is not used strncpy( (sinfo_struct.slot_init_fcn), slot_element, ( (strlen(slot_element) > sizeof(sinfo_struct.slot_init_fcn)) ? (sizeof(sinfo_struct.slot_init_fcn)) : strlen(slot_element)) ); /* Set the last character in string to NULL since strncpy may mor may not copy the trailing NULL */ sinfo_struct.slot_init_fcn[sizeof(sinfo_struct.slot_init_fcn) - 1] =(char) NULL; { /* stripping off trailing new line character, '\n' from init function name if necessary */ unsigned int i; for(i = 0; i < sizeof(sinfo_struct.slot_init_fcn); i++){ if(sinfo_struct.slot_init_fcn[i] == '\n') sinfo_struct.slot_init_fcn[i] = (char)NULL; } } } element_num++; break; default: // SAB... since this is a daemon we reallly don't want to // be doing printf's .... fprintf(stderr, "\nIncorrect field present.\n"); } } /* *copying the contents of sinfo_struct into the array of similar structures if it's a valid entry *(i.e. init fcn & dll filename are non-NULL...and the latter exists and is valid?) */ if( (sinfo_struct.dll_location != NULL) && (sinfo_struct.slot_init_fcn != NULL) ) { memcpy(&sinfo[Index], &sinfo_struct, sizeof(sinfo_struct)); // similar to sinfo[Index] = &sinfo_struct; PrintSlotInfo( &(sinfo[Index]) ); Index++; } #ifdef ALLOCATE if (slot_entry) { free(slot_entry); slot_entry = NULL; } #endif } if( Index >= NUMBER_SLOTS_MANAGED ) fprintf(stderr, "\nThe maximum number of slots supported has been reached\n"); if (fp) fclose( fp ); NumberSlotsInDB = Index; // This is required since it sets the count in // the shared memory segment return TRUE; } opencryptoki-2.3.1+dfsg/usr/sbin/pkcsslotd/odm.h0000751000175000017500000003735211327631345017462 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/sbin/pkcsslotd/odm.h,v 1.1 2005/01/18 16:09:03 kyoder Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #ifndef _ODM_H #define _ODM_H 1 #include "MyObjects.h" /* Header file doesn't use void param lists in prototypes and the compiler is complaining */ int odm_initialize(void); int odm_terminate(void); int *odmErrno(void); typedef struct _ConstInfo { unsigned const int Code; unsigned const char Name[64]; /* UCHAR Descrip[256]; */ } ConstInfo, *pConstInfo; #define CONSTINFO(_X) { (_X), (#_X) } /********************* * Function Prototypes *********************/ const unsigned char *ODMConst( unsigned int Val ); const unsigned char *ConstName( pConstInfo pInfoArray, unsigned int InfoArraySize, unsigned int ConstValue ); #endif /* _ODM_H */ opencryptoki-2.3.1+dfsg/usr/sbin/pkcsslotd/log.h0000751000175000017500000004425111327631345017460 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/sbin/pkcsslotd/log.h,v 1.2 2005/02/22 20:49:30 mhalcrow Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #ifndef _LOG_H #define _LOG_H 1 #ifndef FALSE #define FALSE 0 #endif /* FALSE */ #ifndef TRUE #define TRUE (!(FALSE)) #endif /* TRUE */ #ifndef MAX_LOGGING_FACILITIES #define MAX_LOGGING_FACILITIES 16 #endif /* MAX_LOGGING_FACILITIES */ #ifndef TRUNCATE_LOGS_ON_START #define TRUNCATE_LOGS_ON_START 0 #endif /* TRUNCATE_LOGS_ON_START */ /* Use an enum here? */ #define DEBUG_NONE (0) #define DEBUG_LEVEL0 (100) /* Less detail */ #define DEBUG_LEVEL1 (DEBUG_LEVEL0 + 100) /* . */ #define DEBUG_LEVEL2 (DEBUG_LEVEL1 + 100) /* v */ #define DEBUG_LEVEL3 (DEBUG_LEVEL2 + 100) /* More detail */ #define DEBUG_LEVEL4 (DEBUG_LEVEL3 + 100) #define DEBUG_LEVEL5 (DEBUG_LEVEL4 + 100) #define DNONE (DEBUG_NONE) #define DL0 (DEBUG_LEVEL0) #define DL1 (DEBUG_LEVEL1) #define DL2 (DEBUG_LEVEL2) #define DL3 (DEBUG_LEVEL3) #define DL4 (DEBUG_LEVEL4) #define DL5 (DEBUG_LEVEL5) #ifndef DbgPrint #define DbgPrint DbgLog #endif /* DbgPrint */ /************** * Structures * **************/ /************************************************************************ * Yes, the structures are somewhat redundant; this is an evolutionary * side-effect. They should probably be combined into a single struct * - SCM ************************************************************************/ typedef unsigned int u_int32; typedef u_int32 LogHandle, *pLogHandle; typedef u_int32 BOOL, bool, BOOLEAN, boolean; typedef struct _logging_facility_info { BOOL Initialized; char Descrip[255]; u_int32 LogOption; char *Filename; BOOL UseSyslog; u_int32 LogLevel; pid_t pid; } LoggingFacilityInfo, *pLoggingFacilityInfo; typedef struct _LoggingFacility { char *Label; pLogHandle phLog; char *Filename; BOOL UseSyslog; u_int32 LogLevel; } LoggingFacility, *pLoggingFacility; /******************************** * Exported Function Prototypes * ********************************/ void DbgLog ( u_int32 DebugLevel, char *Format, ... ); void ErrLog ( char *Format, ... ); void LogLog ( char *Format, ... ); void WarnLog ( char *Format, ... ); void TraceLog ( char *Format, ... ); void InfoLog ( char *Format, ... ); BOOL PKCS_Log ( LogHandle *phLog, char *Format, va_list ap ); BOOL NewLoggingFacility ( char *ID, pLoggingFacility pStuff ); BOOL CloseLoggingFacility ( LogHandle hLog ); BOOL GetCurrentTimeString ( char *Buffer ); u_int32 SetDebugLevel ( u_int32 Val ); u_int32 GetDebugLevel ( void ); #endif /* _LOG_H */ opencryptoki-2.3.1+dfsg/usr/sbin/pkcsslotd/odm.c0000751000175000017500000006501511327631345017452 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #include "pthread.h" #pragma info(none) #include "pkcsslotd.h" #include "SlotDB.c" #pragma info(restore) /* Header file doesn't use void param lists in prototypes and the compiler is complaining */ extern int odm_initialize(void); extern int odm_terminate(void); extern int *odmErrno(void); #define ODM_DIRECTORY CONFIG_PATH /***************************** * Function Prototypes * *****************************/ static BOOL BlankPadNoNull ( char *Dest, char *Src, u_int32 SrcLen ); #ifdef PKCS64 static void PrintSlotInfo ( Slot_Info_t_64 *P ); #else static void PrintSlotInfo ( Slot_Info_t *P ); #endif #pragma info(none) #pragma info(restore) BOOL BooleanVal ( char *ptr, int length, BOOL *result ) { int i; char *p = ptr; /* Takes a text-based way of entering Yes/No and converts it to 1 or 0 */ if ( ptr == NULL ) return FALSE; /* skip over leading whitespace */ i = 0; while ( (i < length) && (isspace(ptr[i])) ) { i++; } if ( i >= length ) { *result = FALSE; return TRUE; } /* p points to the 1st non-space character */ p = &(ptr[i]); /* Does p start with Y|T|1 (yes, True, 1)? */ if ( p[0] == 'y' || p[0] == 'Y' || p[0] == 'T' || p[0] == 't' ) { *result = TRUE; return TRUE; } /* What about N|F|0 (zero)? */ if ( p[0] == 'n' || p[0] == 'N' || p[0] == '0' || p[0] == 'F' || p[0] == 'f' ) { *result = FALSE; return TRUE; } /* 0 is checked for above. Any other number is TRUE */ if ( isdigit( p[0] ) ) { *result = TRUE; return TRUE; } /* We've got unrecognized data */ return FALSE; } #ifdef PKCS64 void PrintSlotInfo ( Slot_Info_t_64 *P ) { #else void PrintSlotInfo ( Slot_Info_t *P ) { #endif #ifdef PKCS64 CK_SLOT_INFO_64 *ck = NULL; #else CK_SLOT_INFO *ck = NULL; #endif ck = &(P->pk_slot); if (! P->present) return; DbgLog(DL3, "slot_number: %d", P->slot_number); DbgLog(DL3, "present : %d", P->present); DbgLog(DL3, "pk_slot :"); DbgLog(DL3, " slotDescription: '%.64s'", ck->slotDescription); DbgLog(DL3, " manufacturerID : '%.32s'", ck->manufacturerID); DbgLog(DL3, " flags : %#x", ck->flags); DbgLog(DL3, " hardwareVersion: %d.%d", ck->hardwareVersion.major, ck->hardwareVersion.minor); DbgLog(DL3, " firmwareVersion: %d.%d", ck->firmwareVersion.major, ck->firmwareVersion.minor); DbgLog(DL3, "dll_location: '%s'", P->dll_location); DbgLog(DL3, "slot_init_fcn: '%s'", P->slot_init_fcn); DbgLog(DL3, "correlator: '%s'", P->correlator); DbgLog(DL3, "global_sessions: %#X", P->global_sessions); DbgLog(DL3, "************************************************"); return; } static BOOL BlankPadNoNull ( char *Dest, char *Src, u_int32 Len ) { char *s = NULL; /* Allocate Len bytes */ if ( (s = (char *) malloc(Len)) == NULL ) { return FALSE; } /* Fill with blanks */ memset(s, ' ', Len); /* Copy the string, but not the trailing NULL */ memcpy(s, Src, ( ( strlen(Src) < Len ) ? strlen(Src) : Len ) ); /* Copy Len bytes into Dest */ memcpy(Dest, s, Len); /* Free storage */ free(s); return TRUE; } BOOL ReadSlotInfoDB ( void ) { CLASS_SYMBOL csSlot; char *odm_path = NULL; struct ck_slot *p = NULL; struct listinfo lInfo; u_int32 i; unsigned char Index = 0; unsigned char ValidEntries = 0; char StartDir[PATH_MAX + 1]; if ( odm_initialize() != 0 ) { ErrLog(SLOTD_MSG(ODMFAIL, "odm_initialize failed (0x%X)\n"), odmerrno); return FALSE; } sprintf(StartDir,"%s",ODM_DIRECTORY); if ( (odm_path = odm_set_path(StartDir)) == (char *) -1 ) { ErrLog(SLOTD_MSG(ODMSET, "Failed to set ODM path (0x%X)"), odmerrno); return FALSE; } DbgLog(DL0, "Set ODM search path from %s to %s", odm_path, StartDir); if ( (csSlot = odm_open_class( ck_slot_CLASS )) < (CLASS_SYMBOL) 0 ) { DbgLog(DL0, "ReadSlotInfoDB: odm_open_class() failed; %s (%d; %#x)", ODMConst(odmerrno), odmerrno, odmerrno); if ( odm_path != NULL ) { free (odm_path); } return FALSE; } if ( (p = get_ck_slot_list ( csSlot, "", &lInfo, NUMBER_SLOTS_MANAGED, 1) ) == (struct ck_slot *) -1 ) { DbgLog (DL0, "ReadSlotInfoDB: get_ck_info_list() failed: %s (%d; %#x)", ODMConst(odmerrno), odmerrno, odmerrno); if ( odm_path != NULL ) { free (odm_path); } return FALSE; } if ( p == NULL ) { DbgLog ( DL0, "ReadSlotInfoDB: get_ck_info_list() returned NULL"); if ( odm_path != NULL ) { free (odm_path); } return FALSE; } DbgLog (DL0, "ReadSlotInfoDB: %d entries found in database", lInfo.num); for ( i = 0; i < lInfo.num; i++ ) { BOOL Res = FALSE; #ifdef PKCS64 CK_SLOT_INFO_64 *pSlot = NULL; #else CK_SLOT_INFO *pSlot = NULL; #endif /* Present */ /* Set in sinfo[] later, after we've verified Index */ if ( ! BooleanVal( &(p[i].Present[0]), sizeof(p[i].Present), &Res) ) { DbgLog(DL0,"ReadSlotInfoDB: BooleanVal() failed for Present.\n"); continue; } if ( ! Res ) { /* The database has this slot marked as not present */ DbgLog(DL2, "ReadSlotInfoDB: Slot '%s' (DB index %d) is marked as not present. Skipping.", p[i].SlotDescription, i); continue; } /* Verify that we've got space to store this entry */ if ( Index >= NUMBER_SLOTS_MANAGED ) { DbgLog(DL0,"ReadSlotInfoDB: Database contains entries for at least %d present slots. We support %d. Ignoring everything after %d.", Index + 1, NUMBER_SLOTS_MANAGED, NUMBER_SLOTS_MANAGED ); break; } pSlot = &(sinfo[Index].pk_slot); /* Check to see that our data structure isn't already in use */ if ( sinfo[Index].present ) { DbgLog (DL0, "ReadSlotInfoDB: Multiple entries in the database for slot # %d. Exiting.", Index); DbgLog ( DL0,"ReadSlotInfoDB: My data structure isn't empty and it should be!"); if ( odm_path != NULL ) { free (odm_path); } if ( p != NULL ) { free (p); } return FALSE; } DbgLog(DL2, "ReadSlotInfoDB: Reading information for slot %d --> %s", Index, p[i].SlotDescription); /* SlotNumber */ /* Warn the user that the SlotNumber field in the DB is depricated */ #ifdef DEV if ( p[i].SlotNumber != 0 ) { WarnLog("ReadSlotInfoDB: The database contains a SlotNumber entry for a '%s' slot", p[i].SlotDescription ); WarnLog("ReadSlotInfoDB: The system ignores this value and assigns the slot number dynamically."); } #endif sinfo[Index].slot_number = Index; /* Present */ /* No test here because we've already passed it above */ sinfo[Index].present = (CK_BOOL) TRUE; /* Slot Description */ #pragma info(none) if ( ! BlankPadNoNull ( (char *) &(pSlot->slotDescription[0]), &(p[i].SlotDescription[0]), sizeof(pSlot->slotDescription) ) ) { #pragma info(restore) ErrLog(SLOTD_MSG(SLOTSKIP, "ReadSlotInfoDB: Error reading SlotDescription '%s'. Skipping."), p[i].SlotDescription); /* Null out the sinfo struct */ memset( pSlot, '\0', sizeof(*pSlot) ); sinfo[Index].present = (CK_BOOL) FALSE; continue; } /* ManufacturerID */ #pragma info(none) if ( ! BlankPadNoNull ( (char *) &(pSlot->manufacturerID[0]), &(p[i].ManufacturerID[0]), sizeof(pSlot->manufacturerID) ) ) { #pragma info(restore) DbgLog(DL0,"ReadSlotInfoDB: Error reading ManufacturerID '%s'. Skipping.", p[i].ManufacturerID); /* Null out the sinfo struct */ memset( pSlot, '\0', sizeof(*pSlot) ); sinfo[Index].present = (CK_BOOL) FALSE; continue; } /* TokenPresent */ if ( ! BooleanVal( &(p[i].TokenPresent[0]), sizeof(p[i].TokenPresent), &Res) ) { DbgLog(DL0,"ReadSlotInfoDB: BooleanVal() failed for TokenPresent.\n"); memset( pSlot, '\0', sizeof(*pSlot) ); sinfo[Index].present = (CK_BOOL) FALSE; continue; } if ( Res ) { pSlot->flags |= (CKF_TOKEN_PRESENT); } /* RemovableToken */ if ( ! BooleanVal( &(p[i].RemovableToken[0]), sizeof(p[i].RemovableToken), &Res) ) { DbgLog(DL0,"ReadSlotInfoDB: BooleanVal() failed for RemovableToken.\n"); memset( pSlot, '\0', sizeof(*pSlot) ); sinfo[Index].present = (CK_BOOL) FALSE; continue; } if ( Res ) { pSlot->flags |= (CKF_REMOVABLE_DEVICE); } /* HardwareSlot */ if ( ! BooleanVal( &(p[i].HardwareSlot[0]), sizeof(p[i].HardwareSlot), &Res) ) { DbgLog(DL0,"ReadSlotInfoDB: BooleanVal() failed for HardwareSlot.\n"); memset( pSlot, '\0', sizeof(*pSlot) ); sinfo[Index].present = (CK_BOOL) FALSE; continue; } if ( Res ) { pSlot->flags |= (CKF_HW_SLOT); } /* HardwareVersion */ pSlot->hardwareVersion.major = (CK_BYTE) p[i].HwVersionMajor; pSlot->hardwareVersion.minor = (CK_BYTE) p[i].HwVersionMinor; /* FirmwareVersion */ pSlot->firmwareVersion.major = (CK_BYTE) p[i].FwVersionMajor; pSlot->firmwareVersion.minor = (CK_BYTE) p[i].FwVersionMinor; /* DLLLocation */ { struct stat64 statbuf; int Err; strncpy ( &(sinfo[Index].dll_location[0]), p[i].SlotDll, ( (strlen(p[i].SlotDll) > sizeof(sinfo[Index].dll_location)) ? (sizeof(sinfo[Index].dll_location)) : (strlen(p[i].SlotDll) ) ) ); /* Set the last character in the array to NULL since strncpy may mor may not copy the trailing NULL */ sinfo[Index].dll_location[ sizeof(sinfo[Index].dll_location) - 1] = '\0'; if ( stat64( sinfo[Index].dll_location, &statbuf ) < 0 ) { /* File not found, or other error */ #pragma info(none) Err = errno; #pragma info(restore) if ( Err == ENOENT ) { WarnLog ( "***** ReadSlotInfoDB: %s: file not found (%s). Skipping DB entry.", sinfo[Index].dll_location, SysError(Err) ); } else { DbgLog (DL0, "***** ReadSlotInfoDB: looking at %s, stat64() returned %s (%d; %#x)", sinfo[Index].dll_location, SysError(Err), Err, Err); } memset( pSlot, '\0', sizeof(*pSlot) ); sinfo[Index].present = (CK_BOOL) FALSE; continue; } } /* end DLLLocation unconditional block */ /* SlotInitFcn */ /* FIXME: Make sure this is non-NULL */ strncpy( &(sinfo[Index].slot_init_fcn[0]), &(p[i].SlotInitFcn[0]), ( strlen(p[i].SlotInitFcn) > sizeof(sinfo[Index].slot_init_fcn) ) ? sizeof(sinfo[Index].slot_init_fcn) : strlen(p[i].SlotInitFcn) ); /* Set the last character in the array to NULL since strncpy may mor may not copy the trailing NULL */ sinfo[Index].slot_init_fcn[ sizeof(sinfo[Index].slot_init_fcn) - 1 ] = '\0'; /* Correlator */ /* FIXME: Make sure this is non-NULL */ strncpy( &(sinfo[Index].correlator[0]), &(p[i].Correlator[0]), ( strlen(p[i].Correlator) > sizeof(sinfo[Index].correlator) ) ? sizeof(sinfo[Index].correlator) : strlen(p[i].Correlator) ); /* Set the last character in the array to NULL since strncpy may mor may not copy the trailing NULL */ sinfo[Index].correlator[ sizeof(sinfo[Index].correlator) - 1 ] = '\0'; PrintSlotInfo( &(sinfo[Index]) ); Index++; } /* end for i */ NumberSlotsInDB = Index; if ( p != NULL ) { free(p); } /* Do we have a memory leak here? */ if ( odm_path != NULL ) { odm_set_path(odm_path); free (odm_path); } return TRUE; } opencryptoki-2.3.1+dfsg/usr/sbin/pkcsslotd/log.c0000751000175000017500000010342211327631345017447 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #include "pthread.h" #include "pkcsslotd.h" #define DEFAULT_PROGRAM_NAME "Program" #ifndef PROGRAM_NAME #define PROGRAM_NAME DEFAULT_PROGRAM_NAME #endif /* PROGRAM_NAME */ #ifdef DEV #ifndef DEFAULT_LOG_FILE #define DEFAULT_LOG_FILE "/tmp/" ## PROGRAM_NAME ## ".log" #endif /* DEFAULT_LOG_FILE */ #else /* production build */ #ifndef DEFAULT_LOG_FILE #define DEFAULT_LOG_FILE NULL #endif /* DEFAULT_LOG_FILE */ #endif /* DEV */ #ifndef LOG_FILE #define LOG_FILE DEFAULT_LOG_FILE #endif /* LOG_FILE */ #ifndef DEFAULT_DEBUG_LEVEL /********************* DEFAULT_DEBUG_LEVEL is generally defined in another file (pkcsslotd.h?) The #defines here generally won't change much. *********************/ #ifdef DEV #define DEFAULT_DEBUG_LEVEL DEBUG_LEVEL0 #else #define DEFAULT_DEBUG_LEVEL DEBUG_NONE #endif /* DEFAULT_DEBUG_LEVEL */ #endif /* DEFAULT_DEBUG_LEVEL */ static u_int32 DefaultLogOption = ( LOG_CONS | LOG_NOWAIT | LOG_ODELAY | LOG_PID ); static BOOL Initialized = FALSE; static BOOL LoggingInitialized = FALSE; static u_int32 SysDebugLevel = DEFAULT_DEBUG_LEVEL; static char *ProgramName = PROGRAM_NAME; static LoggingFacilityInfo LogInfo[MAX_LOGGING_FACILITIES]; static LogHandle hLogDebug; static LogHandle hLogErr; static LogHandle hLogLog; static LogHandle hLogTrace; static LogHandle hLogWarn; static LogHandle hLogInfo; static LoggingFacility SystemLogFacilities[] = { { " DEBUG", &hLogDebug, LOG_FILE, TRUE, LOG_DEBUG }, { " INFO", &hLogInfo, LOG_FILE, TRUE, LOG_INFO }, { " TRACE", &hLogTrace, LOG_FILE, TRUE, LOG_INFO }, { " LOG", &hLogLog, LOG_FILE, TRUE, LOG_NOTICE }, { "WARNING", &hLogWarn, LOG_FILE, TRUE, LOG_WARNING }, { " ERROR", &hLogErr, LOG_FILE, TRUE, LOG_ERR } }; /***************************************** * Function Prototypes * *****************************************/ static int InitDataStructs ( void ); static BOOL InitLogging ( void ); static pLoggingFacilityInfo GetLogInfoPtr ( LogHandle hLog ); static BOOL GetFreeLogInfo ( pLogHandle Dest ); static void CloseAllLoggingFacilities ( void ); static BOOL SetLogPriorityMask ( LogHandle hLog, u_int32 Priority ); static BOOL SyslogOpen ( pLoggingFacilityInfo pInfo ); /************************************************************* * GetCurrentTimeString - * * Writes the current date & time into *Buffer * *************************************************************/ BOOL GetCurrentTimeString ( char *Buffer ) { /* Note: The specs for ctime_r and asctime_r say that Buffer needs to be 26 characters long. Not sure if that includes a triling NULL - SCM */ time_t t; struct tm tm; ASSERT(Buffer != NULL); time(&t); localtime_r(&t, &tm); asctime_r( &tm , &(Buffer[0]) ); /* asctime_r puts a \n at the end, so we'll remove that */ Buffer[strlen(Buffer)-1] = '\0'; return TRUE; } /*********************************************************************** * InitDataStructs - * * Called durining initalization to set up the LogInfo array * ***********************************************************************/ static int InitDataStructs ( void ) { unsigned int i; for ( i = 0; i < (sizeof(LogInfo) / sizeof(LogInfo[0])); i++ ) { LogInfo[i].Initialized = FALSE; LogInfo[i].Descrip[0] = '\0'; LogInfo[i].LogOption = DefaultLogOption; } Initialized = TRUE; return TRUE; } /********************************************************************** * GetFreeLogInfo - * * Return the handle for the next available Log Facility structure * * After calling this function, the facility will be marked as in use * ***********************************************************************/ static BOOL GetFreeLogInfo ( pLogHandle Dest ) { u_int32 i; if ( ! Initialized ) { InitDataStructs(); } for ( i = 0; i < ( sizeof(LogInfo) / sizeof(LogInfo[0]) ); i++ ) { if ( LogInfo[i].Initialized == FALSE ) { /* Set this here so that we don't return the same identifier twice in the case where GetFreeLogInfo() is called twice in a row */ LogInfo[i].Initialized = TRUE; *Dest = i; return TRUE; } } #ifdef DEV fprintf(stderr, "No available thread logging structs.\n"); #endif return FALSE; } /********************************************************************** * GetLogInfoPtr - * * Given a handle, return a pointer to the appropriate LoggingFacilityInfo structure * ***********************************************************************/ static pLoggingFacilityInfo GetLogInfoPtr ( LogHandle hLog ) { if ( hLog >= (sizeof(LogInfo) / sizeof(LogInfo[0]) ) ) { #ifdef DEV fprintf(stderr, "Illegal LogHandle value: %#X\n", hLog); #endif return NULL; } if ( LogInfo[hLog].Initialized != TRUE ) { #ifdef DEV fprintf(stderr, "GetLogInfoPtr() called for a non-initialized handle\n"); #endif return NULL; } return &(LogInfo[hLog]); } /*********************************************************************** * NewLoggingFacility - * * Given an ID ( char string which will appear in the messages ), * open a logging facility and return a handle to it in * pLoggingStuff->phLog * ***********************************************************************/ BOOL NewLoggingFacility ( char *ID, pLoggingFacility pStuff ) { int LogFacility; pLoggingFacilityInfo pInfo = NULL; LogHandle hLog; pLogHandle Result; extern BOOL Daemon; /* We use Daemon here instead of IsDaemon because these facilities might get set up before we've actually daemonized */ if ( Daemon ) { LogFacility = LOG_DAEMON; } else { LogFacility = LOG_USER; } /* See if there's room in the array. This'd be nice if it were dynamically allocated */ if ( ! GetFreeLogInfo(&hLog) ) { return FALSE; } /* Get a pointer to the syslog_data structure */ if ( (pInfo = GetLogInfoPtr(hLog)) == NULL ) { return FALSE; } Result = pStuff->phLog; /* Set this before the filename is checked because we may want to use the descrip and/or filename in the logs */ pInfo->UseSyslog = pStuff->UseSyslog; pInfo->LogOption = DefaultLogOption; pInfo->pid = 0; pInfo->LogLevel = pStuff->LogLevel; sprintf( pInfo->Descrip, "%s %s", pStuff->Label, ID ); /* ensure that the last character is a NULL */ pInfo->Descrip[sizeof(pInfo->Descrip)-1] = '\0'; /* Some sanity checking on filename... */ if ( (pStuff->Filename != NULL) && (strlen(pStuff->Filename) > 0) ) { FILE *fd; #if TRUNCATE_LOGS_ON_START /* * Truncating files on the start will present problems if the user creates * their own logging facilities after the program's been running for a while * But the non-syslog logging is intended for debug purposes only, anyway. * */ char FileMode[] = "w"; #else char FileMode[] = "a"; #endif /* TRUNCATE_LOGS_ON_START */ if ( ( fd = fopen((pStuff->Filename), FileMode ) ) == NULL ) { #ifdef DEV fprintf(stderr, "%s could not be opened\n", pStuff->Filename); #endif pInfo->Filename = NULL; } else { /* Tag the file */ char buf[100]; GetCurrentTimeString( &(buf[0]) ); #ifdef DEV #if TRUNCATE_LOGS_ON_START /* buf contains the date stamp */ fprintf(fd, "********* %s %s truncated *********\n", buf, pStuff->Filename); #else fprintf(fd, "********* %s \"%s\" logging to %s *********\n", buf, pInfo->Descrip, pStuff->Filename); #endif /* TRUNCATE_LOGS_ON_START */ #endif fflush(fd); fclose(fd); pInfo->Filename = pStuff->Filename; } } else { pInfo->Filename = NULL; } if ( pInfo->UseSyslog ) { /* open the logging facility */ if (! SyslogOpen( pInfo ) ) { return FALSE; } } /* Redundant; Initialized is set to 1 in GetFreeLogInfo */ pInfo->Initialized = TRUE; *Result = hLog; return TRUE; } /*********************************************************************** * CloseLoggingFacility - * * Closes the logging facility whose handle is hLog. * Sets up the data structure for reuse later if desired * ***********************************************************************/ BOOL CloseLoggingFacility ( LogHandle hLog ) { pLoggingFacilityInfo pInfo = NULL; if ( (pInfo = GetLogInfoPtr(hLog)) == NULL ) { return FALSE; } pInfo->Descrip[0] = '\0'; pInfo->LogOption = 0; pInfo->Filename = NULL; pInfo->pid = 0; if ( pInfo->UseSyslog ) { closelog( ); } pInfo->Initialized = FALSE; return TRUE; } /***************************************** * CloseAllLoggingFacilities - * * Closes down all the logging stuff we've set up *****************************************/ static void CloseAllLoggingFacilities ( void ) { u_int32 i = 0; for ( i = 0; i < (sizeof(LogInfo) / sizeof(LogInfo[0])); i++ ) { /* Makes assumption that these handles all are sequential. Bad Style */ if ( LogInfo[i].Initialized ) { CloseLoggingFacility(i); } } return; } /*********************************************************************** * SetLogPriorityMask - * * Sets the log priority mask to exactly what is passed in as a parameter * This means that you should pass in LOG_UPTO(LOG_DEBUG) if that's what you mean * Passing in LOG_DEBUG will ONLY print debug messages * ***********************************************************************/ static BOOL SetLogPriorityMask ( LogHandle hLog, u_int32 Priority ) { pLoggingFacilityInfo pInfo = NULL; /* Get a pointer to the syslog_data structure */ if ( (pInfo = GetLogInfoPtr(hLog)) == NULL ) { return FALSE; } /* Make sure that they called NewLoggingFacility() for this handle */ if ( pInfo->Initialized != TRUE ) { return FALSE; } if ( ! pInfo->UseSyslog ) { #ifdef DEV fprintf(stderr, "SetLogPriorityMask: Tried to set the mask on a log handle that isn't using syslog\n"); #endif return FALSE; } else { setlogmask( Priority ); } return TRUE; } /*********************************************************************** * PKCS_Log - * * The primitive logging function which logs a message on hLog * ***********************************************************************/ BOOL PKCS_Log ( pLogHandle phLog, char *Format, va_list ap ) { char Buffer[PATH_MAX]; pLoggingFacilityInfo pInfo; if ( Format == NULL ) { return FALSE; } if ( (pInfo = GetLogInfoPtr(*phLog)) == NULL ) { return FALSE; } if ( (pInfo->pid != getpid() ) && (pInfo->UseSyslog) ) { /* Looks like our PID changed since the last call. We have to re-open */ if (! SyslogOpen(pInfo) ) { return FALSE; } } if ( vsprintf(&(Buffer[0]), Format, ap) < 0 ) { /* Error reporting functions should be rather robust, don't you think? */ /* vsprintf reporting an error */ //fprintf(stderr, "PKCS_ErrLog - vsprintf error for format string %s\n", Format); return FALSE; } /* Get rid of trailing newlines. */ while ( strlen(Buffer) && (Buffer[strlen(Buffer)-1] == '\n') ) { Buffer[strlen(Buffer)-1] = '\0'; } // Development work only. No loging to anything other than syslog for // production level code /* 1/17/00 SCM - If we're not a daemon, we need to print something to stderr for warnings and errors regardless of development/production. This is for errors that occur during startup. I'll agree that we don't need to write to a log file in production mode, however. */ /* Production mode: Write to stderr if we're not a daemon, and the priority of the message is at least LOG_WARNING Development mode: Write to stderr if we're not a daemon */ if ( ! IsDaemon() ) { BOOL WriteNow; #ifdef DEV WriteNow = TRUE; #else WriteNow = (pInfo->LogLevel <= LOG_WARNING); #endif /* DEV */ if ( WriteNow ) { fprintf(stderr, "%s[%d.%d]: %s\n", pInfo->Descrip, getpid(), (int)pthread_self(), Buffer); } } /* Don't log to a separate log file in production mode */ #ifdef DEV if ( pInfo->Filename != NULL ) { FILE *fd; if ( (fd = fopen ( pInfo->Filename, "a+" ) ) == NULL ) { fprintf(stderr, "PKCS_Log: fopen failed for %s\n", pInfo->Filename); } else { char buf[32]; /* Specs say 26-character array */ GetCurrentTimeString( &(buf[0]) ); /* Date/Time stamp, descrip, Error message */ fprintf ( fd, "%s %s[%d.%d]: ", buf, pInfo->Descrip, getpid(), pthread_self() ); fprintf ( fd, "%s\n", Buffer); fflush ( fd ); fclose ( fd ); } } /* end if pInfo->Filename */ #endif /* DEV */ /* Always log to syslog, if we're using it */ if ( pInfo->UseSyslog ) { syslog(pInfo->LogLevel, Buffer); } return TRUE; } /**************************************************************************** * * Would like to have a generic function to which I pass the hLog where I'd * like to do the logging and have a #defined macro which passes it along... * * But the preprocessor and variable # args don't work & play well together * ****************************************************************************/ /***************************************** * DbgLog - * * Log messages using the debug facility *****************************************/ void DbgLog ( u_int32 DebugLevel, char *Format, ... ) { va_list ap; if ( DebugLevel > SysDebugLevel ) { return; } if ( ! LoggingInitialized ) { InitLogging(); } va_start( ap, Format ); PKCS_Log( &hLogDebug, Format, ap); va_end ( ap ) ; return; } /***************************************** * ErrLog - * * Log Messges using the error facility *****************************************/ void ErrLog ( char *Format, ... ) { va_list ap; if ( ! LoggingInitialized ) { InitLogging(); } va_start( ap, Format ); PKCS_Log( &hLogErr, Format, ap); va_end ( ap ) ; return; } /***************************************** * LogLog - * * Log messages using the log facility *****************************************/ void LogLog ( char *Format, ... ) { va_list ap; if ( ! LoggingInitialized ) { InitLogging(); } va_start( ap, Format ); PKCS_Log( &hLogLog, Format, ap); va_end ( ap ) ; return; } /***************************************** * WarnLog - * * Log messages using the warning facility *****************************************/ void WarnLog ( char *Format, ... ) { va_list ap; if ( ! LoggingInitialized ) { InitLogging(); } va_start( ap, Format ); PKCS_Log( &hLogWarn, Format, ap); va_end ( ap ) ; return; } /***************************************** * TraceLog - * * Log messages using the trace facility *****************************************/ void TraceLog ( char *Format, ... ) { va_list ap; if ( ! LoggingInitialized ) { InitLogging(); } va_start( ap, Format ); PKCS_Log( &hLogTrace, Format, ap); va_end ( ap ) ; return; } /***************************************** * InfoLog - * * Log messages using the info facility *****************************************/ void InfoLog ( char *Format, ... ) { va_list ap; if ( ! LoggingInitialized ) { InitLogging(); } va_start( ap, Format ); PKCS_Log( &hLogInfo, Format, ap); va_end ( ap ) ; return; } /*********************************************************************** * InitLogging - * * Sets up the various logging facilities. Must be called before * any of the logging functions can be used. ***********************************************************************/ static BOOL InitLogging ( void ) { unsigned int i; char *s = ProgramName; /* if ProgramName is NULL, we'll just print the level... */ if ( ProgramName == NULL ) { s = ""; } /* Set up logging for all the facilities in SystemLogFacilities[] */ for ( i = 0; i < ( sizeof(SystemLogFacilities) / (sizeof(SystemLogFacilities[0])) ); i++ ) { if (! NewLoggingFacility(s, &(SystemLogFacilities[i]) ) ) { #ifdef DEV fprintf(stderr, "InitLogging: NewLoggingFacility failed: %s\n", s); #endif return FALSE; } } /* end for i */ atexit(CloseAllLoggingFacilities); LoggingInitialized = TRUE; return TRUE; } /************************************************************* * SetDebugLevel - * * * Sets the level at which debug messages get logged to Val. * Returns the old value *************************************************************/ u_int32 SetDebugLevel ( u_int32 Val ) { u_int32 OldVal = SysDebugLevel; SysDebugLevel = Val; return OldVal; } /************************************************************* * GetDebugLevel * * Returns the level at which the program will log debug messages * *************************************************************/ u_int32 GetDebugLevel ( void ) { return SysDebugLevel; } #if 0 int main ( int argc, char *argv[], char *envp[] ) { ErrLog("This is an error test, attempt 1"); DbgLog(DEBUG_LEVEL0, "This is a DEBUG test level 0, attempt 1"); DbgLog(DEBUG_LEVEL1, "This is a DEBUG test level 1, attempt 1"); SetDebugLevel(DEBUG_NONE); DbgLog(DEBUG_LEVEL1, "This is a DEBUG test level 1, attempt 2"); DbgLog(DEBUG_LEVEL0, "This is a DEBUG test level 0, attempt 2"); ErrLog("This is an error test, attempt 2"); return 0; } #endif /* 0 */ static BOOL SyslogOpen ( pLoggingFacilityInfo pInfo ) { extern BOOL Daemon; ASSERT(pInfo != NULL); if ( !( pInfo->UseSyslog ) ) { /* it's not really an error to call SyslogOpen for a facility that doesn't use it */ return TRUE; } if ( pInfo->pid != 0 ) { /* We've been initialized before, so close the previous instance */ closelog(); } /* Default to log all messages. This can be changed by a subsequent call to SetLogPriorityMask */ setlogmask( LOG_UPTO(LOG_DEBUG)); /* Mark this as having been set by this process */ pInfo->pid = getpid(); return TRUE; } opencryptoki-2.3.1+dfsg/usr/sbin/pkcsslotd/err.c0000751000175000017500000010433011327631345017455 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #include "pthread.h" #include "pkcsslotd.h" static ConstInfo SysErrorInfo[] = { CONSTINFO(EPERM), CONSTINFO(ENOENT), CONSTINFO(ESRCH), CONSTINFO(EINTR), CONSTINFO(EIO), CONSTINFO(ENXIO), CONSTINFO(E2BIG), CONSTINFO(ENOEXEC), CONSTINFO(EBADF), CONSTINFO(ECHILD), CONSTINFO(EAGAIN), CONSTINFO(ENOMEM), CONSTINFO(EACCES), CONSTINFO(EFAULT), CONSTINFO(ENOTBLK), CONSTINFO(EBUSY), CONSTINFO(EEXIST), CONSTINFO(EXDEV), CONSTINFO(ENODEV), CONSTINFO(ENOTDIR), CONSTINFO(EISDIR), CONSTINFO(EINVAL), CONSTINFO(ENFILE), CONSTINFO(EMFILE), CONSTINFO(ENOTTY), CONSTINFO(ETXTBSY), CONSTINFO(EFBIG), CONSTINFO(ENOSPC), CONSTINFO(ESPIPE), CONSTINFO(EROFS), CONSTINFO(EMLINK), CONSTINFO(EPIPE), CONSTINFO(EDOM), CONSTINFO(ERANGE), CONSTINFO(ENOMSG), CONSTINFO(EIDRM), CONSTINFO(ECHRNG), CONSTINFO(EL2NSYNC), CONSTINFO(EL3HLT), CONSTINFO(EL3RST), CONSTINFO(ELNRNG), CONSTINFO(EUNATCH), CONSTINFO(ENOCSI), CONSTINFO(EL2HLT), CONSTINFO(EDEADLK), CONSTINFO(ESTALE), CONSTINFO(EWOULDBLOCK), CONSTINFO(EINPROGRESS), CONSTINFO(EALREADY), CONSTINFO(ENOTSOCK), CONSTINFO(EDESTADDRREQ), CONSTINFO(EMSGSIZE), CONSTINFO(EPROTOTYPE), CONSTINFO(ENOPROTOOPT), CONSTINFO(EPROTONOSUPPORT), CONSTINFO(ESOCKTNOSUPPORT), CONSTINFO(EOPNOTSUPP), CONSTINFO(EPFNOSUPPORT), CONSTINFO(EAFNOSUPPORT), CONSTINFO(EADDRINUSE), CONSTINFO(EADDRNOTAVAIL), CONSTINFO(ENETDOWN), CONSTINFO(ENETUNREACH), CONSTINFO(ENETRESET), CONSTINFO(ECONNABORTED), CONSTINFO(ECONNRESET), CONSTINFO(ENOBUFS), CONSTINFO(EISCONN), CONSTINFO(ENOTCONN), CONSTINFO(ESHUTDOWN), CONSTINFO(ETIMEDOUT), CONSTINFO(ECONNREFUSED), CONSTINFO(EHOSTDOWN), CONSTINFO(EHOSTUNREACH), CONSTINFO(ERESTART), CONSTINFO(EUSERS), CONSTINFO(ELOOP), CONSTINFO(ENAMETOOLONG), CONSTINFO(ENOTEMPTY), CONSTINFO(EDQUOT), CONSTINFO(EREMOTE), CONSTINFO(ENOSYS), CONSTINFO(ETOOMANYREFS), CONSTINFO(EILSEQ), CONSTINFO(ECANCELED), CONSTINFO(ENOSR), CONSTINFO(ETIME), CONSTINFO(EBADMSG), CONSTINFO(EPROTO), CONSTINFO(ENODATA), CONSTINFO(ENOSTR), CONSTINFO(ENOTSUP), CONSTINFO(EMULTIHOP), CONSTINFO(ENOLINK), CONSTINFO(EOVERFLOW), }; static int SysErrorSize = ( sizeof(SysErrorInfo) / sizeof(SysErrorInfo[0])); static ConstInfo SignalInfo[] = { CONSTINFO(SIGHUP), CONSTINFO(SIGINT), CONSTINFO(SIGQUIT), CONSTINFO(SIGILL), CONSTINFO(SIGTRAP), CONSTINFO(SIGABRT), CONSTINFO(SIGFPE), CONSTINFO(SIGKILL), CONSTINFO(SIGBUS), CONSTINFO(SIGSEGV), CONSTINFO(SIGSYS), CONSTINFO(SIGPIPE), CONSTINFO(SIGALRM), CONSTINFO(SIGTERM), CONSTINFO(SIGURG), CONSTINFO(SIGSTOP), CONSTINFO(SIGTSTP), CONSTINFO(SIGCONT), CONSTINFO(SIGCHLD), CONSTINFO(SIGTTIN), CONSTINFO(SIGTTOU), CONSTINFO(SIGIO), CONSTINFO(SIGXCPU), CONSTINFO(SIGXFSZ), CONSTINFO(SIGWINCH), CONSTINFO(SIGPWR), CONSTINFO(SIGUSR1), CONSTINFO(SIGUSR2), CONSTINFO(SIGPROF), CONSTINFO(SIGVTALRM), CONSTINFO(SIGIOT), CONSTINFO(SIGCLD), CONSTINFO(SIGPOLL), #if 0 CONSTINFO(SIG_DFL), CONSTINFO(SIG_IGN), CONSTINFO(SIG_HOLD), CONSTINFO(SIG_CATCH), CONSTINFO(SIG_ERR), #endif /* 0 */ }; static int SignalInfoSize = (sizeof(SignalInfo) / sizeof(SignalInfo[0])); #ifndef NODAE static ConstInfo DAEError[] = { CONSTINFO(DAE_E_OK), CONSTINFO(DAE_E_NOTAGAIN), CONSTINFO(DAE_E_PINVALID), CONSTINFO(DAE_E_PWRONG), CONSTINFO(DAE_E_PERROR), CONSTINFO(DAE_E_CHILD), CONSTINFO(DAE_E_SESSION), CONSTINFO(DAE_E_SIGNAL), CONSTINFO(DAE_E_CLOSE), CONSTINFO(DAE_E_DEVNULL), CONSTINFO(DAE_E_CHDIR), CONSTINFO(DAE_E_SRCPREP), CONSTINFO(DAE_E_NOPSALLOC), CONSTINFO(DAE_E_AINVALID), CONSTINFO(DAE_E_SETPSALLOC), CONSTINFO(DAE_E_EXCLINVALID), CONSTINFO(DAE_E_EXCLERROR), CONSTINFO(DAE_E_EXCLBUSY), }; static int DAEErrorSize = (sizeof(DAEError) / sizeof(DAEError[0])); #endif #ifndef NOODM static ConstInfo ODMError[] = { CONSTINFO(ODMI_OPEN_ERR), CONSTINFO(ODMI_MALLOC_ERR), CONSTINFO(ODMI_MAGICNO_ERR), CONSTINFO(ODMI_NO_OBJECT), CONSTINFO(ODMI_BAD_CRIT), CONSTINFO(ODMI_INTERNAL_ERR), CONSTINFO(ODMI_TOOMANYCLASSES), CONSTINFO(ODMI_LINK_NOT_FOUND), CONSTINFO(ODMI_INVALID_CLASS), CONSTINFO(ODMI_CLASS_EXISTS), CONSTINFO(ODMI_CLASS_DNE), CONSTINFO(ODMI_BAD_CLASSNAME), CONSTINFO(ODMI_UNLINKCLASS_ERR), CONSTINFO(ODMI_UNLINKCLXN_ERR), CONSTINFO(ODMI_INVALID_CLXN), CONSTINFO(ODMI_CLXNMAGICNO_ERR), CONSTINFO(ODMI_BAD_CLXNNAME), CONSTINFO(ODMI_CLASS_PERMS), CONSTINFO(ODMI_BAD_TIMEOUT), CONSTINFO(ODMI_BAD_TOKEN), CONSTINFO(ODMI_LOCK_BLOCKED), CONSTINFO(ODMI_LOCK_ENV), CONSTINFO(ODMI_UNLOCK), CONSTINFO(ODMI_BAD_LOCK), CONSTINFO(ODMI_LOCK_ID), CONSTINFO(ODMI_PARAMS), CONSTINFO(ODMI_OPEN_PIPE), CONSTINFO(ODMI_READ_PIPE), CONSTINFO(ODMI_FORK), CONSTINFO(ODMI_INVALID_PATH), CONSTINFO(ODMI_READ_ONLY), CONSTINFO(ODMI_NO_SPACE), CONSTINFO(VCHAR_OPEN_ERR), CONSTINFO(VCHAR_MAGICNO_ERR), CONSTINFO(VCHAR_CLASS_DNE), CONSTINFO(VCHAR_BADSTRINGADDR), CONSTINFO(VCHAR_CLASS_PERMS) }; static int ODMErrorSize = (sizeof(ODMError) / sizeof(ODMError[0])); #endif static ConstInfo PkcsReturnInfo[] = { CONSTINFO(CKR_OK), CONSTINFO(CKR_CANCEL), CONSTINFO(CKR_HOST_MEMORY), CONSTINFO(CKR_SLOT_ID_INVALID), CONSTINFO(CKR_GENERAL_ERROR), CONSTINFO(CKR_FUNCTION_FAILED), CONSTINFO(CKR_ARGUMENTS_BAD), CONSTINFO(CKR_NO_EVENT), CONSTINFO(CKR_NEED_TO_CREATE_THREADS), CONSTINFO(CKR_CANT_LOCK), CONSTINFO(CKR_ATTRIBUTE_READ_ONLY), CONSTINFO(CKR_ATTRIBUTE_SENSITIVE), CONSTINFO(CKR_ATTRIBUTE_TYPE_INVALID), CONSTINFO(CKR_ATTRIBUTE_VALUE_INVALID), CONSTINFO(CKR_DATA_INVALID), CONSTINFO(CKR_DATA_LEN_RANGE), CONSTINFO(CKR_DEVICE_ERROR), CONSTINFO(CKR_DEVICE_MEMORY), CONSTINFO(CKR_DEVICE_REMOVED), CONSTINFO(CKR_ENCRYPTED_DATA_INVALID), CONSTINFO(CKR_ENCRYPTED_DATA_LEN_RANGE), CONSTINFO(CKR_FUNCTION_CANCELED), CONSTINFO(CKR_FUNCTION_NOT_PARALLEL), CONSTINFO(CKR_FUNCTION_NOT_SUPPORTED), CONSTINFO(CKR_KEY_HANDLE_INVALID), CONSTINFO(CKR_KEY_SIZE_RANGE), CONSTINFO(CKR_KEY_TYPE_INCONSISTENT), CONSTINFO(CKR_KEY_NOT_NEEDED), CONSTINFO(CKR_KEY_CHANGED), CONSTINFO(CKR_KEY_NEEDED), CONSTINFO(CKR_KEY_INDIGESTIBLE), CONSTINFO(CKR_KEY_FUNCTION_NOT_PERMITTED), CONSTINFO(CKR_KEY_NOT_WRAPPABLE), CONSTINFO(CKR_KEY_UNEXTRACTABLE), CONSTINFO(CKR_MECHANISM_INVALID), CONSTINFO(CKR_MECHANISM_PARAM_INVALID), CONSTINFO(CKR_OBJECT_HANDLE_INVALID), CONSTINFO(CKR_OPERATION_ACTIVE), CONSTINFO(CKR_OPERATION_NOT_INITIALIZED), CONSTINFO(CKR_PIN_INCORRECT), CONSTINFO(CKR_PIN_INVALID), CONSTINFO(CKR_PIN_LEN_RANGE), CONSTINFO(CKR_PIN_EXPIRED), CONSTINFO(CKR_PIN_LOCKED), CONSTINFO(CKR_SESSION_CLOSED), CONSTINFO(CKR_SESSION_COUNT), CONSTINFO(CKR_SESSION_HANDLE_INVALID), CONSTINFO(CKR_SESSION_PARALLEL_NOT_SUPPORTED), CONSTINFO(CKR_SESSION_READ_ONLY), CONSTINFO(CKR_SESSION_EXISTS), CONSTINFO(CKR_SESSION_READ_ONLY_EXISTS), CONSTINFO(CKR_SESSION_READ_WRITE_SO_EXISTS), CONSTINFO(CKR_SIGNATURE_INVALID), CONSTINFO(CKR_SIGNATURE_LEN_RANGE), CONSTINFO(CKR_TEMPLATE_INCOMPLETE), CONSTINFO(CKR_TEMPLATE_INCONSISTENT), CONSTINFO(CKR_TOKEN_NOT_PRESENT), CONSTINFO(CKR_TOKEN_NOT_RECOGNIZED), CONSTINFO(CKR_TOKEN_WRITE_PROTECTED), CONSTINFO(CKR_UNWRAPPING_KEY_HANDLE_INVALID), CONSTINFO(CKR_UNWRAPPING_KEY_SIZE_RANGE), CONSTINFO(CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT), CONSTINFO(CKR_USER_ALREADY_LOGGED_IN), CONSTINFO(CKR_USER_NOT_LOGGED_IN), CONSTINFO(CKR_USER_PIN_NOT_INITIALIZED), CONSTINFO(CKR_USER_TYPE_INVALID), CONSTINFO(CKR_USER_ANOTHER_ALREADY_LOGGED_IN), CONSTINFO(CKR_USER_TOO_MANY_TYPES), CONSTINFO(CKR_WRAPPED_KEY_INVALID), CONSTINFO(CKR_WRAPPED_KEY_LEN_RANGE), CONSTINFO(CKR_WRAPPING_KEY_HANDLE_INVALID), CONSTINFO(CKR_WRAPPING_KEY_SIZE_RANGE), CONSTINFO(CKR_WRAPPING_KEY_TYPE_INCONSISTENT), CONSTINFO(CKR_RANDOM_SEED_NOT_SUPPORTED), CONSTINFO(CKR_RANDOM_NO_RNG), CONSTINFO(CKR_BUFFER_TOO_SMALL), CONSTINFO(CKR_SAVED_STATE_INVALID), CONSTINFO(CKR_INFORMATION_SENSITIVE), CONSTINFO(CKR_STATE_UNSAVEABLE), CONSTINFO(CKR_CRYPTOKI_NOT_INITIALIZED), CONSTINFO(CKR_CRYPTOKI_ALREADY_INITIALIZED), CONSTINFO(CKR_MUTEX_BAD), CONSTINFO(CKR_MUTEX_NOT_LOCKED), CONSTINFO(CKR_VENDOR_DEFINED), }; static int PkcsReturnSize = ( sizeof(PkcsReturnInfo) / sizeof(PkcsReturnInfo[0]) ); static ConstInfo PkcsFlagsInfo[] = { CONSTINFO( ( CKF_RNG | CKF_HW | CKF_LIBRARY_CANT_CREATE_OS_THREADS | CKF_TOKEN_PRESENT )), CONSTINFO( ( CKF_REMOVABLE_DEVICE | CKF_OS_LOCKING_OK | CKF_RW_SESSION | CKF_WRITE_PROTECTED )), CONSTINFO( ( CKF_SERIAL_SESSION | CKF_HW_SLOT | CKF_LOGIN_REQUIRED )), CONSTINFO( CKF_USER_PIN_INITIALIZED ), CONSTINFO( CKF_RESTORE_KEY_NOT_NEEDED ), CONSTINFO( CKF_CLOCK_ON_TOKEN), CONSTINFO( ( CKF_PROTECTED_AUTHENTICATION_PATH | CKF_ENCRYPT )), CONSTINFO( ( CKF_DUAL_CRYPTO_OPERATIONS | CKF_DECRYPT )), CONSTINFO(CKF_DIGEST), CONSTINFO(CKF_SIGN), CONSTINFO(CKF_SIGN_RECOVER), CONSTINFO(CKF_VERIFY), CONSTINFO(CKF_VERIFY_RECOVER), CONSTINFO(CKF_GENERATE), CONSTINFO( ( CKF_GENERATE_KEY_PAIR | CKF_USER_PIN_COUNT_LOW )), CONSTINFO( ( CKF_USER_PIN_FINAL_TRY| CKF_WRAP )), CONSTINFO( ( CKF_UNWRAP | CKF_USER_PIN_LOCKED )), CONSTINFO( ( CKF_DERIVE /*| CKF_USER_PIN_MANUFACT_VALUE*/ )), CONSTINFO(CKF_SO_PIN_DERIVED), CONSTINFO(CKF_SO_CARD), CONSTINFO(CKF_SO_PIN_COUNT_LOW), CONSTINFO(CKF_SO_PIN_FINAL_TRY), CONSTINFO(CKF_SO_PIN_LOCKED), /*CONSTINFO(CKF_SO_PIN_MANUFACT_VALUE),*/ CONSTINFO(CKF_EXTENSION), }; static int PkcsFlagsSize = ( sizeof(PkcsFlagsInfo) / sizeof(PkcsFlagsInfo[0])); static ConstInfo PkcsMechanismInfo[] = { CONSTINFO(CKM_RSA_PKCS_KEY_PAIR_GEN), CONSTINFO(CKM_RSA_PKCS), CONSTINFO(CKM_RSA_9796), CONSTINFO(CKM_RSA_X_509), CONSTINFO(CKM_MD2_RSA_PKCS), CONSTINFO(CKM_MD5_RSA_PKCS), CONSTINFO(CKM_SHA1_RSA_PKCS), CONSTINFO(CKM_DSA_KEY_PAIR_GEN), CONSTINFO(CKM_DSA), CONSTINFO(CKM_DSA_SHA1), CONSTINFO(CKM_DH_PKCS_KEY_PAIR_GEN), CONSTINFO(CKM_DH_PKCS_DERIVE), CONSTINFO(CKM_RC2_KEY_GEN), CONSTINFO(CKM_RC2_ECB), CONSTINFO(CKM_RC2_CBC), CONSTINFO(CKM_RC2_MAC), CONSTINFO(CKM_RC2_MAC_GENERAL), CONSTINFO(CKM_RC2_CBC_PAD), CONSTINFO(CKM_RC4_KEY_GEN), CONSTINFO(CKM_RC4), CONSTINFO(CKM_DES_KEY_GEN), CONSTINFO(CKM_DES_ECB), CONSTINFO(CKM_DES_CBC), CONSTINFO(CKM_DES_MAC), CONSTINFO(CKM_DES_MAC_GENERAL), CONSTINFO(CKM_DES_CBC_PAD), CONSTINFO(CKM_DES2_KEY_GEN), CONSTINFO(CKM_DES3_KEY_GEN), CONSTINFO(CKM_DES3_ECB), CONSTINFO(CKM_DES3_CBC), CONSTINFO(CKM_DES3_MAC), CONSTINFO(CKM_DES3_MAC_GENERAL), CONSTINFO(CKM_DES3_CBC_PAD), CONSTINFO(CKM_CDMF_KEY_GEN), CONSTINFO(CKM_CDMF_ECB), CONSTINFO(CKM_CDMF_CBC), CONSTINFO(CKM_CDMF_MAC), CONSTINFO(CKM_CDMF_MAC_GENERAL), CONSTINFO(CKM_CDMF_CBC_PAD), CONSTINFO(CKM_MD2), CONSTINFO(CKM_MD2_HMAC), CONSTINFO(CKM_MD2_HMAC_GENERAL), CONSTINFO(CKM_MD5), CONSTINFO(CKM_MD5_HMAC), CONSTINFO(CKM_MD5_HMAC_GENERAL), CONSTINFO(CKM_SHA_1), CONSTINFO(CKM_SHA_1_HMAC), CONSTINFO(CKM_SHA_1_HMAC_GENERAL), CONSTINFO(CKM_CAST_KEY_GEN), CONSTINFO(CKM_CAST_ECB), CONSTINFO(CKM_CAST_CBC), CONSTINFO(CKM_CAST_MAC), CONSTINFO(CKM_CAST_MAC_GENERAL), CONSTINFO(CKM_CAST_CBC_PAD), CONSTINFO(CKM_CAST3_KEY_GEN), CONSTINFO(CKM_CAST3_ECB), CONSTINFO(CKM_CAST3_CBC), CONSTINFO(CKM_CAST3_MAC), CONSTINFO(CKM_CAST3_MAC_GENERAL), CONSTINFO(CKM_CAST3_CBC_PAD), CONSTINFO(CKM_CAST5_KEY_GEN), CONSTINFO(CKM_CAST128_KEY_GEN), CONSTINFO(CKM_CAST5_ECB), CONSTINFO(CKM_CAST128_ECB), CONSTINFO(CKM_CAST5_CBC), CONSTINFO(CKM_CAST128_CBC), CONSTINFO(CKM_CAST5_MAC), CONSTINFO(CKM_CAST128_MAC), CONSTINFO(CKM_CAST5_MAC_GENERAL), CONSTINFO(CKM_CAST128_MAC_GENERAL), CONSTINFO(CKM_CAST5_CBC_PAD), CONSTINFO(CKM_CAST128_CBC_PAD), CONSTINFO(CKM_RC5_KEY_GEN), CONSTINFO(CKM_RC5_ECB), CONSTINFO(CKM_RC5_CBC), CONSTINFO(CKM_RC5_MAC), CONSTINFO(CKM_RC5_MAC_GENERAL), CONSTINFO(CKM_RC5_CBC_PAD), CONSTINFO(CKM_IDEA_KEY_GEN), CONSTINFO(CKM_IDEA_ECB), CONSTINFO(CKM_IDEA_CBC), CONSTINFO(CKM_IDEA_MAC), CONSTINFO(CKM_IDEA_MAC_GENERAL), CONSTINFO(CKM_IDEA_CBC_PAD), CONSTINFO(CKM_GENERIC_SECRET_KEY_GEN), CONSTINFO(CKM_CONCATENATE_BASE_AND_KEY), CONSTINFO(CKM_CONCATENATE_BASE_AND_DATA), CONSTINFO(CKM_CONCATENATE_DATA_AND_BASE), CONSTINFO(CKM_XOR_BASE_AND_DATA), CONSTINFO(CKM_EXTRACT_KEY_FROM_KEY), CONSTINFO(CKM_SSL3_PRE_MASTER_KEY_GEN), CONSTINFO(CKM_SSL3_MASTER_KEY_DERIVE), CONSTINFO(CKM_SSL3_KEY_AND_MAC_DERIVE), CONSTINFO(CKM_SSL3_MD5_MAC), CONSTINFO(CKM_SSL3_SHA1_MAC), CONSTINFO(CKM_MD5_KEY_DERIVATION), CONSTINFO(CKM_MD2_KEY_DERIVATION), CONSTINFO(CKM_SHA1_KEY_DERIVATION), CONSTINFO(CKM_PBE_MD2_DES_CBC), CONSTINFO(CKM_PBE_MD5_DES_CBC), CONSTINFO(CKM_PBE_MD5_CAST_CBC), CONSTINFO(CKM_PBE_MD5_CAST3_CBC), CONSTINFO(CKM_PBE_MD5_CAST5_CBC), CONSTINFO(CKM_PBE_MD5_CAST128_CBC), CONSTINFO(CKM_PBE_SHA1_CAST5_CBC), CONSTINFO(CKM_PBE_SHA1_CAST128_CBC), CONSTINFO(CKM_PBE_SHA1_RC4_128), CONSTINFO(CKM_PBE_SHA1_RC4_40), CONSTINFO(CKM_PBE_SHA1_DES3_EDE_CBC), CONSTINFO(CKM_PBE_SHA1_DES2_EDE_CBC), CONSTINFO(CKM_PBE_SHA1_RC2_128_CBC), CONSTINFO(CKM_PBE_SHA1_RC2_40_CBC), CONSTINFO(CKM_PBA_SHA1_WITH_SHA1_HMAC), CONSTINFO(CKM_KEY_WRAP_LYNKS), CONSTINFO(CKM_KEY_WRAP_SET_OAEP), CONSTINFO(CKM_SKIPJACK_KEY_GEN), CONSTINFO(CKM_SKIPJACK_ECB64), CONSTINFO(CKM_SKIPJACK_CBC64), CONSTINFO(CKM_SKIPJACK_OFB64), CONSTINFO(CKM_SKIPJACK_CFB64), CONSTINFO(CKM_SKIPJACK_CFB32), CONSTINFO(CKM_SKIPJACK_CFB16), CONSTINFO(CKM_SKIPJACK_CFB8), CONSTINFO(CKM_SKIPJACK_WRAP), CONSTINFO(CKM_SKIPJACK_PRIVATE_WRAP), CONSTINFO(CKM_SKIPJACK_RELAYX), CONSTINFO(CKM_KEA_KEY_PAIR_GEN), CONSTINFO(CKM_KEA_KEY_DERIVE), CONSTINFO(CKM_FORTEZZA_TIMESTAMP), CONSTINFO(CKM_BATON_KEY_GEN), CONSTINFO(CKM_BATON_ECB128), CONSTINFO(CKM_BATON_ECB96), CONSTINFO(CKM_BATON_CBC128), CONSTINFO(CKM_BATON_COUNTER), CONSTINFO(CKM_BATON_SHUFFLE), CONSTINFO(CKM_BATON_WRAP), CONSTINFO(CKM_ECDSA_KEY_PAIR_GEN), CONSTINFO(CKM_ECDSA), CONSTINFO(CKM_ECDSA_SHA1), CONSTINFO(CKM_JUNIPER_KEY_GEN), CONSTINFO(CKM_JUNIPER_ECB128), CONSTINFO(CKM_JUNIPER_CBC128), CONSTINFO(CKM_JUNIPER_COUNTER), CONSTINFO(CKM_JUNIPER_SHUFFLE), CONSTINFO(CKM_JUNIPER_WRAP), CONSTINFO(CKM_FASTHASH), CONSTINFO(CKM_VENDOR_DEFINED), }; static unsigned int PkcsMechanismSize = (sizeof(PkcsMechanismInfo) / sizeof(PkcsMechanismInfo[0])); static ConstInfo PkcsObjectInfo[] = { CONSTINFO(CKO_DATA), CONSTINFO(CKO_CERTIFICATE), CONSTINFO(CKO_PUBLIC_KEY), CONSTINFO(CKO_PRIVATE_KEY), CONSTINFO(CKO_SECRET_KEY), CONSTINFO(CKO_VENDOR_DEFINED), }; static unsigned int PkcsObjectSize = (sizeof(PkcsObjectInfo) / sizeof(PkcsObjectInfo[0])); static ConstInfo PkcsKeyInfo[] = { CONSTINFO(CKK_RSA), CONSTINFO(CKK_DSA), CONSTINFO(CKK_DH), CONSTINFO(CKK_ECDSA), CONSTINFO(CKK_KEA), CONSTINFO(CKK_GENERIC_SECRET), CONSTINFO(CKK_RC2), CONSTINFO(CKK_RC4), CONSTINFO(CKK_DES), CONSTINFO(CKK_DES2), CONSTINFO(CKK_DES3), CONSTINFO(CKK_CAST), CONSTINFO(CKK_CAST3), CONSTINFO( (CKK_CAST5 | CKK_CAST128 )), CONSTINFO(CKK_RC5), CONSTINFO(CKK_IDEA), CONSTINFO(CKK_SKIPJACK), CONSTINFO(CKK_BATON), CONSTINFO(CKK_JUNIPER), CONSTINFO(CKK_CDMF), CONSTINFO(CKK_VENDOR_DEFINED), }; static unsigned int PkcsKeySize = ( sizeof(PkcsKeyInfo) / sizeof(PkcsKeyInfo[0]) ); static ConstInfo PkcsAttributeInfo[] = { CONSTINFO(CKA_CLASS), CONSTINFO(CKA_TOKEN), CONSTINFO(CKA_PRIVATE), CONSTINFO(CKA_LABEL), CONSTINFO(CKA_APPLICATION), CONSTINFO(CKA_VALUE), CONSTINFO(CKA_CERTIFICATE_TYPE), CONSTINFO(CKA_ISSUER), CONSTINFO(CKA_SERIAL_NUMBER), CONSTINFO(CKA_KEY_TYPE), CONSTINFO(CKA_SUBJECT), CONSTINFO(CKA_ID), CONSTINFO(CKA_SENSITIVE), CONSTINFO(CKA_ENCRYPT), CONSTINFO(CKA_DECRYPT), CONSTINFO(CKA_WRAP), CONSTINFO(CKA_UNWRAP), CONSTINFO(CKA_SIGN), CONSTINFO(CKA_SIGN_RECOVER), CONSTINFO(CKA_VERIFY), CONSTINFO(CKA_VERIFY_RECOVER), CONSTINFO(CKA_DERIVE), CONSTINFO(CKA_START_DATE), CONSTINFO(CKA_END_DATE), CONSTINFO(CKA_MODULUS), CONSTINFO(CKA_MODULUS_BITS), CONSTINFO(CKA_PUBLIC_EXPONENT), CONSTINFO(CKA_PRIVATE_EXPONENT), CONSTINFO(CKA_PRIME_1), CONSTINFO(CKA_PRIME_2), CONSTINFO(CKA_EXPONENT_1), CONSTINFO(CKA_EXPONENT_2), CONSTINFO(CKA_COEFFICIENT), CONSTINFO(CKA_PRIME), CONSTINFO(CKA_SUBPRIME), CONSTINFO(CKA_BASE), CONSTINFO(CKA_VALUE_BITS), CONSTINFO(CKA_VALUE_LEN), CONSTINFO(CKA_EXTRACTABLE), CONSTINFO(CKA_LOCAL), CONSTINFO(CKA_NEVER_EXTRACTABLE), CONSTINFO(CKA_ALWAYS_SENSITIVE), CONSTINFO(CKA_MODIFIABLE), CONSTINFO(CKA_ECDSA_PARAMS), CONSTINFO(CKA_EC_POINT), CONSTINFO(CKA_VENDOR_DEFINED), }; static unsigned int PkcsAttributeSize = ( sizeof(PkcsAttributeInfo) / sizeof(PkcsAttributeInfo[0]) ); #if 0 static ConstInfo PkcsSessionStateInfo[] = { CONSTINFO(CKS_RO_PUBLIC_SESSION), CONSTINFO(CKS_RO_USER_FUNCTIONS), CONSTINFO(CKS_RW_PUBLIC_SESSION), CONSTINFO(CKS_RW_USER_FUNCTIONS), CONSTINFO(CKS_RW_SO_FUNCTIONS), }; #endif static ConstInfo PkcsResponseSeverityInfo[] = { { SEV_EXPECTED, "expected" }, { SEV_ALLOWED, "allowed" }, { SEV_ERROR, "an error" }, { SEV_FATAL, "fatal" }, }; static unsigned int PkcsResponseSeveritySize = ( sizeof(PkcsResponseSeverityInfo) / sizeof(PkcsResponseSeverityInfo[0]) ); const unsigned char *ConstName( pConstInfo pInfoArray, unsigned int InfoArraySize, unsigned int ConstValue ) { unsigned int i; unsigned const char *retval = NULL; for ( i = 0; i < InfoArraySize; i++ ) { if ( pInfoArray[i].Code == ConstValue ) { retval = &(pInfoArray[i].Name[0]); break; } /* end if */ } /* end for i */ if ( retval == NULL ) { if ( ConstValue == 0 ) { retval = (const unsigned char *) "NULL"; } else { retval = (const unsigned char *) "\"<*>CONSTANT NOT FOUND<*>\""; } } return retval; } #ifndef NODAE const unsigned char *DAEConst( unsigned int Val ) { return ConstName( DAEError, DAEErrorSize, Val); } #endif const unsigned char *SignalConst ( unsigned int Val ) { return ConstName ( SignalInfo, SignalInfoSize, Val ); } #ifndef NOODM const unsigned char *ODMConst( unsigned int Val ) { return ConstName( ODMError, ODMErrorSize, Val); } #endif const unsigned char *SysConst ( unsigned int Val ) { return ConstName ( SysErrorInfo, SysErrorSize, Val ); } const unsigned char *PkcsReturn ( unsigned int Val ) { return ConstName( PkcsReturnInfo, PkcsReturnSize, Val ); } const unsigned char *PkcsFlags ( unsigned int Val ) { return ConstName( PkcsFlagsInfo, PkcsFlagsSize, Val ); } const unsigned char *PkcsMechanism ( unsigned int Val) { return ConstName(PkcsMechanismInfo, PkcsMechanismSize, Val); } const unsigned char *PkcsObject ( unsigned int Val ) { return ConstName ( PkcsObjectInfo, PkcsObjectSize, Val ); } const unsigned char *PkcsKey ( unsigned int Val ) { return ConstName( PkcsKeyInfo, PkcsKeySize, Val); } const unsigned char *PkcsAttribute ( unsigned int Val ) { return ConstName ( PkcsAttributeInfo, PkcsAttributeSize, Val); } const unsigned char *ResponseSeverity( unsigned int Val ) { return ConstName ( PkcsResponseSeverityInfo, PkcsResponseSeveritySize, Val); } opencryptoki-2.3.1+dfsg/usr/sbin/pkcsslotd/SlotDB.cre0000751000175000017500000003706211327631345020352 0ustar jfjf # # Common Public License Version 0.5 # THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF # THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, # REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES # RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. # # 1. DEFINITIONS # # "Contribution" means: # a) in the case of the initial Contributor, the # initial code and documentation distributed under # this Agreement, and # # b) in the case of each subsequent Contributor: # i) changes to the Program, and # ii) additions to the Program; # # where such changes and/or additions to the Program # originate from and are distributed by that # particular Contributor. A Contribution 'originates' # from a Contributor if it was added to the Program # by such Contributor itself or anyone acting on such # Contributor's behalf. Contributions do not include # additions to the Program which: (i) are separate # modules of software distributed in conjunction with # the Program under their own license agreement, and # (ii) are not derivative works of the Program. # # # "Contributor" means any person or entity that distributes # the Program. # # "Licensed Patents " mean patent claims licensable by a # Contributor which are necessarily infringed by the use or # sale of its Contribution alone or when combined with the # Program. # # "Program" means the Contributions distributed in # accordance with this Agreement. # # "Recipient" means anyone who receives the Program under # this Agreement, including all Contributors. # # 2. GRANT OF RIGHTS # # a) Subject to the terms of this Agreement, each # Contributor hereby grants Recipient a # non-exclusive, worldwide, royalty-free copyright # license to reproduce, prepare derivative works of, # publicly display, publicly perform, distribute and # sublicense the Contribution of such Contributor, if # any, and such derivative works, in source code and # object code form. # # b) Subject to the terms of this Agreement, each # Contributor hereby grants Recipient a # non-exclusive, worldwide, royalty-free patent # license under Licensed Patents to make, use, sell, # offer to sell, import and otherwise transfer the # Contribution of such Contributor, if any, in source # code and object code form. This patent license # shall apply to the combination of the Contribution # and the Program if, at the time the Contribution is # added by the Contributor, such addition of the # Contribution causes such combination to be covered # by the Licensed Patents. The patent license shall # not apply to any other combinations which include # the Contribution. No hardware per se is licensed # hereunder. # # c) Recipient understands that although each ## Contributor grants the licenses to its # Contributions set forth herein, no assurances are # provided by any Contributor that the Program does # not infringe the patent or other intellectual # property rights of any other entity. Each # Contributor disclaims any liability to Recipient # for claims brought by any other entity based on # infringement of intellectual property rights or # otherwise. As a condition to exercising the rights # and licenses granted hereunder, each Recipient # hereby assumes sole responsibility to secure any # other intellectual property rights needed, if any. # # For example, if a third party patent license is # required to allow Recipient to distribute the # Program, it is Recipient's responsibility to # acquire that license before distributing the # Program. # # d) Each Contributor represents that to its # knowledge it has sufficient copyright rights in its # Contribution, if any, to grant the copyright # license set forth in this Agreement. # # 3. REQUIREMENTS # # A Contributor may choose to distribute the Program in # object code form under its own license agreement, provided # that: # a) it complies with the terms and conditions of # this Agreement; and # # b) its license agreement: # i) effectively disclaims on behalf of all # Contributors all warranties and conditions, express # and implied, including warranties or conditions of # title and non-infringement, and implied warranties # or conditions of merchantability and fitness for a # particular purpose; # # ii) effectively excludes on behalf of all # Contributors all liability for damages, including # direct, indirect, special, incidental and # consequential damages, such as lost profits; # # iii) states that any provisions which differ from # this Agreement are offered by that Contributor # alone and not by any other party; and # # iv) states that source code for the Program is # available from such Contributor, and informs # licensees how to obtain it in a reasonable manner # on or through a medium customarily used for # software exchange. # # When the Program is made available in source code form: # a) it must be made available under this Agreement; # and # b) a copy of this Agreement must be included with # each copy of the Program. # # Contributors may not remove or alter any copyright notices # contained within the Program. # # Each Contributor must identify itself as the originator of # its Contribution, if any, in a manner that reasonably # allows subsequent Recipients to identify the originator of # the Contribution. # # # 4. COMMERCIAL DISTRIBUTION # # Commercial distributors of software may accept certain # responsibilities with respect to end users, business # partners and the like. While this license is intended to # facilitate the commercial use of the Program, the # Contributor who includes the Program in a commercial # product offering should do so in a manner which does not # create potential liability for other Contributors. # Therefore, if a Contributor includes the Program in a # commercial product offering, such Contributor ("Commercial # Contributor") hereby agrees to defend and indemnify every # other Contributor ("Indemnified Contributor") against any # losses, damages and costs (collectively "Losses") arising # from claims, lawsuits and other legal actions brought by a # third party against the Indemnified Contributor to the # extent caused by the acts or omissions of such Commercial # Contributor in connection with its distribution of the # Program in a commercial product offering. The obligations # in this section do not apply to any claims or Losses # relating to any actual or alleged intellectual property # infringement. In order to qualify, an Indemnified # Contributor must: a) promptly notify the Commercial # Contributor in writing of such claim, and b) allow the # Commercial Contributor to control, and cooperate with the # Commercial Contributor in, the defense and any related # settlement negotiations. The Indemnified Contributor may # participate in any such claim at its own expense. # # # For example, a Contributor might include the Program in a # commercial product offering, Product X. That Contributor # is then a Commercial Contributor. If that Commercial # Contributor then makes performance claims, or offers # warranties related to Product X, those performance claims # and warranties are such Commercial Contributor's # responsibility alone. Under this section, the Commercial # Contributor would have to defend claims against the other # Contributors related to those performance claims and # warranties, and if a court requires any other Contributor # to pay any damages as a result, the Commercial Contributor # must pay those damages. # # # 5. NO WARRANTY # # EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE # PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR # IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR # CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR # FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely # responsible for determining the appropriateness of using # and distributing the Program and assumes all risks # associated with its exercise of rights under this # Agreement, including but not limited to the risks and # costs of program errors, compliance with applicable laws, # damage to or loss of data, programs or equipment, and # unavailability or interruption of operations. # # 6. DISCLAIMER OF LIABILITY # EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER # RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, # OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION # LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE # OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGES. # # 7. GENERAL # # If any provision of this Agreement is invalid or # unenforceable under applicable law, it shall not affect # the validity or enforceability of the remainder of the # terms of this Agreement, and without further action by the # parties hereto, such provision shall be reformed to the # minimum extent necessary to make such provision valid and # enforceable. # # # If Recipient institutes patent litigation against a # Contributor with respect to a patent applicable to # software (including a cross-claim or counterclaim in a # lawsuit), then any patent licenses granted by that # Contributor to such Recipient under this Agreement shall # terminate as of the date such litigation is filed. In # addition, If Recipient institutes patent litigation # against any entity (including a cross-claim or # counterclaim in a lawsuit) alleging that the Program # itself (excluding combinations of the Program with other # software or hardware) infringes such Recipient's # patent(s), then such Recipient's rights granted under # Section 2(b) shall terminate as of the date such # litigation is filed. # # All Recipient's rights under this Agreement shall # terminate if it fails to comply with any of the material # terms or conditions of this Agreement and does not cure # such failure in a reasonable period of time after becoming # aware of such noncompliance. If all Recipient's rights # under this Agreement terminate, Recipient agrees to cease # use and distribution of the Program as soon as reasonably # practicable. However, Recipient's obligations under this # Agreement and any licenses granted by Recipient relating # to the Program shall continue and survive. # # Everyone is permitted to copy and distribute copies of # this Agreement, but in order to avoid inconsistency the # Agreement is copyrighted and may only be modified in the # following manner. The Agreement Steward reserves the right # to publish new versions (including revisions) of this # Agreement from time to time. No one other than the # Agreement Steward has the right to modify this Agreement. # # IBM is the initial Agreement Steward. IBM may assign the # responsibility to serve as the Agreement Steward to a # suitable separate entity. Each new version of the # Agreement will be given a distinguishing version number. # The Program (including Contributions) may always be # distributed subject to the version of the Agreement under # which it was received. In addition, after a new version of # the Agreement is published, Contributor may elect to # distribute the Program (including its Contributions) under # the new version. Except as expressly stated in Sections # 2(a) and 2(b) above, Recipient receives no rights or # licenses to the intellectual property of any Contributor # under this Agreement, whether expressly, by implication, # estoppel or otherwise. All rights in the Program not # expressly granted under this Agreement are reserved. # # # This Agreement is governed by the laws of the State of New # York and the intellectual property laws of the United # States of America. No party to this Agreement will bring a # legal action under this Agreement more than one year after # the cause of action arose. Each party waives its rights to # a jury trial in any resulting litigation. # # # #*/ # #/* (C) COPYRIGHT International Business Machines Corp. 2001 */ class ck_slot { char Present[20]; short SlotNumber; char SlotDescription[64]; char ManufacturerID[32]; char TokenPresent[20]; char RemovableToken[20]; char HardwareSlot[20]; short HwVersionMajor; short HwVersionMinor; short FwVersionMajor; short FwVersionMinor; char Correlator[1024]; char SlotDll[1024]; char SlotInitFcn[1024]; }; opencryptoki-2.3.1+dfsg/usr/sbin/pkcsslotd/slotd_msg.h0000751000175000017500000003664311327631345020700 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/sbin/pkcsslotd/slotd_msg.h,v 1.1 2005/01/18 16:09:04 kyoder Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #ifndef _H_SLOTD_MSG #define _H_SLOTD_MSG #include #include #define MF_SLOTD "slotd.cat" /* The following was generated from slotd.msg. */ /* definitions for set MS_SLOTD */ #define MS_SLOTD 1 #define SHMEMCR 1 #define IPCRM 2 #define SHMEMAT 3 #define SHMEMDE 4 #define SHMEMKEY 5 #define ODMFAIL 6 #define ODMSET 7 #define SLOTSKIP 8 #define SLOTFAIL 9 #endif opencryptoki-2.3.1+dfsg/usr/sbin/pkcsslotd/mutex.c0000751000175000017500000006077511327631345020045 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #include "pthread.h" #include "pkcsslotd.h" #if SYSVSEM #error "Caveat Emptor... this does not work" #include #include int Shm_Sem=-1; // system 5 shared memory semaphore... pthread_mutex_t semmtx = PTHREAD_MUTEX_INITIALIZER; // local mutex for semaphore functions... static struct sembuf xlock_lock[2]={ 0,0,0, 0,1,SEM_UNDO }; static struct sembuf xlock_unlock[1] = { 0,-1,(IPC_NOWAIT | SEM_UNDO) }; #endif #if SPINXPL #include #include #include #include static int xplfd=-1; #endif int CreateXProcLock(void *xpl) { #if (PTHREADXPL) int err; pthread_mutex_t *pmtx = (pthread_mutex_t *)xpl; /* Initialize the attributes object */ if ( (err = pthread_mutexattr_init(&mtxattr)) != 0 ) { DbgLog(DL0,"InitializeMutexes: pthread_mutexattr_init() failed - returned %#x\n", err); return FALSE; } /* Set the attribute variable so that mutexes created with it can be shared across processes */ if ( (err = pthread_mutexattr_setpshared( &mtxattr, PTHREAD_PROCESS_SHARED )) != 0 ) { DbgLog(DL0,"InitializeMutexes: pthread_mutexattr_setpshared() failed - returned %#x\n", err); return FALSE; } /* Initialize the global shared memory mutex */ if ( (err = pthread_mutex_init(pmtx,&mtxattr)) != 0 ) { DbgLog(DL0,"InitializeMutexes: pthread_mutex_init() failed. returned %#x\n", err); return FALSE; } #elif (POSIXSEM) #error "this won't work since these are really the AIX calls.." #elif (SPINXPL) xplfd = open (XPL_FILE,O_CREAT|O_RDWR,S_IRWXU|S_IRWXG|S_IRWXO); #elif (SYSVSEM) #error "Caveat Emptor... this does not work" //#error "Define XPL fcns for SYSTEM V Semaphores" key_t tok; // This really needs some work... since we need to differentiate between // the various Xprocess locks which may exist... However at this time // we know there is only one so we will just instantiate it as a global... // The other calls will ingnore thei9r parameters for SysV sems tok = ftok(TOK_PATH ,'b'); DbgLog(DL0,"creating semaphore %x \n",tok); pthread_mutex_lock (&semmtx); if ( (Shm_Sem = semget(tok,1,IPC_CREAT | 0666)) < 0 ) { DbgLog(DL0,"creating semaphore check for existing \n"); if (errno == EEXIST) { if ((Shm_Sem = semget(tok,0,0)) < 0) { DbgLog(DL0,"Failed to get semaphore for Xprocess locking \n "); pthread_mutex_unlock (&semmtx); return FALSE; } } else { DbgLog(DL0,"Failed to get semaphore for Xprocess locking error not eexist \n "); pthread_mutex_unlock(&semmtx); return FALSE; } } pthread_mutex_unlock(&semmtx); DbgLog(DL0,"Semid = %d \n",Shm_Sem); return TRUE; #elif NOXPROCLOCK return TRUE; #else #error "Define XPL fcns" #endif return TRUE; } int DestroyXProcLock(void *xpl) { #if (PTHREADXPL) /* Destroy the global shared memory mutex */ pthread_mutex_destroy((xpl)); /* Destroy the attribute object used to create all the mutexes */ pthread_mutexattr_destroy( &mtxattr ); return TRUE; #elif (POSIXSEM) #error "this won't work since these are really the AIX calls.." #elif SYSVSEM #error "Caveat Emptor... this does not work" //error "Define XPL fcns" pthread_mutex_lock(&semmtx); semctl(Shm_Sem,1,IPC_RMID,0); pthread_mutex_unlock(&semmtx); return TRUE; #elif NOXPROCLOCK return TRUE; #elif SPINXPL return TRUE; #else #error "Define XPL fcns" #endif } int XProcLock(void *xpl) { #if (PTHREADXPL) return pthread_mutex_lock((xpl)); #elif (POSIXSEM) #error "this won't work since these are really the AIX calls.." #elif SYSVSEM #error "Caveat Emptor... this does not work" //#error "Define XPL fcns" pthread_mutex_lock(&semmtx); semop(Shm_Sem,&xlock_lock[0],2); pthread_mutex_unlock(&semmtx); return TRUE; #elif NOXPROCLOCK return TRUE; #elif SPINXPL flock(xplfd,LOCK_EX); return TRUE; #else #error "Define XPL fcns" #endif } int XProcUnLock(void *xpl) { #if (PTHREADXPL) return pthread_mutex_unlock((xpl)); #elif (POSIXSEM) #error "this won't work since these are really the AIX calls.." #elif SYSVSEM #error "Caveat Emptor... this does not work" //#error "Define XPL fcns" pthread_mutex_lock(&semmtx); semop(Shm_Sem,&xlock_unlock[0],1); pthread_mutex_unlock(&semmtx); return TRUE; #elif NOXPROCLOCK return TRUE; #elif SPINXPL flock(xplfd,LOCK_UN); return TRUE; #else #error "Define XPL fcns" #endif } /********************************************************************************* * * InitializeMutexes - * * Initializes the global shared memory mutex, and sets up mtxattr, * the attribute identifier used to create all the per-process mutexes * *********************************************************************************/ int InitializeMutexes ( void ) { int err; #if 1 if ( (err = CreateXProcLock(&(shmp->slt_mutex))) != TRUE){ DbgLog(DL0,"InitializeMutexes: CreateXProcLock() failed - returned %#x\n", err); return FALSE; } #else #if !defined(PKCS64) /* Initialize the attributes object */ if ( (err = pthread_mutexattr_init(&mtxattr)) != 0 ) { DbgLog(DL0,"InitializeMutexes: pthread_mutexattr_init() failed - returned %#x\n", err); return FALSE; } /* Set the attribute variable so that mutexes created with it can be shared across processes */ if ( (err = pthread_mutexattr_setpshared( &mtxattr, PTHREAD_PROCESS_SHARED )) != 0 ) { DbgLog(DL0,"InitializeMutexes: pthread_mutexattr_setpshared() failed - returned %#x\n", err); return FALSE; } /* Initialize the global shared memory mutex */ if ( (err = pthread_mutex_init(&(shmp->slt_mutex),&mtxattr)) != 0 ) { DbgLog(DL0,"InitializeMutexes: pthread_mutex_init() failed. returned %#x\n", err); return FALSE; } #endif #endif #if TEST_COND_VARS if ( ! InitializeConditionVariables() ) { return FALSE; } #endif /* TEST_COND_VARS */ return TRUE; } #if TEST_COND_VARS BOOL InitializeConditionVariables ( void ) { int err; if ( (err = pthread_condattr_init( &(shmp->shmem_cv_attr) ) ) != 0 ) { DbgLog(DL0,"InitializeConditionVariables: pthread_condattr_init returned %s (%d; %#x)\n", SysConst(err), err, err); return FALSE; } if ( (err = pthread_cond_init( &(shmp->shmem_cv), &(shmp->shmem_cv_attr) ) ) != 0 ) { DbgLog(DL0,"InitializeConditionVariables: pthread_cond_init returned %s (%d; %#x)\n", SysConst(err), err, err); return FALSE; } if ( (err = pthread_mutex_init( &(shmp->shmem_cv_mutex), &mtxattr ) ) != 0 ) { DbgLog(DL0,"InitializeConditionVariables: pthread_mutex_init returned %s (%d; %#x)\n", SysConst(err), err, err); return FALSE; } return TRUE; } BOOL DestroyConditionVariables ( void ) { int err; if ( (err = pthread_mutex_destroy ( &(shmp->shmem_cv_mutex) ) ) != 0 ) { DbgLog(DL0,"DestroyConditionVariables: pthread_mutex_destroy returned %s (%d; %#x)\n", SysConst(err), err, err); return FALSE; } if ( (err = pthread_cond_destroy( &(shmp->shmem_cv) ) ) != 0 ) { DbgLog(DL0,"DestroyConditionVariables: pthread_cond_destroy returned %s (%d; %#x)\n", SysConst(err), err, err); return FALSE; } if ( (err = pthread_condattr_destroy( &(shmp->shmem_cv_attr) ) ) != 0 ) { DbgLog(DL0,"DestroyConditionVariables: pthread_condattr_destroy returned %s (%d; %#x)\n", SysConst(err), err, err); return FALSE; } return TRUE; } #endif /* TEST_COND_VARS */ /*********************************************************************** * DestroyMutexes - * * Destroys all the mutexes used by the program * ***********************************************************************/ int DestroyMutexes ( void ) { /* Get the global shared memory mutex */ #if 1 XProcLock(&(shmp->slt_mutex)); #else #ifdef PKCS64 msem_lock(&(shmp->slt_mutex), 0 ); #else pthread_mutex_lock(&(shmp->slt_mutex)); #endif #endif #if TEST_COND_VARS if ( ! DestroyConditionVariables() ) { return FALSE; } #endif /* TEST_COND_VARS */ #ifdef FIXME // SAB FIXME... This is really useless as we don't use the // per process mutexes on the shared memory... thank goodness, since // this would have complicated the linux port as it does not support // Process shared mutexes // of course when we want to use these mutexes we need to figure out // how to handle it in linux... /* Destroy the per-process mutexes */ for ( i = 0; i < NUMBER_PROCESSES_ALLOWED; i++ ) { /* Should I get and release the per-process mutexes here? */ /* No. The only way this'll get called is if no processes are currently attached to the slotmgr So, in theory, noone should be holding a mutex - if they are, it's in error */ /* FIXME: Should make sure that they were successfully created before destroying them */ #ifdef PKCS64 msem_remove(&(shmp->proc_table[i].proc_mutex)); #else pthread_mutex_destroy( &(shmp->proc_table[i].proc_mutex) ); #endif } #endif /* Give up the global shared memory mutex */ /* (we have to release it before we destroy it, otherwise the behavior's undefined) */ #if 1 XProcUnLock(&(shmp->slt_mutex)); DestroyXProcLock(&(shmp->slt_mutex)); #else #ifdef PKCS64 msem_unlock(&(shmp->slt_mutex),0); /* Destroy the global shared memory mutex */ msem_remove(&(shmp->slt_mutex)); #else pthread_mutex_unlock(&(shmp->slt_mutex)); /* Destroy the global shared memory mutex */ pthread_mutex_destroy(&(shmp->slt_mutex)); /* Destroy the attribute object used to create all the mutexes */ pthread_mutexattr_destroy( &mtxattr ); #endif #endif return TRUE; } opencryptoki-2.3.1+dfsg/usr/sbin/pkcsslotd/shmem.c0000751000175000017500000006357511327631345020015 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #include "pthread.h" #include "pkcsslotd.h" #include #include #include #include #include #include #include #include #define MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) #define MAPFILENAME CONFIG_PATH "/.apimap" /*********************************************************************** * CreateSharedMemory - * * Creates and initializes a shared memory file. This function will fail if the * memory is already allocated since we're the owner of it. * ***********************************************************************/ int CreateSharedMemory ( void ) { struct stat statbuf; char *Path = NULL; struct group *grp; struct shmid_ds shm_info; #if !MMAP if ( ((Path = getenv("PKCS11_SHMEM_FILE")) == NULL ) || ( Path[0] == '\0' ) ) { Path = TOK_PATH; } InfoLog( "Shared memory file is %s", Path); // Get shared memory key token all users of the shared memory // need to get the same token if ( stat(Path, &statbuf) < 0 ) { ErrLog(SLOTD_MSG(SHMEMKEY, "Shared Memory Key Token creation file does not exist")); return FALSE; } // SAB Get the group information for the PKCS#11 group... fail if // it does not exist grp = getgrnam("pkcs11"); if ( !grp ) { ErrLog("Group PKCS#11 does not exist "); return FALSE; // Group does not exist... setup is wrong.. } tok = ftok(Path ,'b'); // Allocate the shared memory... Fail if the memory is already // allocated since the slot mgr is the owner of it. // Is this some attempt at exclusivity, or is that just a side effect? - SCM 9/1 shmid = shmget( tok, sizeof( Slot_Mgr_Shr_t ), IPC_CREAT | IPC_EXCL | S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP ); // Explanation of options to shmget(): /* * IPC_CREAT Creates the data structure if it does not already exist. * IPC_EXCL Causes the shmget subroutine to be unsuccessful if the * IPC_CREAT flag is also set, and the data structure already exists. * S_IRUSR Permits the process that owns the data structure to read it. * S_IWUSR Permits the process that owns the data structure to modify it. * S_IRGRP Permits the group associated with the data structure to read it. * S_IWGRP Permits the group associated with the data structure to modify it. * * * WE DON"T WANT OTHERS * S_IROTH Permits others to read the data structure. * S_IWOTH Permits others to modify the data structure. */ if ( shmid < 0 ) { ErrLog(SLOTD_MSG(SHMEMCR, "Shared memory creation failed (0x%X)\n"), errno); ErrLog(SLOTD_MSG(IPCRM, "perform ipcrm -M 0x%X\n"), tok); return FALSE; } // SAB Set the group ownership of the shared mem segment.. // we already have the group structure.. if ( shmctl(shmid, IPC_STAT,&shm_info) == 0 ) { shm_info.shm_perm.gid = grp->gr_gid; if (shmctl(shmid,IPC_SET,&shm_info) == -1) { ErrLog("Failed to set group ownership for shm \n"); shmctl(shmid, IPC_RMID,NULL); } } else { ErrLog("Can't get status of shared memory %d\n",errno); // we know it was created... we need to destroy it... shmctl(shmid, IPC_RMID,NULL); } return TRUE; #else { #warning "EXPERIMENTAL" int fd; int i; char *buffer; grp = getgrnam("pkcs11"); if ( !grp ) { ErrLog("Group \"pkcs11\" does not exist! Please run %s/pkcs11_startup.", SBIN_PATH); return FALSE; // Group does not exist... setup is wrong.. } fd = open(MAPFILENAME,O_RDWR,MODE); if (fd < 0 ) { // File does not exist... this is cool, we creat it here fd = open(MAPFILENAME,O_RDWR|O_CREAT,MODE); // Create the file if (fd < 0 ){ // We are really hosed here, since we should be able // to create the file now ErrLog("%s: open(%s): %s", __FUNCTION__, MAPFILENAME, strerror(errno)); return FALSE; } else { if (fchmod(fd, MODE) == -1) { ErrLog("%s: fchmod(%s): %s", __FUNCTION__, MAPFILENAME, strerror(errno)); close(fd); return FALSE; } if (fchown(fd, 0, grp->gr_gid) == -1) { ErrLog("%s: fchown(%s, root, pkcs11): %s", __FUNCTION__, MAPFILENAME, strerror(errno)); close(fd); return FALSE; } // Create a buffer and make the file the right length i = sizeof(Slot_Mgr_Shr_t); buffer = malloc(sizeof(Slot_Mgr_Shr_t)); memset(buffer,'\0',i); write(fd,buffer,i); free(buffer); close(fd); } } else { ErrLog("%s: [%s] exists; you may already have a pkcsslot daemon running. If this " "is not the case, then the prior daemon was not shut down cleanly. " "Please delete this file and try again\n", __FUNCTION__, MAPFILENAME); close(fd); return FALSE; } return TRUE; } #endif } /*********************************************************************** * * AttachToSharedMemeory - * * Called after creating the shared memory file * Basically allows us to have access to the memory we've just created * ***********************************************************************/ int AttachToSharedMemeory ( void ) { #if !MMAP shmp = NULL; shmp = (Slot_Mgr_Shr_t *) shmat( shmid, NULL, 0 ); if ( !shmp ) { ErrLog(SLOTD_MSG(SHMEMAT, "Shared memory attach failed (0x%X)\n"), errno); return FALSE; } /* Initizalize the memory to 0 */ memset ( shmp, '\0', sizeof(*shmp) ); return TRUE; #else { #warning "EXPERIMENTAL" int fd; int i; char *buffer; fd = open(MAPFILENAME,O_RDWR,MODE); if (fd < 0 ){ return FALSE; //Failed } shmp = (Slot_Mgr_Shr_t *)mmap(NULL,sizeof(Slot_Mgr_Shr_t),PROT_READ|PROT_WRITE, MAP_SHARED,fd,0); close(fd); if ( ! shmp ) { return FALSE; } return TRUE; } #endif } /*********************************************************************** * * DetachFromSharedMemory - * * Un-does AttachToSharedMemory() :) * ***********************************************************************/ void DetachFromSharedMemory ( void ) { #if !MMAP if ( shmp == NULL ) return; if ( shmdt(shmp) != 0 ) { ErrLog(SLOTD_MSG(SHMEMDE, "Attempted to detach from an invalid shared memory pointer")); } shmp = NULL; return; #else if ( shmp == NULL ) return; munmap((void *)shmp,sizeof(*shmp)); unlink(MAPFILENAME); #endif } /*********************************************************************** * * DestroySharedMemory - * * Closes (destroys) the shared memory file we created with CreateSharedMemory() * * We should make sure that everyone else has detached before we do this * if we manage to exit before this gets called, you have to call ipcrm * to clean things up... * ***********************************************************************/ void DestroySharedMemory ( void ) { if (shmctl (shmid, IPC_RMID, 0) != 0) { perror ("error in closing shared memory segment"); } return; } /*********************************************************************** * * InitSharedMemory - * * Set up our newly allocated shared memory segment * * ***********************************************************************/ int InitSharedMemory ( Slot_Mgr_Shr_t *sp ) { #ifdef PKCS64 CK_INFO_PTR_64 ckinf = NULL; #else CK_INFO_PTR ckinf = NULL; #endif CK_VERSION_PTR ckver; CK_SLOT_ID id; uint16 procindex; char *package_version_tmp; char *tok_str; CK_BYTE lib_major; CK_BYTE lib_minor; ckinf = &(sp->ck_info); ckver = &(ckinf->cryptokiVersion); ckver->major = CRYPTOKI_API_MAJOR_V; ckver->minor = CRYPTOKI_API_MINOR_V; sp->ck_info.cryptokiVersion.major = CRYPTOKI_API_MAJOR_V; memset ( ckinf->manufacturerID, ' ', sizeof(ckinf->manufacturerID) ); memset ( ckinf->libraryDescription, ' ', sizeof(ckinf->libraryDescription) ); memcpy ( ckinf->manufacturerID, MFG, strlen(MFG) ); memcpy ( ckinf->libraryDescription, LIB, strlen(LIB) ); ckver = &(ckinf->libraryVersion); ckver->major = LIB_MAJOR_V; ckver->minor = LIB_MINOR_V; #ifdef PACKAGE_VERSION package_version_tmp = malloc(strlen(PACKAGE_VERSION)+1); if (package_version_tmp) { strcpy(package_version_tmp, PACKAGE_VERSION); tok_str = strtok(package_version_tmp, "."); if (tok_str) { lib_major = (CK_BYTE)atoi(tok_str); tok_str = strtok(NULL, "."); if (tok_str) { lib_minor = (CK_BYTE)atoi(tok_str); ckver->major = lib_major; ckver->minor = lib_minor; } } free(package_version_tmp); } #endif /* * populate the Slot entries... */ sp->num_slots = NumberSlotsInDB; /* FIXME: Change NUMBER_SLOTS_MANAGED in loop condition to NumberSlotsInDB? */ for ( id=0; ( (id < NUMBER_SLOTS_MANAGED) && (sinfo[id].present == TRUE ) ) ; id++ ) { /* Was sinfo[id].pk_slot.slotDescription[0] != '0' - assume typo 9/1 SCM */ #ifdef PKCS64 CK_SLOT_INFO_64 *dest = &(sp->slot_info[id].pk_slot); CK_SLOT_INFO_64 *src = &(sinfo[id].pk_slot); #else CK_SLOT_INFO *dest = &(sp->slot_info[id].pk_slot); CK_SLOT_INFO *src = &(sinfo[id].pk_slot); #endif sp->slot_info[id].slot_number = sinfo[id].slot_number; sp->slot_info[id].present = sinfo[id].present; memset ( &(dest->slotDescription[0]), ' ', sizeof(dest->slotDescription) ); memset ( &(dest->manufacturerID[0]), ' ', sizeof(dest->manufacturerID) ); memcpy ( &(dest->slotDescription[0]), &(src->slotDescription[0]), sizeof( src->slotDescription ) ); memcpy ( &(dest->manufacturerID[0]), &(src->manufacturerID[0]), sizeof( src->manufacturerID ) ); dest->flags = src->flags; memcpy ( &(dest->hardwareVersion), &(src->hardwareVersion), sizeof(src->hardwareVersion) ); memcpy ( &(dest->firmwareVersion), &(src->firmwareVersion), sizeof(src->firmwareVersion) ); /* FIXME: We really should check the length of the strings before copying it */ strcpy( sp->slot_info[id].dll_location, sinfo[id].dll_location ); strcpy( sp->slot_info[id].slot_init_fcn, sinfo[id].slot_init_fcn ); strcpy( sp->slot_info[id].correlator, sinfo[id].correlator ); } /* end for id */ for( ; id < NUMBER_SLOTS_MANAGED; id++ ) { sp->slot_info[id].slot_number = id; } /* Initialize the process side of things. */ /* for now don't worry about the condition variables */ for ( procindex=0; procindex < NUMBER_PROCESSES_ALLOWED; procindex++ ) { /* Initialize the mutex variables. */ #if FIXME #error "No usage of the per process mutexes..." #ifdef PKCS64 msem_init( &(sp->proc_table[procindex].proc_mutex), 1 ); #else pthread_mutex_init( &(sp->proc_table[procindex].proc_mutex), &mtxattr ); #endif #endif sp->proc_table[procindex].inuse = FALSE; } return TRUE; } opencryptoki-2.3.1+dfsg/usr/sbin/pkcsslotd/garbage_linux.c0000751000175000017500000007563511327631345021513 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #include "pthread.h" #include "pkcsslotd.h" #include #include #include #include #define PROC_BASE "/proc" extern BOOL GCBlockSignals (void); #if !defined(NOGARBAGE) #include "garbage_linux.h" #ifdef PKCS64 BOOL IsValidProcessEntry ( pid_t_64 pid, time_t_64 RegTime ); #else BOOL IsValidProcessEntry ( pid_t pid, time_t RegTime ); #endif int Stat2Proc ( int pid, proc_t *p ); pthread_t GCThread; /* Garbage Collection thread's handle */ static BOOL ThreadRunning = FALSE; /* If we're already running or not */ #if THREADED static void *GCMain ( void *Ptr ); static void GCCancel ( void *Ptr ); #else void *GCMain ( void *Ptr ); void GCCancel ( void *Ptr ); #endif /********************************************************************************* * StartGCThread - * * Entry point that starts the garbage collection thread * *********************************************************************************/ BOOL StartGCThread ( Slot_Mgr_Shr_t *MemPtr ) { int err; #if !(THREADED) return TRUE; #endif if ( ThreadRunning ) { DbgLog (DL0, "StartGCThread: Thread already running."); return FALSE; } if ( ( err = pthread_create( &GCThread, NULL, GCMain, ((void *)MemPtr) ) ) != 0 ) { DbgLog(DL0,"StartGCThread: pthread_create returned %s (%d; %#x)", SysConst(err), err, err ); return FALSE; } ThreadRunning = TRUE; #ifdef DEV // Only development builds LogLog ( "StartGCThread: garbage collection thread started as ID %d (%#x) by ID %d (%#x)", GCThread, GCThread, pthread_self(), pthread_self() ); #endif return TRUE; } /********************************************************************************* * StopGCThread - * * Entry point which causes the Garbage collection thread to terminate * Waits for the thread to terminate before continuing * *********************************************************************************/ BOOL StopGCThread ( void *Ptr ) { int err; void *Status; #if !(THREADED) return TRUE; #endif if ( ! ThreadRunning ) { DbgLog(DL0,"StopGCThread was called when the garbage collection thread was not running"); return FALSE; } DbgLog(DL0, "StopGCThread: tid %d is stopping the garbage collection thread (tid %d)", pthread_self(), GCThread); /* Cause the GC thread to be cancelled */ if ( ( err = pthread_cancel(GCThread)) != 0 ) { DbgLog(DL0,"StopGCThread: pthread_cancel returned %s (%d; %#x)", SysConst(err), err, err ); return FALSE; } /* Synchronize with the GC thread (aka: wait for it to terminate) */ if ( (err = pthread_join ( GCThread, &Status ) ) != 0 ) { DbgLog(DL0,"StopGCThread: pthread_join returned %s (%d; %#x)", SysConst(err), err, err ); return FALSE; } if ( Status != PTHREAD_CANCELED ) { DbgLog(DL0,"Hmm. Thread was cancelled, but didn't return the appropriate return status"); } ThreadRunning = FALSE; return TRUE; } /********************************************************************************* * GCMain - * * The Garbage collection thread's main() * Basically, run until cancelled by another thread * *********************************************************************************/ void *GCMain ( void *Ptr) { #if THREADED int OrigCancelState; int OrigCancelType; int LastCancelState; #endif Slot_Mgr_Shr_t *MemPtr = (Slot_Mgr_Shr_t *) Ptr; ASSERT ( MemPtr != NULL ); sleep(2); // SAB Linux likes to have us delay // Linux threading model appears to have some issues with regards to // signals.... Need to look at this FIXME.. /* setup */ /* Block the signals that go to the main thread */ /* FIXME: We probably want to make it so that signals go only to the main thread by default */ // SBADE .... FIXME... remove the blocking of signals see what happens.. // GCBlockSignals(); /* Make it so that we can only be cancelled when we reach a cancellation point */ /* cancellation points are listed here: http://techlib.austin.ibm.com/techlib/manuals/adoclib/aixprggd/genprogc/termthre.htm#D3A4499176manu */ /* PTHREAD_CANCEL_DEFERRED should be the default */ #if THREADED pthread_setcancelstate ( PTHREAD_CANCEL_ENABLE, &OrigCancelState ); pthread_setcanceltype ( PTHREAD_CANCEL_DEFERRED, &OrigCancelType ); /* push cleanup routines */ pthread_cleanup_push ( GCCancel, MemPtr ); #endif DbgLog(DL0, "Garbage collection running... PID %d\n",getpid()); while ( 1 ) { DbgLog(DL0, "Garbage collection running..."); /* Don't allow cancellations while mucking with shared memory or holding mutexes */ #if THREADED pthread_setcancelstate ( PTHREAD_CANCEL_DISABLE, &LastCancelState ); #endif CheckForGarbage(MemPtr); #if THREADED /* re-enable cancellations */ pthread_setcancelstate ( PTHREAD_CANCEL_ENABLE, &LastCancelState ); /* Test for cancellation by the main thread */ pthread_testcancel(); #endif DbgLog(DL5, "Garbage collection finished."); /* now we pause */ sleep(10); } /* end while 1 */ #if THREADED /* Yeah, yeah. Has to be here because some implementations use macros that have to be balanced */ pthread_cleanup_pop ( 0 ); #endif /* return implicitly calls pthread_cancel() */ /* but it'll never really get executed; pthread_testcancel() implicitly calls pthread_exit() if there's a cancellation pending */ return NULL; } /********************************************************************************* * GCCancel - * * Cleanup routine called when Garbage collection thread exits/is cancelled * *********************************************************************************/ void GCCancel ( void *Ptr ) { /* Yeah, yeah. Doesn't do anything, but I had plans */ DbgLog(DL3, "GCCancel: tid: %d running cleanup routine", pthread_self()); return; } /********************************************************************************* * CheckForGarbage - * * The routine that actually does cleanup * *********************************************************************************/ BOOL CheckForGarbage ( Slot_Mgr_Shr_t *MemPtr ) { int SlotIndex; int ProcIndex; int Err; BOOL ValidPid; ASSERT( MemPtr != NULL_PTR ); #ifdef DEV DbgLog(DL5, "Thread %d is checking for garbage", pthread_self()); #endif /* DEV */ #ifdef DEV DbgLog (DL5, "Garbage collection attempting global shared memory lock"); #endif /* DEV */ /* Grab the global Shared mem mutex since we might modify global_session_count */ #if 1 Err = XProcLock(&(MemPtr->slt_mutex)); if ( Err != TRUE ) { DbgLog (DL0, "Garbage collection: Locking attempt for global shmem mutex returned %s", SysConst(Err) ); return FALSE; } #else #ifdef PKCS64 Err = msem_lock(&(MemPtr->slt_mutex),0); #else Err = pthread_mutex_lock ( &(MemPtr->slt_mutex) ); #endif if ( Err != 0 ) { DbgLog (DL0, "Garbage collection: Locking attempt for global shmem mutex returned %s", SysConst(Err) ); return FALSE; } #endif #ifdef DEV DbgLog ( DL5, "Garbage collection: Got global shared memory lock"); #endif /* DEV */ for ( ProcIndex = 0; ProcIndex < NUMBER_PROCESSES_ALLOWED; ProcIndex++ ) { #ifdef PKCS64 Slot_Mgr_Proc_t_64 *pProc = &(MemPtr->proc_table[ProcIndex]); #else Slot_Mgr_Proc_t *pProc = &(MemPtr->proc_table[ProcIndex]); #endif ASSERT(pProc != NULL_PTR); if ( ! (pProc->inuse) ) { continue; } ValidPid = ( (IsValidProcessEntry ( pProc->proc_id, pProc->reg_time )) && (pProc->proc_id != 0) ); if ( ( pProc->inuse ) && (! ValidPid ) ) { #ifdef DEV DbgLog(DL1, "Garbage collection routine found bad entry for pid %d (Index: %d); removing from table", pProc->proc_id, ProcIndex ); #endif /* DEV */ /* */ /* Clean up session counts */ /* */ for ( SlotIndex = 0; SlotIndex < NUMBER_SLOTS_MANAGED; SlotIndex++ ) { #ifdef PKCS64 unsigned int *pGlobalSessions = &(MemPtr->slot_info[SlotIndex].global_sessions); unsigned int *pProcSessions = &(pProc->slot_session_count[SlotIndex]); #else int *pGlobalSessions = &(MemPtr->slot_info[SlotIndex].global_sessions); int *pProcSessions = &(pProc->slot_session_count[SlotIndex]); #endif if ( *pProcSessions > 0 ) { #ifdef DEV DbgLog ( DL2, "GC: Invalid pid (%d) is holding %d sessions open on slot %d. Global session count for this slot is %d", pProc->proc_id, *pProcSessions, SlotIndex, *pGlobalSessions ); #endif /* DEV */ if ( *pProcSessions > *pGlobalSessions ) { #ifdef DEV WarnLog ( "Garbage Collection: Illegal values in table for defunct process"); DbgLog ( DL0, "Garbage collection: A process ( Index: %d, pid: %d ) showed %d sessions open on slot %s, but the global count for this slot is only %d", ProcIndex, pProc->proc_id, *pProcSessions, SlotIndex, *pGlobalSessions ); #endif /* DEV */ *pGlobalSessions = 0; } else { *pGlobalSessions -= *pProcSessions; } *pProcSessions = 0; } /* end if *pProcSessions */ } /* end for SlotIndex */ /* */ /* NULL out everything except the mutex */ /* */ #if PER_PROCESS_MUTEXES /* Grab the mutex for this proc's shared memory data structure */ #ifdef PKCS64 Err = msem_lock(&(pProc->proc_mutex),MSEM_IF_NOWAIT); #else Err = pthread_mutex_trylock( &(pProc->proc_mutex) ); #endif if ( ( Err != 0 ) ) { /* We didn't get the lock! */ /* Attempting to destroy a locked mutex results in undefined behavior */ /* http://techlib.austin.ibm.com/techlib/manuals/adoclib/libs/basetrf1/pthreads.htm */ DbgLog (DL0,"Unable to get per-process mutex for pid %d (%s) - skipping", pProc->proc_id, SysConst( Err ) ); /* The exit routine will figure out that this is an invalid process entry (by calling IsValidProcessEntry()), and won't prevent the slotd from exiting because of this entry. */ continue; } #endif /* PER_PROCESS_MUTEXES */ memset( &(pProc->inuse), '\0', sizeof(pProc->inuse) ); memset( &(pProc->proc_id), '\0', sizeof(pProc->proc_id) ); memset( &(pProc->slotmap), '\0', sizeof(pProc->slotmap) ); memset( &(pProc->blocking), '\0', sizeof(pProc->blocking )); memset( &(pProc->error), '\0', sizeof(pProc->error) ); memset( &(pProc->slot_session_count), '\0', sizeof(pProc->slot_session_count) ); memset( &(pProc->reg_time), '\0', sizeof(pProc->reg_time) ); } /* end if inuse && ValidPid */ #if PER_PROCESS_MUTEXES #ifdef PKCS64 msem_unlock(&(pProc->proc_mutex),0) #else pthread_mutex_unlock( &(pProc->proc_mutex)); #endif #endif /* PER_PROCESS_MUTEXES */ } /* end for ProcIndex */ #if 1 XProcUnLock(&(MemPtr->slt_mutex)); #else #ifdef PKCS64 msem_unlock(&(MemPtr->slt_mutex),0); #else pthread_mutex_unlock ( &(MemPtr->slt_mutex) ); #endif #endif DbgLog ( DL5, "Garbage collection: Released global shared memory lock"); return TRUE; } /********************************************************************************* * Stat2Proc - * * Fills a proc_t structure (defined in garbage_linux.h) * with a given pid's stat information found in the /proc//stat file * *********************************************************************************/ int Stat2Proc (int pid, proc_t *p) { char buf[800]; // about 40 fields, 64-bit decimal is about 20 chars char fbuf[800]; // about 40 fields, 64-bit decimal is about 20 chars char *tmp; int fd, num; // FILE *fp; // sprintf(buf, "%s/%d/stat", PROC_BASE, pid); // if( (fp = fopen(buf, "r")) == NULL ) // return FALSE; sprintf(fbuf, "%s/%d/stat", PROC_BASE, pid); printf("Buff = %s \n",fbuf); fflush(stdout); if( (fd = open(fbuf, O_RDONLY, 0)) == -1) return FALSE; num = read(fd, buf, 800); close(fd); if(num < 80) return FALSE; // buf[num] = '\0'; tmp = strrchr(buf, ')'); // split into "PID (cmd" and "" *tmp = (char)NULL; // replacing trailing ')' with NULL // Tmp now points to the rest of the buffer. // buff points to the command... /* fill in default values for older kernels */ p->exit_signal = SIGCHLD; p->processor = 0; /* now parse the two strings, tmp & buf, separately, skipping the leading "(" */ memset(p->cmd, 0, sizeof(p->cmd)); sscanf(buf, "%d (%15c", &p->pid, p->cmd); // comm[16] in kernel num = sscanf(tmp + 2, // skip space after ')' as well "%c " "%d %d %d %d %d " "%lu %lu %lu %lu %lu %lu %lu " "%ld %ld %ld %ld %ld %ld " "%lu %lu " "%ld " "%lu %lu %lu %lu %lu %lu " "%*s %*s %*s %*s " // discard, no RT signals & Linux 2.1 used hex (no use for RT signals) "%lu %lu %lu " "%d %d", &p->state, &p->ppid, &p->pgrp, &p->session, &p->tty, &p->tpgid, &p->flags, &p->min_flt, &p->cmin_flt, &p->maj_flt, &p->cmaj_flt, &p->utime, &p->stime, &p->cutime, &p->cstime, &p->priority, &p->nice, &p->timeout, &p->it_real_value, &p->start_time, &p->vsize, &p->rss, &p->rss_rlim, &p->start_code, &p->end_code, &p->start_stack, &p->kstk_esp, &p->kstk_eip, /* p->signal, p->blocked, p->sigignore, p->sigcatch, */ /* can't use */ &p->wchan, &p->nswap, &p->cnswap, /* -- Linux 2.0.35 ends here -- */ &p->exit_signal, &p->processor /* 2.2.1 ends with "exit_signal" */ /* -- Linux 2.2.8 and 2.3.47 end here -- */ ); /* fprintf(stderr, "Stat2Proc() converted %d fields.\n", num); */ if (p->tty == 0) p->tty = -1; // the old notty val, updated elsewhere before moving to 0 p->vsize /= 1024; if(num < 30) return FALSE; if(p->pid != pid) return FALSE; return TRUE; } /********************************************************************************* * IsValidProcessEntry - * * Checks to see if the process identifed by pid is the same process * that registered with us * *********************************************************************************/ #ifdef PKCS64 BOOL IsValidProcessEntry ( pid_t_64 pid, time_t_64 RegTime ) { #else BOOL IsValidProcessEntry ( pid_t pid, time_t RegTime ) { #endif int Err; int valid; proc_t *p; proc_t procstore; /* If kill(pid, 0) returns -1 and errno/Err = ESRCH, the pid doesn't exist */ if ( kill(pid, 0) == -1 ) { Err = errno; if ( Err == ESRCH ) { /* The process was not found */ DbgLog(DL3, "IsValidProcessEntry: PID %d was not found in the process table (kill() returned %s)", pid, SysConst(Err) ); return FALSE; } else { /* some other error occurred */ DbgLog(DL3, "IsValidProcessEntry: kill() returned %s (%d; %#x)", SysConst(Err), Err, Err); return FALSE; } } /* end if kill */ /* Okay, the process exists, now we see if it's really ours */ #ifdef ALLOCATE p = (proc_t *)malloc(sizeof(proc_t)); #else p = &procstore; memset(p, 0, sizeof(proc_t)); #endif if( !(valid = Stat2Proc( (int)pid, p )) ) return FALSE; if ( p->pid == pid ) { if ( RegTime >= p->start_time ) { // checking for matching start times return TRUE; } else { /* p->start_time contains the time at which the process began ?? (22nd element in /proc//stat file) */ DbgLog(DL1, "IsValidProcessEntry: PID %d started at %lu; registered at %ld", pid, p->start_time, RegTime); DbgLog(DL4, "IsValidProcessEntry: PID Returned %d flags at %#x; state at %#x", p->pid, p->flags, p->state); } } return FALSE; } #endif // NO Garbage opencryptoki-2.3.1+dfsg/usr/sbin/pkcsslotd/err.h0000751000175000017500000004370711327631345017474 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/sbin/pkcsslotd/err.h,v 1.3 2006/04/05 20:07:48 kyoder Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #ifndef _SLOTD_ERR_H #define _SLOTD_ERR_H #ifdef DEV #ifndef ASSERT #define ASSERT(_expr) _ASSERT((_expr),(__FILE__),(__LINE__)) #define _ASSERT(_expr, _fname, _line) \ if (!(_expr)) { \ ErrLog("****** ****** ***** ***** ***** ***** ***** ***** ***** ****** ******"); \ ErrLog("****** ASSERTION FAILED '%s'; %s, line %d", (#_expr), (_fname), (_line)); \ ErrLog("****** ****** ***** ***** ***** ***** ***** ***** ***** ****** ******"); \ ErrLog("Exiting."); \ abort(); \ } #endif /* ASSERT */ #ifndef ASSERT_FUNC #define ASSERT_FUNC(_expr, _func) _ASSERT_FUNC((_expr), (_func), (__FILE__), (__LINE__)) #define _ASSERT_FUNC(_expr, _func, _fname, _line) \ if (!(_expr)) { \ ErrLog("****** ****** ***** ***** ***** ***** ***** ***** ***** ****** ******"); \ ErrLog("****** ASSERTION FAILED '%s'; %s, line %d", (#_expr), (_fname), (_line)); \ ErrLog("Additional information from '%s':\n", (#_func)); \ { _func; } \ ErrLog("End of additional information from '%s'\n", (#_func) ); \ ErrLog("****** ****** ***** ***** ***** ***** ***** ***** ***** ****** ******"); \ ErrLog("Exiting."); \ abort(); \ } #endif /* ASSERT_FUNC */ #else #ifndef ASSERT #define ASSERT(_expr) #endif /* ASSERT */ #ifndef ASSERT_FUNC #define ASSERT_FUNC(_expr, _func_to_call) #endif /* ASSERT_FUNC */ #endif /* DEV */ #define SEV_EXPECTED 0x01 #define SEV_ALLOWED 0x02 #define SEV_ERROR 0x03 #define SEV_FATAL 0x04 typedef struct _ConstInfo { unsigned const int Code; unsigned const char Name[128]; /* UCHAR Descrip[256]; */ } ConstInfo, *pConstInfo; #define CONSTINFO(_X) { (_X), (#_X) } const unsigned char *ConstName ( pConstInfo pInfoArray, unsigned int InfoArraySize, unsigned int ConstValue ); #ifdef _DAE_H const unsigned char *DAEConst ( unsigned int Val ); #endif /* _DAE_H */ #ifndef _H_ERRNO #define _H_ERRNO #endif #ifdef _H_ERRNO const unsigned char *SysConst ( unsigned int Val ); #define SysError( _x ) SysConst((_x)) #endif /* _H_ERRNO */ const unsigned char *SignalConst ( unsigned int Val ); #ifdef _H_ODMI const unsigned char *ODMConst ( unsigned int Val ); #endif /* _H_ODMI */ #ifdef _PKCS11TYPES_H_ const unsigned char *PkcsReturn ( unsigned int Val ); const unsigned char *PkcsFlags ( unsigned int Val ); const unsigned char *PkcsMechanism ( unsigned int Val ); const unsigned char *PkcsObject ( unsigned int Val ); const unsigned char *PkcsKey ( unsigned int Val ); const unsigned char *PkcsAttribute ( unsigned int Val ); #endif /* _PKCS11TYPES_H_ */ const unsigned char *ResponseSeverity( unsigned int Val ); #endif /* _SLOTD_ERR_H */ opencryptoki-2.3.1+dfsg/usr/sbin/pkcsslotd/slotd.msg0000751000175000017500000003743411327631345020370 0ustar jfjf $ $ Common Public License Version 0.5 $ THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF $ THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, $ REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES $ RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. $ $ 1. DEFINITIONS $ $ "Contribution" means: $ a) in the case of the initial Contributor, the $ initial code and documentation distributed under $ this Agreement, and $ $ b) in the case of each subsequent Contributor: $ i) changes to the Program, and $ ii) additions to the Program; $ $ where such changes and/or additions to the Program $ originate from and are distributed by that $ particular Contributor. A Contribution 'originates' $ from a Contributor if it was added to the Program $ by such Contributor itself or anyone acting on such $ Contributor's behalf. Contributions do not include $ additions to the Program which: (i) are separate $ modules of software distributed in conjunction with $ the Program under their own license agreement, and $ (ii) are not derivative works of the Program. $ $ $ "Contributor" means any person or entity that distributes $ the Program. $ $ "Licensed Patents " mean patent claims licensable by a $ Contributor which are necessarily infringed by the use or $ sale of its Contribution alone or when combined with the $ Program. $ $ "Program" means the Contributions distributed in $ accordance with this Agreement. $ $ "Recipient" means anyone who receives the Program under $ this Agreement, including all Contributors. $ $ 2. GRANT OF RIGHTS $ $ a) Subject to the terms of this Agreement, each $ Contributor hereby grants Recipient a $ non-exclusive, worldwide, royalty-free copyright $ license to reproduce, prepare derivative works of, $ publicly display, publicly perform, distribute and $ sublicense the Contribution of such Contributor, if $ any, and such derivative works, in source code and $ object code form. $ $ b) Subject to the terms of this Agreement, each $ Contributor hereby grants Recipient a $ non-exclusive, worldwide, royalty-free patent $ license under Licensed Patents to make, use, sell, $ offer to sell, import and otherwise transfer the $ Contribution of such Contributor, if any, in source $ code and object code form. This patent license $ shall apply to the combination of the Contribution $ and the Program if, at the time the Contribution is $ added by the Contributor, such addition of the $ Contribution causes such combination to be covered $ by the Licensed Patents. The patent license shall $ not apply to any other combinations which include $ the Contribution. No hardware per se is licensed $ hereunder. $ $ c) Recipient understands that although each $$ Contributor grants the licenses to its $ Contributions set forth herein, no assurances are $ provided by any Contributor that the Program does $ not infringe the patent or other intellectual $ property rights of any other entity. Each $ Contributor disclaims any liability to Recipient $ for claims brought by any other entity based on $ infringement of intellectual property rights or $ otherwise. As a condition to exercising the rights $ and licenses granted hereunder, each Recipient $ hereby assumes sole responsibility to secure any $ other intellectual property rights needed, if any. $ $ For example, if a third party patent license is $ required to allow Recipient to distribute the $ Program, it is Recipient's responsibility to $ acquire that license before distributing the $ Program. $ $ d) Each Contributor represents that to its $ knowledge it has sufficient copyright rights in its $ Contribution, if any, to grant the copyright $ license set forth in this Agreement. $ $ 3. REQUIREMENTS $ $ A Contributor may choose to distribute the Program in $ object code form under its own license agreement, provided $ that: $ a) it complies with the terms and conditions of $ this Agreement; and $ $ b) its license agreement: $ i) effectively disclaims on behalf of all $ Contributors all warranties and conditions, express $ and implied, including warranties or conditions of $ title and non-infringement, and implied warranties $ or conditions of merchantability and fitness for a $ particular purpose; $ $ ii) effectively excludes on behalf of all $ Contributors all liability for damages, including $ direct, indirect, special, incidental and $ consequential damages, such as lost profits; $ $ iii) states that any provisions which differ from $ this Agreement are offered by that Contributor $ alone and not by any other party; and $ $ iv) states that source code for the Program is $ available from such Contributor, and informs $ licensees how to obtain it in a reasonable manner $ on or through a medium customarily used for $ software exchange. $ $ When the Program is made available in source code form: $ a) it must be made available under this Agreement; $ and $ b) a copy of this Agreement must be included with $ each copy of the Program. $ $ Contributors may not remove or alter any copyright notices $ contained within the Program. $ $ Each Contributor must identify itself as the originator of $ its Contribution, if any, in a manner that reasonably $ allows subsequent Recipients to identify the originator of $ the Contribution. $ $ $ 4. COMMERCIAL DISTRIBUTION $ $ Commercial distributors of software may accept certain $ responsibilities with respect to end users, business $ partners and the like. While this license is intended to $ facilitate the commercial use of the Program, the $ Contributor who includes the Program in a commercial $ product offering should do so in a manner which does not $ create potential liability for other Contributors. $ Therefore, if a Contributor includes the Program in a $ commercial product offering, such Contributor ("Commercial $ Contributor") hereby agrees to defend and indemnify every $ other Contributor ("Indemnified Contributor") against any $ losses, damages and costs (collectively "Losses") arising $ from claims, lawsuits and other legal actions brought by a $ third party against the Indemnified Contributor to the $ extent caused by the acts or omissions of such Commercial $ Contributor in connection with its distribution of the $ Program in a commercial product offering. The obligations $ in this section do not apply to any claims or Losses $ relating to any actual or alleged intellectual property $ infringement. In order to qualify, an Indemnified $ Contributor must: a) promptly notify the Commercial $ Contributor in writing of such claim, and b) allow the $ Commercial Contributor to control, and cooperate with the $ Commercial Contributor in, the defense and any related $ settlement negotiations. The Indemnified Contributor may $ participate in any such claim at its own expense. $ $ $ For example, a Contributor might include the Program in a $ commercial product offering, Product X. That Contributor $ is then a Commercial Contributor. If that Commercial $ Contributor then makes performance claims, or offers $ warranties related to Product X, those performance claims $ and warranties are such Commercial Contributor's $ responsibility alone. Under this section, the Commercial $ Contributor would have to defend claims against the other $ Contributors related to those performance claims and $ warranties, and if a court requires any other Contributor $ to pay any damages as a result, the Commercial Contributor $ must pay those damages. $ $ $ 5. NO WARRANTY $ $ EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE $ PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT $ WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR $ IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR $ CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR $ FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely $ responsible for determining the appropriateness of using $ and distributing the Program and assumes all risks $ associated with its exercise of rights under this $ Agreement, including but not limited to the risks and $ costs of program errors, compliance with applicable laws, $ damage to or loss of data, programs or equipment, and $ unavailability or interruption of operations. $ $ 6. DISCLAIMER OF LIABILITY $ EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER $ RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY $ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, $ OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION $ LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF $ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT $ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT $ OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE $ OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE $ POSSIBILITY OF SUCH DAMAGES. $ $ 7. GENERAL $ $ If any provision of this Agreement is invalid or $ unenforceable under applicable law, it shall not affect $ the validity or enforceability of the remainder of the $ terms of this Agreement, and without further action by the $ parties hereto, such provision shall be reformed to the $ minimum extent necessary to make such provision valid and $ enforceable. $ $ $ If Recipient institutes patent litigation against a $ Contributor with respect to a patent applicable to $ software (including a cross-claim or counterclaim in a $ lawsuit), then any patent licenses granted by that $ Contributor to such Recipient under this Agreement shall $ terminate as of the date such litigation is filed. In $ addition, If Recipient institutes patent litigation $ against any entity (including a cross-claim or $ counterclaim in a lawsuit) alleging that the Program $ itself (excluding combinations of the Program with other $ software or hardware) infringes such Recipient's $ patent(s), then such Recipient's rights granted under $ Section 2(b) shall terminate as of the date such $ litigation is filed. $ $ All Recipient's rights under this Agreement shall $ terminate if it fails to comply with any of the material $ terms or conditions of this Agreement and does not cure $ such failure in a reasonable period of time after becoming $ aware of such noncompliance. If all Recipient's rights $ under this Agreement terminate, Recipient agrees to cease $ use and distribution of the Program as soon as reasonably $ practicable. However, Recipient's obligations under this $ Agreement and any licenses granted by Recipient relating $ to the Program shall continue and survive. $ $ Everyone is permitted to copy and distribute copies of $ this Agreement, but in order to avoid inconsistency the $ Agreement is copyrighted and may only be modified in the $ following manner. The Agreement Steward reserves the right $ to publish new versions (including revisions) of this $ Agreement from time to time. No one other than the $ Agreement Steward has the right to modify this Agreement. $ $ IBM is the initial Agreement Steward. IBM may assign the $ responsibility to serve as the Agreement Steward to a $ suitable separate entity. Each new version of the $ Agreement will be given a distinguishing version number. $ The Program (including Contributions) may always be $ distributed subject to the version of the Agreement under $ which it was received. In addition, after a new version of $ the Agreement is published, Contributor may elect to $ distribute the Program (including its Contributions) under $ the new version. Except as expressly stated in Sections $ 2(a) and 2(b) above, Recipient receives no rights or $ licenses to the intellectual property of any Contributor $ under this Agreement, whether expressly, by implication, $ estoppel or otherwise. All rights in the Program not $ expressly granted under this Agreement are reserved. $ $ $ This Agreement is governed by the laws of the State of New $ York and the intellectual property laws of the United $ States of America. No party to this Agreement will bring a $ legal action under this Agreement more than one year after $ the cause of action arose. Each party waives its rights to $ a jury trial in any resulting litigation. $ $ $ $*/ $ $/* (C) COPYRIGHT International Business Machines Corp. 2001 */ $ messages for pkcsslotd $quote " define quote character. $len $ Do not translate ODM or ipcrm $set MS_SLOTD Define initial set$ SHMEMCR "Shared memory creation failed (0x%X)\n" IPCRM "Perform ipcrm -M 0x%X\n" SHMEMAT "Shared memory attach failed (0x%X)\n" SHMEMDE "Attempt to detech from an inbalid shared memory pointer" SHMEMKEY "Shared Memory Key Token creation file does not exist" ODMFAIL "Failed to initialize ODM (0x%X)\n" ODMSET "Failed to set ODM path (0x%X)\n" SLOTSKIP "Error reading slot description '%s'. Skipping." SLOTFAIL "Failed to read slot database.\n" opencryptoki-2.3.1+dfsg/usr/sbin/pkcsslotd/daemon.c0000751000175000017500000004210611327631345020132 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #include "pthread.h" #include "pkcsslotd.h" /* We export Daemon so that we can daemonize or not based on a command-line argument */ BOOL Daemon = (BOOL) BECOME_DAEMON; BOOL IveDaemonized = FALSE; static u_int32 PathSize = PATH_MAX + 1; static char *StartDir = NULL; BOOL IsDaemon ( void ) { return (BOOL) ( (Daemon) && (IveDaemonized) ); } BOOL SaveStartupDirectory ( char *Arg0 ) { unsigned int Err; char cwd[PATH_MAX+1]; char arg[PATH_MAX+1]; char *dname = NULL; ASSERT( Arg0 != NULL ); if ( getcwd ( cwd, PathSize ) == NULL ) { Err = errno; DbgLog(DL0,"SaveStartupDirectory: getcwd returned %s (%d)", SysConst(Err), Err); return FALSE; } /* Free previous copy */ if ( StartDir != NULL ) { free(StartDir); StartDir = NULL; } /* Allocate memory */ if ( (StartDir = calloc ( PathSize, sizeof(char) ) ) == NULL ) { Err = errno; DbgLog(DL0,"SaveStartupDirectory: Unable to allocate %d bytes of memory for storage of the CWD. %s (%d)\n", SysConst(Err), Err ); exit(1); } /* If Arg0 contains a /, then dirname(Arg0) is appended to cwd */ /* This will handle the case where you were in directory foo, and started the daemon * as bar/daemon */ /* FIXME: This will not work properly if the daemon was found by searching the PATH */ /* Make a local copy of the string because dirname() modifies it's arguments */ strcpy( arg, Arg0 ); dname = dirname ( arg ); /* note that dirname("daemon") and dirname("./daemon") will return "." */ if ( strcmp( dname, "." ) != 0 ) { /* there's a / in it... */ sprintf(StartDir, "%s/%s", cwd, dname); } else { sprintf(StartDir, "%s", cwd); } return TRUE; } BOOL GetStartDirectory ( char *Buffer, u_int32 BufSize ) { ASSERT(Buffer != NULL); if ( StartDir == NULL ) { DbgLog(DL0,"GetStartDirectory: Function called before SaveStartupDirectory()"); return FALSE; } /* what the hell is this? */ if ( BufSize < PathSize ) { return FALSE; } memcpy(Buffer, StartDir, strlen(StartDir) + 1 ); return TRUE; } opencryptoki-2.3.1+dfsg/usr/sbin/pkcsslotd/Makefile.am0000640000175000017500000000103311327631345020546 0ustar jfjfsbin_PROGRAMS=pkcsslotd pkcsslotd_LDFLAGS = -lpthread # Not all versions of automake observe sbinname_CFLAGS pkcsslotd_CFLAGS = -DSPINXPL -DPROGRAM_NAME=\"$(@)\" -DNOODM -DNODAE \ -I../. -I../../include/pkcs11 -I../../include/pkcs11/stdll # Not all versions of automake observe sbinname_CFLAGS AM_CFLAGS = -DSPINXPL -DPROGRAM_NAME=\"$(@)\" -DNOODM -DNODAE \ -I../. -I../../include/pkcs11 -I../../include/pkcs11/stdll pkcsslotd_SOURCES = slotmgr.c shmem.c signal.c mutex.c err.c log.c daemon.c \ no_odm.c garbage_linux.copencryptoki-2.3.1+dfsg/usr/sbin/pkcsslotd/pk_config_data0000751000175000017500000000060011327631345021367 0ustar jfjfTRUE|0|IBM,7025-F50 AIX (crypt0 - 30-70)|IBM,7025-F50|TRUE|FALSE|FALSE|0|0|1|1|0|/usr/lib/pkcs11/stdll/PKCS11_4758.so|SC_Initialize TRUE|1|IBM,7025-F50 AIX (crypt1 - 30-70)|IBM,7025-F50|TRUE|FALSE|FALSE|0|0|1|1|1|/usr/lib/pkcs11/stdll/PKCS11_4758.so|SC_Initialize TRUE|2|IBM,7025-F50 AIX (SOFT)|IBM,7025-F50|TRUE|FALSE|FALSE|0|0|1|1|X|/usr/lib/pkcs11/stdll/PKCS11_SW.so|SW_Initialize opencryptoki-2.3.1+dfsg/usr/sbin/pkcsslotd/garbage.c0000751000175000017500000006706111327631345020266 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #include "pthread.h" #pragma info(none) #include "pkcsslotd.h" #pragma info(restore) extern BOOL GCBlockSignals (void); #if !defined(NOGARBAGE) #ifdef PKCS64 BOOL IsValidProcessEntry ( pid_t_64 pid, time_t_64 RegTime ); #else BOOL IsValidProcessEntry ( pid_t pid, time_t RegTime ); #endif static pthread_t GCThread; /* Garbage Collection thread's handle */ static BOOL ThreadRunning = FALSE; /* If we're already running or not */ static void *GCMain ( void *Ptr ); static void GCCancel ( void *Ptr ); /********************************************************************************* * StartGCThread - * * Entry point that starts the garbage collection thread * *********************************************************************************/ BOOL StartGCThread ( Slot_Mgr_Shr_t *MemPtr ) { int err; pthread_attr_t attr; if ( ThreadRunning ) { DbgLog (DL0, "StartGCThread: Thread already running."); return FALSE; } if ( ( err = pthread_create( &GCThread, NULL, GCMain, ((void *)MemPtr) ) ) != 0 ) { DbgLog(DL0,"StartGCThread: pthread_create returned %s (%d; %#x)", SysConst(err), err, err ); return FALSE; } ThreadRunning = TRUE; #ifdef DEV // Only development builds LogLog ( "StartGCThread: garbage collection thread started as ID %d (%#x) by ID %d (%#x)", GCThread, GCThread, pthread_self(), pthread_self() ); #endif return TRUE; } /********************************************************************************* * StopGCThread - * * Entry point which causes the Garbage collection thread to terminate * Waits for the thread to terminate before continuing * *********************************************************************************/ BOOL StopGCThread ( void *Ptr ) { int err; Slot_Mgr_Shr_t *MemPtr = (Slot_Mgr_Shr_t *) Ptr; void *Status; if ( ! ThreadRunning ) { DbgLog(DL0,"StopGCThread was called when the garbage collection thread was not running"); return FALSE; } DbgLog(DL0, "StopGCThread: tid %d is stopping the garbage collection thread (tid %d)", pthread_self(), GCThread); /* Cause the GC thread to be cancelled */ if ( ( err = pthread_cancel(GCThread)) != 0 ) { DbgLog(DL0,"StopGCThread: pthread_cancel returned %s (%d; %#x)", SysConst(err), err, err ); return FALSE; } /* Synchronize with the GC thread (aka: wait for it to terminate) */ if ( (err = pthread_join ( GCThread, &Status ) ) != 0 ) { DbgLog(DL0,"StopGCThread: pthread_join returned %s (%d; %#x)", SysConst(err), err, err ); return FALSE; } if ( Status != PTHREAD_CANCELED ) { DbgLog(DL0,"Hmm. Thread was cancelled, but didn't return the appropriate return status"); } ThreadRunning = FALSE; return TRUE; } /********************************************************************************* * GCMain - * * The Garbage collection thread's main() * Basically, run until cancelled by another thread * *********************************************************************************/ static void *GCMain ( void *Ptr) { int OrigCancelState; int OrigCancelType; int LastCancelState; int i; Slot_Mgr_Shr_t *MemPtr = (Slot_Mgr_Shr_t *) Ptr; ASSERT ( MemPtr != NULL ); /* setup */ /* Block the signals that go to the main thread */ /* FIXME: We probably want to make it so that signals go only to the main thread by default */ GCBlockSignals(); /* Make it so that we can only be cancelled when we reach a cancellation point */ /* cancellation points are listed here: http://techlib.austin.ibm.com/techlib/manuals/adoclib/aixprggd/genprogc/termthre.htm#D3A4499176manu */ /* PTHREAD_CANCEL_DEFERRED should be the default */ pthread_setcancelstate ( PTHREAD_CANCEL_ENABLE, &OrigCancelState ); pthread_setcanceltype ( PTHREAD_CANCEL_DEFERRED, &OrigCancelType ); /* push cleanup routines */ pthread_cleanup_push ( GCCancel, MemPtr ); while ( 1 ) { DbgLog(DL5, "Garbage collection running..."); /* Don't allow cancellations while mucking with shared memory or holding mutexes */ pthread_setcancelstate ( PTHREAD_CANCEL_DISABLE, &LastCancelState ); CheckForGarbage(MemPtr); /* re-enable cancellations */ pthread_setcancelstate ( PTHREAD_CANCEL_ENABLE, &LastCancelState ); /* Test for cancellation by the main thread */ pthread_testcancel(); DbgLog(DL5, "Garbage collection finished."); /* now we pause */ sleep(10); } /* end while 1 */ /* Yeah, yeah. Has to be here because some implementations use macros that have to be balanced */ pthread_cleanup_pop ( 0 ); /* return implicitly calls pthread_cancel() */ /* but it'll never really get executed; pthread_testcancel() implicitly calls pthread_exit() if there's a cancellation pending */ return NULL; } /********************************************************************************* * GCCancel - * * Cleanup routine called when Garbage collection thread exits/is cancelled * *********************************************************************************/ static void GCCancel ( void *Ptr ) { Slot_Mgr_Shr_t *MemPtr = (Slot_Mgr_Shr_t *) Ptr; /* Yeah, yeah. Doesn't do anything, but I had plans */ DbgLog(DL3, "GCCancel: tid: %d running cleanup routine", pthread_self()); return; } /********************************************************************************* * CheckForGarbage - * * The routine that actually does cleanup * *********************************************************************************/ BOOL CheckForGarbage ( Slot_Mgr_Shr_t *MemPtr ) { int SlotIndex; int ProcIndex; int Err; BOOL ValidPid; ASSERT( MemPtr != NULL_PTR ); #ifdef DEV DbgLog(DL5, "Thread %d is checking for garbage", pthread_self()); #endif /* DEV */ #ifdef DEV DbgLog (DL5, "Garbage collection attempting global shared memory lock"); #endif /* DEV */ /* Grab the global Shared mem mutex since we might modify global_session_count */ #ifdef PKCS64 Err = msem_lock(&(MemPtr->slt_mutex),0); #else Err = pthread_mutex_lock ( &(MemPtr->slt_mutex) ); #endif if ( Err != 0 ) { DbgLog (DL0, "Garbage collection: Locking attempt for global shmem mutex returned %s", SysConst(Err) ); return FALSE; } #ifdef DEV DbgLog ( DL5, "Garbage collection: Got global shared memory lock"); #endif /* DEV */ for ( ProcIndex = 0; ProcIndex < NUMBER_PROCESSES_ALLOWED; ProcIndex++ ) { #ifdef PKCS64 Slot_Mgr_Proc_t_64 *pProc = &(MemPtr->proc_table[ProcIndex]); #else Slot_Mgr_Proc_t *pProc = &(MemPtr->proc_table[ProcIndex]); #endif ASSERT(pProc != NULL_PTR); if ( ! (pProc->inuse) ) { continue; } ValidPid = ( (IsValidProcessEntry ( pProc->proc_id, pProc->reg_time )) && (pProc->proc_id != 0) ); if ( ( pProc->inuse ) && (! ValidPid ) ) { #ifdef DEV DbgLog(DL1, "Garbage collection routine found bad entry for pid %d (Index: %d); removing from table", pProc->proc_id, ProcIndex ); #endif /* DEV */ /* */ /* Clean up session counts */ /* */ for ( SlotIndex = 0; SlotIndex < NUMBER_SLOTS_MANAGED; SlotIndex++ ) { #ifdef PKCS64 unsigned int *pGlobalSessions = &(MemPtr->slot_info[SlotIndex].global_sessions); unsigned int *pProcSessions = &(pProc->slot_session_count[SlotIndex]); #else int *pGlobalSessions = &(MemPtr->slot_info[SlotIndex].global_sessions); int *pProcSessions = &(pProc->slot_session_count[SlotIndex]); #endif if ( *pProcSessions > 0 ) { #ifdef DEV DbgLog ( DL2, "GC: Invalid pid (%d) is holding %d sessions open on slot %d. Global session count for this slot is %d", pProc->proc_id, *pProcSessions, SlotIndex, *pGlobalSessions ); #endif /* DEV */ if ( *pProcSessions > *pGlobalSessions ) { #ifdef DEV WarnLog ( "Garbage Collection: Illegal values in table for defunct process"); DbgLog ( DL0, "Garbage collection: A process ( Index: %d, pid: %d ) showed %d sessions open on slot %s, but the global count for this slot is only %d", ProcIndex, pProc->proc_id, *pProcSessions, SlotIndex, *pGlobalSessions ); #endif /* DEV */ *pGlobalSessions = 0; } else { *pGlobalSessions -= *pProcSessions; } *pProcSessions = 0; } /* end if *pProcSessions */ } /* end for SlotIndex */ /* */ /* NULL out everything except the mutex */ /* */ #if PER_PROCESS_MUTEXES /* Grab the mutex for this proc's shared memory data structure */ #ifdef PKCS64 Err = msem_lock(&(pProc->proc_mutex),MSEM_IF_NOWAIT); #else Err = pthread_mutex_trylock( &(pProc->proc_mutex) ); #endif if ( ( Err != 0 ) ) { /* We didn't get the lock! */ /* Attempting to destroy a locked mutex results in undefined behavior */ /* http://techlib.austin.ibm.com/techlib/manuals/adoclib/libs/basetrf1/pthreads.htm */ DbgLog (DL0,"Unable to get per-process mutex for pid %d (%s) - skipping", pProc->proc_id, SysConst( Err ) ); /* The exit routine will figure out that this is an invalid process entry (by calling IsValidProcessEntry()), and won't prevent the slotd from exiting because of this entry. */ continue; } #endif /* PER_PROCESS_MUTEXES */ memset( &(pProc->inuse), '\0', sizeof(pProc->inuse) ); memset( &(pProc->proc_id), '\0', sizeof(pProc->proc_id) ); memset( &(pProc->slotmap), '\0', sizeof(pProc->slotmap) ); memset( &(pProc->blocking), '\0', sizeof(pProc->blocking )); memset( &(pProc->error), '\0', sizeof(pProc->error) ); memset( &(pProc->slot_session_count), '\0', sizeof(pProc->slot_session_count) ); memset( &(pProc->reg_time), '\0', sizeof(pProc->reg_time) ); } /* end if inuse && ValidPid */ #if PER_PROCESS_MUTEXES #ifdef PKCS64 msem_unlock(&(pProc->proc_mutex),0) #else pthread_mutex_unlock( &(pProc->proc_mutex)); #endif #endif /* PER_PROCESS_MUTEXES */ } /* end for ProcIndex */ #ifdef PKCS64 msem_unlock(&(MemPtr->slt_mutex),0); #else pthread_mutex_unlock ( &(MemPtr->slt_mutex) ); #endif DbgLog ( DL5, "Garbage collection: Released global shared memory lock"); return TRUE; } /********************************************************************************* * IsValidProcessEntry - * * Checks to see if the process identifed by pid is the same process * that registered with us * *********************************************************************************/ #ifdef PKCS64 BOOL IsValidProcessEntry ( pid_t_64 pid, time_t_64 RegTime ) { #else BOOL IsValidProcessEntry ( pid_t pid, time_t RegTime ) { #endif #ifdef PKCS64 pid_t Index = (pid_t)pid; #else pid_t Index = pid; #endif struct procsinfo64 ProcInfo[1]; /* getprocs wants arrays; I'm just being anal; I know it's stupid to declare an array of 1 element */ struct fdsinfo_2000 FileInfo[1]; /* if you pass a struct fdsinfo, you get a core dump */ int Count = 1; int Err; /* Note that Index is modified by this call; use pid to see what process id we're looking for afterwards */ if ( getprocs ( &(ProcInfo[0]), sizeof(ProcInfo), NULL, NULL, &Index, Count ) != Count ) { Err = errno; if ( Err == EINVAL ) { /* The process was not found */ DbgLog(DL3, "IsValidProcessEntry: PID %d was not found in the process table (getprocs() returned %s)", pid, SysConst(Err) ); return FALSE; } else { /* some other error occurred */ DbgLog(DL3,"IsValidProcessEntry: getprocs() returned %s (%d; %#x)", SysConst(Err), Err, Err); return FALSE; } } /* end if getprocs */ /* Okay, the process exists, now we see if it's really ours */ if ( ProcInfo[0].pi_pid == pid) { if ( RegTime >= ProcInfo[0].pi_start ) { return TRUE; } else { /* ProcInfo[0].pi_start contains the time at which the process began */ DbgLog(DL1, "IsValidProcessEntry: PID %d started at %lld; registered at %ld", pid, ProcInfo[0].pi_start, RegTime); DbgLog(DL4, "IsValidProcessEntry: PID Returned %d flags at %#x; state at %#x index %d", ProcInfo[0].pi_pid, ProcInfo[0].pi_flags, ProcInfo[0].pi_state,Index); } } return FALSE; } #endif // NO Garbage opencryptoki-2.3.1+dfsg/usr/sbin/pkcsslotd/pkcsslotd.h0000751000175000017500000005215111327631345020703 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/sbin/pkcsslotd/pkcsslotd.h,v 1.3 2006/04/05 20:07:48 kyoder Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ /*********************************************************************** * * Slot Manager Daemon header file * ***********************************************************************/ #ifndef _PKCSSLOTMGR_H #define _PKCSSLOTMGR_H 1 #ifndef TEST_MUTEXES #define TEST_MUTEXES 0 #endif /* TEST_MUTEXES */ /***************** * Include Files * *****************/ /********************************************************************************************************** * According to: http://www.rs6000.ibm.com/doc_link/en_US/a_doc_lib/aixprggd/genprogc/multi-thread_prg.htm * * The pthread.h header file must be the first included file of each source file using the threads library, * because it defines some important macros that affect other header files. Having the pthread.h header * file as the first included file ensures the usage of thread-safe subroutines. **********************************************************************************************************/ #include #include #ifndef NODAE #include // SAB XXX remove dependency on libdae #endif #include #include #include #include #include #ifndef NOODM // SAB XXX removed ODM dependency #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "log.h" #include /* include err.h last because it needs to see variables defined in order for it to work properly */ #include "err.h" /******* * NLS * *******/ #include "slotd_msg.h" #define MSG_SET MS_SLOTD nl_catd catd; #define SLOTD_MSG(n,s) catgets(catd,MSG_SET,n,s) /*********** * Defines * ***********/ #ifdef DEV #ifndef BECOME_DAEMON #define BECOME_DAEMON FALSE #endif /* BECOME_DAEMON */ #ifndef DEFAULT_LOG_FILE #define DEFAULT_LOG_FILE (TOK_PATH ".log") #endif /* DEFAULT_LOG_FILE */ #ifndef DEFAULT_DEBUG_LEVEL #define DEFAULT_DEBUG_LEVEL DEBUG_LEVEL0 #endif /* DEFAULT_DEBUG_LEVEL */ #else /* DEV not defined */ #define BECOME_DAEMON TRUE #define DEFAULT_DEBUG_LEVEL DEBUG_NONE #endif /* DEV */ #ifndef PER_PROCESS_MUTEXES #define PER_PROCESS_MUTEXES 0 #endif /******************** * Global Variables * ********************/ #ifdef SLOTD_DECLARE_VARS FILE *logfile; // global variable for the logger Slot_Mgr_Shr_t *shmp; // pointer to the shared memory region. int shmid; key_t tok; pthread_mutexattr_t mtxattr; // Mutex attribute for the shared memory Mutex #if 1 #ifdef PKCS64 Slot_Info_t_64 sinfo[NUMBER_SLOTS_MANAGED]; #else Slot_Info_t sinfo[NUMBER_SLOTS_MANAGED]; #endif #else // Temporarily hardcode the entries into the sinfo table #ifdef PKCS64 Slot_Info_t_64 sinfo[NUMBER_SLOTS_MANAGED] = { #else Slot_Info_t sinfo[NUMBER_SLOTS_MANAGED] = { #endif {0,TRUE, {"IBM AIX Proto Slot 0", "DEEP", CKF_TOKEN_PRESENT, {0,0},{1,1} }, "/usr/lib/pkcs11/stdll/PKCS11_4758.so","SC_Initialize","0",0}, {1,TRUE, {"IBM AIX Proto Slot 0", "DEEP", CKF_TOKEN_PRESENT, {0,0},{1,1} }, "/usr/lib/pkcs11/stdll/PKCS11_4758.so","SC_Initialize","1",0}, //{1,TRUE, // {"IBM AIX Proto Slot 1", // "SHALLOW", // CKF_TOKEN_PRESENT, {0,0},{1,1} }, // "/usr/lib/pkcs11/stdll/PKCS11_LW.so","LW_Initialize","0",0}, // Last entry.... {0,FALSE, {"0", "0", 0, {0,0},{0,0} }, NULL,NULL,NULL,0 } }; #endif unsigned char NumberSlotsInDB = 0; #else extern FILE *logfile; // global variable for the logger extern Slot_Mgr_Shr_t *shmp; // pointer to the shared memory region. extern int shmid; extern key_t tok; extern pthread_mutexattr_t mtxattr; // Mutex attribute for the shared memory Mutex #ifdef PKCS64 extern Slot_Info_t_64 sinfo[NUMBER_SLOTS_MANAGED]; #else extern Slot_Info_t sinfo[NUMBER_SLOTS_MANAGED]; #endif extern unsigned char NumberSlotsInDB; #endif /* SLOTD_DECLARE_VARS */ /*********************** * Function Prototypes * ***********************/ /* System non-prototyped functions causing warnings */ /* Still throws a warning; sigh - SCM */ /* int *_Errno();*/ /* pointer to function which returns int */ /* daemon.c */ BOOL IsDaemon ( void ); BOOL GetStartDirectory ( char *Buffer, u_int32 BufSize ); BOOL SaveStartupDirectory ( char *Arg0 ); /* garbage.c */ BOOL StopGCThread ( void *Ptr ); BOOL StartGCThread ( Slot_Mgr_Shr_t *MemPtr ); BOOL CheckForGarbage ( Slot_Mgr_Shr_t *MemPtr ); /* mutex.c */ int InitializeMutexes ( void ); int DestroyMutexes ( void ); #if TEST_COND_VARS BOOL DestroyConditionVariables ( void ); BOOL InitializeConditionVariables ( void ); #endif /* TEST_COND_VARS */ /* shmem.c */ int CreateSharedMemory ( void ); int AttachToSharedMemeory ( void ); int InitSharedMemory ( Slot_Mgr_Shr_t *sp ); void DetachFromSharedMemory ( void ); void DestroySharedMemory ( void ); /* signal.c */ int SetupSignalHandlers ( void ); void slotdGenericSignalHandler( int Signal ); /* odm.c */ BOOL ReadSlotInfoDB ( void ); /* Cross Process locking */ int XProcLock(void *); int XProcUnLock(void *); int CreateXProcLock(void *); int DestroyXProcLock(void *); #endif /* _SLOTMGR_H */ opencryptoki-2.3.1+dfsg/usr/sbin/pkcsslotd/garbage_linux.h0000751000175000017500000004303111327631345021501 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/sbin/pkcsslotd/garbage_linux.h,v 1.3 2006/03/09 17:21:01 mhalcrow Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #ifndef GARBAGE_LINUX_H #define GARBAGE_LINUX_H typedef struct { int pid; /* process id */ char cmd[16], /* command line string vector for /proc//cmdline */ state; /* single-char code for process state [R, S, D, Z, or T] */ int ppid, /* pid of parent process */ pgrp, /* process group id */ session, /* session id */ tty, /* full device number of controlling terminal */ tpgid; /* terminal process group id */ unsigned long flags, /* kernel flags for the process */ min_flt, /* number of minor page faults since process start */ cmin_flt, /* cumulative min_flt of process and child processes */ maj_flt, /* number of major page faults since process start */ cmaj_flt, /* cumulative maj_flt of process and child processes */ utime, /* user-mode CPU time accumulated by process */ stime; /* kernel-mode CPU time accumulated by process */ long cutime, /* cumulative utime of process and reaped children */ cstime, /* cumulative stime of process and reaped children */ priority, /* kernel scheduling priority */ nice, /* standard unix nice level of process */ timeout, /* ? */ it_real_value; /* ? */ unsigned long start_time, /* start time of process -- seconds since 1-1-70 */ vsize; /* number of pages of virtual memory ... */ long rss; /* resident set size from /proc//stat (pages) */ unsigned long rss_rlim, /* resident set size limit? */ start_code, /* address of beginning of code segment */ end_code, /* address of end of code segment */ start_stack, /* address of the bottom of stack for the process */ kstk_esp, /* kernel stack pointer */ kstk_eip; /* kernel instruction pointer */ char /* Linux 2.1.7x and up have more signals. This handles 88. */ /* long long (instead of char xxxxxx[24]) handles 64 */ signal[24], /* mask of pending signals */ blocked[24], /* mask of blocked signals */ sigignore[24], /* mask of ignored signals */ sigcatch[24]; /* mask of caught signals */ unsigned long wchan, /* address of kernel wait channel proc is sleeping in */ nswap, /* ? */ cnswap; /* cumulative nswap ? */ int exit_signal, processor; } proc_t; #endif opencryptoki-2.3.1+dfsg/usr/sbin/pkcs_slot/0000751000175000017500000000000011327631345016510 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/sbin/pkcs_slot/Makefile.am0000640000175000017500000000003111327631345020536 0ustar jfjfsbin_SCRIPTS = pkcs_slot opencryptoki-2.3.1+dfsg/usr/sbin/pkcs_slot/pkcs_slot.in0000640000175000017500000004747311327631345021060 0ustar jfjf#!/bin/bash # # # $Header: /cvsroot/opencryptoki/opencryptoki/usr/sbin/pkcs_slot/pkcs_slot.in,v 1.4 2006/04/17 18:23:06 danielhjones Exp $ # # # Common Public License Version 0.5 # THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF # THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, # REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES # RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. # # 1. DEFINITIONS # # "Contribution" means: # a) in the case of the initial Contributor, the # initial code and documentation distributed under # this Agreement, and # # b) in the case of each subsequent Contributor: # i) changes to the Program, and # ii) additions to the Program; # # where such changes and/or additions to the Program # originate from and are distributed by that # particular Contributor. A Contribution 'originates' # from a Contributor if it was added to the Program # by such Contributor itself or anyone acting on such # Contributor's behalf. Contributions do not include # additions to the Program which: (i) are separate # modules of software distributed in conjunction with # the Program under their own license agreement, and # (ii) are not derivative works of the Program. # # # "Contributor" means any person or entity that distributes # the Program. # # "Licensed Patents " mean patent claims licensable by a # Contributor which are necessarily infringed by the use or # sale of its Contribution alone or when combined with the # Program. # # "Program" means the Contributions distributed in # accordance with this Agreement. # # "Recipient" means anyone who receives the Program under # this Agreement, including all Contributors. # # 2. GRANT OF RIGHTS # # a) Subject to the terms of this Agreement, each # Contributor hereby grants Recipient a # non-exclusive, worldwide, royalty-free copyright # license to reproduce, prepare derivative works of, # publicly display, publicly perform, distribute and # sublicense the Contribution of such Contributor, if # any, and such derivative works, in source code and # object code form. # # b) Subject to the terms of this Agreement, each # Contributor hereby grants Recipient a # non-exclusive, worldwide, royalty-free patent # license under Licensed Patents to make, use, sell, # offer to sell, import and otherwise transfer the # Contribution of such Contributor, if any, in source # code and object code form. This patent license # shall apply to the combination of the Contribution # and the Program if, at the time the Contribution is # added by the Contributor, such addition of the # Contribution causes such combination to be covered # by the Licensed Patents. The patent license shall # not apply to any other combinations which include # the Contribution. No hardware per se is licensed # hereunder. # # c) Recipient understands that although each ## Contributor grants the licenses to its # Contributions set forth herein, no assurances are # provided by any Contributor that the Program does # not infringe the patent or other intellectual # property rights of any other entity. Each # Contributor disclaims any liability to Recipient # for claims brought by any other entity based on # infringement of intellectual property rights or # otherwise. As a condition to exercising the rights # and licenses granted hereunder, each Recipient # hereby assumes sole responsibility to secure any # other intellectual property rights needed, if any. # # For example, if a third party patent license is # required to allow Recipient to distribute the # Program, it is Recipient's responsibility to # acquire that license before distributing the # Program. # # d) Each Contributor represents that to its # knowledge it has sufficient copyright rights in its # Contribution, if any, to grant the copyright # license set forth in this Agreement. # # 3. REQUIREMENTS # # A Contributor may choose to distribute the Program in # object code form under its own license agreement, provided # that: # a) it complies with the terms and conditions of # this Agreement; and # # b) its license agreement: # i) effectively disclaims on behalf of all # Contributors all warranties and conditions, express # and implied, including warranties or conditions of # title and non-infringement, and implied warranties # or conditions of merchantability and fitness for a # particular purpose; # # ii) effectively excludes on behalf of all # Contributors all liability for damages, including # direct, indirect, special, incidental and # consequential damages, such as lost profits; # # iii) states that any provisions which differ from # this Agreement are offered by that Contributor # alone and not by any other party; and # # iv) states that source code for the Program is # available from such Contributor, and informs # licensees how to obtain it in a reasonable manner # on or through a medium customarily used for # software exchange. # # When the Program is made available in source code form: # a) it must be made available under this Agreement; # and # b) a copy of this Agreement must be included with # each copy of the Program. # # Contributors may not remove or alter any copyright notices # contained within the Program. # # Each Contributor must identify itself as the originator of # its Contribution, if any, in a manner that reasonably # allows subsequent Recipients to identify the originator of # the Contribution. # # # 4. COMMERCIAL DISTRIBUTION # # Commercial distributors of software may accept certain # responsibilities with respect to end users, business # partners and the like. While this license is intended to # facilitate the commercial use of the Program, the # Contributor who includes the Program in a commercial # product offering should do so in a manner which does not # create potential liability for other Contributors. # Therefore, if a Contributor includes the Program in a # commercial product offering, such Contributor ("Commercial # Contributor") hereby agrees to defend and indemnify every # other Contributor ("Indemnified Contributor") against any # losses, damages and costs (collectively "Losses") arising # from claims, lawsuits and other legal actions brought by a # third party against the Indemnified Contributor to the # extent caused by the acts or omissions of such Commercial # Contributor in connection with its distribution of the # Program in a commercial product offering. The obligations # in this section do not apply to any claims or Losses # relating to any actual or alleged intellectual property # infringement. In order to qualify, an Indemnified # Contributor must: a) promptly notify the Commercial # Contributor in writing of such claim, and b) allow the # Commercial Contributor to control, and cooperate with the # Commercial Contributor in, the defense and any related # settlement negotiations. The Indemnified Contributor may # participate in any such claim at its own expense. # # # For example, a Contributor might include the Program in a # commercial product offering, Product X. That Contributor # is then a Commercial Contributor. If that Commercial # Contributor then makes performance claims, or offers # warranties related to Product X, those performance claims # and warranties are such Commercial Contributor's # responsibility alone. Under this section, the Commercial # Contributor would have to defend claims against the other # Contributors related to those performance claims and # warranties, and if a court requires any other Contributor # to pay any damages as a result, the Commercial Contributor # must pay those damages. # # # 5. NO WARRANTY # # EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE # PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR # IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR # CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR # FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely # responsible for determining the appropriateness of using # and distributing the Program and assumes all risks # associated with its exercise of rights under this # Agreement, including but not limited to the risks and # costs of program errors, compliance with applicable laws, # damage to or loss of data, programs or equipment, and # unavailability or interruption of operations. # # 6. DISCLAIMER OF LIABILITY # EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER # RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, # OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION # LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE # OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGES. # # 7. GENERAL # # If any provision of this Agreement is invalid or # unenforceable under applicable law, it shall not affect # the validity or enforceability of the remainder of the # terms of this Agreement, and without further action by the # parties hereto, such provision shall be reformed to the # minimum extent necessary to make such provision valid and # enforceable. # # # If Recipient institutes patent litigation against a # Contributor with respect to a patent applicable to # software (including a cross-claim or counterclaim in a # lawsuit), then any patent licenses granted by that # Contributor to such Recipient under this Agreement shall # terminate as of the date such litigation is filed. In # addition, If Recipient institutes patent litigation # against any entity (including a cross-claim or # counterclaim in a lawsuit) alleging that the Program # itself (excluding combinations of the Program with other # software or hardware) infringes such Recipient's # patent(s), then such Recipient's rights granted under # Section 2(b) shall terminate as of the date such # litigation is filed. # # All Recipient's rights under this Agreement shall # terminate if it fails to comply with any of the material # terms or conditions of this Agreement and does not cure # such failure in a reasonable period of time after becoming # aware of such noncompliance. If all Recipient's rights # under this Agreement terminate, Recipient agrees to cease # use and distribution of the Program as soon as reasonably # practicable. However, Recipient's obligations under this # Agreement and any licenses granted by Recipient relating # to the Program shall continue and survive. # # Everyone is permitted to copy and distribute copies of # this Agreement, but in order to avoid inconsistency the # Agreement is copyrighted and may only be modified in the # following manner. The Agreement Steward reserves the right # to publish new versions (including revisions) of this # Agreement from time to time. No one other than the # Agreement Steward has the right to modify this Agreement. # # IBM is the initial Agreement Steward. IBM may assign the # responsibility to serve as the Agreement Steward to a # suitable separate entity. Each new version of the # Agreement will be given a distinguishing version number. # The Program (including Contributions) may always be # distributed subject to the version of the Agreement under # which it was received. In addition, after a new version of # the Agreement is published, Contributor may elect to # distribute the Program (including its Contributions) under # the new version. Except as expressly stated in Sections # 2(a) and 2(b) above, Recipient receives no rights or # licenses to the intellectual property of any Contributor # under this Agreement, whether expressly, by implication, # estoppel or otherwise. All rights in the Program not # expressly granted under this Agreement are reserved. # # # This Agreement is governed by the laws of the State of New # York and the intellectual property laws of the United # States of America. No party to this Agreement will bring a # legal action under this Agreement more than one year after # the cause of action arose. Each party waives its rights to # a jury trial in any resulting litigation. # # # #*/ # #/* (C) COPYRIGHT International Business Machines Corp. 2001 */ DEEP4758_DLL="@STDLL_PATH@/PKCS11_4758.so" DEEP4758_DLL_FN="PKCS11_4758.so" DEEP4758_INIT="SC_Initialize" SOFT_DIR="@DB_PATH@/swtok" SOFT_DLL="@STDLL_PATH@/libpkcs11_sw.so" SOFT_DLL_FN="libpkcs11_sw.so" SOFT_INIT="ST_Initialize" ICA_DIR="@DB_PATH@/lite" ICA_DLL="@STDLL_PATH@/libpkcs11_ica.so" ICA_DLL_FN="libpkcs11_ica.so" ICA_INIT="ST_Initialize" BCOM_DIR="@DB_PATH@/bcom" BCOM_DLL="@STDLL_PATH@/PKCS11_BC.so" BCOM_DLL_FN="PKCS11_BC.so" BCOM_INIT="ST_Initialize" AEP_DIR="@DB_PATH@/aep" AEP_DLL="@STDLL_PATH@/PKCS11_AEP.so" AEP_DLL_FN="PKCS11_AEP.so" AEP_INIT="ST_Initialize" CR_DIR="@DB_PATH@/cr" CR_DLL="@STDLL_PATH@/PKCS11_CR.so" CR_DLL_FN="PKCS11_CR.so" CR_INIT="ST_Initialize" TPM_DIR="@DB_PATH@/tpm" TPM_DLL="@STDLL_PATH@/libpkcs11_tpm.so" TPM_DLL_FN="libpkcs11_tpm.so" TPM_INIT="ST_Initialize" CCA_DIR="@DB_PATH@/ccatok" CCA_DLL="@STDLL_PATH@/libpkcs11_cca.so" CCA_DLL_FN="libpkcs11_cca.so" CCA_INIT="ST_Initialize" SYSTEM=`uname -s` MANUFACTURER=`uname -rs` # Return Codes OK=0 INVALID_PARAMS=1 NOT_CRYPT_DEVICE=2 NOT_VALID_DEVICE=3 NO_DATABASE=4 if [ ! $# = 2 ] then echo "Usage: $0 devicenumber depth" exit $INVALID_PARAMS fi DEVICE=$1 DEPTH=$2 # Check for the existance of the directories if [ ! -d @DB_PATH@ ] then mkdir -p @DB_PATH@ chgrp pkcs11 @DB_PATH@ chmod -R g+rwx @DB_PATH@ fi # If the depth is "soft" then we are configuring the soft token.... if [ $DEPTH = "soft" ] then test -d $SOFT_DIR if [ $? -ne 0 ] then mkdir $SOFT_DIR chgrp pkcs11 $SOFT_DIR mkdir "$SOFT_DIR"/TOK_OBJ chgrp pkcs11 "$SOFT_DIR"/TOK_OBJ fi SYS_SLOT="Soft" fi # If the depth is "tpm" then we are configuring the tpm token.... if [ $DEPTH = "tpm" ] then test -d $TPM_DIR if [ $? -ne 0 ] then mkdir $TPM_DIR chgrp pkcs11 $TPM_DIR fi SYS_SLOT="TPM" fi if [ $DEPTH = "cca" ] then test -d $CCA_DIR if [ $? -ne 0 ] then mkdir $CCA_DIR chgrp pkcs11 $CCA_DIR mkdir "$CCA_DIR"/TOK_OBJ chgrp pkcs11 "$CCA_DIR"/TOK_OBJ fi SYS_SLOT="CCA" fi # If we are using a shallow device, make sure that the directory # to store token objects is available, if not create it and change # the ownership to the pkcs11 group if [ $DEPTH = "ica" ] then test -d $ICA_DIR if [ $? -ne 0 ] then mkdir $ICA_DIR chgrp pkcs11 $ICA_DIR mkdir "$ICA_DIR"/TOK_OBJ chgrp pkcs11 "$ICA_DIR"/TOK_OBJ fi SYS_SLOT="ICA" fi if [ $DEPTH = "bcom" ] then test -d $BCOM_DIR if [ $? -ne 0 ] then mkdir $BCOM_DIR chgrp pkcs11 $BCOM_DIR mkdir "$BCOM_DIR"/TOK_OBJ chgrp pkcs11 "$BCOM_DIR"/TOK_OBJ fi SYS_SLOT="BCOM" fi if [ $DEPTH = "aep" ] then test -d $AEP_DIR if [ $? -ne 0 ] then mkdir $AEP_DIR chgrp pkcs11 $AEP_DIR mkdir "$AEP_DIR"/TOK_OBJ chgrp pkcs11 "$AEP_DIR"/TOK_OBJ fi SYS_SLOT="AEP" fi if [ $DEPTH = "cr" ] then test -d $CR_DIR if [ $? -ne 0 ] then mkdir $CR_DIR chgrp pkcs11 $CR_DIR mkdir "$CR_DIR"/TOK_OBJ chgrp pkcs11 "$CR_DIR"/TOK_OBJ fi SYS_SLOT="CRNT" fi # The device name is now parsed to find the minor number of the # device we are examining. Since the last letter of crypt is "t" # everything after the t is treated as the device number if [ $DEPTH = "deep" ] then SYS_SLOT="$DEVICE" fi SLOT_DESCRIPTION=`echo $MANUFACTURER $SYSTEM "("$SYS_SLOT")"` CFGFILE=@CONFIG_PATH@/@CONFIG_FILE@ if [ $DEPTH = "deep" ] then echo "TRUE|0|$SLOT_DESCRIPTION|$MANUFACTURER|TRUE|FALSE|TRUE|0|0|1|1|$DEVICE|$DEEP4758_DLL_FN|$DEEP4758_INIT" >>$CFGFILE elif [ $DEPTH = "ica" ] then echo "TRUE|0|$SLOT_DESCRIPTION|$MANUFACTURER|TRUE|FALSE|TRUE|0|0|1|1|NONE|$ICA_DLL_FN|$ICA_INIT" >>$CFGFILE elif [ $DEPTH = "bcom" ] then echo "TRUE|0|$SLOT_DESCRIPTION|$MANUFACTURER|TRUE|FALSE|TRUE|0|0|1|1|NONE|$BCOM_DLL_FN|$BCOM_INIT" >>$CFGFILE elif [ $DEPTH = "aep" ] then echo "TRUE|0|$SLOT_DESCRIPTION|$MANUFACTURER|TRUE|FALSE|TRUE|0|0|1|1|NONE|$AEP_DLL_FN|$AEP_INIT" >>$CFGFILE elif [ $DEPTH = "cr" ] then echo "TRUE|0|$SLOT_DESCRIPTION|$MANUFACTURER|TRUE|FALSE|TRUE|0|0|1|1|NONE|$CR_DLL_FN|$CR_INIT" >>$CFGFILE elif [ $DEPTH = "soft" ] then echo "TRUE|0|$SLOT_DESCRIPTION|$MANUFACTURER|TRUE|FALSE|FALSE|0|0|1|1|NONE|$SOFT_DLL_FN|$SOFT_INIT" >>$CFGFILE elif [ $DEPTH = "tpm" ] then echo "TRUE|0|$SLOT_DESCRIPTION|$MANUFACTURER|TRUE|FALSE|TRUE|0|0|1|1|NONE|$TPM_DLL_FN|$TPM_INIT" >>$CFGFILE elif [ $DEPTH = "cca" ] then echo "TRUE|0|$SLOT_DESCRIPTION|$MANUFACTURER|TRUE|FALSE|TRUE|0|0|1|1|NONE|$CCA_DLL_FN|$CCA_INIT" >>$CFGFILE fi cd @DB_PATH@ chmod -R g+wrx . exit $OK opencryptoki-2.3.1+dfsg/usr/sbin/pkcscca_migrate/0000751000175000017500000000000011327631345017626 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/sbin/pkcscca_migrate/csulincl.h0000640000175000017500000014577111327631345021632 0ustar jfjf/******************************************************************************/ /* Licensed Materials Property of IBM */ /* (C) Copyright IBM Corporation, 1997, 2005 */ /* All Rights Reserved */ /* US Government Users Restricted Rights - */ /* Use, duplication or disclosure restricted by */ /* GSA ADP Schedule Contract with IBM Corp. */ /******************************************************************************/ /* */ /* This header file contains the Security API C language */ /* prototypes. See the user publications for more information. */ /* */ /******************************************************************************/ #ifndef __CSULINCL #define __CSULINCL /* * define system linkage macros for the target platform */ #define SECURITYAPI /* * define system linkage to the security API */ #define CSNBCKI CSNBCKI_32 #define CSNBCKM CSNBCKM_32 #define CSNBDKX CSNBDKX_32 #define CSNBDKM CSNBDKM_32 #define CSNBMKP CSNBMKP_32 #define CSNBKEX CSNBKEX_32 #define CSNBKGN CSNBKGN_32 #define CSNBKIM CSNBKIM_32 #define CSNBKPI CSNBKPI_32 #define CSNBKRC CSNBKRC_32 #define CSNBKRD CSNBKRD_32 #define CSNBKRL CSNBKRL_32 #define CSNBKRR CSNBKRR_32 #define CSNBKRW CSNBKRW_32 #define CSNDKRC CSNDKRC_32 #define CSNDKRD CSNDKRD_32 #define CSNDKRL CSNDKRL_32 #define CSNDKRR CSNDKRR_32 #define CSNDKRW CSNDKRW_32 #define CSNBKYT CSNBKYT_32 #define CSNBKSI CSNBKSI_32 #define CSNBKTC CSNBKTC_32 #define CSNBKTR CSNBKTR_32 #define CSNBRNG CSNBRNG_32 #define CSNBDEC CSNBDEC_32 #define CSNBENC CSNBENC_32 #define CSNBMGN CSNBMGN_32 #define CSNBMVR CSNBMVR_32 #define CSNBKTB CSNBKTB_32 #define CSNDPKG CSNDPKG_32 #define CSNDPKB CSNDPKB_32 #define CSNBOWH CSNBOWH_32 #define CSNDPKI CSNDPKI_32 #define CSNDDSG CSNDDSG_32 #define CSNDDSV CSNDDSV_32 #define CSNDKTC CSNDKTC_32 #define CSNDPKX CSNDPKX_32 #define CSNDSYI CSNDSYI_32 #define CSNDSYX CSNDSYX_32 #define CSUACFQ CSUACFQ_32 #define CSUACFC CSUACFC_32 #define CSNDSBC CSNDSBC_32 #define CSNDSBD CSNDSBD_32 #define CSUALCT CSUALCT_32 #define CSUAACM CSUAACM_32 #define CSUAACI CSUAACI_32 #define CSNDPKH CSNDPKH_32 #define CSNDPKR CSNDPKR_32 #define CSUAMKD CSUAMKD_32 #define CSNDRKD CSNDRKD_32 #define CSNDRKL CSNDRKL_32 #define CSNBPTR CSNBPTR_32 #define CSNBCPE CSNBCPE_32 #define CSNBCPA CSNBCPA_32 #define CSNBPGN CSNBPGN_32 #define CSNBPVR CSNBPVR_32 #define CSNDSYG CSNDSYG_32 #define CSNBDKG CSNBDKG_32 #define CSNBEPG CSNBEPG_32 #define CSNBCVE CSNBCVE_32 #define CSNBCSG CSNBCSG_32 #define CSNBCSV CSNBCSV_32 #define CSNBCVG CSNBCVG_32 #define CSNBKTP CSNBKTP_32 #define CSNDPKE CSNDPKE_32 #define CSNDPKD CSNDPKD_32 #define CSNBPEX CSNBPEX_32 #define CSNBPEXX CSNBPEXX_32 #define CSUARNT CSUARNT_32 #define CSNBCVT CSNBCVT_32 #define CSNBMDG CSNBMDG_32 #define CSUACRA CSUACRA_32 #define CSUACRD CSUACRD_32 #define CSNBTRV CSNBTRV_32 #define CSUAPCV CSUAPCV_32 #define CSNBKYTX CSNBKYTX_32 #define CSNBSPN CSNBSPN_32 #define CSNBSKY CSNBSKY_32 #define CSNBPCU CSNBPCU_32 #define CSUAPRB CSUAPRB_32 #define CSUADHK CSUADHK_32 #define CSUADHQ CSUADHQ_32 #define CSNDTBC CSNDTBC_32 #define CSNDRKX CSNDRKX_32 #define CSNBKET CSNBKET_32 /* * security API prototypes */ /* Clear Key Import */ extern void SECURITYAPI CSNBCKI_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * clear_key, unsigned char * target_key_identifier); /* Clear Key Import Multiple */ extern void SECURITYAPI CSNBCKM_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * clear_key_length, unsigned char * clear_key, unsigned char * target_key_identifier); /* Data Key Export */ extern void SECURITYAPI CSNBDKX_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * source_key_identifier, unsigned char * exporter_key_identifier, unsigned char * target_key_token); /* Data Key Import */ extern void SECURITYAPI CSNBDKM_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * source_key_token, unsigned char * importer_key_identifier, unsigned char * target_key_identifier); /* DES Master Key Process */ extern void SECURITYAPI CSNBMKP_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_part); /* Key Export */ extern void SECURITYAPI CSNBKEX_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_type, unsigned char * source_key_identifier, unsigned char * exporter_key_identifier, unsigned char * target_key_token); /* Key Generate */ extern void SECURITYAPI CSNBKGN_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_form, unsigned char * key_length, unsigned char * key_type_1, unsigned char * key_type_2, unsigned char * KEK_key_identifier_1, unsigned char * KEK_key_identifier_2, unsigned char * generated_key_identifier_1, unsigned char * generated_key_identifier_2); /* Key Import */ extern void SECURITYAPI CSNBKIM_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_type, unsigned char * source_key_token, unsigned char * importer_key_identifier, unsigned char * target_key_identifier); /* Key Part Import */ extern void SECURITYAPI CSNBKPI_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_part, unsigned char * key_identifier); /* Key Storage Initialization */ extern void SECURITYAPI CSNBKSI_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * file_name_length, unsigned char * file_name, long * description_length, unsigned char * description, unsigned char * clear_master_key); /* Key Record Create */ extern void SECURITYAPI CSNBKRC_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_label); /* Key Record Delete */ extern void SECURITYAPI CSNBKRD_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_identifier); /* Key Record List */ extern void SECURITYAPI CSNBKRL_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_label, long * data_set_name_length, unsigned char * data_set_name, unsigned char * security_server_name); /* Key Record Read */ extern void SECURITYAPI CSNBKRR_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_label, unsigned char * key_token); /* Key Record Write */ extern void SECURITYAPI CSNBKRW_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_token, unsigned char * key_label); /* PKA Key Record Create */ extern void SECURITYAPI CSNDKRC_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_label, long * key_token_length, unsigned char * key_token); /* PKA Key Record Delete */ extern void SECURITYAPI CSNDKRD_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_identifier); /* PKA Key Record List */ extern void SECURITYAPI CSNDKRL_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_label, long * data_set_name_length, unsigned char * data_set_name, unsigned char * security_server_name); /* PKA Key Record Read */ extern void SECURITYAPI CSNDKRR_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_label, long * key_token_length, unsigned char * key_token); /* PKA Key Record Write */ extern void SECURITYAPI CSNDKRW_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_label, long * key_token_length, unsigned char * key_token ); /* Key Test */ extern void SECURITYAPI CSNBKYT_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_identifier, unsigned char * random_number, unsigned char * verification_pattern); /* Key Test Extended @b3a*/ extern void SECURITYAPI CSNBKYTX_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_identifier, unsigned char * random_number, unsigned char * verification_pattern, unsigned char * kek_key_identifier); /* Des Key Token Change */ extern void SECURITYAPI CSNBKTC_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_identifier); /* Key Translate */ extern void SECURITYAPI CSNBKTR_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * input_key_token, unsigned char * input_KEK_key_identifier, unsigned char * output_KEK_key_identifier, unsigned char * output_key_token); /* Random Number Generate */ extern void SECURITYAPI CSNBRNG_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * form, unsigned char * random_number); /* Decipher */ extern void SECURITYAPI CSNBDEC_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_identifier, long * text_length, unsigned char * ciphertext, unsigned char * initialization_vector, long * rule_array_count, unsigned char * rule_array, unsigned char * chaining_vector, unsigned char * plaintext); /* Encipher */ extern void SECURITYAPI CSNBENC_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_identifier, long * text_length, unsigned char * plaintext, unsigned char * initialization_vector, long * rule_array_count, unsigned char * rule_array, long * pad_character, unsigned char * chaining_vector, unsigned char * ciphertext); /* MAC Generate */ extern void SECURITYAPI CSNBMGN_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_identifier, long * text_length, unsigned char * text, long * rule_array_count, unsigned char * rule_array, unsigned char * chaining_vector, unsigned char * MAC); /* MAC Verify */ extern void SECURITYAPI CSNBMVR_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_identifier, long * text_length, unsigned char * text, long * rule_array_count, unsigned char * rule_array, unsigned char * chaining_vector, unsigned char * MAC); /* Key Token Build */ extern void SECURITYAPI CSNBKTB_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_token, unsigned char * key_type, long * rule_array_count, unsigned char * rule_array, unsigned char * key_value, void * reserved_field_1, long * reserved_field_2, unsigned char * reserved_field_3, unsigned char * control_vector, unsigned char * reserved_field_4, long * reserved_field_5, unsigned char * reserved_field_6, unsigned char * master_key_verification_number ); /* PKA Key Generate */ extern void SECURITYAPI CSNDPKG_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * regeneration_data_length, unsigned char * regeneration_data, long * skeleton_key_token_length, unsigned char * skeleton_key_token, unsigned char * transport_key_identifier, long * generated_key_identifier_length, unsigned char * generated_key_identifier); /* PKA Key Token Build */ extern void SECURITYAPI CSNDPKB_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * key_values_structure_length, unsigned char * key_values_structure, long * key_name_ln, unsigned char * key_name, long * reserved_1_length, unsigned char * reserved_1, long * reserved_2_length, unsigned char * reserved_2, long * reserved_3_length, unsigned char * reserved_3, long * reserved_4_length, unsigned char * reserved_4, long * reserved_5_length, unsigned char * reserved_5, long * token_length, unsigned char * token); /* One Way Hash */ extern void SECURITYAPI CSNBOWH_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * text_length, unsigned char * text, long * chaining_vector_length, unsigned char * chaining_vector, long * hash_length, unsigned char * hash); /* PKA Key Import */ extern void SECURITYAPI CSNDPKI_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * source_key_token_length, unsigned char * source_key_token, unsigned char * importer_key_identifier, long * target_key_identifier_length, unsigned char * target_key_identifier); /* Digital Signature Generate */ extern void SECURITYAPI CSNDDSG_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * PKA_private_key_id_length, unsigned char * PKA_private_key_id, long * hash_length, unsigned char * hash, long * signature_field_length, long * signature_bit_length, unsigned char * signature_field); /* Digital Signature Verify */ extern void SECURITYAPI CSNDDSV_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * PKA_public_key_id_length, unsigned char * PKA_public_key_id, long * hash_length, unsigned char * hash, long * signature_field_length, unsigned char * signature_field); /* PKA Key Token Change */ extern void SECURITYAPI CSNDKTC_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * key_id_length, unsigned char * key_id); /* PKA Public Key Extract */ extern void SECURITYAPI CSNDPKX_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * source_key_identifier_length, unsigned char * source_key_identifier, long * target_key_token_length, unsigned char * target_key_token); /* PKA Symmetric Key Import */ extern void SECURITYAPI CSNDSYI_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * RSA_enciphered_key_length, unsigned char * RSA_enciphered_key, long * RSA_private_key_identifier_len, unsigned char * RSA_private_key_identifier, long * target_key_identifier_length, unsigned char * target_key_identifier); /* PKA Symmetric Key Export */ extern void SECURITYAPI CSNDSYX_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * source_key_identifier_length, unsigned char * source_key_identifier, long * RSA_public_key_identifier_len, unsigned char * RSA_public_key_identifier, long * RSA_enciphered_key_length, unsigned char * RSA_enciphered_key); /* Crypto Facility Query */ extern void SECURITYAPI CSUACFQ_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * verb_data_length, unsigned char * verb_data); /* Crypto Facility Control */ extern void SECURITYAPI CSUACFC_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * verb_data_length, unsigned char * verb_data); /* Compose SET Block */ extern void SECURITYAPI CSNDSBC_32(long * ReturnCode, long * ReasonCode, long * ExitDataLength, unsigned char * ExitData, long * RuleArrayCount, unsigned char * RuleArray, unsigned char * BlockContentsIdentifier, long * XDataStringLength, unsigned char * XDataString, long * DataToEncryptLength, unsigned char * DataToEncrypt, long * DataToHashLength, unsigned char * DataToHash, unsigned char * InitializationVector, long * RSAPublicKeyIdentifierLength, unsigned char * RSAPublicKeyIdentifier, long * DESKeyBLockLength, unsigned char * DESKeyBlock, long * RSAOAEPBlockLength, unsigned char * RSAOAEPBlock, unsigned char * ChainingVector, unsigned char * DESEncryptedDataBlock ); /* Decompose SET Block */ extern void SECURITYAPI CSNDSBD_32(long * ReturnCode, long * ReasonCode, long * ExitDataLength, unsigned char * ExitData, long * RuleArrayCount, unsigned char * RuleArray, long * RSAOAEPBlockLength, unsigned char * RSAOAEPBlock, long * DESEncryptedDataBlockLength, unsigned char * DESEncryptedDataBlock, unsigned char * InitializationVector, long * RSAPrivateKeyIdentifierLength, unsigned char * RSAPrivateKeyIdentifier, long * DESKeyBLockLength, unsigned char * DESKeyBlock, unsigned char * BlockContentsIdentifier, long * XDataStringLength, unsigned char * XDataString, unsigned char * ChainingVector, unsigned char * DataBlock, long * HashBlockLength, unsigned char * HashBlock ); /* Access Control Logon */ extern void SECURITYAPI CSUALCT_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * user_id, long * auth_parm_length, unsigned char * auth_parm, long * auth_data_length, unsigned char * auth_data); /* Access Control Maintenance */ extern void SECURITYAPI CSUAACM_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * name, long * output_data_length, unsigned char * output_data); /* Access Control Initialization */ extern void SECURITYAPI CSUAACI_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * verb_data_1_length, unsigned char * verb_data_1, long * verb_data_2_length, unsigned char * verb_data_2); /* PKA Public Key Hash Register */ extern void SECURITYAPI CSNDPKH_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * public_key_name, long * hash_data_length, unsigned char * hash_data); /* PKA Public Key Register */ extern void SECURITYAPI CSNDPKR_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * public_key_name, long * public_key_certificate_length, unsigned char * public_key_certificate); /* Master Key Distribution */ extern void SECURITYAPI CSUAMKD_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * share_index, unsigned char * private_key_name, unsigned char * certifying_key_name, long * certificate_length, unsigned char * certificate, long * clone_info_encrypting_key_length, unsigned char * clone_info_encrypting_key, long * clone_info_length, unsigned char * clone_info); /* Retained Key Delete */ extern void SECURITYAPI CSNDRKD_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_label); /* Retained Key List */ extern void SECURITYAPI CSNDRKL_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_label_mask, long * retained_keys_count, long * key_labels_count, unsigned char * key_labels); /* Symmetric Key Generate */ extern void SECURITYAPI CSNDSYG_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * key_encrypting_key, long * rsapub_key_length, unsigned char * rsapub_key, long * locenc_key_length, unsigned char * locenc_key, long * rsaenc_key_length, unsigned char * rsaenc_key); /* Encrypted PIN Translate */ extern void SECURITYAPI CSNBPTR_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * in_PIN_enc_key_id, unsigned char * out_PIN_enc_key_id, unsigned char * in_PIN_profile, unsigned char * in_PAN_data, unsigned char * in_PIN_blk, long * rule_array_count, unsigned char * rule_array, unsigned char * out_PIN_profile, unsigned char * out_PAN_data, long * sequence_number, unsigned char * put_PIN_blk); /* Clear PIN Encrypt */ extern void SECURITYAPI CSNBCPE_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * PIN_enc_key_id, long * rule_array_count, unsigned char * rule_array, unsigned char * clear_PIN, unsigned char * PIN_profile, unsigned char * PAN_data, long * sequence_number, unsigned char * encrypted_PIN_blk); /* Clear PIN Generate Alternate */ extern void SECURITYAPI CSNBCPA_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * PIN_enc_key_id, unsigned char * PIN_gen_key_id, unsigned char * PIN_profile, unsigned char * PAN_data, unsigned char * encrypted_PIN_blk, long * rule_array_count, unsigned char * rule_array, long * PIN_check_length, unsigned char * data_array, unsigned char * returned_result); /* Clear PIN Generate */ extern void SECURITYAPI CSNBPGN_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * PIN_gen_key_id, long * rule_array_count, unsigned char * rule_array, long * PIN_length, long * PIN_check_length, unsigned char * data_array, unsigned char * returned_result); /* Encrypted PIN Verify */ extern void SECURITYAPI CSNBPVR_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * PIN_enc_key_id, unsigned char * PIN_ver_key_id, unsigned char * PIN_profile, unsigned char * PAN_data, unsigned char * encrypted_PIN_blk, long * rule_array_count, unsigned char * rule_array, long * PIN_check_length, unsigned char * data_array); /* Diversified Key Generate */ extern void SECURITYAPI CSNBDKG_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * generating_key_id, long * data_length, unsigned char * data, unsigned char * decrypting_key_id, unsigned char * generated_key_id); /* Encrypted PIN Generate */ extern void SECURITYAPI CSNBEPG_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * PIN_gen_key_id, unsigned char * outPIN_enc_key_id, long * rule_array_count, unsigned char * rule_array, long * PIN_length, unsigned char * data_array, unsigned char * outPIN_profile, unsigned char * PAN_data, long * sequence_number, unsigned char * encrypted_PIN_blk); /* Cryptographic Variable Encipher */ extern void SECURITYAPI CSNBCVE_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * cvarenc_key_id, long * text_length, unsigned char * plain_text, unsigned char * init_vector, unsigned char * cipher_text); /* CVV Generate */ extern void SECURITYAPI CSNBCSG_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * PAN_data, unsigned char * expiration_date, unsigned char * service_code, unsigned char * key_a_id, unsigned char * key_b_id, unsigned char * generated_cvv); /* CVV Verify */ extern void SECURITYAPI CSNBCSV_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * PAN_data, unsigned char * expiration_date, unsigned char * service_code, unsigned char * key_a_id, unsigned char * key_b_id, unsigned char * generated_cvv); /* Control Vector Generate */ extern void SECURITYAPI CSNBCVG_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_type, long * rule_array_count, unsigned char * rule_array, unsigned char * reserved_field_1, unsigned char * control_vector); /* Key Token Parse */ extern void SECURITYAPI CSNBKTP_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_token, unsigned char * key_type, long * rule_array_count, unsigned char * rule_array, unsigned char * key_value, void * master_key_verification_pattern_v03, long * reserved_field_1, unsigned char * reserved_field_2, unsigned char * control_vector, unsigned char * reserved_field_3, long * reserved_field_4, unsigned char * reserved_field_5, unsigned char * master_key_verification_pattern_v00); /* PKA Encrypt */ extern void SECURITYAPI CSNDPKE_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * key_value_length, unsigned char * key_value, long * data_struct_length, unsigned char * data_struct, long * RSA_public_key_length, unsigned char * RSA_public_key, long * RSA_encipher_length, unsigned char * RSA_encipher); /* PKA Decrypt */ extern void SECURITYAPI CSNDPKD_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * enciphered_key_length, unsigned char * enciphered_key, long * data_struct_length, unsigned char * data_struct, long * RSA_private_key_length, unsigned char * RSA_private_key, long * key_value_length, unsigned char * key_value); /* Prohibit Export */ extern void SECURITYAPI CSNBPEX_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * key_identifier); /* Prohibit Export Extended */ extern void SECURITYAPI CSNBPEXX_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * Source_key_token, unsigned char * Kek_key_identifier); /* Random Number/Known Answer Test */ extern void SECURITYAPI CSUARNT_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array); /* Control Vector Translate */ extern void SECURITYAPI CSNBCVT_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, unsigned char * kek_key_identifier, unsigned char * source_key_token, unsigned char * array_key_left, unsigned char * mask_array_left, unsigned char * array_key_right, unsigned char * mask_array_right, long * rule_array_count, unsigned char * rule_array, unsigned char * target_key_token); /* MDC Generate */ extern void SECURITYAPI CSNBMDG_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * text_length, unsigned char * text_data, long * rule_array_count, unsigned char * rule_array, unsigned char * chaining_vector, unsigned char * MDC); /* Cryptographic Resource Allocate */ extern void SECURITYAPI CSUACRA_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * resource_name_length, unsigned char * resource_name); /* Cryptographic Resource Deallocate */ extern void SECURITYAPI CSUACRD_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * resource_name_length, unsigned char * resource_name); /* Transaction Validation */ extern void SECURITYAPI CSNBTRV_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * transaction_key_length, unsigned char * transaction_key, long * transaction_info_length, unsigned char * transaction_info, long * validation_values_length, unsigned char * validation_values); /* Secure Messaging for Keys */ extern void SECURITYAPI CSNBSKY_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * input_key_indentifier, unsigned char * key_encrypting_key, unsigned char * session_key, long * text_length, unsigned char * clear_text, unsigned char * initialization_vector, long * key_offset, long * key_offset_field_length, unsigned char * cipher_text, unsigned char * output_chaining_value); /* Secure Messaging for PINs */ extern void SECURITYAPI CSNBSPN_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, unsigned char * in_PIN_blk, unsigned char * in_PIN_enc_key_id, unsigned char * in_PIN_profile, unsigned char * in_PAN_data, unsigned char * secmsg_key, unsigned char * out_PIN_profile, unsigned char * out_PAN_data, long * text_length, unsigned char * clear_text, unsigned char * initialization_vector, long * PIN_offset, long * PIN_offset_field_length, unsigned char * cipher_text, unsigned char * output_chaining_value); /* PIN Change/Unblock */ extern void SECURITYAPI CSNBPCU_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * authenticationMasterKeyLength, unsigned char * authenticationMasterKey, long * issuerMasterKeyLength, unsigned char * issuerMasterKey, long * keyGenerationDataLength, unsigned char * keyGenerationData, long * newRefPinKeyLength, unsigned char * newRefPinKey, unsigned char * newRefPinBlock, unsigned char * newRefPinProfile, unsigned char * newRefPanData, long * currentRefPinKeyLength, unsigned char * currentRefPinKey, unsigned char * currentRefPinBlock, unsigned char * currentRefPinProfile, unsigned char * currentRefPanData, long * outputPinDataLength, unsigned char * outputPinData, unsigned char * outputPinProfile, long * outputPinMessageLength, unsigned char * outputPinMessage); /* PCF/CUSP Key Conversion */ extern void SECURITYAPI CSUAPCV_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * KEK_key_identifier_length, unsigned char * KEK_key_identifier, long * PCF_key_list_length, unsigned char * PCF_key_list, long * output_key_list_length, unsigned char * output_key_list); /*Process Request Block*/ extern void SECURITYAPI CSUAPRB_32(long * pReturnCode, long * pReasonCode, long * pExitDataLength, unsigned char * pExitData, long * pRuleArrayCount, unsigned char * pRuleArray, long * pSourceLength, unsigned char * pSource, long * pOutFileNameLength, unsigned char * pOutFileName, long * pReplyLength, unsigned char * pReply); /* Diffie-Hellman Key Load */ extern void SECURITYAPI CSUADHK_32(long * ReturnCode, long * ReasonCode, long * ExitDataLength, unsigned char * ExitData, long * RuleArrayCount, unsigned char * RuleArray, unsigned char * DHModulus, unsigned char * DHGenerator, unsigned char * DHKeyPart, long * TransportKeyHashLength, unsigned char * TransportKeyHash, unsigned char * Reserved1, unsigned char * Reserved2, unsigned char * Reserved3, unsigned char * Reserved4); /* Diffie-Hellman Key Query */ extern void SECURITYAPI CSUADHQ_32(long * ReturnCode, long * ReasonCode, long * ExitDataLength, unsigned char * ExitData, long * RuleArrayCount, unsigned char * RuleArray, unsigned char * DHModulus, unsigned char * DHGenerator, unsigned char * DHKeyPart, long * TransportKeyHashLength, unsigned char * TransportKeyHash, unsigned char * Reserved1, unsigned char * Reserved2, unsigned char * Reserved3, unsigned char * Reserved4); /* Trusted Block Create */ extern void SECURITYAPI CSNDTBC_32 ( long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * input_block_length, unsigned char * input_block_identifier, unsigned char * transport_key_identifier, long * trusted_blokc_length, unsigned char * trusted_blokc_identifier ); /* Remote Key Export */ extern void SECURITYAPI CSNDRKX_32 ( long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * trusted_block_length, unsigned char * trusted_block_identifier, long * certificate_length, unsigned char * certificate, long * certificate_parms_length, unsigned char * certificate_parms, long * transport_key_length, unsigned char * transport_key_identifier, long * rule_id_length, unsigned char * rule_id, long * export_key_kek_length, unsigned char * export_key_kek_identifier, long * export_key_length, unsigned char * export_key_identifier, long * asym_encrypted_key_length, unsigned char * asym_encrypted_key, long * sym_encrypted_key_length, unsigned char * sym_encrypted_key, long * extra_data_length, unsigned char * extra_data, long * key_check_parameters_length, unsigned char * key_check_parameters, long * key_check_length, unsigned char * key_check_value ); /* Key Encryption Translate */ extern void SECURITYAPI CSNBKET_32(long * return_code, long * reason_code, long * exit_data_length, unsigned char * exit_data, long * rule_array_count, unsigned char * rule_array, long * kek_identifier_length, unsigned char * kek_identifier, long * key_in_length, unsigned char * key_in, long * key_out_length, unsigned char * key_out); #endif opencryptoki-2.3.1+dfsg/usr/sbin/pkcscca_migrate/cca_migrate.c0000640000175000017500000005550511327631345022242 0ustar jfjf /* * Licensed materials - Property of IBM * * pkcs11_migrate - A tool to migrate PKCS#11 CCA key objects from one * master key to another. * * Copyright (C) International Business Machines Corp. 2007 * */ /* * There are two things that need migration in a CCA-based PKCS#11 data * store in openCryptoki: * * 1. All the objects in the data store with a CKA_IBM_OPAQUE attribute * 2. The CCA key used to encrypt those objects * * The CCA key used to encrypt the data store's objects is stored in two * files (there are two copies of it), data_store/MK_SO and * data_store/MK_USER. MK_SO is the key encrypted using the md5 hash of * the SO's PIN as the key and likewise MK_USER is encrypted with the md5 * hash of the USER's PIN. * * The shell-script that launches this program needs to do a few things: * * 1. Verify the slot that the user selects * 2. Gather the USER and SO PINs * 3. Locate the data store on disk * -- The data store location will differ deponding on whether we're * migrating on a SLES9 or SLES10 system * 4. Back-up the data store in case of failure * * Items 1-3 above will be passed as args to this program, then the steps * will be: * * 1. Read in all the CCA-based object attributes from the data store * 2. Migrate the CCA-based attributes to the new master key using the CCA APIs * 3. Delete the old unmigrated attributes * 4. Replace the old attributes with the migrated attributes * 5. Close the PKCS#11 data store * 6. Open the data store encryption key files using the SO and USER pins * 7. Migrate those keys using the CCA APIs * 8. Write them back out * 9. Migration is complete * * * Author: Kent Yoder * April 18, 2007 * */ #include #include #include #include #include #include #include #include #include #include #include "cca_migrate.h" int n_flag = 0; int v_flag = 0; void *p11_lib = NULL; void (*CSNDKTC)(); void (*CSNBKTC)(); void *lib_csulcca; CK_FUNCTION_LIST * p11_init(void) { CK_RV rv; CK_RV (*pfoo)(); char *loc1_lib = "/usr/lib/pkcs11/PKCS11_API.so64"; char *loc2_lib = "libopencryptoki.so"; CK_FUNCTION_LIST *funcs = NULL; p11_lib = dlopen(loc1_lib, RTLD_NOW); if (p11_lib != NULL) goto get_list; p11_lib = dlopen(loc2_lib, RTLD_NOW); if (p11_lib == NULL) { print_error("Couldn't get a handle to the PKCS#11 library."); return NULL; } get_list: pfoo = (CK_RV (*)())dlsym(p11_lib,"C_GetFunctionList"); if (pfoo == NULL) { print_error("Couldn't get the address of the C_GetFunctionList routine."); dlclose(p11_lib); return NULL; } rv = pfoo(&funcs); if (rv != CKR_OK) { p11_error("C_GetFunctionList", rv); dlclose(p11_lib); return NULL; } rv = funcs->C_Initialize(NULL_PTR); if (rv != CKR_OK) { p11_error("C_Initialize", rv); dlclose(p11_lib); return NULL; } if (v_flag > 1) printf("PKCS#11 library initialized\n"); return funcs; } void p11_fini(CK_FUNCTION_LIST *funcs) { funcs->C_Finalize(NULL_PTR); if (p11_lib) dlclose(p11_lib); } /* Expect attribute array to have 3 entries, * 0 CKA_IBM_OPAQUE * 1 CKA_CLASS * 2 CKA_KEY_TYPE */ int add_object(CK_OBJECT_HANDLE handle, CK_ATTRIBUTE *attrs, struct object **objs_to_migrate) { struct object *new_obj; CK_ULONG key_type = *(CK_ULONG *)attrs[2].pValue; new_obj = malloc(sizeof(struct object)); if (!new_obj) { print_error("Malloc of %zd bytes failed!", sizeof(struct object)); return 1; } switch (key_type) { case CKK_RSA: case CKK_DES: case CKK_DES3: break; default: free(new_obj); return 0; } new_obj->type = key_type; new_obj->opaque_attr = malloc(attrs[0].ulValueLen); if (!new_obj->opaque_attr) { print_error("Malloc of %lu bytes failed!", attrs[0].ulValueLen); return 2; } new_obj->handle = handle; new_obj->attr_len = attrs[0].ulValueLen; memcpy(new_obj->opaque_attr, attrs[0].pValue, attrs[0].ulValueLen); new_obj->next = *objs_to_migrate; *objs_to_migrate = new_obj; if (v_flag > 1) { char *type_name; if (new_obj->type == CKK_RSA) type_name = RSA_NAME; else if (new_obj->type == CKK_DES) type_name = DES_NAME; else if (new_obj->type == CKK_DES3) type_name = DES3_NAME; else type_name = BAD_NAME; printf("Migratable key object found: type=%s, handle=%lu\n", type_name, handle); } return 0; } int find_opaque_objects(CK_FUNCTION_LIST *funcs, CK_SESSION_HANDLE sess, struct object **objs_to_migrate) { CK_RV rv; CK_OBJECT_HANDLE *handles = NULL, tmp; CK_ULONG ulObjectCount = 0, ulTotalCount = 0; CK_ATTRIBUTE attrs[] = { { CKA_IBM_OPAQUE, NULL, 0 }, { CKA_CLASS, NULL, 0 }, { CKA_KEY_TYPE, NULL, 0 } }; int i, rc; /* Find all objects in the store */ rv = funcs->C_FindObjectsInit(sess, NULL_PTR, 0); if (rv != CKR_OK) { p11_error("C_FindObjectsInit", rv); print_error("Error finding CCA key objects"); return 1; } while (1) { rv = funcs->C_FindObjects(sess, &tmp, 1, &ulObjectCount); if (rv != CKR_OK) { p11_error("C_FindObjects", rv); print_error("Error finding CCA key objects"); free(handles); return 1; } if (ulObjectCount == 0) break; handles = realloc(handles, sizeof(CK_OBJECT_HANDLE) * (++ulTotalCount)); if (!handles) { print_error("Malloc of %lu bytes failed!", ulTotalCount); break; } handles[ulTotalCount - 1] = tmp; } if (v_flag > 1) printf("Found %lu PKCS#11 objects to examine\n", ulTotalCount); /* Don't care if this fails */ funcs->C_FindObjectsFinal(sess); /* At this point we have an array with handles to every object in the store. We only care * about those with a CKA_IBM_OPAQUE attribute, so whittle down the list accordingly */ for (tmp = 0; tmp < ulTotalCount; tmp++) { rv = funcs->C_GetAttributeValue(sess, handles[tmp], attrs, 3); if (rv != CKR_OK) { p11_error("C_GetAttributeValue", rv); print_error("Error finding CCA key objects"); free(handles); return 1; } /* If the opaque attr DNE for this object, move to the next one */ if (attrs[0].ulValueLen == ((CK_ULONG)-1)) continue; /* Allocate space in the template for the actual data */ for (i = 0; i < 3; i++) { attrs[i].pValue = malloc(attrs[i].ulValueLen); if (!attrs[i].pValue) { print_error("Malloc of %lu bytes failed!", attrs[i].ulValueLen); free(handles); return 1; } } /* Pull in the actual data */ rv = funcs->C_GetAttributeValue(sess, handles[tmp], attrs, 3); if (rv != CKR_OK) { p11_error("C_GetAttributeValue", rv); print_error("Error getting object attributes"); free(handles); return 1; } rc = add_object(handles[tmp], attrs, objs_to_migrate); if (rc) { free(handles); return 1; } for (i = 0; i < 3; i++) { free(attrs[i].pValue); attrs[i].pValue = NULL_PTR; attrs[i].ulValueLen = 0; } } free(handles); return 0; } int replace_objects(CK_FUNCTION_LIST *funcs, CK_SESSION_HANDLE sess, struct object *objs_to_migrate) { CK_RV rv; CK_ATTRIBUTE new_attr[] = { { CKA_IBM_OPAQUE, NULL, 0 } }; struct object *tmp; for (tmp = objs_to_migrate; tmp; tmp = tmp->next) { new_attr->pValue = tmp->opaque_attr; new_attr->ulValueLen = tmp->attr_len; if (n_flag == 0) { rv = funcs->C_SetAttributeValue(sess, tmp->handle, new_attr, 1); if (rv != CKR_OK) { p11_error("C_SetAttributeValue", rv); print_error("Error replacing old key with migrated key."); return 1; } } if (v_flag > 0) { char *type_name; if (tmp->type == CKK_RSA) type_name = RSA_NAME; else if (tmp->type == CKK_DES) type_name = DES_NAME; else if (tmp->type == CKK_DES3) type_name = DES3_NAME; else type_name = BAD_NAME; printf("Key object successfully migrated: type=%s, handle=%lu\n", type_name, tmp->handle); } } printf("Successfully migrated the key objects\n"); return 0; } int cca_migrate_des(char *blob, unsigned long blob_size, char **out) { long return_code, reason_code, exit_data_length, rule_array_count; unsigned char *rule_array; unsigned char *key_identifier; //unsigned char exit_data[CCA_KEY_ID_SIZE] = { 0, }; rule_array_count = 1; rule_array = (unsigned char *)"RTCMK "; exit_data_length = 0; key_identifier = calloc(1, blob_size); if (!key_identifier) { print_error("Malloc of %lu bytes failed!", blob_size); return 1; } memcpy(key_identifier, blob, blob_size); CSNBKTC(&return_code, &reason_code, &exit_data_length, NULL,//&exit_data, &rule_array_count, rule_array, key_identifier); if (return_code != CCA_SUCCESS) { cca_error("CSNBKTC (DES Key Token Change)", return_code, reason_code); print_error("Migrating a DES key failed."); return 1; } *out = (char *)key_identifier; return 0; } int cca_migrate_rsa(char *blob, unsigned long blob_size, char **out) { long return_code, reason_code, exit_data_length, rule_array_count, key_identifier_length; unsigned char *rule_array; unsigned char *key_identifier; //unsigned char exit_data[CCA_KEY_ID_SIZE] = { 0, }; rule_array_count = 1; rule_array = (unsigned char *)"RTCMK "; exit_data_length = 0; key_identifier_length = blob_size; key_identifier = calloc(1, blob_size); if (!key_identifier) { print_error("Malloc of %lu bytes failed!", blob_size); return 1; } memcpy(key_identifier, blob, blob_size); CSNDKTC(&return_code, &reason_code, &exit_data_length, NULL,//&exit_data, &rule_array_count, rule_array, &key_identifier_length, key_identifier); if (return_code != CCA_SUCCESS) { cca_error("CSNDKTC (RSA Key Token Change)", return_code, reason_code); print_error("Migrating an RSA key failed."); return 1; } *out = (char *)key_identifier; return 0; } int migrate_master_key(char *path, char *pin) { char master_key[MASTER_KEY_SIZE], *migrated_master_key; char pin_md5_hash[MD5_HASH_SIZE]; int rc; CK_RV rv; rc = compute_md5(pin, strlen(pin), pin_md5_hash); if (rc) { print_error("Error calculating MD5 of PIN!"); return rc; } rv = load_masterkey(path, pin_md5_hash, master_key); if (rv != CKR_OK) { print_error("Error loading master key to migrate: %s", path); return 1; } rc = cca_migrate_des(master_key, MASTER_KEY_SIZE, &migrated_master_key); if (rc) { print_error("Error migrating master key: %s", path); return rc; } if (n_flag == 0) { rv = save_masterkey(path, pin_md5_hash, migrated_master_key); if (rv != CKR_OK) { print_error("Error saving migrated master key: %s", path); return 1; } } return 0; } int migrate_master_keys(char *so_pin, char *user_pin, char *data_store) { struct stat sbuf; char *path; int path_len = strlen(data_store) + 32; int rc; path = calloc(1, path_len); if (!path) { print_error("Malloc of %d bytes failed!", path_len); return 1; } /* Do the SO blob */ snprintf(path, path_len, "%s/MK_SO", data_store); errno = 0; rc = stat(path, &sbuf); if (rc == -1) { print_error("Stat failed for %s: %s\n", path, strerror(errno)); free(path); return 1; } rc = migrate_master_key(path, so_pin); if (rc) { print_error("Migration of the SO's master key failed."); free(path); return 1; } printf("Successfully migrated the SO's master key\n"); /* Do the USER blob */ snprintf(path, path_len, "%s/MK_USER", data_store); errno = 0; rc = stat(path, &sbuf); if (rc == -1) { print_error("Stat failed for %s: %s\n", path, strerror(errno)); free(path); return 1; } rc = migrate_master_key(path, user_pin); if (rc) { print_error("Migration of the USER's master key failed."); free(path); return 1; } printf("Successfully migrated the USER's master key\n"); free(path); return 0; } /* @objs: A linked list of data to migrate and the PKCS#11 handle for the object in * the data store. */ int migrate_objects(struct object *objs_to_migrate) { struct object *tmp; char *migrated_data = NULL; int rc; for (tmp = objs_to_migrate; tmp; tmp = tmp->next) { migrated_data = NULL; if (tmp->type == CKK_RSA) { rc = cca_migrate_rsa((char *)tmp->opaque_attr, tmp->attr_len, &migrated_data); if (rc) { print_error("Migration of RSA key failed."); return rc; } } else if (tmp->type == CKK_DES) { rc = cca_migrate_des((char *)tmp->opaque_attr, tmp->attr_len, &migrated_data); if (rc) { print_error("Migration of DES key failed."); return rc; } } else if (tmp->type == CKK_DES3) { rc = cca_migrate_des((char *)tmp->opaque_attr, tmp->attr_len, &migrated_data); if (rc) { print_error("Migration of 3DES key failed."); return rc; } } else { print_error("Attempted to migrate an unknown object type: 0x%lX." " Ignoring.", tmp->type); } /* replace the original data with the migrated data in the object list */ if (migrated_data) { free(tmp->opaque_attr); tmp->opaque_attr = (CK_BYTE *)migrated_data; if (v_flag > 1) { char *type_name; if (tmp->type == CKK_RSA) type_name = RSA_NAME; else if (tmp->type == CKK_DES) type_name = DES_NAME; else if (tmp->type == CKK_DES3) type_name = DES3_NAME; else type_name = BAD_NAME; printf("Key data successfully changed: type=%s, handle=%lu\n", type_name, tmp->handle); } } } return 0; } void usage(char *pgm) { printf("Usage: %s [-h] [-n] [-v] -c SLOT -d PATH -s PIN -u PIN\n", pgm); printf("\t-c SLOT Migrate the token in slot number SLOT (required)\n"); printf("\t-d PATH Migrate the internal PKCS#11 files located in PATH (required)\n"); printf("\t-s PIN Use PIN as the security officer pin (required)\n"); printf("\t-u PIN Use PIN as the user pin (required)\n"); printf("\t-n Perform the migration steps but don't write the migrated data\n"); printf("\t-v Increase the verbosity of the command output\n"); printf("\t-h Display this usage message\n"); } int main(int argc, char *argv[]) { int opt, c_flag = 0; CK_SLOT_ID slot_id = 0; char *so_pin = NULL, *user_pin = NULL, *data_store = NULL; CK_FUNCTION_LIST *funcs; CK_ULONG slot_count; CK_SESSION_HANDLE sess; CK_RV rv; struct object *objs_to_migrate = NULL, *tmp, *to_free; int exit_code = 0, rc; lib_csulcca = dlopen("libcsulcca.so", (RTLD_GLOBAL | RTLD_NOW)); if (lib_csulcca == NULL) { print_error("Couldn't get a handle to the CCA library."); return NULL; } CSNDKTC = dlsym(lib_csulcca, "CSNDKTC_32"); CSNBKTC = dlsym(lib_csulcca, "CSNBKTC_32"); while ((opt = getopt(argc, argv, "c:d:s:u:nvh")) != -1) { switch (opt) { case 'c': c_flag++; slot_id = atoi(optarg); break; case 'd': data_store = strdup(optarg); break; case 's': so_pin = strdup(optarg); break; case 'u': user_pin = strdup(optarg); break; case 'n': n_flag++; break; case 'v': v_flag++; break; case 'h': usage(argv[0]); return 0; default: usage(argv[0]); return 1; } } if (!c_flag || !data_store || !so_pin || !user_pin) { usage(argv[0]); return 1; } if (n_flag) printf("Dry-run of migration in progress\n"); funcs = p11_init(); if (!funcs) { return 2; } rv = funcs->C_GetSlotList(TRUE, NULL_PTR, &slot_count); if (rv != CKR_OK) { p11_error("C_GetSlotList", rv); exit_code = 3; goto finalize; } if (slot_id >= slot_count) { print_error("%lu is not a valid slot ID.", slot_id); exit_code = 4; goto finalize; } if (v_flag > 1) printf("Slot id %lu is valid\n", slot_id); /* Open a r/w session */ rv = funcs->C_OpenSession(slot_id, CKF_RW_SESSION|CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &sess); if (rv != CKR_OK) { p11_error("C_OpenSession", rv); exit_code = 5; goto finalize; } if (v_flag > 1) printf("PKCS#11 r/w session opened\n"); /* Login as the SO just validate the supplied pin */ rv = funcs->C_Login(sess, CKU_SO, (CK_BYTE *)so_pin, strlen(so_pin)); if (rv != CKR_OK) { p11_error("C_Login (SO)", rv); exit_code = 6; goto finalize; } if (v_flag > 1) printf("PKCS#11 SO login successful\n"); /* Logout the SO */ rv = funcs->C_Logout(sess); if (rv != CKR_OK) { p11_error("C_Logout", rv); exit_code = 7; goto finalize; } /* Login as the USER to validate the supplied pin and do the migration */ rv = funcs->C_Login(sess, CKU_USER, (CK_BYTE *)user_pin, strlen(user_pin)); if (rv != CKR_OK) { p11_error("C_Login (USER)", rv); exit_code = 8; goto finalize; } if (v_flag > 1) printf("PKCS#11 USER login successful\n"); /* Find the affected PKCS#11 objects */ rc = find_opaque_objects(funcs, sess, &objs_to_migrate); if (rc) { exit_code = 9; goto close; } /* XXX Print status: migrating X pub keys, X priv keys, X 3DES keys... */ /* Use the CCA lib to migrate them to the new master key */ rv = migrate_objects(objs_to_migrate); if (rv != CKR_OK) { exit_code = 10; goto close; } /* XXX Print status */ /* Delete the old PKCS#11 objects (or just attribs if possible) and replace with the * migrated data */ rc = replace_objects(funcs, sess, objs_to_migrate); if (rc) { exit_code = 11; goto close; } /* XXX Print status: X objects successfully migrated */ /* Free the list of PKCS#11 objects */ for (to_free = objs_to_migrate; to_free; to_free = tmp) { tmp = to_free->next; free(to_free->opaque_attr); free(to_free); } /* Migrate the keys used to encrypt the data store */ rc = migrate_master_keys(so_pin, user_pin, data_store); if (rc) { exit_code = 12; goto close; } close: funcs->C_CloseSession(sess); finalize: p11_fini(funcs); return exit_code; } char * p11strerror(CK_RV rc) { switch (rc) { case CKR_OK: return "CKR_OK"; case CKR_CANCEL: return "CKR_CANCEL"; case CKR_HOST_MEMORY: return "CKR_HOST_MEMORY"; case CKR_SLOT_ID_INVALID: return "CKR_SLOT_ID_INVALID"; case CKR_GENERAL_ERROR: return "CKR_GENERAL_ERROR"; case CKR_FUNCTION_FAILED: return "CKR_FUNCTION_FAILED"; case CKR_ARGUMENTS_BAD: return "CKR_ARGUMENTS_BAD"; case CKR_NO_EVENT: return "CKR_NO_EVENT"; case CKR_NEED_TO_CREATE_THREADS: return "CKR_NEED_TO_CREATE_THREADS"; case CKR_CANT_LOCK: return "CKR_CANT_LOCK"; case CKR_ATTRIBUTE_READ_ONLY: return "CKR_ATTRIBUTE_READ_ONLY"; case CKR_ATTRIBUTE_SENSITIVE: return "CKR_ATTRIBUTE_SENSITIVE"; case CKR_ATTRIBUTE_TYPE_INVALID: return "CKR_ATTRIBUTE_TYPE_INVALID"; case CKR_ATTRIBUTE_VALUE_INVALID: return "CKR_ATTRIBUTE_VALUE_INVALID"; case CKR_DATA_INVALID: return "CKR_DATA_INVALID"; case CKR_DATA_LEN_RANGE: return "CKR_DATA_LEN_RANGE"; case CKR_DEVICE_ERROR: return "CKR_DEVICE_ERROR"; case CKR_DEVICE_MEMORY: return "CKR_DEVICE_MEMORY"; case CKR_DEVICE_REMOVED: return "CKR_DEVICE_REMOVED"; case CKR_ENCRYPTED_DATA_INVALID: return "CKR_ENCRYPTED_DATA_INVALID"; case CKR_ENCRYPTED_DATA_LEN_RANGE: return "CKR_ENCRYPTED_DATA_LEN_RANGE"; case CKR_FUNCTION_CANCELED: return "CKR_FUNCTION_CANCELED"; case CKR_FUNCTION_NOT_PARALLEL: return "CKR_FUNCTION_NOT_PARALLEL"; case CKR_FUNCTION_NOT_SUPPORTED: return "CKR_FUNCTION_NOT_SUPPORTED"; case CKR_KEY_HANDLE_INVALID: return "CKR_KEY_HANDLE_INVALID"; case CKR_KEY_SIZE_RANGE: return "CKR_KEY_SIZE_RANGE"; case CKR_KEY_TYPE_INCONSISTENT: return "CKR_KEY_TYPE_INCONSISTENT"; case CKR_KEY_NOT_NEEDED: return "CKR_KEY_NOT_NEEDED"; case CKR_KEY_CHANGED: return "CKR_KEY_CHANGED"; case CKR_KEY_NEEDED: return "CKR_KEY_NEEDED"; case CKR_KEY_INDIGESTIBLE: return "CKR_KEY_INDIGESTIBLE"; case CKR_KEY_FUNCTION_NOT_PERMITTED: return "CKR_KEY_FUNCTION_NOT_PERMITTED"; case CKR_KEY_NOT_WRAPPABLE: return "CKR_KEY_NOT_WRAPPABLE"; case CKR_KEY_UNEXTRACTABLE: return "CKR_KEY_UNEXTRACTABLE"; case CKR_MECHANISM_INVALID: return "CKR_MECHANISM_INVALID"; case CKR_MECHANISM_PARAM_INVALID: return "CKR_MECHANISM_PARAM_INVALID"; case CKR_OBJECT_HANDLE_INVALID: return "CKR_OBJECT_HANDLE_INVALID"; case CKR_OPERATION_ACTIVE: return "CKR_OPERATION_ACTIVE"; case CKR_OPERATION_NOT_INITIALIZED: return "CKR_OPERATION_NOT_INITIALIZED"; case CKR_PIN_INCORRECT: return "CKR_PIN_INCORRECT"; case CKR_PIN_INVALID: return "CKR_PIN_INVALID"; case CKR_PIN_LEN_RANGE: return "CKR_PIN_LEN_RANGE"; case CKR_PIN_EXPIRED: return "CKR_PIN_EXPIRED"; case CKR_PIN_LOCKED: return "CKR_PIN_LOCKED"; case CKR_SESSION_CLOSED: return "CKR_SESSION_CLOSED"; case CKR_SESSION_COUNT: return "CKR_SESSION_COUNT"; case CKR_SESSION_HANDLE_INVALID: return "CKR_SESSION_HANDLE_INVALID"; case CKR_SESSION_PARALLEL_NOT_SUPPORTED: return "CKR_SESSION_PARALLEL_NOT_SUPPORTED"; case CKR_SESSION_READ_ONLY: return "CKR_SESSION_READ_ONLY"; case CKR_SESSION_EXISTS: return "CKR_SESSION_EXISTS"; case CKR_SESSION_READ_ONLY_EXISTS: return "CKR_SESSION_READ_ONLY_EXISTS"; case CKR_SESSION_READ_WRITE_SO_EXISTS: return "CKR_SESSION_READ_WRITE_SO_EXISTS"; case CKR_SIGNATURE_INVALID: return "CKR_SIGNATURE_INVALID"; case CKR_SIGNATURE_LEN_RANGE: return "CKR_SIGNATURE_LEN_RANGE"; case CKR_TEMPLATE_INCOMPLETE: return "CKR_TEMPLATE_INCOMPLETE"; case CKR_TEMPLATE_INCONSISTENT: return "CKR_TEMPLATE_INCONSISTENT"; case CKR_TOKEN_NOT_PRESENT: return "CKR_TOKEN_NOT_PRESENT"; case CKR_TOKEN_NOT_RECOGNIZED: return "CKR_TOKEN_NOT_RECOGNIZED"; case CKR_TOKEN_WRITE_PROTECTED: return "CKR_TOKEN_WRITE_PROTECTED"; case CKR_UNWRAPPING_KEY_HANDLE_INVALID: return "CKR_UNWRAPPING_KEY_HANDLE_INVALID"; case CKR_UNWRAPPING_KEY_SIZE_RANGE: return "CKR_UNWRAPPING_KEY_SIZE_RANGE"; case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT"; case CKR_USER_ALREADY_LOGGED_IN: return "CKR_USER_ALREADY_LOGGED_IN"; case CKR_USER_NOT_LOGGED_IN: return "CKR_USER_NOT_LOGGED_IN"; case CKR_USER_PIN_NOT_INITIALIZED: return "CKR_USER_PIN_NOT_INITIALIZED"; case CKR_USER_TYPE_INVALID: return "CKR_USER_TYPE_INVALID"; case CKR_USER_ANOTHER_ALREADY_LOGGED_IN: return "CKR_USER_ANOTHER_ALREADY_LOGGED_IN"; case CKR_USER_TOO_MANY_TYPES: return "CKR_USER_TOO_MANY_TYPES"; case CKR_WRAPPED_KEY_INVALID: return "CKR_WRAPPED_KEY_INVALID"; case CKR_WRAPPED_KEY_LEN_RANGE: return "CKR_WRAPPED_KEY_LEN_RANGE"; case CKR_WRAPPING_KEY_HANDLE_INVALID: return "CKR_WRAPPING_KEY_HANDLE_INVALID"; case CKR_WRAPPING_KEY_SIZE_RANGE: return "CKR_WRAPPING_KEY_SIZE_RANGE"; case CKR_WRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_WRAPPING_KEY_TYPE_INCONSISTENT"; case CKR_RANDOM_SEED_NOT_SUPPORTED: return "CKR_RANDOM_SEED_NOT_SUPPORTED"; case CKR_RANDOM_NO_RNG: return "CKR_RANDOM_NO_RNG"; case CKR_BUFFER_TOO_SMALL: return "CKR_BUFFER_TOO_SMALL"; case CKR_SAVED_STATE_INVALID: return "CKR_SAVED_STATE_INVALID"; case CKR_INFORMATION_SENSITIVE: return "CKR_INFORMATION_SENSITIVE"; case CKR_STATE_UNSAVEABLE: return "CKR_STATE_UNSAVEABLE"; case CKR_CRYPTOKI_NOT_INITIALIZED: return "CKR_CRYPTOKI_NOT_INITIALIZED"; case CKR_CRYPTOKI_ALREADY_INITIALIZED: return "CKR_CRYPTOKI_ALREADY_INITIALIZED"; case CKR_MUTEX_BAD: return "CKR_MUTEX_BAD"; case CKR_MUTEX_NOT_LOCKED: return "CKR_MUTEX_NOT_LOCKED"; default: return "UNKNOWN"; } return "UNKNOWN"; } opencryptoki-2.3.1+dfsg/usr/sbin/pkcscca_migrate/pkcscca_migrate.sh0000751000175000017500000001113111327631345023301 0ustar jfjf#!/bin/sh # # Script to aid the migration app for an openCryptoki CCA token # # Steps: # 1. Back up the entire data store # 2. Attempt migration # 3. If migration fails, restore the backup # # This will support two versions of openCryptoki, 2.1.7 and the SLES10 # version. The differences are in the location of the executables and # data store. # # Author: Kent Yoder # # The openCryptoki 2.1.7 location CONF_LOC_1=/usr/lib/pkcs11/methods/pkcsconf64 # The openCryptoki SLES10 location CONF_LOC_2=/usr/sbin/pkcsconf64 # The openCryptoki 2.1.7 location STORE_LOC_1=/etc/pkcs11/ccatok # The openCryptoki SLES10 location STORE_LOC_2=/var/lib/opencryptoki/ccatok SO_PIN= USER_PIN= SLOT_ID= PKCSCONF= MIGRATION_APP=/usr/sbin/pkcscca_migrate TAR=/bin/tar BACKUP_DIRNAME="`pwd`" BACKUP_FILENAME="pkcs11_cca_data_backup_`date +%Y%m%d_%H%M%S`.tar.gz" BACKUP_FILE="$BACKUP_DIRNAME/$BACKUP_FILENAME" DATA_STORE= usage() { echo "Usage: $0 " echo echo "Options:" echo echo "--slot-id The slot of the token you wish to migrate" echo "--dry-run Perform the steps without actually writing the migrated data" echo "-v Increase the verbosity of the migration utility" echo exit 255 } backup() { echo "Backing up the data store before we migrate" cd $DATA_STORE # Backup the old store before we begin $TAR zcf $BACKUP_FILE . cd - if ! test -f $BACKUP_FILE; then echo "Unable to perform backup to $BACKUP_FILE" exit 7 fi echo "Wrote backup file: $BACKUP_FILE" } restore() { echo "Restoring from backup..." cd $DATA_STORE rm -rf ./* $TAR zxf $BACKUP_FILE cd - echo "Restore complete." } migrate() { # # Get the USER and SO pins # read -s -p "Please enter this token's USER PIN: " USER_PIN echo read -s -p "Please enter this token's SO PIN: " SO_PIN echo # # Double check the user's entered slot id # $PKCSCONF -s -c $SLOT_ID read -p "About to migrate this token. Continue? [y/N] " RESP if test "x$RESP" != "xy" && test "x$RESP" != "xY"; then echo "Aborted by user." exit 6 fi # # Backup before we begin # backup # # Do the migration using the app # echo "Migrating..." set -x $MIGRATION_APP $DRY_RUN $VERBOSE -c $SLOT_ID -d $DATA_STORE -s $SO_PIN -u $USER_PIN RC=$? set +x if test $RC -ne 0; then echo "Migration failed with return code $RC, restoring from backup." restore # # XXX Give the user some advice based on the error code # echo echo "Migration failed." echo exit $RC fi echo "Success" exit 0 } # # Program execution begins here # P11GROUP=0 for G in `groups` ; do if test "x$G" == "xpkcs11"; then P11GROUP=1 fi done if test $EUID -ne 0 && test $P11GROUP -eq 0; then echo "It appears that you're not root or a member of the pkcs11 group." echo "You may run into trouble when trying to migrate some internal data used by openCryptoki." read -p "Would you like to try anyway? [y/N]? " RESP if test "x$RESP" != "xy" && test "x$RESP" != "xY"; then echo "Aborted." exit 1 fi fi # Find the correct pkcsconf64 if test -x $CONF_LOC_1; then PKCSCONF=$CONF_LOC_1 elif test -x $CONF_LOC_2; then PKCSCONF=$CONF_LOC_2 else echo "Couldn't find pkcsconf64 executable! The following locations were checked:" echo "$CONF_LOC_1" echo "$CONF_LOC_2" echo "Exiting." exit 2 fi # Find the correct data store location if test -d $STORE_LOC_1; then DATA_STORE=$STORE_LOC_1 elif test -d $STORE_LOC_2; then DATA_STORE=$STORE_LOC_2 else echo "Couldn't find data store to archive! The following locations were checked:" echo "$STORE_LOC_1" echo "$STORE_LOC_2" echo "Exiting." exit 3 fi while test "x$1" != "x"; do case "$1" in --slot-id) if test "x$2" == "x"; then usage fi SLOT_ID=$2 shift 2 ;; --dry-run) DRY_RUN="-n" shift ;; -v) VERBOSE="${VERBOSE:-"-"}v" shift ;; *) usage ;; esac done # Get a list of valid slot numbers SLOTS=`$PKCSCONF -s | awk '/Slot #/ {print $2 " "}'` if test "x$SLOT_ID" != "x"; then if test "x${SLOTS/"\#$SLOT_ID "/}" == "x$SLOTS"; then echo "Slot $SLOT_ID is not a valid slot number." exit 4 fi else # No slot provided, display active slots for user to choose from echo "A slot id was not provided, below is a list of the available pkcs11 slots:" echo $PKCSCONF -s echo while : ; do read -p "Which slot would you like to migrate (enter \"x\" to exit)? " RESP test "x$RESP" == "x" && continue test "x$RESP" == "xx" && exit 5 SLOT_ID=$RESP if test "x${SLOTS/"\#$SLOT_ID "/}" == "x$SLOTS"; then echo "Slot $SLOT_ID is not a valid slot number." continue fi break done fi # All is well, begin at migrate migrate opencryptoki-2.3.1+dfsg/usr/sbin/pkcscca_migrate/README.pkcscca_migrate0000640000175000017500000000720611327631345023631 0ustar jfjf README for the CCA secure-key token migration utility The CCA secure-key token migration utility consists of two programs: pkcscca_migrate.sh A shell script that invokes the pkcscca_migrate utility. The script does some data location validation, token validation and token data backup. It is recommended that this script be used to perform the migration. pkcscca_migrate A utility that will migrate all of the CCA token data to the new CCA master key. To use the migration utility, make sure that there are no applications actively using the PKCS#11 interface to the CCA secure-key token by stopping any applications that use the PKCS#11 interface to the CCA secure-key token. Using the pkcsconf64 utility, find/verify the slot number of the CCA secure-key token: pkcsconf64 -s pkcsconf64 -t The CCA secure-key token will have "(CCA)" at the end of the slot description and the token information will identify the token as the "IBM CCA Token." Once you have determined the proper slot number of the CCA secure-key token, invoke the CCA secure-key token migration script: pkcscca_migrate.sh --slot-id X where "X" is the slot number of the CCA secure-key token Optionally, you can specify the "--dry-run" and/or "-v" options on the script invocation. --dry-run This will cause the migration utility to perform all of the steps in the migration but will not commit the changes needed to run under the new CCA master key. Any errors encountered will be reported. -v This will increase the verbosity of the migration utility. Multiple "-v" arguments can be specified to increase the amount of verbose information displayed. Using the pkcscca_migrate.sh script will create a backup copy of the CCA secure-key token data in the openCryptoki main data store directory. Should any errors be encountered during the migration, the original data will be restored. Here is a description of the steps involved in the migration: - The script will check to see if you are running as root or that you are a member of the "pkcs11" group. If neither of these is the case, the script will exit. - The script will look for the pkcsconf64 utility in two locations: /usr/lib/pkcs11/methods or /usr/sbin If the utility is not found, the script will exit. - The script will look for the CCA token data store in two locations: /etc/pkcs11/ccatok or /var/lib/opencryptoki/ccatok If the data store is not found, the script will exit. - The script will then validate the slot number: - If a slot number has been supplied as an argument to the script, it will be verified as a valid slot number. - If a slot number was not supplied as an argument to the script, then the pkcsconf64 utility will be used to display a list of valid slots. You must then choose the slot you wish to migrate. - The Security Office (SO) pin and the User pin are both required for the migration. You will be prompted for both of these pins. - The selected slot information will be displayed and you will be prompted to verify that you want to perform the migration. - The current CCA token data store will be backed up in the current directory. Be sure that you have write access to the current directory. If the backup file cannot be created, the script will exit. - The migration utility, pkcscca_migrate, will be invoked to perform the actual migration. Any errors encountered will be reported. - Should an error have been encountered during the migration, the CCA token data store will be restored from the backup that was created earlier. - If no errors have been encountered, then the migration has been successful. opencryptoki-2.3.1+dfsg/usr/sbin/pkcscca_migrate/cca_migrate.h0000640000175000017500000000445511327631345022245 0ustar jfjf /* * Licensed materials - Property of IBM * * pkcs11_migrate - A tool to migrate PKCS#11 CCA key objects from one * master key to another. * * Copyright (C) International Business Machines Corp. 2007 * */ #ifndef __CCA_MIGRATE_H_ #define __CCA_MIGRATE_H_ #define SHA1_HASH_SIZE 20 #define CCA_KEY_ID_SIZE 64 #define MASTER_KEY_SIZE CCA_KEY_ID_SIZE #define DES_BLOCK_SIZE 8 #define DES_KEY_SIZE 8 #define MD5_HASH_SIZE 16 #define CCA_SUCCESS 0 #define RSA_NAME "RSA" #define DES_NAME "DES" #define DES3_NAME "3DES" #define BAD_NAME "Unknown" CK_RV sw_des3_cbc(CK_BYTE *, CK_ULONG, CK_BYTE *, CK_ULONG *, CK_BYTE *, CK_BYTE *, CK_BYTE); #define sw_des3_cbc_encrypt(clear, len, cipher, len2, iv, key) \ sw_des3_cbc(clear, len, cipher, len2, iv, key, 1) #define sw_des3_cbc_decrypt(clear, len, cipher, len2, iv, key) \ sw_des3_cbc(clear, len, cipher, len2, iv, key, 0) typedef struct _MASTER_KEY_FILE_T { CK_BYTE key[MASTER_KEY_SIZE]; CK_BYTE sha_hash[SHA1_HASH_SIZE]; } MASTER_KEY_FILE_T; #define EVP_SUCCESS 1 #define HASH_SHA1 1 #define HASH_MD5 2 #define print_openssl_errors() \ do { \ ERR_load_crypto_strings(); \ ERR_print_errors_fp(stderr); \ } while (0) int compute_hash(int hash_type, int buf_size, char* buf, char* digest); #define compute_sha(a,b,c) compute_hash(HASH_SHA1,b,a,c) #define compute_md5(a,b,c) compute_hash(HASH_MD5,b,a,c) char *p11strerror(CK_RV); #define p11_error(s,rc) fprintf(stderr, "%s:%d %s failed: rc=0x%lX (%s)\n", __FILE__, \ __LINE__, s, rc, p11strerror(rc)) #define print_error(x, ...) fprintf(stderr, "%s:%d " x "\n", __FILE__, __LINE__, ##__VA_ARGS__) #define cca_error(f,rc,rsn) fprintf(stderr, "%s:%d " f " failed. return code: %ld, reason" \ "code: %ld\n", __FILE__, __LINE__, rc, rsn) #define print_hex(x, y) \ do { \ unsigned char *hex = x; \ int i; \ for (i = 0; i < y; i++) { \ printf("%02x", hex[i]); \ if (((i+1) % 32) == 0) \ printf("\n"); \ else if (((i+1) % 4) == 0) \ printf(" "); \ } \ } while (0) struct object { CK_OBJECT_HANDLE handle; CK_ULONG type; CK_BYTE *opaque_attr; CK_ULONG attr_len; struct object *next; }; CK_RV load_masterkey(char *path, char *pin_md5, char *master_key); CK_RV save_masterkey(char *path, char *pin_md5, char *master_key); #endif opencryptoki-2.3.1+dfsg/usr/sbin/pkcscca_migrate/Makefile.am0000640000175000017500000000063011327631345021661 0ustar jfjf sbin_PROGRAMS=pkcscca_migrate sbin_SCRIPTS=pkcscca_migrate.sh pkcscca_migrate_SOURCES = cca_migrate.c loadsave_cca.c pkcscca_migrate_CFLAGS = -DSPINXPL -DLINUX -DPROGRAM_NAME=\"$(@)\" -DNOODM -DNODAE pkcscca_migrate_LDFLAGS = -lcrypto -ldl # Not all versions of automake observe sbinname_CFLAGS AM_CFLAGS = -DSPINXPL -DLINUX -DPROGRAM_NAME=\"$(@)\" -DNOODM -DNODAE INCLUDES = -I. -I../../include/pkcs11 opencryptoki-2.3.1+dfsg/usr/sbin/pkcscca_migrate/loadsave_cca.c0000640000175000017500000001524211327631345022402 0ustar jfjf/* * Licensed materials - Property of IBM * * pkcs11_migrate - A tool to migrate PKCS#11 CCA key objects from one * master key to another. * * Copyright (C) International Business Machines Corp. 2007 * */ #include #include #include #include #include #include #include #include #include #include #include #include "cca_migrate.h" CK_RV sw_des3_cbc(CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *init_v, CK_BYTE *key_value, CK_BYTE encrypt) { des_key_schedule des_key1; des_key_schedule des_key2; des_key_schedule des_key3; const_des_cblock key_SSL1, key_SSL2, key_SSL3; des_cblock ivec; // the des decrypt will only fail if the data length is not evenly divisible // by 8 if (in_data_len % 8) { print_error("Data not a multiple of 8"); return CKR_DATA_LEN_RANGE; } // The key as passed in is a 24 byte string containing 3 keys // pick it apart and create the key schedules memcpy(&key_SSL1, key_value, (size_t)8); memcpy(&key_SSL2, key_value+8, (size_t)8); memcpy(&key_SSL3, key_value+16, (size_t)8); des_set_key_unchecked(&key_SSL1, des_key1); des_set_key_unchecked(&key_SSL2, des_key2); des_set_key_unchecked(&key_SSL3, des_key3); memcpy(ivec, init_v, sizeof(ivec)); // Encrypt or decrypt the data if (encrypt) { des_ede3_cbc_encrypt(in_data, out_data, in_data_len, des_key1, des_key2, des_key3, &ivec, DES_ENCRYPT); *out_data_len = in_data_len; } else { des_ede3_cbc_encrypt(in_data, out_data, in_data_len, des_key1, des_key2, des_key3, &ivec, DES_DECRYPT); *out_data_len = in_data_len; } return CKR_OK; } CK_RV add_pkcs_padding(CK_BYTE *ptr, CK_ULONG block_size, CK_ULONG data_len, CK_ULONG total_len) { CK_ULONG i, pad_len; CK_BYTE pad_value; pad_len = block_size - (data_len % block_size); pad_value = (CK_BYTE)pad_len; if (data_len + pad_len > total_len){ print_error("Padding error"); return CKR_FUNCTION_FAILED; } for (i = 0; i < pad_len; i++) ptr[i] = pad_value; return CKR_OK; } int compute_hash(int hash_type, int buf_size, char *buf, char *digest) { EVP_MD_CTX md_ctx; unsigned int result_size; int rv; switch (hash_type) { case HASH_SHA1: rv = EVP_DigestInit(&md_ctx, EVP_sha1()); break; case HASH_MD5: rv = EVP_DigestInit(&md_ctx, EVP_md5()); break; default: rv = 1; goto out; break; } if (rv != EVP_SUCCESS) { rv = 2; goto err; } rv = EVP_DigestUpdate(&md_ctx, buf, buf_size); if (rv != EVP_SUCCESS) { rv = 3; goto err; } result_size = EVP_MD_CTX_size(&md_ctx); rv = EVP_DigestFinal(&md_ctx, (unsigned char *)digest, &result_size); if (rv != EVP_SUCCESS) { rv = 4; goto err; } else rv = 0; goto out; err: print_openssl_errors(); out: return rv; } CK_RV load_masterkey(char *path, char *pin_md5, char *master_key) { FILE * fp = NULL; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_BYTE cipher[sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE clear[sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE des3_key[3 * DES_KEY_SIZE]; MASTER_KEY_FILE_T mk; CK_ULONG cipher_len, clear_len;//, hash_len; CK_RV rc; memset( master_key, 0x0, MASTER_KEY_SIZE ); // this file gets created on C_InitToken so we can assume that it always exists // fp = fopen(path, "r" ); if (!fp) { print_error("Error opening master key file: %s", path); rc = CKR_FUNCTION_FAILED; goto done; } clear_len = cipher_len = (sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE - 1) & ~(DES_BLOCK_SIZE - 1); rc = fread( cipher, cipher_len, 1, fp ); if (rc != 1) { print_error("Error reading master key file: %s", path); rc = CKR_FUNCTION_FAILED; goto done; } // decrypt the master key data using the MD5 of the pin // (we can't use the SHA of the pin since the SHA of the pin is stored // in the token data file). // memcpy( des3_key, pin_md5, MD5_HASH_SIZE ); memcpy( des3_key + MD5_HASH_SIZE, pin_md5, DES_KEY_SIZE ); rc = sw_des3_cbc_decrypt( cipher, cipher_len, clear, &clear_len, (CK_BYTE *)"12345678", des3_key ); if (rc != CKR_OK){ print_error("Error decrypting master key file after read"); goto done; } memcpy( (CK_BYTE *)&mk, clear, sizeof(mk) ); // // technically should strip PKCS padding here but since I already know what // the length should be, I don't bother. // // compare the hashes // rc = compute_sha( (char *)mk.key, MASTER_KEY_SIZE, (char *)hash_sha ); if (rc) { print_error("Error computing SHA1 of master key after read: %s", path); } if (memcmp(hash_sha, mk.sha_hash, SHA1_HASH_SIZE) != 0) { print_error("Hash of loaded master key %s doesn't match!", path); rc = CKR_FUNCTION_FAILED; goto done; } memcpy( master_key, mk.key, MASTER_KEY_SIZE ); rc = CKR_OK; done: if (fp) fclose(fp); return rc; } CK_RV save_masterkey(char *path, char *pin_md5, char *master_key) { FILE * fp = NULL; CK_BYTE cleartxt [sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE ciphertxt[sizeof(MASTER_KEY_FILE_T) + DES_BLOCK_SIZE]; CK_BYTE des3_key[3 * DES_KEY_SIZE]; MASTER_KEY_FILE_T mk; CK_ULONG cleartxt_len, ciphertxt_len, padded_len; CK_RV rc; memcpy(mk.key, master_key, MASTER_KEY_SIZE); rc = compute_sha(master_key, MASTER_KEY_SIZE, (char *)mk.sha_hash); if (rc) { print_error("Error computing SHA1 of master key before write"); goto done; } // encrypt the key data // memcpy( des3_key, pin_md5, MD5_HASH_SIZE ); memcpy( des3_key + MD5_HASH_SIZE, pin_md5, DES_KEY_SIZE ); ciphertxt_len = sizeof(ciphertxt); cleartxt_len = sizeof(mk); memcpy(cleartxt, &mk, cleartxt_len); padded_len = DES_BLOCK_SIZE * (cleartxt_len / DES_BLOCK_SIZE + 1); add_pkcs_padding(cleartxt + cleartxt_len, DES_BLOCK_SIZE, cleartxt_len, padded_len); rc = sw_des3_cbc_encrypt(cleartxt, padded_len, ciphertxt, &ciphertxt_len, (CK_BYTE *)"12345678", des3_key); if (rc != CKR_OK){ print_error("Error encrypting master key before write"); goto done; } // write the file // // probably ought to ensure the permissions are correct // fp = fopen(path, "w" ); if (!fp) { print_error("Error opening master key file for write: %s", path); rc = CKR_FUNCTION_FAILED; goto done; } rc = fwrite( ciphertxt, ciphertxt_len, 1, fp ); if (rc != 1) { print_error("Error writing master key: %s", path); rc = CKR_FUNCTION_FAILED; goto done; } rc = CKR_OK; done: if (fp) fclose(fp); return rc; } opencryptoki-2.3.1+dfsg/usr/sbin/Makefile.am0000640000175000017500000000015211327631345016541 0ustar jfjf if CCA CCA_APP = pkcscca_migrate endif SUBDIRS = pkcsslotd pkcs11_startup pkcs_slot pkcsconf $(CCA_APP) opencryptoki-2.3.1+dfsg/usr/sbin/pkcs11_startup/0000751000175000017500000000000011327631345017373 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/sbin/pkcs11_startup/pkcs11_startup.in0000640000175000017500000004521711327631345022620 0ustar jfjf#!/bin/bash # # # $Header: /cvsroot/opencryptoki/opencryptoki/usr/sbin/pkcs11_startup/pkcs11_startup.in,v 1.4 2007/11/08 22:06:17 kyoder Exp $ # # # Common Public License Version 0.5 # THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF # THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, # REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES # RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. # # 1. DEFINITIONS # # "Contribution" means: # a) in the case of the initial Contributor, the # initial code and documentation distributed under # this Agreement, and # # b) in the case of each subsequent Contributor: # i) changes to the Program, and # ii) additions to the Program; # # where such changes and/or additions to the Program # originate from and are distributed by that # particular Contributor. A Contribution 'originates' # from a Contributor if it was added to the Program # by such Contributor itself or anyone acting on such # Contributor's behalf. Contributions do not include # additions to the Program which: (i) are separate # modules of software distributed in conjunction with # the Program under their own license agreement, and # (ii) are not derivative works of the Program. # # # "Contributor" means any person or entity that distributes # the Program. # # "Licensed Patents " mean patent claims licensable by a # Contributor which are necessarily infringed by the use or # sale of its Contribution alone or when combined with the # Program. # # "Program" means the Contributions distributed in # accordance with this Agreement. # # "Recipient" means anyone who receives the Program under # this Agreement, including all Contributors. # # 2. GRANT OF RIGHTS # # a) Subject to the terms of this Agreement, each # Contributor hereby grants Recipient a # non-exclusive, worldwide, royalty-free copyright # license to reproduce, prepare derivative works of, # publicly display, publicly perform, distribute and # sublicense the Contribution of such Contributor, if # any, and such derivative works, in source code and # object code form. # # b) Subject to the terms of this Agreement, each # Contributor hereby grants Recipient a # non-exclusive, worldwide, royalty-free patent # license under Licensed Patents to make, use, sell, # offer to sell, import and otherwise transfer the # Contribution of such Contributor, if any, in source # code and object code form. This patent license # shall apply to the combination of the Contribution # and the Program if, at the time the Contribution is # added by the Contributor, such addition of the # Contribution causes such combination to be covered # by the Licensed Patents. The patent license shall # not apply to any other combinations which include # the Contribution. No hardware per se is licensed # hereunder. # # c) Recipient understands that although each ## Contributor grants the licenses to its # Contributions set forth herein, no assurances are # provided by any Contributor that the Program does # not infringe the patent or other intellectual # property rights of any other entity. Each # Contributor disclaims any liability to Recipient # for claims brought by any other entity based on # infringement of intellectual property rights or # otherwise. As a condition to exercising the rights # and licenses granted hereunder, each Recipient # hereby assumes sole responsibility to secure any # other intellectual property rights needed, if any. # # For example, if a third party patent license is # required to allow Recipient to distribute the # Program, it is Recipient's responsibility to # acquire that license before distributing the # Program. # # d) Each Contributor represents that to its # knowledge it has sufficient copyright rights in its # Contribution, if any, to grant the copyright # license set forth in this Agreement. # # 3. REQUIREMENTS # # A Contributor may choose to distribute the Program in # object code form under its own license agreement, provided # that: # a) it complies with the terms and conditions of # this Agreement; and # # b) its license agreement: # i) effectively disclaims on behalf of all # Contributors all warranties and conditions, express # and implied, including warranties or conditions of # title and non-infringement, and implied warranties # or conditions of merchantability and fitness for a # particular purpose; # # ii) effectively excludes on behalf of all # Contributors all liability for damages, including # direct, indirect, special, incidental and # consequential damages, such as lost profits; # # iii) states that any provisions which differ from # this Agreement are offered by that Contributor # alone and not by any other party; and # # iv) states that source code for the Program is # available from such Contributor, and informs # licensees how to obtain it in a reasonable manner # on or through a medium customarily used for # software exchange. # # When the Program is made available in source code form: # a) it must be made available under this Agreement; # and # b) a copy of this Agreement must be included with # each copy of the Program. # # Contributors may not remove or alter any copyright notices # contained within the Program. # # Each Contributor must identify itself as the originator of # its Contribution, if any, in a manner that reasonably # allows subsequent Recipients to identify the originator of # the Contribution. # # # 4. COMMERCIAL DISTRIBUTION # # Commercial distributors of software may accept certain # responsibilities with respect to end users, business # partners and the like. While this license is intended to # facilitate the commercial use of the Program, the # Contributor who includes the Program in a commercial # product offering should do so in a manner which does not # create potential liability for other Contributors. # Therefore, if a Contributor includes the Program in a # commercial product offering, such Contributor ("Commercial # Contributor") hereby agrees to defend and indemnify every # other Contributor ("Indemnified Contributor") against any # losses, damages and costs (collectively "Losses") arising # from claims, lawsuits and other legal actions brought by a # third party against the Indemnified Contributor to the # extent caused by the acts or omissions of such Commercial # Contributor in connection with its distribution of the # Program in a commercial product offering. The obligations # in this section do not apply to any claims or Losses # relating to any actual or alleged intellectual property # infringement. In order to qualify, an Indemnified # Contributor must: a) promptly notify the Commercial # Contributor in writing of such claim, and b) allow the # Commercial Contributor to control, and cooperate with the # Commercial Contributor in, the defense and any related # settlement negotiations. The Indemnified Contributor may # participate in any such claim at its own expense. # # # For example, a Contributor might include the Program in a # commercial product offering, Product X. That Contributor # is then a Commercial Contributor. If that Commercial # Contributor then makes performance claims, or offers # warranties related to Product X, those performance claims # and warranties are such Commercial Contributor's # responsibility alone. Under this section, the Commercial # Contributor would have to defend claims against the other # Contributors related to those performance claims and # warranties, and if a court requires any other Contributor # to pay any damages as a result, the Commercial Contributor # must pay those damages. # # # 5. NO WARRANTY # # EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE # PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR # IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR # CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR # FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely # responsible for determining the appropriateness of using # and distributing the Program and assumes all risks # associated with its exercise of rights under this # Agreement, including but not limited to the risks and # costs of program errors, compliance with applicable laws, # damage to or loss of data, programs or equipment, and # unavailability or interruption of operations. # # 6. DISCLAIMER OF LIABILITY # EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER # RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, # OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION # LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE # OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGES. # # 7. GENERAL # # If any provision of this Agreement is invalid or # unenforceable under applicable law, it shall not affect # the validity or enforceability of the remainder of the # terms of this Agreement, and without further action by the # parties hereto, such provision shall be reformed to the # minimum extent necessary to make such provision valid and # enforceable. # # # If Recipient institutes patent litigation against a # Contributor with respect to a patent applicable to # software (including a cross-claim or counterclaim in a # lawsuit), then any patent licenses granted by that # Contributor to such Recipient under this Agreement shall # terminate as of the date such litigation is filed. In # addition, If Recipient institutes patent litigation # against any entity (including a cross-claim or # counterclaim in a lawsuit) alleging that the Program # itself (excluding combinations of the Program with other # software or hardware) infringes such Recipient's # patent(s), then such Recipient's rights granted under # Section 2(b) shall terminate as of the date such # litigation is filed. # # All Recipient's rights under this Agreement shall # terminate if it fails to comply with any of the material # terms or conditions of this Agreement and does not cure # such failure in a reasonable period of time after becoming # aware of such noncompliance. If all Recipient's rights # under this Agreement terminate, Recipient agrees to cease # use and distribution of the Program as soon as reasonably # practicable. However, Recipient's obligations under this # Agreement and any licenses granted by Recipient relating # to the Program shall continue and survive. # # Everyone is permitted to copy and distribute copies of # this Agreement, but in order to avoid inconsistency the # Agreement is copyrighted and may only be modified in the # following manner. The Agreement Steward reserves the right # to publish new versions (including revisions) of this # Agreement from time to time. No one other than the # Agreement Steward has the right to modify this Agreement. # # IBM is the initial Agreement Steward. IBM may assign the # responsibility to serve as the Agreement Steward to a # suitable separate entity. Each new version of the # Agreement will be given a distinguishing version number. # The Program (including Contributions) may always be # distributed subject to the version of the Agreement under # which it was received. In addition, after a new version of # the Agreement is published, Contributor may elect to # distribute the Program (including its Contributions) under # the new version. Except as expressly stated in Sections # 2(a) and 2(b) above, Recipient receives no rights or # licenses to the intellectual property of any Contributor # under this Agreement, whether expressly, by implication, # estoppel or otherwise. All rights in the Program not # expressly granted under this Agreement are reserved. # # # This Agreement is governed by the laws of the State of New # York and the intellectual property laws of the United # States of America. No party to this Agreement will bring a # legal action under this Agreement more than one year after # the cause of action arose. Each party waives its rights to # a jury trial in any resulting litigation. # # # #*/ # #/* (C) COPYRIGHT International Business Machines Corp. 2001 */ # this is the Linux and NON-ODM startup script # Get the operating System.... Everything else falls into that # Get a list of crypto adapters and set error code to 0 CARDS=`ls /dev/crypt* 2>/dev/null | sed s?\/dev\/??g 2>/dev/null` ERRORS=0 STATCOMMAND=/usr/lib/pkcs11/methods/4758_status rm -f @CONFIG_PATH@/@CONFIG_FILE@ >/dev/null 2>&1 # always whack the entire config file and build # it from scratch # Create the pkcs11 group if it does not exist... cat /etc/group|grep pkcs11 >/dev/null 2>&1 rc=$? if [ $rc = 1 ] then if [ -x @GROUPADD@ ] then @GROUPADD@ pkcs11 >/dev/null 2>&1 else echo "Couldn't execute @GROUPADD@. Please add the group 'pkcs11' manually." fi fi if [ -x @USERMOD@ -a -x @ID@ ] then # add the pkcs group # replace spaces by commas @USERMOD@ -G $( @ID@ --groups --name root | /bin/sed -e 'y/ /,/'),pkcs11 root else echo "Couldn't execute @USERMOD@. Please add root to the group 'pkcs11' manually." fi # For each card run the status command and if successful # create the odm stanza for the file if [ -x $STATCOMMAND ] then for i in $CARDS do $STATCOMMAND -c $i RC=$? if [ $RC = 101 ] then # need to make this the minor number of the device only x=`ls -l /dev/$i | awk '{ print $6 }'` @METHOD_PATH@/pkcs_slot $x deep elif [ $RC = 102 ] then # SAB XXX Need to get the groups created elsewhere # actually we should build the correlator list here # and pass the list in all at once x=`ls -l /dev/$i | awk '{ print $6 }'` if [ -z $CORRLIST ] then CORRLIST="${x}" else CORRLIST="${CORRLIST},${x}" fi fi done fi # Add the TPM device automatically if it exists if [ -f @STDLL_PATH@/libpkcs11_tpm.so ] then @METHOD_PATH@/pkcs_slot 0 tpm fi # Addition for AEP Devices if [ -f @STDLL_PATH@/PKCS11_AEP.so ] then /bin/cat /proc/devices | grep paep >/dev/null 2>&1 rc=$? if [ $rc = 0 ] then @METHOD_PATH@/pkcs_slot 0 aep fi fi # Add the ICA device if it exists # Starting from version 1.3, libica supports software # fallback when no specialized hardware is found, so # we default for including the ica token when it's # stdll is present (s390x by default) - KlausK Jul'09 if [ -f @STDLL_PATH@/libpkcs11_ica.so ] then @METHOD_PATH@/pkcs_slot 0 ica fi #add the broadcom device if [ -f @STDLL_PATH@/PKCS11_BC.so ] then /bin/cat /proc/devices | grep cryptonet >/dev/null 2>&1 rc=$? if [ $rc = 0 ] then @METHOD_PATH@/pkcs_slot 0 bcom fi fi #add the Corrent device if [ -f @STDLL_PATH@/PKCS11_CR.so ] then /bin/cat /proc/misc | grep cr702x >/dev/null 2>&1 rc=$? if [ $rc = 0 ] then @METHOD_PATH@/pkcs_slot 0 cr fi fi # add the CCA token # CCA stdll is always built by default in supported archs, so check for both # the CCA stdll *and* for a library needed by the CCA token - KlausK Jul'09 # The libraries required by CCA token are provided by the 'xcryptolinzGA' # RPM package, available from the IBM web site. if [ -f @STDLL_PATH@/libpkcs11_cca.so ] && [ -f /usr/lib64/libcsulmkapi.so.1 ] then @METHOD_PATH@/pkcs_slot 0 cca fi # Add the SW token last, so that "dumb" apps that always open # slot 0 will get a HW token if one exists if [ -f @STDLL_PATH@/libpkcs11_sw.so ] then @METHOD_PATH@/pkcs_slot 0 soft fi if [ $ERRORS -ne 0 ] then exit -1 fi exit 0 opencryptoki-2.3.1+dfsg/usr/sbin/pkcs11_startup/Makefile.am0000640000175000017500000000003611327631345021426 0ustar jfjfsbin_SCRIPTS = pkcs11_startup opencryptoki-2.3.1+dfsg/usr/sbin/pkcsconf/0000751000175000017500000000000011327631345016315 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/sbin/pkcsconf/pkcsconf_msg.h0000751000175000017500000004126711327631345021157 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/sbin/pkcsconf/pkcsconf_msg.h,v 1.1 2005/04/11 20:22:18 mhalcrow Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #ifndef _H_PKCSCONF_MSG #define _H_PKCSCONF_MSG #include #include #define MF_PKCSCONF "pkcsconf.cat" /* The following was generated from ../../../../../../../../src/bos/usr/lib/pkcs11/methods/pkcsconf/pkcsconf.msg. */ /* definitions for set MS_PKCSINIT */ #define MS_PKCSINIT 1 #define EXCLUSION 1 #define SOPIN 2 #define USERPIN 3 #define NEWUSER 4 #define NEWSO 5 #define VNEWUSER 6 #define VNEWSO 7 #define GETLABEL 8 #define INCORRECTPIN 9 #define PINMISMATCH 10 #define SHMEM 11 #define SLOTNUMS 12 #define SLOTNUM 13 #define PRESENT 14 #define DLLLOC 15 #define INITFCN 16 #define COORELATE 17 #define GLOBAL 18 #define INFOERROR 19 #define PKCSINFO 20 #define VVERSION 21 #define MANUFACT 22 #define FLAGS 23 #define LIBDESCRIPT 24 #define LIBVERSION 25 #define SLOTERROR 26 #define LISTERROR 27 #define MECHERROR 28 #define LISTERROR2 29 #define INFOERROR2 30 #define MECH 31 #define MECHLABEL 32 #define KEYSIZE 33 #define SLOTERROR2 34 #define SLOTINFO 35 #define SLOTDESC 36 #define HWVERSION 37 #define FWVERSION 38 #define TOKERROR 39 #define TOKINFO 40 #define TOKLABEL 41 #define MODEL 42 #define SERIAL 43 #define SESSIONS 44 #define RWSESSIONS 45 #define PINLEN 46 #define PUBMEM 47 #define PRIVMEM 48 #define TIME 49 #define INITERROR 50 #define OPENERROR 51 #define LOGINERROR 52 #define SETPIN 53 #define LOGOUTERROR 54 #define CLOSEERROR 55 #define LOADERROR 56 #define FUNCTERROR 57 #define LIBERROR 58 #define SLOTMGRERROR 59 #define INVALIDCARD 60 #define USAGE 61 #define USAGE1 62 #define USAGE2 63 #define USAGE3 64 #define USAGE4 65 #define USAGE5 66 #define USAGE6 67 #define USAGE7 68 #define USAGE8 69 #define USAGE9 70 #endif opencryptoki-2.3.1+dfsg/usr/sbin/pkcsconf/pkcsconf.c0000751000175000017500000014662011327631345020303 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "slotmgr.h" #include "pkcsconf_msg.h" #define MSG_SET MS_PKCSINIT nl_catd catd; #define PKCSINIT_MSG(n,s) catgets(catd,MSG_SET,n,s) #define LEEDS_DEFAULT_PIN "87654321" #define PIN_SIZE 80 #define BACK_SPACE 8 #define DELETE 127 #define LINE_FEED 10 #define CFG_SO_PIN 0x0001 #define CFG_USER_PIN 0x0002 #define CFG_SLOT 0x0004 #define CFG_PKCS_INFO 0x0008 #define CFG_TOKEN_INFO 0x0010 #define CFG_SLOT_INFO 0x0020 #define CFG_MECHANISM_INFO 0x0040 #define CFG_INITIALIZE 0x0080 #define CFG_INIT_USER 0x0100 #define CFG_SET_USER 0x0200 #define CFG_SET_SO 0x0400 #define CFG_NEW_PIN 0x0800 #define CFG_SHARED_MEM 0x1000 #define CFG_LIST_SLOT 0x2000 CK_RV init(void); void usage(char *); int echo(int); int get_pin(CK_CHAR **); CK_RV cleanup(void); CK_RV display_pkcs11_info(void); CK_RV get_slot_list(int, CK_CHAR_PTR); CK_RV display_slot_info(void); CK_RV display_token_info(void); CK_RV display_mechanism_info(void); void display_shared_memory(void); void *attach_shared_memory(void); void detach_shared_memory(char *); CK_RV validate_slot(CK_CHAR_PTR); CK_RV init_token(CK_CHAR_PTR); CK_RV init_user_pin(CK_CHAR_PTR, CK_CHAR_PTR); CK_RV list_slot(void); CK_RV set_user_pin(CK_USER_TYPE, CK_CHAR_PTR, CK_CHAR_PTR); void * dllPtr; CK_FUNCTION_LIST_PTR FunctionPtr = NULL; CK_SLOT_ID_PTR SlotList = NULL; CK_ULONG SlotCount = 0; Slot_Mgr_Shr_t * shmp = NULL; int in_slot; int main(int argc, char *argv[]){ CK_RV rc = CKR_OK; // Return Code CK_FLAGS flags = 0; // Bit mask for what options were passed in CK_CHAR_PTR sopin = NULL, // The Security Office PIN pin = NULL, // The User PIN newpin = NULL, // To store PIN changes newpin2 = NULL, // To store validation of PIN change slot = NULL; // The PKCS slot number int c, // To store passed in options newpinlen, newpin2len, errflag = 0; // Error Flag /* Open the Message Catalog */ setlocale(LC_ALL, ""); catd = catopen(MF_PKCSCONF,0); /* Parse the command line parameters */ while ((c = getopt (argc, argv, "itsmMIc:S:U:upPn:l")) != (-1)){ switch (c){ case 'c': /* a specific card (slot) is specified */ flags |= CFG_SLOT; slot = (CK_CHAR_PTR) malloc(strlen(optarg)); memcpy(slot, optarg, strlen(optarg)); break; case 'S': /* the SO pin */ flags |= CFG_SO_PIN; sopin = (CK_CHAR_PTR) malloc(strlen(optarg)); memcpy(sopin, optarg, strlen(optarg)); break; case 'U': /* the user pin */ flags |= CFG_USER_PIN; pin = (CK_CHAR_PTR) malloc(strlen(optarg)); memcpy(pin, optarg, strlen(optarg)); break; case 'n': /* the new pin */ flags |= CFG_NEW_PIN; newpin = (CK_CHAR_PTR) malloc(strlen(optarg)); memcpy(newpin, optarg, strlen(optarg)); break; case 'i': /* display PKCS11 info */ flags |= CFG_PKCS_INFO; break; case 't': /* display token info */ flags |= CFG_TOKEN_INFO; break; case 's': /* display slot info */ flags |= CFG_SLOT_INFO; break; case 'm': /* display mechanism info */ flags |= CFG_MECHANISM_INFO; break; #if SHM case 'M': /* display shared memory */ flags |= CFG_SHARED_MEM; break; #endif case 'I': /* initialize the token */ flags |= CFG_INITIALIZE; break; case 'u': /* initialize the user PIN */ flags |= CFG_INIT_USER; break; case 'p': /* set the user PIN */ flags |= CFG_SET_USER; break; case 'P': /* set the SO PIN */ flags |= CFG_SET_SO; break; case 'l': /* display slot description */ flags |= CFG_LIST_SLOT; break; default: /* if something else was passed in it is an error */ errflag++; break; } } if (errflag != 0) /* If there was an error print the usage statement */ usage(argv[0]); /* Eliminate the ability to specify -I -p -u -P without a slot number */ if ( (flags & (CFG_INITIALIZE | CFG_INIT_USER | CFG_SET_USER | CFG_SET_SO)) && !(flags & CFG_SLOT)){ usage(argv[0]); } /* Load the PKCS11 library and start the slotmanager if it is not running */ if ( init() != CKR_OK ) exit(-1); #if SHM /* If a slot number was passed in validate the slot number */ if (flags & CFG_SLOT) validate_slot(slot); #else if (flags & CFG_SLOT) { in_slot = atol((char *)slot); } #endif /* Get the slot list and indicate if a slot number was passed in or not */ if (get_slot_list(flags & CFG_SLOT, slot)) goto done; /* If the user tries to set the user and SO pin at the same time print an * error massage and exit indicating the function failed */ if ((flags & CFG_SET_USER) && (flags & CFG_SET_SO)) { printf(PKCSINIT_MSG(EXCLUSION, "Setting the SO and user PINs are mutually exclusive.\n")); fflush(stdout); return CKR_FUNCTION_FAILED; } /* If the user wants to display PKCS11 info call the function to do so */ if (flags & CFG_PKCS_INFO) display_pkcs11_info(); /* If the user wants to display token info call the function to do so */ if (flags & CFG_TOKEN_INFO) display_token_info(); /* If the user wants to display slot info call the function to do so */ if (flags & CFG_SLOT_INFO) display_slot_info(); /* If the user wants to display slot info call the function to do so */ if (flags & CFG_LIST_SLOT) list_slot(); /* If the user wants to display mechanism info call the function to do so */ if (flags & CFG_MECHANISM_INFO) display_mechanism_info(); #if SHM /* If the user wants to display shared memory info call the function to do so */ if (flags & CFG_SHARED_MEM) display_shared_memory(); #endif /* If the user wants to initialize the card check to see if they passed in * the SO pin, if not ask for the PIN */ if (flags & CFG_INITIALIZE){ if (~flags & CFG_SO_PIN){ int rc; do { printf(PKCSINIT_MSG(SOPIN, "Enter the SO PIN: ")); fflush(stdout); rc = get_pin(&(sopin)); } while (rc == -EINVAL); } rc = init_token(sopin); } /* If the user wants to initialize the User PIN, check to see if they have * passed in the SO PIN, if not ask for it. Then check to see if they passed * the New User PIN on the command line if not ask for the PIN and verify it */ if (flags & CFG_INIT_USER){ if (~flags & CFG_SO_PIN) { int rc; do { printf(PKCSINIT_MSG(SOPIN, "Enter the SO PIN: ")); fflush(stdout); rc = get_pin(&sopin); } while (rc == -EINVAL); } if (~flags & CFG_NEW_PIN) { int rc; do { printf(PKCSINIT_MSG(NEWUSER, "Enter the new user PIN: ")); fflush(stdout); rc = get_pin(&newpin); } while (rc == -EINVAL); newpinlen = strlen(newpin); do { printf(PKCSINIT_MSG(VNEWUSER, "Re-enter the new user PIN: ")); fflush(stdout); rc = get_pin(&newpin2); } while (rc == -EINVAL); newpin2len = strlen(newpin2); if (newpinlen != newpin2len || memcmp(newpin, newpin2, strlen((char *)newpin)) != 0) { printf(PKCSINIT_MSG(PINMISMATCH, "New PINs do not match.\n")); fflush(stdout); exit(CKR_PIN_INVALID); } } rc = init_user_pin(newpin, sopin); } /* If the user wants to set the SO PIN, check to see if they have passed the * current SO PIN and the New PIN in. If not prompt and validate them. */ if (flags & CFG_SET_SO){ if (~flags & CFG_SO_PIN) { int rc; do { printf(PKCSINIT_MSG(SOPIN, "Enter the SO PIN: ")); fflush(stdout); rc = get_pin(&sopin); } while (rc == -EINVAL); } if (~flags & CFG_NEW_PIN) { int rc; do { printf(PKCSINIT_MSG(NEWSO, "Enter the new SO PIN: ")); fflush(stdout); rc = get_pin(&newpin); } while (rc == -EINVAL); newpinlen = strlen(newpin); do { printf(PKCSINIT_MSG(VNEWSO, "Re-enter the new SO PIN: ")); fflush(stdout); rc = get_pin(&newpin2); } while (rc == -EINVAL); newpin2len = strlen(newpin2); if (newpinlen != newpin2len || memcmp(newpin, newpin2, strlen((char *)newpin)) != 0) { printf(PKCSINIT_MSG(PINMISMATCH, "New PINs do not match.\n")); fflush(stdout); exit(CKR_PIN_INVALID); } } rc = set_user_pin(CKU_SO, sopin, newpin); } /* If the user wants to set the User PIN, check to see if they have passed the * current User PIN and the New PIN in. If not prompt and validate them. */ if (flags & CFG_SET_USER){ if (~flags & CFG_USER_PIN) { int rc; do { printf(PKCSINIT_MSG(USERPIN, "Enter user PIN: ")); fflush(stdout); rc = get_pin(&pin); } while (rc == -EINVAL); } if (~flags & CFG_NEW_PIN) { do { printf(PKCSINIT_MSG(NEWUSER, "Enter the new user PIN: ")); fflush(stdout); rc = get_pin(&newpin); } while (rc == -EINVAL); newpinlen = strlen(newpin); do { printf(PKCSINIT_MSG(VNEWUSER, "Re-enter the new user PIN: ")); fflush(stdout); rc = get_pin(&newpin2); } while (rc == -EINVAL); newpin2len = strlen(newpin2); if (newpinlen != newpin2len || memcmp(newpin, newpin2, strlen((char *)newpin)) != 0) { printf(PKCSINIT_MSG(PINMISMATCH, "New PINs do not match.\n")); fflush(stdout); exit(CKR_PIN_INVALID); } } rc = set_user_pin(CKU_USER, pin, newpin); } /* We are done, detach from shared memory, and free the memory we may have * allocated. In the case of PIN's we memset them to ensure that they are not * left around in system memory*/ done: #if SHM detach_shared_memory((char *)shmp); free (slot); #endif if (sopin) { memset(sopin, 0, strlen((char *)sopin)); free (sopin); } if (pin) { memset(pin, 0, strlen((char *)pin)); free (pin); } if (newpin) { memset(newpin, 0, strlen((char *)newpin)); free (newpin); } if (newpin2) { memset(newpin2, 0, strlen((char *)newpin2)); free (newpin2); } return rc; } int get_pin(CK_CHAR **pin) { int count; char buff[PIN_SIZE] = { 0 }, c = 0; int rc = 0; *pin = NULL; /* Turn off echoing to the terminal when getting the password */ echo(FALSE); /* Get each character and print out a '*' for each input */ for (count = 0; (c != LINE_FEED) && (count < PIN_SIZE); count++) { buff[count] = getc(stdin); c = buff[count]; if (c == BACK_SPACE || c == DELETE) { printf("\nBackspace and delete character not allowed. " "Please retry entering your PIN.\n"); rc = -EINVAL; echo(TRUE); fflush(stdout); goto out; } if ((c != LINE_FEED)) printf("*"); fflush(stdout); } echo(TRUE); /* After we get the password go to the next line */ printf("\n"); fflush(stdout); /* Allocate 80 bytes for the user PIN. This is large enough * for the tokens supported in AIX 5.0 and 5.1 */ *pin = (unsigned char *)malloc(PIN_SIZE); if (!(*pin)) { rc = -ENOMEM; goto out; } /* Strip the carage return from the user input (it is not part * of the PIN) and put the PIN in the return buffer */ buff[count - 1] = '\0'; /* keep the trailing null for the strlen */ strncpy((char *)*pin, buff, (strlen((char *)buff) + 1)); out: return rc; } int echo(int bool){ struct termios term; /* flush standard out to make sure everything that needs to be displayed has * been displayed */ fflush(stdout); /* get the current terminal attributes */ if (tcgetattr(STDIN_FILENO, &term) != 0) return -1; /* Since we are calling this function we must want to read in a char at a * time. Therefore set the cc structure before setting the terminal attrs */ term.c_cc[VMIN] = 1; term.c_cc[VTIME] = 0; /* If we are turning off the display of input characters AND with the inverse * of the ECHO mask, if we are turning on the display OR with the ECHO mask. * We also set if we are reading in canonical or noncanonical mode. */ if (bool) term.c_lflag |= (ECHO | ICANON); else term.c_lflag &= ~(ECHO | ICANON); /* Set the attributes, and flush the streams so that any input already * displayed on the terminal is invalid */ if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &term) != 0) return -1; return 0; } #if SHM void display_shared_memory(void){ int lcv; // Loop control variable /* display message headers */ printf(PKCSINIT_MSG(SHMEM, "Shared Memory Data\n")); printf(PKCSINIT_MSG(SLOTNUMS, "\tNumber of Slots: %d\n"), shmp->num_slots); /* go through all the slots and display the shared memeory information */ for (lcv = 0; lcv < shmp->num_slots; lcv++) { printf("\n"); printf(PKCSINIT_MSG(SLOTNUM, "\tSlot Number: %d\n"), shmp->slot_info[lcv].slot_number); printf(PKCSINIT_MSG(PRESENT, "\tPresent: %d\n"), shmp->slot_info[lcv].present); printf(PKCSINIT_MSG(DLLLOC, "\tDLL Location: %s\n"), shmp->slot_info[lcv].dll_location); printf(PKCSINIT_MSG(INITFCN, "\tInit Function: %s\n"), shmp->slot_info[lcv].slot_init_fcn); printf(PKCSINIT_MSG(COORELATE, "\tCoorelator: %s\n"), shmp->slot_info[lcv].correlator); printf(PKCSINIT_MSG(GLOBAL, "\tGlobal Sessions: 0x%X\n"), shmp->slot_info[lcv].global_sessions); } } #endif CK_RV display_pkcs11_info(void){ CK_RV rc; CK_INFO CryptokiInfo; /* Get the PKCS11 infomation structure and if fails print message */ rc = FunctionPtr->C_GetInfo(&CryptokiInfo); if (rc != CKR_OK) { printf(PKCSINIT_MSG(INFOERROR, "Error getting PKCS#11 info: 0x%X\n"), rc); return rc; } /* display the header and information */ printf(PKCSINIT_MSG(PKCSINFO, "PKCS#11 Info\n")); printf(PKCSINIT_MSG((int)VERSION, "\tVersion %d.%d \n"), CryptokiInfo.cryptokiVersion.major, CryptokiInfo.cryptokiVersion.minor); printf(PKCSINIT_MSG(MANUFACT, "\tManufacturer: %32s \n"), CryptokiInfo.manufacturerID); printf(PKCSINIT_MSG(FLAGS, "\tFlags: 0x%X \n"), CryptokiInfo.flags); printf(PKCSINIT_MSG(LIBDESCRIPT, "\tLibrary Description: %32s \n"), CryptokiInfo.libraryDescription); printf(PKCSINIT_MSG(LIBVERSION, "\tLibrary Version %d.%d \n"), CryptokiInfo.libraryVersion.major, CryptokiInfo.libraryVersion.minor); return rc; } CK_RV get_slot_list(int cond, CK_CHAR_PTR slot){ CK_RV rc; // Return Code CK_SLOT_ID_PTR TempSlotList = NULL; // Temporary Slot List /* Find out how many tokens are present in slots */ rc = FunctionPtr->C_GetSlotList(TRUE, NULL_PTR, &SlotCount); if (rc != CKR_OK) { printf(PKCSINIT_MSG(SLOTERROR, "Error getting number of slots: 0x%X\n"), rc); return rc; } if (SlotCount == 0) { printf("C_GetSlotCount returned 0 slots. Check that your tokens" " are installed correctly.\n"); return -ENODEV; } /* Allocate enough space for the slots information */ SlotList = (CK_SLOT_ID_PTR) malloc(SlotCount * sizeof(CK_SLOT_ID)); rc = FunctionPtr->C_GetSlotList(TRUE, SlotList, &SlotCount); if (rc != CKR_OK) { printf(PKCSINIT_MSG(LISTERROR, "Error getting slot list: 0x%X\n"), rc); return rc; } /* If the conditional variable cond is true then slot should * contain a char string representing a slot number to examine. * The validate_slot function has already been run, therefore we now that * the slot exsists in the system. */ if (cond) { /* NOTE: This function changes slot list to not be the PKCS11 slot list, * but instead the list of slots which we are going to be working with. * This allows us to do the same operation on multiple slots; however, the * configuration routines currently expect only one slot to be passed in * with the -c flag. Therefore, the slot list will contain only the slot * passed in with the -c flag. */ TempSlotList = (CK_SLOT_ID_PTR) malloc(sizeof(CK_SLOT_ID)); /* The validate_slot function set the variable in_slot to tell * us the array position of the passed in card. We can therefore * use this position and assume it is valid. */ *TempSlotList = SlotList[in_slot]; free (SlotList); SlotList = (CK_SLOT_ID_PTR) malloc(sizeof(CK_SLOT_ID)); *SlotList = *TempSlotList; SlotCount = 1; free (TempSlotList); } return CKR_OK; } CK_RV display_mechanism_info(void){ CK_RV rc; // Return Code CK_MECHANISM_TYPE_PTR MechanismList = NULL; // Head to Mechanism list CK_MECHANISM_INFO MechanismInfo; // Structure to hold Mechanism Info CK_ULONG MechanismCount = 0; // Number of supported mechanisms unsigned int lcv, lcv2; // Loop Control Variables for (lcv = 0; lcv < SlotCount; lcv++){ /* For each slot find out how many mechanisms are supported */ rc = FunctionPtr->C_GetMechanismList(SlotList[lcv], NULL_PTR, &MechanismCount); if (rc != CKR_OK) { printf(PKCSINIT_MSG(MECHERROR, "Error getting number of mechanisms: 0x%X\n"), rc); return rc; } /* Allocate enough memory to store all the supported mechanisms */ MechanismList = (CK_MECHANISM_TYPE_PTR) malloc(MechanismCount * sizeof(CK_MECHANISM_TYPE)); /* This time get the mechanism list */ rc = FunctionPtr->C_GetMechanismList(SlotList[lcv], MechanismList, &MechanismCount); if (rc != CKR_OK) { printf(PKCSINIT_MSG(LISTERROR2, "Error getting mechanisms list: 0x%X\n"), rc); return rc; } /* For each Mechanism in the List */ for (lcv2 = 0; lcv2 < MechanismCount; lcv2++){ /* Get the Mechanism Info and display it */ rc = FunctionPtr->C_GetMechanismInfo(SlotList[lcv], MechanismList[lcv2], &MechanismInfo); if (rc != CKR_OK) { printf(PKCSINIT_MSG(INFOERROR2, "Error getting mechanisms info: 0x%X\n"), rc); return rc; } printf(PKCSINIT_MSG(MECH, "Mechanism #%d\n"), lcv2); printf(PKCSINIT_MSG(MECHLABEL, "\tMechanism: 0x%X\n"), MechanismList[lcv2]); printf(PKCSINIT_MSG(KEYSIZE, "\tKey Size: %d-%d\n"), MechanismInfo.ulMinKeySize, MechanismInfo.ulMaxKeySize); printf(PKCSINIT_MSG(FLAGS, "\tFlags: 0x%X\n"), MechanismInfo.flags); } /* Free the memory we allocated for the mechanism list */ free (MechanismList); } return CKR_OK; } CK_RV display_slot_info(void){ CK_RV rc; // Return Code CK_SLOT_INFO SlotInfo; // Structure to hold slot information unsigned int lcv; // Loop control Variable for (lcv = 0; lcv < SlotCount; lcv++){ /* Get the info for the slot we are examining and store in SlotInfo*/ rc = FunctionPtr->C_GetSlotInfo(SlotList[lcv], &SlotInfo); if (rc != CKR_OK) { printf(PKCSINIT_MSG(SLOTERROR2, "Error getting slot info: 0x%X\n"), rc); return rc; } /* Display the slot information */ printf(PKCSINIT_MSG(SLOTINFO, "Slot #%d Info\n"), SlotList[lcv]); printf(PKCSINIT_MSG(SLOTDESC, "\tDescription: %.64s\n"), SlotInfo.slotDescription); printf(PKCSINIT_MSG(MANUFACT, "\tManufacturer: %.32s\n"), SlotInfo.manufacturerID); printf(PKCSINIT_MSG(FLAGS, "\tFlags: 0x%X ("), SlotInfo.flags); if (SlotInfo.flags & CKF_TOKEN_PRESENT) printf(PKCSINIT_MSG(FLAGS, "TOKEN_PRESENT|")); if (SlotInfo.flags & CKF_REMOVABLE_DEVICE) printf(PKCSINIT_MSG(FLAGS, "REMOVABLE_DEVICE|")); if (SlotInfo.flags & CKF_HW_SLOT) printf(PKCSINIT_MSG(FLAGS, "HW_SLOT|")); printf(")\n"); printf(PKCSINIT_MSG(HWVERSION, "\tHardware Version: %d.%d\n"), SlotInfo.hardwareVersion.major, SlotInfo.hardwareVersion.minor); printf(PKCSINIT_MSG(FWVERSION, "\tFirmware Version: %d.%d\n"), SlotInfo.firmwareVersion.major, SlotInfo.firmwareVersion.minor); } return CKR_OK; } CK_RV list_slot(void){ CK_RV rc; // Return code CK_SLOT_INFO SlotInfo; // Structure to hold slot information unsigned int lcv; // Loop control variable for (lcv = 0; lcv < SlotCount; lcv++){ /* Get the info for the slot we are examining and store in SlotInfo*/ rc = FunctionPtr->C_GetSlotInfo(SlotList[lcv], &SlotInfo); if (rc != CKR_OK) { printf(PKCSINIT_MSG(SLOTERROR2, "Error getting slot info: 0x%X\n"), rc); return rc; } /* Display the slot description */ printf("%ld:", SlotList[lcv]); printf(PKCSINIT_MSG(SLOTDESC, "\tDescription: %.64s\n"), SlotInfo.slotDescription); } return CKR_OK; } CK_RV display_token_info(void){ CK_RV rc; // Return Code CK_TOKEN_INFO TokenInfo; // Variable to hold Token Information unsigned int lcv; // Loop control variable for (lcv = 0; lcv < SlotCount; lcv++){ /* Get the Token info for each slot in the system */ rc = FunctionPtr->C_GetTokenInfo(SlotList[lcv], &TokenInfo); if (rc != CKR_OK) { printf(PKCSINIT_MSG(TOKERROR, "Error getting token info: 0x%X\n"), rc); return rc; } /* Display the token information */ printf(PKCSINIT_MSG(TOKINFO, "Token #%d Info:\n"), SlotList[lcv]); printf(PKCSINIT_MSG(TOKLABEL, "\tLabel: %.32s\n"), TokenInfo.label); printf(PKCSINIT_MSG(MANUFACT, "\tManufacturer: %.32s\n"), TokenInfo.manufacturerID); printf(PKCSINIT_MSG(MODEL, "\tModel: %.16s\n"), TokenInfo.model); printf(PKCSINIT_MSG(SERIAL, "\tSerial Number: %.16s\n"), TokenInfo.serialNumber); printf(PKCSINIT_MSG(FLAGS, "\tFlags: 0x%X ("), TokenInfo.flags); /* print more informative flag message */ if (TokenInfo.flags & CKF_RNG) printf(PKCSINIT_MSG(FLAGS, "RNG|")); if (TokenInfo.flags & CKF_WRITE_PROTECTED) printf(PKCSINIT_MSG(FLAGS, "WRITE_PROTECTED|")); if (TokenInfo.flags & CKF_LOGIN_REQUIRED) printf(PKCSINIT_MSG(FLAGS, "LOGIN_REQUIRED|")); if (TokenInfo.flags & CKF_USER_PIN_INITIALIZED) printf(PKCSINIT_MSG(FLAGS, "USER_PIN_INITIALIZED|")); if (TokenInfo.flags & CKF_RESTORE_KEY_NOT_NEEDED) printf(PKCSINIT_MSG(FLAGS, "RESTORE_KEY_NOT_NEEDED|")); if (TokenInfo.flags & CKF_CLOCK_ON_TOKEN) printf(PKCSINIT_MSG(FLAGS, "CLOCK_ON_TOKEN|")); if (TokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) printf(PKCSINIT_MSG(FLAGS, "PROTECTED_AUTHENTICATION_PATH|")); if (TokenInfo.flags & CKF_DUAL_CRYPTO_OPERATIONS) printf(PKCSINIT_MSG(FLAGS, "DUAL_CRYPTO_OPERATIONS|")); if (TokenInfo.flags & CKF_TOKEN_INITIALIZED) printf(PKCSINIT_MSG(FLAGS, "TOKEN_INITIALIZED|")); if (TokenInfo.flags & CKF_SECONDARY_AUTHENTICATION) printf(PKCSINIT_MSG(FLAGS, "SECONDARY_AUTHENTICATION|")); if (TokenInfo.flags & CKF_USER_PIN_COUNT_LOW) printf(PKCSINIT_MSG(FLAGS, "USER_PIN_COUNT_LOW|")); if (TokenInfo.flags & CKF_USER_PIN_FINAL_TRY) printf(PKCSINIT_MSG(FLAGS, "USER_PIN_FINAL_TRY|")); if (TokenInfo.flags & CKF_USER_PIN_LOCKED) printf(PKCSINIT_MSG(FLAGS, "USER_PIN_LOCKED|")); if (TokenInfo.flags & CKF_USER_PIN_TO_BE_CHANGED) printf(PKCSINIT_MSG(FLAGS, "USER_PIN_TO_BE_CHANGED|")); if (TokenInfo.flags & CKF_SO_PIN_COUNT_LOW) printf(PKCSINIT_MSG(FLAGS, "SO_PIN_COUNT_LOW|")); if (TokenInfo.flags & CKF_SO_PIN_FINAL_TRY) printf(PKCSINIT_MSG(FLAGS, "SO_PIN_FINAL_TRY|")); if (TokenInfo.flags & CKF_SO_PIN_LOCKED) printf(PKCSINIT_MSG(FLAGS, "SO_PIN_LOCKED|")); if (TokenInfo.flags & CKF_SO_PIN_TO_BE_CHANGED) printf(PKCSINIT_MSG(FLAGS, "SO_PIN_TO_BE_CHANGED|")); printf(")\n"); printf(PKCSINIT_MSG(SESSIONS, "\tSessions: %d/%d\n"), TokenInfo.ulSessionCount, TokenInfo.ulMaxSessionCount); printf(PKCSINIT_MSG(RWSESSIONS, "\tR/W Sessions: %d/%d\n"), TokenInfo.ulRwSessionCount, TokenInfo.ulMaxRwSessionCount); printf(PKCSINIT_MSG(PINLEN, "\tPIN Length: %d-%d\n"), TokenInfo.ulMinPinLen, TokenInfo.ulMaxPinLen); printf(PKCSINIT_MSG(PUBMEM, "\tPublic Memory: 0x%X/0x%X\n"), TokenInfo.ulFreePublicMemory, TokenInfo.ulTotalPublicMemory); printf(PKCSINIT_MSG(PRIVMEM, "\tPrivate Memory: 0x%X/0x%X\n"), TokenInfo.ulFreePrivateMemory, TokenInfo.ulTotalPrivateMemory); printf(PKCSINIT_MSG(HWVERSION, "\tHardware Version: %d.%d\n"), TokenInfo.hardwareVersion.major, TokenInfo.hardwareVersion.minor); printf(PKCSINIT_MSG(FWVERSION, "\tFirmware Version: %d.%d\n"), TokenInfo.firmwareVersion.major, TokenInfo.firmwareVersion.minor); printf(PKCSINIT_MSG(TIME, "\tTime: %.16s\n"), TokenInfo.utcTime); } return CKR_OK; } CK_RV init_token(CK_CHAR_PTR pin){ /* Note this function reinitializes a token to the state it was * in just after the initial install of the microcode (clu files). * It does the following actions (if SO pin is correct): * (1) Purges all Token Objects * (2) Resets SO PIN back ot the default * (3) Purges the USER PIN * (4) Sets the Token Label */ CK_RV rc; // Return Code CK_ULONG pinlen; // Length of the PIN CK_CHAR label[32], // What we want to set the Label of the card to enteredlabel[33]; // Max size of 32 + carriage return; unsigned int lcv; // Loop Control Varable /* Find out the size of the entered PIN */ pinlen = strlen((char *)pin); /* Get the token label from the user, NOTE it states to give a unique label * but it is never verified as unique. This is becuase Netscape requires a * unique token label; however the PKCS11 spec does not. */ printf(PKCSINIT_MSG(GETLABEL, "Enter a unique token label: ")); fflush(stdout); fgets((char *)enteredlabel, sizeof(enteredlabel), stdin); /* First clear the label array. We must have 32 characters for PADDING then * we start all labels with 'IBM 4758 - ' therefore we use some of the label * information for our own use. This is primarily done for support reasons, * we are able to look at the labels and determine what is in the system */ memset(label, ' ', 32); strncpy((char *)label, (char *)enteredlabel, strlen((char *)enteredlabel) - 1); // Strip the \n /* It is possible to initialize all tokens although this would not give us a * unique token label would it? Normally this would be called with only one * token in the slot list. Slot list is not the slot list of the system only * a list of slots we are working with */ for (lcv = 0; lcv < SlotCount; lcv++){ rc = FunctionPtr->C_InitToken(SlotList[lcv], pin, pinlen, label); if (rc != CKR_OK) { if (rc == CKR_PIN_INCORRECT) { printf(PKCSINIT_MSG(INCORRECTPIN, "Incorrect PIN Entered.\n")); fflush(stdout); } else { printf(PKCSINIT_MSG(INITERROR, "Error initializing token: 0x%X\n"), rc); fflush(stdout); } return rc; } } return CKR_OK; } CK_RV init_user_pin(CK_CHAR_PTR pin, CK_CHAR_PTR sopin){ CK_RV rc; // Return Value CK_FLAGS flags = 0; // Mask that we will use when opening the session CK_SESSION_HANDLE session_handle; // The session handle we get CK_ULONG pinlen, sopinlen; // Length of the user and SO PINs /* get the length of the PINs */ pinlen = strlen((char *)pin); sopinlen = strlen((char *)sopin); /* set the mask we will use for Open Session */ flags |= CKF_SERIAL_SESSION; flags |= CKF_RW_SESSION; /* We need to open a read/write session to the adapter to initialize the user * PIN. Attempt to do so */ rc = FunctionPtr->C_OpenSession(SlotList[0], flags, NULL, NULL, &session_handle); if (rc != CKR_OK){ printf(PKCSINIT_MSG(OPENERROR, "Error opening session: 0x%X\n"), rc); fflush(stdout); return rc; } /* After the session is open, we must login as the SO to initialize the PIN */ rc = FunctionPtr->C_Login(session_handle, CKU_SO, sopin, sopinlen); if (rc != CKR_OK){ if (rc == CKR_PIN_INCORRECT) { printf(PKCSINIT_MSG(INCORRECTPIN, "Incorrect PIN Entered.\n")); fflush(stdout); } else { printf(PKCSINIT_MSG(LOGINERROR, "Error logging in: 0x%X\n"), rc); fflush(stdout); } return rc; } /* Call the function to Init the PIN */ rc = FunctionPtr->C_InitPIN(session_handle, pin, pinlen); if (rc != CKR_OK){ printf(PKCSINIT_MSG(SETPIN, "Error setting PIN: 0x%X\n"), rc); fflush(stdout); } /* Logout so that others can use the PIN */ rc = FunctionPtr->C_Logout(session_handle); if (rc != CKR_OK){ printf(PKCSINIT_MSG(LOGOUTERROR, "Error logging out: 0x%X\n"), rc); fflush(stdout); } /* Close the session */ rc = FunctionPtr->C_CloseSession(session_handle); if (rc != CKR_OK){ printf(PKCSINIT_MSG(CLOSEERROR, "Error closing session: 0x%X\n"), rc); fflush(stdout); return rc; } return CKR_OK; } CK_RV set_user_pin(CK_USER_TYPE user, CK_CHAR_PTR oldpin, CK_CHAR_PTR newpin){ CK_RV rc; // Return Value CK_FLAGS flags = 0; // Mash ot open the session with CK_SESSION_HANDLE session_handle; // The handle of the session we will open CK_ULONG oldpinlen, newpinlen; // The size of the new and ole PINS /* NOTE: This function is used for both the settinf of the SO and USER pins, * the CK_USER_TYPE specifes which we are changing. */ /* Get the size of the PINs */ oldpinlen = strlen((char *)oldpin); newpinlen = strlen((char *)newpin); /* set the flags we will open the session with */ flags |= CKF_SERIAL_SESSION; flags |= CKF_RW_SESSION; /* Open the Session */ rc = FunctionPtr->C_OpenSession(SlotList[0], flags, NULL, NULL, &session_handle); if (rc != CKR_OK){ printf(PKCSINIT_MSG(OPENERROR, "Error opening session: 0x%X\n"), rc); fflush(stdout); return rc; } /* Login to the session we just created as the pkcs11 passed in USER type */ rc = FunctionPtr->C_Login(session_handle, user, oldpin, oldpinlen); if (rc != CKR_OK){ if (rc == CKR_PIN_INCORRECT) { printf(PKCSINIT_MSG(INCORRECTPIN, "Incorrect PIN Entered.\n")); fflush(stdout); } else { printf(PKCSINIT_MSG(LOGINERROR, "Error logging in: 0x%X\n"), rc); fflush(stdout); } return rc; } /* set the new PIN */ rc = FunctionPtr->C_SetPIN(session_handle, oldpin, oldpinlen, newpin, newpinlen); if (rc != CKR_OK){ printf(PKCSINIT_MSG(SETPIN, "Error setting PIN: 0x%X\n"), rc); fflush(stdout); } /* and of course clean up after ourselves */ rc = FunctionPtr->C_CloseSession(session_handle); if (rc != CKR_OK){ printf(PKCSINIT_MSG(CLOSEERROR, "Error closing session: 0x%X\n"), rc); fflush(stdout); return rc; } return CKR_OK; } CK_RV init(void){ CK_RV rc = CKR_OK; // Return Code void (*symPtr)(); // Pointer for the Dll /* Open the PKCS11 API shared library, and inform the user is there is an * error */ /* The host machine should have the right library in the * LD_LIBRARY_PATH */ dllPtr = dlopen("libopencryptoki.so", RTLD_NOW); if (!dllPtr) { printf(PKCSINIT_MSG(LOADERROR, "Error loading PKCS#11 library\n")); printf(PKCSINIT_MSG(LOADERROR, "dlopen error: %s\n"), dlerror()); fflush(stdout); return -1; } /* Get the list of the PKCS11 functions this token support */ symPtr = (void (*)())dlsym(dllPtr, "C_GetFunctionList"); if (!symPtr) { rc = errno; printf(PKCSINIT_MSG(FUNCTERROR, "Error getting function list: 0x%X\n"), rc); fflush(stdout); return rc; } symPtr(&FunctionPtr); #if SHM /* Since this program uses PKCS11 function calls we need to make sure that * the slot daemon is running. If the shared memory is created, then we * know slot manager is running. Therefore, if we fail to attach to the * memory, we assume that slots is not running and attempt to start it. * After 1/2 second we try again and if it fails we fail. */ if ((shmp = attach_shared_memory()) == NULL) { system("/usr/sbin/pkcsslotd"); usleep(500); if ((shmp = attach_shared_memory()) == NULL) { printf(PKCSINIT_MSG(SLOTMGRERROR, "Error communicating with slot manager: 0x%x\n"), errno); fflush(stdout); cleanup(); } } #endif /* If we get here we know the slot manager is running and we can use PKCS11 * calls, so we will execute the PKCS11 Initilize command. */ rc = FunctionPtr->C_Initialize(NULL); if (rc != CKR_OK) { printf(PKCSINIT_MSG(LIBERROR, "Error initializing the PKCS11 library: 0x%X\n"), rc); fflush(stdout); cleanup(); } return CKR_OK; } CK_RV cleanup(void){ CK_RV rc; // Return Code /* To clean up we will free the slot list we create, call the Finalize * routine for PKCS11 and close the dynamically linked library */ free (SlotList); rc = FunctionPtr->C_Finalize(NULL); if (dllPtr) dlclose(dllPtr); exit (rc); } void usage(char *progname){ /* If we get here the user needs help, so give it to them */ printf(PKCSINIT_MSG(USAGE, "usage:\t%s [-itsmMIupP] [-c slotnumber -U userPIN -S SOPin -n newpin]\n"), progname); printf(PKCSINIT_MSG(USAGE1, "\t-i display PKCS11 info\n")); printf(PKCSINIT_MSG(USAGE2, "\t-t display token info\n")); printf(PKCSINIT_MSG(USAGE3, "\t-s display slot info\n")); printf(PKCSINIT_MSG(USAGE4, "\t-m display mechanism list\n")); printf(PKCSINIT_MSG(USAGE6, "\t-I initialize token \n")); printf(PKCSINIT_MSG(USAGE7, "\t-u initialize user PIN\n")); printf(PKCSINIT_MSG(USAGE8, "\t-p set the user PIN\n")); printf(PKCSINIT_MSG(USAGE9, "\t-P set the SO PIN\n")); exit(-1); } #if SHM void * attach_shared_memory() { key_t tok; int shmid; char *shmp; struct stat statbuf; // Really should fstat the tok_path if (stat(TOK_PATH,&statbuf) < 0 ){ // The Stat token origin file does not work... Kick it out return NULL; } tok = ftok(TOK_PATH,'b'); // Get the shared memory id. shmid = shmget(tok,sizeof(Slot_Mgr_Shr_t), S_IROTH|S_IWOTH|S_IWUSR|S_IWGRP|S_IRGRP|S_IRUSR|S_IWUSR); if ( shmid < 0 ) { return NULL; } /* Attach to shared memroy */ shmp = (void *)shmat(shmid,NULL,0); if ( !shmp ) { return NULL; } return shmp; } void detach_shared_memory (char *shmp) { /* We could call the shmdt (shared memory detatch) directly but this is more * readable */ shmdt(shmp); } CK_RV validate_slot(CK_CHAR_PTR slot) { int lcv; // Loop control variable long slot_num; // integer value for the slot (long should be large enough) CK_BOOL valid = FALSE; // Conditional variable /* Make sure the slot passed in is not NULL */ if (! slot) return CKR_ATTRIBUTE_VALUE_INVALID; slot_num = atol(slot); for(lcv = 0; lcv < shmp->num_slots; lcv++) { /* Compare what is in shared memory to the slot passed in */ if (shmp->slot_info[lcv].slot_number == slot_num) { valid = TRUE; // indicate the slot is valid in_slot = lcv; // set the slot value to be array position break; // no need to check the rest } } if (valid) return CKR_OK; else { /* This should really read Slot, but since translation has been done this * will need to wait until 5.1 to be translated correctly */ printf(PKCSINIT_MSG(INVALIDCARD, "Invalid Card: %s\n"), slot); fflush(stdout); return CKR_ATTRIBUTE_VALUE_INVALID; } } #endif opencryptoki-2.3.1+dfsg/usr/sbin/pkcsconf/pkcsconf.msg0000751000175000017500000004410411327631345020641 0ustar jfjf $ $ $ $Header: /cvsroot/opencryptoki/opencryptoki/usr/sbin/pkcsconf/pkcsconf.msg,v 1.1 2005/04/11 20:22:18 mhalcrow Exp $ $ $ $ Common Public License Version 0.5 $ THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF $ THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, $ REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES $ RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. $ $ 1. DEFINITIONS $ $ "Contribution" means: $ a) in the case of the initial Contributor, the $ initial code and documentation distributed under $ this Agreement, and $ $ b) in the case of each subsequent Contributor: $ i) changes to the Program, and $ ii) additions to the Program; $ $ where such changes and/or additions to the Program $ originate from and are distributed by that $ particular Contributor. A Contribution 'originates' $ from a Contributor if it was added to the Program $ by such Contributor itself or anyone acting on such $ Contributor's behalf. Contributions do not include $ additions to the Program which: (i) are separate $ modules of software distributed in conjunction with $ the Program under their own license agreement, and $ (ii) are not derivative works of the Program. $ $ $ "Contributor" means any person or entity that distributes $ the Program. $ $ "Licensed Patents " mean patent claims licensable by a $ Contributor which are necessarily infringed by the use or $ sale of its Contribution alone or when combined with the $ Program. $ $ "Program" means the Contributions distributed in $ accordance with this Agreement. $ $ "Recipient" means anyone who receives the Program under $ this Agreement, including all Contributors. $ $ 2. GRANT OF RIGHTS $ $ a) Subject to the terms of this Agreement, each $ Contributor hereby grants Recipient a $ non-exclusive, worldwide, royalty-free copyright $ license to reproduce, prepare derivative works of, $ publicly display, publicly perform, distribute and $ sublicense the Contribution of such Contributor, if $ any, and such derivative works, in source code and $ object code form. $ $ b) Subject to the terms of this Agreement, each $ Contributor hereby grants Recipient a $ non-exclusive, worldwide, royalty-free patent $ license under Licensed Patents to make, use, sell, $ offer to sell, import and otherwise transfer the $ Contribution of such Contributor, if any, in source $ code and object code form. This patent license $ shall apply to the combination of the Contribution $ and the Program if, at the time the Contribution is $ added by the Contributor, such addition of the $ Contribution causes such combination to be covered $ by the Licensed Patents. The patent license shall $ not apply to any other combinations which include $ the Contribution. No hardware per se is licensed $ hereunder. $ $ c) Recipient understands that although each $# Contributor grants the licenses to its $ Contributions set forth herein, no assurances are $ provided by any Contributor that the Program does $ not infringe the patent or other intellectual $ property rights of any other entity. Each $ Contributor disclaims any liability to Recipient $ for claims brought by any other entity based on $ infringement of intellectual property rights or $ otherwise. As a condition to exercising the rights $ and licenses granted hereunder, each Recipient $ hereby assumes sole responsibility to secure any $ other intellectual property rights needed, if any. $ $ For example, if a third party patent license is $ required to allow Recipient to distribute the $ Program, it is Recipient's responsibility to $ acquire that license before distributing the $ Program. $ $ d) Each Contributor represents that to its $ knowledge it has sufficient copyright rights in its $ Contribution, if any, to grant the copyright $ license set forth in this Agreement. $ $ 3. REQUIREMENTS $ $ A Contributor may choose to distribute the Program in $ object code form under its own license agreement, provided $ that: $ a) it complies with the terms and conditions of $ this Agreement; and $ $ b) its license agreement: $ i) effectively disclaims on behalf of all $ Contributors all warranties and conditions, express $ and implied, including warranties or conditions of $ title and non-infringement, and implied warranties $ or conditions of merchantability and fitness for a $ particular purpose; $ $ ii) effectively excludes on behalf of all $ Contributors all liability for damages, including $ direct, indirect, special, incidental and $ consequential damages, such as lost profits; $ $ iii) states that any provisions which differ from $ this Agreement are offered by that Contributor $ alone and not by any other party; and $ $ iv) states that source code for the Program is $ available from such Contributor, and informs $ licensees how to obtain it in a reasonable manner $ on or through a medium customarily used for $ software exchange. $ $ When the Program is made available in source code form: $ a) it must be made available under this Agreement; $ and $ b) a copy of this Agreement must be included with $ each copy of the Program. $ $ Contributors may not remove or alter any copyright notices $ contained within the Program. $ $ Each Contributor must identify itself as the originator of $ its Contribution, if any, in a manner that reasonably $ allows subsequent Recipients to identify the originator of $ the Contribution. $ $ $ 4. COMMERCIAL DISTRIBUTION $ $ Commercial distributors of software may accept certain $ responsibilities with respect to end users, business $ partners and the like. While this license is intended to $ facilitate the commercial use of the Program, the $ Contributor who includes the Program in a commercial $ product offering should do so in a manner which does not $ create potential liability for other Contributors. $ Therefore, if a Contributor includes the Program in a $ commercial product offering, such Contributor ("Commercial $ Contributor") hereby agrees to defend and indemnify every $ other Contributor ("Indemnified Contributor") against any $ losses, damages and costs (collectively "Losses") arising $ from claims, lawsuits and other legal actions brought by a $ third party against the Indemnified Contributor to the $ extent caused by the acts or omissions of such Commercial $ Contributor in connection with its distribution of the $ Program in a commercial product offering. The obligations $ in this section do not apply to any claims or Losses $ relating to any actual or alleged intellectual property $ infringement. In order to qualify, an Indemnified $ Contributor must: a) promptly notify the Commercial $ Contributor in writing of such claim, and b) allow the $ Commercial Contributor to control, and cooperate with the $ Commercial Contributor in, the defense and any related $ settlement negotiations. The Indemnified Contributor may $ participate in any such claim at its own expense. $ $ $ For example, a Contributor might include the Program in a $ commercial product offering, Product X. That Contributor $ is then a Commercial Contributor. If that Commercial $ Contributor then makes performance claims, or offers $ warranties related to Product X, those performance claims $ and warranties are such Commercial Contributor's $ responsibility alone. Under this section, the Commercial $ Contributor would have to defend claims against the other $ Contributors related to those performance claims and $ warranties, and if a court requires any other Contributor $ to pay any damages as a result, the Commercial Contributor $ must pay those damages. $ $ $ 5. NO WARRANTY $ $ EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE $ PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT $ WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR $ IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR $ CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR $ FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely $ responsible for determining the appropriateness of using $ and distributing the Program and assumes all risks $ associated with its exercise of rights under this $ Agreement, including but not limited to the risks and $ costs of program errors, compliance with applicable laws, $ damage to or loss of data, programs or equipment, and $ unavailability or interruption of operations. $ $ 6. DISCLAIMER OF LIABILITY $ EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER $ RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY $ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, $ OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION $ LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF $ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT $ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT $ OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE $ OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE $ POSSIBILITY OF SUCH DAMAGES. $ $ 7. GENERAL $ $ If any provision of this Agreement is invalid or $ unenforceable under applicable law, it shall not affect $ the validity or enforceability of the remainder of the $ terms of this Agreement, and without further action by the $ parties hereto, such provision shall be reformed to the $ minimum extent necessary to make such provision valid and $ enforceable. $ $ $ If Recipient institutes patent litigation against a $ Contributor with respect to a patent applicable to $ software (including a cross-claim or counterclaim in a $ lawsuit), then any patent licenses granted by that $ Contributor to such Recipient under this Agreement shall $ terminate as of the date such litigation is filed. In $ addition, If Recipient institutes patent litigation $ against any entity (including a cross-claim or $ counterclaim in a lawsuit) alleging that the Program $ itself (excluding combinations of the Program with other $ software or hardware) infringes such Recipient's $ patent(s), then such Recipient's rights granted under $ Section 2(b) shall terminate as of the date such $ litigation is filed. $ $ All Recipient's rights under this Agreement shall $ terminate if it fails to comply with any of the material $ terms or conditions of this Agreement and does not cure $ such failure in a reasonable period of time after becoming $ aware of such noncompliance. If all Recipient's rights $ under this Agreement terminate, Recipient agrees to cease $ use and distribution of the Program as soon as reasonably $ practicable. However, Recipient's obligations under this $ Agreement and any licenses granted by Recipient relating $ to the Program shall continue and survive. $ $ Everyone is permitted to copy and distribute copies of $ this Agreement, but in order to avoid inconsistency the $ Agreement is copyrighted and may only be modified in the $ following manner. The Agreement Steward reserves the right $ to publish new versions (including revisions) of this $ Agreement from time to time. No one other than the $ Agreement Steward has the right to modify this Agreement. $ $ IBM is the initial Agreement Steward. IBM may assign the $ responsibility to serve as the Agreement Steward to a $ suitable separate entity. Each new version of the $ Agreement will be given a distinguishing version number. $ The Program (including Contributions) may always be $ distributed subject to the version of the Agreement under $ which it was received. In addition, after a new version of $ the Agreement is published, Contributor may elect to $ distribute the Program (including its Contributions) under $ the new version. Except as expressly stated in Sections $ 2(a) and 2(b) above, Recipient receives no rights or $ licenses to the intellectual property of any Contributor $ under this Agreement, whether expressly, by implication, $ estoppel or otherwise. All rights in the Program not $ expressly granted under this Agreement are reserved. $ $ $ This Agreement is governed by the laws of the State of New $ York and the intellectual property laws of the United $ States of America. No party to this Agreement will bring a $ legal action under this Agreement more than one year after $ the cause of action arose. Each party waives its rights to $ a jury trial in any resulting litigation. $ $ $ $*/ $ $/* (C) COPYRIGHT International Business Machines Corp. 2001 */ $ $ COMPONENT_NAME: pkcs11 $ $ messages for init $quote " define quote character $len $set MS_PKCSINIT Define initial set# EXCLUSION "Setting the SO and user PINs are mutually exclusive.\n" SOPIN "Enter the SO PIN: " USERPIN "Enter the user PIN: " NEWUSER "Enter the new user PIN: " NEWSO "Enter the new SO PIN: " VNEWUSER "Re-enter the new user PIN: " VNEWSO "Re-enter the new SO PIN: " GETLABEL "Enter a unique token label: " INCORRECTPIN "Invalid PIN Entered." PINMISMATCH "New PINs do not match.\n" SHMEM "Shared Memory Data\n" SLOTNUMS "\tNumber of Slots: %d\n" SLOTNUM "\tSlot Number: %d\n" PRESENT "\tPresent: %d\n" DLLLOC "\tDLL Location: %s\n" INITFCN "\tInit Function: %s\n" COORELATE "\tCoorelator: %s\n" GLOBAL "\tGlobal Sessions: 0x%X\n" INFOERROR "Error getting PKCS#11 info: 0x%X\n" PKCSINFO "PKCS#11 Info\n" VERSION "\tVersion %d.%d\n" MANUFACT "\tManufacuter: %.32s\n" FLAGS "\tFlags: 0x%X\n" LIBDESCRIPT "\tLibrary Description: %.32s\n" LIBVERSION "\tLibrary Version %d.d\n" SLOTERROR "Error getting the number of slots: 0x%X\n" LISTERROR "Error getting the slot list: 0x%X\n" MECHERROR "Error getting the number of mechanisms: 0x%X\n" LISTERROR2 "Error getting the mechanism list: 0x%X\n" INFOERROR2 "Error getting mechanism info: 0x%X\n" MECH "Mechanism #%d\n" MECHLABEL "\tMechanism: 0x%X\n" KEYSIZE "\tKey Size: %d-%d\n" SLOTERROR2 "Error getting slot info: 0x%X\n" SLOTINFO "Slot #%d Info\n" SLOTDESC "\tDescription: %.64s\n" HWVERSION "\tHardware Version: %d.%d\n" FWVERSION "\tFirmware Version: %d.%d\n" TOKERROR "Error getting token info: 0x%X\n" TOKINFO "Token #%d Info:\n" TOKLABEL "\tLabel: %.32s\n" MODEL "\tModel: %.16s\n" SERIAL "\tSerial Number: %.16s\n" SESSIONS "\tSessions: %d/%d\n" RWSESSIONS "\tR/W Sessions: %d/%d\n" PINLEN "\tPIN Length: %d-%d\n" PUBMEM "\tPublic Memory: 0x%X/0x%X\n" PRIVMEM "\tPrivate Memory: 0x%X/0x%X\n" TIME "\tTime: %.16s\n" INITERROR "Error Initializing Token: 0x%X\n" OPENERROR "Error opening session: 0x%X\n" LOGINERROR "Error logging in: 0x%X\n" SETPIN "Error setting PIN: 0x%X\n" LOGOUTERROR "Error logging out: 0x%X\n" CLOSEERROR "Error closing session: 0x%X\n" LOADERROR "Error loading PKCS#11 library: 0x%X\n" FUNCTERROR "Error getting function list: 0x%X\n" LIBERROR "Error initializing the PKCS11 library: 0x%X\n" SLOTMGRERROR "Error communicating with slot manager: 0x%X\n" INVALIDCARD "Invalid card: %s\n" USAGE "usage:\t%s [-iImMpPstu] [-c slotnumber -U userPIN -S SOPin -n newPIN]\n" USAGE1 "\t-i display PKCS11 info\n" USAGE2 "\t-t display token info\n" USAGE3 "\t-s display slot info\n" USAGE4 "\t-m display mechanism list\n" USAGE5 "\t-M display shared memory\n" USAGE6 "\t-I initialize token\n" USAGE7 "\t-u initialize user PIN\n" USAGE8 "\t-p set the user PIN\n" USAGE9 "\t-P set the SO PIN\n" opencryptoki-2.3.1+dfsg/usr/sbin/pkcsconf/Makefile.am0000640000175000017500000000054711327631345020357 0ustar jfjfsbin_PROGRAMS=pkcsconf pkcsconf_LDFLAGS = -lpthread -ldl # Not all versions of automake observe sbinname_CFLAGS pkcsconf_CFLAGS = -DSPINXPL -D_THREAD_SAFE -DDEBUG -DDEV -DAPI # Not all versions of automake observe sbinname_CFLAGS AM_CFLAGS = -DSPINXPL -D_THREAD_SAFE -DDEBUG -DDEV -DAPI pkcsconf_SOURCES = pkcsconf.c INCLUDES = -I../../include/pkcs11 -I.opencryptoki-2.3.1+dfsg/usr/Makefile.am0000640000175000017500000000010711327631345015606 0ustar jfjfif DAEMON DAEMONDIRS = include sbin endif SUBDIRS = lib $(DAEMONDIRS) opencryptoki-2.3.1+dfsg/usr/include/0000751000175000017500000000000011327631345015177 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/include/pkcs11/0000751000175000017500000000000011327631345016301 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/include/pkcs11/local_types.h0000751000175000017500000003636111327631345021004 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/include/pkcs11/local_types.h,v 1.1 2005/01/18 16:09:04 kyoder Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #ifndef __LOCAL_TYPES #define __LOCAL_TYPES typedef unsigned char uint8; typedef unsigned short uint16; // typedef short int16; typedef unsigned int uint32; // typedef int int32; #endif opencryptoki-2.3.1+dfsg/usr/include/pkcs11/stdll/0000751000175000017500000000000011327631345017423 5ustar jfjfopencryptoki-2.3.1+dfsg/usr/include/pkcs11/stdll/encrypt.h0000751000175000017500000003724411327631345021275 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/include/pkcs11/stdll/encrypt.h,v 1.1 2005/01/18 16:09:04 kyoder Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #ifndef _STDLL_ENCRYPT_H #define _STDLL_ENCRYPT_H #include #include "stdll_gen.h" B_ALGORITHM_OBJ EncryptObj [ CKS_NUMBER_OF_SLOTS ] [ CKS_MAX_SESSIONS ]; B_ALGORITHM_OBJ BSafe_Algorithm_Object; B_ALGORITHM_METHOD *RSA_ENCRYPT_CHOOSER[] = { &AM_RSA_ENCRYPT, (B_ALGORITHM_METHOD *)NULL_PTR }; B_ALGORITHM_OBJ BSafe_Random_Object; B_ALGORITHM_METHOD *MD5_RANDOM_CHOOSER[] = { &AM_MD5_RANDOM, (B_ALGORITHM_METHOD *)NULL_PTR }; B_ALGORITHM_METHOD *RSA_SIGN_CHOOSER[] = { &AM_MD5, &AM_RSA_CRT_ENCRYPT, (B_ALGORITHM_METHOD *)NULL_PTR }; #endif opencryptoki-2.3.1+dfsg/usr/include/pkcs11/stdll/decrypt.h0000751000175000017500000003663211327631345021263 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/include/pkcs11/stdll/decrypt.h,v 1.1 2005/01/18 16:09:04 kyoder Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #ifndef _STDLL_DECRYPT_H #define _STDLL_DECRYPT_H #include #include "stdll_gen.h" B_ALGORITHM_OBJ DecryptObj [ CKS_NUMBER_OF_SLOTS ] [ CKS_MAX_SESSIONS ]; B_ALGORITHM_OBJ BSafe_Algorithm_Object; B_ALGORITHM_METHOD *RSA_DECRYPT_CHOOSER[] = { &AM_RSA_CRT_DECRYPT, (B_ALGORITHM_METHOD *)NULL_PTR}; #endif opencryptoki-2.3.1+dfsg/usr/include/pkcs11/stdll/keys.h0000751000175000017500000003645411327631345020566 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/include/pkcs11/stdll/keys.h,v 1.1 2005/01/18 16:09:04 kyoder Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #ifndef _STDLL_KEYS_H #define _STDLL_KEYS_H #include #include /* This header file will be eliminated when the objects are actually created * by the library rather than being hard coded into it. */ B_KEY_OBJ BSafe_Key_Object; #endif opencryptoki-2.3.1+dfsg/usr/include/pkcs11/stdll/functions.h0000751000175000017500000003776111327631345021625 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/include/pkcs11/stdll/functions.h,v 1.1 2005/01/18 16:09:04 kyoder Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #ifndef _STDLL_PKCS_FUNCTIONS_H #define _STDLL_PKCS_FUNCTIONS_H extern CK_RV SC_GetTokenInfo(); extern CK_RV SC_GetMechanismList(); extern CK_RV SC_GetMechanismInfo(); extern CK_RV SC_OpenSession(); extern CK_RV SC_CloseSession(); extern CK_RV SC_GetSessionInfo(); extern CK_RV SC_Login(); extern CK_RV SC_Logout(); extern CK_RV SC_CreateObject(); extern CK_RV SC_CopyObject(); extern CK_RV SC_DestroyObject(); extern CK_RV SC_GetAttributeValue(); extern CK_RV SC_SetAttributeValue(); extern CK_RV SC_FindObjectsInit(); extern CK_RV SC_FindObjects(); extern CK_RV SC_FindObjectsFinal(); extern CK_RV SC_EncryptInit(); extern CK_RV SC_Encrypt(); extern CK_RV SC_DecryptInit(); extern CK_RV SC_Decrypt(); extern CK_RV SC_SignInit(); extern CK_RV SC_Sign(); extern CK_RV SC_Verify(); extern CK_RV SC_VerifyRecover(); extern CK_RV SC_GenerateKey(); extern CK_RV SC_GenerateKeyPair(); extern CK_RV SC_WrapKey(); extern CK_RV SC_UnwrapKey(); extern CK_RV SC_GenerateRandom(); #endif opencryptoki-2.3.1+dfsg/usr/include/pkcs11/stdll/stdll_gen.h0000751000175000017500000004157011327631345021561 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/include/pkcs11/stdll/stdll_gen.h,v 1.1 2005/01/18 16:09:04 kyoder Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #ifndef _PKCS11_GENERAL_H #define _PKCS11_GENERAL_H #include #include "pkcs11o.h" #include "stdll.h" #define CKS_MAX_SESSIONS 10 #define CKS_NUMBER_OF_MECHANISMS 2 #define CKS_NUMBER_OF_OBJECTS 100 /* Size of Object Array */ #define CKS_NUMBER_OF_SLOTS 1 #define DLL_LBL "Prototype Software Token (BSAFE)" #define DLL_MFG "IBM Austin: RS/6000 Division " #define DLL_MODEL "BSAFE Prototype " #define DLL_SERIAL "mdmcl00-02 03-SEPTEMBER-1999 " #define DBG_LABEL "pkcs11.c: " typedef struct SC_Slot { CK_SLOT_ID MySlotID; CK_TOKEN_INFO MyToken; CK_BBOOL LoggedIn; /* Is this redundant of MyState? */ CK_CHAR_PTR MyDevice; CK_STATE MyState; /* Login Status */ CK_USER_TYPE MyUserType; /* R/O, R/E User */ } SC_Slot_t; SC_Slot_t slots[ CKS_NUMBER_OF_SLOTS ]; CK_ULONG SlotCount; STDLL_FcnList_t MyFunctionList; CK_MECHANISM_TYPE MyMechanisms[ CKS_NUMBER_OF_MECHANISMS ]; typedef struct SC_Session { CK_SESSION_HANDLE SessionList; CK_SESSION_INFO_PTR SessionInfo; } SC_Session_t; SC_Session_t sessions[ CKS_NUMBER_OF_SLOTS ] [ CKS_MAX_SESSIONS ]; SC_OBJECT_HANDLE_PTR ObjectList [ CKS_NUMBER_OF_SLOTS ] [ CKS_MAX_SESSIONS ]; SC_OBJECT_HANDLE_PTR TokenObjectList; /* Find Objects */ typedef struct SC_FindObjects { CK_BBOOL FindObjectReady; CK_ATTRIBUTE_PTR FindObjectAttr; CK_ULONG FindObjectNum; } SC_FindObjects_t; SC_FindObjects_t FindParameters[ CKS_NUMBER_OF_SLOTS ] [ CKS_MAX_SESSIONS ]; /* Loop Control Variable */ /* XXX Global? What about concurrent access? */ int lcv; #endif opencryptoki-2.3.1+dfsg/usr/include/pkcs11/stdll.h0000751000175000017500000007361111327631345017607 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/include/pkcs11/stdll.h,v 1.2 2005/02/22 20:47:40 mhalcrow Exp $ */ // /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ // // API Local control blocks within the PKCS11 Meta API // // // #include #include #include #include #ifndef _STDLL_H #define _STDLL_H typedef struct { CK_SLOT_ID slotID; CK_SESSION_HANDLE sessionh; } ST_SESSION_T ; typedef ST_SESSION_T ST_SESSION_HANDLE; /* CK_FUNCTION_LIST is a structure holding a Cryptoki spec * version and pointers of appropriate types to all the * Cryptoki functions */ /* CK_FUNCTION_LIST is new for v2.0 */ typedef CK_RV (CK_PTR ST_C_Initialize) (void **ppFunctionList,CK_SLOT_ID slotID,CK_CHAR_PTR pCorrelator); typedef CK_RV (CK_PTR ST_C_Finalize) (CK_VOID_PTR pReserved); typedef CK_RV (CK_PTR ST_C_Terminate) (void); typedef CK_RV (CK_PTR ST_C_GetInfo) (CK_INFO_PTR pInfo); typedef CK_RV (CK_PTR ST_C_GetFunctionList) (CK_FUNCTION_LIST_PTR_PTR ppFunctionList); typedef CK_RV (CK_PTR ST_C_GetSlotList) (CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pusCount); typedef CK_RV (CK_PTR ST_C_GetSlotInfo) (CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo); typedef CK_RV (CK_PTR ST_C_GetTokenInfo) (CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo); typedef CK_RV (CK_PTR ST_C_GetMechanismList) (CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pusCount); typedef CK_RV (CK_PTR ST_C_GetMechanismInfo) (CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo); typedef CK_RV (CK_PTR ST_C_InitToken) (CK_SLOT_ID slotID, CK_CHAR_PTR pPin, CK_ULONG usPinLen, CK_CHAR_PTR pLabel); typedef CK_RV (CK_PTR ST_C_InitPIN) (ST_SESSION_T hSession, CK_CHAR_PTR pPin, CK_ULONG usPinLen); typedef CK_RV (CK_PTR ST_C_SetPIN) (ST_SESSION_T hSession, CK_CHAR_PTR pOldPin, CK_ULONG usOldLen, CK_CHAR_PTR pNewPin, CK_ULONG usNewLen); // typedef CK_RV (CK_PTR ST_C_OpenSession) // (CK_SLOT_ID slotID, CK_FLAGS flags, // CK_VOID_PTR pApplication, // CK_RV (*Notify) (CK_SESSION_HANDLE hSession, // CK_NOTIFICATION event, CK_VOID_PTR pApplication), // CK_SESSION_HANDLE_PTR phSession); typedef CK_RV (CK_PTR ST_C_OpenSession) (CK_SLOT_ID slotID, CK_FLAGS flags, CK_SESSION_HANDLE_PTR phSession); typedef CK_RV (CK_PTR ST_C_CloseSession) (ST_SESSION_T hSession); typedef CK_RV (CK_PTR ST_C_CloseAllSessions) (CK_SLOT_ID slotID); typedef CK_RV (CK_PTR ST_C_GetSessionInfo) (ST_SESSION_T hSession, CK_SESSION_INFO_PTR pInfo); typedef CK_RV (CK_PTR ST_C_GetOperationState) (ST_SESSION_T hSession, CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen); typedef CK_RV (CK_PTR ST_C_SetOperationState) (ST_SESSION_T hSession, CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey); typedef CK_RV (CK_PTR ST_C_Login)(ST_SESSION_T hSession, CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG usPinLen); typedef CK_RV (CK_PTR ST_C_Logout)(ST_SESSION_T hSession); typedef CK_RV (CK_PTR ST_C_CreateObject) (ST_SESSION_T hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount, CK_OBJECT_HANDLE_PTR phObject); typedef CK_RV (CK_PTR ST_C_CopyObject) (ST_SESSION_T hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount, CK_OBJECT_HANDLE_PTR phNewObject); typedef CK_RV (CK_PTR ST_C_DestroyObject) (ST_SESSION_T hSession, CK_OBJECT_HANDLE hObject); typedef CK_RV(CK_PTR ST_C_GetObjectSize) (ST_SESSION_T hSession, CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pusSize); typedef CK_RV(CK_PTR ST_C_GetAttributeValue) (ST_SESSION_T hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount); typedef CK_RV(CK_PTR ST_C_SetAttributeValue) (ST_SESSION_T hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount); typedef CK_RV (CK_PTR ST_C_FindObjectsInit) (ST_SESSION_T hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount); typedef CK_RV (CK_PTR ST_C_FindObjects) (ST_SESSION_T hSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG usMaxObjectCount, CK_ULONG_PTR pusObjectCount); typedef CK_RV (CK_PTR ST_C_FindObjectsFinal) (ST_SESSION_T hSession); typedef CK_RV (CK_PTR ST_C_EncryptInit) (ST_SESSION_T hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); typedef CK_RV (CK_PTR ST_C_Encrypt) (ST_SESSION_T hSession, CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pusEncryptedDataLen); typedef CK_RV (CK_PTR ST_C_EncryptUpdate) (ST_SESSION_T hSession, CK_BYTE_PTR pPart, CK_ULONG usPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pusEncryptedPartLen); typedef CK_RV (CK_PTR ST_C_EncryptFinal) (ST_SESSION_T hSession, CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pusLastEncryptedPartLen); typedef CK_RV (CK_PTR ST_C_DecryptInit) (ST_SESSION_T hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); typedef CK_RV (CK_PTR ST_C_Decrypt) (ST_SESSION_T hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG usEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pusDataLen); typedef CK_RV (CK_PTR ST_C_DecryptUpdate) (ST_SESSION_T hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG usEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pusPartLen); typedef CK_RV (CK_PTR ST_C_DecryptFinal) (ST_SESSION_T hSession, CK_BYTE_PTR pLastPart, CK_ULONG_PTR pusLastPartLen); typedef CK_RV (CK_PTR ST_C_DigestInit) (ST_SESSION_T hSession, CK_MECHANISM_PTR pMechanism); typedef CK_RV (CK_PTR ST_C_Digest) (ST_SESSION_T hSession, CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pusDigestLen); typedef CK_RV (CK_PTR ST_C_DigestUpdate) (ST_SESSION_T hSession, CK_BYTE_PTR pPart, CK_ULONG usPartLen); typedef CK_RV (CK_PTR ST_C_DigestKey) (ST_SESSION_T hSession, CK_OBJECT_HANDLE hKey); typedef CK_RV (CK_PTR ST_C_DigestFinal) (ST_SESSION_T hSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pusDigestLen); typedef CK_RV (CK_PTR ST_C_SignInit) (ST_SESSION_T hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); typedef CK_RV (CK_PTR ST_C_Sign) (ST_SESSION_T hSession, CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pusSignatureLen); typedef CK_RV (CK_PTR ST_C_SignUpdate) (ST_SESSION_T hSession, CK_BYTE_PTR pPart, CK_ULONG usPartLen); typedef CK_RV (CK_PTR ST_C_SignFinal) (ST_SESSION_T hSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pusSignatureLen); typedef CK_RV (CK_PTR ST_C_SignRecoverInit) (ST_SESSION_T hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); typedef CK_RV (CK_PTR ST_C_SignRecover) (ST_SESSION_T hSession, CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pusSignatureLen); typedef CK_RV (CK_PTR ST_C_VerifyInit) (ST_SESSION_T hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); typedef CK_RV (CK_PTR ST_C_Verify) (ST_SESSION_T hSession, CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen); typedef CK_RV (CK_PTR ST_C_VerifyUpdate) (ST_SESSION_T hSession, CK_BYTE_PTR pPart, CK_ULONG usPartLen); typedef CK_RV (CK_PTR ST_C_VerifyFinal) (ST_SESSION_T hSession, CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen); typedef CK_RV (CK_PTR ST_C_VerifyRecoverInit) (ST_SESSION_T hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); typedef CK_RV (CK_PTR ST_C_VerifyRecover) (ST_SESSION_T hSession, CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pusDataLen); typedef CK_RV (CK_PTR ST_C_DigestEncryptUpdate) (ST_SESSION_T hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen); typedef CK_RV (CK_PTR ST_C_DecryptDigestUpdate) (ST_SESSION_T hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen); typedef CK_RV (CK_PTR ST_C_SignEncryptUpdate) (ST_SESSION_T hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen); typedef CK_RV (CK_PTR ST_C_DecryptVerifyUpdate) (ST_SESSION_T hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen); typedef CK_RV (CK_PTR ST_C_GenerateKey) (ST_SESSION_T hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount, CK_OBJECT_HANDLE_PTR phKey); typedef CK_RV (CK_PTR ST_C_GenerateKeyPair) (ST_SESSION_T hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG usPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG usPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPrivateKey, CK_OBJECT_HANDLE_PTR phPublicKey); typedef CK_RV (CK_PTR ST_C_WrapKey) (ST_SESSION_T hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pusWrappedKeyLen); typedef CK_RV (CK_PTR ST_C_UnwrapKey) (ST_SESSION_T hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey, CK_ULONG usWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usAttributeCount, CK_OBJECT_HANDLE_PTR phKey); typedef CK_RV (CK_PTR ST_C_DeriveKey) (ST_SESSION_T hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usAttributeCount, CK_OBJECT_HANDLE_PTR phKey); typedef CK_RV (CK_PTR ST_C_SeedRandom) (ST_SESSION_T hSession, CK_BYTE_PTR pSeed, CK_ULONG usSeedLen); typedef CK_RV (CK_PTR ST_C_GenerateRandom) (ST_SESSION_T hSession, CK_BYTE_PTR pRandomData, CK_ULONG usRandomLen); typedef CK_RV (CK_PTR ST_C_GetFunctionStatus) (ST_SESSION_T hSession); typedef CK_RV (CK_PTR ST_C_CancelFunction) (ST_SESSION_T hSession); typedef CK_RV (CK_PTR ST_Notify) (ST_SESSION_T hSession, CK_NOTIFICATION event, CK_VOID_PTR pApplication); typedef CK_RV (CK_PTR ST_C_WaitForSlotEvent) (CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved); struct ST_FCN_LIST{ // Need initialization function But it is different than // the C_Initialize ST_C_Initialize ST_Initialize; ST_C_GetTokenInfo ST_GetTokenInfo; ST_C_GetMechanismList ST_GetMechanismList; ST_C_GetMechanismInfo ST_GetMechanismInfo; ST_C_InitToken ST_InitToken; ST_C_InitPIN ST_InitPIN; ST_C_SetPIN ST_SetPIN; ST_C_OpenSession ST_OpenSession; ST_C_CloseSession ST_CloseSession; ST_C_GetSessionInfo ST_GetSessionInfo; ST_C_GetOperationState ST_GetOperationState; // Not used by Netscape ST_C_SetOperationState ST_SetOperationState; // Not used by Netscape ST_C_Login ST_Login; ST_C_Logout ST_Logout; ST_C_CreateObject ST_CreateObject; ST_C_CopyObject ST_CopyObject; ST_C_DestroyObject ST_DestroyObject; ST_C_GetObjectSize ST_GetObjectSize; ST_C_GetAttributeValue ST_GetAttributeValue; ST_C_SetAttributeValue ST_SetAttributeValue; ST_C_FindObjectsInit ST_FindObjectsInit; ST_C_FindObjects ST_FindObjects; ST_C_FindObjectsFinal ST_FindObjectsFinal; ST_C_EncryptInit ST_EncryptInit; ST_C_Encrypt ST_Encrypt; ST_C_EncryptUpdate ST_EncryptUpdate; // Not used by Netscape ST_C_EncryptFinal ST_EncryptFinal; // Not used by Netscape ST_C_DecryptInit ST_DecryptInit; ST_C_Decrypt ST_Decrypt; ST_C_DecryptUpdate ST_DecryptUpdate; // Not used by Netscape ST_C_DecryptFinal ST_DecryptFinal; // Not used by Netscape ST_C_DigestInit ST_DigestInit; ST_C_Digest ST_Digest; ST_C_DigestUpdate ST_DigestUpdate; ST_C_DigestKey ST_DigestKey; ST_C_DigestFinal ST_DigestFinal; ST_C_SignInit ST_SignInit; ST_C_Sign ST_Sign; ST_C_SignUpdate ST_SignUpdate; ST_C_SignFinal ST_SignFinal; ST_C_SignRecoverInit ST_SignRecoverInit; ST_C_SignRecover ST_SignRecover; ST_C_VerifyInit ST_VerifyInit; ST_C_Verify ST_Verify; ST_C_VerifyUpdate ST_VerifyUpdate; ST_C_VerifyFinal ST_VerifyFinal; ST_C_VerifyRecoverInit ST_VerifyRecoverInit; ST_C_VerifyRecover ST_VerifyRecover; ST_C_DigestEncryptUpdate ST_DigestEncryptUpdate; ST_C_DecryptDigestUpdate ST_DecryptDigestUpdate; ST_C_SignEncryptUpdate ST_SignEncryptUpdate; ST_C_DecryptVerifyUpdate ST_DecryptVerifyUpdate; ST_C_GenerateKey ST_GenerateKey; ST_C_GenerateKeyPair ST_GenerateKeyPair; ST_C_WrapKey ST_WrapKey; // Netscape optionsl will use En/Decrypt ST_C_UnwrapKey ST_UnwrapKey; ST_C_DeriveKey ST_DeriveKey; ST_C_SeedRandom ST_SeedRandom; ST_C_GenerateRandom ST_GenerateRandom; // Question if these have to be implemented for Netscape support ST_C_GetFunctionStatus ST_GetFunctionStatus; ST_C_CancelFunction ST_CancelFunction; }; typedef struct ST_FCN_LIST STDLL_FcnList_t; #endif opencryptoki-2.3.1+dfsg/usr/include/pkcs11/pkcs11.h0000640000175000017500000003605011327631345017560 0ustar jfjf/* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (c) COPYRIGHT International Business Machines Corp. 2001 */ #ifndef OPENCRYPTOKI_PKCS11_H #define OPENCRYPTOKI_PKCS11_H #include #include #endif opencryptoki-2.3.1+dfsg/usr/include/pkcs11/apictl.h0000751000175000017500000004230011327631345017730 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/include/pkcs11/apictl.h,v 1.2 2005/02/22 20:47:32 mhalcrow Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #include #include #include #include #include #ifndef _APILOCAL_H #define _APILOCAL_H typedef struct { void *Previous; void *Next; CK_SLOT_ID SltId; // Slot ID for indexing into the function list pointer CK_SESSION_HANDLE RealHandle; // Handle returned by the STDLL } Session_Struct_t; #ifdef PK64 // 64Bit work... Need to have a pointer to session struct typedef Session_Struct_t * SessStructP ; #endif // SAB Add a linked list of STDLL's loaded to // only load and get list once, but let multiple slots us it. typedef struct{ CK_BOOL DLLoaded; // Flag to indicate if the STDDL has been loaded char *dll_name; // Malloced space to copy the name. void *dlop_p; int dll_load_count; // STDLL_FcnList_t *FcnList; // Function list pointer for the STDLL } DLL_Load_t; typedef struct { CK_BOOL DLLoaded; // Flag to indicate if the STDDL has been loaded void *dlop_p; // Pointer to the value returned from the DL open STDLL_FcnList_t *FcnList; // Function list pointer for the STDLL DLL_Load_t *dll_information; void (*pSTfini)(); // Addition of Final function. void (*pSTcloseall)(); // Addition of close all for leeds code #ifdef PK64 SessStructP Slot_Sess[65535]; // allocate sessions for 2**16 sessions #endif } API_Slot_t; // Per process API structure. // Allocate one per process on the C_Initialize. This will be // a global type for the API and will be used through out. // typedef struct { pid_t Pid; pthread_mutex_t ProcMutex; // Mutex for the process level should this be necessary key_t shm_tok; Session_Struct_t *SessListBeg; // Beginning of the session linked list for this process Session_Struct_t *SessListEnd; // pthread_mutex_t SessListMutex; void *SharedMemP; uint16 MgrProcIndex; // Index into shared memory for This process ctl block API_Slot_t SltList[NUMBER_SLOTS_MANAGED]; DLL_Load_t DLLs[NUMBER_SLOTS_MANAGED]; // worst case we have a separate DLL per slot } API_Proc_Struct_t; #endif opencryptoki-2.3.1+dfsg/usr/include/pkcs11/pkcs11o.h0000751000175000017500000005572711327631345017756 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/include/pkcs11/pkcs11o.h,v 1.1 2005/01/18 16:09:04 kyoder Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #ifndef _PKCS11OBJECTS_H #define _PKCS11OBJECTS_H #include "pkcs11types.h" #define SC_CLASS 0x00 #define SC_TOKEN 0x01 #define SC_PRIVATE 0x02 #define SC_MODIFIABLE 0x03 #define SC_LABEL 0x04 #define SC_KEY_TYPE 0x05 #define SC_KEY_ID 0x06 #define SC_KEY_START 0x07 #define SC_KEY_END 0x08 #define SC_KEY_DERIVE 0x09 #define SC_KEY_LOCAL 0x10 typedef union SC_OBJECT { struct { CK_ATTRIBUTE class; /* Object type */ CK_ATTRIBUTE token; /* True for token object */ CK_ATTRIBUTE bPrivate; /* True for private objects */ CK_ATTRIBUTE bModifiable; /* True if can be modified */ CK_ATTRIBUTE label; /* Description of the object */ CK_ATTRIBUTE application; /* Description of the managing app */ CK_ATTRIBUTE value; /* Value of the object */ } Data; struct { CK_ATTRIBUTE class; /* Object type */ CK_ATTRIBUTE token; /* True for token object */ CK_ATTRIBUTE bPrivate; /* True for private objects */ CK_ATTRIBUTE bModifiable; /* True if can be modified */ CK_ATTRIBUTE label; /* Description of the object */ CK_ATTRIBUTE type; /* Type of Certificate */ CK_ATTRIBUTE subject; /* DER encoded subject name */ CK_ATTRIBUTE id; /* Key identifier for key pair */ CK_ATTRIBUTE issuer; /* DER encoded issuer name */ CK_ATTRIBUTE serial; /* DER encoded serial number */ CK_ATTRIBUTE value; /* BER encoding of the certificate */ } Cert; struct { CK_ATTRIBUTE class; /* Object type */ CK_ATTRIBUTE token; /* True for token object */ CK_ATTRIBUTE bPrivate; /* True for private objects */ CK_ATTRIBUTE bModifiable; /* True if can be modified */ CK_ATTRIBUTE label; /* Description of the object */ CK_ATTRIBUTE type; /* Type of Key */ CK_ATTRIBUTE id; /* Key identifier for the key */ CK_ATTRIBUTE start; /* Start date for the key */ CK_ATTRIBUTE end; /* End date for the key */ CK_ATTRIBUTE derive; /* TRUE: keys can be derived from */ CK_ATTRIBUTE local; /* Generated locally */ CK_ATTRIBUTE subject; /* DER encoded key subject name */ CK_ATTRIBUTE encrypt; /* TRUE: can encrypt */ CK_ATTRIBUTE verify; /* TRUE: sign is an appendix */ CK_ATTRIBUTE v_recover; /* TRUE: verify where data in sign */ CK_ATTRIBUTE wrap; /* TRUE: if can wrap other keys */ CK_ATTRIBUTE modulus; /* Modulus n */ CK_ATTRIBUTE length; /* Length in bits of modulus n */ CK_ATTRIBUTE exponent; /* Public Exponent e */ } PubKey; struct { CK_ATTRIBUTE class; /* Object type */ CK_ATTRIBUTE token; /* True for token object */ CK_ATTRIBUTE bPrivate; /* True for private objects */ CK_ATTRIBUTE bModifiable; /* True if can be modified */ CK_ATTRIBUTE label; /* Description of the object */ CK_ATTRIBUTE type; /* Type of Key */ CK_ATTRIBUTE id; /* Key identifier for the key */ CK_ATTRIBUTE start; /* Start date for the key */ CK_ATTRIBUTE end; /* End date for the key */ CK_ATTRIBUTE derive; /* TRUE: keys can be derived from */ CK_ATTRIBUTE local; /* Generated locally */ CK_ATTRIBUTE subject; /* DER encoded key subject name */ CK_ATTRIBUTE sensitive; /* TRUE: key is sensitive */ CK_ATTRIBUTE decrypt; /* TRUE: can decrypt */ CK_ATTRIBUTE sign; /* TRUE: sign as an appendix */ CK_ATTRIBUTE s_recover; /* TRUE: verify where data in sign */ CK_ATTRIBUTE unwrap; /* TRUE: if can unwrap other keys */ CK_ATTRIBUTE extractable; /* TRUE: can be extracted */ CK_ATTRIBUTE always_sens; /* TRUE: if sensitive always been T */ CK_ATTRIBUTE never_extract;/* TRUE: if extractable never set T */ CK_ATTRIBUTE modulus; /* Modulus n */ CK_ATTRIBUTE pub_exp; /* Public Exponent e */ CK_ATTRIBUTE priv_exp; /* Public Exponent d */ CK_ATTRIBUTE prime1; /* Prime p */ CK_ATTRIBUTE prime2; /* Prime q */ CK_ATTRIBUTE exp1; /* Private Exponent d modulo p-1 */ CK_ATTRIBUTE exp2; /* Private Exponent d modulo q-1 */ CK_ATTRIBUTE coefficient; /* CRT coefficient q^(-1) mod p */ } PrivKey; struct { CK_ATTRIBUTE class; /* Object type */ CK_ATTRIBUTE token; /* True for token object */ CK_ATTRIBUTE bPrivate; /* True for private objects */ CK_ATTRIBUTE bModifiable; /* True if can be modified */ CK_ATTRIBUTE label; /* Description of the object */ CK_ATTRIBUTE type; /* Type of Key */ CK_ATTRIBUTE id; /* Key identifier for the key */ CK_ATTRIBUTE start; /* Start date for the key */ CK_ATTRIBUTE end; /* End date for the key */ CK_ATTRIBUTE derive; /* TRUE: keys can be derived from */ CK_ATTRIBUTE local; /* Generated locally */ CK_ATTRIBUTE sensitive; /* TRUE: key is sensitive */ CK_ATTRIBUTE encrypt; /* TRUE: can encrypt */ CK_ATTRIBUTE decrypt; /* TRUE: can decrypt */ CK_ATTRIBUTE sign; /* TRUE: sign as an appendix */ CK_ATTRIBUTE verify; /* TRUE: sign is an appendix */ CK_ATTRIBUTE wrap; /* TRUE: if can wrap other keys */ CK_ATTRIBUTE unwrap; /* TRUE: if can unwrap other keys */ CK_ATTRIBUTE extractable; /* TRUE: can be extracted */ CK_ATTRIBUTE always_sens; /* TRUE: if sensitive always been T */ CK_ATTRIBUTE never_extract;/* TRUE: if extractable never set T */ CK_ATTRIBUTE value; /* Key value */ CK_ATTRIBUTE len; /* Length in bytes of key */ } SecretKey; CK_ATTRIBUTE generic[28]; // PrivKey is the largest structure with 28 Attributes } SC_OBJECT; typedef SC_OBJECT * SC_OBJECT_PTR; typedef struct SC_SESSION_HANDLE * SC_SESSION_HANDLE_PTR; typedef struct SC_OBJECT_HANDLE * SC_OBJECT_HANDLE_PTR; typedef struct SC_SESSION_HANDLE { CK_SESSION_HANDLE session; SC_SESSION_HANDLE_PTR next; } SC_SESSION_HANDLE; typedef struct SC_OBJECT_HANDLE { CK_OBJECT_HANDLE object; SC_OBJECT_HANDLE_PTR next; } SC_OBJECT_HANDLE; #endif opencryptoki-2.3.1+dfsg/usr/include/pkcs11/pkcs32.h0000751000175000017500000005046711327631345017576 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/include/pkcs11/pkcs32.h,v 1.2 2005/02/22 20:47:35 mhalcrow Exp $ */ //---------------------------------------------------------------------------- /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ // // File: PKCS11Types.h // // //---------------------------------------------------------------------------- #ifndef _PKCS1132_H_ #define _PKCS1132_H_ #ifdef __cplusplus extern "C" { #endif /* These are the new definitions need for the structures in * leeds_stdll largs.h (and elsewhere) */ typedef unsigned int CK_ULONG_32; typedef int CK_LONG_32; typedef unsigned int * CK_ULONG_PTR_32; typedef CK_ULONG_32 CK_MECHANISM_TYPE_32; typedef CK_ULONG_32 CK_SESSION_HANDLE_32; typedef CK_ULONG_32 CK_SLOT_ID_32; typedef CK_ULONG_32 CK_FLAGS_32; typedef CK_ULONG_32 CK_USER_TYPE_32; typedef CK_ULONG_32 CK_OBJECT_HANDLE_32; typedef CK_OBJECT_HANDLE_32 * CK_OBJECT_HANDLE__PTR_32; typedef CK_ULONG_32 CK_ATTRIBUTE_TYPE_32; typedef CK_ULONG_32 CK_STATE_32; typedef CK_ULONG_32 CK_OBJECT_CLASS_32; typedef CK_BYTE CK_PTR CK_BYTE_PTR_32; typedef CK_CHAR CK_PTR CK_CHAR_PTR_32; typedef CK_ULONG_32 CK_MAC_GENERAL_PARAMS_32; typedef CK_MAC_GENERAL_PARAMS_32 CK_PTR CK_MAC_GENERAL_PARAMS_PTR_32; // SSL 3 Mechanism pointers for the Leeds card. typedef struct CK_SSL3_RANDOM_DATA_32 { CK_BYTE_PTR_32 pClientRandom; CK_ULONG_32 ulClientRandomLen; CK_BYTE_PTR_32 pServerRandom; CK_ULONG_32 ulServerRandomLen; } CK_SSL3_RANDOM_DATA_32; typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS_32 { CK_SSL3_RANDOM_DATA_32 RandomInfo; CK_VERSION_PTR pVersion; } CK_SSL3_MASTER_KEY_DERIVE_PARAMS_32; typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS_32 CK_PTR \ CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR_32; typedef struct CK_SSL3_KEY_MAT_OUT_32 { CK_OBJECT_HANDLE_32 hClientMacSecret; CK_OBJECT_HANDLE_32 hServerMacSecret; CK_OBJECT_HANDLE_32 hClientKey; CK_OBJECT_HANDLE_32 hServerKey; CK_BYTE_PTR_32 pIVClient; CK_BYTE_PTR_32 pIVServer; } CK_SSL3_KEY_MAT_OUT_32; typedef CK_SSL3_KEY_MAT_OUT_32 CK_PTR CK_SSL3_KEY_MAT_OUT_PTR_32; typedef struct CK_SSL3_KEY_MAT_PARAMS_32 { CK_ULONG_32 ulMacSizeInBits; CK_ULONG_32 ulKeySizeInBits; CK_ULONG_32 ulIVSizeInBits; CK_BBOOL bIsExport; CK_SSL3_RANDOM_DATA_32 RandomInfo; CK_SSL3_KEY_MAT_OUT_PTR_32 pReturnedKeyMaterial; } CK_SSL3_KEY_MAT_PARAMS_32; typedef CK_SSL3_KEY_MAT_PARAMS_32 CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR_32; typedef struct CK_KEY_DERIVATION_STRING_DATA_32 { CK_BYTE_PTR_32 pData; CK_ULONG_32 ulLen; } CK_KEY_DERIVATION_STRING_DATA_32; typedef CK_KEY_DERIVATION_STRING_DATA_32 CK_PTR \ CK_KEY_DERIVATION_STRING_DATA_PTR_32; typedef struct CK_TOKEN_INFO_32 { CK_CHAR label[32]; /* blank padded */ CK_CHAR manufacturerID[32]; /* blank padded */ CK_CHAR model[16]; /* blank padded */ CK_CHAR serialNumber[16]; /* blank padded */ CK_FLAGS_32 flags; /* see below */ // SAB FIXME needs to be 32 bit /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount, * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been * changed from CK_USHORT to CK_ULONG for v2.0 */ CK_ULONG_32 ulMaxSessionCount; /* max open sessions */ CK_ULONG_32 ulSessionCount; /* sess. now open */ CK_ULONG_32 ulMaxRwSessionCount; /* max R/W sessions */ CK_ULONG_32 ulRwSessionCount; /* R/W sess. now open */ CK_ULONG_32 ulMaxPinLen; /* in bytes */ CK_ULONG_32 ulMinPinLen; /* in bytes */ CK_ULONG_32 ulTotalPublicMemory; /* in bytes */ CK_ULONG_32 ulFreePublicMemory; /* in bytes */ CK_ULONG_32 ulTotalPrivateMemory; /* in bytes */ CK_ULONG_32 ulFreePrivateMemory; /* in bytes */ /* hardwareVersion, firmwareVersion, and time are new for * v2.0 */ CK_VERSION hardwareVersion; /* version of hardware */ CK_VERSION firmwareVersion; /* version of firmware */ CK_CHAR utcTime[16]; /* time */ } CK_TOKEN_INFO_32; typedef struct CK_SESSION_INFO_32 { CK_SLOT_ID_32 slotID; CK_STATE_32 state; CK_FLAGS_32 flags; /* see below */ /* ulDeviceError was changed from CK_USHORT to CK_ULONG for * v2.0 */ CK_ULONG_32 ulDeviceError; /* device-dependent error code */ } CK_SESSION_INFO_32; typedef struct CK_MECHANISM_INFO_32 { CK_ULONG_32 ulMinKeySize; CK_ULONG_32 ulMaxKeySize; CK_FLAGS_32 flags; } CK_MECHANISM_INFO_32; /* CK_MECHANISM_32 is a structure that specifies a particular * mechanism */ typedef struct CK_MECHANISM_32 { CK_MECHANISM_TYPE_32 mechanism; CK_VOID_PTR pParameter; /* ulParameterLen was changed from CK_USHORT to CK_ULONG for * v2.0 */ CK_ULONG_32 ulParameterLen; /* in bytes */ } CK_MECHANISM_32; /* CK_ATTRIBUTE is a structure that includes the type, length * and value of an attribute */ typedef struct CK_ATTRIBUTE_32 { CK_ATTRIBUTE_TYPE_32 type; CK_ULONG_32 pValue; // SAB XXX XXX Was CK_VOID_PTR which is 64Bit /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */ CK_ULONG_32 ulValueLen; /* in bytes */ } CK_ATTRIBUTE_32; #pragma pack() #ifdef __cplusplus } #endif #endif // _PKCS1132_HS_H_ opencryptoki-2.3.1+dfsg/usr/include/pkcs11/pkcs11types.h0000751000175000017500000022561611327631345020660 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/include/pkcs11/pkcs11types.h,v 1.5 2007/12/05 22:52:01 mhalcrow Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ //---------------------------------------------------------------------------- // // File: PKCS11Types.h // // //---------------------------------------------------------------------------- #ifndef _PKCS11TYPES_H_ #define _PKCS11TYPES_H_ #ifdef __cplusplus extern "C" { #endif #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE (!FALSE) #endif // AIX Addition for 64Bit work. // All types are 32bit types, therefore the longs have to be // typedefed to be 32bit values. typedef unsigned int uint_32; typedef int int_32; #define CK_PTR * #define CK_CALLBACK_FUNCTION(returnType, name) \ returnType (* name) #ifndef NULL_PTR #define NULL_PTR ((void *) NULL) #endif /* NULL_PTR */ /* an unsigned 8-bit value */ typedef unsigned char CK_BYTE; /* an unsigned 8-bit character */ typedef CK_BYTE CK_CHAR; /* an 8-bit UTF-8 character */ typedef CK_BYTE CK_UTF8CHAR; /* a BYTE-sized Boolean flag */ typedef CK_BYTE CK_BBOOL; /* an unsigned value, at least 32 bits long */ typedef unsigned long int CK_ULONG; /* a signed value, the same size as a CK_ULONG */ /* CK_LONG is new for v2.0 */ typedef long int CK_LONG; /* at least 32 bits; each bit is a Boolean flag */ typedef CK_ULONG CK_FLAGS; /* some special values for certain CK_ULONG variables */ #define CK_UNAVAILABLE_INFORMATION (~0UL) #define CK_EFFECTIVELY_INFINITE 0 typedef CK_BYTE CK_PTR CK_BYTE_PTR; typedef CK_CHAR CK_PTR CK_CHAR_PTR; typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR; typedef CK_ULONG CK_PTR CK_ULONG_PTR; typedef void CK_PTR CK_VOID_PTR; /* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */ typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR; /* The following value is always invalid if used as a session */ /* handle or object handle */ #define CK_INVALID_HANDLE 0 typedef struct CK_VERSION { CK_BYTE major; /* integer portion of version number */ CK_BYTE minor; /* 1/100ths portion of version number */ } CK_VERSION; typedef CK_VERSION CK_PTR CK_VERSION_PTR; typedef struct CK_INFO { CK_VERSION cryptokiVersion; /* Cryptoki interface ver */ CK_CHAR manufacturerID[32]; /* blank padded */ CK_FLAGS flags; /* must be zero */ /* libraryDescription and libraryVersion are new for v2.0 */ CK_CHAR libraryDescription[32]; /* blank padded */ CK_VERSION libraryVersion; /* version of library */ } CK_INFO; typedef CK_INFO CK_PTR CK_INFO_PTR; /* CK_NOTIFICATION enumerates the types of notifications that * Cryptoki provides to an application */ /* CK_NOTIFICATION has been changed from an enum to a CK_ULONG * for v2.0 */ typedef CK_ULONG CK_NOTIFICATION; #define CKN_SURRENDER 0 typedef CK_ULONG CK_SLOT_ID; typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR; /* CK_SLOT_INFO provides information about a slot */ typedef struct CK_SLOT_INFO { CK_CHAR slotDescription[64]; /* blank padded */ CK_CHAR manufacturerID[32]; /* blank padded */ CK_FLAGS flags; /* hardwareVersion and firmwareVersion are new for v2.0 */ CK_VERSION hardwareVersion; /* version of hardware */ CK_VERSION firmwareVersion; /* version of firmware */ } CK_SLOT_INFO; /* flags: bit flags that provide capabilities of the slot * Bit Flag Mask Meaning */ #define CKF_TOKEN_PRESENT 0x00000001 /* a token is there */ #define CKF_REMOVABLE_DEVICE 0x00000002 /* removable devices*/ #define CKF_HW_SLOT 0x00000004 /* hardware slot */ typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR; /* CK_TOKEN_INFO provides information about a token */ typedef struct CK_TOKEN_INFO { CK_CHAR label[32]; /* blank padded */ CK_CHAR manufacturerID[32]; /* blank padded */ CK_CHAR model[16]; /* blank padded */ CK_CHAR serialNumber[16]; /* blank padded */ CK_FLAGS flags; /* see below */ /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount, * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been * changed from CK_USHORT to CK_ULONG for v2.0 */ CK_ULONG ulMaxSessionCount; /* max open sessions */ CK_ULONG ulSessionCount; /* sess. now open */ CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */ CK_ULONG ulRwSessionCount; /* R/W sess. now open */ CK_ULONG ulMaxPinLen; /* in bytes */ CK_ULONG ulMinPinLen; /* in bytes */ CK_ULONG ulTotalPublicMemory; /* in bytes */ CK_ULONG ulFreePublicMemory; /* in bytes */ CK_ULONG ulTotalPrivateMemory; /* in bytes */ CK_ULONG ulFreePrivateMemory; /* in bytes */ /* hardwareVersion, firmwareVersion, and time are new for * v2.0 */ CK_VERSION hardwareVersion; /* version of hardware */ CK_VERSION firmwareVersion; /* version of firmware */ CK_CHAR utcTime[16]; /* time */ } CK_TOKEN_INFO; /* The flags parameter is defined as follows: * Bit Flag Mask Meaning */ #define CKF_RNG 0x00000001 /* has random # * generator */ #define CKF_WRITE_PROTECTED 0x00000002 /* token is * write- * protected */ #define CKF_LOGIN_REQUIRED 0x00000004 /* user must * login */ #define CKF_USER_PIN_INITIALIZED 0x00000008 /* normal user's * PIN is set */ /* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0. If it is set, * that means that *every* time the state of cryptographic * operations of a session is successfully saved, all keys * needed to continue those operations are stored in the state */ #define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020 /* CKF_CLOCK_ON_TOKEN is new for v2.0. If it is set, that means * that the token has some sort of clock. The time on that * clock is returned in the token info structure */ #define CKF_CLOCK_ON_TOKEN 0x00000040 /* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0. If it is * set, that means that there is some way for the user to login * without sending a PIN through the Cryptoki library itself */ #define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100 /* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0. If it is true, * that means that a single session with the token can perform * dual simultaneous cryptographic operations (digest and * encrypt; decrypt and digest; sign and encrypt; and decrypt * and sign) */ #define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200 /* CKF_TOKEN_INITIALIZED is new for v2.11. If it is true, the * token has been initialized using C_InitializeToken or an * equivalent mechanism outside the scope of this standard. * Calling C_InitializeToken when this flag is set will cause * the token to be reinitialized. */ #define CKF_TOKEN_INITIALIZED 0x00000400 /* CKF_SECONDARY_AUTHENTICATION is new for v2.11. If it is * true, the token supports secondary authentication for private * key objects. According to the 2.11 spec pg. 45, this flag * is deprecated and this flags should never be true. */ #define CKF_SECONDARY_AUTHENTICATION 0x00000800 /* CKF_USER_PIN_COUNT_LOW is new in v2.11. This flag is true * is an incorrect user PIN has been entered at least once * since the last successful authentication. */ #define CKF_USER_PIN_COUNT_LOW 0x00010000 /* CKF_USER_PIN_FINAL_TRY is new in v2.11. This flag is true if * supplying an incorrect user PIN will cause it to become * locked. */ #define CKF_USER_PIN_FINAL_TRY 0x00020000 /* CKF_USER_PIN_LOCKED is new in v2.11. This is true if the * user PIN has been locked. User login to the token is not * possible. */ #define CKF_USER_PIN_LOCKED 0x00040000 /* CKF_USER_PIN_TO_BE_CHANGED is new in v2.11. This flag is * true if the user PIN value is the default value set by * token initialization of manufacturing, or the PIN has * been expired by the card. */ #define CKF_USER_PIN_TO_BE_CHANGED 0x00080000 /* CKF_SO_PIN_COUNT_LOW is new in v2.11. This flag is true if * and incorrect SO login PIN has been entered at least once * since the last successful authentication. */ #define CKF_SO_PIN_COUNT_LOW 0x00100000 /* CKF_SO_PIN_FINAL_TRY is new in v2.11. This flag is true if * supplying an incorrect SO PIN will cause it to become * locked. */ #define CKF_SO_PIN_FINAL_TRY 0x00200000 /* CKF_SO_PIN_LOCKED is new in v2.11. This flag is true if * the SO PIN has been locked. User login to the token is not * possible. */ #define CKF_SO_PIN_LOCKED 0x00400000 /* CKF_SO_PIN_TO_BE_CHANGED is new in v2.11. This flag is true * if the SO PIN calue is the default value set by token init- * ialization of manufacturing, or the PIN has been expired by * the card. */ #define CKF_SO_PIN_TO_BE_CHANGED 0x00800000 #if 0 /* IBM extended Token Info Flags - defined by Michael Hamann */ /* These Flags are not part of PKCS#11 Version 2.01 */ /* This will be used to track the state of login retries */ #define CKF_USER_PIN_COUNT_LOW 0x00010000 #define CKF_USER_PIN_FINAL_TRY 0x00020000 #define CKF_USER_PIN_LOCKED 0x00040000 #define CKF_USER_PIN_MANUFACT_VALUE 0x00080000 #define CKF_SO_PIN_COUNT_LOW 0x00100000 #define CKF_SO_PIN_FINAL_TRY 0x00200000 #define CKF_SO_PIN_LOCKED 0x00400000 #define CKF_SO_PIN_MANUFACT_VALUE 0x00800000 #endif /* other IBM extended Token info Flags 05/29/99 */ #define CKF_SO_PIN_DERIVED 0x01000000 // Sec Officer pin on card is derived from card id #define CKF_SO_CARD 0x02000000 // Security Officer Card /* End of IBM extented Token Info Flags */ typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR; /* CK_SESSION_HANDLE is a Cryptoki-assigned value that * identifies a session */ typedef CK_ULONG CK_SESSION_HANDLE; typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR; /* CK_USER_TYPE enumerates the types of Cryptoki users */ /* CK_USER_TYPE has been changed from an enum to a CK_ULONG for * v2.0 */ typedef CK_ULONG CK_USER_TYPE; /* Security Officer */ #define CKU_SO 0 /* Normal user */ #define CKU_USER 1 /* CK_STATE enumerates the session states */ /* CK_STATE has been changed from an enum to a CK_ULONG for * v2.0 */ typedef CK_ULONG CK_STATE; #define CKS_RO_PUBLIC_SESSION 0 #define CKS_RO_USER_FUNCTIONS 1 #define CKS_RW_PUBLIC_SESSION 2 #define CKS_RW_USER_FUNCTIONS 3 #define CKS_RW_SO_FUNCTIONS 4 /* CK_SESSION_INFO provides information about a session */ typedef struct CK_SESSION_INFO { CK_SLOT_ID slotID; CK_STATE state; CK_FLAGS flags; /* see below */ /* ulDeviceError was changed from CK_USHORT to CK_ULONG for * v2.0 */ CK_ULONG ulDeviceError; /* device-dependent error code */ } CK_SESSION_INFO; /* The flags are defined in the following table: * Bit Flag Mask Meaning */ #define CKF_RW_SESSION 0x00000002 /* session is r/w */ #define CKF_SERIAL_SESSION 0x00000004 /* no parallel */ typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR; /* CK_OBJECT_HANDLE is a token-specific identifier for an * object */ typedef CK_ULONG CK_OBJECT_HANDLE; typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR; /* CK_OBJECT_CLASS is a value that identifies the classes (or * types) of objects that Cryptoki recognizes. It is defined * as follows: */ /* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for * v2.0 */ typedef CK_ULONG CK_OBJECT_CLASS; /* The following classes of objects are defined: */ #define CKO_DATA 0x00000000 #define CKO_CERTIFICATE 0x00000001 #define CKO_PUBLIC_KEY 0x00000002 #define CKO_PRIVATE_KEY 0x00000003 #define CKO_SECRET_KEY 0x00000004 /* CKO_HW_FEATURE and CKO_DOMAIN_PARAMETERS are new for v2.11 */ #define CKO_HW_FEATURE 0x00000005 #define CKO_DOMAIN_PARAMETERS 0x00000006 #define CKO_VENDOR_DEFINED 0x80000000 typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR; /* CK_HW_FEATURE_TYPE is a value that identifies a hardware * feature type of a device. This is new for v2.11. */ typedef CK_ULONG CK_HW_FEATURE_TYPE; /* The following hardware feature types are defined: */ #define CKH_MONOTONIC_COUNTER 0x00000001 #define CKH_CLOCK 0x00000002 #define CKH_VENDOR_DEFINED 0x80000000 /* CK_KEY_TYPE is a value that identifies a key type */ /* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */ typedef CK_ULONG CK_KEY_TYPE; /* the following key types are defined: */ #define CKK_RSA 0x00000000 #define CKK_DSA 0x00000001 #define CKK_DH 0x00000002 /* CKK_ECDSA and CKK_KEA are new for v2.0 */ /* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred */ #define CKK_ECDSA 0x00000003 #define CKK_EC 0x00000003 #define CKK_X9_42_DH 0x00000004 #define CKK_KEA 0x00000005 #define CKK_GENERIC_SECRET 0x00000010 #define CKK_RC2 0x00000011 #define CKK_RC4 0x00000012 #define CKK_DES 0x00000013 #define CKK_DES2 0x00000014 #define CKK_DES3 0x00000015 /* all these key types are new for v2.0 */ #define CKK_CAST 0x00000016 #define CKK_CAST3 0x00000017 /* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred */ #define CKK_CAST5 0x00000018 #define CKK_CAST128 0x00000018 /* CAST128=CAST5 */ #define CKK_RC5 0x00000019 #define CKK_IDEA 0x0000001A #define CKK_SKIPJACK 0x0000001B #define CKK_BATON 0x0000001C #define CKK_JUNIPER 0x0000001D #define CKK_CDMF 0x0000001E /* CKK_AES is new for v2.11 */ #define CKK_AES 0x0000001F #define CKK_VENDOR_DEFINED 0x80000000 /* CK_CERTIFICATE_TYPE is a value that identifies a certificate * type */ /* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG * for v2.0 */ typedef CK_ULONG CK_CERTIFICATE_TYPE; /* The following certificate types are defined: */ #define CKC_X_509 0x00000000 /* CKC_X_509_ATTR_CERT is new for v2.11 */ #define CKC_X_509_ATTR_CERT 0x00000001 #define CKC_VENDOR_DEFINED 0x80000000 /* CK_ATTRIBUTE_TYPE is a value that identifies an attribute * type */ /* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for * v2.0 */ typedef CK_ULONG CK_ATTRIBUTE_TYPE; /* The following attribute types are defined: */ #define CKA_CLASS 0x00000000 #define CKA_TOKEN 0x00000001 #define CKA_PRIVATE 0x00000002 #define CKA_LABEL 0x00000003 #define CKA_APPLICATION 0x00000010 #define CKA_VALUE 0x00000011 /* CKA_OBJECT_ID is new for v2.11 */ #define CKA_OBJECT_ID 0x00000012 #define CKA_CERTIFICATE_TYPE 0x00000080 #define CKA_ISSUER 0x00000081 #define CKA_SERIAL_NUMBER 0x00000082 /* CKA_AC_ISSUER, CKA_OWNER, CKA_ATTR_TYPES and CKA_TRUSTED * are new for v2.11 */ #define CKA_AC_ISSUER 0x00000083 #define CKA_OWNER 0x00000084 #define CKA_ATTR_TYPES 0x00000085 #define CKA_TRUSTED 0x00000086 #define CKA_KEY_TYPE 0x00000100 #define CKA_SUBJECT 0x00000101 #define CKA_ID 0x00000102 #define CKA_SENSITIVE 0x00000103 #define CKA_ENCRYPT 0x00000104 #define CKA_DECRYPT 0x00000105 #define CKA_WRAP 0x00000106 #define CKA_UNWRAP 0x00000107 #define CKA_SIGN 0x00000108 #define CKA_SIGN_RECOVER 0x00000109 #define CKA_VERIFY 0x0000010A #define CKA_VERIFY_RECOVER 0x0000010B #define CKA_DERIVE 0x0000010C #define CKA_START_DATE 0x00000110 #define CKA_END_DATE 0x00000111 #define CKA_MODULUS 0x00000120 #define CKA_MODULUS_BITS 0x00000121 #define CKA_PUBLIC_EXPONENT 0x00000122 #define CKA_PRIVATE_EXPONENT 0x00000123 #define CKA_PRIME_1 0x00000124 #define CKA_PRIME_2 0x00000125 #define CKA_EXPONENT_1 0x00000126 #define CKA_EXPONENT_2 0x00000127 #define CKA_COEFFICIENT 0x00000128 #define CKA_PRIME 0x00000130 #define CKA_SUBPRIME 0x00000131 #define CKA_BASE 0x00000132 /* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */ #define CKA_PRIME_BITS 0x00000133 #define CKA_SUBPRIME_BITS 0x00000134 #define CKA_VALUE_BITS 0x00000160 #define CKA_VALUE_LEN 0x00000161 /* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE, * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS, * and CKA_EC_POINT are new for v2.0 */ #define CKA_EXTRACTABLE 0x00000162 #define CKA_LOCAL 0x00000163 #define CKA_NEVER_EXTRACTABLE 0x00000164 #define CKA_ALWAYS_SENSITIVE 0x00000165 /* CKA_KEY_GEN_MECHANISM is new for v2.11 */ #define CKA_KEY_GEN_MECHANISM 0x00000166 #define CKA_MODIFIABLE 0x00000170 /* CKA_ECDSA_PARAMS is deprecated in v2.11, CKA_EC_PARAMS is preferred */ #define CKA_ECDSA_PARAMS 0x00000180 #define CKA_EC_PARAMS 0x00000180 #define CKA_EC_POINT 0x00000181 /* The following are new for v2.11 */ #define CKA_SECONDARY_AUTH 0x00000200 #define CKA_AUTH_PIN_FLAGS 0x00000201 #define CKA_HW_FEATURE_TYPE 0x00000300 #define CKA_RESET_ON_INIT 0x00000301 #define CKA_HAS_RESET 0x00000302 #define CKA_VENDOR_DEFINED 0x80000000 /* For use in storing objects that have an encrypted or otherwise * opaque attribute. Support has been added to use this attribute * in key objects only. */ #define CKA_IBM_OPAQUE CKA_VENDOR_DEFINED + 1 /* CK_ATTRIBUTE is a structure that includes the type, length * and value of an attribute */ typedef struct CK_ATTRIBUTE { CK_ATTRIBUTE_TYPE type; CK_VOID_PTR pValue; /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */ CK_ULONG ulValueLen; /* in bytes */ } CK_ATTRIBUTE; typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR; /* CK_DATE is a structure that defines a date */ typedef struct CK_DATE{ CK_CHAR year[4]; /* the year ("1900" - "9999") */ CK_CHAR month[2]; /* the month ("01" - "12") */ CK_CHAR day[2]; /* the day ("01" - "31") */ } CK_DATE; /* CK_MECHANISM_TYPE is a value that identifies a mechanism * type */ /* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for * v2.0 */ typedef CK_ULONG CK_MECHANISM_TYPE; /* the following mechanism types are defined: */ #define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000 #define CKM_RSA_PKCS 0x00000001 #define CKM_RSA_9796 0x00000002 #define CKM_RSA_X_509 0x00000003 /* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS * are new for v2.0. They are mechanisms which hash and sign */ #define CKM_MD2_RSA_PKCS 0x00000004 #define CKM_MD5_RSA_PKCS 0x00000005 #define CKM_SHA1_RSA_PKCS 0x00000006 /* The following are new for v2.11: */ #define CKM_RIPEMD128_RSA_PKCS 0x00000007 #define CKM_RIPEMD160_RSA_PKCS 0x00000008 #define CKM_RSA_PKCS_OAEP 0x00000009 #define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000A #define CKM_RSA_X9_31 0x0000000B #define CKM_SHA1_RSA_X9_31 0x0000000C #define CKM_RSA_PKCS_PSS 0x0000000D #define CKM_SHA1_RSA_PKCS_PSS 0x0000000E #define CKM_DSA_KEY_PAIR_GEN 0x00000010 #define CKM_DSA 0x00000011 #define CKM_DSA_SHA1 0x00000012 #define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020 #define CKM_DH_PKCS_DERIVE 0x00000021 /* The following are new for v2.11 */ #define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030 #define CKM_X9_42_DH_DERIVE 0x00000031 #define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032 #define CKM_X9_42_MQV_DERIVE 0x00000033 #define CKM_SHA256_RSA_PKCS 0x00000043 #define CKM_RC2_KEY_GEN 0x00000100 #define CKM_RC2_ECB 0x00000101 #define CKM_RC2_CBC 0x00000102 #define CKM_RC2_MAC 0x00000103 /* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */ #define CKM_RC2_MAC_GENERAL 0x00000104 #define CKM_RC2_CBC_PAD 0x00000105 #define CKM_RC4_KEY_GEN 0x00000110 #define CKM_RC4 0x00000111 #define CKM_DES_KEY_GEN 0x00000120 #define CKM_DES_ECB 0x00000121 #define CKM_DES_CBC 0x00000122 #define CKM_DES_MAC 0x00000123 /* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */ #define CKM_DES_MAC_GENERAL 0x00000124 #define CKM_DES_CBC_PAD 0x00000125 #define CKM_DES2_KEY_GEN 0x00000130 #define CKM_DES3_KEY_GEN 0x00000131 #define CKM_DES3_ECB 0x00000132 #define CKM_DES3_CBC 0x00000133 #define CKM_DES3_MAC 0x00000134 /* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN, * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC, * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */ #define CKM_DES3_MAC_GENERAL 0x00000135 #define CKM_DES3_CBC_PAD 0x00000136 #define CKM_CDMF_KEY_GEN 0x00000140 #define CKM_CDMF_ECB 0x00000141 #define CKM_CDMF_CBC 0x00000142 #define CKM_CDMF_MAC 0x00000143 #define CKM_CDMF_MAC_GENERAL 0x00000144 #define CKM_CDMF_CBC_PAD 0x00000145 #define CKM_MD2 0x00000200 /* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */ #define CKM_MD2_HMAC 0x00000201 #define CKM_MD2_HMAC_GENERAL 0x00000202 #define CKM_MD5 0x00000210 /* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */ #define CKM_MD5_HMAC 0x00000211 #define CKM_MD5_HMAC_GENERAL 0x00000212 #define CKM_SHA_1 0x00000220 /* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */ #define CKM_SHA_1_HMAC 0x00000221 #define CKM_SHA_1_HMAC_GENERAL 0x00000222 /* The following are new for v2.11 */ #define CKM_RIPEMD128 0x00000230 #define CKM_RIPEMD128_HMAC 0x00000231 #define CKM_RIPEMD128_HMAC_GENERAL 0x00000232 #define CKM_RIPEMD160 0x00000240 #define CKM_RIPEMD160_HMAC 0x00000241 #define CKM_RIPEMD160_HMAC_GENERAL 0x00000242 #define CKM_SHA256 0x00000250 #define CKM_SHA256_HMAC 0x00000251 #define CKM_SHA256_HMAC_GENERAL 0x00000252 #define CKM_SHA384 0x00000260 #define CKM_SHA384_HMAC 0x00000261 #define CKM_SHA384_HMAC_GENERAL 0x00000262 #define CKM_SHA512 0x00000270 #define CKM_SHA512_HMAC 0x00000271 #define CKM_SHA512_HMAC_GENERAL 0x00000272 /* All of the following mechanisms are new for v2.0 */ /* Note that CAST128 and CAST5 are the same algorithm */ #define CKM_CAST_KEY_GEN 0x00000300 #define CKM_CAST_ECB 0x00000301 #define CKM_CAST_CBC 0x00000302 #define CKM_CAST_MAC 0x00000303 #define CKM_CAST_MAC_GENERAL 0x00000304 #define CKM_CAST_CBC_PAD 0x00000305 #define CKM_CAST3_KEY_GEN 0x00000310 #define CKM_CAST3_ECB 0x00000311 #define CKM_CAST3_CBC 0x00000312 #define CKM_CAST3_MAC 0x00000313 #define CKM_CAST3_MAC_GENERAL 0x00000314 #define CKM_CAST3_CBC_PAD 0x00000315 #define CKM_CAST5_KEY_GEN 0x00000320 #define CKM_CAST128_KEY_GEN 0x00000320 #define CKM_CAST5_ECB 0x00000321 #define CKM_CAST128_ECB 0x00000321 #define CKM_CAST5_CBC 0x00000322 #define CKM_CAST128_CBC 0x00000322 #define CKM_CAST5_MAC 0x00000323 #define CKM_CAST128_MAC 0x00000323 #define CKM_CAST5_MAC_GENERAL 0x00000324 #define CKM_CAST128_MAC_GENERAL 0x00000324 #define CKM_CAST5_CBC_PAD 0x00000325 #define CKM_CAST128_CBC_PAD 0x00000325 #define CKM_RC5_KEY_GEN 0x00000330 #define CKM_RC5_ECB 0x00000331 #define CKM_RC5_CBC 0x00000332 #define CKM_RC5_MAC 0x00000333 #define CKM_RC5_MAC_GENERAL 0x00000334 #define CKM_RC5_CBC_PAD 0x00000335 #define CKM_IDEA_KEY_GEN 0x00000340 #define CKM_IDEA_ECB 0x00000341 #define CKM_IDEA_CBC 0x00000342 #define CKM_IDEA_MAC 0x00000343 #define CKM_IDEA_MAC_GENERAL 0x00000344 #define CKM_IDEA_CBC_PAD 0x00000345 #define CKM_GENERIC_SECRET_KEY_GEN 0x00000350 #define CKM_CONCATENATE_BASE_AND_KEY 0x00000360 #define CKM_CONCATENATE_BASE_AND_DATA 0x00000362 #define CKM_CONCATENATE_DATA_AND_BASE 0x00000363 #define CKM_XOR_BASE_AND_DATA 0x00000364 #define CKM_EXTRACT_KEY_FROM_KEY 0x00000365 #define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370 #define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371 #define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372 /* The following are new for v2.11 */ #define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373 #define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374 #define CKM_TLS_MASTER_KEY_DERIVE 0x00000375 #define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376 #define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377 #define CKM_SSL3_MD5_MAC 0x00000380 #define CKM_SSL3_SHA1_MAC 0x00000381 #define CKM_MD5_KEY_DERIVATION 0x00000390 #define CKM_MD2_KEY_DERIVATION 0x00000391 #define CKM_SHA1_KEY_DERIVATION 0x00000392 #define CKM_SHA256_KEY_DERIVATION 0x00000393 #define CKM_PBE_MD2_DES_CBC 0x000003A0 #define CKM_PBE_MD5_DES_CBC 0x000003A1 #define CKM_PBE_MD5_CAST_CBC 0x000003A2 #define CKM_PBE_MD5_CAST3_CBC 0x000003A3 #define CKM_PBE_MD5_CAST5_CBC 0x000003A4 #define CKM_PBE_MD5_CAST128_CBC 0x000003A4 #define CKM_PBE_SHA1_CAST5_CBC 0x000003A5 #define CKM_PBE_SHA1_CAST128_CBC 0x000003A5 #define CKM_PBE_SHA1_RC4_128 0x000003A6 #define CKM_PBE_SHA1_RC4_40 0x000003A7 #define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8 #define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9 #define CKM_PBE_SHA1_RC2_128_CBC 0x000003AA #define CKM_PBE_SHA1_RC2_40_CBC 0x000003AB /* CKM_PKCS5_PBKD2 is new for v2.11 */ #define CKM_PKCS5_PBKD2 0x000003B0 #define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0 #define CKM_KEY_WRAP_LYNKS 0x00000400 #define CKM_KEY_WRAP_SET_OAEP 0x00000401 /* Fortezza mechanisms */ #define CKM_SKIPJACK_KEY_GEN 0x00001000 #define CKM_SKIPJACK_ECB64 0x00001001 #define CKM_SKIPJACK_CBC64 0x00001002 #define CKM_SKIPJACK_OFB64 0x00001003 #define CKM_SKIPJACK_CFB64 0x00001004 #define CKM_SKIPJACK_CFB32 0x00001005 #define CKM_SKIPJACK_CFB16 0x00001006 #define CKM_SKIPJACK_CFB8 0x00001007 #define CKM_SKIPJACK_WRAP 0x00001008 #define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009 #define CKM_SKIPJACK_RELAYX 0x0000100a #define CKM_KEA_KEY_PAIR_GEN 0x00001010 #define CKM_KEA_KEY_DERIVE 0x00001011 #define CKM_FORTEZZA_TIMESTAMP 0x00001020 #define CKM_BATON_KEY_GEN 0x00001030 #define CKM_BATON_ECB128 0x00001031 #define CKM_BATON_ECB96 0x00001032 #define CKM_BATON_CBC128 0x00001033 #define CKM_BATON_COUNTER 0x00001034 #define CKM_BATON_SHUFFLE 0x00001035 #define CKM_BATON_WRAP 0x00001036 /* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11, * CKM_EC_KEY_PAIR_GEN is preferred. */ #define CKM_ECDSA_KEY_PAIR_GEN 0x00001040 #define CKM_EC_KEY_PAIR_GEN 0x00001040 #define CKM_ECDSA 0x00001041 #define CKM_ECDSA_SHA1 0x00001042 /* The following are new for v2.11 */ #define CKM_ECDH1_DERIVE 0x00001050 #define CKM_ECDH1_COFACTOR_DERIVE 0x00001051 #define CKM_ECMQV_DERIVE 0x00001052 #define CKM_JUNIPER_KEY_GEN 0x00001060 #define CKM_JUNIPER_ECB128 0x00001061 #define CKM_JUNIPER_CBC128 0x00001062 #define CKM_JUNIPER_COUNTER 0x00001063 #define CKM_JUNIPER_SHUFFLE 0x00001064 #define CKM_JUNIPER_WRAP 0x00001065 #define CKM_FASTHASH 0x00001070 /* The following are new for v2.11 */ #define CKM_AES_KEY_GEN 0x00001080 #define CKM_AES_ECB 0x00001081 #define CKM_AES_CBC 0x00001082 #define CKM_AES_MAC 0x00001083 #define CKM_AES_MAC_GENERAL 0x00001084 #define CKM_AES_CBC_PAD 0x00001085 #define CKM_DSA_PARAMETER_GEN 0x00002000 #define CKM_DH_PKCS_PARAMETER_GEN 0x00002001 #define CKM_X9_42_DH_PARAMETER_GEN 0x00002002 #define CKM_VENDOR_DEFINED 0x80000000 typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR; /* CK_MECHANISM is a structure that specifies a particular * mechanism */ typedef struct CK_MECHANISM { CK_MECHANISM_TYPE mechanism; CK_VOID_PTR pParameter; /* ulParameterLen was changed from CK_USHORT to CK_ULONG for * v2.0 */ CK_ULONG ulParameterLen; /* in bytes */ } CK_MECHANISM; typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR; /* CK_MECHANISM_INFO provides information about a particular * mechanism */ typedef struct CK_MECHANISM_INFO { CK_ULONG ulMinKeySize; CK_ULONG ulMaxKeySize; CK_FLAGS flags; } CK_MECHANISM_INFO; /* The flags are defined as follows: * Bit Flag Mask Meaning */ #define CKF_HW 0x00000001 /* performed by HW */ /* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN, * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER, * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP, * and CKF_DERIVE are new for v2.0. They specify whether or not * a mechanism can be used for a particular task */ #define CKF_ENCRYPT 0x00000100 #define CKF_DECRYPT 0x00000200 #define CKF_DIGEST 0x00000400 #define CKF_SIGN 0x00000800 #define CKF_SIGN_RECOVER 0x00001000 #define CKF_VERIFY 0x00002000 #define CKF_VERIFY_RECOVER 0x00004000 #define CKF_GENERATE 0x00008000 #define CKF_GENERATE_KEY_PAIR 0x00010000 #define CKF_WRAP 0x00020000 #define CKF_UNWRAP 0x00040000 #define CKF_DERIVE 0x00080000 /* The following are new for v2.11 */ #define CKF_EC_F_P 0x00100000 #define CKF_EC_F_2M 0x00200000 #define CKF_EC_ECPARAMETERS 0x00400000 #define CKF_EC_NAMEDCURVE 0x00800000 #define CKF_EC_UNCOMPRESS 0x01000000 #define CKF_EC_COMPRESS 0x02000000 #define CKF_EXTENSION 0x80000000 /* FALSE for 2.01 */ typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR; /* CK_RV is a value that identifies the return value of a * Cryptoki function */ /* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */ typedef CK_ULONG CK_RV; #define CKR_OK 0x00000000 #define CKR_CANCEL 0x00000001 #define CKR_HOST_MEMORY 0x00000002 #define CKR_SLOT_ID_INVALID 0x00000003 /* CKR_FLAGS_INVALID was removed for v2.0 */ /* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */ #define CKR_GENERAL_ERROR 0x00000005 #define CKR_FUNCTION_FAILED 0x00000006 /* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS, * and CKR_CANT_LOCK are new for v2.01 */ #define CKR_ARGUMENTS_BAD 0x00000007 #define CKR_NO_EVENT 0x00000008 #define CKR_NEED_TO_CREATE_THREADS 0x00000009 #define CKR_CANT_LOCK 0x0000000A #define CKR_ATTRIBUTE_READ_ONLY 0x00000010 #define CKR_ATTRIBUTE_SENSITIVE 0x00000011 #define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012 #define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013 #define CKR_DATA_INVALID 0x00000020 #define CKR_DATA_LEN_RANGE 0x00000021 #define CKR_DEVICE_ERROR 0x00000030 #define CKR_DEVICE_MEMORY 0x00000031 #define CKR_DEVICE_REMOVED 0x00000032 #define CKR_ENCRYPTED_DATA_INVALID 0x00000040 #define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041 #define CKR_FUNCTION_CANCELED 0x00000050 #define CKR_FUNCTION_NOT_PARALLEL 0x00000051 /* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */ #define CKR_FUNCTION_NOT_SUPPORTED 0x00000054 #define CKR_KEY_HANDLE_INVALID 0x00000060 /* CKR_KEY_SENSITIVE was removed for v2.0 */ #define CKR_KEY_SIZE_RANGE 0x00000062 #define CKR_KEY_TYPE_INCONSISTENT 0x00000063 /* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED, * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED, * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for * v2.0 */ #define CKR_KEY_NOT_NEEDED 0x00000064 #define CKR_KEY_CHANGED 0x00000065 #define CKR_KEY_NEEDED 0x00000066 #define CKR_KEY_INDIGESTIBLE 0x00000067 #define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068 #define CKR_KEY_NOT_WRAPPABLE 0x00000069 #define CKR_KEY_UNEXTRACTABLE 0x0000006A #define CKR_MECHANISM_INVALID 0x00000070 #define CKR_MECHANISM_PARAM_INVALID 0x00000071 /* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID * were removed for v2.0 */ #define CKR_OBJECT_HANDLE_INVALID 0x00000082 #define CKR_OPERATION_ACTIVE 0x00000090 #define CKR_OPERATION_NOT_INITIALIZED 0x00000091 #define CKR_PIN_INCORRECT 0x000000A0 #define CKR_PIN_INVALID 0x000000A1 #define CKR_PIN_LEN_RANGE 0x000000A2 /* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */ #define CKR_PIN_EXPIRED 0x000000A3 #define CKR_PIN_LOCKED 0x000000A4 #define CKR_SESSION_CLOSED 0x000000B0 #define CKR_SESSION_COUNT 0x000000B1 #define CKR_SESSION_HANDLE_INVALID 0x000000B3 #define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4 #define CKR_SESSION_READ_ONLY 0x000000B5 #define CKR_SESSION_EXISTS 0x000000B6 /* CKR_SESSION_READ_ONLY_EXISTS and * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */ #define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7 #define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8 #define CKR_SIGNATURE_INVALID 0x000000C0 #define CKR_SIGNATURE_LEN_RANGE 0x000000C1 #define CKR_TEMPLATE_INCOMPLETE 0x000000D0 #define CKR_TEMPLATE_INCONSISTENT 0x000000D1 #define CKR_TOKEN_NOT_PRESENT 0x000000E0 #define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1 #define CKR_TOKEN_WRITE_PROTECTED 0x000000E2 #define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0 #define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1 #define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2 #define CKR_USER_ALREADY_LOGGED_IN 0x00000100 #define CKR_USER_NOT_LOGGED_IN 0x00000101 #define CKR_USER_PIN_NOT_INITIALIZED 0x00000102 #define CKR_USER_TYPE_INVALID 0x00000103 /* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES * are new to v2.01 */ #define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104 #define CKR_USER_TOO_MANY_TYPES 0x00000105 #define CKR_WRAPPED_KEY_INVALID 0x00000110 #define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112 #define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113 #define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114 #define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115 #define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120 /* These are new to v2.0 */ #define CKR_RANDOM_NO_RNG 0x00000121 /* CKR_DOMAIN_PARAMS_INVALID is new for v2.11 */ #define CKR_DOMAIN_PARAMS_INVALID 0x00000130 #define CKR_BUFFER_TOO_SMALL 0x00000150 #define CKR_SAVED_STATE_INVALID 0x00000160 #define CKR_INFORMATION_SENSITIVE 0x00000170 #define CKR_STATE_UNSAVEABLE 0x00000180 /* These are new to v2.01 */ #define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190 #define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191 #define CKR_MUTEX_BAD 0x000001A0 #define CKR_MUTEX_NOT_LOCKED 0x000001A1 #define CKR_VENDOR_DEFINED 0x80000000 /* CK_NOTIFY is an application callback that processes events */ typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_NOTIFICATION event, CK_VOID_PTR pApplication /* passed to C_OpenSession */ ); /* CK_CREATEMUTEX is an application callback for creating a * mutex object */ typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)( CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */ ); /* CK_DESTROYMUTEX is an application callback for destroying a * mutex object */ typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)( CK_VOID_PTR pMutex /* pointer to mutex */ ); /* CK_LOCKMUTEX is an application callback for locking a mutex */ typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)( CK_VOID_PTR pMutex /* pointer to mutex */ ); /* CK_UNLOCKMUTEX is an application callback for unlocking a * mutex */ typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)( CK_VOID_PTR pMutex /* pointer to mutex */ ); /* CK_C_INITIALIZE_ARGS provides the optional arguments to * C_Initialize */ // SAB the mutex ones had pf infront previously.. // The spec says otherwise. typedef struct CK_C_INITIALIZE_ARGS { CK_CREATEMUTEX CreateMutex; CK_DESTROYMUTEX DestroyMutex; CK_LOCKMUTEX LockMutex; CK_UNLOCKMUTEX UnlockMutex; CK_FLAGS flags; CK_VOID_PTR pReserved; } CK_C_INITIALIZE_ARGS; /* flags: bit flags that provide capabilities of the slot * Bit Flag Mask Meaning */ #define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001 #define CKF_OS_LOCKING_OK 0x00000002 typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR; /* additional flags for parameters to functions */ /* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */ #define CKF_DONT_BLOCK 1 /* CK_KEA_DERIVE_PARAMS provides the parameters to the * CKM_KEA_DERIVE mechanism */ /* CK_KEA_DERIVE_PARAMS is new for v2.0 */ typedef struct CK_KEA_DERIVE_PARAMS { CK_BBOOL isSender; CK_ULONG ulRandomLen; CK_BYTE_PTR pRandomA; CK_BYTE_PTR pRandomB; CK_ULONG ulPublicDataLen; CK_BYTE_PTR pPublicData; } CK_KEA_DERIVE_PARAMS; typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR; /* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just * holds the effective keysize */ typedef CK_ULONG CK_RC2_PARAMS; typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR; /* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC * mechanism */ typedef struct CK_RC2_CBC_PARAMS { /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for * v2.0 */ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ CK_BYTE iv[8]; /* IV for CBC mode */ } CK_RC2_CBC_PARAMS; typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR; /* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the * CKM_RC2_MAC_GENERAL mechanism */ /* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */ typedef struct CK_RC2_MAC_GENERAL_PARAMS { CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ CK_ULONG ulMacLength; /* Length of MAC in bytes */ } CK_RC2_MAC_GENERAL_PARAMS; typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \ CK_RC2_MAC_GENERAL_PARAMS_PTR; /* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and * CKM_RC5_MAC mechanisms */ /* CK_RC5_PARAMS is new for v2.0 */ typedef struct CK_RC5_PARAMS { CK_ULONG ulWordsize; /* wordsize in bits */ CK_ULONG ulRounds; /* number of rounds */ } CK_RC5_PARAMS; typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR; /* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC * mechanism */ /* CK_RC5_CBC_PARAMS is new for v2.0 */ typedef struct CK_RC5_CBC_PARAMS { CK_ULONG ulWordsize; /* wordsize in bits */ CK_ULONG ulRounds; /* number of rounds */ CK_BYTE_PTR pIv; /* pointer to IV */ CK_ULONG ulIvLen; /* length of IV in bytes */ } CK_RC5_CBC_PARAMS; typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR; /* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the * CKM_RC5_MAC_GENERAL mechanism */ /* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */ typedef struct CK_RC5_MAC_GENERAL_PARAMS { CK_ULONG ulWordsize; /* wordsize in bits */ CK_ULONG ulRounds; /* number of rounds */ CK_ULONG ulMacLength; /* Length of MAC in bytes */ } CK_RC5_MAC_GENERAL_PARAMS; typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \ CK_RC5_MAC_GENERAL_PARAMS_PTR; /* CK_MAC_GENERAL_PARAMS provides the parameters to most block * ciphers' MAC_GENERAL mechanisms. Its value is the length of * the MAC */ /* CK_MAC_GENERAL_PARAMS is new for v2.0 */ typedef CK_ULONG CK_MAC_GENERAL_PARAMS; typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR; /* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the * CKM_SKIPJACK_PRIVATE_WRAP mechanism */ /* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */ typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS { CK_ULONG ulPasswordLen; CK_BYTE_PTR pPassword; CK_ULONG ulPublicDataLen; CK_BYTE_PTR pPublicData; CK_ULONG ulPAndGLen; CK_ULONG ulQLen; CK_ULONG ulRandomLen; CK_BYTE_PTR pRandomA; CK_BYTE_PTR pPrimeP; CK_BYTE_PTR pBaseG; CK_BYTE_PTR pSubprimeQ; } CK_SKIPJACK_PRIVATE_WRAP_PARAMS; typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \ CK_SKIPJACK_PRIVATE_WRAP_PTR; /* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the * CKM_SKIPJACK_RELAYX mechanism */ /* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */ typedef struct CK_SKIPJACK_RELAYX_PARAMS { CK_ULONG ulOldWrappedXLen; CK_BYTE_PTR pOldWrappedX; CK_ULONG ulOldPasswordLen; CK_BYTE_PTR pOldPassword; CK_ULONG ulOldPublicDataLen; CK_BYTE_PTR pOldPublicData; CK_ULONG ulOldRandomLen; CK_BYTE_PTR pOldRandomA; CK_ULONG ulNewPasswordLen; CK_BYTE_PTR pNewPassword; CK_ULONG ulNewPublicDataLen; CK_BYTE_PTR pNewPublicData; CK_ULONG ulNewRandomLen; CK_BYTE_PTR pNewRandomA; } CK_SKIPJACK_RELAYX_PARAMS; typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \ CK_SKIPJACK_RELAYX_PARAMS_PTR; typedef struct CK_PBE_PARAMS { CK_CHAR_PTR pInitVector; CK_CHAR_PTR pPassword; CK_ULONG ulPasswordLen; CK_CHAR_PTR pSalt; CK_ULONG ulSaltLen; CK_ULONG ulIteration; } CK_PBE_PARAMS; typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR; /* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the * CKM_KEY_WRAP_SET_OAEP mechanism */ /* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */ typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS { CK_BYTE bBC; /* block contents byte */ CK_BYTE_PTR pX; /* extra data */ CK_ULONG ulXLen; /* length of extra data in bytes */ } CK_KEY_WRAP_SET_OAEP_PARAMS; typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \ CK_KEY_WRAP_SET_OAEP_PARAMS_PTR; typedef struct CK_SSL3_RANDOM_DATA { CK_BYTE_PTR pClientRandom; CK_ULONG ulClientRandomLen; CK_BYTE_PTR pServerRandom; CK_ULONG ulServerRandomLen; } CK_SSL3_RANDOM_DATA; typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS { CK_SSL3_RANDOM_DATA RandomInfo; CK_VERSION_PTR pVersion; } CK_SSL3_MASTER_KEY_DERIVE_PARAMS; typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \ CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR; typedef struct CK_SSL3_KEY_MAT_OUT { CK_OBJECT_HANDLE hClientMacSecret; CK_OBJECT_HANDLE hServerMacSecret; CK_OBJECT_HANDLE hClientKey; CK_OBJECT_HANDLE hServerKey; CK_BYTE_PTR pIVClient; CK_BYTE_PTR pIVServer; } CK_SSL3_KEY_MAT_OUT; typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR; typedef struct CK_SSL3_KEY_MAT_PARAMS { CK_ULONG ulMacSizeInBits; CK_ULONG ulKeySizeInBits; CK_ULONG ulIVSizeInBits; CK_BBOOL bIsExport; CK_SSL3_RANDOM_DATA RandomInfo; CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial; } CK_SSL3_KEY_MAT_PARAMS; typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR; typedef struct CK_KEY_DERIVATION_STRING_DATA { CK_BYTE_PTR pData; CK_ULONG ulLen; } CK_KEY_DERIVATION_STRING_DATA; typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \ CK_KEY_DERIVATION_STRING_DATA_PTR; /* The CK_EXTRACT_PARAMS is used for the * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit * of the base key should be used as the first bit of the * derived key */ /* CK_EXTRACT_PARAMS is new for v2.0 */ typedef CK_ULONG CK_EXTRACT_PARAMS; typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR; /* CK_FUNCTION_LIST is a structure holding a Cryptoki spec * version and pointers of appropriate types to all the * Cryptoki functions */ /* CK_FUNCTION_LIST is new for v2.0 */ typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST; typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR; typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR; typedef CK_RV (CK_PTR CK_C_Initialize) (CK_VOID_PTR pReserved); typedef CK_RV (CK_PTR CK_C_Finalize) (CK_VOID_PTR pReserved); typedef CK_RV (CK_PTR CK_C_Terminate) (void); typedef CK_RV (CK_PTR CK_C_GetInfo) (CK_INFO_PTR pInfo); typedef CK_RV (CK_PTR CK_C_GetFunctionList) (CK_FUNCTION_LIST_PTR_PTR ppFunctionList); typedef CK_RV (CK_PTR CK_C_GetSlotList) (CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pusCount); typedef CK_RV (CK_PTR CK_C_GetSlotInfo) (CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo); typedef CK_RV (CK_PTR CK_C_GetTokenInfo) (CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo); typedef CK_RV (CK_PTR CK_C_GetMechanismList) (CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pusCount); typedef CK_RV (CK_PTR CK_C_GetMechanismInfo) (CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo); typedef CK_RV (CK_PTR CK_C_InitToken) (CK_SLOT_ID slotID, CK_CHAR_PTR pPin, CK_ULONG usPinLen, CK_CHAR_PTR pLabel); typedef CK_RV (CK_PTR CK_C_InitPIN) (CK_SESSION_HANDLE hSession, CK_CHAR_PTR pPin, CK_ULONG usPinLen); typedef CK_RV (CK_PTR CK_C_SetPIN) (CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, CK_ULONG usOldLen, CK_CHAR_PTR pNewPin, CK_ULONG usNewLen); typedef CK_RV (CK_PTR CK_C_OpenSession) (CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, CK_RV (*Notify) (CK_SESSION_HANDLE hSession, CK_NOTIFICATION event, CK_VOID_PTR pApplication), CK_SESSION_HANDLE_PTR phSession); typedef CK_RV (CK_PTR CK_C_CloseSession) (CK_SESSION_HANDLE hSession); typedef CK_RV (CK_PTR CK_C_CloseAllSessions) (CK_SLOT_ID slotID); typedef CK_RV (CK_PTR CK_C_GetSessionInfo) (CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo); typedef CK_RV (CK_PTR CK_C_GetOperationState) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen); typedef CK_RV (CK_PTR CK_C_SetOperationState) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey); typedef CK_RV (CK_PTR CK_C_Login)(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG usPinLen); typedef CK_RV (CK_PTR CK_C_Logout)(CK_SESSION_HANDLE hSession); typedef CK_RV (CK_PTR CK_C_CreateObject) (CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount, CK_OBJECT_HANDLE_PTR phObject); typedef CK_RV (CK_PTR CK_C_CopyObject) (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount, CK_OBJECT_HANDLE_PTR phNewObject); typedef CK_RV (CK_PTR CK_C_DestroyObject) (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject); typedef CK_RV(CK_PTR CK_C_GetObjectSize) (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pusSize); typedef CK_RV(CK_PTR CK_C_GetAttributeValue) (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount); typedef CK_RV(CK_PTR CK_C_SetAttributeValue) (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount); typedef CK_RV (CK_PTR CK_C_FindObjectsInit) (CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount); typedef CK_RV (CK_PTR CK_C_FindObjects) (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG usMaxObjectCount, CK_ULONG_PTR pusObjectCount); typedef CK_RV (CK_PTR CK_C_FindObjectsFinal) (CK_SESSION_HANDLE hSession); typedef CK_RV (CK_PTR CK_C_EncryptInit) (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); typedef CK_RV (CK_PTR CK_C_Encrypt) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pusEncryptedDataLen); typedef CK_RV (CK_PTR CK_C_EncryptUpdate) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG usPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pusEncryptedPartLen); typedef CK_RV (CK_PTR CK_C_EncryptFinal) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pusLastEncryptedPartLen); typedef CK_RV (CK_PTR CK_C_DecryptInit) (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); typedef CK_RV (CK_PTR CK_C_Decrypt) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG usEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pusDataLen); typedef CK_RV (CK_PTR CK_C_DecryptUpdate) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG usEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pusPartLen); typedef CK_RV (CK_PTR CK_C_DecryptFinal) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart, CK_ULONG_PTR pusLastPartLen); typedef CK_RV (CK_PTR CK_C_DigestInit) (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism); typedef CK_RV (CK_PTR CK_C_Digest) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pusDigestLen); typedef CK_RV (CK_PTR CK_C_DigestUpdate) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG usPartLen); typedef CK_RV (CK_PTR CK_C_DigestKey) (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey); typedef CK_RV (CK_PTR CK_C_DigestFinal) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pusDigestLen); typedef CK_RV (CK_PTR CK_C_SignInit) (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); typedef CK_RV (CK_PTR CK_C_Sign) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pusSignatureLen); typedef CK_RV (CK_PTR CK_C_SignUpdate) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG usPartLen); typedef CK_RV (CK_PTR CK_C_SignFinal) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pusSignatureLen); typedef CK_RV (CK_PTR CK_C_SignRecoverInit) (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); typedef CK_RV (CK_PTR CK_C_SignRecover) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pusSignatureLen); typedef CK_RV (CK_PTR CK_C_VerifyInit) (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); typedef CK_RV (CK_PTR CK_C_Verify) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen); typedef CK_RV (CK_PTR CK_C_VerifyUpdate) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG usPartLen); typedef CK_RV (CK_PTR CK_C_VerifyFinal) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen); typedef CK_RV (CK_PTR CK_C_VerifyRecoverInit) (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); typedef CK_RV (CK_PTR CK_C_VerifyRecover) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pusDataLen); typedef CK_RV (CK_PTR CK_C_DigestEncryptUpdate) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen); typedef CK_RV (CK_PTR CK_C_DecryptDigestUpdate) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen); typedef CK_RV (CK_PTR CK_C_SignEncryptUpdate) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen); typedef CK_RV (CK_PTR CK_C_DecryptVerifyUpdate) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen); typedef CK_RV (CK_PTR CK_C_GenerateKey) (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount, CK_OBJECT_HANDLE_PTR phKey); typedef CK_RV (CK_PTR CK_C_GenerateKeyPair) (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG usPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG usPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPrivateKey, CK_OBJECT_HANDLE_PTR phPublicKey); typedef CK_RV (CK_PTR CK_C_WrapKey) (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pusWrappedKeyLen); typedef CK_RV (CK_PTR CK_C_UnwrapKey) (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey, CK_ULONG usWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usAttributeCount, CK_OBJECT_HANDLE_PTR phKey); typedef CK_RV (CK_PTR CK_C_DeriveKey) (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usAttributeCount, CK_OBJECT_HANDLE_PTR phKey); typedef CK_RV (CK_PTR CK_C_SeedRandom) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG usSeedLen); typedef CK_RV (CK_PTR CK_C_GenerateRandom) (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData, CK_ULONG usRandomLen); typedef CK_RV (CK_PTR CK_C_GetFunctionStatus) (CK_SESSION_HANDLE hSession); typedef CK_RV (CK_PTR CK_C_CancelFunction) (CK_SESSION_HANDLE hSession); typedef CK_RV (CK_PTR CK_Notify) (CK_SESSION_HANDLE hSession, CK_NOTIFICATION event, CK_VOID_PTR pApplication); typedef CK_RV (CK_PTR CK_C_WaitForSlotEvent) (CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved); struct CK_FUNCTION_LIST { CK_VERSION version; CK_C_Initialize C_Initialize; CK_C_Finalize C_Finalize; CK_C_GetInfo C_GetInfo; CK_C_GetFunctionList C_GetFunctionList; CK_C_GetSlotList C_GetSlotList; CK_C_GetSlotInfo C_GetSlotInfo; CK_C_GetTokenInfo C_GetTokenInfo; CK_C_GetMechanismList C_GetMechanismList; CK_C_GetMechanismInfo C_GetMechanismInfo; CK_C_InitToken C_InitToken; CK_C_InitPIN C_InitPIN; CK_C_SetPIN C_SetPIN; CK_C_OpenSession C_OpenSession; CK_C_CloseSession C_CloseSession; CK_C_CloseAllSessions C_CloseAllSessions; CK_C_GetSessionInfo C_GetSessionInfo; CK_C_GetOperationState C_GetOperationState; CK_C_SetOperationState C_SetOperationState; CK_C_Login C_Login; CK_C_Logout C_Logout; CK_C_CreateObject C_CreateObject; CK_C_CopyObject C_CopyObject; CK_C_DestroyObject C_DestroyObject; CK_C_GetObjectSize C_GetObjectSize; CK_C_GetAttributeValue C_GetAttributeValue; CK_C_SetAttributeValue C_SetAttributeValue; CK_C_FindObjectsInit C_FindObjectsInit; CK_C_FindObjects C_FindObjects; CK_C_FindObjectsFinal C_FindObjectsFinal; CK_C_EncryptInit C_EncryptInit; CK_C_Encrypt C_Encrypt; CK_C_EncryptUpdate C_EncryptUpdate; CK_C_EncryptFinal C_EncryptFinal; CK_C_DecryptInit C_DecryptInit; CK_C_Decrypt C_Decrypt; CK_C_DecryptUpdate C_DecryptUpdate; CK_C_DecryptFinal C_DecryptFinal; CK_C_DigestInit C_DigestInit; CK_C_Digest C_Digest; CK_C_DigestUpdate C_DigestUpdate; CK_C_DigestKey C_DigestKey; CK_C_DigestFinal C_DigestFinal; CK_C_SignInit C_SignInit; CK_C_Sign C_Sign; CK_C_SignUpdate C_SignUpdate; CK_C_SignFinal C_SignFinal; CK_C_SignRecoverInit C_SignRecoverInit; CK_C_SignRecover C_SignRecover; CK_C_VerifyInit C_VerifyInit; CK_C_Verify C_Verify; CK_C_VerifyUpdate C_VerifyUpdate; CK_C_VerifyFinal C_VerifyFinal; CK_C_VerifyRecoverInit C_VerifyRecoverInit; CK_C_VerifyRecover C_VerifyRecover; CK_C_DigestEncryptUpdate C_DigestEncryptUpdate; CK_C_DecryptDigestUpdate C_DecryptDigestUpdate; CK_C_SignEncryptUpdate C_SignEncryptUpdate; CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate; CK_C_GenerateKey C_GenerateKey; CK_C_GenerateKeyPair C_GenerateKeyPair; CK_C_WrapKey C_WrapKey; CK_C_UnwrapKey C_UnwrapKey; CK_C_DeriveKey C_DeriveKey; CK_C_SeedRandom C_SeedRandom; CK_C_GenerateRandom C_GenerateRandom; CK_C_GetFunctionStatus C_GetFunctionStatus; CK_C_CancelFunction C_CancelFunction; CK_C_WaitForSlotEvent C_WaitForSlotEvent; }; #ifdef __cplusplus } #endif #endif // _PKCS11TYPES_H_ opencryptoki-2.3.1+dfsg/usr/include/pkcs11/apiclient.h0000751000175000017500000005256311327631345020440 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/include/pkcs11/apiclient.h,v 1.2 2005/02/22 20:47:32 mhalcrow Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #ifndef _APICLIENT_H #define _APICLIENT_H #include "pkcs11types.h" #define VERSION_MAJOR 2 // Version 2 of the PKCS library #define VERSION_MINOR 01 // minor revision .10 of PKCS11 #ifdef __cplusplus extern "C" { #endif CK_RV C_CancelFunction ( CK_SESSION_HANDLE ); CK_RV C_CloseAllSessions ( CK_SLOT_ID ); CK_RV C_CloseSession ( CK_SESSION_HANDLE ); CK_RV C_CopyObject ( CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR ); CK_RV C_CreateObject ( CK_SESSION_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR ); CK_RV C_Decrypt ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR ); CK_RV C_DecryptDigestUpdate ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR ); CK_RV C_DecryptFinal ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR ); CK_RV C_DecryptInit ( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE ); CK_RV C_DecryptUpdate ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR ); CK_RV C_DecryptVerifyUpdate ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR ); CK_RV C_DeriveKey ( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR ); CK_RV C_DestroyObject ( CK_SESSION_HANDLE, CK_OBJECT_HANDLE ); CK_RV C_Digest ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR ); CK_RV C_DigestEncryptUpdate ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR ); CK_RV C_DigestFinal ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR ); CK_RV C_DigestInit ( CK_SESSION_HANDLE, CK_MECHANISM_PTR ); CK_RV C_DigestKey ( CK_SESSION_HANDLE, CK_OBJECT_HANDLE ); CK_RV C_DigestUpdate ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG ); CK_RV C_Encrypt ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR ); CK_RV C_EncryptFinal ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR ); CK_RV C_EncryptInit ( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE ); CK_RV C_EncryptUpdate ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR ); CK_RV C_Finalize ( CK_VOID_PTR ); CK_RV C_FindObjects ( CK_SESSION_HANDLE, CK_OBJECT_HANDLE_PTR, CK_ULONG, CK_ULONG_PTR ); CK_RV C_FindObjectsFinal ( CK_SESSION_HANDLE ); CK_RV C_FindObjectsInit ( CK_SESSION_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG ); CK_RV C_GenerateKey ( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR ); CK_RV C_GenerateKeyPair ( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_ATTRIBUTE_PTR, CK_ULONG, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR, CK_OBJECT_HANDLE_PTR ); CK_RV C_GenerateRandom ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG ); CK_RV C_GetAttributeValue ( CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG ); CK_RV C_GetFunctionList ( CK_FUNCTION_LIST_PTR_PTR ); CK_RV C_GetFunctionStatus ( CK_SESSION_HANDLE ); CK_RV C_GetInfo ( CK_INFO_PTR ); CK_RV C_GetMechanismInfo ( CK_SLOT_ID, CK_MECHANISM_TYPE, CK_MECHANISM_INFO_PTR ); CK_RV C_GetMechanismList ( CK_SLOT_ID, CK_MECHANISM_TYPE_PTR, CK_ULONG_PTR ); CK_RV C_GetObjectSize ( CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ULONG_PTR ); CK_RV C_GetOperationState ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR ); CK_RV C_GetSessionInfo ( CK_SESSION_HANDLE, CK_SESSION_INFO_PTR ); CK_RV C_GetSlotInfo ( CK_SLOT_ID, CK_SLOT_INFO_PTR ); CK_RV C_GetSlotList ( CK_BBOOL, CK_SLOT_ID_PTR, CK_ULONG_PTR ); CK_RV C_GetTokenInfo ( CK_SLOT_ID, CK_TOKEN_INFO_PTR ); CK_RV C_Initialize ( CK_VOID_PTR ); CK_RV C_InitPIN ( CK_SESSION_HANDLE, CK_CHAR_PTR, CK_ULONG ); CK_RV C_InitToken ( CK_SLOT_ID, CK_CHAR_PTR, CK_ULONG, CK_CHAR_PTR ); CK_RV C_Login ( CK_SESSION_HANDLE, CK_USER_TYPE, CK_CHAR_PTR, CK_ULONG ); CK_RV C_Logout ( CK_SESSION_HANDLE ); CK_RV C_OpenSession ( CK_SLOT_ID, CK_FLAGS, CK_VOID_PTR, CK_NOTIFY, CK_SESSION_HANDLE_PTR ); CK_RV C_SeedRandom ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG ); CK_RV C_SetAttributeValue ( CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG ); CK_RV C_SetOperationState ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_OBJECT_HANDLE, CK_OBJECT_HANDLE ); CK_RV C_SetPIN ( CK_SESSION_HANDLE, CK_CHAR_PTR, CK_ULONG, CK_CHAR_PTR, CK_ULONG ); CK_RV C_Sign ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR ); CK_RV C_SignEncryptUpdate ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR ); CK_RV C_SignFinal ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR ); CK_RV C_SignInit ( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE ); CK_RV C_SignRecover ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR ); CK_RV C_SignRecoverInit ( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE ); CK_RV C_SignUpdate ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG ); CK_RV C_UnwrapKey ( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR ); CK_RV C_Verify ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG ); CK_RV C_VerifyFinal ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG ); CK_RV C_VerifyInit ( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE ); CK_RV C_VerifyRecover ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR ); CK_RV C_VerifyRecoverInit ( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE ); CK_RV C_VerifyUpdate ( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG ); CK_RV C_WaitForSlotEvent ( CK_FLAGS, CK_SLOT_ID_PTR, CK_VOID_PTR ); CK_RV C_WrapKey ( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, CK_OBJECT_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR ); #ifdef __cplusplus } #endif #endif // _APICLIENT_H opencryptoki-2.3.1+dfsg/usr/include/pkcs11/Makefile.am0000640000175000017500000000024411327631345020335 0ustar jfjfopencryptoki_headers = apiclient.h pkcs11types.h pkcs11.h opencryptokiincludedir=$(includedir)/opencryptoki opencryptokiinclude_HEADERS = $(opencryptoki_headers) opencryptoki-2.3.1+dfsg/usr/include/pkcs11/pkcs11err.h0000751000175000017500000004372111327631345020277 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/include/pkcs11/pkcs11err.h,v 1.2 2006/04/05 20:07:44 kyoder Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #ifndef _SLOTD_ERR_H #define _SLOTD_ERR_H #ifdef DEV #ifndef ASSERT #define ASSERT(_expr) _ASSERT((_expr),(__FILE__),(__LINE__)) #define _ASSERT(_expr, _fname, _line) \ if (!(_expr)) { \ ErrLog("****** ****** ***** ***** ***** ***** ***** ***** ***** ****** ******"); \ ErrLog("****** ASSERTION FAILED '%s'; %s, line %d", (#_expr), (_fname), (_line)); \ ErrLog("****** ****** ***** ***** ***** ***** ***** ***** ***** ****** ******"); \ ErrLog("Exiting."); \ abort(); \ } #endif /* ASSERT */ #ifndef ASSERT_FUNC #define ASSERT_FUNC(_expr, _func) _ASSERT_FUNC((_expr), (_func), (__FILE__), (__LINE__)) #define _ASSERT_FUNC(_expr, _func, _fname, _line) \ if (!(_expr)) { \ ErrLog("****** ****** ***** ***** ***** ***** ***** ***** ***** ****** ******"); \ ErrLog("****** ASSERTION FAILED '%s'; %s, line %d", (#_expr), (_fname), (_line)); \ ErrLog("Additional information from '%s':\n", (#_func)); \ { _func; } \ ErrLog("End of additional information from '%s'\n", (#_func) ); \ ErrLog("****** ****** ***** ***** ***** ***** ***** ***** ***** ****** ******"); \ ErrLog("Exiting."); \ abort(); \ } #endif /* ASSERT_FUNC */ #else #ifndef ASSERT #define ASSERT(_expr) {} #endif /* ASSERT */ #ifndef ASSERT_FUNC #define ASSERT_FUNC(_expr, _func_to_call) {} #endif /* ASSERT_FUNC */ #endif /* DEV */ #define SEV_EXPECTED 0x01 #define SEV_ALLOWED 0x02 #define SEV_ERROR 0x03 #define SEV_FATAL 0x04 typedef struct _ConstInfo { unsigned const int Code; unsigned const char Name[128]; /* UCHAR Descrip[256]; */ } ConstInfo, *pConstInfo; #define CONSTINFO(_X) { (_X), (#_X) } const unsigned char *ConstName ( pConstInfo pInfoArray, unsigned int InfoArraySize, unsigned int ConstValue ); #ifdef _DAE_H const unsigned char *DAEConst ( unsigned int Val ); #endif /* _DAE_H */ #ifdef _H_ERRNO const unsigned char *SysConst ( unsigned int Val ); #define SysError( _x ) SysConst((_x)) #endif /* _H_ERRNO */ #ifdef _H_SIGNAL const unsigned char *SignalConst ( unsigned int Val ); #endif /* _H_SIGNAL */ #ifdef _H_ODMI const unsigned char *ODMConst ( unsigned int Val ); #endif /* _H_ODMI */ #ifdef _PKCS11TYPES_H_ const unsigned char *PkcsReturn ( unsigned int Val ); const unsigned char *PkcsFlags ( unsigned int Val ); const unsigned char *PkcsMechanism ( unsigned int Val ); const unsigned char *PkcsObject ( unsigned int Val ); const unsigned char *PkcsKey ( unsigned int Val ); const unsigned char *PkcsAttribute ( unsigned int Val ); #endif /* _PKCS11TYPES_H_ */ const unsigned char *ResponseSeverity( unsigned int Val ); #endif /* _SLOTD_ERR_H */ opencryptoki-2.3.1+dfsg/usr/include/pkcs11/slotmgr.h0000751000175000017500000006050411327631345020151 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/include/pkcs11/slotmgr.h,v 1.7 2006/04/17 18:23:06 danielhjones Exp $ */ // /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ // //Slot Manager Daemon Constants... // // #include #include #include #include #ifdef PKCS64 #include #endif #ifndef _SLOTMGR_H #define _SLOTMGR_H #ifdef DEV #define TOK_PATH SBIN_PATH "/pkcsslotd" #else #define TOK_PATH SBIN_PATH "/pkcsslotd" #endif /* DEV */ #if (SPINXPL) #define XPL_FILE "/tmp/.pkapi_xpk" #endif #define PID_FILE_PATH CONFIG_PATH "/.slotpid" #ifndef CK_BOOL #define CK_BOOL CK_BBOOL #endif /* CK_BOOL */ #ifndef TEST_COND_VARS #define TEST_COND_VARS 0 #endif /* TEST_COND_VARS */ #define NUMBER_SLOTS_MANAGED 32 #define NUMBER_PROCESSES_ALLOWED 1000 // // Per Process Data structure // one entry in the table is grabbed by each process // when it attaches to the shared memory and released // when the C_Finalize is called. typedef struct{ pthread_mutex_t proc_mutex; pthread_cond_t proc_slot_cond; CK_BOOL inuse; // flag indicating if the entry is in use pid_t proc_id; // This could also be used to indicate inuse. however // we will actualy use it to provide a check for a bad // process which did not C_finalize and remove itself // properly. uint32 slotmap; // Bit map of the slots with events App uses this // in the C_WaitForSlotEvent call uint8 blocking; // Flag to use if a thread is blocking on the condition // variable Used by C_Finalize to wake up the uint8 error ; // indication of an error causing the thread sleeping on the // condition variable to wakeup. uint32 slot_session_count[NUMBER_SLOTS_MANAGED]; // Per process session // count for garbage collection clean up of the global // session count. time_t reg_time; // Time application registered } Slot_Mgr_Proc_t; // // Shared Memory Region of Slot information // // Slot info structure which contains the PKCS11 CK_SLOT_INFO // as well as the local information typedef struct{ CK_SLOT_ID slot_number; CK_BOOL present; CK_SLOT_INFO pk_slot; char dll_location[PATH_MAX+1]; // location of slot management DLL char slot_init_fcn[PATH_MAX+1]; // function to call to initialize the token in the slot char correlator[PATH_MAX+1]; // Slot DLL Slotindex to dev correlation string uint32 global_sessions; // counter of the total sessions on a token in // a slot. Used for quick check of no // sessions }Slot_Info_t; #ifdef PKCS64 /* * Constant size types and structures to allow 32-bit daemon to work with * 64-bit libraries. * * Note - ulong long is 8 bytes for both 32-bit and 64-bit applications. * */ typedef signed long long pid_t_64; typedef unsigned long long time_t_64; typedef unsigned long long CK_SLOT_ID_64; typedef unsigned long long CK_FLAGS_64; typedef struct CK_INFO_64 { CK_VERSION cryptokiVersion; /* Cryptoki interface ver */ CK_CHAR manufacturerID[32]; /* blank padded */ CK_CHAR pad1[6]; /* pad for dword alignment */ CK_FLAGS_64 flags; /* must be zero */ /* libraryDescription and libraryVersion are new for v2.0 */ CK_CHAR libraryDescription[32]; /* blank padded */ CK_VERSION libraryVersion; /* version of library */ CK_CHAR pad2[6]; /* pad for dword alignment */ } CK_INFO_64; typedef CK_INFO_64 CK_PTR CK_INFO_PTR_64; typedef struct CK_SLOT_INFO_64 { CK_CHAR slotDescription[64]; /* blank padded */ CK_CHAR manufacturerID[32]; /* blank padded */ CK_FLAGS_64 flags; /* hardwareVersion and firmwareVersion are new for v2.0 */ CK_VERSION hardwareVersion; /* version of hardware */ CK_VERSION firmwareVersion; /* version of firmware */ CK_CHAR pad[4]; /* pad for dword alignment */ } CK_SLOT_INFO_64; typedef struct Slot_Mgr_Proc_t_64 { #if SYSVSEM int slt_mutex; #elif PTHREADXPL pthread_mutex_t slt_mutex; #elif POSIXSEM #error "Need to implement this" #elif NOXPROCLOCK int slt_mutex; // unused. #elif SPINXPL unsigned int slt_mutex; #endif // pthread_cond_t proc_slot_cond; CK_BOOL inuse; // flag indicating if the entry is in use pid_t_64 proc_id;// This could also be used to indicate inuse. however // we will actualy use it to provide a check for a bad // process which did not C_finalize and remove itself // properly. uint32 slotmap; // Bit map of the slots with events App uses this // in the C_WaitForSlotEvent call uint8 blocking; // Flag to use if a thread is blocking on the condition // variable Used by C_Finalize to wake up the uint8 error ; // indication of an error causing the thread sleeping on the // condition variable to wakeup. uint32 slot_session_count[NUMBER_SLOTS_MANAGED]; // Per process session // count for garbage collection clean up of the global // session count. time_t_64 reg_time; // Time application registered } Slot_Mgr_Proc_t_64; // // Shared Memory Region of Slot information // // Slot info structure which contains the PKCS11 CK_SLOT_INFO // as well as the local information typedef struct{ CK_SLOT_ID_64 slot_number; CK_BOOL present; char pad1[7]; // pad for dword alignment CK_SLOT_INFO_64 pk_slot; char dll_location[PATH_MAX+1]; // location of slot management DLL char slot_init_fcn[PATH_MAX+1]; // function to call to initialize the token in the slot char correlator[PATH_MAX+1]; // Slot DLL Slotindex to dev correlation string char pad2[5]; // pad for dword alignment uint32 global_sessions; // counter of the total sessions on a token in char pad3[4]; // pad for dword alignment // a slot. Used for quick check of no // sessions }Slot_Info_t_64; typedef struct { /************************************************************* * Mutexes for access and control of the structures. * When a process wants to register with the slot mgr * it will have to get the mutex on the shared memory region * and then finds an empty slot in the process table to use. * This simplifies the management capabilities. *************************************************************/ #if SYSVSEM int slt_mutex; #elif PTHREADXPL pthread_mutex_t slt_mutex; #elif POSIXSEM #error "Need to implement this" #elif NOXPROCLOCK int slt_mutex; // unused. #elif SPINXPL unsigned int slt_mutex; #endif /* Information that the API calls will use. */ uint8 num_slots; CK_INFO_64 ck_info; Slot_Info_t_64 slot_info[NUMBER_SLOTS_MANAGED]; Slot_Mgr_Proc_t_64 proc_table[NUMBER_PROCESSES_ALLOWED]; } Slot_Mgr_Shr_t; #else typedef struct { /************************************************************* * Mutexes for access and control of the structures. * When a process wants to register with the slot mgr * it will have to get the mutex on the shared memory region * and then finds an empty slot in the process table to use. * This simplifies the management capabilities. *************************************************************/ #if SYSVSEM int slt_mutex; #elif PTHREADXPL pthread_mutex_t slt_mutex; #elif POSIXSEM #error "Need to implement this" #elif NOXPROCLOCK int slt_mutex; // unused. #elif SPINXPL unsigned int slt_mutex; #endif /* Information that the API calls will use. */ uint8 num_slots; CK_INFO ck_info; Slot_Info_t slot_info[NUMBER_SLOTS_MANAGED]; Slot_Mgr_Proc_t proc_table[NUMBER_PROCESSES_ALLOWED]; } Slot_Mgr_Shr_t; #endif // Loging type constants // #define ERROR 1 #define INFO 2 // Call to populate the shared memory #define STR "01234567890123456789012345678901" #define MFG "IBM " #define LIB "Meta PKCS11 LIBRARY " #define MAJOR_V 1 #define MINOR_V 2 #ifndef CRYPTOKI_API_MAJOR_V #define CRYPTOKI_API_MAJOR_V 0x2 #endif #ifndef CRYPTOKI_API_MINOR_V #define CRYPTOKI_API_MINOR_V 0xb #endif #define LIB_MAJOR_V 1 #define LIB_MINOR_V 4 #define RESTART_SYS_CALLS 1 // // Function prototypes // /* shmem.c */ int CreateSharedMemory ( void ); int AttachToSharedMemeory ( void ); int InitSharedMemory ( Slot_Mgr_Shr_t *sp ); void DetachFromSharedMemory ( void ); void DestroySharedMemory ( void ); /* mutex.c */ int InitializeMutexes ( void ); int DestroyMutexes ( void ); /* signal.c */ void slotdSIGTERMhandler ( int signum ); int SetupSignalHandlers ( void ); void slotdGenericSignalHandler( int Signal ); #endif /* _SLOTMGR_H */ opencryptoki-2.3.1+dfsg/usr/include/pkcs11/testcert.h0000751000175000017500000005314311327631345020320 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/include/pkcs11/testcert.h,v 1.1 2005/01/18 16:09:04 kyoder Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #define TestCert_Label "Self Signed Cert for PKCS#11" char DN[83] = { 48, 81, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 9, 48, 7, 6, 3, 85, 4, 3, 19, 0 }; char Issuer[83] = { 48, 81, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 9, 48, 7, 6, 3, 85, 4, 3, 19, 0 }; char Cert[541] = { 48, 130, 2, 25, 48, 130, 1, 130, 160, 3, 2, 1, 2, 2, 4, 55, 196, 11, 144, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 4, 5, 0, 48, 81, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 9, 48, 7, 6, 3, 85, 4, 3, 19, 0, 48, 30, 23, 13, 57, 57, 48, 56, 50, 52, 49, 53, 50, 56, 49, 54, 90, 23, 13, 48, 50, 48, 52, 49, 54, 49, 53, 50, 56, 49, 54, 90, 48, 81, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 0, 49, 9, 48, 7, 6, 3, 85, 4, 3, 19, 0, 48, 129, 159, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 129, 141, 0, 48, 129, 137, 2, 129, 129, 0, 160, 224, 39, 50, 200, 43, 125, 162, 219, 163, 93, 182, 28, 38, 105, 248, 255, 78, 10, 54, 255, 234, 184, 7, 45, 219, 23, 131, 54, 130, 37, 184, 205, 41, 40, 38, 229, 190, 17, 130, 75, 151, 190, 209, 226, 37, 38, 145, 26, 237, 169, 117, 114, 169, 55, 107, 225, 24, 205, 171, 226, 82, 69, 57, 241, 149, 32, 188, 86, 234, 5, 206, 0, 20, 237, 210, 101, 109, 143, 160, 182, 15, 201, 2, 252, 237, 241, 120, 179, 187, 112, 143, 31, 156, 90, 173, 211, 130, 151, 164, 199, 235, 48, 223, 124, 145, 100, 3, 104, 188, 49, 110, 232, 54, 108, 30, 33, 169, 197, 137, 92, 244, 7, 135, 208, 216, 9, 141, 2, 3, 1, 0, 1, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 4, 5, 0, 3, 129, 129, 0, 66, 115, 199, 229, 210, 234, 31, 199, 15, 171, 65, 13, 86, 149, 206, 161, 252, 120, 220, 228, 215, 39, 23, 180, 166, 151, 48, 77, 112, 119, 145, 165, 123, 159, 48, 0, 169, 191, 5, 16, 48, 199, 161, 49, 134, 91, 190, 235, 37, 80, 91, 96, 205, 43, 177, 13, 224, 10, 92, 211, 40, 50, 69, 103, 241, 121, 120, 227, 189, 99, 95, 92, 174, 83, 31, 45, 119, 103, 96, 192, 208, 245, 58, 248, 106, 203, 27, 218, 149, 139, 46, 204, 27, 104, 241, 98, 22, 58, 212, 207, 122, 100, 241, 39, 233, 54, 40, 66, 87, 177, 129, 12, 65, 107, 116, 30, 176, 220, 20, 183, 16, 104, 229, 84, 19, 35, 84, 204 }; char PrivKey[633] = { 48, 130, 2, 117, 2, 1, 0, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 4, 130, 2, 95, 48, 130, 2, 91, 2, 1, 0, 2, 129, 129, 0, 160, 224, 39, 50, 200, 43, 125, 162, 219, 163, 93, 182, 28, 38, 105, 248, 255, 78, 10, 54, 255, 234, 184, 7, 45, 219, 23, 131, 54, 130, 37, 184, 205, 41, 40, 38, 229, 190, 17, 130, 75, 151, 190, 209, 226, 37, 38, 145, 26, 237, 169, 117, 114, 169, 55, 107, 225, 24, 205, 171, 226, 82, 69, 57, 241, 149, 32, 188, 86, 234, 5, 206, 0, 20, 237, 210, 101, 109, 143, 160, 182, 15, 201, 2, 252, 237, 241, 120, 179, 187, 112, 143, 31, 156, 90, 173, 211, 130, 151, 164, 199, 235, 48, 223, 124, 145, 100, 3, 104, 188, 49, 110, 232, 54, 108, 30, 33, 169, 197, 137, 92, 244, 7, 135, 208, 216, 9, 141, 2, 3, 1, 0, 1, 2, 129, 128, 9, 209, 3, 179, 78, 145, 144, 206, 2, 54, 250, 189, 229, 3, 215, 13, 145, 142, 146, 130, 254, 164, 180, 236, 3, 57, 78, 58, 252, 117, 126, 149, 195, 55, 18, 179, 36, 235, 175, 39, 211, 51, 4, 58, 204, 96, 213, 244, 158, 191, 7, 203, 25, 223, 7, 121, 182, 183, 139, 189, 68, 71, 30, 224, 44, 126, 87, 202, 196, 83, 124, 134, 139, 54, 29, 50, 175, 106, 126, 193, 7, 52, 67, 12, 115, 251, 84, 232, 222, 118, 41, 195, 5, 182, 176, 73, 79, 103, 107, 141, 96, 170, 242, 175, 183, 154, 13, 224, 45, 40, 49, 96, 146, 3, 9, 26, 21, 115, 33, 183, 118, 174, 68, 13, 198, 220, 105, 69, 2, 65, 0, 208, 30, 177, 14, 227, 148, 126, 152, 149, 117, 190, 215, 106, 133, 96, 66, 114, 141, 175, 245, 146, 81, 1, 197, 182, 147, 187, 214, 33, 125, 144, 126, 229, 192, 141, 200, 168, 106, 238, 231, 122, 104, 55, 70, 94, 82, 1, 155, 209, 245, 162, 101, 78, 1, 57, 33, 11, 205, 97, 202, 170, 26, 48, 43, 2, 65, 0, 197, 226, 253, 53, 187, 167, 237, 30, 197, 139, 227, 116, 80, 173, 71, 136, 99, 143, 199, 246, 94, 102, 86, 110, 152, 149, 122, 165, 243, 16, 98, 220, 143, 90, 3, 235, 88, 67, 41, 235, 146, 37, 192, 88, 54, 160, 79, 102, 76, 127, 246, 232, 222, 20, 70, 217, 22, 119, 50, 80, 182, 179, 153, 39, 2, 64, 122, 166, 203, 212, 41, 125, 23, 10, 151, 114, 151, 240, 222, 31, 18, 118, 182, 138, 23, 252, 18, 169, 216, 240, 139, 68, 15, 124, 7, 170, 183, 96, 129, 200, 116, 6, 160, 114, 188, 175, 0, 173, 176, 125, 177, 18, 133, 78, 46, 115, 163, 172, 46, 71, 124, 66, 164, 112, 250, 195, 244, 113, 144, 151, 2, 64, 52, 212, 28, 117, 51, 219, 232, 217, 198, 51, 74, 77, 203, 27, 247, 116, 217, 223, 144, 170, 157, 25, 5, 10, 17, 130, 22, 116, 39, 39, 192, 188, 209, 40, 94, 211, 125, 132, 176, 180, 75, 23, 248, 249, 147, 219, 200, 86, 175, 37, 154, 109, 32, 156, 153, 45, 107, 105, 246, 236, 197, 89, 189, 17, 2, 64, 92, 208, 59, 86, 221, 175, 121, 63, 31, 217, 197, 148, 228, 143, 254, 51, 187, 57, 71, 38, 153, 157, 38, 65, 121, 247, 184, 55, 159, 47, 207, 153, 186, 45, 117, 138, 229, 175, 95, 21, 161, 206, 167, 112, 119, 67, 201, 138, 92, 243, 1, 142, 133, 117, 15, 106, 195, 57, 136, 191, 217, 48, 0, 98, }; char PubKey[162] = { 48, 129, 159, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 129, 141, 0, 48, 129, 137, 2, 129, 129, 0, 160, 224, 39, 50, 200, 43, 125, 162, 219, 163, 93, 182, 28, 38, 105, 248, 255, 78, 10, 54, 255, 234, 184, 7, 45, 219, 23, 131, 54, 130, 37, 184, 205, 41, 40, 38, 229, 190, 17, 130, 75, 151, 190, 209, 226, 37, 38, 145, 26, 237, 169, 117, 114, 169, 55, 107, 225, 24, 205, 171, 226, 82, 69, 57, 241, 149, 32, 188, 86, 234, 5, 206, 0, 20, 237, 210, 101, 109, 143, 160, 182, 15, 201, 2, 252, 237, 241, 120, 179, 187, 112, 143, 31, 156, 90, 173, 211, 130, 151, 164, 199, 235, 48, 223, 124, 145, 100, 3, 104, 188, 49, 110, 232, 54, 108, 30, 33, 169, 197, 137, 92, 244, 7, 135, 208, 216, 9, 141, 2, 3, 1, 0, 1 }; opencryptoki-2.3.1+dfsg/usr/include/pkcs11/pkcs11log.h0000751000175000017500000004460011327631345020265 0ustar jfjf/* * $Header: /cvsroot/opencryptoki/opencryptoki/usr/include/pkcs11/pkcs11log.h,v 1.1 2005/01/18 16:09:04 kyoder Exp $ */ /* Common Public License Version 0.5 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. */ /* (C) COPYRIGHT International Business Machines Corp. 2001 */ #ifndef _LOG_H #define _LOG_H 1 #include #include #include #include #include #include #include #include #include #include "pkcs11err.h" #ifndef FALSE #define FALSE 0 #endif /* FALSE */ #ifndef TRUE #define TRUE (!(FALSE)) #endif /* TRUE */ #ifndef MAX_LOGGING_FACILITIES #define MAX_LOGGING_FACILITIES 16 #endif /* MAX_LOGGING_FACILITIES */ #ifndef TRUNCATE_LOGS_ON_START #define TRUNCATE_LOGS_ON_START 0 #endif /* TRUNCATE_LOGS_ON_START */ /* Use an enum here? */ #define DEBUG_NONE (0) #define DEBUG_LEVEL0 (100) /* Less detail */ #define DEBUG_LEVEL1 (DEBUG_LEVEL0 + 100) /* . */ #define DEBUG_LEVEL2 (DEBUG_LEVEL1 + 100) /* v */ #define DEBUG_LEVEL3 (DEBUG_LEVEL2 + 100) /* More detail */ #define DEBUG_LEVEL4 (DEBUG_LEVEL3 + 100) #define DEBUG_LEVEL5 (DEBUG_LEVEL4 + 100) #define DNONE (DEBUG_NONE) #define DL0 (DEBUG_LEVEL0) #define DL1 (DEBUG_LEVEL1) #define DL2 (DEBUG_LEVEL2) #define DL3 (DEBUG_LEVEL3) #define DL4 (DEBUG_LEVEL4) #define DL5 (DEBUG_LEVEL5) #ifndef DbgPrint #define DbgPrint DbgLog #endif /* DbgPrint */ /************** * Structures * **************/ /************************************************************************ * Yes, the structures are somewhat redundant; this is an evolutionary * side-effect. They should probably be combined into a single struct * - SCM ************************************************************************/ typedef u_int32 LogHandle, *pLogHandle; typedef u_int32 BOOL, bool, BOOLEAN, boolean; typedef struct _logging_facility_info { BOOL Initialized; char Descrip[255]; u_int32 LogOption; char *Filename; BOOL UseSyslog; u_int32 LogLevel; struct syslog_data LogData; pid_t pid; } LoggingFacilityInfo, *pLoggingFacilityInfo; typedef struct _LoggingFacility { char *Label; pLogHandle phLog; char *Filename; BOOL UseSyslog; u_int32 LogLevel; } LoggingFacility, *pLoggingFacility; /******************************** * Exported Function Prototypes * ********************************/ void DbgLog ( u_int32 DebugLevel, char *Format, ... ); void ErrLog ( char *Format, ... ); void LogLog ( char *Format, ... ); void WarnLog ( char *Format, ... ); void TraceLog ( char *Format, ... ); void InfoLog ( char *Format, ... ); BOOL PKCS_Log ( LogHandle *phLog, char *Format, va_list ap ); BOOL NewLoggingFacility ( char *ID, pLoggingFacility pStuff ); BOOL CloseLoggingFacility ( LogHandle hLog ); BOOL GetCurrentTimeString ( char *Buffer ); u_int32 SetDebugLevel ( u_int32 Val ); u_int32 GetDebugLevel ( void ); #endif /* _LOG_H */ opencryptoki-2.3.1+dfsg/usr/include/Makefile.am0000640000175000017500000000002111327631345017224 0ustar jfjfSUBDIRS = pkcs11