libica Programmer's Reference Linux on System z Version 2.3.0

libica Programmer's Reference Linux on System z Version 2.3.0
Linux on System z
libica Programmer's Reference
Version 2.3.0
SC34-2602-04
Linux on System z
libica Programmer's Reference
Version 2.3.0
SC34-2602-04
Note
Before using this document, be sure to read the information in “Notices” on page 165.
This edition applies to version 2.3.0 of libica and to all subsequent releases and modifications until otherwise
indicated in new editions. This edition replaces SC34-2602-03.
© Copyright IBM Corporation 2009, 2013.
US Government Users Restricted Rights – Use, duplication or disclosure restricted by GSA ADP Schedule Contract
with IBM Corp.
Contents
Summary of changes . . . . . . . . . v
|
Updates for libica Version 2.3.0 . . . . . . . . v
Previous updates for libica Version 2.2.0 . . . . . v
Previous updates for libica Version 2.1.0 . . . . . vi
About this document
. . . . . . . . vii
How this document is organized . .
Who should read this document . .
Assumptions . . . . . . .
Distribution independence . . . .
Conventions used in this book. . .
Terminology . . . . . . . .
Highlighting . . . . . . . .
Other Linux on System z publications.
Finding IBM books . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. vii
. vii
. viii
. viii
. viii
. viii
. . ix
. . ix
. . ix
Chapter 1. General information about
libica . . . . . . . . . . . . . . . . 1
libica examples . . . . . . . . . .
System z cryptographic hardware support .
IBM crypto adapter . . . . . . . . .
Getting IBM crypto adapter (zcrypt) status
information . . . . . . . . . . .
.
.
.
.
.
.
. 1
. 1
. 2
.
.
. 2
Chapter 2. Installing and using libica
Version 2.3.0. . . . . . . . . . . . . 3
Installing libica Version 2.3.0 . . . . . . .
Installing libica Version 2.3.0 from the binary
package . . . . . . . . . . . . .
Installing libica Version 2.3.0 from the source
package . . . . . . . . . . . . .
Using libica Version 2.3.0 . . . . . . . .
libica Version 1, Version 2, Version 2.1.0, Version
2.2.0, and Version 2.3.0 coexistence . . . . .
.
. 3
.
. 3
.
.
. 3
. 4
.
. 4
Chapter 3. libica Version 2.3.0
Application Programming Interfaces
(APIs). . . . . . . . . . . . . . . . 5
Open and close adapter functions . . . .
ica_open_adapter . . . . . . . . .
ica_close_adapter . . . . . . . . .
Secure hash operations . . . . . . . .
ica_sha1 . . . . . . . . . . . .
ica_sha224 . . . . . . . . . . .
ica_sha256 . . . . . . . . . . .
ica_sha384 . . . . . . . . . . .
ica_sha512 . . . . . . . . . . .
Pseudo random number generation function
ica_random_number_generate . . . .
RSA key generation functions . . . . .
ica_rsa_key_generate_mod_expo . . .
ica_rsa_key_generate_crt . . . . . .
RSA encrypt and decrypt operations . . .
ica_rsa_mod_expo . . . . . . . .
© Copyright IBM Corp. 2009, 2013
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 7
. 8
. 8
. 9
. 9
. 10
. 11
. 12
. 13
. 14
. 14
. 15
. 15
. 15
. 16
. 16
|
ica_rsa_crt . . . . . . . . .
DES functions . . . . . . . .
ica_des_cbc . . . . . . . .
ica_des_cbc_cs . . . . . . .
ica_des_cfb . . . . . . . .
ica_des_cmac . . . . . . . .
ica_des_cmac_intermediate . . .
ica_des_cmac_last . . . . . .
ica_des_ctr. . . . . . . . .
ica_des_ctrlist. . . . . . . .
ica_des_ecb . . . . . . . .
ica_des_ofb . . . . . . . .
Compatibility with earlier versions
TDES/3DES functions . . . . . .
ica_3des_cbc . . . . . . . .
ica_3des_cbc_cs . . . . . . .
ica_3des_cfb . . . . . . . .
ica_3des_cmac . . . . . . .
ica_3des_cmac_intermediate . . .
ica_3des_cmac_last . . . . . .
ica_3des_ctr . . . . . . . .
ica_3des_ctrlist . . . . . . .
ica_3des_ecb . . . . . . . .
ica_3des_ofb . . . . . . . .
Compatibility with earlier versions
AES functions . . . . . . . .
ica_aes_cbc . . . . . . . .
ica_aes_cbc_cs . . . . . . .
ica_aes_ccm . . . . . . . .
ica_aes_cfb . . . . . . . .
ica_aes_cmac . . . . . . . .
ica_aes_cmac_intermediate . . .
ica_aes_cmac_last . . . . . .
ica_aes_ctr . . . . . . . . .
ica_aes_ctrlist . . . . . . . .
ica_aes_ecb . . . . . . . .
ica_aes_gcm . . . . . . . .
ica_aes_ofb . . . . . . . .
ica_aes_xts. . . . . . . . .
Compatibility with earlier versions
Information retrieval function . . .
ica_get_version . . . . . . .
ica_get_functionlist . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
17
18
18
19
20
21
22
23
24
26
27
27
28
29
30
30
32
33
34
35
36
37
38
39
40
40
41
42
43
45
46
47
48
49
50
51
52
54
55
56
57
57
57
Chapter 4. Accessing libica Version
2.3.0 functions via the PKCS #11 API
(openCryptoki) . . . . . . . . . . . 59
Introduction . . . . . . . . . . .
Stack overview . . . . . . . . .
Functions provided by openCryptoki with
token . . . . . . . . . . . .
Installing openCryptoki . . . . . . .
Installing from the binary package. . .
Installing from the source package. . .
Installing libica Version 2.3.0. . . . .
. .
. .
ica
. .
. .
. .
. .
. .
. 59
. 59
.
.
.
.
.
60
62
62
62
63
iii
Configuring openCryptoki . . . . . .
Setting up tokens and daemons. . . .
Initializing the token . . . . . . .
Using openCryptoki . . . . . . . .
Getting openCryptoki status information
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
63
63
64
65
65
Chapter 5. libica defines, typedefs,
structs, and return codes. . . . . . . 67
Defines . .
Typedefs .
Structs . .
Return codes
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
67
67
68
70
AES with CFB mode example . . . . . .
AES with CTR mode example . . . . . .
AES with OFB mode example . . . . . .
AES with XTS mode example . . . . . .
CMAC example . . . . . . . . . .
Makefile example . . . . . . . . . .
Common Public License - V1.0 . . . . .
Getting libica Version 2.3.0 status information
openCryptoki code samples . . . . . .
Coding samples (C) . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
101
113
123
131
141
145
145
149
149
149
Appendix. Supported mechanism list
for the ica token . . . . . . . . . . 161
Chapter 6. libica tools . . . . . . . . 71
icainfo - Show available libica functions .
icastats - Show use of libica functions .
.
.
.
.
.
.
. 71
. 72
Accessibility . . . . . . . . . . . . 163
Documentation accessibility
IBM and accessibility . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 163
. 163
Chapter 7. Examples . . . . . . . . . 75
DES with ECB mode example . . . . .
SHA-256 example . . . . . . . . .
Pseudo random number generation example
Key generation example . . . . . . .
RSA example . . . . . . . . . . .
DES with CTR mode example . . . . .
Triple DES with CBC mode example . . .
iv
libica Programmer's Reference
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
75
78
83
84
91
95
98
Notices . . . . . . . . . . . . . . 165
Trademarks .
.
.
.
.
.
.
.
.
.
.
.
.
. 167
Glossary . . . . . . . . . . . . . 169
Index . . . . . . . . . . . . . . . 171
Summary of changes
This revision reflects changes to the Development stream for libica Version 2.3.0.
|
Updates for libica Version 2.3.0
|
This revision reflects changes related to Version 2.3.0 of libica.
|
|
|
|
New information
v New API added. See “ica_get_functionlist” on page 57.
v New defines and structs have been added. See Chapter 5, “libica defines,
typedefs, structs, and return codes,” on page 67
Previous updates for libica Version 2.2.0
This revision reflects changes related to Version 2.2.0 of libica.
New information
v Cryptographic hardware support with openCryptoki
v New APIs have been added:
–
–
–
–
–
ica_3des_cbc_cs
ica_3des_cmac
ica_3des_cmac_intermediate
ica_3des_cmac_last
ica_aes_cbc_cs
– ica_aes_ccm
– ica_aes_cmac_intermediate
– ica_aes_cmac_last
–
–
–
–
–
ica_aes_gcm
ica_des_cbc_cs
ica_des_cmac
ica_des_cmac_intermediate
ica_des_cmac_last
v New commands have been added. See Chapter 6, “libica tools,” on page 71.
Changed information
v Minor changes and corrections have been made to some of the APIs.
This revision also includes maintenance and editorial changes.
Deleted information
v Some obsolete examples have been removed.
© Copyright IBM Corporation © IBM 2009, 2013
v
Previous updates for libica Version 2.1.0
This revision reflects changes related to Version 2.1.0 of libica.
New information
v
v
v
v
Support for IBM® zEnterprise® 196 has been added.
New APIs have been added.
New examples have been added. See Chapter 7, “Examples,” on page 75.
New defines and structs have been added. See Chapter 5, “libica defines,
typedefs, structs, and return codes,” on page 67.
Changed information
v The example makefile has been updated. See “Makefile example” on page 145.
This revision also includes maintenance and editorial changes.
Deleted information
v The following functions are deprecated in libica Version 2.1.0, and no longer
documented in this book. They are, however, still available in this version of
libica. For documentation on these functions, see the Version 2.0 libica
Programmer's Reference.
– ica_des_encrypt
– ica_des_decrypt
– ica_3des_encrypt
– ica_3des_decrypt
–
–
vi
ica_aes_encrypt
ica_aes_decrypt
libica Programmer's Reference
About this document
This document describes how to install and use Version 2.3.0 of the Library for
IBM Cryptographic Architecture (libica).
libica Version 2.3.0 is a library of cryptographic functions used to write
cryptographic applications on IBM System z®, both with and without
cryptographic hardware.
Unless stated otherwise, the tools described in this book are available for the 64-bit
architecture and 31-bit architectures with version 2.6 or higher of the Linux kernel.
You can find the latest version of this document on the developerWorks® website
at:
http://www.ibm.com/developerworks/linux/linux390/development_documentation.html
How this document is organized
Chapter 1, “General information about libica,” on page 1 has general information
about libica Version 2.3.0.
Chapter 2, “Installing and using libica Version 2.3.0,” on page 3 contains
installation and set up instructions, and coexistence information for libica Version
2.3.0.
Chapter 3, “libica Version 2.3.0 Application Programming Interfaces (APIs),” on
page 5 describes the libica Version 2.3.0 APIs.
Chapter 4, “Accessing libica Version 2.3.0 functions via the PKCS #11 API
(openCryptoki),” on page 59 describes how the cryptographic functions provided
by libica Version 2.3.0 can be accessed using the PKCS #11 API implemented by
openCryptoki.
Chapter 5, “libica defines, typedefs, structs, and return codes,” on page 67 lists the
defines, typedefs, structs, and return codes for libica Version 2.3.0.
Chapter 6, “libica tools,” on page 71 contains tools to investigate the capabilities of
your cryptographic hardware and how these capabilities are used by applications
that use libica.
Chapter 7, “Examples,” on page 75 is a set of programming examples that use the
libica Version 2.3.0 APIs.
Who should read this document
This document is intended for C programmers that want to access IBM System z
hardware support for cryptographic methods.
In particular, this document addresses programmers who write hardware-specific
plug-ins for cryptographic libraries such as openssl and openCryptoki.
© Copyright IBM Corp. 2009, 2013
vii
Assumptions
The following general assumptions are made about your background knowledge:
v You have an understanding of basic computer architecture, operating systems,
and programs.
v You have an understanding of Linux and IBM System z terminology.
v You have knowledge about cryptographic applications and solution design, as
well as the required cryptographic functions and algorithms.
Distribution independence
This book does not provide information that is specific to a particular Linux
distribution.
The tools it describes are distribution independent.
Conventions used in this book
This section informs you about the styles, highlighting, and assumptions used
throughout the book.
Terminology
In this book, the term booting is used for running boot loader code that loads the
Linux operating system. IPL is used for issuing an IPL command or to load
boot-loader code.
In this book, the term Required hardware support refers to specific processor
instructions that must be available on the processor in order for the function to
benefit from hardware support. Functions will fail on systems that do not provide
the required hardware support, unless a software fallback is available as indicated
in Table 2 on page 5. An example is that the ica_des_cbc function has KMC-DEA
listed under Required hardware support. This function cannot benefit from
hardware support unless the processor has the KMC-DEA instruction. However,
ica_des_cbc will work on all processors because according to Table 2 on page 5
there is a software fallback for this function.
For more information, see:
v The z/Architecture® Principles of Operation, SA22-7832-06
v the IBM Redbooks® publication System z Cryptographic Services and z/OS® PKI
Services, SG24-7470-00
IBM systems mentioned in this book have both long names and short names. They
correspond as follows:
Table 1. IBM systems
Long name
Short name
™
®
IBM eServer zSeries 990
IBM System z9
®
z9
®
z10™
IBM System z196
z196
IBM System z10
viii
z990
libica Programmer's Reference
Highlighting
This book uses the following highlighting styles:
v Paths and URLs are highlighted in monospace.
v Variables are highlighted in italics.
v Commands in text are highlighted in bold.
v Input and output as normally seen on a computer screen is shown
within a screen frame.
Prompts are shown as number signs:
#
Other Linux on System z publications
Current versions of the Linux on System z publications can be found at:
https://www.ibm.com/developerworks/linux/linux390/documentation_dev.html
v Device Drivers, Features, and Commands, SC33-8411
v Using the Dump Tools, SC33-8412
v How to use FC-attached SCSI devices with Linux on System z, SC33-8413
v
v
v
v
How to Improve Performance with PAV, SC33-8414
How to use Execute-in-Place Technology with Linux on z/VM®, SC34-2594
How to Set up a Terminal Server Environment on z/VM, SC34-2596
Kernel Messages
v libica Programmer’s Reference, SC34-2602
Finding IBM books
The PDF version of this book contains URL links to much of the referenced
literature.
For some of the referenced IBM books, links have been omitted to avoid pointing
to a particular edition of a book. You can locate the latest versions of the
referenced IBM books through the IBM Publications Center at:
http://www.ibm.com/shop/publications/order
About this document
ix
x
libica Programmer's Reference
Chapter 1. General information about libica
The libica library provides hardware support for cryptographic functions.
The cryptographic adapters are used for asymmetric encryption and decryption.
The CPACF instructions are used for symmetric encryption and decryption, pseudo
random number generation, message authentication, and Secure Hashing. For
some of these functions, if the hardware is not available or has failed, libica uses
the low-level cryptographic functions of OpenSSL, if available.
This product includes software developed by the OpenSSL Project for use in the
OpenSSL Toolkit (http://www.openssl.org). This product includes cryptographic
software written by Eric Young ([email protected]).
The libica library is part of the openCryptoki project in SourceForge. It is primarily
used by OpenSSL through the IBM OpenSSL CA engine or by openCryptoki
through the ica_s390 token. A higher level of security can be achieved by using it
through the PKCS11 API implemented by openCryptoki.
The libica library works only on IBM System z hardware.
IBM reserves the right to change or modify this API at any time. However, an
effort is made to keep the API compatible with later versions within a major
release.
The icastats command, described in Linux on System z: Device Driver, Features, and
Commands, is used to obtain statistics about cryptographic processes. The icastats
command shows whether libica is using cryptographic hardware or software
fallback for each specific libica function.
libica examples
There is a list of sample programs in the libica source for each API, as well as
instructions about how to use the functions.
You can find the open source version of libica at:
|
http://sourceforge.net/projects/opencryptoki/files/libica
Sample programs area also in Chapter 7, “Examples,” on page 75.
System z cryptographic hardware support
The following lists different types of cryptographic hardware support that may be
available in a System z server.
IBM CP Assist for Cryptographic Function (CPACF):
DES, TDES, AES128, AES192, AES256, SHA-1, SHA256, SHA384, SHA512, PRNG
Crypto cards:
Accelerator: RSA (CRT, MOD-EXPO) 1024, 2048 and 4096 bit key size
© Copyright IBM Corporation © IBM 2009, 2013
1
Co-processor: RSA (CRT, MOD-EXPO) 1024, 2048 and 4096 bit key size, RNG and
so on
IBM crypto adapter
Information about how to install IBM crypto adapter and get status information.
Installing IBM crypto adapter
Check if you have plugged in and enabled your IBM crypto adapter and validate
your model and type configuration (Accelerator or Co-Processor).
To do this, enter the command:
$ lszcrypt
card06: CEX3A
Load the z90crypt module if the following error message is displayed:
error - cryptographic device driver zcrypt is not loaded!
To load this module permanently you can set up:
Red Hat Enterprise Linux 6.2:
echo "modprobe z90crypt" > /etc/sysconfig/modules/z90crypt.modules
chmod +x /etc/sysconfig/modules/z90crypt.modules
SUSE Linux Enterprise 11 SP2:
chkconfig z90crypt on
Use the chzcrypt command to enable (online state) and disable (offline state) the
IBM crypto adapter:
$ chzcrypt -e 0x06
$ chzcrypt -d 0x06
// set card06 online
// set card06 offline
For more information about the IBM crypto adapter, refer to Linux on System z:
Device Drivers, Features, and Commands:
http://public.dhe.ibm.com/software/dw/linux390/docu/l3n1dd13.pdf
Getting IBM crypto adapter (zcrypt) status information
Use the lszcrypt command to retrieve basic status information.
/proc/driver/z90crypt provides more details about request counts, queues, and
pending requests.
For more information about the IBM crypto adapter, refer to Linux on System z:
Device Drivers, Features, and Commands:
http://public.dhe.ibm.com/software/dw/linux390/docu/l3n1dd13.pdf
2
libica Programmer's Reference
Chapter 2. Installing and using libica Version 2.3.0
Information about where to download the libica Version 2.3.0 library from and
how to install it.
Installing libica Version 2.3.0
You can obtain the libica Version 2.3.0 library from the SourceForge website.
The website is at:
http://sourceforge.net/projects/opencryptoki/files/libica/
Follow the installation instructions on this website to download the libica Version
2.3.0 package and then follow the instructions in “Installing libica Version 2.3.0
from the binary package” or “Installing libica Version 2.3.0 from the source
package” to install libica Version 2.3.0.
Installing libica Version 2.3.0 from the binary package
You can install libica Version 2.3.0 from the binary package.
Examples for Red Hat Enterprise Linux 6.2 and SUSE Linux Enterprise 11 SP2:
Use the following commands:
For Red Hat Enterprise Linux 6.2:
$ rpm -qa | grep -i libica
libica-2.1.0-2.el6.s390x
libica-2.1.0-2.el6.s390
// 64bit
// 32bit compatibility mode
For SUSE Linux Enterprise 11 SP2:
$ rpm -qa | grep -i libica
libica-2_1_0-2.1.0-0.9.1
// 64bit
libica-2_1_0-32bit-2.1.0-0.9.1 // 32bit compatibility mode
If this package is not currently installed on your system, install:
Red Hat Enterprise Linux 6.2:
$ yum install libica
SUSE Linux Enterprise 11 SP2:
$ zypper install libica
Installing libica Version 2.3.0 from the source package
If you prefer you can install the source package.
To do so, download the latest version of the libica Version 2.3.0 sources from:
http://sourceforge.net/projects/opencryptoki/libica
© Copyright IBM Corp. 2009, 2013
3
Extract the tar archive. There should be a new directory named libica-2.x.x.
Change to that directory and execute the following scripts and commands:
$
$
$
$
./bootstrap
./configure
make
make install
where:
bootstrap
Initial setup, basic configurations
configure
Check configurations and build the Makefile
make
Compile and link
make install
Install the libraries
Using libica Version 2.3.0
The function prototypes are provided in the header file, include/ica_api.h.
Applications using these functions must link libica and libcrypto. The libcrypto
library is available from the OpenSSL package. You must have OpenSSL in order to
run libica Version 2.3.0 programs.
libica Version 1, Version 2, Version 2.1.0, Version 2.2.0, and Version
2.3.0 coexistence
Some of the libica Version 1 APIs are available in libica Version 2, libica Version
2.1.0, libica Version 2.2.0, and libica Version 2.3.0.
Some of them, such as those APIs that work with an environment other than Linux
on IBM System z, were removed and are not present in libica Version 2 or later
versions. If your application program has calls to libica Version 1 APIs, check to
see whether these APIs are in libica Version 2.3.0. If they are, these API calls
should still work. However, we suggest that you convert your application to use
the equivalent libica Version 2.3.0 functions. See Chapter 3, “libica Version 2.3.0
Application Programming Interfaces (APIs),” on page 5.
libica key generation is restricted to the limits imposed by the OpenSSL
implementation. Thus, the value of a public exponent passed to libica cannot be
greater than the maximum value that would fit in an unsigned long integer.
4
libica Programmer's Reference
Chapter 3. libica Version 2.3.0 Application Programming
Interfaces (APIs)
A list of APIs for libica Version 2.3.0.
Table 2 lists the APIs for libica Version 2.3.0.
Table 2. libica Version 2.3.0 APIs
Function
libica Version 2.3.0 API name
Key
length in
bits
Supported on
z9
z10
z196
CPACF
function
Software
fallback
Open and close adapter functions
Open adapter handle
“ica_open_adapter” on page 8
N/A
Yes Yes
Yes
No
N/A
Close adapter handle
“ica_close_adapter” on page 8
N/A
Yes Yes
Yes
No
N/A
Secure hash operations
Secure hash using the
SHA-1 algorithm.
“ica_sha1” on page 9
N/A
Yes Yes
Yes
Yes
Yes
Secure hash using the
SHA-224 algorithm.
“ica_sha224” on page 10
N/A
No Yes
Yes
Yes
Yes
Secure hash using the
SHA-256 algorithm.
“ica_sha256” on page 11
N/A
Yes Yes
Yes
Yes
Yes
Secure hash using the
SHA-384 algorithm.
“ica_sha384” on page 12
N/A
No Yes
Yes
Yes
Yes
Secure hash using the
SHA-512 algorithm.
“ica_sha512” on page 13
N/A
No Yes
Yes
Yes
Yes
Yes Yes
Yes
Yes
Yes
Random number generation
Generate a pseudo
random number.
“ica_random_number_generate”
on page 14
N/A
RSA key generation functions
Generate RSA keys in
modulus/exponent
format.
“ica_rsa_key_generate_mod_expo”
on page 15
N/A
Yes Yes
Yes
No
Software
only
Generate RSA keys in
CRT format.
“ica_rsa_key_generate_crt” on
page 15
N/A
Yes Yes
Yes
No
Software
only
Yes
No
Key length
maximum
4 K bits
RSA encryption and decryption operations
RSA encryption and
decryption operation
using a key in
modulus/exponent
format.
“ica_rsa_mod_expo” on page 16
© Copyright IBM Corporation © IBM 2009, 2013
Depending Yes Yes
on
supported
key size of
Crypto
Express
feature
5
Table 2. libica Version 2.3.0 APIs (continued)
Function
RSA encryption and
decryption operation
using a key in
Chinese-Remainder
Theorem (CRT) format.
libica Version 2.3.0 API name
“ica_rsa_crt” on page 17
Key
length in
bits
Supported on
z10
z196
CPACF
function
Software
fallback
Depending Yes Yes
on
supported
key size of
Crypto
Express
feature
Yes
No
Key length
maximum
4 K bits
z9
DES functions
DES with Cipher Block
Chaining mode
“ica_des_cbc” on page 18
56
Yes Yes
Yes
Yes
Yes
DES with CBC-Cipher
text stealing mode
“ica_des_cbc_cs” on page 19
56
Yes Yes
Yes
Yes
Yes
DES with Cipher
Feedback mode
“ica_des_cfb” on page 20
56
No No
Yes
Yes
No
DES with CMAC mode
“ica_des_cmac” on page 21
56
No No
Yes
Yes
No
DES with CMAC mode
process intermediate
chunks
“ica_des_cmac_intermediate” on
page 22
56
No No
Yes
Yes
No
DES with CMAC mode
process last chunk
“ica_des_cmac_last” on page 23
56
No No
Yes
Yes
No
DES with Counter mode
“ica_des_ctr” on page 24
56
No No
Yes
Yes
No
DES with Counter mode,
using a list of counters
“ica_des_ctrlist” on page 26
56
No No
Yes
Yes
No
DES with Electronic
Codebook mode.
“ica_des_ecb” on page 27
56
Yes Yes
Yes
Yes
Yes
DES with Output
Feedback mode
“ica_des_ofb” on page 27
56
No No
Yes
Yes
No
TDES/3DES functions
TDES with Cipher Block
Chaining mode
“ica_3des_cbc” on page 30
168
Yes Yes
Yes
Yes
Yes
TDES with CBC-Cipher
text Stealing mode
“ica_3des_cbc_cs” on page 30
168
Yes Yes
Yes
Yes
Yes
TDES with Cipher
Feedback mode
“ica_3des_cfb” on page 32
168
No No
Yes
Yes
No
TDES with CMAC mode
“ica_3des_cmac” on page 33
168
No No
Yes
Yes
No
TDES with CMAC mode
process intermediate
chunks
“ica_3des_cmac_intermediate” on
page 34
168
No No
Yes
Yes
No
TDES with CMAC mode
process last chunk
“ica_3des_cmac_last” on page 35
168
No No
Yes
Yes
No
TDES with Counter mode “ica_3des_ctr” on page 36
168
No No
Yes
Yes
No
TDES with Counter
mode, using a list of
counters
“ica_3des_ctrlist” on page 37
168
No No
Yes
Yes
No
TDES with Electronic
Codebook mode
“ica_3des_ecb” on page 38
168
Yes Yes
Yes
Yes
Yes
6
libica Programmer's Reference
Table 2. libica Version 2.3.0 APIs (continued)
Function
libica Version 2.3.0 API name
TDES with Output
Feedback mode
Key
length in
bits
“ica_3des_ofb” on page 39
Supported on
z10
z196
CPACF
function
Software
fallback
168
No No
Yes
Yes
No
z9
AES functions
AES with Cipher Block
Chaining mode.
“ica_aes_cbc” on page 41
128, 192,
256
Yes Yes
Yes
Yes
Yes
AES with CBC-Cipher
text stealing mode.
“ica_aes_cbc_cs” on page 42
128, 192,
256
Yes Yes
Yes
Yes
Yes
AES with Counter with
Cipher Block Chaining Message Authentication
Code mode.
“ica_aes_ccm” on page 43
128, 192,
256
No No
Yes
Yes
No
AES with Cipher
Feedback mode.
“ica_aes_cfb” on page 45
128, 192,
256
No No
Yes
Yes
No
AES with CMAC mode
“ica_aes_cmac” on page 46
128, 192,
256
No No
Yes
Yes
No
AES with CMAC mode
process intermediate
chunks
“ica_aes_cmac_intermediate” on
page 47
128, 192,
256
No No
Yes
Yes
No
AES with CMAC mode
process last chunk
“ica_aes_cmac_last” on page 48
128, 192,
256
No No
Yes
Yes
No
AES with Counter mode.
“ica_aes_ctr” on page 49
128, 192,
256
No No
Yes
Yes
No
AES with Counter mode,
using a list of counters
“ica_aes_ctrlist” on page 50
128, 192,
256
No No
Yes
Yes
No
AES with Electronic
Codebook mode.
“ica_aes_ecb” on page 51
128, 192,
256
Yes Yes
Yes
Yes
Yes
AES with Galois /
Counter mode.
“ica_aes_gcm” on page 52
128, 192,
256
No No
Yes
Yes
No
AES with Output
Feedback mode.
“ica_aes_ofb” on page 54
128, 192,
256
No No
Yes
Yes
No
AES with XEX-based
“ica_aes_xts” on page 55
Tweaked CodeBook mode
(TCB) with CipherText
Stealing (CTS).
128, 256
No No
Yes
Yes
No
Information retrieval functions
|
|
|
Return version
information for libica.
“ica_get_version” on page 57
N/A
Yes Yes
Yes
No
N/A
Return a list of crypto
mechanisms supported
by libica.
“ica_get_functionlist” on page 57
N/A
Yes Yes
Yes
No
N/A
Open and close adapter functions
These functions open or close the crypto adapter. It is recommended to open the
crypto adapter before using any of the libica crypto functions, and to close it after
the last usage of the libica crypto functions. However, in this version of the libica
only the RSA-related functions ica_rsa_mod_expo and ica_rsa_crt require a valid
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
7
adapter handle as input. A pointer to the value DRIVER_NOT_LOADED indicates
an invalid adapter handle. The parameter ica_adapter_handle_t is a redefine of int.
These functions are included in: include/ica_api.h.
ica_open_adapter
Purpose
Opens an adapter.
Format
unsigned int ica_open_adapter(ica_adapter_handle_t *adapter_handle);
Parameters
ica_adapter_handle_t *adapter_handle
Pointer to the file descriptor for the adapter or to DRIVER_NOT_LOADED if
opening the crypto adapter failed.
Opening an adapter succeeds if a cryptographic device is accessible for reading
and writing. By default, cryptographic access must be available with one of the
following path names: /udev/z90crypt, /dev/z90crypt, or /dev/zcrypt for the
adapter open request to succeed. If the environment variable
LIBICA_CRYPT_DEVICE is set to a valid path name of an accessible
cryptographic device, accessing the device with that path name takes
precedence over the default path names.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_close_adapter
Purpose
Closes an adapter.
Comments
This API closes a device handle.
Format
unsigned int ica_close_adapter(ica_adapter_handle_t adapter_handle);
Parameters
ica_adapter_handle_t adapter_handle
Pointer to a previously opened device handle.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
8
libica Programmer's Reference
Secure hash operations
These functions are included in: include/ica_api.h.
These functions perform secure hash on input data using the chosen algorithm of
SHA-1, SHA-224, SHA-256, SHA-384, or SHA-512.
SHA context structs contain information about how much of the actual work was
already performed. Also, it contains the part of the hash that is already produced.
For the user, it is only interesting in cases where the message is not hashed at
once, because the context is needed for further operations.
ica_sha1
Purpose
Performs a secure hash operation on the input data using the SHA-1 algorithm.
Format
unsigned int ica_sha1(unsigned int message_part,
unsigned int input_length,
unsigned char *input_data,
sha_context_t *sha_context,
unsigned char *output_data);
Required hardware support
KIMD-SHA-1, or KLMD-SHA-1
Parameters
unsigned int message_part
The message chaining state. This parameter must be one of the following
values:
SHA_MSG_PART_ONLY
A single hash operation
SHA_MSG_PART_FIRST
The first part
SHA_MSG_PART_MIDDLE
The middle part
SHA_MSG_PART_FINAL
The last part
unsigned int input_length
Length in bytes of the input data to be hashed using the SHA-1 algorithm.
This value must be greater than zero.
unsigned char *input_data
Pointer to the input data to be hashed.
sha_context_t *sha_context
Pointer to the SHA-1 context structure used to store intermediate values
needed when chaining is used. The contents are ignored for message part
SHA_MSG_PART_ONLY and SHA_MSG_PART_FIRST. This structure must
contain the returned value of the preceding call to ica_sha1 for message part
SHA_MSG_PART_MIDDLE and SHA_MSG_PART_FINAL. For message part
SHA_MSG_PART_FIRST and SHA_MSG_PART_FINAL, the returned value can
be used for a chained call of ica_sha1. Therefore, the application must not
modify the contents of this structure in between chained calls.
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
9
unsigned char *output_data
Pointer to the buffer to contain the resulting hash data. The resulting output
data has a length of SHA_HASH_LENGTH. Make sure that the buffer is at
least this size.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_sha224
Purpose
Performs a secure hash operation on the input data using the SHA-224 algorithm.
Format
unsigned int ica_sha224(unsigned int message_part,
unsigned int input_length,
unsigned char *input_data,
sha256_context_t *sha256_context,
unsigned char *output_data);
Required hardware support
KIMD-SHA-256, or KLMD-SHA-256
Parameters
unsigned int message_part
The message chaining state. This parameter must be one of the following
values:
SHA_MSG_PART_ONLY
A single hash operation
SHA_MSG_PART_FIRST
The first part
SHA_MSG_PART_MIDDLE
The middle part
SHA_MSG_PART_FINAL
The last part
unsigned int input_length
Length in bytes of the input data to be hashed using the SHA-224 algorithm.
This value must be greater than zero.
unsigned char *input_data
Pointer to the input data to be hashed.
sha256_context_t *sha256_context
Pointer to the SHA-256 context structure used to store intermediate values
needed when chaining is used. The contents are ignored for message part
SHA_MSG_PART_ONLY and SHA_MSG_PART_FIRST. This structure must
contain the returned value of the preceding call to ica_sha224 for message part
SHA_MSG_PART_MIDDLE and SHA_MSG_PART_FINAL. For message part
SHA_MSG_PART_FIRST and SHA_MSG_PART_FINAL, the returned value can
be used for a chained call of ica_sha224. Therefore, the application must not
modify the contents of this structure in between chained calls.
10
libica Programmer's Reference
Note: Due to the algorithm used by SHA-224, a SHA-256 context must be
used.
unsigned char *output_data
Pointer to the buffer to contain the resulting hash data. The resulting output
data has a length of SHA224_HASH_LENGTH. Make sure that the buffer is at
least this size.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_sha256
Purpose
Performs a secure hash on the input data using the SHA-256 algorithm.
Format
unsigned int ica_sha256(unsigned int message_part,
unsigned int input_length,
unsigned char *input_data,
sha256_context_t *sha256_context,
unsigned char *output_data);
Required hardware support
KIMD-SHA-256, or KLMD-SHA-256
Parameters
unsigned int message_part
The message chaining state. This parameter must be one of the following
values:
SHA_MSG_PART_ONLY
A single hash operation
SHA_MSG_PART_FIRST
The first part
SHA_MSG_PART_MIDDLE
The middle part
SHA_MSG_PART_FINAL
The last part
unsigned int input_length
Length in bytes of the input data to be hashed using the SHA-256 algorithm.
This value must be greater than zero.
unsigned char *input_data
Pointer to the input data to be hashed.
sha256_context_t *sha256_context
Pointer to the SHA-256 context structure used to store intermediate values
needed when chaining is used. The contents are ignored for message part
SHA_MSG_PART_ONLY and SHA_MSG_PART_FIRST. This structure must
contain the returned value of the preceding call to ica_sha256 for message part
SHA_MSG_PART_MIDDLE and SHA_MSG_PART_FINAL. For message part
SHA_MSG_PART_FIRST and SHA_MSG_PART_FINAL, the returned value can
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
11
be used for a chained call of ica_sha256. Therefore, the application must not
modify the contents of this structure in between chained calls.
unsigned char *output_data
Pointer to the buffer to contain the resulting hash data. The resulting output
data has a length of SHA256_HASH_LENGTH. Make sure that the buffer is at
least this size.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_sha384
Purpose
Performs a secure hash on the input data using the SHA-384 algorithm.
Format
unsigned int ica_sha384(unsigned int message_part,
uint64_t input_length,
unsigned char *input_data,
sha512_context_t *sha512_context,
unsigned char *output_data);
Required hardware support
KIMD-SHA-512, or KLMD-SHA-512
Parameters
unsigned int message_part
The message chaining state. This parameter must be one of the following
values:
SHA_MSG_PART_ONLY
A single hash operation
SHA_MSG_PART_FIRST
The first part
SHA_MSG_PART_MIDDLE
The middle part
SHA_MSG_PART_FINAL
The last part
uint64_t input_length
Length in bytes of the input data to be hashed using the SHA-384 algorithm.
This value must be greater than zero.
unsigned char *input_data
Pointer to the input data to be hashed.
sha512_context_t *sha512_context
Pointer to the SHA-512 context structure used to store intermediate values
needed when chaining is used. The contents are ignored for message part
SHA_MSG_PART_ONLY and SHA_MSG_PART_FIRST. This structure must
contain the returned value of the preceding call to ica_sha384 for message part
SHA_MSG_PART_MIDDLE and SHA_MSG_PART_FINAL. For message part
SHA_MSG_PART_FIRST and SHA_MSG_PART_FINAL, the returned value can
12
libica Programmer's Reference
be used for a chained call of ica_sha384. Therefore, the application must not
modify the contents of this structure in between chained calls.
Note: Due to the algorithm used by SHA-384, a SHA-512 context must be
used.
unsigned char *output_data
Pointer to the buffer to contain the resulting hash data. The resulting output
data has a length of SHA384_HASH_LENGTH. Make sure that the buffer is at
least this size.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_sha512
Purpose
Performs a secure hash operation on input data using the SHA-512 algorithm.
Format
unsigned int ica_sha512(unsigned int message_part,
uint64_t input_length,
unsigned char *input_data,
sha512_context_t *sha512_context,
unsigned char *output_data);
Required hardware support
KIMD-SHA-512, or KLMD-SHA-512
Parameters
unsigned int message_part
The message chaining state. This parameter must be one of the following
values:
SHA_MSG_PART_ONLY
A single hash operation
SHA_MSG_PART_FIRST
The first part
SHA_MSG_PART_MIDDLE
The middle part
SHA_MSG_PART_FINAL
The last part
uint64_t input_length
Length in bytes of the input data to be hashed using the SHA-512 algorithm.
This value must be greater than zero.
unsigned char *input_data
Pointer to the input data to be hashed.
sha512_context_t *sha512_context
Pointer to the SHA-512 context structure used to store intermediate values
needed when chaining is used. The contents are ignored for message part
SHA_MSG_PART_ONLY and SHA_MSG_PART_FIRST. This structure must
contain the returned value of the preceding call to ica_sha512 for message part
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
13
SHA_MSG_PART_MIDDLE and SHA_MSG_PART_FINAL. For message part
SHA_MSG_PART_FIRST and SHA_MSG_PART_FINAL, the returned value can
be used for a chained call of ica_sha512. Therefore, the application must not
modify the contents of this structure in between chained calls.
unsigned char *output_data
Pointer to the buffer to contain the resulting hash data. The resulting output
data has a length of SHA512_HASH_LENGTH. Make sure that the buffer is at
least this size.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
Pseudo random number generation function
This function is included in: include/ica_api.h.
This function generates pseudo random data. Parameter *ouput_data is a pointer to
a buffer of byte length output_length. output_length number of bytes of pseudo
random data is placed in the buffer pointed to by output_data.
libica initialization tries to seed the CPACF random generator. To get the seed,
device /dev/hwrng is opened. Device /dev/hwrng provides true random data from
crypto adapters over the crypto device driver (module name z90crypt). If that fails,
the initialization mechanism uses device /dev/urandom. Within the initialization, a
byte counter s390_byte_count is set to 0. If the CPACF pseudo random generator is
available, after 4096 bytes of the pseudo random number are generated, the
random number generator is seeded again. If the CPACF pseudo random generator
is not available, random numbers are read from /dev/urandom.
ica_random_number_generate
Purpose
Generates a pseudo random number.
Format
unsigned int ica_random_number_generate(unsigned int output_length,
unsigned char *output_data);
Required hardware support
KMC-PRNG
Parameters
unsigned int output_length
Length in bytes of the output_data buffer, and the length of the generated
pseudo random number.
unsigned char *output_data
Pointer to the buffer to receive the generated pseudo random number.
Return codes
0
14
libica Programmer's Reference
Success
For return codes indicating exceptions, see “Return codes” on page 70.
RSA key generation functions
These functions are included in: include/ica_api.h.
These functions generate an RSA public/private key pair. These functions are
performed using software through OpenSSL. Hardware is not used.
ica_rsa_key_generate_mod_expo
Purpose
Generates RSA keys in modulus/exponent format.
Comments
For specific information about some of these parameters, see the considerations in
“Structs” on page 68.
Format
unsigned int ica_rsa_key_generate_mod_expo(ica_adapter_handle_t adapter_handle,
unsigned int modulus_bit_length,
ica_rsa_key_mod_expo_t *public_key,
ica_rsa_key_mod_expo_t *private_key);
Parameters
ica_adapter_handle_t adapter_handle
Pointer to a previously opened device handle.
unsigned int modulus_bit_length
Length in bits of the modulus. This value should comply with the length of the
keys (in bytes), according to this calculation:
key_length = (modulus_bits + 7) / 8
ica_rsa_key_mod_expo_t *public_key
Pointer to where the generated public key is to be placed. If the exponent
element in the public key is not set, it is randomly generated. A poorly chosen
exponent could result in the program looping endlessly. Common public
exponents are 3 and 65537.
ica_rsa_key_mod_expo_t *private_key
Pointer to where the generated private key in modulus/exponent format is to
be placed. The length of both the private and public keys should be set in
bytes. This value should comply with the length of the keys (in bytes),
according to this calculation:
key_length = (modulus_bits + 7) / 8
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_rsa_key_generate_crt
Purpose
Generates RSA keys in Chinese-Remainder Theorem (CRT) format.
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
15
Comments
For specific information about some of these parameters, see the considerations in
“Structs” on page 68.
Format
unsigned int ica_rsa_key_generate_crt(ica_adapter_handle_t adapter_handle,
unsigned int modulus_bit_length,
ica_rsa_key_mod_expo_t *public_key,
ica_rsa_key_crt_t *private_key);
Parameters
ica_adapter_handle_t adapter_handle
Pointer to a previously opened device handle.
unsigned int modulus_bit_length
Length in bits of the modulus part of the key. This value should comply with
the length of the keys (in bytes), according to this calculation:
key_length = (modulus_bits + 7) / 8
ica_rsa_key_mod_expo_t *public_key
Pointer to where the generated public key is to be placed. If the exponent
element in the public key is not set, it is randomly generated. A poorly chosen
exponent can result in the program looping endlessly. Common public
exponents are 3 and 65537.
ica_rsa_key_crt_t *private_key
Pointer to where the generated private key in CRT format is to be placed.
Length of both private and public keys should be set in bytes. This value
should comply with the length of the keys (in bytes), according to this
calculation
key_length = (modulus_bits + 7) / 8
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
RSA encrypt and decrypt operations
These functions are included in: include/ica_api.h.
These functions perform a modulus/exponent operation using an RSA key whose
type is either ica_rsa_key_mod_expo_t or ica_rsa_key_crt_t.
ica_rsa_mod_expo
Purpose
Performs an RSA encryption or decryption operation using a key in
modulus/exponent format.
Comments
Make sure that your message is padded before using this function.
16
libica Programmer's Reference
Format
unsigned int ica_rsa_mod_expo(ica_adapter_handle_t adapter_handle,
unsigned char *input_data,
ica_rsa_key_mod_expo_t *rsa_key,
unsigned char *output_data);
Parameters
ica_adapter_handle_t adapter_handle
Pointer to a previously opened device handle.
unsigned char *input_data
Pointer to the input data to be encrypted or decrypted. This data must be in
big endian format. Make sure that the input data is not longer than the bit
length of the key. The byte length for the input data and the key must be the
same. Right align the input data inside the data block.
ica_rsa_key_mod_expo_t *rsa_key
Pointer to the key to be used, in modulus/exponent format.
unsigned char *output_data
Pointer to the location where the output results are to be placed. This buffer
has to be at least the same size as input_data and therefore at least the same
size as the size of the modulus.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_rsa_crt
Purpose
Performs an RSA encryption or decryption operation using a key in CRT format.
Comments
Make sure that your message is padded before using this function.
Format
unsigned int ica_rsa_crt(ica_adapter_handle_t adapter_handle,
unsigned char *input_data,
ica_rsa_key_crt_t *rsa_key,
unsigned char *output_data);
Parameters
ica_adapter_handle_t adapter_handle
Pointer to a previously opened device handle.
unsigned char *input_data
Pointer to the input data to be encrypted or decrypted. This data must be in
big endian format. Make sure that the input data is not longer than the bit
length of the key. The byte length for the input data and the key must be the
same. Right align the input data inside the data block.
ica_rsa_key_crt_t *rsa_key
Pointer to the key to be used, in CRT format.
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
17
unsigned char *output_data
Pointer to the location where the output results are to be placed. This buffer
must be as large as the input_data, and as large as the length of the modulus
specified in rsa_key.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
DES functions
These functions are included in: include/ica_api.h.
These functions perform encryption and decryption and computation or
verification of message authentication codes using a DES (DEA) key. A DES key
has a size of 8 bytes. Each byte of a DES key contains one parity bit, such that each
64-bit DES key contains only 56 security-relevant bits. The cipher block size for
DES is 8 bytes.
To securely apply DES encryption to messages that are longer than the cipher
block size, modes of operation can be used to chain multiple encryption,
decryption, or authentication operations. Most modes of operation require an
initialization vector as additional input. As long as the messages are encrypted or
decrypted using such a mode of operation, and have a size that is a multiple of a
particular block size (mostly the cipher block size), the functions encrypting or
decrypting according to a mode of operation also compute an output vector. This
output vector can be used as the initialization vector of a chained encryption or
decryption operation in the same mode with the same block size and the same key.
When decrypting a cipher text, these values used for the decryption function must
match the corresponding settings of the encryption function that transformed the
plain text into the cipher text:
v The mode of operation
v The key
v The initialization vector (if applicable)
v For the ica_des_cfb function, the lcfb parameter
ica_des_cbc
Purpose
Encrypt or decrypt data with a DES key using Cipher Block Chaining (CBC) mode,
as described in NIST Special Publication 800-38A Chapter 6.2.
Format
unsigned int ica_des_cbc(const unsigned char *in_data,
unsigned char *out_data,
unsigned long data_length,
const unsigned char *key,
unsigned char *iv,
unsigned int direction);
Required hardware support
KMC-DEA
18
libica Programmer's Reference
Parameters
const unsigned char *in_data
Pointer to a readable buffer that contains the message to be encrypted or
decrypted. The size of the message in bytes is data_length. This buffer must be
at least as large as data_length.
unsigned char *out_data
Pointer to a writable buffer to contain the resulting encrypted or decrypted
message. The size of this buffer in bytes must be at least as large as data_length.
unsigned long data_length
Length in bytes of the message to be encrypted or decrypted, which resides at
the beginning of in_data. data_length must be a multiple of the cipher block size
(a multiple of 8 bytes for DES).
const unsigned char *key
Pointer to a valid DES key of 8 bytes in length.
unsigned char *iv
Pointer to a valid initialization vector of cipher block size number of bytes (8
bytes for DES). This vector is overwritten by this function. The result value in
iv can be used as the initialization vector for a chained ica_des_cbc or
ica_des_cbc_cs call with the same key.
unsigned int direction
0
Use the decrypt function.
1
Use the encrypt function.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_des_cbc_cs
Purpose
Encrypt or decrypt data with a DES key using Cipher Block Chaining with
Ciphertext Stealing (CBC-CS) mode, as described in NIST Special Publication
800-38A, Chapter 6.2 and the Addendum to NIST Special Publication 800-38A on
"Recommendation for Block Cipher Modes of Operation: Three Variants of
Ciphertext Stealing for CBC Mode".
ica_des_cbc_cs can be used to encrypt or decrypt the last chunk of a message
consisting of multiple chunks, where all chunks except the last one are encrypted
or decrypted by chained calls to ica_des_cbc. To do this, the resulting iv of the last
call to ica_des_cbc is fed into the iv of the ica_des_cbc_cs call, provided that the
chunk is greater than the cipher block size (8 bytes for DES).
Format
unsigned int ica_des_cbc_cs(const unsigned char *in_data,
unsigned char *out_data,
unsigned long data_length,
const unsigned char *key,
unsigned char *iv,
unsigned int direction,
unsigned int variant);
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
19
Required hardware support
KMC-DEA
Parameters
const unsigned char *in_data
Pointer to a readable buffer that contains the message to be encrypted or
decrypted. The size of the message in bytes is data_length. The size of this
buffer must be at least as large as the data_length.
unsigned char *out_data
Pointer to a writable buffer to contain the resulting encrypted or decrypted
message. This buffer must be at least as large as data_length.
unsigned long data_length
Length in bytes of the message to be encrypted or decrypted, which resides at
the beginning of in_data. data_length must be greater than or equal to the cipher
block size (8 bytes for DES).
const unsigned char *key
Pointer to a valid DES key of 8 bytes in length.
unsigned char *iv
Pointer to a valid initialization vector of cipher block size number of bytes.
This vector is overwritten during the function. For variant equal to 1 or variant
equal to 2, the result value in iv can be used as the initialization vector for a
chained ica_des_cbc or ica_des_cbc_cs call with the same key, if data_length is
a multiple of the cipher block size.
unsigned int direction
0
Use the decrypt function.
1
Use the encrypt function.
unsigned int variant
1
Use variant CBC-CS1 of the Addendum to NIST Special Publication
800-38A to encrypt or decrypt the message: always keep last two
blocks in order.
2
Use variant CBC-CS2 of the Addendum to NIST Special Publication
800-38A to encrypt or decrypt the message: switch order of the last two
blocks if data_length is not a multiple of the cipher block size (a
multiple of 8 bytes for DES).
3
Use variant CBC-CS3 of the Addendum to NIST Special Publication
800-38A to encrypt or decrypt the message: always switch order of the
last two blocks.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_des_cfb
Purpose
Encrypt or decrypt data with a DES key using Cipher Feedback (CFB) mode, as
described in NIST Special Publication 800-38A Chapter 6.3.
20
libica Programmer's Reference
Format
unsigned int ica_des_cfb(const unsigned char *in_data,
unsigned char *out_data,
unsigned long data_length,
const unsigned char *key,
unsigned char *iv,
unsigned int lcfb,
unsigned int direction);
Required hardware support
KMF-DEA
Parameters
const unsigned char *in_data
Pointer to a readable buffer that contains the message to be encrypted or
decrypted. The size of the message in bytes is data_length. The size of this
buffer must be at least as large as the data_length parameter.
unsigned char *out_data
Pointer to a writable buffer to contain the resulting encrypted or decrypted
message. The size of this buffer in bytes must be at least as large as the
data_length parameter.
unsigned long data_length
Length in bytes of the message to be encrypted or decrypted, which resides at
the beginning of in_data.
const unsigned char *key
Pointer to a valid DES key of 8 bytes in length.
unsigned char *iv
Pointer to a valid initialization vector of cipher block size bytes (8 bytes for
DES). This vector is overwritten during the function. The result value in iv can
be used as the initialization vector for a chained ica_des_cfb call with the same
key, if data_length in the preceding call is a multiple of the lcfb parameter.
unsigned int lcfb
Length in bytes of the cipher feedback, which is a value greater than or equal
to 1 and less than or equal to the cipher block size (8 bytes for DES).
unsigned int direction
0
Use the decrypt function.
1
Use the encrypt function.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_des_cmac
Purpose
Authenticate data or verify the authenticity of data with a DES key using the Block
Cipher Based Message Authentication Code (CMAC) mode, as described in NIST
Special Publication 800-38B. ica_des_cmac can be used to authenticate or verify the
authenticity of a complete message.
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
21
Format
unsigned int ica_des_cmac(const unsigned char *message,
unsigned long message_length,
unsigned char *mac,
unsigned int mac_length,
const unsigned char *key,
unsigned int direction);
Required hardware support
KMAC-DEA
PCC-Compute-Last_block-CMAC-Using-DEA
Parameters
const unsigned char *message
Pointer to a readable buffer of size greater than or equal to message_length
bytes. This buffer contains a message to be authenticated or of which the
authenticity is to be verified.
unsigned long message_length
Length in bytes of the message to be authenticated or verified.
unsigned char *mac
Pointer to a buffer of size greater than or equal to mac_length bytes. If direction
is equal to 1, the buffer must be writable and a message authentication code
for the message in message of size mac_length bytes is written to the buffer. If
direction is equal to 0, the buffer must be readable and contain a message
authentication code to be verified against the message in message.
unsigned int mac_length
Length in bytes of the message authentication code mac, which is less than or
equal to the cipher block size (8 bytes for DES). It is recommended to use a
mac_length of 8.
const unsigned char *key
Pointer to a valid DES key of 8 bytes in length.
unsigned int direction
0
Verify message authentication code.
1
Compute message authentication code for the message.
Return codes
0
Success
EFAULT
If direction is equal to 0 and the verification of the message authentication
code fails.
For return codes indicating exceptions, see “Return codes” on page 70.
ica_des_cmac_intermediate
Purpose
Authenticate data or verify the authenticity of data with a DES key using the Block
Cipher Based Message Authentication Code (CMAC) mode, as described in NIST
Special Publication 800-38B. ica_des_cmac_intermediate and ica_des_cmac_last can
be used when the message to be authenticated or to be verified using CMAC is
supplied in multiple chunks. ica_des_cmac_intermediate is used to process all but
the last chunk. All message chunks to be processed by ica_des_cmac_intermediate
must have a size that is a multiple of the cipher block size (8 bytes for DES).
22
libica Programmer's Reference
Note that ica_des_cmac_intermediate has no direction argument. This function can
be used during authentication and during authenticity verification.
Format
unsigned int ica_des_cmac_intermediate(const unsigned char *message,
unsigned long message_length,
const unsigned char *key,
unsigned char *iv);
Required hardware support
KMAC-DEA
Parameters
const unsigned char *message
Pointer to a readable buffer of size greater than or equal to message_length
bytes. This buffer contains a non-final part of a message to be authenticated, or
of which the authenticity is to be verified.
unsigned long message_length
Length in bytes of the message part in message. This value must be a multiple
of the cipher block size.
const unsigned char *key
Pointer to a valid DES key of 8 bytes in length.
unsigned char *iv
Pointer to a valid initialization vector of cipher block size bytes (8 bytes for
DES). For the first message part, this parameter must be set to a string of
zeros. For processing the n-th message part, this parameter must be the
resulting iv value of the ica_des_cmac_intermediate function applied to the
(n-1)-th message part. This vector is overwritten during the function. The result
value in iv can be used as the initialization vector for a chained call to
ica_des_cmac_initermediate, or to ica_des_cmac_last with the same key.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_des_cmac_last
Purpose
Authenticate data or verify the authenticity of data with a DES key using the Block
Cipher Based Message Authentication Code (CMAC) mode, as described in NIST
Special Publication 800-38B. ica_des_cmac_last can be used to authenticate or
verify the authenticity of a complete message or of the final part of a message for
which all preceding parts were processed with ica_des_cmac_intermediate.
Format
unsigned int ica_des_cmac_last(const unsigned char *message,
unsigned long message_length,
unsigned char *mac,
unsigned int mac_length,
const unsigned char *key,
unsigned char *iv,
unsigned int direction);
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
23
Required hardware support
KMAC-DEA
PCC-Compute-Last_block-CMAC-Using-DEA
Parameters
const unsigned char *message
Pointer to a readable buffer of size greater than or equal to message_length
bytes. This buffer contains a message or the final part of a message, to be
either authenticated or of which the authenticity is to be verified.
unsigned long message_length
Length in bytes of the message to be authenticated or verified.
unsigned char *mac
Pointer to a buffer of size greater than or equal to mac_length bytes. If direction
is equal to 1, the buffer must be writable and a message authentication code
for the message in message of size mac_length bytes is written to the buffer. If
direction is equal to 0, the buffer must be readable and contain a message
authentication code that is verified against the message in message.
unsigned int mac_length
Length in bytes of the message authentication code mac that is less than or
equal to the cipher block size (8 bytes for DES). It is recommended to use a
mac_length of 8.
const unsigned char *key
Pointer to a valid DES key of 8 bytes in length.
unsigned char *iv
Pointer to a valid initialization vector of cipher block size number of bytes. If
iv is NULL, message is assumed to be the complete message to be processed.
Otherwise, message is the final part of a composite message to be processed
and iv contains the output vector resulting from processing all previous parts
with chained calls to ica_des_cmac_intermediate (the value returned in iv of
the ica_des_cmac_intermediate call applied to the penultimate message part).
unsigned int direction
0
Verify message authentication code.
1
Compute message authentication code for the message.
Return codes
0
Success
EFAULT
If direction is equal to 0 and the verification of the message authentication
code fails.
For return codes indicating exceptions, see “Return codes” on page 70.
ica_des_ctr
Purpose
Encrypt or decrypt data with a DES key using Counter (CTR) mode, as described
in NIST Special Publication 800-38A Chapter 6.5. With the counter mode, each
message block of the same size as the cipher block (8 bytes for DES) is combined
with a counter value of the same size during encryption and decryption.
Starting with an initial counter value to be combined with the first message block,
subsequent counter values to be combined with subsequent message blocks are
24
libica Programmer's Reference
derived from preceding counter values by an increment function. The increment
function used in ica_des_ctr is an arithmetic increment without carry on the M
least significant bytes in the counter, where M is a parameter to ica_des_ctr.
Format
unsigned int ica_des_ctr(const unsigned char *in_data,
unsigned char *out_data,
unsigned long data_length,
const unsigned char *key,
unsigned char *ctr,
unsigned int ctr_width,
unsigned int direction);
Required hardware support
KMCTR-DEA
Parameters
const unsigned char *in_data
Pointer to a readable buffer that contains the message to be encrypted or
decrypted. The size of the message in bytes is data_length. The size of this
buffer must be at least as large as data_length.
unsigned char *out_data
Pointer to a writable buffer to contain the resulting encrypted or decrypted
message. The size of this buffer in bytes must be at least as large as data_length.
unsigned long data_length
Length in bytes of the message to be encrypted or decrypted, which resides at
the beginning of in_data.
const unsigned char *key
Pointer to a valid DES key of 8 bytes in length.
unsigned char *ctr
Pointer to a readable and writable buffer of the same size as the cipher block
in bytes. ctr contains an initialization value for a counter function, and it is
replaced by a new value. That new value can be used as the initialization
value for a counter function in a chained ica_des_ctr call with the same key, if
the data_length used in the preceding call is a multiple of the cipher block size.
unsigned int ctr_width
A number M between 1 and the cipher block size. This value is used by the
counter increment function, which increments a counter value by incrementing
without carry the least significant M bytes of the counter value.
unsigned int direction
0
Use the decrypt function.
1
Use the encrypt function.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
25
ica_des_ctrlist
Purpose
Encrypt or decrypt data with a DES key using Counter (CTR) mode, as described
in NIST Special Publication 800-38A ,Chapter 6.5. With the counter mode, each
message block of the same size as the cipher block is combined with a counter
value of the same size during encryption and decryption.
The ica_des_ctrlist function assumes that a list n of precomputed counter values is
provided, where n is the smallest integer that is less than or equal to the message
size divided by the cipher block size. This function is used to optimally utilize IBM
System z hardware support for non-standard counter functions.
Format
unsigned int ica_des_ctrlist(const unsigned char *in_data,
unsigned char *out_data,
unsigned long data_length,
const unsigned char *key,
const unsigned char *ctrlist,
unsigned int direction);
Required hardware support
KMCTR-DEA
Parameters
const unsigned char *in_data
Pointer to a readable buffer that contains the message to be encrypted or
decrypted. The size of the message in bytes is data_length. The size of this
buffer must be at least as large as data_length.
unsigned char *out_data
Pointer to a writable buffer to contain the resulting encrypted or decrypted
message. The size of this buffer in bytes must be at least as large as data_length.
unsigned long data_length
Length in bytes of the message to be encrypted or decrypted, which resides at
the beginning of in_data.
Calls to ica_des_ctrlist with the same key can be chained if:
v With the possible exception of the last call in the chain the data_length used
is a multiple of the cipher block size.
v The ctrlist argument of each chained call contains a list of counters that
follows the counters used in the preceding call.
const unsigned char *key
Pointer to a valid DES key of 8 bytes in length.
const unsigned char *ctrlist
Pointer to a readable buffer of a size greater than or equal to data_length, and a
multiple of the cipher block size (8 bytes for DES). ctrlist should contain a list
of precomputed counter values, each of the same size as the cipher block.
unsigned int direction
0
Use the decrypt function.
1
Use the encrypt function.
Return codes
0
26
libica Programmer's Reference
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_des_ecb
Purpose
Encrypt or decrypt data with a DES key using Electronic Code Book (ECB) mode,
as described in NIST Special Publication 800-38A Chapter 6.1.
Format
unsigned int ica_des_ecb(const unsigned char *in_data,
unsigned char *out_data,
unsigned long data_length,
const unsigned char *key,
unsigned int direction);
Required hardware support
KM-DEA
Parameters
const unsigned char *in_data
Pointer to a readable buffer that contains the message to be encrypted or
decrypted. The size of the message in bytes is data_length. The size of this
buffer must be at least as large as data_length.
unsigned char *out_data
Pointer to a writeable buffer to contain the resulting encrypted or decrypted
message. The size of this buffer in bytes must be at least as large as data_length.
unsigned long data_length
Length in bytes of the message to be encrypted or decrypted, which resides at
the beginning of in_data. data_length must be a multiple of the cipher block size
(8 bytes for DES).
const unsigned char *key
Pointer to a valid DES key of 8 bytes in length.
unsigned int direction
0
Use the decrypt function.
1
Use the encrypt function.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_des_ofb
Purpose
Encrypt or decrypt data with a DES key using Output Feedback (OFB) mode, as
described in NIST Special Publication 800-38A Chapter 6.4.
Format
unsigned int ica_des_ofb(const unsigned char *in_data,
unsigned char *out_data,
unsigned long data_length,
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
27
const unsigned char *key,
unsigned int key_length,
unsigned char *iv,
unsigned int direction);
Required hardware support
KMO-DEA
Parameters
const unsigned char *in_data
Pointer to a readable buffer that contains the message to be encrypted or
decrypted. The size of the message in bytes is data_length. The size of this
buffer must be at least as large as data_length.
unsigned char *out_data
Pointer to a writable buffer that contains the resulting encrypted or decrypted
message. The size of this buffer must be at least as large as data_length.
unsigned long data_length
Length in bytes of the message to be encrypted or decrypted, which resides at
the beginning of in_data.
const unsigned char *key
Pointer to a valid DES key of 8 bytes in length.
unsigned char *iv
Pointer to a valid initialization vector of the same size as the cipher block in
bytes (8 bytes for DES). This vector is overwritten during the function. If
data_length is a multiple of the cipher block size (8 bytes for DES), the result
value in iv can be used as the initialization vector for a chained ica_des_ofb
call with the same key.
unsigned int direction
0
Use the decrypt function.
1
Use the encrypt function.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
Compatibility with earlier versions
In order to stay compatible with earlier versions of libica, the following DES
interfaces remain supported:
unsigned int ica_des_encrypt(unsigned int mode,
unsigned int data_length, unsigned char *input_data,
ica_des_vector_t *iv, ica_des_key_single_t *des_key,
unsigned char *output_data);
unsigned int ica_des_decrypt(unsigned int mode,
unsigned int data_length, unsigned char *input_data,
ica_des_vector_t *iv, ica_des_key_single_t *des_key,
unsigned char *output_data);
Table 3 on page 29 shows libica Version 2.0 DES functions calls, and their
corresponding libica Version 2.3.0 DES function calls.
28
libica Programmer's Reference
Table 3. Compatibility of libica Version 2.0 DES functions calls to libica Version 2.3.0 DES function calls
Calling this libica Version 2.0 DES function
Corresponds to calling this libica Version 2.3.0 DES
function
ica_des_encrypt(MODE_ECB, data_length,in_data,NULL,
key, out_data);
ica_des_ecb(in_data,out_data,(long)data_length,
key,1);
ica_des_encrypt(MODE_CBC,data_length,in_data,iv,
key,out_data);
ica_des_cbc(in_data,out_data,(long)data_length,
key,iv,1);
ica_des_decrypt(MODE_ECB,data_length,in_data,NULL,
key,out_data);
ica_des_ecb(in_data,out_data,(long)data_length,
key,0);
ica_des_decrypt(MODE_CBC,data_length,in_data,iv,
key,out_data);
ica_des_cbc(in_data,out_data,(long)data_length,
key,iv,0);
The functions ica_des_encrypt and ica_des_decrypt remain supported, but their
use is discouraged in favor of ica_des_ecb and ica_des_cbc.
For a detailed description of the earlier APIs, see libica Programmers Reference
Version 2.0.
TDES/3DES functions
These functions are included in: include/ica_api.h.
These functions perform encryption and decryption or computation and
verification of message authentication codes using a triple-DES (3DES, TDES or
TDEA) key. A 3DES key consists of a concatenation of three DES keys, each of
which has a size of 8 bytes. Note that each byte of a DES key contains one parity
bit, such that each 64-bit DES key contains only 56 security-relevant bits. The
cipher block size for 3DES is 8 bytes.
3DES is known in two variants: a two key variant and a three key variant. This
library implements only the three key variant. The two key variant can be derived
from functions for the three key variant by using the same key as the first and
third key.
To securely apply 3DES encryption to messages that are longer than the cipher
block size, modes of operation can be used to chain multiple encryption,
decryption, or authentication operations. Most modes of operation require an
initialization vector as additional input. As long as the messages are encrypted or
decrypted using such a mode of operation and have a size that is a multiple of a
particular block size (mostly the cipher block size), the functions encrypting or
decryption according to that mode of operation also compute an output vector that
can be used as the initialization vector of a chained encryption or decryption
operation in the same mode with the same block size and the same key.
Note that when decrypting a cipher text, the mode of operation, the key, the
initialization vector (if applicable), and for ica_3des_cfb the lcfb value used for the
decryption function must match the corresponding settings of the encryption
function that was used to transform the plain text into the cipher text.
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
29
ica_3des_cbc
Purpose
Encrypt or decrypt data with an 3DES key using Cipher Block Chaining (CBC)
mode, as described in NIST Special Publication 800-38A Chapter 6.2.
Format
unsigned int ica_3des_cbc(const unsigned char *in_data,
unsigned char *out_data,
unsigned long data_length,
const unsigned char *key,
unsigned char *iv,
unsigned int direction);
Required hardware support
KMC-TDEA-192
Parameters
const unsigned char *in_data
Pointer to a readable buffer that contains the message to be encrypted or
decrypted. The size of the message in bytes is data_length. The size of this
buffer must be at least as large as data_length.
unsigned char *out_data
Pointer to a writable buffer to contain the resulting encrypted or decrypted
message. The size of this buffer in bytes must be at least as large as data_length.
unsigned long data_length
Length in bytes of the message to be encrypted or decrypted, which resides at
the beginning of in_data. data_length must be a multiple of the cipher block size
(8 bytes for 3DES).
const unsigned char *key
Pointer to a valid 3DES key of 24 bytes in length.
unsigned char *iv
Pointer to a valid initialization vector of cipher block size number of bytes.
This vector is overwritten during the function. The result value in iv can be
used as the initialization vector for a chained ica_3des_cbc or ica_3des_cbc_cs
call with the same key.
unsigned int direction
0
Use the decrypt function.
1
Use the encrypt function.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_3des_cbc_cs
Purpose
Encrypt or decrypt data with a 3DES key using Cipher Block Chaining with
Ciphertext Stealing (CBC-CS) mode, as described in NIST Special Publication
30
libica Programmer's Reference
800-38A Chapter 6.2 and the Addendum to NIST Special Publication 800-38A on
"Recommendation for Block Cipher Modes of Operation: Three Variants of
Ciphertext Stealing for CBC Mode".
ica_3des_cbc_cs can be used to encrypt or decrypt the last chunk of a message
consisting of multiple chunks, where all chinks except the last one are encrypted or
decrypted by chained calls to ica_3des_cbc. To do this, the resulting iv of the last
call to ica_3des_cbc is fed into the iv of the ica_3des_cbc_cs call, provided that the
chunk is greater than the cipher block size (8 bytes for 3DES).
Format
unsigned int ica_3des_cbc_cs(const unsigned char *in_data,
unsigned char *out_data,
unsigned long data_length,
const unsigned char *key,
unsigned char *iv,
unsigned int direction,
unsigned int variant);
Required hardware support
KMC-TDEA-192
Parameters
const unsigned char *in_data
Pointer to a readable buffer that contains the message to be encrypted or
decrypted. The size of the message in bytes is data_length. The size of this
buffer must be at least as large as data_length.
unsigned char *out_data
Pointer to a writable buffer to contain the resulting encrypted or decrypted
message. The size of this buffer in bytes must be at least as large as data_length.
unsigned long data_length
Length in bytes of the message to be encrypted or decrypted, which resides at
the beginning of in_data. data_length must be greater than or equal to the cipher
block size (8 bytes for 3DES).
const unsigned char *key
Pointer to a valid 3DES key of 24 bytes in length.
unsigned char *iv
Pointer to a valid initialization vector of the same size as the cipher block in
bytes. This vector is overwritten during the function. For variant equal to 1 or
variant equal to 2, the result value in iv can be used as the initialization vector
for a chained ica_3des_cbc or ica_3des_cbc_cs call with the same key, if
data_length is a multiple of the cipher block size.
unsigned int direction
0
Use the decrypt function.
1
Use the encrypt function.
unsigned int variant
1
Use variant CBC-CS1 of the Addendum to NIST Special Publication
800-38A to encrypt or decrypt the message: always keep last two
blocks in order.
2
Use variant CBC-CS2 of the Addendum to NIST Special Publication
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
31
800-38A to encrypt or decrypt the message: switch order of the last two
blocks if data_length is not a multiple of the cipher block size (a
multiple of 8 bytes for 3DES).
Use variant CBC-CS3 of the Addendum to NIST Special Publication
800-38A to encrypt or decrypt the message: always switch order of the
last two blocks.
3
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_3des_cfb
Purpose
Encrypt or decrypt data with a 3DES key using Cipher Feedback (CFB) mode, as
described in NIST Special Publication 800-38A Chapter 6.3.
Format
unsigned int ica_3des_cfb(const unsigned char *in_data,
unsigned char *out_data,
unsigned long data_length,
const unsigned char *key,
unsigned char *iv,
unsigned int lcfb,
unsigned int direction);
Required hardware support
KMF-TDEA-192
Parameters
const unsigned char *in_data
Pointer to a readable buffer that contains the message to be encrypted or
decrypted. The size of the message in bytes is data_length. The size of this
buffer must be at least as large as data_length.
unsigned char *out_data
Pointer to a writable buffer to contain the resulting encrypted or decrypted
message. The size of this buffer in bytes must be at least as large as data_length.
unsigned long data_length
Length in bytes of the message to be encrypted or decrypted, which resides at
the beginning of in_data.
const unsigned char *key
Pointer to a valid 3DES key of 24 bytes in length.
unsigned char *iv
Pointer to a valid initialization vector of cipher block size number of bytes (8
bytes for 3DES). This vector is overwritten during the function. The result
value in iv can be used as the initialization vector for a chained ica_3des_cfb
call with the same key, if the data_length in the preceding call is a multiple of
lcfb.
unsigned int lcfb
Length in bytes of the cipher feedback, which is a value greater than or equal
to 1 and less than or equal to the cipher block size (8 bytes for 3DES).
32
libica Programmer's Reference
unsigned int direction
0
Use the decrypt function.
1
Use the encrypt function.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_3des_cmac
Purpose
Authenticate data or verify the authenticity of data with an 3DES key using the
Block Cipher Based Message Authentication Code (CMAC) mode, as described in
NIST Special Publication 800-38B. ica_3des_cmac can be used to authenticate or
verify the authenticity of a complete message.
Format
unsigned int ica_3des_cmac(const unsigned char *message,
unsigned long message_length,
unsigned char *mac,
unsigned int mac_length,
const unsigned char *key,
unsigned int direction);
Required hardware support
KMAC-TDEA-192
PCC-Compute-Last_block-CMAC-Using-TDEA-192
Parameters
const unsigned char *message
Pointer to a readable buffer of size greater than or equal to message_length
bytes. This buffer contains a message to be authenticated, or of which the
authenticity is to be verified.
unsigned long message_length
Length in bytes of the message to be authenticated or verified.
unsigned char *mac
Pointer to a buffer of size greater than or equal to mac_length bytes. If direction
is equal to 1, the buffer must be writable and a message authentication code
for the message in message of size mac_length bytes is written to the buffer. If
direction is equal to 0, the buffer must be readable and contain a message
authentication code to be verified against the message in message.
unsigned int mac_length
Length in bytes of the message authentication code mac, which is less than or
equal to the cipher block size (8 bytes for 3DES). It is recommended to use a
mac_length of 8.
const unsigned char *key
Pointer to a valid 3DES key of 24 bytes in length.
unsigned int direction
0
Verify message authentication code.
1
Compute message authentication code for the message.
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
33
Return codes
0
Success
EFAULT
If direction is equal to 0 and the verification of the message authentication
code fails.
For return codes indicating exceptions, see “Return codes” on page 70.
ica_3des_cmac_intermediate
Purpose
Authenticate data or verify the authenticity of data with an 3DES key using the
Block Cipher Based Message Authentication Code (CMAC) mode, as described in
NIST Special Publication 800-38B. ica_3des_cmac_intermediate and
ica_3des_cmac_last can be used when the message to be authenticated or to be
verified using CMAC is supplied in multiple chunks. ica_3des_cmac_intermediate
is used to process all but the last chunk. All message chunks to be processed by
ica_3des_cmac_intermediate must have a size that is a multiple of the cipher block
size (a multiple of 8 bytes for 3DES).
Note that ica_3des_cmac_intermediate has no direction argument. This function
can be used during authentication and during authenticity verification.
Format
unsigned int ica_3des_cmac_intermediate(const unsigned char *message,
unsigned long message_length,
const unsigned char *key,
unsigned char *iv);
Required hardware support
KMAC-TDEA-192
Parameters
const unsigned char *message
Pointer to a readable buffer of size greater than or equal to message_length
bytes. This buffer contains a non-final part of a message to be authenticated, or
of which the authenticity is to be verified.
unsigned long message_length
Length in bytes of the message part in message. This value must be a multiple
of the cipher block size.
const unsigned char *key
Pointer to a valid 3DES key of 24 bytes in length.
unsigned char *iv
Pointer to a valid initialization vector of size cipher block size (8 bytes for
3DES). For the first message part, this parameter must be set to a string of
zeros. For processing the n-th message part, this parameter must be the
resulting iv value of the ica_3des_cmac_intermediate applied to the (n-1)-th
message part. This vector is overwritten during the function. The result value
in iv can be used as the initialization vector for a chained call to
ica_3des_cmac_initermediate or to ica_3des_cmac_last with the same key.
Return codes
0
34
libica Programmer's Reference
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_3des_cmac_last
Purpose
Authenticate data or verify the authenticity of data with an 3DES key using the
Block Cipher Based Message Authentication Code (CMAC) mode, as described in
NIST Special Publication 800-38B. ica_3des_cmac_last can be used to authenticate
or verify the authenticity of a complete message or of the final part of a message,
for which all preceding parts were processed with ica_3des_cmac_intermediate.
Format
unsigned int ica_3des_cmac_last(const unsigned char *message,
unsigned long message_length,
unsigned char *mac,
unsigned int mac_length,
const unsigned char *key,
unsigned char *iv,
unsigned int direction);
Required hardware support
KMAC-TDEA,-192
PCC-Compute-Last_block-CMAC-Using-TDEA-192
Parameters
const unsigned char *message
Pointer to a readable buffer of size greater than or equal to message_length
bytes. It contains a message or the final part of a message to be authenticated,
or of which the authenticity is to be verified.
unsigned long message_length
Length in bytes of the message to be authenticated or verified.
unsigned char *mac
Pointer to a buffer of size greater than or equal to mac_length bytes. If direction
is equal to 1, the buffer must be writable and a message authentication code
for the message in message of size mac_length bytes is written to the buffer. If
direction is equal to 0, the buffer must be readable and contain a message
authentication code that is to be verified against the message in message.
unsigned int mac_length
Length in bytes of the message authentication code mac in bytes that is less
than or equal to the cipher block size (8 bytes for 3DES). It is recommended to
use a mac_length of 8.
const unsigned char *key
Pointer to a valid 3DES key of 24 bytes in length.
unsigned char *iv
Pointer to a valid initialization vector of cipher block size number of bytes. If
iv is NULL, message is assumed to be the complete message to be processed.
Otherwise, message is the final part of a composite message to be processed
and iv contains the output vector resulting from processing all previous parts
with chained calls to ica_des_cmac_intermediate (the value returned in iv of
the ica_des_cmac_intermediate call applied to the penultimate message part.
unsigned int direction
0
Verify message authentication code.
1
Compute message authentication code for the message.
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
35
Return codes
0
Success
EFAULT
If direction is equal to 0 and the verification of the message authentication
code fails.
For return codes indicating exceptions, see “Return codes” on page 70.
ica_3des_ctr
Purpose
Encrypt or decrypt data with a triple-length DES key using Counter (CTR) mode,
as described in NIST Special Publication 800-38A Chapter 6.5. With the counter
mode, each message block of size cipher block size (8 bytes for 3DES) is combined
with a counter value of the same size during encryption and decryption.
Starting with an initial counter value to be combined with the first message block,
subsequent counter values to be combined with subsequent message blocks are
derived from preceding counter values by an increment function. The increment
function used in ica_3des_ctr is an arithmetic increment without carry on the M
least significant bytes in the counter, where M is a parameter to ica_3des_ctr.
Format
unsigned int ica_3des_ctr(const unsigned char *in_data,
unsigned char *out_data,
unsigned long data_length,
const unsigned char *key,
unsigned char *ctr,
unsigned int ctr_width,
unsigned int direction);
Required hardware support
KMCTR-TDEA-192
Parameters
const unsigned char *in_data
Pointer to a readable buffer that contains the message to be encrypted or
decrypted. The size of the message in bytes is data_length. The size of this
buffer must be at least as large as data_length.
unsigned char *out_data
Pointer to a writable buffer to contain the resulting encrypted or decrypted
message. The size of this buffer in bytes must be at least as large as data_length.
unsigned long data_length
Length in bytes of the message to be encrypted or decrypted, which resides at
the beginning of in_data.
const unsigned char *key
Pointer to a valid 3DES key of 24 bytes in length.
unsigned char *ctr
Pointer to a readable and writable buffer of the same size as the cipher block
in bytes. ctr contains an initialization value for a counter function that is
replaced by a new value. The new value can be used as an initialization value
for a counter function in a chained ica_3des_ctr call with the same key, if the
data_length used in the preceding call is a multiple of the cipher block size.
36
libica Programmer's Reference
unsigned int ctr_width
A number M between 1 and the cipher block size. The value is used by the
counter increment function, which increments a counter value by incrementing
without carry the least significant M bytes of the counter value.
unsigned int direction
0
Use the decrypt function.
1
Use the encrypt function.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_3des_ctrlist
Purpose
Encrypt or decrypt data with an 3DES key using Counter (CTR) mode, as
described in NIST Special Publication 800-38A ,Chapter 6.5. With the counter
mode, each message block of the same size as the cipher block is combined with a
counter value of the same size during encryption and decryption.
The ica_3des_ctrlist function assumes that a list n of precomputed counter values
is provided where n is the smallest integer that is less than or equal to the message
size divided by the cipher block size. This function is used to optimally utilize IBM
System z hardware support for non-standard counter functions.
Format
unsigned int ica_3des_ctrlist(const unsigned char *in_data,
unsigned char *out_data,
unsigned long data_length,
const unsigned char *key,
const unsigned char *ctrlist,
unsigned int direction);
Required hardware support
KMCTR-TDEA-192
Parameters
const unsigned char *in_data
Pointer to a readable buffer that contains the message to be encrypted or
decrypted. The size of the message in bytes is data_length. The size of this
buffer must be at least as large as data_length.
unsigned char *out_data
Pointer to a writable buffer to contain the resulting encrypted or decrypted
message. The size of this buffer in bytes must be at least as large as data_length.
unsigned long data_length
Length in bytes of the message to be encrypted or decrypted, which resides at
the beginning of in_data.
Calls to ica_3des_ctrlist with the same key can be chained if:
v With the possible exception of the last call in the chain the data_length used
is a multiple of the cipher block size.
v The ctrlist argument of each chained call contains a list of counters that
follows the counters used in the preceding call.
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
37
const unsigned char *key
Pointer to a valid 3DES key of 24 bytes in length.
const unsigned char *ctrlist
Pointer to a readable buffer that is both of size greater than or equal to
data_length, and a multiple of the cipher block size (8 bytes for 3DES). ctrlist
should contain a list of precomputed counter values, each of the same size as
the cipher block.
unsigned int direction
0
Use the decrypt function.
1
Use the encrypt function.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_3des_ecb
Purpose
Encrypt or decrypt data with an 3DES key using Electronic Code Book (ECB)
mode, as described in NIST Special Publication 800-38A Chapter 6.1.
Format
unsigned int ica_3des_ecb(const unsigned char *in_data,
unsigned char *out_data,
unsigned long data_length,
const unsigned char *key,
unsigned int direction);
Required hardware support
KM-DEA-192
Parameters
const unsigned char *in_data
Pointer to a readable buffer that contains the message to be encrypted or
decrypted. The size of the message in bytes is data_length. The size of this
buffer must be at least as large as data_length.
unsigned char *out_data
Pointer to a writeable buffer to contain the resulting encrypted or decrypted
message. The size of this buffer in bytes must be at least as large as data_length.
unsigned long data_length
Length in bytes of the message to be encrypted or decrypted, which resides at
the beginning of in_data. data_length must be a multiple of the cipher block size
(8 bytes for 3DES).
const unsigned char *key
Pointer to a valid 3DES key of 24 bytes in length.
unsigned int direction
0
Use the decrypt function.
1
Use the encrypt function.
38
libica Programmer's Reference
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_3des_ofb
Purpose
Encrypt or decrypt data with an 3DES key using Output Feedback (OFB) mode, as
described in NIST Special Publication 800-38A Chapter 6.4.
Format
unsigned int ica_3des_ofb(const unsigned char *in_data,
unsigned char *out_data,
unsigned long data_length,
const unsigned char *key,
unsigned int key_length,
unsigned char *iv,
unsigned int direction);
Required hardware support
KMO-TDEA-192
Parameters
const unsigned char *in_data
Pointer to a readable buffer that contains the message to be encrypted or
decrypted. The size of the message in bytes is data_length. The size of this
buffer must be at least as large as data_length.
unsigned char *out_data
Pointer to a writable buffer that contains the resulting encrypted or decrypted
message. The size of this buffer in bytes must be at least as large as data_length.
unsigned long data_length
Length in bytes of the message to be encrypted or decrypted, which resides at
the beginning of in_data.
const unsigned char *key
Pointer to a valid 3DES key of 24 bytes in length.
unsigned char *iv
Pointer to a valid initialization vector of the same size as the cipher block in
bytes (8 bytes for 3DES). This vector is overwritten during the function. If
data_length is a multiple of the cipher block size (a multiple of 8 for 3DES), the
result value in iv can be used as the initialization vector for a chained
ica_3des_ofb call with the same key.
unsigned int direction
0
Use the decrypt function.
1
Use the encrypt function.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
39
Compatibility with earlier versions
In order to stay compatible with earlier versions of libica, the following 3DES
interfaces remain supported:
unsigned int ica_3des_encrypt(unsigned int mode,
unsigned int data_length, unsigned char *input_data,
ica_des_vector_t *iv, ica_des_key_triple_t *des_key,
unsigned char *output_data);
unsigned int ica_3des_decrypt(unsigned int mode,
unsigned int data_length, unsigned char *input_data,
ica_des_vector_t *iv, ica_des_key_triple_t *des_key,
unsigned char *output_data);
Table 4 shows libica Version 2.0 TDES functions calls, and their corresponding
libica Version 2.3.0 TDES function calls.
Table 4. Compatibility of libica Version 2.0 TDES functions calls to libica Version 2.3.0 TDES function calls
Calling this libica Version 2.0 TDES function
Corresponds to calling this libica Version 2.3.0 TDES
function
ica_3des_encrypt(MODE_ECB, data_length,in_data,NULL, ica_3des_ecb(in_data,out_data,(long)data_length,
key, out_data);
key,1);
ica_3des_encrypt(MODE_CBC,data_length,in_data,iv,
key,out_data);
ica_3des_cbc(in_data,out_data,(long)data_length,
key,iv,1);
ica_3des_decrypt(MODE_ECB,data_length,in_data,NULL,
key,out_data);
ica_3des_ecb(in_data,out_data,(long)data_length,
key,0);
ica_3des_decrypt(MODE_CBC,data_length,in_data,iv,
key,out_data);
ica_3des_cbc(in_data,out_data,(long)data_length,,
key,iv,0);
The functions ica_3des_encrypt and ica_3des_decrypt remain supported, but their
use is discouraged in favor of ica_3des_ecb and ica_3des_cbc.
For a detailed description of the earlier APIs, see libica Programmers Reference
Version 2.0.
AES functions
These functions are included in: include/ica_api.h.
These functions perform encryption and decryption or computation or verification
of message authentication codes using an AES key. Supported key lengths are 16,
24 or 32 bytes for AES-128, AES-192 and AES-256 respectively. The cipher block
size for AES is 16 bytes.
To securely apply AES encryption to messages that are longer than the cipher
block size, modes of operation can be used to chain multiple encryption,
decryption, or authentication operations. Most modes of operation require an
initialization vector as additional input.
As long as the messages are encrypted or decrypted using such a mode of
operation, have a size that is a multiple of a particular block size (mostly the
cipher block size), the functions encrypting or decryption according to a mode of
operation also compute an output vector. The output vector can be used as the
initialization vector of a chained encryption or decryption operation in the same
mode with the same block size and the same key.
40
libica Programmer's Reference
Note that when decrypting a cipher text the mode of operation, the key, the
initialization vector (if applicable), and for ica_aes_cfb the lcfb value used for the
decryption function must match the corresponding settings of the encryption
function that transformed the plain text into the cipher text.
ica_aes_cbc
Purpose
Encrypt or decrypt data with an AES key using Cipher Block Chaining (CBC)
mode, as described in NIST Special Publication 800-38A Chapter 6.2.
Format
unsigned int ica_aes_cbc(const unsigned char *in_data,
unsigned char *out_data,
unsigned long data_length,
const unsigned char *key,
unsigned int key_length,
unsigned char *iv,
unsigned int direction);
Required hardware support
KMC-AES-128, KMC-AES-192, or KMC-AES-256
Parameters
const unsigned char *in_data
Pointer to a readable buffer that contains the message to be encrypted or
decrypted. The size of the message in bytes is data_length. The size of this
buffer must be at least as large as data_length.
unsigned char *out_data
Pointer to a writable buffer to contain the resulting encrypted or decrypted
message. The size of this buffer in bytes must be at least as large as data_length.
unsigned long data_length
Length in bytes of the message to be encrypted or decrypted, which resides at
the beginning of in_data. data_length must be a multiple of the cipher block size
(a multiple of 16 for AES).
const unsigned char *key
Pointer to a valid AES key.
unsigned int key_length
Length in bytes of the AES key. Supported sizes are 16, 24, and 32, for
AES-128, AES-192, and AES-256 respectively. Therefore, you can use the
definitions: AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
unsigned char *iv
Pointer to a valid initialization vector of the same size as the cipher block in
bytes. This vector is overwritten during the function. The result value in iv can
be used as the initialization vector for a chained ica_aes_cbc or ica_aes_cbc_cs
call with the same key.
unsigned int direction
0
Use the decrypt function.
1
Use the encrypt function.
Return codes
0
Success
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
41
For return codes indicating exceptions, see “Return codes” on page 70.
ica_aes_cbc_cs
Purpose
Encrypt or decrypt data with an AES key using Cipher Block Chaining with
Ciphertext Stealing (CBC-CS) mode, as described in NIST Special Publication
800-38A Chapter 6.2, and the Addendum to NIST Special Publication 800-38A on
"Recommendation for Block Cipher Modes of Operation: Three Variants of
Ciphertext Stealing for CBC Mode".
ica_aes_cbc_cs can be used to encrypt or decrypt the last chunk of a message
consisting of multiple chunks, where all chunks except the last one are encrypted
or decrypted by chained calls to ica_aes_cbc. To do this, the resulting iv of the last
call to ica_aes_cbc is fed into the iv of the ica_aes_cbc_cs call, provided that the
chunk is greater than the cipher block size (greater than 16 bytes for AES).
Format
unsigned int ica_aes_cbc_cs(const unsigned char *in_data,
unsigned char *out_data,
unsigned long data_length,
const unsigned char *key,
unsigned int key_length,
unsigned char *iv,
unsigned int direction,
unsigned int variant);
Required hardware support
KMC-AES-128, KMC-AES-192 or KMC-AES-256
Parameters
const unsigned char *in_data
Pointer to a readable buffer that contains the message to be encrypted or
decrypted. The size of the message in bytes is data_length. The size of this
buffer must be at least as large as data_length.
unsigned char *out_data
Pointer to a writable buffer to contain the resulting encrypted or decrypted
message. The size of this buffer in bytes must be at least as large as data_length.
unsigned long data_length
Length in bytes of the message to be encrypted or decrypted, which resides at
the beginning of in_data. data_length must be greater than or equal to the cipher
block size (16 bytes for AES).
const unsigned char *key
Pointer to a valid AES key.
unsigned int key_length
Length in bytes of the AES key. Supported sizes are 16, 24, and 32, for
AES-128, AES-192, and AES-256 respectively. . Therefore, you can use the
definitions: AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
unsigned char *iv
Pointer to a valid initialization vector of cipher block size number of bytes.
This vector is overwritten during the function. For variant equal to 1 or variant
42
libica Programmer's Reference
equal to 2, the result value in iv can be used as the initialization vector for a
chained ica_aes_cbc or ica_aes_cbc_cs call with the same key, if data_length is a
multiple of the cipher block size.
unsigned int direction
0
Use the decrypt function.
1
Use the encrypt function.
unsigned int variant
1
Use variant CBC-CS1 of the Addendum to NIST Special Publication
800-38A to encrypt or decrypt the message: always keep last two
blocks in order.
2
Use variant CBC-CS2 of the Addendum to NIST Special Publication
800-38A to encrypt or decrypt the message: switch order of the last two
blocks if data_length is not a multiple of the cipher block size (a
multiple of 16 bytes for AES).
3
Use variant CBC-CS3 of the Addendum to NIST Special Publication
800-38A to encrypt or decrypt the message: always switch order of the
last two blocks.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_aes_ccm
Purpose
Encrypt and authenticate or decrypt data and check authenticity of data with an
AES key using Counter with Cipher Block Chaining Message Authentication Code
(CCM) mode, as described in NIST Special Publication 800-38C. Formatting and
counter functions are implemented according to NIST 800-38C Appendix A.
Format
unsigned int ica_aes_ccm(unsigned char *payload,
unsigned long payload_length,
unsigned char *ciphertext_n_mac,
unsigned int mac_length,
const unsigned char *assoc_data,
unsigned long assoc_data_length,
const unsigned char *nonce,
unsigned int nonce_length,
const unsigned char *key,
unsigned int key_length,
unsigned int direction);
Required hardware support
KMCTR-AES-128, KMCTR-AES-192, or KMCTR-AES-256
KMAC-AES-128, KMAC-AES-192, or KMAC-AES-256
Parameters
unsigned char *payload
Pointer to a buffer of size greater than or equal to payload_length bytes. If
direction is equal to 1, the payload buffer must be readable and contain a
payload message of size payload_length to be encrypted. If direction is equal to
0, the payload buffer must be writable. If the authentication verification
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
43
succeeds, the decrypted message in the most significant payload_length bytes of
ciphertext_n_mac is written to this buffer. Otherwise, the contents of this buffer
is undefined.
unsigned long payload_length
Length in bytes of the message to be encrypted or decrypted. This value can be
0 unless assoc_data_length is equal to 0.
unsigned char *ciphertext_n_mac
Pointer to a buffer of size greater than or equal to payload_length plus
mac_length bytes. If direction is equal to 1, the buffer must be writable and the
encrypted message from payload followed by the message authentication code
for the nonce, the payload, and associated data are written to that buffer. If
direction is equal to 0, then the buffer is readable and contains an encrypted
message of length payload_length followed by a message authentication code of
length mac_length.
unsigned int mac_length
Length in bytes of the message authentication code. Valid values are: 4, 6, 8,
10, 12, and 16.
const unsigned char *assoc_data
Pointer to a readable buffer of size greater than or equal to assoc_data_length
bytes. The associated data in the most significant assoc_data_length bytes is
subject to the authentication code computation, but is not encrypted.
unsigned long assoc_data_length
Length of the associated data in assoc_data. This value can be 0 unless
payload_length is equal to 0.
const unsigned char *nonce
Pointer to readable buffer of size greater than or equal to nonce_length bytes,
which contains a nonce (number used once) of size nonce_length bytes.
unsigned int nonce_length
Length of the nonce in bytes. Valid values are greater than 6 and less than 14.
const unsigned char *key
Specifies a pointer to a valid AES key.
unsigned int key_length
Length in bytes of the AES key. Supported sizes are 16, 24, and 32 for AES-128,
AES-192 and AES-256 respectively. Therefore, you can use the definitions:
AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
unsigned int direction
0
Use the decrypt function.
1
Use the encrypt function.
Return codes
0
Success
EFAULT
If direction is equal to 0 and the verification of the message authentication
code fails.
For return codes indicating exceptions, see “Return codes” on page 70.
44
libica Programmer's Reference
ica_aes_cfb
Purpose
Encrypt or decrypt data with an AES key using Cipher Feedback (CFB) mode, as
described in NIST Special Publication 800-38A Chapter 6.3.
Format
unsigned int ica_aes_cfb(const unsigned char *in_data,
unsigned char *out_data,
unsigned long data_length,
const unsigned char *key,
unsigned int key_length,
unsigned char *iv,
unsigned int lcfb,
unsigned int direction);
Required hardware support
KMF-AES-128, KMF-AES-192, or KMF-AES-256
Parameters
const unsigned char *in_data
Pointer to a readable buffer that contains the message to be encrypted or
decrypted. The size of the message in bytes is data_length. The size of this
buffer must be at least as large as data_length.
unsigned char *out_data
Pointer to a writable buffer to contain the resulting encrypted or decrypted
message. The size of this buffer in bytes must be at least as large as data_length.
unsigned long data_length
Length in bytes of the message to be encrypted or decrypted, which resides at
the beginning of in_data.
const unsigned char *key
Pointer to a valid AES key.
unsigned int key_length
Length in bytes of the AES key. Supported sizes are 16, 24, and 32, for
AES-128, AES-192, and AES-256 respectively. Therefore, you can use the
definitions: AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
unsigned char *iv
Pointer to a valid initialization vector of the same size as the cipher block in
bytes (16 bytes for AES). This vector is overwritten during the function. The
result value in iv can be used as the initialization vector for a chained
ica_aes_cfb call with the same key, if the data_length in the preceding call is a
multiple of lcfb.
unsigned int lcfb
Length in bytes of the cipher feedback, which is a value greater than or equal
to 1 and less than or equal to the cipher block size (16 bytes for AES).
unsigned int direction
0
Use the decrypt function.
1
Use the encrypt function.
Return codes
0
Success
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
45
For return codes indicating exceptions, see “Return codes” on page 70.
ica_aes_cmac
Purpose
Authenticate data or verify the authenticity of data with an AES key using the
Block Cipher Based Message Authentication Code (CMAC) mode, as described in
NIST Special Publication 800-38B. ica_aes_cmac can be used to authenticate or
verify the authenticity of a complete message.
Format
unsigned int ica_aes_cmac(const unsigned char *message,
unsigned long message_length,
unsigned char *mac,
unsigned int mac_length,
const unsigned char *key,
unsigned int key_length,
unsigned int direction);
Required hardware support
KMAC-AES-128, KMAC-AES-192 or KMAC-AES-256
PCC-Compute-Last_block-CMAC-Using-AES-128, PCC-Compute-Last_blockCMAC-Using-AES-192, or PCC-Compute-Last_block-CMAC-Using-AES-256
Parameters
const unsigned char *message
Pointer to a readable buffer of size greater than or equal to message_length
bytes. This buffer contains a message to be authenticated, or of which the
authenticity is to be verified.
unsigned long message_length
Length in bytes of the message to be authenticated or verified.
unsigned char *mac
Pointer to a buffer of size greater than or equal to mac_length bytes. If direction
is equal to 1, the buffer must be writable and a message authentication code
for the message in message of size mac_length bytes is written to this buffer. If
direction is equal to 0, this buffer must be readable and contain a message
authentication code to be verified against the message in message.
unsigned int mac_length
Length in bytes of the message authentication code mac in bytes, which is less
than or equal to the cipher block size (16 bytes for AES). It is recommended to
use values greater than or equal to 8.
const unsigned char *key
Pointer to a valid AES key.
unsigned int key_length
Length in bytes of the AES key. Supported sizes are 16, 24, and 32 for AES-128,
AES-192, and AES-256 respectively. Therefore, you can use the definitions:
AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
unsigned int direction
0
Verify message authentication code.
1
Compute message authentication code for the message.
Return codes
0
46
libica Programmer's Reference
Success
EFAULT
If direction is equal to 0 and the verification of the message authentication
code fails.
For return codes indicating exceptions, see “Return codes” on page 70.
ica_aes_cmac_intermediate
Purpose
Authenticate data or verify the authenticity of data with an AES key using the
Block Cipher Based Message Authentication Code (CMAC) mode, as described in
NIST Special Publication 800-38B. ica_aes_cmac_intermediate and
ica_aes_cmac_last can be used when the message to be authenticated or to be
verified using CMAC is supplied in multiple chunks. ica_aes_cmac_intermediate is
used to process all but the last chunk. All message chunks to be processed by
ica_aes_cmac_intermediate must have a size that is a multiple of the cipher block
size (a multiple of 16 bytes for AES).
Note that ica_aes_cmac_intermediate has no direction argument. This function can
be used during authentication and during authenticity verification.
Format
unsigned int ica_aes_cmac_intermediate(const unsigned char *message,
unsigned long message_length,
const unsigned char *key,
unsigned int key_length,
unsigned char *iv);
Required hardware support
KMAC-AES-128, KMAC-AES-192, or KMAC-AES-256
Parameters
const unsigned char *message
Pointer to a readable buffer of size greater than or equal to message_length
bytes. This buffer contains a non-final part of a message, to be authenticated or
of which the authenticity is to be verified.
unsigned long message_length
Length in bytes of the message part in message. This value must be a multiple
of the cipher block size.
const unsigned char *key
Pointer to a valid AES key.
unsigned int key_length
Length in bytes of the AES key. Supported sizes are 16, 24, and 32 for AES-128,
AES-192, and AES-256 respectively. Therefore, you can use the definitions:
AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
unsigned char *iv
Pointer to a valid initialization vector of cipher block size number of bytes (16
bytes for AES). For the first message part, this parameter must be set to a
string of zeros. For processing the n-th message part, this parameter must be
the resulting iv value of the ica_aes_cmac_intermediate function applied to the
(n-1)-th message part. This vector is overwritten during the function. The result
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
47
value in iv can be used as the initialization vector for a chained call to
ica_aes_cmac_initermediate or to ica_aes_cmac_last with the same key.
Return codes
Success
0
For return codes indicating exceptions, see “Return codes” on page 70.
ica_aes_cmac_last
Purpose
Authenticate data or verify the authenticity of data with an AES key using the
Block Cipher Based Message Authentication Code (CMAC) mode, as described in
NIST Special Publication 800-38B. ica_aes_cmac_last can be used to authenticate or
verify the authenticity of a complete message, or of the final part of a message for
which all preceding parts were processed with ica_aes_cmac_intermediate.
Format
unsigned int ica_aes_cmac_last(const unsigned char *message,
unsigned long message_length,
unsigned char *mac,
unsigned int mac_length,
const unsigned char *key,
unsigned int key_length,
unsigned char *iv,
unsigned int direction);
Required hardware support
KMAC-AES-128, KMAC-AES-192 or KMAC-AES-256
PCC-Compute-Last_block-CMAC-Using-AES-128, PCC-Compute-Last_blockCMAC-Using-AES-192, or PCC-Compute-Last_block-CMAC-Using-AES-256
Parameters
const unsigned char *message
Pointer to a readable buffer of size greater than or equal to message_length
bytes. This buffer contains a message or the final part of a message to be
authenticated, or of which the authenticity is to be verified.
unsigned long message_length
Length in bytes of the message to be authenticated or verified.
unsigned char *mac
Pointer to a buffer of size greater than or equal to mac_length bytes. If direction
is equal to 1, the buffer must be writable and a message authentication code
for the message in message of size mac_length bytes is written to the buffer. If
direction is equal to 0, the buffer must be readable and contain a message
authentication code that is verified against the message in message.
unsigned int mac_length
Length in bytes of the message authentication code mac in bytes, which is less
than or equal to the cipher block size (16 bytes for AES). It is recommended to
use values greater than or equal to 8.
const unsigned char *key
Pointer to a valid AES key.
unsigned int key_length
Length in bytes of the AES key. Supported sizes are 16, 24, and 32 for AES-128,
48
libica Programmer's Reference
AES-192, and AES-256 respectively. Therefore, you can use the definitions:
AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
unsigned char *iv
Pointer to a valid initialization vector of cipher block size number of bytes. If
iv is NULL, message is assumed to be the complete message to be processed.
Otherwise, message is the final part of a composite message to be processed,
and iv contains the output vector resulting from processing all previous parts
with chained calls to ica_aes_cmac_intermediate (the value returned in iv of
the ica_aes_cmac_intermediate call applied to the penultimate message part).
unsigned int direction
0
Verify message authentication code.
1
Compute message authentication code for the message.
Return codes
0
Success
EFAULT
If direction is equal to 0 and the verification of the message authentication
code fails.
For return codes indicating exceptions, see “Return codes” on page 70.
ica_aes_ctr
Purpose
Encrypt or decrypt data with an AES key using Counter (CTR) mode, as described
in NIST Special Publication 800-38A Chapter 6.5. With the counter mode, each
message block of size cipher block size (16 bytes for AES) is combined with a
counter value of the same size during encryption and decryption.
Starting with an initial counter value to be combined with the first message block,
subsequent counter values to be combined with subsequent message blocks are
derived from preceding counter values by an increment function. The increment
function used in ica_aes_ctr is an arithmetic increment without carry on the M
least significant bytes in the counter where M is a parameter to ica_aes_ctr.
Format
unsigned int ica_aes_ctr(const unsigned char *in_data,
unsigned char *out_data,
unsigned long data_length,
const unsigned char *key,
unsigned int key_length,
unsigned char *ctr,
unsigned int ctr_width,
unsigned int direction);
Required hardware support
KMCTR-AES-128, KMCTR-AES-192, or KMCTR-AES-256
Parameters
const unsigned char *in_data
Pointer to a readable buffer that contains the message to be encrypted or
decrypted. The size of the message in bytes is data_length. The size of this
buffer must be at least as large as data_length.
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
49
unsigned char *out_data
Pointer to a writable buffer to contain the resulting encrypted or decrypted
message. The size of this buffer in bytes must be at least as large as data_length.
unsigned long data_length
Length in bytes of the message to be encrypted or decrypted, which resides at
the beginning of in_data.
const unsigned char *key
Pointer to a valid AES key.
unsigned int key_length
Length in bytes of the AES key. Supported sizes are 16, 24, and 32 for AES-128,
AES-192, and AES-256 respectively. Therefore, you can use the definitions:
AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
unsigned char *ctr
Pointer to a readable and writable buffer of the same size as the cipher block
in bytes. ctr contains an initialization value for a counter function, and it is
replaced by a new value. That new value can be used as an initialization value
for a counter function in a chained ica_aes_ctr call with the same key, if the
data_length used in the preceding call is a multiple of the cipher block size.
unsigned int ctr_width
A number M between 1 and the cipher block size. The value is used by the
counter increment function, which increments a counter value by incrementing
without carry the least significant M bytes of the counter value.
unsigned int direction
0
Use the decrypt function.
1
Use the encrypt function.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_aes_ctrlist
Purpose
Encrypt or decrypt data with an AES key using Counter (CTR) mode, as described
in NIST Special Publication 800-38A ,Chapter 6.5. With the counter mode, each
message block of the same size as the cipher block in bytes is combined with a
counter value of the same size during encryption and decryption.
The ica_aes_ctrlist function assumes that a list n of precomputed counter values is
provided, where n is the smallest integer that is less than or equal to the message
size divided by the cipher block size. This function optimally uses IBM System z
hardware support for non-standard counter functions.
Format
unsigned int ica_aes_ctrlist(const unsigned char *in_data,
unsigned char *out_data,
unsigned long data_length,
const unsigned char *key,
unsigned int key_length,
const unsigned char *ctrlist,
unsigned int direction);
50
libica Programmer's Reference
Required hardware support
KMCTR-DEAKMCTR-AES-128, KMCTR-AES-192, or KMCTR-AES-256
Parameters
const unsigned char *in_data
Pointer to a readable buffer that contains the message to be encrypted or
decrypted. The size of the message in bytes is data_length. The size of this
buffer must be at least as large as data_length.
unsigned char *out_data
Pointer to a writable buffer to contain the resulting encrypted or decrypted
message. The size of this buffer in bytes must be at least as large as data_length.
unsigned long data_length
Length in bytes of the message to be encrypted or decrypted, which resides at
the beginning of in_data.
Calls to ica_aes_ctrlist with the same key can be chained if:
v With the possible exception of the last call in the chain the data_length used
is a multiple of the cipher block size.
v The ctrlist argument of each chained call contains a list of counters that
follows the counters used in the preceding call.
const unsigned char *key
Pointer to a valid AES key.
unsigned int key_length
Length in bytes of the AES key. Supported sizes are 16, 24, and 32 for AES-128,
AES-192, and AES-256 respectively. Therefore, you can use the definitions:
AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
const unsigned char *ctrlist
Pointer to a readable buffer that is both of a size greater than or equal to
data_length, and a multiple of the cipher block size (16 bytes for AES). ctrlist
should contain a list of precomputed counter values, each of the same size as
the cipher block.
unsigned int direction
0
Use the decrypt function.
1
Use the encrypt function.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_aes_ecb
Purpose
Encrypt or decrypt data with an AES key using Electronic Code Book (ECB) mode,
as described in NIST Special Publication 800-38A Chapter 6.1.
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
51
Format
unsigned int ica_aes_ecb(const unsigned char *in_data,
unsigned char *output,
unsigned int data_length,
const unsigned char *key,
unsigned int key_length,
unsigned int direction);
Required hardware support
KM-AES-128, KM-AES-192, or KM-AES-256
Parameters
const unsigned char *in_data
Pointer to a readable buffer that contains the message to be encrypted or
decrypted. The size of the message in bytes is data_length. The size of this
buffer must be at least as large as data_length.
unsigned char *out_data
Pointer to a writable buffer to contain the resulting encrypted or decrypted
message. The size of this buffer in bytes must be at least as large as data_length.
unsigned long data_length
Length in bytes of the message to be encrypted or decrypted, which resides at
the beginning of in_data. data_length must be a multiple of the cipher block size
(a multiple of 16 for AES).
const unsigned char *key
Pointer to a valid AES key.
unsigned int key_length
Length in bytes of the AES key. Supported sizes are 16, 24, and 32 for AES-128,
AES-192, and AES-256 respectively. Therefore, you can use the definitions:
AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
unsigned int direction
0
Use the decrypt function.
1
Use the encrypt function.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
ica_aes_gcm
Purpose
Encrypt data and authenticate data or decrypt data and check authenticity of data
with an AES key using the Galois/Counter (GCM) mode, as described in NIST
Special Publication 800-38D. If no message needs to be encrypted or decrypted and
only authentication or authentication checks are requested, then this method
implements the GMAC mode.
Format
unsigned int ica_aes_gcm(unsigned char *plaintext,
unsigned long plaintext_length,
unsigned char *ciphertext,
const unsigned char *iv,
unsigned int iv_length,
52
libica Programmer's Reference
const unsigned char *aad,
unsigned long aad_length,
unsigned char *tag,
unsigned int tag_length,
const unsigned char *key,
unsigned int key_length,
unsigned int direction);
Required hardware support
KM-AES-128, KM-AES-192 or KM-AES-256
KIMD-GHASH
KMCTR-AES-128, KMCTR_AES-192 or KMCTR-AES-256
Parameters
unsigned char *plaintext
Pointer to a buffer of size greater than or equal to plaintext_length bytes. If
direction is equal to 1, the plaintext buffer must be readable and contain a
payload message of size plaintext_length to be encrypted. If direction is equal to
0, the plaintext buffer must be writable and if the authentication verification
succeeds, the decrypted message in the most significant plaintext_length bytes
of ciphertext is written to the buffer. Otherwise, the contents of the buffer are
undefined.
unsigned long plaintext_length
Length in bytes of the message to be encrypted or decrypted. This value can be
0 unless aad_length is equal to 0. The value must be greater than or equal to 0
and less than (2**36) - 32.
unsigned char *ciphertext
Pointer to a buffer of size greater than or equal to plaintext_length bytes. If
direction is equal to 1, then this buffer must be writable and the encrypted
message from plaintext is written to that buffer. If direction is equal to 0, then
this buffer is readable and contains an encrypted message of length
plaintext_length.
const unsigned char *iv
Pointer to a readable buffer of size greater than or equal to iv_length bytes,
which contains an initialization vector of size iv_length.
unsigned int iv_length
Length in bytes of the initialization vector in iv. The value must be greater
than 0 and less than 2**61. A length of 12 is recommended.
const unsigned char *aad
Pointer to a readable buffer of size greater than or equal to aad_length bytes.
The additional authenticated data in the most significant aad_length bytes is
subject to the message authentication code computation, but is not encrypted.
unsigned int aad_length
Length in bytes of the additional authenticated data in aad. The value must be
greater than or equal to 0 and less than 2**61.
unsigned char *tag
Pointer to a buffer of size greater than or equal to tag_length bytes. If direction
is equal to 1, this buffer must be writable, and a message authentication code
for the additional authenticated data in aad and the plain text in plaintext of
size tag_length bytes is written to this buffer. If direction is equal to 0, this buffer
must be readable and contain a message authentication code to be verified
against the additional authenticated data in aad and the decrypted cipher text
from ciphertext.
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
53
unsigned int tag_length
Length in bytes of the message authentication code tag in bytes. Valid values
are: 4, 8, 12, 13, 14, 15, and 16.
const unsigned char *key
Pointer to a valid AES key.
unsigned int key_length
Length in bytes of the AES key. Supported sizes are 16, 24, and 32 for AES-128,
AES-192, and AES-256 respectively. Therefore, you can use the definitions:
AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
unsigned int direction
0
Verify message authentication code and decrypt encrypted payload.
1
Encrypt payload and compute message authentication code for the
additional authenticated data and the payload.
Return codes
0
Success
EFAULT
If direction is equal to 0 and the verification of the message authentication
code fails.
For return codes indicating exceptions, see “Return codes” on page 70.
ica_aes_ofb
Purpose
Encrypt or decrypt data with an AES key using Output Feedback (OFB) mode, as
described in NIST Special Publication 800-38A Chapter 6.4.
Format
unsigned int ica_aes_ofb(const unsigned char *in_data,
unsigned char *out_data,
unsigned long data_length,
const unsigned char *key,
unsigned int key_length,
unsigned char *iv,
unsigned int direction);
Required hardware support
KMO-AES-128, KMO-AES-192, or KMO-AES-256
Parameters
const unsigned char *in_data
Pointer to a readable buffer that contains the message to be encrypted or
decrypted. The size of the message in bytes is data_length. The size of this
buffer must be at least as large as data_length.
unsigned char *out_data
Pointer to a writable buffer that to contain the resulting encrypted or
decrypted message. The size of this buffer in bytes must be at least as large as
data_length.
unsigned long data_length
Length in bytes of the message to be encrypted or decrypted, which resides at
the beginning of in_data.
54
libica Programmer's Reference
const unsigned char *key
Pointer to a valid AES key.
unsigned int key_length
Length in bytes of the AES key. Supported sizes are 16, 24, and 32 for AES-128,
AES-192, and AES-256 respectively. Therefore, you can use the definitions:
AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
unsigned char *iv
Pointer to a valid initialization vector of the same size as the cipher block, in
bytes (16 bytes for AES). This vector is overwritten during the function. If
data_length is a multiple of the cipher block size (16 bytes for AES), the result
value in iv can be used as the initialization vector for a chained ica_aes_ofb
call with the same key.
unsigned int direction
0
Use the decrypt function.
1
Use the encrypt function.
Return codes
Success
0
For return codes indicating exceptions, see “Return codes” on page 70.
ica_aes_xts
Purpose
Encrypt or decrypt data with an AES key using the XEX Tweakable Bloc Cipher
with Ciphertext Stealing (XTS) mode, as described in NIST Special Publication
800-38E and IEEE standard 1619-2007.
Format
unsigned int ica_aes_xts(const unsigned char *in_data,
unsigned char *out_data,
unsigned long data_length,
const unsigned char *key1,
const unsigned char *key2,
unsigned int key_length,
unsigned char *tweak,
unsigned int direction);
Required hardware support
KM-XTS-AES-128, or KM-XTS-AES-256
PCC-Compute-XTS-Parameter-Using-AES-128, or PCC-Compute-XTS-ParameterUsing-AES-256
Parameters
const unsigned char *in_data
Pointer to a readable buffer that contains the message to be encrypted or
decrypted. The size of the message in bytes is data_length. The size of this
buffer must be at least as large as data_length.
unsigned char *out_data
Pointer to a writable buffer to contain the resulting encrypted or decrypted
message. The size of this buffer in bytes must be at least as large as data_length.
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
55
unsigned long data_length
Length in bytes of the message to be encrypted or decrypted, which resides at
the beginning of in_data. The minimal value of data_length is 16.
const unsigned char *key1
Pointer to a buffer containing a valid AES key. key1 is used for the actual
encryption of the message buffer, combined with some vector computed from
the tweak value (Key1 in IEEE Std 1619-2007).
const unsigned char *key2
Pointer to a buffer containing a valid AES key key2 is used to encrypt the
tweak (Key2 in IEEE Std 1619-2007).
unsigned int key_length
The length in bytes of the AES key. XTS supported AES key sizes are 16 and
32, for AES-128 and AES-256 respectively. Therefore, you can use:
2 * AES_KEY_LEN128 and 2 * AES_KEY_LEN256.
unsigned char *tweak
Pointer to a valid 16-byte tweak value (as in IEEE standard 1619-2007). This
tweak is overwritten during the function. If data_length is a multiple of the
cipher block size (a multiple of 16 for AES), the result value in tweak can be
used as the tweak value for a chained ica_aes_xts call with the same key pair.
unsigned int direction
0
Use the decrypt function.
1
Use the encrypt function.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
Compatibility with earlier versions
In order to stay compatible with earlier versions of libica, the following AES
interfaces remain supported:
unsigned int ica_aes_encrypt(unsigned int mode,
unsigned int data_length, unsigned char *input_data,
ica_aes_vector_t *iv, unsigned int key_length, unsigned char *aes_key,
unsigned char *output_data);
unsigned int ica_aes_decrypt(unsigned int mode,
unsigned int data_length, unsigned char *input_data,
ica_aes_vector_t *iv, unsigned int key_length, unsigned char *aes_key,
unsigned char *output_data);
Table 5 shows libica Version 2.0 AES functions calls, and their corresponding libica
Version 2.3.0 AES function calls.
Table 5. Compatibility of libica Version 2.0 AES functions calls to libica Version 2.3.0 AES function calls
Calling this libica Version 2.0 AES function
Corresponds to calling this libica Version 2.3.0 AES
function
ica_aes_encrypt(MODE_ECB, data_length,in_data,NULL,
key_length,key,out_data);
ica_aes_ecb(in_data,out_data,(long)data_length,
key,key_length,1);
ica_aes_encrypt(MODE_CBC,data_length,in_data,iv,
key_length,key,out_data);
ica_des_cbc(in_data,out_data,(long)data_length,
key,key_length,iv,1);
ica_aes_decrypt(MODE_ECB,data_length,in_data,NULL,
key_length,key,out_data);
ica_aes_ecb(in_data,out_data,(long)data_length,
key,key_length,0);
56
libica Programmer's Reference
Table 5. Compatibility of libica Version 2.0 AES functions calls to libica Version 2.3.0 AES function calls (continued)
Calling this libica Version 2.0 AES function
Corresponds to calling this libica Version 2.3.0 AES
function
ica_aes_decrypt(MODE_CBC,data_length,in_data,iv,
key_length,key,out_data);
ica_aes_cbc(in_data,out_data,(long)data_length,
key,key_length,iv,0);
The functions ica_aes_encrypt and ica_aes_decrypt remain supported, but their
use is discouraged in favor of ica_aes_ecb and ica_aes_cbc.
For a detailed description of the earlier APIs, see libica Programmers Reference
Version 2.0.
Information retrieval function
|
These functions are included in: include/ica_api.h.
ica_get_version
Purpose
Return libica version information.
Format
unsigned int ica_get_version(libica_version_info *version_info);
Parameters
libica_version_info *version_info
Pointer to a libica_version_info structure. The structure is filled with the current
libica version information.
Return codes
0
Success
For return codes indicating exceptions, see “Return codes” on page 70.
|
ica_get_functionlist
|
Purpose
|
Returns a list of crypto mechanisms supported by libica.
|
|
|
Format
|
Parameters
|
|
|
|
|
|
|
libica_func_list_element *mech_list
Null or pointer to an array of at least as many libica_func_list_element structures
as denoted in the *mech_list_len argument. If the value in the *mech_list_len
argument is equal to or greater than the number of mechanisms available in
libica then the libica_func_list_element structures in *mech_list are filled (in the
order of the array indices) with information for the supported otherwise the
*mech_list argument remains unchanged.
unsigned int ica_get_functionlist(libica_func_list_element *mech_list,
unsigned int *mech_list_len);
Chapter 3. libica Version 2.3.0 Application Programming Interfaces (APIs)
57
|
|
|
|
unsigned int *mech_list_len
Pointer to an integer which contain the actual number of array elements
(number of structures). If *mech_list was NULL the contents of *mech_list_len
will be replaced by the number of mechanisms available in libica.
|
|
|
|
Return codes
|
For return codes indicating exceptions, see “Return codes” on page 70.
|
Recommended usage
|
|
|
First call ica_get_functionlist with a NULL mechanism list, then allocate the
mechanism list according to number of mechanisms in libica returned by that
function, and then call ica_get_functionlist with the allocated mechanism list.
0
Success
EINVAL
The value in *mech_list is to small
58
libica Programmer's Reference
Chapter 4. Accessing libica Version 2.3.0 functions via the
PKCS #11 API (openCryptoki)
How the cryptographic functions provided by libica Version 2.3.0 can be accessed
using the PKCS #11 API implemented by openCryptoki is described in this section.
For more information about the PKCS #11 standard, see
http://www.rsa.com/rsalabs/
Introduction
In order to enable hardware cryptographic function support on System z you need
to prepare some hardware components, install and load specific driver modules
and libraries, configure and start daemons, and set up your system environment.
openCryptoki, and in particular the slot manager, can handle several tokens, which
can have different support for different hardware devices or software solutions.
This section focusses on the ica-token, which interacts with the libica Version 2.3.0
library. libica Version 2.3.0 is able to operate with the IBM CP Assist for
Cryptographic Function (CPACF) for symmetric cryptographic functions as well as
with the IBM Crypto adapter cards (for asymmetric cryptographic functions). In
some special cases where the hardware crypto engines do not support a specific
algorithm, libica Version 2.3.0 is able to fall back to a software solution.
Stack overview
openCryptoki consists of a slot manager and an API for slot token dynamic link
libraries (STDLLs).
The slot manager runs as a daemon to control the number of token slots provided
to applications, and it interacts with applications using a shared memory region.
Slot manager
The slot manager (pkcsslotd) assigns tokens to slots within the system. The slot
manager runs as a daemon to control the number of token slots provided, and it
interacts with applications.
openCryptoki API
The openCryptoki API (libopencryptoki.so) provides the interfaces as outlined in
the PKCS #11 specification and supplies each application with the slot management
facility. This API also loads token-specific modules (STDLLs) that provide the
token specific implementation of the cryptographic functions (cryptographic
operations, session management, object management, and so on).
For more details about this standard, refer to the RSA web site:
http://www.rsa.com/rsalabs/
Slot token dynamic link libraries (STDLLs)
STDLLs are plug-in modules to the openCryptoki (main) API. They provide
token-specific functions that implement the interfaces. Specific devices can be
© Copyright IBM Corporation © IBM 2009, 2013
59
supported by building an appropriate STDLL.
Figure 1 illustrates the stack and the process flow:
Figure 1. Stack and process flow
Functions provided by openCryptoki with ica token
The PKCS #11 functions that manage tokens, slots, sessions are described in the
PKCS #11 standard.
The following is the list of cryptographic mechanisms implemented for the ica
token as of openCryptoki version 2.4.0:
v CKM_RSA_PKCS_KEY_PAIR_GEN
v CKM_RSA_PKCS
v
v
v
v
60
CKM_RSA_X_509
CKM_MD2_RSA_PKCS
CKM_MD5_RSA_PKCS
CKM_SHA1_RSA_PKCS
libica Programmer's Reference
|
|
|
v
v
v
v
v
CKM_SHA256_RSA_PKCS
CKM_SHA384_RSA_PKCS
CKM_SHA512_RSA_PKCS
CKM_DES_KEY_GEN
CKM_DES_ECB
v
v
v
v
v
v
v
CKM_DES_CBC
CKM_DES_CBC_PAD
CKM_DES3_KEY_GEN
CKM_DES3_ECB
CKM_DES3_CBC
CKM_DES3_CBC_PAD
CKM_MD2
v
v
v
v
v
v
CKM_MD5
CKM_MD5_HMAC
CKM_MD5_HMAC_GENERAL
CKM_SHA_1
CKM_SHA_1_HMAC
CKM_SHA_1_HMAC_GENERAL
v CKM_SHA256
v CKM_SHA256_HMAC
v CKM_SHA256_HMAC_GENERAL
v
v
v
v
CKM_SHA384
CKM_SHA384_HMAC
CKM_SHA384_HMAC_GENERAL
CKM_SHA512
v CKM_SHA512_HMAC
v CKM_SHA512_HMAC_GENERAL
v CKM_SSL3_PRE_MASTER_KEY_GEN
v
v
v
v
v
CKM_SSL3_MASTER_KEY_DERIVE
CKM_SSL3_KEY_AND_MAC_DERIVE
CKM_SSL3_MD5_MAC
CKM_SSL3_SHA1_MAC
CKM_AES_KEY_GEN
v CKM_AES_ECB
v CKM_AES_CBC
v CKM_AES_CBC_PAD
v CKM_AES_CTR
The PKCS #11 standard describes the exact API for the above mechanisms, for
more information, see
http://www.rsa.com/rsalabs/
For more details about how to use openCryptoki, see “Using openCryptoki” on
page 65.
Chapter 4. Accessing libica Version 2.3.0 functions via the PKCS #11 API (openCryptoki)
61
Installing openCryptoki
Follow the instructions in this section to install openCryptoki.
Installing from the binary package
The current distributions already provide the openCryptoki binary RPM's.
Check whether you have already installed openCryptoki in your current
environment:
$ rpm -qa | grep -i opencryptoki
Example For Red Hat Enterprise Linux 6.2 and SUSE Linux Enterprise 11 SP2: As
a minimum, the following packages should be present:
For Red Hat Enterprise Linux 6.2:
opencryptoki-2.4-2.el6.s390x
opencryptoki-libs-2.4-2.el6.s390x
opencryptoki-libs-2.4-2.el6.s390
// Daemon, Tools
// libraries 64bit
// libraries 32bit
For SUSE Linux Enterprise 11 SP2:
openCryptoki-2.4-0.9.1
openCryptoki-64bit-2.4-0.9.1
openCryptoki-32bit-2.4-0.9.1
// Daemon, Tools)
// libraries 64bit
// libraries 32bit
If these packages are not currently installed on your system, issue the following
commands to install them:
Red Hat Enterprise Linux 6.2:
$ yum install opencryptoki
SUSE Linux Enterprise 11 SP2:
$ zypper install openCryptoki
Installing from the source package
If you prefer you can install openCryptoki from the source package.
1. Download the latest version of the openCryptoki sources from:
http://sourceforge.net/projects/opencryptoki/
2. Decompress the tar archive. There should be a new directory named
opencryptoki-2.4-x.x.x.
3. Change to that directory and issue the following scripts and commands:
$
$
$
$
./bootstrap
./configure
make
make install
where:
62
libica Programmer's Reference
bootstrap
Initial setup, basic configurations
configure
Check configurations and build the Makefile
make
Compile and link
make install
Install the libraries
Installing libica Version 2.3.0
To make use of the hardware support of cryptographic functions it is necessary to
install the libica Version 2.3.0 package.
For information about how to install libica Version 2.3.0, see Chapter 2, “Installing
and using libica Version 2.3.0,” on page 3.
Configuring openCryptoki
To configure openCryptoki, you need to set up tokens and daemons and then
initialize the token.
Setting up tokens and daemons
After you have successfully installed openCryptoki, the following libraries are in
place:
/usr/lib64/opencryptoki/libopencryptoki.so
openCryptoki base library
/usr/lib64/opencryptoki/stdll/libpkcs11_ica.so
libica token library
/usr/lib64/opencryptoki/stdll/libpkcs11_swk.so
software token library
Note: An analogous set of libraries is available for 32 bit compatibility mode.
A preconfigured list of all available tokens that are ready to register to the
openCryptoki slot daemon is required before the openCryptoki daemon can start.
pkcs11_startup generates this list of tokens including their configuration
parameter:
$ pkcs11_startup
After the pkcs11_startup script has completed, the list of predefined tokens that
are ready to register can be found in /var/lib/opencryptoki/pk_config_data.
By default there are two tokens (ica-token and software token) present on the
system. pk_config_data should provide the following content:
TRUE|0|Linux 2.6.32-220.el6.s390x Linux (ICA)|Linux 2.6.32-220.el6.s390x|TRUE|FALSE|TRUE|0|0|1|1|NONE|libpkcs11_ica.so|ST_Initialize
TRUE|0|Linux 2.6.32-220.el6.s390x Linux (Soft)|Linux 2.6.32-220.el6.s390x|TRUE|FALSE|FALSE|0|0|1|1|NONE|libpkcs11_sw.so|ST_Initialize
Start the slot-daemon, which reads out the configuration information and sets up
the tokens:
$ pkcsslotd start
For a permanent solution, set up:
Chapter 4. Accessing libica Version 2.3.0 functions via the PKCS #11 API (openCryptoki)
63
$ chkconfig pkcsslotd on
Initializing the token
The daemon including all registered tokens is now ready to operate, but before
you can start requesting cryptographic operations you need to initialize the token
and set up the PINs.
In openCryptoki there is a SO PIN (Security Officer) for administrative purposes
and a User PIN (standard PIN) which is used for cryptographic functions that
require a session login. The following command provides some useful slot
information:
pkcsconf -s
Slot #1 Info
Description: Linux 2.6.32-220.el6.s390x Linux (ICA)
Manufacturer: Linux 2.6.32-220.el6.s390x
Flags: 0x5 (TOKEN_PRESENT|HW_SLOT)
Hardware Version: 0.0
Firmware Version: 1.1
Slot #2 Info
Description: Linux 2.6.32-220.el6.s390x Linux (Soft)
Manufacturer: Linux 2.6.32-220.el6.s390x
Flags: 0x1 (TOKEN_PRESENT)
Hardware Version: 0.0
Firmware Version: 1.1
Find your preferred token in the details list and select the correct slot number. This
number is used in the next initialization steps to identify your token:
$ pkcsconf -I -c <slot> // Initialize the Token and setup a Token Label
$ pkcsconf -u -c <slot> // Initialize the user PIN (SO PIN required)
$ pkcsconf -P -c <slot> // change the SO PIN (recommended)
$ pkcsconf -p -c <slot> // change the user PIN (optional)
pkcsconf -I: During token initialization you are asked for a token label. Provide a
meaningful name, you may need this reference later for identification purposes.
pkcsconf -u: When you enter the user PIN initialization you are asked for the SO
PIN, which is by default 87654321. The length of the user PIN must be between 4
to 8 characters.
pkcsconf -P: For security reasons it is recommended that you change the default
SO PIN. Use the pkcsconf -P option to change the SO PIN.
pkcsconf -p: You can also change the user PIN with pkcsconf -p option. After you
have completed the PIN setup the token is prepared and ready for use.
Note: It's recommended that you define a user PIN that is different from 12345678.
This is because this pattern is checked internally and marked as default PIN.
64
libica Programmer's Reference
Using openCryptoki
How you can get status information about openCryptoki is described in this
section.
For a list of code samples, refer to “Coding samples (C)” on page 149.
Getting openCryptoki status information
You can check the slot and token information, and the PIN status at any time.
This information is provided by the pkcsconf command.
$ pkcsconf -t
Label: IBM ICA Token
Model: IBM ICA
Flags: 0x44D
(RNG|LOGIN_REQUIRED|USER_PIN_INITIALIZED|CLOCK_ON_TOKEN|TOKEN_INITIALIZED)
PIN Length: 4-8
The most important information is as follows:
v The token Label you assigned at the initialization phase.
v The Model name provides information of the token that is in use (here the ica
token).
v The Flags provide information about the token initialization state, the PIN state,
and features such as “Random Number Generator”, “Clock on token” and
requirements such as “Login required”, which means there are some (at least
one) mechanisms that require a session login to make use of that cryptographic
function.
v The PIN length range declared for this token.
Use the following command to retrieve a complete list of algorithms (or
mechanisms) that are supported by the token:
$ pkcsconf -m -c <slot>
Mechanism #2
Mechanism: 0x131 (CKM_DES3_KEY_GEN)
Key Size: 24-24
Flags: 0x8001 (CKF_HW|CKF_GENERATE)
...
Mechanism #10
Mechanism: 0x132 (CKM_DES3_ECB)
Key Size: 24-24
Flags: 0x60301 (CKF_HW|CKF_ENCRYPT|CKF_DECRYPT|CKF_WRAP|CKF_UNWRAP)
Mechanism #11
Mechanism: 0x133 (CKM_DES3_CBC)
Key Size: 24-24
Flags: 0x60301 (CKF_HW|CKF_ENCRYPT|CKF_DECRYPT|CKF_WRAP|CKF_UNWRAP)
...
The list displays all mechanisms supported by this token. The mechanism ID and
name corresponds to the PKCS #11 specification. Each mechanism provides its
supported key size and the some properties such as hardware support and
mechanism information flags. These flags provide information about the modes of
operation for this mechanism. Typical operations are encrypt, decrypt, wrap key,
unwrap key, sign, verify and so on.
Chapter 4. Accessing libica Version 2.3.0 functions via the PKCS #11 API (openCryptoki)
65
66
libica Programmer's Reference
Chapter 5. libica defines, typedefs, structs, and return codes
These defines, typedefs, structs, and return codes are used when programming
with the libica Version 2.3.0 APIs.
The APIs are described in Chapter 3, “libica Version 2.3.0 Application Programming
Interfaces (APIs),” on page 5. To use them, include ica_api.h in your programs.
Defines
These defines are new with libica Version 2.3.0 or were changed from libica Version
1 or libica Version 2.
Use these defines instead of the equivalent libica Version 1 defines. There is no
difference in their values.
#define ica_adapter_handle_t int
#define SHA_HASH_LENGTH 20
#define SHA1_HASH_LENGTH SHA_HASH_LENGTH
#define SHA224_HASH_LENGTH 28
#define SHA256_HASH_LENGTH 32
#define SHA384_HASH_LENGTH 48
#define SHA512_HASH_LENGTH 64
#define ica_aes_key_t ica_key_t
#define ICA_ENCRYPT 1
#define ICA_DECRYPT 0
Typedefs
These typedefs are available to ensure compatibility with libica Version 1 types.
typedef ica_des_vector_t ICA_DES_VECTOR;
typedef ica_des_key_single_t ICA_KEY_DES_SINGLE;
typedef ica_des_key_triple_t ICA_KEY_DES_TRIPLE;
typedef ica_aes_vector_t ICA_AES_VECTOR;
typedef ica_aes_key_single_t ICA_KEY_AES_SINGLE;
typedef ica_aes_key_len_128_t ICA_KEY_AES_LEN128;
typedef ica_aes_key_len_192_t ICA_KEY_AES_LEN192;
typedef ica_aes_key_len_256_t ICA_KEY_AES_LEN256;
typedef sha_context_t SHA_CONTEXT;
typedef sha256_context_t SHA256_CONTEXT;
typedef sha512_context_t SHA512_CONTEXT;
typedef unsigned char ica_des_vector_t[8];
typedef unsigned char ica_des_key_single_t[8];
typedef unsigned char ica_key_t[8];
typedef unsigned char ica_aes_vector_t[16];
typedef unsigned char ica_aes_key_single_t[8];
typedef unsigned char ica_aes_key_len_128_t[16];
typedef unsigned char ica_aes_key_len_192_t[24];
typedef unsigned char ica_aes_key_len_256_t[32];
© Copyright IBM Corporation © IBM 2009, 2013
67
Structs
These structs are used in the API of libica Version 2.3.0.
For the definitions of older functions, see previous versions of this book. The older
functions are no longer recommended for use, but they are supported.
typedef struct {
unsigned int key_length;
unsigned char* modulus;
unsigned char* exponent;
} ica_rsa_key_mod_expo_t;
typedef struct {
unsigned int key_length;
unsigned char* p;
unsigned char* q;
unsigned char* dp;
unsigned char* dq;
unsigned char* qInverse;
} ica_rsa_key_crt_t;
typedef struct {
unsigned int mech_mode_id;
unsigned int flags;
unsigned int property;
} libica_func_list_element;
* mech_mode_id: Unique mechanism ID for each mechanism implemented in libica
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
68
libica Programmer's Reference
SHA1 1
SHA224 2
SHA256 3
SHA384 4
SHA512 5
DES_ECB 20
DES_CBC 21
DES_CBC_CS 22
DES_OFB 23
DES_CFB 24
DES_CTR 25
DES_CTRLST 26
DES_CBC_MAC 27
DES_CMAC 28
DES3_ECB 41
DES3_CBC 42
DES3_CBC_CS 43
DES3_OFB 44
DES3_CFB 45
DES3_CTR 46
DES3_CTRLST 47
DES3_CBC_MAC 48
DES3_CMAC 49
AES_ECB 60
AES_CBC 61
AES_CBC_CS 62
AES_OFB 63
AES_CFB 64
AES_CTR 65
AES_CTRLST 66
AES_CBC_MAC 67
AES_CMAC 68
AES_CCM 69
AES_GCM 70
AES_XTS 71
P_RNG 80
|
|
|
|
#define
#define
#define
#define
|
|
For more details regarding these mechanism please refer to the openCryptoki v
2.20 specification.
|
|
|
* flags
This flag represents the type of hardware/software support for each
mechanism.
|
|
|
#define ICA_FLAG_SHW 4
Static hardware support (operations on CPACF). Hardware support will be
available unless a hardware error occurs.
|
|
|
#define ICA_FLAG_DHW 2
Dynamic hardware support (operations on crypto cards). Hardware support
will be available unless the hardware is reconfigured.
|
|
|
|
#define ICA_FLAG_SW 1
Software support. If both static and dynamic hardware support as well as
software support are available, then software support is used as fall back if
hardware support fails.
|
|
|
* property
This property field is optional depending on the mechanism. It is used to
declare mechanism specific parameters, such as key sizes for RSA and AES.
RSA_ME 90
RSA_CRT 91
RSA_KEY_GEN_ME 92
RSA_KEY_GEN_CRT 93
|
For RSA mechanisms:
|
|
- bit 0
512 bit key size support
|
|
- bit 1
1024 bit key size support
|
|
- bit 2
2048 bit key size support
|
|
- bit 3
4096 bit key size support
|
For AES mechanisms:
|
|
- bit 0
128 bit key size support
|
|
- bit 1
192 bit key size support
|
|
- bit 2
256 bit key size support
|
For all non-RSA/AES mechanisms this field is empty.
Take note of these considerations:
v The buffers pointed to by members of type unsigned char * must be manually
allocated and deallocated by the user.
v Key parts must always be right-aligned in their fields.
v All buffers pointed to by members modulus and exponent in struct
ica_rsa_key_mod_expo_t must be of length key_length.
Chapter 5. libica defines, typedefs, structs, and return codes
69
v All buffers pointed to by members p, q, dp, dq, and qInverse in struct
ica_rsa_key_crt_t must be of size key_length / 2 or larger.
v In the struct ica_rsa_key_crt_t, the buffers p, dp, and qInverse must contain 8 bytes
of zero padding in front of the actual values.
v If an exponent is set in struct ica_rsa_key_mod_expo_t as part of a public key for
key generation, be aware that due to a restriction in OpenSSL, the public
exponent cannot be larger than a size of unsigned long. Therefore, you must
have zeros left padded in the buffer pointed to by exponent in the struct
ica_rsa_key_mod_expo_t struct. Be aware that this buffer also must be of size
key_length.
v This key_length value should be calculated from the length of the modulus in
bits, according to this calculation:
key_length = (modulus_bits + 7) / 8
typedef struct {
uint64_t runningLength;
unsigned char shaHash[LENGTH_SHA_HASH];
} sha_context_t;
typedef struct {
uint64_t runningLength;
unsigned char sha256Hash[LENGTH_SHA256_HASH];
} sha256_context_t;
typedef struct {
uint64_t runningLengthHigh;
uint64_t runningLengthLow;
unsigned char sha512Hash[LENGTH_SHA512_HASH];
} sha512_context_t;
typedef struct {
unsigned int major_version;
unsigned int minor_version;
unsigned int fixpack_version;
} libica_version_info;
Return codes
The libica Version 2 and libica Version 2.3.0 functions use these standard Linux
return codes:
0
Success
EFAULT
The message authentication failed.
EINVAL
Incorrect parameter
EIO
I/O error
EPERM
Operation not permitted by Hardware (CPACF).
ENODEV
No such device
ENOMEM
Not enough memory
errno When libica calls open, close, begin_sigill_section, or OpenSSL function
RSA_generate_key, the error codes of these programs are returned.
70
libica Programmer's Reference
Chapter 6. libica tools
The libica package includes tools to investigate the capabilities of your
cryptographic hardware and how these capabilities are used by applications that
use libica.
icainfo - Show available libica functions
Purpose
Use this command to find out which libica functions are available on your Linux
system.
Format
icainfo syntax
icainfo
-q
-v
-h
Where:
-q or --quiet
Suppresses an explanatory introduction to the list of functions in the command
output.
-v or --version
Displays the version number of icainfo, then exits.
-h or --help
Displays help information for the command.
Examples
1. To show which libica functions are available on your Linux system enter:
# icainfo
The following CP Assist for Cryptographic Function (CPACF) operations are
supported by libica on this system:
SHA-1:
yes
SHA-256:
yes
SHA-512:
yes
DES:
yes
TDES-128:
yes
TDES-192:
yes
AES-128:
yes
AES-192:
yes
AES-256:
yes
PRNG:
yes
© Copyright IBM Corp. 2009, 2013
71
CCM-AES-128:
CMAC-AES-128:
CMAC-AES-192:
CMAC-AES-256:
yes
yes
yes
yes
2. To list the libica functions without the introduction enter:
# icainfo -q
SHA-1:
SHA-256:
SHA-512:
DES:
TDES-128:
TDES-192:
AES-128:
AES-192:
AES-256:
PRNG:
CCM-AES-128:
CMAC-AES-128:
CMAC-AES-192:
CMAC-AES-256:
yes
yes
yes
yes
yes
yes
yes
yes
yes
yes
yes
yes
yes
yes
icastats - Show use of libica functions
Purpose
Use this command to find out whether libica uses hardware acceleration features
or works with software fallbacks. The command also shows which specific
functions of libica are used.
Format
icastats syntax
icastats
-r
-v
-h
Where:
-r or --reset
Sets the function counters to zero.
-v or --version
Displays the version number of icastats, then exits.
-h or --help
Displays help information for the command.
Examples
To display the current use of libica functions issue:
# icastats
function | # hardware | # software
----------+------------+-----------SHA-1 |
0 |
0
72
libica Programmer's Reference
SHA-224
SHA-256
SHA-384
SHA-512
RANDOM
MOD EXPO
RSA CRT
DES ENC
DES DEC
3DES ENC
3DES DEC
AES ENC
AES DEC
CMAC GEN
CMAC VER
CCM ENC
CCM DEC
CCM AUTH
GCM ENC
GCM DEC
GCM AUTH
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
Chapter 6. libica tools
73
74
libica Programmer's Reference
Chapter 7. Examples
These sample program segments illustrate the libica Version 2.3.0 APIs.
These sample programs are from the libica Version 2.3.0 RPM, and they were
enhanced to use the libica Version 2.3.0 APIs.
These examples are released under the Common Public License - V1.0, which is
stated in full at the end of this chapter. See “Common Public License - V1.0” on
page 145.
Table 6 lists the examples for libica, and the makefile used to create the library.
Table 6. libica examples
Description
Location
DES with ECB mode example
“DES with ECB mode example”
SHA-256 example
“SHA-256 example” on page 78
Pseudo random number generation example
“Pseudo random number generation example” on page
83
Key generation example
“Key generation example” on page 84
RSA example
“RSA example” on page 91
DES with CTR mode example
“DES with CTR mode example” on page 95
Triple DES with CBC mode example
“Triple DES with CBC mode example” on page 98
AES with CFB mode example
“AES with CFB mode example” on page 101
AES with CTR mode example
“AES with CTR mode example” on page 113
AES with OFB mode example
“AES with OFB mode example” on page 123
AES with XTS mode example
“AES with XTS mode example” on page 131
CMAC example
“CMAC example” on page 141
Makefile example
“Makefile example” on page 145
Getting libica Version 2.3.0 status information
“Getting libica Version 2.3.0 status information” on page
149
openCryptoki code samples
“openCryptoki code samples” on page 149
DES with ECB mode example
This program prints the version of libica and then encrypts the contents of a
character array (plain_data[]) using DES in ECE mode and a key stored in another
character array (des_key[]). The program then decrypts the result and prints it as a
string. Intermediate results are written as hex dumps.
/* This program is released under the Common Public License V1.0
*
* You should have received a copy of Common Public License V1.0 along with
* with this program.
*
* Copyright IBM Corp. 2011
*
*/
© Copyright IBM Corp. 2009, 2013
75
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <ica_api.h>
#define DES_CIPHER_BLOCK_SIZE 8
/* Prints hex values to standard out. */
static void dump_data(unsigned char *data, unsigned long length);
/* Prints a description of the return value to standard out. */
static int handle_ica_error(int rc);
int main(char **argv, int argc)
{
int rc;
libica_version_info version;
/* This example uses a static key. In real life you would
* use your real DES key, which is negotiated between the
* encrypting and the decrypting entity.
*
* Note: DES key size is cipher block size (DES_CIPHER_BLOCK_SIZE)
*/
unsigned char des_key[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
};
/* This is the plain data, you want to encrypt. For the
* encryption mode, used in this example, it is necessary,
* that the length of the encrypted data is a multiple of
* cipher block size (DES_CIPHER_BLOCK_SIZE).
*/
unsigned char plain_data[] = {
0x55, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6c, 0x69,
0x62, 0x69, 0x63, 0x61, 0x20, 0x69, 0x73, 0x20,
0x73, 0x6d, 0x61, 0x72, 0x74, 0x20, 0x61, 0x6e,
0x64, 0x20, 0x65, 0x61, 0x73, 0x79, 0x21, 0x00,
};
unsigned char cipher_data[sizeof(plain_data)];
unsigned char decrypt_data[sizeof(plain_data)];
/* Print out libica version.
*/
ica_get_version(&version);
printf("libica version %i.%i.%i\n\n",
version.major_version,
version.minor_version,
version.fixpack_version);
/* Dump key and plain data to standard output, just for
* a visual control.
*/
printf("DES key:\n");
dump_data(des_key, DES_CIPHER_BLOCK_SIZE);
printf("plain data:\n");
dump_data(plain_data, sizeof(plain_data));
/* Encrypt plain data to cipher data, using libica API.
*/
rc = ica_des_ecb(plain_data, cipher_data, sizeof(plain_data),
des_key,
ICA_ENCRYPT);
/* Error handling (if necessary).
*/
76
libica Programmer's Reference
if (rc)
return handle_ica_error(rc);
/* Dump encrypted data.
*/
printf("encrypted data:\n");
dump_data(cipher_data, sizeof(plain_data));
/* Decrypt cipher data to decrypted data, using libica API.
* Note: The same DES key must be used for encryption and decryption.
*/
rc = ica_des_ecb(cipher_data, decrypt_data, sizeof(plain_data),
des_key,
ICA_DECRYPT);
/* Error handling (if necessary).
*/
if (rc)
return handle_ica_error(rc);
/* Dump decrypted data.
* Note: Please compare output with the plain data, they are the same.
*/
printf("decrypted data:\n");
dump_data(decrypt_data, sizeof(plain_data));
/* Surprise... :-)
* Note: The following will only work in this example!
*/
printf("%s\n", decrypt_data);
}
static void dump_data(unsigned char *data, unsigned long length)
{
unsigned char *ptr;
int i;
for (ptr = data, i = 1; ptr < (data+length); ptr++, i++) {
printf("0x%02x ", *ptr);
if ((i % DES_CIPHER_BLOCK_SIZE) == 0)
printf("\n");
}
if (i % DES_CIPHER_BLOCK_SIZE)
printf("\n");
}
static int handle_ica_error(int rc)
{
switch (rc) {
case 0:
printf("OK\n");
break;
case EINVAL:
printf("Incorrect parameter.\n");
break;
case EPERM:
printf("Operation not permitted by Hardware (CPACF).\n");
break;
case EIO:
printf("I/O error.\n");
break;
default:
printf("unknown error.\n");
}
return rc;
}
Chapter 7. Examples
77
SHA-256 example
/* This program is released under the Common Public License V1.0
*
* You should have received a copy of Common Public License V1.0 along with
* with this program.
*/
/* Copyright IBM Corp. 2005, 2009, 2011 */
/* (C) COPYRIGHT International Business Machines Corp. 2005, 2009
#include <fcntl.h>
#include <sys/errno.h>
#include <stdio.h>
#include <string.h>
#include "ica_api.h"
*/
#define NUM_FIPS_TESTS 3
unsigned char FIPS_TEST_DATA[NUM_FIPS_TESTS][64] = {
// Test 0: "abc"
{ 0x61,0x62,0x63 },
// Test 1: "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
{
0x61,0x62,0x63,0x64,0x62,0x63,0x64,0x65,0x63,0x64,0x65,0x66,0x64,0x65,0x66,0x67,
0x65,0x66,0x67,0x68,0x66,0x67,0x68,0x69,0x67,0x68,0x69,0x6a,0x68,0x69,0x6a,0x6b,
0x69,0x6a,0x6b,0x6c,0x6a,0x6b,0x6c,0x6d,0x6b,0x6c,0x6d,0x6e,0x6c,0x6d,0x6e,0x6f,
0x6d,0x6e,0x6f,0x70,0x6e,0x6f,0x70,0x71,
},
// Test 2: 1,000,000 ’a’ -- don’t actually use this... see the special case
// in the loop below.
{
0x61,
},
};
unsigned int
// Test 0:
3,
// Test 1:
56,
// Test 2:
1000000,
};
FIPS_TEST_DATA_SIZE[NUM_FIPS_TESTS] = {
"abc"
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
1,000,000 ’a’
unsigned char FIPS_TEST_RESULT[NUM_FIPS_TESTS][LENGTH_SHA256_HASH] =
{
// Hash for test 0: "abc"
{
0xBA,0x78,0x16,0xBF,0x8F,0x01,0xCF,0xEA,0x41,0x41,0x40,0xDE,0x5D,0xAE,0x22,0x23,
0xB0,0x03,0x61,0xA3,0x96,0x17,0x7A,0x9C,0xB4,0x10,0xFF,0x61,0xF2,0x00,0x15,0xAD,
},
// Hash for test 1: "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
{
0x24,0x8D,0x6A,0x61,0xD2,0x06,0x38,0xB8,0xE5,0xC0,0x26,0x93,0x0C,0x3E,0x60,0x39,
0xA3,0x3C,0xE4,0x59,0x64,0xFF,0x21,0x67,0xF6,0xEC,0xED,0xD4,0x19,0xDB,0x06,0xC1,
},
// Hash for test 2: 1,000,000 ’a’
{
0xCD,0xC7,0x6E,0x5C,0x99,0x14,0xFB,0x92,0x81,0xA1,0xC7,0xE2,0x84,0xD7,0x3E,0x67,
0xF1,0x80,0x9A,0x48,0xA4,0x97,0x20,0x0E,0x04,0x6D,0x39,0xCC,0xC7,0x11,0x2C,0xD0,
},
};
void dump_array(unsigned char *ptr, unsigned int size)
{
unsigned char *ptr_end;
unsigned char *h;
78
libica Programmer's Reference
int i = 1, trunc = 0;
if (size > 64) {
trunc = size - 64;
size = 64;
}
h = ptr;
ptr_end = ptr + size;
while (h < ptr_end) {
printf("0x%02x ", *h);
h++;
if (i == 8) {
if (h != ptr_end)
printf("\n");
i = 1;
} else {
++i;
}
}
printf("\n");
if (trunc > 0)
printf("... %d bytes not printed\n", trunc);
}
int old_api_sha256_test(void)
{
ICA_ADAPTER_HANDLE adapter_handle;
SHA256_CONTEXT Sha256Context;
int rc = 0, i = 0;
unsigned char input_data[1000000];
unsigned int output_hash_length = LENGTH_SHA256_HASH;
unsigned char output_hash[LENGTH_SHA256_HASH];
rc = icaOpenAdapter(0, &adapter_handle);
if (rc != 0) {
printf("icaOpenAdapter failed and returned %d (0x%x).\n", rc, rc);
if (rc == ENODEV)
printf("The usual cause of this on zSeries is that the CPACF instruction is not available.\n");
return 2;
}
for (i = 0; i < NUM_FIPS_TESTS; i++) {
// Test 2 is a special one, because we want to keep the size of the
// executable down, so we build it special, instead of using a static
if (i != 2)
memcpy(input_data, FIPS_TEST_DATA[i], FIPS_TEST_DATA_SIZE[i]);
else
memset(input_data, ’a’, FIPS_TEST_DATA_SIZE[i]);
printf("\nOriginal data for test %d:\n", i);
dump_array(input_data, FIPS_TEST_DATA_SIZE[i]);
rc = icaSha256(adapter_handle,
SHA_MSG_PART_ONLY,
FIPS_TEST_DATA_SIZE[i],
input_data,
LENGTH_SHA256_CONTEXT,
&Sha256Context,
&output_hash_length,
output_hash);
if (rc != 0) {
printf("icaSha256 failed with errno %d (0x%x).\n", rc, rc);
return 2;
}
Chapter 7. Examples
79
if (output_hash_length != LENGTH_SHA256_HASH) {
printf("icaSha256 returned an incorrect output data length, %u (0x%x).\n",
output_hash_length, output_hash_length);
return 2;
}
printf("\nOutput hash for test %d:\n", i);
dump_array(output_hash, output_hash_length);
if (memcmp(output_hash, FIPS_TEST_RESULT[i], LENGTH_SHA256_HASH) != 0) {
printf("This does NOT match the known result.\n");
} else {
printf("Yes, it’s what it should be.\n");
}
}
// This test is the same as test 2, except that we use the SHA256_CONTEXT and
// break it into calls of 1024 bytes each.
printf("\nOriginal data for test 2(chunks = 1024) is calls of 1024 ’a’s at a time\n");
i = FIPS_TEST_DATA_SIZE[2];
while (i > 0) {
unsigned int shaMessagePart;
memset(input_data, ’a’, 1024);
if (i == FIPS_TEST_DATA_SIZE[2])
shaMessagePart = SHA_MSG_PART_FIRST;
else if (i <= 1024)
shaMessagePart = SHA_MSG_PART_FINAL;
else
shaMessagePart = SHA_MSG_PART_MIDDLE;
rc = icaSha256(adapter_handle,
shaMessagePart,
(i < 1024) ? i : 1024,
input_data,
LENGTH_SHA256_CONTEXT,
&Sha256Context,
&output_hash_length,
output_hash);
if (rc != 0) {
printf("icaSha256 failed with errno %d (0x%x) on iteration %d.\n", rc, rc, i);
return 2;
}
i -= 1024;
}
if (output_hash_length != LENGTH_SHA256_HASH) {
printf("icaSha256 returned an incorrect output data length, %u (0x%x).\n",
output_hash_length, output_hash_length);
return 2;
}
printf("\nOutput hash for test 2(chunks = 1024):\n");
dump_array(output_hash, output_hash_length);
if (memcmp(output_hash, FIPS_TEST_RESULT[2], LENGTH_SHA256_HASH) != 0) {
printf("This does NOT match the known result.\n");
} else {
printf("Yes, it’s what it should be.\n");
}
// This test is the same as test 2, except that we use the SHA256_CONTEXT and
// break it into calls of 64 bytes each.
printf("\nOriginal data for test 2(chunks = 64) is calls of 64 ’a’s at a time\n");
i = FIPS_TEST_DATA_SIZE[2];
while (i > 0) {
unsigned int shaMessagePart;
80
libica Programmer's Reference
memset(input_data, ’a’, 64);
if (i == FIPS_TEST_DATA_SIZE[2])
shaMessagePart = SHA_MSG_PART_FIRST;
else if (i <= 64)
shaMessagePart = SHA_MSG_PART_FINAL;
else
shaMessagePart = SHA_MSG_PART_MIDDLE;
rc = icaSha256(adapter_handle,
shaMessagePart,
(i < 64) ? i : 64,
input_data,
LENGTH_SHA256_CONTEXT,
&Sha256Context,
&output_hash_length,
output_hash);
if (rc != 0) {
printf("icaSha256 failed with errno %d (0x%x) on iteration %d.\n", rc, rc, i);
return 2;
}
i -= 64;
}
if (output_hash_length != LENGTH_SHA256_HASH) {
printf("icaSha256 returned an incorrect output data length, %u (0x%x).\n",
output_hash_length, output_hash_length);
return 2;
}
printf("\nOutput hash for test 2(chunks = 64):\n");
dump_array(output_hash, output_hash_length);
if (memcmp(output_hash, FIPS_TEST_RESULT[2], LENGTH_SHA256_HASH) != 0) {
printf("This does NOT match the known result.\n");
} else {
printf("Yes, it’s what it should be.\n");
}
printf("\nAll SHA256 tests completed successfully\n");
icaCloseAdapter(adapter_handle);
return 0;
}
int new_api_sha256_test(void)
{
sha256_context_t sha256_context;
int rc = 0, i = 0;
unsigned char input_data[1000000];
unsigned int output_hash_length = LENGTH_SHA256_HASH;
unsigned char output_hash[LENGTH_SHA256_HASH];
for (i = 0; i < NUM_FIPS_TESTS; i++) {
// Test 2 is a special one, because we want to keep the size of the
// executable down, so we build it special, instead of using a static
if (i != 2)
memcpy(input_data, FIPS_TEST_DATA[i], FIPS_TEST_DATA_SIZE[i]);
else
memset(input_data, ’a’, FIPS_TEST_DATA_SIZE[i]);
printf("\nOriginal data for test %d:\n", i);
dump_array(input_data, FIPS_TEST_DATA_SIZE[i]);
rc = ica_sha256(SHA_MSG_PART_ONLY, FIPS_TEST_DATA_SIZE[i], input_data,
Chapter 7. Examples
81
&sha256_context, output_hash);
if (rc != 0) {
printf("icaSha256 failed with errno %d (0x%x).\n", rc, rc);
return rc;
}
printf("\nOutput hash for test %d:\n", i);
dump_array(output_hash, output_hash_length);
if (memcmp(output_hash, FIPS_TEST_RESULT[i], LENGTH_SHA256_HASH) != 0)
printf("This does NOT match the known result.\n");
else
printf("Yes, it’s what it should be.\n");
}
// This test is the same as test 2, except that we use the SHA256_CONTEXT and
// break it into calls of 1024 bytes each.
printf("\nOriginal data for test 2(chunks = 1024) is calls of 1024"
" ’a’s at a time\n");
i = FIPS_TEST_DATA_SIZE[2];
while (i > 0) {
unsigned int sha_message_part;
memset(input_data, ’a’, 1024);
if (i == FIPS_TEST_DATA_SIZE[2])
sha_message_part = SHA_MSG_PART_FIRST;
else if (i <= 1024)
sha_message_part = SHA_MSG_PART_FINAL;
else
sha_message_part = SHA_MSG_PART_MIDDLE;
rc = ica_sha256(sha_message_part, (i < 1024) ? i : 1024,
input_data, &sha256_context, output_hash);
if (rc != 0) {
printf("ica_sha256 failed with errno %d (0x%x) on"
" iteration %d.\n", rc, rc, i);
return rc;
}
i -= 1024;
}
printf("\nOutput hash for test 2(chunks = 1024):\n");
dump_array(output_hash, output_hash_length);
if (memcmp(output_hash, FIPS_TEST_RESULT[2], LENGTH_SHA256_HASH) != 0)
printf("This does NOT match the known result.\n");
else
printf("Yes, it’s what it should be.\n");
// This test is the same as test 2, except that we use the
// SHA256_CONTEXT and break it into calls of 64 bytes each.
printf("\nOriginal data for test 2(chunks = 64) is calls of 64 ’a’s at"
" a time\n");
i = FIPS_TEST_DATA_SIZE[2];
while (i > 0) {
unsigned int sha_message_part;
memset(input_data, ’a’, 64);
if (i == FIPS_TEST_DATA_SIZE[2])
sha_message_part = SHA_MSG_PART_FIRST;
else if (i <= 64)
sha_message_part = SHA_MSG_PART_FINAL;
else
sha_message_part = SHA_MSG_PART_MIDDLE;
rc = ica_sha256(sha_message_part, (i < 64) ? i : 64,
input_data, &sha256_context, output_hash);
82
libica Programmer's Reference
if (rc != 0) {
printf("ica_sha256 failed with errno %d (0x%x) on iteration"
" %d.\n", rc, rc, i);
return rc;
}
i -= 64;
}
printf("\nOutput hash for test 2(chunks = 64):\n");
dump_array(output_hash, output_hash_length);
if (memcmp(output_hash, FIPS_TEST_RESULT[2], LENGTH_SHA256_HASH) != 0)
printf("This does NOT match the known result.\n");
else
printf("Yes, it’s what it should be.\n");
printf("\nAll SHA256 tests completed successfully\n");
return 0;
}
int main(int argc, char **argv)
{
int rc = 0;
rc = old_api_sha256_test();
if (rc) {
printf("old_api_sha256_test: returned rc = %i\n", rc);
return rc;
}
rc = new_api_sha256_test();
if (rc) {
printf("new_api_sha256_test: returned rc = %i\n", rc);
return rc;
}
return rc;
}
Pseudo random number generation example
This example uses the old (libica Version 1) API. Examples for using the new
(libica Version 2.3.0) API for random number generation are located in other
examples, such as the DES with CTR mode example.
/* This program is released under the Common Public License V1.0
*
* You should have received a copy of Common Public License V1.0 along with
* with this program.
*/
/* Copyright IBM Corp. 2010, 2011 */
#include <fcntl.h>
#include <sys/errno.h>
#include <stdio.h>
#include "ica_api.h"
unsigned char R[512];
extern int errno;
void dump_array(unsigned char *ptr, unsigned int size)
{
unsigned char *ptr_end;
unsigned char *h;
int i = 1;
Chapter 7. Examples
83
h = ptr;
ptr_end = ptr + size;
while (h < (unsigned char *)ptr_end) {
printf("0x%02x ",(unsigned char ) *h);
h++;
if (i == 8) {
printf("\n");
i = 1;
} else {
++i;
}
}
printf("\n");
}
int main(int ac, char **av)
{
int rc;
ICA_ADAPTER_HANDLE adapter_handle;
rc = icaOpenAdapter(0, &adapter_handle);
if (rc != 0) {
printf("icaOpenAdapter failed and returned %d (0x%x).\n", rc, rc);
}
rc = icaRandomNumberGenerate(adapter_handle, sizeof R, R);
if (rc != 0) {
printf("icaRandomNumberGenerate failed and returned %d (0x%x).\n", rc, rc);
#ifdef __s390__
if (rc == ENODEV)
printf("The usual cause of this on zSeries is that the CPACF instruction is not available.\n");
#endif
}
else {
printf("\nHere it is:\n");
}
dump_array(R, sizeof R);
if (!rc) {
printf("\nWell, does it look random?\n\n");
}
icaCloseAdapter(adapter_handle);
return 0;
}
Key generation example
This example uses the various key generation APIs, as well as those to open and
close an adapter, and random number generation.
/* This program is released under the Common Public License V1.0
*
* You should have received a copy of Common Public License V1.0 along with
* with this program.
*/
/* (C) COPYRIGHT International Business Machines Corp. 2001, 2009
#include <sys/errno.h>
#include <fcntl.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
84
libica Programmer's Reference
*/
#include <strings.h>
#include "ica_api.h"
#define KEY_BYTES ((key_bits + 7) / 8)
#define KEY_BYTES_MAX 256
extern int errno;
void dump_array(char *ptr, int size)
{
char *ptr_end;
char *h;
int i = 1;
h = ptr;
ptr_end = ptr + size;
while (h < ptr_end) {
printf("0x%02x ",(unsigned char ) *h);
h++;
if (i == 8) {
printf("\n");
i = 1;
} else {
++i;
}
}
printf("\n");
}
int main(int argc, char **argv)
{
ICA_ADAPTER_HANDLE adapter_handle;
ICA_KEY_RSA_CRT crtkey;
ICA_KEY_RSA_MODEXPO wockey, wockey2;
unsigned char decrypted[KEY_BYTES_MAX], encrypted[KEY_BYTES_MAX],
original[KEY_BYTES_MAX];
int rc;
unsigned int length, length2;
unsigned int exponent_type = RSA_PUBLIC_FIXED, key_bits = 1024;
length = sizeof wockey;
length2 = sizeof wockey2;
bzero(&wockey, sizeof wockey);
bzero(&wockey2, sizeof wockey2);
rc = icaOpenAdapter(0, &adapter_handle);
if (rc != 0) {
printf("icaOpenAdapter failed and returned %d (0x%x).\n", rc,
rc);
}
exponent_type = RSA_PUBLIC_FIXED;
printf("a fixed exponent . . .\n");
rc = icaRandomNumberGenerate(adapter_handle, KEY_BYTES,
wockey.keyRecord);
if (rc != 0) {
printf("icaRandomNumberGenerate failed and returned %d (0x%x)"
".\n", rc, rc);
return -1;
}
wockey.nLength = KEY_BYTES / 2;
wockey.expLength = sizeof(unsigned long);
wockey.expOffset = SZ_HEADER_MODEXPO;
wockey.keyRecord[wockey.expLength - 1] |= 1;
if (argc > 1) {
key_bits = atoi(argv[1]);
if (key_bits > KEY_BYTES_MAX * 8) {
Chapter 7. Examples
85
printf("The maximum key length is %d bits.",
KEY_BYTES_MAX * 8);
exit(0);
}
wockey.modulusBitLength = key_bits;
printf("Using %u-bit keys and ", key_bits);
if (argc > 2) {
switch (argv[2][0]) {
case ’3’:
exponent_type = RSA_PUBLIC_3;
printf("exponent 3 . . .\n");
wockey.expLength = 1;
break;
case ’6’:
exponent_type = RSA_PUBLIC_65537;
printf("exponent 65537 . . .\n");
wockey.expLength = 3;
break;
case ’R’:
case ’r’:
exponent_type = RSA_PUBLIC_RANDOM;
printf("a random exponent . . .\n");
break;
default:
break;
}
}
}
rc = icaRandomNumberGenerate(adapter_handle, sizeof(original),
original);
if (rc != 0) {
printf("icaRandomNumberGenerate failed and returned %d (0x%x)"
".\n", rc, rc);
return rc;
}
original[0] = 0;
rc = icaRsaKeyGenerateModExpo(adapter_handle, key_bits, exponent_type,
&length, &wockey, &length2, &wockey2);
if (rc != 0) {
printf("icaRsaKeyGenerateModExpo failed and returned %d (0x%x)"
".\n", rc, rc);
return rc;
}
printf("Public key:\n");
dump_array((char *) wockey.keyRecord, 2 * KEY_BYTES);
printf("Private key:\n");
dump_array((char *) wockey2.keyRecord, 2 * KEY_BYTES);
bzero(encrypted, KEY_BYTES);
length = KEY_BYTES;
printf("encrypt \n");
rc = icaRsaModExpo(adapter_handle, KEY_BYTES,
&length, encrypted);
if (rc != 0) {
printf("icaRsaModExpo failed and returned %d
return rc;
}
bzero(decrypted, KEY_BYTES);
length = KEY_BYTES;
printf("decrypt \n");
rc = icaRsaModExpo(adapter_handle, KEY_BYTES,
&length, decrypted);
if (rc != 0) {
printf("icaRsaModExpo failed and returned %d
86
libica Programmer's Reference
original, &wockey,
(0x%x).\n", rc, rc);
encrypted, &wockey2,
(0x%x).\n", rc,
rc);
return rc;
}
printf("Original:\n");
dump_array((char *) original, KEY_BYTES);
printf("Result of encrypt:\n");
dump_array((char *) encrypted, KEY_BYTES);
printf("Result of decrypt:\n");
dump_array((char *) decrypted, KEY_BYTES);
if (memcmp(original, decrypted, KEY_BYTES) != 0) {
printf("This does not match the original plaintext.
icaCloseAdapter(adapter_handle);
return errno ? errno : -1;
} else {
printf("Success! The key pair checks out.\n");
if (memcmp(original, encrypted, KEY_BYTES) == 0) {
printf("But the ciphertext equals the plaintext."
"That can’t be good.\n");
return -1;
}
}
fflush(stdout);
Failure!\n");
length = sizeof wockey;
length2 = sizeof crtkey;
bzero(&wockey, sizeof wockey);
wockey.expLength = sizeof(unsigned long);
if (exponent_type == RSA_PUBLIC_FIXED) {
wockey.keyType = KEYTYPE_MODEXPO;
wockey.keyLength = sizeof wockey;
wockey.modulusBitLength = key_bits;
wockey.nLength = KEY_BYTES;
wockey.expOffset = SZ_HEADER_MODEXPO;
wockey.expLength = sizeof (unsigned long);
wockey.nOffset = KEY_BYTES + wockey.expOffset;
rc = icaRandomNumberGenerate(adapter_handle, KEY_BYTES,
wockey.keyRecord);
if (rc != 0) {
printf("icaRandomNumberGenerate failed and returned %d"
"(0x%x).\n", rc, rc);
return rc;
}
wockey.keyRecord[wockey.expLength - 1] |= 1;
}
rc = icaRsaKeyGenerateCrt(adapter_handle, key_bits, exponent_type,
&length, &wockey, &length2, &crtkey);
printf("wockey.modulusBitLength = %i, crtkey.modulusBitLength = %i"
" \n", wockey.modulusBitLength, crtkey.modulusBitLength);
if (rc != 0) {
printf("icaRsaKeyGenerateCrt failed and returned %d (0x%x)"
".\n", rc, rc);
return rc;
}
printf("Public key:\n");
dump_array((char *) wockey.keyRecord, 2 * KEY_BYTES);
printf("Private key:\n");
dump_array((char *) crtkey.keyRecord, 5 * KEY_BYTES / 2 + 24);
bzero(encrypted, KEY_BYTES);
length = KEY_BYTES;
rc = icaRsaModExpo(adapter_handle, KEY_BYTES, original, &wockey,
&length, encrypted);
if (rc != 0)
printf("icaRsaModExpo failed and returned %d (0x%x).\n", rc, rc);
Chapter 7. Examples
87
bzero(decrypted, KEY_BYTES);
length = KEY_BYTES;
rc = icaRsaCrt(adapter_handle, KEY_BYTES, encrypted, &crtkey, &length,
decrypted);
if (rc != 0)
printf("icaRsaCrt failed and returned %d (0x%x).\n", rc, rc);
printf("Original:\n");
dump_array((char *) original, KEY_BYTES);
printf("Result of encrypt:\n");
dump_array((char *) encrypted, KEY_BYTES);
printf("Result of decrypt:\n");
dump_array((char *) decrypted, KEY_BYTES);
if (memcmp(original, decrypted, KEY_BYTES) != 0) {
printf("This does not match the original plaintext. Failure!\n");
icaCloseAdapter(adapter_handle);
return errno ? errno : -1;
} else {
printf("Success! The key pair checks out.\n");
if (memcmp(original, encrypted, KEY_BYTES) == 0) {
printf("But the ciphertext equals the plaintext. That can’t be good.\n");
return -1;
}
}
fflush(stdout);
printf("TEST NEW API - MOD_EXPO\n");
rc = ica_close_adapter(adapter_handle);
printf("ica_close_adapter rc = %i\n", rc);
rc = ica_open_adapter(&adapter_handle);
if (rc)
printf("Adapter not open\n");
else
printf("Adapter open\n");
ica_rsa_key_mod_expo_t modexpo_public_key;
unsigned char modexpo_public_n[KEY_BYTES];
bzero(modexpo_public_n, KEY_BYTES);
unsigned char modexpo_public_e[KEY_BYTES];
bzero(modexpo_public_e, KEY_BYTES);
modexpo_public_key.modulus = modexpo_public_n;
modexpo_public_key.exponent = modexpo_public_e;
modexpo_public_key.key_length = KEY_BYTES;
if (exponent_type == RSA_PUBLIC_65537)
*(unsigned long*)((unsigned char *)modexpo_public_key.exponent +
modexpo_public_key.key_length sizeof(unsigned long)) = 65537;
if (exponent_type == RSA_PUBLIC_3)
*(unsigned long*)((unsigned char *)modexpo_public_key.exponent +
modexpo_public_key.key_length sizeof(unsigned long)) = 3;
ica_rsa_key_mod_expo_t modexpo_private_key;
unsigned char modexpo_private_n[KEY_BYTES];
bzero(modexpo_private_n, KEY_BYTES);
unsigned char modexpo_private_e[KEY_BYTES];
bzero(modexpo_private_e, KEY_BYTES);
modexpo_private_key.modulus = modexpo_private_n;
modexpo_private_key.exponent = modexpo_private_e;
modexpo_private_key.key_length = KEY_BYTES;
rc = ica_rsa_key_generate_mod_expo(adapter_handle,
key_bits,
&modexpo_public_key,
&modexpo_private_key);
if (rc)
88
libica Programmer's Reference
printf("ica_rsa_key_generate_mod_expo rc = %i\n",rc);
printf("Public key:\n");
dump_array((char *) (char
dump_array((char *) (char
printf("Private key:\n");
dump_array((char *) (char
dump_array((char *) (char
*)modexpo_public_key.exponent, KEY_BYTES);
*)modexpo_public_key.modulus, KEY_BYTES);
*)modexpo_private_key.exponent, KEY_BYTES);
*)modexpo_private_key.modulus, KEY_BYTES);
bzero(encrypted, KEY_BYTES);
length = KEY_BYTES;
printf("encrypt \n");
rc = ica_rsa_mod_expo(adapter_handle, original, &modexpo_public_key,
encrypted);
if (rc != 0) {
printf("ica_rsa_mod_expo failed and returned %d (0x%x).\n", rc,
rc);
return rc;
}
bzero(decrypted, KEY_BYTES);
length = KEY_BYTES;
printf("decrypt \n");
rc = ica_rsa_mod_expo(adapter_handle, encrypted, &modexpo_private_key,
decrypted);
if (rc != 0) {
printf("ica_rsa_mod_expo failed and returned %d (0x%x).\n", rc,
rc);
return rc;
}
printf("Original:\n");
dump_array((char *) original, KEY_BYTES);
printf("Result of encrypt:\n");
dump_array((char *) encrypted, KEY_BYTES);
printf("Result of decrypt:\n");
dump_array((char *) decrypted, KEY_BYTES);
if (memcmp(original, decrypted, KEY_BYTES) != 0) {
printf("This does not match the original plaintext. Failure!\n");
return -1;
} else {
printf("Success! The key pair checks out.\n");
if (memcmp(original, encrypted, KEY_BYTES) == 0) {
printf("But the ciphertext equals the plaintext. That can’t be good.\n");
return -1;
}
}
fflush(stdout);
printf("TEST NEW API - CRT\n");
ica_rsa_key_mod_expo_t public_key;
ica_rsa_key_crt_t private_key;
unsigned char public_n[KEY_BYTES];
bzero(public_n, KEY_BYTES);
unsigned char public_e[KEY_BYTES];
bzero(public_e, KEY_BYTES);
public_key.modulus = public_n;
public_key.exponent = public_e;
public_key.key_length = KEY_BYTES;
unsigned char private_p[(key_bits + 7) / (8 * 2) + 8];
bzero(private_p, KEY_BYTES + 1);
unsigned char private_q[(key_bits + 7) / (8 * 2)];
bzero(private_q, KEY_BYTES);
unsigned char private_dp[(key_bits + 7) / (8 * 2) + 8];
bzero(private_dp, KEY_BYTES + 1);
Chapter 7. Examples
89
unsigned char private_dq[(key_bits + 7) / (8 * 2)];
bzero(private_dq, KEY_BYTES);
unsigned char private_qInverse[(key_bits + 7) / (8 * 2) + 8];
bzero(private_qInverse, KEY_BYTES + 1);
private_key.p = private_p;
private_key.q = private_q;
private_key.dp = private_dp;
private_key.dq = private_dq;
private_key.qInverse = private_qInverse;
private_key.key_length = (key_bits + 7) / 8;
if (exponent_type == RSA_PUBLIC_65537)
*(unsigned long*)((unsigned char *)public_key.exponent +
public_key.key_length sizeof(unsigned long)) = 65537;
if (exponent_type == RSA_PUBLIC_3)
*(unsigned long*)((unsigned char *)public_key.exponent +
public_key.key_length sizeof(unsigned long)) = 3;
rc = ica_rsa_key_generate_crt(adapter_handle, key_bits, &public_key,
&private_key);
if (rc != 0) {
printf("ica_rsa_key_generate_crt failed and returned %d (0x%x)"
".\n", rc, rc);
return rc;
}
printf("Public key:\n");
dump_array((char *) (char *)&public_key, 2 * KEY_BYTES);
printf("Private key:\n");
dump_array((char *) (char *)&private_key, 5 * KEY_BYTES / 2 + 24);
bzero(encrypted, KEY_BYTES);
length = KEY_BYTES;
rc = ica_rsa_mod_expo(adapter_handle, original, &public_key, encrypted);
if (rc != 0) {
printf("ica_rsa_mod_expo failed and returned %d (0x%x).\n",
rc, rc);
return rc;
}
bzero(decrypted, KEY_BYTES);
length = KEY_BYTES;
rc = ica_rsa_crt(adapter_handle, encrypted, &private_key, decrypted);
if (rc != 0) {
printf("icaRsaCrt failed and returned %d (0x%x).\n", rc, rc);
return rc;
}
printf("Original:\n");
dump_array((char *) original, KEY_BYTES);
printf("Result of encrypt:\n");
dump_array((char *) encrypted, KEY_BYTES);
printf("Result of decrypt:\n");
dump_array((char *) decrypted, KEY_BYTES);
if (memcmp(original, decrypted, KEY_BYTES) != 0) {
printf("This does not match the original plaintext."
"Failure!\n");
} else {
printf("Success! The key pair checks out.\n");
if (memcmp(original, encrypted, KEY_BYTES) == 0) {
printf("But the ciphertext equals the plaintext."
"That can’t be good.\n");
}
}
90
libica Programmer's Reference
fflush(stdout);
ica_close_adapter(adapter_handle);
return 0;
}
RSA example
/* This program is released under the Common Public License V1.0
*
* You should have received a copy of Common Public License V1.0 along with
* with this program.
*/
/* Copyright IBM Corp. 2001, 2009, 2011 */
#include
#include
#include
#include
#include
#include
#include
<fcntl.h>
<memory.h>
<sys/errno.h>
<stdio.h>
<stdlib.h>
<strings.h>
"ica_api.h"
unsigned char pubkey1024[] =
{ 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,
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,
0x00,
0x03 };
unsigned char modulus1024[] =
{ 0xec, 0x51,
0x2e, 0x24,
0xad, 0xee,
0x61, 0xda,
0x52, 0xda,
0x65, 0x1b,
0x2a, 0x5f,
0xb7, 0x38,
0x59, 0x81,
0x13, 0x26,
0x50, 0x9d,
0x68, 0x1a,
0x58, 0x22,
0x89, 0x0b,
0x9e, 0x3f,
0xc3, 0x59,
0xab,
0x52,
0xc7,
0x32,
0x28,
0x02,
0xe1,
0xb5,
0x77,
0x9c,
0xd6,
0x98,
0x40,
0x56,
0x8a,
0x4b,
0xa1,
0x2e,
0x7d,
0x97,
0x45,
0xcb,
0xdf,
0xa2,
0x6b,
0xca,
0x79,
0xca,
0x19,
0x9e,
0x50,
0xf6,
0xf8,
0x3c,
0x00,
0xb4,
0x55,
0xbe,
0xe9,
0x78,
0x6b,
0x5e,
0x59,
0x11,
0x29,
0x3e,
0xf1,
0xbb,
0x40,
0x51,
0xaf,
0x32,
0xc6,
0xf4,
0xe3,
0x9d,
0x2e,
0x0a,
0x99,
0xce,
0x72,
0xd5,
0x0a,
0xc9,
0x2c,
0x6d,
0xe1,
0x97,
0xb2,
0x2c,
0xbc,
0x15,
0xa9,
0x1f,
0x50,
0x37,
0x4c,
0x6d,
0x59,
0xa5,
0x08,
0x98,
0xa8,
0xe3,
0x46,
0x6b,
0x47,
0xe2,
0xdb,
0x3c,
0xe5,
0x63,
0x41,
0x75,
0x4a,
0x93 };
unsigned char Bp[] =
{ 0x00,
0xa7,
0xf5,
0x90,
0x53,
0x00,
0xa2,
0xc9,
0x19,
0x4e,
0x00,
0x18,
0x04,
0x6d,
0x8d,
0x00,
0x2c,
0x16,
0x64,
0xde,
0x00,
0xa9,
0xd9,
0xb7,
0xa6,
0x00,
0xb4,
0xa6,
0x17,
0x94,
0x00,
0xb9,
0x8b,
0x67,
0x32,
0x00,
0xcf,
0x9e,
0x4a,
0xfa,
Chapter 7. Examples
91
0x5d,
0x96,
0x81,
0xe4,
0xcf,
0x38,
0x65,
0x93,
0x58,
0x95,
0x3b,
0x50,
0x3e,
0xb6,
0x3c,
0xf1,
0x90,
0xca,
0x95,
0x88,
0xbb,
0x2f,
0x9e,
0x6b,
0x30,
0xfa,
0x79,
0xc1,
0x19,
0x22,
0x75,
0x87 };
unsigned char Bq[] =
{ 0xa0,
0xd0,
0x90,
0x09,
0x9d,
0x2b,
0xd9,
0x4c,
0x3a,
0x84,
0x7d,
0x71,
0xf0,
0xf3,
0xa2,
0x59,
0x18,
0x4a,
0xc4,
0x79,
0x16,
0x5a,
0xac,
0x5e,
0xa4,
0x8c,
0xca,
0xd0,
0xf0,
0xfc,
0x49,
0x38,
0x1c,
0x7c,
0x7e,
0xc0,
0x1f,
0x2c,
0xcc,
0xd2,
0x3c,
0xce,
0x2d,
0xae,
0x68,
0xf5,
0x76,
0x85,
0x49,
0xdf,
0x3d,
0xa6,
0x9a,
0xa7,
0x9c,
0xd3,
0x09,
0x9e,
0xbc,
0xc1,
0xc5,
0xec,
0xd8,
0x3b };
unsigned char Np[] =
{ 0x00,
0xfb,
0xf0,
0x58,
0xfd,
0x8c,
0x61,
0xc2,
0xd6,
0x00,
0xb7,
0x6e,
0x6f,
0xf7,
0xb7,
0x54,
0x17,
0xdc,
0x00,
0x73,
0x2d,
0x26,
0x75,
0x04,
0xe0,
0xd8,
0xf9,
0x00,
0x24,
0x86,
0x24,
0xd4,
0x5d,
0x92,
0xda,
0x6a,
0x00,
0x42,
0x22,
0x17,
0xcd,
0xd9,
0x2f,
0xe0,
0x4c,
0x00,
0xfe,
0x46,
0x12,
0xf9,
0x18,
0x47,
0x6d,
0xa1,
0x00,
0x8f,
0x79,
0xa3,
0xde,
0xc8,
0xf7,
0xb6,
0xa2,
0x00,
0x16,
0xd1,
0x1a,
0x4b,
0x26,
0x33,
0x30,
0x4b };
unsigned char Nq[] =
{ 0xf0,
0xb8,
0xd8,
0x0e,
0x6c,
0xc1,
0x46,
0x72,
0x57,
0xc6,
0xbc,
0x2a,
0xe8,
0xed,
0x74,
0x86,
0x24,
0x6f,
0xa7,
0x36,
0x22,
0x08,
0x02,
0x0d,
0xf6,
0xd2,
0x2f,
0xb9,
0x68,
0x7a,
0x6e,
0x55,
0x2a,
0xbb,
0xbd,
0x21,
0x2f,
0x43,
0xb2,
0x3b,
0x5a,
0x36,
0x43,
0x05,
0x1c,
0x70,
0xb1,
0xc8,
0x6d,
0x4f,
0xdc,
0xfa,
0xe8,
0x7b,
0xeb,
0xbc,
0x8e,
0x6d,
0x9a,
0x22,
0x27,
0xe3,
0x44,
0xd9 };
unsigned char U[] =
{ 0x00,
0x83,
0x96,
0x02,
0x26,
0x8e,
0x5d,
0x36,
0x39,
0x00,
0xf1,
0xb5,
0x0c,
0x5d,
0x75,
0x8e,
0x6e,
0x74,
0x00,
0xca,
0x30,
0xe3,
0x74,
0x62,
0xb6,
0x1c,
0x7c,
0x00,
0x06,
0x32,
0x37,
0x03,
0xf2,
0xd9,
0xbe,
0x25,
0x00,
0x58,
0x40,
0xb7,
0x47,
0x9d,
0x69,
0x8a,
0xd8,
0x00,
0x4a,
0x36,
0x51,
0xd3,
0x4e,
0x4a,
0x14,
0xa4,
0x00,
0x04,
0x48,
0xbc,
0x33,
0xc8,
0x9a,
0xb1,
0x4f,
0x00,
0x5e,
0xb9,
0x22,
0x20,
0x7d,
0xe1,
0x85,
0xde };
0x02,
0xb0,
0x92,
0x97,
0x05,
0x0d,
0x15,
0x1d,
0x25,
0x2d,
0x35,
0x3d,
0x45,
0x4d,
0x08,
0x28,
0x0d,
0xed,
0x06,
0x0e,
0x16,
0x1e,
0x26,
0x2e,
0x36,
0x3e,
0x46,
0x4e,
0x68,
0xaa,
0x8e,
0x00,
0x07,
0x0f,
0x17,
0x1f,
0x27,
0x2f,
0x37,
0x3f,
0x47,
0x4f,
0x30,
0x76,
0x34,
0x00,
0x08,
0x10,
0x18,
0x20,
0x28,
0x30,
0x38,
0x40,
0x48,
0x50,
0x9a,
0x30,
0xe0,
0x01,
0x09,
0x11,
0x19,
0x21,
0x29,
0x31,
0x39,
0x41,
0x49,
0x51,
0x32,
0x3d,
0xd5,
0x02,
0x0a,
0x12,
0x1a,
0x22,
0x2a,
0x32,
0x3a,
0x42,
0x4a,
0x52,
0x08,
0x84,
0xcc,
0x03,
0x0b,
0x13,
0x1b,
0x23,
0x2b,
0x33,
0x3b,
0x43,
0x4b,
0x53,
unsigned char R[128];
unsigned char A[] =
{ 0x00,
0x57,
0x5f,
0x36,
0x04,
0x0c,
0x14,
0x1c,
0x24,
0x2c,
0x34,
0x3c,
0x44,
0x4c,
92
libica Programmer's Reference
0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b,
0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63 };
unsigned char Ciphertext[] =
{ 0xb2, 0xb2,
0xee, 0x4c,
0x51, 0x60,
0x29, 0xfa,
0xe0, 0xac,
0x7f, 0x1e,
0x56, 0x5a,
0xcd, 0x77,
0x64, 0x58,
0xaa, 0xe7,
0x9a, 0xa9,
0x40, 0x7a,
0x6c, 0xe6,
0xa8, 0xea,
0x87, 0x6e,
0xd7, 0x14,
0x82, 0xd7, 0x2c, 0x6f, 0x53, 0x29,
0xd1, 0x77, 0xb7, 0x13, 0xf3, 0x1c,
0xd8, 0xa9, 0x4e, 0x52, 0x72, 0x43,
0x51, 0xaa, 0xd8, 0xbc, 0x31, 0x21,
0x9b, 0x4e, 0x0, 0x94, 0xac, 0x91,
0xfd, 0xfb, 0x1c, 0xfa, 0xa8, 0xe8,
0x1, 0x17, 0xf1, 0x5f, 0x1, 0xba,
0xa1, 0x8c, 0x74, 0x8a, 0xef, 0xfa,
0x79, 0x13, 0xaa, 0x54, 0x13, 0x2b,
0xc3, 0x50, 0x3b, 0x69, 0x3b, 0xb,
0x9d, 0x15, 0x8a, 0x6, 0x45, 0x71,
0x80, 0x85, 0x4a, 0xbe, 0x68, 0x48,
0xdd, 0x96, 0xb0, 0xdc, 0xf4, 0x23,
0x21, 0x9f, 0xbc, 0x6b, 0x15, 0xa4,
0x93, 0x56, 0xae, 0xa7, 0x17, 0x4e,
0xe4, 0x69, 0x4, 0xd5, 0x2e, 0x62 };
extern int errno;
void dump_array(unsigned char *ptr, unsigned int size)
{
unsigned char *ptr_end;
unsigned char *h;
int i = 1;
h = ptr;
ptr_end = ptr + size;
while (h < (unsigned char *)ptr_end) {
printf("0x%02x ",(unsigned char ) *h);
h++;
if (i == 8) {
printf("\n");
i = 1;
} else {
++i;
}
}
printf("\n");
}
int main()
{
ICA_ADAPTER_HANDLE adapter_handle;
ICA_KEY_RSA_CRT icakey;
ICA_KEY_RSA_MODEXPO wockey;
caddr_t key;
caddr_t my_result;
caddr_t my_result2;
/* icaRsaModExpo_t rsawoc; */
int i;
unsigned int length;
i = icaOpenAdapter(0, &adapter_handle);
if (i != 0) {
printf("icaOpenAdapter failed and returned %d (0x%x), errno=%d\n", i, i, errno);
return i;
}
/*
* encrypt with public key
*/
Chapter 7. Examples
93
printf("modulus size = %ld\n", (long)sizeof(modulus1024));
bzero(&wockey, sizeof(wockey));
wockey.keyType = KEYTYPE_MODEXPO;
wockey.keyLength = sizeof(ICA_KEY_RSA_MODEXPO);
wockey.modulusBitLength = sizeof(modulus1024) * 8;
wockey.nLength = sizeof(modulus1024);
wockey.expLength = sizeof(pubkey1024);
key = (caddr_t)wockey.keyRecord;
bcopy(&pubkey1024, key, sizeof(pubkey1024));
wockey.expOffset = key - (char *) &wockey;
key += sizeof(pubkey1024);
bcopy(&modulus1024, key, sizeof(modulus1024));
wockey.nOffset = key - (char *) &wockey;
my_result = (caddr_t) malloc(sizeof(A));
bzero(my_result, sizeof(A));
length = sizeof(A);
printf("wockey.modulusBitLength = %i\n", wockey.modulusBitLength);
if ((i = icaRsaModExpo(adapter_handle, sizeof(A), A,
&wockey, &length, (unsigned char *)my_result)) != 0) {
printf("icaRsaModExpo failed and returned %d (0x%x).\n", i, i);
}
printf("\n\n\n\n\n result of encrypt with public key\n");
dump_array((unsigned char *)my_result,sizeof(A));
printf("Ciphertext \n");
dump_array(Ciphertext,sizeof(A));
if (memcmp(my_result,Ciphertext,sizeof(A))){
printf("Ciphertext mismatch\n");
return 0;
} else {
printf("ENCRYPT WORKED\n");
}
bzero(&icakey, sizeof(icakey));
/* Card level CRT operation */
icakey.keyType = KEYTYPE_PKCSCRT;
icakey.keyLength = sizeof(ICA_KEY_RSA_CRT);
icakey.modulusBitLength = sizeof(modulus1024)*8;
my_result2 = (caddr_t)malloc(sizeof(A));
bzero(my_result2,sizeof(A));
key = (caddr_t)icakey.keyRecord;
/*
* Bp is copied into the key */
bcopy(Bp,key,sizeof(Bp));
icakey.dpLength = sizeof(Bp);
icakey.dpOffset = key - (char *)&icakey;
key += sizeof(Bp);
/*
* Bq is copied into the key */
bcopy(Bq,key,sizeof(Bq));
icakey.dqLength = sizeof(Bq);
icakey.dqOffset = key - (char *)&icakey;
key += sizeof(Bq);
/*
* Np is copied into the key */
bcopy(Np,key,sizeof(Np));
icakey.pLength = sizeof(Np);
icakey.pOffset = key - (char *)&icakey;
key += sizeof(Np);
94
libica Programmer's Reference
/*
* Nq is copied into the key */
bcopy(Nq,key,sizeof(Nq));
icakey.qLength = sizeof(Nq);
icakey.qOffset = key - (char *)&icakey;
key += sizeof(Nq);
/*
* U is copied into the key */
bcopy(U,key,sizeof(U));
icakey.qInvLength = sizeof(U);
icakey.qInvOffset = key - (char *)&icakey;
key += sizeof(U);
/*
printf("size of Bp=%d\n",sizeof(Bp));
printf("size of Bq=%d\n",sizeof(Bq));
printf("size of Np=%d\n",sizeof(Np));
printf("size of Nq=%d\n",sizeof(Nq));
printf("size of U=%d\n",sizeof(U));
printf("size of R=%d\n",sizeof(R));
printf("icakey private Key record\n");
dump_array(&icakey,sizeof(ICA_KEY_RSA_CRT)); */
length = sizeof(Ciphertext);
icakey.modulusBitLength = length * 8;
icakey.keyLength = length;
if ((i = icaRsaCrt(adapter_handle, sizeof(Ciphertext), Ciphertext,
&icakey, &length, (unsigned char *)my_result2)) != 0) {
printf("icaRsaCrt failed and returned %d (0x%x).\n", i, i);
}
printf("Result of decrypt\n");
dump_array((unsigned char *)my_result2, sizeof(A));
printf("original data\n");
dump_array(A, sizeof(A));
if( memcmp(A,my_result2,sizeof(A)) != 0) {
printf("Results do not match. Failure!\n");
return -1;
} else {
printf("Results match!\n");
}
icaCloseAdapter(adapter_handle);
return 0;
}
DES with CTR mode example
/* This program is released under the Common Public License V1.0
*
* You should have received a copy of Common Public License V1.0 along with
* with this program.
*/
/* Copyright IBM Corp. 2010, 2011 */
#include <fcntl.h>
#include <sys/errno.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include "ica_api.h"
#define NR_RANDOM_TESTS 100
Chapter 7. Examples
95
void dump_array(unsigned char *ptr, unsigned int size)
{
unsigned char *ptr_end;
unsigned char *h;
int i = 1;
h = ptr;
ptr_end = ptr + size;
while (h < (unsigned char *)ptr_end) {
printf("0x%02x ",(unsigned char ) *h);
h++;
if (i == 8) {
printf("\n");
i = 1;
} else {
++i;
}
}
printf("\n");
}
void dump_ctr_data(unsigned char *iv, unsigned int iv_length,
unsigned char *key, unsigned int key_length,
unsigned char *input_data, unsigned int data_length,
unsigned char *output_data)
{
printf("IV \n");
dump_array(iv, iv_length);
printf("Key \n");
dump_array(key, key_length);
printf("Input Data\n");
dump_array(input_data, data_length);
printf("Output Data\n");
dump_array(output_data, data_length);
}
int random_des_ctr(int iteration, int silent, unsigned int data_length, unsigned int iv_length)
{
unsigned int key_length = sizeof(ica_des_key_single_t);
if (data_length % sizeof(ica_des_vector_t))
iv_length = sizeof(ica_des_vector_t);
printf("Test Parameters for iteration = %i\n", iteration);
printf("key length = %i, data length = %i, iv length = %i\n",
key_length, data_length, iv_length);
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
char
char
char
char
char
char
iv[iv_length];
tmp_iv[iv_length];
key[key_length];
input_data[data_length];
encrypt[data_length];
decrypt[data_length];
int rc = 0;
rc = ica_random_number_generate(data_length, input_data);
if (rc) {
printf("random number generate returned rc = %i, errno = %i\n", rc, errno);
return rc;
}
rc = ica_random_number_generate(iv_length, iv);
if (rc) {
printf("random number generate returned rc = %i, errno = %i\n", rc, errno);
return rc;
}
rc = ica_random_number_generate(key_length, key);
if (rc) {
96
libica Programmer's Reference
printf("random number generate returned rc = %i, errno = %i\n", rc, errno);
return rc;
}
memcpy(tmp_iv, iv, iv_length);
rc = ica_des_ctr(input_data, encrypt, data_length, key, tmp_iv,
32,1);
if (rc) {
printf("ica_des_ctr encrypt failed with rc = %i\n", rc);
dump_ctr_data(iv, iv_length, key, key_length, input_data,
data_length, encrypt);
return rc;
}
if (!silent && !rc) {
printf("Encrypt:\n");
dump_ctr_data(iv, iv_length, key, key_length, input_data,
data_length, encrypt);
}
memcpy(tmp_iv, iv, iv_length);
rc = ica_des_ctr(encrypt, decrypt, data_length, key, tmp_iv,
32, 0);
if (rc) {
printf("ica_des_ctr decrypt failed with rc = %i\n", rc);
dump_ctr_data(iv, iv_length, key, key_length, encrypt,
data_length, decrypt);
return rc;
}
if (!silent && !rc) {
printf("Decrypt:\n");
dump_ctr_data(iv, iv_length, key, key_length, encrypt,
data_length, decrypt);
}
if (memcmp(decrypt, input_data, data_length)) {
printf("Decryption Result does not match the original data!\n");
printf("Original data:\n");
dump_array(input_data, data_length);
printf("Decryption Result:\n");
dump_array(decrypt, data_length);
rc++;
}
return rc;
}
int main(int argc, char **argv)
{
unsigned int silent = 0;
unsigned int endless = 0;
if (argc > 1) {
if (strstr(argv[1], "silent"))
silent = 1;
if (strstr(argv[1], "endless"))
endless = 1;
}
int rc = 0;
int error_count = 0;
int i = 0;
unsigned int data_length = sizeof(ica_des_key_single_t);
unsigned int iv_length = sizeof(ica_des_key_single_t);
if (endless) {
silent = 1;
while (1) {
printf("i = %i\n",i);
Chapter 7. Examples
97
rc = random_des_ctr(i, silent, 320, 320);
if (rc) {
printf("kat_des_ctr failed with rc = %i\n",
rc);
return rc;
} else
printf("kat_des_ctr finished successfuly\n");
i++;
}
} else {
for (i = 1; i < NR_RANDOM_TESTS; i++) {
rc = random_des_ctr(i, silent, data_length, iv_length);
if (rc) {
printf("random_des_ctr failed with rc = %i\n",
rc);
error_count++;
} else
printf("random_des_ctr finished "
"successfuly\n");
if (!(data_length % sizeof(ica_des_key_single_t))) {
/* Always when the full block size is reached use a
* counter with the same size as the data */
rc = random_des_ctr(i, silent,
data_length, data_length);
if (rc) {
printf("random_des_ctr failed with "
"rc = %i\n", rc);
error_count++;
} else
printf("random_des_ctr finished "
"successfuly\n");
}
data_length++;
}
}
if (error_count)
printf("%i testcases failed\n", error_count);
else
printf("All testcases finished successfully\n");
return rc;
}
Triple DES with CBC mode example
/* This program is released under the Common Public License V1.0
*
* You should have received a copy of Common Public License V1.0 along with
* with this program.
*/
/* Copyright IBM Corp. 2010, 2011 */
#include <fcntl.h>
#include <sys/errno.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include "ica_api.h"
#define NR_RANDOM_TESTS 10000
void dump_array(unsigned char *ptr, unsigned int size)
{
unsigned char *ptr_end;
unsigned char *h;
98
libica Programmer's Reference
int i = 1;
h = ptr;
ptr_end = ptr + size;
while (h < (unsigned char *)ptr_end) {
printf("0x%02x ",(unsigned char ) *h);
h++;
if (i == 8) {
printf("\n");
i = 1;
} else {
++i;
}
}
printf("\n");
}
void dump_cbc_data(unsigned char *iv, unsigned int iv_length,
unsigned char *key, unsigned int key_length,
unsigned char *input_data, unsigned int data_length,
unsigned char *output_data)
{
printf("IV \n");
dump_array(iv, iv_length);
printf("Key \n");
dump_array(key, key_length);
printf("Input Data\n");
dump_array(input_data, data_length);
printf("Output Data\n");
dump_array(output_data, data_length);
}
int load_random_test_data(unsigned char *data, unsigned int data_length,
unsigned char *iv, unsigned int iv_length,
unsigned char *key, unsigned int key_length)
{
int rc;
rc = ica_random_number_generate(data_length, data);
if (rc) {
printf("ica_random_number_generate with rc = %i errnor = %i\n",
rc, errno);
return rc;
}
rc = ica_random_number_generate(iv_length, iv);
if (rc) {
printf("ica_random_number_generate with rc = %i errnor = %i\n",
rc, errno);
return rc;
}
rc = ica_random_number_generate(key_length, key);
if (rc) {
printf("ica_random_number_generate with rc = %i errnor = %i\n",
rc, errno);
return rc;
}
return rc;
}
int random_3des_cbc(int iteration, int silent, unsigned int data_length)
{
unsigned int iv_length = sizeof(ica_des_vector_t);
unsigned int key_length = sizeof(ica_des_key_triple_t);
unsigned
unsigned
unsigned
unsigned
char
char
char
char
iv[iv_length];
tmp_iv[iv_length];
key[key_length];
input_data[data_length];
Chapter 7. Examples
99
unsigned char encrypt[data_length];
unsigned char decrypt[data_length];
int rc = 0;
memset(encrypt, 0x00, data_length);
memset(decrypt, 0x00, data_length);
load_random_test_data(input_data, data_length, iv, iv_length, key,
key_length);
memcpy(tmp_iv, iv, iv_length);
printf("Test Parameters for iteration = %i\n", iteration);
printf("key length = %i, data length = %i, iv length = %i\n",
key_length, data_length, iv_length);
rc = ica_3des_cbc(input_data, encrypt, data_length, key, tmp_iv, 1);
if (rc) {
printf("ica_3des_cbc encrypt failed with rc = %i\n", rc);
dump_cbc_data(iv, iv_length, key, key_length, input_data,
data_length, encrypt);
}
if (!silent && !rc) {
printf("Encrypt:\n");
dump_cbc_data(iv, iv_length, key, key_length, input_data,
data_length, encrypt);
}
if (rc) {
printf("3DES CBC test exited after encryption\n");
return rc;
}
memcpy(tmp_iv, iv, iv_length);
rc = ica_3des_cbc(encrypt, decrypt, data_length, key, tmp_iv,
0);
if (rc) {
printf("ica_3des_cbc decrypt failed with rc = %i\n", rc);
dump_cbc_data(iv, iv_length, key, key_length, encrypt,
data_length, decrypt);
return rc;
}
if (!silent && !rc) {
printf("Decrypt:\n");
dump_cbc_data(iv, iv_length, key, key_length, encrypt,
data_length, decrypt);
}
if (memcmp(decrypt, input_data, data_length)) {
printf("Decryption Result does not match the original data!\n");
printf("Original data:\n");
dump_array(input_data, data_length);
printf("Decryption Result:\n");
dump_array(decrypt, data_length);
rc++;
}
return rc;
}
int main(int argc, char **argv)
{
// Default mode is 0. ECB,CBC and CFQ tests will be performed.
unsigned int silent = 0;
if (argc > 1) {
if (strstr(argv[1], "silent"))
100
libica Programmer's Reference
silent = 1;
}
int rc = 0;
int error_count = 0;
int iteration;
unsigned int data_length = sizeof(ica_des_vector_t);
for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) {
int silent = 1;
rc = random_3des_cbc(iteration, silent, data_length);
if (rc) {
printf("random_3des_cbc failed with rc = %i\n", rc);
error_count++;
goto out;
} else
printf("random_3des_cbc finished successfuly\n");
data_length += sizeof(ica_des_vector_t);
}
out:
if (error_count)
printf("%i testcases failed\n", error_count);
else
printf("All testcases finished successfully\n");
return rc;
}
AES with CFB mode example
/* This program is released under the Common Public License V1.0
*
* You should have received a copy of Common Public License V1.0 along with
* with this program.
*/
/* Copyright IBM Corp. 2010, 2011 */
#include <fcntl.h>
#include <sys/errno.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include "ica_api.h"
#define NR_TESTS 12
#define NR_RANDOM_TESTS 1000
/* CFB128 data -1- AES128 */
unsigned char NIST_KEY_CFB_E1[] = {
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
};
unsigned char NIST_IV_CFB_E1[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
};
unsigned char NIST_EXPECTED_IV_CFB_E1[] = {
0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20,
0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a,
};
unsigned char NIST_TEST_DATA_CFB_E1[] = {
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
};
Chapter 7. Examples
101
unsigned char NIST_TEST_RESULT_CFB_E1[] = {
0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20,
0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a,
};
unsigned int NIST_LCFB_E1 = 128 / 8;
/* CFB128 data -2- AES128 */
unsigned char NIST_KEY_CFB_E2[] = {
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
};
unsigned char NIST_IV_CFB_E2[] = {
0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20,
0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a,
};
unsigned char NIST_EXPECTED_IV_CFB_E2[] = {
0xc8, 0xa6, 0x45, 0x37, 0xa0, 0xb3, 0xa9, 0x3f,
0xcd, 0xe3, 0xcd, 0xad, 0x9f, 0x1c, 0xe5, 0x8b,
};
unsigned char NIST_TEST_DATA_CFB_E2[] = {
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
};
unsigned char NIST_TEST_RESULT_CFB_E2[] = {
0xc8, 0xa6, 0x45, 0x37, 0xa0, 0xb3, 0xa9, 0x3f,
0xcd, 0xe3, 0xcd, 0xad, 0x9f, 0x1c, 0xe5, 0x8b,
};
unsigned int NIST_LCFB_E2 = 128 / 8;
/* CFB8 data -3- AES128 */
unsigned char NIST_KEY_CFB_E3[] = {
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
};
unsigned char NIST_IV_CFB_E3[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
};
unsigned char NIST_EXPECTED_IV_CFB_E3[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x3b,
};
unsigned char NIST_TEST_DATA_CFB_E3[] = {
0x6b,
};
unsigned char NIST_TEST_RESULT_CFB_E3[] = {
0x3b,
};
unsigned int NIST_LCFB_E3 = 8 / 8;
/* CFB8 data -4- AES128 */
unsigned char NIST_KEY_CFB_E4[] = {
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
};
unsigned char NIST_IV_CFB_E4[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
102
libica Programmer's Reference
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x3b,
};
unsigned char NIST_EXPECTED_IV_CFB_E4[] = {
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x3b, 0x79,
};
unsigned char NIST_TEST_DATA_CFB_E4[] = {
0xc1,
};
unsigned char NIST_TEST_RESULT_CFB_E4[] = {
0x79,
};
unsigned int NIST_LCFB_E4 = 8 / 8;
/* CFB 128 data -5- for AES192 */
unsigned char NIST_KEY_CFB_E5[] = {
0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b,
};
unsigned char NIST_IV_CFB_E5[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
};
unsigned char NIST_EXPECTED_IV_CFB_E5[] = {
0xcd, 0xc8, 0x0d, 0x6f, 0xdd, 0xf1, 0x8c, 0xab,
0x34, 0xc2, 0x59, 0x09, 0xc9, 0x9a, 0x41, 0x74,
};
unsigned char NIST_TEST_DATA_CFB_E5[] = {
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
};
unsigned char NIST_TEST_RESULT_CFB_E5[] = {
0xcd, 0xc8, 0x0d, 0x6f, 0xdd, 0xf1, 0x8c, 0xab,
0x34, 0xc2, 0x59, 0x09, 0xc9, 0x9a, 0x41, 0x74,
};
unsigned int NIST_LCFB_E5 = 128 / 8;
/* CFB 128 data -6- for AES192 */
unsigned char NIST_KEY_CFB_E6[] = {
0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b,
};
unsigned char NIST_IV_CFB_E6[] = {
0xcd, 0xc8, 0x0d, 0x6f, 0xdd, 0xf1, 0x8c, 0xab,
0x34, 0xc2, 0x59, 0x09, 0xc9, 0x9a, 0x41, 0x74,
};
unsigned char NIST_EXPECTED_IV_CFB_E6[] = {
0x67, 0xce, 0x7f, 0x7f, 0x81, 0x17, 0x36, 0x21,
0x96, 0x1a, 0x2b, 0x70, 0x17, 0x1d, 0x3d, 0x7a,
};
unsigned char NIST_TEST_DATA_CFB_E6[] = {
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
Chapter 7. Examples
103
};
unsigned char NIST_TEST_RESULT_CFB_E6[] = {
0x67, 0xce, 0x7f, 0x7f, 0x81, 0x17, 0x36, 0x21,
0x96, 0x1a, 0x2b, 0x70, 0x17, 0x1d, 0x3d, 0x7a,
};
unsigned int NIST_LCFB_E6 = 128 / 8;
/* CFB 128 data -7- for AES192 */
unsigned char NIST_KEY_CFB_E7[] = {
0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b,
};
unsigned char NIST_IV_CFB_E7[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
};
unsigned char NIST_EXPECTED_IV_CFB_E7[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xcd,
};
unsigned char NIST_TEST_DATA_CFB_E7[] = {
0x6b,
};
unsigned char NIST_TEST_RESULT_CFB_E7[] = {
0xcd,
};
unsigned int NIST_LCFB_E7 = 8 / 8;
/* CFB 128 data -8- for AES192 */
unsigned char NIST_KEY_CFB_E8[] = {
0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b,
};
unsigned char NIST_IV_CFB_E8[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xcd,
};
unsigned char NIST_EXPECTED_IV_CFB_E8[] = {
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xcd, 0xa2,
};
unsigned char NIST_TEST_DATA_CFB_E8[] = {
0xc1,
};
unsigned char NIST_TEST_RESULT_CFB_E8[] = {
0xa2,
};
unsigned int NIST_LCFB_E8 = 8 / 8;
/* CFB128 data -9- for AES256 */
unsigned char NIST_KEY_CFB_E9[] = {
104
libica Programmer's Reference
0x60,
0x2b,
0x1f,
0x2d,
};
0x3d,
0x73,
0x35,
0x98,
0xeb,
0xae,
0x2c,
0x10,
0x10,
0xf0,
0x07,
0xa3,
0x15,
0x85,
0x3b,
0x09,
0xca,
0x7d,
0x61,
0x14,
0x71,
0x77,
0x08,
0xdf,
0xbe,
0x81,
0xd7,
0xf4,
unsigned char NIST_IV_CFB_E9[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
};
unsigned char NIST_EXPECTED_IV_CFB_E9[] = {
0xdc, 0x7e, 0x84, 0xbf, 0xda, 0x79, 0x16, 0x4b,
0x7e, 0xcd, 0x84, 0x86, 0x98, 0x5d, 0x38, 0x60,
};
unsigned char NIST_TEST_DATA_CFB_E9[] = {
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
};
unsigned char NIST_TEST_RESULT_CFB_E9[] = {
0xdc, 0x7e, 0x84, 0xbf, 0xda, 0x79, 0x16, 0x4b,
0x7e, 0xcd, 0x84, 0x86, 0x98, 0x5d, 0x38, 0x60,
};
unsigned int NIST_LCFB_E9 = 128 / 8;
/* CFB128 data -10- for AES256 */
unsigned char NIST_KEY_CFB_E10[] = {
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca,
0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61,
0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14,
};
0x71,
0x77,
0x08,
0xdf,
0xbe,
0x81,
0xd7,
0xf4,
unsigned char NIST_IV_CFB_E10[] = {
0xdc, 0x7e, 0x84, 0xbf, 0xda, 0x79, 0x16, 0x4b,
0x7e, 0xcd, 0x84, 0x86, 0x98, 0x5d, 0x38, 0x60,
};
unsigned char NIST_EXPECTED_IV_CFB_E10[] = {
0x39, 0xff, 0xed, 0x14, 0x3b, 0x28, 0xb1, 0xc8,
0x32, 0x11, 0x3c, 0x63, 0x31, 0xe5, 0x40, 0x7b,
};
unsigned char NIST_TEST_DATA_CFB_E10[] = {
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
};
unsigned char NIST_TEST_RESULT_CFB_E10[] = {
0x39, 0xff, 0xed, 0x14, 0x3b, 0x28, 0xb1, 0xc8,
0x32, 0x11, 0x3c, 0x63, 0x31, 0xe5, 0x40, 0x7b,
};
unsigned int NIST_LCFB_E10 = 128 / 8;
/* CFB8 data -11- for AES256 */
unsigned char NIST_KEY_CFB_E11[] = {
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca,
0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61,
0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14,
};
0x71,
0x77,
0x08,
0xdf,
0xbe,
0x81,
0xd7,
0xf4,
unsigned char NIST_IV_CFB_E11[] = {
Chapter 7. Examples
105
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
};
unsigned char NIST_EXPECTED_IV_CFB_E11[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xdc,
};
unsigned char NIST_TEST_DATA_CFB_E11[] = {
0x6b,
};
unsigned char NIST_TEST_RESULT_CFB_E11[] = {
0xdc,
};
unsigned int NIST_LCFB_E11 = 8 / 8;
/* CFB8 data -12- for AES256 */
unsigned char NIST_KEY_CFB_E12[] = {
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca,
0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61,
0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14,
};
0x71,
0x77,
0x08,
0xdf,
0xbe,
0x81,
0xd7,
0xf4,
unsigned char NIST_IV_CFB_E12[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xdc,
};
unsigned char NIST_EXPECTED_IV_CFB_E12[] = {
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xdc, 0x1f,
};
unsigned char NIST_TEST_DATA_CFB_E12[] = {
0xc1,
};
unsigned char NIST_TEST_RESULT_CFB_E12[] = {
0x1f,
};
unsigned int NIST_LCFB_E12 = 8 / 8;
void dump_array(unsigned char *ptr, unsigned int size)
{
unsigned char *ptr_end;
unsigned char *h;
int i = 1;
h = ptr;
ptr_end = ptr + size;
while (h < (unsigned char *)ptr_end) {
printf("0x%02x ",(unsigned char ) *h);
h++;
if (i == 8) {
printf("\n");
i = 1;
} else {
++i;
}
}
printf("\n");
106
libica Programmer's Reference
}
void dump_cfb_data(unsigned char *iv, unsigned int iv_length,
unsigned char *key, unsigned int key_length,
unsigned char *input_data, unsigned int data_length,
unsigned char *output_data)
{
printf("IV \n");
dump_array(iv, iv_length);
printf("Key \n");
dump_array(key, key_length);
printf("Input Data\n");
dump_array(input_data, data_length);
printf("Output Data\n");
dump_array(output_data, data_length);
}
void get_sizes(unsigned int *data_length, unsigned int *iv_length,
unsigned int *key_length, unsigned int iteration)
{
switch (iteration) {
case 1:
*data_length = sizeof(NIST_TEST_DATA_CFB_E1);
*iv_length = sizeof(NIST_IV_CFB_E1);
*key_length = sizeof(NIST_KEY_CFB_E1);
break;
case 2:
*data_length = sizeof(NIST_TEST_DATA_CFB_E2);
*iv_length = sizeof(NIST_IV_CFB_E2);
*key_length = sizeof(NIST_KEY_CFB_E2);
break;
case 3:
*data_length = sizeof(NIST_TEST_DATA_CFB_E3);
*iv_length = sizeof(NIST_IV_CFB_E3);
*key_length = sizeof(NIST_KEY_CFB_E3);
break;
case 4:
*data_length = sizeof(NIST_TEST_DATA_CFB_E4);
*iv_length = sizeof(NIST_IV_CFB_E4);
*key_length = sizeof(NIST_KEY_CFB_E4);
break;
case 5:
*data_length = sizeof(NIST_TEST_DATA_CFB_E5);
*iv_length = sizeof(NIST_IV_CFB_E5);
*key_length = sizeof(NIST_KEY_CFB_E5);
break;
case 6:
*data_length = sizeof(NIST_TEST_DATA_CFB_E6);
*iv_length = sizeof(NIST_IV_CFB_E6);
*key_length = sizeof(NIST_KEY_CFB_E6);
break;
case 7:
*data_length = sizeof(NIST_TEST_DATA_CFB_E7);
*iv_length = sizeof(NIST_IV_CFB_E7);
*key_length = sizeof(NIST_KEY_CFB_E7);
break;
case 8:
*data_length = sizeof(NIST_TEST_DATA_CFB_E8);
*iv_length = sizeof(NIST_IV_CFB_E8);
*key_length = sizeof(NIST_KEY_CFB_E8);
break;
case 9:
*data_length = sizeof(NIST_TEST_DATA_CFB_E9);
*iv_length = sizeof(NIST_IV_CFB_E9);
*key_length = sizeof(NIST_KEY_CFB_E9);
break;
case 10:
Chapter 7. Examples
107
*data_length = sizeof(NIST_TEST_DATA_CFB_E10);
*iv_length = sizeof(NIST_IV_CFB_E10);
*key_length = sizeof(NIST_KEY_CFB_E10);
break;
case 11:
*data_length = sizeof(NIST_TEST_DATA_CFB_E11);
*iv_length = sizeof(NIST_IV_CFB_E11);
*key_length = sizeof(NIST_KEY_CFB_E11);
break;
case 12:
*data_length = sizeof(NIST_TEST_DATA_CFB_E12);
*iv_length = sizeof(NIST_IV_CFB_E12);
*key_length = sizeof(NIST_KEY_CFB_E12);
break;
}
}
void load_test_data(unsigned char *data, unsigned int data_length,
unsigned char *result,
unsigned char *iv, unsigned char *expected_iv,
unsigned int iv_length,
unsigned char *key, unsigned int key_length,
unsigned int *lcfb, unsigned int iteration)
{
switch (iteration) {
case 1:
memcpy(data, NIST_TEST_DATA_CFB_E1, data_length);
memcpy(result, NIST_TEST_RESULT_CFB_E1, data_length);
memcpy(iv, NIST_IV_CFB_E1, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E1, iv_length);
memcpy(key, NIST_KEY_CFB_E1, key_length);
*lcfb = NIST_LCFB_E1;
break;
case 2:
memcpy(data, NIST_TEST_DATA_CFB_E2, data_length);
memcpy(result, NIST_TEST_RESULT_CFB_E2, data_length);
memcpy(iv, NIST_IV_CFB_E2, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E2, iv_length);
memcpy(key, NIST_KEY_CFB_E2, key_length);
*lcfb = NIST_LCFB_E2;
break;
case 3:
memcpy(data, NIST_TEST_DATA_CFB_E3, data_length);
memcpy(result, NIST_TEST_RESULT_CFB_E3, data_length);
memcpy(iv, NIST_IV_CFB_E3, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E3, iv_length);
memcpy(key, NIST_KEY_CFB_E3, key_length);
*lcfb = NIST_LCFB_E3;
break;
case 4:
memcpy(data, NIST_TEST_DATA_CFB_E4, data_length);
memcpy(result, NIST_TEST_RESULT_CFB_E4, data_length);
memcpy(iv, NIST_IV_CFB_E4, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E4, iv_length);
memcpy(key, NIST_KEY_CFB_E4, key_length);
*lcfb = NIST_LCFB_E4;
break;
case 5:
memcpy(data, NIST_TEST_DATA_CFB_E5, data_length);
memcpy(result, NIST_TEST_RESULT_CFB_E5, data_length);
memcpy(iv, NIST_IV_CFB_E5, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E5, iv_length);
memcpy(key, NIST_KEY_CFB_E5, key_length);
*lcfb = NIST_LCFB_E5;
break;
case 6:
108
libica Programmer's Reference
memcpy(data, NIST_TEST_DATA_CFB_E6, data_length);
memcpy(result, NIST_TEST_RESULT_CFB_E6, data_length);
memcpy(iv, NIST_IV_CFB_E6, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E6, iv_length);
memcpy(key, NIST_KEY_CFB_E6, key_length);
*lcfb = NIST_LCFB_E6;
break;
case 7:
memcpy(data, NIST_TEST_DATA_CFB_E7, data_length);
memcpy(result, NIST_TEST_RESULT_CFB_E7, data_length);
memcpy(iv, NIST_IV_CFB_E7, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E7, iv_length);
memcpy(key, NIST_KEY_CFB_E7, key_length);
*lcfb = NIST_LCFB_E7;
break;
case 8:
memcpy(data, NIST_TEST_DATA_CFB_E8, data_length);
memcpy(result, NIST_TEST_RESULT_CFB_E8, data_length);
memcpy(iv, NIST_IV_CFB_E8, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E8, iv_length);
memcpy(key, NIST_KEY_CFB_E8, key_length);
*lcfb = NIST_LCFB_E8;
break;
case 9:
memcpy(data, NIST_TEST_DATA_CFB_E9, data_length);
memcpy(result, NIST_TEST_RESULT_CFB_E9, data_length);
memcpy(iv, NIST_IV_CFB_E9, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E9, iv_length);
memcpy(key, NIST_KEY_CFB_E9, key_length);
*lcfb = NIST_LCFB_E9;
break;
case 10:
memcpy(data, NIST_TEST_DATA_CFB_E10, data_length);
memcpy(result, NIST_TEST_RESULT_CFB_E10, data_length);
memcpy(iv, NIST_IV_CFB_E10, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E10, iv_length);
memcpy(key, NIST_KEY_CFB_E10, key_length);
*lcfb = NIST_LCFB_E10;
break;
case 11:
memcpy(data, NIST_TEST_DATA_CFB_E11, data_length);
memcpy(result, NIST_TEST_RESULT_CFB_E11, data_length);
memcpy(iv, NIST_IV_CFB_E11, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E11, iv_length);
memcpy(key, NIST_KEY_CFB_E11, key_length);
*lcfb = NIST_LCFB_E11;
break;
case 12:
memcpy(data, NIST_TEST_DATA_CFB_E12, data_length);
memcpy(result, NIST_TEST_RESULT_CFB_E12, data_length);
memcpy(iv, NIST_IV_CFB_E12, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E12, iv_length);
memcpy(key, NIST_KEY_CFB_E12, key_length);
*lcfb = NIST_LCFB_E12;
break;
}
}
int kat_aes_cfb(int iteration, int silent)
{
unsigned int data_length;
unsigned int iv_length;
unsigned int key_length;
get_sizes(&data_length, &iv_length, &key_length, iteration);
Chapter 7. Examples
109
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
char
char
char
char
char
char
char
char
iv[iv_length];
tmp_iv[iv_length];
expected_iv[iv_length];
key[key_length];
input_data[data_length];
encrypt[data_length];
decrypt[data_length];
result[data_length];
int rc = 0;
unsigned int lcfb;
memset(encrypt, 0x00, data_length);
memset(decrypt, 0x00, data_length);
load_test_data(input_data, data_length, result, iv, expected_iv,
iv_length, key, key_length, &lcfb, iteration);
memcpy(tmp_iv, iv, iv_length);
printf("Test Parameters for iteration = %i\n", iteration);
printf("key length = %i, data length = %i, iv length = %i,"
" lcfb = %i\n", key_length, data_length, iv_length, lcfb);
if (iteration == 3)
rc = ica_aes_cfb(input_data, encrypt, lcfb, key, key_length, tmp_iv,
lcfb, 1);
else
rc = ica_aes_cfb(input_data, encrypt, data_length, key, key_length,
tmp_iv, lcfb, 1);
if (rc) {
printf("ica_aes_cfb encrypt failed with rc = %i\n", rc);
dump_cfb_data(iv, iv_length, key, key_length, input_data,
data_length, encrypt);
}
if (!silent && !rc) {
printf("Encrypt:\n");
dump_cfb_data(iv, iv_length, key, key_length, input_data,
data_length, encrypt);
}
if (memcmp(result, encrypt, data_length)) {
printf("Encryption Result does not match the known ciphertext!\n");
printf("Expected data:\n");
dump_array(result, data_length);
printf("Encryption Result:\n");
dump_array(encrypt, data_length);
rc++;
}
if (memcmp(expected_iv, tmp_iv, iv_length)) {
printf("Update of IV does not match the expected IV!\n");
printf("Expected IV:\n");
dump_array(expected_iv, iv_length);
printf("Updated IV:\n");
dump_array(tmp_iv, iv_length);
printf("Original IV:\n");
dump_array(iv, iv_length);
rc++;
}
if (rc) {
printf("AES OFB test exited after encryption\n");
return rc;
}
memcpy(tmp_iv, iv, iv_length);
if (iteration == 3)
rc = ica_aes_cfb(encrypt, decrypt, lcfb, key, key_length, tmp_iv,
110
libica Programmer's Reference
lcfb, 0);
else
rc = ica_aes_cfb(encrypt, decrypt, data_length, key, key_length,
tmp_iv, lcfb, 0);
if (rc) {
printf("ica_aes_cfb decrypt failed with rc = %i\n", rc);
dump_cfb_data(iv, iv_length, key, key_length, encrypt,
data_length, decrypt);
return rc;
}
if (!silent && !rc) {
printf("Decrypt:\n");
dump_cfb_data(iv, iv_length, key, key_length, encrypt,
data_length, decrypt);
}
if (memcmp(decrypt, input_data, data_length)) {
printf("Decryption Result does not match the original data!\n");
printf("Original data:\n");
dump_array(input_data, data_length);
printf("Decryption Result:\n");
dump_array(decrypt, data_length);
rc++;
}
return rc;
}
int load_random_test_data(unsigned char *data, unsigned int data_length,
unsigned char *iv, unsigned int iv_length,
unsigned char *key, unsigned int key_length)
{
int rc;
rc = ica_random_number_generate(data_length, data);
if (rc) {
printf("ica_random_number_generate with rc = %i errnor = %i\n",
rc, errno);
return rc;
}
rc = ica_random_number_generate(iv_length, iv);
if (rc) {
printf("ica_random_number_generate with rc = %i errnor = %i\n",
rc, errno);
return rc;
}
rc = ica_random_number_generate(key_length, key);
if (rc) {
printf("ica_random_number_generate with rc = %i errnor = %i\n",
rc, errno);
return rc;
}
return rc;
}
int random_aes_cfb(int iteration, int silent, unsigned int data_length,
unsigned int lcfb)
{
unsigned int iv_length = sizeof(ica_aes_vector_t);
unsigned int key_length = AES_KEY_LEN128;
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
char
char
char
char
char
char
iv[iv_length];
tmp_iv[iv_length];
key[key_length];
input_data[data_length];
encrypt[data_length];
decrypt[data_length];
Chapter 7. Examples
111
int rc = 0;
for (key_length = AES_KEY_LEN128; key_length <= AES_KEY_LEN256; key_length += 8) {
memset(encrypt, 0x00, data_length);
memset(decrypt, 0x00, data_length);
load_random_test_data(input_data, data_length, iv, iv_length, key,
key_length);
memcpy(tmp_iv, iv, iv_length);
printf("Test Parameters for iteration = %i\n", iteration);
printf("key length = %i, data length = %i, iv length = %i,"
" lcfb = %i\n", key_length, data_length, iv_length, lcfb);
rc = ica_aes_cfb(input_data, encrypt, data_length, key, key_length,
tmp_iv, lcfb, 1);
if (rc) {
printf("ica_aes_cfb encrypt failed with rc = %i\n", rc);
dump_cfb_data(iv, iv_length, key, key_length, input_data,
data_length, encrypt);
}
if (!silent && !rc) {
printf("Encrypt:\n");
dump_cfb_data(iv, iv_length, key, key_length, input_data,
data_length, encrypt);
}
if (rc) {
printf("AES OFB test exited after encryption\n");
return rc;
}
memcpy(tmp_iv, iv, iv_length);
rc = ica_aes_cfb(encrypt, decrypt, data_length, key, key_length,
tmp_iv, lcfb, 0);
if (rc) {
printf("ica_aes_cfb decrypt failed with rc = %i\n", rc);
dump_cfb_data(iv, iv_length, key, key_length, encrypt,
data_length, decrypt);
return rc;
}
if (!silent && !rc) {
printf("Decrypt:\n");
dump_cfb_data(iv, iv_length, key, key_length, encrypt,
data_length, decrypt);
}
if (memcmp(decrypt, input_data, data_length)) {
printf("Decryption Result does not match the original data!\n");
printf("Original data:\n");
dump_array(input_data, data_length);
printf("Decryption Result:\n");
dump_array(decrypt, data_length);
rc++;
}
}
return rc;
}
int main(int argc, char **argv)
{
unsigned int silent = 0;
unsigned int endless = 0;
if (argc > 1) {
112
libica Programmer's Reference
if (strstr(argv[1], "silent"))
silent = 1;
if (strstr(argv[1], "endless"))
endless = 1;
}
int rc = 0;
int error_count = 0;
int iteration;
for(iteration = 1; iteration <= NR_TESTS; iteration++) {
rc = kat_aes_cfb(iteration, silent);
if (rc) {
printf("kat_aes_cfb failed with rc = %i\n", rc);
error_count++;
} else
printf("kat_aes_cfb finished successfuly\n");
}
unsigned int data_length = 1;
unsigned int lcfb = 1;
unsigned int j;
for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) {
for (j = 1; j <= 3; j++) {
int silent = 1;
if (!(data_length % lcfb)) {
rc = random_aes_cfb(iteration, silent, data_length, lcfb);
if (rc) {
printf("random_aes_cfb failed with rc = %i\n", rc);
error_count++;
} else
printf("random_aes_cfb finished successfuly\n");
}
switch (j) {
case 1:
lcfb = 1;
break;
case 2:
lcfb = 8;
break;
case 3:
lcfb = 16;
break;
}
}
if (data_length == 1)
data_length = 8;
else
data_length += 8;
}
if (error_count)
printf("%i testcases failed\n", error_count);
else
printf("All testcases finished successfully\n");
return rc;
}
AES with CTR mode example
/* This program is released under the Common Public License V1.0
*
* You should have received a copy of Common Public License V1.0 along with
* with this program.
*/
/* Copyright IBM Corp. 2010, 2011 */
#include <fcntl.h>
Chapter 7. Examples
113
#include
#include
#include
#include
#include
#include
<sys/errno.h>
<stdio.h>
<string.h>
<strings.h>
<stdlib.h>
"ica_api.h"
#define NR_TESTS 7
/* CTR data - 1 for AES128 */
unsigned char NIST_KEY_CTR_E1[] = {
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
};
unsigned char NIST_IV_CTR_E1[] = {
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
};
unsigned char NIST_EXPECTED_IV_CTR_E1[] = {
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xff, 0x00,
};
unsigned char NIST_TEST_DATA_CTR_E1[] = {
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
};
unsigned char NIST_TEST_RESULT_CTR_E1[] = {
0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26,
0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce,
};
/* CTR data - 2 for AES128 */
unsigned char NIST_KEY_CTR_E2[] = {
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
};
unsigned char NIST_IV_CTR_E2[] = {
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
};
unsigned char NIST_EXPECTED_IV_CTR_E2[] = {
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xff, 0x03,
};
unsigned char NIST_TEST_DATA_CTR_E2[] = {
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17,
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac,
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e,
0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4,
0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52,
0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b,
0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37,
};
0x96,
0x2a,
0x9c,
0x51,
0x11,
0xef,
0x17,
0x10,
unsigned char NIST_TEST_RESULT_CTR_E2[] = {
0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26,
0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce,
0x98, 0x06, 0xf6, 0x6b, 0x79, 0x70, 0xfd, 0xff,
0x86, 0x17, 0x18, 0x7b, 0xb9, 0xff, 0xfd, 0xff,
114
libica Programmer's Reference
0x5a,
0x5b,
0x1e,
0x79,
};
0xe4,
0x4f,
0x03,
0x21,
0xdf,
0x09,
0x1d,
0x70,
0x3e,
0x02,
0xda,
0xa0,
0xdb,
0x0d,
0x2f,
0xf3,
0xd5,
0xb0,
0xbe,
0x00,
/* CTR data - 3 - for AES192 */
unsigned char NIST_KEY_CTR_E3[] = {
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca,
0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61,
0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14,
};
0xd3,
0x3e,
0x03,
0x9c,
0x5e,
0xab,
0xd1,
0xee,
0x71,
0x77,
0x08,
0xdf,
0xbe,
0x81,
0xd7,
0xf4,
unsigned char NIST_IV_CTR_E3[] = {
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
};
unsigned char NIST_EXPECTED_IV_CTR_E3[] = {
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xff, 0x00,
};
unsigned char NIST_TEST_DATA_CTR_E3[] = {
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
};
unsigned char NIST_TEST_RESULT_CTR_E3[] = {
0x60, 0x1e, 0xc3, 0x13, 0x77, 0x57, 0x89, 0xa5,
0xb7, 0xa7, 0xf5, 0x04, 0xbb, 0xf3, 0xd2, 0x28,
};
/* CTR data - 4 - for AES192 */
unsigned char NIST_KEY_CTR_E4[] = {
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca,
0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61,
0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14,
};
0x71,
0x77,
0x08,
0xdf,
0xbe,
0x81,
0xd7,
0xf4,
unsigned char NIST_IV_CTR_E4[] = {
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xff, 0x00,
};
unsigned char NIST_EXPECTED_IV_CTR_E4[] = {
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xff, 0x01,
};
unsigned char NIST_TEST_DATA_CTR_E4[] = {
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
};
unsigned char NIST_TEST_RESULT_CTR_E4[] = {
0xf4, 0x43, 0xe3, 0xca, 0x4d, 0x62, 0xb5, 0x9a,
0xca, 0x84, 0xe9, 0x90, 0xca, 0xca, 0xf5, 0xc5,
};
/* CTR data 5 - for AES 256 */
unsigned char NIST_KEY_CTR_E5[] = {
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
Chapter 7. Examples
115
0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4,
};
unsigned char NIST_IV_CTR_E5[] = {
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
};
unsigned char NIST_EXPECTED_IV_CTR_E5[] = {
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xff, 0x03,
};
unsigned char NIST_TEST_DATA_CTR_E5[] = {
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17,
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac,
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e,
0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4,
0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52,
0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b,
0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37,
};
0x96,
0x2a,
0x9c,
0x51,
0x11,
0xef,
0x17,
0x10,
unsigned char NIST_TEST_RESULT_CTR_E5[] = {
0x60, 0x1e, 0xc3, 0x13, 0x77, 0x57, 0x89, 0xa5,
0xb7, 0xa7, 0xf5, 0x04, 0xbb, 0xf3, 0xd2, 0x28,
0xf4, 0x43, 0xe3, 0xca, 0x4d, 0x62, 0xb5, 0x9a,
0xca, 0x84, 0xe9, 0x90, 0xca, 0xca, 0xf5, 0xc5,
0x2b, 0x09, 0x30, 0xda, 0xa2, 0x3d, 0xe9, 0x4c,
0xe8, 0x70, 0x17, 0xba, 0x2d, 0x84, 0x98, 0x8d,
0xdf, 0xc9, 0xc5, 0x8d, 0xb6, 0x7a, 0xad, 0xa6,
0x13, 0xc2, 0xdd, 0x08, 0x45, 0x79, 0x41, 0xa6,
};
/* CTR data 6 - for AES 256.
* Data is != BLOCK_SIZE */
unsigned char NIST_KEY_CTR_E6[] = {
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca,
0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61,
0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14,
};
0x71,
0x77,
0x08,
0xdf,
0xbe,
0x81,
0xd7,
0xf4,
unsigned char NIST_IV_CTR_E6[] = {
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
};
unsigned char NIST_EXPECTED_IV_CTR_E6[] = {
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xff, 0x03,
};
unsigned char NIST_TEST_DATA_CTR_E6[] = {
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17,
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac,
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e,
0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4,
0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52,
0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b,
};
0x96,
0x2a,
0x9c,
0x51,
0x11,
0xef,
0x17,
unsigned char NIST_TEST_RESULT_CTR_E6[] = {
0x60, 0x1e, 0xc3, 0x13, 0x77, 0x57, 0x89, 0xa5,
0xb7, 0xa7, 0xf5, 0x04, 0xbb, 0xf3, 0xd2, 0x28,
116
libica Programmer's Reference
0xf4,
0xca,
0x2b,
0xe8,
0xdf,
};
0x43,
0x84,
0x09,
0x70,
0xc9,
0xe3,
0xe9,
0x30,
0x17,
0xc5,
0xca,
0x90,
0xda,
0xba,
0x8d,
0x4d,
0xca,
0xa2,
0x2d,
0xb6,
0x62,
0xca,
0x3d,
0x84,
0x7a,
0xb5,
0xf5,
0xe9,
0x98,
0xad,
0x9a,
0xc5,
0x4c,
0x8d,
0xa6,
/* CTR data 7 - for AES 256
* Counter as big as the data. Therefore the counter
* should not be updated. Because it is already pre
* computed. */
unsigned char NIST_KEY_CTR_E7[] = {
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4,
};
unsigned char NIST_IV_CTR_E7[]
0xf0, 0xf1, 0xf2, 0xf3, 0xf4,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc,
};
= {
0xf5,
0xfd,
0xf5,
0xfd,
0xf5,
0xfd,
0xf5,
0xfd,
0xf6,
0xfe,
0xf6,
0xff,
0xf6,
0xff,
0xf6,
0xff,
0xf7,
0xff,
0xf7,
0x00,
0xf7,
0x01,
0xf7,
0x02,
unsigned char NIST_EXPECTED_IV_CTR_E7[] = {
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xff, 0x00,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xff, 0x01,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xff, 0x02,
};
unsigned char NIST_TEST_DATA_CTR_E7[] = {
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17,
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac,
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e,
0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4,
0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52,
0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b,
0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37,
};
0x96,
0x2a,
0x9c,
0x51,
0x11,
0xef,
0x17,
0x10,
unsigned char NIST_TEST_RESULT_CTR_E7[] = {
0x60, 0x1e, 0xc3, 0x13, 0x77, 0x57, 0x89, 0xa5,
0xb7, 0xa7, 0xf5, 0x04, 0xbb, 0xf3, 0xd2, 0x28,
0xf4, 0x43, 0xe3, 0xca, 0x4d, 0x62, 0xb5, 0x9a,
0xca, 0x84, 0xe9, 0x90, 0xca, 0xca, 0xf5, 0xc5,
0x2b, 0x09, 0x30, 0xda, 0xa2, 0x3d, 0xe9, 0x4c,
0xe8, 0x70, 0x17, 0xba, 0x2d, 0x84, 0x98, 0x8d,
0xdf, 0xc9, 0xc5, 0x8d, 0xb6, 0x7a, 0xad, 0xa6,
0x13, 0xc2, 0xdd, 0x08, 0x45, 0x79, 0x41, 0xa6,
};
void dump_array(unsigned char *ptr, unsigned int size)
{
unsigned char *ptr_end;
unsigned char *h;
Chapter 7. Examples
117
int i = 1;
h = ptr;
ptr_end = ptr + size;
while (h < (unsigned char *)ptr_end) {
printf("0x%02x ",(unsigned char ) *h);
h++;
if (i == 8) {
printf("\n");
i = 1;
} else {
++i;
}
}
printf("\n");
}
void dump_ctr_data(unsigned char *iv, unsigned int iv_length,
unsigned char *key, unsigned int key_length,
unsigned char *input_data, unsigned int data_length,
unsigned char *output_data)
{
printf("IV \n");
dump_array(iv, iv_length);
printf("Key \n");
dump_array(key, key_length);
printf("Input Data\n");
dump_array(input_data, data_length);
printf("Output Data\n");
dump_array(output_data, data_length);
}
void get_sizes(unsigned int *data_length, unsigned int *iv_length,
unsigned int *key_length, unsigned int iteration)
{
switch (iteration) {
case 1:
*data_length = sizeof(NIST_TEST_DATA_CTR_E1);
*iv_length = sizeof(NIST_IV_CTR_E1);
*key_length = sizeof(NIST_KEY_CTR_E1);
break;
case 2:
*data_length = sizeof(NIST_TEST_DATA_CTR_E2);
*iv_length = sizeof(NIST_IV_CTR_E2);
*key_length = sizeof(NIST_KEY_CTR_E2);
break;
case 3:
*data_length = sizeof(NIST_TEST_DATA_CTR_E3);
*iv_length = sizeof(NIST_IV_CTR_E3);
*key_length = sizeof(NIST_KEY_CTR_E3);
break;
case 4:
*data_length = sizeof(NIST_TEST_DATA_CTR_E4);
*iv_length = sizeof(NIST_IV_CTR_E4);
*key_length = sizeof(NIST_KEY_CTR_E4);
break;
case 5:
*data_length = sizeof(NIST_TEST_DATA_CTR_E5);
*iv_length = sizeof(NIST_IV_CTR_E5);
*key_length = sizeof(NIST_KEY_CTR_E5);
break;
case 6:
*data_length = sizeof(NIST_TEST_DATA_CTR_E6);
*iv_length = sizeof(NIST_IV_CTR_E6);
*key_length = sizeof(NIST_KEY_CTR_E6);
break;
case 7:
118
libica Programmer's Reference
*data_length = sizeof(NIST_TEST_DATA_CTR_E7);
*iv_length = sizeof(NIST_IV_CTR_E7);
*key_length = sizeof(NIST_KEY_CTR_E7);
break;
}
}
void load_test_data(unsigned char *data, unsigned int data_length,
unsigned char *result,
unsigned char *iv, unsigned char *expected_iv,
unsigned int iv_length,
unsigned char *key, unsigned int key_length,
unsigned int iteration)
{
switch (iteration) {
case 1:
memcpy(data, NIST_TEST_DATA_CTR_E1, data_length);
memcpy(result, NIST_TEST_RESULT_CTR_E1, data_length);
memcpy(iv, NIST_IV_CTR_E1, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_CTR_E1, iv_length);
memcpy(key, NIST_KEY_CTR_E1, key_length);
break;
case 2:
memcpy(data, NIST_TEST_DATA_CTR_E2, data_length);
memcpy(result, NIST_TEST_RESULT_CTR_E2, data_length);
memcpy(iv, NIST_IV_CTR_E2, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_CTR_E2, iv_length);
memcpy(key, NIST_KEY_CTR_E2, key_length);
break;
case 3:
memcpy(data, NIST_TEST_DATA_CTR_E3, data_length);
memcpy(result, NIST_TEST_RESULT_CTR_E3, data_length);
memcpy(iv, NIST_IV_CTR_E3, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_CTR_E3, iv_length);
memcpy(key, NIST_KEY_CTR_E3, key_length);
break;
case 4:
memcpy(data, NIST_TEST_DATA_CTR_E4, data_length);
memcpy(result, NIST_TEST_RESULT_CTR_E4, data_length);
memcpy(iv, NIST_IV_CTR_E4, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_CTR_E4, iv_length);
memcpy(key, NIST_KEY_CTR_E4, key_length);
break;
case 5:
memcpy(data, NIST_TEST_DATA_CTR_E5, data_length);
memcpy(result, NIST_TEST_RESULT_CTR_E5, data_length);
memcpy(iv, NIST_IV_CTR_E5, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_CTR_E5, iv_length);
memcpy(key, NIST_KEY_CTR_E5, key_length);
break;
case 6:
memcpy(data, NIST_TEST_DATA_CTR_E6, data_length);
memcpy(result, NIST_TEST_RESULT_CTR_E6, data_length);
memcpy(iv, NIST_IV_CTR_E6, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_CTR_E6, iv_length);
memcpy(key, NIST_KEY_CTR_E6, key_length);
break;
case 7:
memcpy(data, NIST_TEST_DATA_CTR_E7, data_length);
memcpy(result, NIST_TEST_RESULT_CTR_E7, data_length);
memcpy(iv, NIST_IV_CTR_E7, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_CTR_E7, iv_length);
memcpy(key, NIST_KEY_CTR_E7, key_length);
break;
}
Chapter 7. Examples
119
}
int random_aes_ctr(int iteration, int silent, unsigned int data_length, unsigned int iv_length)
{
unsigned int key_length = AES_KEY_LEN256;
if (data_length % sizeof(ica_aes_vector_t))
iv_length = sizeof(ica_aes_vector_t);
printf("Test Parameters for iteration = %i\n", iteration);
printf("key length = %i, data length = %i, iv length = %i\n",
key_length, data_length, iv_length);
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
char
char
char
char
char
char
iv[iv_length];
tmp_iv[iv_length];
key[key_length];
input_data[data_length];
encrypt[data_length];
decrypt[data_length];
int rc = 0;
rc = ica_random_number_generate(data_length, input_data);
if (rc) {
printf("random number generate returned rc = %i, errno = %i\n", rc, errno);
return rc;
}
rc = ica_random_number_generate(iv_length, iv);
if (rc) {
printf("random number generate returned rc = %i, errno = %i\n", rc, errno);
return rc;
}
rc = ica_random_number_generate(key_length, key);
if (rc) {
printf("random number generate returned rc = %i, errno = %i\n", rc, errno);
return rc;
}
memcpy(tmp_iv, iv, iv_length);
rc = ica_aes_ctr(input_data, encrypt, data_length, key, key_length,
tmp_iv, 32, 1);
if (rc) {
printf("ica_aes_ctr encrypt failed with rc = %i\n", rc);
dump_ctr_data(iv, iv_length, key, key_length, input_data,
data_length, encrypt);
return rc;
}
if (!silent && !rc) {
printf("Encrypt:\n");
dump_ctr_data(iv, iv_length, key, key_length, input_data,
data_length, encrypt);
}
memcpy(tmp_iv, iv, iv_length);
rc = ica_aes_ctr(encrypt, decrypt, data_length, key, key_length,
tmp_iv, 32, 0);
if (rc) {
printf("ica_aes_ctr decrypt failed with rc = %i\n", rc);
dump_ctr_data(iv, iv_length, key, key_length, encrypt,
data_length, decrypt);
return rc;
}
if (!silent && !rc) {
printf("Decrypt:\n");
dump_ctr_data(iv, iv_length, key, key_length, encrypt,
data_length, decrypt);
120
libica Programmer's Reference
}
if (memcmp(decrypt, input_data, data_length)) {
printf("Decryption Result does not match the original data!\n");
printf("Original data:\n");
dump_array(input_data, data_length);
printf("Decryption Result:\n");
dump_array(decrypt, data_length);
rc++;
}
return rc;
}
int kat_aes_ctr(int iteration, int silent)
{
unsigned int data_length;
unsigned int iv_length;
unsigned int key_length;
get_sizes(&data_length, &iv_length, &key_length, iteration);
printf("Test Parameters for iteration = %i\n", iteration);
printf("key length = %i, data length = %i, iv length = %i\n",
key_length, data_length, iv_length);
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
char
char
char
char
char
char
char
char
iv[iv_length];
tmp_iv[iv_length];
expected_iv[iv_length];
key[key_length];
input_data[data_length];
encrypt[data_length];
decrypt[data_length];
result[data_length];
int rc = 0;
load_test_data(input_data, data_length, result, iv, expected_iv,
iv_length, key, key_length, iteration);
memcpy(tmp_iv, iv, iv_length);
if (iv_length == 16)
rc = ica_aes_ctr(input_data, encrypt, data_length, key, key_length,
tmp_iv, 32, 1);
else
rc = ica_aes_ctrlist(input_data, encrypt, data_length, key, key_length,
tmp_iv, 1);
if (rc) {
printf("ica_aes_ctr encrypt failed with rc = %i\n", rc);
dump_ctr_data(iv, iv_length, key, key_length, input_data,
data_length, encrypt);
}
if (!silent && !rc) {
printf("Encrypt:\n");
dump_ctr_data(iv, iv_length, key, key_length, input_data,
data_length, encrypt);
}
if (memcmp(result, encrypt, data_length)) {
printf("Encryption Result does not match the known ciphertext!\n");
printf("Expected data:\n");
dump_array(result, data_length);
printf("Encryption Result:\n");
dump_array(encrypt, data_length);
rc++;
}
if (memcmp(expected_iv, tmp_iv, iv_length)) {
Chapter 7. Examples
121
printf("Update of IV does not match the expected IV!\n");
printf("Expected IV:\n");
dump_array(expected_iv, iv_length);
printf("Updated IV:\n");
dump_array(tmp_iv, iv_length);
printf("Original IV:\n");
dump_array(iv, iv_length);
rc++;
}
if (rc) {
printf("AES CTR test exited after encryption\n");
return rc;
}
memcpy(tmp_iv, iv, iv_length);
rc = ica_aes_ctr(encrypt, decrypt, data_length, key, key_length,
tmp_iv, 32,0);
if (rc) {
printf("ica_aes_ctr decrypt failed with rc = %i\n", rc);
dump_ctr_data(iv, iv_length, key, key_length, encrypt,
data_length, decrypt);
return rc;
}
if (!silent && !rc) {
printf("Decrypt:\n");
dump_ctr_data(iv, iv_length, key, key_length, encrypt,
data_length, decrypt);
}
if (memcmp(decrypt, input_data, data_length)) {
printf("Decryption Result does not match the original data!\n");
printf("Original data:\n");
dump_array(input_data, data_length);
printf("Decryption Result:\n");
dump_array(decrypt, data_length);
rc++;
}
return rc;
}
int main(int argc, char **argv)
{
// Default mode is 0. ECB,CBC and CFQ tests will be performed.
unsigned int silent = 0;
unsigned int endless = 0;
if (argc > 1) {
if (strstr(argv[1], "silent"))
silent = 1;
if (strstr(argv[1], "endless"))
endless = 1;
}
int rc = 0;
int error_count = 0;
int iteration;
if (!endless)
for(iteration = 1; iteration <= NR_TESTS; iteration++) {
rc = kat_aes_ctr(iteration, silent);
if (rc) {
printf("kat_aes_ctr failed with rc = %i\n", rc);
error_count++;
} else
printf("kat_aes_ctr finished successfuly\n");
}
int i = 0;
122
libica Programmer's Reference
if (endless)
while (1) {
printf("i = %i\n",i);
silent = 1;
rc = random_aes_ctr(i, silent, 320, 320);
if (rc) {
printf("kat_aes_ctr failed with rc = %i\n", rc);
return rc;
} else
printf("kat_aes_ctr finished successfuly\n");
i++;
}
if (error_count)
printf("%i testcases failed\n", error_count);
else
printf("All testcases finished successfully\n");
return rc;
}
AES with OFB mode example
/* This program is released under the Common Public License V1.0
*
* You should have received a copy of Common Public License V1.0 along with
* with this program.
*/
/* Copyright IBM Corp. 2010, 2011 */
#include <fcntl.h>
#include <sys/errno.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include "ica_api.h"
#define NR_TESTS 6
#define NR_RANDOM_TESTS 10000
/* OFB data - 1 for AES128 */
unsigned char NIST_KEY_OFB_E1[] = {
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
};
unsigned char NIST_IV_OFB_E1[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
};
unsigned char NIST_EXPECTED_IV_OFB_E1[] = {
0x50, 0xfe, 0x67, 0xcc, 0x99, 0x6d, 0x32, 0xb6,
0xda, 0x09, 0x37, 0xe9, 0x9b, 0xaf, 0xec, 0x60,
};
unsigned char NIST_TEST_DATA_OFB_E1[] = {
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
};
unsigned char NIST_TEST_RESULT_OFB_E1[] = {
0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20,
0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a,
};
Chapter 7. Examples
123
/* OFB data - 2 for AES128 */
unsigned char NIST_KEY_OFB_E2[] = {
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
};
unsigned char NIST_IV_OFB_E2[] = {
0x50, 0xfe, 0x67, 0xcc, 0x99, 0x6d, 0x32, 0xb6,
0xda, 0x09, 0x37, 0xe9, 0x9b, 0xaf, 0xec, 0x60,
};
unsigned char NIST_EXPECTED_IV_OFB_E2[] = {
0xd9, 0xa4, 0xda, 0xda, 0x08, 0x92, 0x23, 0x9f,
0x6b, 0x8b, 0x3d, 0x76, 0x80, 0xe1, 0x56, 0x74,
};
unsigned char NIST_TEST_DATA_OFB_E2[] = {
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
};
unsigned char NIST_TEST_RESULT_OFB_E2[] = {
0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
};
/* OFB data - 3 - for AES192 */
unsigned char NIST_KEY_OFB_E3[] = {
0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b,
};
unsigned char NIST_IV_OFB_E3[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
};
unsigned char NIST_EXPECTED_IV_OFB_E3[] = {
0xa6, 0x09, 0xb3, 0x8d, 0xf3, 0xb1, 0x13, 0x3d,
0xdd, 0xff, 0x27, 0x18, 0xba, 0x09, 0x56, 0x5e,
};
unsigned char NIST_TEST_DATA_OFB_E3[] = {
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
};
unsigned char NIST_TEST_RESULT_OFB_E3[] = {
0xcd, 0xc8, 0x0d, 0x6f, 0xdd, 0xf1, 0x8c, 0xab,
0x34, 0xc2, 0x59, 0x09, 0xc9, 0x9a, 0x41, 0x74,
};
/* OFB data - 4 - for AES192 */
unsigned char NIST_KEY_OFB_E4[] = {
0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52,
0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b,
};
unsigned char NIST_IV_OFB_E4[] = {
0xa6, 0x09, 0xb3, 0x8d, 0xf3, 0xb1, 0x13, 0x3d,
0xdd, 0xff, 0x27, 0x18, 0xba, 0x09, 0x56, 0x5e,
};
unsigned char NIST_EXPECTED_IV_OFB_E4[] = {
0x52, 0xef, 0x01, 0xda, 0x52, 0x60, 0x2f, 0xe0,
124
libica Programmer's Reference
0x97, 0x5f, 0x78, 0xac, 0x84, 0xbf, 0x8a, 0x50,
};
unsigned char NIST_TEST_DATA_OFB_E4[] = {
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
};
unsigned char NIST_TEST_RESULT_OFB_E4[] = {
0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
};
/* OFB data 5 - for AES 256 */
unsigned char NIST_KEY_OFB_E5[] = {
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca,
0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61,
0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14,
};
0x71,
0x77,
0x08,
0xdf,
0xbe,
0x81,
0xd7,
0xf4,
unsigned char NIST_IV_OFB_E5[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
};
unsigned char NIST_EXPECTED_IV_OFB_E5[] = {
0xb7, 0xbf, 0x3a, 0x5d, 0xf4, 0x39, 0x89, 0xdd,
0x97, 0xf0, 0xfa, 0x97, 0xeb, 0xce, 0x2f, 0x4a,
};
unsigned char NIST_TEST_DATA_OFB_E5[] = {
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
};
unsigned char NIST_TEST_RESULT_OFB_E5[] = {
0xdc, 0x7e, 0x84, 0xbf, 0xda, 0x79, 0x16, 0x4b,
0x7e, 0xcd, 0x84, 0x86, 0x98, 0x5d, 0x38, 0x60,
};
/* OFB data 6 - for AES 256 */
unsigned char NIST_KEY_OFB_E6[] = {
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca,
0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61,
0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14,
};
0x71,
0x77,
0x08,
0xdf,
0xbe,
0x81,
0xd7,
0xf4,
unsigned char NIST_IV_OFB_E6[] = {
0xb7, 0xbf, 0x3a, 0x5d, 0xf4, 0x39, 0x89, 0xdd,
0x97, 0xf0, 0xfa, 0x97, 0xeb, 0xce, 0x2f, 0x4a,
};
unsigned char NIST_EXPECTED_IV_OFB_E6[] = {
0xe1, 0xc6, 0x56, 0x30, 0x5e, 0xd1, 0xa7, 0xa6,
0x56, 0x38, 0x05, 0x74, 0x6f, 0xe0, 0x3e, 0xdc,
};
unsigned char NIST_TEST_DATA_OFB_E6[] = {
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
};
unsigned char NIST_TEST_RESULT_OFB_E6[] = {
0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
Chapter 7. Examples
125
};
void dump_array(unsigned char *ptr, unsigned int size)
{
unsigned char *ptr_end;
unsigned char *h;
int i = 1;
h = ptr;
ptr_end = ptr + size;
while (h < (unsigned char *)ptr_end) {
printf("0x%02x ",(unsigned char ) *h);
h++;
if (i == 8) {
printf("\n");
i = 1;
} else {
++i;
}
}
printf("\n");
}
void dump_ofb_data(unsigned char *iv, unsigned int iv_length,
unsigned char *key, unsigned int key_length,
unsigned char *input_data, unsigned int data_length,
unsigned char *output_data)
{
printf("IV \n");
dump_array(iv, iv_length);
printf("Key \n");
dump_array(key, key_length);
printf("Input Data\n");
dump_array(input_data, data_length);
printf("Output Data\n");
dump_array(output_data, data_length);
}
void get_sizes(unsigned int *data_length, unsigned int *iv_length,
unsigned int *key_length, unsigned int iteration)
{
switch (iteration) {
case 1:
*data_length = sizeof(NIST_TEST_DATA_OFB_E1);
*iv_length = sizeof(NIST_IV_OFB_E1);
*key_length = sizeof(NIST_KEY_OFB_E1);
break;
case 2:
*data_length = sizeof(NIST_TEST_DATA_OFB_E2);
*iv_length = sizeof(NIST_IV_OFB_E2);
*key_length = sizeof(NIST_KEY_OFB_E2);
break;
case 3:
*data_length = sizeof(NIST_TEST_DATA_OFB_E3);
*iv_length = sizeof(NIST_IV_OFB_E3);
*key_length = sizeof(NIST_KEY_OFB_E3);
break;
case 4:
*data_length = sizeof(NIST_TEST_DATA_OFB_E4);
*iv_length = sizeof(NIST_IV_OFB_E4);
*key_length = sizeof(NIST_KEY_OFB_E4);
break;
case 5:
*data_length = sizeof(NIST_TEST_DATA_OFB_E5);
*iv_length = sizeof(NIST_IV_OFB_E5);
*key_length = sizeof(NIST_KEY_OFB_E5);
126
libica Programmer's Reference
break;
case 6:
*data_length = sizeof(NIST_TEST_DATA_OFB_E6);
*iv_length = sizeof(NIST_IV_OFB_E6);
*key_length = sizeof(NIST_KEY_OFB_E6);
break;
}
}
void load_test_data(unsigned char *data, unsigned int data_length,
unsigned char *result,
unsigned char *iv, unsigned char *expected_iv,
unsigned int iv_length,
unsigned char *key, unsigned int key_length,
unsigned int iteration)
{
switch (iteration) {
case 1:
memcpy(data, NIST_TEST_DATA_OFB_E1, data_length);
memcpy(result, NIST_TEST_RESULT_OFB_E1, data_length);
memcpy(iv, NIST_IV_OFB_E1, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_OFB_E1, iv_length);
memcpy(key, NIST_KEY_OFB_E1, key_length);
break;
case 2:
memcpy(data, NIST_TEST_DATA_OFB_E2, data_length);
memcpy(result, NIST_TEST_RESULT_OFB_E2, data_length);
memcpy(iv, NIST_IV_OFB_E2, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_OFB_E2, iv_length);
memcpy(key, NIST_KEY_OFB_E2, key_length);
break;
case 3:
memcpy(data, NIST_TEST_DATA_OFB_E3, data_length);
memcpy(result, NIST_TEST_RESULT_OFB_E3, data_length);
memcpy(iv, NIST_IV_OFB_E3, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_OFB_E3, iv_length);
memcpy(key, NIST_KEY_OFB_E3, key_length);
break;
case 4:
memcpy(data, NIST_TEST_DATA_OFB_E4, data_length);
memcpy(result, NIST_TEST_RESULT_OFB_E4, data_length);
memcpy(iv, NIST_IV_OFB_E4, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_OFB_E4, iv_length);
memcpy(key, NIST_KEY_OFB_E4, key_length);
break;
case 5:
memcpy(data, NIST_TEST_DATA_OFB_E5, data_length);
memcpy(result, NIST_TEST_RESULT_OFB_E5, data_length);
memcpy(iv, NIST_IV_OFB_E5, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_OFB_E5, iv_length);
memcpy(key, NIST_KEY_OFB_E5, key_length);
break;
case 6:
memcpy(data, NIST_TEST_DATA_OFB_E6, data_length);
memcpy(result, NIST_TEST_RESULT_OFB_E6, data_length);
memcpy(iv, NIST_IV_OFB_E6, iv_length);
memcpy(expected_iv, NIST_EXPECTED_IV_OFB_E6, iv_length);
memcpy(key, NIST_KEY_OFB_E6, key_length);
break;
}
}
int load_random_test_data(unsigned char *data, unsigned int data_length,
unsigned char *iv, unsigned int iv_length,
unsigned char *key, unsigned int key_length)
Chapter 7. Examples
127
{
int rc;
rc = ica_random_number_generate(data_length, data);
if (rc) {
printf("ica_random_number_generate with rc = %i errnor = %i\n",
rc, errno);
return rc;
}
rc = ica_random_number_generate(iv_length, iv);
if (rc) {
printf("ica_random_number_generate with rc = %i errnor = %i\n",
rc, errno);
return rc;
}
rc = ica_random_number_generate(key_length, key);
if (rc) {
printf("ica_random_number_generate with rc = %i errnor = %i\n",
rc, errno);
return rc;
}
return rc;
}
int random_aes_ofb(int iteration, int silent, unsigned int data_length)
{
int i;
int rc = 0;
unsigned int iv_length = sizeof(ica_aes_vector_t);
unsigned int key_length = AES_KEY_LEN128;
unsigned char iv[iv_length];
unsigned char tmp_iv[iv_length];
unsigned char input_data[data_length];
unsigned char encrypt[data_length];
unsigned char decrypt[data_length];
for (i = 0; i <= 2; i++) {
unsigned char key[key_length];
memset(encrypt, 0x00, data_length);
memset(decrypt, 0x00, data_length);
load_random_test_data(input_data, data_length, iv, iv_length, key,
key_length);
memcpy(tmp_iv, iv, iv_length);
printf("Test Parameters for iteration = %i\n", iteration);
printf("key length = %i, data length = %i, iv length = %i\n",
key_length, data_length, iv_length);
rc = ica_aes_ofb(input_data, encrypt, data_length, key, key_length,
tmp_iv, 1);
if (rc) {
printf("ica_aes_ofb encrypt failed with rc = %i\n", rc);
dump_ofb_data(iv, iv_length, key, key_length, input_data,
data_length, encrypt);
}
if (!silent && !rc) {
printf("Encrypt:\n");
dump_ofb_data(iv, iv_length, key, key_length, input_data,
data_length, encrypt);
}
if (rc) {
printf("AES OFB test exited after encryption\n");
return rc;
}
memcpy(tmp_iv, iv, iv_length);
128
libica Programmer's Reference
rc = ica_aes_ofb(encrypt, decrypt, data_length, key, key_length,
tmp_iv, 0);
if (rc) {
printf("ica_aes_ofb decrypt failed with rc = %i\n", rc);
dump_ofb_data(iv, iv_length, key, key_length, encrypt,
data_length, decrypt);
return rc;
}
if (!silent && !rc) {
printf("Decrypt:\n");
dump_ofb_data(iv, iv_length, key, key_length, encrypt,
data_length, decrypt);
}
if (memcmp(decrypt, input_data, data_length)) {
printf("Decryption Result does not match the original data!\n");
printf("Original data:\n");
dump_array(input_data, data_length);
printf("Decryption Result:\n");
dump_array(decrypt, data_length);
rc++;
return rc;
}
key_length += 8;
}
return rc;
}
int kat_aes_ofb(int iteration, int silent)
{
unsigned int data_length;
unsigned int iv_length;
unsigned int key_length;
get_sizes(&data_length, &iv_length, &key_length, iteration);
printf("Test Parameters for iteration = %i\n", iteration);
printf("key length = %i, data length = %i, iv length = %i\n",
key_length, data_length, iv_length);
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
char
char
char
char
char
char
char
char
iv[iv_length];
tmp_iv[iv_length];
expected_iv[iv_length];
key[key_length];
input_data[data_length];
encrypt[data_length];
decrypt[data_length];
result[data_length];
int rc = 0;
load_test_data(input_data, data_length, result, iv, expected_iv,
iv_length, key, key_length, iteration);
memcpy(tmp_iv, iv, iv_length);
rc = ica_aes_ofb(input_data, encrypt, data_length, key, key_length,
tmp_iv, 1);
if (rc) {
printf("ica_aes_ofb encrypt failed with rc = %i\n", rc);
dump_ofb_data(iv, iv_length, key, key_length, input_data,
data_length, encrypt);
}
if (!silent && !rc) {
Chapter 7. Examples
129
printf("Encrypt:\n");
dump_ofb_data(iv, iv_length, key, key_length, input_data,
data_length, encrypt);
}
if (memcmp(result, encrypt, data_length)) {
printf("Encryption Result does not match the known ciphertext!\n");
printf("Expected data:\n");
dump_array(result, data_length);
printf("Encryption Result:\n");
dump_array(encrypt, data_length);
rc++;
}
if (memcmp(expected_iv, tmp_iv, iv_length)) {
printf("Update of IV does not match the expected IV!\n");
printf("Expected IV:\n");
dump_array(expected_iv, iv_length);
printf("Updated IV:\n");
dump_array(tmp_iv, iv_length);
printf("Original IV:\n");
dump_array(iv, iv_length);
rc++;
}
if (rc) {
printf("AES OFB test exited after encryption\n");
return rc;
}
memcpy(tmp_iv, iv, iv_length);
rc = ica_aes_ofb(encrypt, decrypt, data_length, key, key_length,
tmp_iv, 0);
if (rc) {
printf("ica_aes_ofb decrypt failed with rc = %i\n", rc);
dump_ofb_data(iv, iv_length, key, key_length, encrypt,
data_length, decrypt);
return rc;
}
if (!silent && !rc) {
printf("Decrypt:\n");
dump_ofb_data(iv, iv_length, key, key_length, encrypt,
data_length, decrypt);
}
if (memcmp(decrypt, input_data, data_length)) {
printf("Decryption Result does not match the original data!\n");
printf("Original data:\n");
dump_array(input_data, data_length);
printf("Decryption Result:\n");
dump_array(decrypt, data_length);
rc++;
}
return rc;
}
int main(int argc, char **argv)
{
unsigned int silent = 0;
if (argc > 1) {
if (strstr(argv[1], "silent"))
silent = 1;
}
int rc = 0;
int error_count = 0;
int iteration;
130
libica Programmer's Reference
unsigned int data_length = sizeof(ica_aes_vector_t);
for(iteration = 1; iteration <= NR_TESTS; iteration++) {
rc = kat_aes_ofb(iteration, silent);
if (rc) {
printf("kat_aes_ofb failed with rc = %i\n", rc);
error_count++;
} else
printf("kat_aes_ofb finished successfuly\n");
}
for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) {
int silent = 1;
rc = random_aes_ofb(iteration, silent, data_length);
if (rc) {
printf("random_aes_ofb failed with rc = %i\n", rc);
error_count++;
goto out;
} else
printf("random_aes_ofb finished successfuly\n");
data_length += sizeof(ica_aes_vector_t);
}
out:
if (error_count)
printf("%i testcases failed\n", error_count);
else
printf("All testcases finished successfully\n");
return rc;
}
AES with XTS mode example
/* This program is released under the Common Public License V1.0
*
* You should have received a copy of Common Public License V1.0 along with
* with this program.
*/
/* Copyright IBM Corp. 2010, 2011 */
#include <fcntl.h>
#include <sys/errno.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include "ica_api.h"
#define NR_TESTS 5
#define NR_RANDOM_TESTS 20000
/* XTS data -1- AES128 */
unsigned char NIST_KEY_XTS_E1[] = {
0x46, 0xe6, 0xed, 0x9e, 0xf4, 0x2d,
0xc8, 0x93, 0x09, 0x3c, 0x28, 0xe1,
0x91, 0xf5, 0xca, 0xa3, 0xb6, 0xe0,
0x14, 0xe7, 0x83, 0x21, 0x5c, 0x1d,
};
0xcd,
0xfc,
0xbc,
0x5b,
0xb3,
0x0f,
0x5a,
0x61,
unsigned char NIST_TWEAK_XTS_E1[] = {
0x72, 0xf3, 0xb0, 0x54, 0xcb, 0xdc, 0x2f, 0x9e,
0x3c, 0x5b, 0xc5, 0x51, 0xd4, 0x4d, 0xdb, 0xa0,
};
/* TWEAK should not be updated, so the exptected tweak is the same as the
* original TWEAK.
*/
Chapter 7. Examples
131
unsigned char NIST_EXPECTED_TWEAK_XTS_E1[] = {
0x72, 0xf3, 0xb0, 0x54, 0xcb, 0xdc, 0x2f, 0x9e,
0x3c, 0x5b, 0xc5, 0x51, 0xd4, 0x4d, 0xdb, 0xa0,
};
unsigned char NIST_TEST_DATA_XTS_E1[] = {
0xe3, 0x77, 0x8d, 0x68, 0xe7, 0x30, 0xef, 0x94,
0x5b, 0x4a, 0xe3, 0xbc, 0x5b, 0x93, 0x6b, 0xdd,
};
unsigned char NIST_TEST_RESULT_XTS_E1[] = {
0x97, 0x40, 0x9f, 0x1f, 0x71, 0xae, 0x45, 0x21,
0xcb, 0x49, 0xa3, 0x29, 0x73, 0xde, 0x4d, 0x05,
};
/* XTS data -2- AES128 */
unsigned char NIST_KEY_XTS_E2[] = {
0x93, 0x56, 0xcd, 0xad, 0x25, 0x1a,
0x14, 0xce, 0xc2, 0xc4, 0x4a, 0x60,
0xe9, 0xf7, 0x46, 0xcc, 0x65, 0xae,
0x96, 0x68, 0x64, 0xaa, 0x36, 0x26,
};
0xb6,
0x92,
0x3b,
0xd1,
0x11,
0xdd,
0xd4,
0x88,
unsigned char NIST_TWEAK_XTS_E2[] = {
0x68, 0x88, 0x27, 0x83, 0x65, 0x24, 0x36, 0xc4,
0x85, 0x7a, 0x88, 0xc0, 0xc3, 0x73, 0x41, 0x7e,
};
unsigned char NIST_EXPECTED_TWEAK_XTS_E2[] = {
0x68, 0x88, 0x27, 0x83, 0x65, 0x24, 0x36, 0xc4,
0x85, 0x7a, 0x88, 0xc0, 0xc3, 0x73, 0x41, 0x7e,
};
unsigned char NIST_TEST_DATA_XTS_E2[] = {
0xce, 0x17, 0x6b, 0xdd, 0xe3, 0x39, 0x50, 0x5b,
0xa1, 0x5d, 0xea, 0x36, 0xd2, 0x8c, 0xe8, 0x7d,
};
unsigned char NIST_TEST_RESULT_XTS_E2[] = {
0x22, 0xf5, 0xf9, 0x37, 0xdf, 0xb3, 0x9e, 0x5b,
0x74, 0x25, 0xed, 0x86, 0x3d, 0x31, 0x0b, 0xe1,
};
/* XTS data -3- AES128 */
unsigned char NIST_KEY_XTS_E3[] = {
0x63, 0xf3, 0x6e, 0x9c, 0x39, 0x7c,
0xc9, 0x9f, 0x16, 0x44, 0xec, 0xb1,
0xbc, 0x0f, 0x2f, 0x55, 0xfb, 0xe3,
0x4c, 0x39, 0x0f, 0xae, 0x75, 0x2a,
};
0x65,
0xa5,
0x24,
0xd4,
0x23,
0xd9,
0x44,
0xd7,
unsigned char NIST_TWEAK_XTS_E3[] = {
0xcd, 0xb1, 0xbd, 0x34, 0x86, 0xf3, 0x53, 0xcc,
0x16, 0x0a, 0x84, 0x0b, 0xea, 0xdf, 0x03, 0x29,
};
unsigned char NIST_EXPECTED_TWEAK_XTS_E3[] = {
0xcd, 0xb1, 0xbd, 0x34, 0x86, 0xf3, 0x53, 0xcc,
0x16, 0x0a, 0x84, 0x0b, 0xea, 0xdf, 0x03, 0x29,
};
unsigned char NIST_TEST_DATA_XTS_E3[] = {
0x9a, 0x01, 0x49, 0x88, 0x8b, 0xf7, 0x61,
0xa8, 0x14, 0x28, 0xbc, 0x91, 0x40, 0xec,
0x26, 0xed, 0x18, 0x36, 0x8e, 0x24, 0xd4,
0x9c, 0xc5, 0x12, 0x92, 0x9a, 0x88, 0xad,
0x66, 0xc7, 0x63, 0xf4, 0xf5, 0x6b, 0x63,
132
libica Programmer's Reference
0x60,
0xcd,
0x9b,
0x1e,
0xbb,
0x9d,
0xad,
0xee,
0x18,
0x60,
0x91,
0xfa,
0x96,
0x18,
0x42,
0xb5,
0xf2,
0x27,
0x73,
0x04,
0xb1,
0xe6,
0x5a,
0xe1,
0x0e,
0xc5,
0x87,
0x8b,
0xf7,
0x17,
0x97,
0x0e,
0x9e,
0x02,
0x44,
0xe6,
0x02,
0xd2,
0x68,
0x78,
0x43,
0x08,
0xce,
0xb6,
0xa5,
0xc1,
0x69,
0x53,
0xb3,
0xf6,
0x72,
0xd1,
0x92,
0x49,
0xfd,
0xc5,
0xe2,
0xab,
0x5d,
0x6e,
0xba,
0x43,
0xd4,
0x03,
};
0xd9,
0x98,
0x23,
0x54,
0x49,
0xab,
0xf9,
0x8f,
0xb6,
0x81,
0x16,
0x73,
0x7d,
0x40,
0x0f,
0x00,
0x4f,
0xee,
0x72,
0xc9,
0x1a,
0xeb,
0xf5,
0x02,
0x49,
0x99,
0xe7,
0x96,
0x3d,
0xbe,
0xe3,
0xad,
0x43,
0xc4,
0xc4,
0x5b,
0x2d,
0x09,
0xf2,
0xbf,
0xba,
0xf1,
0x86,
0xf8,
0xb0,
0xe0,
0x22,
0x1f,
0xae,
0x9a,
0xd6,
0xcc,
0x95,
0xbf,
0x62,
0x1a,
0xb1,
0x2b,
0xfd,
0x50,
0x82,
0x54,
0x8e,
0x7b,
0x41,
0xf9,
0x8f,
0x82,
0xe9,
0x53,
0xe7,
0x74,
0x64,
0xa1,
0x83,
0x3a,
0x2f,
0x28,
0x47,
0xc7,
0x8d,
0xf2,
0xe3,
0xe6,
0xaa,
0x25,
0xa5,
0x82,
0x02,
0xf7,
0x2d,
0x9a,
0x38,
0xf8,
0xe7,
0xcb,
0xdf,
0x15,
0x11,
0x47,
0xe7,
0x9a,
0xdc,
0xcf,
0xee,
0xa3,
0xd2,
0xee,
0xde,
0x05,
0xc7,
0x74,
0x72,
0x87,
0xa0,
0x6d,
0x80,
0xfa,
0x8c,
0x14,
0xa3,
0x8c,
0x93,
0xd1,
0x4f,
0x9a,
0x32,
0x9e,
0xc0,
0x4f,
0x30,
0x5e,
0x3c,
0xa8,
0x5b,
0x09,
0xfe,
0xd2,
0xdc,
0xb6,
0x46,
0x79,
0xbe,
0xe0,
0x50,
0x33,
0x1a,
0xe0,
0x44,
0x6c,
0xa3,
0xb2,
0x7c,
0x1b,
0xa6,
0xb3,
0x1e,
0x62,
0x8b,
0x6c,
0xdc,
0x13,
0xb3,
0x60,
0x1d,
0xf6,
0x29,
0x65,
0x95,
0x9a,
0x0e,
0x97,
0x0e,
0xd5,
0xa1,
0x06,
0xe6,
0x5d,
0x82,
0xfa,
0xe9,
0x05,
0xf0,
0xe7,
0x71,
0x10,
0x11,
0xc7,
0xf0,
0xf5,
0x0b,
0x0b,
0xb9,
0x61,
0xf5,
0x65,
0xa5,
0x8e,
0x25,
0xb2,
0x02,
0x8e,
0x7c,
0xb8,
0xe2,
0xbe,
0x52,
0x42,
0xa5,
0xaf,
0xd9,
0x50,
0xa2,
0x26,
0xfc,
0x2f,
0xc2,
0x5f,
0xf5,
0x83,
0xba,
0xe5,
0x99,
0x93,
0xee,
0xe2,
0x56,
0xab,
0x49,
0xb8,
0xa8,
0xdc,
0xb8,
0x44,
0xfa,
0x45,
0x4d,
0xfc,
0xdc,
0x45,
0xd9,
0x9a,
0xc8,
0x3a,
0x6f,
0xd6,
0xdd,
0x15,
0xda,
0xec,
0x33,
0xbc,
0x3c,
0xb2,
0x31,
0x14,
0x85,
0x13,
0x95,
0x2e,
0xb7,
0x18,
0x53,
0x97,
0x1c,
0x56,
0xbb,
0x8a,
0x0c,
0xa0,
0x9f,
0x37,
0x25,
0xbe,
0x12,
0x59,
0x46,
0xed,
0x70,
0x3d,
0xa4,
0x1c,
0x97,
0x69,
0xb4,
0xc3,
0xbd,
0x6e,
0xe4,
0xc9,
0xe9,
0x6f,
0x15,
0xce,
0xf9,
0xf4,
0x71,
0xe9,
0x20,
0xab,
0x0c,
0xf1,
0xca,
0xfd,
0xa4,
0xe5,
0xce,
0xea,
0x25,
0x06,
0x10,
0xbb,
0x04,
0xc7,
0x7b,
0x87,
0x68,
0x7d,
0x99,
0x9d,
0x31,
0x33,
0x25,
0xe3,
0x8f,
0xa5,
0x69,
0x03,
0xa0,
0xea,
0x06,
0x99,
0x08,
0xeb,
0xf2,
0x8a,
0x38,
0x9e,
0x6a,
0x3c,
0xe1,
0xe3,
0x6e,
0x45,
0xc0,
0xf5,
0x83,
0xf2,
0x92,
0x8f,
0x09,
0x47,
0x69,
0x5b,
0x65,
0x94,
0x23,
0x81,
0x10,
0x7b,
0xea,
0xde,
0x6d,
0x28,
0xa0,
0x80,
0x8f,
0xf4,
0x93,
0x8f,
0x56,
0xae,
0x0c,
0x45,
0x03,
0x36,
0xaf,
0x16,
0x51,
0xbd,
0xab,
0xd7,
0xa7,
0x84,
0x0d,
0x1f,
0x3a,
0x1d,
0x0a,
0xd6,
0x9e,
0xeb,
0xe8,
0x02,
0x28,
0xde,
0x21,
0xa7,
0x23,
0xca,
0x0b,
0x68,
0xc0,
0x69,
0xba,
0xcc,
0x92,
0x75,
0x6c,
0x21,
0xd1,
0x5b,
0xd6,
unsigned char NIST_TEST_RESULT_XTS_E3[] = {
0x0e, 0xee, 0xf2, 0x8c, 0xa1, 0x59, 0xb8, 0x05,
0xf5, 0xc2, 0x15, 0x61, 0x05, 0x51, 0x67, 0x8a,
0xb7, 0x72, 0xf2, 0x79, 0x37, 0x4f, 0xb1, 0x40,
0xab, 0x55, 0x07, 0x68, 0xdb, 0x42, 0xcf, 0x6c,
0xb7, 0x36, 0x37, 0x64, 0x19, 0x34, 0x19, 0x5f,
Chapter 7. Examples
133
0xfc,
0x84,
0x3f,
0xae,
0x3c,
0x7d,
0x1d,
0xbe,
0xc5,
0x30,
0x4a,
0xc1,
0xda,
0xb5,
0x38,
0x98,
0x89,
0x3b,
0xb9,
0xe6,
0x79,
0x8d,
0x3c,
0x57,
0xd0,
0x14,
0x25,
0x7a,
0x53,
0xee,
0x87,
0x68,
0x63,
0xba,
0x67,
0xf7,
0xe2,
0x7c,
0xb3,
0xe5,
0x2b,
0xba,
0x5c,
0x44,
0xb6,
0x01,
0x33,
0xe5,
0x80,
0x50,
0xd9,
0x92,
0x58,
0xe6,
0x57,
0x72,
0x1b,
0x44,
0x63,
};
0x88,
0x72,
0x51,
0xa7,
0x99,
0x0d,
0x2d,
0x45,
0x3c,
0x77,
0x39,
0x8f,
0x04,
0x69,
0xe4,
0x4e,
0x1b,
0x19,
0x83,
0x0c,
0xeb,
0x75,
0x32,
0x6d,
0x82,
0x9e,
0x25,
0x25,
0x54,
0x12,
0x73,
0x4f,
0xa1,
0x8b,
0x4b,
0x27,
0x57,
0x50,
0x0f,
0x20,
0xd0,
0xfb,
0x1c,
0x97,
0x5a,
0x2c,
0x07,
0x1b,
0xad,
0xce,
0xb5,
0x33,
0x05,
0xd9,
0xb1,
0x2d,
0x85,
0xb3,
0xfe,
0xb8,
0x39,
0x86,
0x7f,
0x04,
0x13,
0x01,
0x9d,
0xf4,
0xc8,
0x0f,
0x71,
0x3c,
0x51,
0x3d,
0xcf,
0x3d,
0x5c,
0x00,
0x69,
0x41,
0xf8,
0xee,
0x16,
0x75,
0x4e,
0x7e,
0x57,
0x6a,
0x2a,
0x52,
0xaf,
0xc0,
0x7e,
0x05,
0xe0,
0xcb,
0xe3,
0x9e,
0xf3,
0x37,
0xcd,
0xe7,
0x30,
0xb7,
0x0f,
0x41,
0x86,
0x09,
0x4f,
0xfe,
0x55,
0x54,
0x4c,
0x4d,
0x7a,
0x6a,
0x0d,
0xd4,
0x2b,
0xea,
0xec,
0x24,
0x82,
0x91,
0x6c,
0xa8,
0x2f,
0x93,
0xfc,
0xf9,
0x1c,
0x0d,
0xef,
0x39,
0x7b,
0x8e,
0xa5,
0x16,
0x8f,
0xeb,
0x4c,
0x6f,
0xfe,
0x1d,
0x61,
0x40,
0x6d,
0x55,
0x34,
0xfb,
0x22,
0x45,
0x2f,
0x52,
0x21,
0xc8,
0xcb,
0x3c,
0x5b,
0xe8,
0x4f,
0x5b,
0x45,
0x5d,
0xc5,
0xc1,
0xa9,
0x0a,
0x31,
0xf4,
0x15,
0x46,
0x9a,
0x71,
0x5a,
0x5b,
0xb4
/* XTS data -4- AES256 */
unsigned char NIST_KEY_XTS_E4[] = {
0x97, 0x09, 0x8b, 0x46, 0x5a, 0x44,
0xe7, 0xa1, 0xc2, 0xdb, 0xfc, 0x40,
0x1a, 0x20, 0xe3, 0x2c, 0x6d, 0x9d,
0x80, 0x72, 0x6f, 0xee, 0x10, 0x54,
0xca,
0xb7,
0xbf,
0x1b,
0x75,
0xa6,
0xda,
0xab,
134
0x08,
0x0a,
0x0d,
0x30,
0xdd,
0x3e,
0x0e,
0x4d,
0x3a,
0x11,
0x26,
0x87,
0x0e,
0x26,
0xc8,
0x4d,
0x44,
0xc0,
0x3f,
0x0a,
0xfb,
0x1f,
0x6f,
0x36,
0xa4,
0xbf,
0xcc,
0xdc,
0x62,
0xaa,
0x4d,
0x32,
0xc0,
0xfc,
0xb2,
0x3f,
0xeb,
0x52,
0xd9,
0x48,
0x45,
0x13,
0xc8,
0xb2,
0xba,
0x29,
0x07,
0x72,
0x82,
0xb6,
0xf3,
0x9c,
0x84,
0x37,
0xb1,
0xea,
0xa4,
0x89,
0xf4,
0xcf,
0x00,
0x7d,
0x87,
0xb2,
0x09,
0x2d,
0x06,
0x91,
0x2c,
0xee,
0x03,
0x7b,
0x08,
0x0f,
0xff,
0x53,
0x57,
0xe4,
0x7c,
0xca,
0xf7,
0xf2,
0x9e,
0x34,
0x34,
0x5a,
0xdd,
0xc8,
0x8f,
0x33,
0x5e,
0x52,
0xcb,
0x47,
0x4c,
0xc7,
0x59,
0xe3,
0xb9,
0x68,
0x35,
0x4c,
0x8e,
0x3b,
0x3e,
0xd2,
0x1a,
0x11,
0x86,
0x2e,
0x44,
0xc7,
0xd9,
0xad,
0x74,
0x1c,
0xa4,
0x9c,
0x5a,
0x7d,
0xd1,
0x7d,
0xc8,
0x82,
0xbb,
0x76,
0x45,
0xa6,
0x00,
0x66,
0x68,
0xcf,
0xa0,
0x2f,
0xd3,
0x04,
0xd9,
0x89,
0xfa,
0xb9,
0x87,
0x61,
0x57,
0x63,
0x5f,
0xe6,
0x91,
0xc0,
0xe0,
0xc2,
0xc8,
0x97,
0xd4,
0x67,
0x2d,
0xb6,
0xe7,
0xe3,
0x30,
0xe5,
0x9c,
0xa1,
0x46,
0xf9,
0x6a,
0x71,
0xf5,
0x30,
0x67,
0x6f,
0x48,
0xad,
0x03,
0x5f,
0xa0,
0x27,
0x05,
0x91,
0x52,
0xf2,
0xad,
0x8e,
0xda,
0xbb,
0xb1,
0xe8,
0x5d,
0x1f,
0x2a,
0xb1,
0x0e,
0x0d,
0x32,
0xe0,
0x9d,
0x5a,
0xe4,
0xd8,
0x11,
0x2d,
0xb6,
0x47,
0x8a,
0x9e,
0x5e,
0xe6,
0x3b,
0xa7,
0x4d,
0x11,
0x98,
0x04,
0x1d,
0x00,
0x09,
0x63,
0x62,
0x7c,
0x8b,
0x9c,
0xb6,
0x4e,
0x15,
0x1f,
0x3d,
0x7a,
0xaf,
0x69,
0x7a,
0xc9,
0x87,
0x4c,
0xe5,
0x35,
0x0b,
0x12,
libica Programmer's Reference
0x47,
0x49,
0x3f,
0xbe,
};
0x54,
0x61,
0xad,
0x07,
0x63,
0x73,
0x8a,
0xbf,
0xca,
0x32,
0xd9,
0xf8,
0x07,
0x14,
0x1f,
0xef,
0xc1,
0x68,
0xcd,
0x96,
0xc1,
0xd1,
0xc6,
0x1b,
0xe4,
0xab,
0x2a,
0x6b,
unsigned char NIST_TWEAK_XTS_E4[] = {
0x15, 0x60, 0x1e, 0x2e, 0x35, 0x85, 0x10, 0xa0,
0x9d, 0xdc, 0xa4, 0xea, 0x17, 0x51, 0xf4, 0x3c,
};
unsigned char NIST_EXPECTED_TWEAK_XTS_E4[] = {
0x15, 0x60, 0x1e, 0x2e, 0x35, 0x85, 0x10, 0xa0,
0x9d, 0xdc, 0xa4, 0xea, 0x17, 0x51, 0xf4, 0x3c,
};
unsigned char NIST_TEST_DATA_XTS_E4[] = {
0xd1, 0x9c, 0xfb, 0x38, 0x3b, 0xaf, 0x87, 0x2e,
0x6f, 0x12, 0x16, 0x87, 0x45, 0x1d, 0xe1, 0x5c,
};
unsigned char NIST_TEST_RESULT_XTS_E4[] = {
0xeb, 0x22, 0x26, 0x9b, 0x14, 0x90, 0x50, 0x27,
0xdc, 0x73, 0xc4, 0xa4, 0x0f, 0x93, 0x80, 0x69,
};
/* XTS data -5- AES256 */
unsigned char NIST_KEY_XTS_E5[] = {
0xfb, 0xf0, 0x77, 0x6e, 0x7d, 0xbe,
0xfb, 0x0c, 0x12, 0x0f, 0x41, 0x85,
0x92, 0x6c, 0x05, 0x2f, 0xd6, 0x5a,
0xd2, 0xf0, 0xd9, 0x8d, 0xa5, 0x4e,
0x08, 0x03, 0xa4, 0x2f, 0xbe, 0x6f,
0x58, 0x49, 0x00, 0xe8, 0xdc, 0x7a,
0x39, 0x1f, 0x82, 0x2d, 0x76, 0xa7,
0xcf, 0xce, 0x7f, 0x8d, 0xde, 0x20,
};
0x49,
0x71,
0x27,
0xdf,
0xd1,
0x11,
0x56,
0x3e,
0x10,
0x21,
0x8c,
0xd5,
0x33,
0x52,
0x68,
0xc8,
unsigned char NIST_TWEAK_XTS_E5[] = {
0x39, 0x5b, 0x6a, 0xcf, 0x9a, 0xdc, 0xd2, 0x91,
0xc2, 0xc9, 0x48, 0x86, 0x36, 0x33, 0xaf, 0xf8,
};
unsigned char NIST_EXPECTED_TWEAK_XTS_E5[] = {
0x39, 0x5b, 0x6a, 0xcf, 0x9a, 0xdc, 0xd2, 0x91,
0xc2, 0xc9, 0x48, 0x86, 0x36, 0x33, 0xaf, 0xf8,
};
unsigned char NIST_TEST_DATA_XTS_E5[] = {
0x3e, 0x2e, 0x26, 0x9d, 0x78, 0x3a, 0x2b,
0xe8, 0x73, 0xd6, 0x73, 0x47, 0x9f, 0x51,
0x73, 0x4f, 0xe0, 0x3e, 0xe3, 0x29, 0x65,
0xc4, 0x79, 0x35, 0xc0, 0xea, 0x99, 0xa0,
0xbd, 0x44, 0x4b, 0xec, 0x12, 0x5b, 0x2c,
0x9d, 0xb9, 0xde, 0x6d, 0x18, 0x35, 0x92,
0x3b, 0x48, 0xa8, 0x77, 0xa9, 0x5a, 0xc2,
0x9c, 0x3d, 0xdf, 0xc7, 0xb4, 0xdb, 0x99,
};
0x29,
0x16,
0xed,
0x64,
0x78,
0x05,
0x55,
0x07,
unsigned char NIST_TEST_RESULT_XTS_E5[] = {
0x4c, 0x70, 0xbd, 0xbb, 0x77, 0x30, 0x2b, 0x7f,
0x1f, 0xdd, 0xca, 0x50, 0xdc, 0x70, 0x73, 0x1e,
0x00, 0x8a, 0x26, 0x55, 0xd2, 0x2a, 0xd0, 0x20,
0x0c, 0x11, 0x1f, 0xd3, 0x2a, 0x67, 0x5a, 0x7e,
0x09, 0x97, 0x11, 0x43, 0x6f, 0x98, 0xd2, 0x1c,
0x72, 0x77, 0x2e, 0x0d, 0xd7, 0x67, 0x2f, 0xf5,
Chapter 7. Examples
135
0xfd, 0x00, 0xdd, 0xcb, 0xe1, 0x1e, 0xb9, 0x7e,
0x69, 0x87, 0x83, 0xbf, 0xa4, 0x05, 0x46, 0xe3,
};
void dump_array(unsigned char *ptr, unsigned int size)
{
unsigned char *ptr_end;
unsigned char *h;
int i = 1;
h = ptr;
ptr_end = ptr + size;
while (h < (unsigned char *)ptr_end) {
printf("0x%02x ",(unsigned char ) *h);
h++;
if (i == 8) {
printf("\n");
i = 1;
} else {
++i;
}
}
printf("\n");
}
void dump_xts_data(unsigned char *tweak, unsigned int tweak_length,
unsigned char *key, unsigned int key_length,
unsigned char *input_data, unsigned int data_length,
unsigned char *output_data)
{
printf("TWEAK \n");
dump_array(tweak, tweak_length);
printf("Key \n");
dump_array(key, key_length);
printf("Input Data\n");
dump_array(input_data, data_length);
printf("Output Data\n");
dump_array(output_data, data_length);
}
void get_sizes(unsigned int *data_length, unsigned int *tweak_length,
unsigned int *key_length, unsigned int iteration)
{
switch (iteration) {
case 1:
*data_length = sizeof(NIST_TEST_DATA_XTS_E1);
*tweak_length = sizeof(NIST_TWEAK_XTS_E1);
*key_length = sizeof(NIST_KEY_XTS_E1);
break;
case 2:
*data_length = sizeof(NIST_TEST_DATA_XTS_E2);
*tweak_length = sizeof(NIST_TWEAK_XTS_E2);
*key_length = sizeof(NIST_KEY_XTS_E2);
break;
case 3:
*data_length = sizeof(NIST_TEST_DATA_XTS_E3);
*tweak_length = sizeof(NIST_TWEAK_XTS_E3);
*key_length = sizeof(NIST_KEY_XTS_E3);
break;
case 4:
*data_length = sizeof(NIST_TEST_DATA_XTS_E4);
*tweak_length = sizeof(NIST_TWEAK_XTS_E4);
*key_length = sizeof(NIST_KEY_XTS_E4);
break;
case 5:
*data_length = sizeof(NIST_TEST_DATA_XTS_E5);
*tweak_length = sizeof(NIST_TWEAK_XTS_E5);
136
libica Programmer's Reference
*key_length = sizeof(NIST_KEY_XTS_E5);
break;
}
}
void load_test_data(unsigned char *data, unsigned int data_length,
unsigned char *result,
unsigned char *tweak, unsigned char *expected_tweak,
unsigned int tweak_length,
unsigned char *key, unsigned int key_length,
unsigned int iteration)
{
switch (iteration) {
case 1:
memcpy(data, NIST_TEST_DATA_XTS_E1, data_length);
memcpy(result, NIST_TEST_RESULT_XTS_E1, data_length);
memcpy(tweak, NIST_TWEAK_XTS_E1, tweak_length);
memcpy(expected_tweak, NIST_EXPECTED_TWEAK_XTS_E1,
tweak_length);
memcpy(key, NIST_KEY_XTS_E1, key_length);
break;
case 2:
memcpy(data, NIST_TEST_DATA_XTS_E2, data_length);
memcpy(result, NIST_TEST_RESULT_XTS_E2, data_length);
memcpy(tweak, NIST_TWEAK_XTS_E2, tweak_length);
memcpy(expected_tweak, NIST_EXPECTED_TWEAK_XTS_E2,
tweak_length);
memcpy(key, NIST_KEY_XTS_E2, key_length);
break;
case 3:
memcpy(data, NIST_TEST_DATA_XTS_E3, data_length);
memcpy(result, NIST_TEST_RESULT_XTS_E3, data_length);
memcpy(tweak, NIST_TWEAK_XTS_E3, tweak_length);
memcpy(expected_tweak, NIST_EXPECTED_TWEAK_XTS_E3,
tweak_length);
memcpy(key, NIST_KEY_XTS_E3, key_length);
break;
case 4:
memcpy(data, NIST_TEST_DATA_XTS_E4, data_length);
memcpy(result, NIST_TEST_RESULT_XTS_E4, data_length);
memcpy(tweak, NIST_TWEAK_XTS_E4, tweak_length);
memcpy(expected_tweak, NIST_EXPECTED_TWEAK_XTS_E4,
tweak_length);
memcpy(key, NIST_KEY_XTS_E4, key_length);
break;
case 5:
memcpy(data, NIST_TEST_DATA_XTS_E5, data_length);
memcpy(result, NIST_TEST_RESULT_XTS_E5, data_length);
memcpy(tweak, NIST_TWEAK_XTS_E5, tweak_length);
memcpy(expected_tweak, NIST_EXPECTED_TWEAK_XTS_E5,
tweak_length);
memcpy(key, NIST_KEY_XTS_E5, key_length);
break;
}
}
int kat_aes_xts(int iteration, int silent)
{
unsigned int data_length;
unsigned int tweak_length;
unsigned int key_length;
get_sizes(&data_length, &tweak_length, &key_length, iteration);
unsigned char tweak[tweak_length];
Chapter 7. Examples
137
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
char
char
char
char
char
char
char
tmp_tweak[tweak_length];
expected_tweak[tweak_length];
key[key_length];
input_data[data_length];
encrypt[data_length];
decrypt[data_length];
result[data_length];
int rc = 0;
memset(encrypt, 0x00, data_length);
memset(decrypt, 0x00, data_length);
load_test_data(input_data, data_length, result, tweak, expected_tweak,
tweak_length, key, key_length, iteration);
memcpy(tmp_tweak, tweak, tweak_length);
printf("Test Parameters for iteration = %i\n", iteration);
printf("key length = %i, data length = %i, tweak length = %i,",
key_length, data_length, tweak_length);
rc = ica_aes_xts(input_data, encrypt, data_length,
key, key+(key_length/2), (key_length/2),
tmp_tweak, 1);
if (rc) {
printf("ica_aes_xts encrypt failed with rc = %i\n", rc);
dump_xts_data(tweak, tweak_length, key, key_length, input_data,
data_length, encrypt);
}
if (!silent && !rc) {
printf("Encrypt:\n");
dump_xts_data(tweak, tweak_length, key, key_length, input_data,
data_length, encrypt);
}
if (memcmp(result, encrypt, data_length)) {
printf("Encryption Result does not match the known ciphertext!\n");
printf("Expected data:\n");
dump_array(result, data_length);
printf("Encryption Result:\n");
dump_array(encrypt, data_length);
rc++;
}
if (memcmp(expected_tweak, tmp_tweak, tweak_length)) {
printf("Update of TWEAK does not match the expected TWEAK!\n");
printf("Expected TWEAK:\n");
dump_array(expected_tweak, tweak_length);
printf("Updated TWEAK:\n");
dump_array(tmp_tweak, tweak_length);
printf("Original TWEAK:\n");
dump_array(tweak, tweak_length);
rc++;
}
if (rc) {
printf("AES XTS test exited after encryption\n");
return rc;
}
memcpy(tmp_tweak, tweak, tweak_length);
rc = ica_aes_xts(encrypt, decrypt, data_length,
key, key+(key_length/2), (key_length/2),
tmp_tweak, 0);
if (rc) {
printf("ica_aes_xts decrypt failed with rc = %i\n", rc);
dump_xts_data(tweak, tweak_length, key, key_length, encrypt,
data_length, decrypt);
return rc;
138
libica Programmer's Reference
}
if (!silent && !rc) {
printf("Decrypt:\n");
dump_xts_data(tweak, tweak_length, key, key_length, encrypt,
data_length, decrypt);
}
if (memcmp(decrypt, input_data, data_length)) {
printf("Decryption Result does not match the original data!\n");
printf("Original data:\n");
dump_array(input_data, data_length);
printf("Decryption Result:\n");
dump_array(decrypt, data_length);
rc++;
}
return rc;
}
int load_random_test_data(unsigned char *data, unsigned int data_length,
unsigned char *iv, unsigned int iv_length,
unsigned char *key, unsigned int key_length)
{
int rc;
rc = ica_random_number_generate(data_length, data);
if (rc) {
printf("ica_random_number_generate with rc = %i errnor = %i\n",
rc, errno);
return rc;
}
rc = ica_random_number_generate(iv_length, iv);
if (rc) {
printf("ica_random_number_generate with rc = %i errnor = %i\n",
rc, errno);
return rc;
}
rc = ica_random_number_generate(key_length, key);
if (rc) {
printf("ica_random_number_generate with rc = %i errnor = %i\n",
rc, errno);
return rc;
}
return rc;
}
int random_aes_xts(int iteration, int silent, unsigned int data_length)
{
int i;
int rc = 0;
unsigned int iv_length = sizeof(ica_aes_vector_t);
unsigned int key_length = AES_KEY_LEN128 * 2;
unsigned char iv[iv_length];
unsigned char tmp_iv[iv_length];
unsigned char input_data[data_length];
unsigned char encrypt[data_length];
unsigned char decrypt[data_length];
for (i = 1; i <= 2; i++) {
unsigned char key[key_length];
memset(encrypt, 0x00, data_length);
memset(decrypt, 0x00, data_length);
load_random_test_data(input_data, data_length, iv, iv_length, key,
key_length);
memcpy(tmp_iv, iv, iv_length);
Chapter 7. Examples
139
printf("Test Parameters for iteration = %i\n", iteration);
printf("key length = %i, data length = %i, iv length = %i\n",
key_length, data_length, iv_length);
rc = ica_aes_xts(input_data, encrypt, data_length,
key, key+(key_length/2), (key_length/2),
tmp_iv, 1);
if (rc) {
printf("ica_aes_xts encrypt failed with rc = %i\n", rc);
dump_xts_data(iv, iv_length, key, key_length, input_data,
data_length, encrypt);
}
if (!silent && !rc) {
printf("Encrypt:\n");
dump_xts_data(iv, iv_length, key, key_length, input_data,
data_length, encrypt);
}
if (rc) {
printf("AES XTS test exited after encryption\n");
return rc;
}
memcpy(tmp_iv, iv, iv_length);
rc = ica_aes_xts(encrypt, decrypt, data_length,
key, key+(key_length/2), (key_length/2),
tmp_iv, 0);
if (rc) {
printf("ica_aes_xts decrypt failed with rc = %i\n", rc);
dump_xts_data(iv, iv_length, key, key_length, encrypt,
data_length, decrypt);
return rc;
}
if (!silent && !rc) {
printf("Decrypt:\n");
dump_xts_data(iv, iv_length, key, key_length, encrypt,
data_length, decrypt);
}
if (memcmp(decrypt, input_data, data_length)) {
printf("Decryption Result does not match the original data!\n");
printf("Original data:\n");
dump_array(input_data, data_length);
printf("Decryption Result:\n");
dump_array(decrypt, data_length);
rc++;
return rc;
}
key_length = AES_KEY_LEN256 * 2;
}
return rc;
}
int main(int argc, char **argv)
{
unsigned int silent = 0;
if (argc > 1) {
if (strstr(argv[1], "silent"))
silent = 1;
}
int rc = 0;
int error_count = 0;
int iteration;
140
libica Programmer's Reference
unsigned int data_length = sizeof(ica_aes_vector_t);
for(iteration = 1; iteration <= NR_TESTS; iteration++) {
rc = kat_aes_xts(iteration, silent);
if (rc) {
printf("kat_aes_xts failed with rc = %i\n", rc);
error_count++;
} else
printf("kat_aes_xts finished successfuly\n");
}
for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) {
int silent = 1;
rc = random_aes_xts(iteration, silent, data_length);
if (rc) {
printf("random_aes_xts failed with rc = %i\n", rc);
error_count++;
goto out;
} else
printf("random_aes_xts finished successfuly\n");
data_length += sizeof(ica_aes_vector_t) / 2;
}
out:
if (error_count)
printf("%i testcases failed\n", error_count);
else
printf("All testcases finished successfully\n");
return rc;
}
CMAC example
/* This program is released under the Common Public License V1.0
*
* You should have received a copy of Common Public License V1.0 along with
* with this program.
*/
/* Copyright IBM Corp. 2010, 2011 */
#include <fcntl.h>
#include <sys/errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ica_api.h"
#define BYTE 8
#define NUM_TESTS 12
unsigned int key_length[12] = {16, 16, 16,
32};
unsigned char key[12][32] = {{
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2,
0x88, 0x09, 0xcf, 0x4f, 0x3c},{
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2,
0x88, 0x09, 0xcf, 0x4f, 0x3c},{
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2,
0x88, 0x09, 0xcf, 0x4f, 0x3c},{
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2,
0x88, 0x09, 0xcf, 0x4f, 0x3c},{
0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64,
0x2b, 0x80, 0x90, 0x79, 0xe5, 0x62, 0xf8,
0x6b, 0x7b},{
0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64,
0x2b, 0x80, 0x90, 0x79, 0xe5, 0x62, 0xf8,
16, 24, 24, 24, 24, 32, 32, 32,
0xa6, 0xab, 0xf7, 0x15,
0xa6, 0xab, 0xf7, 0x15,
0xa6, 0xab, 0xf7, 0x15,
0xa6, 0xab, 0xf7, 0x15,
0x52, 0xc8, 0x10 ,0xf3,
0xea, 0xd2, 0x52, 0x2c,
0x52, 0xc8, 0x10 ,0xf3,
0xea, 0xd2, 0x52, 0x2c,
Chapter 7. Examples
141
0x6b,
0x8e,
0x2b,
0x6b,
0x8e,
0x2b,
0x6b,
0x60,
0xf0,
0x08,
0x60,
0xf0,
0x08,
0x60,
0xf0,
0x08,
0x60,
0xf0,
0x08,
};
0x7b},{
0x73, 0xb0,
0x80, 0x90,
0x7b},{
0x73, 0xb0,
0x80, 0x90,
0x7b},{
0x3d, 0xeb,
0x85, 0x7d,
0xd7, 0x2d,
0x3d, 0xeb,
0x85, 0x7d,
0xd7, 0x2d,
0x3d, 0xeb,
0x85, 0x7d,
0xd7, 0x2d,
0x3d, 0xeb,
0x85, 0x7d,
0xd7, 0x2d,
0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10 ,0xf3,
0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c,
0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10 ,0xf3,
0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c,
0x10,
0x77,
0x98,
0x10,
0x77,
0x98,
0x10,
0x77,
0x98,
0x10,
0x77,
0x98,
0x15,
0x81,
0x10,
0x15,
0x81,
0x10,
0x15,
0x81,
0x10,
0x15,
0x81,
0x10,
0xca,
0x1f,
0xa3,
0xca,
0x1f,
0xa3,
0xca,
0x1f,
0xa3,
0xca,
0x1f,
0xa3,
0x71,
0x35,
0x09,
0x71,
0x35,
0x09,
0x71,
0x35,
0x09,
0x71,
0x35,
0x09,
0xbe,
0x2c,
0x14,
0xbe,
0x2c,
0x14,
0xbe,
0x2c,
0x14,
0xbe,
0x2c,
0x14,
0x2b,
0x07,
0xdf,
0x2b,
0x07,
0xdf,
0x2b,
0x07,
0xdf,
0x2b,
0x07,
0xdf,
0x73, 0xae,
0x3b, 0x61,
0xf4},{
0x73, 0xae,
0x3b, 0x61,
0xf4},{
0x73, 0xae,
0x3b, 0x61,
0xf4},{
0x73, 0xae,
0x3b, 0x61,
0xf4}
unsigned char last_block[3][16] = {{
0x7d, 0xf7, 0x6b, 0x0c, 0x1a, 0xb8, 0x99, 0xb3, 0x3e, 0x42, 0xf0,
0x47, 0xb9, 0x1b, 0x54, 0x6f},{
0x22, 0x45, 0x2d, 0x8e, 0x49, 0xa8, 0xa5, 0x93, 0x9f, 0x73, 0x21,
0xce, 0xea, 0x6d, 0x51, 0x4b},{
0xe5, 0x68, 0xf6, 0x81, 0x94, 0xcf, 0x76, 0xd6, 0x17, 0x4d, 0x4c,
0xc0, 0x43, 0x10, 0xa8, 0x54}
};
unsigned long mlen[12] = { 0, 16, 40, 64, 0,16, 40, 64, 0, 16, 40, 64};
unsigned char message[12][512] = {{
0x00},{
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e,
0x11, 0x73, 0x93, 0x17, 0x2a},{
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e,
0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03,
0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf ,0x8e, 0x51, 0x30,
0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11},{
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e,
0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03,
0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 0x30,
0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19,
0x1a, 0x0a, 0x52, 0xef, 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b,
0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10},{
0x00},{
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e,
0x11, 0x73, 0x93, 0x17, 0x2a},{
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e,
0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03,
0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf ,0x8e, 0x51, 0x30,
0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11},{
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e,
0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03,
0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 0x30,
0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19,
0x1a, 0x0a, 0x52, 0xef, 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b,
0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10},{
0x00},{
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e,
0x11, 0x73, 0x93, 0x17, 0x2a},{
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e,
0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03,
0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf ,0x8e, 0x51, 0x30,
0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11},{
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e,
0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03,
142
libica Programmer's Reference
0xac,
0xc8,
0x1a,
0x17,
};
0x9c,
0x1c,
0x0a,
0xad,
0x9e,
0x46,
0x52,
0x2b,
0xb7,
0xa3,
0xef,
0x41,
0x6f,
0x5c,
0xf6,
0x7b,
0xac,
0xe4,
0x9f,
0xe6,
0x45,
0x11,
0x24,
0x6c,
unsigned char expected_cmac[12][16] = {{
0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37,
0x12, 0x9b, 0x75, 0x67, 0x46},{
0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41,
0x9d, 0xd0, 0x4a, 0x28, 0x7c},{
0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6,
0x61, 0x14, 0x97, 0xc8, 0x27},{
0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d,
0x17, 0x79, 0x36, 0x3c, 0xfe},{
0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd,
0x83, 0xde, 0x7a, 0x93, 0x67},{
0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10,
0x5e, 0x61, 0x7c, 0x51, 0x84},{
0x8a, 0x1d, 0xe5, 0xbe, 0x2e, 0xb3, 0x1a,
0xe6, 0xee, 0x90, 0x8b, 0x0e},{
0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f,
0x96, 0x59, 0xf3, 0x9a, 0x11},{
0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8,
0x1f, 0x46, 0x67, 0xd9, 0x83},{
0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f,
0x8d, 0x8c, 0x37, 0xc3, 0x5c},{
0xaa, 0xf3, 0xd8, 0xf1, 0xde, 0x56, 0x40,
0x69, 0xb9, 0xc9, 0x11, 0xe6},{
0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e,
0x05, 0x6c, 0x31, 0x54, 0x10}
};
0xaf,
0xe5,
0x45,
0x37,
0x8e, 0x51, 0x30,
0xfb, 0xc1, 0x19,
0xdf, 0x4f, 0x9b,
0x10}
0x28, 0x7f, 0xa3, 0x7d,
0x44, 0xf7, 0x9b, 0xdd,
0x30, 0x30, 0xca, 0x32,
0x92, 0xfc, 0x49, 0x74,
0xe5, 0x31, 0xca, 0xc4,
0x90, 0x06, 0x62, 0xf6,
0xad, 0x08, 0x9a, 0x82,
0x79, 0x4d, 0x77, 0x58,
0x9e, 0xfc, 0x6b, 0x55,
0x82, 0xbd, 0x4b, 0xf2,
0xc2, 0x32, 0xf5, 0xb1,
0xd5, 0x69, 0x6a, 0x2c,
unsigned int i = 0;
void dump_array(unsigned char *ptr, unsigned int size)
{
unsigned char *ptr_end;
unsigned char *h;
int i = 1, trunc = 0;
int maxsize = 2000;
puts("Dump:");
if (size > maxsize) {
trunc = size - maxsize;
size = maxsize;
}
h = ptr;
ptr_end = ptr + size;
while (h < ptr_end) {
printf("0x%02x ", *h);
h++;
if (i == 16) {
if (h != ptr_end)
printf("\n");
i = 1;
} else {
++i;
}
}
printf("\n");
if (trunc > 0)
printf("... %d bytes not printed\n", trunc);
}
unsigned char *cmac;
unsigned int cmac_length = 16;
Chapter 7. Examples
143
int api_cmac_test(void)
{
printf("Test of CMAC api\n");
int rc = 0;
for (i = 0 ; i < NUM_TESTS; i++) {
if (!(cmac = malloc(cmac_length)))
return EINVAL;
memset(cmac, 0, cmac_length);
rc = (ica_aes_cmac(message[i], mlen[i],
cmac, cmac_length,
key[i], key_length[i],
ICA_ENCRYPT));
if (rc) {
printf("ica_aes_cmac generate failed with errno %d (0x%x)."
"\n",rc,rc);
return rc;
}
if (memcmp(cmac, expected_cmac[i], cmac_length) != 0) {
printf("This does NOT match the known result. "
"Testcase %i failed\n",i);
printf("\nOutput MAC for test %d:\n", i);
dump_array((unsigned char *)cmac, cmac_length);
printf("\nExpected MAC for test %d:\n", i);
dump_array((unsigned char *)expected_cmac[i], 16);
free(cmac);
return 1;
}
printf("Expected MAC has been generated.\n");
rc = (ica_aes_cmac(message[i], mlen[i],
cmac, cmac_length,
key[i], key_length[i],
ICA_DECRYPT));
if (rc) {
printf("ica_aes_cmac verify failed with errno %d (0x%x).\n",
rc, rc);
free(cmac);
return rc;
}
free(cmac);
if (! rc )
printf("MAC was successful verified. testcase %i "
"succeeded\n",i);
else {
printf("MAC verification failed for testcase %i "
"with RC=%i\n",i,rc);
return rc;
}
}
return 0;
}
int main(int argc, char **argv)
{
int rc = 0;
rc = api_cmac_test();
if (rc) {
printf("api_cmac_test failed with rc = %i\n", rc);
return rc;
}
printf("api_cmac_test was succesful\n");
return 0;
}
144
libica Programmer's Reference
Makefile example
# Specify include directory. Leave blank for default system location.
INCDIR =
# Specify library directory. Leave blank for default system location.
LIBDIR =
# Specify library.
LIBS = -lica
TARGETS = example_des_ecb
all: $(TARGETS)
%: %.c
gcc $(INCDIR) $(LIBDIR) $(LIBS) -o [email protected] $^
clean:
rm -f $(TARGETS)
Common Public License - V1.0
Common Public License - V1.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:
1. in the case of the initial Contributor, the initial code and
documentation distributed under this Agreement, and
2. in the case of each subsequent Contributor:
1. changes to the Program, and
2. 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
1. Subject to the terms of this Agreement, each Contributor
hereby grants Recipient a non-exclusive, worldwide,
Chapter 7. Examples
145
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.
2. 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.
3. 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.
4. 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:
1. it complies with the terms and conditions of this Agreement;
and
2. its license agreement:
1. 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;
2. effectively excludes on behalf of all Contributors
all liability for damages, including direct, indirect,
special, incidental and consequential damages, such as
lost profits;
3. states that any provisions which differ from this
Agreement are offered by that Contributor alone and not
by any other party; and
4. 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.
146
libica Programmer's Reference
When the Program is made available in source code form:
1. it must be made available under this Agreement; and
2. 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
Chapter 7. Examples
147
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.
148
libica Programmer's Reference
Getting libica Version 2.3.0 status information
A list of hardware supported algorithms can be retrieved by icainfo.
$ icainfo
The following CP Assist for Cryptographic Function (CPACF) operations
are supported by libica on this system:
SHA-1:
yes
SHA-256:
yes
SHA-512:
yes
DES:
yes
TDES-128:
yes
TDES-192:
yes
AES-128:
yes
AES-192:
yes
AES-256:
yes
PRNG:
yes
CCM-AES-128:
yes
CMAC-AES-128: yes
CMAC-AES-192: yes
CMAC-AES-256: yes
Use icastats to retrieve the actual statistics about cryptographic algorithms that
have already been used:
# icastats
function | # hardware | # software
----------+------------+------------SHA-1 |
0 |
0
SHA-224 |
0 |
0
SHA-256 |
0 |
0
SHA-384 |
0 |
0
SHA-512 |
0 |
0
RANDOM |
1 |
0
MOD EXPO |
0 |
0
RSA CRT |
0 |
0
DES ENC |
0 |
0
DES DEC |
0 |
0
3DES ENC |
0 |
0
3DES DEC |
0 |
0
AES ENC |
0 |
0
AES DEC |
0 |
0
CMAC GEN |
0 |
0
CMAC VER |
0 |
0
CCM ENC |
0 |
0
CCM DEC |
0 |
0
CCM AUTH |
0 |
0
GCM ENC |
0 |
0
GCM DEC |
0 |
0
GCM AUTH |
0 |
0
For more information about libica Version 2.3.0 refer to the other sections in this
document.
openCryptoki code samples
This section provides the following code samples:
v “Dynamic library call” on page 150
v “Shared linked library” on page 151
Coding samples (C)
To develop an application that uses openCryptoki, you need to access the library.
There are two ways to access the library:
Chapter 7. Examples
149
v Load shared objects using dynamic library calls (dlopen)
v Link the library(statically) to your application during built time
For a list of supported mechanisms for ica-token, refer to “Supported mechanism
list for the ica token,” on page 161.
Dynamic library call
openCryptoki code samples for dynamic library call.
#include
#include
#include
#include
#include
<stdlib.h>
<errno.h>
<stdio.h>
<dlfcn.h>
<pkcs11types.h>
CK_RV init();
CK_RV cleanup();
CK_RV rc;
void *dllPtr, (*symPtr)();
CK_FUNCTION_LIST_PTR FunctionPtr = NULL;
/* return code */
/* pointer to the ock library */
/* pointer to function list */
int main(int argc, char *argv[]){
init(“/usr/lib64/opencryptoki/libopencryptoki.so”); /* opencryptoki initialization */
/* .... other opencryptoki commands.... */
cleanup();
/* cleanup/close shared library */
return 0;
}
CK_RV init(char *libPath){
dllPtr = dlopen(libPath, RTLD_NOW);
/* open the PKCS11 library */
if (!dllPtr) {
printf("Error loading PKCS#11 library \n");
return errno;
}
symPtr = (void (*)())dlsym(dllPtr, "C_GetFunctionList"); /* Get ock function list */
if (!symPtr) {
printf("Error getting function list \n");
return errno;
}
symPtr(&FunctionPtr);
rc = FunctionPtr->C_Initialize(NULL);
/* initialize opencryptoki/tokens) */
if (rc != CKR_OK) {
printf("Error initializing the opencryptoki library: 0x%X\n", rc);
cleanup();
}
printf("Opencryptoki initialized.\n");
return CKR_OK;
}
CK_RV cleanup(void) {
rc = FunctionPtr->C_Finalize(NULL);
if (dllPtr)
dlclose(dllPtr);
return rc;
}
To compile your sample code you need to provide the path of the source/include
files.
Red Hat Enterprise Linux 6.2:
gcc sample_dynamic.c -g -O0 -o sample_dynamic -I /usr/include/opencryptoki/
SUSE Linux Enterprise 11 SP2:
gcc sample_dynamic.c -g -O0 -o sample_dynamic -I /usr/src/debug/opencryptoki-2.4/usr/include/pkcs11/
150
libica Programmer's Reference
Shared linked library
When you use your sample code with a static linked library you can access the
APIs directly.
At the compile time you need to specify the openCryptoki library:
Red Hat Enterprise Linux 6.2:
gcc sample_shared.c -g -O0 -o sample_shared /usr/lib64/opencryptoki/libopencryptoki.so
-I /usr/include/opencryptoki/
SUSE Linux Enterprise 11 SP2:
gcc sample_shared.c -g -O0 -o sample_shared /usr/lib64/opencryptoki/libopencryptoki.so
-I /usr/src/debug/opencryptoki-2.4/usr/include/pkcs11/
The following code samples that interact with the openCryptoki API are based on
the shared linked openCryptoki library.
Base procedures:
The following code sample provides an insight into how to deal with the
openCryptoki API's. After describing some basic functions such as initialization,
session and login handling, the sample shows how to retrieve data, such as get slot
and token information and also detailed mechanism information. It also provides
an introduction about how to create key objects and process symmetric
encryption/decryption (DES). The last section shows RSA key generation with RSA
encrypt and decrypt operations.
Chapter 7. Examples
151
Main program
#include
#include
#include
#include
#include
#include
<stdlib.h>
<errno.h>
<stdio.h>
<dlfcn.h>
<pkcs11types.h>
<defs.h>
K_SLOT_ID
slotID;
CK_SLOT_ID_PTR
pSlotList = NULL;
CK_ULONG
slotCount, ulCount, rsaLen = 2048, msgLen = 8, cipherLen = 8, c;
CK_FLAGS
rw_sessionFlags = CKF_RW_SESSION | CKF_SERIAL_SESSION;
CK_SESSION_HANDLE hSession;
CK_MECHANISM_TYPE_PTR pMechList = NULL;
CK_BYTE keyValue[] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
CK_BYTE msg[]
= {’T’, ’h’, ’e’, ’ ’, ’b’, ’i’, ’r’, ’d’};
CK_OBJECT_HANDLE hPublicKey, hPrivateKey;
/* <insert helper functions (provided below) here> */
int main(int argc, char *argv[]) {
init();
getSlotList(pSlotList, &slotCount);
// get the number of slots
pSlotList = malloc(slotCount * sizeof(CK_SLOT_ID)); // allocate memory
getSlotList(pSlotList, &slotCount);
// retrieve slot list
slotID = *pSlotList;
// first slot provide ica-token
getSlotInfo(slotID);
getTokenInfo(slotID);
getMechanismList(slotID, pMechList, &ulCount);
// retrieve number of mech’s
pMechList = malloc(ulCount * sizeof(CK_MECHANISM_TYPE)); // allocate memory
getMechanismList(slotID, pMechList, &ulCount);
// retrieve mechanism list
getMechanismInfo(slotID, CKM_DES3_ECB);
// get mechanism information
openSession(slotID, rw_sessionFlags, &hSession);
loginSession(CKU_USER, "01234567", 8, hSession);
createKeyObject(hSession, keyValue);
CK_BYTE_PTR pCipherText = malloc(DES_BLOCK_SIZE*sizeof(CK_BYTE));
DESencrypt(hSession, (CK_BYTE_PTR)&msg, msgLen, pCipherText, &cipherLen);
DESdecrypt(hSession, pCipherText, cipherLen, (CK_BYTE_PTR)&msg, &msgLen);
generateRSAKeyPair(hSession, rsaLen, &hPublicKey, &hPrivateKey);
CK_BYTE_PTR pEncryptText = malloc(rsaLen*sizeof(CK_BYTE));
CK_BYTE_PTR pClearText = malloc(rsaLen*sizeof(CK_BYTE));
RSAencrypt(hSession, hPublicKey, (CK_BYTE_PTR)&msg, msgLen, pEncryptText, &rsaLen);
RSAdecrypt(hSession, hPrivateKey, pEncryptText, rsaLen, pClearText, &rsaLen);
logoutSession(hSession); closeSession(hSession);
finalize();
return 0;
}
C_Initialize:
CK_RV init(void){
CK_RV rc;
rc = C_Initialize(NULL);
if (rc != CKR_OK) {
printf("Error initializing the opencryptoki library: 0x%X\n", rc);
}
return CKR_OK;
}
152
libica Programmer's Reference
C_GetSlotList:
CK_RV getSlotList(CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pSlotCount){
CK_RV rc;
rc = C_GetSlotList(TRUE, pSlotList, pSlotCount);
if (rc != CKR_OK) {
printf("Error getting number of slots: %x \n", rc);
return rc;
}
return CKR_OK;
}
C_GetSlotInfo:
CK_RV getSlotInfo(CK_SLOT_ID slotID){
CK_RV
rc;
CK_SLOT_INFO slotInfo;
rc = C_GetSlotInfo(slotID, &slotInfo);
if (rc != CKR_OK) {
printf("Error getting slot information: %x \n", rc);
return rc;
}
printf("Slot %d Information:\n", slotID);
printf(" Description: %.64s\n", slotInfo.slotDescription);
printf(" Manufacturer: %.32s\n", slotInfo.manufacturerID);
printf(" Flags: 0x%X\n", slotInfo.flags);
if ((slotInfo.flags & CKF_TOKEN_PRESENT) == CKF_TOKEN_PRESENT) {
printf("Token Present!\n");
}
if ((slotInfo.flags & CKF_REMOVABLE_DEVICE) ==
CKF_REMOVABLE_DEVICE) {
printf("Removable Device!\n");
}
if ((slotInfo.flags & CKF_HW_SLOT) == CKF_HW_SLOT){
printf("Hardware support!\n");
}
else { printf("Software support!\n");}
printf(" Hardware Version: %d.%d\n",
slotInfo.hardwareVersion.major,
slotInfo.hardwareVersion.minor);
printf(" Firmware Version: %d.%d\n",
slotInfo.firmwareVersion.major,
slotInfo.firmwareVersion.minor);
return CKR_OK;
}
Chapter 7. Examples
153
C_GetTokenInfo:
CK_RV getTokenInfo(CK_SLOT_ID slotID){
CK_RV
rc;
CK_TOKEN_INFO tokInfo;
rc = C_GetTokenInfo(slotID, &tokinfo);
if (rc != CKR_OK) {
printf("Error getting token info: 0x%X\n", rc); return rc;
}
printf("Token #%d Info:\n", slotID);
printf(" Label: %.32s\n", (&tokinfo)->label);
printf(" Manufacturer: %.32s\n", (&tokinfo)->manufacturerID);
printf(" Model: %.16s\n", (&tokinfo)->model);
printf(" Serial Number: %.16s\n", (&tokinfo)->serialNumber);
printf(" Flags: 0x%X\n", (&tokinfo)->flags);
if (((&tokinfo)->flags & CKF_RNG)== CKF_RNG)
printf("
|_ token has random generator\n");
if (((&tokinfo)->flags & CKF_WRITE_PROTECTED)== CKF_WRITE_PROTECTED)
printf("
|_ write protected token\n");
if (((&tokinfo)->flags & CKF_LOGIN_REQUIRED)== CKF_LOGIN_REQUIRED)
printf("
|_ Login required\n");
if (((&tokinfo)->flags & CKF_USER_PIN_INITIALIZED)== CKF_USER_PIN_INITIALIZED)
printf("
|_ User Pin initialized\n");
if (((&tokinfo)->flags & CKF_RESTORE_KEY_NOT_NEEDED)== CKF_RESTORE_KEY_NOT_NEEDED)
printf("
|_ Restore Keys not needed\n");
if (((&tokinfo)->flags & CKF_CLOCK_ON_TOKEN)== CKF_CLOCK_ON_TOKEN)
printf("
|_ Token has hardware clock\n");
if(((&tokinfo)->flags & CKF_PROTECTED_AUTHENTICATION_PATH)==CKF_PROTECTED_AUTHENTICATION_PATH)
printf("
|_ Token has protected configuration path\n");
if (((&tokinfo)->flags & CKF_DUAL_CRYPTO_OPERATIONS)== CKF_DUAL_CRYPTO_OPERATIONS)
printf("
|_ Token supports dual crypto operations\n");
if (((&tokinfo)->flags & CKF_TOKEN_INITIALIZED) == CKF_TOKEN_INITIALIZED)
printf("
|_ Token initialized\n");
if (((&tokinfo)->flags & CKF_SECONDARY_AUTHENTICATION) == CKF_SECONDARY_AUTHENTICATION)
printf("
|_ Token supports secondary authentication\n");
if (((&tokinfo)->flags & CKF_USER_PIN_COUNT_LOW) == CKF_USER_PIN_COUNT_LOW)
printf("
|_ at least one wrong user PIN submitted since last successful authentication\n");
if (((&tokinfo)->flags & CKF_USER_PIN_FINAL_TRY) == CKF_USER_PIN_FINAL_TRY)
printf("
|_ one last try before user PIN become locked\n");
if (((&tokinfo)->flags & CKF_USER_PIN_LOCKED) == CKF_USER_PIN_LOCKED)
printf("
|_ user PIN locked!!!\n");
if (((&tokinfo)->flags & CKF_USER_PIN_TO_BE_CHANGED) == CKF_USER_PIN_TO_BE_CHANGED)
printf("
|_ still default user PIN configured, PIN change recommended.\n");
if (((&tokinfo)->flags & CKF_SO_PIN_COUNT_LOW) == CKF_SO_PIN_COUNT_LOW)
printf("
|_ at least one wrong SO PIN submitted since last successful authentication\n");
if (((&tokinfo)->flags & CKF_SO_PIN_FINAL_TRY) == CKF_SO_PIN_FINAL_TRY)
printf("
|_ one last try before SO PIN become locked\n");
if (((&tokinfo)->flags & CKF_SO_PIN_LOCKED) == CKF_SO_PIN_LOCKED)
printf("
|_ SO PIN locked!!!\n");
if (((&tokinfo)->flags & CKF_SO_PIN_TO_BE_CHANGED) == CKF_SO_PIN_TO_BE_CHANGED)
printf("
|_ still default SO PIN configured, PIN change recommended.\n");
printf(" Sessions: %d/%d\n", (&tokinfo)->ulSessionCount, (&tokinfo)->ulMaxSessionCount);
printf(" R/W Sessions: %d/%d\n", (&tokinfo)->ulRwSessionCount, (&tokinfo)->ulMaxRwSessionCount);
printf(" PIN Length: %d-%d\n", (&tokinfo)->ulMinPinLen, (&tokinfo)->ulMaxPinLen);
printf(" Public Memory: 0x%X/0x%X\n", (&tokinfo)->ulFreePublicMemory, (&tokinfo)->ulTotalPublicMemory);
printf(" Private Memory: 0x%X/0x%X\n",(&tokinfo)->ulFreePrivateMemory, (&tokinfo)->ulTotalPrivateMemory);
printf(" Hardware Version: %d.%d\n", (&tokinfo)->hardwareVersion.major, (&tokinfo)->hardwareVersion.minor);
printf(" Firmware Version: %d.%d\n", (&tokinfo)->firmwareVersion.major, (&tokinfo)->firmwareVersion.minor);
printf(" Time: %.16s\n", (&tokinfo)->utcTime);
return CKR_OK;
}
C_GetMechanismList:
CK_RV getMechanismList(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR
pMechList, CK_ULONG_PTR pulCount) {
CK_RV rc;
rc = C_GetMechanismList(slotID, pMechList, pulCount);
if (rc != CKR_OK) {
printf("Error retrieve mechanism list: %x\n", rc);
return rc;
}
return CKR_OK;
}
154
libica Programmer's Reference
C_GetMechanismInfo:
CK_RV getMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type){
CK_RV rc;
CK_MECHANISM_INFO mechInfo;
rc = C_GetMechanismInfo(slotID, type, &mechinfo);
if (rc != CKR_OK) {
printf("Error in mechanism info: %x\n", rc);
return rc;
}
printf("MinKeySize: %d\n", (&mechinfo)->ulMinKeySize);
printf("MaxKeySize: %d\n", (&mechinfo)->ulMaxKeySize);
printf("Flags: %d\n", (&mechinfo)->flags);
return CKR_OK;
}
C_Finalize:
CK_RV finalize(void) {
CK_RV rc;
rc = C_Finalize(NULL);
if (rc != CKR_OK) {
printf("Error during finalize: %x\n", rc);
return rc;
}
return CKR_OK;
}
Session and login:
C_OpenSession:
CK_RV openSession(CK_SLOT_ID slotID, CK_FLAGS sFlags,
CK_SESSION_HANDLE_PTR phSession) {
CK_RV rc;
rc = C_OpenSession(slotID, sFlags, NULL, NULL, phSession);
if (rc != CKR_OK) {
printf("Error opening session: %x\n", rc); return rc;
}
printf("Open session successful.\n");
return CKR_OK;
}
C_Login:
CK_RV loginSession(CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG ulPinLen,
CK_SESSION_HANDLE hSession) {
CK_RV rc;
rc = C_Login(hSession, userType, pPin, ulPinLen);
if (rc != CKR_OK) {
printf("Error login session: %x\n", rc); return rc;
}
printf("Login session successful.\n");
return CKR_OK;
}
Chapter 7. Examples
155
C_Logout:
CK_RV
CK_RV
rc
if
logoutSession(CK_SESSION_HANDLE hSession) {
rc;
= C_Logout(hSession);
(rc != CKR_OK) {
printf("Error logout session: %x\n", rc); return rc;
}
printf("Logout session successful.\n");
return CKR_OK;
}
C_CloseSession:
CK_RV
CK_RV
rc
if
closeSession(CK_SESSION_HANDLE hSession) {
rc;
= C_CloseSession(hSession);
(rc != CKR_OK) {
printf("Error closing session: 0x%X\n", rc); return rc;
}
printf("Close session successful.\n");
return CKR_OK;
}
Object handling:
C_CreateObject:
CK_RV createKeyObject(CK_SESSION_HANDLE hSession, CK_BYTE keyValue[]) {
CK_RV rc;
CK_OBJECT_HANDLE hKey;
CK_BBOOL true = TRUE;
CK_BBOOL false = FALSE;
CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
CK_KEY_TYPE keyType = CKK_DES;
CK_ATTRIBUTE keyTempl[] = {
{CKA_CLASS, &keyClass, sizeof(keyClass)},
{CKA_KEY_TYPE, &keyType, sizeof(keyType)},
{CKA_ENCRYPT, &true, sizeof(true)},
{CKA_DECRYPT, &true, sizeof(true)},
{CKA_SIGN, &true, sizeof(true)},
{CKA_VERIFY, &true, sizeof(true)},
{CKA_TOKEN, &true, sizeof(true)},
// token object
{CKA_PRIVATE, &false, sizeof(false)},
// public object
{CKA_VALUE, keyValue, sizeof(keyValue)},
{CKA_LABEL, "Public_DES_Key", sizeof("Public_DES_Key")}
};
rc = C_CreateObject(hSession, keyTempl, sizeof (keyTempl)/sizeof (CK_ATTRIBUTE), &hKey);
if (rc != CKR_OK) {
printf("Error creating key object: 0x%X\n", rc); return rc;
}
}
156
libica Programmer's Reference
C_FindObjects:
CK_RV getKey(CK_CHAR_PTR label, int labelLen, CK_OBJECT_HANDLE_PTR hObject,
CK_SESSION_HANDLE hSession) {
CK_RV rc;
CK_ULONG ulMaxObjectCount = 1;
CK_ULONG ulObjectCount;
CK_ATTRIBUTE objectMask[] = { {CKA_LABEL, label, labelLen} };
rc = C_FindObjectsInit(hSession, objectMask, 1);
if (rc != CKR_OK) {
printf("Error FindObjectsInit: 0x%X\n", rc); return rc;
}
rc = C_FindObjects(hSession, hObject, ulMaxObjectCount, &ulObjectCount);
if (rc != CKR_OK) {
printf("Error FindObjects: 0x%X\n", rc); return rc;
}
rc = C_FindObjectsFinal(hSession);
if (rc != CKR_OK) {
printf("Error FindObjectsFinal: 0x%X\n", rc); return rc;
}
}
Cryptographic operations:
C_Encrypt (DES):
K_RV DESencrypt(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pClearData, CK_ULONG ulClearDataLen,
CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen) {
CK_RV rc;
CK_MECHANISM myMechanism = {CKM_DES_ECB, NULL_PTR, 0};
CK_MECHANISM_PTR pMechanism = &myMechanism
CK_OBJECT_HANDLE hKey;
getKey("Public_DES_Key", sizeof("Public_DES_Key"), &hKey, hSession);
rc = C_EncryptInit(hSession, pMechanism, hKey);
if (rc != CKR_OK) {
printf("Error initializing encryption: 0x%X\n", rc);
return rc;
}
rc = C_Encrypt(hSession, pClearData, ulClearDataLen, pEncryptedData, pulEncryptedDataLen);
if (rc != CKR_OK) {
printf("Error during encryption: %x\n", rc);
return rc;
}
CK_BYTE_PTR tmp = pEncryptedData;
for (c=0; c<*pulEncryptedDataLen;c++, pEncryptedData++) {
printf("%X", *pEncryptedData);
}
printf("\n"); pEncryptedData = tmp;
return CKR_OK;
}
Chapter 7. Examples
157
C_Decrypt (DES):
CK_RV DESdecrypt(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen,
CK_BYTE_PTR pClearData, CK_ULONG_PTR pulClearDataLen) {
CK_RV rc;
CK_MECHANISM myMechanism = {CKM_DES_ECB, NULL_PTR, 0};
CK_MECHANISM_PTR pMechanism = &myMechanism
CK_OBJECT_HANDLE hKey;
getKey("Public_DES_Key", sizeof("Public_DES_Key"), &hKey, hSession);
rc = C_DecryptInit(hSession, pMechanism, hKey);
if (rc != CKR_OK) {
printf("Error initializing decryption: 0x%X\n", rc);
return rc;
}
rc = C_Decrypt(hSession, pEncryptedData, ulEncryptedDataLen,
pClearData, pulClearDataLen);
if (rc != CKR_OK) {
printf("Error during decryption: %x\n", rc);
return rc;
}
CK_BYTE_PTR tmp = pClearData;
for (c=0; c<*pulClearDataLen;c++,pClearData++) {
printf("%c", *pClearData);
}
printf("\n"); pClearData = tmp;
return CKR_OK;
}
158
libica Programmer's Reference
C_GenerateKeyPair (RSA):
CK_RV generateRSAKeyPair(CK_SESSION_HANDLE hSession, CK_ULONG keySize,
CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey ) {
CK_RV rc;
CK_BBOOL true = TRUE;
CK_BBOOL false = FALSE;
CK_OBJECT_CLASS keyClassPub = CKO_PUBLIC_KEY;
CK_OBJECT_CLASS keyClassPriv = CKO_PRIVATE_KEY;
CK_KEY_TYPE keyTypeRSA = CKK_RSA;
CK_ULONG modulusBits = keySize;
CK_BYTE_PTR pModulus = malloc(sizeof(CK_BYTE)*modulusBits/8);
CK_BYTE publicExponent[] = {1, 0, 1};
CK_MECHANISM rsaKeyGenMech = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0};
CK_ATTRIBUTE publicKeyTemplate[] = {
{CKA_CLASS, &keyClassPub, sizeof(keyClassPub)},
{CKA_KEY_TYPE, &keyTypeRSA, sizeof(keyTypeRSA)},
{CKA_TOKEN, &true, sizeof(true)},
{CKA_PRIVATE, &true, sizeof(true)},
{CKA_ENCRYPT, &true, sizeof(true)},
{CKA_VERIFY, &true, sizeof(true)},
{CKA_WRAP, &true, sizeof(true)},
{CKA_MODULUS_BITS, &modulusBits, sizeof(modulusBits)},
{CKA_PUBLIC_EXPONENT, publicExponent, sizeof(publicExponent)},
{CKA_LABEL, "My_Private_Token_RSA1024_PubKey",
sizeof("My_Private_Token_RSA1024_PubKey")},
{CKA_MODIFIABLE, &true, sizeof(true)},
};
CK_ATTRIBUTE privateKeyTemplate[] = {
{CKA_CLASS, &keyClassPriv, sizeof(keyClassPriv)},
{CKA_KEY_TYPE, &keyTypeRSA, sizeof(keyTypeRSA)},
{CKA_EXTRACTABLE, &true, sizeof(true)},
{CKA_TOKEN, &true, sizeof(true)},
{CKA_PRIVATE, &true, sizeof(true)},
{CKA_SENSITIVE, &true, sizeof(true)},
{CKA_DECRYPT, &true, sizeof(true)},
{CKA_SIGN, &true, sizeof(true)},
{CKA_UNWRAP, &true, sizeof(true)},
{CKA_LABEL, "My_Private_Token_RSA1024_PrivKey",
sizeof("My_Private_Token_RSA1024_PrivKey")},
{CKA_MODIFIABLE, &true, sizeof(true)},
};
rc = C_GenerateKeyPair(hSession, &rsaKeyGenMech , &publicKeyTemplate,
sizeof(publicKeyTemplate)/sizeof (CK_ATTRIBUTE), &privateKeyTemplate,
sizeof(privateKeyTemplate)/sizeof (CK_ATTRIBUTE), phPublicKey, phPrivateKey);
if (rc != CKR_OK) {
printf("Error generating RSA keys: %x\n", rc);
return rc;
}
}
Chapter 7. Examples
159
C_Encrypt (RSA):
CK_RV RSAencrypt(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey,
CK_BYTE_PTR pClearData, CK_ULONG ulClearDataLen,
CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen) {
CK_RV rc;
CK_MECHANISM rsaMechanism = {CKM_RSA_PKCS, NULL_PTR, 0};
rc = C_EncryptInit(hSession, rsaMechanism, hKey);
if (rc != CKR_OK) {
printf("Error initializing RSA encryption: %x\n", rc);
return rc;
}
rc = C_Encrypt(hSession, pClearData, ulClearDataLen,
pEncryptedData, pulEncryptedDataLen);
if (rc != CKR_OK) {
printf("Error during RSA encryption: %x\n", rc);
return rc;
}
CK_BYTE_PTR tmp = pEncryptedData;
for (c=0; c<*pulEncryptedDataLen;c++,pEncryptedData++) {
printf("%X", *pEncryptedData);
}
printf("\n"); pEncryptedData = tmp;
return CKR_OK;
}
C_Decrypt (RSA):
CK_RV RSAdecrypt(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey,
CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen,
CK_BYTE_PTR pClearData, CK_ULONG_PTR pulClearDataLen) {
CK_RV rc;
CK_MECHANISM rsaMechanism = {CKM_RSA_PKCS, NULL_PTR, 0};
rc = C_DecryptInit(hSession, rsaMechanism, hKey);
if (rc != CKR_OK) {
printf("Error initializing RSA decryption: %x\n", rc);
return rc;
}
rc = C_Decrypt(hSession, pEncryptedData, ulEncryptedDataLen,
pClearData, pulClearDataLen);
if (rc != CKR_OK) {
printf("Error during RSA decryption: %x\n", rc);
return rc;
}
CK_BYTE_PTR tmp = pClearData;
for (c=0; c<*pulClearDataLen;c++,pClearData++) {
printf("%c", *pClearData);
}
printf("\n"); pClearData = tmp;
return CKR_OK;
}
For more information, refer to the current PKCS#11standard/specification:
http://www.cryptsoft.com/pkcs11doc/
160
libica Programmer's Reference
Appendix. Supported mechanism list for the ica token
|
openCryptoki/ica token v2.4.3.
Table 7. Supported mechanism list for the ica token
Mechanisms
C (native)
ica token
CKM_RSA_PKCS_KEY_PAIR_GEN
x
CKM_RSA_PKCS
x
CKM_RSA_X_509
x
CKM_MD2_RSA_PKCS
x
CKM_MD5_RSA_PKCS
x
CKM_SHA1_RSA_PKCS
x
|
CKM_SHA256_RSA_PKCS
x
|
CKM_SHA384_RSA_PKCS
x
|
CKM_SHA512_RSA_PKCS
x
CKM_DES_KEY_GEN
x
CKM_DES_ECB
x
CKM_DES_CBC
x
CKM_DES_CBC_PAD
x
CKM_DES3_KEY_GEN
x
CKM_DES3_ECB
x
CKM_DES3_CBC
x
CKM_DES3_CBC_PAD
x
CKM_MD2
x
CKM_MD5
x
CKM_MD5_HMAC
x
CKM_MD5_HMAC_GENERAL
x
CKM_SHA_1
x
CKM_SHA_1_HMAC
x
CKM_SHA_1_HMAC_GENERAL
x
CKM_SHA256
x
CKM_SHA256_HMAC
x
CKM_SHA256_HMAC_GENERAL
x
© Copyright IBM Corporation © IBM 2009, 2013
161
Table 7. Supported mechanism list for the ica token (continued)
Mechanisms
C (native)
ica token
162
CKM_SHA384
x
CKM_SHA384_HMAC
x
CKM_SHA384_HMAC_GENERAL
x
CKM_SHA512
x
CKM_SHA512_HMAC
x
CKM_SHA512_HMAC_GENERAL
x
CKM_SSL3_PRE_MASTER_KEY_GEN
x
CKM_SSL3_MASTER_KEY_DERIVE
x
CKM_SSL3_KEY_AND_MAC_DERIVE
x
CKM_SSL3_MD5_MAC
x
CKM_SSL3_SHA1_MAC
x
CKM_AES_KEY_GEN
x
CKM_AES_ECB
x
CKM_AES_CBC
x
CKM_AES_CBC_PAD
x
CKM_AES_CTR
x
libica Programmer's Reference
Accessibility
Accessibility features help users who have a disability, such as restricted mobility
or limited vision, to use information technology products successfully.
Documentation accessibility
The Linux on System z publications are in Adobe Portable Document Format
(PDF) and should be compliant with accessibility standards. If you experience
difficulties when you use the PDF file and want to request a Web-based format for
this publication, use the Reader Comment Form in the back of this publication,
send an email to [email protected], or write to:
IBM Deutschland Research & Development GmbH
Information Development
Department 3282
Schoenaicher Strasse 220
71032 Boeblingen
Germany
In the request, be sure to include the publication number and title.
When you send information to IBM, you grant IBM a nonexclusive right to use or
distribute the information in any way it believes appropriate without incurring any
obligation to you.
IBM and accessibility
See the IBM Human Ability and Accessibility Center for more information about
the commitment that IBM has to accessibility at
http://www-03.ibm.com/able/
© Copyright IBM Corp. 2009, 2013
163
164
libica Programmer's Reference
Notices
This information was developed for products and services offered in the U.S.A.
IBM may not offer the products, services, or features discussed in this document in
other countries. Consult your local IBM representative for information on the
products and services currently available in your area. Any reference to an IBM
product, program, or service is not intended to state or imply that only that IBM
product, program, or service may be used. Any functionally equivalent product,
program, or service that does not infringe any IBM intellectual property right may
be used instead. However, it is the user's responsibility to evaluate and verify the
operation of any non-IBM product, program, or service.
IBM may have patents or pending patent applications covering subject matter
described in this document. The furnishing of this document does not grant you
any license to these patents. You can send license inquiries, in writing, to:
IBM Director of Licensing
IBM Corporation
North Castle Drive
Armonk, NY 10504-1785
U.S.A.
For license inquiries regarding double-byte character set (DBCS) information,
contact the IBM Intellectual Property Department in your country or send
inquiries, in writing, to:
IBM World Trade Asia Corporation
Intellectual Property Licensing
Legal and Intellectual Property Law
IBM Japan Ltd.
1623-14, Shimotsuruma, Yamato-shi
Kanagawa 242-8502 Japan
The following paragraph does not apply to the United Kingdom or any other
country where such provisions are inconsistent with local law:INTERNATIONAL
BUSINESS MACHINES CORPORATION PROVIDES THIS PUBLICATION "AS IS"
WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR
PURPOSE. Some states do not allow disclaimer of express or implied warranties in
certain transactions, therefore, this statement may not apply to you.
This information could include technical inaccuracies or typographical errors.
Changes are periodically made to the information herein; these changes will be
incorporated in new editions of the publication. IBM may make improvements
and/or changes in the product(s) and/or the program(s) described in this
publication at any time without notice.
Any references in this information to non-IBM Web sites are provided for
convenience only and do not in any manner serve as an endorsement of those Web
sites. The materials at those Web sites are not part of the materials for this IBM
product and use of those Web sites is at your own risk.
© Copyright IBM Corp. 2009, 2013
165
IBM may use or distribute any of the information you supply in any way it
believes appropriate without incurring any obligation to you.
Licensees of this program who wish to have information about it for the purpose
of enabling: (i) the exchange of information between independently created
programs and other programs (including this one) and (ii) the mutual use of the
information which has been exchanged, should contact:
IBM Corporation
Software Interoperability Coordinator, Department 49XA
3605 Highway 52 N
Rochester, MN 55901
U.S.A.
Such information may be available, subject to appropriate terms and conditions,
including in some cases, payment of a fee.
The licensed program described in this information and all licensed material
available for it are provided by IBM under terms of the IBM Customer Agreement,
IBM International Program License Agreement, or any equivalent agreement
between us.
Any performance data contained herein was determined in a controlled
environment. Therefore, the results obtained in other operating environments may
vary significantly. Some measurements may have been made on development-level
systems and there is no guarantee that these measurements will be the same on
generally available systems. Furthermore, some measurements may have been
estimated through extrapolation. Actual results may vary. Users of this document
should verify the applicable data for their specific environment.
Information concerning non-IBM products was obtained from the suppliers of
those products, their published announcements or other publicly available sources.
IBM has not tested those products and cannot confirm the accuracy of
performance, compatibility or any other claims related to non-IBM products.
Questions on the capabilities of non-IBM products should be addressed to the
suppliers of those products.
This information contains examples of data and reports used in daily business
operations. To illustrate them as completely as possible, the examples include the
names of individuals, companies, brands, and products. All of these names are
fictitious and any similarity to the names and addresses used by an actual business
enterprise is entirely coincidental.
COPYRIGHT LICENSE: This information contains sample application programs in
source language, which illustrate programming techniques on various operating
platforms. You may copy, modify, and distribute these sample programs in any
form without payment to IBM, for the purposes of developing, using, marketing or
distributing application programs conforming to the application programming
interface for the operating platform for which the sample programs are written.
These examples have not been thoroughly tested under all conditions. IBM,
therefore, cannot guarantee or imply reliability, serviceability, or function of these
programs. The sample programs are provided "AS IS", without warranty of any
kind. IBM shall not be liable for any damages arising out of your use of the sample
programs.
166
libica Programmer's Reference
If you are viewing this information softcopy, the photographs and color
illustrations may not appear.
Trademarks
IBM, the IBM logo, and ibm.com® are trademarks or registered trademarks of
International Business Machines Corp., registered in many jurisdictions worldwide.
Other product and service names might be trademarks of IBM or other companies.
A current list of IBM trademarks is available on the Web at "Copyright and
trademark information" at
www.ibm.com/legal/copytrade.shtml
Adobe is either a registered trademark or trademark of Adobe Systems
Incorporated in the United States, and/or other countries.
Intel is a trademark or registered trademark of Intel Corporation or its subsidiaries
in the United States and other countries.
Java™ and all Java-based trademarks and logos are trademarks or registered
trademarks of Oracle and/or its affiliates.
Linux is a registered trademark of Linus Torvalds in the United States, other
countries, or both.
UNIX is a registered trademark of The Open Group in the United States and other
countries.
Notices
167
168
libica Programmer's Reference
Glossary
Central Processor Assist for Cryptographic Function (CPACF)
Hardware that provides support for symmetric ciphers and secure hash
algorithms (SHA) on every central processor. Hence the potential
encryption/decryption throughput scales with the number of central
processors in the system.
Chinese-Remainder Theorem (CRT)
A mathematical problem described by Sun Tsu Suan-Ching using the
remainder from a division operation.
Cipher Block Chaining (CBC)
A method of reducing repetitive patterns in ciphertext by performing an
exclusive-OR operation on each 8-byte block of data with the previously
encrypted 8-byte block before it is encrypted.
Cipher block length
The length of a block that can be encrypted or decrypted by a symmetric
cipher. Each symmetric cipher has a specific cipher block length.
CPACF instructions
Instruction set for the CPACF hardware.
Crypto Express2 (CEX2)
The two PCI-X adapters on a CEX2 feature can be configured in two ways:
Either as cryptographic Coprocessor (CEX2C) for secure key encrypted
transactions, or as cryptographic Accelerator (CEX2A) for Secure Sockets
Layer (SSL) acceleration. A CEX2A works only in clear key mode. Both
adapters can be of the same type, or you can configure one adapter as
CEX2A and the other as CEX2C.
Crypto Express3 (CEX3)
Successor to the Crypto Express2 feature. The two PCI-X adapters on a
CEX3 feature can be configured in two ways: Either as cryptographic
Coprocessor (CEX3C) for secure key encrypted transactions, or as
cryptographic Accelerator (CEX3A) for Secure Sockets Layer (SSL)
acceleration. A CEX3A works only in clear key mode. Both adapters can be
of the same type, or you can configure one adapter as CEX3A and the
other as CEX3C.
electronic code book mode (ECB mode)
A method of enciphering and deciphering data in address spaces or data
spaces. Each 64-bit block of plaintext is separately enciphered and each
block of the ciphertext is separately deciphered.
libica
Library for IBM Cryptographic Architecture.
Mode of operation
A schema describing how to apply a symmetric cipher to encrypt or
decrypt a message that is longer than the cipher block length. The goal of
most modes of operation is to keep the security level of the cipher by
avoiding the situation where blocks that occur more than once will always
be translated to the same value. Some modes of operations allow handling
messages of arbitrary lengths.
modulus-exponent (Mod-Expo)
A type of exponentiation performed using a modulus.
© Copyright IBM Corporation © IBM 2009, 2013
169
Rivest-Shamir-Adleman (RSA)
An algorithm used in public key cryptography. These are the surnames of
the three researchers responsible for creating this asymmetric or
public/private key algorithm.
Secure Hash Algorithm (SHA)
An encryption method in which data is encrypted in a way that is
mathematically impossible to reverse. Different data can possibly produce
the same hash value, but there is no way to use the hash value to
determine the original data.
symmetric cipher
An encryption method that uses the same key for encryption and
decryption. Keys of symmetric ciphers are private keys.
z90crypt
Linux device driver for cryptographic adapters of IBM System z. The libica
Version 2, libica Version 2.1.0, and libica Version 2.3.0 libraries interact
directly with the z90crypt device driver.
170
libica Programmer's Reference
Index
Numerics
31-bit vii
3DES 29
Cipher Based Message Authentication
Code (CMAC) 33
Cipher Based Message Authentication
Code (CMAC) intermediate 34
Cipher Based Message Authentication
Code (CMAC) last 35
Cipher Block Chaining (CBC) 30
Cipher Block Chaining with Cipher
text Stealing (CBC-CS) 30
Cipher Feedback (CFB) 32
Counter (CTR) mode 36
Counter (CTR) mode with list 37
Electronic Code Book (ECB) 38
Output Feedback (OFB) 39
64-bit vii
A
about this document vii
accessibility 163
adapter
close 8
functions 7
open 8
AES 40
Cipher Based Message Authentication
Code (CMAC) 46
Cipher Based Message Authentication
Code (CMAC) last 48
Cipher Block Chaining (CBC) 41
Cipher Block Chaining with Cipher
text Stealing (CBC-CS) 42
Cipher Feedback (CFB) 45
Counter (CTR) mode 49
Counter (CTR) mode with list 50
Counter with CBC MAC (CCM) 43,
52
Electronic Code Book (ECB) 51
Output Feedback (OFB) 54
XEX-based Tweaked CodeBook mode
with CipherText Stealing (XTS) 55
AES with CFB mode
examples 101
AES with CTR mode
examples 113
AES with OFB mode
examples 123
AES with XTS mode
examples 131
API
ica_3des_cbc 30
ica_3des_cbc_cs 30
ica_3des_cfb 32
ica_3des_cmac 33
ica_3des_cmac_intermediate 34
ica_3des_cmac_last 35
ica_3des_ctr 36
© Copyright IBM Corp. 2009, 2013
API (continued)
ica_3des_ctrlist 37
ica_3des_ecb 38
ica_3des_ofb 39
ica_aes_cbc 41
ica_aes_cbc_cs 42
ica_aes_ccm 43
ica_aes_cfb 45
ica_aes_cmac 46
ica_aes_cmac_intermediate 47
ica_aes_cmac_last 48
ica_aes_ctr 49
ica_aes_ctrlist 50
ica_aes_ecb 51
ica_aes_gcm 52
ica_aes_ofb 54
ica_aes_xts 55
ica_close_adapter 8
ica_des_cbc 18
ica_des_cbc_cs 19
ica_des_cfb 20
ica_des_cmac 21
ica_des_cmac_intermediate 22
ica_des_cmac_last 23
ica_des_ctr 24
ica_des_ctrlist 26
ica_des_ecb 27
ica_des_ofb 27
ica_get_functionlist 57
ica_get_version 57
ica_open_adapter 8
ica_random_number_generate 14
ica_rsa_crt 17
ica_rsa_key_generate_crt 15
ica_rsa_key_generate_mod_expo 15
ica_rsa_mod_expo 16
ica_sha1 9
ica_sha224 10
ica_sha256 11
ica_sha384 12
ica_sha512 13
libica Version 2.3.0 5
assumptions viii
available functions 71
C
C_CloseSession 155
C_CreateObject 156
C_Decrypt (DES) 157
C_Decrypt (RSA) 157
C_Encrypt (DES) 157
C_Encrypt (RSA) 157
C_FindObjects 156
C_GenerateKeyPair (RSA)
C_Login 155
C_Logout 155
C_OpenSession 155
chzcrypt 2
CMAC
examples 141
157
commands
icainfo 71
icastats 72
Common Public License - V1.0
conventions viii
CPACF 1
CryptoCard 1
145
D
defines 67
DES 18
Cipher Based Message Authentication
Code (CMAC) 21
Cipher Based Message Authentication
Code (CMAC) intermediate 22, 47
Cipher Based Message Authentication
Code (CMAC) last 23
Cipher Block Chaining (CBC) 18
Cipher Block Chaining with Cipher
text Stealing (CBC-CS) 19
Cipher Feedback (CFB) 20
Counter (CTR) mode 24
Counter (CTR) mode with list 26
Electronic Code Book (ECB) 27
Output Feedback (OFB) 27
DES with CTR mode
examples 95
DES with ECB mode
examples 75
distribution independence viii
dynamic library call 150
E
examples 75
AES with CFB mode 101
AES with CTR mode 113
AES with OFB mode 123
AES with XTS mode 131
CMAC 141
Common Public License - V1.0 145
DES with CTR mode 95
DES with ECB mode 75
key generation 84
makefile 145
pseudo random number 83
RSA 91
SHA-256 78
table 75
triple DES with CBC mode 98
G
glossary
169
H
highlighting
ix
171
I
L
P
IBM books ix
IBM systems viii
IBMPKCS11Impl-Provider 161
ica token 161
ica_3des_cbc 30
ica_3des_cbc_cs 30
ica_3des_cfb 32
ica_3des_cmac 33
ica_3des_cmac_intermediate 34
ica_3des_cmac_last 35
ica_3des_ctr 36
ica_3des_ctrlist 37
ica_3des_ecb 38
ica_3des_ofb 39
ica_aes_cbc 41
ica_aes_cbc_cs 42
ica_aes_ccm 43
ica_aes_cfb 45
ica_aes_cmac 46
ica_aes_cmac_intermediate 47
ica_aes_cmac_last 48
ica_aes_ctr 49
ica_aes_ctrlist 50
ica_aes_ecb 51
ica_aes_gccm 52
ica_aes_ofb 54
ica_aes_xts 55
ica_close_adapter 7, 8
ica_des_cbc 18
ica_des_cbc_cs 19
ica_des_cfb 20
ica_des_cmac 21
ica_des_cmac_intermediate 22
ica_des_cmac_last 23
ica_des_ctr 24
ica_des_ctrlist 26
ica_des_ecb 27
ica_des_ofb 27
ica_get_functionlist 57
ica_get_version 57
ica_open_adapter 7, 8
ica_random_number_generate 14
ica_rsa_crt 17
ica_rsa_key_generate_crt 15
ica_rsa_key_generate_mod_expo 15
ica_rsa_mod_expo 16
ica_sha1 9
ica_sha224 10
ica_sha256 11
ica_sha384 12
ica_sha512 13
icainfo command 71
icastats command 72
icatoken 60
Information retrieval functions 57
libica
APIs 5
coexistance 4
defines 67
examples 1, 75
function list 57
general information
return codes 70
structs 68
typedefs 67
using 4
version 57
libica Version 2.3.0
binary package 3
installation 3
libopencryptoki.so 59
Linux
distribution viii
lszcrypt 2
pk_config_data 63
PKCS #11
functions 60
PKCS #11 functions 60
PKCS #11 standard 59
pkcs11_startup 63
pkcsconf 64
pkcsconf -t 65
pkcsslotd 59
pseudo random number
examples 83
K
key
CRT format 15
modulus/exponent
key generation
examples 84
172
15
libica Programmer's Reference
1
R
random number 14
return codes 70
RSA
examples 91
S
M
makefile
examples
145
N
notices
14
165
O
openCryptoki 59
API 59
base library 63
base procedures 151
binary package 62
C_CloseSession 155
C_CreateObject 156
C_Decrypt (DES) 157
C_Decrypt (RSA) 157
C_Encrypt (DES) 157
C_Encrypt (RSA) 157
C_FindObjects 156
C_GenerateKeyPair (RSA) 157
C_Login 155
C_Logout 155
C_OpenSession 155
code samples 149
crypto adapter 2
icainfo 149
icastats 149
installing 62
libica package 63
libica status information 149
lszcrypt 2
slot manager 59
SO PIN 64
source package 3, 62
standard PIN 64
status information 65
STDLLs 59
token library 63
zcrypt status information 2
overview 59
sample programs 1
secure hash 9
SHA-1 9
SHA-224 10
SHA-256 11
examples 78
SHA-384 12
SHA-512 13
shared linked library 151
slot manager 59
slot token dynamic link libraries
(STDLLs) 59
status information 65
structs 68
summary of changes v
T
TDES 29
Cipher Based Message Authentication
Code (CMAC) 33
Cipher Based Message Authentication
Code (CMAC) intermediate 34
Cipher Based Message Authentication
Code (CMAC) last 35
Cipher Block Chaining (CBC) 30
Cipher Block Chaining with Cipher
text Stealing (CBC-CS) 30
Cipher Feedback (CFB) 32
Counter (CTR) mode 36
Counter (CTR) mode with list 37
Electronic Code Book (ECB) 38
Output Feedback (OFB) 39
terminology viii
token
initializing 64
trademarks 167
triple DES 29
triple DES with CBC mode
examples 98
typedefs 67
W
who should read this document
vii
Z
zcrypt status information
2
Index
173
174
libica Programmer's Reference
Readers’ Comments — We'd Like to Hear from You
Linux on System z
libica Programmer's Reference
Version 2.3.0
Publication No. SC34-2602-04
We appreciate your comments about this publication. Please comment on specific errors or omissions, accuracy,
organization, subject matter, or completeness of this book. The comments you send should pertain to only the
information in this manual or product and the way in which the information is presented.
For technical questions and information about products and prices, please contact your IBM branch office, your
IBM business partner, or your authorized remarketer.
When you send comments to IBM, you grant IBM a nonexclusive right to use or distribute your comments in any
way it believes appropriate without incurring any obligation to you. IBM or any other organizations will only use
the personal information that you supply to contact you about the issues that you state on this form.
Comments:
Thank you for your support.
Submit your comments using one of these channels:
v Send your comments to the address on the reverse side of this form.
v Send your comments via email to: [email protected]
If you would like a response from IBM, please fill in the following information:
Name
Address
Company or Organization
Phone No.
Email address
SC34-2602-04
___________________________________________________________________________________________________
Readers’ Comments — We'd Like to Hear from You
Cut or Fold
Along Line
_ _ _ _ _ _ _Fold
_ _ _and
_ _ _Tape
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _Please
_ _ _ _ do
_ _ not
_ _ _staple
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _Fold
_ _ _and
_ _ Tape
______
PLACE
POSTAGE
STAMP
HERE
IBM Deutschland Research & Development GmbH
Information Development
Department 3248
Schoenaicher Strasse 220
71032 Boeblingen
Germany
________________________________________________________________________________________
Fold and Tape
Please do not staple
Fold and Tape
SC34-2602-04
Cut or Fold
Along Line
SC34-2602-04
Was this manual useful for you? yes no
Thank you for your participation!

* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project

Download PDF

advertisement