summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri John Ledkov <xnox@ubuntu.com>2016-11-24 16:48:43 +0000
committerDimitri John Ledkov <xnox@ubuntu.com>2016-11-24 16:48:43 +0000
commitb33f77cf05cb266494ef8dacd21758271e7103a6 (patch)
treebf5b172d5a7b9bee3877c4fc838cc3ebf9aa308f
Import libica_3.0.1.orig.tar.gz
[dgit import orig libica_3.0.1.orig.tar.gz]
-rw-r--r--AUTHORS5
-rw-r--r--COPYING242
-rw-r--r--ChangeLog76
-rw-r--r--INSTALL182
-rw-r--r--LICENSE242
-rw-r--r--Makefile.am5
-rw-r--r--NEWS0
-rw-r--r--README1
-rwxr-xr-xbootstrap.sh6
-rwxr-xr-xcleanup.sh21
-rw-r--r--configure.in115
-rw-r--r--doc/Makefile.am1
-rw-r--r--doc/icainfo.169
-rw-r--r--doc/icastats.1122
-rw-r--r--include/Makefile.am2
-rw-r--r--include/ica_api.h2960
-rw-r--r--libica.spec100
-rw-r--r--src/Makefile.am18
-rw-r--r--src/fips.c937
-rw-r--r--src/ica_api.c2147
-rw-r--r--src/icainfo.c267
-rw-r--r--src/icastats.c250
-rw-r--r--src/icastats_shared.c314
-rw-r--r--src/include/fips.h62
-rw-r--r--src/include/icastats.h125
-rw-r--r--src/include/init.h26
-rw-r--r--src/include/s390_aes.h725
-rw-r--r--src/include/s390_cbccs.h319
-rw-r--r--src/include/s390_ccm.h342
-rw-r--r--src/include/s390_cmac.h194
-rw-r--r--src/include/s390_common.h40
-rw-r--r--src/include/s390_crypto.h485
-rw-r--r--src/include/s390_ctr.h131
-rw-r--r--src/include/s390_des.h618
-rw-r--r--src/include/s390_drbg.h269
-rw-r--r--src/include/s390_drbg_sha512.h88
-rw-r--r--src/include/s390_gcm.h438
-rw-r--r--src/include/s390_prng.h20
-rw-r--r--src/include/s390_rsa.h47
-rw-r--r--src/include/s390_sha.h185
-rw-r--r--src/include/test_vec.h311
-rw-r--r--src/init.c178
-rw-r--r--src/s390_crypto.c392
-rw-r--r--src/s390_drbg.c882
-rw-r--r--src/s390_drbg_sha512.c666
-rw-r--r--src/s390_prng.c329
-rw-r--r--src/s390_rsa.c1037
-rw-r--r--src/s390_sha.c321
-rw-r--r--src/test_vec.c3831
-rw-r--r--src/tests/Makefile.am51
-rw-r--r--src/tests/icastats_test.c881
-rw-r--r--src/tests/libica_3des_cbc_test.c159
-rw-r--r--src/tests/libica_3des_cfb_test.c178
-rw-r--r--src/tests/libica_3des_ctr_test.c163
-rw-r--r--src/tests/libica_3des_ecb_test.c295
-rw-r--r--src/tests/libica_3des_ofb_test.c164
-rw-r--r--src/tests/libica_3des_test.c138
-rw-r--r--src/tests/libica_aes128_test.c271
-rw-r--r--src/tests/libica_aes192_test.c153
-rw-r--r--src/tests/libica_aes256_test.c153
-rw-r--r--src/tests/libica_aes_cbc_test.c614
-rw-r--r--src/tests/libica_aes_cfb_test.c804
-rw-r--r--src/tests/libica_aes_ctr_test.c638
-rw-r--r--src/tests/libica_aes_ecb_test.c485
-rw-r--r--src/tests/libica_aes_gcm_test.c1043
-rw-r--r--src/tests/libica_aes_ofb_test.c526
-rw-r--r--src/tests/libica_aes_xts_test.c644
-rw-r--r--src/tests/libica_cbccs_test.c548
-rw-r--r--src/tests/libica_ccm_test.c179
-rw-r--r--src/tests/libica_cmac_test.c307
-rw-r--r--src/tests/libica_des_cbc_test.c320
-rw-r--r--src/tests/libica_des_cfb_test.c187
-rw-r--r--src/tests/libica_des_ctr_test.c182
-rw-r--r--src/tests/libica_des_ecb_test.c151
-rw-r--r--src/tests/libica_des_ofb_test.c172
-rw-r--r--src/tests/libica_des_test.c147
-rw-r--r--src/tests/libica_drbg_birthdays.c139
-rw-r--r--src/tests/libica_drbg_test.c623
-rw-r--r--src/tests/libica_fips_test.c66
-rw-r--r--src/tests/libica_get_functionlist.c68
-rw-r--r--src/tests/libica_get_version.c60
-rw-r--r--src/tests/libica_keygen_test.c271
-rw-r--r--src/tests/libica_rng_test.c47
-rw-r--r--src/tests/libica_rsa_key_check_test.c96
-rw-r--r--src/tests/libica_rsa_test.c120
-rw-r--r--src/tests/libica_rsa_test.h2175
-rw-r--r--src/tests/libica_sha1_test.c200
-rw-r--r--src/tests/libica_sha256_test.c190
-rw-r--r--src/tests/libica_sha_test/Makefile.am26
-rw-r--r--src/tests/libica_sha_test/include/critical_error.h14
-rw-r--r--src/tests/libica_sha_test/include/queue_t.h33
-rw-r--r--src/tests/libica_sha_test/include/read_rsp.h14
-rw-r--r--src/tests/libica_sha_test/include/sha_tests.h22
-rw-r--r--src/tests/libica_sha_test/libica_sha_test.c118
-rw-r--r--src/tests/libica_sha_test/queue_t.c60
-rw-r--r--src/tests/libica_sha_test/read_rsp.c200
-rw-r--r--src/tests/libica_sha_test/sha_test_vectors/SHA1.txt36
-rw-r--r--src/tests/libica_sha_test/sha_test_vectors/SHA224.txt39
-rw-r--r--src/tests/libica_sha_test/sha_test_vectors/SHA256.txt39
-rw-r--r--src/tests/libica_sha_test/sha_test_vectors/SHA384.txt43
-rw-r--r--src/tests/libica_sha_test/sha_test_vectors/SHA512.txt43
-rw-r--r--src/tests/libica_sha_test/sha_tests.c186
-rwxr-xr-xsrc/tests/suite.run63
-rw-r--r--src/tests/testcase.h47
104 files changed, 34734 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..508b48e
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,5 @@
+Holger Dengler <hd@linux.vnet.ibm.com>
+Rainer Wolafka <rwolafka@de.ibm.com>
+Ruben Straus <rstraus@de.ibm.com>
+Felix Beck <felix.beck@de.ibm.com>
+Christian Maaser <cmaaser@de.ibm.com>
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..c49429d
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,242 @@
+
+ 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,
+ 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.
+
+ 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
+
+ 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.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..669e525
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,76 @@
+v3.0.1
+ - [PATCH] Fixed msa level detection on zEC/BC12 GA1 and predecessors.
+v3.0.0
+ - [FEATURE] Added FIPS mode.
+ - [PATCH] Sanitized exported symbols.
+ - [PATCH] Removed deprecated APIs. Marked some APIs as deprecated.
+ - [PATCH] Adapted to OpenSSL v1.1.0.
+ - [PATCH] RSA key generation is thread-save now.
+v2.6.2
+ - [PATCH] Performance improvements for des-ctr, 3des-ctr and aes-ctr
+v2.6.1
+ - [Patch] Fixed buffer overflow on random generation
+ - [Patch] Fixed DRBG entropy input
+ - [Patch] Fixed icastats test case
+v2.6.0
+ - [FEATURE] Added NIST compliant deterministic random bit generator (DRBG)
+v2.5.0
+ - [FEATURE] Added streaming support for Galois Counter Mode (AES-GCM)
+ - [FEATURE] Allow RSA Key generation for any granularity (57..4096 bits)
+ - [FEATURE] New RSA CRT Key check API (Convertion of non-compliant keys)
+ - [PATCH] Replaced deprecated RSA_key_generate function
+ - [PATCH] Fixed accounting for GCM, CCM and CMAC. Added accounting for GHASH
+ - [PATCH] Improved configure script to automatically build test cases
+ - [UPDATE] Added SHA test cases. Improved and extended test suite
+ v2.4.0
+ Reworked the statistic measurement facility (icastats)
+ - Statistics are now collected independent from the process context
+ - Statistic data gathered per user
+ - User based statistic management (reset/delete/summerize)
+v2.3.0
+ Changes since Version 2.2.0:
+ - Introduced new API to recieve list of supported algorithms
+v2.2.0
+ Introduce support for more MSA4 extensions.
+ New symetric encryption modes:
+ - CBC-CS (DES, TDES, AES-[128|192|256])
+ - CMAC (DES, TDES, AES-[128|192|256])
+ - CCM (AES-[128|192|256])
+ - GCM (AES-[128|256])
+v2.1.1
+ Changes since Version 2.1.0:
+ - [PATCH] synchronize shared memory ref counting
+ - [PATCH] Fix result/error handling in testcase for ica_get_version()
+ - [PATCH] Fix temporary buffer allocation in ica_get_version()
+ - [UPDATE] Interface (API) description
+ - [PATCH] Fix commandline argument checking in RSA testcase
+ - [PATCH] Remove duplicate entry from target list
+v2.1.0
+- Introduce support for MSA4 extensions. New symmetric encryption modes:
+ CFB, CTR, OFB, XTS, CMAC
+- New API calls:
+ - ica_get_version(...)
+v2.0.6
+Fix for tracker item 3202845.
+ Improve online help for icastats.
+v2.0.5
+Fix for performance improvement
+ Remove signal handler wrapping of crypto instructions.
+v2.0.4
+Fix for STCK buffer length
+ Correctly adjust the STCK buffer length in the PRNG based on whether
+ we are running in 31 or 64 bit.
+v2.0.3
+minor wording fix in icastats tool:
+ changed output wording from SHAxxx to SHA-xxx
+Bugfix for:
+ libica abends with illegal instuction when CPACF is disabled.
+v2.0.2
+Bug fixes in asm, stcke for 31 bit, and fixes in programming samples
+v2.0.1
+Add locking for shared memory segment, which is needed when icastats
+is linked dynamically against libica.
+v2.0
+Substitute software fallbacks with lowlevel OpenSSL function calls.
+Rewrite most of libica.
+Only Linux on System z code.
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..bafe81b
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,182 @@
+Basic Installation
+==================
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+ The file `configure.in' is used to create `configure' by a program
+called `autoconf'. You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ ./bootstrap.sh. This will prepare the initial environment like
+ the 'configure' script.
+
+ 2. Run `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Optionally, if you want to build the included test cases automatically
+ you can call the configure script with the '--enable-testcases' option.
+ `./configure --enable-testcases`. At compile time all test cases will
+ be build automatically.
+
+ Running `configure' takes awhile. While running, it prints some
+ messages telling which features it is checking for.
+
+ 3. Type `make' to compile the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. Optionally, if you want to execute the integrated test suite located
+ in ./src/tests that come with the package, type `./suite.run`.
+ For silent mode (increased performance) use the 'silent' parameter.
+ (e.g. `./suite.run silent`)
+
+ 6. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+NOTE: If you wish to build a 31-bit library on S390X, you will need to
+ pass the following to the ./configure in step 1:
+ --build=s390-unknown-linux-gnu
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. You can give `configure'
+initial values for variables by setting them in the environment. Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+ CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+ env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+ You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory. After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+ By default, `make install' will install libica.so in '/usr/lib/libica.so'
+and ica_api.h in '/usr/include/ica_api.h', except on 64-bit platforms where
+libica.so will be installed in '/usr/lib64/libica.so'
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on. Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+ CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+ If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+ Use and save the results of the tests in FILE instead of
+ `./config.cache'. Set FILE to `/dev/null' to disable caching, for
+ debugging `configure'.
+
+`--help'
+ Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--version'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..c49429d
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,242 @@
+
+ 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,
+ 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.
+
+ 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
+
+ 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.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..c70efce
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,5 @@
+SUBDIRS = src include doc $(MAYBE_OPT)
+DIST_SUBDIRS = src include doc src/tests src/tests/libica_sha_test/
+
+distclean:
+ ./cleanup.sh
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/NEWS
diff --git a/README b/README
new file mode 100644
index 0000000..8ca6bd2
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+refer to INSTALL
diff --git a/bootstrap.sh b/bootstrap.sh
new file mode 100755
index 0000000..6906f68
--- /dev/null
+++ b/bootstrap.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+set -x
+aclocal
+libtoolize --force -c
+automake --add-missing -c --foreign
+autoconf
diff --git a/cleanup.sh b/cleanup.sh
new file mode 100755
index 0000000..6314e2c
--- /dev/null
+++ b/cleanup.sh
@@ -0,0 +1,21 @@
+#! /bin/sh
+
+set -x
+if [ -f Makefile ] ; then
+ make -k clean
+fi
+rm mkinstalldirs
+rm aclocal.m4
+rm -rf autom4te.cache
+rm compile
+rm config.*
+rm configure
+rm depcomp
+rm install-sh
+rm ltmain.sh
+rm missing
+rm libtool
+find . -name Makefile -exec rm {} \;
+find . -name Makefile.in -exec rm {} \;
+find . -depth -name .deps -exec rm -rf {} \;
+
diff --git a/configure.in b/configure.in
new file mode 100644
index 0000000..b7adf79
--- /dev/null
+++ b/configure.in
@@ -0,0 +1,115 @@
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_INIT(libica, 3.0.1, steuer@linux.vnet.ibm.com)
+
+cmdline_CFLAGS="$CFLAGS"
+
+# Compute $target
+AC_CANONICAL_TARGET
+
+AM_INIT_AUTOMAKE(1.9.5)
+
+# Use extensions
+AC_GNU_SOURCE
+
+# Checks for programs.
+AC_PROG_CXX
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_LIBTOOL
+
+# Checks for libraries.
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([fcntl.h memory.h stdlib.h string.h strings.h sys/ioctl.h unistd.h \
+ errno.h stdio.h semaphore.h linux/types.h sys/ioctl.h])
+case "$target" in
+ *s390*)
+ AC_CHECK_HEADERS([openssl/bn.h openssl/rsa.h openssl/rand.h \
+ openssl/sha.h openssl/aes.h openssl/des.h],,
+ AC_MSG_ERROR(openssl-devel package required))
+ ;;
+ *)
+ AC_CHECK_HEADER(linux/icaioctl.h, ,
+ AC_MSG_ERROR([*** Unable to find linux/icaioctl.h]))
+ ;;
+esac
+
+
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_C_INLINE
+AC_TYPE_SIZE_T
+AC_C_VOLATILE
+
+# Checks for library functions.
+AC_PROG_GCC_TRADITIONAL
+AC_FUNC_MALLOC
+AC_FUNC_MEMCMP
+AC_FUNC_STAT
+AC_CHECK_FUNCS([bzero memset])
+
+CFLAGS="$cmdline_CFLAGS"
+AX_PTHREAD
+CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+case $target in
+ *s390x*)
+ CFLAGS="$CFLAGS -D_LINUX_S390X_ -D_LINUX_S390_ -Wall -fvisibility=hidden"
+ ;;
+ *s390*)
+ CFLAGS="$CFLAGS -D_LINUX_S390_ -m31 -Wall"
+ ;;
+esac
+
+dnl --- enable_debug
+AC_ARG_ENABLE(debug,
+ [--enable-debug turn on debugging flags],
+ [enable_debug="yes"],[enable_debug="no"])
+AM_CONDITIONAL(DEBUG, test x$enable_debug = xyes)
+
+if test "x$enable_debug" = xyes; then
+ CFLAGS="$CFLAGS -g -O0 -fstack-protector-all"
+ AC_MSG_RESULT([*** Enabling debugging at user request ***])
+else
+ CFLAGS="$CFLAGS -O2"
+fi
+
+dnl --- enable_testcases
+AC_ARG_ENABLE([testcases],
+ AS_HELP_STRING([--enable-testcases],[build the test cases @<:@default=no@:>@]),
+ [enable_testcases=yes],
+ [enable_testcases=no])
+
+if test "$enable_testcases" = yes; then
+ MAYBE_OPT="src/tests src/tests/libica_sha_test/"
+else
+ MAYBE_OPT=
+fi
+AC_SUBST(MAYBE_OPT)
+
+dnl --- enable_fips
+AC_ARG_ENABLE(fips,
+ [--enable-fips built with FIPS mode support],
+ [enable_fips="yes"],[enable_fips="no"])
+AM_CONDITIONAL(ICA_FIPS, test x$enable_fips = xyes)
+
+if test "x$enable_fips" = xyes; then
+ CFLAGS="$CFLAGS -DICA_FIPS"
+ AC_MSG_RESULT([*** Building libica-fips at user request ***])
+fi
+
+AC_CONFIG_FILES([src/tests/Makefile src/tests/libica_sha_test/Makefile])
+AC_OUTPUT([Makefile src/Makefile include/Makefile doc/Makefile])
+
+echo "CFLAGS=$CFLAGS"
+
+echo "Enabled features:"
+echo " FIPS build: $enable_fips"
+echo " Debug build: $enable_debug"
+echo " Testcases: $enable_testcases"
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..2f7df8a
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1 @@
+man_MANS = icastats.1 icainfo.1
diff --git a/doc/icainfo.1 b/doc/icainfo.1
new file mode 100644
index 0000000..d228623
--- /dev/null
+++ b/doc/icainfo.1
@@ -0,0 +1,69 @@
+.\" icainfo man page source
+.\"
+.\" use
+.\" groff -man -Tutf8 icainfo.1
+.\" or
+.\" nroff -man icainfo.1
+.\" to process this source
+.\"
+.TH ICAINFO 1 2013-12-06 IBM "icainfo user manual"
+.SH NAME
+icainfo \- print information about cryptographic functions supported by libica
+.SH SYNOPSIS
+.B icainfo
+[-v | --version] [-h | --help]
+.SH DESCRIPTION
+.B icainfo
+prints a table that shows libica's support for various cryptographic
+algorithms and information about FIPS support. A sample output is given below:
+.P
+.nf
+ Cryptographic algorithm support
+-------------------------------------------
+ function | # hardware | # software
+---------------+------------+--------------
+ SHA-1 | yes | yes
+ SHA-224 | yes | yes
+ SHA-256 | yes | yes
+ SHA-384 | yes | yes
+ SHA-512 | yes | yes
+ GHASH | yes | no
+ P_RNG | blocked | blocked
+ DRBG-SHA-512 | yes | yes
+ RSA ME | no | yes
+ RSA CRT | no | yes
+ DES ECB | blocked | blocked
+ DES CBC | blocked | blocked
+ DES OFB | blocked | blocked
+ DES CFB | blocked | blocked
+ DES CTR | blocked | blocked
+ DES CMAC | blocked | blocked
+ 3DES ECB | yes | yes
+ 3DES CBC | yes | yes
+ 3DES OFB | yes | no
+ 3DES CFB | yes | no
+ 3DES CTR | yes | no
+ 3DES CMAC | yes | no
+ AES ECB | yes | yes
+ AES CBC | yes | yes
+ AES OFB | yes | no
+ AES CFB | yes | no
+ AES CTR | yes | no
+ AES CMAC | yes | no
+ AES XTS | yes | no
+-------------------------------------------
+Built-in FIPS support: FIPS mode active.
+.fi
+.SH OPTIONS
+.IP "-v or --version"
+show libica version and copyright
+.IP "-h or --help"
+display this help and exit
+.SH RETURN VALUE
+.IP 1
+unknown or invalid argument on invocation
+.IP 0
+successful program execution
+.SH "SEE ALSO"
+.BR icastats (1)
+
diff --git a/doc/icastats.1 b/doc/icastats.1
new file mode 100644
index 0000000..cbd0b5d
--- /dev/null
+++ b/doc/icastats.1
@@ -0,0 +1,122 @@
+.\" icastats man page source
+.\"
+.\" use
+.\" groff -man -Tutf8 icastats.1
+.\" or
+.\" nroff -man icastats.1
+.\" to process this source
+.\"
+.TH ICASTATS 1 2013-12-06 IBM "icaststats user manual"
+.SH NAME
+icastats \- display statistic data for the libica cryptographic functions
+.SH SYNOPSIS
+.B icastats
+[-v | --version] [-h | --help] [--reset-all | -R] [--reset | -r]
+[--delete-all |-D] [--delete | -d] [--all | -A] [--summary | -S] [[-U |
+--user] <username>]
+.SH DESCRIPTION
+.B icastats
+displays statistic data about the usage of cryptographic functions provided by
+libica.
+.br
+Libica is a cryptographic library supporting SHA, RSA, DES and AES in
+different modes of operations. The invocation of each call to all the
+cryptographic functions is tracked with individual counters which can be
+displayed and maintained with icastats.
+.br
+Here is a sample output:
+.P
+.nf
+ function | # hardware | # software
+--------------+-----------------------+-------------------------
+ | ENC CRYPT DEC | ENC CRYPT DEC
+--------------|-----------------------|-------------------------
+ SHA-1 | 0 | 0
+ SHA-224 | 0 | 0
+ SHA-256 | 0 | 0
+ SHA-384 | 0 | 0
+ SHA-512 | 0 | 0
+ GHASH | 0 | 0
+ P_RNG | 0 | 0
+ DRBG-SHA-512 | 0 | 0
+ RSA-ME | 0 | 0
+ RSA-CRT | 0 | 0
+ DES ECB | 0 0 | 0 0
+ DES CBC | 0 0 | 0 0
+ DES OFB | 0 0 | 0 0
+ DES CFB | 0 0 | 0 0
+ DES CTR | 0 0 | 0 0
+ DES CMAC | 0 0 | 0 0
+ 3DES ECB | 0 0 | 0 0
+ 3DES CBC | 0 0 | 0 0
+ 3DES OFB | 0 0 | 0 0
+ 3DES CFB | 0 0 | 0 0
+ 3DES CTR | 0 0 | 0 0
+ 3DES CMAC | 0 0 | 0 0
+ AES ECB | 0 0 | 0 0
+ AES CBC | 0 0 | 0 0
+ AES OFB | 0 0 | 0 0
+ AES CFB | 0 0 | 0 0
+ AES CTR | 0 0 | 0 0
+ AES CMAC | 0 0 | 0 0
+ AES XTS | 0 0 | 0 0
+.fi
+.P
+For each cryptographic function the table shows the number of invocations
+where hardware support was involved or the libica fall back implementation
+in software was used. For the ciphering methods the invocation counter is
+further divided into encrypt and decrypt operation counter values.
+.P
+All the counter values are stored and maintained in one shared memory page
+for each user. This memory area is created automatically with the first run
+of icastats and persists until it is explicitly removed (see the -d option)
+or system shut down. This also means that the statistical data shown with
+icastats is on a per user base and only the root user is able to see and
+maintain the collection of statistic data from libica at system scope.
+.P
+Newer operating systems might remove these shared memory segments
+after the user has logged out from the system (systemd cleanup action).
+In this case all collected statistic data are gone.
+To prevent the statistic data from being removed you can configure the
+systemd to keep all shared memory segments after session exit by
+enabling the "RemoveIPC=no" paramater in "/etc/systemd/logind.conf".
+Alternatively you can setup the systemd user manager to enable user
+lingering by typing "loginctl enable-linger <user>".
+
+.SH OPTIONS
+.IP "-v or --version"
+show libica version and copyright
+.IP "-h or --help"
+display this help and exit
+.IP "-R or --reset-all"
+reset the statistic data for each user that has a shared memory segment to
+zero (only root user)
+.IP "-r or --reset"
+reset the statistic data for the current user to zero
+.IP "-D or --delete-all"
+delete all shared memory segments from all users who have an icastats shared
+memory segment (only root user)
+.IP "-d or --delete"
+delete the libica shared memory area for the current user
+.IP "-A or --all"
+show libica statistic data for each user in the system where a shared
+memory area exists in multiple tables (only root user)
+.IP "-S or --summary"
+show libica statistic data for each user in the system where a shared
+memory area exists in one table accumulating all the per user counter
+values (only root user)
+.IP "-U <username> or --user <username>"
+show statistic values from the given user (only root user)
+.SH FILES
+.nf
+/shm/dev/icastats_<userid>
+.fi
+.SH RETURN VALUE
+.IP 1
+unsupported or unknown argument, argument which requires root privileges
+given but not root user, failures at creating or attaching to the shared
+memory area ...
+.IP 0
+normal and sucessful program execution
+.SH SEE ALSO
+icainfo (1)
diff --git a/include/Makefile.am b/include/Makefile.am
new file mode 100644
index 0000000..c0c1275
--- /dev/null
+++ b/include/Makefile.am
@@ -0,0 +1,2 @@
+nobase_include_HEADERS = ica_api.h
+
diff --git a/include/ica_api.h b/include/ica_api.h
new file mode 100644
index 0000000..5f6c62c
--- /dev/null
+++ b/include/ica_api.h
@@ -0,0 +1,2960 @@
+/* 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.
+ */
+
+/*
+ * Authors(s): Ralph Wuerthner <rwuerthn@de.ibm.com>
+ * Holger Dengler <hd@linux.vnet.ibm.com>
+ * Ingo Tuchscherer <ingo.tuchscherer@linux.vnet.ibm.com>
+ *
+ * Copyright IBM Corp. 2001, 2005, 2009, 2010, 2011, 2013
+ */
+
+#ifndef __ICA_API_H__
+#define __ICA_API_H__
+
+/***************************************************************************
+*** ***
+*** LICENSED MATERIALS - PROPERTY OF IBM ***
+*** ***
+*** All Rights Reserved ***
+*** ***
+*** U.S. Government Users Restricted Rights - Use, ***
+*** duplication or disclosure restricted by GSA ADP ***
+*** Schedule Contract with IBM Corp. ***
+*** ***
+*** ***
+*** ORIGINS: IBM Charlotte, Department VM9A ***
+*** ***
+***************************************************************************/
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#define ICA_EXPORT __attribute__((__visibility__("default")))
+#define ICA_DEPRECATED __attribute__((deprecated))
+
+#define ica_adapter_handle_t int
+typedef ica_adapter_handle_t ICA_ADAPTER_HANDLE;
+#define DRIVER_NOT_LOADED (-1)
+
+/**
+ * Definitions to determine the direction of the symmetric
+ * encryption/decryption functions.
+ */
+#define ICA_ENCRYPT 1
+#define ICA_DECRYPT 0
+
+/**
+ * Symetric encryption/decryption modes
+ */
+#define MODE_ECB 1
+#define MODE_CBC 2
+#define MODE_CFB 3
+#define MODE_OFB 4
+#define MODE_CTR 5
+#define MODE_XTS 6
+#define MODE_GCM 7
+#define MODE_CBCCS 8
+#define MODE_CCM 9
+
+/**
+ * CBC Ciphertext Stealing variants
+ */
+#define ICA_CBCCS_VARIANT1 1
+#define ICA_CBCCS_VARIANT2 2
+#define ICA_CBCCS_VARIANT3 3
+
+#define ICA_FLAG_SHW 4 /* static hardware support (symmetric ops - CPACF) */
+#define ICA_FLAG_DHW 2 /* dynamic hardware support (asymmetric ops - CEX) */
+#define ICA_FLAG_SW 1 /* software implementation (fallback / backup) */
+
+#define SHA1 1
+#define SHA224 2
+#define SHA256 3
+#define SHA384 4
+#define SHA512 5
+#define G_HASH 10
+#define DES_ECB 20
+#define DES_CBC 21
+#define DES_CBC_CS 22
+#define DES_OFB 23
+#define DES_CFB 24
+#define DES_CTR 25
+#define DES_CTRLST 26
+#define DES_CBC_MAC 27
+#define DES_CMAC 28
+#define DES3_ECB 41
+#define DES3_CBC 42
+#define DES3_CBC_CS 43
+#define DES3_OFB 44
+#define DES3_CFB 45
+#define DES3_CTR 46
+#define DES3_CTRLST 47
+#define DES3_CBC_MAC 48
+#define DES3_CMAC 49
+#define AES_ECB 60
+#define AES_CBC 61
+#define AES_CBC_CS 62
+#define AES_OFB 63
+#define AES_CFB 64
+#define AES_CTR 65
+#define AES_CTRLST 66
+#define AES_CBC_MAC 67
+#define AES_CMAC 68
+#define AES_CCM 69
+#define AES_GCM 70
+#define AES_XTS 71
+#define P_RNG 80
+#define RSA_ME 90
+#define RSA_CRT 91
+#define RSA_KEY_GEN_ME 92
+#define RSA_KEY_GEN_CRT 93
+#define SHA512_DRNG 94
+
+/*
+ * Key length for DES/3DES encryption/decryption
+ */
+#define DES_KEY_LENGTH (56/8)
+#define DES3_KEY_LENGTH (168/8)
+
+/**
+ * Key length for AES encryption/decryption
+ */
+#define AES_KEY_LEN128 (128/8)
+#define AES_KEY_LEN192 (192/8)
+#define AES_KEY_LEN256 (256/8)
+
+/**
+ * SHA Message parts
+ */
+#define SHA_MSG_PART_ONLY 0
+#define SHA_MSG_PART_FIRST 1
+#define SHA_MSG_PART_MIDDLE 2
+#define SHA_MSG_PART_FINAL 3
+
+/**
+ * SHA hash lengths
+ */
+#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
+
+/*
+ * ica_drbg
+ */
+#define ICA_DRBG_NEW_STATE_HANDLE NULL
+#define ICA_DRBG_HEALTH_TEST_FAIL (-1)
+#define ICA_DRBG_ENTROPY_SOURCE_FAIL (-2)
+
+/*
+ * The following status flags are used to examine the return value of the
+ * status output interface ica_fips_status().
+ */
+
+/*
+ * 'FIPS mode active'-flag
+ */
+#define ICA_FIPS_MODE 1
+
+/*
+ * 'Powerup test failed'-flags
+ */
+/* Cryptographic algorithm test (KAT or pair-wise consistency test) */
+#define ICA_FIPS_CRYPTOALG 2
+/* Software/Firmware integrity test (not implemented yet) */
+#define ICA_FIPS_INTEGRITY 4
+/* Critical functions test (N/A) */
+#define ICA_FIPS_CRITICALFUNC 8
+
+/*
+ * 'Conditional test failed'-flags
+ */
+/* Pair-wise consistency test for public & private keys (N/A) */
+#define ICA_FIPS_CONSISTENCY 16
+/* Software/Firmware load test (N/A) */
+#define ICA_FIPS_LOAD 32
+/* Manual key entry test (N/A) */
+#define ICA_FIPS_KEYENTRY 64
+/* Continuous random number generator test */
+#define ICA_FIPS_RNG 128
+/* Bypass test (N/A) */
+#define ICA_FIPS_BYPASS 256
+
+/**
+ * Context for SHA1 operations
+ */
+typedef struct {
+ uint64_t runningLength;
+ unsigned char shaHash[SHA_HASH_LENGTH];
+} sha_context_t;
+
+/**
+ * Context for SHA256 and SHA224 operations
+ */
+typedef struct {
+ uint64_t runningLength;
+ unsigned char sha256Hash[SHA256_HASH_LENGTH];
+} sha256_context_t;
+
+/**
+ * Context for SHA512 and SHA384 operations
+ */
+typedef struct {
+ uint64_t runningLengthHigh;
+ uint64_t runningLengthLow;
+ unsigned char sha512Hash[SHA512_HASH_LENGTH];
+} sha512_context_t;
+
+typedef enum {
+ DEA_ENCRYPT,
+ DEA_DECRYPT,
+ TDEA_192_ENCRYPT,
+ TDEA_192_DECRYPT,
+ AES_128_ENCRYPT,
+ AES_128_DECRYPT,
+ AES_192_ENCRYPT,
+ AES_192_DECRYPT,
+ AES_256_ENCRYPT,
+ AES_256_DECRYPT,
+/* XTS belongs to the KM family */
+ AES_128_XTS_ENCRYPT,
+ AES_128_XTS_DECRYPT,
+ AES_256_XTS_ENCRYPT,
+ AES_256_XTS_DECRYPT,
+/* PRNG only for KMC */
+ PRNG,
+} kmc_functions_t;
+
+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;
+
+/**
+ * DES and AES defines and typedefs
+ */
+typedef unsigned char ica_des_vector_t[8];
+typedef unsigned char ica_des_key_single_t[8];
+typedef struct {
+ ica_des_key_single_t key1;
+ ica_des_key_single_t key2;
+ ica_des_key_single_t key3;
+} ica_des_key_triple_t;
+
+typedef unsigned char ica_key_t[8];
+
+/**
+ * AES defines and typedefs
+ */
+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];
+
+/**
+ * Libica version information
+ */
+typedef struct {
+ unsigned int major_version;
+ unsigned int minor_version;
+ unsigned int fixpack_version;
+} libica_version_info;
+
+/**
+ * Definition of a mechanism type
+ **/
+typedef unsigned int libica_mechanism_type;
+
+/**
+ * Information for a particular crypto mechanism supported by libica.
+ * Key sizes are specified in bytes and do not apply to all supported
+ * mechanisms.
+ **/
+typedef struct {
+ unsigned int min_key_size;
+ unsigned int max_key_size;
+ unsigned int flags;
+} libica_mechanism_info;
+
+/**
+ * Definition for a particular crypto mechanism supported by libica.
+ **/
+typedef struct {
+ libica_mechanism_type mech_type;
+ libica_mechanism_info mech_info;
+} libica_mechanism_list_element;
+
+/*
+ * internal specification for a specific crypto mechanism supported by libica
+ **/
+typedef struct {
+ unsigned int mech_mode_id;
+ unsigned int type;
+ unsigned int id;
+ unsigned int flags;
+ unsigned int property;
+} libica_func_list_element_int;
+
+/*
+ * external specification for a specific crypto mechanism supported by libica
+ **/
+typedef struct {
+ unsigned int mech_mode_id;
+ unsigned int flags;
+ unsigned int property;
+} libica_func_list_element;
+
+typedef struct ica_drbg_mech ica_drbg_mech_t;
+typedef struct ica_drbg ica_drbg_t;
+
+/**
+ * Opens the specified adapter
+ * @param adapter_handle Pointer to the file descriptor for the adapter or
+ * to DRIVER_NOT_LOADED if opening the crypto adapter failed.
+ *
+ * @return 0 as long as a valid parameter is given.
+ * EINVAL for invalid parameter.
+ */
+ICA_EXPORT
+unsigned int ica_open_adapter(ica_adapter_handle_t *adapter_handle);
+
+/**
+ * Closes a device handle.
+ * @param adapter_handle Pointer to a previously opened device handle.
+ *
+ * @return 0 if successful.
+ * errno of close() if unsuccessful
+ */
+ICA_EXPORT
+unsigned int ica_close_adapter(ica_adapter_handle_t adapter_handle);
+
+/**
+ * Generate a random number.
+ *
+ * Required HW Support
+ * KMC-PRNG
+ *
+ * @param output_length
+ * Specifies the byte length of the output_data buffer and the desired length
+ * of the random number.
+ * @param output_data
+ * Pointer to the buffer to contain the resulting random number.
+ *
+ * @return 0 if successful.
+ * EINVAL if at least one invalid parameter is given
+ * ENODEV if neither /dev/hwrng nor /dev/urandom are available.
+ * EIO if the operation fails. This should never happen.
+ */
+ICA_EXPORT
+unsigned int ica_random_number_generate(unsigned int output_length,
+ unsigned char *output_data);
+
+/**
+ * Perform secure hash on input data using the SHA-1 algorithm.
+ *
+ * Required HW Support
+ * KIMD-SHA-1, or KLMD-SHA-1
+ *
+ * @param message_part
+ * The message chaining state. Must be one of the following:
+ * 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
+ * @param input_length
+ * The byte length of the input data to be SHA-1 hashed and must be greater
+ * than zero.
+ * @param input_data
+ * Pointer to the input data data.
+ * @param 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.
+ * @param output_data
+ * Pointer to the buffer to contain the resulting hash data. The resulting
+ * output data will have a length of SHA_HASH_LENGTH. Make sure buffer has
+ * at least this size.
+ *
+ * @return 0 if successful.
+ * EINVAL if at least one invalid parameter is given
+ * EIO if the operation fails. This should never happen.
+ */
+ICA_EXPORT
+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);
+
+/**
+ * Perform secure hash on input data using the SHA-224 algorithm.
+ *
+ * Required HW Support
+ * KIMD-SHA-256, or KLMD-SHA-256
+ *
+ * @param message_part
+ * The message chaining state. Must be one of the following:
+ * 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
+ * @param input_length
+ * The byte length of the input data to be SHA-224 hashed and must be greater
+ * than zero.
+ * @param input_data
+ * Pointer to the input data.
+ * @param 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.
+ * Note: Due to the algorithm used by SHA-224, a SHA-256 context must be
+ * used.
+ * @param output_data
+ * Pointer to the buffer to contain the resulting hash data. The resulting
+ * output data will have a length of SHA224_HASH_LENGTH. Make sure buffer has
+ * at least this size.
+ *
+ * @return 0 if successful.
+ * EINVAL if at least one invalid parameter is given
+ * EIO if the operation fails. This should never happen.
+ */
+ICA_EXPORT
+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);
+
+/**
+ * Perform secure hash on input data using the SHA-256 algorithm.
+ *
+ * Required HW Support
+ * KIMD-SHA-256, or KLMD-SHA-256
+ *
+ * @param message_part
+ * The message chaining state. Must be one of the following:
+ * 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
+ * @param input_length
+ * The byte length of the input data to be SHA-256 hashed and must be greater
+ * than zero.
+ * @param input_data
+ * Pointer to the input data.
+ * @param 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
+ * be used for a chained call of ica_sha256. Therefore, the application must not
+ * modify the contents of this structure in between chained calls.
+ * @param output_data
+ * Pointer to the buffer to contain the resulting hash data. The resulting output
+ * data will have a length of SHA256_HASH_LENGTH. Make sure that the buffer
+ * has is at least this size.
+ *
+ * @return 0 if successful.
+ * EINVAL if at least one invalid parameter is given
+ * EIO if the operation fails. This should never happen.
+ */
+ICA_EXPORT
+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);
+
+/**
+ * Perform secure hash on input data using the SHA-384 algorithm.
+ *
+ * Required HW Support
+ * KIMD-SHA-512, or KLMD-SHA-512
+ *
+ * @param message_part
+ * The message chaining state. Must be one of the following:
+ * 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
+ * @param input_length
+ * The byte length of the input data to be SHA-384 hashed and must be greater
+ * than zero.
+ * @param input_data
+ * Pointer to the input data.
+ * @param 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
+ * 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.
+ * @param output_data
+ * Pointer to the buffer to contain the resulting hash data. The resulting
+ * output data will have a length of SHA384_HASH_LENGTH. Make sure buffer has
+ * at least this size.
+ *
+ * @return 0 if successful.
+ * EINVAL if at least one invalid parameter is given
+ * EIO if the operation fails. This should never happen.
+ */
+ICA_EXPORT
+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);
+
+/**
+ * Perform secure hash on input data using the SHA-512 algorithm.
+ *
+ * Required HW Support
+ * KIMD-SHA-512, or KLMD-SHA-512
+ *
+ * @param message_part
+ * The message chaining state. Must be one of the following:
+ * 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
+ * @param input_length
+ * The byte length of the input data to be SHA-512 hashed and must be greater
+ * than zero.
+ * @param input_data
+ * Pointer to the input data.
+ * @param 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 structuremust
+ * contain the returned value of the preceding call to ica_sha512 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_sha512. Therefore, the application must
+ * not modify the contents of this structure in between chained calls.
+ * @param output_data
+ * Pointer to the buffer to contain the resulting hash data. The resulting
+ * output data will have a length of SHA512_HASH_LENGTH. Make sure buffer has
+ * at least this size.
+ *
+ * @return 0 if successful.
+ * EINVAL if at least one invalid parameter is given
+ * EIO if the operation fails. This should never happen.
+ */
+ICA_EXPORT
+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);
+
+/**
+ * Generate RSA keys in modulus/exponent format.
+ * @param adapter_handle
+ * Pointer to a previously opened device handle.
+ * @param modulus_bit_length
+ * Specifies the bit length of the modulus. This value should comply with
+ * length of the keys.
+ * @param 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 will be randomly generated. A not
+ * well chosen exponent may result in the program loooping endlessly. Common
+ * public exponents are 3 and 65537.
+ * @param private_key
+ * Pointer to where the generated private key in modulus/exponent format is to
+ * be placed. Length of both private and public key should be set in bytes.
+ * This value should comply with modulus bit length. Make sure that buffers in
+ * the keys fit to this length.
+ *
+ * @return 0 if successful.
+ * EINVAL if at least one invalid parameter is given.
+ * errno of OpenSSL key generation if it should fail.
+ */
+ICA_EXPORT
+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);
+
+/**
+ * Generate RSA keys in CRT format.
+ * @param adapter_handle
+ * Pointer to a previously opened device handle.
+ * @param modulus_bit_length
+ * Specifies the bit length of the modulus. This value should comply with
+ * length of the keys.
+ * @param 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 will be randomly generated. A not
+ * well chosen exponent may result in the program loooping endlessly. Common
+ * public exponents are 3 and 65537.
+ * @param private_key
+ * Pointer to where the generated private key in CRT format is to be placed.
+ * Length of both private and public key should be set in bytes. This value
+ * should comply with modulus bit length. Make sure that buffers in the keys
+ * fit to this length.
+ *
+ * @return 0 if successful.
+ * EINVAL if at least one invalid parameter is given.
+ * errno of OpenSSL key generation if it should fail.
+ */
+ICA_EXPORT
+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);
+
+/**
+ * @brief Perform a RSA encryption/decryption operation using a key in
+ * modulus/exponent form.
+ *
+ * Make sure your message is padded before using this function. Otherwise you
+ * will risk security!
+ * @param adapter_handle
+ * Pointer to a previously opened device handle.
+ * @param input_data
+ * Pointer to input data to be encrypted/decrypted and is in big endian format.
+ * Make sure input data is not longer than bit length of the key! Byte length
+ * has to be the same. Thus right justify input data inside the data block.
+ * @param rsa_key
+ * Pointer to the key to be used, in modulus/exponent format.
+ * @param output_data
+ * Pointer to where the output results are to be placed.
+ *
+ * @return 0 if successful.
+ * EINVAL if at least one invalid parameter is given.
+ * ENOMEM if memory allocation fails.
+ * EIO if the operation fails. This should never happen.
+ */
+ICA_EXPORT
+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);
+
+/**
+ * @brief Perform a RSA encryption/decryption operation using a key in CRT
+ * form.
+ *
+ * Make sure your message is padded before using this function. Otherwise you
+ * will risk security!
+ * @param adapter_handle
+ * Pointer to a previously opened device handle.
+ * @param input_data
+ * Pointer to input data to be encrypted/decrypted and is in big endian format.
+ * Make sure input data is not longer than bit length of the key! Byte length
+ * has to be the same. Thus right justify input data inside the data block.
+ * @param rsa_key
+ * Pointer to the key to be used, in CRT format.
+ * @param output_data
+ * Pointer to where the output results are to be placed. Buffer has to be as
+ * large as the input_data and length of the modulus specified in rsa_key.
+ *
+ * @return 0 if successful.
+ * EINVAL if at least one invalid parameter is given.
+ * ENOMEM if memory allocation fails.
+ * EIO if the operation fails. This should never happen.
+ */
+ICA_EXPORT
+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);
+
+/*
+ * Check if RSA key credentials in CRT format are presented in
+ * privileged form, respectively prime 'p' > prime 'q'.
+ *
+ * In case of 'p' < 'q', key credentials 'p' and 'q' as well as 'dp'
+ * and 'dq' will be swapped and qInverse will be recalculated.
+ *
+ * @return
+ * 0 if all key credentials are in the correct format.
+ * 1 if the key credentials were re-calculated.
+ * ENOMEM if memory allocation fails.
+ */
+ICA_EXPORT
+unsigned int ica_rsa_crt_key_check(ica_rsa_key_crt_t *rsa_key);
+
+/**
+ * @deprecated, use ica_des_ecb() or ica_des_cbc() instead.
+ *
+ * Encrypt data using a single length DES key.
+ * @param mode Specifies the operational mode and must be:
+ * MODE_ECB - Use Electronic Code Book mode
+ * MODE_CBC - Use Cipher Block Chaining mode
+ * @param data_length
+ * Specifies the byte length of the input data. It has to be a multiple of the
+ * cipher block which has a size of 8 byte.
+ * @param input_data
+ * Pointer to the input data data to be encrypted. Must be a multiple of the
+ * cipher to use hw acceleration.
+ * @param iv
+ * Pointer to a valid 8 byte initialization vector when using CBC mode.
+ * @param des_key
+ * Pointer to a single length DES key.
+ * @param output_data
+ * Pointer to the buffer to contain the resulting encrypted data. Must be a
+ * multiple of the cipher block and at least as big as the buffer for
+ * input_data.
+ *
+ * @return 0 if successful.
+ * EINVAL if at least one invalid parameter is given.
+ * EIO if the operation fails. This should never happen.
+ */
+ICA_EXPORT ICA_DEPRECATED
+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);
+
+/**
+ * @deprecated, use ica_des_ecb() or ica_des_cbc() instead.
+ *
+ * Decrypt data using a single length DES key.
+ * @param mode
+ * Specifies the operational mode and must be:
+ * MODE_ECB - Use Electronic Code Book mode
+ * MODE_CBC - Use Cipher Block Chaining mode
+ * @param data_length
+ * Specifies the byte length of the input data. It has to be a multiple of the
+ * cipher block which has a size of 8 byte.
+ * @param input_data
+ * Pointer to the input data data to be decrypted. Must be a multiple of the
+ * cipher to use hw acceleration.
+ * @param iv
+ * Pointer to a valid 8 byte initialization vector when using CBC mode.
+ * @param des_key
+ * Pointer to a single length DES key.
+ * @param output_data
+ * Pointer to the buffer to contain the resulting decrypted data. Must be a
+ * multiple of the cipher block and at least as big as the buffer for
+ * input_data.
+ *
+ * @return 0 if successful.
+ * EINVAL if at least one invalid parameter is given.
+ * EIO if the operation fails. This should never happen.
+ */
+ICA_EXPORT ICA_DEPRECATED
+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);
+
+/**
+ * @deprecated, use ica_3des_ecb() or ica_3des_cbc() instead.
+ *
+ * Encrypt data using a triple length DES key.
+ * @param mode
+ * Specifies the operational mode and must be:
+ * MODE_ECB - Use Electronic Code Book mode
+ * MODE_CBC - Use Cipher Block Chaining mode
+ * @param data_length
+ * Specifies the byte length of the input data. It has to be a multiple of the
+ * cipher block which has a size of 8 byte.
+ * @param input_data
+ * Pointer to the input data data to be encrypted. Must be a multiple of the
+ * cipher block to use hw acceleration.
+ * @param iv
+ * Pointer to a valid 8 byte initialization vector when using CBC mode.
+ * @param des_key
+ * Pointer to a triple length DES key.
+ * @param output_data
+ * Pointer to the buffer to contain the resulting encrypted data. Must be a
+ * multiple of the cipher block and at least as big as the buffer for
+ * input_data.
+ *
+ * @return 0 if successful.
+ * EINVAL if at least one invalid parameter is given.
+ * EIO if the operation fails. This should never happen.
+ */
+ICA_EXPORT ICA_DEPRECATED
+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);
+
+/**
+ * @deprecated, use ica_3des_ecb() or ica_3des_cbc() instead.
+ *
+ * Decrypt data using a triple length DES key.
+ * @param mode
+ * Specifies the operational mode and must be:
+ * MODE_ECB - Use Electronic Code Book mode
+ * MODE_CBC - Use Cipher Block Chaining mode
+ * @param data_length
+ * Specifies the byte length of the input data. It has to be a multiple of the
+ * cipher block which has a size of 8 byte.
+ * @param input_data
+ * Pointer to the input data data to be decrypted. Must be a multiple of the
+ * cipher block to use hw acceleration.
+ * @param iv
+ * Pointer to a valid 8 byte initialization vector when using CBC mode.
+ * @param des_key
+ * Pointer to a triple length DES key.
+ * @param output_data
+ * Pointer to the buffer to contain the resulting decrypted data. Must be a
+ * multiple of the cipher block and at least as big as the buffer for
+ * input_data.
+ *
+ * @return 0 if successful.
+ * EINVAL if at least one invalid parameter is given.
+ * EIO if the operation fails. This should never happen.
+ */
+ICA_EXPORT ICA_DEPRECATED
+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);
+
+/**
+ * @deprecated, use ica_aes_ecb() or ica_aes_cbc() instead.
+ *
+ * Encrypt data using AES (key_length is 16, 24, or 32)
+ * @param mode
+ * Specifies the operational mode and must be:
+ * MODE_ECB - Use Electronic Code Book mode
+ * MODE_CBC - Use Cipher Block Chaining mode
+ * @param data_length
+ * Specifies the byte length of the input data. Input data length has to be
+ * a multiple of the AES block length, which is 16 bytes.
+ * @param input_data
+ * Pointer to the input data data to be encrypted. Must be a multiple of the
+ * cipher block to use hw acceleration.
+ * @param iv
+ * Pointer to a valid 16 byte initialization vector when using CBC mode.
+ * @param key_length
+ * Length of the AES key being used.
+ * @param aes_key
+ * Pointer to an AES key.
+ * @param output_data
+ * Pointer to the buffer to contain the resulting encrypted data. Must be a
+ * multiple of the cipher block and at least as big as the buffer for
+ * input_data.
+ *
+ * @return 0 if successful.
+ * EINVAL if at least one invalid parameter is given.
+ * EIO if the operation fails. This should never happen.
+ */
+ICA_EXPORT ICA_DEPRECATED
+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);
+
+/**
+ * @deprecated, use ica_aes_ecb() or ica_aes_cbc() instead.
+ *
+ * Decrypt data using AES (key_length is 16, 24, or 32)
+ * @param mode
+ * Specifies the operational mode and must be:
+ * MODE_ECB - Use Electronic Code Book mode
+ * MODE_CBC - Use Cipher Block Chaining mode
+ * @param data_length
+ * Specifies the byte length of the input data. Input data length has to be
+ * a multiple of the AES block length, which is 16 bytes.
+ * @param input_data
+ * Pointer to the input data to be decrypted. Must be a multiple of the
+ * cipher block to use hw acceleration.
+ * @param iv
+ * Pointer to a valid 16 byte initialization vector when using CBC mode.
+ * @param key_length
+ * Length of the AES key being used.
+ * @param aes_key
+ * Pointer to an AES key.
+ * @param output_data
+ * Pointer to the buffer to contain the resulting decrypted data. Must be a
+ * multiple of the cipher block and at least as big as the buffer for
+ * input_data.
+ *
+ * @return 0 if successful.
+ * EINVAL if at least one invalid parameter is given.
+ * EIO if the operation fails. This should never happen.
+ */
+ICA_EXPORT ICA_DEPRECATED
+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);
+
+/**
+ * Encrypt or decrypt data with an DES key using Electronic Cook Book (ECB)
+ * mode as described in NIST Special Publication 800-38A Chapter 6.1.
+ *
+ * Required HW Support
+ * KM-DEA-192
+ *
+ * @param in_data
+ * Pointer to a readable buffer, that contains the message to be en/decrypted.
+ * The size of the message in bytes is data_length. The size of this buffer in
+ * bytes must be at least as big as data_length.
+ * @param out_data
+ * Pointer to a writeable buffer, that will contain the resulting en/decrypted
+ * message. The size of this buffer in bytes must be at least as big as
+ * data_length.
+ * @param data_length
+ * Length in bytes of the message to be en/decrypted, which resides at the
+ * beginning of in_data. data_length must be a multiple of the cipher block
+ * size (i.e. a multiple of 8 for DES).
+ * @param key
+ * Pointer to a valid DES key of 8 bytes length.
+ * @param direction
+ * 0 or 1:
+ * 0 Use the decrypt function.
+ * 1 Use the encrypt function.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_des_ecb(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned int direction);
+
+/**
+ * Encrypt or decrypt data with an DES key using Cipher Block Chaining (CBC)
+ * mode as described in NIST Special Publication 800-38A Chapter 6.2.
+ *
+ * Required HW Support
+ * KMC-DEA
+ *
+ * @param in_data
+ * Pointer to a readable buffer, that contains the message to be en/decrypted.
+ * The size of the message in bytes is data_length. The size of this buffer in
+ * bytes must be at least as big as data_length.
+ * @param out_data
+ * Pointer to a writable buffer, that will contain the resulting en/decrypted
+ * message. The size of this buffer in bytes must be at least as big as
+ * data_length.
+ * @param data_length
+ * Length in bytes of the message to be en/decrypted, which resides at the
+ * beginning of in_data. data_length must be a multiple of the cipher block
+ * size (i.e. a multiple of 8 for DES).
+ * @param key
+ * Pointer to a valid DES key of 8 bytes length.
+ * @param iv
+ * Pointer to a valid initialization vector of cipher block size bytes. This
+ * vector will be overwritten during the function. The result value in iv may
+ * be used as initialization vector for a chained ica_des_cbc call with the
+ * same key.
+ * @param direction
+ * 0 or 1:
+ * 0 Use the decrypt function.
+ * 1 Use the encrypt function.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_des_cbc(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned char *iv,
+ unsigned int direction);
+
+/**
+ * Encrypt or decrypt data with an 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 Moder:
+ * ica_des_cbc_cs may be used to encrypt or decrypt the last chunk of a
+ * message consisting of multiple chunks where all but the last chunk are
+ * encrypted or decrypted by chained calls to ica_des_cbc and the resulting
+ * iv of the last call to ica_des_cbc is fed into the iv of the ica_des_cbc_cs
+ * call provided the chunk is greater than cipher block size (greater than
+ * 8 bytes for DES).
+ *
+ * Required HW Support
+ * KMC-DEA
+ *
+ * @param in_data
+ * Pointer to a readable buffer, that contains the message to be en/decrypted.
+ * The size of the message in bytes is data_length. The size of this buffer
+ * in bytes must be at least as big as data_length.
+ * @param out_data
+ * Pointer to a writable buffer, that will contain the resulting en/decrypted
+ * message. The size of this buffer in bytes must be at least as big as
+ * data_length.
+ * @param data_length
+ * Length in bytes of the message to be en/decrypted, which resides at the
+ * beginning of in_data. data_length must be greater than or equal to the
+ * cipher block size (i.e. a multiple of 8 bytes for DES).
+ * @param key
+ * Pointer to a valid DES key of 8 bytes length.
+ * @param iv
+ * Pointer to a valid initialization vector of cipher block size bytes.
+ * This vector will be overwritten during the function. For variant equals 1
+ * or variant equals 2 the result value in iv may be used as initialization
+ * vector for a chained ica_des_cbc call with the same key if data_length is
+ * a multiple of the cipher block size.
+ * @param direction
+ * 0 or 1:
+ * 0 Use the decrypt function.
+ * 1 Use the encrypt function.
+ * @param variant
+ * 1 Use variant CBC-CS1 of the Addendum to NIST Special Publication 800-38A
+ * to encrypt or decrypt the message: 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 (i.e. a
+ * multiple of 8 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 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_des_cbc_cs(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned char *iv,
+ unsigned int direction,
+ unsigned int variant);
+
+/**
+ * Encrypt or decrypt data with an DES key using Cipher Feedback (CFB) mode as
+ * described in NIST Special Publication 800-38A Chapter 6.3.
+ *
+ * Required HW Support
+ * KMF-DEA
+ *
+ * @param in_data
+ * Pointer to a readable buffer, that contains the message to be en/decrypted.
+ * The size of the message in bytes is data_length. The size of this buffer in
+ * bytes must be at least as big as data_length.
+ * @param out_data
+ * Pointer to a writable buffer, that will contain the resulting en/decrypted
+ * message. The size of this buffer in bytes must be at least as big as
+ * data_length.
+ * @param data_length
+ * Length in bytes of the message to be en/decrypted, which resides at the
+ * beginning of in_data.
+ * @param key
+ * Pointer to a valid DES key of 8 bytes length.
+ * @param iv
+ * Pointer to a valid initialization vector of cipher block size bytes (8 bytes
+ * for DES). This vector will be overwritten during the function. The result
+ * value in iv may be used as initialization vector for a chained ica_des_cfb
+ * call with the same key if data_length in the preceding call is a multiple of
+ * lcfb.
+ * @param 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 (i.e. 8 for DES).
+ * @param direction
+ * 0 or 1:
+ * 0 Use the decrypt function.
+ * 1 Use the encrypt function.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_des_cfb(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned char *iv, unsigned int lcfb,
+ unsigned int direction);
+
+/**
+ * Encrypt or decrypt data with an 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 (i.e. 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 will be derived from preceding counter values by an increment
+ * function. The increment function used in ica_des_ctr is s an arithmetic
+ * increment without carry on the U least significant bytes in the counter
+ * where M is a parameter to ica_des_ctr.
+ *
+ * Required HW Support
+ * KMCTR-DEA
+ *
+ * @param in_data
+ * Pointer to a readable buffer, that contains the message to be en/decrypted.
+ * The size of the message in bytes is data_length. The size of this buffer in
+ * bytes must be at least as big as data_length.
+ * @param out_data
+ * Pointer to a writable buffer, that will contain the resulting en/decrypted
+ * message. The size of this buffer in bytes must be at least as big as
+ * data_length.
+ * @param data_length
+ * Length in bytes of the message to be en/decrypted, which resides at the
+ * beginning of in_data.
+ * @param key
+ * Pointer to a valid DES key of 8 bytes length.
+ * @param ctr
+ * Pointer to a readable and writable buffer of size cipher block size bytes.
+ * ctr contains an initialization value for a counter function and it will be
+ * replaced by a new value. That new value can be used as an initialization
+ * value for a counter function in a chained ica_des_ctr call with the same key
+ * if data_length used in the preceding call is a multiple of the cipher block
+ * size.
+ * @param ctr_width
+ * A number U between 1 and cipher block size. The value is used by the counter
+ * increment function which increments a counter value by incrementing without
+ * carry the least significant U bytes of the counter value.
+ * @param direction
+ * 0 or 1:
+ * 0 Use the decrypt function.
+ * 1 Use the encrypt function.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_des_ctr(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length,
+ unsigned char *key,
+ unsigned char *ctr, unsigned int ctr_width,
+ unsigned int direction);
+
+/**
+ * Encrypt or decrypt data with an 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 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 or equal to the message size
+ * divided by the cipher block size. This function allows to optimally exploit
+ * System z HW support for non-standard counter functions.
+ *
+ * Required HW Support
+ * KMCTR-DEA
+ *
+ * @param in_data
+ * Pointer to a readable buffer, that contains the message to be en/decrypted.
+ * The size of the message in bytes is data_length. The size of this buffer in
+ * bytes must be at least as big as data_length.
+ * @param out_data
+ * Pointer to a writable buffer, that will contain the resulting en/decrypted
+ * message. The size of this buffer in bytes must be at least as big as
+ * data_length.
+ * @param data_length
+ * Length in bytes of the message to be en/decrypted, which resides at the
+ * beginning of in_data. If data_length is a multiple of the cipher block size
+ * then calls of ica_des_ctrlist with the same key can be chained if ctrlist
+ * argument of the chained call contains a list of counters that follows the
+ * counters used in the first call and data_length used in the preceding call
+ * is a multiple of the cipher block size.
+ * @param key
+ * Pointer to a valid DES key of 8 bytes length.
+ * @param ctrlist
+ * Pointer to a readable buffer of that is both of size greater than or equal
+ * to data_length and a multiple of the cipher block size (i.e. 8 bytes for
+ * DES). ctrlist should contain a list of precomputed counter values of size
+ * cipher block size each.
+ * @param direction
+ * 0 or 1:
+ * 0 Use the decrypt function.
+ * 1 Use the encrypt function.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_des_ctrlist(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length,
+ unsigned char *key,
+ const unsigned char *ctrlist,
+ unsigned int direction);
+
+/**
+ * Encrypt or decrypt data with an DES key using Output Feedback (OFB) mode as
+ * described in NIST Special Publication 800-38A Chapter 6.4.
+ *
+ * Required HW Support
+ * KMO-DEA
+ *
+ * @param in_data
+ * Pointer to a readable buffer, that contains the message to be en/decrypted.
+ * The size of the message in bytes is data_length. The size of this buffer in
+ * bytes must be at least as big as data_length.
+ * @param out_data
+ * Pointer to a writable buffer, that contains the resulting en/decrypted
+ * message. The size of this buffer in bytes must be at least as big as
+ * data_length.
+ * @param data_length
+ * Length in bytes of the message to be en/decrypted, which resides at the
+ * beginning of in_data.
+ * @param key
+ * Pointer to a valid DES key of 8 bytes length.
+ * @param iv
+ * Pointer to a valid initialization vector of cipher block size bytes (8 bytes
+ * for DES). This vector will be overwritten during the function. If
+ * data_length is a multiple of the cipher block size (i.e. a multiple of 8 for
+ * DES) the result value in iv may be used as initialization vector for a
+ * chained ica_des_ofb call with the same key.
+ * @param direction
+ * 0 or 1:
+ * 0 Use the decrypt function.
+ * 1 Use the encrypt function.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_des_ofb(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned char *iv, unsigned int direction);
+
+/**
+ * Authenticate data or verify the authenticity of data with an DES key using
+ * the Block Cipher Based Message Authetication 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.
+ *
+ * Required HW Support
+ * KMAC-DEA
+ * PCC-Compute-Last_block-CMAC-Using-DEA
+ *
+ * @param message
+ * Pointer to a readable buffer of size greater than or equal to message_length
+ * bytes. It contains a message to be authenticated or of which the
+ * authenticity shall be verified.
+ * @param message_length
+ * Length in bytes of the message to be authenticated or verified.
+ * @param mac
+ * Pointer to a buffer of size greater than or equal to mac_length bytes. If
+ * direction is 1 the buffer must be writable and a message authentication code
+ * for the message in message of size mac_length bytes will be written to the
+ * buffer. If direction is 0 the buffer must be readable and contain a message
+ * authentication code that will be verified against the message in message.
+ * @param mac_length
+ * Length in bytes of the message authentication code mac in bytes that is less
+ * than or equal to the cipher block size (i.e. 8 bytes for DES). It is
+ * recommended to use values greater than or equal to 8.
+ * @param key
+ * Pointer to a valid DES key of 8 bytes length.
+ * @param direction
+ * 0 or 1:
+ * 0 Verify message authentication code
+ * 1 Compute message authentication code for the message
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ * EFAULT if direction is 0 and the verification of the message authentication
+ * code fails.
+ */
+ICA_EXPORT
+unsigned int ica_des_cmac(const unsigned char *message, unsigned long message_length,
+ unsigned char *mac, unsigned int mac_length,
+ unsigned char *key,
+ unsigned int direction);
+
+/**
+ * Authenticate data or verify the authenticity of data with an DES key using
+ * the Block Cipher Based Message Authentication Code (CMAC) mode as described
+ * in NIST Special Publication 800-38B.
+ * ica_des_cmc_intermediate and ica_des_cmac_last can be used when the message
+ * to be authenticated or to be verfied using CMAC is supplied in multiple
+ * chunks. ica_des_cmac_intermediate is used to process all but the last
+ * chunk. All message chunks to preprocessed by ica_des_cmac_intermediate
+ * must have a size that is a multiple of the cipher block size (i.e a
+ * multiple of 8 bytes for DES).
+ * Note: ica_des_cmac_intermediate has no direction argument it can be used
+ * during an authentication and during authenticity verification.
+ *
+ * Required HW Support
+ * KMAC-DEA
+ *
+ * @param message
+ * Pointer to a readable buffer of size greater than or equal to
+ * message_length bytes. It contains a non final part of a message which
+ * shall be authenticated or of which the authenticity shall be verified.
+ * @param message_length
+ * Length in bytes of the message part in message. It must be a multiple
+ * of the cipher block size.
+ * @param key
+ * Pointer to a valid DES key of 8 bytes length.
+ * @param iv
+ * Pointer to a valid initialization vector of size cipher block size (i.e.
+ * 8 bytes for DES). For the first message part it must be set to a string
+ * of zeros. For processing the n-th message part it must be the resulting iv
+ * value of the ica_des_cmac_intermediate applied to the (n-1)-th message
+ * part. This vector will be overwritten during the function. The result value
+ * in iv may be used as initialization vector for a chained call to
+ * ica_des_cmac_initermediate or to ica_des_cmac_last with the same key.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_des_cmac_intermediate(const unsigned char *message,
+ unsigned long message_length,
+ unsigned char *key,
+ unsigned char *iv);
+
+/**
+ * Authenticate data or verify the authenticity of data with an 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 preprocessed with ica_des_cmac_intermediate.
+ *
+ * Required HW Support
+ * KMAC-DEA,
+ * PCC-Compute-Last_block-CMAC-Using-DEA
+ *
+ * @param 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 shall be verified.
+ * @param message_length
+ * Length in bytes of the message to be authenticated or verified.
+ * @param mac
+ * Pointer to a buffer of size greater than or equal to mac_length bytes.
+ * If direction is 1 the buffer must be writable and a message authentication
+ * code for the message in message of size mac_length bytes will be written to
+ * the buffer.
+ * If direction is 0 the buffer must be readable and contain a message
+ * authentication code that will be verified against the message in message.
+ * @param mac_length
+ * Length in bytes of the message authentication code mac in bytes that is less
+ * than or equal to the cipher block size (i.e. 8 bytes for DES). It is
+ * recommended to use values greater than or equal to 8.
+ * @param key
+ * Pointer to a valid DES key of 8 bytes length.
+ * @param iv
+ * Pointer to a valid initialization vector of size cipher block size. 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, i.e. the value
+ * returned in iv of the ica_des_cmac_intermediate call applied to the
+ * penultimate message part.
+ * @param direction
+ * 0 or 1:
+ * 0 Verify message authentication code
+ * 1 Compute message authentication code for the message
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ * EFAULT if direction is 0 and the verification of the message authentication
+ * code fails.
+ */
+ICA_EXPORT
+unsigned int ica_des_cmac_last(const unsigned char *message, unsigned long message_length,
+ unsigned char *mac, unsigned int mac_length,
+ unsigned char *key,
+ unsigned char *iv,
+ unsigned int direction);
+
+/**
+ * Encrypt or decrypt data with an 3DES key using Electronic Cook Book (ECB)
+ * mode as described in NIST Special Publication 800-38A Chapter 6.1.
+ *
+ * Required HW Support
+ * KM-DEA-192
+ *
+ * @param in_data
+ * Pointer to a readable buffer, that contains the message to be en/decrypted.
+ * The size of the message in bytes is data_length. The size of this buffer in
+ * bytes must be at least as big as data_length.
+ * @param out_data
+ * Pointer to a writeable buffer, that will contain the resulting en/decrypted
+ * message. The size of this buffer in bytes must be at least as big as
+ * data_length.
+ * @param data_length
+ * Length in bytes of the message to be en/decrypted, which resides at the
+ * beginning of in_data. data_length must be a multiple of the cipher block
+ * size (i.e. a multiple of 8 for 3DES).
+ * @param key
+ * Pointer to a valid 3DES key of 24 bytes length.
+ * @param direction
+ * 0 or 1:
+ * 0 Use the decrypt function.
+ * 1 Use the encrypt function.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_3des_ecb(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned int direction);
+
+/**
+ * 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.
+ *
+ * Required HW Support
+ * KMC-TDEA-192
+ *
+ * @param in_data
+ * Pointer to a readable buffer, that contains the message to be en/decrypted.
+ * The size of the message in bytes is data_length. The size of this buffer in
+ * bytes must be at least as big as data_length.
+ * @param out_data
+ * Pointer to a writable buffer, that will contain the resulting en/decrypted
+ * message. The size of this buffer in bytes must be at least as big as
+ * data_length.
+ * @param data_length
+ * Length in bytes of the message to be en/decrypted, which resides at the
+ * beginning of in_data. data_length must be a multiple of the cipher block
+ * size (i.e. a multiple of 8 for 3DES).
+ * @param key
+ * Pointer to a valid 3DES key of 24 bytes length.
+ * @param iv
+ * Pointer to a valid initialization vector of cipher block size bytes. This
+ * vector will be overwritten during the function. The result value in iv may
+ * be used as initialization vector for a chained ica_3des_cbc call with the
+ * same key.
+ * @param direction
+ * 0 or 1:
+ * 0 Use the decrypt function.
+ * 1 Use the encrypt function.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_3des_cbc(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned char *iv,
+ unsigned int direction);
+
+/**
+ * Encrypt or decrypt data with an 3DES 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_3des_cbc_cs may be used to encrypt o decrypt the last chunk of a
+ * message consisting of multiple chunks where all but the last chunk are
+ * encrypted or decrypted by chained calls to ica_3des_cbc and the resulting
+ * iv of the last call to ica_3des_cbc is fed into the iv of the
+ * ica_3des_cbc_cs call provided the chunc is greater than cipher block size
+ * (greater than 8 bytes for 3DES).
+ *
+ * Required HW Support
+ * KMC-TDEA-192
+ *
+ * @param in_data
+ * Pointer to a readable buffer, that contains the message to be en/decrypted.
+ * The size of the message in bytes is data_length. The size of this buffer
+ * in bytes must be at least as big as data_length.
+ * @param out_data
+ * Pointer to a writable buffer, that will contain the resulting en/decrypted
+ * message. The size of this buffer in bytes must be at least as big as
+ * data_length.
+ * @param data_length
+ * Length in bytes of the message to be en/decrypted, which resides at the
+ * beginning of in_data. data_length must be greater than or equal to the
+ * cipher block size (i.e. a multiple of 8 bytes for 3DES).
+ * @param key
+ * Pointer to a valid 3DES key of 24 bytes length.
+ * @param iv
+ * Pointer to a valid initialization vector of cipher block size bytes. This
+ * vector will be overwritten during the function. For variant equals 1 or
+ * variant equals 2 the result value in iv may be used as initialization vector
+ * for a chained ica_3des_cbc call with the same key if data_length is a
+ * multiple of the cipher block size.
+ * @param direction
+ * 0 or 1:
+ * 0 Use the decrypt function.
+ * 1 Use the encrypt function.
+ * @param variant
+ * 1 Use variant CBC-CS1 of the Addendum to NIST Special Publication 800-38A
+ * to encrypt or decrypt the message: 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 (i.e. a
+ * multiple of 8 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 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_3des_cbc_cs(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length,
+ unsigned char *key,
+ unsigned char *iv,
+ unsigned int direction, unsigned int variant);
+
+/**
+ * Encrypt or decrypt data with an 3DES key using Cipher Feedback (CFB) mode as
+ * described in NIST Special Publication 800-38A Chapter 6.3.
+ *
+ * Required HW Support
+ * KMF-TDEA-192
+ *
+ * @param in_data
+ * Pointer to a readable buffer, that contains the message to be en/decrypted.
+ * The size of the message in bytes is data_length. The size of this buffer in
+ * bytes must be at least as big as data_length.
+ * @param out_data
+ * Pointer to a writable buffer, that will contain the resulting en/decrypted
+ * message. The size of this buffer in bytes must be at least as big as
+ * data_length.
+ * @param data_length
+ * Length in bytes of the message to be en/decrypted, which resides at the
+ * beginning of in_data.
+ * @param key
+ * Pointer to a valid 3DES key of 24 bytes length.
+ * @param iv
+ * Pointer to a valid initialization vector of cipher block size bytes (8 bytes
+ * for 3DES). This vector will be overwritten during the function. The result
+ * value in iv may be used as initialization vector for a chained ica_3des_cfb
+ * call with the same key if data_length in the preceding call is a multiple of
+ * lcfb.
+ * @param 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 (i.e. 8 for
+ * 3DES).
+ * @param direction
+ * 0 or 1:
+ * 0 Use the decrypt function.
+ * 1 Use the encrypt function.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_3des_cfb(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned char *iv, unsigned int lcfb,
+ unsigned int direction);
+
+/**
+ * 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 size cipher block size (i.e. 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 will be derived from preceding counter values by an increment
+ * function. The increment function used in ica_3des_ctr is s an arithmetic
+ * increment without carry on the U least significant bytes in the counter
+ * where M is a parameter to ica_3des_ctr.
+ *
+ * Required HW Support
+ * KMCTR-TDEA-192
+ *
+ * @param in_data
+ * Pointer to a readable buffer, that contains the message to be en/decrypted.
+ * The size of the message in bytes is data_length. The size of this buffer in
+ * bytes must be at least as big as data_length.
+ * @param out_data
+ * Pointer to a writable buffer, that will contain the resulting en/decrypted
+ * message. The size of this buffer in bytes must be at least as big as
+ * data_length.
+ * @param data_length
+ * Length in bytes of the message to be en/decrypted, which resides at the
+ * beginning of in_data.
+ * @param key
+ * Pointer to a valid 3DES key of 24 bytes length.
+ * @param ctr
+ * Pointer to a readable and writable buffer of size cipher block size bytes.
+ * ctr contains an initialization value for a counter function and it will be
+ * replaced by a new value. That 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 data_length used in the preceding call is a multiple of the cipher
+ * block size.
+ * @param ctr_width
+ * A number U between 1 and cipher block size. The value is used by the counter
+ * increment function which increments a counter value by incrementing without
+ * carry the least significant U bytes of the counter value.
+ * @param direction
+ * 0 or 1:
+ * 0 Use the decrypt function.
+ * 1 Use the encrypt function.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_3des_ctr(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length,
+ unsigned char *key,
+ unsigned char *ctr, unsigned int ctr_width,
+ unsigned int direction);
+
+/**
+ * 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 size cipher block size 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 or equal to
+ * the message size divided by the cipher block size. This function allows to
+ * optimally exploit System z HW support for non-standard counter functions.
+ *
+ * Required HW Support
+ * KMCTR-TDEA-192
+ *
+ * @param in_data
+ * Pointer to a readable buffer, that contains the message to be en/decrypted.
+ * The size of the message in bytes is data_length. The size of this buffer in
+ * bytes must be at least as big as data_length.
+ * @param out_data
+ * Pointer to a writable buffer, that will contain the resulting en/decrypted
+ * message. The size of this buffer in bytes must be at least as big as
+ * data_length.
+ * @param data_length
+ * Length in bytes of the message to be en/decrypted, which resides at the
+ * beginning of in_data. If data_length is a multiple of the cipher block size
+ * then calls of ica_3des_ctrlist with the same key can be chained if ctrlist
+ * argument of the chained call contains a list of counters that follows the
+ * counters used in the first call and data_length used in the preceding call
+ * is a multiple of the cipher block size.
+ * @param key
+ * Pointer to an 3DES key of 24 bytes length.
+ * @param ctrlist
+ * Pointer to a readable buffer of that is both of size greater than or equal
+ * to data_length and a multiple of the cipher block size (i.e. 8 bytes for
+ * 3DES). ctrlist should contain a list of precomputed counter values of size
+ * cipher block size each.
+ * @param direction
+ * 0 or 1:
+ * 0 Use the decrypt function.
+ * 1 Use the encrypt function.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_3des_ctrlist(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length,
+ unsigned char *key,
+ const unsigned char *ctrlist,
+ unsigned int direction);
+
+/**
+ * Encrypt or decrypt data with an 3DES key using Output Feedback (OFB) mode as
+ * described in NIST Special Publication 800-38A Chapter 6.4.
+ *
+ * Required HW Support
+ * KMO-TDEA-192
+ *
+ * @param in_data
+ * Pointer to a readable buffer, that contains the message to be en/decrypted.
+ * The size of the message in bytes is data_length. The size of this buffer in
+ * bytes must be at least as big as data_length.
+ * @param out_data
+ * Pointer to a writable buffer, that contains the resulting en/decrypted
+ * message. The size of this buffer in bytes must be at least as big as
+ * data_length.
+ * @param data_length
+ * Length in bytes of the message to be en/decrypted, which resides at the
+ * beginning of in_data.
+ * @param key
+ * Pointer to a valid 3DES key of 24 bytes length.
+ * @param iv
+ * Pointer to a valid initialization vector of cipher block size bytes (8 bytes
+ * for DES). This vector will be overwritten during the function. If
+ * data_length is a multiple of the cipher block size (i.e. a multiple of 8 for
+ * 3DES) the result value in iv may be used as initialization vector for a
+ * chained ica_3DES_ofb call with the same key.
+ * @param direction
+ * 0 or 1:
+ * 0 Use the decrypt function.
+ * 1 Use the encrypt function.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_3des_ofb(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned char *iv, unsigned int direction);
+
+/**
+ * Authenticate data or verify the authenticity of data with an 3DES key
+ * using the Block Cipher Based Message Authetication 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.
+ *
+ * Required HW Support
+ * KMAC-TDEA-192
+ * PCC-Compute-Last_block-CMAC-Using-TDEA-192
+ *
+ * @param message
+ * Pointer to a readable buffer of size greater than or equal to
+ * message_length bytes. It contains a message to be authenticated or of
+ * which the authenticity shall be verified.
+ * @param message_length
+ * Length in bytes of the message to be authenticated or verified.
+ * @param mac
+ * Pointer to a buffer of size greater than or equal to mac_length bytes.
+ * If direction is 1 the buffer must be writable and a message authentication
+ * code for the message in message of size mac_length bytes will be written to
+ * the buffer.
+ * If direction is 0 the buffer must be readable and contain a message
+ * authentication code that will be verified against the message in message.
+ * @param mac_length
+ * Length in bytes of the message authentication code mac in bytes that is less
+ * than or equal to the cipher block size (i.e. 8 bytes for TDES). It is
+ * recommended to use values greater than or equal to 8.
+ * @param key
+ * Pointer to a valid 3DES key of 24 bytes length.
+ * @param direction
+ * 0 or 1:
+ * 0 Verify message authentication code
+ * 1 Compute message authentication code for the message
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ * EFAULT if direction is 0 and the verification of the message authentication
+ * code fails.
+ */
+ICA_EXPORT
+unsigned int ica_3des_cmac(const unsigned char *message, unsigned long message_length,
+ unsigned char *mac, unsigned int mac_length,
+ unsigned char *key,
+ unsigned int direction);
+
+/**
+ * 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_cmc_intermediate and ica_3des_cmac_last can be used when the
+ * message to be authenticated or to be verfied using CMAC is supplied in
+ * multiple chunks. ica_3des_cmac_intermediate is used to process all but the
+ * last chunk. All message chunks to preprocessed by
+ * ica_3des_cmac_intermediate must have a size that is a multiple of the
+ * cipher block size (i.e a multiple of 8 bytes for 3DES).
+ * Note: ica_3des_cmac_intermediate has no direction argument it can be used
+ * during an authentication and during authenticity verification.
+ *
+ * Required HW Support
+ * KMAC-TDEA-192,
+ *
+ * @param message
+ * Pointer to a readable buffer of size greater than or equal to message_length
+ * bytes. It contains a non final part of a message which shall be
+ * authenticated or of which the authenticity shall be verified.
+ * @param message_length
+ * Length in bytes of the message part in message. It must be a multiple of the
+ * cipher block size.
+ * @param key
+ * Pointer to a valid 3DES key of 24 bytes length.
+ * @param iv
+ * Pointer to a valid initialization vector of size cipher block size
+ * (i.e. 8 bytes for 3DES). For the first message part it must be set to a
+ * string of zeros. For processing the n-th message part it must be the
+ * resulting iv value of the ica_3des_cmac_intermediate applied to the
+ * (n-1)-th message part. This vector will be overwritten during the function.
+ * The result value in iv may be used as initialization vector for a chained
+ * call to ica_3des_cmac_initermediate or to ica_3des_cmac_last with the same key.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_3des_cmac_intermediate(const unsigned char *message, unsigned long message_length,
+ unsigned char *key,
+ unsigned char *iv);
+
+/**
+ * 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 preprocessed with ica_3des_cmac_intermediate.
+ *
+ * Required HW Support
+ * KMAC-TDEA-192,
+ * PCC-Compute-Last_block-CMAC-Using-TDEA-192
+ *
+ * @param 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 shall be verified.
+ * @param message_length
+ * Length in bytes of the message to be authenticated or verified.
+ * @param mac
+ * Pointer to a buffer of size greater than or equal to mac_length bytes.
+ * If direction is 1 the buffer must be writable and a message authentication
+ * code for the message in message of size mac_length bytes will be written to
+ * the buffer.
+ * If direction is 0 the buffer must be readable and contain a message
+ * authentication code that will be verified against the message in message.
+ * @param mac_length
+ * Length in bytes of the message authentication code mac in bytes that is
+ * less than or equal to the cipher block size (I.e. 8 bytes for DES). It is
+ * recommended to use values greater than or equal to 8.
+ * @param key
+ * Pointer to a valid 3DES key of 24 bytes length.
+ * @param iv
+ * Pointer to a valid initialization vector of size cipher block size. 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_3des_cmac_intermediate, i.e. the value
+ * returned in iv of the ica_3des_cmac_intermediate call applied to the
+ * penultimate message part.
+ * @param direction
+ * 0 or 1:
+ * 0 Verify message authentication code
+ * 1 Compute message authentication code for the message
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ * EFAULT if direction is 0 and the verification of the message authentication
+ * code fails.
+ */
+ICA_EXPORT
+unsigned int ica_3des_cmac_last(const unsigned char *message, unsigned long message_length,
+ unsigned char *mac, unsigned int mac_length,
+ unsigned char *key, unsigned char *iv,
+ unsigned int direction);
+
+/**
+ * Encrypt or decrypt data with an AES key using Electronic Cook Book (ECB)
+ * mode as described in NIST Special Publication 800-38A Chapter 6.1.
+ *
+ * Required HW Support
+ * KM-AES-128, KM-AES-192 or KM-AES-256
+ *
+ * @param in_data
+ * Pointer to a readable buffer, that contains the message to be en/decrypted.
+ * The size of the message in bytes is data_length. The size of this buffer in
+ * bytes must be at least as big as data_length.
+ * @param out_data
+ * Pointer to a writable buffer, that will contain the resulting en/decrypted
+ * message. The size of this buffer in bytes must be at least as big as
+ * data_length.
+ * @param data_length
+ * Length in bytes of the message to be en/decrypted, which resides at the
+ * beginning of in_data. data_length must be a multiple of the cipher block
+ * size (i.e. a multiple of 16 for AES).
+ * @param key
+ * Pointer to a valid AES key.
+ * @param 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
+ * macros: AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
+ * @param direction
+ * 0 or 1:
+ * 0 Use the decrypt function.
+ * 1 Use the encrypt function.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_aes_ecb(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned int key_length,
+ unsigned int direction);
+
+/**
+ * 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.
+ *
+ * Required HW Support
+ * KMC-AES-128, KMC-AES-192 or KMC-AES-256
+ *
+ * @param in_data
+ * Pointer to a readable buffer, that contains the message to be en/decrypted.
+ * The size of the message in bytes is data_length. The size of this buffer in
+ * bytes must be at least as big as data_length.
+ * @param out_data
+ * Pointer to a writable buffer, that will contain the resulting en/decrypted
+ * message. The size of this buffer in bytes must be at least as big as
+ * data_length.
+ * @param data_length
+ * Length in bytes of the message to be en/decrypted, which resides at the
+ * beginning of in_data. data_length must be a multiple of the cipher block
+ * size (i.e. a multiple of 16 for AES).
+ * @param key
+ * Pointer to a valid AES key.
+ * @param 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
+ * macros: AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
+ * @param iv
+ * Pointer to a valid initialization vector of size chipher block size. This
+ * vector will be overwritten during the function. The result value in iv may
+ * be used as initialization vector for a chained ica_aes_cbc call with the
+ * same key.
+ * @param direction
+ * 0 or 1:
+ * 0 Use the decrypt function.
+ * 1 Use the encrypt function.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_aes_cbc(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned int key_length, unsigned char *iv,
+ unsigned int direction);
+
+/**
+ * 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 may be used to encrypt or decrypt the last chunk of a
+ * message consisting of multiple chunks where all but the last chunk are
+ * encrypted or decrypted by chained calls to ica_aes_cbc and the resulting
+ * iv of the last call to ica_aes_cbc is fed into the iv of the
+ * ica_aes_cbc_cs call provided the chunk is greater than cipher block size
+ * (greater than 16 bytes for AES).
+ *
+ * Required HW Support
+ * KMC-AES-128, KMC-AES-192 or KMC-AES-256
+ *
+ * @param in_data
+ * Pointer to a readable buffer, that contains the message to be en/decrypted.
+ * The size of the message in bytes is data_length. The size of this buffer
+ * in bytes must be at least as big as data_length.
+ * @param out_data
+ * Pointer to a writable buffer, that will contain the resulting en/decrypted
+ * message. The size of this buffer in bytes must be at least as big as
+ * data_length.
+ * @param data_length
+ * Length in bytes of the message to be en/decrypted, which resides at the
+ * beginning of in_data. data_length must be greater than or equal to the
+ * cipher block size (i.e. a multiple of 16 bytes for AES).
+ * @param key
+ * Pointer to a valid AES key.
+ * @param 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
+ * macros:
+ * AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
+ * @param iv
+ * Pointer to a valid initialization vector of cipher block size bytes. This
+ * vector will be overwritten during the function. For variant equals 1 or
+ * variant equals 2 the result value in iv may be used as initialization vector
+ * for a chained ica_aes_cbc call with the same key if data_length is a
+ * multiple of the cipher block size.
+ * @param direction
+ * 0 or 1:
+ * 0 Use the decrypt function.
+ * 1 Use the encrypt function.
+ * @param variant
+ * 1 Use variant CBC-CS1 of the Addendum to NIST Special Publication 800-38A
+ * to encrypt or decrypt the message: 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 (i.e. a
+ * multiple of 8 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 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_aes_cbc_cs(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length,
+ unsigned char *key, unsigned int key_length,
+ unsigned char *iv,
+ unsigned int direction, unsigned int variant);
+
+/**
+ * Encrypt or decrypt data with an AES key using Cipher Feedback (CFB) mode as
+ * described in NIST Special Publication 800-38A Chapter 6.3.
+ *
+ * Required HW Support
+ * KMF-AES-128, KMF-AES-192 or KMF-AES-256
+ *
+ * @param in_data
+ * Pointer to a readable buffer, that contains the message to be en/decrypted.
+ * The size of the message in bytes is data_length. The size of this buffer in
+ * bytes must be at least as big as data_length.
+ * @param out_data
+ * Pointer to a writable buffer, that will contain the resulting en/decrypted
+ * message. The size of this buffer in bytes must be at least as big as
+ * data_length.
+ * @param data_length
+ * Length in bytes of the message to be en/decrypted, which resides at the
+ * beginning of in_data.
+ * @param key
+ * Pointer to a valid AES key.
+ * @param 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
+ * macros: AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
+ * @param iv
+ * Pointer to a valid initialization vector of cipher block size bytes (16
+ * bytes for AES). This vector will be overwritten during the function. The
+ * result value in iv may be used as initialization vector for a chained
+ * ica_aes_cfb call with the same key if data_length in the preceding call is a
+ * multiple of lcfb.
+ * @param 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 (i.e. 16 for
+ * AES).
+ * @param direction
+ * 0 or 1:
+ * 0 Use the decrypt function.
+ * 1 Use the encrypt function.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_aes_cfb(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned int key_length, unsigned char *iv, unsigned int lcfb,
+ unsigned int direction);
+
+/**
+ * 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 (i.e. 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 will be derived from preceding counter values by an increment
+ * function. The increment function used in ica_aes_ctr is s an arithmetic
+ * increment without carry on the U least significant bytes in the counter
+ * where M is a parameter to ica_aes_ctr.
+ *
+ * Required HW Support
+ * KMCTR-AES-128, KMCTR-AES-192 or KMCTR-AES-256
+ *
+ * @param in_data
+ * Pointer to a readable buffer, that contains the message to be en/decrypted.
+ * The size of the message in bytes is data_length. The size of this buffer in
+ * bytes must be at least as big as data_length.
+ * @param out_data
+ * Pointer to a writable buffer, that will contain the resulting en/decrypted
+ * message. The size of this buffer in bytes must be at least as big as
+ * data_length.
+ * @param data_length
+ * Length in bytes of the message to be en/decrypted, which resides at the
+ * beginning of in_data.
+ * @param key
+ * Pointer to a valid AES key.
+ * @param 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
+ * macros: AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
+ * @param ctr
+ * Pointer to a readable and writable buffer of size cipher block size bytes.
+ * ctr contains an initialization value for a counter function and it will be
+ * 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 data_length used in the preceding call is a multiple of the cipher block
+ * size.
+ * @param ctr_width
+ * A number U between 1 and cipher block size. The value is used by the counter
+ * increment function which increments a counter value by incrementing without
+ * carry the least significant U bytes of the counter value.
+ * @param direction
+ * 0 or 1:
+ * 0 Use the decrypt function.
+ * 1 Use the encrypt function.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_aes_ctr(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length,
+ unsigned char *key, unsigned int key_length,
+ unsigned char *ctr, unsigned int ctr_width,
+ unsigned int direction);
+
+/**
+ * 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 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 or equal to the message size
+ * divided by the cipher block size. This function allows to optimally exploit
+ * System z HW support for non-standard counter functions.
+ *
+ * Required HW Support
+ * KMCTR-AES-128, KMCTR-AES-192 or KMCTR-AES-256
+ *
+ * @param in_data
+ * Pointer to a readable buffer, that contains the message to be en/decrypted.
+ * The size of the message in bytes is data_length. The size of this buffer in
+ * bytes must be at least as big as data_length.
+ * @param out_data
+ * Pointer to a writable buffer, that will contain the resulting en/decrypted
+ * message. The size of this buffer in bytes must be at least as big as
+ * data_length.
+ * @param data_length
+ * Length in bytes of the message to be en/decrypted, which resides at the
+ * beginning of in_data. If data_length is a multiple of the cipher block size
+ * then calls of ica_aes_ctrlist with the same key can be chained if ctrlist
+ * argument of the chained call contains a list of counters that follows the
+ * counters used in the first call and data_length used in the preceding call
+ * is a multiple of the cipher block size.
+ * @param key
+ * Pointer to a valid AES key.
+ * @param 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
+ * macros: AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
+ * @param ctrlist
+ * Pointer to a readable buffer of that is both of size greater than or equal
+ * to data_length and a multiple of the cipher block size (i.e. 16 bytes for
+ * AES). ctrlist should contain a list of precomputed counter values of size
+ * cipher block size each.
+ * @param direction
+ * 0 or 1:
+ * 0 Use the decrypt function.
+ * 1 Use the encrypt function.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_aes_ctrlist(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length,
+ unsigned char *key, unsigned int key_length,
+ const unsigned char *ctrlist,
+ unsigned int direction);
+
+/**
+ * Encrypt or decrypt data with an AES key using Output Feedback (OFB) mode as
+ * described in NIST Special Publication 800-38A Chapter 6.4.
+ *
+ * Required HW Support
+ * KMO-AES-128, KMO-AES-192 or KMO-AES-256
+ *
+ * @param in_data
+ * Pointer to a readable buffer, that contains the message to be en/decrypted.
+ * The size of the message in bytes is data_length. The size of this buffer in
+ * bytes must be at least as big as data_length.
+ * @param out_data
+ * Pointer to a writable buffer, that contains the resulting en/decrypted
+ * message. The size of this buffer in bytes must be at least as big as
+ * data_length.
+ * @param data_length
+ * Length in bytes of the message to be en/decrypted, which resides at the
+ * beginning of in_data.
+ * @param key
+ * Pointer to a valid AES key.
+ * @param 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
+ * macros: AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
+ * @param iv
+ * Pointer to a valid 16 byte initialization vector. This vector will be
+ * overwritten during the function. If data_length is a multiple of the cipher
+ * block size (i.e. a multiple of 16 for AES) the result value in iv may be
+ * used as initialization vector for a chained ica_aes_ofb call with the same
+ * key.
+ * @param direction
+ * 0 or 1:
+ * 0 Use the decrypt function.
+ * 1 Use the encrypt function.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_aes_ofb(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned int key_length, unsigned char *iv,
+ unsigned int direction);
+
+/**
+ * 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.
+ *
+ * Required HW Support
+ * KMAC-AES-128, KMAC-AES-192 or KMAC-AES-256
+ * PCC-Compute-Last_block-CMAC-Using-AES-128,
+ * PCC-Compute-Last_block-CMAC-Using-AES-192 or
+ * PCC-Compute-Last_block-CMAC-Using-AES-256
+ *
+ * @param message
+ * Pointer to a readable buffer of size greater than or equal to message_length
+ * bytes. It contains a message to be authenticated or of which the
+ * authenticity shall be verified.
+ * @param message_length
+ * Length in bytes of the message to be authenticated or verified.
+ * @param mac
+ * Pointer to a buffer of size greater than or equal to mac_length bytes. If
+ * direction is 1 the buffer must be writable and a message authentication code
+ * for the message in message of size mac_length bytes will be written to the
+ * buffer. If direction is 0 the buffer must be readable and contain a message
+ * authentication code that will be verified against the message in message
+ * @param mac_length
+ * Length in bytes of the message authentication code mac in bytes that is less
+ * than or equal to the cipher block size (I.e. 16 bytes for AES). It is
+ * recommended to use values greater than or equal to 8.
+ * @param key
+ * Pointer to a valid AES key.
+ * @param 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
+ * macros: AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
+ * @param direction
+ * 0 or 1:
+ * 0 Verify message authentication code
+ * 1 Compute message authentication code for the message
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ * EFAULT if direction is 0 and the verification of the message authentication code fails.
+ */
+ICA_EXPORT
+unsigned int ica_aes_cmac(const unsigned char *message, unsigned long message_length,
+ unsigned char *mac, unsigned int mac_length,
+ unsigned char *key, unsigned int key_length,
+ unsigned int direction);
+
+/**
+ * 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_cmc_intermediate and ica_aes_cmac_last can be used when the message
+ * to be authenticated or to be verfied using CMAC is supplied in multiple
+ * chunks. ica_aes_cmac_intermediate is used to process all but the last
+ * chunk. All message chunks to preprocessed by ica_aes_cmac_intermediate
+ * must have a size that is a multiple of the cipher block size (i.e. a
+ * multiple of 16 bytes for AES).
+ * Note: ica_aes_cmac_intermediate has no direction argument it can be used
+ * during an authentication and during authenticity verification.
+ *
+ * Required HW Support
+ * KMAC-AES-128, KMAC-AES-192 or KMAC-AES-256
+ *
+ * @param message
+ * Pointer to a readable buffer of size greater than or equal to message_length
+ * bytes. It contains a non final part of a message which shall be
+ * authenticated or of which the authenticity shall be verified.
+ * @param message_length
+ * Length in bytes of the message part in message. It must be a multiple of
+ * the cipher block size.
+ * @param key
+ * Pointer to a valid AES key.
+ * @param 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
+ * macros: AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
+ * @param iv
+ * Pointer to a valid initialization vector of size cipher block size (i.e.
+ * 16 bytes for AES). For the first message part it must be set to a string
+ * of zeros. For processing the n-th message part it must be the resulting iv
+ * value of the ica_aes_cmac_intermediate applied to the (n-1)-th message
+ * part. This vector will be overwritten during the function.
+ * The result value in iv may be used as initialization vector for a chained
+ * call to ica_aes_cmac_initermediate or to ica_aes_cmac_last with the
+ * same key.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_aes_cmac_intermediate(const unsigned char *message,
+ unsigned long message_length,
+ unsigned char *key, unsigned int key_length,
+ unsigned char *iv);
+
+/**
+ * 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 preprocessed with ica_aes_cmac_intermediate.
+ *
+ * Required HW Support
+ * KMAC-AES-128, KMAC-AES-192 or KMAC-AES-256
+ * PCC-Compute-Last_block-CMAC-Using-AES-128,
+ * PCC-Compute-Last_block-CMAC-Using-AES-192 or
+ * PCC-Compute-Last_block-CMAC-Using-AES-256.
+ *
+ * @param 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 shall be verified.
+ * @param message_length
+ * Length in bytes of the message to be authenticated or verified.
+ * @param mac
+ * Pointer to a buffer of size greater than or equal to mac_length bytes.
+ * If direction is 1 the buffer must be writable and a message authentication
+ * code for the message in message of size mac_length bytes will be written to
+ * the buffer.
+ * If direction is 0 the buffer must be readable and contain a message
+ * authentication code that will be verified against the message in message.
+ * @param mac_length
+ * Length in bytes of the message authentication code mac in bytes that is less
+ * than or equal to the cipher block size (I.e. 16 bytes for AES). It is
+ * recommended to use values greater than or equal to 8.
+ * @param key
+ * Pointer to a valid AES key.
+ * @param 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
+ * macros: AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
+ * @param iv
+ * Pointer to a valid initialization vector of size cipher block size. 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, i.e. the value
+ * returned in iv of the ica_aes_cmac_intermediate call applied to the
+ * penultimate message part.
+ * @param direction
+ * 0 or 1:
+ * 0 Verify message authentication code
+ * 1 Compute message authentication code for the message
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ * EFAULT if direction is 0 and the verification of the message authentication
+ * code fails.
+ */
+ICA_EXPORT
+unsigned int ica_aes_cmac_last(const unsigned char *message, unsigned long message_length,
+ unsigned char *mac, unsigned int mac_length,
+ unsigned char *key, unsigned int key_length,
+ unsigned char *iv,
+ unsigned int direction);
+
+/**
+ * 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.
+ *
+ * Required HW Support
+ * KM-XTS-AES-128 or KM-XTS-AES-256
+ * PCC-Compute-XTS-Parameter-Using-AES-128 or
+ * PCC-Compute-XTS-Parameter-Using-AES-256
+ *
+ * @param in_data
+ * Pointer to a readable buffer, that contains the message to be en/decrypted.
+ * The size of the message in bytes is data_length. The size of this buffer in
+ * bytes must be at least as big as data_length.
+ * @param out_data
+ * Pointer to a writable buffer, that will contain the resulting en/decrypted
+ * message. The size of this buffer in bytes must be at least as big as
+ * data_length.
+ * @param data_length
+ * Length in bytes of the message to be en/decrypted, which resides at the
+ * beginning of in_data. The minimal value of data_length is cipher block size
+ * (i.e. a multiple of 16 for AES).
+ * @param key1
+ * Pointer to a buffer containing a valid AES key. key1 is used for the actual
+ * encryption of the message buffer combined some vector computed from the
+ * tweek value (Key1 in IEEE Std 1619-2007).
+ * @param key2
+ * Pointer to a buffer containing a valid AES key key2 is used to encrypt the
+ * tweak (Key2 in IEEE Std 1619-2007).
+ * @param key_length
+ * The length in bytes of the AES key. For XTS supported AES key sizes are 16
+ * and 32 for AES-128 and AES-256 respectively.
+ * @param tweak
+ * Pointer to a valid 16 byte tweak value (as in IEEE Std 1619-2007). This
+ * tweak will be overwritten during the function. If data_length is a multiple
+ * of the cipher block size the result value in tweak may be used as tweak
+ * value for a chained ica_aes_xts call with the same key pair.
+ * @param direction
+ * 0 or 1:
+ * 0 Use the decrypt function.
+ * 1 Use the encrypt function.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ */
+ICA_EXPORT
+unsigned int ica_aes_xts(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length,
+ unsigned char *key1, unsigned char *key2,
+ unsigned int key_length, unsigned char *tweak,
+ unsigned int direction);
+
+/**
+ * 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.
+ *
+ * Required HW Support
+ * KMCTR-AES-128, KMCTR-AES-192 or KMCTR-AES-256
+ * KMAC-AES-128, KMAC-AES-192 or KMAC-AES-256
+ *
+ * @param payload
+ * Pointer to a buffer of size greater than or equal to payload_length bytes.
+ * If direction equals 1 the payload buffer must be readable and contain a
+ * payload message of size payload_length that will be encrypted.
+ * If direction equals 0 the payload buffer must be writable. If the
+ * authentication verification succeeds the decrypted message in the most
+ * significant payload_length bytes of ciphertext_n_mac will be written to
+ * the buffer otherwise the contents of the buffer will be undefined.
+ * @param payload_length
+ * Length in bytes of the message to be en/decrypted, it may be 0 unless
+ * assoc_data_length is 0.
+ * @param ciphertext_n_mac
+ * Pointer to a buffer of size greater than or equal to payload_length plus
+ * mac_length bytes.
+ * If direction equals 1 then 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 will be written to that buffer.
+ * If direction equals 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.
+ * @param mac_length
+ * Length in bytes of the message authentication code in bytes.
+ * Valid values are 4, 6, 8, 10, 12, 16.
+ * @param 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_lenght bytes is subject to the authentication code computation
+ * but will not be encrypted.
+ * @param assoc_data_length
+ * Length of the associated data in assoc_data. It may be 0 unless
+ * payload_length is 0.
+ * @param nonce
+ * Pointer to readable buffer of size greater than or equal to nonce_length
+ * bytes that contains a nonce of size nonce_length bytes.
+ * @param nonce_length
+ * Length of the nonce in nonce in bytes. Valid values a greater than 6 and
+ * less than 14.
+ * @param key
+ * Pointer to a valid AES key.
+ * @param 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
+ * macros: AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
+ * @param direction
+ * 0 or 1:
+ * 0 Verify message authentication code and decrypt encrypted payload.
+ * 1 Encrypt payload and compute message authentication code for the nonce,
+ * the associated data and the payload.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ * EFAULT if direction is 0 and the verification of the message authentication
+ * code fails.
+ */
+ICA_EXPORT
+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,
+ unsigned char *key, unsigned int key_length,
+ unsigned int direction);
+
+/**
+ * This parameter description applies to:
+ * ica_aes_gcm(), ica_aes_gcm_initialize(),
+ * ica_aes_gcm_intermediate() and ica_aes_gcm_last()
+ *
+ * Encrypt and authenticate or decrypt data and check authenticity 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.
+ *
+ * Required HW Support
+ * KM-AES-128, KM-AES-192 or KM-AES-256
+ * KIMD-GHASH
+ * KMCTR-AES-128, KMCTR_AES-192 or KMCTR-AES-256
+ *
+ * @param plaintext
+ * Pointer to a buffer of size greater than or equal to plaintext_length bytes.
+ * If direction equals 1 the plaintext buffer must be readable and contain a
+ * payload message of size plaintext_length that will be encrypted.
+ * If direction equals 0 the plaintext buffer must be writable. If the
+ * authentication verification succeeds the decrypted message in the most
+ * significant plaintext_length bytes of ciphertext will be written to the
+ * buffer otherwise the contents of the buffer will be undefined.
+ * @param plaintext_length
+ * Length in bytes of the message to be en/decrypted. It must be equal or
+ * greater than 0 and less than (2^36)-32.
+ * In case of intermediate operations the length must not be multiple of
+ * blocksize. Padding will be done automatically. Be aware that this is only
+ * useful when this is the last block.
+ * @param ciphertext
+ * Pointer to a buffer of size greater than or equal to plaintext_length
+ * bytes.
+ * If direction equals 1 then the buffer must be writable and the encrypted
+ * message from plaintext will be written to that buffer.
+ * If direction equals 0 then the buffer is readable and contains an encrypted
+ * message of length plaintext_length.
+ * @param iv
+ * Pointer to a readable buffer of size greater than or equal to iv_length
+ * bytes, that contains an initialization vector of size iv_length.
+ * @param iv_length
+ * Length in bytes of the initialization vector in iv. It must be greater
+ * than 0 and less than 2^61. A length of 12 is recommended.
+ * @param 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 authentication code computation but will not be
+ * encrypted.
+ * @param aad_length
+ * Length in bytes of the additional authenticated data in aad. It must be
+ * equal or greater than 0 and less than 2^61.
+ * In case of ica_aes_gcm_last(), 'aad_length' contains the overall
+ * length of authentication data, cumulated over all intermediate operations.
+ * @param tag
+ * Pointer to a buffer of size greater than or equal to tag_length bytes.
+ * If direction is 1 the 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 will be written to the buffer.
+ * If direction is 0 the buffer must be readable and contain a message
+ * authentication code that will be verified against the additional
+ * authenticated data in aad and decrypted cipher text from ciphertext.
+ * In case of intermediate operations, ica_aes_gcm_intermediate() or
+ * ica_aes_gcm_last(), 'tag' contains the temporary hash/tag value.
+ * @param tag_length
+ * Length in bytes of the message authentication code tag in bytes.
+ * Valid values are 4, 8, 12, 13, 14, 15, 16.
+ * @param key
+ * Pointer to a valid AES key.
+ * @param 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
+ * macros: AES_KEY_LEN128, AES_KEY_LEN192, and AES_KEY_LEN256.
+ * @param icb
+ * initial counter block - Pointer to a writable buffer that will be created
+ * during ica_aes_gcm_initialize() and will be used in ica_aes_gcm_last() for
+ * the final tag computation.
+ * The length of this counter block is AES_BLOCK_SIZE (16 bytes).
+ * @param ucb
+ * usage counter block - Pointer to a writable buffer that will be created
+ * during ica_aes_gcm_initialize() and will be updated (increased) during the
+ * intermediate update operations.
+ * The length of this counter block is AES_BLOCK_SIZE (16 bytes).
+ * @param subkey
+ * Pointer to a writable buffer, generated in ica_aes_gcm_initialize() and used in
+ * ica_aes_gcm_intermediate() and ica_aes_gcm_last().
+ * The length of this buffer is AES_BLOCK_SIZE (16 bytes).
+ * @param ciph_length
+ * Length in bytes of the overall ciphertext, cumulated over all intermediate
+ * operations.
+ * @param final_tag
+ * Pointer to a readable buffer of size greater than or equal to
+ * final_tag_length bytes. If direction is 1 the buffer is not used.
+ * If direction is 0 this message authentication code (tag) will be verified
+ * with the computed message authentication code computed over the intermediate
+ * update operations.
+ * @param final_tag_length
+ * Length in bytes of the final message authentication code (tag).
+ * @param direction
+ * 0 or 1:
+ * 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 0 on success
+ * EINVAL if at least one invalid parameter is given.
+ * EPERM if required hardware support is not available.
+ * EIO if the operation fails.
+ * EFAULT if direction is 0 and the verification of the message authentication
+ * code fails.
+ */
+ICA_EXPORT
+unsigned int ica_aes_gcm(unsigned char *plaintext, unsigned long plaintext_length,
+ unsigned char *ciphertext,
+ const unsigned char *iv, unsigned int iv_length,
+ const unsigned char *aad, unsigned long aad_length,
+ unsigned char *tag, unsigned int tag_length,
+ unsigned char *key, unsigned int key_length,
+ unsigned int direction);
+
+ICA_EXPORT
+unsigned int ica_aes_gcm_initialize(const unsigned char *iv,
+ unsigned int iv_length,
+ unsigned char *key, unsigned int key_length,
+ unsigned char *icb, unsigned char *ucb,
+ unsigned char *subkey, unsigned int direction);
+
+ICA_EXPORT
+unsigned int ica_aes_gcm_intermediate(unsigned char *plaintext,
+ unsigned long plaintext_length, unsigned char *ciphertext,
+ unsigned char *ucb,
+ unsigned char *aad, unsigned long aad_length,
+ unsigned char *tag, unsigned int tag_length,
+ unsigned char *key, unsigned int key_length,
+ unsigned char *subkey, unsigned int direction);
+
+ICA_EXPORT
+unsigned int ica_aes_gcm_last(unsigned char *icb, unsigned long aad_length,
+ unsigned long ciph_length, unsigned char *tag,
+ unsigned char *final_tag, unsigned int final_tag_length,
+ unsigned char *key, unsigned int key_length,
+ unsigned char *subkey, unsigned int direction);
+
+/**
+ * Return libica version information.
+ * @param version_info
+ * Pointer to a libica_version_info structure. The structure will be
+ * filled with the current libica version information.
+ *
+ * @return 0 if version could be determined successfully
+ * EIO if version could not be determined
+ * EINVAL if parameter version_info is NULL
+ */
+ICA_EXPORT
+unsigned int ica_get_version(libica_version_info *version_info);
+
+ICA_EXPORT
+int s390_initialize_functionlist(void);
+
+ICA_EXPORT
+int s390_get_functionlist(libica_func_list_element *pmech_list,
+ unsigned int *pmech_list_len);
+
+/**
+ * Function that returns a list of crypto mechanisms supported by libica.
+ * @param pmech_list
+ * Pointer to an array of libica_func_list_element
+ * If NULL, the API will return the number of elements to allocate
+ * in the @mech_list_len parameter.
+ * If not NULL, libica will assume @mech_list is an array that has
+ * @num elements.
+ * On success, @mech_list will be filled out with the supported libica
+ * crypto mechanisms.
+ * @param pmech_list_len
+ * number of list entries
+ * On input, pointer to the number of elements allocated in the
+ * @mech_list array.
+ * On output, @mech_list_len will contain the number of items copied to
+ * the @mech_list array, or the number of items libica would have returned
+ * in case the @mech_list parameter is set to NULL.
+ * @return
+ * 0 on success
+ * EINVAL if at least one invalid parameter is given
+ *
+ * A typical usage scenario would be that an exploiter makes a first call to
+ * ica_get_functionlist() with @mech_list set to NULL in order to determine
+ * the number of elements to allocate. This is followed by a second call to
+ * ica_get_functionlist() with a valid pointer @list to an array of
+ * libica_func_list_element structures with @mech_list_len elements.
+ */
+ICA_EXPORT
+unsigned int ica_get_functionlist(libica_func_list_element *pmech_list,
+ unsigned int *pmech_list_len);
+
+static inline unsigned int des_directed_fc(int direction)
+{
+ if (direction)
+ return DEA_ENCRYPT;
+ return DEA_DECRYPT;
+}
+
+static inline unsigned int tdes_directed_fc(int direction)
+{
+ if (direction)
+ return TDEA_192_ENCRYPT;
+ return TDEA_192_DECRYPT;
+}
+
+static inline unsigned int aes_directed_fc(unsigned int key_length, int direction)
+{
+ switch (key_length) {
+ case AES_KEY_LEN128:
+ return (direction == ICA_DECRYPT) ?
+ AES_128_DECRYPT : AES_128_ENCRYPT;
+ case AES_KEY_LEN192:
+ return (direction == ICA_DECRYPT) ?
+ AES_192_DECRYPT : AES_192_ENCRYPT;
+ case AES_KEY_LEN256:
+ return (direction == ICA_DECRYPT) ?
+ AES_256_DECRYPT : AES_256_ENCRYPT;
+ }
+ return 0;
+}
+
+/*
+ * ica_drbg: libica's Deterministic Random Bit Generator
+ * (conforming to NIST SP 800-90A)
+ *
+ * Table of currently supported DRBG mechanisms:
+ *
+ * DRBG mechanism supported security max. byte length
+ * strengths (bits) of pers / add
+ * -------------------------------------------------------------
+ * DRBG_SHA512 112, 128, 196, 256 256 / 256
+ *
+ * An ica_drbg_t object holds the internal state of a DRBG instantiation. A
+ * DRBG instantiation is identified by an associated ica_drbg_t * pointer
+ * (state handle).
+ * State handles that do not identify any DRBG instantiation SHALL be NULL
+ * (invalid). Therefore a new state handle SHALL be initialized to NULL.
+ *
+ * If a catastrophic error (<0) is detected, all existing DRBG instantiations
+ * of the corresponding mechanism are in error state making uninstantiation
+ * their only permitted operation. Creation of new DRBG instantiations of
+ * this mechanism are not permitted.
+ */
+ICA_EXPORT
+extern ica_drbg_mech_t *const ICA_DRBG_SHA512;
+
+
+/*
+ * Instantiate function
+ * (create a new DRBG instantiation)
+ *
+ * @sh: State Handle pointer. The (invalid) state handle is set to identify the
+ * new DRBG instantiation and thus becomes valid.
+ * @sec: requested instantiation SECurity strength (bits). The new DRBG
+ * instantiation's security strength is set to the lowest security strength
+ * supported by it's DRBG mechanism (see table) that is greater than or equal
+ * to @sec.
+ * @pr: Prediction Resistance flag. Indicates whether or not prediction
+ * resistance may be required by the consuming application during one or more
+ * requests for pseudorandom bytes.
+ * @mech: MECHanism. The new DRBG instantiation is of this mechanism type.
+ * @pers: PERSonalization string. An optional input that provides
+ * personalization information. The personalisation string SHALL be unique for
+ * all instantiations of the same mechanism type. NULL indicates that no
+ * personalization string is used (not recommended).
+ * @pers_len: Byte length of @pers.
+ *
+ * @return:
+ * 0 Success.
+ * ENOMEM Out of memory.
+ * EINVAL At least one argument is invalid.
+ * ENOTSUP Prediction resistance or the requested security
+ * strength is not supported.
+ * EPERM Failed to obtain a valid timestamp from clock.
+ * ICA_DRBG_HEALTH_TEST_FAIL Health test failed.
+ * ICA_DRBG_ENTROPY_SOURCE_FAIL Entropy source failed.
+ */
+ICA_EXPORT
+int ica_drbg_instantiate(ica_drbg_t **sh,
+ int sec,
+ bool pr,
+ ica_drbg_mech_t *mech,
+ const unsigned char *pers,
+ size_t pers_len);
+
+/*
+ * Reseed function
+ * (reseed a DRBG instantiation)
+ *
+ * @sh: State Handle. Identifies the DRBG instantiation to be reseeded.
+ * @pr: Prediciton Resistance request. Indicates whether or not prediction
+ * resistance is required.
+ * @add: ADDitional input: An optional input. NULL indicates that no additional
+ * input is used.
+ * @add_len: Byte length of @add.
+ *
+ * @return:
+ * 0 Success.
+ * ENOMEM Out of memory.
+ * EINVAL At least one argument is invalid.
+ * ENOTSUP Prediction resistance is not supported.
+ * ICA_DRBG_HEALTH_TEST_FAIL Health test failed.
+ * ICA_DRBG_ENTROPY_SOURCE_FAIL Entropy source failed.
+ */
+ICA_EXPORT
+int ica_drbg_reseed(ica_drbg_t *sh,
+ bool pr,
+ const unsigned char *add,
+ size_t add_len);
+/*
+ * Generate function
+ * (request pseudorandom bytes from a DRBG instantiation)
+ *
+ * @sh: State Handle. Identifies the DRBG instantiation from which pseudorandom
+ * bytes are requested.
+ * @sec: requested SECurity strength: Minimum bits of security that the
+ * generated pseudorandom bytes SHALL offer.
+ * @pr: Prediciton Resistance request. Indicates whether or not prediction
+ * resistance is required.
+ * @add: ADDitional input. An optional input. NULL indicates that no additional input
+ * is used.
+ * @add_len: Byte length of @add.
+ * @prnd: PseudoRaNDom bytes.
+ * @prnd_len: Byte length of @prnd. Requested number of pseudorandom bytes.
+ *
+ * @return:
+ * 0 Success.
+ * ENOMEM Out of memory.
+ * EINVAL At least one argument is invalid.
+ * ENOTSUP Prediction resistance or the requested security
+ * strength is not supported.
+ * EPERM Reseed required.
+ * ICA_DRBG_HEALTH_TEST_FAIL Health test failed.
+ * ICA_DRBG_ENTROPY_SOURCE_FAIL Entropy source failed.
+ */
+ICA_EXPORT
+int ica_drbg_generate(ica_drbg_t *sh,
+ int sec,
+ bool pr,
+ const unsigned char *add,
+ size_t add_len,
+ unsigned char *prnd,
+ size_t prnd_len);
+
+/*
+ * Uninstantiate function
+ * (destroy an existing DRBG instiantiation)
+ *
+ * @sh: State Handle pointer. The corresponding DRBG instantiation is destroyed
+ * and the state handle is set to NULL (invalid).
+ *
+ * @return:
+ * 0 Success.
+ * EINVAL At least one argument is invalid.
+ */
+ICA_EXPORT
+int ica_drbg_uninstantiate(ica_drbg_t **sh);
+
+/*
+ * Health test function
+ * (run health test for a DRBG mechanism function)
+ *
+ * @func: FUNCtion. Pointer indicating which function should be tested. Options
+ * are "ica_drbg_instantiate", "ica_drbg_reseed" and "ica_drbg_generate". The
+ * uninstantiate function is tested whenever other functions are tested.
+ * @sec: SECurity strength. Argument for the call to @func.
+ * @pr: PRediction resistance. Argument for the call to @func.
+ * @mech: MECHanism. The mechanism to be tested.
+ *
+ * @return:
+ * 0 Success.
+ * EINVAL At least one argument is invalid.
+ * ENOTSUP Prediction resistance or security strength is
+ * not supported (when testing instantiate).
+ * ICA_DRBG_HEALTH_TEST_FAIL Health test failed.
+ * ICA_DRBG_ENTROPY_SOURCE_FAIL Entropy source failed.
+ */
+ICA_EXPORT
+int ica_drbg_health_test(void *func,
+ int sec,
+ bool pr,
+ ica_drbg_mech_t *mech);
+
+#ifdef ICA_FIPS
+/*
+ * Additional FIPS interfaces are available for built-in FIPS mode.
+ */
+
+/*
+ * FIPS status output interface.
+ *
+ * @return:
+ * Returns flags indicating the module status. See the ICA_FIPS_* flags.
+ */
+ICA_EXPORT
+int ica_fips_status(void);
+
+/*
+ * FIPS powerups tests.
+ *
+ * The test results can be viewed via the ica_fips_status function.
+ */
+ICA_EXPORT
+void ica_fips_powerup_tests(void);
+#endif /* ICA_FIPS */
+
+#endif /* __ICA_API_H__ */
diff --git a/libica.spec b/libica.spec
new file mode 100644
index 0000000..63368f2
--- /dev/null
+++ b/libica.spec
@@ -0,0 +1,100 @@
+Name: libica
+Version: 3.0.1
+Release: 1%{?dist}
+Summary: Interface library to the ICA device driver
+
+Group: Libraries/Crypto
+License: CPL
+URL: http://sourceforge.net/projects/opencryptoki
+Source0: %{name}-%{version}.tar.gz
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+
+BuildRequires: autoconf automake libtool openssl-devel
+
+%description
+Interface library on Linux for IBM System z to utilize CPACF
+functions and cryptographic processors.
+
+
+%package devel
+Summary: Interface library to the ICA device driver
+Group: Libraries/Crypto
+Requires: libica = %{version}-%{release}, glibc-devel
+
+%description devel
+Interface library on Linux for IBM System z to utilize CPACF
+functions and cryptographic processors.
+
+
+%prep
+%setup -q -n %{name}-%{version}
+
+
+%build
+autoreconf --force --install
+%configure --disable-static
+make %{?_smp_mflags}
+
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make install DESTDIR=$RPM_BUILD_ROOT
+rm -f $RPM_BUILD_ROOT/%{_libdir}/*.la
+
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%files
+%defattr(-,root,root,-)
+%doc LICENSE INSTALL AUTHORS
+%{_mandir}/man*/*
+%{_bindir}/*
+%attr(755,root,root) %{_libdir}/*
+
+%files devel
+%doc LICENSE
+%defattr(-,root,root,-)
+%{_includedir}/ica_api.h
+
+%changelog
+* Wed Nov 23 2016 Patrick Steuer <steuer@linux.vnet.ibm.com>
+- Version v3.0.1
+* Tue Oct 25 2016 Patrick Steuer <steuer@linux.vnet.ibm.com>
+- Version v3.0.0
+* Tue Mar 22 2016 Ingo Tuchscherer <ingo.tuchscherer@linux.vnet.ibm.com>
+- Version v2.6.2
+* Fri Feb 26 2016 Ingo Tuchscherer <ingo.tuchscherer@linux.vnet.ibm.com>
+- Version v2.6.1
+* Thu Feb 18 2016 Ingo Tuchscherer <ingo.tuchscherer@linux.vnet.ibm.com>
+- Version v2.6.0
+* Wed Nov 11 2015 Ingo Tuchscherer <ingo.tuchscherer@linux.vnet.ibm.com>
+- Version v2.5.0
+* Tue Jun 17 2014 Ingo Tuchscherer <ingo.tuchscherer@linux.vnet.ibm.com>
+- Version v2.4.0
+* Wed Mar 20 2013 Ingo Tuchscherer <ingo.tuchscherer@linux.vnet.ibm.com>
+- Version v2.3.0
+* Mon Feb 13 2012 Holger Dengler <hd@linux.vnet.ibm.com>
+- Version v2.2.0
+* Mon Sep 12 2011 Holger Dengler <hd@linux.vnet.ibm.com>
+- Bugfix version v2.1.1
+* Mon May 09 2011 Holger Dengler <hd@linux.vnet.ibm.com>
+- Version v2.1.0
+* Tue Mar 05 2011 Holger Dengler <hd@linux.vnet.ibm.com>
+- Bugfix version 2.0.6
+* Tue Mar 05 2011 Holger Dengler <hd@linux.vnet.ibm.com>
+- Bugfix version 2.0.5
+* Thu Sep 30 2010 Rainer Wolafka <rwolafka@de.ibm.com>
+- Bugfix version 2.0.4
+* Thu Apr 15 2010 Ruben Straus <rstraus@de.ibm.com>
+- Bugfixes version 2.0.3
+* Wed Aug 12 2009 Felix Beck <felix.beck@de.ibm.com>
+- Bugfixes version 2.0.2
+* Wed Feb 4 2009 Felix Beck <felix.beck@de.ibm.com
+- version 2.0
+* Fri Aug 4 2006 Daniel H Jones <danjones@us.ibm.com>
+- initial file created
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..428fb2f
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,18 @@
+INCLUDES = -I ./include -I ../include
+
+lib_LTLIBRARIES = libica.la
+
+libica_la_LDFLAGS = -version-number 3:0:1 $(PACKAGE_VERSION) -lrt -lcrypto
+libica_la_SOURCES = ica_api.c init.c icastats_shared.c \
+ s390_rsa.c s390_crypto.c \
+ s390_prng.c s390_sha.c s390_drbg.c s390_drbg_sha512.c \
+ test_vec.c fips.c
+
+bin_PROGRAMS = icainfo icastats
+
+icainfo_LDADD = libica.la
+icainfo_SOURCES = icainfo.c
+
+icastats_CFLAGS = $(AM_CFLAGS)
+icastats_LDFLAGS = -lrt
+icastats_SOURCES = icastats.c icastats_shared.c
diff --git a/src/fips.c b/src/fips.c
new file mode 100644
index 0000000..4b0e64f
--- /dev/null
+++ b/src/fips.c
@@ -0,0 +1,937 @@
+/*
+ * 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.
+ *
+ * Author(s): Patrick Steuer <patrick.steuer@de.ibm.com>
+ *
+ * Copyright IBM Corp. 2015
+ */
+
+#ifdef ICA_FIPS
+
+#include <errno.h>
+#include <openssl/crypto.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+
+#include <openssl/opensslconf.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif /* OPENSSL_FIPS */
+
+#include "fips.h"
+#include "ica_api.h"
+#include "test_vec.h"
+
+int fips;
+
+static int aes_ecb_kat(void);
+static int aes_cbc_kat(void);
+static int aes_cbc_cs_kat(void);
+static int aes_cfb_kat(void);
+static int aes_ofb_kat(void);
+static int aes_ctr_kat(void);
+static int aes_ccm_kat(void);
+static int aes_gcm_kat(void);
+static int aes_xts_kat(void);
+static int aes_cmac_kat(void);
+
+static int des3_ecb_kat(void);
+static int des3_cbc_kat(void);
+static int des3_cbc_cs_kat(void);
+static int des3_cfb_kat(void);
+static int des3_ofb_kat(void);
+static int des3_ctr_kat(void);
+static int des3_cmac_kat(void);
+
+static int rsa_kat(void);
+
+#define SHA_KAT(_sha_, _ctx_) \
+static int sha##_sha_##_kat(void) { \
+ sha##_ctx_##_context_t ctx; \
+ size_t i; \
+ unsigned char out[SHA##_sha_##_HASH_LENGTH]; \
+ for (i = 0; i < SHA##_sha_##_TV_LEN; i++) { \
+ if (ica_sha##_sha_(SHA_MSG_PART_ONLY, \
+ SHA##_sha_##_TV[i].msg_len, SHA##_sha_##_TV[i].msg, \
+ &ctx, out) || memcmp(SHA##_sha_##_TV[i].md, out, \
+ SHA##_sha_##_HASH_LENGTH)) { \
+ syslog(LOG_ERR, "Libica SHA-%d test failed.", \
+ _sha_); \
+ return 1; \
+ } \
+ } \
+ return 0; \
+}
+SHA_KAT(1, );
+SHA_KAT(224, 256);
+SHA_KAT(256, 256);
+SHA_KAT(384, 512);
+SHA_KAT(512, 512);
+#undef SHA_KAT
+
+void
+fips_init(void)
+{
+ FILE *fd;
+ char fips_flag;
+
+ if ((fd = fopen(FIPS_FLAG, "r")) == NULL)
+ return;
+
+ if (fread(&fips_flag, sizeof(fips_flag), 1, fd) != 1) {
+ fclose(fd);
+ return;
+ }
+ fclose(fd);
+
+ if (fips_flag - '0') {
+ /* Set libica into FIPS mode. */
+ fips |= ICA_FIPS_MODE;
+
+ /* Try to set OpenSSL into FIPS mode. If this is not possible,
+ * all software fallbacks (including RSA key generation) will
+ * be disabled. OpenSSL FIPS mode can be queried using the
+ * FIPS_mode() function. */
+ FIPS_mode_set(1);
+ }
+}
+
+void
+fips_powerup_tests(void)
+{
+ /* Cryptographic algorithm test. */
+ if (ica_drbg_health_test(ica_drbg_generate, 256, true, ICA_DRBG_SHA512)
+ || sha1_kat() || sha224_kat() || sha256_kat() || sha384_kat()
+ || sha512_kat() || des3_ecb_kat() || des3_cbc_kat()
+ || des3_cbc_cs_kat() || des3_cfb_kat() || des3_ofb_kat()
+ || des3_ctr_kat() || des3_cmac_kat() || aes_ecb_kat()
+ || aes_cbc_kat() || aes_cbc_cs_kat() || aes_cfb_kat()
+ || aes_ctr_kat() || aes_ofb_kat() || aes_ccm_kat() || aes_gcm_kat()
+ || aes_xts_kat() || aes_cmac_kat() || rsa_kat()) {
+ fips |= ICA_FIPS_CRYPTOALG;
+ return;
+ }
+}
+
+static int
+aes_ecb_kat(void) {
+ const struct aes_ecb_tv *tv;
+ size_t i;
+ unsigned char *out;
+
+ for (i = 0; i < AES_ECB_TV_LEN; i++) {
+ tv = &AES_ECB_TV[i];
+
+ out = malloc(tv->len);
+
+ if (out == NULL)
+ goto _err_;
+
+ if (ica_aes_ecb(tv->plaintext, out, tv->len, tv->key,
+ tv->keylen, ICA_ENCRYPT) || memcmp(tv->ciphertext, out,
+ tv->len) || ica_aes_ecb(tv->ciphertext, out, tv->len,
+ tv->key, tv->keylen, ICA_DECRYPT) || memcmp(tv->plaintext,
+ out, tv->len))
+ goto _err_;
+
+ free(out);
+ }
+ return 0;
+
+_err_:
+ free(out);
+ syslog(LOG_ERR, "Libica AES-ECB test failed.");
+ return 1;
+}
+
+static int
+aes_cbc_kat(void) {
+ const struct aes_cbc_tv *tv;
+ size_t i;
+ unsigned char iv[AES_BLKSIZE], *out;
+
+ for (i = 0; i < AES_CBC_TV_LEN; i++) {
+ tv = &AES_CBC_TV[i];
+
+ out = malloc(tv->len);
+
+ if (out == NULL)
+ goto _err_;
+
+ memcpy(iv, tv->iv, AES_BLKSIZE);
+ if (ica_aes_cbc(tv->plaintext, out, tv->len, tv->key,
+ tv->keylen, iv, ICA_ENCRYPT) || memcmp(tv->ciphertext, out,
+ tv->len))
+ goto _err_;
+
+ memcpy(iv, AES_CBC_TV[i].iv, AES_BLKSIZE);
+ if (ica_aes_cbc(tv->ciphertext, out, tv->len, tv->key,
+ tv->keylen, iv, ICA_DECRYPT) || memcmp(tv->plaintext, out,
+ tv->len))
+ goto _err_;
+
+ free(out);
+ }
+ return 0;
+
+_err_:
+ free(out);
+ syslog(LOG_ERR, "Libica AES-CBC test failed.");
+ return 1;
+}
+
+static int
+aes_cbc_cs_kat(void)
+{
+ const struct aes_cbc_cs_tv *tv;
+ size_t i;
+ unsigned char iv[AES_BLKSIZE], *out;
+
+ for (i = 0; i < AES_CBC_CS_TV_LEN; i++) {
+ tv = &AES_CBC_CS_TV[i];
+
+ out = malloc(tv->len);
+
+ if (out == NULL)
+ goto _err_;
+
+ memcpy(iv, tv->iv, AES_BLKSIZE);
+ if (ica_aes_cbc_cs(tv->plaintext, out, tv->len, tv->key,
+ tv->keylen, iv, ICA_ENCRYPT, tv->variant)
+ || memcmp(tv->ciphertext, out, tv->len)
+ || memcmp(tv->iv_out, iv, AES_BLKSIZE))
+ goto _err_;
+
+ memcpy(iv, AES_CBC_CS_TV[i].iv, AES_BLKSIZE);
+ if (ica_aes_cbc_cs(tv->ciphertext, out, tv->len, tv->key,
+ tv->keylen, iv, ICA_DECRYPT, tv->variant)
+ || memcmp(tv->plaintext, out, tv->len))
+ goto _err_;
+
+ free(out);
+ }
+ return 0;
+
+_err_:
+ free(out);
+ syslog(LOG_ERR, "Libica AES-CBC-CS test failed.");
+ return 1;
+}
+
+static int
+aes_cfb_kat(void) {
+ const struct aes_cfb_tv *tv;
+ size_t i;
+ unsigned char iv[AES_BLKSIZE], *out;
+
+ for (i = 0; i < AES_CFB_TV_LEN; i++) {
+ tv = &AES_CFB_TV[i];
+
+ out = malloc(tv->len);
+
+ if (out == NULL)
+ goto _err_;
+
+ memcpy(iv, tv->iv, AES_BLKSIZE);
+ if (ica_aes_cfb(tv->plaintext, out, tv->len, tv->key,
+ tv->keylen, iv, tv->lcfb, ICA_ENCRYPT)
+ || memcmp(tv->ciphertext, out, tv->len))
+ goto _err_;
+
+ memcpy(iv, tv->iv, AES_BLKSIZE);
+ if (ica_aes_cfb(tv->ciphertext, out, tv->len, tv->key,
+ tv->keylen, iv, tv->lcfb, ICA_DECRYPT)
+ || memcmp(tv->plaintext, out, tv->len))
+ goto _err_;
+
+ free(out);
+ }
+ return 0;
+
+_err_:
+ free(out);
+ syslog(LOG_ERR, "Libica AES-CFB test failed.");
+ return 1;
+}
+
+static int
+aes_ofb_kat(void) {
+ const struct aes_ofb_tv *tv;
+ size_t i;
+ unsigned char iv[AES_BLKSIZE], *out;
+
+ for (i = 0; i < AES_OFB_TV_LEN; i++) {
+ tv = &AES_OFB_TV[i];
+
+ out = malloc(tv->len);
+
+ if (out == NULL)
+ goto _err_;
+
+ memcpy(iv, tv->iv, AES_BLKSIZE);
+ if (ica_aes_ofb(tv->plaintext, out, tv->len, tv->key,
+ tv->keylen, iv, ICA_ENCRYPT) || memcmp(tv->ciphertext, out,
+ tv->len))
+ goto _err_;
+
+ memcpy(iv, tv->iv, AES_BLKSIZE);
+ if (ica_aes_ofb(tv->ciphertext, out, tv->len, tv->key,
+ tv->keylen, iv, ICA_DECRYPT) || memcmp(tv->plaintext, out,
+ tv->len))
+ goto _err_;
+
+ free(out);
+ }
+ return 0;
+
+_err_:
+ free(out);
+ syslog(LOG_ERR, "Libica AES-OFB test failed.");
+ return 1;
+}
+
+static int
+aes_ctr_kat(void) {
+ const struct aes_ctr_tv *tv;
+ size_t i;
+ unsigned char *out, ctr[AES_BLKSIZE];
+
+ for (i = 0; i < AES_CTR_TV_LEN; i++) {
+ tv = &AES_CTR_TV[i];
+
+ out = malloc(tv->len);
+
+ if (out == NULL)
+ goto _err_;
+
+ memcpy(ctr, tv->ctr, AES_BLKSIZE);
+ if (ica_aes_ctr(tv->plaintext, out, tv->len, tv->key,
+ tv->keylen, ctr, 32, ICA_ENCRYPT) || memcmp(tv->ciphertext,
+ out, tv->len))
+ goto _err_;
+
+ memcpy(ctr, tv->ctr, AES_BLKSIZE);
+ if (ica_aes_ctr(tv->ciphertext, out, tv->len, tv->key,
+ tv->keylen, ctr, 32, ICA_DECRYPT) || memcmp(tv->plaintext,
+ out, tv->len))
+ goto _err_;
+
+ free(out);
+ }
+ return 0;
+
+_err_:
+ free(out);
+ syslog(LOG_ERR, "Libica AES-CTR test failed.");
+ return 1;
+}
+
+static int
+aes_ccm_kat(void) {
+ const struct aes_ccm_tv *tv;
+ size_t i;
+ unsigned char *ciphertext, *payload;
+
+ for (i = 0; i < AES_CCM_TV_LEN; i++) {
+ tv = &AES_CCM_TV[i];
+
+ ciphertext = malloc(tv->payloadlen + tv->taglen);
+ payload = malloc(tv->payloadlen);
+
+ if (payload == NULL || ciphertext == NULL)
+ goto _err_;
+
+ if (ica_aes_ccm(payload, tv->payloadlen, tv->ciphertext,
+ tv->taglen, tv->adata, tv->adatalen, tv->nonce,
+ tv->noncelen, tv->key, tv->keylen, ICA_DECRYPT)
+ != tv->rv)
+ goto _err_;
+
+ if ((tv->rv == 0) && (memcmp(tv->payload, payload,
+ tv->payloadlen) || ica_aes_ccm(tv->payload, tv->payloadlen,
+ ciphertext, tv->taglen, tv->adata, tv->adatalen, tv->nonce,
+ tv->noncelen, tv->key, tv->keylen, ICA_ENCRYPT)
+ || memcmp(tv->ciphertext, ciphertext, tv->payloadlen
+ + tv->taglen)))
+ goto _err_;
+
+ free(payload);
+ free(ciphertext);
+ }
+ return 0;
+
+_err_:
+ free(ciphertext);
+ free(payload);
+ syslog(LOG_ERR, "Libica AES-CCM test failed.");
+ return 1;
+}
+
+static int
+aes_gcm_kat(void) {
+ const struct aes_gcm_tv *tv;
+ size_t i, lastlen;
+ unsigned char *out, *tag, icb[AES_BLKSIZE], ucb[AES_BLKSIZE],
+ subkey[AES_BLKSIZE];
+
+ for (i = 0; i < AES_GCM_TV_LEN; i++) {
+ tv = &AES_GCM_TV[i];
+
+ out = malloc(tv->len);
+ tag = malloc(tv->taglen);
+
+ if (tag == NULL || out == NULL)
+ goto _err_;
+
+ if ((ica_aes_gcm(out, tv->len, tv->ciphertext, tv->iv,
+ tv->ivlen, tv->aad, tv->aadlen, tv->tag, tv->taglen,
+ tv->key, tv->keylen, ICA_DECRYPT) != tv->rv)
+ || ((tv->rv == 0)
+ && memcmp(tv->plaintext, out, tv->len)))
+ goto _err_;
+
+ if ((tv->rv == 0) && (ica_aes_gcm(tv->plaintext, tv->len,
+ out, tv->iv, tv->ivlen, tv->aad, tv->aadlen, tag,
+ tv->taglen, tv->key, tv->keylen, ICA_ENCRYPT)
+ || memcmp(tv->tag, tag, tv->taglen)
+ || memcmp(tv->ciphertext, out, tv->len)))
+ goto _err_;
+
+ free(tag);
+ free(out);
+ }
+
+ for (i = 0; i < AES_GCM_TV_LEN; i++) {
+ tv = &AES_GCM_TV[i];
+
+ /* Divide the test vector into two chunks. */
+ if (tv->len <= AES_BLKSIZE)
+ lastlen = 0;
+ else {
+ lastlen = tv->len % AES_BLKSIZE;
+ /* Last chunk can only be 16 bytes long, if test
+ * vector is at least 32 bytes long. */
+ if (lastlen == 0 && tv->len >= 2 * AES_BLKSIZE)
+ lastlen = AES_BLKSIZE;
+ }
+
+ out = malloc(tv->len);
+ tag = malloc(AES_BLKSIZE);
+
+ if (tag == NULL || out == NULL)
+ goto _err_;
+
+ memset(tag, 0, AES_BLKSIZE);
+ if (ica_aes_gcm_initialize(tv->iv, tv->ivlen, tv->key,
+ tv->keylen, icb, ucb, subkey, ICA_DECRYPT)
+ || ica_aes_gcm_intermediate(out, tv->len - lastlen,
+ tv->ciphertext, ucb, tv->aad, tv->aadlen, tag,
+ tv->taglen, tv->key, tv->keylen, subkey, ICA_DECRYPT)
+ || ica_aes_gcm_intermediate(out + (tv->len - lastlen),
+ lastlen, tv->ciphertext + (tv->len - lastlen), ucb,
+ NULL, 0, tag, tv->taglen, tv->key, tv->keylen,
+ subkey, ICA_DECRYPT) || (ica_aes_gcm_last(icb, tv->aadlen,
+ tv->len, tag, tv->tag, tv->taglen, tv->key, tv->keylen,
+ subkey, ICA_DECRYPT) != tv->rv) || ((tv->rv == 0)
+ && memcmp(tv->plaintext, out, tv->len)))
+ goto _err_;
+
+ memset(tag, 0, AES_BLKSIZE);
+ memset(out, 0, AES_BLKSIZE);
+ memset(icb, 0, sizeof(icb));
+ memset(icb, 0, sizeof(ucb));
+ memset(subkey, 0, sizeof(subkey));
+ if ((tv->rv == 0) && (ica_aes_gcm_initialize(tv->iv, tv->ivlen,
+ tv->key, tv->keylen, icb, ucb, subkey, ICA_ENCRYPT)
+ || ica_aes_gcm_intermediate(tv->plaintext,
+ tv->len - lastlen, out, ucb, tv->aad, tv->aadlen, tag,
+ tv->taglen, tv->key, tv->keylen, subkey, ICA_ENCRYPT)
+ || ica_aes_gcm_intermediate(tv->plaintext
+ + (tv->len - lastlen), lastlen, out + (tv->len - lastlen),
+ ucb, NULL, 0, tag, tv->taglen, tv->key, tv->keylen, subkey,
+ ICA_ENCRYPT) || ica_aes_gcm_last(icb, tv->aadlen, tv->len,
+ tag, NULL, tv->taglen, tv->key, tv->keylen, subkey,
+ ICA_ENCRYPT) || memcmp(tv->ciphertext, out, tv->len)
+ || memcmp(tv->tag, tag, tv->taglen)))
+ goto _err_;
+
+ free(tag);
+ free(out);
+ }
+ return 0;
+
+_err_:
+ free(tag);
+ free(out);
+ syslog(LOG_ERR, "Libica AES-GCM test failed.");
+ return 1;
+}
+
+static int
+aes_xts_kat(void) {
+ const struct aes_xts_tv *tv;
+ size_t i;
+ unsigned char *out, tweak[16];
+
+ for (i = 0; i < AES_XTS_TV_LEN; i++) {
+ tv = &AES_XTS_TV[i];
+
+ out = malloc(tv->len);
+
+ if (out == NULL)
+ goto _err_;
+
+ memcpy(tweak, tv->tweak, sizeof(tweak));
+ if (ica_aes_xts(tv->plaintext, out, tv->len, tv->key1,
+ tv->key2, tv->keylen, tweak, ICA_ENCRYPT)
+ || memcmp(tv->ciphertext, out, tv->len))
+ goto _err_;
+
+ memcpy(tweak, tv->tweak, sizeof(tweak));
+ if (ica_aes_xts(tv->ciphertext, out, tv->len, tv->key1,
+ tv->key2, tv->keylen, tweak, ICA_DECRYPT)
+ || memcmp(tv->plaintext, out, tv->len))
+ goto _err_;
+
+ free(out);
+ }
+ return 0;
+
+_err_:
+ free(out);
+ syslog(LOG_ERR, "Libica AES-XTS test failed.");
+ return 1;
+}
+
+static int
+aes_cmac_kat(void)
+{
+ const struct aes_cmac_tv *tv;
+ size_t i, lastlen;
+ unsigned char *mac, iv[AES_BLKSIZE];
+
+ for (i = 0; i < AES_CMAC_TV_LEN; i++) {
+ tv = &AES_CMAC_TV[i];
+
+ mac = malloc(tv->maclen);
+
+ if (mac == NULL)
+ goto _err_;
+
+ if ((ica_aes_cmac(tv->msg, tv->msglen, tv->mac, tv->maclen,
+ tv->key, tv->keylen, ICA_DECRYPT) != tv->rv)
+ || ((tv->rv == 0) && (ica_aes_cmac(tv->msg, tv->msglen,
+ mac, tv->maclen, tv->key, tv->keylen, ICA_ENCRYPT)
+ || memcmp(tv->mac, mac, tv->maclen))))
+ goto _err_;
+
+ free(mac);
+ }
+
+ for (i = 0; i < AES_CMAC_TV_LEN; i++) {
+ tv = &AES_CMAC_TV[i];
+
+ if (tv->msglen <= AES_BLKSIZE)
+ continue;
+
+ lastlen = tv->msglen % AES_BLKSIZE ? tv->msglen % AES_BLKSIZE
+ : AES_BLKSIZE;
+ memset(iv, 0, AES_BLKSIZE);
+
+ if (ica_aes_cmac_intermediate(tv->msg, tv->msglen - lastlen,
+ tv->key, tv->keylen, iv) || (ica_aes_cmac_last(tv->msg
+ + (tv->msglen - lastlen), lastlen, tv->mac, tv->maclen,
+ tv->key, tv->keylen, iv, ICA_DECRYPT) != tv->rv))
+ return 1;
+
+ if (tv->rv != 0)
+ continue;
+
+ mac = malloc(tv->maclen);
+
+ if (mac == NULL)
+ goto _err_;
+
+ memset(iv, 0, AES_BLKSIZE);
+ if (ica_aes_cmac_intermediate(tv->msg, tv->msglen - lastlen,
+ tv->key, tv->keylen, iv) || ica_aes_cmac_last(tv->msg
+ + (tv->msglen - lastlen), lastlen, mac, tv->maclen,
+ tv->key, tv->keylen, iv, ICA_ENCRYPT) || memcmp(tv->mac,
+ mac, tv->maclen))
+ goto _err_;
+
+ free(mac);
+ }
+ return 0;
+
+_err_:
+ free(mac);
+ syslog(LOG_ERR, "Libica AES-CMAC test failed.");
+ return 1;
+}
+
+static int
+des3_ecb_kat(void) {
+ const struct des3_ecb_tv *tv;
+ size_t i;
+ unsigned char *out;
+
+ for (i = 0; i < DES3_ECB_TV_LEN; i++) {
+ tv = &DES3_ECB_TV[i];
+
+ out = malloc(tv->len);
+
+ if (out == NULL)
+ goto _err_;
+
+ if (ica_3des_ecb(tv->plaintext, out, tv->len,
+ (unsigned char *)tv->key, ICA_ENCRYPT)
+ || memcmp(tv->ciphertext, out, tv->len)
+ || ica_3des_ecb(tv->ciphertext, out, tv->len,
+ (unsigned char *)tv->key, ICA_DECRYPT)
+ || memcmp(tv->plaintext, out, tv->len))
+ goto _err_;
+
+ free(out);
+ }
+ return 0;
+
+_err_:
+ free(out);
+ syslog(LOG_ERR, "Libica 3DES-ECB test failed.");
+ return 1;
+}
+
+static int
+des3_cbc_kat(void) {
+ const struct des3_cbc_tv *tv;
+ size_t i;
+ unsigned char iv[DES3_BLKSIZE], *out;
+
+ for (i = 0; i < DES3_CBC_TV_LEN; i++) {
+ tv = &DES3_CBC_TV[i];
+
+ out = malloc(tv->len);
+
+ if (out == NULL)
+ goto _err_;
+
+ memcpy(iv, tv->iv, DES3_BLKSIZE);
+ if (ica_3des_cbc(tv->plaintext, out, tv->len,
+ (unsigned char *)tv->key, iv, ICA_ENCRYPT)
+ || memcmp(tv->ciphertext, out, tv->len))
+ goto _err_;
+
+ memcpy(iv, tv->iv, DES3_BLKSIZE);
+ if (ica_3des_cbc(tv->ciphertext, out, tv->len,
+ (unsigned char *)tv->key, iv, ICA_DECRYPT)
+ || memcmp(tv->plaintext, out, tv->len))
+ goto _err_;
+
+ free(out);
+ }
+ return 0;
+
+_err_:
+ free(out);
+ syslog(LOG_ERR, "Libica 3DES-CBC test failed.");
+ return 1;
+}
+
+static int
+des3_cbc_cs_kat(void){
+ const struct des3_cbc_cs_tv *tv;
+ size_t i;
+ unsigned char iv[DES3_BLKSIZE], *out;
+
+ for (i = 0; i < DES3_CBC_CS_TV_LEN; i++) {
+ tv = &DES3_CBC_CS_TV[i];
+
+ out = malloc(tv->len);
+
+ if (out == NULL)
+ goto _err_;
+
+ memcpy(iv, tv->iv, DES3_BLKSIZE);
+ if (ica_3des_cbc_cs(tv->plaintext, out, tv->len,
+ (unsigned char *)tv->key, iv, ICA_ENCRYPT, tv->variant)
+ || memcmp(tv->ciphertext, out, tv->len))
+ goto _err_;
+
+ memcpy(iv, tv->iv, DES3_BLKSIZE);
+ if (ica_3des_cbc_cs(tv->ciphertext, out, tv->len,
+ (unsigned char *)tv->key, iv,
+ ICA_DECRYPT, tv->variant)
+ || memcmp(tv->plaintext, out, tv->len))
+ goto _err_;
+
+ free(out);
+ }
+ return 0;
+
+_err_:
+ free(out);
+ syslog(LOG_ERR, "Libica 3DES-CBC-CS test failed.");
+ return 1;
+}
+
+static int
+des3_cfb_kat(void) {
+ const struct des3_cfb_tv *tv;
+ size_t i;
+ unsigned char iv[DES3_BLKSIZE], *out;
+
+ for (i = 0; i < DES3_CFB_TV_LEN; i++) {
+ tv = &DES3_CFB_TV[i];
+
+ out = malloc(tv->len);
+
+ if (out == NULL)
+ goto _err_;
+
+ memcpy(iv, tv->iv, DES3_BLKSIZE);
+ if (ica_3des_cfb(tv->plaintext, out, tv->len,
+ (unsigned char *)tv->key, iv, tv->lcfb, ICA_ENCRYPT)
+ || memcmp(tv->ciphertext, out, tv->len))
+ goto _err_;
+
+ memcpy(iv, tv->iv, DES3_BLKSIZE);
+ if (ica_3des_cfb(tv->ciphertext, out, tv->len,
+ (unsigned char *)tv->key, iv, tv->lcfb, ICA_DECRYPT)
+ || memcmp(tv->plaintext, out, tv->len))
+ goto _err_;
+
+ free(out);
+ }
+ return 0;
+
+_err_:
+ free(out);
+ syslog(LOG_ERR, "Libica 3DES-CFB test failed.");
+ return 1;
+}
+
+static int
+des3_ofb_kat(void) {
+ const struct des3_ofb_tv *tv;
+ size_t i;
+ unsigned char iv[DES3_BLKSIZE], *out;
+
+ for (i = 0; i < DES3_OFB_TV_LEN; i++) {
+ tv = &DES3_OFB_TV[i];
+
+ out = malloc(tv->len);
+
+ if (out == NULL)
+ goto _err_;
+
+ memcpy(iv, tv->iv, DES3_BLKSIZE);
+ if (ica_3des_ofb(tv->plaintext, out, tv->len,
+ (unsigned char *)tv->key, iv, ICA_ENCRYPT)
+ || memcmp(tv->ciphertext, out, tv->len))
+ goto _err_;
+
+ memcpy(iv, tv->iv, DES3_BLKSIZE);
+ if (ica_3des_ofb(tv->ciphertext, out, tv->len,
+ (unsigned char *)tv->key, iv, ICA_DECRYPT)
+ || memcmp(tv->plaintext, out, tv->len))
+ goto _err_;
+
+ free(out);
+ }
+ return 0;
+
+_err_:
+ free(out);
+ syslog(LOG_ERR, "Libica 3DES-OFB test failed.");
+ return 1;
+}
+
+static int
+des3_ctr_kat(void) {
+ const struct des3_ctr_tv *tv;
+ size_t i;
+ unsigned char *out, ctr[DES3_BLKSIZE];
+
+ for (i = 0; i < DES3_CTR_TV_LEN; i++) {
+ tv = &DES3_CTR_TV[i];
+
+ out = malloc(tv->len);
+
+ if (out == NULL)
+ goto _err_;
+
+ memcpy(ctr, tv->ctr, DES3_BLKSIZE);
+ if (ica_3des_ctr(tv->plaintext, out, tv->len,
+ (unsigned char *)tv->key, ctr, 32, ICA_ENCRYPT)
+ || memcmp(tv->ciphertext, out, tv->len))
+ goto _err_;
+
+ memcpy(ctr, tv->ctr, DES3_BLKSIZE);
+ if (ica_3des_ctr(tv->ciphertext, out, tv->len,
+ (unsigned char *)tv->key, ctr, 32, ICA_DECRYPT)
+ || memcmp(tv->plaintext, out, tv->len))
+ goto _err_;
+
+ free(out);
+ }
+ return 0;
+
+_err_:
+ free(out);
+ syslog(LOG_ERR, "Libica 3DES-CTR test failed.");
+ return 1;
+}
+
+static int
+des3_cmac_kat(void)
+{
+ const struct des3_cmac_tv *tv;
+ size_t i, lastlen;
+ unsigned char *mac, iv[DES3_BLKSIZE];
+
+ for (i = 0; i < DES3_CMAC_TV_LEN; i++) {
+ tv = &DES3_CMAC_TV[i];
+
+ mac = malloc(tv->maclen);
+
+ if (mac == NULL)
+ goto _err_;
+
+ if ((ica_3des_cmac(tv->msg, tv->msglen, tv->mac, tv->maclen,
+ (unsigned char *)tv->key, ICA_DECRYPT) != tv->rv)
+ || ((tv->rv == 0) && (ica_3des_cmac(tv->msg, tv->msglen,
+ mac, tv->maclen, (unsigned char *)tv->key, ICA_ENCRYPT)
+ || memcmp(tv->mac, mac, tv->maclen))))
+ goto _err_;
+
+ free(mac);
+ }
+ for (i = 0; i < DES3_CMAC_TV_LEN; i++) {
+ tv = &DES3_CMAC_TV[i];
+
+ if (tv->msglen <= DES3_BLKSIZE)
+ continue;
+
+ lastlen = tv->msglen % DES3_BLKSIZE ? tv->msglen % DES3_BLKSIZE
+ : DES3_BLKSIZE;
+ memset(iv, 0, DES3_BLKSIZE);
+
+ if (ica_3des_cmac_intermediate(tv->msg, tv->msglen - lastlen,
+ (unsigned char *)tv->key, iv)
+ || (ica_3des_cmac_last(tv->msg + (tv->msglen - lastlen),
+ lastlen, tv->mac, tv->maclen, (unsigned char *)tv->key, iv,
+ ICA_DECRYPT) != tv->rv))
+ return 1;
+
+ if (tv->rv != 0)
+ continue;
+
+ mac = malloc(tv->maclen);
+
+ if (mac == NULL)
+ goto _err_;
+
+ memset(iv, 0, DES3_BLKSIZE);
+ if (ica_3des_cmac_intermediate(tv->msg, tv->msglen - lastlen,
+ (unsigned char *)tv->key, iv)
+ || ica_3des_cmac_last(tv->msg + (tv->msglen - lastlen),
+ lastlen, mac, tv->maclen, (unsigned char *)tv->key, iv,
+ ICA_ENCRYPT) || memcmp(tv->mac, mac, tv->maclen))
+ goto _err_;
+
+ free(mac);
+ }
+ return 0;
+
+_err_:
+ free(mac);
+ syslog(LOG_ERR, "Libica 3DES-CMAC test failed.");
+ return 1;
+}
+
+static int
+rsa_kat(void)
+{
+ ica_rsa_key_mod_expo_t pubkey;
+ ica_rsa_key_crt_t privkey;
+ ica_adapter_handle_t ah;
+ const struct rsa_tv *tv;
+ size_t i, keylen, crtparamlen;
+ unsigned char *out;
+
+ if (ica_open_adapter(&ah))
+ return 1;
+
+ for (i = 0; i < RSA_TV_LEN; i++) {
+ tv = &RSA_TV[i];
+
+ keylen = (tv->mod + 7) / 8;
+ crtparamlen = (keylen + 1) / 2;
+
+ pubkey.key_length = keylen;
+ privkey.key_length = keylen;
+
+ out = malloc(keylen);
+ pubkey.exponent = malloc(keylen);
+ pubkey.modulus = malloc(keylen);
+ privkey.q = malloc(crtparamlen);
+ privkey.dq = malloc(crtparamlen);
+ /* Some values have 8 bytes of zero padding. */
+ privkey.p = malloc(crtparamlen + 8);
+ privkey.dp = malloc(crtparamlen + 8);
+ privkey.qInverse = malloc(crtparamlen + 8);
+
+ if (privkey.qInverse == NULL || privkey.dq == NULL
+ || privkey.dp == NULL || privkey.q == NULL
+ || privkey.p == NULL || pubkey.modulus == NULL
+ || pubkey.exponent == NULL || out == NULL)
+ goto _err_;
+
+ memcpy(pubkey.exponent, tv->e, keylen);
+ memcpy(pubkey.modulus, tv->n, keylen);
+ memcpy(privkey.q, tv->q, crtparamlen);
+ memcpy(privkey.dq, tv->dq, crtparamlen);
+ memcpy(privkey.p, tv->p, crtparamlen + 8);
+ memcpy(privkey.dp, tv->dp, crtparamlen + 8);
+ memcpy(privkey.qInverse, tv->qinv, crtparamlen + 8);
+
+ if (ica_rsa_mod_expo(ah, tv->plaintext, &pubkey, out)
+ || memcmp(tv->ciphertext, out, keylen)
+ || ica_rsa_crt(ah, tv->ciphertext, &privkey, out)
+ || memcmp(tv->plaintext, out, keylen))
+ goto _err_;
+
+ free(out);
+ free(pubkey.exponent);
+ free(pubkey.modulus);
+ free(privkey.p);
+ free(privkey.q);
+ free(privkey.dp);
+ free(privkey.dq);
+ free(privkey.qInverse);
+ }
+ ica_close_adapter(ah);
+ return 0;
+
+_err_:
+ ica_close_adapter(ah);
+ free(out);
+ free(pubkey.exponent);
+ free(pubkey.modulus);
+ free(privkey.p);
+ free(privkey.q);
+ free(privkey.dp);
+ free(privkey.dq);
+ free(privkey.qInverse);
+ syslog(LOG_ERR, "Libica RSA test failed.");
+ return 1;
+}
+
+#endif /* FIPS_H */
diff --git a/src/ica_api.c b/src/ica_api.c
new file mode 100644
index 0000000..f0c5995
--- /dev/null
+++ b/src/ica_api.c
@@ -0,0 +1,2147 @@
+/* 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.
+ */
+
+/**
+ * Authors: Felix Beck <felix.beck@de.ibm.com>
+ * Christian Maaser <cmaaser@de.ibm.com>
+ * Rainer Wolafka <rwolafka@de.ibm.com>
+ * Holger Dengler <hd@linux.vnet.ibm.com>
+ * Ingo Tuchscherer <ingo.tuchscherer@linux.vnet.ibm.com>
+ *
+ * Copyright IBM Corp. 2009, 2010, 2011, 2013
+ */
+
+#define __USE_GNU
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <stdint.h>
+#include <linux/types.h>
+#include <stdbool.h>
+
+#include "ica_api.h"
+#include "icastats.h"
+#include "fips.h"
+#include "s390_rsa.h"
+#include "s390_crypto.h"
+#include "s390_sha.h"
+#include "s390_prng.h"
+#include "s390_des.h"
+#include "s390_aes.h"
+#include "s390_cmac.h"
+#include "s390_cbccs.h"
+#include "s390_ccm.h"
+#include "s390_gcm.h"
+#include "s390_drbg.h"
+
+#define DEFAULT_CRYPT_DEVICE "/udev/z90crypt"
+#define DEFAULT2_CRYPT_DEVICE "/dev/z90crypt"
+#define DEFAULT3_CRYPT_DEVICE "/dev/zcrypt"
+
+#define MAX_VERSION_LENGTH 16
+
+static unsigned int check_des_parms(unsigned int mode,
+ unsigned long data_length,
+ const unsigned char *in_data,
+ const unsigned char *iv,
+ const unsigned char *des_key,
+ const unsigned char *out_data)
+{
+ if ((in_data == NULL) ||
+ (out_data == NULL) ||
+ (des_key == NULL))
+ return EINVAL;
+
+ switch (mode) {
+ case MODE_ECB:
+ if (data_length & 0x07)
+ return EINVAL;
+ break;
+ case MODE_CBC:
+ if (iv == NULL)
+ return EINVAL;
+ if (data_length & 0x07)
+ return EINVAL;
+ break;
+ case MODE_CBCCS:
+ if (iv == NULL)
+ return EINVAL;
+ if (data_length <= DES_BLOCK_SIZE)
+ return EINVAL;
+ break;
+ case MODE_CFB:
+ if (iv == NULL)
+ return EINVAL;
+ break;
+ case MODE_CTR:
+ if (iv == NULL)
+ return EINVAL;
+ break;
+ case MODE_OFB:
+ if (iv == NULL)
+ return EINVAL;
+ break;
+ default:
+ /* unsupported mode */
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+static unsigned int check_aes_parms(unsigned int mode,
+ unsigned int data_length,
+ const unsigned char *in_data,
+ const unsigned char *iv,
+ unsigned int key_length,
+ const unsigned char *aes_key,
+ const unsigned char *out_data)
+{
+ if ((in_data == NULL) ||
+ (out_data == NULL) ||
+ (aes_key == NULL))
+ return EINVAL;
+
+ if ((key_length != AES_KEY_LEN128) &&
+ (key_length != AES_KEY_LEN192) &&
+ (key_length != AES_KEY_LEN256))
+ return EINVAL;
+
+ switch (mode) {
+ case MODE_ECB:
+ if (data_length & 0x0F)
+ return EINVAL;
+ break;
+ case MODE_CBC:
+ if (iv == NULL)
+ return EINVAL;
+ if (data_length & 0x0F)
+ return EINVAL;
+ break;
+ case MODE_CBCCS:
+ if (iv == NULL)
+ return EINVAL;
+ if (data_length <= AES_BLOCK_SIZE)
+ return EINVAL;
+ break;
+ case MODE_CFB:
+ if (iv == NULL)
+ return EINVAL;
+ break;
+ case MODE_CTR:
+ if (iv == NULL)
+ return EINVAL;
+ break;
+ case MODE_OFB:
+ if (iv == NULL)
+ return EINVAL;
+ break;
+ case MODE_XTS:
+ if (iv == NULL)
+ return EINVAL;
+ if (key_length == AES_KEY_LEN192)
+ return EINVAL;
+ if (data_length < AES_BLOCK_SIZE)
+ return EINVAL;
+ break;
+ case MODE_CCM:
+ case MODE_GCM:
+ if (iv == NULL)
+ return EINVAL;
+ break;
+ default:
+ /* unsupported mode */
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+static unsigned int check_cmac_parms(unsigned int block_size,
+ const unsigned char *message, unsigned int message_length,
+ unsigned char *mac, unsigned int mac_length,
+ unsigned char *keys, unsigned int key_length,
+ unsigned char *iv)
+{
+
+ if (keys == NULL)
+ return EINVAL;
+
+ if (mac == NULL) { /* intermediate */
+ if (iv == NULL)
+ return EINVAL;
+
+ if (message_length % block_size)
+ return EINVAL;
+ }
+
+ if ((mac_length == 0) ||
+ (mac_length > block_size))
+ return EINVAL;
+
+ if ((message_length != 0) &&
+ (message == NULL))
+ return EINVAL;
+
+ switch (block_size) {
+ case DES_BLOCK_SIZE:
+ break;
+ case AES_BLOCK_SIZE:
+ if ((key_length != AES_KEY_LEN128) &&
+ (key_length != AES_KEY_LEN192) &&
+ (key_length != AES_KEY_LEN256))
+ return EINVAL;
+ break;
+ default:
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+static unsigned int check_gcm_parms(unsigned long text_length,
+ const unsigned char *aad,
+ unsigned long aad_length,
+ const unsigned char *tag, unsigned int tag_length,
+ unsigned int iv_length)
+{
+ if ((text_length > S390_GCM_MAX_TEXT_LENGTH) ||
+ (aad_length > S390_GCM_MAX_AAD_LENGTH) ||
+ (iv_length > S390_GCM_MAX_IV_LENGTH) ||
+ (iv_length == 0))
+ return EINVAL;
+
+ if (tag == NULL)
+ return EINVAL;
+
+ switch (tag_length) {
+ case 4:
+ case 8:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ case 16:
+ break;
+ default:
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+static unsigned int check_ccm_parms(unsigned long payload_length,
+ const unsigned char *assoc_data,
+ unsigned long assoc_data_length,
+ const unsigned char *mac,
+ unsigned int mac_length,
+ unsigned int nonce_length)
+{
+ if ((payload_length == 0) && (assoc_data_length == 0))
+ return EINVAL;
+
+ if ((nonce_length > S390_CCM_MAX_NONCE_LENGTH) ||
+ (nonce_length < S390_CCM_MIN_NONCE_LENGTH))
+ return EINVAL;
+
+ /* if nonce_length is equal S390_CCM_MIN_NONCE_LENGTH, payload_length
+ * is only limited by the value range of its data type unsigned long
+ * and need no further checking */
+ if ((nonce_length > S390_CCM_MIN_NONCE_LENGTH) &&
+ (payload_length > ((1ull << (8*(15-nonce_length))))))
+ return EINVAL;
+
+ if (mac == NULL)
+ return EINVAL;
+
+ if ((mac_length > S390_CCM_MAX_MAC_LENGTH) ||
+ (mac_length < S390_CCM_MIN_MAC_LENGTH) ||
+ (mac_length % 2))
+ return EINVAL;
+
+ return 0;
+}
+
+static unsigned int check_message_part(unsigned int message_part)
+{
+ if (message_part != SHA_MSG_PART_ONLY &&
+ message_part != SHA_MSG_PART_FIRST &&
+ message_part != SHA_MSG_PART_MIDDLE &&
+ message_part != SHA_MSG_PART_FINAL)
+ return EINVAL;
+ else
+ return 0;
+}
+
+unsigned int ica_open_adapter(ica_adapter_handle_t *adapter_handle)
+{
+ char *name, status_mask[64];
+
+ if (!adapter_handle)
+ return EINVAL;
+
+ *adapter_handle = DRIVER_NOT_LOADED;
+ name = getenv("LIBICA_CRYPT_DEVICE");
+ if (name)
+ *adapter_handle = open(name, O_RDWR);
+ else {
+ *adapter_handle = open(DEFAULT_CRYPT_DEVICE, O_RDWR);
+ if (*adapter_handle == -1)
+ *adapter_handle = open(DEFAULT2_CRYPT_DEVICE, O_RDWR);
+ if (*adapter_handle == -1)
+ *adapter_handle = open(DEFAULT3_CRYPT_DEVICE, O_RDWR);
+ }
+ if (*adapter_handle != -1) {
+ /* Test if character device is accessible. */
+ if (!ioctl(*adapter_handle, Z90STAT_STATUS_MASK, &status_mask)) {
+ return 0;
+ }
+ }
+
+ /*
+ * Do not fail if crypto device driver is not loaded and CPACF is not
+ * available as the software fallback will still work without an adapter
+ * handle.
+ */
+ return 0;
+}
+
+unsigned int ica_close_adapter(ica_adapter_handle_t adapter_handle)
+{
+ if (adapter_handle == DRIVER_NOT_LOADED)
+ return 0;
+ if (close(adapter_handle))
+ return errno;
+
+ return 0;
+}
+
+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)
+{
+ int rc;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ /* check for obvious errors in parms */
+ if ((input_data == NULL) ||
+ (sha_context == NULL) ||
+ (output_data == NULL))
+ return EINVAL;
+
+ /* make sure some message part is specified */
+ rc = check_message_part(message_part);
+ if (rc)
+ return rc;
+
+ /* check for maximum and minimum input data length */
+ /* if this is the first or middle part, the input */
+ /* data length must be a multiple of 64 bytes */
+ if ((input_length & 0x3f) &&
+ ((message_part == SHA_MSG_PART_FIRST) ||
+ (message_part == SHA_MSG_PART_MIDDLE)))
+ return EINVAL;
+
+ /*
+ * If this is the middle or final part, the running
+ * length should not be zero
+ */
+ rc = s390_sha1((unsigned char *) &sha_context->shaHash,
+ input_data, input_length, output_data, message_part,
+ (uint64_t *) &sha_context->runningLength);
+
+ if (!rc)
+ memcpy(&sha_context->shaHash, output_data, SHA_HASH_LENGTH);
+
+ return rc;
+}
+
+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)
+{
+ unsigned int rc;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ /* check for obvious errors in parms */
+ if ((input_data == NULL) ||
+ (sha256_context == NULL) ||
+ (output_data == NULL))
+ return EINVAL;
+
+ /* make sure some message part is specified */
+ rc = check_message_part(message_part);
+ if (rc)
+ return rc;
+
+ /*
+ * for FIRST or MIDDLE calls the input
+ * data length must be a multiple of 64 bytes.
+ */
+ if (input_length & 0x3f &&
+ (message_part == SHA_MSG_PART_FIRST ||
+ message_part == SHA_MSG_PART_MIDDLE))
+ return EINVAL;
+
+ return s390_sha224((unsigned char *) &sha256_context->sha256Hash,
+ input_data, input_length, output_data, message_part,
+ (uint64_t *)&sha256_context->runningLength);
+}
+
+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)
+{
+ unsigned int rc;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ /* check for obvious errors in parms */
+ if ((input_data == NULL) ||
+ (sha256_context == NULL) ||
+ (output_data == NULL))
+ return EINVAL;
+
+ /* make sure some message part is specified */
+ rc = check_message_part(message_part);
+ if (rc)
+ return rc;
+
+ /*
+ * for FIRST or MIDDLE calls the input
+ * data length must be a multiple of 64 bytes.
+ */
+ if (input_length & 0x3f &&
+ (message_part == SHA_MSG_PART_FIRST ||
+ message_part == SHA_MSG_PART_MIDDLE))
+ return EINVAL;
+
+ return s390_sha256((unsigned char *) &sha256_context->sha256Hash,
+ input_data, input_length, output_data, message_part,
+ (uint64_t *) &sha256_context->runningLength);
+}
+
+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)
+{
+ unsigned int rc;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ /* check for obvious errors in parms */
+ if ((input_data == NULL) ||
+ (sha512_context == NULL) ||
+ (output_data == NULL))
+ return EINVAL;
+
+ /* make sure some message part is specified */
+ rc = check_message_part(message_part);
+ if (rc)
+ return rc;
+
+ /*
+ * for FIRST or MIDDLE calls the input
+ * data length must be a multiple of 128 bytes.
+ */
+ if (input_length & 0x7f &&
+ (message_part == SHA_MSG_PART_FIRST ||
+ message_part == SHA_MSG_PART_MIDDLE))
+ return EINVAL;
+
+ return s390_sha384((unsigned char *) &sha512_context->sha512Hash,
+ input_data, input_length, output_data, message_part,
+ (uint64_t *) &(sha512_context->runningLengthLow),
+ (uint64_t *) &(sha512_context->runningLengthHigh));
+}
+
+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)
+{
+ unsigned int rc;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ /* check for obvious errors in parms */
+ if ((input_data == NULL) ||
+ (sha512_context == NULL) ||
+ (output_data == NULL))
+ return EINVAL;
+
+ /* make sure some message part is specified */
+ rc = check_message_part(message_part);
+ if (rc)
+ return rc;
+
+ /*
+ * for FIRST or MIDDLE calls the input
+ * data length must be a multiple of 128 bytes.
+ */
+ if (input_length & 0x7f &&
+ (message_part == SHA_MSG_PART_FIRST ||
+ message_part == SHA_MSG_PART_MIDDLE))
+ return EINVAL;
+
+ return s390_sha512((unsigned char *)&sha512_context->sha512Hash,
+ input_data, input_length, output_data, message_part,
+ (uint64_t *) &sha512_context->runningLengthLow,
+ (uint64_t *) &sha512_context->runningLengthHigh);
+}
+
+unsigned int ica_random_number_generate(unsigned int output_length,
+ unsigned char *output_data)
+{
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ /* check for obvious errors in parms */
+ if (output_data == NULL)
+ return EINVAL;
+
+ return s390_prng(output_data, output_length);
+}
+
+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)
+{
+ unsigned int num_ignored_bytes;
+ unsigned char *public_exponent;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (public_key->key_length != private_key->key_length)
+ return EINVAL;
+ /* Keys should comply with modulus_bit_length */
+ if ((modulus_bit_length + 7) / 8 != public_key->key_length)
+ return EINVAL;
+ /* Minimum length for public exponent is sizeof(unsigned long) */
+ if (public_key->key_length < sizeof(unsigned long))
+ return EINVAL;
+
+ /* OpenSSL takes only exponents of type unsigned long, so we have to
+ * be sure that we give a value of the right size to OpenSSL.
+ */
+ num_ignored_bytes = public_key->key_length - sizeof(unsigned long);
+ public_exponent = public_key->exponent;
+
+ for (; num_ignored_bytes; --num_ignored_bytes, ++public_exponent)
+ if (*public_exponent != 0)
+ return EINVAL;
+
+ /* There is no need to zeroize any buffers here. This will be done in
+ * the lower routines.
+ */
+ return rsa_key_generate_mod_expo(adapter_handle, modulus_bit_length,
+ public_key, private_key);
+}
+
+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)
+{
+ unsigned int num_ignored_bytes;
+ unsigned char *public_exponent;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (public_key->key_length != private_key->key_length)
+ return EINVAL;
+ if ((modulus_bit_length + 7) / 8 != public_key->key_length)
+ return EINVAL;
+ if (public_key->key_length < sizeof(unsigned long))
+ return EINVAL;
+
+ num_ignored_bytes = public_key->key_length - sizeof(unsigned long);
+ public_exponent = public_key->exponent;
+
+ for (; num_ignored_bytes; --num_ignored_bytes, ++public_exponent)
+ if (*public_exponent != 0)
+ return EINVAL;
+
+ /* There is no need to zeroize any buffers here. This will be done in
+ * the lower routines.
+ */
+ return rsa_key_generate_crt(adapter_handle, modulus_bit_length,
+ public_key, private_key);
+}
+
+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)
+{
+ ica_rsa_modexpo_t rb;
+ int hardware, rc;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ /* check for obvious errors in parms */
+ if (input_data == NULL || rsa_key == NULL || output_data == NULL)
+ return EINVAL;
+
+ /* fill driver structure */
+ rb.inputdata = (char *)input_data;
+ rb.inputdatalength = rsa_key->key_length;
+ rb.outputdata = (char *)output_data;
+ rb.outputdatalength = rsa_key->key_length;
+ rb.b_key = (char *)rsa_key->exponent;
+ rb.n_modulus = (char *)rsa_key->modulus;
+
+ hardware = ALGO_SW;
+ if (adapter_handle == DRIVER_NOT_LOADED)
+ rc = rsa_mod_expo_sw(&rb);
+ else {
+ rc = ioctl(adapter_handle, ICARSAMODEXPO, &rb);
+ if (!rc)
+ hardware = ALGO_HW;
+ else
+ rc = rsa_mod_expo_sw(&rb);
+ }
+ if (rc == 0)
+ stats_increment(ICA_STATS_RSA_ME, hardware, ENCRYPT);
+
+ return rc;
+}
+
+unsigned int ica_rsa_crt_key_check(ica_rsa_key_crt_t *rsa_key)
+{
+ int pq_comp;
+ int keyfmt = 1;
+ BIGNUM *bn_p;
+ BIGNUM *bn_q;
+ BIGNUM *bn_invq;
+ BN_CTX *ctx;
+ unsigned char *tmp_buf = NULL;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ /* check if p > q */
+ pq_comp = memcmp( (rsa_key->p + 8), (rsa_key->q), rsa_key->key_length/2);
+ if (pq_comp < 0) /* unprivileged key format */
+ keyfmt = 0;
+
+ if (!keyfmt) {
+ /* swap p and q */
+ tmp_buf = calloc(1, rsa_key->key_length/2);
+ if (!tmp_buf)
+ return ENOMEM;
+ memcpy(tmp_buf, rsa_key->p + 8, rsa_key->key_length/2);
+ memcpy(rsa_key->p + 8, rsa_key->q, rsa_key->key_length/2);
+ memcpy(rsa_key->q, tmp_buf, rsa_key->key_length/2);
+
+ /* swap dp and dq */
+ memcpy(tmp_buf, rsa_key->dp + 8, rsa_key->key_length/2);
+ memcpy(rsa_key->dp + 8, rsa_key->dq, rsa_key->key_length/2);
+ memcpy(rsa_key->dq, tmp_buf, rsa_key->key_length/2);
+
+ /* calculate new qInv */
+ bn_p = BN_new();
+ bn_q = BN_new();
+ bn_invq = BN_new();
+ ctx = BN_CTX_new();
+
+ BN_bin2bn(rsa_key->p, rsa_key->key_length/2+8, bn_p);
+ BN_bin2bn(rsa_key->q, rsa_key->key_length/2, bn_q);
+
+ /* qInv = (1/q) mod p */
+ BN_mod_inverse(bn_invq, bn_q, bn_p, ctx);
+ memset(tmp_buf, 0, rsa_key->key_length/2);
+ BN_bn2bin(bn_invq, tmp_buf);
+
+ memcpy(rsa_key->qInverse + 8, tmp_buf, rsa_key->key_length/2);
+
+ free(tmp_buf);
+
+ return 1;
+ }
+ return 0;
+}
+
+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)
+{
+ ica_rsa_modexpo_crt_t rb;
+ int hardware, rc;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ /* check for obvious errors in parms */
+ if (input_data == NULL || rsa_key == NULL || output_data == NULL)
+ return EINVAL;
+
+ /* fill driver structure */
+ rb.inputdata = (char *)input_data;
+ rb.inputdatalength = rsa_key->key_length;
+ rb.outputdata = (char *)output_data;
+ rb.outputdatalength = rsa_key->key_length;
+
+ ica_rsa_crt_key_check(rsa_key);
+
+ rb.np_prime = (char *)rsa_key->p;
+ rb.nq_prime = (char *)rsa_key->q;
+ rb.bp_key = (char *)rsa_key->dp;
+ rb.bq_key = (char *)rsa_key->dq;
+ rb.u_mult_inv = (char *)rsa_key->qInverse;
+
+ hardware = ALGO_SW;
+ if (adapter_handle == DRIVER_NOT_LOADED)
+ rc = rsa_crt_sw(&rb);
+ else {
+ rc = ioctl(adapter_handle, ICARSACRT, &rb);
+ if(!rc)
+ hardware = ALGO_HW;
+ else
+ rc = rsa_crt_sw(&rb);
+ }
+ if (rc == 0)
+ stats_increment(ICA_STATS_RSA_CRT, hardware, ENCRYPT);
+
+ return rc;
+}
+
+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)
+{
+#ifdef ICA_FIPS
+ if (fips)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_des_parms(mode, data_length, input_data,
+ (unsigned char *) iv, (unsigned char *) des_key,
+ output_data))
+ return EINVAL;
+
+ if (mode == MODE_ECB) {
+ return s390_des_ecb(DEA_ENCRYPT, data_length,
+ input_data, (unsigned char *) des_key,
+ output_data);
+ } else if (mode == MODE_CBC) {
+ return s390_des_cbc(DEA_ENCRYPT, data_length,
+ input_data, (unsigned char *) iv,
+ (unsigned char *) des_key, output_data);
+ }
+ return EINVAL;
+}
+
+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)
+{
+#ifdef ICA_FIPS
+ if (fips)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_des_parms(mode, data_length, input_data,
+ (unsigned char *) iv, (unsigned char *) des_key,
+ output_data))
+ return EINVAL;
+
+ if (mode == MODE_ECB) {
+ return s390_des_ecb(DEA_DECRYPT, data_length,
+ input_data, (unsigned char *) des_key,
+ output_data);
+ } else if (mode == MODE_CBC) {
+ return s390_des_cbc(DEA_DECRYPT, data_length,
+ input_data, (unsigned char *) iv,
+ (unsigned char *) des_key, output_data);
+ }
+ return EINVAL;
+}
+
+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)
+{
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_des_parms(mode, data_length, input_data,
+ (unsigned char *) iv, (unsigned char *) des_key,
+ output_data))
+ return EINVAL;
+
+ if (mode == MODE_ECB) {
+ return s390_des_ecb(TDEA_192_ENCRYPT, data_length,
+ input_data,(unsigned char *) des_key,
+ output_data);
+ } else if (mode == MODE_CBC) {
+ return s390_des_cbc(TDEA_192_ENCRYPT, data_length,
+ input_data, (unsigned char *) iv,
+ (unsigned char *) des_key, output_data);
+ }
+ return EINVAL;
+}
+
+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)
+{
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_des_parms(mode, data_length, input_data,
+ (unsigned char *) iv, (unsigned char *) des_key,
+ output_data))
+ return EINVAL;
+
+ if (mode == MODE_ECB) {
+ return s390_des_ecb(TDEA_192_DECRYPT, data_length,
+ input_data, (unsigned char *) des_key,
+ output_data);
+ } else if (mode == MODE_CBC) {
+ return s390_des_cbc(TDEA_192_DECRYPT, data_length,
+ input_data, (unsigned char *) iv,
+ (unsigned char *) des_key, output_data);
+ }
+ return EINVAL;
+}
+
+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 function_code;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ /* check for obvious errors in parms */
+ if (check_aes_parms(mode, data_length, input_data,
+ (unsigned char *) iv, key_length, aes_key,
+ output_data))
+ return EINVAL;
+
+ function_code = aes_directed_fc(key_length, ICA_ENCRYPT);
+
+ switch (mode) {
+ case MODE_CBC:
+ return s390_aes_cbc(function_code, data_length, input_data,
+ (unsigned char *) iv, aes_key,
+ output_data);
+ case MODE_ECB:
+ return s390_aes_ecb(function_code, data_length, input_data,
+ aes_key, output_data);
+ default:
+ return EINVAL;
+ }
+
+ return EINVAL;
+}
+
+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)
+{
+ unsigned int function_code;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ /* check for obvious errors in parms */
+ if (check_aes_parms(mode, data_length, input_data,
+ (unsigned char *) iv, key_length, aes_key,
+ output_data))
+ return EINVAL;
+
+ function_code = aes_directed_fc(key_length, ICA_DECRYPT);
+
+ switch (mode) {
+ case MODE_CBC:
+ return s390_aes_cbc(function_code, data_length, input_data,
+ (unsigned char *) iv, aes_key,
+ output_data);
+ case MODE_ECB:
+ return s390_aes_ecb(function_code, data_length, input_data,
+ aes_key, output_data);
+ default:
+ return EINVAL;
+ }
+
+ return EINVAL;
+}
+
+unsigned int ica_des_ecb(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned int direction)
+{
+#ifdef ICA_FIPS
+ if (fips)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_des_parms(MODE_ECB, data_length, in_data, NULL, key, out_data))
+ return EINVAL;
+
+ return s390_des_ecb(des_directed_fc(direction), data_length,
+ in_data, key, out_data);
+}
+
+unsigned int ica_des_cbc(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned char *iv,
+ unsigned int direction)
+{
+#ifdef ICA_FIPS
+ if (fips)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_des_parms(MODE_CBC, data_length, in_data, iv, key, out_data))
+ return EINVAL;
+
+ return s390_des_cbc(des_directed_fc(direction), data_length,
+ in_data, iv, key, out_data);
+}
+
+unsigned int ica_des_cbc_cs(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length,
+ unsigned char *key, unsigned char *iv,
+ unsigned int direction, unsigned int variant)
+{
+#ifdef ICA_FIPS
+ if (fips)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_des_parms(MODE_CBCCS, data_length, in_data, iv, key, out_data))
+ return EINVAL;
+
+ return s390_des_cbccs(des_directed_fc(direction),
+ in_data, out_data, data_length,
+ key, iv, variant);
+}
+
+unsigned int ica_des_cfb(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned char *iv, unsigned int lcfb,
+ unsigned int direction)
+{
+#ifdef ICA_FIPS
+ if (fips)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_des_parms(MODE_CFB, data_length, in_data, iv, key, out_data))
+ return EINVAL;
+ /* The cipher feedback has to be between 1 and cipher block size. */
+ if ((lcfb == 0) || (lcfb > DES_BLOCK_SIZE))
+ return EINVAL;
+
+ return s390_des_cfb(des_directed_fc(direction), data_length,
+ in_data, iv, key, out_data, lcfb);
+}
+
+unsigned int ica_des_ofb(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned char *iv, unsigned int direction)
+{
+#ifdef ICA_FIPS
+ if (fips)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_des_parms(MODE_OFB, data_length, in_data, iv, key, out_data))
+ return EINVAL;
+
+ return s390_des_ofb(des_directed_fc(direction), data_length,
+ in_data, iv, key, out_data);
+}
+
+unsigned int ica_des_ctr(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length,
+ unsigned char *key,
+ unsigned char *ctr, unsigned int ctr_width,
+ unsigned int direction)
+{
+#ifdef ICA_FIPS
+ if (fips)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_des_parms(MODE_CTR, data_length, in_data, ctr, key, out_data))
+ return EINVAL;
+
+ if ((ctr_width & (8 - 1)) ||
+ (ctr_width < 8) ||
+ (ctr_width > (DES_BLOCK_SIZE*8)))
+ return EINVAL;
+
+ return s390_des_ctr(des_directed_fc(direction),
+ in_data, out_data, data_length,
+ key, ctr, ctr_width);
+}
+
+unsigned int ica_des_ctrlist(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length,
+ unsigned char *key,
+ const unsigned char *ctrlist,
+ unsigned int direction)
+{
+#ifdef ICA_FIPS
+ if (fips)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_des_parms(MODE_CTR, data_length, in_data, ctrlist, key, out_data))
+ return EINVAL;
+
+ return s390_des_ctrlist(des_directed_fc(direction),
+ data_length, in_data, ctrlist,
+ key, out_data);
+}
+
+unsigned int ica_des_cmac(const unsigned char *message, unsigned long message_length,
+ unsigned char *mac, unsigned int mac_length,
+ unsigned char *key,
+ unsigned int direction)
+{
+#ifdef ICA_FIPS
+ if (fips)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ return ica_des_cmac_last(message, message_length,
+ mac, mac_length,
+ key,
+ NULL,
+ direction);
+}
+
+unsigned int ica_des_cmac_intermediate(const unsigned char *message,
+ unsigned long message_length,
+ unsigned char *key,
+ unsigned char *iv)
+{
+ unsigned long function_code;
+ int rc;
+
+#ifdef ICA_FIPS
+ if (fips)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_cmac_parms(DES_BLOCK_SIZE,
+ message, message_length,
+ NULL, DES_BLOCK_SIZE, /* no mac available (intermediate) */
+ key, DES_BLOCK_SIZE,
+ iv))
+ return EINVAL;
+
+ function_code = des_directed_fc(ICA_DECRYPT);
+ rc = s390_cmac(function_code, message, message_length,
+ DES_BLOCK_SIZE, key,
+ DES_BLOCK_SIZE, NULL, /* no mac available (intermediate) */
+ iv);
+
+ if(!rc)
+ stats_increment(ICA_STATS_DES_CMAC, ALGO_HW, ICA_DECRYPT);
+ return rc;
+}
+
+unsigned int ica_des_cmac_last(const unsigned char *message, unsigned long message_length,
+ unsigned char *mac, unsigned int mac_length,
+ unsigned char *key,
+ unsigned char *iv,
+ unsigned int direction)
+{
+ unsigned char tmp_mac[DES_BLOCK_SIZE];
+ unsigned long function_code;
+ int rc;
+
+#ifdef ICA_FIPS
+ if (fips)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_cmac_parms(DES_BLOCK_SIZE,
+ message, message_length,
+ mac, mac_length,
+ key, DES_BLOCK_SIZE,
+ iv))
+ return EINVAL;
+
+ function_code = des_directed_fc(direction);
+ if (direction) {
+ /* generate */
+ rc = s390_cmac(function_code, message, message_length,
+ DES_BLOCK_SIZE, key, mac_length, mac, iv);
+ if (rc)
+ return rc;
+ else
+ stats_increment(ICA_STATS_DES_CMAC, ALGO_HW, direction);
+ } else {
+ /* verify */
+ rc = s390_cmac(function_code, message, message_length,
+ DES_BLOCK_SIZE, key, mac_length, tmp_mac, iv);
+ if (rc)
+ return rc;
+ if (memcmp(tmp_mac, mac, mac_length))
+ return EFAULT;
+ else
+ stats_increment(ICA_STATS_DES_CMAC, ALGO_HW, direction);
+ }
+
+ return 0;
+}
+
+unsigned int ica_3des_ecb(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned int direction)
+{
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_des_parms(MODE_ECB, data_length, in_data, NULL, key, out_data))
+ return EINVAL;
+
+ return s390_des_ecb(tdes_directed_fc(direction), data_length,
+ in_data, key, out_data);
+}
+
+unsigned int ica_3des_cbc(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned char *iv,
+ unsigned int direction)
+{
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_des_parms(MODE_CBC, data_length, in_data, iv, key, out_data))
+ return EINVAL;
+
+ return s390_des_cbc(tdes_directed_fc(direction), data_length,
+ in_data, iv, key, out_data);
+}
+
+unsigned int ica_3des_cbc_cs(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length,
+ unsigned char *key, unsigned char *iv,
+ unsigned int direction, unsigned int variant)
+{
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_des_parms(MODE_CBCCS, data_length, in_data, iv, key, out_data))
+ return EINVAL;
+
+ return s390_des_cbccs(tdes_directed_fc(direction),
+ in_data, out_data, data_length,
+ key, iv, variant);
+}
+
+unsigned int ica_3des_cfb(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned char *iv, unsigned int lcfb,
+ unsigned int direction)
+{
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_des_parms(MODE_CFB, data_length, in_data, iv, key, out_data))
+ return EINVAL;
+ /* The cipher feedback has to be between 1 and cipher block size. */
+ if ((lcfb == 0) || (lcfb > DES_BLOCK_SIZE))
+ return EINVAL;
+
+ return s390_des_cfb(tdes_directed_fc(direction), data_length,
+ in_data, iv, key, out_data, lcfb);
+}
+
+unsigned int ica_3des_ofb(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned char *iv, unsigned int direction)
+{
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_des_parms(MODE_OFB, data_length, in_data, iv, key, out_data))
+ return EINVAL;
+
+ return s390_des_ofb(tdes_directed_fc(direction), data_length,
+ in_data, iv, key, out_data);
+}
+
+unsigned int ica_3des_ctr(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length,
+ unsigned char *key,
+ unsigned char *ctr, unsigned int ctr_width,
+ unsigned int direction)
+{
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_des_parms(MODE_CTR, data_length, in_data, ctr, key, out_data))
+ return EINVAL;
+
+ if ((ctr_width & (8 - 1)) ||
+ (ctr_width < 8) ||
+ (ctr_width > (DES_BLOCK_SIZE*8)))
+ return EINVAL;
+
+ return s390_des_ctr(tdes_directed_fc(direction),
+ in_data, out_data, data_length,
+ key, ctr, ctr_width);
+}
+
+unsigned int ica_3des_ctrlist(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length,
+ unsigned char *key,
+ const unsigned char *ctrlist,
+ unsigned int direction)
+{
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_des_parms(MODE_CTR, data_length, in_data, ctrlist, key, out_data))
+ return EINVAL;
+
+ return s390_des_ctrlist(tdes_directed_fc(direction),
+ data_length, in_data, ctrlist,
+ key, out_data);
+}
+
+unsigned int ica_3des_cmac(const unsigned char *message, unsigned long message_length,
+ unsigned char *mac, unsigned int mac_length,
+ unsigned char *key,
+ unsigned int direction)
+{
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ return ica_3des_cmac_last(message, message_length,
+ mac, mac_length,
+ key,
+ NULL,
+ direction);
+}
+
+unsigned int ica_3des_cmac_intermediate(const unsigned char *message,
+ unsigned long message_length,
+ unsigned char *key,
+ unsigned char *iv)
+{
+ unsigned long function_code;
+ int rc;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_cmac_parms(DES_BLOCK_SIZE,
+ message, message_length,
+ NULL, DES_BLOCK_SIZE, /* no mac available (intermediate) */
+ key, 3*DES_BLOCK_SIZE,
+ iv))
+ return EINVAL;
+
+ function_code = tdes_directed_fc(ICA_DECRYPT);
+ rc = s390_cmac(function_code, message, message_length,
+ 3*DES_BLOCK_SIZE, key,
+ DES_BLOCK_SIZE, NULL, /* no mac available (intermediate) */
+ iv);
+
+ if (!rc)
+ stats_increment(ICA_STATS_3DES_CMAC, ALGO_HW, DECRYPT);
+ return rc;
+}
+
+unsigned int ica_3des_cmac_last(const unsigned char *message, unsigned long message_length,
+ unsigned char *mac, unsigned int mac_length,
+ unsigned char *key,
+ unsigned char *iv,
+ unsigned int direction)
+{
+ unsigned char tmp_mac[DES_BLOCK_SIZE];
+ unsigned long function_code;
+ int rc;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_cmac_parms(DES_BLOCK_SIZE,
+ message, message_length,
+ mac, mac_length,
+ key, 3*DES_BLOCK_SIZE,
+ iv))
+ return EINVAL;
+
+ function_code = tdes_directed_fc(direction);
+ if (direction) {
+ /* generate */
+ rc = s390_cmac(function_code, message, message_length,
+ 3*DES_BLOCK_SIZE, key, mac_length, mac, iv);
+ if (rc)
+ return rc;
+ else
+ stats_increment(ICA_STATS_3DES_CMAC, ALGO_HW, direction);
+ } else {
+ /* verify */
+ rc = s390_cmac(function_code, message, message_length,
+ 3*DES_BLOCK_SIZE, key, mac_length, tmp_mac, iv);
+ if (rc)
+ return rc;
+ if (memcmp(tmp_mac, mac, mac_length))
+ return EFAULT;
+ else
+ stats_increment(ICA_STATS_3DES_CMAC, ALGO_HW, direction);
+ }
+
+ return 0;
+}
+
+unsigned int ica_aes_ecb(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned int key_length,
+ unsigned int direction)
+{
+ unsigned int function_code;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_aes_parms(MODE_ECB, data_length, in_data, NULL, key_length,
+ key, out_data))
+ return EINVAL;
+
+ function_code = aes_directed_fc(key_length, direction);
+ return s390_aes_ecb(function_code, data_length, in_data, key, out_data);
+}
+
+unsigned int ica_aes_cbc(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned int key_length, unsigned char *iv,
+ unsigned int direction)
+{
+ unsigned int function_code;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_aes_parms(MODE_CBC, data_length, in_data, iv, key_length,
+ key, out_data))
+ return EINVAL;
+
+ function_code = aes_directed_fc(key_length, direction);
+ return s390_aes_cbc(function_code, data_length, in_data, iv, key, out_data);
+}
+
+unsigned int ica_aes_cbc_cs(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length,
+ unsigned char *key, unsigned int key_length,
+ unsigned char *iv,
+ unsigned int direction, unsigned int variant)
+{
+ unsigned int function_code;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_aes_parms(MODE_CBCCS, data_length, in_data, iv, key_length,
+ key, out_data))
+ return EINVAL;
+
+ function_code = aes_directed_fc(key_length, direction);
+ return s390_aes_cbccs(function_code, in_data, out_data, data_length,
+ key, key_length, iv, variant);
+}
+
+unsigned int ica_aes_cfb(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned int key_length, unsigned char *iv, unsigned int lcfb,
+ unsigned int direction)
+{
+ unsigned int function_code;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_aes_parms(MODE_CFB, data_length, in_data, iv, key_length,
+ key, out_data))
+ return EINVAL;
+ /* The cipher feedback has to be between 1 and cipher block size. */
+ if ((lcfb == 0) || (lcfb > AES_BLOCK_SIZE))
+ return EINVAL;
+
+ function_code = aes_directed_fc(key_length, direction);
+ return s390_aes_cfb(function_code, data_length, in_data, iv, key, out_data,
+ lcfb);
+}
+
+unsigned int ica_aes_ofb(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length, unsigned char *key,
+ unsigned int key_length, unsigned char *iv,
+ unsigned int direction)
+{
+ unsigned int function_code;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_aes_parms(MODE_OFB, data_length, in_data, iv, key_length,
+ key, out_data))
+ return EINVAL;
+
+ function_code = aes_directed_fc(key_length, direction);
+ return s390_aes_ofb(function_code, data_length, in_data, iv, key, out_data);
+}
+
+unsigned int ica_aes_ctr(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length,
+ unsigned char *key, unsigned int key_length,
+ unsigned char *ctr, unsigned int ctr_width,
+ unsigned int direction)
+{
+ unsigned int function_code;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_aes_parms(MODE_CTR, data_length, in_data, ctr, key_length,
+ key, out_data))
+ return EINVAL;
+
+ if ((ctr_width & (8 - 1)) ||
+ (ctr_width < 8) ||
+ (ctr_width > (AES_BLOCK_SIZE*8)))
+ return EINVAL;
+
+ function_code = aes_directed_fc(key_length, direction);
+ return s390_aes_ctr(function_code,
+ in_data, out_data, data_length,
+ key, ctr, ctr_width);
+}
+
+unsigned int ica_aes_ctrlist(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length,
+ unsigned char *key, unsigned int key_length,
+ const unsigned char *ctrlist,
+ unsigned int direction)
+{
+ unsigned int function_code;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_aes_parms(MODE_CTR, data_length, in_data, ctrlist, key_length,
+ key, out_data))
+ return EINVAL;
+
+ function_code = aes_directed_fc(key_length, direction);
+ return s390_aes_ctrlist(function_code, data_length, in_data, ctrlist,
+ key, out_data);
+}
+
+unsigned int ica_aes_xts(const unsigned char *in_data, unsigned char *out_data,
+ unsigned long data_length,
+ unsigned char *key1, unsigned char *key2,
+ unsigned int key_length, unsigned char *tweak,
+ unsigned int direction)
+{
+ unsigned int function_code;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_aes_parms(MODE_XTS, data_length, in_data, tweak, key_length,
+ key1, out_data))
+ return EINVAL;
+
+ if (key2 == NULL)
+ return EINVAL;
+
+ switch (key_length) {
+ case AES_KEY_LEN128:
+ function_code = (direction == ICA_DECRYPT) ?
+ AES_128_XTS_DECRYPT : AES_128_XTS_ENCRYPT;
+ break;
+ case AES_KEY_LEN256:
+ function_code = (direction == ICA_DECRYPT) ?
+ AES_256_XTS_DECRYPT : AES_256_XTS_ENCRYPT;
+ break;
+ default:
+ return EINVAL;
+ }
+
+ return s390_aes_xts(function_code, data_length, in_data, tweak,
+ key1, key2, key_length, out_data);
+}
+
+unsigned int ica_aes_cmac(const unsigned char *message, unsigned long message_length,
+ unsigned char *mac, unsigned int mac_length,
+ unsigned char *key, unsigned int key_length,
+ unsigned int direction)
+{
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ return ica_aes_cmac_last(message, message_length,
+ mac, mac_length,
+ key, key_length,
+ NULL,
+ direction);
+}
+
+unsigned int ica_aes_cmac_intermediate(const unsigned char *message,
+ unsigned long message_length,
+ unsigned char *key, unsigned int key_length,
+ unsigned char *iv)
+{
+ unsigned long function_code;
+ int rc;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_cmac_parms(AES_BLOCK_SIZE,
+ message, message_length,
+ NULL, AES_BLOCK_SIZE, /* no mac available (intermediate) */
+ key, key_length,
+ iv))
+ return EINVAL;
+
+ function_code = aes_directed_fc(key_length, ICA_DECRYPT);
+ rc = s390_cmac(function_code, message, message_length,
+ key_length, key,
+ AES_BLOCK_SIZE, NULL, /* no mac available (intermediate) */
+ iv);
+
+ if (!rc)
+ stats_increment(ICA_STATS_AES_CMAC, ALGO_HW, ICA_DECRYPT);
+ return rc;
+}
+
+unsigned int ica_aes_cmac_last(const unsigned char *message, unsigned long message_length,
+ unsigned char *mac, unsigned int mac_length,
+ unsigned char *key, unsigned int key_length,
+ unsigned char *iv,
+ unsigned int direction)
+{
+ unsigned char tmp_mac[AES_BLOCK_SIZE];
+ unsigned long function_code;
+ int rc;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_cmac_parms(AES_BLOCK_SIZE,
+ message, message_length,
+ mac, mac_length,
+ key, key_length,
+ iv))
+ return EINVAL;
+
+ function_code = aes_directed_fc(key_length, direction);
+ if (direction) {
+ /* generate */
+ rc = s390_cmac(function_code, message, message_length,
+ key_length, key, mac_length, mac, iv);
+ if (rc)
+ return rc;
+ else
+ stats_increment(ICA_STATS_AES_CMAC, ALGO_HW, direction);
+ } else {
+ /* verify */
+ rc = s390_cmac(function_code, message, message_length,
+ key_length, key, mac_length, tmp_mac, iv);
+ if (rc)
+ return rc;
+ if (memcmp(tmp_mac, mac, mac_length))
+ return EFAULT;
+ else
+ stats_increment(ICA_STATS_AES_CMAC, ALGO_HW, direction);
+ }
+
+ return 0;
+}
+
+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,
+ unsigned char *key, unsigned int key_length,
+ unsigned int direction)
+{
+ unsigned char tmp_mac[AES_BLOCK_SIZE];
+ unsigned char *mac;
+ unsigned long function_code;
+ int rc;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_aes_parms(MODE_CCM, payload_length, payload, nonce, key_length,
+ key, ciphertext_n_mac))
+ return EINVAL;
+ if (check_ccm_parms(payload_length,
+ assoc_data, assoc_data_length,
+ ciphertext_n_mac + payload_length, mac_length,
+ nonce_length))
+ return EINVAL;
+
+ function_code = aes_directed_fc(key_length, direction);
+ mac = (direction == ICA_ENCRYPT) ?
+ (unsigned char *)(ciphertext_n_mac + payload_length) :
+ tmp_mac;
+
+ rc = s390_ccm(function_code,
+ payload, payload_length,
+ ciphertext_n_mac,
+ assoc_data, assoc_data_length,
+ nonce, nonce_length,
+ mac, mac_length,
+ key);
+ if (rc)
+ return rc;
+
+ if (direction == ICA_DECRYPT) {
+ /* verify */
+ if (memcmp((unsigned char *)(ciphertext_n_mac + payload_length),
+ tmp_mac, mac_length))
+ return EFAULT;
+ }
+
+ return 0;
+}
+
+unsigned int ica_aes_gcm(unsigned char *plaintext, unsigned long plaintext_length,
+ unsigned char *ciphertext,
+ const unsigned char *iv, unsigned int iv_length,
+ const unsigned char *aad, unsigned long aad_length,
+ unsigned char *tag, unsigned int tag_length,
+ unsigned char *key, unsigned int key_length,
+ unsigned int direction)
+{
+ unsigned char tmp_tag[AES_BLOCK_SIZE];
+ unsigned long function_code;
+ int rc;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_aes_parms(MODE_GCM, plaintext_length, plaintext, iv, key_length,
+ key, ciphertext))
+ return EINVAL;
+ if (check_gcm_parms(plaintext_length, aad, aad_length, tag, tag_length, iv_length))
+ return EINVAL;
+
+ function_code = aes_directed_fc(key_length, direction);
+ if (direction) {
+ /* encrypt & generate */
+ rc = s390_gcm(function_code,
+ plaintext, plaintext_length,
+ ciphertext,
+ iv, iv_length,
+ aad, aad_length,
+ tag, tag_length,
+ key);
+ if (rc)
+ return rc;
+ } else {
+ /* decrypt & verify */
+ rc = s390_gcm(function_code,
+ plaintext, plaintext_length,
+ ciphertext,
+ iv, iv_length,
+ aad, aad_length,
+ tmp_tag, AES_BLOCK_SIZE,
+ key);
+ if (rc)
+ return rc;
+
+ if (memcmp(tmp_tag, tag, tag_length))
+ return EFAULT;
+ }
+ return 0;
+}
+
+unsigned int ica_aes_gcm_initialize(const unsigned char *iv,
+ unsigned int iv_length,
+ unsigned char *key,
+ unsigned int key_length,
+ unsigned char *icb,
+ unsigned char *ucb,
+ unsigned char *subkey,
+ unsigned int direction)
+{
+ unsigned long function_code;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ function_code = aes_directed_fc(key_length, direction);
+
+ return s390_gcm_initialize(function_code, iv, iv_length,
+ key, icb, ucb, subkey);
+}
+
+unsigned int ica_aes_gcm_intermediate(unsigned char *plaintext,
+ unsigned long plaintext_length,
+ unsigned char *ciphertext,
+ unsigned char *cb,
+ unsigned char *aad, unsigned long aad_length,
+ unsigned char *tag, unsigned int tag_length,
+ unsigned char *key, unsigned int key_length,
+ unsigned char *subkey, unsigned int direction)
+{
+ unsigned long function_code;
+ int rc, iv_length_dummy = 12;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_aes_parms(MODE_GCM, plaintext_length, plaintext, cb, key_length,
+ key, ciphertext))
+ return EINVAL;
+ if (check_gcm_parms(plaintext_length, aad, aad_length, tag, tag_length,
+ iv_length_dummy))
+ return EINVAL;
+
+ function_code = aes_directed_fc(key_length, direction);
+ if (direction) {
+ /* encrypt & generate */
+ rc = s390_gcm_intermediate(function_code, plaintext, plaintext_length,
+ ciphertext, cb, aad, aad_length, tag, tag_length, key, subkey);
+ if (rc)
+ return rc;
+ } else {
+ /* decrypt & verify */
+ rc = s390_gcm_intermediate(function_code, plaintext, plaintext_length,
+ ciphertext, cb, aad, aad_length, tag, AES_BLOCK_SIZE, key, subkey);
+ if (rc)
+ return rc;
+ }
+ return 0;
+}
+
+unsigned int ica_aes_gcm_last( unsigned char *icb,
+ unsigned long aad_length, unsigned long ciph_length,
+ unsigned char *tag,
+ unsigned char *final_tag, unsigned int final_tag_length,
+ unsigned char *key, unsigned int key_length,
+ unsigned char *subkey, unsigned int direction)
+{
+ unsigned long function_code;
+ int rc;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ function_code = aes_directed_fc(key_length, direction);
+ if (direction) {
+ /* encrypt & generate */
+ rc = s390_gcm_last(function_code, icb, aad_length, ciph_length,
+ tag, AES_BLOCK_SIZE, key, subkey);
+ if (rc)
+ return rc;
+ } else {
+ /* decrypt & verify */
+ rc = s390_gcm_last(function_code, icb, aad_length, ciph_length,
+ tag, AES_BLOCK_SIZE, key, subkey);
+ if (rc)
+ return rc;
+
+ if (memcmp(tag, final_tag, final_tag_length))
+ return EFAULT;
+ }
+ return 0;
+}
+
+unsigned int ica_get_version(libica_version_info *version_info)
+{
+#ifdef VERSION
+ int rc;
+ int i;
+ char *pch;
+ char *saveptr;
+
+ int length = strnlen(VERSION, MAX_VERSION_LENGTH);
+ char buffer[length+1];
+
+ if (version_info == NULL) {
+ return EINVAL;
+ }
+
+ rc = snprintf(buffer, (length+1), "%s", VERSION);
+ if (rc <= 0) {
+ return EIO;
+ }
+
+ for (pch = strtok_r(buffer, ".", &saveptr), i = 1;
+ pch != NULL;
+ pch = strtok_r(NULL, ".", &saveptr), i++)
+ {
+ switch(i) {
+ case 1:
+ version_info->major_version = atoi(pch);
+ break;
+ case 2:
+ version_info->minor_version = atoi(pch);
+ break;
+ case 3:
+ version_info->fixpack_version = atoi(pch);
+ break;
+ default:
+ return EIO;
+ }
+ }
+
+ if (i < 3)
+ return EIO;
+
+ return 0;
+#else
+ /* We expect the libica version information in the format x.y.z
+ * defined in the macro VERSION as part of the build process. */
+ return EIO;
+#endif
+}
+
+unsigned int ica_get_functionlist(libica_func_list_element *pmech_list,
+ unsigned int *pmech_list_len)
+{
+ return s390_get_functionlist(pmech_list, pmech_list_len);
+}
+
+/*
+ * ica_drbg: libica's Deterministic Random Bit Generator
+ * (conforming to NIST SP 800-90A)
+ */
+ica_drbg_mech_t *const ICA_DRBG_SHA512 = &DRBG_SHA512;
+
+static inline int ica_drbg_error(int status)
+{
+ switch(status){
+ case 0:
+ return 0;
+ case DRBG_RESEED_REQUIRED:
+ case DRBG_NONCE_INV:
+ return EPERM;
+ case DRBG_NOMEM:
+ return ENOMEM;
+ case DRBG_SH_INV:
+ case DRBG_MECH_INV:
+ case DRBG_PERS_INV:
+ case DRBG_ADD_INV:
+ case DRBG_REQUEST_INV:
+ return EINVAL;
+ case DRBG_SEC_NOTSUPP:
+ case DRBG_PR_NOTSUPP:
+ return ENOTSUP;
+ case DRBG_HEALTH_TEST_FAIL:
+ return ICA_DRBG_HEALTH_TEST_FAIL;
+ case DRBG_ENTROPY_SOURCE_FAIL:
+ return ICA_DRBG_ENTROPY_SOURCE_FAIL;
+ default:
+ return -1; /* unreachable */
+ }
+}
+
+int ica_drbg_instantiate(ica_drbg_t **sh,
+ int sec,
+ bool pr,
+ ica_drbg_mech_t *mech,
+ const unsigned char *pers,
+ size_t pers_len)
+{
+ int status;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ status = drbg_mech_valid(mech);
+ if(status)
+ return ica_drbg_error(status);
+
+ /* Run instantiate health test (11.3.2). */
+ pthread_rwlock_wrlock(&mech->lock);
+ status = drbg_health_test(drbg_instantiate, sec, pr, mech);
+ pthread_rwlock_unlock(&mech->lock);
+ if(status)
+ return ica_drbg_error(status);
+
+ /* Instantiate. */
+ status = drbg_instantiate(sh, sec, pr, mech, pers, pers_len, false,
+ NULL, 0, NULL, 0);
+ if(0 > status)
+ mech->error_state = status;
+
+ return ica_drbg_error(status);
+}
+
+int ica_drbg_reseed(ica_drbg_t *sh,
+ bool pr,
+ const unsigned char *add,
+ size_t add_len)
+{
+ int status;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if(!sh)
+ return ica_drbg_error(DRBG_SH_INV);
+ status = drbg_mech_valid(sh->mech);
+ if(status)
+ return ica_drbg_error(status);
+
+ /* Reseed health test runs whenever generate is tested (11.3.4). */
+
+ /* Reseed. */
+ status = drbg_reseed(sh, pr, add, add_len, false, NULL, 0);
+ if(0 > status)
+ sh->mech->error_state = status;
+
+ return ica_drbg_error(status);
+}
+
+int ica_drbg_generate(ica_drbg_t *sh,
+ int sec,
+ bool pr,
+ const unsigned char *add,
+ size_t add_len,
+ unsigned char *prnd,
+ size_t prnd_len)
+{
+ int status;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if(!sh)
+ return ica_drbg_error(DRBG_SH_INV);
+ status = drbg_mech_valid(sh->mech);
+ if(status)
+ return ica_drbg_error(status);
+
+ /* Run generate and reseed health tests before first use of these
+ * functions and when indicated by the test counter (11.3.3). */
+ pthread_rwlock_wrlock(&sh->mech->lock);
+ if(!(sh->mech->test_ctr %= sh->mech->test_intervall)){
+ status = drbg_health_test(drbg_reseed, sec, pr, sh->mech);
+ if(!status)
+ status = drbg_health_test(drbg_generate, sec, pr,
+ sh->mech);
+ if(status){
+ pthread_rwlock_unlock(&sh->mech->lock);
+ return ica_drbg_error(status);
+ }
+ }
+ sh->mech->test_ctr++;
+ pthread_rwlock_unlock(&sh->mech->lock);
+
+ /* Generate. */
+ status = pthread_rwlock_rdlock(&sh->mech->lock);
+ if(EAGAIN == status)
+ return ica_drbg_error(DRBG_REQUEST_INV);
+ status = drbg_generate(sh, sec, pr, add, add_len, false, NULL, 0, prnd,
+ prnd_len);
+ pthread_rwlock_unlock(&sh->mech->lock);
+ if(0 > status)
+ sh->mech->error_state = status;
+
+ /* Inhibit output if mechanism is in error state (11.3.6). */
+ if(sh->mech->error_state)
+ drbg_zmem(prnd, prnd_len);
+
+ return ica_drbg_error(status);
+}
+
+int ica_drbg_uninstantiate(ica_drbg_t **sh)
+{
+ /* Uninstantiate health test runs whenever other functions are
+ * tested (11.3.5). */
+
+ /* Uninstantiate. */
+ return ica_drbg_error(drbg_uninstantiate(sh, false));
+}
+
+int ica_drbg_health_test(void *func,
+ int sec,
+ bool pr,
+ ica_drbg_mech_t *mech)
+{
+ int status;
+
+ status = drbg_mech_valid(mech);
+ if(status)
+ return ica_drbg_error(status);
+
+ /* Health test. */
+ pthread_rwlock_wrlock(&mech->lock);
+ if(ica_drbg_instantiate == func)
+ status = drbg_health_test(drbg_instantiate, sec, pr, mech);
+ else if(ica_drbg_reseed == func)
+ status = drbg_health_test(drbg_reseed, sec, pr, mech);
+ else if(ica_drbg_generate == func){
+ status = drbg_health_test(drbg_reseed, sec, pr, mech);
+ if(!status)
+ status = drbg_health_test(drbg_generate, sec, pr,
+ mech);
+ mech->test_ctr = 1; /* reset test counter */
+ }
+ else
+ status = DRBG_REQUEST_INV;
+ pthread_rwlock_unlock(&mech->lock);
+
+ return ica_drbg_error(status);
+}
+
+#ifdef ICA_FIPS
+
+int
+ica_fips_status(void)
+{
+ return fips;
+}
+
+void
+ica_fips_powerup_tests(void)
+{
+ fips_powerup_tests();
+}
+
+#endif /* ICA_FIPS */
diff --git a/src/icainfo.c b/src/icainfo.c
new file mode 100644
index 0000000..05495b8
--- /dev/null
+++ b/src/icainfo.c
@@ -0,0 +1,267 @@
+/* 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.
+ */
+
+/*
+ * Display a list of all CP Assist for Cryptographic Function (CPACF)
+ * operations supported by libica on a system.
+ *
+ * Author(s): Ralph Wuerthner <rwuerthn@de.ibm.com>
+ * Holger Dengler <hd@linux.vnet.ibm.com>
+ * Benedikt Klotz <benedikt.klotz@de.ibm.com>
+ * Ingo Tuchscherer <ingo.tuchscherer@de.ibm.com>
+ *
+ * Copyright IBM Corp. 2007, 2011, 2014
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <libgen.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "fips.h"
+#include "ica_api.h"
+#include "s390_crypto.h"
+
+#define CMD_NAME "icainfo"
+#define COPYRIGHT "Copyright IBM Corp. 2007, 2014."
+
+void print_version(void)
+{
+ printf(CMD_NAME ": libica version " VERSION "\n" COPYRIGHT "\n");
+}
+
+void print_help(char *cmd)
+{
+ printf("Usage: %s [OPTION]\n", cmd);
+ printf
+ ("Display a list of all CP Assist for Cryptographic Function "
+ "(CPACF)\noperations supported by libica on this system.\n"
+ "\n" "Options:\n"
+ " -v, --version show version information\n"
+ " -h, --help display this help text\n");
+}
+
+#define getopt_string "qvh"
+static struct option getopt_long_options[] = {
+ {"version", 0, 0, 'v'},
+ {"help", 0, 0, 'h'},
+ {0, 0, 0, 0}
+};
+
+
+struct crypt_pair {
+ char *name;
+ int algo_id;
+};
+
+static struct crypt_pair crypt_map[] = {
+ {"SHA-1", SHA1},
+ {"SHA-224", SHA224},
+ {"SHA-256", SHA256},
+ {"SHA-384", SHA384},
+ {"SHA-512", SHA512},
+ {"GHASH", G_HASH},
+ {"P_RNG", P_RNG},
+ {"DRBG-SHA-512", SHA512_DRNG},
+ {"RSA ME", RSA_ME},
+ {"RSA CRT", RSA_CRT},
+ {"DES ECB", DES_ECB},
+ {"DES CBC", DES_CBC},
+ {"DES OFB", DES_OFB},
+ {"DES CFB", DES_CFB},
+ {"DES CTR", DES_CTR},
+ {"DES CMAC", DES_CMAC},
+ {"3DES ECB", DES3_ECB},
+ {"3DES CBC", DES3_CBC},
+ {"3DES OFB", DES3_OFB},
+ {"3DES CFB", DES3_OFB},
+ {"3DES CTR", DES3_CTR},
+ {"3DES CMAC", DES3_CMAC},
+ {"AES ECB", AES_ECB},
+ {"AES CBC", AES_CBC},
+ {"AES OFB", AES_OFB},
+ {"AES CFB", AES_CFB},
+ {"AES CTR", AES_CTR},
+ {"AES CMAC", AES_CMAC},
+ {"AES XTS", AES_XTS},
+ {NULL,0}
+};
+
+
+int is_crypto_card_loaded()
+{
+ DIR* sysDir;
+ FILE *file;
+ char dev[PATH_MAX] = "/sys/devices/ap/";
+ struct dirent *direntp;
+ char *type = NULL;
+ size_t size;
+ char c;
+
+ if ((sysDir = opendir(dev)) == NULL )
+ return 0;
+
+ while((direntp = readdir(sysDir)) != NULL){
+ if(strstr(direntp->d_name, "card") != 0){
+ snprintf(dev, PATH_MAX, "/sys/devices/ap/%s/type",
+ direntp->d_name);
+
+ if ((file = fopen(dev, "r")) == NULL){
+ closedir(sysDir);
+ return 0;
+ }
+
+ if (getline(&type, &size, file) == -1){
+ fclose(file);
+ closedir(sysDir);
+ return 0;
+ }
+
+ /* ignore \n
+ * looking for CEX??A and CEX??C
+ * Skip type CEX??P cards
+ */
+ if (type[strlen(type)-2] == 'P'){
+ free(type);
+ type = NULL;
+ fclose(file);
+ continue;
+ }
+ free(type);
+ type = NULL;
+ fclose(file);
+
+ snprintf(dev, PATH_MAX, "/sys/devices/ap/%s/online",
+ direntp->d_name);
+ if ((file = fopen(dev, "r")) == NULL){
+ closedir(sysDir);
+ return 0;
+ }
+ if((c = fgetc(file)) == '1'){
+ fclose(file);
+ return 1;
+ }
+ fclose(file);
+ }
+ }
+ closedir(sysDir);
+ return 0;
+}
+
+
+
+int main(int argc, char **argv)
+{
+ int rc;
+ int index = 0;
+ unsigned int mech_len;
+ libica_func_list_element *pmech_list = NULL;
+ int flag;
+
+ while ((rc = getopt_long(argc, argv, getopt_string,
+ getopt_long_options, &index)) != -1) {
+ switch (rc) {
+ case 'v':
+ print_version();
+ exit(0);
+ break;
+ case 'h':
+ print_help(basename(argv[0]));
+ exit(0);
+ default:
+ fprintf(stderr, "Try '%s --help' for more"
+ " information.\n", basename(argv[0]));
+ exit(1);
+ }
+ }
+ if (optind < argc) {
+ fprintf(stderr, "%s: invalid option.\n"
+ "Try '%s --help' for more information.\n",
+ argv[0], basename(argv[0]));
+ exit(1);
+ }
+
+ printf(" Cryptographic algorithm support \n");
+ printf("-------------------------------------------\n");
+
+ if (ica_get_functionlist(NULL, &mech_len) != 0){
+ perror("get_functionlist: ");
+ return EXIT_FAILURE;
+ }
+ pmech_list = malloc(sizeof(libica_func_list_element)*mech_len);
+ if (ica_get_functionlist(pmech_list, &mech_len) != 0){
+ perror("get_functionlist: ");
+ free(pmech_list);
+ return EXIT_FAILURE;
+ }
+
+ flag = is_crypto_card_loaded();
+
+ #define CELL_SIZE 3
+
+ int i, j;
+ printf(" function | hardware | software \n");
+ printf("---------------+------------+------------\n");
+ for(i = 0;crypt_map[i].algo_id;i++){
+ for(j=0;j<mech_len;j++){
+ if(crypt_map[i].algo_id == pmech_list[j].mech_mode_id){
+#ifdef ICA_FIPS
+ if (((ica_fips_status() & ICA_FIPS_MODE)
+ && !fips_approved(pmech_list[j].mech_mode_id))
+ || ica_fips_status() >> 1) {
+ printf("%14s | blocked "
+ "| blocked\n",
+ crypt_map[i].name);
+ break;
+ }
+#endif /* ICA_FIPS */
+ if (flag) {
+ printf("%14s | %*s | %*s\n",
+ crypt_map[i].name,
+ CELL_SIZE,
+ pmech_list[j].flags &
+ (ICA_FLAG_SHW | ICA_FLAG_DHW)
+ ? "yes" : "no",
+ CELL_SIZE,
+ pmech_list[j].flags & ICA_FLAG_SW
+ ? "yes" : "no");
+ } else {
+ printf("%14s | %*s | %*s\n",
+ crypt_map[i].name,
+ CELL_SIZE,
+ (pmech_list[j].flags &
+ ICA_FLAG_SHW)
+ ? "yes" : "no",
+ CELL_SIZE,
+ pmech_list[j].flags & ICA_FLAG_SW
+ ? "yes" : "no");
+
+ }
+ break;
+ }
+
+ }
+ }
+ free(pmech_list);
+
+ printf("-------------------------------------------\n");
+#ifdef ICA_FIPS
+ printf("Built-in FIPS support: FIPS mode %s.\n",
+ ica_fips_status() & ICA_FIPS_MODE ? "active" : "inactive");
+ if (ica_fips_status() >> 1)
+ printf("FIPS SELF-TEST FAILURE. CHECK THE SYSLOG.\n");
+#else
+ printf("No built-in FIPS support.\n");
+#endif /* ICA_FIPS */
+
+ return EXIT_SUCCESS;
+}
diff --git a/src/icastats.c b/src/icastats.c
new file mode 100644
index 0000000..80a12fd
--- /dev/null
+++ b/src/icastats.c
@@ -0,0 +1,250 @@
+/* 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.
+ */
+
+/*
+ * Authors(s): Christian Maaser <cmaaser@de.ibm.com>
+ * Holger Dengler <hd@linux.vnet.ibm.com>
+ * Benedikt Klotz <benedikt.klotz@de.ibm.com>
+ * Ingo Tuchscherer <ingo.tuchscherer@de.ibm.com>
+ *
+ * Copyright IBM Corp. 2009, 2010, 2011, 2014
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <getopt.h>
+#include <pwd.h>
+#include <libgen.h>
+#include "icastats.h"
+
+#define CMD_NAME "icastats"
+#define COPYRIGHT "Copyright IBM Corp. 2009, 2010, 2011, 2014."
+
+void print_version(void)
+{
+ printf(CMD_NAME ": libica version " VERSION "\n" COPYRIGHT "\n");
+}
+
+void print_help(char *cmd)
+{
+ printf("Usage: %s [OPTION]\n\n", cmd);
+ printf("This command is used to indicate whether libica uses hardware crypto functions or\n"
+ "software fallbacks. It provides an overview of the algorithms with modes of operation.\n"
+ "\n"
+ "Options:\n"
+ " -r, --reset set the own function counters to zero.\n"
+ " -R, --reset-all reset the statistsics from all users. (root user only)\n"
+ " -d, --delete delete your own statistics.\n"
+ " -D, --delete-all delete the statistics from all users. (root user only)\n"
+ " -U, --user <userid> show the statistics from one user. (root user only)\n"
+ " -S, --summary show the accumulated statistics from alle users. (root user only)\n"
+ " -A, --all show the statistic tables from all users. (root user only)\n"
+ " -v, --version output version information\n"
+ " -h, --help display help information\n");
+}
+
+#define getopt_string "rRdDU:SAvh"
+static struct option getopt_long_options[] = {
+ {"reset", 0, 0, 'r'},
+ {"reset-all", 0, 0, 'R'},
+ {"delete", 0, 0, 'd'},
+ {"delete-all", 0, 0, 'D'},
+ {"user", required_argument, 0, 'U'},
+ {"summary", 0, 0, 'S'},
+ {"all", 0, 0, 'A'},
+ {"version", 0, 0, 'v'},
+ {"help", 0, 0, 'h'},
+ {0, 0, 0, 0}
+};
+
+const char *const STATS_DESC[ICA_NUM_STATS] = {
+ STAT_STRINGS
+};
+
+
+
+#define CELL_SIZE 10
+void print_stats(stats_entry_t *stats)
+{
+ printf(" function | hardware | software\n");
+ printf("--------------+--------------------------+-------------------------\n");
+ printf(" | ENC CRYPT DEC | ENC CRYPT DEC \n");
+ printf("--------------+--------------------------+-------------------------\n");
+ unsigned int i;
+ for (i = 0; i < ICA_NUM_STATS; ++i){
+ if(i<=ICA_STATS_RSA_CRT){
+ printf(" %12s | %*d | %*d\n",
+ STATS_DESC[i],
+ CELL_SIZE,
+ stats[i].enc.hw,
+ CELL_SIZE,
+ stats[i].enc.sw);
+ } else{
+ printf(" %12s |%*d %*d |%*d %*d\n",
+ STATS_DESC[i],
+ CELL_SIZE,
+ stats[i].enc.hw,
+ CELL_SIZE,
+ stats[i].dec.hw,
+ CELL_SIZE,
+ stats[i].enc.sw,
+ CELL_SIZE,
+ stats[i].dec.sw);
+
+ }
+ }
+}
+
+
+
+
+int main(int argc, char *argv[])
+{
+ int rc = 0;
+ int index = 0;
+ int reset = 0;
+ int delete = 0;
+ int sum = 0;
+ int user = -1;
+ int all = 0;
+ struct passwd *pswd;
+
+ while ((rc = getopt_long(argc, argv, getopt_string,
+ getopt_long_options, &index)) != -1) {
+ switch (rc) {
+ case 'r':
+ reset = 1;
+ break;
+ case 'R':
+ if(geteuid() != 0){
+ fprintf(stderr,"You have no rights to reset all shared memory"
+ " segments!\n");
+ return EXIT_FAILURE;
+ }
+ reset = 2;
+ break;
+ case 'd':
+ delete = 1;
+ break;
+ case 'D':
+ if(geteuid() != 0){
+ fprintf(stderr,"You have no rights to delete all shared memory"
+ " segments!\n");
+ return EXIT_FAILURE;
+ }
+
+ delete = 2;
+ break;
+ case 'U':
+ if((pswd = getpwnam(optarg)) == NULL){
+ fprintf(stderr, "The username %s is not known"
+ " on this system.\n", optarg );
+ return EXIT_FAILURE;
+ }
+ user = pswd->pw_uid;
+ break;
+ case 'S':
+ sum = 1;
+ break;
+ case 'A':
+ all = 1;
+ break;
+ case 'v':
+ print_version();
+ exit(0);
+ break;
+ case 'h':
+ print_help(basename(argv[0]));
+ exit(0);
+ default:
+ fprintf(stderr,
+ "Try '%s --help' for more information.\n",
+ basename(argv[0]));
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (optind < argc) {
+ fprintf(stderr, "%s: invalid option.\n\
+ Try '%s --help' for more information.\n",
+ argv[0], basename(argv[0]));
+ return EXIT_FAILURE;
+ }
+
+ if(delete == 2){
+ if(delete_all() == -1){
+ perror("deleteall: ");
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+ } else if(delete){
+ stats_mmap(user);
+ stats_munmap(SHM_DESTROY);
+ return EXIT_SUCCESS;
+ }
+ if(all){
+ char *usr;
+ stats_entry_t *entries;
+ while((usr = get_next_usr()) != NULL){
+ if((entries = malloc(sizeof(stats_entry_t)*ICA_NUM_STATS)) == NULL){
+ perror("malloc: ");
+ return EXIT_FAILURE;
+ }
+ get_stats_data(entries);;
+ printf("user: %s\n", usr);
+ print_stats(entries);
+ free(entries);
+ }
+ return EXIT_SUCCESS;
+ }
+
+ if (sum){
+ stats_entry_t *entries;
+ if((entries = malloc(sizeof(stats_entry_t)*ICA_NUM_STATS)) == NULL){
+ perror("malloc: ");
+ return EXIT_FAILURE;
+ }
+
+ if(!get_stats_sum(entries)){
+ perror("get_stats_sum: ");
+ return EXIT_FAILURE;
+ }
+ print_stats(entries);
+ return EXIT_SUCCESS;
+
+
+ }
+
+ if(reset == 2){
+ while(get_next_usr() != NULL)
+ stats_reset();
+ return EXIT_SUCCESS;
+
+ }
+ /* Need to open shm before it can be reseted */
+ if (stats_mmap(user)) {
+ fprintf(stderr, "Could not map shared memory region to local "
+ "address space.\n");
+ return EXIT_FAILURE;
+ }
+
+ if (reset) {
+ stats_reset();
+ } else{
+ stats_entry_t *stats;
+ if((stats = malloc(sizeof(stats_entry_t)*ICA_NUM_STATS)) == NULL){
+ perror("malloc: ");
+ return EXIT_FAILURE;
+ }
+ get_stats_data(stats);
+ print_stats(stats);
+
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/src/icastats_shared.c b/src/icastats_shared.c
new file mode 100644
index 0000000..3fa29d3
--- /dev/null
+++ b/src/icastats_shared.c
@@ -0,0 +1,314 @@
+/* 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.
+ */
+
+/**
+ * Authors: Christian Maaser <cmaaser@de.ibm.com>
+ * Holger Dengler <hd@linux.vnet.ibm.com>
+ * Benedikt Klotz <benedikt.klotz@de.ibm.com>
+ *
+ * Copyright IBM Corp. 2009, 2011, 2013
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include "icastats.h"
+
+#define NOT_INITIALIZED (-1)
+#define NAME_LENGHT 20
+
+static stats_entry_t *stats = NULL;
+volatile int stats_shm_handle = NOT_INITIALIZED;
+
+
+
+static void atomic_add(int *x, int i)
+{
+ int old;
+ int new;
+ asm volatile (" l %0,%2\n"
+ "0: lr %1,%0\n"
+ " ar %1,%3\n"
+ " cs %0,%1,%2\n"
+ " jl 0b"
+ :"=&d" (old), "=&d"(new), "=Q"(*x)
+ :"d"(i), "Q"(*x)
+ :"cc", "memory");
+}
+
+
+/* open shared memory segment
+ * Arguments:
+ * @user: if user is -1 stats_mmap will open the shared memory segent of the same
+ * user.
+ * If it is not -1, stats_mmap will treat it as uid and will open the shared memory
+ * segment of this userid
+ * return value:
+ * 0 - Success
+ * -1 - Error: See errno for errorcode
+ */
+
+int stats_mmap(int user)
+{
+ if (stats == NULL) {
+ char shm_id[NAME_LENGHT];
+ sprintf(shm_id, "icastats_%d", user == -1? geteuid(): user);
+
+ stats_shm_handle = shm_open(shm_id, O_CREAT | O_RDWR,
+ S_IRUSR | S_IWUSR);
+
+ if (stats_shm_handle == NOT_INITIALIZED)
+ return -1;
+ if (ftruncate(stats_shm_handle, STATS_SHM_SIZE) == -1)
+ return -1;
+
+ stats = (stats_entry_t *) mmap(NULL, STATS_SHM_SIZE, PROT_READ |
+ PROT_WRITE, MAP_SHARED,
+ stats_shm_handle, 0);
+ if (stats == MAP_FAILED){
+ close(stats_shm_handle);
+ stats = NULL;
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/* Close and/or delete the shared memory segment
+ * Argument:
+ * @unlink - if unlink is true the shared memory segment will be
+ * deleted. If it is false it will only be closed.
+ */
+
+void stats_munmap(int unlink)
+{
+ char shm_id[NAME_LENGHT];
+ sprintf(shm_id, "icastats_%d", geteuid());
+
+ if (stats == NULL)
+ return;
+
+ munmap(stats, STATS_SHM_SIZE);
+ close(stats_shm_handle);
+ stats_shm_handle = NOT_INITIALIZED;
+
+ if(unlink == SHM_DESTROY)
+ shm_unlink(shm_id);
+ stats = NULL;
+}
+
+/* query the shared memory segment for a specific field
+ * arguments:
+ * @field - the enum of the field see icastats.h
+ * @hardware - valid values are ALGO_SW for software statistics
+ * and ALGO_HW for hardware statistics
+ * @direction - valid values are ENCRYPT and DECRYPT
+ */
+
+uint32_t stats_query(stats_fields_t field, int hardware, int direction)
+{
+ if (stats == NULL)
+ return 0;
+
+ if (direction == ENCRYPT)
+ if (hardware == ALGO_HW)
+ return stats[field].enc.hw;
+ else
+ return stats[field].enc.sw;
+ else
+ if (hardware == ALGO_HW)
+ return stats[field].dec.hw;
+ else
+ return stats[field].dec.sw;
+}
+
+/* Returns the statistic data in a stats_entry_t array
+ * @entries - Needs to be a array of size ICA_NUM_STATS.
+ */
+
+void get_stats_data(stats_entry_t *entries)
+{
+ unsigned int i;
+ for(i = 0;i<ICA_NUM_STATS; i++){
+ entries[i].enc.hw = stats_query(i, ALGO_HW, ENCRYPT);
+ entries[i].enc.sw = stats_query(i, ALGO_SW, ENCRYPT);
+ entries[i].dec.hw = stats_query(i, ALGO_HW, DECRYPT);
+ entries[i].dec.sw = stats_query(i, ALGO_SW, DECRYPT);
+ }
+}
+
+
+
+/* get the statistic data from all shared memory segments
+ * accumulated in one variable
+ * @sum: sum must be array of the size of ICA_NUM_STATS
+ * After a call to this function sum contains the accumulated
+ * data of all shared memory segments.
+ * Return value:
+ * 1 - Success
+ * 0 - Error, check errno!
+ */
+
+int get_stats_sum(stats_entry_t *sum)
+{
+ unsigned int i;
+ struct dirent *direntp;
+ DIR *shmDir;
+
+ memset(sum, 0, sizeof(stats_entry_t)*ICA_NUM_STATS);
+ if((shmDir = opendir("/dev/shm")) == NULL)
+ return 0;
+
+ while((direntp = readdir(shmDir)) != NULL){
+ if(strstr(direntp->d_name, "icastats_") != NULL){
+ int fd;
+ stats_entry_t *tmp;
+
+ if((getpwuid(atoi(&direntp->d_name[9]))) == NULL){
+ closedir(shmDir);
+ return 0;
+ }
+
+ if ((fd = shm_open(direntp->d_name, O_RDONLY, 0)) == -1){
+ closedir(shmDir);
+ return 0;
+ }
+ if ((tmp = (stats_entry_t *)mmap(NULL, STATS_SHM_SIZE,
+ PROT_READ, MAP_SHARED,
+ fd, 0)) == MAP_FAILED){
+ closedir(shmDir);
+ close(fd);
+ return 0;
+ }
+
+ for(i = 0; i<ICA_NUM_STATS; ++i){
+ sum[i].enc.hw += tmp[i].enc.hw;
+ sum[i].enc.sw += tmp[i].enc.sw;
+ sum[i].dec.hw += tmp[i].dec.hw;
+ sum[i].dec.sw += tmp[i].dec.sw;
+ }
+ munmap(tmp, STATS_SHM_SIZE);
+ close(fd);
+ }
+ }
+ closedir(shmDir);
+ return 1;
+}
+
+/* Open the shared memory segment of the next user!
+ * Each call to this function will open one file of the
+ * /dev/shm directory. The function will return NULL when all files
+ * in the directory were opened.
+ * WARNING: You should never call this function only one time! Call this funtion in a loop with
+ * abort condition unequal NULL.
+ * The directory will reamin open if you don't wait for NULL!
+ * Return value:
+ * the name of the next user!
+ * It is NULL when all files were opened.
+ */
+
+char *get_next_usr()
+{
+ struct dirent *direntp;
+ static DIR *shmDir = NULL;
+
+ /* Closes shm and set stats NULL */
+ stats_munmap(SHM_CLOSE);
+
+ if(shmDir == NULL){
+ if((shmDir = opendir("/dev/shm")) == NULL)
+ return NULL;
+ }
+ while((direntp = readdir(shmDir)) != NULL){
+ if(strstr(direntp->d_name, "icastats_") != NULL){
+ int uid = atoi(&direntp->d_name[9]);
+ struct passwd *pwd;
+ if((pwd = getpwuid(uid)) == NULL)
+ return NULL;
+ if(stats_mmap(uid) == -1)
+ return NULL;
+
+ return pwd->pw_name;
+ } else{
+ continue;
+ }
+ }
+ closedir(shmDir);
+ shmDir = NULL;
+ return NULL;
+}
+
+/* increments a field of the shared memory segment
+ * arguments:
+ * @field - the enum of the field see icastats.h
+ * @hardware - valid values are ALGO_SW for software statistics
+ * and ALGO_HW for hardware statistics
+ * @direction - valid values are ENCRYPT and DECRYPT
+ */
+
+
+void stats_increment(stats_fields_t field, int hardware, int direction)
+{
+ if (stats == NULL)
+ return;
+
+ if(direction == ENCRYPT)
+ if (hardware == ALGO_HW)
+ atomic_add((int *)&stats[field].enc.hw, 1);
+ else
+ atomic_add((int *)&stats[field].enc.sw, 1);
+ else
+ if (hardware == ALGO_HW)
+ atomic_add((int *)&stats[field].dec.hw, 1);
+ else
+ atomic_add((int *)&stats[field].dec.sw, 1);
+}
+
+
+/* Reset the shared memory segment to zero
+ */
+void stats_reset()
+{
+ if (stats == NULL)
+ return;
+
+ memset(stats, 0, sizeof(stats_entry_t)*ICA_NUM_STATS);
+}
+
+
+/* Delete all shared memory segments
+ * Return values:
+ * 1 - Success
+ * 0 - Error, check errno!
+ */
+
+int delete_all()
+{
+ stats_munmap(SHM_DESTROY);
+ struct dirent *direntp;
+ DIR *shmDir;
+ if((shmDir = opendir("/dev/shm")) == NULL)
+ return 0;
+
+ while((direntp = readdir(shmDir)) != NULL){
+ if(strstr(direntp->d_name, "icastats_") != NULL){
+ if(shm_unlink(direntp->d_name) == -1)
+ return 0;
+ }
+ }
+ closedir(shmDir);
+ return 1;
+}
+
diff --git a/src/include/fips.h b/src/include/fips.h
new file mode 100644
index 0000000..57476ad
--- /dev/null
+++ b/src/include/fips.h
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ *
+ * Author(s): Patrick Steuer <patrick.steuer@de.ibm.com>
+ *
+ * Copyright IBM Corp. 2015
+ */
+
+#ifdef ICA_FIPS
+#ifndef FIPS_H
+#define FIPS_H
+
+#include "ica_api.h"
+
+#define FIPS_FLAG "/proc/sys/crypto/fips_enabled"
+
+extern int fips; /* module status */
+
+
+/*
+ * Initialize global fips var to 1 resp. 0 when FIPS_FLAG is 1 resp. 0 (or not
+ * present).
+ */
+void fips_init(void);
+
+/*
+ * Powerup tests: crypto algorithm test, SW/FW integrity test (not implemented
+ * yet), critical function test (no critical functions). The tests set the
+ * corresponding status flags.
+ */
+void fips_powerup_tests(void);
+
+/*
+ * List of non-fips-approved algorithms
+ */
+static const int FIPS_BLACKLIST[] = {DES_ECB, DES_CBC, DES_CBC_CS, DES_OFB,
+ DES_CFB, DES_CTR, DES_CTRLST, DES_CBC_MAC, DES_CMAC, P_RNG};
+static const size_t FIPS_BLACKLIST_LEN = sizeof(FIPS_BLACKLIST)
+ / sizeof(FIPS_BLACKLIST[0]);
+
+/*
+ * Returns 1 if the algorithm identified by @id is FIPS approved.
+ * Returns 0 otherwise.
+ */
+static inline int
+fips_approved(int id)
+{
+ int i;
+
+ for (i = 0; i < FIPS_BLACKLIST_LEN; i++) {
+ if (id == FIPS_BLACKLIST[i])
+ return 0;
+ }
+
+ return 1;
+}
+
+#endif /* FIPS_H */
+#endif /* ICA_FIPS */
diff --git a/src/include/icastats.h b/src/include/icastats.h
new file mode 100644
index 0000000..e96fb6c
--- /dev/null
+++ b/src/include/icastats.h
@@ -0,0 +1,125 @@
+/* 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.
+ */
+
+/**
+ * Authors: Christian Maaser <cmaaser@de.ibm.com>
+ * Benedikt Klotz <benedikt.klotz@de.ibm.com>
+ *
+ * Copyright IBM Corp. 2009, 2013
+ */
+
+#ifndef __ICA_STATS_H__
+#define __ICA_STATS_H__
+
+#include <stdint.h>
+
+
+typedef struct crypt_opts{
+ uint32_t hw;
+ uint32_t sw;
+} crypt_opts_t;
+
+typedef struct statis_entry {
+ crypt_opts_t enc;
+ crypt_opts_t dec;
+} stats_entry_t;
+
+
+typedef enum stats_fields {
+ /* crypt counter */
+ ICA_STATS_SHA1 = 0,
+ ICA_STATS_SHA224,
+ ICA_STATS_SHA256,
+ ICA_STATS_SHA384,
+ ICA_STATS_SHA512,
+ ICA_STATS_GHASH,
+ ICA_STATS_PRNG,
+ ICA_STATS_DRBGSHA512,
+ ICA_STATS_RSA_ME,
+ ICA_STATS_RSA_CRT, /* add new crypt counters above RSA_CRT
+ (see print_stats function) */
+
+ /* enc and dec counter */
+ ICA_STATS_DES_ECB,
+ ICA_STATS_DES_CBC,
+ ICA_STATS_DES_OFB,
+ ICA_STATS_DES_CFB,
+ ICA_STATS_DES_CTR,
+ ICA_STATS_DES_CMAC,
+ ICA_STATS_3DES_ECB,
+ ICA_STATS_3DES_CBC,
+ ICA_STATS_3DES_OFB,
+ ICA_STATS_3DES_CFB,
+ ICA_STATS_3DES_CTR,
+ ICA_STATS_3DES_CMAC,
+ ICA_STATS_AES_ECB,
+ ICA_STATS_AES_CBC,
+ ICA_STATS_AES_OFB,
+ ICA_STATS_AES_CFB,
+ ICA_STATS_AES_CTR,
+ ICA_STATS_AES_CMAC,
+ ICA_STATS_AES_XTS,
+
+ /* number of counters */
+ ICA_NUM_STATS
+} stats_fields_t;
+
+#define STAT_STRINGS \
+ "SHA-1", \
+ "SHA-224", \
+ "SHA-256", \
+ "SHA-384", \
+ "SHA-512", \
+ "GHASH", \
+ "P_RNG", \
+ "DRBG-SHA-512", \
+ "RSA-ME", \
+ "RSA-CRT", \
+ "DES ECB", \
+ "DES CBC", \
+ "DES OFB", \
+ "DES CFB", \
+ "DES CTR", \
+ "DES CMAC", \
+ "3DES ECB", \
+ "3DES CBC", \
+ "3DES OFB", \
+ "3DES CFB", \
+ "3DES CTR", \
+ "3DES CMAC", \
+ "AES ECB", \
+ "AES CBC", \
+ "AES OFB", \
+ "AES CFB", \
+ "AES CTR", \
+ "AES CMAC", \
+ "AES XTS"
+
+
+
+#define STATS_SHM_SIZE (sizeof(stats_entry_t) * ICA_NUM_STATS)
+#define ENCRYPT 1
+#define DECRYPT 0
+
+#define ALGO_SW 0
+#define ALGO_HW 1
+
+#define SHM_CLOSE 0
+#define SHM_DESTROY 1
+
+
+int stats_mmap(int user);
+void stats_munmap(int unlink);
+uint32_t stats_query(stats_fields_t field, int hardware, int direction);
+void get_stats_data(stats_entry_t *entries);
+void stats_increment(stats_fields_t field, int hardware, int direction);
+int get_stats_sum(stats_entry_t *sum);
+char *get_next_usr();
+void stats_reset();
+int delete_all();
+
+
+#endif
diff --git a/src/include/init.h b/src/include/init.h
new file mode 100644
index 0000000..fc60eee
--- /dev/null
+++ b/src/include/init.h
@@ -0,0 +1,26 @@
+/* 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.
+ */
+
+/**
+ * Authors: Felix Beck <felix.beck@de.ibm.com>
+ * Christian Maaser <cmaaser@de.ibm.com>
+ *
+ * Copyright IBM Corp. 2009
+ */
+
+#ifndef INIT_H
+#define INIT_H
+
+#include <signal.h>
+#include <setjmp.h>
+
+#define EXCEPTION_RV 20
+
+int begin_sigill_section(struct sigaction *oldact, sigset_t * oldset);
+void end_sigill_section(struct sigaction *oldact, sigset_t * oldset);
+
+#endif
+
diff --git a/src/include/s390_aes.h b/src/include/s390_aes.h
new file mode 100644
index 0000000..dc5f9be
--- /dev/null
+++ b/src/include/s390_aes.h
@@ -0,0 +1,725 @@
+/* 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.
+ */
+
+/**
+ * Authors: Felix Beck <felix.beck@de.ibm.com>
+ * Christian Maaser <cmaaser@de.ibm.com>
+ * Holger Dengler <hd@linux.vnet.ibm.com>
+ *
+ * Copyright IBM Corp. 2009, 2010, 2011
+ */
+
+#ifndef S390_AES_H
+#define S390_AES_H
+#include <openssl/aes.h>
+#include <openssl/crypto.h>
+#include <stdlib.h>
+
+#include <openssl/opensslconf.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif /* OPENSSL_FIPS */
+
+#include "fips.h"
+#include "ica_api.h"
+#include "icastats.h"
+#include "init.h"
+#include "s390_crypto.h"
+#include "s390_ctr.h"
+
+#define AES_BLOCK_SIZE 16
+
+static inline int __s390_aes_ctrlist(unsigned int fc, unsigned long data_length,
+ const unsigned char *in_data,
+ const unsigned char *ctrlist,
+ unsigned char *key,
+ unsigned char *out_data)
+{
+ int rc = EPERM;
+ int hardware = ALGO_HW;
+
+ if (*s390_msa4_functions[fc].enabled)
+ rc = s390_ctr_hw(s390_msa4_functions[fc].hw_fc,
+ data_length, in_data, key,
+ out_data, ctrlist);
+ if (rc) {
+ hardware = ALGO_SW;
+ return rc;
+ }
+ stats_increment(ICA_STATS_AES_CTR, hardware,
+ (s390_msa4_functions[fc].hw_fc &
+ S390_CRYPTO_DIRECTION_MASK) ==
+ 0 ?ENCRYPT:DECRYPT);
+ return rc;
+}
+
+
+
+static inline int s390_aes_ctrlist(unsigned int fc, unsigned long data_length,
+ const unsigned char *in_data,
+ const unsigned char *ctrlist,
+ unsigned char *key, unsigned char *out_data)
+{
+ int rc = 0;
+ unsigned char rest_in_data[AES_BLOCK_SIZE];
+ unsigned char rest_out_data[AES_BLOCK_SIZE];
+ unsigned long rest_data_length;
+ unsigned long tmp_data_length;
+
+ rest_data_length = data_length % AES_BLOCK_SIZE;
+ tmp_data_length = data_length - rest_data_length;
+
+ if (tmp_data_length) {
+ rc = __s390_aes_ctrlist(fc, tmp_data_length, in_data,
+ ctrlist, key, out_data);
+ if (rc)
+ return rc;
+ }
+
+ if (rest_data_length) {
+ memcpy(rest_in_data, in_data + tmp_data_length,
+ rest_data_length);
+
+ rc = __s390_aes_ctrlist(fc, AES_BLOCK_SIZE,
+ rest_in_data,
+ ctrlist + tmp_data_length,
+ key, rest_out_data);
+ if (rc)
+ return rc;
+
+ memcpy(out_data + tmp_data_length,
+ rest_out_data, rest_data_length);
+ }
+
+ return rc;
+}
+
+static inline int s390_aes_ctr(unsigned int fc, const unsigned char *in_data,
+ unsigned char *out_data, unsigned long data_length,
+ unsigned char *key, unsigned char *ctr,
+ unsigned int ctr_width)
+{
+ const unsigned char *src;
+ unsigned char *tmp_ctrlist = NULL;
+ unsigned long chunk_length;
+ unsigned long rest_length;
+ unsigned long tmp_length;
+
+ int rc = 0;
+
+ if (data_length <= AES_BLOCK_SIZE) {
+ /* short message handling */
+ rc = s390_aes_ctrlist(fc, data_length, in_data, ctr,
+ key, out_data);
+ if (rc)
+ goto free_out;
+
+ __inc_aes_ctr((struct uint128 *)ctr, ctr_width);
+ return rc;
+ }
+
+ /* find largest possible message chunk */
+ chunk_length = NEXT_BS(data_length, AES_BLOCK_SIZE);
+ tmp_ctrlist = malloc(chunk_length);
+
+ /* page size chunk fall back */
+ if ((!tmp_ctrlist) && (data_length > LARGE_MSG_CHUNK)) {
+ chunk_length = LARGE_MSG_CHUNK;
+ tmp_ctrlist = malloc(chunk_length);
+ }
+
+ /* single block chunk fall back */
+ if (!tmp_ctrlist)
+ chunk_length = AES_BLOCK_SIZE;
+
+ for (src = in_data, rest_length = data_length;
+ src < (in_data + data_length);
+ src += chunk_length, out_data += chunk_length,
+ rest_length -= chunk_length) {
+ tmp_length = (rest_length < chunk_length) ?
+ rest_length : chunk_length;
+ if (tmp_ctrlist) {
+ __fill_aes_ctrlist(tmp_ctrlist,
+ NEXT_BS(tmp_length, AES_BLOCK_SIZE),
+ (struct uint128 *)ctr, ctr_width);
+
+ rc = s390_aes_ctrlist(fc, tmp_length, src,
+ tmp_ctrlist, key, out_data);
+ if (rc)
+ goto free_out;
+ } else {
+ /* single block fall back */
+ rc = s390_aes_ctrlist(fc, tmp_length, src,
+ ctr, key, out_data);
+ if (rc)
+ goto free_out;
+
+ __inc_aes_ctr((struct uint128 *)ctr, ctr_width);
+ }
+ }
+
+free_out:
+ if (tmp_ctrlist)
+ free(tmp_ctrlist);
+
+ return rc;
+}
+
+static inline int s390_aes_ecb_hw(unsigned int function_code,
+ unsigned long input_length,
+ const unsigned char *input_data,
+ unsigned char *keys,
+ unsigned char *output_data)
+{
+ int rc = 0;
+ rc = s390_km(function_code, keys, output_data, input_data,
+ input_length);
+ if (rc >= 0)
+ return 0;
+ else
+ return EIO;
+}
+
+static inline int s390_aes_ecb_sw(unsigned int function_code,
+ unsigned long input_length,
+ const unsigned char *input_data,
+ unsigned char *keys,
+ unsigned char *output_data)
+{
+ AES_KEY aes_key;
+ unsigned int direction;
+ unsigned int key_size = (function_code & 0x0f) *
+ sizeof(ica_aes_key_single_t);
+
+#ifdef ICA_FIPS
+ if ((fips & ICA_FIPS_MODE) && (!FIPS_mode()))
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (function_code & S390_CRYPTO_DIRECTION_MASK) {
+ AES_set_decrypt_key(keys, key_size * 8, &aes_key);
+ direction = AES_DECRYPT;
+ } else {
+ AES_set_encrypt_key(keys, key_size * 8, &aes_key);
+ direction = AES_ENCRYPT;
+ }
+ int i;
+ for (i = 0; i < input_length; i += AES_BLOCK_SIZE) {
+ AES_ecb_encrypt(input_data + i, output_data + i,
+ &aes_key, direction);
+ }
+
+ return 0;
+}
+
+static inline int s390_aes_cbc_hw(unsigned int function_code,
+ unsigned long input_length,
+ const unsigned char *input_data,
+ unsigned char *iv,
+ unsigned char *keys,
+ unsigned char *output_data)
+{
+ struct {
+ ica_aes_vector_t iv;
+ ica_aes_key_len_256_t keys;
+ } key_buffer;
+ unsigned int key_size = (function_code & 0x0f) *
+ sizeof(ica_aes_key_single_t);
+
+ memcpy(&key_buffer.iv, iv, sizeof(ica_aes_vector_t));
+ memcpy(&key_buffer.keys, keys, key_size);
+
+ int rc = 0;
+ rc = s390_kmc(function_code, &key_buffer,
+ output_data, input_data, input_length);
+
+ memset(&key_buffer.keys, 0, key_size);
+
+ if (rc >= 0) {
+ memcpy(iv, &key_buffer.iv, sizeof(ica_aes_vector_t));
+ return 0;
+ } else
+ return EIO;
+}
+
+static inline int s390_aes_cbc_sw(unsigned int function_code,
+ unsigned long input_length,
+ const unsigned char *input_data,
+ unsigned char *iv,
+ unsigned char *keys,
+ unsigned char *output_data)
+{
+ AES_KEY aes_key;
+ unsigned int direction;
+ unsigned int key_size = (function_code & 0x0f) *
+ sizeof(ica_aes_key_single_t);
+
+#ifdef ICA_FIPS
+ if ((fips & ICA_FIPS_MODE) && (!FIPS_mode()))
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (function_code & S390_CRYPTO_DIRECTION_MASK) {
+ AES_set_decrypt_key(keys, key_size * 8, &aes_key);
+ direction = AES_DECRYPT;
+ } else {
+ AES_set_encrypt_key(keys, key_size * 8, &aes_key);
+ direction = AES_ENCRYPT;
+ }
+ AES_cbc_encrypt(input_data, output_data, input_length,
+ &aes_key, (unsigned char *) iv, direction);
+
+ return 0;
+}
+
+static inline int s390_aes_ecb(unsigned int fc, unsigned long data_length,
+ const unsigned char *in_data, unsigned char *key,
+ unsigned char *out_data)
+{
+ int rc = 1;
+ int hardware = ALGO_HW;
+
+ if (*s390_kmc_functions[fc].enabled)
+ rc = s390_aes_ecb_hw(s390_kmc_functions[fc].hw_fc,
+ data_length, in_data, key,
+ out_data);
+ if (rc) {
+ rc = s390_aes_ecb_sw(s390_kmc_functions[fc].hw_fc,
+ data_length, in_data, key,
+ out_data);
+ hardware = ALGO_SW;
+ }
+ stats_increment(ICA_STATS_AES_ECB,
+ hardware,
+ (s390_kmc_functions[fc].hw_fc &
+ S390_CRYPTO_DIRECTION_MASK) == 0 ?
+ ENCRYPT:DECRYPT);
+ return rc;
+}
+
+static inline int s390_aes_cbc(unsigned int fc, unsigned long data_length,
+ const unsigned char *in_data, unsigned char *iv,
+ unsigned char *key, unsigned char *out_data)
+{
+ int rc = 1;
+ int hardware = ALGO_HW;
+
+ if (*s390_kmc_functions[fc].enabled)
+ rc = s390_aes_cbc_hw(s390_kmc_functions[fc].hw_fc,
+ data_length, in_data, iv, key,
+ out_data);
+ if (rc) {
+ hardware = ALGO_SW;
+ rc = s390_aes_cbc_sw(s390_kmc_functions[fc].hw_fc,
+ data_length, in_data, iv, key,
+ out_data);
+ }
+ stats_increment(ICA_STATS_AES_CBC,
+ hardware, (s390_kmc_functions[fc].hw_fc &
+ S390_CRYPTO_DIRECTION_MASK) == 0 ?ENCRYPT:DECRYPT);
+ return rc;
+}
+
+static inline int s390_aes_cfb_hw(unsigned int function_code,
+ unsigned long input_length,
+ const unsigned char *input_data,
+ unsigned char *iv,
+ const unsigned char *keys,
+ unsigned char *output_data,
+ unsigned int lcfb)
+{
+ struct {
+ ica_aes_vector_t iv;
+ ica_aes_key_len_256_t keys;
+ } key_buffer;
+
+ unsigned int key_size = (function_code & 0x0f) *
+ sizeof(ica_aes_key_single_t);
+
+ memcpy(&key_buffer.iv, iv, sizeof(ica_aes_vector_t));
+ memcpy(&key_buffer.keys, keys, key_size);
+
+ int rc = -1;
+ rc = s390_kmf(function_code, &key_buffer,
+ output_data, input_data, input_length, &lcfb);
+
+ memset(&key_buffer.keys, 0, key_size);
+
+ if (rc >= 0) {
+ memcpy(iv, &key_buffer.iv, sizeof(ica_aes_vector_t));
+ return 0;
+ } else
+ return EIO;
+}
+
+static inline int __s390_aes_cfb(unsigned int fc, unsigned long data_length,
+ const unsigned char *in_data,
+ unsigned char *iv, const unsigned char *key,
+ unsigned char *out_data, unsigned int lcfb)
+{
+ int rc = 1;
+ int hardware = ALGO_HW;
+
+ if (*s390_msa4_functions[fc].enabled)
+ rc = s390_aes_cfb_hw(s390_msa4_functions[fc].hw_fc,
+ data_length, in_data, iv, key,
+ out_data, lcfb);
+ if (rc) {
+ hardware = ALGO_SW;
+ return EPERM;
+ }
+
+ stats_increment(ICA_STATS_AES_CFB, hardware,
+ (s390_kmc_functions[fc].hw_fc &
+ S390_CRYPTO_DIRECTION_MASK) == 0 ?
+ ENCRYPT:DECRYPT);
+
+ return rc;
+}
+
+static inline int s390_aes_cfb(unsigned int fc, unsigned long data_length,
+ const unsigned char *in_data, unsigned char *iv,
+ const unsigned char *key, unsigned char *out_data,
+ unsigned int lcfb)
+{
+ int rc = 0;
+ /* Temporary buffers with size of lcfb should be
+ * sufficiant, using static maximum lcfb instead. */
+ unsigned char rest_in_data[AES_BLOCK_SIZE];
+ unsigned char rest_out_data[AES_BLOCK_SIZE];
+ unsigned long rest_data_length;
+ unsigned long tmp_data_length;
+
+ rest_data_length = data_length % lcfb;
+ tmp_data_length = data_length - rest_data_length;
+
+ if (tmp_data_length) {
+ rc = __s390_aes_cfb(fc, tmp_data_length, in_data,
+ iv, key, out_data, lcfb);
+ if (rc)
+ return rc;
+ }
+
+ if (rest_data_length) {
+ memcpy(rest_in_data, in_data + tmp_data_length,
+ rest_data_length);
+
+ rc = __s390_aes_cfb(fc, lcfb, rest_in_data,
+ iv, key, rest_out_data, lcfb);
+ if (rc)
+ return rc;
+
+ memcpy(out_data + tmp_data_length,
+ rest_out_data, rest_data_length);
+ }
+
+ return rc;
+}
+
+static inline int s390_aes_ofb_hw(unsigned int function_code,
+ unsigned long input_length,
+ const unsigned char *input_data,
+ unsigned char *iv,
+ const unsigned char *keys,
+ unsigned char *output_data)
+{
+ struct {
+ ica_aes_vector_t iv;
+ ica_aes_key_len_256_t keys;
+ } key_buffer;
+
+ unsigned int key_size = (function_code & 0x0f) *
+ sizeof(ica_aes_key_single_t);
+
+ memcpy(&key_buffer.iv, iv, sizeof(ica_aes_vector_t));
+ memcpy(&key_buffer.keys, keys, key_size);
+
+ int rc = -1;
+
+ rc = s390_kmo(function_code, &key_buffer,
+ output_data, input_data, input_length);
+
+ memset(&key_buffer.keys, 0, key_size);
+
+ if (rc >= 0) {
+ memcpy(iv, &key_buffer.iv, sizeof(ica_aes_vector_t));
+ return 0;
+ } else
+ return EIO;
+}
+
+static inline int __s390_aes_ofb(unsigned int fc, unsigned long input_length,
+ const unsigned char *input_data,
+ unsigned char *iv, const unsigned char *keys,
+ unsigned char *output_data)
+{
+ int rc = EPERM;
+ int hardware = ALGO_HW;
+
+ if (*s390_msa4_functions[fc].enabled)
+ rc = s390_aes_ofb_hw(s390_msa4_functions[fc].hw_fc,
+ input_length, input_data, iv, keys,
+ output_data);
+ if (rc) {
+ hardware = ALGO_SW;
+ return rc;
+ }
+
+ stats_increment(ICA_STATS_AES_OFB, hardware,
+ (s390_kmc_functions[fc].hw_fc &
+ S390_CRYPTO_DIRECTION_MASK) == 0 ?
+ ENCRYPT:DECRYPT);
+ return rc;
+}
+
+static inline int s390_aes_ofb(unsigned int fc, unsigned long data_length,
+ const unsigned char *in_data,
+ unsigned char *iv, const unsigned char *key,
+ unsigned char *out_data)
+{
+ int rc = 0;
+ unsigned char rest_in_data[AES_BLOCK_SIZE];
+ unsigned char rest_out_data[AES_BLOCK_SIZE];
+ unsigned long rest_data_length;
+ unsigned long tmp_data_length;
+
+ rest_data_length = data_length % AES_BLOCK_SIZE;
+ tmp_data_length = data_length - rest_data_length;
+
+ if (tmp_data_length) {
+ rc = __s390_aes_ofb(fc, tmp_data_length, in_data,
+ iv, key, out_data);
+ if (rc)
+ return rc;
+ }
+
+ if (rest_data_length) {
+ memcpy(rest_in_data, in_data + tmp_data_length,
+ rest_data_length);
+
+ rc = __s390_aes_ofb(fc, AES_BLOCK_SIZE,
+ rest_in_data,
+ iv, key, rest_out_data);
+ if (rc)
+ return rc;
+
+ memcpy(out_data + tmp_data_length,
+ rest_out_data, rest_data_length);
+ }
+
+ return rc;
+}
+
+static inline int s390_aes_xts_parm(unsigned long function_code,
+ unsigned int key_size, unsigned char *key,
+ unsigned char *xts_parm)
+{
+ int rc = 0;
+ struct {
+ unsigned char keys[key_size];
+ ica_aes_vector_t tweak;
+ unsigned char block_seq[sizeof(ica_aes_vector_t)];
+ unsigned char intermediate_bit_idx[sizeof(ica_aes_vector_t)];
+ unsigned char xts_parameter[sizeof(ica_aes_vector_t)];
+ } parm_block;
+
+ memset(parm_block.block_seq, 0x00, sizeof(parm_block.block_seq));
+ memcpy(&parm_block.tweak, xts_parm,
+ sizeof(parm_block.tweak));
+ memcpy(&parm_block.keys, key, key_size);
+ memset(parm_block.intermediate_bit_idx, 0x00,
+ sizeof(parm_block.intermediate_bit_idx));
+
+ /* In PCC we do not differentiate between encryption and decryption */
+ rc = s390_pcc(function_code & 0x7f, &parm_block);
+
+ memset(&parm_block.keys, 0, key_size);
+
+ if (rc >= 0) {
+ memcpy(xts_parm, parm_block.xts_parameter,
+ sizeof(ica_aes_vector_t));
+ return 0;
+ } else
+ return EIO;
+}
+
+static inline int s390_aes_xts_msg_dec(unsigned long function_code,
+ unsigned long data_length,
+ const unsigned char *in_data,
+ unsigned char *out_data, void *param,
+ unsigned int key_size)
+{
+ int rc;
+ unsigned char tmp_in_data[AES_BLOCK_SIZE];
+ unsigned long rest_data_length;
+ unsigned long tmp_data_length;
+ struct {
+ unsigned char keys[key_size];
+ ica_aes_vector_t iv;
+ } tmp_param;
+
+ rest_data_length = data_length % AES_BLOCK_SIZE;
+ tmp_data_length = data_length - rest_data_length - AES_BLOCK_SIZE;
+
+ if (rest_data_length == 0) {
+ /* complete msg handling */
+ rc = s390_km(function_code, param,
+ out_data, in_data, data_length);
+ if (rc < 0)
+ return EIO;
+
+ return rc;
+ }
+
+ if (tmp_data_length) {
+ rc = s390_km(function_code, param,
+ out_data, in_data, tmp_data_length);
+ if (rc < 0)
+ return EIO;
+ }
+
+ /* backup iv n-1 */
+ memcpy(&tmp_param, param, sizeof(tmp_param));
+
+ /* dummy step to calculate iv n */
+ rc = s390_km(function_code, param, out_data + tmp_data_length, in_data + tmp_data_length, AES_BLOCK_SIZE);
+ if (rc < 0)
+ return EIO;
+
+ /* block n-1 (with iv n) */
+ rc = s390_km(function_code, param, out_data + tmp_data_length, in_data + tmp_data_length, AES_BLOCK_SIZE);
+ if (rc < 0)
+ return EIO;
+
+ memcpy(tmp_in_data,
+ in_data + tmp_data_length + AES_BLOCK_SIZE,
+ rest_data_length);
+ memcpy_r_allign(tmp_in_data, AES_BLOCK_SIZE,
+ out_data + tmp_data_length, AES_BLOCK_SIZE,
+ AES_BLOCK_SIZE - rest_data_length);
+ memcpy(out_data + tmp_data_length + AES_BLOCK_SIZE,
+ out_data + tmp_data_length, rest_data_length);
+
+ /* block n (with iv n-1) */
+ rc = s390_km(function_code, &tmp_param,
+ out_data + tmp_data_length,
+ tmp_in_data, AES_BLOCK_SIZE);
+ if (rc < 0)
+ return EIO;
+
+ return rc;
+}
+
+static inline int s390_aes_xts_msg_enc(unsigned long function_code,
+ unsigned long data_length,
+ const unsigned char *in_data,
+ unsigned char *out_data, void *param)
+{
+ int rc;
+ unsigned char tmp_in_data[AES_BLOCK_SIZE];
+ unsigned long rest_data_length;
+ unsigned long tmp_data_length;
+
+ rest_data_length = data_length % AES_BLOCK_SIZE;
+ tmp_data_length = data_length - rest_data_length;
+
+ /* tmp_data_length is at least AES_BLOCK_SIZE */
+ rc = s390_km(function_code, param,
+ out_data, in_data, tmp_data_length);
+ if (rc < 0)
+ return EIO;
+
+ if (rest_data_length) {
+ /* XTS cipher text stealing for uncomplete blocks */
+ memcpy(tmp_in_data,
+ in_data + tmp_data_length,
+ rest_data_length);
+ memcpy_r_allign(tmp_in_data, AES_BLOCK_SIZE,
+ out_data + (tmp_data_length - AES_BLOCK_SIZE),
+ AES_BLOCK_SIZE,
+ AES_BLOCK_SIZE - rest_data_length);
+ memcpy(out_data + tmp_data_length,
+ out_data + (tmp_data_length - AES_BLOCK_SIZE),
+ rest_data_length);
+
+ rc = s390_km(function_code, param,
+ out_data + (tmp_data_length - AES_BLOCK_SIZE),
+ tmp_in_data, AES_BLOCK_SIZE);
+ if (rc < 0)
+ return EIO;
+ }
+
+ return rc;
+}
+
+static inline int s390_aes_xts_hw(unsigned int function_code,
+ unsigned long input_length,
+ const unsigned char *input_data,
+ unsigned char *tweak,
+ unsigned char *key1,
+ unsigned char *key2,
+ unsigned int key_size,
+ unsigned char *output_data)
+{
+ int rc = -1;
+ /* This works similar as AES CBC, but uses km instead of kmc. Also we
+ * need to specify the parameter block in order with key first and
+ * XTS parameter behind. */
+ struct {
+ unsigned char keys[key_size];
+ ica_aes_vector_t iv;
+ } key_buffer;
+
+ memcpy(key_buffer.keys, key1, key_size);
+ memcpy(&key_buffer.iv, tweak, sizeof(ica_aes_vector_t));
+
+ /* Get XTS parameter through PCC first. */
+ rc = s390_aes_xts_parm(function_code, key_size, key2,
+ (unsigned char *) &key_buffer.iv);
+ if (rc)
+ return EIO;
+
+ if (function_code & S390_CRYPTO_DIRECTION_MASK)
+ rc = s390_aes_xts_msg_dec(function_code, input_length,
+ input_data, output_data, &key_buffer,
+ key_size);
+ else
+ rc = s390_aes_xts_msg_enc(function_code, input_length,
+ input_data, output_data, &key_buffer);
+
+ memset(key_buffer.keys, 0, key_size);
+
+ /* The iv/tweak is not updated for XTS mode. */
+ if (rc < 0)
+ return EIO;
+
+ return 0;
+}
+
+static inline int s390_aes_xts(unsigned int fc, unsigned long data_length,
+ const unsigned char *in_data, unsigned char *tweak,
+ unsigned char *key1, unsigned char *key2,
+ unsigned int key_length, unsigned char *out_data)
+{
+ int rc = 1;
+ int hardware = ALGO_HW;
+
+ if (*s390_msa4_functions[fc].enabled)
+ rc = s390_aes_xts_hw(s390_msa4_functions[fc].hw_fc,
+ data_length, in_data, tweak,
+ key1, key2, key_length, out_data);
+ if (rc) {
+ hardware = ALGO_SW;
+ return rc;
+ }
+
+ stats_increment(ICA_STATS_AES_XTS, hardware,
+ (s390_kmc_functions[fc].hw_fc &
+ S390_CRYPTO_DIRECTION_MASK) == 0 ?
+ ENCRYPT:DECRYPT);
+ return rc;
+}
+#endif
diff --git a/src/include/s390_cbccs.h b/src/include/s390_cbccs.h
new file mode 100644
index 0000000..dd5843e
--- /dev/null
+++ b/src/include/s390_cbccs.h
@@ -0,0 +1,319 @@
+/* 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.
+ */
+
+/**
+ * Authors: Holger Dengler <hd@linux.vnet.ibm.com>
+ *
+ * Copyright IBM Corp. 2011
+ */
+
+#include "s390_common.h"
+
+#ifndef S390_CBCCS_H
+#define S390_CBCCS_H
+
+static inline unsigned int
+cbccs_last_block_swap(unsigned char *base, unsigned long length,
+ unsigned int block_size,
+ unsigned int direction, unsigned int variant)
+{
+ unsigned char tmp[block_size];
+ unsigned long rest_length;
+ unsigned long head_length;
+
+ rest_length = length % block_size;
+
+ switch (variant) {
+ case 1:
+ /* keep last two blocks in order */
+ break;
+ case 2:
+ /* switch order of the last two blocks if length is not
+ * a multiple of the cipher block size, otherwise keep last
+ * two blocks in order */
+ if (rest_length == 0)
+ break;
+ case 3:
+ /* always switch order of the last two blocks */
+ if (rest_length == 0)
+ rest_length = block_size;
+ head_length = length - rest_length;
+
+ if (direction) {
+ /* encrypt */
+ memcpy(tmp,
+ base + (head_length - block_size) + rest_length,
+ block_size);
+ memcpy(base + head_length,
+ base + (head_length - block_size),
+ rest_length);
+ memcpy(base + (head_length - block_size),
+ tmp,
+ block_size);
+ } else {
+ /*decrypt */
+ memcpy(tmp,
+ base + (head_length - block_size),
+ block_size);
+ memcpy(base + (head_length - block_size),
+ base + head_length,
+ rest_length);
+ memcpy(base + (head_length - block_size) + rest_length,
+ tmp,
+ block_size);
+ }
+ break;
+ default:
+ /* unsupported variant */
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+static inline unsigned int
+s390_des_cbccs_enc(unsigned int fc, const unsigned char *in_data,
+ unsigned char *out_data, unsigned long data_length,
+ const unsigned char *key,
+ unsigned char *iv, unsigned int variant)
+{
+ unsigned int rc;
+ unsigned char tmp_in_data[DES_BLOCK_SIZE];
+ unsigned long rest_data_length;
+ unsigned long tmp_data_length;
+
+ rest_data_length = data_length % DES_BLOCK_SIZE;
+ tmp_data_length = data_length - rest_data_length;
+
+ /* tmp_data_length is at least DES_BLOCK_SIZE */
+ rc = s390_des_cbc(fc, tmp_data_length, in_data, iv, key, out_data);
+ if (rc)
+ return rc;
+
+ if (rest_data_length) {
+ /* zero padding for uncomplete last block */
+ memset(tmp_in_data, 0, DES_BLOCK_SIZE);
+ memcpy(tmp_in_data, in_data + tmp_data_length, rest_data_length);
+
+ rc = s390_des_cbc(fc, DES_BLOCK_SIZE, tmp_in_data, iv, key,
+ out_data + (tmp_data_length - DES_BLOCK_SIZE) +
+ rest_data_length);
+ if (rc)
+ return rc;
+ }
+
+ return cbccs_last_block_swap(out_data, data_length,
+ DES_BLOCK_SIZE, ICA_ENCRYPT, variant);
+}
+
+static inline unsigned int
+s390_des_cbccs_dec(unsigned int fc, const unsigned char *in_data,
+ unsigned char *out_data, unsigned long data_length,
+ const unsigned char *key,
+ unsigned char *iv, unsigned int variant)
+{
+ unsigned int rc;
+ unsigned char tmp_in_data[2* DES_BLOCK_SIZE];
+ unsigned long rest_data_length;
+ unsigned long swap_length;
+ unsigned long tmp_data_length;
+ unsigned char tmp_iv[DES_BLOCK_SIZE];
+ unsigned char tmp_out_data[DES_BLOCK_SIZE];
+
+ rest_data_length = data_length % DES_BLOCK_SIZE;
+ swap_length = (rest_data_length) ?
+ DES_BLOCK_SIZE + rest_data_length :
+ 2* DES_BLOCK_SIZE;
+ tmp_data_length = data_length - swap_length;
+
+ /* copy last 2 blocks to temporary buffer, because blocks can not
+ * be re-ordered in in_data (const) */
+ memset(tmp_in_data, 0, 2*DES_BLOCK_SIZE);
+ memcpy(tmp_in_data, in_data + tmp_data_length, swap_length);
+
+ rc = cbccs_last_block_swap(tmp_in_data, swap_length,
+ DES_BLOCK_SIZE, ICA_DECRYPT, variant);
+ if (rc)
+ return rc;
+
+ if (rest_data_length == 0) {
+ /* complete message handling */
+ if (tmp_data_length) {
+ rc = s390_des_cbc(fc, tmp_data_length, in_data,
+ iv, key, out_data);
+ if (rc)
+ return rc;
+ }
+
+ return s390_des_cbc(fc, swap_length, tmp_in_data,
+ iv, key, out_data + tmp_data_length);
+ }
+
+ if (tmp_data_length) {
+ rc = s390_des_cbc(fc, tmp_data_length, in_data,
+ iv, key, out_data);
+ if (rc)
+ return rc;
+ }
+
+ /* decrypt block C(n) with zero iv */
+ memset(tmp_iv, 0, DES_BLOCK_SIZE);
+ rc = s390_des_cbc(fc, DES_BLOCK_SIZE,
+ tmp_in_data + rest_data_length,
+ tmp_iv, key, tmp_out_data);
+ if(rc)
+ return rc;
+
+ /* complete block C*(n-1) to C(n-1) and decrypt it */
+ memcpy_r_allign(tmp_in_data, DES_BLOCK_SIZE,
+ tmp_out_data, DES_BLOCK_SIZE,
+ DES_BLOCK_SIZE - rest_data_length);
+ rc = s390_des_cbc(fc, DES_BLOCK_SIZE, tmp_in_data,
+ iv, key, out_data + tmp_data_length);
+ if(rc)
+ return rc;
+
+ /* XOR tmp_out_data with C*(n-1) */
+ block_xor(out_data + tmp_data_length + DES_BLOCK_SIZE,
+ tmp_in_data, tmp_out_data, rest_data_length);
+
+ return 0;
+}
+
+static inline unsigned int
+s390_aes_cbccs_enc(unsigned int fc, const unsigned char *in_data,
+ unsigned char *out_data, unsigned long data_length,
+ unsigned char *key, unsigned int key_length,
+ unsigned char *iv, unsigned int variant)
+{
+ unsigned int rc;
+ unsigned char tmp_in_data[AES_BLOCK_SIZE];
+ unsigned long rest_data_length;
+ unsigned long tmp_data_length;
+
+ rest_data_length = data_length % AES_BLOCK_SIZE;
+ tmp_data_length = data_length - rest_data_length;
+
+ /* tmp_data_length is at least AES_BLOCK_SIZE */
+ rc = s390_aes_cbc(fc, tmp_data_length, in_data, iv, key, out_data);
+ if (rc)
+ return rc;
+
+ if (rest_data_length) {
+ memset(tmp_in_data, 0, AES_BLOCK_SIZE);
+ memcpy(tmp_in_data, in_data + tmp_data_length, AES_BLOCK_SIZE);
+
+ rc = s390_aes_cbc(fc, AES_BLOCK_SIZE, tmp_in_data, iv, key,
+ out_data + (tmp_data_length - AES_BLOCK_SIZE) +
+ rest_data_length);
+ if (rc)
+ return rc;
+ }
+
+ return cbccs_last_block_swap(out_data, data_length,
+ AES_BLOCK_SIZE, ICA_ENCRYPT, variant);
+}
+
+static inline unsigned int
+s390_aes_cbccs_dec(unsigned int fc, const unsigned char *in_data,
+ unsigned char *out_data, unsigned long data_length,
+ unsigned char *key, unsigned int key_length,
+ unsigned char *iv, unsigned int variant)
+{
+ unsigned int rc;
+ unsigned char tmp_in_data[2* AES_BLOCK_SIZE];
+ unsigned long rest_data_length;
+ unsigned long swap_length;
+ unsigned long tmp_data_length;
+ unsigned char tmp_iv[AES_BLOCK_SIZE];
+ unsigned char tmp_out_data[AES_BLOCK_SIZE];
+
+ rest_data_length = data_length % AES_BLOCK_SIZE;
+ swap_length = (rest_data_length) ?
+ (AES_BLOCK_SIZE + rest_data_length) :
+ (2* AES_BLOCK_SIZE);
+ tmp_data_length = data_length - swap_length;
+
+ /* copy last 2 blocks to temporary buffer, because blocks can not
+ * be re-ordered in in_data (const) */
+ memset(tmp_in_data, 0, 2* AES_BLOCK_SIZE);
+ memcpy(tmp_in_data, in_data + tmp_data_length, swap_length);
+
+ rc = cbccs_last_block_swap(tmp_in_data, swap_length,
+ AES_BLOCK_SIZE, ICA_DECRYPT, variant);
+ if (rc)
+ return rc;
+
+ if (rest_data_length == 0) {
+ /* complete message handling */
+ if (tmp_data_length) {
+ rc = s390_aes_cbc(fc, tmp_data_length, in_data,
+ iv, key, out_data);
+ if (rc)
+ return rc;
+ }
+
+ return s390_aes_cbc(fc, swap_length, tmp_in_data,
+ iv, key, out_data + tmp_data_length);
+ }
+
+ if (tmp_data_length) {
+ rc = s390_aes_cbc(fc, tmp_data_length, in_data,
+ iv, key, out_data);
+ if (rc)
+ return rc;
+ }
+
+ /* decrypt block C(n) with zero iv */
+ memset(tmp_iv, 0, AES_BLOCK_SIZE);
+ rc = s390_aes_cbc(fc, AES_BLOCK_SIZE,
+ tmp_in_data + rest_data_length,
+ tmp_iv, key, tmp_out_data);
+ if(rc)
+ return rc;
+
+ /* complete block C*(n-1) to C(n-1) and decrypt it */
+ memcpy_r_allign(tmp_in_data, AES_BLOCK_SIZE,
+ tmp_out_data, AES_BLOCK_SIZE,
+ AES_BLOCK_SIZE - rest_data_length);
+ rc = s390_aes_cbc(fc, AES_BLOCK_SIZE, tmp_in_data,
+ iv, key, out_data + tmp_data_length);
+ if(rc)
+ return rc;
+
+ /* XOR tmp_out_data with C*(n-1) */
+ block_xor(out_data + tmp_data_length + AES_BLOCK_SIZE,
+ tmp_in_data, tmp_out_data, rest_data_length);
+
+ return 0;
+}
+
+static inline int s390_des_cbccs(unsigned int fc, const unsigned char *in_data,
+ unsigned char *out_data, unsigned long data_length,
+ unsigned char *key,
+ unsigned char *iv, unsigned int variant)
+{
+ if (s390_msa4_functions[fc].hw_fc & S390_CRYPTO_DIRECTION_MASK)
+ return s390_des_cbccs_dec(fc, in_data, out_data, data_length,
+ key, iv, variant);
+ else
+ return s390_des_cbccs_enc(fc, in_data, out_data, data_length,
+ key, iv, variant);
+}
+
+static inline int s390_aes_cbccs(unsigned int fc, const unsigned char *in_data,
+ unsigned char *out_data, unsigned long data_length,
+ unsigned char *key, unsigned int key_length,
+ unsigned char *iv, unsigned int variant)
+{
+ if (s390_msa4_functions[fc].hw_fc & S390_CRYPTO_DIRECTION_MASK)
+ return s390_aes_cbccs_dec(fc, in_data, out_data, data_length,
+ key, key_length, iv, variant);
+ else
+ return s390_aes_cbccs_enc(fc, in_data, out_data, data_length,
+ key, key_length, iv, variant);
+}
+#endif
diff --git a/src/include/s390_ccm.h b/src/include/s390_ccm.h
new file mode 100644
index 0000000..55564a8
--- /dev/null
+++ b/src/include/s390_ccm.h
@@ -0,0 +1,342 @@
+/* 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.
+ */
+
+/**
+ * Authors: Ruben Straus <rstraus@de.ibm.com>
+ * Holger Dengler <hd@linux.vnet.ibm.com>
+ *
+ * Copyright IBM Corp. 2010
+ */
+
+#ifndef S390_CCM_H
+#define S390_CCM_H
+
+#include "s390_ctr.h"
+
+#define S390_CCM_MAX_NONCE_LENGTH 13
+#define S390_CCM_MIN_NONCE_LENGTH 7
+#define S390_CCM_MAX_MAC_LENGTH 16
+#define S390_CCM_MIN_MAC_LENGTH 4
+
+/* assoc_data first meta block with data
+ * for small assoc_data_length */
+struct meta_ad_small {
+ uint16_t length;
+ unsigned char data[14];
+} __attribute__((packed));
+
+/* assoc_data first meta block with prefix and data
+ * for medium assoc_data_length */
+struct meta_ad_medium {
+ unsigned char prefix[2];
+ uint32_t length;
+ unsigned char data[10];
+} __attribute__((packed));
+
+/* assoc_data first meta block with prefix and data
+ * for large assoc_data_length */
+struct meta_ad_large {
+ unsigned char prefix[2];
+ uint64_t length;
+ unsigned char data[6];
+} __attribute__((packed));
+
+/* assoc_data meta block union with size cipher block size */
+typedef union {
+ struct meta_ad_small small;
+ struct meta_ad_medium medium;
+ struct meta_ad_large large;
+} __attribute__((packed)) ad_meta_t;
+
+static inline unsigned int fc_to_key_length(unsigned int function_code)
+{
+ switch(function_code | 0x7F) {
+ case S390_CRYPTO_AES_128_ENCRYPT:
+ return 128/8;
+ case S390_CRYPTO_AES_192_ENCRYPT:
+ return 192/8;
+ case S390_CRYPTO_AES_256_ENCRYPT:
+ default:
+ return 256/8;
+ }
+}
+
+static inline void __compute_meta_b0(const unsigned char *nonce,
+ unsigned long nonce_length,
+ unsigned long assoc_data_length,
+ uint64_t payload_length,
+ unsigned long mac_length,
+ unsigned char *meta_b0)
+{
+ struct {
+ uint8_t reserved :1;
+ uint8_t adata :1;
+ uint8_t t_enc :3;
+ uint8_t q_enc :3;
+ } __attribute__((packed)) meta_flags;
+
+ memset(meta_b0, 0x00, AES_BLOCK_SIZE);
+
+ /* meta flags */
+ memset(&meta_flags, 0x00, sizeof(meta_flags));
+ if (assoc_data_length)
+ meta_flags.adata = 1;
+
+ meta_flags.t_enc = (mac_length-2) / 2;
+ meta_flags.q_enc = (15 - nonce_length) - 1;
+
+ memcpy(meta_b0, &meta_flags, sizeof(meta_flags));
+
+ /* encoding N */
+ memcpy(meta_b0 + sizeof(meta_flags), nonce, nonce_length);
+
+ /* encoding Q */
+ memcpy_r_allign(meta_b0, AES_BLOCK_SIZE,
+ &payload_length, sizeof(payload_length),
+ AES_BLOCK_SIZE - (sizeof(meta_flags) + nonce_length));
+}
+
+static inline void __compute_initial_ctr(const unsigned char *nonce,
+ unsigned long nonce_length,
+ unsigned long payload_length,
+ unsigned char *ctr)
+{
+ struct {
+ uint8_t reserved :2;
+ uint8_t zero :3;
+ uint8_t q_enc :3;
+ } __attribute__((packed)) ctr_flags;
+
+ memset(ctr, 0x00, AES_BLOCK_SIZE);
+
+ memset(&ctr_flags, 0x00, sizeof(ctr_flags));
+ ctr_flags.q_enc = (15 - nonce_length) - 1;
+
+ memcpy(ctr, &ctr_flags, sizeof(ctr_flags));
+ memcpy(ctr + sizeof(ctr_flags), nonce, nonce_length);
+}
+
+static inline unsigned int __auth_assoc_data(unsigned int function_code,
+ const unsigned char *assoc_data,
+ uint64_t assoc_data_length,
+ const unsigned char *key,
+ unsigned int key_length,
+ unsigned char *iv)
+{
+ unsigned int rc;
+ ad_meta_t meta;
+ unsigned char *meta_data;
+ unsigned long meta_data_length;
+ unsigned char tmp_block[AES_BLOCK_SIZE];
+ const unsigned char *rest;
+ unsigned long rest_length;
+ unsigned long head_length;
+ unsigned long tail_length;
+
+ /* preparing first block of assoc_data */
+ if (assoc_data_length < ((1ull << 16)-(1ull << 8))) {
+ meta.small.length = assoc_data_length;
+ meta_data = meta.small.data;
+ meta_data_length = sizeof(meta.small.data);
+ } else if (assoc_data_length < (1ull << 32)) {
+ meta.medium.prefix[0] = 0xff;
+ meta.medium.prefix[1] = 0xfe;
+ meta.medium.length = assoc_data_length;
+ meta_data = meta.medium.data;
+ meta_data_length = sizeof(meta.medium.data);
+ } else {
+ meta.large.prefix[0] = 0xff;
+ meta.large.prefix[1] = 0xff;
+ meta.large.length = assoc_data_length;
+ meta_data = meta.large.data;
+ meta_data_length = sizeof(meta.large.data);
+ }
+
+ if (assoc_data_length < meta_data_length) {
+ memset(meta_data, 0x00, meta_data_length);
+ memcpy(meta_data, assoc_data, assoc_data_length);
+ rest_length = 0;
+ rest = NULL;
+ } else {
+ memcpy(meta_data, assoc_data, meta_data_length);
+ rest_length = assoc_data_length - meta_data_length;
+ rest = assoc_data + meta_data_length;
+ }
+
+ /* processing first block of assoc_data */
+ rc = s390_cmac(function_code,
+ (unsigned char *)&meta, AES_BLOCK_SIZE,
+ key_length, key,
+ AES_BLOCK_SIZE, NULL, /* cmac_intermediate */
+ iv);
+ if (rc)
+ return rc;
+
+ /* processing remaining assoc_data */
+ if (rest_length) {
+ tail_length = rest_length % AES_BLOCK_SIZE;
+ head_length = rest_length - tail_length;
+
+ if (head_length) {
+ rc = s390_cmac(function_code,
+ rest, head_length,
+ key_length, key,
+ AES_BLOCK_SIZE, NULL, /* cmac_intermediate */
+ iv);
+ if (rc)
+ return rc;
+
+ rest += head_length;
+ }
+
+ /* assoc_data padding */
+ if (tail_length) {
+ memset(tmp_block, 0x00, AES_BLOCK_SIZE);
+ memcpy(tmp_block, rest, tail_length);
+
+ rc = s390_cmac(function_code,
+ tmp_block, AES_BLOCK_SIZE,
+ key_length, key,
+ AES_BLOCK_SIZE, NULL, /* cmac_intermediate */
+ iv);
+ if (rc)
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
+static inline unsigned int s390_ccm_authenticate(unsigned int function_code,
+ const unsigned char *payload,
+ uint64_t payload_length,
+ const unsigned char *assoc_data,
+ unsigned long assoc_data_length,
+ const unsigned char *nonce,
+ unsigned int nonce_length,
+ unsigned char *tag,
+ unsigned int tag_length,
+ const unsigned char *key,
+ unsigned int key_length)
+{
+ unsigned int rc;
+ unsigned char meta_b0[AES_BLOCK_SIZE];
+ unsigned char tmp_block[AES_BLOCK_SIZE];
+ unsigned long head_length;
+ unsigned long tail_length;
+
+ /* compute meta information block B0 */
+ __compute_meta_b0(nonce, nonce_length,
+ assoc_data_length, payload_length, tag_length,
+ meta_b0);
+
+ /* kmac of first block (intermediate) */
+ memset(tag, 0x00, AES_BLOCK_SIZE);
+ rc = s390_cmac(function_code,
+ meta_b0, AES_BLOCK_SIZE,
+ key_length, key,
+ AES_BLOCK_SIZE, NULL, /* cmac_intermediate */
+ tag);
+ if (rc)
+ return rc;
+
+ /* kmac of assoc_data blocks (intermediate) */
+ if (assoc_data_length) {
+ rc = __auth_assoc_data(function_code,
+ assoc_data, assoc_data_length,
+ key, key_length,
+ tag);
+ if (rc)
+ return rc;
+ }
+
+ /* kmac of payload (intermediate) */
+ tail_length = payload_length % AES_BLOCK_SIZE;
+ head_length = payload_length - tail_length;
+
+ if (head_length) {
+ rc = s390_cmac(function_code,
+ payload, head_length,
+ key_length, key,
+ AES_BLOCK_SIZE, NULL, /* cmac_intermediate */
+ tag);
+ if (rc)
+ return rc;
+ }
+
+ if (tail_length) {
+ memset(tmp_block, 0x00, AES_BLOCK_SIZE);
+ memcpy(tmp_block, payload + head_length, tail_length);
+
+ rc = s390_cmac(function_code,
+ tmp_block, AES_BLOCK_SIZE,
+ key_length, key,
+ AES_BLOCK_SIZE, NULL, /* cmac_intermediate */
+ tag);
+ if (rc)
+ return rc;
+ }
+
+ return 0;
+}
+
+static inline unsigned int s390_ccm(unsigned int function_code,
+ unsigned char *payload, unsigned long payload_length,
+ unsigned char *ciphertext,
+ const unsigned char *assoc_data, unsigned long assoc_data_length,
+ const unsigned char *nonce, unsigned long nonce_length,
+ unsigned char *mac, unsigned long mac_length,
+ unsigned char *key)
+{
+ unsigned char initial_ctr[AES_BLOCK_SIZE];
+ unsigned char cipher_ctr[AES_BLOCK_SIZE];
+ unsigned char tag[AES_BLOCK_SIZE];
+ unsigned int ccm_ctr_width;
+ unsigned int rc;
+
+ /* compute initial counter */
+ __compute_initial_ctr(nonce, nonce_length, payload_length, initial_ctr);
+ ccm_ctr_width = (15 - nonce_length) * 8;
+
+ if (payload_length) {
+ /* compute counter for en-/decryption */
+ memcpy(cipher_ctr, initial_ctr, AES_BLOCK_SIZE);
+ __inc_aes_ctr((struct uint128 *)cipher_ctr, ccm_ctr_width);
+
+ /* en-/decrypt */
+ if (function_code % 2) {
+ /* decrypt */
+ rc = s390_aes_ctr(UNDIRECTED_FC(function_code),
+ ciphertext, payload, payload_length,
+ key, cipher_ctr, ccm_ctr_width);
+ if (rc)
+ return rc;
+ } else {
+ /*encrypt */
+ rc = s390_aes_ctr(UNDIRECTED_FC(function_code),
+ payload, ciphertext, payload_length,
+ key, cipher_ctr, ccm_ctr_width);
+ if (rc)
+ return rc;
+ }
+ }
+
+ /* generate tag */
+ rc = s390_ccm_authenticate(UNDIRECTED_FC(function_code),
+ payload, payload_length,
+ assoc_data, assoc_data_length,
+ nonce, nonce_length,
+ tag, mac_length,
+ key, fc_to_key_length(function_code));
+ if (rc)
+ return rc;
+
+ /* encrypt tag into mac */
+ return s390_aes_ctr(UNDIRECTED_FC(function_code),
+ tag, mac, mac_length,
+ key, initial_ctr, ccm_ctr_width);
+}
+#endif
diff --git a/src/include/s390_cmac.h b/src/include/s390_cmac.h
new file mode 100644
index 0000000..1358a9e
--- /dev/null
+++ b/src/include/s390_cmac.h
@@ -0,0 +1,194 @@
+/* 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.
+ */
+
+/**
+ * Authors: Ruben Straus <rstraus@de.ibm.com>
+ * Holger Dengler <hd@linux.vnet.ibm.com>
+ *
+ * Copyright IBM Corp. 2010, 2011
+ */
+
+#include <string.h>
+#include <errno.h>
+#include <openssl/aes.h>
+
+#include "ica_api.h"
+#include "icastats.h"
+#include "init.h"
+#include "s390_crypto.h"
+#include "s390_aes.h"
+#include "s390_des.h"
+
+#ifndef S390_CMAC
+#define S390_CMAC_H
+
+#define PARM_BLOCK_SIZE 72
+
+typedef unsigned char parm_block_t[PARM_BLOCK_SIZE];
+
+struct parm_block_lookup {
+ unsigned int block_size;
+ unsigned char *base;
+ uint8_t *ml;
+ unsigned char *message;
+ unsigned char *iv;
+ unsigned char *keys;
+};
+
+static inline void parm_block_lookup_init(struct parm_block_lookup *lookup,
+ parm_block_t base,
+ unsigned int block_size)
+{
+ lookup->block_size = block_size;
+ lookup->base = base;
+ lookup->ml = (uint8_t *)base;
+ lookup->message = (unsigned char *)(base + 8);
+ lookup->iv = (unsigned char *)(lookup->message + block_size);
+ lookup->keys = (unsigned char *)(lookup->iv + block_size);
+}
+
+static inline unsigned int fc_block_size(unsigned int fc)
+{
+ unsigned int rc;
+
+ switch(fc) {
+ case S390_CRYPTO_DEA_ENCRYPT:
+ case S390_CRYPTO_TDEA_128_ENCRYPT:
+ case S390_CRYPTO_TDEA_192_ENCRYPT:
+ rc = DES_BLOCK_SIZE;
+ break;
+ case S390_CRYPTO_AES_128_ENCRYPT:
+ case S390_CRYPTO_AES_192_ENCRYPT:
+ case S390_CRYPTO_AES_256_ENCRYPT:
+ default:
+ rc = AES_BLOCK_SIZE;
+ break;
+ }
+
+ return rc;
+}
+
+static inline void _stats_increment(unsigned int fc, int hw, int direction)
+{
+ switch(fc) {
+ case 1:
+ case 9:
+ stats_increment(ICA_STATS_DES_CMAC, hw, direction);
+ break;
+ case 2:
+ case 3:
+ case 10:
+ case 11:
+ stats_increment(ICA_STATS_3DES_CMAC, hw, direction);
+ break;
+ case 18:
+ case 19:
+ case 20:
+ case 26:
+ case 27:
+ case 28:
+ stats_increment(ICA_STATS_AES_CMAC, hw, direction);
+ break;
+ default:
+ break;
+ }
+}
+
+static inline int s390_cmac_hw(unsigned long fc,
+ const unsigned char *message,
+ unsigned long message_length,
+ unsigned int key_size, const unsigned char *key,
+ unsigned int cmac_length, unsigned char *cmac,
+ unsigned char *iv)
+{
+ parm_block_t parm_block;
+ struct parm_block_lookup pb_lookup;
+ unsigned int length_tail;
+ unsigned long length_head;
+ int rc;
+
+ /* CMAC uses encrypt function code for generate and verify. */
+ fc &= S390_CRYPTO_FUNCTION_MASK;
+ memset(parm_block, 0, sizeof(parm_block));
+
+ parm_block_lookup_init(&pb_lookup, parm_block, fc_block_size(fc));
+ memcpy(pb_lookup.keys, key, key_size);
+
+ /* copy iv into param block, if available (intermediate) */
+ if (iv != NULL)
+ memcpy(pb_lookup.iv, iv, pb_lookup.block_size);
+
+
+ if (cmac == NULL) {
+ /* intermediate */
+ rc = s390_kmac(fc, pb_lookup.iv, message, message_length);
+ memset(pb_lookup.keys, 0, key_size);
+ if (rc < 0)
+ return rc;
+
+ _stats_increment(fc, ALGO_HW, ENCRYPT);
+
+ /* rescue iv for chained calls (intermediate) */
+ memcpy(iv, pb_lookup.iv, pb_lookup.block_size);
+ } else {
+ if (message_length) {
+ length_tail = message_length % pb_lookup.block_size;
+ if (length_tail)
+ length_head = message_length - length_tail;
+ else {
+ length_head = message_length - pb_lookup.block_size;
+ length_tail = pb_lookup.block_size;
+ }
+
+ if (length_head) {
+ rc = s390_kmac(fc, pb_lookup.iv,
+ message, length_head);
+ if (rc < 0) {
+ memset(pb_lookup.keys, 0, key_size);
+ return EIO;
+ }
+ _stats_increment(fc, ALGO_HW, ENCRYPT);
+ }
+
+ *pb_lookup.ml = length_tail * 8; /* message length in bits */
+ memcpy(pb_lookup.message, message + length_head, length_tail);
+ }
+ /* calculate final block (last/full) */
+ rc = s390_pcc(fc, pb_lookup.base);
+ memset(pb_lookup.keys, 0, key_size);
+ if (rc < 0)
+ return EIO;
+
+ _stats_increment(fc, ALGO_HW, ENCRYPT);
+ memcpy(cmac, pb_lookup.iv, cmac_length);
+ }
+
+ return 0;
+}
+
+static inline int s390_cmac(unsigned long fc,
+ const unsigned char *message,
+ unsigned long message_length,
+ unsigned int key_length, const unsigned char *key,
+ unsigned int mac_length, unsigned char *mac,
+ unsigned char *iv)
+{
+ int rc;
+
+ if (*s390_msa4_functions[fc].enabled)
+ rc = s390_cmac_hw(s390_msa4_functions[fc].hw_fc,
+ message, message_length,
+ key_length, key,
+ mac_length, mac,
+ iv);
+ else {
+ return EPERM;
+ }
+
+ return rc;
+}
+#endif
+
diff --git a/src/include/s390_common.h b/src/include/s390_common.h
new file mode 100644
index 0000000..e66baa8
--- /dev/null
+++ b/src/include/s390_common.h
@@ -0,0 +1,40 @@
+/* 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.
+ */
+
+/**
+ * Authors: Holger Dengler <hd@linux.vnet.ibm.com>
+ *
+ * Copyright IBM Corp. 2011
+ */
+#include <stdint.h>
+
+#ifndef S390_COMMON_H
+#define S390_COMMON_H
+
+#define UNDIRECTED_FC(x) (((x)/2)*2)
+
+struct uint128 {
+ uint64_t g[2];
+};
+
+static inline void block_xor(unsigned char dest[], unsigned char a[],
+ unsigned char b[], unsigned int length)
+{
+ unsigned int i;
+ for (i = 0; i < length; i++) {
+ dest[i] = a[i] ^ b[i];
+ }
+}
+
+static inline void memcpy_r_allign(void *dest, int dest_bs,
+ void *src, int src_bs, int size)
+{
+ memcpy((unsigned char *)dest + (dest_bs - size),
+ (unsigned char *)src + (src_bs - size), size);
+}
+
+#endif /* S390_COMMON_H */
+
diff --git a/src/include/s390_crypto.h b/src/include/s390_crypto.h
new file mode 100644
index 0000000..e969eec
--- /dev/null
+++ b/src/include/s390_crypto.h
@@ -0,0 +1,485 @@
+/* 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.
+ */
+
+/*
+ * Support for s390 cryptographic instructions.
+ *
+ * Author(s): Thomas Spatzier
+ * Jan Glauber <jan.glauber@de.ibm.com>
+ * Ralph Wuerthner <rwuerthn@de.ibm.com>
+ * Felix Beck <felix.beck@de.ibm.com>
+ * Christian Maaser <cmaaser@de.ibm.com>
+ * Holger Dengler <hd@linux.vnet.ibm.com>
+ * Ingo Tuchscherer <ingo.tuchscherer.linux.vnet.ibm.com>
+ *
+ * Copyright IBM Corp. 2007, 2009, 2011, 2013
+ */
+#include <ica_api.h>
+
+#ifndef S390_CRYPTO_H
+#define S390_CRYPTO_H
+
+#define S390_CRYPTO_TEST_MASK(mask, function) \
+ (((unsigned char *)(mask))[((function) & 0x7F) >> 3] & \
+ (0x80 >> ((function) & 0x07)))
+
+#define KM 1
+#define KMC 2
+#define KIMD 3
+#define MSA4 4
+#define ADAPTER 5
+#define PPNO 6
+
+enum s390_crypto_instruction {
+ S390_CRYPTO_DIRECTION_MASK = 0x80,
+ S390_CRYPTO_FUNCTION_MASK = 0x7f
+};
+
+enum s390_crypto_function {
+ /*
+ * The S390_QUERY function is always available for all 4 KM, KMC, KIMD and
+ * KLMD instructions and the PPNO instructions to query the available functions.
+ */
+ S390_CRYPTO_QUERY = 0x00,
+ /*
+ * The S390_SHA_* functions are available for KIMD and KLMD instructions.
+ */
+ S390_CRYPTO_SHA_1 = 0x01,
+ S390_CRYPTO_SHA_256 = 0x02,
+ S390_CRYPTO_SHA_512 = 0x03,
+ S390_CRYPTO_GHASH = 0x41,
+ /*
+ * The following functions are available for KM,KMC,KMF,KMO,
+ * and KMCTR instructions.
+ */
+ S390_CRYPTO_DEA_ENCRYPT = 0x01,
+ S390_CRYPTO_DEA_DECRYPT = 0x01 | 0x80,
+ S390_CRYPTO_TDEA_128_ENCRYPT = 0x02,
+ S390_CRYPTO_TDEA_128_DECRYPT = 0x02 | 0x80,
+ S390_CRYPTO_TDEA_192_ENCRYPT = 0x03,
+ S390_CRYPTO_TDEA_192_DECRYPT = 0x03 | 0x80,
+ S390_CRYPTO_AES_128_ENCRYPT = 0x12,
+ S390_CRYPTO_AES_128_DECRYPT = 0x12 | 0x80,
+ S390_CRYPTO_AES_192_ENCRYPT = 0x13,
+ S390_CRYPTO_AES_192_DECRYPT = 0x13 | 0x80,
+ S390_CRYPTO_AES_256_ENCRYPT = 0x14,
+ S390_CRYPTO_AES_256_DECRYPT = 0x14 | 0x80,
+ /* XTS is only available for the KM instruction */
+ S390_CRYPTO_AES_128_XTS_ENCRYPT = 0x32,
+ S390_CRYPTO_AES_128_XTS_DECRYPT = 0x32 | 0x80,
+ S390_CRYPTO_AES_256_XTS_ENCRYPT = 0x34,
+ S390_CRYPTO_AES_256_XTS_DECRYPT = 0x34 | 0x80,
+ /*
+ * The S390_PRNG is only available for the KMC instruction.
+ */
+ S390_CRYPTO_PRNG = 0x43,
+ /*
+ * The S390_SHA512_DRNG_* functions are available for the PPNO instruction.
+ */
+ S390_CRYPTO_SHA512_DRNG_GEN = 0x03,
+ S390_CRYPTO_SHA512_DRNG_SEED = 0x03 | 0x80
+};
+
+extern unsigned int sha1_switch, sha256_switch, sha512_switch, des_switch,
+ tdes_switch, aes128_switch, aes192_switch, aes256_switch,
+ prng_switch, tdea128_switch, tdea192_switch, sha512_drng_switch,
+ msa4_switch, msa5_switch;
+
+typedef struct {
+ unsigned int dummy_fc;
+ unsigned int hw_fc;
+ unsigned int *enabled;
+} s390_supported_function_t;
+
+/* Append new dummy fc codes to the end of enumeration. They are used as index
+ * to get the right fc code for the hardware. */
+typedef enum {
+ SHA_1,
+ SHA_224,
+ SHA_256,
+ SHA_384,
+ SHA_512,
+ GHASH
+} kimd_functions_t;
+
+typedef enum {
+ CMAC_AES_128_GENERATE,
+ CMAC_AES_128_VERIFY,
+ CMAC_AES_192_GENERATE,
+ CMAC_AES_192_VERIFY,
+ CMAC_AES_256_GENERATE,
+ CMAC_AES_256_VERIFY
+} pcc_functions_t;
+
+typedef enum {
+ SHA512_DRNG_GEN,
+ SHA512_DRNG_SEED
+} ppno_functions_t;
+
+extern s390_supported_function_t s390_kmc_functions[];
+extern s390_supported_function_t s390_msa4_functions[];
+extern s390_supported_function_t s390_kimd_functions[];
+extern s390_supported_function_t s390_ppno_functions[];
+
+void s390_crypto_switches_init(void);
+
+/**
+ * s390_pcc:
+ * @func: the function code passed to KM; see s390_kmc_func *
+ * @param: address of parameter block; see POP for details on each func
+ *
+ * Executes the PCC operation of the CPU.
+ *
+ * Returns -1 for failure, 0 for the query func, number of processed
+ * bytes for encryption/decryption funcs
+ */
+static inline int s390_pcc(unsigned long func, void *param)
+{
+ register long __func asm("0") = func;
+ register void *__param asm("1") = param;
+
+ asm volatile (
+ "0: .long 0xb92c0000 \n"
+ " brc 1, 0b \n"
+ :
+ : "d"(__func), "a"(__param)
+ : "cc", "memory");
+ return 0;
+}
+
+/**
+ * s390_kmac:
+ * @func: the function code passed to KMAC; see s390_kmac_func
+ * @param: address of parameter block; see POP for details on each func
+ * @src: address of source memory area
+ * @src_len: length of src operand in bytes
+ *
+ * Executes the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) operation of the CPU.
+ *
+ * Returns -1 for failure, 0 for the query func, number of processed
+ * bytes for encryption/decryption funcs
+ */
+static inline int s390_kmac(unsigned long func, void *param,
+ const unsigned char *src, long src_len)
+{
+ register long __func asm("0") = func;
+ register void *__param asm("1") = param;
+ register const unsigned char *__src asm("2") = src;
+ register long __src_len asm("3") = src_len;
+
+ asm volatile (
+ "0: .insn rre, 0xb91e0000,%0,%0 \n"
+ " brc 1, 0b \n"
+ : "+a"(__src), "+d"(__src_len)
+ : "d"(__func), "a"(__param)
+ : "cc", "memory");
+ return func ? src_len - __src_len : __src_len;
+}
+
+/**
+ * s390_kmctr:
+ * @func: the function code passed to KMCTR; see s390_km_func
+ * @param: address of parameter block; see POP for details on each func
+ * @dest: address of destination memory area
+ * @src: address of source memory area
+ * @src_len: length of src operand in bytes
+ *
+ * Executes the KMCTR (CIPHER MESSAGE WITH COUNTER) operation of the CPU.
+ *
+ * Returns -1 for failure, 0 for the query func, number of processed
+ * bytes for encryption/decryption funcs
+ */
+static inline int s390_kmctr(unsigned long func, void *param, unsigned char *dest,
+ const unsigned char *src, long src_len,
+ unsigned char *counter)
+{
+ register long __func asm("0") = func;
+ register void *__param asm("1") = param;
+ register const unsigned char *__src asm("2") = src;
+ register long __src_len asm("3") = src_len;
+ register unsigned char *__dest asm("4") = dest;
+ register unsigned char *__ctr asm("6") = counter;
+
+ asm volatile(
+ "0: .insn rrf,0xb92d0000,%2,%0,%3,0 \n"
+ "1: brc 1,0b \n"
+ : "+a" (__src), "+d" (__src_len), "+a" (__dest), "+a" (__ctr)
+ : "d" (__func), "a" (__param)
+ : "cc", "memory");
+
+ return func ? src_len - __src_len : __src_len;
+}
+
+/**
+ * s390_kmf:
+ * @func: the function code passed to KMF; see s390_kmf_func
+ * @param: address of parameter block; see POP for details on each func
+ * @dest: address of destination memory area
+ * @src: address of source memory area
+ * @src_len: length of src operand in bytes
+ *
+ * Executes the KMF (CIPHER MESSAGE) operation of the CPU.
+ *
+ * Returns -1 for failure, 0 for the query func, number of processed
+ * bytes for encryption/decryption funcs
+ */
+static inline int s390_kmf(unsigned long func, void *param, unsigned char *dest,
+ const unsigned char *src, long src_len, unsigned int *lcfb)
+{
+ register long __func asm("0") = ((*lcfb & 0x000000ff) << 24) | func;
+ register void *__param asm("1") = param;
+ register const unsigned char *__src asm("2") = src;
+ register long __src_len asm("3") = src_len;
+ register unsigned char *__dest asm("4") = dest;
+
+ asm volatile (
+ "0: .insn rre,0xb92a0000,%2,%0 \n"
+ " brc 1,0b \n"
+ : "+a"(__src), "+d"(__src_len), "+a"(__dest)
+ : "d"(__func), "a"(__param)
+ : "cc", "memory");
+
+ return func ? src_len - __src_len : __src_len;
+}
+
+/**
+ * s390_kmo:
+ * @func: the function code passed to KMO; see s390_kmc_func
+ * @param: address of parameter block; see POP for details on each func
+ * @dest: address of destination memory area
+ * @src: address of source memory area
+ * @src_len: length of src operand in bytes
+ *
+ * Executes the KMO (CIPHER MESSAGE WITH CHAINING) operation of the CPU.
+ *
+ * Returns -1 for failure, 0 for the query func, number of processed
+ * bytes for encryption/decryption funcs
+ */
+static inline int s390_kmo(unsigned long func, void *param, unsigned char *dest,
+ const unsigned char *src, long src_len)
+{
+ register long __func asm("0") = func;
+ register void *__param asm("1") = param;
+ register const unsigned char *__src asm("2") = src;
+ register long __src_len asm("3") = src_len;
+ register unsigned char *__dest asm("4") = dest;
+
+ asm volatile (
+ "0: .insn rre, 0xb92b0000,%2,%0 \n"
+ " brc 1, 0b \n"
+ : "+a"(__src), "+d"(__src_len), "+a"(__dest)
+ : "d"(__func), "a"(__param)
+ : "cc", "memory");
+
+ return func ? src_len - __src_len : __src_len;
+}
+
+/**
+ * s390_km:
+ * @func: the function code passed to KM; see s390_km_func
+ * @param: address of parameter block; see POP for details on each func
+ * @dest: address of destination memory area
+ * @src: address of source memory area
+ * @src_len: length of src operand in bytes
+ *
+ * Executes the KM (CIPHER MESSAGE) operation of the CPU.
+ *
+ * Returns -1 for failure, 0 for the query func, number of processed
+ * bytes for encryption/decryption funcs
+ */
+static inline int s390_km(unsigned long func, void *param, unsigned char *dest,
+ const unsigned char *src, long src_len)
+{
+ register long __func asm("0") = func;
+ register void *__param asm("1") = param;
+ register const unsigned char *__src asm("2") = src;
+ register long __src_len asm("3") = src_len;
+ register unsigned char *__dest asm("4") = dest;
+
+ asm volatile (
+ "0: .insn rre,0xb92e0000,%2,%0 \n" /* KM opcode */
+ " brc 1,0b \n" /* handle partial completion */
+ : "+a"(__src), "+d"(__src_len), "+a"(__dest)
+ : "d"(__func), "a"(__param)
+ : "cc", "memory");
+
+ return func ? src_len - __src_len : __src_len;
+}
+
+/**
+ * s390_kmc:
+ * @func: the function code passed to KM; see s390_kmc_func
+ * @param: address of parameter block; see POP for details on each func
+ * @dest: address of destination memory area
+ * @src: address of source memory area
+ * @src_len: length of src operand in bytes
+ *
+ * Executes the KMC (CIPHER MESSAGE WITH CHAINING) operation of the CPU.
+ *
+ * Returns -1 for failure, 0 for the query func, number of processed
+ * bytes for encryption/decryption funcs
+ */
+static inline int s390_kmc(unsigned long func, void *param, unsigned char *dest,
+ const unsigned char *src, long src_len)
+{
+ register long __func asm("0") = func;
+ register void *__param asm("1") = param;
+ register const unsigned char *__src asm("2") = src;
+ register long __src_len asm("3") = src_len;
+ register unsigned char *__dest asm("4") = dest;
+
+ asm volatile (
+ "0: .insn rre, 0xb92f0000,%2,%0 \n" /* KMC opcode */
+ " brc 1, 0b \n" /* handle partial completion */
+ : "+a"(__src), "+d"(__src_len), "+a"(__dest)
+ : "d"(__func), "a"(__param)
+ : "cc", "memory");
+
+ return func ? src_len - __src_len : __src_len;
+}
+
+/**
+ * s390_kimd:
+ * @func: the function code passed to KM; see s390_kimd_func
+ * @param: address of parameter block; see POP for details on each func
+ * @src: address of source memory area
+ * @src_len: length of src operand in bytes
+ *
+ * Executes the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) operation
+ * of the CPU.
+ *
+ * Returns -1 for failure, 0 for the query func, number of processed
+ * bytes for digest funcs
+ */
+static inline int s390_kimd(unsigned long func, void *param,
+ const unsigned char *src, long src_len)
+{
+ register long __func asm("0") = func;
+ register void *__param asm("1") = param;
+ register const unsigned char *__src asm("2") = src;
+ register long __src_len asm("3") = src_len;
+
+ asm volatile (
+ "0: .insn rre,0xb93e0000,%0,%0 \n" /* KIMD opcode */
+ " brc 1,0b \n" /* handle partial completion */
+ : "+a"(__src), "+d"(__src_len)
+ : "d"(__func), "a"(__param)
+ : "cc", "memory");
+
+ return func ? src_len - __src_len : __src_len;
+}
+
+/**
+ * s390_klmd:
+ * @func: the function code passed to KM; see s390_klmd_func
+ * @param: address of parameter block; see POP for details on each func
+ * @src: address of source memory area
+ * @src_len: length of src operand in bytes
+ *
+ * Executes the KLMD (COMPUTE LAST MESSAGE DIGEST) operation of the CPU.
+ *
+ * Returns -1 for failure, 0 for the query func, number of processed
+ * bytes for digest funcs
+ */
+static inline int s390_klmd(unsigned long func, void *param, const unsigned char *src,
+ long src_len)
+{
+ register long __func asm("0") = func;
+ register void *__param asm("1") = param;
+ register const unsigned char *__src asm("2") = src;
+ register long __src_len asm("3") = src_len;
+
+ asm volatile (
+ "0: .insn rre,0xb93f0000,%0,%0 \n" /* KLMD opcode */
+ " brc 1,0b \n" /* handle partial completion */
+ : "+a"(__src), "+d"(__src_len)
+ : "d"(__func), "a"(__param)
+ : "cc", "memory");
+
+ return func ? src_len - __src_len : __src_len;
+}
+
+/*
+ * s390_ppno:
+ *
+ * @func: FUNction code. See s390_ppno_func.
+ * @param: PARAMeter block.
+ * @dest: DESTination. Address of destination memory area.
+ * @dest_len: Byte length of @dest
+ * @src: SouRCe. Address of source memory area.
+ * @src_len: Byte length of @src
+ *
+ * Executes the PPNO (Perform Pseudorandom Number Operation) operation of the
+ * CPU. See POP for details.
+ *
+ * @return:
+ * -1 Failure.
+ * 0 Success.
+ * no. of processed bytes
+ */
+static inline int s390_ppno(long func,
+ void *param,
+ unsigned char *dest,
+ long dest_len,
+ const unsigned char *src,
+ long src_len)
+{
+ register long __func asm("0") = func;
+ register void *__param asm("1") = param;
+ register unsigned char *__dest asm("2") = dest;
+ register long __dest_len asm("3") = dest_len;
+ register const unsigned char *__src asm("4") = src;
+ register long __src_len asm("5") = src_len;
+ int ret = -1;
+
+ asm volatile(
+ "0: .insn rre,0xb93c0000,%1,%5\n\t" /* PPNO opcode */
+ " brc 1,0b\n\t" /* handle partial completion */
+ " la %0,0\n\t"
+ : "+d" (ret), "+a"(__dest), "+d"(__dest_len)
+ : "d"(__func), "a"(__param), "a"(__src), "d"(__src_len)
+ : "cc", "memory"
+ );
+
+ if(ret < 0)
+ return ret;
+
+ return func ? dest_len - __dest_len : 0;
+}
+
+static inline void s390_stckf_hw(void *buf)
+{
+ asm volatile(".insn s,0xb27c0000,%0"
+ : "=Q" (*((unsigned long long *)buf)) : : "cc");
+}
+
+static inline void s390_stcke_hw(void *buf)
+{
+ asm volatile(".insn s,0xb2780000,%0"
+ : "=Q" (*((unsigned long long *)buf)) : : "cc");
+}
+
+static inline void s390_stck(void *buf)
+{
+#ifdef _LINUX_S390X_
+ s390_stckf_hw(buf);
+#else
+ s390_stcke_hw(buf);
+#endif
+}
+
+static inline int __stfle(unsigned long long *list, int doublewords)
+{
+ typedef struct { unsigned long long _[doublewords]; } addrtype;
+ register unsigned long __nr asm("0") = doublewords - 1;
+
+ asm volatile(".insn s,0xb2b00000,%0" /* stfle */
+ : "=m" (*(addrtype *) list), "+d" (__nr) : : "cc");
+ return __nr + 1;
+}
+
+#endif
+
diff --git a/src/include/s390_ctr.h b/src/include/s390_ctr.h
new file mode 100644
index 0000000..2f203ae
--- /dev/null
+++ b/src/include/s390_ctr.h
@@ -0,0 +1,131 @@
+/* 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.
+ */
+
+/**
+ * Authors: Felix Beck <felix.beck@de.ibm.com>
+ * Holger Dengler <hd@linux.vnet.ibm.com>
+ * Patrick Steuer <patrick.steuer@de.ibm.com>
+ *
+ * Copyright IBM Corp. 2010, 2011
+ */
+
+#ifndef S390_CTR_H
+#define S390_CTR_H
+
+#include "s390_common.h"
+
+/*
+ * Get least multiple of @bs that is greater or equal than @n.
+ */
+#define NEXT_BS(n, bs) ((n + (bs - 1)) & (~(bs - 1)))
+
+#define LARGE_MSG_CHUNK 4096 /* page size */
+
+static inline void __inc_des_ctr(uint64_t *iv, int ctr_bits)
+{
+ uint64_t ctr, mask;
+
+ ctr = *iv;
+ if (ctr_bits >= 64)
+ mask = 0ULL;
+ else
+ mask = ~0ULL << (ctr_bits - 64);
+ *iv &= mask;
+ ++ctr;
+ *iv |= ctr & ~mask;
+}
+
+static inline void __inc_aes_ctr(struct uint128 *iv, int ctr_bits)
+{
+ struct uint128 ctr, mask;
+
+ ctr.g[1] = iv->g[1];
+ ctr.g[0] = iv->g[0];
+ if (ctr_bits >= 64) {
+ mask.g[1] = 0ULL;
+ mask.g[0] = ~0ULL << (ctr_bits - 64);
+ }
+ else {
+ mask.g[1] = ~0ULL << ctr_bits;
+ mask.g[0] = ~0ULL;
+ }
+ iv->g[1] &= mask.g[1];
+ iv->g[0] &= mask.g[0];
+ if(++(ctr.g[1]))
+ ++(ctr.g[0]);
+ iv->g[1] |= ctr.g[1] & ~mask.g[1];
+ iv->g[0] |= ctr.g[0] & ~mask.g[0];
+}
+
+/*
+ * Fill @ctrlist with 8 byte counter blocks. @ctrlistlen must be a multiple of
+ * 8 (DES_BLOCK_SIZE).
+ */
+static inline void __fill_des_ctrlist(uint8_t *ctrlist, size_t ctrlistlen,
+ uint64_t *iv, int ctr_bits) {
+ uint64_t ctr, mask, *block;
+
+ ctr = *iv;
+ if (ctr_bits >= 64)
+ mask = 0ULL;
+ else
+ mask = ~0ULL << ctr_bits;
+
+ *iv &= mask;
+ for (block = (uint64_t *)ctrlist; block < (uint64_t *)ctrlist +
+ ctrlistlen / sizeof(uint64_t); block++) {
+ *block = (ctr & ~mask) | *iv;
+ ++ctr;
+ }
+ *iv |= ctr & ~mask;
+}
+
+/*
+ * Fill @ctrlist with 16 byte counter blocks. @ctrlistlen must be a multiple of
+ * 16 (AES_BLOCK_SIZE).
+ */
+static inline void __fill_aes_ctrlist(uint8_t *ctrlist, size_t ctrlistlen,
+ struct uint128 *iv, int ctr_bits) {
+ struct uint128 ctr, mask, *block;
+
+ ctr.g[1] = iv->g[1];
+ ctr.g[0] = iv->g[0];
+ if (ctr_bits >= 64) {
+ mask.g[1] = 0ULL;
+ mask.g[0] = ~0ULL << (ctr_bits - 64);
+ }
+ else {
+ mask.g[1] = ~0ULL << ctr_bits;
+ mask.g[0] = ~0ULL;
+ }
+ iv->g[1] &= mask.g[1];
+ iv->g[0] &= mask.g[0];
+ for (block = (struct uint128 *)ctrlist; block <
+ (struct uint128 *)ctrlist + ctrlistlen / sizeof(struct uint128);
+ block++) {
+ block->g[1] = (ctr.g[1] & ~mask.g[1]) | iv->g[1];
+ block->g[0] = (ctr.g[0] & ~mask.g[0]) | iv->g[0];
+ if(++(ctr.g[1]))
+ ++(ctr.g[0]);
+ }
+ iv->g[1] |= ctr.g[1] & ~mask.g[1];
+ iv->g[0] |= ctr.g[0] & ~mask.g[0];
+}
+
+static inline int s390_ctr_hw(unsigned int function_code, unsigned long data_length,
+ const unsigned char *in_data, unsigned char *key,
+ unsigned char *out_data, const unsigned char *ctrlist)
+{
+ int rc = -1;
+ rc = s390_kmctr(function_code, key, out_data, in_data,
+ data_length, (unsigned char *)ctrlist);
+ if (rc >= 0)
+ return 0;
+ else
+ return EIO;
+}
+
+#endif
diff --git a/src/include/s390_des.h b/src/include/s390_des.h
new file mode 100644
index 0000000..100a1d0
--- /dev/null
+++ b/src/include/s390_des.h
@@ -0,0 +1,618 @@
+/* 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.
+ */
+
+/**
+ * Authors: Felix Beck <felix.beck@de.ibm.com>
+ * Christian Maaser <cmaaser@de.ibm.com>
+ * Holger Dengler <hd@linux.vnet.ibm.com>
+ *
+ * Copyright IBM Corp. 2009, 2010, 2011
+ */
+
+#ifndef S390_DES_H
+#define S390_DES_H
+
+#include <errno.h>
+#include <openssl/crypto.h>
+#include <openssl/des.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/opensslconf.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif /* OPENSSL_FIPS */
+
+#include "icastats.h"
+#include "s390_crypto.h"
+#include "s390_ctr.h"
+
+#define DES_BLOCK_SIZE 8
+
+static inline int s390_des_ecb_hw(unsigned int function_code, unsigned long input_length,
+ const unsigned char *input_data, unsigned char *keys,
+ unsigned char *output_data)
+{
+ int rc = -1;
+ rc = s390_km(function_code, keys, output_data, input_data,
+ input_length);
+
+ if (rc >= 0)
+ return 0;
+ else
+ return EIO;
+}
+
+
+static inline int s390_des_ecb_sw(unsigned int function_code, unsigned long input_length,
+ const unsigned char *input_data, const unsigned char *keys,
+ unsigned char *output_data)
+{
+#ifdef ICA_FIPS
+ if ((fips & ICA_FIPS_MODE) && (!FIPS_mode()))
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ DES_key_schedule key_schedule1;
+ DES_key_schedule key_schedule2;
+ DES_key_schedule key_schedule3;
+ switch (function_code & S390_CRYPTO_FUNCTION_MASK) {
+ case S390_CRYPTO_DEA_ENCRYPT:
+ DES_set_key_unchecked((const_DES_cblock *) keys,
+ &key_schedule1);
+ for (; input_length; input_length -= sizeof(DES_cblock)) {
+ DES_ecb_encrypt((const_DES_cblock *) input_data,
+ (DES_cblock *) output_data,
+ &key_schedule1,
+ (function_code &
+ S390_CRYPTO_DIRECTION_MASK) ? 0 : 1);
+ input_data += sizeof(DES_cblock);
+ output_data += sizeof(DES_cblock);
+ }
+ break;
+
+ case S390_CRYPTO_TDEA_128_ENCRYPT:
+ DES_set_key_unchecked((const_DES_cblock *) keys,
+ &key_schedule1);
+ DES_set_key_unchecked((const_DES_cblock *) keys + 1,
+ &key_schedule2);
+ for (; input_length; input_length -= sizeof(DES_cblock)) {
+ DES_ecb2_encrypt((const_DES_cblock *)
+ input_data,
+ (DES_cblock *) output_data,
+ &key_schedule1, &key_schedule2,
+ (function_code &
+ S390_CRYPTO_DIRECTION_MASK) ? 0 : 1);
+ input_data += sizeof(DES_cblock);
+ output_data += sizeof(DES_cblock);
+ }
+ break;
+
+ case S390_CRYPTO_TDEA_192_ENCRYPT:
+ DES_set_key_unchecked((const_DES_cblock *) keys,
+ &key_schedule1);
+ DES_set_key_unchecked((const_DES_cblock *) keys + 1,
+ &key_schedule2);
+ DES_set_key_unchecked((const_DES_cblock *) keys + 2,
+ &key_schedule3);
+ for (; input_length; input_length -= sizeof(DES_cblock)) {
+ DES_ecb3_encrypt((const_DES_cblock *)
+ input_data,
+ (DES_cblock *) output_data,
+ &key_schedule1, &key_schedule2,
+ &key_schedule3, (function_code &
+ S390_CRYPTO_DIRECTION_MASK) ? 0 : 1);
+ input_data += sizeof(DES_cblock);
+ output_data += sizeof(DES_cblock);
+ }
+ break;
+ }
+
+ return 0;
+}
+
+
+static inline int s390_des_cbc_hw(unsigned int function_code,
+ unsigned long input_length,
+ const unsigned char *input_data, unsigned char *iv,
+ const unsigned char *keys, unsigned char *output_data)
+{
+ struct {
+ ica_des_vector_t iv;
+ ica_des_key_triple_t keys;
+ } key_buffer;
+
+ int rc = -1;
+ unsigned int key_size = (function_code & S390_CRYPTO_FUNCTION_MASK) *
+ sizeof(ica_des_key_single_t);
+ memcpy(&key_buffer.iv, iv, sizeof(ica_des_vector_t));
+ memcpy(&key_buffer.keys, keys, key_size);
+
+ rc = s390_kmc(function_code, &key_buffer, output_data,
+ input_data, input_length);
+
+ memset(&key_buffer.keys, 0, key_size);
+
+ if (rc >= 0) {
+ memcpy(iv, &key_buffer.iv, sizeof(ica_des_vector_t));
+ return 0;
+ } else
+ return EIO;
+}
+
+
+static inline int s390_des_cbc_sw(unsigned int function_code,
+ unsigned long input_length,
+ const unsigned char *input_data, unsigned char *iv,
+ const unsigned char *keys, unsigned char *output_data)
+{
+#ifdef ICA_FIPS
+ if ((fips & ICA_FIPS_MODE) && (!FIPS_mode()))
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ DES_key_schedule key_schedule1;
+ DES_key_schedule key_schedule2;
+ DES_key_schedule key_schedule3;
+ switch (function_code & S390_CRYPTO_FUNCTION_MASK) {
+ case S390_CRYPTO_DEA_ENCRYPT:
+ DES_set_key_unchecked((const_DES_cblock *) keys,
+ &key_schedule1);
+ DES_ncbc_encrypt(input_data, output_data, input_length,
+ &key_schedule1, (DES_cblock *) iv,
+ (function_code & S390_CRYPTO_DIRECTION_MASK) ?
+ 0 : 1);
+ break;
+ case S390_CRYPTO_TDEA_128_ENCRYPT:
+ DES_set_key_unchecked((const_DES_cblock *) keys,
+ &key_schedule1);
+ DES_set_key_unchecked((const_DES_cblock *) keys + 1,
+ &key_schedule2);
+ DES_ede2_cbc_encrypt(input_data, output_data, input_length,
+ &key_schedule1, &key_schedule2,
+ (DES_cblock *) iv,
+ (function_code &
+ S390_CRYPTO_DIRECTION_MASK) ? 0 : 1);
+ break;
+ case S390_CRYPTO_TDEA_192_ENCRYPT:
+ DES_set_key_unchecked((const_DES_cblock *) keys,
+ &key_schedule1);
+ DES_set_key_unchecked((const_DES_cblock *) keys + 1,
+ &key_schedule2);
+ DES_set_key_unchecked((const_DES_cblock *) keys + 2,
+ &key_schedule3);
+ DES_ede3_cbc_encrypt(input_data, output_data, input_length,
+ &key_schedule1, &key_schedule2,
+ &key_schedule3, (DES_cblock *) iv,
+ (function_code &
+ S390_CRYPTO_DIRECTION_MASK) ? 0 : 1);
+ break;
+ };
+
+ return 0;
+}
+
+static inline int s390_des_ecb(unsigned int fc, unsigned long data_length,
+ const unsigned char *in_data, unsigned char *key,
+ unsigned char *out_data)
+{
+ int rc = 1;
+ int hardware = ALGO_HW;
+
+ if (*s390_kmc_functions[fc].enabled)
+ rc = s390_des_ecb_hw(s390_kmc_functions[fc].hw_fc,
+ data_length, in_data, key,
+ out_data);
+ if (rc) {
+ rc = s390_des_ecb_sw(s390_kmc_functions[fc].hw_fc,
+ data_length, in_data, key,
+ out_data);
+ hardware = ALGO_SW;
+ }
+
+ switch (s390_kmc_functions[fc].hw_fc & S390_CRYPTO_FUNCTION_MASK) {
+ case S390_CRYPTO_DEA_ENCRYPT:
+ stats_increment(ICA_STATS_DES_ECB, hardware,
+ (s390_kmc_functions[fc].hw_fc &
+ S390_CRYPTO_DIRECTION_MASK) ==
+ 0 ? ENCRYPT : DECRYPT);
+ break;
+ case S390_CRYPTO_TDEA_128_ENCRYPT:
+ case S390_CRYPTO_TDEA_192_ENCRYPT:
+ stats_increment(ICA_STATS_3DES_ECB, hardware,
+ (s390_kmc_functions[fc].hw_fc &
+ S390_CRYPTO_DIRECTION_MASK) ==
+ 0 ? ENCRYPT : DECRYPT);
+ break;
+ }
+
+ return rc;
+}
+
+static inline int s390_des_cbc(unsigned int fc, unsigned long data_length,
+ const unsigned char *in_data, unsigned char *iv,
+ const unsigned char *key, unsigned char *out_data)
+{
+ int rc = 1;
+ int hardware = ALGO_HW;
+
+ if (*s390_kmc_functions[fc].enabled)
+ rc = s390_des_cbc_hw(s390_kmc_functions[fc].hw_fc,
+ data_length, in_data, iv, key,
+ out_data);
+ if (rc) {
+ rc = s390_des_cbc_sw(s390_kmc_functions[fc].hw_fc,
+ data_length, in_data, iv, key,
+ out_data);
+ hardware = ALGO_SW;
+ }
+
+ switch (s390_kmc_functions[fc].hw_fc & S390_CRYPTO_FUNCTION_MASK) {
+ case S390_CRYPTO_DEA_ENCRYPT:
+ stats_increment(ICA_STATS_DES_CBC, hardware,
+ (s390_kmc_functions[fc].hw_fc &
+ S390_CRYPTO_DIRECTION_MASK) ==
+ 0 ? ENCRYPT : DECRYPT);
+ break;
+ case S390_CRYPTO_TDEA_128_ENCRYPT:
+ case S390_CRYPTO_TDEA_192_ENCRYPT:
+ stats_increment(ICA_STATS_3DES_CBC, hardware,
+ (s390_kmc_functions[fc].hw_fc &
+ S390_CRYPTO_DIRECTION_MASK) ==
+ 0 ? ENCRYPT : DECRYPT);
+ break;
+ }
+ return rc;
+}
+
+static inline int s390_des_cfb_hw(unsigned int function_code,
+ unsigned long data_length,
+ const unsigned char *in_data, unsigned char *iv,
+ const unsigned char *key, unsigned char *out_data,
+ unsigned int lcfb)
+{
+ struct {
+ ica_des_vector_t iv;
+ ica_des_key_triple_t keys;
+ } key_buffer;
+ int rc = -1;
+
+ unsigned int key_size = (function_code & S390_CRYPTO_FUNCTION_MASK) *
+ sizeof(ica_des_key_single_t);
+ memcpy(&key_buffer.iv, iv, sizeof(ica_des_vector_t));
+ memcpy(&key_buffer.keys, key, key_size);
+
+ rc = s390_kmf(function_code, &key_buffer, out_data,
+ in_data, data_length, &lcfb);
+
+ memset(&key_buffer.keys, 0, key_size);
+
+ if (rc >= 0) {
+ memcpy(iv, &key_buffer.iv, sizeof(ica_des_vector_t));
+ return 0;
+ } else
+ return EIO;
+}
+
+static inline int __s390_des_cfb(unsigned int fc, unsigned long data_length,
+ const unsigned char *in_data, unsigned char *iv,
+ const unsigned char *key, unsigned char *out_data,
+ unsigned int lcfb)
+{
+ int rc = 1;
+ int hardware = ALGO_HW;
+
+ if (*s390_msa4_functions[fc].enabled)
+ rc = s390_des_cfb_hw(s390_msa4_functions[fc].hw_fc,
+ data_length, in_data, iv, key,
+ out_data, lcfb);
+ if (rc) {
+ hardware = ALGO_SW;
+ return EPERM;
+ }
+ switch (s390_msa4_functions[fc].hw_fc & S390_CRYPTO_FUNCTION_MASK) {
+ case S390_CRYPTO_DEA_ENCRYPT:
+ stats_increment(ICA_STATS_DES_CFB, hardware,
+ (s390_msa4_functions[fc].hw_fc &
+ S390_CRYPTO_DIRECTION_MASK) ==
+ 0 ? ENCRYPT : DECRYPT);
+ break;
+ case S390_CRYPTO_TDEA_128_ENCRYPT:
+ case S390_CRYPTO_TDEA_192_ENCRYPT:
+ stats_increment(ICA_STATS_3DES_CFB, hardware,
+ (s390_msa4_functions[fc].hw_fc &
+ S390_CRYPTO_DIRECTION_MASK) ==
+ 0 ? ENCRYPT : DECRYPT);
+ break;
+ }
+ return rc;
+}
+
+static inline int s390_des_ofb_hw(unsigned int function_code,
+ unsigned int input_length,
+ const unsigned char *input_data, unsigned char *iv,
+ const unsigned char *keys, unsigned char *output_data)
+{
+ struct {
+ ica_des_vector_t iv;
+ ica_des_key_triple_t keys;
+ } key_buffer;
+
+ int rc = -1;
+ unsigned int key_size = (function_code & S390_CRYPTO_FUNCTION_MASK) *
+ sizeof(ica_des_key_single_t);
+ memcpy(&key_buffer.iv, iv, sizeof(ica_des_vector_t));
+ memcpy(&key_buffer.keys, keys, key_size);
+
+ rc = s390_kmo(function_code, &key_buffer, output_data,
+ input_data, input_length);
+
+ memset(&key_buffer.keys, 0, key_size);
+
+ if (rc >= 0) {
+ memcpy(iv, &key_buffer.iv, sizeof(ica_des_vector_t));
+ return 0;
+ } else
+ return EIO;
+}
+
+static inline int __s390_des_ofb(unsigned int fc, unsigned int input_length,
+ const unsigned char *input_data, unsigned char *iv,
+ const unsigned char *keys, unsigned char *output_data)
+{
+ int rc = 1;
+ int hardware = ALGO_HW;
+
+ if (*s390_msa4_functions[fc].enabled)
+ rc = s390_des_ofb_hw(s390_msa4_functions[fc].hw_fc,
+ input_length, input_data, iv, keys,
+ output_data);
+ if (rc) {
+ hardware = ALGO_SW;
+ return rc;
+ }
+ switch (s390_msa4_functions[fc].hw_fc & S390_CRYPTO_FUNCTION_MASK) {
+ case S390_CRYPTO_DEA_ENCRYPT:
+ stats_increment(ICA_STATS_DES_OFB, hardware,
+ (s390_msa4_functions[fc].hw_fc &
+ S390_CRYPTO_DIRECTION_MASK) ==
+ 0 ? ENCRYPT : DECRYPT);
+ break;
+ case S390_CRYPTO_TDEA_128_ENCRYPT:
+ case S390_CRYPTO_TDEA_192_ENCRYPT:
+ stats_increment(ICA_STATS_3DES_OFB, hardware,
+ (s390_msa4_functions[fc].hw_fc &
+ S390_CRYPTO_DIRECTION_MASK) ==
+ 0 ? ENCRYPT : DECRYPT);
+ break;
+ }
+ return rc;
+}
+
+static inline int s390_des_cfb(unsigned int fc, unsigned long data_length,
+ const unsigned char *in_data, unsigned char *iv,
+ const unsigned char *key, unsigned char *out_data,
+ unsigned int lcfb)
+{
+ int rc = 0;
+ /* Temporary buffers with size of lcfb should be
+ * sufficiant, using static maximun lcfb instead. */
+ unsigned char rest_in_data[DES_BLOCK_SIZE];
+ unsigned char rest_out_data[DES_BLOCK_SIZE];
+ unsigned long rest_data_length;
+ unsigned long tmp_data_length;
+
+ rest_data_length = data_length % lcfb;
+ tmp_data_length = data_length - rest_data_length;
+
+ if (tmp_data_length) {
+ rc = __s390_des_cfb(fc, tmp_data_length, in_data,
+ iv, key, out_data, lcfb);
+ if (rc)
+ return rc;
+ }
+
+ if (rest_data_length) {
+ memcpy(rest_in_data, in_data + tmp_data_length,
+ rest_data_length);
+
+ rc = __s390_des_cfb(fc, lcfb, rest_in_data, iv, key,
+ rest_out_data, lcfb);
+ if (rc)
+ return rc;
+
+ memcpy(out_data + tmp_data_length,
+ rest_out_data, rest_data_length);
+ }
+
+ return rc;
+}
+
+static inline int s390_des_ofb(unsigned int fc, unsigned long data_length,
+ const unsigned char *in_data, unsigned char *iv,
+ const unsigned char *key, unsigned char *out_data)
+{
+ int rc = 0;
+ unsigned char rest_in_data[DES_BLOCK_SIZE];
+ unsigned char rest_out_data[DES_BLOCK_SIZE];
+ unsigned long rest_data_length;
+ unsigned long tmp_data_length;
+
+ rest_data_length = data_length % DES_BLOCK_SIZE;
+ tmp_data_length = data_length - rest_data_length;
+
+ if (tmp_data_length) {
+ rc = __s390_des_ofb(fc, tmp_data_length, in_data,
+ iv, key, out_data);
+ if (rc)
+ return rc;
+ }
+
+ if (rest_data_length) {
+ memcpy(rest_in_data, in_data + tmp_data_length,
+ rest_data_length);
+
+ rc = __s390_des_ofb(fc, DES_BLOCK_SIZE,
+ rest_in_data,
+ iv, key, rest_out_data);
+ if (rc)
+ return rc;
+
+ memcpy(out_data + tmp_data_length,
+ rest_out_data, rest_data_length);
+ }
+
+ return rc;
+}
+
+static inline int __s390_des_ctrlist(unsigned int fc, unsigned long data_length,
+ const unsigned char *in_data,
+ const unsigned char *ctrlist,
+ unsigned char *key,
+ unsigned char *out_data)
+{
+ int rc = EPERM;
+ int hardware = ALGO_HW;
+
+ if (*s390_msa4_functions[fc].enabled)
+ rc = s390_ctr_hw(s390_msa4_functions[fc].hw_fc,
+ data_length, in_data, key,
+ out_data, ctrlist);
+ if (rc) {
+ hardware = ALGO_SW;
+ return rc;
+ }
+ switch (s390_msa4_functions[fc].hw_fc & S390_CRYPTO_FUNCTION_MASK) {
+ case S390_CRYPTO_DEA_ENCRYPT:
+ stats_increment(ICA_STATS_DES_CTR, hardware,
+ (s390_msa4_functions[fc].hw_fc &
+ S390_CRYPTO_DIRECTION_MASK) ==
+ 0 ?ENCRYPT: DECRYPT);
+ break;
+ case S390_CRYPTO_TDEA_128_ENCRYPT:
+ case S390_CRYPTO_TDEA_192_ENCRYPT:
+ stats_increment(ICA_STATS_3DES_CTR, hardware,
+ (s390_msa4_functions[fc].hw_fc &
+ S390_CRYPTO_DIRECTION_MASK) ==
+ 0 ?ENCRYPT: DECRYPT);
+ break;
+ }
+ return rc;
+}
+
+static inline int s390_des_ctrlist(unsigned int fc, unsigned long data_length,
+ const unsigned char *in_data,
+ const unsigned char *ctrlist,
+ unsigned char *key, unsigned char *out_data)
+{
+ int rc = 0;
+ unsigned char rest_in_data[DES_BLOCK_SIZE];
+ unsigned char rest_out_data[DES_BLOCK_SIZE];
+ unsigned long rest_data_length;
+ unsigned long tmp_data_length;
+
+ rest_data_length = data_length % DES_BLOCK_SIZE;
+ tmp_data_length = data_length - rest_data_length;
+
+ if (tmp_data_length) {
+ rc = __s390_des_ctrlist(fc, tmp_data_length, in_data,
+ ctrlist, key, out_data);
+ if (rc)
+ return rc;
+ }
+
+ if (rest_data_length) {
+ memcpy(rest_in_data, in_data + tmp_data_length,
+ rest_data_length);
+
+ rc = __s390_des_ctrlist(fc, DES_BLOCK_SIZE,
+ rest_in_data,
+ ctrlist + tmp_data_length,
+ key, rest_out_data);
+ if (rc)
+ return rc;
+
+ memcpy(out_data + tmp_data_length,
+ rest_out_data, rest_data_length);
+ }
+
+ return rc;
+}
+
+static inline int s390_des_ctr(unsigned int fc, const unsigned char *in_data,
+ unsigned char *out_data, unsigned long data_length,
+ unsigned char *key, unsigned char *ctr,
+ unsigned int ctr_width)
+{
+ const unsigned char *src;
+ unsigned char *tmp_ctrlist = NULL;
+ unsigned long chunk_length;
+ unsigned long rest_length;
+ unsigned long tmp_length;
+
+ int rc = 0;
+
+ if (data_length <= DES_BLOCK_SIZE) {
+ /* short message handling */
+ rc = s390_des_ctrlist(fc, data_length, in_data, ctr,
+ key, out_data);
+ if (rc)
+ goto free_out;
+
+ __inc_des_ctr((uint64_t *)ctr, ctr_width);
+ return rc;
+ }
+
+ /* find largest possible message chunk */
+ /* get next multiple of blocksize of data_length */
+ chunk_length = NEXT_BS(data_length, DES_BLOCK_SIZE);
+ tmp_ctrlist = malloc(chunk_length);
+
+ /* page size chunk fall back */
+ if ((!tmp_ctrlist) && (data_length > LARGE_MSG_CHUNK)) {
+ chunk_length = LARGE_MSG_CHUNK;
+ tmp_ctrlist = malloc(chunk_length);
+ }
+
+ /* single block chunk fall back */
+ if (!tmp_ctrlist)
+ chunk_length = DES_BLOCK_SIZE;
+
+ for (src = in_data, rest_length = data_length;
+ src < (in_data + data_length);
+ src += chunk_length, out_data += chunk_length,
+ rest_length -= chunk_length) {
+ tmp_length = (rest_length < chunk_length) ?
+ rest_length : chunk_length;
+ if (tmp_ctrlist) {
+ __fill_des_ctrlist(tmp_ctrlist,
+ NEXT_BS(tmp_length, DES_BLOCK_SIZE),
+ (uint64_t *)ctr, ctr_width);
+
+ rc = s390_des_ctrlist(fc, tmp_length, src,
+ tmp_ctrlist, key, out_data);
+ if (rc)
+ goto free_out;
+ } else {
+ rc = s390_des_ctrlist(fc, tmp_length, src,
+ ctr, key, out_data);
+ if (rc)
+ goto free_out;
+
+ __inc_des_ctr((uint64_t *)ctr, ctr_width);
+ }
+ }
+
+free_out:
+ if (tmp_ctrlist)
+ free(tmp_ctrlist);
+
+ return rc;
+}
+
+#endif
+
diff --git a/src/include/s390_drbg.h b/src/include/s390_drbg.h
new file mode 100644
index 0000000..d75faa9
--- /dev/null
+++ b/src/include/s390_drbg.h
@@ -0,0 +1,269 @@
+/*
+ * 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.
+ *
+ * DRBG conforming to NIST SP800-90A
+ *
+ * Author(s): Patrick Steuer <patrick.steuer@de.ibm.com>
+ *
+ * Copyright IBM Corp. 2015
+ *
+ * This file contains infrastructure that should be used when implementing more
+ * DRBG mechanisms. Don't forget to add the new DRBG mechanism to the DRBG
+ * mechanism list.
+ */
+
+#ifndef S390_DRBG_H
+#define S390_DRBG_H
+
+#include <pthread.h>
+
+#define DRBG_ADD_ENTROPY_LEN 18 /* bytes of entropy input used in
+ addition to the required minimum */
+#define DRBG_NONCE_LEN 16 /* byte length of nonce */
+#define DRBG_OUT_LEN (512 / 8) /* byte length of SHA-512 output */
+
+/*
+ * DRBG security strengths (bits)
+ */
+#define DRBG_SEC_112 112
+#define DRBG_SEC_128 128
+#define DRBG_SEC_192 192
+#define DRBG_SEC_256 256
+
+/*
+ * DRBG mechanism function return codes
+ */
+/* error flags (> 0): */
+#define DRBG_RESEED_REQUIRED 1
+#define DRBG_NOMEM 2
+#define DRBG_SH_INV 3
+#define DRBG_MECH_INV 4
+#define DRBG_PERS_INV 5
+#define DRBG_ADD_INV 6
+#define DRBG_REQUEST_INV 7
+#define DRBG_NONCE_INV 8
+#define DRBG_SEC_NOTSUPP 9
+#define DRBG_PR_NOTSUPP 10
+/* catastrophic error flags (< 0): */
+#define DRBG_HEALTH_TEST_FAIL (-1)
+#define DRBG_ENTROPY_SOURCE_FAIL (-2)
+
+/*
+ * DRBG mechanism type
+ */
+struct ica_drbg_mech{
+ const char *id;
+
+ /* Mechanism constants */
+ const int highest_supp_sec;
+ const size_t seed_len;
+ const size_t max_pers_len;
+ const size_t max_add_len;
+ const size_t max_len;
+ const size_t max_no_of_bytes_per_req;
+ const uint64_t reseed_intervall;
+
+ /* Pointers to mechanism functions */
+ int (*instantiate)(void **ws,
+ int sec,
+ const unsigned char *pers,
+ size_t pers_len,
+ const unsigned char *entropy,
+ size_t entropy_len,
+ const unsigned char *nonce,
+ size_t nonce_len);
+
+ int (*reseed)(void *ws,
+ const unsigned char *add,
+ size_t add_len,
+ const unsigned char *entropy,
+ size_t entropy_len);
+
+ int (*generate)(void *ws,
+ const unsigned char *add,
+ size_t add_len,
+ unsigned char *prnd_bytes,
+ size_t prnd_bytes_len);
+
+ int (*uninstantiate)(void **ws,
+ bool test_mode);
+
+ int (*health_test)(void *func,
+ int sec,
+ bool pr);
+
+ /* Health testing: A thread holds this wrlock while performing
+ * self-tests such that no other thread can do a generate operation in
+ * this time: generate requires this rdlock (11.3). */
+ pthread_rwlock_t lock;
+ const uint64_t test_intervall;
+ uint64_t test_ctr;
+ int error_state;
+};
+
+/*
+ * DRBG type
+ */
+struct ica_drbg{
+ pthread_mutex_t lock; /* serialize operations on working state */
+ ica_drbg_mech_t *mech; /* DRBG mechanism */
+
+ /*
+ * Internal state
+ */
+ void *ws; /* working state */
+ /* administrative information: */
+ int sec; /* security strength */
+ bool pr; /* prediction resistance flag */
+};
+
+/*
+ * DRBG mechanism list. Add new DRBG mechanism here:
+ */
+extern ica_drbg_mech_t DRBG_SHA512;
+
+extern ica_drbg_mech_t *const DRBG_MECH_LIST[];
+extern const size_t DRBG_MECH_LIST_LEN;
+
+/*
+ * DRBG SEI (source of entropy input) list. Add devices/change priorities here:
+ */
+extern const char *const DRBG_SEI_LIST[];
+extern const size_t DRBG_SEI_LIST_LEN;
+
+/*
+ * DRBG mechanism functions
+ *
+ * @test_mode = true enables testing interface (see 11.2).
+ */
+int drbg_instantiate(ica_drbg_t **sh,
+ int sec,
+ bool pr,
+ ica_drbg_mech_t *mech,
+ const unsigned char *pers,
+ size_t pers_len,
+ bool test_mode,
+ const unsigned char *test_nonce,
+ size_t test_nonce_len,
+ const unsigned char *test_entropy,
+ size_t test_entropy_len);
+
+int drbg_reseed(ica_drbg_t *sh,
+ bool pr,
+ const unsigned char *add,
+ size_t add_len,
+ bool test_mode,
+ const unsigned char *entropy,
+ size_t entropy_len);
+
+int drbg_generate(ica_drbg_t *sh,
+ int sec,
+ bool pr,
+ const unsigned char *add,
+ size_t add_len,
+ bool test_mode,
+ const unsigned char *test_entropy,
+ size_t test_entropy_len,
+ unsigned char *prnd,
+ size_t prnd_len);
+
+int drbg_uninstantiate(ica_drbg_t **sh,
+ bool test_mode);
+
+int drbg_health_test(const void *func,
+ int sec,
+ bool pr,
+ ica_drbg_mech_t *mech);
+
+/*
+ * Auxiliary functions
+ */
+/* Hash derivation function based on SHA-512. Used by DRBG_SHA512 and
+ * DRBG_DUAL_EC mechanism. */
+int drbg_hash_df(const unsigned char *input_string,
+ size_t input_string_len,
+ unsigned char *req_bytes,
+ size_t req_bytes_len);
+
+/* Obtain entropy input from an entropy source, a NRBG or another DRBG.
+ * The request for prediciton resistence (@pr) rules out the use of a DRBG that
+ * does not have access to either an entropy source or NRBG (see 9.). */
+int drbg_get_entropy_input(bool pr,
+ int min_entropy,
+ size_t max_len,
+ unsigned char *entropy,
+ size_t entropy_len);
+
+/* Obtain a nonce. The nonce is made of a timestamp, the thread id and a
+ * counter */
+int drbg_get_nonce(unsigned char *nonce,
+ size_t nonce_len);
+
+/* Zeroise memory to erase sensitive data. */
+static inline void drbg_zmem(void *ptr,
+ size_t len)
+{
+ if(ptr)
+ memset(ptr, 0, len);
+
+ /* protect this code from unwanted compiler optimization */
+ __asm__ __volatile__ ("": :"r"(ptr) :"memory");
+}
+
+/* Check if memory area was zeroised. */
+static inline int drbg_check_zmem(void *ptr,
+ size_t len)
+{
+ int i;
+
+ if(!ptr)
+ return DRBG_HEALTH_TEST_FAIL;
+
+ for(i = 0; i < len; i++){
+ if(((unsigned char *)ptr)[i])
+ return DRBG_HEALTH_TEST_FAIL;
+ }
+
+ return 0;
+}
+
+/* Test whether a mechanism is valid. Returns EINVAL for unsupported
+ * mechanisms, the error state (<0) for mechanisms in error state or 0 on
+ * success. */
+static inline int drbg_mech_valid(const ica_drbg_mech_t *mech)
+{
+ int i;
+
+ if(!mech)
+ return DRBG_MECH_INV;
+
+ /* Check if @mech is supported. */
+ for(i = DRBG_MECH_LIST_LEN - 1; i >= 0; i--){
+ if(DRBG_MECH_LIST[i] == mech)
+ break;
+ }
+ if(i < 0)
+ return DRBG_MECH_INV;
+
+ /* Check if @mech is in error state. */
+ if(mech->error_state)
+ return mech->error_state;
+
+ return 0;
+}
+
+
+/* Initilize a recursive mutex. */
+static inline void drbg_recursive_mutex_init(pthread_mutex_t *lock)
+{
+ pthread_mutexattr_t attr;
+
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(lock, &attr);
+}
+
+#endif
diff --git a/src/include/s390_drbg_sha512.h b/src/include/s390_drbg_sha512.h
new file mode 100644
index 0000000..d4458f8
--- /dev/null
+++ b/src/include/s390_drbg_sha512.h
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ *
+ * DRBG conforming to NIST SP800-90A
+ *
+ * Author(s): Patrick Steuer <patrick.steuer@de.ibm.com>
+ *
+ * Copyright IBM Corp. 2015
+ */
+
+#ifndef S390_DRBG_SHA512_H
+#define S390_DRBG_SHA512_H
+
+#include <stdint.h>
+
+#include "ica_api.h"
+
+#define DRBG_SHA512_SEED_LEN (888 / 8)
+
+/*
+ * SHA-512 DRBG mechanism working state type (see POP)
+ */
+struct drbg_sha512_ws{
+ uint32_t rsvd0; /* padding */
+ uint32_t reseed_ctr; /* reseed counter */
+ uint64_t stream_bytes; /* no. of generated bytes */
+ unsigned char rsvd1; /* padding */
+ unsigned char v[DRBG_SHA512_SEED_LEN]; /* V */
+ unsigned char rsvd2; /* padding */
+ unsigned char c[DRBG_SHA512_SEED_LEN]; /* C */
+};
+
+/*
+ * SHA-512 DRBG mechanism functions
+ */
+int drbg_sha512_instantiate(void **ws,
+ int sec_strength,
+ const unsigned char *pers,
+ size_t pers_len,
+ const unsigned char *entropy,
+ size_t entropy_len,
+ const unsigned char *nonce,
+ size_t nonce_len);
+
+int drbg_sha512_instantiate_ppno(void **ws,
+ int sec_strength,
+ const unsigned char *pers,
+ size_t pers_len,
+ const unsigned char *entropy,
+ size_t entropy_len,
+ const unsigned char *nonce,
+ size_t nonce_len);
+
+int drbg_sha512_reseed(void *ws,
+ const unsigned char *add,
+ size_t add_len,
+ const unsigned char *entropy,
+ size_t entropy_len);
+
+int drbg_sha512_reseed_ppno(void *ws,
+ const unsigned char *add,
+ size_t add_len,
+ const unsigned char *entropy,
+ size_t entropy_len);
+
+int drbg_sha512_generate(void *ws,
+ const unsigned char *add,
+ size_t add_len,
+ unsigned char *prnd,
+ size_t prnd_len);
+
+int drbg_sha512_generate_ppno(void *ws,
+ const unsigned char *add,
+ size_t add_len,
+ unsigned char *prnd,
+ size_t prnd_len);
+
+int drbg_sha512_uninstantiate(void **ws,
+ bool test_mode);
+
+int drbg_sha512_health_test(void *func,
+ int sec,
+ bool pr);
+
+#endif
diff --git a/src/include/s390_gcm.h b/src/include/s390_gcm.h
new file mode 100644
index 0000000..0c03137
--- /dev/null
+++ b/src/include/s390_gcm.h
@@ -0,0 +1,438 @@
+/* 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.
+ */
+
+/**
+ * Authors: Felix Beck <felix.beck@de.ibm.com>
+ * Holger Dengler <hd@linux.vnet.ibm.com>
+ *
+ * Copyright IBM Corp. 2010, 2011
+ */
+
+#ifndef S390_GCM_H
+#define S390_GCM_H
+
+#include "s390_ctr.h"
+
+#define S390_GCM_MAX_TEXT_LENGTH (0x0000000fffffffe0ul) /* (2^31)-32 */
+#define S390_GCM_MAX_AAD_LENGTH (0x2000000000000000ul) /* (2^61) */
+#define S390_GCM_MAX_IV_LENGTH (0x2000000000000000ul) /* (2^61) */
+
+/* the recommended iv length for GCM is 96 bit or 12 byte */
+#define GCM_RECOMMENDED_IV_LENGTH 12
+
+/* ctr with for GCM is specified with 32 bit */
+#define GCM_CTR_WIDTH 32
+
+/* Helper struct containing last uncomplete ciphertext block
+ * with padding, aad_length and ciphertext_length. */
+unsigned char zero_block[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+static unsigned char partial_j[] = {
+ 0x00, 0x00, 0x00, 0x01,
+};
+
+struct pad_meta {
+ unsigned char pad[AES_BLOCK_SIZE];
+ uint64_t length_a;
+ uint64_t length_b;
+} __attribute__((packed));
+
+static inline int s390_ghash_hw(unsigned int fc,
+ const unsigned char *in_data,
+ unsigned long data_length,
+ unsigned char *iv,
+ const unsigned char *subkey)
+{
+ struct {
+ unsigned char iv[AES_BLOCK_SIZE];
+ unsigned char hash_subkey[AES_BLOCK_SIZE];
+ } __attribute__((packed)) parmblock;
+ int rc = 0;
+ int hardware = ALGO_HW;
+
+ memcpy(parmblock.iv, iv, AES_BLOCK_SIZE);
+ memcpy(parmblock.hash_subkey, subkey, AES_BLOCK_SIZE);
+
+ rc = s390_kimd(fc, &parmblock, in_data, data_length);
+ if(rc == data_length) {
+ /* All data has been processed */
+ memcpy(iv, parmblock.iv, AES_BLOCK_SIZE);
+ stats_increment(ICA_STATS_GHASH, hardware, ENCRYPT);
+ return 0;
+ }
+
+ return EIO;
+}
+
+static inline int s390_ghash(const unsigned char *in_data, unsigned long data_length,
+ const unsigned char *key, unsigned char *iv)
+{
+ if (!s390_kimd_functions[GHASH].enabled)
+ return EPERM;
+
+ return s390_ghash_hw(s390_kimd_functions[GHASH].hw_fc,
+ in_data, data_length,
+ iv, key);
+}
+
+static inline unsigned int __compute_j0(const unsigned char *iv,
+ unsigned int iv_length,
+ const unsigned char *subkey_h,
+ unsigned char *j0)
+{
+ int rc;
+ struct pad_meta iv_pad_meta;
+ unsigned long head_length;
+ unsigned long tail_length;
+
+ /* iv_length of 12 bytes is recommended */
+ if (iv_length == GCM_RECOMMENDED_IV_LENGTH) {
+ memcpy(j0, iv, iv_length);
+ memcpy(j0 + iv_length, partial_j, sizeof(partial_j));
+ return 0;
+ }
+
+ memset(j0, 0x00, AES_BLOCK_SIZE);
+
+ memset(iv_pad_meta.pad, 0x00, sizeof(iv_pad_meta.pad));
+ iv_pad_meta.length_a = (uint64_t)0ul; /* unused for j0 */
+ iv_pad_meta.length_b = (uint64_t)(iv_length * 8ul);
+
+ tail_length = iv_length % AES_BLOCK_SIZE;
+ head_length = iv_length - tail_length;
+
+ if (head_length) {
+ rc = s390_ghash(iv, head_length, subkey_h, j0);
+ if (rc)
+ return rc;
+ }
+
+ if (tail_length) {
+ memcpy(iv_pad_meta.pad, iv + head_length, tail_length);
+ rc = s390_ghash((unsigned char *)&iv_pad_meta,
+ sizeof(iv_pad_meta),
+ subkey_h, j0);
+ if (rc)
+ return rc;
+ } else {
+ /* no padding necessary, only ghash meta information */
+ rc = s390_ghash((unsigned char *)&iv_pad_meta.length_a,
+ AES_BLOCK_SIZE,
+ subkey_h, j0);
+ if (rc)
+ return rc;
+ }
+
+ return 0;
+}
+
+static inline unsigned int s390_gcm_authenticate(const unsigned char *ciphertext, unsigned long text_length,
+ const unsigned char *aad, unsigned long aad_length,
+ const unsigned char *subkey_h, unsigned char *iv)
+{
+ unsigned int rc;
+ unsigned char aad_pad[AES_BLOCK_SIZE];
+ unsigned long head_length;
+ unsigned long tail_length;
+ struct pad_meta c_pad_meta;
+
+ memset(iv, 0x00, AES_BLOCK_SIZE);
+
+ memset(c_pad_meta.pad, 0x00, sizeof(c_pad_meta.pad));
+ c_pad_meta.length_a = (uint64_t)(aad_length * 8ul);
+ c_pad_meta.length_b = (uint64_t)(text_length * 8ul);
+
+ if (aad_length) {
+ tail_length = aad_length % AES_BLOCK_SIZE;
+ head_length = aad_length - tail_length;
+
+ /* ghash aad head */
+ if (head_length) {
+ rc = s390_ghash(aad, head_length, subkey_h, iv);
+ if (rc)
+ return rc;
+ }
+
+ /* ghash aad tail */
+ if (tail_length) {
+ memset(aad_pad, 0x00, AES_BLOCK_SIZE);
+ memcpy(aad_pad, aad + head_length, tail_length);
+
+ rc = s390_ghash(aad_pad, AES_BLOCK_SIZE, subkey_h, iv);
+ if (rc)
+ return rc;
+ }
+ }
+
+ if (text_length) {
+ tail_length = text_length % AES_BLOCK_SIZE;
+ head_length = text_length - tail_length;
+
+ /* ghash ciphertext head */
+ if (head_length) {
+ rc = s390_ghash(ciphertext, head_length, subkey_h, iv);
+ if (rc)
+ return rc;
+ }
+
+ /* ghash ciphertext tail and meta data */
+ if (tail_length) {
+ memcpy(c_pad_meta.pad, ciphertext + head_length, tail_length);
+
+ rc = s390_ghash((unsigned char *)&c_pad_meta,
+ sizeof(c_pad_meta), subkey_h, iv);
+ if (rc)
+ return rc;
+ } else {
+ rc = s390_ghash((unsigned char *)&c_pad_meta.length_a,
+ AES_BLOCK_SIZE, subkey_h, iv);
+ if (rc)
+ return rc;
+ }
+ } else {
+ /* ghash meta data only */
+ rc = s390_ghash((unsigned char *)&c_pad_meta.length_a,
+ AES_BLOCK_SIZE,
+ subkey_h, iv);
+ if (rc)
+ return rc;
+ }
+
+ return 0;
+}
+
+static inline unsigned int s390_gcm_authenticate_intermediate(
+ const unsigned char *ciphertext, unsigned long text_length,
+ unsigned char *aad, unsigned long aad_length,
+ const unsigned char *subkey_h, unsigned char *iv)
+{
+ unsigned int rc;
+ unsigned char aad_pad[AES_BLOCK_SIZE];
+ unsigned long head_length;
+ unsigned long tail_length;
+ struct pad_meta c_pad_meta;
+
+ memset(c_pad_meta.pad, 0x00, sizeof(c_pad_meta.pad));
+
+ if (aad_length) {
+ tail_length = aad_length % AES_BLOCK_SIZE;
+ head_length = aad_length - tail_length;
+
+ /* ghash aad head */
+ if (head_length) {
+ rc = s390_ghash(aad, head_length, subkey_h, iv);
+ if (rc)
+ return rc;
+ }
+
+ /* ghash aad tail */
+ if (tail_length) {
+ memset(aad_pad, 0x00, AES_BLOCK_SIZE);
+ memcpy(aad_pad, aad + head_length, tail_length);
+
+ rc = s390_ghash(aad_pad, AES_BLOCK_SIZE, subkey_h, iv);
+ if (rc)
+ return rc;
+ }
+ }
+
+ if (text_length) {
+ tail_length = text_length % AES_BLOCK_SIZE;
+ head_length = text_length - tail_length;
+
+ /* ghash ciphertext head */
+ if (head_length) {
+ rc = s390_ghash(ciphertext, head_length, subkey_h, iv);
+ if (rc)
+ return rc;
+ }
+
+ /* ghash ciphertext tail and meta data */
+ if (tail_length) {
+
+ memcpy(c_pad_meta.pad, ciphertext + head_length, tail_length);
+
+ rc = s390_ghash((unsigned char *)&c_pad_meta,
+ AES_BLOCK_SIZE, subkey_h, iv);
+ if (rc)
+ return rc;
+
+ }
+ }
+ return 0;
+}
+
+static inline unsigned int s390_gcm_authenticate_last(
+ unsigned long aad_length, unsigned long ciph_length,
+ const unsigned char *subkey_h, unsigned char *iv)
+{
+ unsigned int rc;
+ struct pad_meta c_pad_meta;
+
+ memset(c_pad_meta.pad, 0x00, sizeof(c_pad_meta.pad));
+ c_pad_meta.length_a = (uint64_t)(aad_length * 8ul);
+ c_pad_meta.length_b = (uint64_t)(ciph_length * 8ul);
+
+ /* ghash meta data only */
+ rc = s390_ghash((unsigned char *)&c_pad_meta.length_a,
+ AES_BLOCK_SIZE,
+ subkey_h, iv);
+ if (rc)
+ return rc;
+
+ return 0;
+}
+
+static inline int s390_gcm(unsigned int function_code,
+ unsigned char *plaintext, unsigned long text_length,
+ unsigned char *ciphertext,
+ const unsigned char *iv, unsigned long iv_length,
+ const unsigned char *aad, unsigned long aad_length,
+ unsigned char *tag, unsigned long tag_length,
+ unsigned char *key)
+{
+ unsigned char subkey_h[AES_BLOCK_SIZE];
+ unsigned char j0[AES_BLOCK_SIZE];
+ unsigned char tmp_ctr[AES_BLOCK_SIZE];
+ /* temporary tag must be of size cipher block size */
+ unsigned char tmp_tag[AES_BLOCK_SIZE];
+ unsigned int rc;
+
+ if (!msa4_switch)
+ return EPERM;
+
+ /* calculate subkey H */
+ rc = s390_aes_ecb(UNDIRECTED_FC(function_code),
+ AES_BLOCK_SIZE, zero_block,
+ key, subkey_h);
+ if (rc)
+ return rc;
+
+ /* calculate initial counter, based on iv */
+ __compute_j0(iv, iv_length, subkey_h, j0);
+
+ /* prepate initial counter for cipher */
+ memcpy(tmp_ctr, j0, AES_BLOCK_SIZE);
+ __inc_aes_ctr((struct uint128 *)tmp_ctr, GCM_CTR_WIDTH);
+
+ /* en-/decrypt payload */
+ if (function_code % 2) {
+ /* decrypt */
+ rc = s390_aes_ctr(UNDIRECTED_FC(function_code),
+ ciphertext, plaintext, text_length,
+ key, tmp_ctr, GCM_CTR_WIDTH);
+ if (rc)
+ return rc;
+ } else {
+ /* encrypt */
+ rc = s390_aes_ctr(UNDIRECTED_FC(function_code),
+ plaintext, ciphertext, text_length,
+ key, tmp_ctr, GCM_CTR_WIDTH);
+ if (rc)
+ return rc;
+ }
+
+ /* generate authentication tag */
+ rc = s390_gcm_authenticate(ciphertext, text_length,
+ aad, aad_length,
+ subkey_h, tmp_tag);
+ if (rc)
+ return rc;
+
+ /* encrypt tag */
+ return s390_aes_ctr(UNDIRECTED_FC(function_code),
+ tmp_tag, tag, tag_length,
+ key, j0, GCM_CTR_WIDTH);
+}
+
+static inline int s390_gcm_initialize(unsigned int function_code,
+ const unsigned char *iv,
+ unsigned long iv_length,
+ unsigned char *key,
+ unsigned char *icb,
+ unsigned char *ucb,
+ unsigned char *subkey)
+{
+ int rc;
+
+ if (!icb || !ucb)
+ return -EINVAL;
+
+ /* calculate subkey H */
+ rc = s390_aes_ecb(UNDIRECTED_FC(function_code),
+ AES_BLOCK_SIZE, zero_block, key, subkey);
+ if (rc)
+ return rc;
+
+ /* calculate initial counter, based on iv */
+ __compute_j0(iv, iv_length, subkey, icb);
+
+ /* prepate usage counter for cipher */
+ memcpy(ucb, icb, AES_BLOCK_SIZE);
+ __inc_aes_ctr((struct uint128 *)ucb, GCM_CTR_WIDTH);
+
+ return 0;
+}
+
+static inline int s390_gcm_intermediate(unsigned int function_code,
+ unsigned char *plaintext, unsigned long text_length,
+ unsigned char *ciphertext,
+ unsigned char *ctr,
+ unsigned char *aad, unsigned long aad_length,
+ unsigned char *tag, unsigned long tag_length,
+ unsigned char *key, unsigned char *subkey)
+{
+ unsigned int rc;
+
+ if (!msa4_switch)
+ return EPERM;
+
+ /* en-/decrypt payload */
+ if (function_code % 2) {
+ /* decrypt */
+ rc = s390_aes_ctr(UNDIRECTED_FC(function_code), ciphertext, plaintext,
+ text_length, key, ctr, GCM_CTR_WIDTH);
+ if (rc)
+ return rc;
+ } else {
+ /* encrypt */
+ rc = s390_aes_ctr(UNDIRECTED_FC(function_code), plaintext, ciphertext,
+ text_length, key, ctr, GCM_CTR_WIDTH);
+ if (rc)
+ return rc;
+ }
+
+ /* generate authentication tag */
+ rc = s390_gcm_authenticate_intermediate(ciphertext, text_length, aad,
+ aad_length, subkey, tag);
+ if (rc)
+ return rc;
+
+ return 0;
+}
+
+static inline int s390_gcm_last(unsigned int function_code, unsigned char *icb,
+ unsigned long aad_length, unsigned long ciph_length,
+ unsigned char *tag, unsigned long tag_length,
+ unsigned char *key, unsigned char *subkey)
+{
+ unsigned char tmp_tag[AES_BLOCK_SIZE];
+ int rc;
+
+ /* generate authentication tag */
+ memcpy(tmp_tag, tag, tag_length);
+ rc = s390_gcm_authenticate_last(aad_length, ciph_length, subkey, tmp_tag);
+ if (rc)
+ return rc;
+
+ /* encrypt tag */
+ return s390_aes_ctr(UNDIRECTED_FC(function_code), tmp_tag, tag, tag_length,
+ key, icb, GCM_CTR_WIDTH);
+}
+#endif
diff --git a/src/include/s390_prng.h b/src/include/s390_prng.h
new file mode 100644
index 0000000..5219337
--- /dev/null
+++ b/src/include/s390_prng.h
@@ -0,0 +1,20 @@
+/* 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.
+ */
+
+/**
+ * Authors: Felix Beck <felix.beck@de.ibm.com>
+ * Christian Maaser <cmaaser@de.ibm.com>
+ *
+ * Copyright IBM Corp. 2009
+ */
+
+#ifndef S390_PRNG_H
+#define S390_PRNG_H
+
+int s390_prng_init(void);
+int s390_prng(unsigned char *output_data, unsigned int output_length);
+#endif
+
diff --git a/src/include/s390_rsa.h b/src/include/s390_rsa.h
new file mode 100644
index 0000000..5d30cfc
--- /dev/null
+++ b/src/include/s390_rsa.h
@@ -0,0 +1,47 @@
+/* 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.
+ */
+
+/**
+ * Authors: Felix Beck <felix.beck@de.ibm.com>
+ * Christian Maaser <cmaaser@de.ibm.com>
+ *
+ * Copyright IBM Corp. 2009, 2011
+ */
+
+#ifndef S390_RSA_H
+#define S390_RSA_H
+
+#include <openssl/bn.h>
+#include <asm/zcrypt.h>
+#include <semaphore.h>
+#include "ica_api.h"
+
+typedef struct ica_rsa_modexpo ica_rsa_modexpo_t;
+typedef struct ica_rsa_modexpo_crt ica_rsa_modexpo_crt_t;
+typedef struct ica_rsa_modexpo ica_rsa_modmult_t;
+unsigned int rsa_key_generate_mod_expo(ica_adapter_handle_t deviceHandle,
+ unsigned int modulus_bit_length,
+ ica_rsa_key_mod_expo_t *public_key,
+ ica_rsa_key_mod_expo_t *private_key);
+unsigned int ica_rsa_key_generate_crt(ica_adapter_handle_t device_handle,
+ unsigned int modulus_bit_length,
+ ica_rsa_key_mod_expo_t *public_key,
+ ica_rsa_key_crt_t *private_key);
+unsigned int rsa_key_generate_mod_expo(ica_adapter_handle_t deviceHandle,
+ unsigned int modulus_bit_length,
+ ica_rsa_key_mod_expo_t *public_key,
+ ica_rsa_key_mod_expo_t *private_key);
+unsigned int rsa_key_generate_crt(ica_adapter_handle_t deviceHandle,
+ unsigned int modulus_bit_length,
+ ica_rsa_key_mod_expo_t *public_key,
+ ica_rsa_key_crt_t *private_key);
+unsigned int rsa_crt_sw(ica_rsa_modexpo_crt_t * pCrt);
+unsigned int rsa_mod_mult_sw(ica_rsa_modmult_t * pMul);
+unsigned int rsa_mod_expo_sw(ica_rsa_modexpo_t *pMex);
+
+sem_t openssl_crypto_lock_mtx;
+#endif
+
diff --git a/src/include/s390_sha.h b/src/include/s390_sha.h
new file mode 100644
index 0000000..1cec7be
--- /dev/null
+++ b/src/include/s390_sha.h
@@ -0,0 +1,185 @@
+/* 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.
+ */
+
+/**
+ * Authors: Felix Beck <felix.beck@de.ibm.com>
+ * Christian Maaser <cmaaser@de.ibm.com>
+ *
+ * Copyright IBM Corp. 2009
+ */
+
+#ifndef S390_SHA_H
+#define S390_SHA_H
+
+static unsigned char SHA_1_DEFAULT_IV[] = {
+ 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, 0x98, 0xba, 0xdc, 0xfe,
+ 0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0 };
+
+static unsigned char SHA_224_DEFAULT_IV[] = {
+ 0xc1, 0x05, 0x9e, 0xd8, 0x36, 0x7c, 0xd5, 0x07, 0x30, 0x70, 0xdd, 0x17,
+ 0xf7, 0x0e, 0x59, 0x39, 0xff, 0xc0, 0x0b, 0x31, 0x68, 0x58, 0x15, 0x11,
+ 0x64, 0xf9, 0x8f, 0xa7, 0xbe, 0xfa, 0x4f, 0xa4 };
+
+static unsigned char SHA_256_DEFAULT_IV[] = {
+ 0x6a, 0x09, 0xe6, 0x67, 0xbb, 0x67, 0xae, 0x85, 0x3c, 0x6e, 0xf3, 0x72,
+ 0xa5, 0x4f, 0xf5, 0x3a, 0x51, 0x0e, 0x52, 0x7f, 0x9b, 0x05, 0x68, 0x8c,
+ 0x1f, 0x83, 0xd9, 0xab, 0x5b, 0xe0, 0xcd, 0x19 };
+
+static unsigned char SHA_384_DEFAULT_IV[] = {
+ 0xcb, 0xbb, 0x9d, 0x5d, 0xc1, 0x05, 0x9e, 0xd8, 0x62, 0x9a, 0x29, 0x2a,
+ 0x36, 0x7c, 0xd5, 0x07, 0x91, 0x59, 0x01, 0x5a, 0x30, 0x70, 0xdd, 0x17,
+ 0x15, 0x2f, 0xec, 0xd8, 0xf7, 0x0e, 0x59, 0x39, 0x67, 0x33, 0x26, 0x67,
+ 0xff, 0xc0, 0x0b, 0x31, 0x8e, 0xb4, 0x4a, 0x87, 0x68, 0x58, 0x15, 0x11,
+ 0xdb, 0x0c, 0x2e, 0x0d, 0x64, 0xf9, 0x8f, 0xa7, 0x47, 0xb5, 0x48, 0x1d,
+ 0xbe, 0xfa, 0x4f, 0xa4 };
+
+static unsigned char SHA_512_DEFAULT_IV[] = {
+ 0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08, 0xbb, 0x67, 0xae, 0x85,
+ 0x84, 0xca, 0xa7, 0x3b, 0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 0xf8, 0x2b,
+ 0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1, 0x51, 0x0e, 0x52, 0x7f,
+ 0xad, 0xe6, 0x82, 0xd1, 0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
+ 0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b, 0x5b, 0xe0, 0xcd, 0x19,
+ 0x13, 0x7e, 0x21, 0x79 };
+
+typedef struct {
+ unsigned int hw_function_code;
+ unsigned int hash_length;
+ unsigned int vector_length;
+ unsigned int block_length;
+ unsigned char *default_iv;
+} SHA_CONSTANTS;
+
+static const SHA_CONSTANTS sha_constants[] = {
+ {S390_CRYPTO_SHA_1, 20, 20, 64, SHA_1_DEFAULT_IV},
+ {S390_CRYPTO_SHA_256, 28, 32, 64, SHA_224_DEFAULT_IV},
+ {S390_CRYPTO_SHA_256, 32, 32, 64, SHA_256_DEFAULT_IV},
+ {S390_CRYPTO_SHA_512, 48, 64, 128, SHA_384_DEFAULT_IV},
+ {S390_CRYPTO_SHA_512, 64, 64, 128, SHA_512_DEFAULT_IV}
+};
+
+int s390_sha1(unsigned char *iv, unsigned char *input_data,
+ unsigned int input_length, unsigned char *output_data,
+ unsigned int message_part, uint64_t *running_length);
+
+int s390_sha224(unsigned char *iv, unsigned char *input_data,
+ unsigned int input_length, unsigned char *output_data,
+ unsigned int message_part, uint64_t *running_length);
+
+int s390_sha256(unsigned char *iv, unsigned char *input_data,
+ unsigned int input_length, unsigned char *output_data,
+ unsigned int message_part, uint64_t *running_length);
+
+int s390_sha384(unsigned char *iv, unsigned char *input_data,
+ uint64_t input_length, unsigned char *output_data,
+ unsigned int message_part, uint64_t *running_length_lo,
+ uint64_t *running_length_hi);
+
+int s390_sha512(unsigned char *iv, unsigned char *input_data,
+ uint64_t input_length, unsigned char *output_data,
+ unsigned int message_part, uint64_t *running_length_lo,
+ uint64_t *running_length_hi);
+
+static inline int s390_sha_hw(unsigned char *iv, unsigned char *input_data,
+ uint64_t input_length, unsigned char *output_data,
+ unsigned int message_part, uint64_t *running_length_lo,
+ uint64_t *running_length_hi, kimd_functions_t sha_function)
+{
+ int rc = 0;
+
+ uint64_t sum_lo = 0, sum_hi = 0;
+ unsigned long remnant = 0;
+ int complete_blocks_length = 0;
+
+ unsigned char *default_iv = sha_constants[sha_function].default_iv;
+ unsigned int hash_length = sha_constants[sha_function].hash_length;
+ unsigned int vector_length = sha_constants[sha_function].vector_length;
+ unsigned int hw_function_code
+ = sha_constants[sha_function].hw_function_code;
+
+ /* A internal buffer for the SHA hash and stream bit length. For SHA512
+ * this can be at most 128 byte for the hash plus 16 byte for the
+ * stream length. */
+ unsigned char shabuff[128 + 16];
+
+ if (input_length) {
+ remnant = input_length % sha_constants[sha_function].block_length;
+ complete_blocks_length = input_length - remnant;
+ }
+
+ if (message_part == SHA_MSG_PART_ONLY ||
+ message_part == SHA_MSG_PART_FIRST) {
+ memcpy(shabuff, default_iv, vector_length);
+ *running_length_lo = 0;
+ if (running_length_hi)
+ *running_length_hi = 0;
+ }
+ else
+ memcpy(shabuff, (void *)iv, vector_length);
+
+ sum_lo = *running_length_lo;
+ if(running_length_hi)
+ sum_hi = *running_length_hi;
+
+ if ((message_part == SHA_MSG_PART_FIRST ||
+ message_part == SHA_MSG_PART_MIDDLE) && (remnant != 0))
+ return EINVAL;
+
+ if (complete_blocks_length) {
+ rc = s390_kimd(hw_function_code, shabuff, input_data,
+ complete_blocks_length);
+ if (rc > 0) {
+ /* Check for overflow in sum_lo */
+ sum_lo += rc;
+ if(sum_lo < *running_length_lo || sum_lo < rc)
+ sum_hi += 1;
+ rc = 0;
+ }
+ }
+
+ if (rc == 0 && (message_part == SHA_MSG_PART_ONLY ||
+ message_part == SHA_MSG_PART_FINAL)) {
+ sum_lo += (uint64_t)remnant;
+ if(sum_lo < remnant)
+ sum_hi += 1;
+
+ if(running_length_hi){
+ sum_hi = (sum_hi << 3) + (sum_lo >> (64 - 3));
+ sum_lo = sum_lo << 3;
+ memcpy(shabuff + vector_length,
+ (unsigned char *)&sum_hi, sizeof(sum_hi));
+ memcpy(shabuff + vector_length + sizeof(sum_hi),
+ (unsigned char *)&sum_lo, sizeof(sum_lo));
+ }
+ else {
+ sum_lo = sum_lo << 3;
+ memcpy(shabuff + vector_length,
+ (unsigned char *)&sum_lo, sizeof(sum_lo));
+ }
+ rc = s390_klmd(hw_function_code, shabuff,
+ input_data + complete_blocks_length, remnant);
+ if (rc > 0)
+ rc = 0;
+ }
+
+ if (rc == 0) {
+ memcpy((void *)output_data, shabuff, hash_length);
+ if (message_part != SHA_MSG_PART_FINAL &&
+ message_part != SHA_MSG_PART_ONLY) {
+ memcpy((void *)iv, shabuff, vector_length);
+ *running_length_lo = sum_lo;
+ if(running_length_hi)
+ *running_length_hi = sum_hi;
+ }
+ }
+
+ if (rc < 0)
+ return EIO;
+
+ return rc;
+}
+
+#endif
+
diff --git a/src/include/test_vec.h b/src/include/test_vec.h
new file mode 100644
index 0000000..00950ad
--- /dev/null
+++ b/src/include/test_vec.h
@@ -0,0 +1,311 @@
+/*
+ * 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. 2015
+ */
+#ifndef TEST_VEC_H
+#define TEST_VEC_H
+
+#include <stdbool.h>
+#include <stddef.h>
+
+#define AES128_KEYLEN (128 / 8)
+#define AES192_KEYLEN (192 / 8)
+#define AES256_KEYLEN (256 / 8)
+#define DES3_KEYLEN (192 / 8)
+
+#define AES_BLKSIZE (128 / 8)
+#define DES3_BLKSIZE ( 64 / 8)
+
+struct aes_ecb_tv {
+ size_t keylen;
+ size_t len;
+ unsigned char *key;
+ unsigned char *plaintext;
+ unsigned char *ciphertext;
+};
+
+struct aes_cbc_tv {
+ size_t keylen;
+ size_t len;
+ unsigned char *key;
+ unsigned char iv[AES_BLKSIZE];
+ unsigned char *plaintext;
+ unsigned char *ciphertext;
+};
+
+struct aes_cbc_cs_tv {
+ size_t keylen;
+ size_t len;
+ unsigned char *key;
+ unsigned char iv[AES_BLKSIZE];
+ unsigned char iv_out[AES_BLKSIZE];
+ unsigned char *plaintext;
+ unsigned char *ciphertext;
+ int variant;
+};
+
+struct aes_cfb_tv {
+ size_t keylen;
+ size_t len;
+ int lcfb;
+ unsigned char *key;
+ unsigned char iv[AES_BLKSIZE];
+ unsigned char *plaintext;
+ unsigned char *ciphertext;
+};
+
+struct aes_ofb_tv {
+ size_t keylen;
+ size_t len;
+ unsigned char *key;
+ unsigned char iv[AES_BLKSIZE];
+ unsigned char *plaintext;
+ unsigned char *ciphertext;
+};
+
+struct aes_ctr_tv {
+ size_t keylen;
+ size_t len;
+ unsigned char *key;
+ unsigned char ctr[AES_BLKSIZE];
+ unsigned char *plaintext;
+ unsigned char *ciphertext;
+};
+
+struct aes_ccm_tv {
+ size_t keylen;
+ size_t noncelen;
+ size_t adatalen;
+ size_t payloadlen;
+ size_t taglen;
+ unsigned char *key;
+ unsigned char *nonce;
+ unsigned char *adata;
+ unsigned char *payload;
+ unsigned char *ciphertext;
+ int rv;
+};
+
+struct aes_gcm_tv {
+ size_t keylen;
+ size_t ivlen;
+ size_t len;
+ size_t aadlen;
+ size_t taglen;
+ unsigned char *key;
+ unsigned char *iv;
+ unsigned char *plaintext;
+ unsigned char *aad;
+ unsigned char *tag;
+ unsigned char *ciphertext;
+ int rv;
+};
+
+struct aes_xts_tv {
+ size_t len;
+ size_t keylen;
+ unsigned char *key1;
+ unsigned char *key2;
+ unsigned char tweak[16];
+ unsigned char *plaintext;
+ unsigned char *ciphertext;
+};
+
+struct aes_cmac_tv {
+ size_t keylen;
+ size_t msglen;
+ size_t maclen;
+ unsigned char *key;
+ unsigned char *msg;
+ unsigned char *mac;
+ int rv;
+};
+
+struct des3_ecb_tv {
+ size_t len;
+ unsigned char key[DES3_KEYLEN];
+ unsigned char *plaintext;
+ unsigned char *ciphertext;
+};
+
+struct des3_cbc_tv {
+ size_t len;
+ unsigned char key[DES3_KEYLEN];
+ unsigned char iv[DES3_BLKSIZE];
+ unsigned char *plaintext;
+ unsigned char *ciphertext;
+};
+
+struct des3_cbc_cs_tv {
+ size_t len;
+ unsigned char key[DES3_KEYLEN];
+ unsigned char iv[DES3_BLKSIZE];
+ unsigned char *plaintext;
+ unsigned char *ciphertext;
+ int variant;
+};
+
+struct des3_cfb_tv {
+ size_t len;
+ int lcfb;
+ unsigned char key[DES3_KEYLEN];
+ unsigned char iv[DES3_BLKSIZE];
+ unsigned char *plaintext;
+ unsigned char *ciphertext;
+};
+
+struct des3_ofb_tv {
+ size_t len;
+ unsigned char key[DES3_KEYLEN];
+ unsigned char iv[DES3_BLKSIZE];
+ unsigned char *plaintext;
+ unsigned char *ciphertext;
+};
+
+struct des3_ctr_tv {
+ size_t len;
+ unsigned char key[DES3_KEYLEN];
+ unsigned char ctr[DES3_BLKSIZE];
+ unsigned char *plaintext;
+ unsigned char *ciphertext;
+};
+
+struct des3_cmac_tv {
+ size_t msglen;
+ size_t maclen;
+ unsigned char key[DES3_KEYLEN];
+ unsigned char *msg;
+ unsigned char *mac;
+ int rv;
+};
+
+struct rsa_tv {
+ unsigned char *n;
+ unsigned char *p;
+ unsigned char *dp;
+ unsigned char *q;
+ unsigned char *dq;
+ unsigned char *qinv;
+ unsigned char *e;
+ unsigned char *d;
+ unsigned char *plaintext;
+ unsigned char *ciphertext;
+ int mod;
+};
+
+struct sha_tv {
+ size_t msg_len;
+ unsigned char *msg;
+ unsigned char *md;
+};
+
+struct drbg_sha512_tv {
+ bool no_reseed;
+ bool pr;
+ size_t entropy_len;
+ size_t nonce_len;
+ size_t pers_len;
+ size_t add_len;
+ size_t prnd_len;
+
+ struct{
+ unsigned char *entropy;
+ unsigned char *nonce;
+ unsigned char *pers;
+
+ unsigned char *v;
+ unsigned char *c;
+ int reseed_ctr;
+ } inst;
+
+ struct {
+ unsigned char *entropy;
+ unsigned char *add;
+
+ unsigned char *v;
+ unsigned char *c;
+ int reseed_ctr;
+ } res, gen1, gen2;
+
+ unsigned char *prnd;
+};
+
+#ifdef ICA_FIPS
+extern const struct aes_ecb_tv AES_ECB_TV[];
+extern const size_t AES_ECB_TV_LEN;
+
+extern const struct aes_cbc_tv AES_CBC_TV[];
+extern const size_t AES_CBC_TV_LEN;
+
+extern const struct aes_cbc_cs_tv AES_CBC_CS_TV[];
+extern const size_t AES_CBC_CS_TV_LEN;
+
+extern const struct aes_cfb_tv AES_CFB_TV[];
+extern const size_t AES_CFB_TV_LEN;
+
+extern const struct aes_ofb_tv AES_OFB_TV[];
+extern const size_t AES_OFB_TV_LEN;
+
+extern const struct aes_ctr_tv AES_CTR_TV[];
+extern const size_t AES_CTR_TV_LEN;
+
+extern const struct aes_ccm_tv AES_CCM_TV[];
+extern const size_t AES_CCM_TV_LEN;
+
+extern const struct aes_gcm_tv AES_GCM_TV[];
+extern const size_t AES_GCM_TV_LEN;
+
+extern const struct aes_xts_tv AES_XTS_TV[];
+extern const size_t AES_XTS_TV_LEN;
+
+extern const struct aes_cmac_tv AES_CMAC_TV[];
+extern const size_t AES_CMAC_TV_LEN;
+
+extern const struct des3_ecb_tv DES3_ECB_TV[];
+extern const size_t DES3_ECB_TV_LEN;
+
+extern const struct des3_cbc_tv DES3_CBC_TV[];
+extern const size_t DES3_CBC_TV_LEN;
+
+extern const struct des3_cbc_cs_tv DES3_CBC_CS_TV[];
+extern const size_t DES3_CBC_CS_TV_LEN;
+
+extern const struct des3_cfb_tv DES3_CFB_TV[];
+extern const size_t DES3_CFB_TV_LEN;
+
+extern const struct des3_ofb_tv DES3_OFB_TV[];
+extern const size_t DES3_OFB_TV_LEN;
+
+extern const struct des3_ctr_tv DES3_CTR_TV[];
+extern const size_t DES3_CTR_TV_LEN;
+
+extern const struct des3_cmac_tv DES3_CMAC_TV[];
+extern const size_t DES3_CMAC_TV_LEN;
+
+extern const struct rsa_tv RSA_TV[];
+extern const size_t RSA_TV_LEN;
+
+extern const struct sha_tv SHA1_TV[];
+extern const size_t SHA1_TV_LEN;
+
+extern const struct sha_tv SHA224_TV[];
+extern const size_t SHA224_TV_LEN;
+
+extern const struct sha_tv SHA256_TV[];
+extern const size_t SHA256_TV_LEN;
+
+extern const struct sha_tv SHA384_TV[];
+extern const size_t SHA384_TV_LEN;
+
+extern const struct sha_tv SHA512_TV[];
+extern const size_t SHA512_TV_LEN;
+#endif /* ICA_FIPS */
+
+extern const struct drbg_sha512_tv DRBG_SHA512_TV[];
+extern const size_t DRBG_SHA512_TV_LEN;
+
+#endif /* TEST_VEC_H */
diff --git a/src/init.c b/src/init.c
new file mode 100644
index 0000000..8a3da4c
--- /dev/null
+++ b/src/init.c
@@ -0,0 +1,178 @@
+/* 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.
+ */
+
+/**
+ * Authors: Felix Beck <felix.beck@de.ibm.com>
+ * Christian Maaser <cmaaser@de.ibm.com>
+ * Ingo Tuchscherer <ingo.tuchscherer.linux.vnet.ibm.com>
+ *
+ * Copyright IBM Corp. 2001, 2009, 2011
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/rand.h>
+#include <openssl/crypto.h>
+#include <semaphore.h>
+#include <pthread.h>
+#include <syslog.h>
+
+#include "init.h"
+#include "fips.h"
+#include "icastats.h"
+#include "s390_rsa.h"
+#include "s390_prng.h"
+#include "s390_crypto.h"
+#include "ica_api.h"
+
+static pthread_key_t envq_key;
+static pthread_once_t envq_key_once = PTHREAD_ONCE_INIT;
+
+static void destroy_envq(void* envq)
+{
+ free(envq);
+}
+
+static void make_envq_key()
+{
+ pthread_key_create(&envq_key, destroy_envq);
+}
+
+static void sigill_handler(int sig)
+{
+ jmp_buf* envq = pthread_getspecific(envq_key);
+ if (envq) {
+ longjmp(*envq, EXCEPTION_RV);
+ }
+}
+
+int begin_sigill_section(struct sigaction *oldact, sigset_t *oldset)
+{
+ struct sigaction newact;
+ sigset_t newset;
+
+ sigemptyset(&newset);
+ sigaddset(&newset, SIGILL);
+ sigprocmask(SIG_UNBLOCK, &newset, oldset);
+ newact.sa_handler = (void *)sigill_handler;
+ newact.sa_flags = 0;
+ sigaction(SIGILL, &newact, oldact);
+
+ jmp_buf* envq;
+ pthread_once(&envq_key_once, make_envq_key);
+ if ((envq = pthread_getspecific(envq_key)) == 0)
+ {
+ envq = malloc(sizeof(jmp_buf));
+ pthread_setspecific(envq_key, envq);
+ }
+ if (setjmp(*envq) != 0) {
+ end_sigill_section(oldact, oldset);
+ return -1;
+ }
+ return 0;
+}
+
+void end_sigill_section(struct sigaction *oldact, sigset_t *oldset)
+{
+ sigaction(SIGILL, oldact, 0);
+ sigprocmask(SIG_SETMASK, oldset, 0);
+}
+
+static pthread_mutex_t *openssl_locks;
+
+static void openssl_lock_callback(int mode, int num, char *file, int line)
+{
+ if (mode & CRYPTO_LOCK) {
+ pthread_mutex_lock(&(openssl_locks[num]));
+ }
+ else {
+ pthread_mutex_unlock(&(openssl_locks[num]));
+ }
+}
+
+static unsigned long get_thread_id(void)
+{
+ return (unsigned long)pthread_self();
+}
+
+static void init_openssl_locks(void)
+{
+ int i, crypt_num_locks;
+
+ crypt_num_locks = CRYPTO_num_locks();
+ openssl_locks = (pthread_mutex_t *)
+ OPENSSL_malloc(crypt_num_locks *
+ sizeof(pthread_mutex_t));
+ for (i = 0; i < CRYPTO_num_locks(); i++) {
+ pthread_mutex_init(&(openssl_locks[i]),NULL);
+ }
+
+ CRYPTO_set_id_callback((unsigned long (*)())get_thread_id);
+ CRYPTO_set_locking_callback((void (*)
+ (int, int, const char*, int))openssl_lock_callback);
+
+ sem_init(&openssl_crypto_lock_mtx, 0, crypt_num_locks);
+}
+
+static void free_openssl_locks(void)
+{
+ int i;
+
+ CRYPTO_set_locking_callback(NULL);
+ for (i = 0; i < CRYPTO_num_locks(); i++)
+ pthread_mutex_destroy(&(openssl_locks[i]));
+
+ OPENSSL_free(openssl_locks);
+}
+
+void openssl_init(void)
+{
+ /* initial seed the openssl random generator */
+ unsigned char random_data[64];
+ s390_prng(random_data, sizeof(random_data));
+ RAND_seed(random_data, sizeof(random_data));
+ init_openssl_locks();
+}
+
+/* Switches have to be done first. Otherwise we will not have hw support
+ * in initialization */
+void __attribute__ ((constructor)) icainit(void)
+{
+ /* some init stuff but only when application is NOT icastats */
+ if (strcmp(program_invocation_name, "icastats")) {
+
+ if(stats_mmap(-1) == -1){
+ syslog(LOG_INFO,
+ "Failed to access shared memory segment for libica statistics.");
+ }
+
+ s390_crypto_switches_init();
+
+#ifdef ICA_FIPS
+ fips_init();
+ fips_powerup_tests();
+#else
+ /* The fips_powerup_tests() include the ica_drbg_health_test(). */
+ ica_drbg_health_test(ica_drbg_generate, 256, true,
+ ICA_DRBG_SHA512);
+#endif /* ICA_FIPS */
+
+ s390_prng_init();
+
+ s390_initialize_functionlist();
+
+ openssl_init();
+ }
+}
+
+void __attribute__ ((destructor)) icaexit(void)
+{
+ stats_munmap(SHM_CLOSE);
+ free_openssl_locks();
+}
diff --git a/src/s390_crypto.c b/src/s390_crypto.c
new file mode 100644
index 0000000..17cc068
--- /dev/null
+++ b/src/s390_crypto.c
@@ -0,0 +1,392 @@
+/* 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.
+ */
+
+/*
+ * Entry point for crypto graphic instructions on s390. If a instruction
+ * is not available, instruction will be simulated in software.
+ *
+ * Authors(s): Ralph Wuerthner <rwuerthn@de.ibm.com>
+ * Jan Glauber <jan.glauber@de.ibm.com>
+ * Felix Beck <felix.beck@de.ibm.com>
+ * Christian Maaser <cmaaser@de.ibm.com>
+ * Holger Dengler <hd@linux.vnet.ibm.com>
+ * Ingo Tuchscherer <ingo.tuchscherer.linux.vnet.ibm.com>
+ *
+ * Copyright IBM Copr. 2007, 2009, 2011, 2013
+ */
+
+#include <stdint.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "fips.h"
+#include "init.h"
+#include "s390_crypto.h"
+
+unsigned int sha1_switch, sha256_switch, sha512_switch, des_switch,
+ tdes_switch, aes128_switch, aes192_switch, aes256_switch,
+ prng_switch, tdea128_switch, tdea192_switch, sha512_drng_switch,
+ msa4_switch, msa5_switch;
+
+s390_supported_function_t s390_kimd_functions[] = {
+ {SHA_1, S390_CRYPTO_SHA_1, &sha1_switch},
+ {SHA_224, S390_CRYPTO_SHA_256, &sha256_switch},
+ {SHA_256, S390_CRYPTO_SHA_256, &sha256_switch},
+ {SHA_384, S390_CRYPTO_SHA_512, &sha512_switch},
+ {SHA_512, S390_CRYPTO_SHA_512, &sha512_switch},
+ {GHASH, S390_CRYPTO_GHASH, &msa4_switch}
+};
+
+s390_supported_function_t s390_kmc_functions[] = {
+ {DEA_ENCRYPT, S390_CRYPTO_DEA_ENCRYPT, &des_switch},
+ {DEA_DECRYPT, S390_CRYPTO_DEA_DECRYPT, &des_switch},
+ {TDEA_192_ENCRYPT, S390_CRYPTO_TDEA_192_ENCRYPT, &tdes_switch},
+ {TDEA_192_DECRYPT, S390_CRYPTO_TDEA_192_DECRYPT, &tdes_switch},
+ {AES_128_ENCRYPT, S390_CRYPTO_AES_128_ENCRYPT, &aes128_switch},
+ {AES_128_DECRYPT, S390_CRYPTO_AES_128_DECRYPT, &aes128_switch},
+ {AES_192_ENCRYPT, S390_CRYPTO_AES_192_ENCRYPT, &aes192_switch},
+ {AES_192_DECRYPT, S390_CRYPTO_AES_192_DECRYPT, &aes192_switch},
+ {AES_256_ENCRYPT, S390_CRYPTO_AES_256_ENCRYPT, &aes256_switch},
+ {AES_256_DECRYPT, S390_CRYPTO_AES_256_DECRYPT, &aes256_switch},
+ {AES_128_XTS_ENCRYPT, S390_CRYPTO_AES_128_XTS_ENCRYPT, &msa4_switch},
+ {AES_128_XTS_DECRYPT, S390_CRYPTO_AES_128_XTS_DECRYPT, &msa4_switch},
+ {AES_256_XTS_ENCRYPT, S390_CRYPTO_AES_256_XTS_ENCRYPT, &msa4_switch},
+ {AES_256_XTS_DECRYPT, S390_CRYPTO_AES_256_XTS_DECRYPT, &msa4_switch},
+ {PRNG, S390_CRYPTO_PRNG, &prng_switch}
+};
+
+s390_supported_function_t s390_msa4_functions[] = {
+ {DEA_ENCRYPT, S390_CRYPTO_DEA_ENCRYPT, &msa4_switch},
+ {DEA_DECRYPT, S390_CRYPTO_DEA_DECRYPT, &msa4_switch},
+ {TDEA_192_ENCRYPT, S390_CRYPTO_TDEA_192_ENCRYPT, &msa4_switch},
+ {TDEA_192_DECRYPT, S390_CRYPTO_TDEA_192_DECRYPT, &msa4_switch},
+ {AES_128_ENCRYPT, S390_CRYPTO_AES_128_ENCRYPT, &msa4_switch},
+ {AES_128_DECRYPT, S390_CRYPTO_AES_128_DECRYPT, &msa4_switch},
+ {AES_192_ENCRYPT, S390_CRYPTO_AES_192_ENCRYPT, &msa4_switch},
+ {AES_192_DECRYPT, S390_CRYPTO_AES_192_DECRYPT, &msa4_switch},
+ {AES_256_ENCRYPT, S390_CRYPTO_AES_256_ENCRYPT, &msa4_switch},
+ {AES_256_DECRYPT, S390_CRYPTO_AES_256_DECRYPT, &msa4_switch},
+ {AES_128_XTS_ENCRYPT, S390_CRYPTO_AES_128_XTS_ENCRYPT, &msa4_switch},
+ {AES_128_XTS_DECRYPT, S390_CRYPTO_AES_128_XTS_DECRYPT, &msa4_switch},
+ {AES_256_XTS_ENCRYPT, S390_CRYPTO_AES_256_XTS_ENCRYPT, &msa4_switch},
+ {AES_256_XTS_DECRYPT, S390_CRYPTO_AES_256_XTS_DECRYPT, &msa4_switch}
+};
+
+s390_supported_function_t s390_ppno_functions[] = {
+ {SHA512_DRNG_GEN, S390_CRYPTO_SHA512_DRNG_GEN, &sha512_drng_switch},
+ {SHA512_DRNG_SEED, S390_CRYPTO_SHA512_DRNG_SEED, &sha512_drng_switch},
+};
+
+int read_cpuinfo(void)
+{
+ int msa = 0;
+ FILE *handle = fopen("/proc/cpuinfo", "r");
+ if (handle) {
+ char buffer[80];
+ int i = 0;
+ while(fgets(buffer, sizeof(buffer), handle)) {
+ i++;
+ if(strstr(buffer,"features") && strstr(buffer,"msa")) {
+ msa = 1;
+ break;
+ }
+ }
+ fclose(handle);
+ }
+ return msa;
+}
+
+int read_facility_bits(void)
+{
+ int msa = 0;
+ unsigned long long facility_bits[2] = {0};
+ struct sigaction oldact;
+ sigset_t oldset;
+ int rc = -1;
+
+ rc = begin_sigill_section(&oldact, &oldset);
+ if (!rc) {
+ rc = __stfle(facility_bits, 2);
+ end_sigill_section(&oldact, &oldset);
+ }
+ /* __stfle always returns the no. of double words needed to store the
+ * facility bits. This quantity is machine dependent. However, we just
+ * need the first two double words. */
+ if(rc >= 2){
+ if(facility_bits[0] & (1ULL << (63 - 17)))
+ msa = 1;
+ if(facility_bits[1] & (1ULL << (127 - 76)))
+ msa = 3;
+ if(facility_bits[1] & (1ULL << (127 - 77)))
+ msa = 4;
+ if(facility_bits[0] & (1ULL << (63 - 57)))
+ msa = 5;
+ }
+
+ return msa;
+}
+
+void set_switches(int msa)
+{
+ unsigned char mask[16];
+ unsigned int n;
+ unsigned int on = 0;
+ struct sigaction oldact;
+ sigset_t oldset;
+ /* The function arrays contain integers. Thus to compute the amount of
+ * their elements the result of sizeof(*functions) has to be divided by
+ * sizeof(int).
+ * The msa4_switch will be set in the kimd function. Because this is
+ * the only switch for all MSA4 functions we just set it through the
+ * kimd query and do not need to over the whole array. Therfore there
+ * is also no distict setting of the switch needed in form
+ * msa4_switch = 1. */
+
+ /* kmc query */
+ memset(mask, 0, sizeof(mask));
+ if (msa) {
+ if (begin_sigill_section(&oldact, &oldset) == 0) {
+ s390_kmc(S390_CRYPTO_QUERY, mask, (void *) 0, (void *) 0, 0);
+ end_sigill_section(&oldact, &oldset);
+ }
+ }
+ for (n = 0; n < (sizeof(s390_kmc_functions) /
+ sizeof(s390_supported_function_t)); n++) {
+ if (S390_CRYPTO_TEST_MASK(mask, s390_kmc_functions[n].hw_fc))
+ on = 1;
+ else
+ on = 0;
+ *s390_kmc_functions[n].enabled = on;
+ }
+
+ /* kimd query */
+ memset(mask, 0, sizeof(mask));
+ if (msa) {
+ if (begin_sigill_section(&oldact, &oldset) == 0) {
+ s390_kimd(S390_CRYPTO_QUERY, mask, (void *) 0, 0);
+ end_sigill_section(&oldact, &oldset);
+ }
+ }
+ for (n = 0; n < (sizeof(s390_kimd_functions) /
+ sizeof(s390_supported_function_t)); n++) {
+ if (S390_CRYPTO_TEST_MASK(mask, s390_kimd_functions[n].hw_fc))
+ on = 1;
+ else
+ on = 0;
+ *s390_kimd_functions[n].enabled = on;
+ }
+
+ /* ppno query */
+ memset(mask, 0, sizeof(mask));
+ if (5 <= msa) {
+ msa5_switch = 1;
+ if (begin_sigill_section(&oldact, &oldset) == 0) {
+ s390_ppno(S390_CRYPTO_QUERY, mask, NULL, 0, NULL, 0);
+ end_sigill_section(&oldact, &oldset);
+ }
+ }
+ for (n = 0; n < (sizeof(s390_ppno_functions) /
+ sizeof(s390_supported_function_t)); n++) {
+ if (S390_CRYPTO_TEST_MASK(mask, s390_ppno_functions[n].hw_fc))
+ on = 1;
+ else
+ on = 0;
+ *s390_ppno_functions[n].enabled = on;
+ }
+}
+
+void s390_crypto_switches_init(void)
+{
+ int msa;
+
+ msa = read_facility_bits();
+ if (!msa)
+ msa = read_cpuinfo();
+
+ set_switches(msa);
+}
+
+/*
+ * The first field represents the mechanism ID.
+ * The second field represents the function family type (category),
+ * The third filed represents the function code.
+ * This function code will be used later to check if HW support
+ * is available and modifies the SW/HW-support-flag.
+ * SHW - static hardware support (CPACF)
+ * DHW - dynamic hardware support (crypto adapter)
+ * SW - software support
+ * Bit field flags: [0|0|0|0|0|SHW|DHW|SW]
+ * The last filed represent the property flags
+ */
+libica_func_list_element_int icaList[] = {
+ {SHA1, KIMD, SHA_1 , ICA_FLAG_SW, 0},
+ {SHA224, KIMD, SHA_256 , ICA_FLAG_SW, 0},
+ {SHA256, KIMD, SHA_256 , ICA_FLAG_SW, 0},
+ {SHA384, KIMD, SHA_512 , ICA_FLAG_SW, 0},
+ {SHA512, KIMD, SHA_512 , ICA_FLAG_SW, 0},
+ {G_HASH, KIMD, GHASH , 0, 0},
+
+ {DES_ECB, KMC, DEA_ENCRYPT, ICA_FLAG_SW, 0},
+ {DES_CBC, KMC, DEA_ENCRYPT, ICA_FLAG_SW, 0},
+ {DES_OFB, MSA4, DEA_ENCRYPT, 0, 0},
+ {DES_CFB, MSA4, DEA_ENCRYPT, 0, 0},
+ {DES_CTR, MSA4, DEA_ENCRYPT, 0, 0},
+ {DES_CMAC, MSA4, DEA_ENCRYPT, 0, 0}, // CPACF only (MSA4)
+
+ {DES3_ECB, KMC, TDEA_192_ENCRYPT, ICA_FLAG_SW, 0},
+ {DES3_CBC, KMC, TDEA_192_ENCRYPT, ICA_FLAG_SW, 0},
+ {DES3_OFB, MSA4, TDEA_192_ENCRYPT, 0, 0},
+ {DES3_CFB, MSA4, TDEA_192_ENCRYPT, 0, 0},
+ {DES3_CTR, MSA4, TDEA_192_ENCRYPT, 0, 0},
+ {DES3_CMAC, MSA4, TDEA_192_ENCRYPT, 0, 0},
+
+ {AES_ECB, KMC, AES_128_ENCRYPT, ICA_FLAG_SW, 0},
+ {AES_CBC, KMC, AES_128_ENCRYPT, ICA_FLAG_SW, 0},
+ {AES_OFB, MSA4, AES_128_ENCRYPT, 0, 0},
+ {AES_CFB, MSA4, AES_128_ENCRYPT, 0, 0},
+ {AES_CTR, MSA4, AES_128_ENCRYPT, 0, 0},
+ {AES_CMAC, MSA4, AES_128_ENCRYPT, 0, 0},
+ {AES_CCM, MSA4, AES_128_ENCRYPT, 0, 0},
+ {AES_GCM, MSA4, AES_128_ENCRYPT, 0, 0},
+ {AES_XTS, MSA4, AES_128_XTS_ENCRYPT, 0, 0},
+ {P_RNG, ADAPTER, 0, ICA_FLAG_SHW | ICA_FLAG_SW, 0}, // SHW (CPACF) + SW
+ {RSA_ME, ADAPTER, 0, ICA_FLAG_DHW | ICA_FLAG_SW, 0x0F}, // DHW (CEX) + SW / 512,1024,2048, 4096 bit key length
+ {RSA_CRT, ADAPTER, 0, ICA_FLAG_DHW | ICA_FLAG_SW, 0x0F}, // DHW (CEX) + SW / 512,1024,2048, 4096 bit key length
+ {RSA_KEY_GEN_ME, ADAPTER, 0, ICA_FLAG_SW, 0}, // SW (openssl)
+ {RSA_KEY_GEN_CRT, ADAPTER, 0, ICA_FLAG_SW, 0}, // SW (openssl)
+
+ {SHA512_DRNG, PPNO, SHA512_DRNG_GEN, ICA_FLAG_SW, 0},
+
+/* available for the MSA4 instruction */
+/* available for the RSA instruction */
+
+};
+
+/*
+ * initializes the libica function list
+ * Query s390_xxx_functions for each algorithm to check
+ * CPACF support and update the corresponding SHW-flags.
+ */
+int s390_initialize_functionlist() {
+
+ unsigned int list_len = sizeof(icaList)/sizeof(libica_func_list_element_int);
+
+ unsigned int x;
+ for (x = 0; x < list_len; x++) {
+ switch ((int)icaList[x].type) {
+ case KIMD:
+ icaList[x].flags = icaList[x].flags |
+ ((*s390_kimd_functions[icaList[x].id].enabled)? 4: 0);
+ break;
+ case KMC:
+ icaList[x].flags = icaList[x].flags |
+ ((*s390_kmc_functions[icaList[x].id].enabled)? 4: 0);
+ if (icaList[x].id == AES_128_ENCRYPT) { // check for the maximum size
+ if (*s390_kmc_functions[icaList[AES_256_ENCRYPT].id].enabled)
+ icaList[x].property = icaList[x].property | 4; // 256 bit
+ if (*s390_kmc_functions[icaList[AES_192_ENCRYPT].id].enabled)
+ icaList[x].property = icaList[x].property | 2; // 192 bit
+ if (*s390_kmc_functions[icaList[AES_128_ENCRYPT].id].enabled)
+ icaList[x].property = icaList[x].property | 1; // 128 bit
+ }
+ break;
+ case MSA4:
+ icaList[x].flags = icaList[x].flags |
+ ((*s390_msa4_functions[icaList[x].id].enabled)? 4: 0);
+ if (icaList[x].id == AES_128_ENCRYPT) { // check for the maximum size
+ if (*s390_msa4_functions[icaList[AES_256_ENCRYPT].id].enabled)
+ icaList[x].property = icaList[x].property | 4; // 256 bit
+ if (*s390_msa4_functions[icaList[AES_192_ENCRYPT].id].enabled)
+ icaList[x].property = icaList[x].property | 2; // 192 bit
+ if (*s390_msa4_functions[icaList[AES_128_ENCRYPT].id].enabled)
+ icaList[x].property = icaList[x].property | 1; // 128 bit
+ }
+ else if (icaList[x].id == AES_128_XTS_ENCRYPT) { // check for the maximum size
+ if (*s390_msa4_functions[icaList[AES_256_XTS_ENCRYPT].id].enabled)
+ icaList[x].property = icaList[x].property | 2; // 256 bit
+ if (*s390_msa4_functions[icaList[AES_128_XTS_ENCRYPT].id].enabled)
+ icaList[x].property = icaList[x].property | 1; // 128 bit
+ }
+ break;
+ case PPNO:
+ icaList[x].flags = icaList[x].flags |
+ ((*s390_ppno_functions[icaList[x].id].enabled)? 4: 0);
+ break;
+ default:
+ /* Do nothing. */
+ break;
+ }
+ }
+ return 0;
+}
+
+/**
+ * Function that returns a list of crypto mechanisms supported by libica.
+ * @param pmech_list
+ * Pointer to an array of libica_func_list_element
+ * If NULL, the API will return the number of elements to allocate
+ * in the @pmech_list_len parameter.
+ * If not NULL, libica will assume @pmech_list is an array that has
+ * @pmech_list_len elements.
+ * On success, @pmech_list will be filled out with the supported libica
+ * crypto mechanisms.
+ * @param pmech_list_len
+ * number of list entries
+ * On input, pointer to the number of elements allocated in the
+ * @pmech_list array.
+ * On output, @pmech_list_len will contain the number of items copied to
+ * the @pmech_list array, or the number of items libica would have returned
+ * in case the @pmech_list parameter is set to NULL.
+ *
+ * @return
+ * 0 on success
+ * EINVAL if at least one invalid parameter is given
+ *
+ * A typical usage scenario would be that an exploiter makes a first call to
+ * ica_get_functionlist() with @pmech_list set to NULL in order to determine
+ * the number of elements to allocate. This is followed by a second call to
+ * ica_get_functionlist() with a valid pointer @pmech_list to an array of
+ * libica_func_list_element structures with @pmech_list_len elements.
+ */
+int s390_get_functionlist(libica_func_list_element *pmech_list,
+ unsigned int *pmech_list_len) {
+ int x;
+
+ if (!pmech_list_len) {
+ return EINVAL;
+ }
+
+ if (!pmech_list) {
+ *pmech_list_len = sizeof(icaList)/sizeof(libica_func_list_element_int);
+ return 0;
+ }
+ else if (*pmech_list_len <
+ (sizeof(icaList)/sizeof(libica_func_list_element_int)) ) {
+ return EINVAL;
+ }
+
+ for (x=0; x<*pmech_list_len; x++) {
+ pmech_list[x].mech_mode_id = icaList[x].mech_mode_id;
+ pmech_list[x].flags = icaList[x].flags;
+ pmech_list[x].property = icaList[x].property;
+#ifdef ICA_FIPS
+ /* Disable the algorithm in the following cases:
+ * - We are running in FIPS mode and the algorithm is not FIPS
+ * approved.
+ * - We are in an error state. */
+ if (((fips & ICA_FIPS_MODE) && !fips_approved(icaList[x].mech_mode_id))
+ || fips >> 1) {
+ pmech_list[x].flags = 0;
+ pmech_list[x].property = 0;
+ }
+#endif /* ICA_FIPS */
+ }
+
+ return 0;
+}
+
diff --git a/src/s390_drbg.c b/src/s390_drbg.c
new file mode 100644
index 0000000..75f9bc6
--- /dev/null
+++ b/src/s390_drbg.c
@@ -0,0 +1,882 @@
+/*
+ * 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.
+ *
+ * DRBG conforming to NIST SP800-90A
+ *
+ * Author(s): Patrick Steuer <patrick.steuer@de.ibm.com>
+ *
+ * Copyright IBM Corp. 2015
+ */
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <syslog.h>
+
+#include "fips.h"
+#include "s390_crypto.h"
+#include "s390_drbg.h"
+#include "s390_sha.h"
+
+#define MAX_NO_OF_BYTES (255 * DRBG_OUT_LEN) /* limit for hash_df */
+
+/*
+ * Test DRBG mechanisms
+ */
+static ica_drbg_mech_t DRBG_TESTMECH1 = {.error_state = DRBG_HEALTH_TEST_FAIL};
+static ica_drbg_mech_t DRBG_TESTMECH2 = {.error_state = 0};
+
+/*
+ * Auxiliary functions
+ */
+static int test_uninstantiate(ica_drbg_mech_t *mech);
+
+static int test_instantiate_error_handling(ica_drbg_mech_t *mech);
+
+static int test_reseed_error_handling(ica_drbg_mech_t *mech);
+
+static int test_generate_error_handling(ica_drbg_mech_t *mech);
+
+static int set_error_state(ica_drbg_mech_t *mech,
+ int error);
+
+/*
+ * DRBG mechanism list. Add new DRBG mechanism here:
+ */
+ica_drbg_mech_t *const DRBG_MECH_LIST[] = {&DRBG_SHA512,
+ &DRBG_TESTMECH1,
+ &DRBG_TESTMECH2};
+const size_t DRBG_MECH_LIST_LEN = sizeof(DRBG_MECH_LIST)
+ / sizeof(DRBG_MECH_LIST[0]);
+
+/*
+ * DRBG SEI list. The first string (element 0) has the highest priority.
+ */
+const char *const DRBG_SEI_LIST[] = {"/dev/hwrng",
+ "/dev/prandom"};
+const size_t DRBG_SEI_LIST_LEN = sizeof(DRBG_SEI_LIST)
+ / sizeof(DRBG_SEI_LIST[0]);
+
+/*
+ * DRBG mechanism functions
+ */
+int drbg_instantiate(ica_drbg_t **sh,
+ int sec,
+ bool pr,
+ ica_drbg_mech_t *mech,
+ const unsigned char *pers,
+ size_t pers_len,
+ bool test_mode,
+ const unsigned char *test_nonce,
+ size_t test_nonce_len,
+ const unsigned char *test_entropy,
+ size_t test_entropy_len)
+{
+ void *init_ws;
+ int status;
+
+ /* 9.1 Instantiate Process */
+
+ if(!sh || *sh)
+ return DRBG_SH_INV;
+ status = drbg_mech_valid(mech);
+ if(status)
+ return status;
+
+ /* step 1 */
+ if(sec > mech->highest_supp_sec)
+ return DRBG_SEC_NOTSUPP;
+
+ /* step 2: pr is supported. */
+
+ /* step 3 */
+ if(!pers)
+ pers_len = 0;
+ else if(pers_len <= 0)
+ pers = NULL;
+ if(pers_len > mech->max_pers_len)
+ return DRBG_PERS_INV;
+
+ /* step 4 */
+ if(sec <= DRBG_SEC_112)
+ sec = DRBG_SEC_112;
+ else
+ if(sec <= DRBG_SEC_128)
+ sec = DRBG_SEC_128;
+ else
+ if(sec <= DRBG_SEC_192)
+ sec = DRBG_SEC_192;
+ else
+ sec = DRBG_SEC_256;
+
+ /* step 5: Null step. */
+
+ const size_t entropy_len = !test_mode ?
+ (sec + 7) / 8 + DRBG_ADD_ENTROPY_LEN :
+ test_entropy_len;
+ const size_t nonce_len = !test_mode ? DRBG_NONCE_LEN : test_nonce_len;
+ unsigned char entropy[entropy_len];
+ unsigned char nonce[nonce_len];
+
+ /* step 6 */
+ if(!test_mode) /* use entropy from SEI */
+ status = drbg_get_entropy_input(pr, sec, mech->max_len,
+ entropy, entropy_len);
+ else{
+ if(test_entropy){ /* use test entropy */
+ memcpy(entropy, test_entropy, entropy_len);
+ status = 0;
+ }
+ else{ /* test for entropy source failure */
+ status = drbg_get_entropy_input(pr, sec, mech->max_len,
+ entropy, entropy_len);
+ }
+ }
+
+ /* step 7 */
+ if(status){
+ status = DRBG_ENTROPY_SOURCE_FAIL;
+ goto _exit_;
+ }
+
+ /* step 8 */
+ if(!test_mode){ /* use thread id + timestamp + counter */
+ status = drbg_get_nonce(nonce, nonce_len);
+ }
+ else{ /* use test nonce */
+ memcpy(nonce, test_nonce, nonce_len);
+ }
+ if(status){
+ status = DRBG_NONCE_INV;
+ goto _exit_;
+ }
+
+ /* step 9 */
+ status = mech->instantiate(&init_ws, sec, pers, pers_len, entropy,
+ entropy_len, nonce, nonce_len);
+ if(status){
+ if(0 > status)
+ set_error_state(mech, status);
+ goto _exit_;
+ }
+
+ /* step 10 */
+ *sh = malloc(sizeof(ica_drbg_t));
+ if(!*sh){
+ status = DRBG_NOMEM;
+ goto _exit_;
+ }
+
+ /* step 11 */
+ drbg_recursive_mutex_init(&(*sh)->lock);
+ (*sh)->mech = mech;
+ (*sh)->ws = init_ws;
+ (*sh)->sec = sec;
+ (*sh)->pr = pr;
+
+ /* step 12 */
+_exit_:
+ drbg_zmem(entropy, entropy_len);
+ drbg_zmem(nonce, nonce_len);
+ return status;
+}
+
+int drbg_reseed(ica_drbg_t *sh,
+ bool pr,
+ const unsigned char *add,
+ size_t add_len,
+ bool test_mode,
+ const unsigned char *test_entropy,
+ size_t test_entropy_len)
+{
+ int status;
+
+ /* 9.2 Reseed Process */
+
+ /* step 1 */
+ if(!sh || !sh->ws)
+ return DRBG_SH_INV;
+ status = drbg_mech_valid(sh->mech);
+ if(status)
+ return status;
+
+ /* step 2 */
+ if(pr && !sh->pr)
+ return DRBG_PR_NOTSUPP;
+
+ /* step 3 */
+ if(!add)
+ add_len = 0;
+ else if(add_len <= 0)
+ add = NULL;
+ if(add_len > sh->mech->max_add_len)
+ return DRBG_ADD_INV;
+
+ const size_t entropy_len = !test_mode ?
+ (sh->sec + 7) / 8 + DRBG_ADD_ENTROPY_LEN :
+ test_entropy_len;
+ unsigned char entropy[entropy_len];
+
+ /* step 4 */
+ if(!test_mode) /* use entropy from SEI */
+ status = drbg_get_entropy_input(pr, sh->sec, sh->mech->max_len,
+ entropy, entropy_len);
+ else{
+ if(test_entropy){ /* use test entropy */
+ memcpy(entropy, test_entropy, entropy_len);
+ status = 0;
+ }
+ else{ /* test for entropy source failure */
+ status = drbg_get_entropy_input(pr, sh->sec,
+ sh->mech->max_len,
+ entropy, entropy_len);
+ }
+ }
+
+ /* step 5 */
+ if(status){
+ status = DRBG_ENTROPY_SOURCE_FAIL;
+ goto _exit_;
+ }
+
+ /* steps 6 and 7 */
+ pthread_mutex_lock(&sh->lock);
+ status = sh->mech->reseed(sh->ws, add, add_len, entropy, entropy_len);
+ pthread_mutex_unlock(&sh->lock);
+ if(0 > status)
+ set_error_state(sh->mech, status);
+
+ /* step 8 */
+_exit_:
+ drbg_zmem(entropy, entropy_len);
+ return status; /* return reseed status */
+}
+
+int drbg_generate(ica_drbg_t *sh,
+ int sec,
+ bool pr,
+ const unsigned char *add,
+ size_t add_len,
+ bool test_mode,
+ const unsigned char *test_entropy,
+ size_t test_entropy_len,
+ unsigned char *prnd,
+ size_t prnd_len)
+{
+ int status;
+ bool reseed_required;
+
+ /* 9.3 Generate Process */
+
+ /* step 1 */
+ if(!sh || !sh->ws)
+ return DRBG_SH_INV;
+ status = drbg_mech_valid(sh->mech);
+ if(status)
+ return status;
+
+ /* step 2 */
+ if(prnd_len > sh->mech->max_no_of_bytes_per_req)
+ return DRBG_REQUEST_INV;
+
+ /* step 3 */
+ if(sec > sh->sec)
+ return DRBG_SEC_NOTSUPP;
+
+ /* step 4 */
+ if(!add)
+ add_len = 0;
+ else if(add_len <= 0)
+ add = NULL;
+ if(add_len > sh->mech->max_add_len)
+ return DRBG_ADD_INV;
+
+ /* step 5 */
+ if(pr && !sh->pr)
+ return DRBG_PR_NOTSUPP;
+
+ /* step 6 */
+ reseed_required = false;
+
+ /* step 7 */
+_reseed_req_:
+ pthread_mutex_lock(&sh->lock);
+ if(pr || reseed_required){
+ /* steps 7.1 and 7.3 */
+ status = drbg_reseed(sh, pr, add, add_len, test_mode,
+ test_entropy, test_entropy_len);
+ /* step 7.2 */
+ if(status){
+ pthread_mutex_unlock(&sh->lock);
+ return status; /* return reseed status */
+ }
+ /* step 7.4 */
+ add = NULL;
+ add_len = 0;
+ /* step 7.5 */
+ reseed_required = false;
+ }
+
+ /* steps 8 and 10 */
+ status = sh->mech->generate(sh->ws, add, add_len, prnd, prnd_len);
+ pthread_mutex_unlock(&sh->lock);
+
+ /* step 9 */
+ if(DRBG_RESEED_REQUIRED == status){
+ /* step 9.1 */
+ reseed_required = true;
+ /* step 9.2 */
+ if(sh->pr)
+ pr = true;
+ /* step 9.3 */
+ goto _reseed_req_;
+ }
+ else if(0 > status)
+ set_error_state(sh->mech, status);
+
+ /* step 11 */
+ return status;
+}
+
+int drbg_uninstantiate(ica_drbg_t **sh,
+ bool test_mode)
+{
+ int status;
+
+ /* 9.4 Uninstantiate Process */
+
+ /* step 1 */
+ if(!sh || !(*sh) || !(*sh)->ws)
+ return DRBG_SH_INV;
+ status = drbg_mech_valid((*sh)->mech);
+ if(status > 0) /* uninst. is possible in error state (< 0) */
+ return status;
+
+ /* step 2 */
+ pthread_mutex_lock(&(*sh)->lock);
+ status = (*sh)->mech->uninstantiate(&(*sh)->ws, test_mode);
+ if(status){
+ if(0 > status)
+ set_error_state((*sh)->mech, status);
+ return status; /* return uninstantiate status */
+ }
+ pthread_mutex_unlock(&(*sh)->lock);
+ pthread_mutex_destroy(&(*sh)->lock);
+ drbg_zmem(*sh, sizeof(ica_drbg_t));
+ if(test_mode)
+ status = drbg_check_zmem(*sh, sizeof(ica_drbg_t));
+ free(*sh);
+ *sh = NULL;
+
+ /* step 3 */
+ return status;
+}
+
+int drbg_health_test(const void *func,
+ int sec,
+ bool pr,
+ ica_drbg_mech_t *mech)
+{
+ int status, i;
+ const int SEC[] = {DRBG_SEC_112, DRBG_SEC_128, DRBG_SEC_192,
+ DRBG_SEC_256};
+
+ status = drbg_mech_valid(mech);
+ if(status)
+ return status;
+
+ if(drbg_instantiate == func){
+ /* Test vectors. */
+ status = mech->health_test(drbg_instantiate, sec, pr);
+ if(status){
+ if(0 > status)
+ set_error_state(mech, status);
+ return status;
+ }
+
+ /* Error handling test. */
+ status = test_instantiate_error_handling(mech);
+ if(status)
+ return set_error_state(mech, DRBG_HEALTH_TEST_FAIL);
+
+ /* Uninstantiate test. */
+ status = test_uninstantiate(mech);
+ if(status)
+ return set_error_state(mech, DRBG_HEALTH_TEST_FAIL);
+
+ return 0;
+ }
+ else if(drbg_reseed == func){
+ /* Test vectors. */
+ status = mech->health_test(drbg_reseed, sec, pr);
+ if(status){
+ if(0 > status)
+ return set_error_state(mech, status);
+ return status;
+ }
+
+ /* Error handling test. */
+ status = test_reseed_error_handling(mech);
+ if(status)
+ return set_error_state(mech, status);
+
+ /* Uninstantiate test. */
+ status = test_uninstantiate(mech);
+ if(status)
+ return set_error_state(mech, status);
+
+ return 0;
+ }
+ else if(drbg_generate == func){
+ /* Test vectors: test all combinations sec, pr supp, pr req */
+ for(i = 0; i < sizeof(SEC) / sizeof(SEC[0]); i++){
+ if(SEC[i] > mech->highest_supp_sec)
+ break;
+
+ status = mech->health_test(drbg_generate, SEC[i],
+ false);
+ if(status){
+ if(0 > status)
+ set_error_state(mech, status);
+ return status;
+ }
+
+ status = mech->health_test(drbg_generate, SEC[i],
+ true);
+ if(status){
+ if(0 > status)
+ set_error_state(mech, status);
+ return status;
+ }
+ }
+
+ /* Error handling test. */
+ status = test_generate_error_handling(mech);
+ if(status)
+ return set_error_state(mech, status);
+
+ /* Uninstantiate test.*/
+ status = test_uninstantiate(mech);
+ if(status)
+ return set_error_state(mech, status);
+
+ return 0;
+ }
+ else
+ return DRBG_REQUEST_INV;
+}
+
+/*
+ * Auxiliary functions
+ */
+int drbg_get_entropy_input(bool pr,
+ int min_entropy,
+ size_t max_len,
+ unsigned char *entropy,
+ size_t entropy_len)
+{
+ size_t min_len;
+ size_t priority;
+ FILE *fd;
+ int status;
+
+ /* NIST SP800-90C Get_entropy_input */
+
+ if(!entropy)
+ return DRBG_REQUEST_INV;
+ if(0 > min_entropy)
+ min_entropy = 0;
+
+ min_len = ((min_entropy + 7) / 8);
+
+ if(min_len > max_len)
+ return DRBG_REQUEST_INV;
+
+ if(entropy_len < min_len || entropy_len > max_len)
+ return DRBG_REQUEST_INV;
+
+ for(priority = 0; priority < DRBG_SEI_LIST_LEN; priority++){
+ fd = fopen(DRBG_SEI_LIST[priority], "r");
+ if(fd){
+ status = fread(entropy, entropy_len, 1, fd);
+ fclose(fd);
+ if(status == 1)
+ return 0;
+ }
+ }
+
+ return DRBG_ENTROPY_SOURCE_FAIL;
+}
+
+int drbg_get_nonce(unsigned char *nonce,
+ size_t nonce_len)
+{
+ size_t i;
+ static uint16_t ctr;
+
+ /* The buffer for nonce must hold a 16 byte timestamp. */
+ if(DRBG_NONCE_LEN != nonce_len)
+ return DRBG_NONCE_INV;
+
+ /* Get timestamp from TOD clock. */
+ s390_stcke_hw(nonce);
+ /* The value in the bits 72 - 111 is non-zero when the clock is
+ * running. */
+ const unsigned char zero_buff[(111 - 72 + 1) / 8] = {0};
+ int status = !memcmp(nonce + (72 / 8), &zero_buff,
+ (111 - 72 + 1) / 8);
+ if(status)
+ return DRBG_NONCE_INV;
+
+ /* Get thread id. */
+ pthread_t thread_id = pthread_self();
+
+ /* Store bytewise XOR of the thread id in first byte. */
+ for(i = 0; i < sizeof(thread_id); i++)
+ *nonce ^= *((unsigned char *)&thread_id + i);
+
+ /* Store counter in the last two bytes. Since TOD clock is thread-save,
+ * this counter is chosen not to be thread-safe. */
+ *((uint16_t *)(nonce + DRBG_NONCE_LEN - 2)) = ctr;
+ ctr++;
+
+ return 0;
+}
+
+int drbg_hash_df(const unsigned char *input,
+ size_t input_len,
+ unsigned char *req_bytes,
+ size_t req_bytes_len)
+{
+ uint64_t shabuff[2];
+ size_t i;
+ int status;
+ unsigned char counter;
+
+ /* 10.4.1 Hash_df Process */
+
+ if(!req_bytes_len)
+ return 0; /* no bytes requested: do nothing */
+ if(!req_bytes || !input)
+ return DRBG_REQUEST_INV;
+ if (MAX_NO_OF_BYTES < req_bytes_len)
+ return DRBG_REQUEST_INV;
+
+ const uint32_t no_of_bits_to_return = req_bytes_len * 8;
+
+ /* steps 1 and 2 */
+ const size_t len = (req_bytes_len + DRBG_OUT_LEN - 1) / DRBG_OUT_LEN;
+ unsigned char temp[len * DRBG_OUT_LEN];
+
+ /* step 3 */
+ counter = 0x01;
+
+ /* step 4 */
+ const size_t _tmp_len = 1 + sizeof(no_of_bits_to_return) + input_len;
+ unsigned char _tmp[_tmp_len];
+ memcpy(_tmp + 1, &no_of_bits_to_return, sizeof(no_of_bits_to_return));
+ memcpy(_tmp + 1 + sizeof(no_of_bits_to_return), input, input_len);
+ for(i = 1; i <= len; i++){
+ /* step 4.1 */
+ _tmp[0] = counter;
+ status = s390_sha_hw(SHA_512_DEFAULT_IV, _tmp, _tmp_len,
+ temp + (i - 1) * DRBG_OUT_LEN,
+ SHA_MSG_PART_ONLY, &shabuff[0],
+ &shabuff[1], SHA_512);
+ if(status){
+ status = DRBG_HEALTH_TEST_FAIL;
+ goto _exit_;
+ }
+ /* step 4.2 */
+ counter++;
+ }
+
+ /* step 5 */
+ memcpy(req_bytes, temp, req_bytes_len);
+
+ /* step 6 */
+_exit_:
+ drbg_zmem(_tmp, _tmp_len);
+ drbg_zmem(temp, len * DRBG_OUT_LEN);
+ return status;
+}
+
+static int test_uninstantiate(ica_drbg_mech_t *mech)
+{
+ /* Error handling test. */
+ int status;
+
+ status = drbg_uninstantiate(NULL, false);
+ if(DRBG_SH_INV != status)
+ return DRBG_HEALTH_TEST_FAIL;
+
+ /* Test if internal state is zeroised. */
+ ica_drbg_t *sh = NULL;
+ status = drbg_instantiate(&sh, mech->highest_supp_sec, true, mech,
+ NULL, 0, false, NULL, 0, NULL, 0);
+ if(status)
+ return status;
+
+ status = drbg_uninstantiate(&sh, true);
+ if(status)
+ return status;
+
+ return 0;
+}
+
+static int test_instantiate_error_handling(ica_drbg_mech_t *mech)
+{
+ int test_no = 0, status;
+
+ /* Pointer to state handle is NULL. */
+ test_no++;
+ status = drbg_instantiate(NULL, 0, true, mech, NULL, 0, false, NULL,
+ 0, NULL, 0);
+ if(DRBG_SH_INV != status)
+ return test_no;
+
+ /* State handle is already in use. */
+ test_no++;
+ ica_drbg_t *sh = NULL;
+ ica_drbg_t test_sh = {.lock = PTHREAD_MUTEX_INITIALIZER};
+ drbg_recursive_mutex_init(&test_sh.lock);
+ sh = &test_sh;
+ test_sh.mech = mech;
+ test_sh.ws = (void *)"ws";
+ status = drbg_instantiate(&sh, 0, true, mech, NULL, 0, false, NULL, 0,
+ NULL, 0);
+ if(DRBG_SH_INV != status)
+ return test_no;
+ test_sh.mech = NULL;
+ sh = NULL;
+
+ /* Mechanism is not supported. */
+ test_no++;
+ ica_drbg_mech_t test_mech = {.lock = PTHREAD_RWLOCK_INITIALIZER};
+ status = drbg_instantiate(&sh, 0, true, &test_mech, NULL, 0, false,
+ NULL, 0, NULL, 0);
+ if(DRBG_MECH_INV != status)
+ return test_no;
+
+ /* Mechanism in error state. */
+ test_no++;
+ status = drbg_instantiate(&sh, 0, true, &DRBG_TESTMECH1, NULL, 0,
+ false, NULL, 0, NULL, 0);
+ if(0 <= status)
+ return test_no;
+
+ /* Security strength is not supported. */
+ test_no++;
+ status = drbg_instantiate(&sh, mech->highest_supp_sec + 1, true, mech,
+ NULL, 0, true, NULL, 0, NULL, 0);
+ if(DRBG_SEC_NOTSUPP != status)
+ return test_no;
+
+ /* Personalization string is too long. */
+ test_no++;
+ status = drbg_instantiate(&sh, 0, true, mech, (unsigned char *)"pers",
+ mech->max_pers_len + 1, false, NULL, 0, NULL,
+ 0);
+ if(DRBG_PERS_INV != status)
+ return test_no;
+
+ /* Entropy source failed. */
+ test_no++;
+ status = drbg_instantiate(&sh, 0, true, mech, NULL, 0, true, NULL, 0,
+ NULL, 0);
+ if(DRBG_ENTROPY_SOURCE_FAIL != status)
+ return test_no;
+
+ return 0;
+}
+
+static int test_reseed_error_handling(ica_drbg_mech_t *mech)
+{
+ int test_no = 0, status;
+
+ /* Invalid state handle. */
+ status = drbg_reseed(NULL, true, NULL, 0, false, NULL, 0);
+ if(DRBG_SH_INV != status)
+ return test_no;
+
+ /* Mechanism is not supported. */
+ test_no++;
+ ica_drbg_mech_t test_mech = {.lock = PTHREAD_RWLOCK_INITIALIZER};
+ ica_drbg_t test_sh = {.lock = PTHREAD_MUTEX_INITIALIZER};
+ drbg_recursive_mutex_init(&test_sh.lock);
+ test_sh.mech = &test_mech;
+ test_sh.ws = (void *)"ws";
+ status = drbg_reseed(&test_sh, true, NULL, 0, false, NULL, 0);
+ if(DRBG_MECH_INV != status)
+ return test_no;
+ test_sh.mech = NULL;
+
+ /* Mechanism is in error state */
+ test_no++;
+ test_sh.mech = &DRBG_TESTMECH1;
+ status = drbg_reseed(&test_sh, true, NULL, 0, false, NULL, 0);
+ if(0 <= status)
+ return test_no;
+ test_sh.mech = NULL;
+
+ /* Prediction resistance is requested but not supported. */
+ test_no++;
+ test_sh.mech = &DRBG_TESTMECH2;
+ status = drbg_reseed(&test_sh, true, NULL, 0, false, NULL, 0);
+ if(DRBG_PR_NOTSUPP != status)
+ return test_no;
+ test_sh.mech = NULL;
+
+ /* Additional input is too long. */
+ test_no++;
+ test_sh.mech = mech;
+ status = drbg_reseed(&test_sh, false, (unsigned char *)"add",
+ mech->max_add_len + 1, false, NULL, 0);
+ if(DRBG_ADD_INV != status)
+ return test_no;
+ test_sh.mech = NULL;
+
+ /* Entropy source failed. */
+ test_no++;
+ test_sh.mech = mech;
+ status = drbg_reseed(&test_sh, false, NULL, 0, true, NULL, 0);
+ if(DRBG_ENTROPY_SOURCE_FAIL != status)
+ return test_no;
+ test_sh.mech = NULL;
+
+ return 0;
+}
+
+static int test_generate_error_handling(ica_drbg_mech_t *mech)
+{
+ const int SEC[] = {DRBG_SEC_112, DRBG_SEC_128, DRBG_SEC_192,
+ DRBG_SEC_256};
+ int test_no = 0, status, i;
+ unsigned char prnd;
+
+ /* Invalid state handle. */
+ test_no++;
+ status = drbg_generate(NULL, mech->highest_supp_sec, false, NULL, 0,
+ false, NULL, 0, &prnd, sizeof(prnd));
+ if(DRBG_SH_INV != status)
+ return test_no;
+
+ /* Mechanism is not supported. */
+ test_no++;
+ ica_drbg_mech_t test_mech = {.lock = PTHREAD_RWLOCK_INITIALIZER};
+ ica_drbg_t test_sh = {.lock = PTHREAD_MUTEX_INITIALIZER};
+ drbg_recursive_mutex_init(&test_sh.lock);
+ test_sh.mech = &test_mech;
+ test_sh.ws = (void *)"ws";
+ status = drbg_generate(&test_sh, mech->highest_supp_sec, false, NULL, 0,
+ false, NULL, 0, &prnd, sizeof(prnd));
+ if(DRBG_MECH_INV != status)
+ return test_no;
+ test_sh.mech = NULL;
+
+ /* Mechanism is in error state. */
+ test_no++;
+ test_sh.mech = &DRBG_TESTMECH1;
+ status = drbg_generate(&test_sh, mech->highest_supp_sec, false, NULL, 0,
+ false, NULL, 0, &prnd, sizeof(prnd));
+ if(0 <= status)
+ return test_no;
+ test_sh.mech = NULL;
+
+ /* Too many pseudorandom bytes requested. */
+ test_no++;
+ test_sh.mech = mech;
+
+ status = drbg_generate(&test_sh, mech->highest_supp_sec, false, NULL,
+ 0, false, NULL, 0, &prnd,
+ mech->max_no_of_bytes_per_req + 1);
+ if(DRBG_REQUEST_INV != status)
+ return test_no;
+ test_sh.mech = NULL;
+
+ /* Requested security strength is too high. */
+ test_no++;
+ test_sh.mech = mech;
+ test_sh.sec = DRBG_SEC_112;
+
+ status = drbg_generate(&test_sh, DRBG_SEC_112 + 1, false, NULL, 0,
+ true, NULL, 0, &prnd, sizeof(prnd));
+ if(DRBG_SEC_NOTSUPP != status)
+ return test_no;
+ test_sh.mech = NULL;
+ test_sh.sec = 0;
+
+ /* Additional input is too long. */
+ test_no++;
+ test_sh.mech = mech;
+ test_sh.sec = mech->highest_supp_sec;
+
+ status = drbg_generate(&test_sh, mech->highest_supp_sec, false,
+ (unsigned char *)"add", mech->max_add_len + 1,
+ false, NULL, 0, &prnd, sizeof(prnd));
+ if(DRBG_ADD_INV != status)
+ return test_no;
+ test_sh.mech = NULL;
+ test_sh.sec = 0;
+
+ /* Prediction resistance is requested but not supported. */
+ test_no++;
+ test_sh.mech = mech;
+ test_sh.sec = mech->highest_supp_sec;
+ for(i = 0; i < sizeof(SEC); i++){
+ if(SEC[i] > mech->highest_supp_sec)
+ break;
+ status = drbg_generate(&test_sh, SEC[i], true, NULL, 0, true,
+ NULL, 0, &prnd, sizeof(prnd));
+ if(DRBG_PR_NOTSUPP != status)
+ return test_no;
+ }
+ test_sh.mech = NULL;
+ test_sh.sec = 0;
+
+ /* Entropy source failed. */
+ test_no++;
+ test_sh.mech = mech;
+ test_sh.sec = mech->highest_supp_sec;
+ test_sh.pr = true;
+
+ status = drbg_generate(&test_sh, mech->highest_supp_sec, true, NULL, 0,
+ true, NULL, 0, &prnd, sizeof(prnd));
+ if(DRBG_ENTROPY_SOURCE_FAIL != status)
+ return test_no;
+ test_sh.mech = NULL;
+ test_sh.sec = 0;
+ test_sh.pr = false;
+
+ return 0;
+}
+
+static int set_error_state(ica_drbg_mech_t *mech,
+ int error)
+{
+#ifdef ICA_FIPS
+ fips |= ICA_FIPS_RNG;
+
+ /* Write to syslog in FIPS-enabled built. The DRBG failure is critical
+ * here since the old PRNG code is diasbled at compile time. */
+ switch (error) {
+ case DRBG_HEALTH_TEST_FAIL:
+ syslog(LOG_ERR, "Libica DRBG-%s test failed.", mech->id);
+ break;
+ case DRBG_ENTROPY_SOURCE_FAIL:
+ syslog(LOG_ERR, "Libica DRBG-%s entropy source failed.",
+ mech->id);
+ break;
+ default:
+ break; /* unreachable */
+ }
+#endif /* ICA_FIPS */
+
+ return mech->error_state = error;
+}
diff --git a/src/s390_drbg_sha512.c b/src/s390_drbg_sha512.c
new file mode 100644
index 0000000..0eea8a6
--- /dev/null
+++ b/src/s390_drbg_sha512.c
@@ -0,0 +1,666 @@
+/*
+ * 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.
+ *
+ * DRBG conforming to NIST SP800-90A
+ *
+ * Author(s): Patrick Steuer <patrick.steuer@de.ibm.com>
+ *
+ * Copyright IBM Corp. 2015
+ */
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "s390_crypto.h"
+#include "s390_drbg.h"
+#include "s390_drbg_sha512.h"
+#include "icastats.h"
+#include "s390_sha.h"
+#include "test_vec.h"
+
+typedef struct drbg_sha512_ws ws_t; /* typedef for readability only */
+
+/*
+ * Auxiliary functions
+ */
+static int generate_add(ws_t *ws,
+ const unsigned char *add,
+ size_t add_len);
+
+static int hashgen(const unsigned char *v,
+ unsigned char *prnd,
+ size_t prnd_len);
+
+static int test_instantiate(int sec,
+ bool pr);
+
+static int test_reseed(int sec,
+ bool pr);
+
+static int test_generate(int sec,
+ bool pr);
+
+/* Calculate @v = (@v + @s) mod 2 ^ (8 * DRBG_SHA512_SEED_LEN).
+ * Make sure that @s_len <= v_len = DRBG_SHA512_SEED_LEN. */
+static inline void mod_add(unsigned char *v,
+ const unsigned char *s,
+ size_t s_len)
+{
+ int i;
+ uint16_t c = 0;
+
+ v = v + DRBG_SHA512_SEED_LEN - 1;
+ s = s + s_len - 1;
+
+ for(i = 1; i <= s_len; i++, v--, s--)
+ *v = (c = *v + *s + (uint8_t)(c >> 8));
+ for(; i <= DRBG_SHA512_SEED_LEN; i++, v--)
+ *v = (c = *v + (uint8_t)(c >> 8));
+}
+
+/*
+ * SHA-512 DRBG mechanism
+ */
+ica_drbg_mech_t DRBG_SHA512 = {
+ .id = "SHA-512",
+
+ /* 10.1 Mechanisms Based on Hash Functions */
+ .highest_supp_sec = DRBG_SEC_256, /* = 256 bits */
+ .seed_len = DRBG_SHA512_SEED_LEN, /* = 888 bits */
+ .max_pers_len = 256, /* < 2^35 bits */
+ .max_add_len = 256, /* < 2^35 bits */
+ .max_len = 256 - DRBG_NONCE_LEN, /* < 2^35 bits */
+ .max_no_of_bytes_per_req = 524288L / 8, /* < 2^19 bits */
+ .reseed_intervall = UINT32_MAX - 1, /* < 2^48 */
+
+ .instantiate = drbg_sha512_instantiate,
+ .reseed = drbg_sha512_reseed,
+ .generate = drbg_sha512_generate,
+ .uninstantiate = drbg_sha512_uninstantiate,
+ .health_test = drbg_sha512_health_test,
+
+ /* Health test */
+ .lock = PTHREAD_RWLOCK_INITIALIZER,
+ .test_intervall = UINT64_MAX,
+ .test_ctr = 0,
+ .error_state = 0,
+};
+
+/*
+ * SHA-512 DRBG mechanism functions
+ *
+ * No checks for invalid arguments are done here. The corresponding drbg_* -
+ * functions are responsible for this.
+ */
+int drbg_sha512_instantiate_ppno(void **ws,
+ int sec,
+ const unsigned char *pers,
+ size_t pers_len,
+ const unsigned char *entropy,
+ size_t entropy_len,
+ const unsigned char *nonce,
+ size_t nonce_len)
+{
+ int status;
+
+ /* 10.1.1.2 Hash_DRBG Instantiate Process */
+
+ *ws = calloc(1, sizeof(ws_t)); /* buffer must be zero! (see POP) */
+ if(!*ws)
+ return DRBG_NOMEM;
+
+ const size_t seed_material_len = entropy_len + nonce_len + pers_len;
+ unsigned char seed_material[seed_material_len];
+
+ /* step 1 */
+ memcpy(seed_material, entropy, entropy_len);
+ memcpy(seed_material + entropy_len, nonce, nonce_len);
+ memcpy(seed_material + entropy_len + nonce_len, pers, pers_len);
+
+ /* steps 2 - 5 */
+ status = s390_ppno(S390_CRYPTO_SHA512_DRNG_SEED, *ws, NULL, 0,
+ seed_material, seed_material_len);
+ if(status)
+ status = DRBG_HEALTH_TEST_FAIL;
+
+ /* step 6 */
+ drbg_zmem(seed_material, seed_material_len);
+ return status;
+}
+
+int drbg_sha512_instantiate(void **ws,
+ int sec,
+ const unsigned char *pers,
+ size_t pers_len,
+ const unsigned char *entropy,
+ size_t entropy_len,
+ const unsigned char *nonce,
+ size_t nonce_len)
+{
+ const size_t seed_material_len = entropy_len + nonce_len + pers_len;
+ unsigned char seed_material[seed_material_len];
+ int status;
+
+ /* 10.1.1.2 Hash_DRBG Instantiate Process */
+
+ *ws = malloc(sizeof(ws_t));
+ if(!*ws)
+ return DRBG_NOMEM;
+
+ unsigned char _0x00v[1 + sizeof(((ws_t *)*ws)->v)];
+
+ /* step 1 */
+ memcpy(seed_material, entropy, entropy_len);
+ memcpy(seed_material + entropy_len, nonce, nonce_len);
+ memcpy(seed_material + entropy_len + nonce_len, pers, pers_len);
+
+ /* steps 2 and 3 */
+ status = drbg_hash_df(seed_material, seed_material_len,
+ ((ws_t *)*ws)->v, sizeof(((ws_t *)*ws)->v));
+ if(status){
+ drbg_zmem(*ws, sizeof(ws_t));
+ free(*ws);
+ *ws = NULL;
+ goto _exit_;
+ }
+
+ /* step 4 */
+ _0x00v[0] = 0x00;
+ memcpy(_0x00v + 1, ((ws_t *)*ws)->v, sizeof(((ws_t *)*ws)->v));
+
+ status = drbg_hash_df(_0x00v, sizeof(_0x00v), ((ws_t *)*ws)->c,
+ sizeof(((ws_t *)*ws)->c));
+ if(status){
+ drbg_zmem(*ws, sizeof(ws_t));
+ free(*ws);
+ *ws = NULL;
+ goto _exit_;
+ }
+
+ /* step 5 */
+ ((ws_t *)*ws)->reseed_ctr = 1;
+
+ /* step 6 */
+_exit_:
+ drbg_zmem(_0x00v, sizeof(_0x00v));
+ drbg_zmem(seed_material, seed_material_len);
+ return status;
+}
+
+int drbg_sha512_reseed_ppno(void *ws,
+ const unsigned char *add,
+ size_t add_len,
+ const unsigned char *entropy,
+ size_t entropy_len)
+{
+ const size_t seed_material_len = entropy_len + add_len;
+ unsigned char seed_material[seed_material_len];
+ int status;
+
+ /* 10.1.1.3 Hash_DRBG Reseed Process */
+
+ /* step 1 (0x01||V is prepended by ppno, see POP)*/
+ memcpy(seed_material, entropy, entropy_len);
+ memcpy(seed_material + entropy_len, add, add_len);
+
+ /* steps 2 - 5 */
+ status = s390_ppno(S390_CRYPTO_SHA512_DRNG_SEED, ws, NULL, 0,
+ seed_material, seed_material_len);
+ if(status)
+ status = DRBG_HEALTH_TEST_FAIL;
+
+ /* step 6 */
+ drbg_zmem(seed_material, seed_material_len);
+
+ return status;
+}
+
+int drbg_sha512_reseed(void *ws,
+ const unsigned char *add,
+ size_t add_len,
+ const unsigned char *entropy,
+ size_t entropy_len)
+{
+ int status;
+ unsigned char *seed_material;
+ unsigned char _0x00v[1 + sizeof(((ws_t *)ws)->v)];
+ const size_t seed_material_len = 1 + sizeof(((ws_t *)ws)->v)
+ + entropy_len + add_len;
+
+ /* 10.1.1.3 Hash_DRBG Reseed Process */
+ seed_material = malloc(seed_material_len);
+ if(!seed_material)
+ return DRBG_NOMEM;
+
+ /* step 1 */
+ seed_material[0] = 0x01;
+ memcpy(seed_material + 1, ((ws_t *)ws)->v, sizeof(((ws_t *)ws)->v));
+ memcpy(seed_material + 1 + sizeof(((ws_t *)ws)->v), entropy,
+ entropy_len);
+ memcpy(seed_material + 1 + sizeof(((ws_t *)ws)->v) + entropy_len, add,
+ add_len);
+
+ /* steps 2 and 3 */
+ status = drbg_hash_df(seed_material, seed_material_len,
+ ((ws_t *)ws)->v, sizeof(((ws_t *)ws)->v));
+ if(status)
+ goto _exit_;
+
+ /* step 4 */
+ _0x00v[0] = 0x00;
+ memcpy(_0x00v + 1, ((ws_t *)ws)->v, sizeof(((ws_t *)ws)->v));
+ status = drbg_hash_df(_0x00v, sizeof(_0x00v), ((ws_t *)ws)->c,
+ sizeof(((ws_t *)ws)->c));
+ if(status)
+ goto _exit_;
+
+ /* step 5 */
+ ((ws_t *)ws)->reseed_ctr = 1;
+
+ /* step 6 */
+_exit_:
+ drbg_zmem(_0x00v, sizeof(_0x00v));
+ drbg_zmem(seed_material, seed_material_len);
+ free(seed_material);
+
+ return status;
+}
+
+int drbg_sha512_generate_ppno(void *ws,
+ const unsigned char *add,
+ size_t add_len,
+ unsigned char *prnd,
+ size_t prnd_len)
+{
+ int status;
+
+ /* increase corresponding icastats counter */
+ stats_increment(ICA_STATS_DRBGSHA512, ALGO_HW, ENCRYPT);
+
+ /* 10.1.1.4 Hash_DRBG Generate Process */
+
+ /* step 1 */
+ if(DRBG_SHA512.reseed_intervall < ((ws_t *)ws)->reseed_ctr)
+ return DRBG_RESEED_REQUIRED;
+
+ /* step 2 */
+ if(add){
+ status = generate_add(ws, add, add_len);
+ if(status)
+ return status;
+ }
+
+ /* steps 3 - 6 */
+ status = s390_ppno(S390_CRYPTO_SHA512_DRNG_GEN, ws, prnd, prnd_len,
+ NULL, 0);
+ if(status != prnd_len)
+ return DRBG_HEALTH_TEST_FAIL;
+
+ /* step 7 */
+ return 0;
+}
+
+int drbg_sha512_generate(void *ws,
+ const unsigned char *add,
+ size_t add_len,
+ unsigned char *prnd,
+ size_t prnd_len)
+{
+ unsigned char _0x03v[1 + sizeof(((ws_t *)ws)->v)] = {0};
+ unsigned char h[DRBG_OUT_LEN];
+ uint64_t shabuff[2];
+ int status;
+
+ /* increase corresponding icastats counter */
+ stats_increment(ICA_STATS_DRBGSHA512, ALGO_SW, ENCRYPT);
+
+ /* 10.1.1.4 Hash_DRBG Generate Process */
+
+ /* step 1 */
+ if(DRBG_SHA512.reseed_intervall < ((ws_t *)ws)->reseed_ctr)
+ return DRBG_RESEED_REQUIRED;
+
+ /* step 2 */
+ if(add){
+ status = generate_add(ws, add, add_len);
+ if(status)
+ return status;
+ }
+
+ /* step 3 */
+ status = hashgen(((ws_t *)ws)->v, prnd, prnd_len);
+ if(status)
+ return status;
+
+ /* step 4 */
+ _0x03v[0] = 0x03;
+ memcpy(_0x03v + 1, ((ws_t *)ws)->v, sizeof(((ws_t *)ws)->v));
+ status = s390_sha_hw(SHA_512_DEFAULT_IV, _0x03v, sizeof(_0x03v), h,
+ SHA_MSG_PART_ONLY, &shabuff[0], &shabuff[1],
+ SHA_512);
+ if(status){
+ status = DRBG_HEALTH_TEST_FAIL;
+ goto _exit_;
+ }
+
+ /* step 5 */
+ mod_add(((ws_t *)ws)->v, h, sizeof(h));
+ mod_add(((ws_t *)ws)->v, ((ws_t *)ws)->c, sizeof(((ws_t *)ws)->c));
+ mod_add(((ws_t *)ws)->v, (unsigned char *)&((ws_t *)ws)->reseed_ctr,
+ sizeof(((ws_t *)ws)->reseed_ctr));
+
+ /* step 6 */
+ ((ws_t *)ws)->reseed_ctr++;
+
+ ((ws_t *)ws)->stream_bytes += prnd_len; /* stay analogous to ppno */
+
+ /* step 7 */
+_exit_:
+ drbg_zmem(_0x03v, sizeof(_0x03v));
+ drbg_zmem(h, sizeof(h));
+ return status;
+}
+
+int drbg_sha512_uninstantiate(void **ws,
+ bool test_mode)
+{
+ drbg_zmem((*ws), sizeof(ws_t));
+
+ if(test_mode){
+ int status = drbg_check_zmem(*ws, sizeof(ws_t));
+ if(status)
+ return status;
+ }
+
+ free(*ws);
+ *ws = NULL;
+ return 0;
+}
+
+int drbg_sha512_health_test(void *func,
+ int sec,
+ bool pr)
+{
+ static bool hw_check;
+
+ /* Use ppno if available. */
+ if(!hw_check){
+ if(sha512_drng_switch){
+ DRBG_SHA512.instantiate = drbg_sha512_instantiate_ppno;
+ DRBG_SHA512.reseed = drbg_sha512_reseed_ppno;
+ DRBG_SHA512.generate = drbg_sha512_generate_ppno;
+ }
+ else if(sha512_switch){
+ DRBG_SHA512.instantiate = drbg_sha512_instantiate;
+ DRBG_SHA512.reseed = drbg_sha512_reseed;
+ DRBG_SHA512.generate = drbg_sha512_generate;
+ }
+ else
+ return DRBG_HEALTH_TEST_FAIL;
+ hw_check = true;
+ }
+
+ /* Health test. */
+ if(drbg_instantiate == func)
+ return test_instantiate(sec, pr);
+ else if(drbg_reseed == func)
+ return test_reseed(sec, pr);
+ else if(drbg_generate == func)
+ return test_generate(sec, pr);
+ else
+ return DRBG_REQUEST_INV;
+}
+
+/*
+ * Auxiliary functions
+ */
+static int test_instantiate(int sec,
+ bool pr)
+{
+ ica_drbg_t *sh = NULL;
+ const struct drbg_sha512_tv *tv;
+ int status, i;
+
+ for(i = 0; i < DRBG_SHA512_TV_LEN; i++){
+ tv = &DRBG_SHA512_TV[i];
+ if(tv->pr != pr)
+ continue;
+
+ status = drbg_instantiate(&sh, sec, pr, &DRBG_SHA512,
+ tv->inst.pers, tv->pers_len, true,
+ tv->inst.nonce, tv->nonce_len,
+ tv->inst.entropy, tv->entropy_len);
+ if(status)
+ return status;
+
+ if(memcmp(tv->inst.v, ((ws_t *)(sh->ws))->v,
+ DRBG_SHA512.seed_len) ||
+ memcmp(tv->inst.c, ((ws_t *)(sh->ws))->c,
+ DRBG_SHA512.seed_len) ||
+ tv->inst.reseed_ctr != ((ws_t *)(sh->ws))->reseed_ctr){
+ drbg_uninstantiate(&sh, false);
+ return DRBG_HEALTH_TEST_FAIL;
+ }
+
+ status = drbg_uninstantiate(&sh, false);
+ if(status)
+ return DRBG_HEALTH_TEST_FAIL;
+ }
+
+ return 0;
+}
+
+static int test_reseed(int sec,
+ bool pr)
+{
+ ws_t ws;
+ ica_drbg_t sh = {.mech = &DRBG_SHA512, .ws = &ws, .sec = sec,
+ .pr = pr};
+ const struct drbg_sha512_tv *tv;
+ int status, i;
+
+ drbg_recursive_mutex_init(&sh.lock);
+
+ for(i = 0; i < DRBG_SHA512_TV_LEN; i++){
+ tv = &DRBG_SHA512_TV[i];
+ if(tv->pr || tv->no_reseed)
+ continue;
+
+ memcpy(ws.v, tv->inst.v, DRBG_SHA512.seed_len);
+ memcpy(ws.c, tv->inst.c, DRBG_SHA512.seed_len);
+ ws.reseed_ctr = tv->inst.reseed_ctr;
+
+ status = drbg_reseed(&sh, pr, tv->res.add, tv->add_len, true,
+ tv->res.entropy, tv->entropy_len);
+ if(status)
+ return status;
+
+ if(memcmp(tv->res.v, ((ws_t *)sh.ws)->v,
+ DRBG_SHA512.seed_len) ||
+ memcmp(tv->res.c, ((ws_t *)sh.ws)->c,
+ DRBG_SHA512.seed_len) ||
+ tv->res.reseed_ctr != ((ws_t *)sh.ws)->reseed_ctr)
+ return DRBG_HEALTH_TEST_FAIL;
+ }
+
+ return 0;
+}
+
+static int test_generate(int sec,
+ bool pr)
+{
+ ws_t ws;
+ ica_drbg_t sh = {.mech = &DRBG_SHA512, .ws = &ws, .sec = sec,
+ .pr = true};
+ int status, i;
+ const struct drbg_sha512_tv *tv;
+ unsigned char prnd;
+
+ drbg_recursive_mutex_init(&sh.lock);
+
+ /* Use appropriate test vectors for self-test */
+ do{
+ for(i = 0; i < DRBG_SHA512_TV_LEN; i++){
+ tv = &DRBG_SHA512_TV[i];
+ if(tv->pr != pr)
+ continue;
+
+ if(!tv->no_reseed && !tv->pr){
+ memcpy(ws.v, tv->res.v, DRBG_SHA512.seed_len);
+ memcpy(ws.c, tv->res.c, DRBG_SHA512.seed_len);
+ ws.reseed_ctr = tv->res.reseed_ctr;
+ }
+ else{
+ memcpy(ws.v, tv->inst.v, DRBG_SHA512.seed_len);
+ memcpy(ws.c, tv->inst.c, DRBG_SHA512.seed_len);
+ ws.reseed_ctr = tv->inst.reseed_ctr;
+ }
+
+ unsigned char prnd[tv->prnd_len];
+ status = drbg_generate(&sh, sec, pr, tv->gen1.add,
+ tv->add_len, true,
+ tv->gen1.entropy,
+ tv->entropy_len, prnd,
+ tv->prnd_len);
+ if(status)
+ return status;
+
+ if(memcmp(tv->gen1.v, ((ws_t *)sh.ws)->v,
+ DRBG_SHA512.seed_len) ||
+ memcmp(tv->gen1.c, ((ws_t *)sh.ws)->c,
+ DRBG_SHA512.seed_len) ||
+ tv->gen1.reseed_ctr != ((ws_t *)sh.ws)->reseed_ctr)
+ return DRBG_HEALTH_TEST_FAIL;
+
+ status = drbg_generate(&sh, sec, pr, tv->gen2.add,
+ tv->add_len, true,
+ tv->gen2.entropy,
+ tv->entropy_len, prnd,
+ tv->prnd_len);
+ if(status)
+ return status;
+
+ if(memcmp(tv->gen2.v, ((ws_t *)sh.ws)->v,
+ DRBG_SHA512.seed_len) ||
+ memcmp(tv->gen2.c, ((ws_t *)sh.ws)->c,
+ DRBG_SHA512.seed_len) ||
+ tv->gen2.reseed_ctr != ((ws_t *)sh.ws)->reseed_ctr)
+ return DRBG_HEALTH_TEST_FAIL;
+
+ if(memcmp(tv->prnd, prnd, tv->prnd_len))
+ return DRBG_HEALTH_TEST_FAIL;
+ }
+
+ /* If pr = false, also run self-test with sh.pr = false. */
+ if(pr || !sh.pr)
+ break;
+ else
+ sh.pr = false;
+ }while(true);
+
+ /* Set reseed counter to meet the reseed intervall. */
+ if(!pr){
+ ws.reseed_ctr = DRBG_SHA512.reseed_intervall + 1;
+ status = drbg_generate(&sh, sec, pr, NULL, 0, false, NULL, 0,
+ &prnd, sizeof(prnd));
+ if(2 != ws.reseed_ctr)
+ return DRBG_HEALTH_TEST_FAIL;
+ }
+
+ return 0;
+}
+
+static int generate_add(ws_t *ws,
+ const unsigned char *add,
+ size_t add_len)
+{
+ unsigned char *_0x02v;
+ const size_t _0x02v_len = 1 + sizeof(ws->v) + add_len;
+ unsigned char w[DRBG_OUT_LEN];
+ uint64_t shabuff[2];
+ int status;
+
+ /* 10.1.1.4 Hash_DRBG Generate Process, step 2.x */
+
+ /* step 2.1 */
+ _0x02v = malloc(_0x02v_len);
+ if(!_0x02v)
+ return DRBG_NOMEM;
+ _0x02v[0] = 0x02;
+ memcpy(_0x02v + 1, ws->v, sizeof(ws->v));
+ memcpy(_0x02v + 1 + sizeof(ws->v), add, add_len);
+ status = s390_sha_hw(SHA_512_DEFAULT_IV, _0x02v, _0x02v_len, w,
+ SHA_MSG_PART_ONLY, &shabuff[0], &shabuff[1],
+ SHA_512);
+ if(status){
+ status = DRBG_HEALTH_TEST_FAIL;
+ goto _exit_;
+ }
+
+ /* step 2.2 */
+ mod_add(ws->v, w, sizeof(w));
+
+_exit_:
+ drbg_zmem(w, DRBG_OUT_LEN);
+ drbg_zmem(_0x02v, _0x02v_len);
+ free(_0x02v);
+ return status;
+}
+
+static int hashgen(const unsigned char *v,
+ unsigned char *prnd,
+ size_t prnd_len)
+{
+ unsigned char data[DRBG_SHA512_SEED_LEN];
+ unsigned char w_i[DRBG_OUT_LEN];
+ unsigned char *w;
+ size_t m, i;
+ uint64_t shabuff[2];
+ int status;
+ const unsigned char _0x01 = 0x01;
+
+ /* 10.1.1.4 Hashgen Process */
+
+ if(0 >= prnd_len)
+ return 0; /* no pseudorandom bytes requested */
+
+ /* step 1 */
+ m = (prnd_len + DRBG_OUT_LEN - 1) / DRBG_OUT_LEN;
+
+ /* step 2 */
+ memcpy(data, v, sizeof(data));
+
+ /* step 3 */
+ w = malloc(m * DRBG_OUT_LEN);
+ if(!w)
+ return DRBG_NOMEM;
+
+ /* step 4 */
+ for(i = 1; i <= m; i++){
+ status = s390_sha_hw(SHA_512_DEFAULT_IV, data, sizeof(data),
+ w_i, SHA_MSG_PART_ONLY, &shabuff[0],
+ &shabuff[1], SHA_512);
+ if(status){
+ status = DRBG_HEALTH_TEST_FAIL;
+ goto _exit_;
+ }
+ memcpy(w + (i - 1) * DRBG_OUT_LEN, w_i, DRBG_OUT_LEN);
+ mod_add(data, &_0x01, sizeof(_0x01));
+ }
+
+ /* step 5 */
+ memcpy(prnd, w, prnd_len);
+
+ /* step 6 */
+_exit_:
+ drbg_zmem(data, sizeof(data));
+ drbg_zmem(w_i, DRBG_OUT_LEN);
+ drbg_zmem(w, m * DRBG_OUT_LEN);
+ free(w);
+ return status;
+}
diff --git a/src/s390_prng.c b/src/s390_prng.c
new file mode 100644
index 0000000..895c0ec
--- /dev/null
+++ b/src/s390_prng.c
@@ -0,0 +1,329 @@
+/* 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.
+ */
+
+/**
+ * Some parts of this file have been moved from former icalinux.c to this file.
+ *
+ * Authors: Felix Beck <felix.beck@de.ibm.com>
+ * Christian Maaser <cmaaser@de.ibm.com>
+ *
+ * Copyright IBM Corp. 2009, 2011
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <semaphore.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "ica_api.h"
+#include "init.h"
+#include "s390_prng.h"
+#include "s390_crypto.h"
+#include "icastats.h"
+#include "s390_drbg.h"
+
+/*
+ * On 31 bit systems we have to use the instruction STCKE while on 64 bit
+ * systems we can use STCKF. STCKE uses a 16 byte buffer while STCKF uses
+ * an 8 byte buffer.
+ */
+#ifdef _LINUX_S390X_
+#define STCK_BUFFER 8
+#else
+#define STCK_BUFFER 16
+#endif
+
+/*
+ * State handle for the global ica_drbg instantiation.
+ */
+ica_drbg_t *ica_drbg_global = ICA_DRBG_NEW_STATE_HANDLE;
+
+sem_t semaphore;
+
+union zprng_pb_t {
+ unsigned char ch[32];
+ uint64_t uint;
+};
+
+/*
+ * Parameter block for the KMC(PRNG) instruction.
+ */
+union zprng_pb_t zPRNG_PB = {{0x0F, 0x2B, 0x8E, 0x63, 0x8C, 0x8E, 0xD2, 0x52,
+ 0x64, 0xB7, 0xA0, 0x7B, 0x75, 0x28, 0xB8, 0xF4,
+ 0x75, 0x5F, 0xD2, 0xA6, 0x8D, 0x97, 0x11, 0xFF,
+ 0x49, 0xD8, 0x23, 0xF3, 0x7E, 0x21, 0xEC, 0xA0}};
+
+unsigned int s390_prng_limit = 4096;
+unsigned long s390_byte_count;
+
+#ifndef ICA_FIPS
+static const char *const PRNG_SEI_LIST[] = {"/dev/hwrng", "/dev/prandom",
+ "/dev/urandom", NULL /* last list element */};
+
+/* Static functions */
+static int s390_add_entropy(void);
+static int s390_prng_sw(unsigned char *output_data,
+ unsigned int output_length);
+static int s390_prng_hw(unsigned char *random_bytes, unsigned int num_bytes);
+static int s390_prng_seed(void *srv, unsigned int count);
+#endif /* ICA_FIPS */
+
+/* Constant */
+#define PRNG_BLK_SZ 8
+
+int s390_prng_init(void)
+{
+ int rc = -1;
+#ifndef ICA_FIPS
+ FILE *handle;
+ int i;
+ unsigned char seed[16];
+#endif /* ICA_FIPS */
+
+ /*
+ * Create a global ica_drbg instance if sha512 or sha512 drng is
+ * available. However, the old prng is still initialized but
+ * only used as a fallback.
+ */
+ if (sha512_switch || sha512_drng_switch) {
+ rc = ica_drbg_instantiate(&ica_drbg_global, 256, true,
+ ICA_DRBG_SHA512, (unsigned char *)"GLOBAL INSTANCE", 15);
+ }
+
+#ifndef ICA_FIPS /* Old prng code disabled with FIPS built. */
+ sem_init(&semaphore, 0, 1);
+
+ rc = ENODEV;
+ for(i = 0; PRNG_SEI_LIST[i] != NULL; i++){
+ handle = fopen(PRNG_SEI_LIST[i], "r");
+ if(handle){
+ rc = fread(seed, sizeof(seed), 1, handle);
+ fclose(handle);
+ if(rc == 1) {
+ rc = s390_prng_seed(seed, sizeof(seed) /
+ sizeof(long long));
+ break;
+ } else {
+ rc = EIO;
+ }
+ }
+ }
+
+ /*
+ * If the original seeding failed, we should try to stir in some
+ * entropy anyway (since we already put out a message).
+ */
+ s390_byte_count = 0;
+#endif /* ICA_FIPS */
+
+ return rc;
+}
+
+#ifndef ICA_FIPS
+/*
+ * Adds some entropy to the system.
+ *
+ * This is called at the first request for random and again if more than ten
+ * seconds have passed since the last request for random bytes.
+ */
+static int s390_add_entropy(void)
+{
+ FILE *handle;
+ unsigned char entropy[4 * STCK_BUFFER];
+ unsigned int K;
+ unsigned char seed[32];
+ int rc;
+
+ if (!prng_switch)
+ return ENOTSUP;
+
+ for (K = 0; K < 16; K++) {
+ s390_stck(entropy + 0 * STCK_BUFFER);
+ s390_stck(entropy + 1 * STCK_BUFFER);
+ s390_stck(entropy + 2 * STCK_BUFFER);
+ s390_stck(entropy + 3 * STCK_BUFFER);
+ if(s390_kmc(0x43, zPRNG_PB.ch, entropy, entropy,
+ sizeof(entropy)) < 0) {
+ return EIO;
+ }
+ memcpy(zPRNG_PB.ch, entropy, sizeof(zPRNG_PB.ch));
+ }
+ /* Add some additional entropy. */
+ rc = ENODEV;
+ for(K = 0; PRNG_SEI_LIST[K] != NULL; K++){
+ handle = fopen(PRNG_SEI_LIST[K], "r");
+ if(handle){
+ rc = fread(seed, sizeof(seed), 1, handle);
+ fclose(handle);
+ if(rc == 1) {
+ rc = s390_kmc(0x43, zPRNG_PB.ch, seed, seed,
+ sizeof(seed));
+ if (rc >= 0) {
+ memcpy(zPRNG_PB.ch, seed, sizeof(seed));
+ rc = 0;
+ } else {
+ rc = EIO;
+ }
+ break;
+ } else {
+ rc = EIO;
+ }
+ }
+ }
+
+ return rc;
+}
+#endif /* ICA_FIPS */
+
+
+/*
+ * This is the function that does the heavy lifting.
+ *
+ * It is here that the PRNG is actually done.
+ */
+int s390_prng(unsigned char *output_data, unsigned int output_length)
+{
+ size_t i;
+ int rc = -1;
+ unsigned char *ptr = output_data;
+
+ const size_t q = output_length
+ / ICA_DRBG_SHA512->max_no_of_bytes_per_req;
+ const size_t r = output_length
+ % ICA_DRBG_SHA512->max_no_of_bytes_per_req;
+
+ /*
+ * Try to use the global ica_drbg instantiation. If it does not exist
+ * or it does not work, the old prng code is used.
+ */
+ if (ica_drbg_global) {
+ for (i = 0; i < q; i++) {
+ rc = ica_drbg_generate(ica_drbg_global, 256, false,
+ NULL, 0, ptr,
+ ICA_DRBG_SHA512->max_no_of_bytes_per_req);
+ if (rc)
+ break;
+
+ ptr += ICA_DRBG_SHA512->max_no_of_bytes_per_req;
+ }
+ if (r > 0) {
+ rc = ica_drbg_generate(ica_drbg_global, 256, false,
+ NULL, 0, ptr, r);
+ }
+ if (rc == 0)
+ return 0;
+ }
+
+#ifndef ICA_FIPS /* Old prng code disabled with FIPS built. */
+ if (prng_switch)
+ rc = s390_prng_hw(output_data, output_length);
+ if (rc == 0)
+ stats_increment(ICA_STATS_PRNG, ALGO_HW, ENCRYPT);
+ else {
+ rc = s390_prng_sw(output_data, output_length);
+ stats_increment(ICA_STATS_PRNG, ALGO_SW, ENCRYPT);
+ }
+#endif /* ICA_FIPS */
+
+ return rc;
+}
+
+#ifndef ICA_FIPS
+static int s390_prng_sw(unsigned char *output_data, unsigned int output_length)
+{
+ FILE *handle = fopen("/dev/urandom", "r");
+ if (!handle)
+ return ENODEV;
+ if (1 != fread(output_data, output_length, 1, handle)) {
+ fclose(handle);
+ return EIO;
+ }
+
+ fclose(handle);
+ return 0;
+}
+
+static int s390_prng_hw(unsigned char *random_bytes, unsigned int num_bytes)
+{
+ unsigned int i, remainder;
+ unsigned char last_dw[STCK_BUFFER];
+ int rc = -1;
+
+ rc = 0;
+
+ sem_wait(&semaphore);
+
+ /* Add some additional entropy when the byte count is reached.*/
+ if (s390_byte_count > s390_prng_limit)
+ rc = s390_add_entropy();
+
+ if (!rc) {
+ /* The kmc(PRNG) instruction requires a multiple of PRNG_BLK_SZ, so we
+ * will save the remainder and then do a final chunk if we have
+ * non-zero remainder.
+ */
+ remainder = num_bytes % PRNG_BLK_SZ;
+ num_bytes -= remainder;
+
+ for (i = 0; i < (num_bytes / STCK_BUFFER); i++)
+ s390_stck(random_bytes + i * STCK_BUFFER);
+
+ rc = s390_kmc(S390_CRYPTO_PRNG, zPRNG_PB.ch, random_bytes,
+ random_bytes, num_bytes);
+ if (rc > 0) {
+ s390_byte_count += rc;
+ rc = 0;
+ }
+
+ // If there was a remainder, we'll use an internal buffer to handle it.
+ if (!rc && remainder) {
+ s390_stck(last_dw);
+ rc = s390_kmc(S390_CRYPTO_PRNG, zPRNG_PB.ch, last_dw,
+ last_dw, STCK_BUFFER);
+ if (rc > 0) {
+ s390_byte_count += rc;
+ rc = 0;
+ }
+ memcpy(random_bytes + num_bytes, last_dw, remainder);
+ }
+ if (rc < 0)
+ return EIO;
+ else
+ rc = 0;
+
+ }
+ sem_post(&semaphore);
+
+ return rc;
+}
+
+/*
+ * This is the function that seeds the random number generator.
+ * SRV is the source randomization value.
+ * count is the number of doublewords (8 bytes) in the SRV..
+ */
+static int s390_prng_seed(void *srv, unsigned int count)
+{
+ int rc = -1;
+ unsigned int i;
+
+ if (!prng_switch)
+ return ENOTSUP;
+
+ // Add entropy using the source randomization value.
+ for (i = 0; i < count; i++) {
+ zPRNG_PB.uint ^= *((uint64_t *) srv + i * 8);
+ if ((rc = s390_add_entropy()))
+ break;
+ }
+ // Stir one last time.
+ rc = s390_add_entropy();
+ return rc;
+}
+#endif /* ICA_FIPS */
diff --git a/src/s390_rsa.c b/src/s390_rsa.c
new file mode 100644
index 0000000..811d935
--- /dev/null
+++ b/src/s390_rsa.c
@@ -0,0 +1,1037 @@
+/* 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.
+ */
+
+/**
+ * Authors: Felix Beck <felix.beck@de.ibm.com>
+ * Christian Maaser <cmaaser@de.ibm.com>
+ *
+ * Some parts of the content of this file have been moved from former
+ * icalinux.c to this file.
+ *
+ * Copyright IBM Corp. 2009, 2011
+ */
+
+#include <string.h>
+#include <errno.h>
+#include <stdint.h>
+#include <openssl/crypto.h>
+#include <openssl/rsa.h>
+#include <openssl/crypto.h>
+#include <pthread.h>
+#include <semaphore.h>
+
+#include <openssl/opensslconf.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif /* OPENSSL_FIPS */
+
+#include "fips.h"
+#include "s390_rsa.h"
+#include "s390_prng.h"
+
+static unsigned int mod_expo_sw(int arg_length, char *arg, int exp_length,
+ char *exp, int mod_length, char *mod,
+ int *res_length, char *res, BN_CTX *ctx);
+static unsigned int mod_mul_sw(int fc_1_length, char *fc1, int fc_2_length,
+ char *fc2, int mod_length, char *mod,
+ int *res_length, char *res, BN_CTX *ctx);
+static unsigned int mod_sw(int arg_length, char *arg, int mod_length,
+ char *mod, int *res_length, char *res, BN_CTX *ctx);
+static unsigned int add_sw(int aug_length, char *aug, int add_length,
+ char *add, int *res_length, char *res, BN_CTX *ctx);
+static unsigned int mod_sub_sw(int min_length, char *minu, int sub_length,
+ char *sub, int mod_length, char *mod,
+ int *res_length, char *res, BN_CTX * ctx);
+static unsigned int mul_sw(int fc_1_length, char *fc1, int fc_2_length,
+ char *fc2, int *res_length, char *res, BN_CTX *ctx);
+static unsigned int mod_expo_sw(int arg_length, char *arg, int exp_length,
+ char *exp, int mod_length, char *mod,
+ int *res_length, char *res, BN_CTX *ctx);
+
+struct thread_data
+{
+ unsigned int mod_bit_length;
+ unsigned long *pub_exp;
+ RSA *rsa;
+};
+
+static void *__rsa_key_generate(void *ptr)
+{
+ struct thread_data *pth_data;
+ unsigned int modulus_bit_length;
+ unsigned long *public_exponent;
+
+ pth_data = (struct thread_data*)ptr;
+ modulus_bit_length = pth_data->mod_bit_length;
+ public_exponent = pth_data->pub_exp;
+
+#ifdef ICA_FIPS
+ if ((fips & ICA_FIPS_MODE) && (!FIPS_mode()))
+ return NULL;
+#endif /* ICA_FIPS */
+
+ if (*public_exponent == 0)
+ {
+ do {
+ if (s390_prng((unsigned char*)public_exponent,
+ sizeof(unsigned long)) != 0)
+ return NULL;
+ } while (*public_exponent <= 2 || !(*public_exponent % 2));
+ }
+
+ RSA *rsa = RSA_new();
+ BIGNUM *exp = BN_new();
+ if (!exp || !rsa) {
+ RSA_free(rsa);
+ BN_free(exp);
+ return NULL;
+ }
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ BN_GENCB *cb = BN_GENCB_new();
+ if(!cb) {
+ RSA_free(rsa);
+ BN_free(exp);
+ return NULL;
+ }
+#else
+ BN_GENCB dummy;
+ BN_GENCB *cb = &dummy;
+#endif /* OPENSSL_VERSION_NUMBER */
+
+ BN_set_word(exp, *public_exponent);
+ BN_GENCB_set_old(cb, NULL, NULL);
+
+ if (RSA_generate_key_ex(rsa, modulus_bit_length, exp, cb) == 0) {
+ RSA_free(rsa);
+ rsa = NULL;
+ pth_data->rsa = NULL;
+ }
+
+ BN_free(exp);
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ BN_GENCB_free(cb);
+#endif /* OPENSSL_VERSION_NUMBER */
+ pth_data->rsa = rsa;
+ return 0;
+}
+
+
+RSA* rsa_key_generate(unsigned int modulus_bit_length,
+ unsigned long *public_exponent)
+{
+ pthread_t tid;
+ struct thread_data th_data;
+ int rc;
+
+ sem_wait(&openssl_crypto_lock_mtx);
+
+ th_data.mod_bit_length = modulus_bit_length;
+ th_data.pub_exp = public_exponent;
+ rc = pthread_create(&(tid), NULL, (void *)&__rsa_key_generate,
+ (void *)(&th_data));
+ if (rc)
+ return 0;
+ rc = pthread_join(tid, NULL);
+
+ if (!rc && th_data.rsa) {
+ sem_post(&openssl_crypto_lock_mtx);
+ return th_data.rsa;
+ }
+ sem_post(&openssl_crypto_lock_mtx);
+ return NULL;
+}
+
+/**
+ * @brief Create a RSA modulus/expo key pair
+ *
+ * This function generates and returns a public/private key pair in
+ * modulus/exponent format. A completion code is returned to indicate
+ * success/failure.
+ * @param device_handle
+ * Previously opened device handle.
+ * @param modulus_bit_length
+ * Bit length of modulus to be generated.
+ * @param public_key
+ * Buffer for the public key. On output contains the public key.
+ * @param private_key
+ * Buffer of the private key. On output contains the private key.
+ *
+ * Returns 0 if successful.
+ */
+unsigned int rsa_key_generate_mod_expo(ica_adapter_handle_t deviceHandle,
+ unsigned int modulus_bit_length,
+ ica_rsa_key_mod_expo_t *public_key,
+ ica_rsa_key_mod_expo_t *private_key)
+{
+#ifdef ICA_FIPS
+ if ((fips & ICA_FIPS_MODE) && (!FIPS_mode()))
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ RSA *rsa = rsa_key_generate(modulus_bit_length,
+ (unsigned long*)(public_key->exponent +
+ public_key->key_length -
+ sizeof(unsigned long)));
+ if (!rsa)
+ return errno;
+
+ const BIGNUM *n, *d;
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ RSA_get0_key(rsa, &n, NULL, &d);
+#else
+ n = rsa->n;
+ d = rsa->d;
+#endif /* OPENSSL_VERSION_NUMBER */
+
+ /* Set key buffers zero to make sure there is no
+ * unneeded junk in between.
+ */
+ memset(public_key->modulus, 0, public_key->key_length);
+ memset(private_key->modulus, 0, private_key->key_length);
+ memset(private_key->exponent, 0, private_key->key_length);
+
+ unsigned int bn_length = BN_num_bytes(n);
+ unsigned int offset = 0;
+
+ if (bn_length < public_key->key_length)
+ offset = public_key->key_length - bn_length;
+ else
+ offset = 0;
+ BN_bn2bin(n, public_key->modulus + offset);
+
+ memcpy(private_key->modulus, public_key->modulus,
+ public_key->key_length);
+
+ bn_length = BN_num_bytes(d);
+ if (bn_length < private_key->key_length)
+ offset = private_key->key_length - bn_length;
+ else
+ offset = 0;
+ BN_bn2bin(d, private_key->exponent + offset);
+
+ RSA_free(rsa);
+
+ return 0;
+}
+
+/**
+ * This function generates and returns a public/private key pair in CRT format.
+ *
+ * @param device_handle
+ * Previously opened device handle.
+ * @param modulus_bit_length
+ * Bit length of modulus to be generated.
+ * @param public_key
+ * Buffer for the public key. On output contains the public key.
+ * @param private_key
+ * Buffer of the private key. On output contains the private key.
+ *
+ * Returns 0 if successful.
+ */
+unsigned int rsa_key_generate_crt(ica_adapter_handle_t deviceHandle,
+ unsigned int modulus_bit_length,
+ ica_rsa_key_mod_expo_t *public_key,
+ ica_rsa_key_crt_t *private_key)
+{
+#ifdef ICA_FIPS
+ if ((fips & ICA_FIPS_MODE) && (!FIPS_mode()))
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ RSA *rsa = rsa_key_generate(modulus_bit_length,
+ (unsigned long*)(public_key->exponent +
+ public_key->key_length -
+ sizeof(unsigned long)));
+ if (!rsa)
+ return errno;
+
+ const BIGNUM *n, *p, *q, *dmp1, *dmq1, *iqmp;
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ RSA_get0_key(rsa, &n, NULL, NULL);
+ RSA_get0_factors(rsa, &p, &q);
+ RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
+#else
+ n = rsa->n;
+ p = rsa->p;
+ q = rsa->q;
+ dmp1 = rsa->dmp1;
+ dmq1 = rsa->dmq1;
+ iqmp = rsa->iqmp;
+#endif /* OPENSSL_VERSION_NUMBER */
+
+ /* Public exponent has already been set, no need to do this here.
+ * For public key, only modulus needs to be set.
+ */
+ memset(public_key->modulus, 0, public_key->key_length);
+
+ /* Make sure that key parts are copied to the end of the buffer */
+ unsigned int offset = 0;
+
+ unsigned int bn_length = BN_num_bytes(n);
+ if (bn_length < public_key->key_length)
+ offset = public_key->key_length - bn_length;
+ else
+ offset = 0;
+ BN_bn2bin(n, public_key->modulus + offset);
+
+ memset(private_key->p, 0, (private_key->key_length+1) / 2 + 8);
+ memset(private_key->q, 0, (private_key->key_length+1) / 2);
+ memset(private_key->dp, 0, (private_key->key_length+1) / 2 + 8);
+ memset(private_key->dq, 0, (private_key->key_length+1) / 2);
+ memset(private_key->qInverse, 0, (private_key->key_length+1) / 2 + 8);
+
+ unsigned int key_part_length = (private_key->key_length+1) / 2;
+
+ /* We add the "+8" because it is a requirement by the crypto adapters
+ * to have an 8 byte zero pad in the beginning of the fields for:
+ * p, dp, and qInverse.
+ */
+
+ /* Copy p into buffer */
+ bn_length = BN_num_bytes(p);
+ if(bn_length < key_part_length)
+ offset = key_part_length - bn_length;
+ else
+ offset = 0;
+ BN_bn2bin(p, private_key->p + 8 + offset);
+
+ /* Copy q into buffer */
+ bn_length = BN_num_bytes(q);
+ if(bn_length < key_part_length)
+ offset = key_part_length - bn_length;
+ else
+ offset = 0;
+ BN_bn2bin(q, private_key->q + offset);
+
+ /* Copy dp into buffer */
+ bn_length = BN_num_bytes(dmp1);
+ if(bn_length < key_part_length)
+ offset = key_part_length - bn_length;
+ else
+ offset = 0;
+ BN_bn2bin(dmp1, private_key->dp + 8 + offset);
+
+ /* Copy dq into buffer */
+ bn_length = BN_num_bytes(dmq1);
+ if(bn_length < key_part_length)
+ offset = key_part_length - bn_length;
+ else
+ offset = 0;
+ BN_bn2bin(dmq1, private_key->dq + offset);
+
+ /* Copy qInverse into buffer */
+ bn_length = BN_num_bytes(iqmp);
+ if(bn_length < key_part_length)
+ offset = key_part_length - bn_length;
+ else
+ offset = 0;
+
+ BN_bn2bin(iqmp, private_key->qInverse + 8 + offset);
+
+ RSA_free(rsa);
+
+ return 0;
+}
+/**
+ * @deprecated Perform a modular muliplication operation in software.
+ */
+unsigned int rsa_mod_mult_sw(ica_rsa_modmult_t *pMul)
+{
+ int rc = 0;
+ BN_CTX *ctx = NULL;
+
+#ifdef ICA_FIPS
+ if ((fips & ICA_FIPS_MODE) && (!FIPS_mode()))
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if ((ctx = BN_CTX_new()) == NULL) {
+ return errno;
+ }
+
+ rc = mod_mul_sw(pMul->inputdatalength, pMul->inputdata,
+ pMul->inputdatalength, pMul->b_key,
+ pMul->inputdatalength, pMul->n_modulus,
+ (int *)&(pMul->outputdatalength),
+ pMul->outputdata, ctx);
+ BN_CTX_free(ctx);
+ if (rc)
+ rc = EIO;
+ return rc;
+}
+
+/**
+ * Perform a multiprecision modular multiplication using a multiplicand,
+ * multiplier and modulus.
+ */
+static unsigned int mod_mul_sw(int fc_1_length, char *fc1, int fc_2_length,
+ char *fc2, int mod_length, char *mod,
+ int *res_length, char *res, BN_CTX *ctx)
+{
+ int rc = 0;
+ int ln = 0;
+ int pad = 0;
+ BIGNUM *b_fc1 = NULL;
+ BIGNUM *b_fc2 = NULL;
+ BIGNUM *b_mod = NULL;
+ BIGNUM *b_res = NULL;
+
+#ifdef ICA_FIPS
+ if ((fips & ICA_FIPS_MODE) && (!FIPS_mode()))
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ BN_CTX_start(ctx);
+
+ b_fc1 = BN_CTX_get(ctx);
+ b_fc2 = BN_CTX_get(ctx);
+ b_mod = BN_CTX_get(ctx);
+ if ((b_res = BN_CTX_get(ctx)) == NULL) {
+ rc = ENOMEM;
+ goto cleanup;
+ }
+
+ b_fc1 = BN_bin2bn((const unsigned char *)fc1, fc_1_length, b_fc1);
+ b_fc2 = BN_bin2bn((const unsigned char *)fc2, fc_2_length, b_fc2);
+ b_mod = BN_bin2bn((const unsigned char *)mod, mod_length, b_mod);
+
+ if (!(BN_mod_mul(b_res, b_fc1, b_fc2, b_mod, ctx))) {
+ goto err;
+ }
+
+ if ((ln = BN_num_bytes(b_res)) > *res_length) {
+ rc = EIO;
+ goto cleanup;
+ }
+
+ if (ln)
+ pad = *res_length - ln;
+
+ ln = BN_bn2bin(b_res,(unsigned char *)(res + pad));
+
+ if (pad)
+ memset(res, 0, pad);
+
+ goto cleanup;
+
+ err:
+ rc = EIO;
+
+ cleanup:
+ BN_CTX_end(ctx);
+
+ return rc;
+}
+
+/**
+ * Perform a mod expo operation using a key in modulus/exponent form, in
+ * software.
+ * @param pMex
+ * Address of an ica_rsa_modexpo_t, containing:
+ * input_length - The byte length of the input data
+ * input_data - Pointer to input data
+ * b_key - Pointer to the exponent
+ * n_modulus - Pointer to the modulus
+ * output_length - On input it contains the byte length of the output
+ * buffer. On output it contains the actual byte
+ * length of the output_data
+ * output_data - Pointer to the output buffer
+ *
+ * Returns 0 if successful.
+ */
+unsigned int rsa_mod_expo_sw(ica_rsa_modexpo_t *pMex)
+{
+ int rc = 0;
+ BN_CTX *ctx = NULL;
+
+#ifdef ICA_FIPS
+ if ((fips & ICA_FIPS_MODE) && (!FIPS_mode()))
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if ((ctx = BN_CTX_new()) == NULL) {
+ return errno;
+ }
+
+ /* check if modulus value > data value */
+ if ((memcmp(pMex->n_modulus, pMex->inputdata,
+ pMex->inputdatalength)) <= 0)
+ return EINVAL;
+
+ rc = mod_expo_sw(pMex->inputdatalength, pMex->inputdata,
+ pMex->inputdatalength, pMex->b_key,
+ pMex->inputdatalength, pMex->n_modulus,
+ (int *)&(pMex->outputdatalength), pMex->outputdata, ctx);
+
+ BN_CTX_free(ctx);
+ if (rc == 1)
+ rc = EIO;
+ return rc;
+}
+
+/**
+ * Perform a mod expo operation using a key in modulus/exponent form, in
+ * software.
+ * @param arg_length
+ * The byte length of the input data
+ * @param arg
+ * Pointer to input data
+ * @param exp_length
+ * The byte length of the exponent
+ * @param exp
+ * Pointer to the exponent
+ * @param mod_length
+ * The byte length of the modulus
+ * @param mod
+ * Pointer to the modulus
+ * @param res_length
+ * On input it points to the byte length of the output buffer. On output it
+ * points to the actual byte length of the output_data
+ * @param res
+ * Pointer to the output buffer
+ * @param ctx
+ * Pointer to a BN_CTX
+ *
+ * Returns 0 if successful BN error code if unsuccessful.
+ */
+static unsigned int mod_expo_sw(int arg_length, char *arg, int exp_length,
+ char *exp, int mod_length, char *mod,
+ int *res_length, char *res, BN_CTX *ctx)
+{
+ int rc = 0;
+ int ln = 0;
+ int pad = 0;
+ BIGNUM *b_arg = NULL;
+ BIGNUM *b_exp = NULL;
+ BIGNUM *b_mod = NULL;
+ BIGNUM *b_res = NULL;
+ BN_CTX *mod_expo_ctx = NULL;
+ int mod_expo_rc = 1;
+
+#ifdef ICA_FIPS
+ if ((fips & ICA_FIPS_MODE) && (!FIPS_mode()))
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ BN_CTX_start(ctx);
+
+ b_arg = BN_CTX_get(ctx);
+ b_exp = BN_CTX_get(ctx);
+ b_mod = BN_CTX_get(ctx);
+ if ((b_res = BN_CTX_get(ctx)) == NULL) {
+ rc = ENOMEM;
+ goto cleanup;
+ }
+
+ b_arg = BN_bin2bn((const unsigned char *)arg, arg_length, b_arg);
+ b_exp = BN_bin2bn((const unsigned char *)exp, exp_length, b_exp);
+ b_mod = BN_bin2bn((const unsigned char *)mod, mod_length, b_mod);
+
+ // Evidently BN_mod_exp gets a *lot* of temp BN's, so it
+ // needs a context all its own.
+ if ((mod_expo_ctx = BN_CTX_new()) == NULL) {
+ goto err;
+ }
+
+ mod_expo_rc = BN_mod_exp(b_res, b_arg, b_exp, b_mod, mod_expo_ctx);
+ BN_CTX_free(mod_expo_ctx);
+
+ if (!(mod_expo_rc)) {
+ goto err;
+ }
+
+ if ((ln = BN_num_bytes(b_res)) > *res_length) {
+ rc = 1;
+ goto cleanup;
+ }
+
+ if (ln)
+ pad = *res_length - ln;
+
+ ln = BN_bn2bin(b_res, (unsigned char *)(res + pad));
+
+ if (pad)
+ memset(res, 0, pad);
+
+ goto cleanup;
+
+ err:
+ rc = EIO;
+
+ cleanup:
+ BN_CTX_end(ctx);
+
+ return rc;
+}
+
+/**
+ * Perform a RSA mod expo on input data using a key in CRT format, in software.
+ *
+ * @param pCrt
+ * Address of an ica_rsa_modexpo_crt_t, containing:
+ * input_length: The byte length of the input data.
+ * input_data: Pointer to input data b
+ * output_length: On input it contains the byte length of the output
+ * buffer. On output it contains the actual byte length
+ * of the output_data
+ * output_data: Pointer to the output buffer
+ * bp_key: Pointer to dp
+ * bq_key: Pointer to dq
+ * np_prime: Pointer to p
+ * nq_prime: Pointer to q
+ * u_mult_inv: Pointer to u
+ *
+ * Returns 0 if successful
+ */
+unsigned int rsa_crt_sw(ica_rsa_modexpo_crt_t * pCrt)
+{
+ int rc = 0;
+ int long_length = 0;
+ int short_length = 0;
+ BN_CTX *ctx = NULL;
+
+#ifdef ICA_FIPS
+ if ((fips & ICA_FIPS_MODE) && (!FIPS_mode()))
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ short_length = (pCrt->inputdatalength+1) / 2;
+ long_length = short_length + 8;
+/*
+ Use variable buffer length. Earlier version contained fixed 136byte
+ size for ir buffers. Thus the software fallback should be able to
+ handle keys of bigger size, too.
+*/
+ char ir1[long_length];
+ int ir_1_length = sizeof(ir1);
+ char ir2[long_length];
+ int ir_2_length = sizeof(ir2);
+ char temp[long_length];
+ int temp_length = sizeof(temp);
+
+ if ((ctx = BN_CTX_new()) == NULL) {
+ return errno;
+ }
+
+ memset(ir1, 0, sizeof(ir1));
+ if ((rc = mod_sw(pCrt->inputdatalength, pCrt->inputdata,
+ long_length, pCrt->np_prime, &ir_1_length, ir1, ctx)) != 0)
+ goto err;
+
+ memset(temp, 0, sizeof(temp));
+ if ((rc = mod_expo_sw(ir_1_length, ir1,
+ long_length, pCrt->bp_key,
+ long_length, pCrt->np_prime,
+ &temp_length, temp, ctx)) != 0)
+ goto err;
+
+ memset(ir1, 0, sizeof(ir1));
+ memcpy(ir1, temp, temp_length);
+ ir_1_length = temp_length;
+
+ memset(ir2, 0, sizeof(ir2));
+ if ((rc = mod_sw(pCrt->inputdatalength, pCrt->inputdata,
+ short_length, pCrt->nq_prime, &ir_2_length,
+ ir2, ctx)) != 0)
+ goto err;
+
+ temp_length = sizeof(temp);
+ memset(temp, 0, sizeof(temp));
+ if ((rc = mod_expo_sw(ir_2_length, ir2,
+ short_length, pCrt->bq_key,
+ short_length, pCrt->nq_prime,
+ &temp_length, temp, ctx)) != 0)
+ goto err;
+
+ memset(ir2, 0, sizeof(ir2));
+ memcpy(ir2, temp, temp_length);
+ ir_2_length = temp_length;
+
+ temp_length = sizeof(ir1);
+ if ((rc = mod_sub_sw(ir_1_length, ir1,
+ ir_2_length, ir2,
+ long_length, pCrt->np_prime,
+ &temp_length, ir1, ctx)) != 0) {
+ if (rc != -1) {
+ goto err;
+ } else {
+ if (ir_2_length > pCrt->outputdatalength) {
+ memcpy(pCrt->outputdata,
+ ir2 + (ir_2_length -
+ pCrt->outputdatalength),
+ pCrt->outputdatalength);
+ } else {
+ if (ir_2_length < pCrt->outputdatalength) {
+ memset(pCrt->outputdata, 0,
+ (pCrt->outputdatalength -
+ ir_2_length));
+ memcpy(pCrt->outputdata +
+ (pCrt->outputdatalength -
+ ir_2_length), ir2, ir_2_length);
+ } else {
+ memcpy(pCrt->outputdata, ir2,
+ ir_2_length);
+ }
+ }
+ rc = 0;
+ goto cleanup;
+ }
+ }
+
+ ir_1_length = temp_length;
+
+ temp_length = sizeof(temp);
+ memset(temp, 0, sizeof(temp));
+ if ((rc = mod_mul_sw(ir_1_length, ir1,
+ long_length, pCrt->u_mult_inv,
+ long_length, pCrt->np_prime,
+ &temp_length, temp, ctx)) != 0)
+ goto err;
+
+ if ((rc = mul_sw(temp_length, temp,
+ short_length, pCrt->nq_prime,
+ (int *)&(pCrt->outputdatalength), pCrt->outputdata, ctx)) != 0)
+ goto err;
+
+ if ((rc = add_sw(pCrt->outputdatalength, pCrt->outputdata,
+ ir_2_length, ir2,
+ (int *)&(pCrt->outputdatalength), pCrt->outputdata, ctx)) != 0)
+ goto err;
+
+ goto cleanup;
+
+ err:
+ rc = EIO;
+
+ cleanup:
+ BN_CTX_free(ctx);
+
+ return rc;
+}
+
+/**
+ * Perform a 'residue modulo' operation using an argument and a modulus.
+ * @param arg_length The byte length of the input data
+ * @param arg Pointer to input data
+ * @param mod_length The byte length of the modulus
+ * @param mod Pointer to the modulus
+ * @param res_length
+ * On input it points to the byte length of the output buffer. On output it
+ * points to the actual byte length of the output_data.
+ * @param res Pointer to the output buffer
+ * @param ctx Pointer to a BN_CTX
+ *
+ * Returns 0 if successful, BN error code if unsuccessful
+ */
+static unsigned int mod_sw(int arg_length, char *arg, int mod_length,
+ char *mod, int *res_length, char *res, BN_CTX *ctx)
+{
+ int rc = 0;
+ int ln = 0;
+ int pad = 0;
+ BIGNUM *b_arg = NULL;
+ BIGNUM *b_mod = NULL;
+ BIGNUM *b_res = NULL;
+
+#ifdef ICA_FIPS
+ if ((fips & ICA_FIPS_MODE) && (!FIPS_mode()))
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ BN_CTX_start(ctx);
+
+ b_arg = BN_CTX_get(ctx);
+ b_mod = BN_CTX_get(ctx);
+ if ((b_res = BN_CTX_get(ctx)) == NULL) {
+ rc = -ENOMEM;
+ goto cleanup;
+ }
+
+ b_arg = BN_bin2bn((const unsigned char *)arg, arg_length, b_arg);
+ b_mod = BN_bin2bn((const unsigned char *)mod, mod_length, b_mod);
+
+ if (!(BN_mod(b_res, b_arg, b_mod, ctx))) {
+ goto err;
+ }
+
+ if ((ln = BN_num_bytes(b_res)) > *res_length) {
+ rc = 1;
+ goto cleanup;
+ }
+
+ if (ln)
+ pad = *res_length - ln;
+
+ ln = BN_bn2bin(b_res, (unsigned char *)(res + pad));
+
+ if (pad)
+ memset(res, 0, pad);
+
+ goto cleanup;
+
+ err:
+ rc = EIO;
+
+ cleanup:
+ BN_CTX_end(ctx);
+
+ return rc;
+}
+
+/**
+ * Perform a multiprecision subtraction modulo a modulus using a minuend,
+ * subtrahend and modulus
+ *
+ * @param min_length The byte length of the minuend
+ * @param min Pointer to minuend
+ * @param sub_length The byte length of the subtrahend
+ * @param sub Pointer to the subtrahend
+ * @param mod_length The byte length of the modulus
+ * @param mod The modulus
+ * @param res_length
+ * On input it points to the byte length of the output buffer. On output it
+ * points to the actual byte length of the output_data
+ * @param res Pointer to the output buffer
+ * @param ctx Pointer to a BN_CTX
+ *
+ * Returns 0 if successful, BN error code if unsuccessful
+ * Process:
+ * 1) If the subtrahend exceeds the minuend, use add_sw to
+ * add the modulus to the minuend
+ * 2) Call BN_CTX_get for the minuend, subtrahend & result BN's
+ * 3) Convert the minuend and subtrahend BN's using BN_bin2bn
+ * 4) Call BN_sub
+ * 5) Convert the result from a BN to a string using BN_bn2bin
+ * 6) Call BN_free for the minuend, subtrahend and result BN's
+ */
+static unsigned int mod_sub_sw(int min_length, char *minu, int sub_length,
+ char *sub, int mod_length, char *mod,
+ int *res_length, char *res, BN_CTX * ctx)
+{
+ int rc = 0;
+ int ln = 0;
+ int pad = 0;
+
+ int min_size, sub_size, dif_size;
+
+#ifdef ICA_FIPS
+ if ((fips & ICA_FIPS_MODE) && (!FIPS_mode()))
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ BIGNUM *b_min = NULL;
+ BIGNUM *b_sub = NULL;
+ BIGNUM *b_mod = NULL;
+ BIGNUM *b_res = NULL;
+
+ BN_CTX_start(ctx);
+
+ b_min = BN_CTX_get(ctx);
+ b_sub = BN_CTX_get(ctx);
+ b_mod = BN_CTX_get(ctx);
+ if ((b_res = BN_CTX_get(ctx)) == NULL) {
+ rc = -ENOMEM;
+ goto cleanup;
+ }
+
+ b_min = BN_bin2bn((const unsigned char *)minu, min_length, b_min);
+ b_sub = BN_bin2bn((const unsigned char *)sub, sub_length, b_sub);
+ b_mod = BN_bin2bn((const unsigned char *)mod, mod_length, b_mod);
+
+ min_size = BN_num_bytes(b_min);
+ sub_size = BN_num_bytes(b_sub);
+
+ /* if sub == min, the result is zero, but it's an error */
+ if (sub_size == min_size) {
+ dif_size = memcmp(sub, minu, sub_length);
+ if (dif_size == 0) {
+ memset(res, 0, *res_length);
+ rc = -1;
+ goto cleanup;
+ }
+ }
+ /* if sub < min, the result is just min - sub */
+ if ((sub_size < min_size) || ((sub_size == min_size) && (dif_size < 0))) {
+ if (!(BN_sub(b_res, b_min, b_sub))) {
+ goto err;
+ }
+ } else { /* sub > min, so the result is (min + mod) - sub */
+ if (!(BN_add(b_res, b_min, b_mod))) {
+ goto err;
+ }
+ if (!(BN_sub(b_res, b_res, b_sub))) {
+ goto err;
+ }
+ }
+
+ if ((ln = BN_num_bytes(b_res)) > *res_length) {
+ rc = 1;
+ goto cleanup;
+ }
+
+ if (ln)
+ pad = *res_length - ln;
+
+ ln = BN_bn2bin(b_res, (unsigned char *)(res + pad));
+
+ if (pad)
+ memset(res, 0, pad);
+
+ goto cleanup;
+
+ err:
+ rc = EIO;
+
+ cleanup:
+ BN_CTX_end(ctx);
+
+ return rc;
+}
+
+/**
+ * Perform a multiprecision addition using an augend and addend
+ * @param aug_length The byte length of the augend
+ * @param aug Pointer to augend
+ * @param add_length The byte length of the addend
+ * @param add Pointer to the addend
+ * @param res_length On input it points to the byte length of the output buffer.
+ * On output it points to the actual byte length of the
+ * output_data
+ * @param res Pointer to the output buffer
+ * @param ctx Pointer to a BN_CTX
+ *
+ * Returns 0 if successful, BN error code if unsuccessful
+ * Process:
+ * 1) Call BN_CTX_get for the augend, addend and result BN's
+ * 2) Convert the augend and addend BN's using BN_bin2bn
+ * 3) Call BN_add
+ * 4) Convert the result from a BN to a string using BN_bn2bin
+ * 5) Call BN_free for the augend, addend and result BN's
+*/
+static unsigned int add_sw(int aug_length, char *aug, int add_length,
+ char *add, int *res_length, char *res, BN_CTX *ctx)
+{
+ int rc = 0;
+ int ln = 0;
+ int pad = 0;
+ BIGNUM *b_aug = NULL;
+ BIGNUM *b_add = NULL;
+ BIGNUM *b_res = NULL;
+
+ BN_CTX_start(ctx);
+
+#ifdef ICA_FIPS
+ if ((fips & ICA_FIPS_MODE) && (!FIPS_mode()))
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ b_aug = BN_CTX_get(ctx);
+ b_add = BN_CTX_get(ctx);
+ if ((b_res = BN_CTX_get(ctx)) == NULL) {
+ rc = -ENOMEM;
+ goto cleanup;
+ }
+
+ b_aug = BN_bin2bn((const unsigned char *)aug, aug_length, b_aug);
+ b_add = BN_bin2bn((const unsigned char *)add, add_length, b_add);
+
+ if (!(BN_add(b_res, b_aug, b_add))) {
+ goto err;
+ }
+
+ if ((ln = BN_num_bytes(b_res)) > *res_length) {
+ rc = 1;
+ goto cleanup;
+ }
+
+ if (ln)
+ pad = *res_length - ln;
+
+ ln = BN_bn2bin(b_res, (unsigned char *)(res + pad));
+
+ if (pad)
+ memset(res, 0, pad);
+
+ goto cleanup;
+
+ err:
+ rc = EIO;
+
+ cleanup:
+ BN_CTX_end(ctx);
+
+ return rc;
+}
+
+/**
+ * Perform a multiprecision multiply using a multiplicand and multiplier.
+ * @param fc_1_length The byte length of the multiplicand
+ * @param fc1 Pointer to multiplicand
+ * @param fc_2_length The byte length of the multiplier
+ * @param fc2 Pointer to the multiplier
+ * @param res_length
+ * On input it points to the byte length of the output buffer. On output it
+ * points to the actual byte length of the output_data.
+ * @param res Pointer to the output buffer
+ * @param ctx Pointer to a BN_CTX
+ *
+ * Returns 0 if successful, BN error code if unsuccessful
+ */
+static unsigned int mul_sw(int fc_1_length, char *fc1, int fc_2_length,
+ char *fc2, int *res_length, char *res, BN_CTX *ctx)
+{
+ int rc = 0;
+ int ln = 0;
+ int pad = 0;
+ BIGNUM *b_fc1 = NULL;
+ BIGNUM *b_fc2 = NULL;
+ BIGNUM *b_res = NULL;
+
+ BN_CTX_start(ctx);
+
+#ifdef ICA_FIPS
+ if ((fips & ICA_FIPS_MODE) && (!FIPS_mode()))
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ b_fc1 = BN_CTX_get(ctx);
+ b_fc2 = BN_CTX_get(ctx);
+ if ((b_res = BN_CTX_get(ctx)) == NULL) {
+ rc = -ENOMEM;
+ goto cleanup;
+ }
+
+ b_fc1 = BN_bin2bn((const unsigned char *)fc1, fc_1_length, b_fc1);
+ b_fc2 = BN_bin2bn((const unsigned char *)fc2, fc_2_length, b_fc2);
+
+ if (!(BN_mul(b_res, b_fc1, b_fc2, ctx))) {
+ goto err;
+ }
+
+ if ((ln = BN_num_bytes(b_res)) > *res_length) {
+ rc = 1;
+ goto cleanup;
+ }
+
+ if (ln)
+ pad = *res_length - ln;
+
+ ln = BN_bn2bin(b_res, (unsigned char *)(res + pad));
+
+ if (pad)
+ memset(res, 0, pad);
+
+ goto cleanup;
+
+ err:
+ rc = EIO;
+
+ cleanup:
+ BN_CTX_end(ctx);
+
+ return rc;
+}
+
diff --git a/src/s390_sha.c b/src/s390_sha.c
new file mode 100644
index 0000000..6a5c2a5
--- /dev/null
+++ b/src/s390_sha.c
@@ -0,0 +1,321 @@
+/* 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.
+ */
+
+/**
+ * Authors: Felix Beck <felix.beck@de.ibm.com>
+ * Holger Dengler <hd@linux.vnet.ibm.com>
+ * Christian Maaser <cmaaser@de.ibm.com>
+ *
+ * Copyright IBM Corp. 2009, 2011
+ */
+
+#include <string.h>
+#include <errno.h>
+#include <openssl/crypto.h>
+#include <openssl/sha.h>
+
+#include <openssl/opensslconf.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif /* OPENSSL_FIPS */
+
+#include "fips.h"
+#include "s390_crypto.h"
+#include "s390_sha.h"
+#include "init.h"
+#include "icastats.h"
+
+static int s390_sha1_sw(unsigned char *iv, unsigned char *input_data,
+ unsigned int input_length, unsigned char *output_data,
+ unsigned int message_part, uint64_t *running_length)
+{
+ SHA_CTX ctx;
+ unsigned int vector_length = 20;
+
+#ifdef ICA_FIPS
+ if ((fips & ICA_FIPS_MODE) && (!FIPS_mode()))
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (message_part == SHA_MSG_PART_ONLY ||
+ message_part == SHA_MSG_PART_FIRST) {
+ SHA1_Init(&ctx);
+ } else {
+ memcpy((unsigned char *) &ctx.Nl,
+ (unsigned char *) running_length,
+ sizeof(*running_length));
+ memcpy((unsigned char *) &ctx.h0, iv, vector_length);
+ ctx.num = 0;
+ }
+
+ SHA1_Update(&ctx, input_data, input_length);
+
+ if (message_part == SHA_MSG_PART_ONLY ||
+ message_part == SHA_MSG_PART_FINAL) {
+ SHA1_Final(output_data, &ctx);
+ } else {
+ memcpy((unsigned char *) running_length,
+ (unsigned char *) &ctx.Nl,
+ sizeof(*running_length));
+ memcpy(output_data, (unsigned char *) &ctx.h0,
+ SHA_DIGEST_LENGTH);
+ memcpy(iv, (unsigned char *) &ctx.h0, vector_length);
+ }
+
+ return 0;
+}
+
+static int s390_sha224_sw(unsigned char *iv, unsigned char *input_data,
+ unsigned int input_length,
+ unsigned char *output_data,
+ unsigned int message_part, uint64_t *running_length)
+{
+ SHA256_CTX ctx;
+ unsigned int vector_length = 32;
+
+#ifdef ICA_FIPS
+ if ((fips & ICA_FIPS_MODE) && (!FIPS_mode()))
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (message_part == SHA_MSG_PART_ONLY ||
+ message_part == SHA_MSG_PART_FIRST) {
+ SHA224_Init(&ctx);
+ } else {
+ ctx.Nl = *running_length;
+ memcpy((unsigned char *) &ctx.h[0], iv, vector_length);
+ ctx.md_len = SHA224_DIGEST_LENGTH;
+ ctx.num = 0;
+ }
+
+ SHA224_Update(&ctx, input_data, input_length);
+
+ if (message_part == SHA_MSG_PART_ONLY ||
+ message_part == SHA_MSG_PART_FINAL) {
+ SHA224_Final(output_data, &ctx);
+ } else {
+ *running_length = ctx.Nl;
+ memcpy(output_data, (unsigned char *) &ctx.h[0],
+ SHA224_DIGEST_LENGTH);
+ memcpy(iv, (unsigned char *) &ctx.h[0], vector_length);
+ }
+
+ return 0;
+}
+
+static int s390_sha256_sw(unsigned char *iv, unsigned char *input_data,
+ unsigned int input_length,
+ unsigned char *output_data,
+ unsigned int message_part, uint64_t *running_length)
+{
+ SHA256_CTX ctx;
+ unsigned int vector_length = 32;
+
+#ifdef ICA_FIPS
+ if ((fips & ICA_FIPS_MODE) && (!FIPS_mode()))
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (message_part == SHA_MSG_PART_ONLY ||
+ message_part == SHA_MSG_PART_FIRST) {
+ SHA256_Init(&ctx);
+ } else {
+ ctx.Nl = *running_length;
+ memcpy((unsigned char *) &ctx.h[0], iv, vector_length);
+ ctx.md_len = SHA256_DIGEST_LENGTH;
+ ctx.num = 0;
+ }
+
+ SHA256_Update(&ctx, input_data, input_length);
+
+ if (message_part == SHA_MSG_PART_ONLY ||
+ message_part == SHA_MSG_PART_FINAL) {
+ SHA256_Final(output_data, &ctx);
+ } else {
+ *running_length = ctx.Nl;
+ memcpy(output_data, (unsigned char *) &ctx.h[0],
+ SHA256_DIGEST_LENGTH);
+ memcpy(iv, (unsigned char *) &ctx.h[0], vector_length);
+ }
+
+ return 0;
+}
+
+static int s390_sha384_sw(unsigned char *iv, unsigned char *input_data,
+ uint64_t input_length,
+ unsigned char *output_data,
+ unsigned int message_part,
+ uint64_t *running_length_lo,
+ uint64_t *running_length_hi)
+{
+ SHA512_CTX ctx;
+ unsigned int vector_length = 64;
+
+#ifdef ICA_FIPS
+ if ((fips & ICA_FIPS_MODE) && (!FIPS_mode()))
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (message_part == SHA_MSG_PART_ONLY ||
+ message_part == SHA_MSG_PART_FIRST) {
+ SHA384_Init(&ctx);
+ } else {
+ ctx.Nl = *running_length_lo;
+ ctx.Nh = *running_length_hi;
+ ctx.num = 0;
+ ctx.md_len = SHA384_DIGEST_LENGTH;
+ memcpy((unsigned char *) &ctx.h[0], iv, vector_length);
+ }
+
+ SHA384_Update(&ctx, input_data, input_length);
+
+ if (message_part == SHA_MSG_PART_ONLY ||
+ message_part == SHA_MSG_PART_FINAL)
+ SHA384_Final(output_data, &ctx);
+ else {
+ *running_length_lo = ctx.Nl;
+ *running_length_hi = ctx.Nh;
+ memcpy(output_data, (unsigned char *) &ctx.h[0],
+ SHA384_DIGEST_LENGTH);
+ memcpy(iv, (unsigned char *) &ctx.h[0], vector_length);
+ }
+
+ return 0;
+}
+
+int s390_sha512_sw(unsigned char *iv, unsigned char *input_data,
+ uint64_t input_length, unsigned char *output_data,
+ unsigned int message_part, uint64_t *running_length_lo,
+ uint64_t *running_length_hi)
+{
+ SHA512_CTX ctx;
+ unsigned int vector_length = 64;
+
+#ifdef ICA_FIPS
+ if ((fips & ICA_FIPS_MODE) && (!FIPS_mode()))
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (message_part == SHA_MSG_PART_ONLY || message_part == SHA_MSG_PART_FIRST) {
+ SHA512_Init(&ctx);
+ } else {
+ ctx.md_len = SHA512_DIGEST_LENGTH;
+ ctx.Nl = *running_length_lo;
+ ctx.Nh = *running_length_hi;
+ ctx.num = 0;
+ memcpy((unsigned char *) &ctx.h[0], iv, vector_length);
+ }
+
+ SHA512_Update(&ctx, input_data, input_length);
+
+ if (message_part == SHA_MSG_PART_ONLY ||
+ message_part == SHA_MSG_PART_FINAL)
+ SHA512_Final(output_data, &ctx);
+ else {
+ *running_length_lo = ctx.Nl;
+ *running_length_hi = ctx.Nh;
+ memcpy(output_data, (unsigned char *) &ctx.h[0],
+ SHA512_DIGEST_LENGTH);
+ memcpy(iv, (unsigned char *) &ctx.h[0], vector_length);
+ }
+
+ return 0;
+}
+
+int s390_sha1(unsigned char *iv, unsigned char *input_data,
+ unsigned int input_length, unsigned char *output_data,
+ unsigned int message_part, uint64_t *running_length)
+{
+ int rc = 1;
+ if (sha1_switch)
+ rc = s390_sha_hw(iv, input_data, input_length, output_data,
+ message_part, running_length, NULL, SHA_1);
+ if (rc) {
+ rc = s390_sha1_sw(iv, input_data, input_length, output_data,
+ message_part, running_length);
+ stats_increment(ICA_STATS_SHA1, ALGO_SW, ENCRYPT);
+ } else
+ stats_increment(ICA_STATS_SHA1, ALGO_HW, ENCRYPT);
+
+ return rc;
+}
+
+int s390_sha224(unsigned char *iv, unsigned char *input_data,
+ unsigned int input_length, unsigned char *output_data,
+ unsigned int message_part, uint64_t *running_length)
+{
+ int rc = 1;
+ if (sha256_switch)
+ rc = s390_sha_hw(iv, input_data, input_length, output_data,
+ message_part, running_length, NULL, SHA_224);
+ if (rc) {
+ rc = s390_sha224_sw(iv, input_data, input_length, output_data,
+ message_part, running_length);
+ stats_increment(ICA_STATS_SHA224, ALGO_SW, ENCRYPT);
+ } else
+ stats_increment(ICA_STATS_SHA224, ALGO_HW, ENCRYPT);
+
+ return rc;
+}
+
+int s390_sha256(unsigned char *iv, unsigned char *input_data,
+ unsigned int input_length, unsigned char *output_data,
+ unsigned int message_part, uint64_t *running_length)
+{
+ int rc = 1;
+ if (sha256_switch)
+ rc = s390_sha_hw(iv, input_data, input_length, output_data,
+ message_part, running_length, NULL, SHA_256);
+ if (rc) {
+ rc = s390_sha256_sw(iv, input_data, input_length, output_data,
+ message_part, running_length);
+ stats_increment(ICA_STATS_SHA256, ALGO_SW, ENCRYPT);
+ } else
+ stats_increment(ICA_STATS_SHA256, ALGO_HW, ENCRYPT);
+
+ return rc;
+}
+int s390_sha384(unsigned char *iv, unsigned char *input_data,
+ uint64_t input_length, unsigned char *output_data,
+ unsigned int message_part, uint64_t *running_length_lo,
+ uint64_t *running_length_hi)
+{
+ int rc = 1;
+ if (sha512_switch)
+ rc = s390_sha_hw(iv, input_data, input_length, output_data,
+ message_part, running_length_lo,
+ running_length_hi, SHA_384);
+ if (rc) {
+ rc = s390_sha384_sw(iv, input_data, input_length, output_data,
+ message_part, running_length_lo,
+ running_length_hi);
+ stats_increment(ICA_STATS_SHA384, ALGO_SW, ENCRYPT);
+ } else
+ stats_increment(ICA_STATS_SHA384, ALGO_HW, ENCRYPT);
+
+ return rc;
+}
+
+int s390_sha512(unsigned char *iv, unsigned char *input_data,
+ uint64_t input_length, unsigned char *output_data,
+ unsigned int message_part, uint64_t *running_length_lo,
+ uint64_t *running_length_hi)
+{
+ int rc = 1;
+ if (sha512_switch)
+ rc = s390_sha_hw(iv, input_data, input_length, output_data,
+ message_part, running_length_lo,
+ running_length_hi, SHA_512);
+ if (rc) {
+ rc = s390_sha512_sw(iv, input_data, input_length, output_data,
+ message_part, running_length_lo,
+ running_length_hi);
+ stats_increment(ICA_STATS_SHA512, ALGO_SW, ENCRYPT);
+ } else
+ stats_increment(ICA_STATS_SHA512, ALGO_HW, ENCRYPT);
+
+ return rc;
+}
diff --git a/src/test_vec.c b/src/test_vec.c
new file mode 100644
index 0000000..d0b0f8f
--- /dev/null
+++ b/src/test_vec.c
@@ -0,0 +1,3831 @@
+/*
+ * 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. 2015
+ */
+
+#include <errno.h>
+
+#include "ica_api.h"
+#include "test_vec.h"
+
+#ifdef ICA_FIPS
+const struct rsa_tv RSA_TV[] = {
+{
+.n = (unsigned char []){
+0xba, 0xd4, 0x7a, 0x84, 0xc1, 0x78, 0x2e, 0x4d, 0xbd, 0xd9, 0x13, 0xf2, 0xa2,
+0x61, 0xfc, 0x8b, 0x65, 0x83, 0x84, 0x12, 0xc6, 0xe4, 0x5a, 0x20, 0x68, 0xed,
+0x6d, 0x7f, 0x16, 0xe9, 0xcd, 0xf4, 0x46, 0x2b, 0x39, 0x11, 0x95, 0x63, 0xca,
+0xfb, 0x74, 0xb9, 0xcb, 0xf2, 0x5c, 0xfd, 0x54, 0x4b, 0xda, 0xe2, 0x3b, 0xff,
+0x0e, 0xbe, 0x7f, 0x64, 0x41, 0x04, 0x2b, 0x7e, 0x10, 0x9b, 0x9a, 0x8a, 0xfa,
+0xa0, 0x56, 0x82, 0x1e, 0xf8, 0xef, 0xaa, 0xb2, 0x19, 0xd2, 0x1d, 0x67, 0x63,
+0x48, 0x47, 0x85, 0x62, 0x2d, 0x91, 0x8d, 0x39, 0x5a, 0x2a, 0x31, 0xf2, 0xec,
+0xe8, 0x38, 0x5a, 0x81, 0x31, 0xe5, 0xff, 0x14, 0x33, 0x14, 0xa8, 0x2e, 0x21,
+0xaf, 0xd7, 0x13, 0xba, 0xe8, 0x17, 0xcc, 0x0e, 0xe3, 0x51, 0x4d, 0x48, 0x39,
+0x00, 0x7c, 0xcb, 0x55, 0xd6, 0x84, 0x09, 0xc9, 0x7a, 0x18, 0xab, 0x62, 0xfa,
+0x6f, 0x9f, 0x89, 0xb3, 0xf9, 0x4a, 0x27, 0x77, 0xc4, 0x7d, 0x61, 0x36, 0x77,
+0x5a, 0x56, 0xa9, 0xa0, 0x12, 0x7f, 0x68, 0x24, 0x70, 0xbe, 0xf8, 0x31, 0xfb,
+0xec, 0x4b, 0xcd, 0x7b, 0x50, 0x95, 0xa7, 0x82, 0x3f, 0xd7, 0x07, 0x45, 0xd3,
+0x7d, 0x1b, 0xf7, 0x2b, 0x63, 0xc4, 0xb1, 0xb4, 0xa3, 0xd0, 0x58, 0x1e, 0x74,
+0xbf, 0x9a, 0xde, 0x93, 0xcc, 0x46, 0x14, 0x86, 0x17, 0x55, 0x39, 0x31, 0xa7,
+0x9d, 0x92, 0xe9, 0xe4, 0x88, 0xef, 0x47, 0x22, 0x3e, 0xe6, 0xf6, 0xc0, 0x61,
+0x88, 0x4b, 0x13, 0xc9, 0x06, 0x5b, 0x59, 0x11, 0x39, 0xde, 0x13, 0xc1, 0xea,
+0x29, 0x27, 0x49, 0x1e, 0xd0, 0x0f, 0xb7, 0x93, 0xcd, 0x68, 0xf4, 0x63, 0xf5,
+0xf6, 0x4b, 0xaa, 0x53, 0x91, 0x6b, 0x46, 0xc8, 0x18, 0xab, 0x99, 0x70, 0x65,
+0x57, 0xa1, 0xc2, 0xd5, 0x0d, 0x23, 0x25, 0x77, 0xd1
+},
+.p = (unsigned char []){
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8 bytes zero padding */
+0xe7, 0xc9, 0xe4, 0xb3, 0xe5, 0xd7, 0xac, 0x9e, 0x83, 0xbe, 0x08, 0x32, 0x81,
+0x05, 0x35, 0x6d, 0xfe, 0xef, 0xe2, 0x22, 0xf2, 0x6c, 0x95, 0x37, 0x8e, 0xff,
+0xd2, 0x15, 0x0f, 0xad, 0xf7, 0xba, 0x23, 0xf5, 0xb4, 0x70, 0x5d, 0x82, 0xe4,
+0xf1, 0xbc, 0x45, 0x05, 0x70, 0x67, 0xc7, 0xde, 0xf7, 0x3e, 0x21, 0x00, 0xf7,
+0x56, 0xee, 0x6d, 0x54, 0x79, 0x65, 0xfa, 0x4f, 0x24, 0xb8, 0x5d, 0x68, 0x86,
+0x7f, 0x03, 0xd7, 0xc8, 0x86, 0xd1, 0xdb, 0xcc, 0xa4, 0xc5, 0x89, 0x74, 0x57,
+0x01, 0xb3, 0x62, 0xa1, 0xf1, 0x41, 0x7f, 0x47, 0x1d, 0x84, 0x75, 0xb6, 0xb7,
+0xa1, 0x6a, 0x4c, 0x48, 0xef, 0x1f, 0x55, 0x6e, 0xdc, 0x3f, 0x0f, 0xf6, 0xba,
+0x13, 0xd3, 0x65, 0xd6, 0xe8, 0x27, 0x51, 0xf2, 0x07, 0xd9, 0x11, 0x01, 0xc8,
+0xee, 0xa1, 0x01, 0x3c, 0xcd, 0xd9, 0xe1, 0xde, 0x4c, 0x38, 0x7f
+},
+.q = (unsigned char []){
+0xce, 0x58, 0x60, 0x2e, 0x05, 0x1f, 0x0f, 0x46, 0x47, 0xc4, 0xec, 0x57, 0xf6,
+0x82, 0xe5, 0x73, 0x7f, 0xc4, 0x82, 0xa8, 0xa1, 0xff, 0xac, 0x90, 0x43, 0xbb,
+0xa4, 0xfb, 0xa3, 0x38, 0x7d, 0x7d, 0xd2, 0x15, 0x45, 0x07, 0xaf, 0x1e, 0x28,
+0xbd, 0x81, 0xb6, 0x1f, 0xcd, 0xfe, 0x35, 0xf9, 0x73, 0x4e, 0x0d, 0x9b, 0x53,
+0x68, 0x2e, 0xc7, 0x85, 0xf1, 0xf6, 0xe6, 0x22, 0x4f, 0x63, 0xd1, 0x0b, 0xf7,
+0x84, 0x84, 0xb8, 0x3a, 0x42, 0x54, 0xf3, 0x33, 0xd0, 0xfb, 0x3f, 0x3e, 0x9e,
+0x18, 0x34, 0xbe, 0xde, 0x52, 0xe3, 0x07, 0x8a, 0xc2, 0x79, 0xa8, 0x62, 0xfb,
+0x90, 0xaf, 0x26, 0x6d, 0x75, 0x91, 0xc8, 0x1f, 0x20, 0xb7, 0x18, 0xd0, 0x7d,
+0x51, 0xbf, 0xc2, 0x21, 0xb6, 0x6a, 0x25, 0x40, 0x3b, 0x4a, 0xc1, 0xa6, 0x8d,
+0x67, 0x3f, 0xdd, 0x95, 0x9b, 0x01, 0xec, 0xf3, 0xd0, 0xa7, 0xaf
+},
+.e = (unsigned char []){
+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, 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, 0x01, 0x00, 0x01
+},
+.d = (unsigned char []){
+0x40, 0xd6, 0x0f, 0x24, 0xb6, 0x1d, 0x76, 0x78, 0x3d, 0x3b, 0xb1, 0xdc, 0x00,
+0xb5, 0x5f, 0x96, 0xa2, 0xa6, 0x86, 0xf5, 0x9b, 0x37, 0x50, 0xfd, 0xb1, 0x5c,
+0x40, 0x25, 0x1c, 0x37, 0x0c, 0x65, 0xca, 0xda, 0x22, 0x26, 0x73, 0x81, 0x1b,
+0xc6, 0xb3, 0x05, 0xed, 0x7c, 0x90, 0xff, 0xcb, 0x3a, 0xbd, 0xdd, 0xc8, 0x33,
+0x66, 0x12, 0xff, 0x13, 0xb4, 0x2a, 0x75, 0xcb, 0x7c, 0x88, 0xfb, 0x93, 0x62,
+0x91, 0xb5, 0x23, 0xd8, 0x0a, 0xcc, 0xe5, 0xa0, 0x84, 0x2c, 0x72, 0x4e, 0xd8,
+0x5a, 0x13, 0x93, 0xfa, 0xf3, 0xd4, 0x70, 0xbd, 0xa8, 0x08, 0x3f, 0xa8, 0x4d,
+0xc5, 0xf3, 0x14, 0x99, 0x84, 0x4f, 0x0c, 0x7c, 0x1e, 0x93, 0xfb, 0x1f, 0x73,
+0x4a, 0x5a, 0x29, 0xfb, 0x31, 0xa3, 0x5c, 0x8a, 0x08, 0x22, 0x45, 0x5f, 0x1c,
+0x85, 0x0a, 0x49, 0xe8, 0x62, 0x97, 0x14, 0xec, 0x6a, 0x26, 0x57, 0xef, 0xe7,
+0x5e, 0xc1, 0xca, 0x6e, 0x62, 0xf9, 0xa3, 0x75, 0x6c, 0x9b, 0x20, 0xb4, 0x85,
+0x5b, 0xdc, 0x9a, 0x3a, 0xb5, 0x8c, 0x43, 0xd8, 0xaf, 0x85, 0xb8, 0x37, 0xa7,
+0xfd, 0x15, 0xaa, 0x11, 0x49, 0xc1, 0x19, 0xcf, 0xe9, 0x60, 0xc0, 0x5a, 0x9d,
+0x4c, 0xea, 0x69, 0xc9, 0xfb, 0x6a, 0x89, 0x71, 0x45, 0x67, 0x48, 0x82, 0xbf,
+0x57, 0x24, 0x1d, 0x77, 0xc0, 0x54, 0xdc, 0x4c, 0x94, 0xe8, 0x34, 0x9d, 0x37,
+0x62, 0x96, 0x13, 0x7e, 0xb4, 0x21, 0x68, 0x61, 0x59, 0xcb, 0x87, 0x8d, 0x15,
+0xd1, 0x71, 0xed, 0xa8, 0x69, 0x28, 0x34, 0xaf, 0xc8, 0x71, 0x98, 0x8f, 0x20,
+0x3f, 0xc8, 0x22, 0xc5, 0xdc, 0xee, 0x7f, 0x6c, 0x48, 0xdf, 0x66, 0x3e, 0xa3,
+0xdc, 0x75, 0x5e, 0x7d, 0xc0, 0x6a, 0xeb, 0xd4, 0x1d, 0x05, 0xf1, 0xca, 0x28,
+0x91, 0xe2, 0x67, 0x97, 0x83, 0x24, 0x4d, 0x06, 0x8f
+},
+.ciphertext = (unsigned char []){
+0x70, 0x99, 0x2c, 0x9d, 0x95, 0xa4, 0x90, 0x8d, 0x2a, 0x94, 0xb3, 0xab, 0x9f,
+0xa1, 0xcd, 0x64, 0x3f, 0x12, 0x0e, 0x32, 0x6f, 0x9d, 0x78, 0x08, 0xaf, 0x50,
+0xca, 0xc4, 0x2c, 0x4b, 0x0b, 0x4e, 0xeb, 0x7f, 0x0d, 0x4d, 0xf3, 0x03, 0xa5,
+0x68, 0xfb, 0xfb, 0x82, 0xb0, 0xf5, 0x83, 0x00, 0xd2, 0x53, 0x57, 0x64, 0x57,
+0x21, 0xbb, 0x71, 0x86, 0x1c, 0xaf, 0x81, 0xb2, 0x7a, 0x56, 0x08, 0x2c, 0x80,
+0xa1, 0x46, 0x49, 0x9f, 0xb4, 0xea, 0xb5, 0xbd, 0xe4, 0x49, 0x3f, 0x5d, 0x00,
+0xf1, 0xa4, 0x37, 0xbb, 0xc3, 0x60, 0xdf, 0xcd, 0x80, 0x56, 0xfe, 0x6b, 0xe1,
+0x0e, 0x60, 0x8a, 0xdb, 0x30, 0xb6, 0xc2, 0xf7, 0x65, 0x24, 0x28, 0xb8, 0xd3,
+0x2d, 0x36, 0x29, 0x45, 0x98, 0x2a, 0x46, 0x58, 0x5d, 0x21, 0x02, 0xef, 0x79,
+0x95, 0xa8, 0xba, 0x6e, 0x8a, 0xd8, 0xfd, 0x16, 0xbd, 0x7a, 0xe8, 0xf5, 0x3c,
+0x3d, 0x7f, 0xcf, 0xba, 0x29, 0x0b, 0x57, 0xce, 0x7f, 0x8f, 0x09, 0xc8, 0x28,
+0xd6, 0xf2, 0xd3, 0xce, 0x56, 0xf1, 0x31, 0xbd, 0x94, 0x61, 0xe5, 0x66, 0x7e,
+0x5b, 0x73, 0xed, 0xac, 0x77, 0xf5, 0x04, 0xda, 0xc4, 0xf2, 0x02, 0xa9, 0x57,
+0x0e, 0xb4, 0x51, 0x5b, 0x2b, 0xf5, 0x16, 0x40, 0x7d, 0xb8, 0x31, 0x51, 0x8d,
+0xb8, 0xa2, 0x08, 0x3e, 0xc7, 0x01, 0xe8, 0xfd, 0x38, 0x7c, 0x43, 0x0b, 0xb1,
+0xa7, 0x2d, 0xec, 0xa5, 0xb4, 0x9d, 0x42, 0x9c, 0xf9, 0xde, 0xb0, 0x9c, 0xc4,
+0x51, 0x8d, 0xc5, 0xf5, 0x7c, 0x08, 0x9a, 0xa2, 0xd3, 0x42, 0x0e, 0x56, 0x7e,
+0x73, 0x21, 0x02, 0xc2, 0xc9, 0x2b, 0x88, 0xa0, 0x7c, 0x69, 0xd7, 0x09, 0x17,
+0x14, 0x0a, 0xb3, 0x82, 0x3c, 0x63, 0xf3, 0x12, 0xd3, 0xf1, 0x1f, 0xa8, 0x7b,
+0xa2, 0x9d, 0xa3, 0xc7, 0x22, 0x4b, 0x4f, 0xb4, 0xbc
+},
+.plaintext = (unsigned char []){
+0x7e, 0x65, 0xb9, 0x98, 0xa0, 0x5f, 0x62, 0x6b, 0x02, 0x8c, 0x75, 0xdc, 0x3f,
+0xbf, 0x98, 0x96, 0x3d, 0xce, 0x66, 0xd0, 0xf4, 0xc3, 0xae, 0x42, 0x37, 0xcf,
+0xf3, 0x04, 0xd8, 0x4d, 0x88, 0x36, 0xcb, 0x6b, 0xad, 0x9a, 0xc8, 0x6f, 0x9d,
+0x1b, 0x8a, 0x28, 0xdd, 0x70, 0x40, 0x47, 0x88, 0xb8, 0x69, 0xd2, 0x42, 0x9f,
+0x1e, 0xc0, 0x66, 0x3e, 0x51, 0xb7, 0x53, 0xf7, 0x45, 0x1c, 0x6b, 0x46, 0x45,
+0xd9, 0x91, 0x26, 0xe4, 0x57, 0xc1, 0xda, 0xc4, 0x95, 0x51, 0xd8, 0x6a, 0x8a,
+0x97, 0x4a, 0x31, 0x31, 0xe9, 0xb3, 0x71, 0xd5, 0xc2, 0x14, 0xcc, 0x9f, 0xf2,
+0x40, 0xc2, 0x99, 0xbd, 0x0e, 0x62, 0xdb, 0xc7, 0xa9, 0xa2, 0xda, 0xd9, 0xfa,
+0x54, 0x04, 0xad, 0xb0, 0x06, 0x32, 0xd3, 0x63, 0x32, 0xd5, 0xbe, 0x61, 0x06,
+0xe9, 0xe6, 0xec, 0x81, 0xca, 0xc4, 0x5c, 0xd3, 0x39, 0xcc, 0x87, 0xab, 0xbe,
+0x7f, 0x89, 0x43, 0x08, 0x00, 0xe1, 0x6e, 0x03, 0x2a, 0x66, 0x21, 0x0b, 0x25,
+0xe9, 0x26, 0xed, 0xa2, 0x43, 0xd9, 0xf0, 0x99, 0x55, 0x49, 0x6d, 0xdb, 0xc7,
+0x7e, 0xf7, 0x4f, 0x17, 0xfe, 0xe4, 0x1c, 0x44, 0x35, 0xe7, 0x8b, 0x46, 0x96,
+0x5b, 0x71, 0x3d, 0x72, 0xce, 0x8a, 0x31, 0xaf, 0x64, 0x15, 0x38, 0xad, 0xd3,
+0x87, 0xfe, 0xdf, 0xd8, 0x8b, 0xb2, 0x2a, 0x42, 0xeb, 0x3b, 0xda, 0x40, 0xf7,
+0x2e, 0xca, 0xd9, 0x41, 0xdb, 0xff, 0xdd, 0x47, 0xb3, 0xe7, 0x77, 0x37, 0xda,
+0x74, 0x15, 0x53, 0xa4, 0x5b, 0x63, 0x0d, 0x07, 0x0b, 0xcc, 0x52, 0x05, 0x80,
+0x4b, 0xf8, 0x0e, 0xe2, 0xd5, 0x16, 0x12, 0x87, 0x5d, 0xbc, 0x47, 0x96, 0x96,
+0x00, 0x52, 0xf1, 0x68, 0x7e, 0x00, 0x74, 0x00, 0x7e, 0x6a, 0x33, 0xab, 0x8b,
+0x20, 0x85, 0xc0, 0x33, 0xf9, 0x89, 0x2b, 0x6f, 0x74
+},
+.mod = 2048,
+.dq = (unsigned char []){
+0xCB, 0x5B, 0x75, 0x8E, 0x65, 0x25, 0xB3, 0x1C, 0x04, 0x67, 0x22, 0xB5, 0x9E,
+0x10, 0x6A, 0xA9, 0x65, 0x65, 0xF9, 0x8E, 0xCF, 0xF8, 0xF5, 0xCC, 0x47, 0xB4,
+0x8A, 0x68, 0x24, 0xF7, 0xEB, 0x55, 0x30, 0xD2, 0x1D, 0x71, 0xF1, 0x37, 0xBB,
+0xD6, 0xE8, 0x1A, 0xE1, 0x45, 0x56, 0x1F, 0x43, 0x74, 0x4B, 0x9C, 0x45, 0x53,
+0xF1, 0xFD, 0x08, 0x4E, 0x0D, 0xA4, 0xD2, 0x31, 0x46, 0x24, 0x8D, 0x45, 0x49,
+0xEE, 0xA4, 0x0E, 0x1B, 0xFC, 0x7B, 0x54, 0x23, 0xE0, 0xF5, 0x7B, 0xE2, 0xEE,
+0x53, 0xD4, 0xC7, 0xB6, 0xBB, 0xE1, 0x5A, 0xF1, 0x79, 0xB0, 0x04, 0x2F, 0x68,
+0xD5, 0xB2, 0x88, 0x20, 0xA0, 0x19, 0xC8, 0x2C, 0x45, 0x45, 0xAD, 0x82, 0xEB,
+0xBE, 0xC1, 0x49, 0x45, 0x88, 0x4D, 0x1B, 0xE1, 0x2D, 0x8E, 0x03, 0x43, 0x6D,
+0x60, 0x30, 0x24, 0xE4, 0xE8, 0x1B, 0x01, 0xB7, 0x58, 0x0F, 0xA9
+},
+.dp = (unsigned char []){
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8 bytes zero padding */
+0x7A, 0x54, 0x57, 0x5B, 0x8A, 0x86, 0x55, 0x18, 0x23, 0xB7, 0x7B, 0x64, 0x0C,
+0x2B, 0xCF, 0x93, 0x09, 0xE5, 0x58, 0x97, 0xD1, 0x11, 0xF5, 0x7E, 0xA8, 0xFD,
+0xE2, 0xC6, 0x32, 0xCC, 0x41, 0xDD, 0xFF, 0x74, 0x81, 0x92, 0x7C, 0x07, 0xC5,
+0x04, 0xBF, 0xB4, 0x3D, 0xB6, 0xA1, 0x4F, 0x1F, 0x21, 0xA5, 0xAC, 0x8D, 0x71,
+0xFC, 0x73, 0x41, 0x48, 0x3F, 0xF9, 0xCE, 0x2D, 0x4E, 0xD7, 0xEE, 0x94, 0x67,
+0xC7, 0x49, 0x23, 0xED, 0x35, 0x1A, 0x34, 0xC2, 0xC0, 0x83, 0x70, 0x93, 0xF2,
+0x07, 0x77, 0xC1, 0x2A, 0x6E, 0xC5, 0x7E, 0x82, 0xED, 0xD5, 0x26, 0xBB, 0x14,
+0x17, 0x20, 0x9E, 0xBA, 0x2F, 0x59, 0x7E, 0x21, 0x50, 0x24, 0x08, 0x2C, 0xD2,
+0xEF, 0xFB, 0xB5, 0xD7, 0xC2, 0x16, 0x5E, 0x6D, 0x3A, 0x2F, 0x19, 0x86, 0xB3,
+0xA1, 0x1D, 0x60, 0x25, 0xD3, 0x0E, 0x96, 0xE2, 0x57, 0x9F, 0xC9
+},
+.qinv = (unsigned char []){
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8 bytes zero padding */
+0x17, 0x2B, 0xDA, 0x79, 0xDE, 0x9F, 0xEE, 0x37, 0x61, 0xA3, 0x49, 0xC9, 0x4D,
+0x28, 0xA0, 0x24, 0x03, 0xB6, 0x0A, 0xDE, 0x88, 0xC9, 0x26, 0xEB, 0xC6, 0xAF,
+0x46, 0x49, 0xBE, 0x73, 0x33, 0x30, 0x72, 0xAB, 0xFE, 0x7B, 0x3E, 0xE4, 0x4C,
+0xAF, 0xA9, 0x0C, 0xD0, 0xF7, 0x61, 0xFC, 0xCE, 0x20, 0x35, 0xE5, 0x2E, 0x53,
+0x9B, 0x05, 0x29, 0x3C, 0xAC, 0x05, 0x63, 0xED, 0x32, 0x93, 0xB3, 0x9D, 0xB8,
+0x9D, 0x53, 0x5E, 0xB8, 0xC5, 0xDE, 0xC9, 0xEF, 0x6B, 0x2F, 0x1D, 0x94, 0x1B,
+0x2F, 0xE9, 0xB4, 0x8A, 0xE6, 0xCA, 0x15, 0xCA, 0xC7, 0x08, 0xDA, 0x35, 0xD2,
+0xBA, 0x6F, 0x33, 0x31, 0x18, 0x1C, 0xE8, 0x46, 0xED, 0x6D, 0xFA, 0xEF, 0xE5,
+0x57, 0x6A, 0x65, 0x01, 0x9C, 0xD7, 0xF7, 0x04, 0xB3, 0xFF, 0xA5, 0x94, 0xCF,
+0x41, 0x8B, 0x14, 0xCA, 0x62, 0x02, 0xD0, 0x9E, 0x22, 0x60, 0xE4
+},
+},
+};
+
+const struct des3_ctr_tv DES3_CTR_TV[] = {
+{
+.len = 64,
+.key = {
+0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80,
+0x90, 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
+},
+.ctr = {
+0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+},
+.plaintext = (unsigned char []){
+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
+},
+.ciphertext = (unsigned char []){
+0x17, 0x4d, 0xdf, 0xde, 0x7b, 0xe0, 0x2f, 0xb7, 0x58, 0x49, 0x76, 0xe5, 0x80,
+0xbd, 0x49, 0x45, 0x64, 0x3a, 0xe4, 0x42, 0xfe, 0x4c, 0x25, 0xd4, 0x79, 0x74,
+0xf0, 0xe6, 0x0b, 0x3d, 0x20, 0xac, 0x04, 0x42, 0xe1, 0x00, 0xe8, 0xd0, 0x35,
+0x18, 0xad, 0xf6, 0x44, 0x23, 0x4b, 0xb7, 0x05, 0xf7, 0xf8, 0x3a, 0xf7, 0x9a,
+0x8b, 0x62, 0x46, 0x3c, 0x2c, 0xaa, 0x45, 0x77, 0xbe, 0xab, 0x94, 0x80
+},
+},
+};
+
+const struct aes_ctr_tv AES_CTR_TV[] = {
+{
+.keylen = AES128_KEYLEN,
+.len = 64,
+.key = (unsigned char []){
+0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09,
+0xcf, 0x4f, 0x3c
+},
+.ctr = {
+0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc,
+0xfd, 0xfe, 0xff
+},
+.plaintext = (unsigned char []){
+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
+},
+.ciphertext = (unsigned char []){
+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, 0x5a, 0xe4, 0xdf, 0x3e, 0xdb, 0xd5, 0xd3,
+0x5e, 0x5b, 0x4f, 0x09, 0x02, 0x0d, 0xb0, 0x3e, 0xab, 0x1e, 0x03, 0x1d, 0xda,
+0x2f, 0xbe, 0x03, 0xd1, 0x79, 0x21, 0x70, 0xa0, 0xf3, 0x00, 0x9c, 0xee
+},
+},
+{
+.keylen = AES192_KEYLEN,
+.len = 64,
+.key = (unsigned char []){
+0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80,
+0x90, 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b
+},
+.ctr = {
+0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc,
+0xfd, 0xfe, 0xff
+},
+.plaintext = (unsigned char []){
+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
+},
+.ciphertext = (unsigned char []){
+0x1a, 0xbc, 0x93, 0x24, 0x17, 0x52, 0x1c, 0xa2, 0x4f, 0x2b, 0x04, 0x59, 0xfe,
+0x7e, 0x6e, 0x0b, 0x09, 0x03, 0x39, 0xec, 0x0a, 0xa6, 0xfa, 0xef, 0xd5, 0xcc,
+0xc2, 0xc6, 0xf4, 0xce, 0x8e, 0x94, 0x1e, 0x36, 0xb2, 0x6b, 0xd1, 0xeb, 0xc6,
+0x70, 0xd1, 0xbd, 0x1d, 0x66, 0x56, 0x20, 0xab, 0xf7, 0x4f, 0x78, 0xa7, 0xf6,
+0xd2, 0x98, 0x09, 0x58, 0x5a, 0x97, 0xda, 0xec, 0x58, 0xc6, 0xb0, 0x50
+},
+},
+{
+.keylen = AES256_KEYLEN,
+.len = 64,
+.key = (unsigned char []){
+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
+},
+.ctr = {
+0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc,
+0xfd, 0xfe, 0xff
+},
+.plaintext = (unsigned char []){
+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
+},
+.ciphertext = (unsigned char []){
+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
+},
+},
+};
+
+const struct des3_cmac_tv DES3_CMAC_TV[] = {
+{
+.msglen = 32,
+.maclen = 8,
+.key = {
+0x37, 0xea, 0xe9, 0x8f, 0xf4, 0x2a, 0xfb, 0x25, 0xf2, 0x23, 0x1c, 0x02, 0x8c,
+0x29, 0xda, 0x9d, 0xef, 0x3d, 0xa8, 0xd0, 0xc7, 0x7f, 0xbf, 0x45
+},
+.msg = (unsigned char []){
+0xf2, 0x66, 0xce, 0xc0, 0x1c, 0x5f, 0xc0, 0x8c, 0x0b, 0xda, 0xbc, 0x95, 0x37,
+0xbd, 0x1a, 0xa2, 0xdf, 0x9f, 0x2b, 0x8f, 0xfb, 0xe5, 0xcc, 0x94, 0x72, 0x2a,
+0x3b, 0xca, 0x8d, 0xe5, 0x29, 0xea
+},
+.mac = (unsigned char []){
+0xb3, 0x80, 0x9c, 0x8b, 0x0e, 0xb9, 0xdd, 0x8d
+},
+.rv = 0,
+},
+{
+.msglen = 32,
+.maclen = 8,
+.key = {
+0x13, 0x58, 0xfb, 0x67, 0x15, 0x5e, 0x01, 0x45, 0xd0, 0x2c, 0x54, 0xa1, 0x20,
+0x6b, 0x5d, 0x7f, 0x1c, 0x04, 0xba, 0x46, 0xc7, 0x4a, 0x5d, 0x49
+},
+.msg = (unsigned char []){
+0xe3, 0x8b, 0x4c, 0x3e, 0x7a, 0x82, 0x64, 0x3b, 0xeb, 0x31, 0x92, 0x42, 0x65,
+0x55, 0xad, 0x9c, 0x9b, 0x26, 0x20, 0xd6, 0x77, 0x37, 0x3f, 0xc4, 0x0c, 0x9d,
+0xdb, 0xc4, 0xcd, 0x53, 0x13, 0x47
+},
+.mac = (unsigned char []){
+0xb0, 0x00, 0xe2, 0xea, 0x1e, 0xf4, 0x8a, 0x8f
+},
+.rv = EFAULT,
+},
+};
+
+const struct aes_cmac_tv AES_CMAC_TV[] = {
+{
+.keylen = AES128_KEYLEN,
+.msglen = 65,
+.maclen = 16,
+.key = (unsigned char []){
+0xd1, 0x49, 0x44, 0x1e, 0x66, 0x7b, 0x24, 0x5d, 0x46, 0x40, 0xe0, 0x4c, 0x53,
+0xca, 0x6f, 0x51
+},
+.msg = (unsigned char []){
+0xcb, 0xb3, 0x47, 0x94, 0xbc, 0x8b, 0xfd, 0xf9, 0x3d, 0x3c, 0x8d, 0x9f, 0x87,
+0xec, 0x14, 0x82, 0xb5, 0x16, 0xb4, 0x8b, 0x1e, 0x8a, 0x89, 0xb5, 0xe3, 0xb5,
+0xdf, 0x70, 0xc4, 0x23, 0xa2, 0x43, 0x38, 0x42, 0x15, 0xb4, 0xbc, 0x69, 0xc7,
+0x6c, 0x6b, 0x18, 0xc4, 0x97, 0xcf, 0x82, 0x08, 0x8a, 0xf7, 0x48, 0x39, 0xa8,
+0xc9, 0x88, 0x95, 0x86, 0x9a, 0x16, 0x29, 0x4d, 0xfc, 0x09, 0x43, 0x60, 0xd7
+},
+.mac = (unsigned char []){
+0x64, 0xf5, 0xe8, 0xdc, 0xe5, 0xc3, 0xe0, 0xf9, 0xcc, 0x22, 0x4e, 0x30, 0x6d,
+0xe7, 0x0b, 0x87
+},
+.rv = 0,
+},
+{
+.keylen = AES128_KEYLEN,
+.msglen = 65,
+.maclen = 16,
+.key = (unsigned char []){
+0xc2, 0xf5, 0xd4, 0x83, 0x7f, 0x9f, 0x75, 0xfb, 0x44, 0x0c, 0x3b, 0xcc, 0xad,
+0x7c, 0x2e, 0x69
+},
+.msg = (unsigned char []){
+0x6a, 0x84, 0x59, 0x4c, 0x4b, 0x38, 0x65, 0xf0, 0x47, 0xc9, 0x60, 0x38, 0x06,
+0x0b, 0x5b, 0x41, 0x3d, 0xb0, 0xd4, 0xe0, 0x81, 0xc6, 0x2e, 0x40, 0x5b, 0x81,
+0x5e, 0xcd, 0x9e, 0x3b, 0xe6, 0x51, 0xf8, 0xb9, 0x07, 0x5d, 0xc8, 0xb0, 0x32,
+0xeb, 0x2f, 0x87, 0xc1, 0x41, 0x6a, 0x5f, 0xe4, 0x19, 0x5f, 0x51, 0xde, 0xfe,
+0x75, 0xf6, 0x71, 0xf9, 0xa9, 0x2d, 0x96, 0x6d, 0xdf, 0x18, 0x72, 0x40, 0x75
+},
+.mac = (unsigned char []){
+0xdf, 0x8c, 0x8c, 0x61, 0xe8, 0xd6, 0x04, 0xe2, 0x4c, 0x7e, 0x3d, 0x01, 0x15,
+0xdb, 0xe8, 0x98
+},
+.rv = EFAULT,
+},
+{
+.keylen = AES192_KEYLEN,
+.msglen = 64,
+.maclen = 8,
+.key = (unsigned char []){
+0x20, 0xd2, 0x2c, 0x3b, 0x6a, 0xb3, 0x8c, 0x59, 0x95, 0xe2, 0x2b, 0x34, 0x1f,
+0x35, 0x9b, 0xe2, 0x56, 0x16, 0xb2, 0xb8, 0xc7, 0x26, 0x95, 0x10
+},
+.msg = (unsigned char []){
+0xa1, 0xc0, 0x41, 0xd1, 0xd4, 0xe7, 0xcd, 0x6a, 0x95, 0x3f, 0x2e, 0x48, 0x37,
+0xe3, 0xe6, 0x76, 0xed, 0x48, 0x63, 0x3a, 0x2f, 0x15, 0x82, 0x8f, 0x5f, 0x35,
+0x51, 0xd5, 0xad, 0x2a, 0x19, 0xc8, 0x38, 0xa4, 0x9c, 0xaf, 0x75, 0x52, 0x9b,
+0xd5, 0xd5, 0xf8, 0x9b, 0x3d, 0xa2, 0xc2, 0xe9, 0x92, 0x2a, 0xd8, 0xdc, 0x5d,
+0x20, 0x32, 0x5a, 0x7b, 0x3f, 0xae, 0x9d, 0xcd, 0x30, 0x5f, 0x37, 0x31
+},
+.mac = (unsigned char []){
+0xaa, 0xc4, 0xd4, 0xf4, 0x17, 0x2e, 0x1f, 0x05
+},
+.rv = 0,
+},
+{
+.keylen = AES192_KEYLEN,
+.msglen = 64,
+.maclen = 8,
+.key = (unsigned char []){
+0x22, 0xe2, 0x9a, 0xa7, 0x54, 0x7e, 0x5e, 0xd3, 0xa6, 0x46, 0x11, 0xe0, 0x4f,
+0x1d, 0x55, 0xf7, 0xa3, 0x97, 0xc1, 0x61, 0x96, 0x69, 0x87, 0x9c
+},
+.msg = (unsigned char []){
+0x77, 0x3b, 0x57, 0x7b, 0x95, 0xe2, 0x9d, 0x36, 0xfb, 0x30, 0x77, 0x9d, 0x2e,
+0xa2, 0x3e, 0x2f, 0xfe, 0xd9, 0xe1, 0xb4, 0x6a, 0xed, 0xe4, 0x2b, 0xbe, 0x03,
+0xa9, 0x04, 0xfe, 0x22, 0xef, 0x8f, 0x87, 0x42, 0x98, 0xb5, 0xf4, 0xa6, 0xaf,
+0xe6, 0x3f, 0x6c, 0xa9, 0x52, 0x28, 0x63, 0xeb, 0x5c, 0xdb, 0x1c, 0x8d, 0x4b,
+0xcd, 0x44, 0x5e, 0x43, 0xe7, 0x30, 0x28, 0x75, 0xe6, 0xba, 0x35, 0x92
+},
+.mac = (unsigned char []){
+0x16, 0xbf, 0x98, 0xc7, 0xa5, 0xde, 0xff, 0x18
+},
+.rv = EFAULT,
+},
+{
+.keylen = AES256_KEYLEN,
+.msglen = 64,
+.maclen = 8,
+.key = (unsigned char []){
+0xf7, 0x0b, 0x8a, 0x4e, 0xee, 0x35, 0x18, 0xbb, 0xa0, 0x71, 0xaf, 0x55, 0xf2,
+0x5f, 0x7b, 0x69, 0x8a, 0x5b, 0x7d, 0xc8, 0x86, 0x5c, 0xda, 0xca, 0x6d, 0x1c,
+0x79, 0x93, 0x65, 0x7a, 0xcc, 0x95
+},
+.msg = (unsigned char []){
+0x79, 0x5e, 0xe1, 0xaf, 0x75, 0x04, 0x62, 0x1a, 0xac, 0x32, 0x9f, 0x50, 0x81,
+0x91, 0x2d, 0xe5, 0x45, 0xfa, 0x11, 0x17, 0x4f, 0x39, 0x79, 0xb1, 0x4f, 0x11,
+0xaa, 0x30, 0xdf, 0x81, 0x3a, 0x23, 0x5b, 0x46, 0x7f, 0xd8, 0xf3, 0xa1, 0x47,
+0x34, 0xfe, 0x5a, 0xc9, 0xe3, 0x91, 0x05, 0xdc, 0xb2, 0x51, 0x84, 0x67, 0x38,
+0x85, 0xcd, 0x19, 0xbc, 0x70, 0xee, 0x5a, 0x53, 0xdd, 0x4e, 0x81, 0x49
+},
+.mac = (unsigned char []){
+0x93, 0x54, 0x27, 0x34, 0xd6, 0xcd, 0x43, 0xde
+},
+.rv = 0,
+},
+{
+.keylen = AES256_KEYLEN,
+.msglen = 64,
+.maclen = 8,
+.key = (unsigned char []){
+0x0c, 0x45, 0x6d, 0x19, 0x9a, 0xba, 0xe4, 0x75, 0x87, 0x34, 0xf5, 0x06, 0xc4,
+0xe9, 0xcc, 0xdb, 0x76, 0x7e, 0x4f, 0xd1, 0x56, 0xd5, 0xa4, 0x08, 0x57, 0x26,
+0xf3, 0x93, 0x8a, 0x51, 0x6d, 0x74
+},
+.msg = (unsigned char []){
+0x78, 0xf3, 0xbf, 0x56, 0x8f, 0x1c, 0x3f, 0x28, 0x66, 0xef, 0xf8, 0xa2, 0x46,
+0xa7, 0x0c, 0xf0, 0xfa, 0xee, 0x4c, 0x30, 0x78, 0xf3, 0xfb, 0x27, 0xc4, 0xbd,
+0xd5, 0x33, 0x12, 0xbf, 0x50, 0x81, 0x2b, 0xac, 0x22, 0x80, 0x11, 0x8c, 0x03,
+0x96, 0xe6, 0x10, 0xb4, 0x11, 0x0a, 0x22, 0x40, 0x60, 0x84, 0xc1, 0x82, 0x83,
+0xa3, 0x0c, 0xe7, 0xc0, 0xe4, 0x9c, 0x76, 0x98, 0x17, 0x17, 0x0d, 0xf9
+},
+.mac = (unsigned char []){
+0xc4, 0xc5, 0xbe, 0x3c, 0x94, 0xfb, 0x7b, 0x9c
+},
+.rv = EFAULT,
+},
+};
+
+const struct aes_xts_tv AES_XTS_TV[] = {
+{
+.len = 256 / 8,
+.keylen = AES128_KEYLEN,
+.key1 = (unsigned char []){
+0x78, 0x3a, 0x83, 0xec, 0x52, 0xa2, 0x74, 0x05, 0xdf, 0xf9, 0xde, 0x4c, 0x57,
+0xf9, 0xc9, 0x79
+},
+.key2 = (unsigned char []){
+0xb3, 0x60, 0xb6, 0xa5, 0xdf, 0x88, 0xd6, 0x7e, 0xc1, 0xa0, 0x52, 0xe6, 0xf5,
+0x82, 0xa7, 0x17
+},
+.tweak = {
+0x88, 0x6e, 0x97, 0x5b, 0x29, 0xbd, 0xf6, 0xf0, 0xc0, 0x1b, 0xb4, 0x7f, 0x61,
+0xf6, 0xf0, 0xf5
+},
+.plaintext = (unsigned char []){
+0xb0, 0x4d, 0x84, 0xda, 0x85, 0x6b, 0x9a, 0x59, 0xce, 0x2d, 0x62, 0x67, 0x46,
+0xf6, 0x89, 0xa8, 0x05, 0x1d, 0xac, 0xd6, 0xbc, 0xe3, 0xb9, 0x90, 0xaa, 0x90,
+0x1e, 0x40, 0x30, 0x64, 0x88, 0x79
+},
+.ciphertext = (unsigned char []){
+0xf9, 0x41, 0x03, 0x9e, 0xba, 0xb8, 0xca, 0xc3, 0x9d, 0x59, 0x24, 0x7c, 0xbb,
+0xcb, 0x4d, 0x81, 0x6c, 0x72, 0x6d, 0xae, 0xd1, 0x15, 0x77, 0x69, 0x2c, 0x55,
+0xe4, 0xac, 0x6d, 0x3e, 0x68, 0x20
+},
+},
+{
+.len = 384 / 8,
+.keylen = AES256_KEYLEN,
+.key1 = (unsigned char []){
+0x7f, 0xb0, 0x92, 0x2f, 0xce, 0x09, 0xed, 0xdd, 0x36, 0x65, 0xa1, 0x1f, 0x52,
+0x35, 0xd5, 0x1e, 0xf7, 0x72, 0x06, 0xa7, 0xde, 0x45, 0x47, 0x75, 0xb6, 0x9d,
+0xcc, 0x54, 0x59, 0xac, 0xdb, 0x24
+},
+.key2 = (unsigned char []){
+0xcc, 0xf0, 0x5c, 0x41, 0x5a, 0xf5, 0xab, 0x8a, 0x06, 0x62, 0x3d, 0x19, 0x8d,
+0x5b, 0x91, 0x85, 0x95, 0xa9, 0xdc, 0xaa, 0xf5, 0x39, 0x2e, 0xe7, 0x17, 0xc1,
+0x04, 0x7f, 0x2f, 0x08, 0xf6, 0x2b
+},
+.tweak = {
+0x8e, 0xa3, 0x63, 0x8b, 0x9d, 0x40, 0x62, 0xf1, 0x69, 0x19, 0x6f, 0xf4, 0x55,
+0x5a, 0xd0, 0xaf
+},
+.plaintext = (unsigned char []){
+0xbb, 0xb2, 0x34, 0xdb, 0x01, 0xbe, 0x79, 0xd3, 0xdc, 0x7d, 0xcf, 0x49, 0xbc,
+0x53, 0xb8, 0xef, 0xc6, 0x2f, 0xe7, 0x17, 0x94, 0x39, 0x06, 0x1d, 0x73, 0xa6,
+0xb2, 0x0e, 0xdb, 0x9b, 0x7d, 0xa0, 0x45, 0x0b, 0x19, 0xf0, 0x20, 0x82, 0x02,
+0x09, 0xaf, 0xe0, 0x81, 0x12, 0xae, 0x4a, 0xfd, 0xd3
+},
+.ciphertext = (unsigned char []){
+0xcb, 0xf6, 0x88, 0x48, 0xc4, 0x20, 0x49, 0xef, 0xb1, 0x46, 0xe2, 0xd1, 0xe4,
+0x11, 0x5f, 0x62, 0xe4, 0xfa, 0xa4, 0xef, 0xff, 0x19, 0x8f, 0x1a, 0x0a, 0xa0,
+0xc9, 0x8b, 0xa0, 0x2c, 0xc4, 0x4d, 0xa3, 0x76, 0xd7, 0x62, 0xd6, 0x15, 0x1f,
+0x23, 0x45, 0x87, 0xbf, 0x12, 0x8b, 0x6a, 0x7f, 0xfa
+},
+},
+};
+const struct aes_gcm_tv AES_GCM_TV[] = {
+{
+.keylen = AES128_KEYLEN,
+.ivlen = 1024 / 8,
+.len = 408 / 8,
+.aadlen = 720 / 8,
+.taglen = 32 / 8,
+.key = (unsigned char []){
+0x73, 0xa0, 0xf9, 0xc5, 0xd2, 0x70, 0xf6, 0xcf, 0x41, 0xae, 0x23, 0x1c, 0x4f,
+0x5a, 0x8c, 0x66
+},
+.iv = (unsigned char []){
+0xf7, 0x32, 0xde, 0x5e, 0xcb, 0x76, 0x90, 0xd7, 0x25, 0xad, 0x2a, 0xdd, 0x4c,
+0x6d, 0x22, 0xc6, 0x79, 0x74, 0xfd, 0x3b, 0x73, 0x5a, 0x58, 0xf8, 0x5c, 0x2a,
+0x4e, 0x03, 0x10, 0x6d, 0xf2, 0x4e, 0x80, 0xaa, 0x85, 0x3f, 0x7c, 0x12, 0xbd,
+0xaa, 0xe2, 0x73, 0x80, 0xb3, 0x44, 0x55, 0xb0, 0xfd, 0x14, 0x98, 0x63, 0xb6,
+0xb0, 0x62, 0xcc, 0xe5, 0x7b, 0x9b, 0xaf, 0x74, 0x95, 0x1a, 0x10, 0xa3, 0x5a,
+0xec, 0x7e, 0x00, 0xf5, 0xc3, 0x81, 0xfe, 0x18, 0x73, 0xdf, 0x48, 0xe6, 0x72,
+0x6e, 0x11, 0x85, 0xe3, 0xc9, 0x06, 0xb5, 0x42, 0xf1, 0x3d, 0x60, 0x9d, 0xab,
+0x9c, 0xc4, 0xfc, 0xf9, 0xfc, 0xfb, 0xb0, 0x73, 0x11, 0x3d, 0xcd, 0xa0, 0x37,
+0x5d, 0xc5, 0x9b, 0x2c, 0x92, 0x88, 0x8c, 0x80, 0x1a, 0x34, 0x8a, 0x79, 0x72,
+0x87, 0xca, 0x13, 0xca, 0x73, 0xfc, 0x88, 0x27, 0xda, 0x0e, 0x39
+},
+.plaintext = NULL,
+.aad = (unsigned char []){
+0x28, 0x7a, 0x84, 0xad, 0xae, 0x06, 0x17, 0xde, 0x9d, 0xf7, 0x55, 0x2f, 0xd1,
+0x18, 0xde, 0x05, 0x6b, 0x17, 0xf5, 0xe5, 0x75, 0x20, 0x39, 0x48, 0xf8, 0xae,
+0x11, 0x0e, 0xce, 0x97, 0xb2, 0x1b, 0x09, 0xfd, 0xf0, 0x82, 0xba, 0x30, 0x23,
+0x63, 0x7e, 0x29, 0x97, 0x30, 0x29, 0x08, 0xd8, 0x83, 0x0a, 0xf5, 0x8c, 0x4d,
+0xd0, 0x9d, 0xc0, 0x76, 0x78, 0xc1, 0xc0, 0xde, 0x31, 0x16, 0x73, 0x8c, 0x20,
+0x86, 0x4f, 0xb2, 0x0c, 0xb3, 0xae, 0xe1, 0xfc, 0x65, 0x7d, 0x94, 0xfc, 0xda,
+0x10, 0xa2, 0x47, 0xe8, 0x9f, 0x98, 0x99, 0x26, 0x57, 0xb6, 0xee, 0xdf
+},
+.tag = (unsigned char []){
+0x73, 0x9f, 0xf5, 0x69
+},
+.ciphertext = (unsigned char []){
+0xdb, 0x7c, 0x4e, 0x60, 0x6d, 0xb6, 0xe3, 0xbc, 0x14, 0x7a, 0x9e, 0xec, 0xfc,
+0x76, 0x18, 0x2e, 0x66, 0xdd, 0xaa, 0x8e, 0xdb, 0x21, 0x5a, 0x97, 0x9d, 0x58,
+0x2c, 0xfc, 0xc8, 0xb0, 0x28, 0x6b, 0x73, 0xdb, 0x6c, 0xbb, 0x18, 0x28, 0x1c,
+0xb4, 0xa7, 0x62, 0xd0, 0x32, 0xad, 0x1c, 0x80, 0x16, 0xce, 0xa9, 0x2a
+},
+.rv = EFAULT,
+},
+{
+.keylen = AES128_KEYLEN,
+.ivlen = 1024 / 8,
+.len = 408 / 8,
+.aadlen = 720 / 8,
+.taglen = 32 / 8,
+.key = (unsigned char []){
+0x39, 0xe0, 0xf6, 0xf4, 0x21, 0x8c, 0x54, 0x81, 0x71, 0xfa, 0xb2, 0x72, 0xdf,
+0xe0, 0x65, 0x03
+},
+.iv = (unsigned char []){
+0xe3, 0x90, 0x6e, 0x24, 0x83, 0x91, 0x1f, 0xc3, 0x4d, 0xf8, 0x59, 0xed, 0x45,
+0x70, 0xe6, 0x7c, 0x2b, 0xf6, 0x15, 0x83, 0xa9, 0xd3, 0xbe, 0xb7, 0x57, 0x1d,
+0xaa, 0x78, 0xd2, 0x5f, 0x26, 0xd1, 0xda, 0xe0, 0xad, 0xfe, 0x47, 0xb4, 0xad,
+0x15, 0x6b, 0x73, 0x29, 0x2c, 0xe9, 0x04, 0xc5, 0xab, 0xa4, 0x22, 0x31, 0xec,
+0x6b, 0xad, 0x86, 0x4a, 0x51, 0x32, 0x86, 0xac, 0xcd, 0xac, 0x7a, 0xaa, 0xea,
+0x2c, 0xc5, 0x6b, 0x8f, 0x35, 0xd7, 0x91, 0x0c, 0x5c, 0xa8, 0x0e, 0x0d, 0xb9,
+0xd5, 0xca, 0x57, 0x88, 0x78, 0x20, 0x88, 0x65, 0x28, 0x7f, 0x7b, 0x60, 0x61,
+0xc1, 0x1d, 0x14, 0x6d, 0x95, 0x23, 0x28, 0x04, 0xca, 0x35, 0xd5, 0x6e, 0xad,
+0x4d, 0xa5, 0xdd, 0x95, 0x0a, 0x16, 0xda, 0xf4, 0xcc, 0x22, 0x13, 0xe2, 0x5f,
+0xe0, 0x14, 0x4a, 0x2a, 0xa9, 0x35, 0x73, 0xce, 0x22, 0xe1, 0x6b
+},
+.plaintext = (unsigned char []) {
+0x4d, 0x81, 0x76, 0x44, 0x79, 0x42, 0x4b, 0xb7, 0xff, 0x0b, 0x36, 0x1f, 0x2f,
+0xef, 0x8d, 0x0e, 0xcc, 0x47, 0xe7, 0xed, 0xdc, 0x4b, 0x98, 0xe7, 0xb3, 0xb6,
+0x58, 0x19, 0x26, 0x93, 0x9c, 0x5c, 0xea, 0x8f, 0x58, 0xa6, 0x17, 0x57, 0x74,
+0xd4, 0x7e, 0xdf, 0xe4, 0xb8, 0xf3, 0xa6, 0xc0, 0xb9, 0x3b, 0x56, 0x53
+},
+.aad = (unsigned char []){
+0xbf, 0xb9, 0x37, 0x07, 0x39, 0xdc, 0x3d, 0x0c, 0x5c, 0xc1, 0x68, 0x25, 0xa8,
+0xd9, 0x9d, 0x03, 0x69, 0xc3, 0x4c, 0x4b, 0xf0, 0x46, 0x18, 0x33, 0xe3, 0x4d,
+0xf8, 0x1a, 0xb3, 0xff, 0xa0, 0xbf, 0x3f, 0x8f, 0xf8, 0xb5, 0xbc, 0xd3, 0x4c,
+0x3a, 0xc8, 0xb6, 0xf1, 0xff, 0x35, 0x44, 0x28, 0x24, 0x1a, 0xd7, 0x03, 0x25,
+0x34, 0xa3, 0x76, 0x1e, 0x05, 0xae, 0xb6, 0x8c, 0x2b, 0xa0, 0x0f, 0xf6, 0x3f,
+0x27, 0xe6, 0x40, 0xf0, 0x01, 0xb6, 0xe7, 0x4e, 0xc9, 0x46, 0xc5, 0x60, 0xf2,
+0xcb, 0x17, 0x14, 0xbb, 0x3a, 0xc9, 0x8b, 0xff, 0xc9, 0x92, 0xd6, 0xa2
+},
+.tag = (unsigned char []){
+0x36, 0x2e, 0x23, 0x7d
+},
+.ciphertext = (unsigned char []){
+0x3c, 0xaf, 0x65, 0xe4, 0xb9, 0x77, 0x3c, 0xee, 0x60, 0xbb, 0x85, 0xf6, 0xc5,
+0xa4, 0x4b, 0xeb, 0x7d, 0xd3, 0xdc, 0xb3, 0x35, 0x12, 0xd5, 0x52, 0x48, 0x18,
+0x4d, 0x6b, 0x72, 0xc9, 0x80, 0x38, 0xb3, 0xbc, 0xae, 0x17, 0xbe, 0x58, 0xd1,
+0x49, 0x28, 0xe6, 0xbb, 0xa9, 0xbf, 0x92, 0x9d, 0x34, 0xf1, 0x0f, 0xfe
+},
+.rv = 0,
+},
+{
+.keylen = AES192_KEYLEN,
+.ivlen = 1024 / 8,
+.len = 408 / 8,
+.aadlen = 720 / 8,
+.taglen = 32 / 8,
+.key = (unsigned char []){
+0xd0, 0x98, 0xb5, 0x67, 0xfa, 0x48, 0x22, 0x5c, 0xbe, 0x27, 0xdb, 0x9f, 0x89,
+0xb4, 0xc0, 0x66, 0x57, 0xad, 0xf9, 0x77, 0x3a, 0x3e, 0xa9, 0x60
+},
+.iv = (unsigned char []){
+0xaf, 0xd3, 0xda, 0x93, 0x10, 0x20, 0x56, 0xe7, 0x6b, 0x72, 0x82, 0x68, 0x51,
+0x95, 0x9c, 0x06, 0xb5, 0x8a, 0x74, 0x33, 0x5f, 0x0a, 0x26, 0x4a, 0x7b, 0x24,
+0xc7, 0x3f, 0x25, 0x5d, 0xb8, 0x73, 0x8b, 0xc6, 0xbd, 0x00, 0x42, 0xaf, 0x16,
+0xe6, 0x1e, 0xbb, 0x64, 0x18, 0x6a, 0x88, 0xf5, 0xdc, 0xb7, 0x40, 0xfb, 0xe5,
+0xeb, 0x4c, 0xb9, 0x13, 0xc4, 0xf2, 0xb9, 0x8b, 0x47, 0x24, 0x0c, 0x04, 0xde,
+0x7c, 0x8c, 0x3c, 0x41, 0xca, 0x67, 0x93, 0x06, 0xb6, 0xa8, 0x3f, 0x6f, 0xad,
+0x7e, 0x33, 0xa6, 0x2f, 0x30, 0x81, 0x6b, 0x6f, 0x1b, 0xde, 0x10, 0x6b, 0x1a,
+0x4c, 0xa5, 0x81, 0xef, 0x36, 0x49, 0x04, 0x32, 0xfd, 0x4c, 0x83, 0x61, 0x33,
+0x12, 0xdb, 0xd5, 0xd4, 0xc0, 0x3e, 0xf8, 0x83, 0x47, 0x6d, 0x97, 0x65, 0xae,
+0xd3, 0xd4, 0x2a, 0xa7, 0x71, 0x67, 0xb7, 0xae, 0xeb, 0xcf, 0x88
+},
+.plaintext = NULL,
+.aad = (unsigned char []){
+0x8f, 0xcf, 0xfa, 0x39, 0x5f, 0xc0, 0x11, 0x81, 0xc0, 0xe0, 0xc0, 0x96, 0xa9,
+0x8d, 0x40, 0x53, 0x57, 0x08, 0xa3, 0xf7, 0x1c, 0xe4, 0x4d, 0x8b, 0xba, 0xcd,
+0xf7, 0xa7, 0xdd, 0x11, 0x9a, 0x50, 0x3a, 0xe5, 0x4b, 0x91, 0xbe, 0x91, 0x7c,
+0xd0, 0x31, 0xb3, 0x53, 0x64, 0x31, 0x49, 0x4e, 0xc2, 0x5a, 0x6e, 0x1c, 0x26,
+0x5c, 0x79, 0xa2, 0xe8, 0x47, 0x98, 0xe0, 0xca, 0xf1, 0x64, 0xd3, 0x16, 0x33,
+0x2c, 0x9a, 0xf2, 0x67, 0x29, 0x3e, 0x1c, 0x06, 0x06, 0xe0, 0xa6, 0x46, 0x1a,
+0x59, 0xb4, 0x81, 0xe0, 0x6a, 0x69, 0x79, 0x43, 0x11, 0x76, 0xfe, 0x74
+},
+.tag = (unsigned char []){
+0x49, 0x5c, 0x55, 0x5d
+},
+.ciphertext = (unsigned char []){
+0x2c, 0x81, 0x49, 0x87, 0xdc, 0x8f, 0xe0, 0x45, 0x6f, 0x17, 0xb3, 0x29, 0x21,
+0x1c, 0x29, 0xc2, 0xe5, 0xa3, 0xb5, 0x60, 0x02, 0x80, 0xd4, 0x13, 0x6f, 0x09,
+0xa2, 0x88, 0x2a, 0xa1, 0x06, 0x74, 0x2c, 0x55, 0x99, 0xb2, 0xe4, 0xd9, 0x3d,
+0xf8, 0x87, 0x71, 0x73, 0x1f, 0x30, 0xfd, 0xbe, 0xf0, 0x7b, 0x46, 0x48
+},
+.rv = EFAULT,
+},
+{
+.keylen = AES192_KEYLEN,
+.ivlen = 1024 / 8,
+.len = 408 / 8,
+.aadlen = 720 / 8,
+.taglen = 32 / 8,
+.key = (unsigned char []){
+0x89, 0xd9, 0x4a, 0x67, 0x35, 0x35, 0x90, 0x0d, 0x5e, 0xbc, 0x1f, 0x60, 0x1c,
+0x03, 0xff, 0xfd, 0xaf, 0xb6, 0x7e, 0xfe, 0xb7, 0xda, 0x1c, 0x0b
+},
+.iv = (unsigned char []){
+0x71, 0x5e, 0xb8, 0x27, 0x88, 0xa7, 0x76, 0x57, 0x52, 0x30, 0x34, 0x6c, 0x7d,
+0x7c, 0xbc, 0x20, 0x1f, 0xd7, 0x42, 0xd2, 0x78, 0x16, 0x6b, 0x2d, 0x9f, 0x77,
+0xb4, 0x78, 0x64, 0xf6, 0xb9, 0x8e, 0x1e, 0xd1, 0x90, 0x48, 0x0b, 0x4e, 0x4a,
+0x79, 0xdc, 0xa0, 0xd9, 0xef, 0xd9, 0xd2, 0x6b, 0x90, 0x10, 0x54, 0x9d, 0x7c,
+0x3d, 0x8c, 0x2e, 0xbd, 0x01, 0xf5, 0x59, 0xef, 0xd6, 0xf5, 0x36, 0x1a, 0xb2,
+0xfd, 0xab, 0x1f, 0x0c, 0xc7, 0xd0, 0x36, 0x52, 0x8c, 0xcc, 0x80, 0x7e, 0xb4,
+0x02, 0xd2, 0x1b, 0x66, 0xa5, 0x2a, 0x8f, 0xf4, 0xaa, 0xb0, 0xd3, 0x37, 0x7a,
+0x6b, 0xca, 0x45, 0xcc, 0x9a, 0x58, 0x47, 0x9a, 0x93, 0x98, 0x16, 0xb5, 0x1c,
+0x86, 0xc4, 0x45, 0xdc, 0x51, 0xeb, 0xf3, 0x6d, 0x6d, 0x72, 0xdb, 0x7f, 0xe5,
+0xf7, 0xf9, 0x0c, 0x13, 0x14, 0x06, 0x4b, 0xc2, 0x29, 0xb6, 0xca
+},
+.plaintext = (unsigned char []) {
+0x8f, 0x8b, 0x42, 0xb5, 0x2c, 0xc9, 0xa0, 0x80, 0xe8, 0x4b, 0x48, 0x0e, 0xca,
+0x78, 0xd1, 0xb6, 0x74, 0x5c, 0x63, 0x69, 0x4a, 0x70, 0xa3, 0xb4, 0xc1, 0xd4,
+0x57, 0xfe, 0xa9, 0x82, 0x1b, 0x63, 0x34, 0x38, 0xa5, 0x11, 0x19, 0xd4, 0x2b,
+0xc7, 0x01, 0xa0, 0x5a, 0xb7, 0x55, 0x3f, 0xd4, 0xe6, 0x17, 0x13, 0x64
+},
+.aad = (unsigned char []){
+0x40, 0x66, 0x52, 0xd7, 0x9e, 0x0f, 0xef, 0x78, 0x1e, 0x5d, 0x74, 0xe9, 0x01,
+0x73, 0x60, 0x42, 0x3f, 0x31, 0x8c, 0x95, 0x41, 0x8b, 0xaa, 0x49, 0x8e, 0xe0,
+0xc5, 0x0d, 0xad, 0x71, 0xc4, 0xed, 0xaa, 0xe9, 0xbd, 0x6f, 0x57, 0x57, 0x32,
+0xb7, 0x36, 0xf2, 0x8d, 0xf1, 0x5e, 0x92, 0x1f, 0x15, 0x0c, 0xab, 0x05, 0x87,
+0x25, 0xab, 0xda, 0xa4, 0x23, 0x12, 0x7e, 0x47, 0x12, 0x26, 0xff, 0x0c, 0x53,
+0x8c, 0xcd, 0x8e, 0x36, 0x3b, 0x21, 0x58, 0xc0, 0x70, 0x55, 0xc2, 0xaa, 0x97,
+0x57, 0x7d, 0xd1, 0xec, 0x19, 0x58, 0x43, 0x49, 0x48, 0xb0, 0x95, 0x0e
+},
+.tag = (unsigned char []){
+0x64, 0x35, 0xff, 0xde
+},
+.ciphertext = (unsigned char []){
+0x12, 0x92, 0xe7, 0xac, 0xb4, 0x8a, 0xb1, 0xda, 0xd5, 0x0f, 0x28, 0x1c, 0x6e,
+0xc3, 0x5c, 0x98, 0x00, 0x1d, 0x3d, 0xbf, 0x98, 0x34, 0x28, 0x23, 0x88, 0xaa,
+0x43, 0xcd, 0x17, 0x51, 0x1b, 0x65, 0x6e, 0xa7, 0x95, 0x5b, 0x57, 0x61, 0xe4,
+0x2f, 0x7a, 0xa6, 0xcb, 0x58, 0xc9, 0xb0, 0x0f, 0xc2, 0x7b, 0x22, 0x4d
+},
+.rv = 0,
+},
+{
+.keylen = AES256_KEYLEN,
+.ivlen = 1024 / 8,
+.len = 408 / 8,
+.aadlen = 720 / 8,
+.taglen = 32 / 8,
+.key = (unsigned char []){
+0xc8, 0x18, 0xc1, 0xa7, 0x53, 0xe7, 0x84, 0x1f, 0x58, 0x43, 0x87, 0xeb, 0x7a,
+0x38, 0x1f, 0x99, 0xaf, 0xee, 0x72, 0xf4, 0x63, 0x4b, 0x6d, 0x46, 0xe4, 0xce,
+0xad, 0x3d, 0xf2, 0x0b, 0x3b, 0x5a
+},
+.iv = (unsigned char []){
+0xc3, 0x76, 0x0e, 0x41, 0x3d, 0x6c, 0x98, 0x62, 0x81, 0xc2, 0x09, 0xb4, 0xaf,
+0xdc, 0x67, 0x4a, 0xea, 0x43, 0xc7, 0xfe, 0xe6, 0x86, 0x3f, 0x80, 0xfe, 0x15,
+0x16, 0xcd, 0xb2, 0x1e, 0xe5, 0x6d, 0xb7, 0x73, 0x5b, 0x98, 0xba, 0xe8, 0x14,
+0xb6, 0xe1, 0x49, 0x4b, 0x57, 0xda, 0xdd, 0xb4, 0x92, 0xef, 0x08, 0xcf, 0xff,
+0x73, 0xcf, 0x58, 0x9f, 0x1d, 0xa9, 0x44, 0xa4, 0x21, 0xe2, 0x49, 0xdd, 0x02,
+0xec, 0xc5, 0x91, 0x1a, 0x9a, 0xed, 0x11, 0xd7, 0x87, 0x17, 0xb4, 0xe6, 0xcb,
+0x56, 0xbf, 0x77, 0x7f, 0x94, 0x3f, 0xd0, 0xc4, 0x8f, 0x4a, 0xa8, 0xff, 0xdf,
+0x5a, 0x12, 0x9e, 0x71, 0x6d, 0xbe, 0xa7, 0x14, 0x39, 0xd0, 0x77, 0xfb, 0x69,
+0x3d, 0x0e, 0x29, 0x3a, 0xb2, 0xe1, 0xd5, 0xb9, 0x26, 0xa0, 0x1c, 0xef, 0xe3,
+0xe6, 0x88, 0x12, 0xc2, 0x80, 0xd5, 0x65, 0xa5, 0xc5, 0x71, 0x02
+},
+.plaintext = NULL,
+.aad = (unsigned char []){
+0x16, 0xbc, 0xa6, 0xec, 0xc8, 0x7f, 0x32, 0xb7, 0x78, 0xed, 0xc9, 0x06, 0xab,
+0x86, 0x23, 0xef, 0x37, 0xee, 0x16, 0x70, 0x67, 0x26, 0xa9, 0x8a, 0x23, 0x5a,
+0xe5, 0x89, 0xd5, 0x1a, 0x1f, 0x56, 0x1d, 0xc6, 0xfd, 0x30, 0x24, 0x48, 0xf7,
+0x08, 0x25, 0x6f, 0xcc, 0x62, 0xec, 0xd4, 0x1b, 0xaa, 0x9e, 0xe3, 0x23, 0x56,
+0x42, 0xb0, 0xff, 0x12, 0x47, 0x03, 0xd1, 0x8f, 0xb7, 0x48, 0x63, 0xe7, 0x5a,
+0x80, 0x55, 0xc2, 0xc9, 0x7b, 0x49, 0xc6, 0xdc, 0xb0, 0xaa, 0xeb, 0xb6, 0x24,
+0x00, 0x32, 0x84, 0x2f, 0xf5, 0xd1, 0xb4, 0x29, 0xa0, 0xa5, 0x1d, 0xd7
+},
+.tag = (unsigned char []){
+0xfb, 0xaf, 0xce, 0xd4
+},
+.ciphertext = (unsigned char []){
+0xaa, 0x58, 0x42, 0x8e, 0x79, 0xa7, 0x4a, 0x14, 0x35, 0x9b, 0x89, 0xea, 0x78,
+0x62, 0xfe, 0xb1, 0xb7, 0xb7, 0x65, 0x72, 0xe9, 0x57, 0x35, 0x9c, 0x9a, 0x62,
+0x85, 0xe2, 0x9a, 0x0f, 0xb4, 0x7a, 0x90, 0xca, 0x7e, 0xe7, 0x1d, 0x41, 0x36,
+0x50, 0x23, 0x21, 0xb3, 0x78, 0xe5, 0xa0, 0x4b, 0xb0, 0xc9, 0xeb, 0x5c
+},
+.rv = EFAULT,
+},
+{
+.keylen = AES256_KEYLEN,
+.ivlen = 1024 / 8,
+.len = 408 / 8,
+.aadlen = 720 / 8,
+.taglen = 32 / 8,
+.key = (unsigned char []){
+0xe1, 0x7c, 0x5c, 0xa6, 0x66, 0x29, 0xba, 0xd6, 0x86, 0xd9, 0x83, 0x51, 0x03,
+0xf8, 0xcb, 0x28, 0x43, 0xc0, 0x98, 0x0b, 0xc6, 0xef, 0x29, 0x47, 0xea, 0x5c,
+0xce, 0xc3, 0x84, 0xa2, 0x55, 0x99
+},
+.iv = (unsigned char []){
+0x4b, 0x3e, 0xe3, 0x05, 0x78, 0xad, 0x93, 0x88, 0x40, 0x44, 0xdc, 0xff, 0xdf,
+0x28, 0x6a, 0x1a, 0xf8, 0xa9, 0xae, 0x27, 0x39, 0xac, 0x13, 0x89, 0x18, 0x89,
+0xb0, 0xf9, 0x8a, 0x60, 0xde, 0x71, 0x02, 0xf5, 0x8a, 0xaf, 0xf0, 0xc4, 0x3d,
+0x85, 0x0f, 0xf9, 0x79, 0x86, 0x5d, 0xb6, 0xea, 0xb2, 0xd1, 0x7d, 0xb4, 0x1a,
+0x12, 0x0e, 0xe5, 0x09, 0xf9, 0xbf, 0x44, 0x66, 0x10, 0xa9, 0x86, 0x35, 0x81,
+0xd6, 0xa5, 0x65, 0x83, 0x52, 0x42, 0xf1, 0x11, 0xbe, 0x68, 0x60, 0x33, 0xa7,
+0xbb, 0xec, 0x53, 0x28, 0xa8, 0xe3, 0x6b, 0x02, 0xa9, 0x5e, 0xef, 0xf6, 0x18,
+0xdc, 0xb2, 0x03, 0x31, 0x9b, 0xc4, 0x61, 0x47, 0xf2, 0x87, 0x03, 0x8b, 0xa3,
+0x37, 0x3c, 0xfb, 0xbe, 0xcd, 0x20, 0xbb, 0xaa, 0xc2, 0xdb, 0xf0, 0x0c, 0x1b,
+0x26, 0xb6, 0x44, 0x9f, 0xa1, 0xd0, 0x22, 0x1d, 0x5b, 0x35, 0xe6
+},
+.plaintext = (unsigned char []) {
+0x50, 0x46, 0xc7, 0xfe, 0x0d, 0x32, 0x90, 0x52, 0x5b, 0x78, 0x92, 0xbf, 0x19,
+0xd6, 0x4c, 0x5d, 0x99, 0x88, 0x1a, 0x3b, 0xfb, 0xb2, 0x1f, 0x00, 0x07, 0xe6,
+0x0c, 0xea, 0x99, 0x2d, 0x22, 0x54, 0x9e, 0xce, 0x21, 0x91, 0x21, 0x6b, 0x6c,
+0x68, 0x20, 0x28, 0x64, 0x49, 0x2f, 0x1f, 0xd1, 0x5b, 0x89, 0x16, 0xd3
+},
+.aad = (unsigned char []){
+0x51, 0xc8, 0xaa, 0x89, 0x03, 0x3a, 0x74, 0x8f, 0x0a, 0x63, 0xec, 0x08, 0x95,
+0xd5, 0xbf, 0x9d, 0x5f, 0xe2, 0x76, 0x69, 0x9f, 0x2a, 0x04, 0xfc, 0xf5, 0x84,
+0xbf, 0x1d, 0xfe, 0x0a, 0x26, 0x7b, 0x81, 0x28, 0xff, 0x38, 0x87, 0x3e, 0x45,
+0xf4, 0xf8, 0x53, 0x84, 0x7e, 0x45, 0xa9, 0x95, 0x60, 0x18, 0x6e, 0x08, 0x81,
+0xf8, 0xe9, 0xd3, 0xce, 0xcb, 0x93, 0xdb, 0x4a, 0x8c, 0xc8, 0x6c, 0x05, 0xff,
+0x44, 0x92, 0x41, 0xf1, 0xe5, 0x65, 0xbe, 0x9a, 0x68, 0xb6, 0x18, 0xa7, 0x01,
+0x61, 0x46, 0xdb, 0x62, 0x57, 0x7d, 0xe7, 0xd0, 0x5c, 0x29, 0x5b, 0x7b
+},
+.tag = (unsigned char []){
+0xf9, 0x05, 0xb7, 0xf7
+},
+.ciphertext = (unsigned char []){
+0xc4, 0xbc, 0x2e, 0x5d, 0xc4, 0xec, 0x97, 0x66, 0x5d, 0x0c, 0xc5, 0x59, 0x7e,
+0x4b, 0x18, 0x8e, 0xff, 0x9d, 0x54, 0x79, 0x87, 0x24, 0xfe, 0xf2, 0x8e, 0x93,
+0x8b, 0x61, 0x1c, 0x3e, 0x15, 0xfb, 0x32, 0x23, 0xdd, 0x87, 0x91, 0x34, 0x62,
+0x4f, 0x2d, 0x07, 0x1e, 0x31, 0xa8, 0xbd, 0x79, 0x8e, 0x94, 0x9d, 0xb5
+},
+.rv = 0,
+},
+{
+.keylen = AES256_KEYLEN,
+.ivlen = 96 / 8,
+.len = 128 / 8,
+.aadlen = 128 / 8,
+.taglen = 104 / 8,
+.key = (unsigned char []){
+0x57, 0xc2, 0xf2, 0x48, 0x59, 0x89, 0x2c, 0xfd, 0x8c, 0x80, 0xa9, 0xb9, 0xdb,
+0xab, 0x4f, 0x78, 0xb2, 0x2b, 0xdd, 0xed, 0xec, 0x57, 0xe0, 0xbd, 0x30, 0xb8,
+0xd9, 0x3d, 0xf4, 0xeb, 0x16, 0x74
+},
+.iv = (unsigned char []){
+0x85, 0x5b, 0x19, 0x8c, 0xc1, 0xd8, 0x57, 0x77, 0x0d, 0xc9, 0xee, 0x93
+},
+.plaintext = (unsigned char []) {
+0xf9, 0x7f, 0x43, 0x2d, 0xb7, 0x61, 0xec, 0xe8, 0xdc, 0x1e, 0x7b, 0xdd, 0x47,
+0x6d, 0xc2, 0xef
+},
+.aad = (unsigned char []){
+0xcd, 0x32, 0xfd, 0xa7, 0x6b, 0x12, 0x2c, 0x60, 0x9d, 0x0a, 0xf6, 0x0f, 0x2c,
+0x39, 0x2b, 0x8b
+},
+.tag = (unsigned char []){
+0x2b, 0xd9, 0x69, 0xae, 0x43, 0xa2, 0xdb, 0x5b, 0xaf, 0xd7, 0x9e, 0x17, 0x51
+},
+.ciphertext = (unsigned char []){
+0xe0, 0x7b, 0xa0, 0x42, 0x16, 0xd5, 0x00, 0x99, 0x9a, 0x25, 0xad, 0xd7, 0x10,
+0x2c, 0x70, 0x36
+},
+.rv = 0,
+},
+{
+.keylen = AES256_KEYLEN,
+.ivlen = 96 / 8,
+.len = 128 / 8,
+.aadlen = 128 / 8,
+.taglen = 104 / 8,
+.key = (unsigned char []){
+0xe3, 0xc0, 0x0c, 0xe8, 0x1f, 0xfb, 0xca, 0xcc, 0x56, 0x7a, 0x06, 0x34, 0x28,
+0x49, 0x53, 0x86, 0xad, 0x51, 0xae, 0x83, 0x13, 0x22, 0x3a, 0xba, 0xbb, 0x2c,
+0x59, 0xa2, 0x2d, 0x35, 0x34, 0x28
+},
+.iv = (unsigned char []){
+0x91, 0x96, 0xfe, 0x6f, 0x8d, 0x34, 0x1f, 0x69, 0xf8, 0x86, 0x32, 0xff
+},
+.plaintext = (unsigned char []) {
+0x54, 0x0c, 0x5d, 0x33, 0xd9, 0x43, 0x96, 0xea, 0xd0, 0x9b, 0x84, 0x56, 0xff,
+0x12, 0x73, 0x50
+},
+.aad = (unsigned char []){
+0x88, 0x0f, 0x98, 0xc2, 0xa0, 0xfb, 0xed, 0x6b, 0xf3, 0xbf, 0xf7, 0x1d, 0xea,
+0x42, 0x7f, 0x5f
+},
+.tag = (unsigned char []){
+0x08, 0xfe, 0xad, 0xdb, 0x09, 0x05, 0x9a, 0xce, 0xa8, 0x67, 0xa8, 0xcd, 0xe2
+},
+.ciphertext = (unsigned char []){
+0xc2, 0x26, 0x0f, 0xc8, 0x37, 0x9d, 0x0f, 0x11, 0xbd, 0x06, 0xe5, 0xd7, 0x44,
+0x77, 0xd3, 0xe7
+},
+.rv = 0,
+},
+{
+.keylen = AES192_KEYLEN,
+.ivlen = 1024 / 8,
+.len = 408 / 8,
+.aadlen = 128 / 8,
+.taglen = 96 / 8,
+.key = (unsigned char []){
+0x37, 0xb3, 0x56, 0x2a, 0x59, 0x12, 0xcc, 0xf6, 0xcb, 0xcc, 0xdd, 0x3f, 0xcf,
+0x9d, 0x76, 0x95, 0xfb, 0x8a, 0xf1, 0x08, 0x52, 0xb2, 0x1f, 0x1d
+},
+.iv = (unsigned char []){
+0x2f, 0x59, 0x77, 0xf7, 0x42, 0x65, 0xa0, 0x7e, 0xd8, 0x47, 0xad, 0x27, 0xb5,
+0xcb, 0x85, 0xba, 0x25, 0x66, 0xe4, 0x63, 0xb9, 0xc6, 0x15, 0xf8, 0xd5, 0xb1,
+0x83, 0xd7, 0xb5, 0x39, 0x35, 0xe2, 0xb5, 0x7f, 0xc7, 0x5e, 0x36, 0x88, 0x10,
+0x2d, 0xa0, 0x46, 0x44, 0x29, 0x3c, 0x6c, 0x86, 0xb6, 0xc2, 0x42, 0xc6, 0xcd,
+0xaf, 0xb2, 0x91, 0x99, 0xb8, 0x0c, 0x4f, 0x46, 0x53, 0xa1, 0x1b, 0xbb, 0x0a,
+0xc3, 0x1e, 0xc1, 0x63, 0x0e, 0x03, 0x2d, 0x39, 0xec, 0x02, 0x83, 0xce, 0x6e,
+0xc0, 0x99, 0xb3, 0x32, 0xae, 0x4e, 0x0a, 0xc1, 0x97, 0x67, 0xa1, 0x05, 0x0c,
+0x48, 0xef, 0xab, 0xa1, 0xc1, 0xb2, 0xaa, 0xcb, 0xa9, 0x57, 0x0e, 0xcf, 0xbb,
+0xed, 0xe4, 0xd2, 0x32, 0x73, 0xd3, 0xd5, 0x18, 0xef, 0x68, 0x59, 0x26, 0xc1,
+0x70, 0xe1, 0xed, 0xf0, 0x46, 0x74, 0xc6, 0x22, 0xfe, 0x98, 0x4d
+},
+.plaintext = (unsigned char []) {
+0xd0, 0xd8, 0x95, 0xb6, 0xb8, 0x0f, 0x97, 0xe4, 0xa6, 0x09, 0x55, 0x60, 0x94,
+0x2d, 0xdb, 0xa4, 0xd7, 0x3c, 0xda, 0xf0, 0x9f, 0xf6, 0xa4, 0x38, 0x1b, 0x5b,
+0x03, 0xf4, 0xbd, 0x75, 0x16, 0x49, 0x42, 0x68, 0x66, 0x89, 0xf3, 0xac, 0xc6,
+0x2b, 0x02, 0x43, 0x1a, 0x9a, 0xd4, 0x03, 0x5e, 0x3f, 0x8e, 0x20, 0xc6
+},
+.aad = (unsigned char []){
+0xd0, 0xed, 0xbf, 0x82, 0x83, 0x2c, 0x6f, 0x35, 0x8d, 0xd5, 0x00, 0xb9, 0x79,
+0xc1, 0x5f, 0x47
+},
+.tag = (unsigned char []){
+0xa0, 0xea, 0x4b, 0xbd, 0xc4, 0x9a, 0x10, 0x29, 0x8c, 0x9a, 0x97, 0x3d
+},
+.ciphertext = (unsigned char []){
+0xd3, 0x29, 0xc6, 0x6a, 0x4f, 0x46, 0x0a, 0xe6, 0xf0, 0x5b, 0x0d, 0xfd, 0x2e,
+0xb4, 0x47, 0x6c, 0x0f, 0x29, 0x3c, 0x08, 0xce, 0xc5, 0x7e, 0x6d, 0x6a, 0xda,
+0xe9, 0x61, 0x14, 0x45, 0xb8, 0x9f, 0x32, 0xb2, 0x3f, 0xdc, 0x5c, 0x1d, 0xd3,
+0x3f, 0xa6, 0x2d, 0x19, 0x0f, 0x4b, 0x5b, 0xd8, 0x1f, 0x0e, 0x97, 0xa8
+},
+.rv = 0,
+},
+{
+.keylen = AES128_KEYLEN,
+.ivlen = 96 / 8,
+.len = 408 / 8,
+.aadlen = 720 / 8,
+.taglen = 120 / 8,
+.key = (unsigned char []){
+0x32, 0x66, 0x43, 0x0c, 0x1c, 0xad, 0x19, 0x32, 0x10, 0x13, 0xce, 0xec, 0x77,
+0xdc, 0x54, 0x09
+},
+.iv = (unsigned char []){
+0x44, 0xe3, 0xc6, 0xf6, 0x19, 0xa3, 0x73, 0xc7, 0x97, 0xda, 0x3e, 0x62
+},
+.plaintext = (unsigned char []) {
+0xe7, 0x3c, 0x85, 0x98, 0x26, 0x8b, 0x79, 0xf4, 0x0a, 0x34, 0x14, 0x75, 0xf0,
+0x3f, 0xe8, 0x08, 0x56, 0xa6, 0xd9, 0x36, 0xf7, 0xa0, 0x57, 0xa9, 0xec, 0x5b,
+0xeb, 0x41, 0x85, 0x34, 0x01, 0x35, 0x83, 0xf3, 0xd9, 0x08, 0x23, 0x59, 0xec,
+0xb4, 0x0e, 0x95, 0x76, 0xec, 0x58, 0xcb, 0x5b, 0xfe, 0x28, 0x63, 0xb5
+},
+.aad = (unsigned char []){
+0x45, 0xee, 0x7d, 0x52, 0xf7, 0xd8, 0x0a, 0x6c, 0x6b, 0x5f, 0xb0, 0xf2, 0x67,
+0xd3, 0x06, 0x79, 0xc6, 0xa4, 0xbe, 0x41, 0xe4, 0xc7, 0xd2, 0xcd, 0x43, 0x1c,
+0x8d, 0xe7, 0x57, 0x70, 0x10, 0x91, 0xa3, 0x77, 0x6e, 0x40, 0xd5, 0xc9, 0xec,
+0xd7, 0xc5, 0x0c, 0xc8, 0x50, 0xef, 0x3a, 0x3f, 0xeb, 0xe4, 0x30, 0xaf, 0x0c,
+0xb2, 0xdd, 0xc5, 0x03, 0x3f, 0x5d, 0x68, 0x72, 0x8f, 0xf4, 0xe3, 0x61, 0x37,
+0x4c, 0x88, 0xdc, 0x7f, 0x33, 0x38, 0x60, 0x4a, 0xc3, 0x62, 0x8a, 0xe1, 0x2a,
+0x13, 0x2b, 0x5f, 0x42, 0x13, 0x13, 0x5c, 0x81, 0x14, 0x0e, 0xc5, 0xbe
+},
+.tag = (unsigned char []){
+0x85, 0x43, 0xd4, 0xe7, 0x20, 0x50, 0xdc, 0x37, 0xc5, 0x85, 0xef, 0xbd, 0xa5,
+0xdf, 0x95
+},
+.ciphertext = (unsigned char []){
+0x6d, 0x1f, 0x6b, 0xc3, 0xd7, 0xba, 0x16, 0xef, 0x28, 0x98, 0x91, 0xee, 0x89,
+0x12, 0xae, 0x54, 0xdb, 0xf2, 0xd2, 0xcd, 0x84, 0xff, 0xb8, 0x1b, 0xe5, 0xb9,
+0x9c, 0x5a, 0x06, 0x9b, 0xfa, 0xf4, 0xea, 0x50, 0xb3, 0x54, 0xdf, 0x24, 0x35,
+0x65, 0x46, 0x2a, 0xba, 0x25, 0xe5, 0x20, 0xa4, 0xdc, 0x71, 0x1b, 0xdb
+},
+.rv = 0,
+},
+{
+.keylen = AES192_KEYLEN,
+.ivlen = 8 / 8,
+.len = 104 / 8,
+.aadlen = 160 / 8,
+.taglen = 64 / 8,
+.key = (unsigned char []){
+0x27, 0xd2, 0x0c, 0x93, 0xe1, 0x2c, 0xa2, 0x1a, 0x59, 0x09, 0x54, 0x25, 0xfc,
+0xe8, 0x46, 0xad, 0x45, 0x71, 0x62, 0x8e, 0xce, 0x9f, 0x6b, 0x91
+},
+.iv = (unsigned char []){
+0x43
+},
+.plaintext = (unsigned char []) {
+0xbb, 0x0f, 0x56, 0x3e, 0x30, 0x33, 0x7f, 0x0c, 0x38, 0x47, 0xdc, 0xe3, 0xd2
+},
+.aad = (unsigned char []){
+0xcc, 0xca, 0xe3, 0xab, 0x11, 0x6b, 0x5a, 0x3d, 0xfd, 0x8c, 0x8b, 0xf7, 0xd5,
+0xe7, 0xb6, 0xa0, 0xa4, 0xcd, 0xb4, 0x0a
+},
+.tag = (unsigned char []){
+0x1a, 0xa6, 0xb6, 0x6a, 0x18, 0xd5, 0x98, 0xe6
+},
+.ciphertext = (unsigned char []){
+0x2f, 0x83, 0xe6, 0xaa, 0xf6, 0xfb, 0xcd, 0x07, 0x28, 0xcb, 0x99, 0x2a, 0x0d
+},
+.rv = 0,
+},
+{
+.keylen = AES128_KEYLEN,
+.ivlen = 1024 / 8,
+.len = 408 / 8,
+.aadlen = 128 / 8,
+.taglen = 112 / 8,
+.key = (unsigned char []){
+0x49, 0xa4, 0xf6, 0x0c, 0xb3, 0xf4, 0x3f, 0xf3, 0x77, 0xc3, 0x43, 0x64, 0x24,
+0x79, 0xd6, 0x4b
+},
+.iv = (unsigned char []){
+0xcb, 0x38, 0x64, 0xdf, 0x26, 0xb1, 0x66, 0xda, 0x4d, 0x1a, 0x32, 0x5d, 0x91,
+0xb1, 0xc8, 0x34, 0xf7, 0xe7, 0x8f, 0xf5, 0x44, 0x85, 0x68, 0xdf, 0xdc, 0x96,
+0x6d, 0xab, 0x49, 0xe9, 0xf7, 0x73, 0x97, 0xbf, 0xb4, 0xc8, 0x3c, 0xef, 0xaa,
+0x9c, 0xaa, 0x64, 0xbe, 0x4d, 0xce, 0x61, 0x0b, 0x26, 0xca, 0xe6, 0xe0, 0x3d,
+0x6c, 0xdc, 0xe0, 0x34, 0x5b, 0x6b, 0xd4, 0xcc, 0xa2, 0x27, 0x93, 0xb4, 0x89,
+0x4b, 0xe9, 0x50, 0x02, 0x4a, 0xf4, 0x22, 0xa4, 0x85, 0xdb, 0xb0, 0x99, 0xe5,
+0xbb, 0x3f, 0x79, 0x2d, 0x8a, 0xed, 0x9c, 0x87, 0xba, 0x9f, 0x0e, 0xa3, 0x75,
+0x00, 0x62, 0xcf, 0x9a, 0x8d, 0x7b, 0x88, 0x4e, 0x1f, 0x8e, 0x88, 0x09, 0x74,
+0x34, 0x3d, 0x7f, 0x7d, 0x03, 0x26, 0x74, 0x84, 0x86, 0x15, 0x72, 0x59, 0x0b,
+0x2f, 0x96, 0x90, 0x6f, 0x0e, 0x76, 0x34, 0xa6, 0x47, 0xcb, 0x79
+},
+.plaintext = (unsigned char []) {
+0xee, 0xda, 0x6c, 0x7c, 0x50, 0x05, 0x61, 0xe6, 0xad, 0xcf, 0x94, 0xb8, 0x45,
+0x51, 0xd9, 0xbb, 0xca, 0x36, 0xd7, 0x0a, 0x54, 0x94, 0x9f, 0x3f, 0x96, 0xc9,
+0xb3, 0x93, 0x1d, 0xe6, 0x04, 0x07, 0x13, 0x0d, 0xfa, 0xb1, 0x02, 0xcc, 0x26,
+0x11, 0x7e, 0x9e, 0xad, 0x80, 0x0c, 0x55, 0x09, 0x18, 0x4f, 0xc9, 0xcf
+},
+.aad = (unsigned char []){
+0xb7, 0x47, 0x07, 0x07, 0xbd, 0x7a, 0xe9, 0xdc, 0x18, 0x1b, 0xb9, 0xd8, 0xaf,
+0xb9, 0x59, 0x60
+},
+.tag = (unsigned char []){
+0x4d, 0xbe, 0x3c, 0xb5, 0x45, 0x58, 0x31, 0x45, 0xe0, 0x89, 0x66, 0xe9, 0x10,
+0x90
+},
+.ciphertext = (unsigned char []){
+0x08, 0xc1, 0xe9, 0x19, 0x6a, 0x22, 0xed, 0x47, 0x90, 0xa6, 0x59, 0x5c, 0x3f,
+0xeb, 0x95, 0xe7, 0xd4, 0x8c, 0xb3, 0x5c, 0x0c, 0x1e, 0x57, 0x95, 0x14, 0x83,
+0x7b, 0xec, 0xca, 0xaf, 0xf5, 0x52, 0x9d, 0x9f, 0x80, 0x5f, 0xe5, 0x72, 0x25,
+0xf9, 0x81, 0x88, 0x90, 0xd9, 0xfb, 0xc9, 0x82, 0xf9, 0x4d, 0x26, 0x48
+},
+.rv = 0,
+},
+{
+.keylen = AES256_KEYLEN,
+.ivlen = 1024 / 8,
+.len = 408 / 8,
+.aadlen = 720 / 8,
+.taglen = 128 / 8,
+.key = (unsigned char []){
+0x87, 0x1a, 0xd3, 0x7e, 0xeb, 0xc6, 0x84, 0x79, 0x44, 0xf7, 0xe4, 0x2f, 0xff,
+0x5a, 0x65, 0xae, 0x62, 0xc5, 0x08, 0x54, 0x48, 0x6f, 0x63, 0xc0, 0x8f, 0x60,
+0x80, 0xf8, 0x3c, 0x08, 0xd6, 0x6a
+},
+.iv = (unsigned char []){
+0xf9, 0x1b, 0x2d, 0x31, 0x61, 0x7e, 0x9a, 0x52, 0x04, 0x20, 0x44, 0xf5, 0x70,
+0x37, 0xb0, 0x96, 0x47, 0x7d, 0x90, 0xe6, 0xe9, 0xd6, 0xf4, 0x0f, 0x67, 0x62,
+0xea, 0x48, 0xfa, 0xc5, 0xa1, 0x82, 0x50, 0x2e, 0xf9, 0x40, 0xd3, 0xd4, 0xc8,
+0x6a, 0x48, 0xf7, 0xe7, 0xc2, 0xc8, 0xd6, 0xba, 0x55, 0xdd, 0xb3, 0x27, 0x69,
+0xdc, 0xc3, 0x10, 0x10, 0xc0, 0x44, 0xa8, 0x0f, 0xa4, 0x4f, 0x20, 0x1c, 0xd8,
+0x72, 0x62, 0x70, 0xd6, 0xf7, 0x0e, 0xd0, 0x13, 0x78, 0xab, 0xe1, 0xd9, 0x34,
+0xd4, 0x83, 0x53, 0x6b, 0xa6, 0x08, 0xe7, 0x23, 0x81, 0xfd, 0x15, 0x23, 0x4a,
+0xd1, 0x4c, 0x5c, 0x2c, 0xf0, 0x83, 0xc0, 0xd0, 0x70, 0x22, 0x83, 0x42, 0x96,
+0x8f, 0xf5, 0xf6, 0x6d, 0x6f, 0x23, 0x95, 0x1c, 0x54, 0xc7, 0xf7, 0x9c, 0x82,
+0xe2, 0x36, 0xe5, 0x51, 0x7f, 0x26, 0x4e, 0xaa, 0xc0, 0x93, 0xc5
+},
+.plaintext = (unsigned char []) {
+0x90, 0x89, 0x42, 0x5f, 0x0d, 0x9d, 0x17, 0x51, 0x64, 0x65, 0x99, 0x00, 0x49,
+0xf0, 0x1a, 0x2e, 0x8e, 0x5f, 0x91, 0xc2, 0xfa, 0xea, 0x84, 0x68, 0x97, 0x36,
+0x06, 0xc1, 0x2b, 0x50, 0x7c, 0xa0, 0x72, 0x81, 0x8b, 0x4f, 0xe2, 0xd6, 0x11,
+0x70, 0x96, 0x38, 0xd2, 0x1e, 0x03, 0x4d, 0xbc, 0xdf, 0x47, 0xcf, 0x59
+},
+.aad = (unsigned char []){
+0xd5, 0xf7, 0xc1, 0xf6, 0x89, 0x65, 0xd9, 0x13, 0xab, 0xc6, 0xbb, 0x01, 0xb3,
+0x3d, 0x35, 0xa3, 0x17, 0xa7, 0xfb, 0xe7, 0xba, 0x2e, 0x53, 0xc7, 0x3d, 0x6c,
+0x44, 0xab, 0xe1, 0xc2, 0x16, 0x0d, 0x54, 0x5d, 0x26, 0x24, 0xf2, 0x54, 0x50,
+0xad, 0x75, 0x13, 0xb2, 0xd3, 0x2f, 0xfa, 0x85, 0x78, 0xc3, 0x0e, 0x96, 0xd7,
+0xba, 0x49, 0xb3, 0x63, 0x4d, 0x99, 0xa1, 0x5e, 0xbf, 0xb3, 0x7d, 0xec, 0xd0,
+0xf8, 0xef, 0xc3, 0x2a, 0xab, 0x40, 0xa0, 0x59, 0x4b, 0xeb, 0xa0, 0xda, 0xc6,
+0xf8, 0xda, 0xa3, 0xac, 0xe9, 0x1b, 0xd0, 0x95, 0x49, 0xa1, 0xf5, 0xe1
+},
+.tag = (unsigned char []){
+0xcc, 0x4d, 0x95, 0x0b, 0x8c, 0x33, 0x30, 0xf0, 0x48, 0xe3, 0xaa, 0x3e, 0x3c,
+0xfb, 0xce, 0x21
+},
+.ciphertext = (unsigned char []){
+0x02, 0x10, 0x1f, 0x84, 0x82, 0x05, 0x2c, 0xb7, 0x70, 0x68, 0x00, 0xe8, 0x31,
+0x0f, 0x5d, 0x44, 0x4d, 0x67, 0x2b, 0x65, 0x59, 0xde, 0x0b, 0x87, 0x92, 0xd7,
+0xc6, 0x4c, 0xb1, 0xbc, 0x58, 0x7d, 0xed, 0xd6, 0x31, 0x59, 0x2f, 0xf6, 0xe9,
+0xc8, 0xfa, 0x28, 0x89, 0x5d, 0x36, 0x85, 0x9b, 0x97, 0x3a, 0x72, 0x24
+},
+.rv = 0,
+},
+};
+
+const struct aes_ccm_tv AES_CCM_TV[] = {
+{
+.keylen = AES128_KEYLEN,
+.noncelen = 13,
+.adatalen = 32,
+.payloadlen = 24,
+.taglen = 16,
+.key = (unsigned char []){
+0x26, 0x51, 0x1f, 0xb5, 0x1f, 0xcf, 0xa7, 0x5c, 0xb4, 0xb4, 0x4d, 0xa7, 0x5a,
+0x6e, 0x5a, 0x0e
+},
+.nonce = (unsigned char []){
+0xea, 0x98, 0xec, 0x44, 0xf5, 0xa8, 0x67, 0x15, 0x01, 0x47, 0x83, 0x17, 0x2e
+},
+.adata = (unsigned char []){
+0xe4, 0x69, 0x2b, 0x9f, 0x06, 0xb6, 0x66, 0xc7, 0x45, 0x1b, 0x14, 0x6c, 0x8a,
+0xeb, 0x07, 0xa6, 0xe3, 0x0c, 0x62, 0x9d, 0x28, 0x06, 0x5c, 0x3d, 0xde, 0x59,
+0x40, 0x32, 0x5b, 0x14, 0xb8, 0x10
+},
+.payload = (unsigned char []){
+0x4d, 0xa4, 0x0b, 0x80, 0x57, 0x9c, 0x1d, 0x9a, 0x53, 0x09, 0xf7, 0xef, 0xec,
+0xb7, 0xc0, 0x59, 0xa2, 0xf9, 0x14, 0x51, 0x1c, 0xa5, 0xfc, 0x10
+},
+.ciphertext = (unsigned char []){
+0x1b, 0xf0, 0xba, 0x0e, 0xbb, 0x20, 0xd8, 0xed, 0xba, 0x59, 0xf2, 0x9a, 0x93,
+0x71, 0x75, 0x0c, 0x9c, 0x71, 0x40, 0x78, 0xf7, 0x3c, 0x33, 0x5d, 0x2f, 0x13,
+0x22, 0xac, 0x69, 0xb8, 0x48, 0xb0, 0x01, 0x47, 0x63, 0x23, 0xae, 0xd8, 0x4c,
+0x47
+},
+.rv = 0,
+},
+{
+.keylen = AES192_KEYLEN,
+.noncelen = 13,
+.adatalen = 32,
+.payloadlen = 24,
+.taglen = 16,
+.key = (unsigned char []){
+0x26, 0x51, 0x1f, 0xb5, 0x1f, 0xcf, 0xa7, 0x5c, 0xb4, 0xb4, 0x4d, 0xa7, 0x5a,
+0x6e, 0x5a, 0x0e
+},
+.nonce = (unsigned char []){
+0x5a, 0x16, 0xa8, 0x90, 0x2b, 0xd7, 0x0f, 0xa0, 0x6c, 0xfe, 0x18, 0x4c, 0x57
+},
+.adata = (unsigned char []){
+0x39, 0x9d, 0x6b, 0x06, 0x52, 0x83, 0x64, 0x57, 0xec, 0x4f, 0x70, 0x1f, 0x0d,
+0xc0, 0xe5, 0xae, 0xd7, 0x3d, 0x16, 0x58, 0x5d, 0x61, 0xcb, 0x1b, 0xb5, 0xb7,
+0xee, 0x82, 0x4f, 0xc2, 0x87, 0xc8
+},
+.payload = NULL,
+.ciphertext = (unsigned char []){
+0x9d, 0x99, 0x3b, 0x94, 0x54, 0x76, 0xac, 0xe0, 0xb9, 0xca, 0x93, 0x29, 0x63,
+0xac, 0x88, 0x35, 0xe1, 0xbd, 0x02, 0xe8, 0x06, 0x5d, 0xa2, 0xd8, 0x16, 0x78,
+0x6c, 0x4d, 0x8c, 0xf1, 0x4c, 0x03, 0xb0, 0x31, 0xff, 0x72, 0x33, 0x11, 0xb3,
+0xc4
+},
+.rv = EFAULT,
+},
+{
+.keylen = AES192_KEYLEN,
+.noncelen = 13,
+.adatalen = 32,
+.payloadlen = 24,
+.taglen = 16,
+.key = (unsigned char []){
+0x26, 0x51, 0x1f, 0xb5, 0x1f, 0xcf, 0xa7, 0x5c, 0xb4, 0xb4, 0x4d, 0xa7, 0x5a,
+0x6e, 0x5a, 0x0e, 0xb8, 0xd9, 0xc8, 0xf3, 0xb9, 0x06, 0xf8, 0x86
+},
+.nonce = (unsigned char []){
+0xea, 0x98, 0xec, 0x44, 0xf5, 0xa8, 0x67, 0x15, 0x01, 0x47, 0x83, 0x17, 0x2e
+},
+.adata = (unsigned char []){
+0xe4, 0x69, 0x2b, 0x9f, 0x06, 0xb6, 0x66, 0xc7, 0x45, 0x1b, 0x14, 0x6c, 0x8a,
+0xeb, 0x07, 0xa6, 0xe3, 0x0c, 0x62, 0x9d, 0x28, 0x06, 0x5c, 0x3d, 0xde, 0x59,
+0x40, 0x32, 0x5b, 0x14, 0xb8, 0x10
+},
+.payload = (unsigned char []){
+0x4d, 0xa4, 0x0b, 0x80, 0x57, 0x9c, 0x1d, 0x9a, 0x53, 0x09, 0xf7, 0xef, 0xec,
+0xb7, 0xc0, 0x59, 0xa2, 0xf9, 0x14, 0x51, 0x1c, 0xa5, 0xfc, 0x10
+},
+.ciphertext = (unsigned char []){
+0x30, 0xc1, 0x54, 0xc6, 0x16, 0x94, 0x6e, 0xcc, 0xc2, 0xe2, 0x41, 0xd3, 0x36,
+0xad, 0x33, 0x72, 0x09, 0x53, 0xe4, 0x49, 0xa0, 0xe6, 0xb0, 0xf0, 0xdb, 0xf8,
+0xe9, 0x46, 0x49, 0x09, 0xbd, 0xf3, 0x37, 0xe4, 0x80, 0x93, 0xc0, 0x82, 0xa1,
+0x0b
+},
+.rv = 0,
+},
+{
+.keylen = AES192_KEYLEN,
+.noncelen = 13,
+.adatalen = 32,
+.payloadlen = 24,
+.taglen = 16,
+.key = (unsigned char []){
+0x26, 0x51, 0x1f, 0xb5, 0x1f, 0xcf, 0xa7, 0x5c, 0xb4, 0xb4, 0x4d, 0xa7, 0x5a,
+0x6e, 0x5a, 0x0e, 0xb8, 0xd9, 0xc8, 0xf3, 0xb9, 0x06, 0xf8, 0x86
+},
+.nonce = (unsigned char []){
+0x5a, 0x16, 0xa8, 0x90, 0x2b, 0xd7, 0x0f, 0xa0, 0x6c, 0xfe, 0x18, 0x4c, 0x57
+},
+.adata = (unsigned char []){
+0x39, 0x9d, 0x6b, 0x06, 0x52, 0x83, 0x64, 0x57, 0xec, 0x4f, 0x70, 0x1f, 0x0d,
+0xc0, 0xe5, 0xae, 0xd7, 0x3d, 0x16, 0x58, 0x5d, 0x61, 0xcb, 0x1b, 0xb5, 0xb7,
+0xee, 0x82, 0x4f, 0xc2, 0x87, 0xc8
+},
+.payload = NULL,
+.ciphertext = (unsigned char []){
+0x0c, 0x95, 0xb6, 0x92, 0xb0, 0x7b, 0x39, 0x03, 0x9b, 0x40, 0xc8, 0x0c, 0xf5,
+0x2f, 0xf7, 0x16, 0x08, 0xae, 0x87, 0xc9, 0x73, 0xac, 0x9c, 0xcb, 0x88, 0xbb,
+0xa8, 0xf2, 0x04, 0xbb, 0x98, 0xb1, 0x7c, 0xb3, 0xc8, 0x64, 0x4e, 0x47, 0x2b,
+0x1e
+},
+.rv = EFAULT,
+},
+{
+.keylen = AES256_KEYLEN,
+.noncelen = 13,
+.adatalen = 32,
+.payloadlen = 24,
+.taglen = 16,
+.key = (unsigned char []){
+0x31, 0x4a, 0x20, 0x2f, 0x83, 0x6f, 0x9f, 0x25, 0x7e, 0x22, 0xd8, 0xc1, 0x17,
+0x57, 0x83, 0x2a, 0xe5, 0x13, 0x1d, 0x35, 0x7a, 0x72, 0xdf, 0x88, 0xf3, 0xef,
+0xf0, 0xff, 0xce, 0xe0, 0xda, 0x4e
+},
+.nonce = (unsigned char []){
+0x35, 0x42, 0xfb, 0xe0, 0xf5, 0x9a, 0x6d, 0x5f, 0x3a, 0xbf, 0x61, 0x9b, 0x7d
+},
+.adata = (unsigned char []){
+0xdd, 0x45, 0x31, 0xf1, 0x58, 0xa2, 0xfa, 0x3b, 0xc8, 0xa3, 0x39, 0xf7, 0x70,
+0x59, 0x50, 0x48, 0xf4, 0xa4, 0x2b, 0xc1, 0xb0, 0x3f, 0x2e, 0x82, 0x4e, 0xfc,
+0x6b, 0xa4, 0x98, 0x51, 0x19, 0xd8
+},
+.payload = (unsigned char []){
+0xc5, 0xb3, 0xd7, 0x13, 0x12, 0xea, 0x14, 0xf2, 0xf8, 0xfa, 0xe5, 0xbd, 0x1a,
+0x45, 0x31, 0x92, 0xb6, 0x60, 0x4a, 0x45, 0xdb, 0x75, 0xc5, 0xed
+},
+.ciphertext = (unsigned char []){
+0x39, 0xc2, 0xe8, 0xf6, 0xed, 0xfe, 0x66, 0x3b, 0x90, 0x96, 0x3b, 0x98, 0xeb,
+0x79, 0xe2, 0xd4, 0xf7, 0xf2, 0x8a, 0x50, 0x53, 0xae, 0x88, 0x81, 0x56, 0x7a,
+0x6b, 0x44, 0x26, 0xf1, 0x66, 0x71, 0x36, 0xbe, 0xd4, 0xa5, 0xe3, 0x2a, 0x2b,
+0xc1
+},
+.rv = 0,
+},
+{
+.keylen = AES256_KEYLEN,
+.noncelen = 13,
+.adatalen = 32,
+.payloadlen = 24,
+.taglen = 16,
+.key = (unsigned char []){
+0x31, 0x4a, 0x20, 0x2f, 0x83, 0x6f, 0x9f, 0x25, 0x7e, 0x22, 0xd8, 0xc1, 0x17,
+0x57, 0x83, 0x2a, 0xe5, 0x13, 0x1d, 0x35, 0x7a, 0x72, 0xdf, 0x88, 0xf3, 0xef,
+0xf0, 0xff, 0xce, 0xe0, 0xda, 0x4e
+},
+.nonce = (unsigned char []){
+0x48, 0xf2, 0xd4, 0xc0, 0xb1, 0x70, 0x72, 0xe0, 0xa9, 0xc3, 0x00, 0xd9, 0x0b
+},
+.adata = (unsigned char []){
+0xc5, 0x61, 0x75, 0xe2, 0xcf, 0xe0, 0xd3, 0x74, 0x54, 0xd9, 0x89, 0xaf, 0xcc,
+0x36, 0x68, 0x6f, 0xb3, 0x4c, 0x01, 0x54, 0x39, 0x60, 0x15, 0x67, 0x50, 0x6a,
+0x4d, 0x00, 0x03, 0x18, 0x2b, 0xe7
+},
+.payload = NULL,
+.ciphertext = (unsigned char []){
+0x27, 0xc5, 0x75, 0xbe, 0x0b, 0x99, 0xaf, 0x9b, 0x10, 0x6f, 0x53, 0xf4, 0x71,
+0xc3, 0x1c, 0xac, 0x4d, 0x54, 0xea, 0x0b, 0xcb, 0x60, 0x2a, 0x33, 0xfb, 0x67,
+0xbb, 0x60, 0x92, 0xcd, 0x57, 0x9f, 0x72, 0x2a, 0xe9, 0xb6, 0x80, 0xda, 0x08,
+0x3d
+},
+.rv = EFAULT,
+},
+};
+
+const struct aes_ecb_tv AES_ECB_TV[] = {
+{
+.keylen = AES128_KEYLEN,
+.len = 160,
+.key = (unsigned char []){
+0x44, 0xf0, 0xee, 0x62, 0x6d, 0x04, 0x46, 0xe0, 0xa3, 0x92, 0x4c, 0xfb, 0x07,
+0x89, 0x44, 0xbb
+},
+.plaintext = (unsigned char []){
+0x9c, 0x29, 0xee, 0xcb, 0x2d, 0xe0, 0x42, 0x54, 0xfa, 0xfb, 0x89, 0x6a, 0x99,
+0x41, 0x02, 0xd1, 0xda, 0x30, 0xdd, 0xb4, 0x9d, 0x82, 0x72, 0x8e, 0xb2, 0x3d,
+0xbd, 0x02, 0x99, 0x01, 0xe9, 0xb7, 0x5b, 0x3d, 0x0a, 0xee, 0x03, 0xf7, 0xa0,
+0x5f, 0x6c, 0x85, 0x2d, 0x8f, 0xad, 0xa0, 0xb5, 0xc2, 0x8e, 0x8c, 0x9a, 0xed,
+0x33, 0x4f, 0xad, 0x11, 0x82, 0x9d, 0xf3, 0xdf, 0xad, 0xc5, 0xc2, 0xe4, 0x71,
+0xeb, 0x41, 0xaf, 0x9e, 0x48, 0xa8, 0xa4, 0x65, 0xe0, 0x3d, 0x5e, 0xbd, 0xb0,
+0x21, 0x69, 0x15, 0x08, 0x1f, 0x3b, 0x5a, 0x0e, 0xbb, 0x23, 0x08, 0xdf, 0xc2,
+0xd2, 0x8e, 0x5a, 0x8b, 0xa3, 0xf3, 0x2a, 0xda, 0xe4, 0xc3, 0x57, 0x59, 0x21,
+0xbc, 0x65, 0x7b, 0x63, 0xd4, 0x6b, 0xa5, 0xa6, 0x18, 0x88, 0x0e, 0xe9, 0xad,
+0x8a, 0xf3, 0xfb, 0xa5, 0x64, 0x3a, 0x50, 0x26, 0xfa, 0xcd, 0x7d, 0x66, 0x7c,
+0xe5, 0x99, 0x32, 0x7f, 0x93, 0x6c, 0xdd, 0xa7, 0xe1, 0xbb, 0x74, 0x2a, 0x33,
+0xa0, 0x19, 0x99, 0x0b, 0x76, 0xbe, 0x64, 0x8a, 0x6e, 0xc7, 0x25, 0xda, 0xed,
+0x54, 0x0e, 0xd9, 0xe7
+},
+.ciphertext = (unsigned char []){
+0x93, 0x1b, 0x2f, 0x5f, 0x3a, 0x58, 0x20, 0xd5, 0x3a, 0x6b, 0xea, 0xaa, 0x64,
+0x31, 0x08, 0x3a, 0x34, 0x88, 0xf4, 0xeb, 0x03, 0xb0, 0xf5, 0xb5, 0x7e, 0xf8,
+0x38, 0xe1, 0x57, 0x96, 0x23, 0x10, 0x3b, 0xd6, 0xe6, 0x80, 0x03, 0x77, 0x53,
+0x8b, 0x2e, 0x51, 0xef, 0x70, 0x8f, 0x3c, 0x49, 0x56, 0x43, 0x2e, 0x8a, 0x8e,
+0xe6, 0xa3, 0x4e, 0x19, 0x06, 0x42, 0xb2, 0x6a, 0xd8, 0xbd, 0xae, 0x6c, 0x2a,
+0xf9, 0xa6, 0xc7, 0x99, 0x6f, 0x3b, 0x60, 0x04, 0xd2, 0x67, 0x1e, 0x41, 0xf1,
+0xc9, 0xf4, 0x0e, 0xe0, 0x3d, 0x1c, 0x4a, 0x52, 0xb0, 0xa0, 0x65, 0x4a, 0x33,
+0x1f, 0x15, 0xf3, 0x4d, 0xce, 0x4a, 0xcb, 0x96, 0xbd, 0x65, 0x07, 0x81, 0x5c,
+0xa4, 0x34, 0x7a, 0x3d, 0xe1, 0x1a, 0x31, 0x1b, 0x7d, 0xe5, 0x35, 0x1c, 0x97,
+0x87, 0xc4, 0x53, 0x81, 0x58, 0xe2, 0x89, 0x74, 0xff, 0xa8, 0x3d, 0x82, 0x96,
+0xdf, 0xe9, 0xcd, 0x09, 0xcd, 0x87, 0xf7, 0xbf, 0x4f, 0x54, 0xd9, 0x7d, 0x28,
+0xd4, 0x78, 0x87, 0x99, 0x16, 0x34, 0x08, 0x32, 0x39, 0x43, 0xb3, 0xe7, 0x2f,
+0x5e, 0xab, 0x66, 0xc1
+},
+},
+{
+.keylen = AES192_KEYLEN,
+.len = 160,
+.key = (unsigned char []){
+0x9c, 0xc2, 0x4e, 0xa1, 0xf1, 0x95, 0x9d, 0x9a, 0x97, 0x2e, 0x71, 0x82, 0xef,
+0x3b, 0x4e, 0x22, 0xa9, 0x7a, 0x87, 0xd0, 0xda, 0x7f, 0xf6, 0x4b
+},
+.plaintext = (unsigned char []){
+0xb8, 0xbb, 0x5c, 0xe5, 0x3a, 0x15, 0xaa, 0x6d, 0xfd, 0xf2, 0xcb, 0x61, 0xbc,
+0x8e, 0x36, 0x17, 0xd1, 0xd0, 0xfe, 0xfe, 0x9b, 0xa5, 0xd1, 0x75, 0x55, 0x04,
+0x70, 0xe3, 0x23, 0x97, 0xf6, 0xf3, 0xb3, 0xe6, 0x5b, 0x43, 0xbd, 0xed, 0x2b,
+0x21, 0xe5, 0xc1, 0x81, 0xd3, 0xc4, 0xc4, 0xc5, 0x26, 0xc4, 0x1c, 0xea, 0xb0,
+0x44, 0x28, 0x95, 0x08, 0x45, 0x80, 0x48, 0xb6, 0x33, 0x52, 0xdf, 0xc3, 0x79,
+0xde, 0x37, 0x3f, 0xd1, 0x9a, 0x2c, 0x90, 0x0c, 0x43, 0x52, 0x4b, 0x75, 0x94,
+0x9e, 0x67, 0x7c, 0xce, 0xda, 0x86, 0x6f, 0x7f, 0x2b, 0xcc, 0x48, 0x44, 0xef,
+0x2e, 0x5d, 0xac, 0x5b, 0x80, 0x4b, 0x40, 0x45, 0xe6, 0x57, 0xc8, 0x15, 0x6d,
+0x1d, 0xcd, 0xb4, 0x3c, 0xbf, 0x2f, 0x5e, 0x00, 0xa4, 0xf9, 0x25, 0x5e, 0x3b,
+0xe2, 0x43, 0x94, 0x36, 0xc4, 0xd0, 0x44, 0x9a, 0x8d, 0x2c, 0x4c, 0x1a, 0x56,
+0xbe, 0xce, 0x98, 0xea, 0x0f, 0xd6, 0x8a, 0xba, 0xf1, 0x23, 0x98, 0x03, 0x99,
+0x94, 0xae, 0xbf, 0xfc, 0x69, 0x2b, 0x90, 0x00, 0xe5, 0x80, 0x47, 0x9b, 0x4f,
+0x4b, 0x28, 0xb5, 0xfe
+},
+.ciphertext = (unsigned char []){
+0x95, 0x2f, 0x45, 0x46, 0xa8, 0xbf, 0x71, 0x66, 0x96, 0x49, 0x17, 0xec, 0xe0,
+0x1b, 0xda, 0x3c, 0x68, 0x57, 0xe4, 0x27, 0xce, 0xf5, 0xda, 0x0f, 0xf9, 0x0b,
+0x0e, 0x4b, 0xf4, 0x4c, 0xf7, 0xcc, 0xfc, 0xcf, 0xdf, 0x01, 0xd7, 0x13, 0xdc,
+0xf9, 0x67, 0x3f, 0x01, 0xc8, 0x7e, 0xae, 0xd5, 0x2b, 0xf4, 0xaa, 0x04, 0x6f,
+0xf7, 0x78, 0x55, 0x8e, 0xa3, 0x96, 0xdc, 0x9c, 0xd2, 0x40, 0x71, 0x61, 0x36,
+0x38, 0x61, 0x48, 0xa5, 0xc7, 0x63, 0x78, 0xb3, 0xff, 0xcd, 0x40, 0x86, 0x44,
+0x07, 0xb8, 0xe6, 0x0b, 0x40, 0xa5, 0x94, 0xe0, 0x61, 0x9e, 0xdd, 0xae, 0x3f,
+0x6d, 0x6e, 0x3b, 0x15, 0xb8, 0x6a, 0xf2, 0x31, 0xe1, 0xba, 0xe5, 0xed, 0x2a,
+0xa5, 0x12, 0xe1, 0x1d, 0xa0, 0xe5, 0x57, 0x2b, 0x67, 0xff, 0xff, 0x93, 0x4c,
+0x36, 0xe5, 0x85, 0xcf, 0xdd, 0x9f, 0x87, 0x70, 0x45, 0xcb, 0x19, 0xc1, 0x83,
+0xb9, 0x94, 0xbf, 0x74, 0x64, 0x58, 0x62, 0xff, 0xa7, 0x26, 0x73, 0x9a, 0xad,
+0xcb, 0x9e, 0x10, 0xaa, 0xff, 0xc8, 0x81, 0xc8, 0x8c, 0xa3, 0xaa, 0x65, 0xb3,
+0x7f, 0x66, 0x7b, 0xcb
+},
+},
+{
+.keylen = AES256_KEYLEN,
+.len = 160,
+.key = (unsigned char []){
+0xc4, 0xa7, 0x1e, 0x05, 0x5a, 0x72, 0x54, 0xdd, 0xa3, 0x60, 0x69, 0x3f, 0xe1,
+0xbe, 0x49, 0xf1, 0x0f, 0xaa, 0x67, 0x31, 0xc3, 0x6d, 0xba, 0xa6, 0x59, 0x0b,
+0x05, 0x97, 0x4e, 0x18, 0x5c, 0x5b
+},
+.plaintext = (unsigned char []){
+0x31, 0xfd, 0x5a, 0x30, 0x7e, 0x27, 0x9b, 0x2f, 0x34, 0x58, 0x1e, 0x2c, 0x43,
+0x23, 0x79, 0xdf, 0x8e, 0xcc, 0xba, 0xf7, 0x95, 0x32, 0x93, 0x89, 0x16, 0x71,
+0x1c, 0xd3, 0x77, 0x54, 0x0b, 0x90, 0x45, 0x37, 0x3e, 0x47, 0xf2, 0x21, 0x4b,
+0x8f, 0x87, 0x60, 0x40, 0xaf, 0x73, 0x3f, 0x6c, 0x9d, 0x8f, 0x03, 0xa7, 0xc5,
+0x8f, 0x87, 0x14, 0xd2, 0xfb, 0xb4, 0xc1, 0x4a, 0xf5, 0x9c, 0x75, 0xb4, 0x83,
+0xad, 0xc7, 0x18, 0x94, 0x6e, 0xe9, 0x07, 0xa1, 0x82, 0x86, 0xcc, 0x4e, 0xfd,
+0x20, 0x67, 0x89, 0x06, 0x4b, 0x6f, 0x1b, 0x19, 0x5f, 0x0d, 0x0d, 0x23, 0x44,
+0x68, 0xe4, 0xf0, 0x0e, 0x6f, 0x1c, 0xad, 0x5c, 0xd3, 0xb9, 0xc0, 0xa6, 0x43,
+0xb3, 0xc0, 0xdd, 0x09, 0x28, 0x0f, 0xf2, 0xe2, 0xa5, 0x92, 0x91, 0x83, 0x40,
+0x93, 0x84, 0xdd, 0x72, 0xdc, 0x94, 0xe3, 0x96, 0x87, 0xea, 0x2b, 0x62, 0x3d,
+0x5d, 0x77, 0x67, 0x00, 0xbd, 0x8b, 0x36, 0xe6, 0x13, 0x0f, 0xfd, 0xe9, 0x66,
+0xf1, 0x34, 0xc4, 0xb1, 0xf3, 0x5f, 0x29, 0xc5, 0xcc, 0x4a, 0x03, 0x29, 0x7e,
+0x1c, 0xcc, 0x95, 0x39
+},
+.ciphertext = (unsigned char []){
+0x2c, 0x48, 0x7f, 0xa9, 0x6f, 0x40, 0x90, 0xc5, 0x6a, 0xa1, 0xb5, 0xbe, 0x81,
+0x91, 0x8a, 0x93, 0x4c, 0x94, 0x92, 0x87, 0x8f, 0xb0, 0xcd, 0x68, 0x6d, 0xcf,
+0x8d, 0x17, 0xd8, 0x64, 0x85, 0x45, 0x4c, 0x51, 0x23, 0x7b, 0xbd, 0x09, 0x20,
+0x5d, 0xce, 0xf1, 0x55, 0x2f, 0x43, 0x0d, 0xd0, 0x98, 0xb9, 0xd8, 0x27, 0xa6,
+0x94, 0x73, 0x0c, 0x13, 0x3a, 0x02, 0x22, 0xc7, 0x7f, 0x54, 0x0f, 0x9d, 0x5f,
+0xc2, 0xd3, 0x6a, 0xf3, 0x59, 0x58, 0x3c, 0x9e, 0x3b, 0x49, 0xdf, 0x88, 0x42,
+0x28, 0xa6, 0x4d, 0xe7, 0x9b, 0x67, 0xf6, 0x62, 0x07, 0xc8, 0x28, 0x13, 0x60,
+0xb9, 0x9b, 0x21, 0x40, 0x42, 0xce, 0x61, 0x36, 0x7f, 0xf9, 0x79, 0x60, 0xe9,
+0x44, 0x45, 0x3c, 0xd6, 0x36, 0x79, 0xbb, 0x44, 0x70, 0x88, 0x97, 0xd2, 0x9b,
+0xc5, 0xe7, 0x0f, 0x9f, 0xc8, 0xf1, 0xf7, 0x15, 0x14, 0x3f, 0xbb, 0x00, 0xf7,
+0xf5, 0xc1, 0xb7, 0xb1, 0x61, 0xec, 0x26, 0xd8, 0xd4, 0x1d, 0x36, 0xfa, 0xb0,
+0xfa, 0x8a, 0x85, 0xc3, 0xee, 0x6c, 0xe4, 0xd3, 0x70, 0x07, 0xeb, 0x7a, 0x89,
+0xd6, 0x75, 0x35, 0x90
+},
+},
+};
+
+const struct aes_cbc_tv AES_CBC_TV[] = {
+{
+.keylen = AES128_KEYLEN,
+.len = 160,
+.key = (unsigned char []){
+0x97, 0xa1, 0x02, 0x55, 0x29, 0xb9, 0x92, 0x5e, 0x25, 0xbb, 0xe7, 0x87, 0x70,
+0xca, 0x2f, 0x99
+},
+.iv = {
+0xd4, 0xb4, 0xea, 0xb9, 0x2a, 0xa9, 0x63, 0x7e, 0x87, 0xd3, 0x66, 0x38, 0x4e,
+0xd6, 0x91, 0x5c
+},
+.plaintext = (unsigned char []){
+0xe8, 0xb8, 0x91, 0x50, 0xd8, 0x43, 0x8b, 0xf5, 0xb1, 0x74, 0x49, 0xd6, 0xed,
+0x26, 0xbd, 0x72, 0x12, 0x7e, 0x10, 0xe4, 0xaa, 0x57, 0xca, 0xd8, 0x52, 0x83,
+0xe8, 0x35, 0x9e, 0x08, 0x92, 0x08, 0xe8, 0x49, 0x21, 0x64, 0x9f, 0x5b, 0x60,
+0xea, 0x21, 0xf7, 0x86, 0x7c, 0xbc, 0x96, 0x20, 0x56, 0x0c, 0x4c, 0x62, 0x38,
+0xdb, 0x02, 0x12, 0x16, 0xdb, 0x45, 0x3c, 0x99, 0x43, 0xf1, 0xf1, 0xa6, 0x05,
+0x46, 0x17, 0x3d, 0xae, 0xf2, 0x55, 0x7c, 0x3c, 0xdd, 0x85, 0x50, 0x31, 0xb3,
+0x53, 0xd4, 0xbf, 0x17, 0x6f, 0x28, 0x43, 0x9e, 0x48, 0x78, 0x5c, 0x37, 0xd3,
+0x8f, 0x27, 0x0a, 0xa4, 0xa6, 0xfa, 0xad, 0x2b, 0xaa, 0xbc, 0xb0, 0xc0, 0xb2,
+0xd1, 0xdd, 0x53, 0x22, 0x93, 0x74, 0x98, 0xce, 0x80, 0x3b, 0xa1, 0x14, 0x84,
+0x40, 0xa5, 0x2e, 0x22, 0x7d, 0xdb, 0xa4, 0x87, 0x2f, 0xe4, 0xd8, 0x1d, 0x2d,
+0x76, 0xa9, 0x39, 0xd2, 0x47, 0x55, 0xad, 0xb8, 0xa7, 0xb8, 0x45, 0x2c, 0xee,
+0xd2, 0xd1, 0x79, 0xe1, 0xa5, 0x84, 0x8f, 0x31, 0x6f, 0x5c, 0x01, 0x63, 0x00,
+0xa3, 0x90, 0xbf, 0xa7
+},
+.ciphertext = (unsigned char []){
+0x22, 0xcd, 0xc3, 0x30, 0x6f, 0xcd, 0x4d, 0x31, 0xcc, 0xd3, 0x27, 0x20, 0xcb,
+0xb6, 0x1b, 0xad, 0x28, 0xd8, 0x55, 0x67, 0x06, 0x57, 0xc4, 0x8c, 0x7b, 0x88,
+0xc3, 0x1f, 0x4f, 0xa1, 0xf9, 0x3c, 0x01, 0xb5, 0x7d, 0xa9, 0x0b, 0xe6, 0x3e,
+0xad, 0x67, 0xd6, 0xa3, 0x25, 0x52, 0x5e, 0x6e, 0xd4, 0x50, 0x83, 0xe6, 0xfb,
+0x70, 0xa5, 0x35, 0x29, 0xd1, 0xfa, 0x0f, 0x55, 0x65, 0x3b, 0x94, 0x2a, 0xf5,
+0x9d, 0x78, 0xa2, 0x66, 0x03, 0x61, 0xd6, 0x3a, 0x72, 0x90, 0x15, 0x5a, 0xc5,
+0xc4, 0x33, 0x12, 0xa2, 0x5b, 0x23, 0x5d, 0xac, 0xbb, 0xc8, 0x63, 0xfa, 0xf0,
+0x09, 0x40, 0xc9, 0x96, 0x24, 0x07, 0x6d, 0xfa, 0x44, 0x06, 0x8e, 0x7c, 0x55,
+0x4c, 0x90, 0x38, 0x17, 0x69, 0x53, 0xe5, 0x71, 0x75, 0x1d, 0xfc, 0x09, 0x54,
+0xd4, 0x1d, 0x11, 0x37, 0x71, 0xb0, 0x64, 0x66, 0xb1, 0xc8, 0xd1, 0x3e, 0x0d,
+0x4c, 0xb6, 0x75, 0xed, 0x58, 0xd1, 0xa6, 0x19, 0xe1, 0x54, 0x09, 0x70, 0x98,
+0x37, 0x81, 0xdc, 0x11, 0xd2, 0xdd, 0x85, 0x25, 0xab, 0x57, 0x45, 0x95, 0x8d,
+0x61, 0x5d, 0xef, 0xda
+},
+},
+{
+.keylen = AES192_KEYLEN,
+.len = 160,
+.key = (unsigned char []){
+0x50, 0x9b, 0xaf, 0x46, 0xfb, 0x9d, 0xe3, 0x42, 0x81, 0xda, 0xfc, 0xc3, 0xdb,
+0x79, 0x59, 0x3b, 0xff, 0xa8, 0x42, 0x69, 0x04, 0x30, 0x26, 0x88
+},
+.iv = {
+0xd6, 0xd8, 0x6e, 0x0c, 0x82, 0xdd, 0x87, 0x88, 0xf4, 0x14, 0x7a, 0x26, 0xf9,
+0xa7, 0x1c, 0x74
+},
+.plaintext = (unsigned char []){
+0x67, 0xd2, 0xdd, 0xa6, 0xda, 0x26, 0xe2, 0x13, 0x07, 0x97, 0x34, 0x00, 0x60,
+0x07, 0x25, 0x72, 0x7a, 0xe8, 0x14, 0x15, 0x51, 0x17, 0x72, 0xf4, 0xa0, 0x9a,
+0xd9, 0x90, 0x3b, 0xcf, 0x90, 0xcc, 0x2c, 0x0d, 0xac, 0x58, 0xba, 0x55, 0x9a,
+0x01, 0x09, 0xc5, 0x4a, 0x9d, 0x61, 0x17, 0xb1, 0x5b, 0xb5, 0x74, 0xca, 0x47,
+0x3e, 0x84, 0x80, 0x47, 0xe9, 0xa5, 0x4e, 0xe4, 0xab, 0xde, 0x76, 0xaf, 0xf9,
+0x84, 0x9c, 0x44, 0x10, 0x9d, 0x16, 0x1f, 0x46, 0x44, 0x2e, 0x16, 0x10, 0xd8,
+0xb0, 0x15, 0xcf, 0x36, 0xa0, 0x10, 0xed, 0x8e, 0xfa, 0x32, 0x07, 0xfd, 0xfc,
+0x8f, 0xcc, 0x54, 0x8f, 0x14, 0x5c, 0x02, 0x7e, 0x44, 0xc5, 0xb0, 0xec, 0x35,
+0xc9, 0x88, 0x6f, 0x4b, 0x9d, 0x65, 0x13, 0xa5, 0xbc, 0x10, 0xd0, 0xea, 0x6b,
+0xbb, 0xc2, 0x6f, 0x54, 0xb1, 0x83, 0xbc, 0xae, 0x27, 0xfb, 0x79, 0x9d, 0x88,
+0x72, 0xff, 0x74, 0x8f, 0xc4, 0x59, 0xd5, 0x5c, 0xfa, 0x25, 0x5a, 0xae, 0x29,
+0xd7, 0x1b, 0x07, 0x6d, 0x9b, 0x44, 0xc1, 0x4d, 0x5c, 0xeb, 0xa9, 0x33, 0x2a,
+0x76, 0x3d, 0x9c, 0x94
+},
+.ciphertext = (unsigned char []){
+0x69, 0x28, 0x29, 0x9c, 0x52, 0xb4, 0xf0, 0x47, 0x92, 0x6f, 0x8a, 0x54, 0x15,
+0x29, 0xda, 0x2d, 0x6b, 0xba, 0xa3, 0x99, 0x14, 0x3c, 0xed, 0x8e, 0xfb, 0x77,
+0xab, 0x47, 0x40, 0x9d, 0x9a, 0x95, 0x3a, 0x38, 0x6c, 0x7a, 0xbd, 0x60, 0x26,
+0xf4, 0x98, 0x31, 0xc7, 0x17, 0x62, 0x7c, 0x2a, 0x5e, 0x77, 0xbd, 0x2d, 0x43,
+0x3d, 0x4d, 0x13, 0x0d, 0xac, 0xd9, 0x27, 0xea, 0x0d, 0x13, 0xa2, 0x3d, 0x01,
+0xa7, 0xcf, 0x39, 0xc6, 0x71, 0x6d, 0xaf, 0xb6, 0xed, 0x55, 0x24, 0x10, 0xef,
+0x5d, 0x27, 0xfb, 0x94, 0x7b, 0xe2, 0xc8, 0x78, 0x2e, 0xee, 0x78, 0x29, 0x19,
+0x6c, 0x7e, 0xdc, 0xf1, 0x51, 0xc6, 0x5f, 0x9a, 0x01, 0xf5, 0x4f, 0x8d, 0x20,
+0xf3, 0x8b, 0x7d, 0xa4, 0xa7, 0xe8, 0x3a, 0x2f, 0x01, 0x27, 0xd5, 0x9d, 0x3e,
+0x24, 0x05, 0xd8, 0x67, 0x4f, 0xc9, 0xf4, 0x1b, 0x60, 0x4f, 0x78, 0x8f, 0x47,
+0x15, 0xf9, 0xd3, 0x62, 0x4e, 0xee, 0x57, 0xf3, 0x87, 0xbf, 0xad, 0xd1, 0x8a,
+0x1f, 0x90, 0x5e, 0x83, 0x9c, 0x26, 0xb8, 0x61, 0x74, 0x82, 0x34, 0x7f, 0xab,
+0x6d, 0x08, 0x84, 0x5a
+},
+},
+{
+.keylen = AES256_KEYLEN,
+.len = 160,
+.key = (unsigned char []){
+0x87, 0x72, 0x5b, 0xd4, 0x3a, 0x45, 0x60, 0x88, 0x14, 0x18, 0x07, 0x73, 0xf0,
+0xe7, 0xab, 0x95, 0xa3, 0xc8, 0x59, 0xd8, 0x3a, 0x21, 0x30, 0xe8, 0x84, 0x19,
+0x0e, 0x44, 0xd1, 0x4c, 0x69, 0x96
+},
+.iv = {
+0xe4, 0x96, 0x51, 0x98, 0x8e, 0xbb, 0xb7, 0x2e, 0xb8, 0xbb, 0x80, 0xbb, 0x9a,
+0xbb, 0xca, 0x34
+},
+.plaintext = (unsigned char []){
+0xbf, 0xe5, 0xc6, 0x35, 0x4b, 0x7a, 0x3f, 0xf3, 0xe1, 0x92, 0xe0, 0x57, 0x75,
+0xb9, 0xb7, 0x58, 0x07, 0xde, 0x12, 0xe3, 0x8a, 0x62, 0x6b, 0x8b, 0xf0, 0xe1,
+0x2d, 0x5f, 0xff, 0x78, 0xe4, 0xf1, 0x77, 0x5a, 0xa7, 0xd7, 0x92, 0xd8, 0x85,
+0x16, 0x2e, 0x66, 0xd8, 0x89, 0x30, 0xf9, 0xc3, 0xb2, 0xcd, 0xf8, 0x65, 0x4f,
+0x56, 0x97, 0x25, 0x04, 0x80, 0x31, 0x90, 0x38, 0x62, 0x70, 0xf0, 0xaa, 0x43,
+0x64, 0x5d, 0xb1, 0x87, 0xaf, 0x41, 0xfc, 0xea, 0x63, 0x9b, 0x1f, 0x80, 0x26,
+0xcc, 0xdd, 0x0c, 0x23, 0xe0, 0xde, 0x37, 0x09, 0x4a, 0x8b, 0x94, 0x1e, 0xcb,
+0x76, 0x02, 0x99, 0x8a, 0x4b, 0x26, 0x04, 0xe6, 0x9f, 0xc0, 0x42, 0x19, 0x58,
+0x5d, 0x85, 0x46, 0x00, 0xe0, 0xad, 0x6f, 0x99, 0xa5, 0x3b, 0x25, 0x04, 0x04,
+0x3c, 0x08, 0xb1, 0xc3, 0xe2, 0x14, 0xd1, 0x7c, 0xde, 0x05, 0x3c, 0xbd, 0xf9,
+0x1d, 0xaa, 0x99, 0x9e, 0xd5, 0xb4, 0x7c, 0x37, 0x98, 0x3b, 0xa3, 0xee, 0x25,
+0x4b, 0xc5, 0xc7, 0x93, 0x83, 0x7d, 0xaa, 0xa8, 0xc8, 0x5c, 0xfc, 0x12, 0xf7,
+0xf5, 0x4f, 0x69, 0x9f
+},
+.ciphertext = (unsigned char []){
+0x5b, 0x97, 0xa9, 0xd4, 0x23, 0xf4, 0xb9, 0x74, 0x13, 0xf3, 0x88, 0xd9, 0xa3,
+0x41, 0xe7, 0x27, 0xbb, 0x33, 0x9f, 0x8e, 0x18, 0xa3, 0xfa, 0xc2, 0xf2, 0xfb,
+0x85, 0xab, 0xdc, 0x8f, 0x13, 0x5d, 0xeb, 0x30, 0x05, 0x4a, 0x1a, 0xfd, 0xc9,
+0xb6, 0xed, 0x7d, 0xa1, 0x6c, 0x55, 0xeb, 0xa6, 0xb0, 0xd4, 0xd1, 0x0c, 0x74,
+0xe1, 0xd9, 0xa7, 0xcf, 0x8e, 0xdf, 0xae, 0xaa, 0x68, 0x4a, 0xc0, 0xbd, 0x9f,
+0x9d, 0x24, 0xba, 0x67, 0x49, 0x55, 0xc7, 0x9d, 0xc6, 0xbe, 0x32, 0xae, 0xe1,
+0xc2, 0x60, 0xb5, 0x58, 0xff, 0x07, 0xe3, 0xa4, 0xd4, 0x9d, 0x24, 0x16, 0x20,
+0x11, 0xff, 0x25, 0x4d, 0xb8, 0xbe, 0x07, 0x8e, 0x8a, 0xd0, 0x7e, 0x64, 0x8e,
+0x6b, 0xf5, 0x67, 0x93, 0x76, 0xcb, 0x43, 0x21, 0xa5, 0xef, 0x01, 0xaf, 0xe6,
+0xad, 0x88, 0x16, 0xfc, 0xc7, 0x63, 0x46, 0x69, 0xc8, 0xc4, 0x38, 0x92, 0x95,
+0xc9, 0x24, 0x1e, 0x45, 0xff, 0xf3, 0x9f, 0x32, 0x25, 0xf7, 0x74, 0x50, 0x32,
+0xda, 0xee, 0xbe, 0x99, 0xd4, 0xb1, 0x9b, 0xcb, 0x21, 0x5d, 0x1b, 0xfd, 0xb3,
+0x6e, 0xda, 0x2c, 0x24
+},
+},
+};
+
+const struct aes_cbc_cs_tv AES_CBC_CS_TV[] = {
+{
+.keylen = AES128_KEYLEN,
+.len = 47,
+.key = (unsigned char []){
+0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, 0x74, 0x65, 0x72, 0x69, 0x79,
+0x61, 0x6b, 0x69
+},
+.iv = {0},
+.iv_out = {
+0xb3, 0xff, 0xfd, 0x94, 0x0c, 0x16, 0xa1, 0x8c, 0x1b, 0x55, 0x49, 0xd2, 0xf8,
+0x38, 0x02, 0x9e
+},
+.plaintext = (unsigned char []){
+0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20,
+0x74, 0x68, 0x65, 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x47,
+0x61, 0x75, 0x27, 0x73, 0x20, 0x43, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x2c,
+0x20, 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x2c
+},
+.ciphertext = (unsigned char []){
+0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, 0xc0, 0x7b, 0x25, 0xe2, 0x5e,
+0xcf, 0xe5, 0x84, 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5, 0xbe, 0x7f,
+0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xb3, 0xff, 0xfd, 0x94, 0x0c, 0x16, 0xa1, 0x8c,
+0x1b, 0x55, 0x49, 0xd2, 0xf8, 0x38, 0x02, 0x9e
+},
+.variant = 1,
+},
+{
+.keylen = AES128_KEYLEN,
+.len = 47,
+.key = (unsigned char []){
+0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, 0x74, 0x65, 0x72, 0x69, 0x79,
+0x61, 0x6b, 0x69
+},
+.iv = {0},
+.iv_out = {
+0xb3, 0xff, 0xfd, 0x94, 0x0c, 0x16, 0xa1, 0x8c, 0x1b, 0x55, 0x49, 0xd2, 0xf8,
+0x38, 0x02, 0x9e
+},
+.plaintext = (unsigned char []){
+0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20,
+0x74, 0x68, 0x65, 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x47,
+0x61, 0x75, 0x27, 0x73, 0x20, 0x43, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x2c,
+0x20, 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x2c
+},
+.ciphertext = (unsigned char []){
+0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, 0xc0, 0x7b, 0x25, 0xe2, 0x5e,
+0xcf, 0xe5, 0x84, 0xb3, 0xff, 0xfd, 0x94, 0x0c, 0x16, 0xa1, 0x8c, 0x1b, 0x55,
+0x49, 0xd2, 0xf8, 0x38, 0x02, 0x9e, 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62,
+0xd5, 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5
+},
+.variant = 2,
+},
+{
+.keylen = AES128_KEYLEN,
+.len = 47,
+.key = (unsigned char []){
+0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, 0x74, 0x65, 0x72, 0x69, 0x79,
+0x61, 0x6b, 0x69
+},
+.iv = {0},
+.iv_out = {
+0xb3, 0xff, 0xfd, 0x94, 0x0c, 0x16, 0xa1, 0x8c, 0x1b, 0x55, 0x49, 0xd2, 0xf8,
+0x38, 0x02, 0x9e
+},
+.plaintext = (unsigned char []){
+0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20,
+0x74, 0x68, 0x65, 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x47,
+0x61, 0x75, 0x27, 0x73, 0x20, 0x43, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x2c,
+0x20, 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x2c
+},
+.ciphertext = (unsigned char []){
+0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, 0xc0, 0x7b, 0x25, 0xe2, 0x5e,
+0xcf, 0xe5, 0x84, 0xb3, 0xff, 0xfd, 0x94, 0x0c, 0x16, 0xa1, 0x8c, 0x1b, 0x55,
+0x49, 0xd2, 0xf8, 0x38, 0x02, 0x9e, 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62,
+0xd5, 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5
+},
+.variant = 3,
+},
+{
+.keylen = AES128_KEYLEN,
+.len = 64,
+.key = (unsigned char []){
+0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, 0x74, 0x65, 0x72, 0x69, 0x79,
+0x61, 0x6b, 0x69
+},
+.iv = {0},
+.iv_out = {
+0x48, 0x07, 0xef, 0xe8, 0x36, 0xee, 0x89, 0xa5, 0x26, 0x73, 0x0d, 0xbc, 0x2f,
+0x7b, 0xc8, 0x40
+},
+.plaintext = (unsigned char []){
+0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20,
+0x74, 0x68, 0x65, 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x47,
+0x61, 0x75, 0x27, 0x73, 0x20, 0x43, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x2c,
+0x20, 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20,
+0x77, 0x6f, 0x6e, 0x74, 0x6f, 0x6e, 0x20, 0x73, 0x6f, 0x75, 0x70, 0x2e
+},
+.ciphertext = (unsigned char []){
+0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, 0xc0, 0x7b, 0x25, 0xe2, 0x5e,
+0xcf, 0xe5, 0x84, 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5, 0xbe, 0x7f,
+0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8, 0x9d, 0xad, 0x8b, 0xbb, 0x96, 0xc4, 0xcd,
+0xc0, 0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8, 0x48, 0x07, 0xef, 0xe8,
+0x36, 0xee, 0x89, 0xa5, 0x26, 0x73, 0x0d, 0xbc, 0x2f, 0x7b, 0xc8, 0x40
+},
+.variant = 1,
+},
+{
+.keylen = AES128_KEYLEN,
+.len = 64,
+.key = (unsigned char []){
+0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, 0x74, 0x65, 0x72, 0x69, 0x79,
+0x61, 0x6b, 0x69
+},
+.iv = {0},
+.iv_out = {
+0x48, 0x07, 0xef, 0xe8, 0x36, 0xee, 0x89, 0xa5, 0x26, 0x73, 0x0d, 0xbc, 0x2f,
+0x7b, 0xc8, 0x40
+},
+.plaintext = (unsigned char []){
+0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20,
+0x74, 0x68, 0x65, 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x47,
+0x61, 0x75, 0x27, 0x73, 0x20, 0x43, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x2c,
+0x20, 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20,
+0x77, 0x6f, 0x6e, 0x74, 0x6f, 0x6e, 0x20, 0x73, 0x6f, 0x75, 0x70, 0x2e
+},
+.ciphertext = (unsigned char []){
+0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, 0xc0, 0x7b, 0x25, 0xe2, 0x5e,
+0xcf, 0xe5, 0x84, 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5, 0xbe, 0x7f,
+0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8, 0x9d, 0xad, 0x8b, 0xbb, 0x96, 0xc4, 0xcd,
+0xc0, 0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8, 0x48, 0x07, 0xef, 0xe8,
+0x36, 0xee, 0x89, 0xa5, 0x26, 0x73, 0x0d, 0xbc, 0x2f, 0x7b, 0xc8, 0x40
+},
+.variant = 2,
+},
+{
+.keylen = AES128_KEYLEN,
+.len = 64,
+.key = (unsigned char []){
+0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, 0x74, 0x65, 0x72, 0x69, 0x79,
+0x61, 0x6b, 0x69
+},
+.iv = {0},
+.iv_out = {
+0x48, 0x07, 0xef, 0xe8, 0x36, 0xee, 0x89, 0xa5, 0x26, 0x73, 0x0d, 0xbc, 0x2f,
+0x7b, 0xc8, 0x40
+},
+.plaintext = (unsigned char []){
+0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20,
+0x74, 0x68, 0x65, 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x47,
+0x61, 0x75, 0x27, 0x73, 0x20, 0x43, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x2c,
+0x20, 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20,
+0x77, 0x6f, 0x6e, 0x74, 0x6f, 0x6e, 0x20, 0x73, 0x6f, 0x75, 0x70, 0x2e
+},
+.ciphertext = (unsigned char []){
+0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, 0xc0, 0x7b, 0x25, 0xe2, 0x5e,
+0xcf, 0xe5, 0x84, 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5, 0xbe, 0x7f,
+0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8, 0x48, 0x07, 0xef, 0xe8, 0x36, 0xee, 0x89,
+0xa5, 0x26, 0x73, 0x0d, 0xbc, 0x2f, 0x7b, 0xc8, 0x40, 0x9d, 0xad, 0x8b, 0xbb,
+0x96, 0xc4, 0xcd, 0xc0, 0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8
+},
+.variant = 3,
+},
+};
+
+const struct des3_cbc_cs_tv DES3_CBC_CS_TV[] = {
+{
+.len = 71,
+.key = {
+0x2a, 0xe6, 0xae, 0x5d, 0x75, 0x34, 0x8f, 0x9d, 0x34, 0xc4, 0xfd, 0x45, 0x85,
+0xb6, 0xba, 0x8c, 0x9d, 0xef, 0x6e, 0xbf, 0xc7, 0x7f, 0xe0, 0x46
+},
+.iv = {
+0xa5, 0x2b, 0x66, 0xc3, 0x34, 0x38, 0x59, 0xe0
+},
+.plaintext = (unsigned char []){
+0x24, 0x19, 0x26, 0x42, 0xf7, 0xc7, 0x0e, 0x7d, 0x75, 0x69, 0xde, 0x8b, 0x86,
+0x20, 0x4a, 0x10, 0xa0, 0x76, 0xe3, 0xf3, 0x79, 0xbc, 0x7f, 0x8a, 0x52, 0x25,
+0xec, 0x4d, 0x76, 0xc0, 0x8a, 0xca, 0x40, 0xcd, 0xe8, 0x86, 0xf5, 0xd9, 0x9b,
+0xc0, 0xb6, 0x65, 0xa1, 0x79, 0x56, 0x37, 0x22, 0x19, 0xcd, 0x52, 0xcb, 0x73,
+0xec, 0x48, 0x62, 0xdf, 0x24, 0x2f, 0xb7, 0x65, 0xb1, 0x85, 0x3b, 0xc6, 0x25,
+0x82, 0x41, 0xe4, 0x1a, 0x1a, 0xd7
+},
+.ciphertext = (unsigned char []){
+0x95, 0x0e, 0x26, 0xc3, 0xf2, 0x46, 0xd7, 0xed, 0xff, 0xbd, 0xd3, 0x0e, 0x9a,
+0x2c, 0x08, 0x2b, 0x48, 0x53, 0x3f, 0xbf, 0x26, 0x29, 0xa9, 0x00, 0x23, 0x35,
+0xbb, 0x63, 0x6d, 0x3c, 0x3c, 0x62, 0x29, 0x1c, 0x9d, 0x7d, 0x67, 0xf8, 0x88,
+0x7f, 0x55, 0x95, 0xbb, 0x02, 0xb2, 0x04, 0x17, 0x35, 0x86, 0x82, 0xf4, 0xdd,
+0x11, 0x9c, 0xb8, 0x9a, 0x01, 0x97, 0xa8, 0x6c, 0xe8, 0x0e, 0xfe, 0xe7, 0x96,
+0x5f, 0x36, 0xfc, 0xc3, 0xd9, 0xa5
+},
+.variant = 1,
+},
+{
+.len = 71,
+.key = {
+0x2a, 0xe6, 0xae, 0x5d, 0x75, 0x34, 0x8f, 0x9d, 0x34, 0xc4, 0xfd, 0x45, 0x85,
+0xb6, 0xba, 0x8c, 0x9d, 0xef, 0x6e, 0xbf, 0xc7, 0x7f, 0xe0, 0x46
+},
+.iv = {
+0xa5, 0x2b, 0x66, 0xc3, 0x34, 0x38, 0x59, 0xe0
+},
+.plaintext = (unsigned char []){
+0x24, 0x19, 0x26, 0x42, 0xf7, 0xc7, 0x0e, 0x7d, 0x75, 0x69, 0xde, 0x8b, 0x86,
+0x20, 0x4a, 0x10, 0xa0, 0x76, 0xe3, 0xf3, 0x79, 0xbc, 0x7f, 0x8a, 0x52, 0x25,
+0xec, 0x4d, 0x76, 0xc0, 0x8a, 0xca, 0x40, 0xcd, 0xe8, 0x86, 0xf5, 0xd9, 0x9b,
+0xc0, 0xb6, 0x65, 0xa1, 0x79, 0x56, 0x37, 0x22, 0x19, 0xcd, 0x52, 0xcb, 0x73,
+0xec, 0x48, 0x62, 0xdf, 0x24, 0x2f, 0xb7, 0x65, 0xb1, 0x85, 0x3b, 0xc6, 0x25,
+0x82, 0x41, 0xe4, 0x1a, 0x1a, 0xd7
+},
+.ciphertext = (unsigned char []){
+0x95, 0x0e, 0x26, 0xc3, 0xf2, 0x46, 0xd7, 0xed, 0xff, 0xbd, 0xd3, 0x0e, 0x9a,
+0x2c, 0x08, 0x2b, 0x48, 0x53, 0x3f, 0xbf, 0x26, 0x29, 0xa9, 0x00, 0x23, 0x35,
+0xbb, 0x63, 0x6d, 0x3c, 0x3c, 0x62, 0x29, 0x1c, 0x9d, 0x7d, 0x67, 0xf8, 0x88,
+0x7f, 0x55, 0x95, 0xbb, 0x02, 0xb2, 0x04, 0x17, 0x35, 0x86, 0x82, 0xf4, 0xdd,
+0x11, 0x9c, 0xb8, 0x9a, 0xe7, 0x96, 0x5f, 0x36, 0xfc, 0xc3, 0xd9, 0xa5,
+0x01, 0x97, 0xa8, 0x6c, 0xe8, 0x0e, 0xfe
+},
+.variant = 2,
+},
+{
+.len = 71,
+.key = {
+0x2a, 0xe6, 0xae, 0x5d, 0x75, 0x34, 0x8f, 0x9d, 0x34, 0xc4, 0xfd, 0x45, 0x85,
+0xb6, 0xba, 0x8c, 0x9d, 0xef, 0x6e, 0xbf, 0xc7, 0x7f, 0xe0, 0x46
+},
+.iv = {
+0xa5, 0x2b, 0x66, 0xc3, 0x34, 0x38, 0x59, 0xe0
+},
+.plaintext = (unsigned char []){
+0x24, 0x19, 0x26, 0x42, 0xf7, 0xc7, 0x0e, 0x7d, 0x75, 0x69, 0xde, 0x8b, 0x86,
+0x20, 0x4a, 0x10, 0xa0, 0x76, 0xe3, 0xf3, 0x79, 0xbc, 0x7f, 0x8a, 0x52, 0x25,
+0xec, 0x4d, 0x76, 0xc0, 0x8a, 0xca, 0x40, 0xcd, 0xe8, 0x86, 0xf5, 0xd9, 0x9b,
+0xc0, 0xb6, 0x65, 0xa1, 0x79, 0x56, 0x37, 0x22, 0x19, 0xcd, 0x52, 0xcb, 0x73,
+0xec, 0x48, 0x62, 0xdf, 0x24, 0x2f, 0xb7, 0x65, 0xb1, 0x85, 0x3b, 0xc6, 0x25,
+0x82, 0x41, 0xe4, 0x1a, 0x1a, 0xd7
+},
+.ciphertext = (unsigned char []){
+0x95, 0x0e, 0x26, 0xc3, 0xf2, 0x46, 0xd7, 0xed, 0xff, 0xbd, 0xd3, 0x0e, 0x9a,
+0x2c, 0x08, 0x2b, 0x48, 0x53, 0x3f, 0xbf, 0x26, 0x29, 0xa9, 0x00, 0x23, 0x35,
+0xbb, 0x63, 0x6d, 0x3c, 0x3c, 0x62, 0x29, 0x1c, 0x9d, 0x7d, 0x67, 0xf8, 0x88,
+0x7f, 0x55, 0x95, 0xbb, 0x02, 0xb2, 0x04, 0x17, 0x35, 0x86, 0x82, 0xf4, 0xdd,
+0x11, 0x9c, 0xb8, 0x9a, 0xe7, 0x96, 0x5f, 0x36, 0xfc, 0xc3, 0xd9, 0xa5, 0x01,
+0x97, 0xa8, 0x6c, 0xe8, 0x0e, 0xfe
+},
+.variant = 3,
+},
+{
+.len = 72,
+.key = {
+0x2a, 0xe6, 0xae, 0x5d, 0x75, 0x34, 0x8f, 0x9d, 0x34, 0xc4, 0xfd, 0x45, 0x85,
+0xb6, 0xba, 0x8c, 0x9d, 0xef, 0x6e, 0xbf, 0xc7, 0x7f, 0xe0, 0x46
+},
+.iv = {
+0xa5, 0x2b, 0x66, 0xc3, 0x34, 0x38, 0x59, 0xe0
+},
+.plaintext = (unsigned char []){
+0x24, 0x19, 0x26, 0x42, 0xf7, 0xc7, 0x0e, 0x7d, 0x75, 0x69, 0xde, 0x8b, 0x86,
+0x20, 0x4a, 0x10, 0xa0, 0x76, 0xe3, 0xf3, 0x79, 0xbc, 0x7f, 0x8a, 0x52, 0x25,
+0xec, 0x4d, 0x76, 0xc0, 0x8a, 0xca, 0x40, 0xcd, 0xe8, 0x86, 0xf5, 0xd9, 0x9b,
+0xc0, 0xb6, 0x65, 0xa1, 0x79, 0x56, 0x37, 0x22, 0x19, 0xcd, 0x52, 0xcb, 0x73,
+0xec, 0x48, 0x62, 0xdf, 0x24, 0x2f, 0xb7, 0x65, 0xb1, 0x85, 0x3b, 0xc6, 0x25,
+0x82, 0x41, 0xe4, 0x1a, 0x1a, 0xd7, 0x15
+},
+.ciphertext = (unsigned char []){
+0x95, 0x0e, 0x26, 0xc3, 0xf2, 0x46, 0xd7, 0xed, 0xff, 0xbd, 0xd3, 0x0e, 0x9a,
+0x2c, 0x08, 0x2b, 0x48, 0x53, 0x3f, 0xbf, 0x26, 0x29, 0xa9, 0x00, 0x23, 0x35,
+0xbb, 0x63, 0x6d, 0x3c, 0x3c, 0x62, 0x29, 0x1c, 0x9d, 0x7d, 0x67, 0xf8, 0x88,
+0x7f, 0x55, 0x95, 0xbb, 0x02, 0xb2, 0x04, 0x17, 0x35, 0x86, 0x82, 0xf4, 0xdd,
+0x11, 0x9c, 0xb8, 0x9a, 0x01, 0x97, 0xa8, 0x6c, 0xe8, 0x0e, 0xfe, 0x75, 0xec,
+0xdd, 0x3b, 0x01, 0xc1, 0x3e, 0xbe, 0xc3
+},
+.variant = 1,
+},
+{
+.len = 72,
+.key = {
+0x2a, 0xe6, 0xae, 0x5d, 0x75, 0x34, 0x8f, 0x9d, 0x34, 0xc4, 0xfd, 0x45, 0x85,
+0xb6, 0xba, 0x8c, 0x9d, 0xef, 0x6e, 0xbf, 0xc7, 0x7f, 0xe0, 0x46
+},
+.iv = {
+0xa5, 0x2b, 0x66, 0xc3, 0x34, 0x38, 0x59, 0xe0
+},
+.plaintext = (unsigned char []){
+0x24, 0x19, 0x26, 0x42, 0xf7, 0xc7, 0x0e, 0x7d, 0x75, 0x69, 0xde, 0x8b, 0x86,
+0x20, 0x4a, 0x10, 0xa0, 0x76, 0xe3, 0xf3, 0x79, 0xbc, 0x7f, 0x8a, 0x52, 0x25,
+0xec, 0x4d, 0x76, 0xc0, 0x8a, 0xca, 0x40, 0xcd, 0xe8, 0x86, 0xf5, 0xd9, 0x9b,
+0xc0, 0xb6, 0x65, 0xa1, 0x79, 0x56, 0x37, 0x22, 0x19, 0xcd, 0x52, 0xcb, 0x73,
+0xec, 0x48, 0x62, 0xdf, 0x24, 0x2f, 0xb7, 0x65, 0xb1, 0x85, 0x3b, 0xc6, 0x25,
+0x82, 0x41, 0xe4, 0x1a, 0x1a, 0xd7, 0x15
+},
+.ciphertext = (unsigned char []){
+0x95, 0x0e, 0x26, 0xc3, 0xf2, 0x46, 0xd7, 0xed, 0xff, 0xbd, 0xd3, 0x0e, 0x9a,
+0x2c, 0x08, 0x2b, 0x48, 0x53, 0x3f, 0xbf, 0x26, 0x29, 0xa9, 0x00, 0x23, 0x35,
+0xbb, 0x63, 0x6d, 0x3c, 0x3c, 0x62, 0x29, 0x1c, 0x9d, 0x7d, 0x67, 0xf8, 0x88,
+0x7f, 0x55, 0x95, 0xbb, 0x02, 0xb2, 0x04, 0x17, 0x35, 0x86, 0x82, 0xf4, 0xdd,
+0x11, 0x9c, 0xb8, 0x9a, 0x01, 0x97, 0xa8, 0x6c, 0xe8, 0x0e, 0xfe, 0x75, 0xec,
+0xdd, 0x3b, 0x01, 0xc1, 0x3e, 0xbe, 0xc3
+},
+.variant = 2,
+},
+{
+.len = 72,
+.key = {
+0x2a, 0xe6, 0xae, 0x5d, 0x75, 0x34, 0x8f, 0x9d, 0x34, 0xc4, 0xfd, 0x45, 0x85,
+0xb6, 0xba, 0x8c, 0x9d, 0xef, 0x6e, 0xbf, 0xc7, 0x7f, 0xe0, 0x46
+},
+.iv = {
+0xa5, 0x2b, 0x66, 0xc3, 0x34, 0x38, 0x59, 0xe0
+},
+.plaintext = (unsigned char []){
+0x24, 0x19, 0x26, 0x42, 0xf7, 0xc7, 0x0e, 0x7d, 0x75, 0x69, 0xde, 0x8b, 0x86,
+0x20, 0x4a, 0x10, 0xa0, 0x76, 0xe3, 0xf3, 0x79, 0xbc, 0x7f, 0x8a, 0x52, 0x25,
+0xec, 0x4d, 0x76, 0xc0, 0x8a, 0xca, 0x40, 0xcd, 0xe8, 0x86, 0xf5, 0xd9, 0x9b,
+0xc0, 0xb6, 0x65, 0xa1, 0x79, 0x56, 0x37, 0x22, 0x19, 0xcd, 0x52, 0xcb, 0x73,
+0xec, 0x48, 0x62, 0xdf, 0x24, 0x2f, 0xb7, 0x65, 0xb1, 0x85, 0x3b, 0xc6, 0x25,
+0x82, 0x41, 0xe4, 0x1a, 0x1a, 0xd7, 0x15
+},
+.ciphertext = (unsigned char []){
+0x95, 0x0e, 0x26, 0xc3, 0xf2, 0x46, 0xd7, 0xed, 0xff, 0xbd, 0xd3, 0x0e, 0x9a,
+0x2c, 0x08, 0x2b, 0x48, 0x53, 0x3f, 0xbf, 0x26, 0x29, 0xa9, 0x00, 0x23, 0x35,
+0xbb, 0x63, 0x6d, 0x3c, 0x3c, 0x62, 0x29, 0x1c, 0x9d, 0x7d, 0x67, 0xf8, 0x88,
+0x7f, 0x55, 0x95, 0xbb, 0x02, 0xb2, 0x04, 0x17, 0x35, 0x86, 0x82, 0xf4, 0xdd,
+0x11, 0x9c, 0xb8, 0x9a, 0xec, 0xdd, 0x3b, 0x01, 0xc1, 0x3e, 0xbe, 0xc3, 0x01,
+0x97, 0xa8, 0x6c, 0xe8, 0x0e, 0xfe, 0x75,
+},
+.variant = 3,
+},
+};
+
+const struct aes_cfb_tv AES_CFB_TV[] = {
+{
+.keylen = AES128_KEYLEN,
+.len = 10,
+.lcfb = 1,
+.key = (unsigned char []){
+0x63, 0x99, 0xc1, 0xdc, 0x06, 0x8b, 0xa3, 0x50, 0x98, 0x45, 0x62, 0x8f, 0xa9,
+0xed, 0x1a, 0x96
+},
+.iv = {
+0x11, 0x57, 0xc2, 0x76, 0x6c, 0x86, 0xb7, 0x54, 0xdf, 0x48, 0x5b, 0xe9, 0xdd,
+0x58, 0x51, 0xdf
+},
+.plaintext = (unsigned char []){
+0xfe, 0xff, 0x4e, 0x2e, 0x24, 0x58, 0xad, 0xdf, 0x2a, 0x54
+},
+.ciphertext = (unsigned char []){
+0xc9, 0xc2, 0x84, 0xe9, 0xab, 0xbf, 0xe6, 0xfb, 0x11, 0xfe
+},
+},
+{
+.keylen = AES192_KEYLEN,
+.len = 10,
+.lcfb = 1,
+.key = (unsigned char []){
+0xba, 0xf0, 0x8b, 0x76, 0x31, 0x7a, 0x65, 0xc5, 0xf0, 0x7a, 0xe6, 0xf5, 0x7e,
+0xb0, 0xe6, 0x54, 0x88, 0x65, 0x93, 0x24, 0xd2, 0x97, 0x09, 0xe3
+},
+.iv = {
+0x0a, 0x02, 0x84, 0x6b, 0x62, 0xab, 0xb6, 0x93, 0xef, 0x31, 0xd7, 0x54, 0x84,
+0x2e, 0xed, 0x29
+},
+.plaintext = (unsigned char []){
+0x98, 0x95, 0x93, 0x24, 0x02, 0x39, 0x3d, 0xc3, 0x3a, 0x60
+},
+.ciphertext = (unsigned char []){
+0x72, 0x9c, 0x0b, 0x6d, 0xeb, 0x75, 0xfa, 0x6e, 0xb5, 0xe8
+},
+},
+{
+.keylen = AES256_KEYLEN,
+.len = 10,
+.lcfb = 1,
+.key = (unsigned char []){
+0xec, 0x13, 0x06, 0x25, 0x51, 0xe4, 0xd7, 0x29, 0x1e, 0x32, 0x0f, 0x56, 0x5b,
+0x74, 0x9e, 0xea, 0x18, 0x09, 0xb6, 0x63, 0xb2, 0x6f, 0x2c, 0x4d, 0x53, 0xb5,
+0x20, 0x58, 0xb8, 0x33, 0xe0, 0xad
+},
+.iv = {
+0xfb, 0xfa, 0x5a, 0x52, 0x8e, 0x20, 0x86, 0x30, 0x12, 0x79, 0x0c, 0x2a, 0xba,
+0xfb, 0x5a, 0x0c
+},
+.plaintext = (unsigned char []){
+0x54, 0x7b, 0xfd, 0x64, 0x2c, 0xf6, 0xe1, 0x2e, 0xd9, 0x42
+},
+.ciphertext = (unsigned char []){
+0x2b, 0xfc, 0x3f, 0x02, 0x09, 0x30, 0x71, 0x40, 0x10, 0x1a
+},
+},
+{
+.keylen = AES128_KEYLEN,
+.len = 160,
+.lcfb = 16,
+.key = (unsigned char []){
+0xae, 0xf4, 0x9d, 0xa3, 0x3f, 0x53, 0x8e, 0xe6, 0x6e, 0x17, 0x8d, 0x4b, 0x61,
+0x21, 0x05, 0x5d
+},
+.iv = {
+0x84, 0x25, 0x66, 0xe6, 0x8b, 0x61, 0xff, 0x7b, 0xf0, 0x01, 0xf2, 0x64, 0x2d,
+0xa6, 0x2f, 0x64
+},
+.plaintext = (unsigned char []){
+0x41, 0x59, 0x91, 0xf6, 0x5e, 0x1a, 0x95, 0x04, 0x0c, 0xef, 0x99, 0x60, 0x55,
+0x6f, 0x61, 0xe6, 0x17, 0x82, 0x7c, 0x30, 0xc7, 0x4b, 0xf3, 0x53, 0xcd, 0xd8,
+0x61, 0x73, 0xdb, 0xe4, 0xcc, 0x98, 0x3a, 0x2e, 0xe6, 0xbc, 0x8c, 0xa6, 0xcf,
+0xb7, 0x11, 0x21, 0xe7, 0xb0, 0xd0, 0x17, 0x8f, 0x2e, 0x13, 0x44, 0x5c, 0x71,
+0x0d, 0xcc, 0x17, 0x6b, 0x78, 0x12, 0x01, 0x97, 0x11, 0x71, 0xf7, 0x48, 0x9f,
+0x18, 0xfa, 0xf1, 0x10, 0xf3, 0x9a, 0xcc, 0xd1, 0xcf, 0x08, 0xc8, 0x5a, 0x95,
+0x8d, 0x76, 0x98, 0xb1, 0x16, 0xf1, 0xc0, 0xd7, 0x58, 0x12, 0xac, 0x9b, 0x0b,
+0x39, 0xae, 0xe7, 0xf7, 0x15, 0x9c, 0xca, 0xd8, 0xfd, 0xae, 0x9b, 0x99, 0xf2,
+0xd6, 0x95, 0xea, 0xcf, 0x12, 0xc6, 0x46, 0x9d, 0x5b, 0x51, 0xa3, 0x4d, 0xe2,
+0x6e, 0xac, 0x73, 0x61, 0x3d, 0xcb, 0x2f, 0x77, 0x12, 0x2c, 0xb1, 0xf8, 0xdd,
+0x51, 0x62, 0x78, 0x6a, 0x12, 0x05, 0x2d, 0xc7, 0xb6, 0xde, 0xa6, 0xac, 0xc4,
+0x98, 0x9d, 0xcc, 0x7e, 0xaf, 0xd9, 0x37, 0x4f, 0x6c, 0x29, 0x69, 0x7c, 0x74,
+0x74, 0x9e, 0xf1, 0x6d
+},
+.ciphertext = (unsigned char []){
+0x66, 0x25, 0x81, 0x14, 0x19, 0xbd, 0xee, 0x71, 0x53, 0x5f, 0x59, 0x7f, 0x7c,
+0x22, 0x8b, 0xaf, 0xd8, 0x90, 0xfd, 0x69, 0xb8, 0x05, 0xa6, 0x99, 0xed, 0x58,
+0x11, 0x6a, 0x82, 0xbd, 0xb2, 0x51, 0xab, 0xea, 0x7a, 0x4e, 0xf8, 0x79, 0xa9,
+0x6f, 0xce, 0x8e, 0xe4, 0x95, 0x18, 0xb9, 0x87, 0x7a, 0x3a, 0x1e, 0x3c, 0xf3,
+0x46, 0xd3, 0xcd, 0x73, 0x73, 0x89, 0x36, 0xd1, 0xcb, 0x6f, 0xff, 0x4b, 0x23,
+0x53, 0xc8, 0xca, 0x50, 0x0a, 0x26, 0x68, 0x98, 0x13, 0xad, 0x2f, 0x67, 0x77,
+0x4e, 0x23, 0x43, 0xf3, 0xe4, 0x83, 0x02, 0x59, 0x09, 0x4d, 0x3b, 0x34, 0x2e,
+0x00, 0xfa, 0xab, 0xeb, 0xa5, 0xb8, 0xa8, 0x93, 0x10, 0x8a, 0x39, 0x0c, 0x64,
+0x98, 0x36, 0xdd, 0xd5, 0xd1, 0x24, 0x89, 0xb2, 0xdd, 0x59, 0x1c, 0xa2, 0x53,
+0x61, 0x03, 0x2e, 0x2d, 0xa1, 0x20, 0x7f, 0x79, 0x3a, 0x1e, 0x69, 0x51, 0x30,
+0x02, 0xa9, 0x0c, 0xcc, 0x03, 0x6b, 0xb6, 0x3e, 0x9c, 0x10, 0xbe, 0x87, 0xdf,
+0x2d, 0xef, 0x96, 0x0c, 0xd7, 0xa1, 0xb1, 0x62, 0x1e, 0x31, 0x17, 0x35, 0xd7,
+0xae, 0xe4, 0x41, 0x9f
+},
+},
+{
+.keylen = AES192_KEYLEN,
+.len = 160,
+.lcfb = 16,
+.key = (unsigned char []){
+0xdc, 0xc8, 0x70, 0x21, 0x42, 0xb2, 0x9e, 0x15, 0x29, 0xf2, 0x3c, 0x5c, 0x37,
+0x66, 0x46, 0x4f, 0x6b, 0xe0, 0xd2, 0xfb, 0xb1, 0x6e, 0x46, 0x82
+},
+.iv = {
+0xe0, 0x81, 0x87, 0x69, 0xd7, 0x7f, 0x23, 0x15, 0x92, 0x4c, 0xf8, 0x1a, 0x36,
+0x91, 0xe2, 0x75
+},
+.plaintext = (unsigned char []){
+0xcb, 0x55, 0x01, 0x11, 0xbf, 0x0a, 0x03, 0xea, 0xf4, 0xf4, 0x9a, 0xf2, 0x14,
+0xfc, 0xc0, 0x5a, 0x32, 0x97, 0x2d, 0x7b, 0x4d, 0xed, 0xe3, 0xe9, 0x81, 0x2a,
+0x27, 0xef, 0x80, 0xd6, 0x80, 0x18, 0x81, 0x19, 0xea, 0xd5, 0x62, 0x31, 0x3e,
+0x40, 0x0f, 0xe0, 0xa0, 0xff, 0xfb, 0xb8, 0x8c, 0x55, 0xa4, 0x2b, 0xd6, 0x81,
+0xd5, 0xc9, 0x3a, 0x8a, 0x61, 0xba, 0x90, 0x90, 0x58, 0xe6, 0x2d, 0x99, 0xfa,
+0x10, 0x9c, 0xfd, 0x49, 0x93, 0x5b, 0x15, 0x08, 0x62, 0xa8, 0xaa, 0xb2, 0xc3,
+0x01, 0xb9, 0xb0, 0xa9, 0x15, 0x7c, 0x83, 0x84, 0x91, 0xcd, 0x73, 0x7a, 0xf4,
+0x38, 0xcb, 0x66, 0xb1, 0xf2, 0x04, 0x20, 0x20, 0x0d, 0xbc, 0x56, 0xaa, 0x66,
+0x55, 0x2c, 0xe4, 0xbe, 0x04, 0xca, 0xce, 0x4a, 0xce, 0x5b, 0xfb, 0xc6, 0x17,
+0xe3, 0xb2, 0x7f, 0x40, 0xec, 0x6d, 0xbc, 0x85, 0xa4, 0x2b, 0x41, 0x0d, 0xcb,
+0x7e, 0xa0, 0xb7, 0x8d, 0x47, 0x22, 0x97, 0xd9, 0xb9, 0x88, 0x75, 0xd6, 0x36,
+0xb8, 0xef, 0x08, 0xc2, 0x54, 0xec, 0x9b, 0xd0, 0x5b, 0xfd, 0xa0, 0x1b, 0xb3,
+0x8e, 0x8b, 0xeb, 0x6a
+},
+.ciphertext = (unsigned char []){
+0x1a, 0x22, 0xb1, 0xbf, 0x57, 0x75, 0xd4, 0x3c, 0x66, 0xf1, 0xa7, 0x30, 0x84,
+0xee, 0xef, 0xdb, 0x3e, 0xd2, 0x4c, 0xeb, 0xd9, 0xe2, 0xbe, 0xf2, 0xf0, 0x58,
+0x67, 0x16, 0x5f, 0xb5, 0x93, 0x0b, 0x60, 0x58, 0xf5, 0x3e, 0xf4, 0x50, 0x33,
+0x53, 0x85, 0x6f, 0xa6, 0xd2, 0xc9, 0x9f, 0x5b, 0x1d, 0xe9, 0x79, 0x5d, 0xa6,
+0xe3, 0x14, 0x36, 0x5e, 0x2d, 0x1b, 0xb3, 0x71, 0x9b, 0x23, 0xe8, 0x30, 0x82,
+0x3b, 0x74, 0x4e, 0x1e, 0xc4, 0x06, 0x50, 0x31, 0x83, 0x20, 0x3f, 0xed, 0xf4,
+0x1b, 0xa0, 0x14, 0xe1, 0x6c, 0xa6, 0x5e, 0x34, 0x25, 0xa5, 0x1b, 0x0a, 0xbf,
+0xca, 0x19, 0x08, 0x16, 0x0a, 0xc8, 0xf2, 0xb5, 0x58, 0x9c, 0x79, 0x54, 0x1b,
+0xb3, 0x55, 0x9f, 0xdf, 0xb8, 0x94, 0x39, 0x4a, 0x07, 0x32, 0x01, 0x52, 0x11,
+0xe9, 0x94, 0xae, 0x02, 0x4a, 0x13, 0x8a, 0xa2, 0x0d, 0x26, 0x7f, 0x79, 0xa6,
+0x40, 0xc2, 0x37, 0x19, 0x25, 0x9c, 0x53, 0x0e, 0xaa, 0x1a, 0xf1, 0x28, 0xbc,
+0x05, 0x09, 0x93, 0xa4, 0x14, 0xc6, 0xdc, 0x89, 0x61, 0x2c, 0x06, 0x37, 0x1a,
+0xfe, 0xda, 0x1f, 0x79
+},
+},
+{
+.keylen = AES256_KEYLEN,
+.len = 160,
+.lcfb = 16,
+.key = (unsigned char []){
+0x4d, 0x3e, 0x4c, 0xec, 0x63, 0xed, 0xaf, 0xbb, 0x4d, 0x60, 0x00, 0x07, 0xe9,
+0x51, 0x24, 0xf5, 0x54, 0xb3, 0x52, 0xad, 0xa4, 0x96, 0x6a, 0x60, 0xda, 0x4c,
+0x89, 0x89, 0x12, 0xca, 0xda, 0x73
+},
+.iv = {
+0x05, 0xae, 0xf5, 0xcc, 0xf4, 0x62, 0x98, 0xe0, 0xfe, 0xb5, 0x8d, 0x77, 0x12,
+0x2b, 0x58, 0xd9
+},
+.plaintext = (unsigned char []){
+0x95, 0xd6, 0xb8, 0x3e, 0x1c, 0x10, 0xc7, 0x21, 0xe0, 0xf0, 0xc3, 0x59, 0x07,
+0xb3, 0xa4, 0xe3, 0x5c, 0x27, 0x94, 0xa6, 0xa8, 0x23, 0x48, 0x74, 0x44, 0x0b,
+0xe7, 0xa7, 0x95, 0xdc, 0x8e, 0x2f, 0x7e, 0xc5, 0xcf, 0x73, 0x9d, 0x0b, 0xb1,
+0x3b, 0x1f, 0xc5, 0x1c, 0xf5, 0xd4, 0xd2, 0x7d, 0x2e, 0xd4, 0xb9, 0x3c, 0x11,
+0x89, 0x3c, 0x7b, 0x9a, 0x64, 0x9b, 0x22, 0xcb, 0xbc, 0x96, 0xa8, 0xcd, 0x58,
+0x47, 0xd1, 0x35, 0xc4, 0x3d, 0x1a, 0x11, 0x85, 0x58, 0x11, 0xb8, 0x2c, 0xff,
+0xbd, 0x22, 0x87, 0xe6, 0xc5, 0x5f, 0x45, 0xd1, 0x24, 0xd4, 0x7d, 0x54, 0x92,
+0x18, 0xc1, 0xea, 0x00, 0x49, 0x28, 0x1d, 0xd5, 0x39, 0xa6, 0x0c, 0xdb, 0xb8,
+0x05, 0x49, 0xdb, 0x3a, 0xf3, 0xb9, 0xf8, 0xd4, 0xca, 0x12, 0x7e, 0xfc, 0xb5,
+0xcd, 0xe7, 0xec, 0xc9, 0x8e, 0x00, 0x8f, 0x1e, 0xde, 0xff, 0x69, 0x80, 0xf1,
+0x72, 0x65, 0x28, 0x06, 0xff, 0x93, 0x95, 0xaf, 0x7a, 0x62, 0xf8, 0x8a, 0xba,
+0xaf, 0x89, 0x74, 0xeb, 0xef, 0x1a, 0x02, 0xd7, 0x8e, 0x4b, 0xd5, 0x21, 0x49,
+0xfa, 0x1e, 0xe1, 0x83
+},
+.ciphertext = (unsigned char []){
+0xfe, 0xdc, 0x27, 0x08, 0xce, 0x2e, 0x24, 0x71, 0xab, 0x8e, 0x66, 0xc6, 0x9a,
+0x34, 0x51, 0xa9, 0x43, 0x80, 0xda, 0x0e, 0x5e, 0x99, 0x98, 0xfa, 0x68, 0x54,
+0x1d, 0x89, 0x9a, 0x57, 0x86, 0x36, 0x1b, 0x7e, 0x51, 0x57, 0x75, 0x7d, 0x6f,
+0xe7, 0x46, 0xc7, 0x9a, 0x88, 0x38, 0xaf, 0xe9, 0xc8, 0x32, 0xcd, 0xa2, 0xa4,
+0xd0, 0xa4, 0x4f, 0x4b, 0x11, 0x81, 0x14, 0x24, 0x50, 0xa6, 0x3f, 0x11, 0x76,
+0xa8, 0x21, 0xf6, 0x6d, 0x16, 0x1d, 0x75, 0xd8, 0x5b, 0xfe, 0xfc, 0x01, 0xe6,
+0x8d, 0x02, 0x12, 0x88, 0x64, 0x8d, 0x89, 0x1d, 0xfd, 0xf8, 0xe6, 0x6e, 0x0e,
+0xf3, 0xa6, 0x56, 0x19, 0xcb, 0x75, 0x24, 0x3e, 0xec, 0xa0, 0x41, 0x55, 0xa4,
+0xc9, 0x13, 0x39, 0x29, 0xde, 0x20, 0x66, 0xde, 0x4c, 0x77, 0xc7, 0xd2, 0x6f,
+0x4c, 0xc9, 0x89, 0x4d, 0xe2, 0xb4, 0x00, 0x85, 0xae, 0x3b, 0xeb, 0x82, 0xb9,
+0x52, 0x41, 0xf4, 0x46, 0x3f, 0xfa, 0x81, 0xb5, 0xf4, 0x18, 0xb7, 0xa7, 0x9c,
+0xe4, 0x46, 0x63, 0x74, 0x7a, 0x6c, 0x78, 0xdc, 0x87, 0xb0, 0xa4, 0xae, 0x52,
+0xd3, 0xf5, 0xce, 0xf9
+},
+},
+};
+
+const struct aes_ofb_tv AES_OFB_TV[] = {
+{
+.keylen = AES128_KEYLEN,
+.len = 160,
+.key = (unsigned char []){
+0xe3, 0x0b, 0x4c, 0x87, 0x4c, 0x4c, 0x4f, 0x6e, 0x0c, 0xf1, 0xf8, 0xef, 0x58,
+0xe5, 0xd3, 0x75
+},
+.iv = {
+0x7e, 0x26, 0xf0, 0x7f, 0x80, 0x24, 0x34, 0x3c, 0xec, 0x35, 0x40, 0x9e, 0x71,
+0xe0, 0xcd, 0x8c
+},
+.plaintext = (unsigned char []){
+0x8c, 0xec, 0xa4, 0xdc, 0x34, 0x6c, 0xfd, 0x6b, 0x15, 0x77, 0x4e, 0x08, 0x2d,
+0xb1, 0xa8, 0x94, 0x97, 0xb7, 0xd8, 0x5d, 0x6b, 0x5b, 0x71, 0x02, 0xe7, 0x74,
+0x17, 0xf7, 0xa2, 0x43, 0xfa, 0xfe, 0x17, 0x11, 0x8b, 0x7a, 0x3b, 0xb4, 0x9d,
+0x16, 0x57, 0xcf, 0x61, 0xb8, 0x66, 0xda, 0x39, 0x5a, 0x5b, 0x3f, 0x34, 0x91,
+0x83, 0xa5, 0x3d, 0xfa, 0x11, 0xfc, 0x0a, 0xc0, 0x53, 0xbd, 0xdf, 0xf4, 0x9d,
+0xd4, 0x72, 0xee, 0x55, 0xf5, 0xe4, 0x3a, 0x2f, 0x8b, 0xc7, 0x85, 0xe2, 0xbc,
+0x42, 0x03, 0x00, 0x69, 0x49, 0x19, 0xff, 0x7b, 0xb4, 0x3f, 0xeb, 0x75, 0xa9,
+0xca, 0xc4, 0x4e, 0xce, 0x96, 0xf6, 0x79, 0xe6, 0x18, 0xdb, 0x5d, 0x74, 0x33,
+0xaf, 0x12, 0xdc, 0xc7, 0xe0, 0x96, 0x3f, 0xf1, 0x0b, 0x45, 0xd8, 0x35, 0xf9,
+0xa8, 0xf4, 0x26, 0x27, 0xe7, 0xf3, 0xfd, 0x50, 0x38, 0x93, 0x26, 0x85, 0x96,
+0x5a, 0xd0, 0xe1, 0x83, 0xf5, 0x95, 0x5e, 0x67, 0x1f, 0xc2, 0xb8, 0x78, 0xdd,
+0x51, 0x05, 0x1e, 0xed, 0xaf, 0x85, 0x31, 0x0d, 0x1e, 0x4e, 0x8f, 0x75, 0xf2,
+0xde, 0xcf, 0x36, 0xc7
+},
+.ciphertext = (unsigned char []){
+0x5d, 0xca, 0xa1, 0x73, 0xed, 0xe1, 0x4f, 0xd2, 0xd6, 0x58, 0x97, 0x39, 0x26,
+0x16, 0x8f, 0xf3, 0x4f, 0xd6, 0xdf, 0x9b, 0xce, 0x32, 0x80, 0xd4, 0x0b, 0x00,
+0xc4, 0x3b, 0x80, 0xe2, 0x97, 0x9a, 0x1e, 0x19, 0x04, 0x5f, 0xec, 0x9a, 0xfb,
+0x4c, 0xf2, 0x64, 0x51, 0x6f, 0x55, 0x10, 0x08, 0x55, 0xc3, 0xaa, 0xd1, 0x7b,
+0x11, 0xbf, 0xcf, 0x05, 0x23, 0xb7, 0x9e, 0xb2, 0x0d, 0x65, 0x94, 0x10, 0x77,
+0xdd, 0x46, 0xec, 0x46, 0x86, 0x4e, 0x0d, 0x79, 0x70, 0x4c, 0x22, 0x50, 0xe7,
+0x2b, 0xf8, 0xb4, 0x48, 0xa6, 0xf0, 0xd3, 0x13, 0x0a, 0xb1, 0x0b, 0x42, 0x3d,
+0x1a, 0x09, 0xd9, 0xff, 0x7a, 0x32, 0xbf, 0x70, 0x04, 0x41, 0xcc, 0xd2, 0x7d,
+0x32, 0x23, 0x91, 0x38, 0x60, 0xc2, 0x80, 0x44, 0xea, 0x57, 0x66, 0xe4, 0x5a,
+0x55, 0xb9, 0x3f, 0x89, 0x48, 0xa9, 0x59, 0xbd, 0x66, 0x61, 0x42, 0x15, 0x66,
+0x89, 0x8e, 0x27, 0x95, 0x0f, 0x04, 0xe7, 0x26, 0x27, 0x9b, 0xcb, 0xc9, 0x90,
+0xa2, 0x2c, 0x80, 0x19, 0x3e, 0xf0, 0xae, 0x65, 0x19, 0x66, 0x71, 0xeb, 0x59,
+0x71, 0x32, 0x40, 0xcf
+},
+},
+{
+.keylen = AES192_KEYLEN,
+.len = 160,
+.key = (unsigned char []){
+0x75, 0x3c, 0x1f, 0x7f, 0x39, 0xaf, 0xd2, 0x86, 0xff, 0x05, 0x13, 0x39, 0xc4,
+0x5d, 0x57, 0xc8, 0x48, 0x85, 0x03, 0x93, 0xb4, 0x11, 0x2f, 0xe5
+},
+.iv = {
+0xd3, 0xee, 0x0d, 0x8d, 0xe5, 0x08, 0x0e, 0xda, 0x4c, 0x26, 0xf5, 0xa3, 0xb9,
+0xca, 0x8a, 0x9f
+},
+.plaintext = (unsigned char []){
+0xad, 0x3c, 0xcd, 0xa2, 0x64, 0x34, 0x31, 0x30, 0xbf, 0x1d, 0xb3, 0x70, 0x3e,
+0x27, 0x12, 0x71, 0x76, 0xfb, 0xaa, 0x7b, 0x6a, 0x5d, 0xa2, 0x71, 0x87, 0x83,
+0xba, 0xf9, 0xf2, 0x8f, 0xcd, 0xd3, 0xed, 0x9c, 0xd3, 0x1a, 0xdc, 0xc7, 0x94,
+0x27, 0xfe, 0x4d, 0xf0, 0x3f, 0x16, 0x72, 0xa5, 0xe5, 0x5c, 0xab, 0x0d, 0xb0,
+0xf4, 0xd4, 0x34, 0xd8, 0x60, 0x34, 0x0d, 0x2f, 0xa0, 0x5b, 0xfe, 0xb0, 0x7e,
+0x92, 0x41, 0x57, 0x06, 0x4a, 0x24, 0xd0, 0xf1, 0x0e, 0x32, 0x93, 0xf7, 0x8a,
+0x26, 0x76, 0xe3, 0xc5, 0x37, 0x34, 0xf2, 0x2d, 0x4e, 0xa3, 0x3e, 0x89, 0x38,
+0x4b, 0xd1, 0x7f, 0x4a, 0x0f, 0x59, 0x35, 0x41, 0x79, 0xce, 0x48, 0xa7, 0xd1,
+0xc1, 0xba, 0x35, 0xe7, 0xf7, 0x77, 0x35, 0xf5, 0x86, 0x80, 0xf0, 0xe8, 0x9b,
+0xf9, 0x24, 0x2a, 0x4f, 0x08, 0x73, 0x22, 0xd9, 0x9e, 0x50, 0x73, 0x36, 0xa8,
+0xe9, 0x03, 0x7b, 0x6f, 0x1b, 0xfb, 0xe4, 0x56, 0x14, 0xab, 0xeb, 0x2f, 0x71,
+0x51, 0x6b, 0x94, 0xca, 0xf6, 0x18, 0x85, 0x1d, 0xdc, 0xfa, 0xc7, 0x42, 0x9a,
+0x21, 0x77, 0xbe, 0x40
+},
+.ciphertext = (unsigned char []){
+0xa9, 0x14, 0x09, 0xfa, 0x69, 0x4a, 0x4a, 0xd3, 0x4a, 0x9c, 0xb1, 0xc1, 0x53,
+0x4a, 0x94, 0x97, 0x9a, 0x5b, 0xeb, 0x39, 0x00, 0x83, 0xa6, 0xa6, 0x1b, 0x4a,
+0x44, 0x36, 0x74, 0x6b, 0xa1, 0x20, 0xf3, 0x7a, 0x0f, 0x3e, 0x97, 0xca, 0xa9,
+0x15, 0x6a, 0x8e, 0xe4, 0x10, 0xb5, 0x3e, 0x67, 0x0c, 0x70, 0x3d, 0x1d, 0x19,
+0xfc, 0xb8, 0x88, 0x7f, 0x15, 0xd1, 0x58, 0x00, 0x02, 0xfd, 0x3c, 0x5d, 0x0e,
+0xaa, 0xf8, 0x1c, 0x3c, 0x26, 0xb8, 0x87, 0x37, 0xbc, 0xa3, 0xf8, 0x88, 0x20,
+0xb4, 0x54, 0x0b, 0x0d, 0xc5, 0xd6, 0xa4, 0x2c, 0xed, 0x0e, 0x2e, 0x38, 0x0c,
+0x29, 0xb4, 0x60, 0xa4, 0x72, 0xe4, 0xec, 0xeb, 0x19, 0xc0, 0x24, 0x1e, 0x33,
+0x97, 0x6d, 0x17, 0x03, 0x34, 0xb6, 0x22, 0x78, 0x55, 0x12, 0x0d, 0xf6, 0x5f,
+0xa6, 0x7e, 0x5a, 0x4f, 0xc6, 0x89, 0x38, 0xf4, 0x5b, 0x82, 0x66, 0x5c, 0x88,
+0x10, 0xbf, 0x8c, 0x8d, 0x83, 0x21, 0x73, 0xeb, 0x68, 0xb8, 0x21, 0xc9, 0x5a,
+0x7f, 0x35, 0x96, 0x1b, 0x03, 0x94, 0xf0, 0xe3, 0x6b, 0x61, 0xc4, 0xf7, 0xb5,
+0x29, 0xb7, 0x7e, 0x42
+},
+},
+{
+.keylen = AES256_KEYLEN,
+.len = 160,
+.key = (unsigned char []){
+0x98, 0xa9, 0x97, 0x1e, 0x86, 0x80, 0x6c, 0xcc, 0x34, 0x95, 0x11, 0x6f, 0xd0,
+0x6d, 0xc9, 0xd1, 0x52, 0x2f, 0xe8, 0x80, 0x60, 0xfd, 0xdd, 0xc3, 0x6e, 0x84,
+0x6f, 0xd3, 0x29, 0xd2, 0x47, 0x48
+},
+.iv = {
+0x99, 0x83, 0xce, 0x04, 0x8f, 0x19, 0xef, 0x40, 0x43, 0x05, 0x4c, 0x03, 0xaa,
+0x01, 0x0b, 0xee
+},
+.plaintext = (unsigned char []){
+0x00, 0xca, 0xa2, 0x33, 0x19, 0x8f, 0x51, 0xbb, 0xf5, 0x93, 0x40, 0x4f, 0x59,
+0x82, 0x69, 0x97, 0xb4, 0xea, 0x38, 0x73, 0x85, 0xcf, 0x74, 0x4c, 0x93, 0xcf,
+0xa0, 0x0e, 0x70, 0x2e, 0x8f, 0x16, 0xff, 0x5a, 0xa7, 0xe1, 0x7a, 0x9a, 0x60,
+0x20, 0xdf, 0x0f, 0x0d, 0xe4, 0xea, 0x6a, 0xbb, 0x38, 0xbc, 0xf1, 0xd7, 0x77,
+0x81, 0x0a, 0x83, 0x18, 0xf6, 0x9b, 0x5e, 0x83, 0x05, 0xf6, 0xd7, 0x27, 0xf0,
+0x6f, 0x00, 0x8b, 0x4b, 0xec, 0x2d, 0x65, 0xcd, 0x4c, 0x51, 0x6c, 0xa4, 0x9f,
+0x62, 0xfb, 0x2f, 0x91, 0x6f, 0x27, 0x3c, 0x45, 0xbb, 0x72, 0x2b, 0xec, 0x78,
+0xc3, 0x16, 0xf9, 0x0b, 0x5e, 0xd5, 0xde, 0x6e, 0xf1, 0xd3, 0x66, 0x60, 0x3c,
+0xed, 0x30, 0x3c, 0x10, 0xe3, 0x3d, 0xd5, 0xc9, 0x9e, 0xb0, 0xf9, 0x94, 0xdb,
+0x5a, 0x78, 0x67, 0xda, 0x9b, 0x53, 0x0f, 0xc4, 0xd0, 0xb9, 0xce, 0x22, 0x4c,
+0x6e, 0xab, 0x78, 0x10, 0x35, 0x9c, 0x97, 0x33, 0xcf, 0x93, 0x3c, 0x57, 0x36,
+0x11, 0xd3, 0x1f, 0xcd, 0xf3, 0xf1, 0xdb, 0x87, 0xcf, 0xd1, 0x7b, 0xe7, 0xf4,
+0xa4, 0x70, 0xa0, 0xb4
+},
+.ciphertext = (unsigned char []){
+0x4b, 0x07, 0x67, 0xfe, 0xc0, 0xd4, 0xbd, 0x07, 0xc7, 0x9c, 0x0f, 0x56, 0x52,
+0xda, 0xfa, 0xdf, 0x10, 0xcf, 0xce, 0x89, 0xe3, 0x25, 0x9d, 0xea, 0x94, 0xd3,
+0x92, 0x52, 0xc6, 0x40, 0x84, 0x0c, 0x28, 0xab, 0xcb, 0xe0, 0xef, 0xca, 0x53,
+0xdc, 0x84, 0xb1, 0xef, 0x55, 0x79, 0xf6, 0xef, 0x28, 0xc2, 0x13, 0xf4, 0x45,
+0x22, 0x0b, 0x03, 0x6f, 0xe3, 0x51, 0xd9, 0x3d, 0xca, 0xe5, 0x7e, 0x65, 0x4a,
+0xc0, 0x1d, 0x39, 0xf8, 0x72, 0x13, 0x72, 0x3f, 0x0a, 0x46, 0x2d, 0x55, 0x36,
+0xb8, 0x33, 0x6d, 0xab, 0x5c, 0x7d, 0x2f, 0xc7, 0x28, 0xf8, 0x65, 0x75, 0x6b,
+0x85, 0xf7, 0x52, 0x61, 0x44, 0x19, 0x0e, 0x04, 0x12, 0xc3, 0x14, 0x26, 0x50,
+0x61, 0x6d, 0xbd, 0xe7, 0xcd, 0xe1, 0x7e, 0x88, 0x7a, 0x60, 0xad, 0x39, 0xf2,
+0xa1, 0x33, 0x0d, 0x82, 0x09, 0xf1, 0x32, 0x33, 0xce, 0x54, 0x31, 0xfd, 0x5c,
+0x29, 0x72, 0x38, 0xf8, 0xb3, 0xff, 0x53, 0xa3, 0xfb, 0x89, 0xc8, 0x41, 0x68,
+0xb0, 0x4f, 0xfa, 0x8f, 0x7f, 0x53, 0xe1, 0x4c, 0x36, 0xa2, 0xd3, 0x12, 0x4d,
+0x68, 0xa2, 0x7f, 0xb5
+},
+},
+};
+
+const struct des3_ecb_tv DES3_ECB_TV[] = {
+{
+.len = 72,
+.key = {
+0xbc, 0x51, 0xa2, 0x29, 0x1a, 0xf4, 0xbc, 0x10, 0x31, 0x57, 0x26, 0x9e, 0x7a,
+0x4c, 0x15, 0xb5, 0xa1, 0x31, 0x97, 0xd9, 0xad, 0x97, 0x0d, 0xb9
+},
+.plaintext = (unsigned char []){
+0x2e, 0xdd, 0x7f, 0x0f, 0xf0, 0x86, 0xab, 0xd0, 0xa1, 0xb1, 0x21, 0xd0, 0x53,
+0xf7, 0xfb, 0x09, 0x59, 0xba, 0x89, 0xfd, 0xcf, 0xb9, 0x7e, 0xb4, 0x22, 0x81,
+0xfd, 0x18, 0x85, 0xa9, 0x5c, 0xf3, 0xd8, 0x4e, 0xc0, 0xb0, 0xfe, 0x2e, 0xbe,
+0x55, 0x50, 0xad, 0xa9, 0x49, 0xa1, 0x52, 0x47, 0x66, 0x03, 0xdf, 0x9b, 0xd0,
+0x9a, 0x48, 0xd0, 0x01, 0xc9, 0xb9, 0xdc, 0x20, 0xd0, 0x82, 0xd1, 0xe7, 0xc2,
+0x73, 0x85, 0xf0, 0xcc, 0xcf, 0xfe, 0xc1
+},
+.ciphertext = (unsigned char []){
+0x54, 0x15, 0xca, 0x2d, 0x2c, 0xab, 0xe7, 0x75, 0xb8, 0x17, 0xb2, 0x2b, 0x8f,
+0xe4, 0x97, 0xde, 0x96, 0xb3, 0xc0, 0xdb, 0x73, 0xe0, 0x2e, 0xf3, 0x44, 0x62,
+0x09, 0x7f, 0x90, 0xf3, 0x34, 0xa1, 0x7d, 0x72, 0x25, 0xcc, 0x44, 0x85, 0xf4,
+0x86, 0xe3, 0x82, 0xb1, 0x6c, 0x12, 0x90, 0xfb, 0x77, 0x77, 0x09, 0xce, 0x7f,
+0x1d, 0x23, 0x9d, 0xfd, 0x23, 0xd0, 0xa1, 0x15, 0xb1, 0xe2, 0x70, 0xd4, 0x30,
+0x73, 0xd1, 0xb6, 0xbb, 0x84, 0xcf, 0x6b
+},
+},
+{
+.len = 80,
+.key = {
+0xb5, 0xcd, 0x0e, 0x1f, 0x1f, 0x86, 0x45, 0x8f, 0x34, 0x2f, 0x26, 0x83, 0xcd,
+0x3b, 0xbf, 0xb9, 0x10, 0x85, 0xe3, 0x8f, 0x67, 0xc2, 0xb9, 0xa1
+},
+.plaintext = (unsigned char []){
+0x94, 0x4c, 0xb9, 0x7a, 0x22, 0x68, 0x39, 0x36, 0x6d, 0xfe, 0xaf, 0x46, 0x80,
+0xb4, 0xad, 0xad, 0x05, 0x37, 0x2c, 0x6f, 0x9c, 0xa4, 0x60, 0xf6, 0x87, 0xa9,
+0x4c, 0xf2, 0x86, 0x48, 0x32, 0xff, 0x5d, 0x57, 0x2e, 0xf1, 0xcf, 0x16, 0x41,
+0xa7, 0xe0, 0x08, 0x2d, 0x6f, 0x48, 0x28, 0x5a, 0xf7, 0xe4, 0x1f, 0x1c, 0x6b,
+0x10, 0x0e, 0x67, 0xe1, 0x37, 0x93, 0x66, 0x0c, 0x34, 0x38, 0x8f, 0xbe, 0xf0,
+0x43, 0xf0, 0xbb, 0x87, 0xd7, 0xaa, 0x8a, 0xb2, 0xcc, 0x98, 0x77, 0x90, 0xc1,
+0x51, 0xcb
+},
+.ciphertext = (unsigned char []){
+0xbd, 0x79, 0x1a, 0xa9, 0xd3, 0x42, 0xdc, 0x4b, 0x7d, 0xda, 0x97, 0xcf, 0x0a,
+0x1f, 0x41, 0xab, 0x30, 0xc3, 0x52, 0xbe, 0x5c, 0x4f, 0xc1, 0x7b, 0x47, 0x67,
+0x30, 0x4a, 0xca, 0x4f, 0x64, 0x2b, 0xf3, 0xae, 0xf7, 0x9d, 0x58, 0x92, 0x51,
+0xbe, 0xab, 0xb5, 0xd4, 0xb3, 0x8f, 0xff, 0x57, 0x4a, 0xaa, 0x4b, 0xd6, 0xde,
+0xfc, 0x6e, 0x67, 0x7c, 0x6f, 0x75, 0x70, 0x43, 0xaf, 0x2f, 0x18, 0x11, 0x3b,
+0xec, 0xfb, 0x5c, 0xbd, 0x83, 0x22, 0x5d, 0x97, 0x9a, 0x32, 0x74, 0xbe, 0x21,
+0xe3, 0xc8
+},
+},
+};
+
+const struct des3_cbc_tv DES3_CBC_TV[] = {
+{
+.len = 72,
+.key = {
+0x2a, 0xe6, 0xae, 0x5d, 0x75, 0x34, 0x8f, 0x9d, 0x34, 0xc4, 0xfd, 0x45, 0x85,
+0xb6, 0xba, 0x8c, 0x9d, 0xef, 0x6e, 0xbf, 0xc7, 0x7f, 0xe0, 0x46
+},
+.iv = {
+0xa5, 0x2b, 0x66, 0xc3, 0x34, 0x38, 0x59, 0xe0
+},
+.plaintext = (unsigned char []){
+0x24, 0x19, 0x26, 0x42, 0xf7, 0xc7, 0x0e, 0x7d, 0x75, 0x69, 0xde, 0x8b, 0x86,
+0x20, 0x4a, 0x10, 0xa0, 0x76, 0xe3, 0xf3, 0x79, 0xbc, 0x7f, 0x8a, 0x52, 0x25,
+0xec, 0x4d, 0x76, 0xc0, 0x8a, 0xca, 0x40, 0xcd, 0xe8, 0x86, 0xf5, 0xd9, 0x9b,
+0xc0, 0xb6, 0x65, 0xa1, 0x79, 0x56, 0x37, 0x22, 0x19, 0xcd, 0x52, 0xcb, 0x73,
+0xec, 0x48, 0x62, 0xdf, 0x24, 0x2f, 0xb7, 0x65, 0xb1, 0x85, 0x3b, 0xc6, 0x25,
+0x82, 0x41, 0xe4, 0x1a, 0x1a, 0xd7, 0x15
+},
+.ciphertext = (unsigned char []){
+0x95, 0x0e, 0x26, 0xc3, 0xf2, 0x46, 0xd7, 0xed, 0xff, 0xbd, 0xd3, 0x0e, 0x9a,
+0x2c, 0x08, 0x2b, 0x48, 0x53, 0x3f, 0xbf, 0x26, 0x29, 0xa9, 0x00, 0x23, 0x35,
+0xbb, 0x63, 0x6d, 0x3c, 0x3c, 0x62, 0x29, 0x1c, 0x9d, 0x7d, 0x67, 0xf8, 0x88,
+0x7f, 0x55, 0x95, 0xbb, 0x02, 0xb2, 0x04, 0x17, 0x35, 0x86, 0x82, 0xf4, 0xdd,
+0x11, 0x9c, 0xb8, 0x9a, 0x01, 0x97, 0xa8, 0x6c, 0xe8, 0x0e, 0xfe, 0x75, 0xec,
+0xdd, 0x3b, 0x01, 0xc1, 0x3e, 0xbe, 0xc3
+},
+},
+{
+.len = 80,
+.key = {
+0xb6, 0x04, 0xec, 0x25, 0x5e, 0x04, 0x54, 0x0b, 0x23, 0x0b, 0x4a, 0xce, 0xf1,
+0x38, 0x40, 0xc1, 0xe9, 0x58, 0xb9, 0xf2, 0xe9, 0x13, 0x9d, 0x57
+},
+.iv = {
+0x58, 0x6c, 0x47, 0x1f, 0x4e, 0xcd, 0xa1, 0xde
+},
+.plaintext = (unsigned char []){
+0x90, 0x0c, 0x63, 0xa0, 0x8f, 0xd1, 0x42, 0xa9, 0xc1, 0x62, 0x63, 0x93, 0x91,
+0xe0, 0xe2, 0xb6, 0x46, 0x97, 0xb7, 0xa5, 0x16, 0xd6, 0x9c, 0xd7, 0x77, 0x96,
+0xd4, 0x90, 0x14, 0x87, 0x73, 0xfc, 0x98, 0x4f, 0x21, 0xa0, 0xc2, 0x86, 0xd7,
+0x3d, 0x86, 0xd8, 0xfd, 0x80, 0x11, 0xaf, 0x8f, 0x81, 0x74, 0xe0, 0x3e, 0xad,
+0x4c, 0xaf, 0xb9, 0x64, 0x12, 0x46, 0x61, 0x5a, 0xad, 0x9b, 0xa8, 0xb0, 0x2f,
+0xde, 0x3e, 0xdf, 0xf3, 0x55, 0x26, 0xd3, 0xba, 0x21, 0x46, 0x5d, 0x2c, 0x99,
+0xf8, 0x7c
+},
+.ciphertext = (unsigned char []){
+0xf7, 0xc0, 0x8a, 0x2c, 0xf5, 0x80, 0x5b, 0xc1, 0x5c, 0x15, 0x7c, 0xff, 0xfe,
+0x5b, 0x67, 0x49, 0x42, 0x6c, 0xde, 0x28, 0x19, 0xc3, 0x7e, 0x93, 0x34, 0xa2,
+0x97, 0x6e, 0x75, 0xb0, 0x3b, 0x50, 0xa3, 0xe7, 0x95, 0x89, 0x61, 0xad, 0x7c,
+0x64, 0x61, 0x41, 0x48, 0xa9, 0xd5, 0x59, 0xe5, 0x66, 0x26, 0x0a, 0x26, 0xef,
+0xe9, 0xe7, 0x5b, 0x24, 0x0f, 0x6d, 0x25, 0xf2, 0x5b, 0x9f, 0x89, 0x1d, 0x1a,
+0xed, 0x44, 0x3c, 0x0e, 0x5a, 0x5e, 0x05, 0xab, 0xde, 0x02, 0xca, 0x86, 0x09,
+0x8d, 0x44
+},
+},
+};
+
+const struct des3_cfb_tv DES3_CFB_TV[] = {
+{
+.len = 10,
+.lcfb = 1,
+.key = {
+0x29, 0x0d, 0xba, 0x49, 0xc1, 0x2a, 0xe9, 0x67, 0x6e, 0xf7, 0x19, 0xef, 0x6b,
+0xec, 0xad, 0x0d, 0x04, 0x79, 0x80, 0x6e, 0x02, 0xe0, 0x70, 0x6e
+},
+.iv = {
+0x2d, 0x5f, 0x4b, 0xed, 0x09, 0x21, 0x47, 0x79
+},
+.plaintext = (unsigned char []){
+0xe8, 0xcb, 0xdd, 0x0d, 0x7e, 0x8a, 0xc9, 0x64, 0xae, 0x2d
+},
+.ciphertext = (unsigned char []){
+0xec, 0xb1, 0x2f, 0xfe, 0xa8, 0x97, 0x76, 0x87, 0x37, 0xaf
+},
+},
+{
+.len = 80,
+.lcfb = 8,
+.key = {
+0x26, 0xfe, 0x46, 0xf7, 0x75, 0xc2, 0x34, 0xb5, 0x29, 0x9e, 0xa1, 0xda, 0x16,
+0x8c, 0xe6, 0x0d, 0xa1, 0xe5, 0x51, 0x57, 0x98, 0x46, 0x8f, 0xb9
+},
+.iv = {
+0x62, 0x6c, 0x2d, 0xfb, 0x4e, 0x4e, 0xd3, 0x66
+},
+.plaintext = (unsigned char []){
+0x0d, 0xc2, 0xc7, 0x5e, 0x4d, 0xdf, 0x8b, 0xbc, 0x36, 0x13, 0xfa, 0x64, 0x42,
+0xd3, 0x9c, 0x2f, 0xa0, 0x31, 0x56, 0x1a, 0x5e, 0x98, 0xec, 0xbf, 0x36, 0x33,
+0xc4, 0xa9, 0x4e, 0x96, 0xb9, 0x6e, 0x84, 0xfd, 0x42, 0x07, 0xe3, 0x84, 0x79,
+0x8b, 0x1f, 0x95, 0x3d, 0xc2, 0x63, 0xc5, 0x1f, 0x86, 0xe6, 0x61, 0x96, 0xd5,
+0x81, 0x7c, 0x3f, 0x04, 0xb8, 0x31, 0x92, 0xe2, 0x62, 0xe1, 0x6e, 0x5b, 0xe9,
+0x14, 0x3b, 0x81, 0x87, 0x5b, 0x9d, 0x37, 0xcc, 0xe9, 0xbf, 0xb0, 0xee, 0xe0,
+0x26, 0xfc
+},
+.ciphertext = (unsigned char []){
+0x04, 0xbf, 0x26, 0x5b, 0xf3, 0x32, 0x51, 0x90, 0x6f, 0xb3, 0x31, 0x05, 0x10,
+0x09, 0xc4, 0xcc, 0x76, 0xe3, 0x4d, 0x30, 0x8e, 0x0e, 0xb2, 0x8e, 0x12, 0xeb,
+0x22, 0x67, 0x4f, 0x21, 0xfa, 0xb2, 0x2b, 0x8f, 0xea, 0x77, 0x66, 0x85, 0x54,
+0x99, 0x20, 0x33, 0xf4, 0xf4, 0x9c, 0x61, 0xc6, 0xa7, 0x43, 0x61, 0x24, 0xb3,
+0xec, 0x42, 0x2f, 0xc6, 0x5a, 0x47, 0x71, 0x51, 0x06, 0x97, 0xc1, 0xe0, 0x1f,
+0x36, 0x66, 0xab, 0xd0, 0x34, 0x7f, 0x68, 0xc1, 0x25, 0xa2, 0x64, 0xe0, 0xd1,
+0xc3, 0xd2
+},
+},
+};
+
+const struct des3_ofb_tv DES3_OFB_TV[] = {
+{
+.len = 72,
+.key = {
+0xfe, 0x80, 0xea, 0x91, 0xe5, 0x45, 0x7f, 0x75, 0x7f, 0x34, 0x2f, 0xdf, 0x1f,
+0xd9, 0xf1, 0xbc, 0x32, 0x29, 0x8a, 0xc8, 0x58, 0x7c, 0x80, 0x54
+},
+.iv = {
+0x07, 0xa1, 0xf8, 0xf1, 0xbb, 0x2e, 0x90, 0xaa
+},
+.plaintext = (unsigned char []){
+0x83, 0x14, 0x3e, 0x9e, 0xc9, 0x91, 0x34, 0xc8, 0x5f, 0xae, 0x01, 0x3b, 0x69,
+0x51, 0x47, 0x0c, 0xae, 0x79, 0xad, 0x7c, 0x8b, 0xbd, 0xef, 0xad, 0xc8, 0x18,
+0x47, 0x77, 0x57, 0xab, 0xc6, 0x3a, 0x0d, 0x14, 0x1e, 0x64, 0x0b, 0x1f, 0x9d,
+0xd4, 0xb0, 0x42, 0x90, 0x4e, 0xbc, 0x7a, 0x30, 0xb7, 0xde, 0x55, 0xca, 0x08,
+0x51, 0x20, 0x26, 0xb5, 0x03, 0xfb, 0x29, 0xa9, 0x64, 0xc1, 0xbf, 0x68, 0xef,
+0xfd, 0x2b, 0x96, 0x98, 0x1f, 0x40, 0x83
+},
+.ciphertext = (unsigned char []){
+0xe5, 0x69, 0x72, 0x0a, 0xd5, 0xae, 0xab, 0x8a, 0x1a, 0xd1, 0xa6, 0xab, 0xbf,
+0x06, 0xd7, 0xe2, 0xf8, 0x03, 0x2f, 0x2f, 0x55, 0x62, 0xee, 0xa0, 0x3b, 0x47,
+0xb9, 0x16, 0x95, 0x42, 0xec, 0x4b, 0xc7, 0x77, 0x31, 0x14, 0xe3, 0xfc, 0x52,
+0xe4, 0x20, 0x82, 0x4b, 0x92, 0x88, 0x38, 0xa4, 0x5c, 0xf0, 0xec, 0xfd, 0x2b,
+0x2d, 0x73, 0xeb, 0x19, 0x85, 0x4c, 0x02, 0x30, 0x64, 0x80, 0x33, 0x74, 0x50,
+0xcc, 0x59, 0x24, 0x1f, 0x02, 0x0e, 0x3e
+},
+},
+{
+.len = 80,
+.key = {
+0x75, 0xcd, 0xd3, 0x07, 0x45, 0xfb, 0xbc, 0x31, 0x04, 0x83, 0x54, 0x26, 0x52,
+0x9b, 0x45, 0xe5, 0xfd, 0x10, 0x2c, 0x7c, 0x8a, 0x9d, 0x1f, 0x1c
+},
+.iv = {
+0x09, 0x77, 0x3d, 0xa8, 0x62, 0xac, 0x17, 0xee
+},
+.plaintext = (unsigned char []){
+0x57, 0xdd, 0xb8, 0x43, 0xff, 0x45, 0x18, 0x60, 0xef, 0x4a, 0xfc, 0x3e, 0x0e,
+0x89, 0x97, 0x89, 0xb3, 0x7d, 0xeb, 0xc9, 0xf9, 0x53, 0x41, 0x5f, 0xb9, 0x68,
+0x67, 0x6f, 0xfc, 0x52, 0x8f, 0x8c, 0x8e, 0x25, 0xba, 0x1c, 0xac, 0x21, 0x4d,
+0xf4, 0xfd, 0x0c, 0xec, 0xfb, 0x19, 0x89, 0xe5, 0x99, 0x30, 0x92, 0x2f, 0xb6,
+0xd0, 0xb7, 0x58, 0x83, 0xa5, 0x23, 0x46, 0x28, 0x47, 0x18, 0xf0, 0x7e, 0x71,
+0x21, 0x10, 0x97, 0x74, 0xfe, 0x4e, 0x14, 0x0b, 0x19, 0x83, 0xc0, 0x36, 0xc9,
+0xf3, 0x0c
+},
+.ciphertext = (unsigned char []){
+0x59, 0x14, 0x41, 0x8e, 0x5d, 0x3b, 0x71, 0x55, 0x42, 0x18, 0x6f, 0xd2, 0xa5,
+0xa8, 0xde, 0x6d, 0x59, 0x39, 0x5b, 0xa1, 0x01, 0xba, 0xb0, 0x5c, 0xde, 0x35,
+0x4a, 0xa9, 0xe5, 0x9a, 0xee, 0x8c, 0x15, 0xbe, 0xa7, 0x2d, 0x07, 0xa3, 0x03,
+0x39, 0xc7, 0xfa, 0x7e, 0x86, 0xe2, 0xe6, 0x3f, 0xf6, 0xc0, 0x03, 0x02, 0x9d,
+0x34, 0xa7, 0x56, 0x26, 0x52, 0x68, 0x08, 0x72, 0x81, 0xde, 0xdf, 0x83, 0xd1,
+0xaa, 0x89, 0x99, 0x8e, 0xb6, 0xd6, 0x9a, 0x15, 0xbf, 0x24, 0xb7, 0xe6, 0x11,
+0x1b, 0x4d
+},
+},
+};
+
+const struct sha_tv SHA1_TV[] = {
+{
+.msg_len = 512 / 8,
+.msg = (unsigned char []){
+0x45, 0x92, 0x7e, 0x32, 0xdd, 0xf8, 0x01, 0xca, 0xf3, 0x5e, 0x18, 0xe7, 0xb5,
+0x07, 0x8b, 0x7f, 0x54, 0x35, 0x27, 0x82, 0x12, 0xec, 0x6b, 0xb9, 0x9d, 0xf8,
+0x84, 0xf4, 0x9b, 0x32, 0x7c, 0x64, 0x86, 0xfe, 0xae, 0x46, 0xba, 0x18, 0x7d,
+0xc1, 0xcc, 0x91, 0x45, 0x12, 0x1e, 0x14, 0x92, 0xe6, 0xb0, 0x6e, 0x90, 0x07,
+0x39, 0x4d, 0xc3, 0x3b, 0x77, 0x48, 0xf8, 0x6a, 0xc3, 0x20, 0x7c, 0xfe
+},
+.md = (unsigned char []){
+0xa7, 0x0c, 0xfb, 0xfe, 0x75, 0x63, 0xdd, 0x0e, 0x66, 0x5c, 0x7c, 0x67, 0x15,
+0xa9, 0x6a, 0x8d, 0x75, 0x69, 0x50, 0xc0
+}
+},
+};
+
+const struct sha_tv SHA224_TV[] = {
+{
+.msg_len = 512 / 8,
+.msg = (unsigned char []){
+0xa3, 0x31, 0x0b, 0xa0, 0x64, 0xbe, 0x2e, 0x14, 0xad, 0x32, 0x27, 0x6e, 0x18,
+0xcd, 0x03, 0x10, 0xc9, 0x33, 0xa6, 0xe6, 0x50, 0xc3, 0xc7, 0x54, 0xd0, 0x24,
+0x3c, 0x6c, 0x61, 0x20, 0x78, 0x65, 0xb4, 0xb6, 0x52, 0x48, 0xf6, 0x6a, 0x08,
+0xed, 0xf6, 0xe0, 0x83, 0x26, 0x89, 0xa9, 0xdc, 0x3a, 0x2e, 0x5d, 0x20, 0x95,
+0xee, 0xea, 0x50, 0xbd, 0x86, 0x2b, 0xac, 0x88, 0xc8, 0xbd, 0x31, 0x8d
+},
+.md = (unsigned char []){
+0xb2, 0xa5, 0x58, 0x6d, 0x9c, 0xbf, 0x0b, 0xaa, 0x99, 0x91, 0x57, 0xb4, 0xaf,
+0x06, 0xd8, 0x8a, 0xe0, 0x8d, 0x7c, 0x9f, 0xaa, 0xb4, 0xbc, 0x1a, 0x96, 0x82,
+0x9d, 0x65
+}
+},
+};
+
+const struct sha_tv SHA256_TV[] = {
+{
+.msg_len = 512 / 8,
+.msg = (unsigned char []){
+0x5a, 0x86, 0xb7, 0x37, 0xea, 0xea, 0x8e, 0xe9, 0x76, 0xa0, 0xa2, 0x4d, 0xa6,
+0x3e, 0x7e, 0xd7, 0xee, 0xfa, 0xd1, 0x8a, 0x10, 0x1c, 0x12, 0x11, 0xe2, 0xb3,
+0x65, 0x0c, 0x51, 0x87, 0xc2, 0xa8, 0xa6, 0x50, 0x54, 0x72, 0x08, 0x25, 0x1f,
+0x6d, 0x42, 0x37, 0xe6, 0x61, 0xc7, 0xbf, 0x4c, 0x77, 0xf3, 0x35, 0x39, 0x03,
+0x94, 0xc3, 0x7f, 0xa1, 0xa9, 0xf9, 0xbe, 0x83, 0x6a, 0xc2, 0x85, 0x09
+},
+.md = (unsigned char []){
+0x42, 0xe6, 0x1e, 0x17, 0x4f, 0xbb, 0x38, 0x97, 0xd6, 0xdd, 0x6c, 0xef, 0x3d,
+0xd2, 0x80, 0x2f, 0xe6, 0x7b, 0x33, 0x19, 0x53, 0xb0, 0x61, 0x14, 0xa6, 0x5c,
+0x77, 0x28, 0x59, 0xdf, 0xc1, 0xaa
+}
+},
+};
+
+const struct sha_tv SHA384_TV[] = {
+{
+.msg_len = 512 / 8,
+.msg = (unsigned char []){
+0x93, 0x03, 0x5d, 0x3a, 0x13, 0xae, 0x1b, 0x06, 0xdd, 0x03, 0x3e, 0x76, 0x4a,
+0xca, 0x01, 0x24, 0x96, 0x1d, 0xa7, 0x9c, 0x36, 0x6c, 0x6c, 0x75, 0x6b, 0xc4,
+0xbc, 0xc1, 0x18, 0x50, 0xa3, 0xa8, 0xd1, 0x20, 0x85, 0x4f, 0x34, 0x29, 0x0f,
+0xff, 0x7c, 0x8d, 0x6d, 0x83, 0x53, 0x1d, 0xbd, 0xd1, 0xe8, 0x1c, 0xc4, 0xed,
+0x42, 0x46, 0xe0, 0x0b, 0xd4, 0x11, 0x3e, 0xf4, 0x51, 0x33, 0x4d, 0xaa
+},
+.md = (unsigned char []){
+0x8d, 0x46, 0xcc, 0x84, 0xb6, 0xc2, 0xde, 0xb2, 0x06, 0xaa, 0x5c, 0x86, 0x17,
+0x98, 0x79, 0x87, 0x51, 0xa2, 0x6e, 0xe7, 0x4b, 0x1d, 0xaf, 0x3a, 0x55, 0x7c,
+0x41, 0xae, 0xbd, 0x65, 0xad, 0xc0, 0x27, 0x55, 0x9f, 0x7c, 0xd9, 0x2b, 0x25,
+0x5b, 0x37, 0x4c, 0x83, 0xbd, 0x55, 0x56, 0x8b, 0x45
+}
+},
+};
+
+const struct sha_tv SHA512_TV[] = {
+{
+.msg_len = 512 / 8,
+.msg = (unsigned char []){
+0xc1, 0xca, 0x70, 0xae, 0x12, 0x79, 0xba, 0x0b, 0x91, 0x81, 0x57, 0x55, 0x8b,
+0x49, 0x20, 0xd6, 0xb7, 0xfb, 0xa8, 0xa0, 0x6b, 0xe5, 0x15, 0x17, 0x0f, 0x20,
+0x2f, 0xaf, 0xd3, 0x6f, 0xb7, 0xf7, 0x9d, 0x69, 0xfa, 0xd7, 0x45, 0xdb, 0xa6,
+0x15, 0x05, 0x68, 0xdb, 0x1e, 0x2b, 0x72, 0x85, 0x04, 0x11, 0x3e, 0xea, 0xc3,
+0x4f, 0x52, 0x7f, 0xc8, 0x2f, 0x22, 0x00, 0xb4, 0x62, 0xec, 0xbf, 0x5d
+},
+.md = (unsigned char []){
+0x04, 0x6e, 0x46, 0x62, 0x39, 0x12, 0xb3, 0x93, 0x2b, 0x8d, 0x66, 0x2a, 0xb4,
+0x25, 0x83, 0x42, 0x38, 0x43, 0x20, 0x63, 0x01, 0xb5, 0x8b, 0xf2, 0x0a, 0xb6,
+0xd7, 0x6f, 0xd4, 0x7f, 0x1c, 0xbb, 0xcf, 0x42, 0x1d, 0xf5, 0x36, 0xec, 0xd7,
+0xe5, 0x6d, 0xb5, 0x35, 0x4e, 0x7e, 0x0f, 0x98, 0x82, 0x2d, 0x21, 0x29, 0xc1,
+0x97, 0xf6, 0xf0, 0xf2, 0x22, 0xb8, 0xec, 0x52, 0x31, 0xf3, 0x96, 0x7d
+}
+},
+};
+#endif /* ICA_FIPS */
+
+const struct drbg_sha512_tv DRBG_SHA512_TV[] = {
+{
+.no_reseed = true,
+.pr = false,
+.entropy_len = 256 / 8,
+.nonce_len = 128 / 8,
+.pers_len = 0,
+.add_len = 0,
+.prnd_len = 2048 / 8,
+
+.inst.entropy = (unsigned char[]){
+0x6b,0x50,0xa7,0xd8,0xf8,0xa5,0x5d,0x7a,0x3d,0xf8,0xbb,0x40,0xbc,0xc3,0xb7,0x22,
+0xd8,0x70,0x8d,0xe6,0x7f,0xda,0x01,0x0b,0x03,0xc4,0xc8,0x4d,0x72,0x09,0x6f,0x8c,
+},
+.inst.nonce = (unsigned char[]){
+0x3e,0xc6,0x49,0xcc,0x62,0x56,0xd9,0xfa,0x31,0xdb,0x7a,0x29,0x04,0xaa,0xf0,0x25,
+},
+.inst.v = (unsigned char[]){
+0xad,0xe3,0x6f,0x9a,0x01,0xc7,0x76,0x61,0x34,0x35,0xf5,0x4e,0x24,0x74,0x22,0x21,
+0x9a,0x29,0x89,0xc7,0x93,0x2e,0x60,0x1e,0xe8,0x14,0x24,0x8d,0xd5,0x03,0xf1,0x65,
+0x5d,0x08,0x22,0x72,0xd5,0xad,0x95,0xe1,0x23,0x1e,0x8a,0xa7,0x13,0xd9,0x2b,0x5e,
+0xbc,0xbb,0x80,0xab,0x8d,0xe5,0x79,0xab,0x5b,0x47,0x4e,0xdd,0xee,0x6b,0x03,0x8f,
+0x0f,0x5c,0x5e,0xa9,0x1a,0x83,0xdd,0xd3,0x88,0xb2,0x75,0x4b,0xce,0x83,0x36,0x57,
+0x4b,0xf1,0x5c,0xca,0x7e,0x09,0xc0,0xd3,0x89,0xc6,0xe0,0xda,0xc4,0x81,0x7e,0x5b,
+0xf9,0xe1,0x01,0xc1,0x92,0x05,0xea,0xf5,0x2f,0xc6,0xc6,0xc7,0x8f,0xbc,0xf4,
+},
+.inst.c = (unsigned char[]){
+0xf4,0xa3,0xe5,0xa0,0x72,0x63,0x95,0xc6,0x4f,0x48,0xd0,0x8b,0x5b,0x5f,0x8e,0x6b,
+0x96,0x1f,0x16,0xed,0xbc,0x66,0x94,0x45,0x31,0xd7,0x47,0x73,0x22,0xa5,0x86,0xce,
+0xc0,0x4c,0xac,0x63,0xb8,0x39,0x50,0xbf,0xe6,0x59,0x6c,0x38,0x58,0x99,0x1f,0x27,
+0xa7,0x9d,0x71,0x2a,0xb3,0x7b,0xf9,0xfb,0x17,0x86,0xaa,0x99,0x81,0xaa,0x43,0xe4,
+0x37,0xd3,0x1e,0x6e,0xe5,0xe6,0xee,0xc2,0xed,0x95,0x4f,0x53,0x0e,0x46,0x8a,0xcc,
+0x45,0xa5,0xdb,0x69,0x0d,0x81,0xc9,0x32,0x92,0xbc,0x8f,0x33,0xe6,0xf6,0x09,0x7c,
+0x8e,0x05,0x19,0x0d,0xf1,0xb6,0xcc,0xf3,0x02,0x21,0x90,0x25,0xec,0xed,0x0e,
+},
+.inst.reseed_ctr = 1,
+
+.gen1.v =(unsigned char[]){
+0xa2,0x87,0x55,0x3a,0x74,0x2b,0x0c,0x27,0x83,0x7e,0xc5,0xd9,0x7f,0xd3,0xb0,0x8d,
+0x30,0x48,0xa0,0xb5,0x4f,0x94,0xf4,0x64,0x19,0xeb,0x6c,0x00,0xf7,0xa9,0x78,0x34,
+0x1d,0x54,0xce,0xd6,0x8d,0xe6,0xe6,0xa1,0x09,0x77,0xf6,0xdf,0x6c,0x72,0x4b,0x26,
+0x78,0x01,0xa8,0x2e,0x3a,0x96,0x7a,0x5f,0xb0,0x63,0x6e,0xdf,0xc9,0x16,0xc0,0x93,
+0x52,0x6f,0x16,0x68,0xea,0x76,0x95,0x50,0x56,0xc9,0x54,0x09,0x44,0xce,0x67,0x73,
+0xd6,0x55,0x30,0xce,0xae,0xa7,0xcf,0xf2,0x70,0xb3,0x57,0x27,0x86,0xe9,0x60,0x09,
+0x73,0x23,0x2e,0xa5,0xdc,0xd3,0x75,0x77,0xc0,0xd9,0x84,0x37,0x19,0x9c,0x69,
+} ,
+.gen1.c = (unsigned char[]){
+0xf4,0xa3,0xe5,0xa0,0x72,0x63,0x95,0xc6,0x4f,0x48,0xd0,0x8b,0x5b,0x5f,0x8e,0x6b,
+0x96,0x1f,0x16,0xed,0xbc,0x66,0x94,0x45,0x31,0xd7,0x47,0x73,0x22,0xa5,0x86,0xce,
+0xc0,0x4c,0xac,0x63,0xb8,0x39,0x50,0xbf,0xe6,0x59,0x6c,0x38,0x58,0x99,0x1f,0x27,
+0xa7,0x9d,0x71,0x2a,0xb3,0x7b,0xf9,0xfb,0x17,0x86,0xaa,0x99,0x81,0xaa,0x43,0xe4,
+0x37,0xd3,0x1e,0x6e,0xe5,0xe6,0xee,0xc2,0xed,0x95,0x4f,0x53,0x0e,0x46,0x8a,0xcc,
+0x45,0xa5,0xdb,0x69,0x0d,0x81,0xc9,0x32,0x92,0xbc,0x8f,0x33,0xe6,0xf6,0x09,0x7c,
+0x8e,0x05,0x19,0x0d,0xf1,0xb6,0xcc,0xf3,0x02,0x21,0x90,0x25,0xec,0xed,0x0e,
+},
+.gen1.reseed_ctr = 2,
+
+.gen2.v = (unsigned char[]){
+0x97,0x2b,0x3a,0xda,0xe6,0x8e,0xa1,0xed,0xd2,0xc7,0x96,0x64,0xdb,0x33,0x3e,0xf8,
+0xc6,0x67,0xb7,0xa3,0x0b,0xfb,0x88,0xa9,0x4b,0xc2,0xb3,0x74,0x1a,0x4e,0xff,0x02,
+0xdd,0xa1,0x7b,0x3a,0x46,0x20,0x37,0x60,0xef,0xd1,0x63,0x17,0xc5,0x0b,0x6a,0xb8,
+0xbc,0x68,0x49,0x73,0xb3,0xa3,0x83,0x57,0x0e,0x00,0x53,0x78,0xdd,0x89,0xf1,0xf9,
+0xa6,0xdc,0xcb,0x83,0xb6,0xe2,0x28,0x21,0x94,0x41,0x33,0x56,0xa7,0x9c,0x52,0x3d,
+0x5e,0x38,0x1f,0x78,0xe1,0x22,0xa9,0xa2,0xd2,0xe6,0x00,0xdb,0xc1,0x61,0x85,0xf5,
+0x1c,0xca,0x1c,0x70,0xf5,0x5d,0x27,0x6a,0x76,0x63,0x1b,0xac,0x4e,0xee,0x7a,
+},
+.gen2.c = (unsigned char[]){
+0xf4,0xa3,0xe5,0xa0,0x72,0x63,0x95,0xc6,0x4f,0x48,0xd0,0x8b,0x5b,0x5f,0x8e,0x6b,
+0x96,0x1f,0x16,0xed,0xbc,0x66,0x94,0x45,0x31,0xd7,0x47,0x73,0x22,0xa5,0x86,0xce,
+0xc0,0x4c,0xac,0x63,0xb8,0x39,0x50,0xbf,0xe6,0x59,0x6c,0x38,0x58,0x99,0x1f,0x27,
+0xa7,0x9d,0x71,0x2a,0xb3,0x7b,0xf9,0xfb,0x17,0x86,0xaa,0x99,0x81,0xaa,0x43,0xe4,
+0x37,0xd3,0x1e,0x6e,0xe5,0xe6,0xee,0xc2,0xed,0x95,0x4f,0x53,0x0e,0x46,0x8a,0xcc,
+0x45,0xa5,0xdb,0x69,0x0d,0x81,0xc9,0x32,0x92,0xbc,0x8f,0x33,0xe6,0xf6,0x09,0x7c,
+0x8e,0x05,0x19,0x0d,0xf1,0xb6,0xcc,0xf3,0x02,0x21,0x90,0x25,0xec,0xed,0x0e,
+},
+.gen2.reseed_ctr = 3,
+
+.prnd = (unsigned char[]){
+0x95,0xb7,0xf1,0x7e,0x98,0x02,0xd3,0x57,0x73,0x92,0xc6,0xa9,0xc0,0x80,0x83,0xb6,
+0x7d,0xd1,0x29,0x22,0x65,0xb5,0xf4,0x2d,0x23,0x7f,0x1c,0x55,0xbb,0x9b,0x10,0xbf,
+0xcf,0xd8,0x2c,0x77,0xa3,0x78,0xb8,0x26,0x6a,0x00,0x99,0x14,0x3b,0x3c,0x2d,0x64,
+0x61,0x1e,0xee,0xb6,0x9a,0xcd,0xc0,0x55,0x95,0x7c,0x13,0x9e,0x8b,0x19,0x0c,0x7a,
+0x06,0x95,0x5f,0x2c,0x79,0x7c,0x27,0x78,0xde,0x94,0x03,0x96,0xa5,0x01,0xf4,0x0e,
+0x91,0x39,0x6a,0xcf,0x8d,0x7e,0x45,0xeb,0xdb,0xb5,0x3b,0xbf,0x8c,0x97,0x52,0x30,
+0xd2,0xf0,0xff,0x91,0x06,0xc7,0x61,0x19,0xae,0x49,0x8e,0x7f,0xbc,0x03,0xd9,0x0f,
+0x8e,0x4c,0x51,0x62,0x7a,0xed,0x5c,0x8d,0x42,0x63,0xd5,0xd2,0xb9,0x78,0x87,0x3a,
+0x0d,0xe5,0x96,0xee,0x6d,0xc7,0xf7,0xc2,0x9e,0x37,0xee,0xe8,0xb3,0x4c,0x90,0xdd,
+0x1c,0xf6,0xa9,0xdd,0xb2,0x2b,0x4c,0xbd,0x08,0x6b,0x14,0xb3,0x5d,0xe9,0x3d,0xa2,
+0xd5,0xcb,0x18,0x06,0x69,0x8c,0xbd,0x7b,0xbb,0x67,0xbf,0xe3,0xd3,0x1f,0xd2,0xd1,
+0xdb,0xd2,0xa1,0xe0,0x58,0xa3,0xeb,0x99,0xd7,0xe5,0x1f,0x1a,0x93,0x8e,0xed,0x5e,
+0x1c,0x1d,0xe2,0x3a,0x6b,0x43,0x45,0xd3,0x19,0x14,0x09,0xf9,0x2f,0x39,0xb3,0x67,
+0x0d,0x8d,0xbf,0xb6,0x35,0xd8,0xe6,0xa3,0x69,0x32,0xd8,0x10,0x33,0xd1,0x44,0x8d,
+0x63,0xb4,0x03,0xdd,0xf8,0x8e,0x12,0x1b,0x6e,0x81,0x9a,0xc3,0x81,0x22,0x6c,0x13,
+0x21,0xe4,0xb0,0x86,0x44,0xf6,0x72,0x7c,0x36,0x8c,0x5a,0x9f,0x7a,0x4b,0x3e,0xe2,
+},
+},
+{
+.no_reseed = true,
+.pr = false,
+.entropy_len = 256 / 8,
+.nonce_len = 128 / 8,
+.pers_len = 0,
+.add_len = 256 / 8,
+.prnd_len = 2048 / 8,
+
+.inst.entropy = (unsigned char[]){
+0x9c,0x96,0xa3,0x4f,0x68,0x68,0x9b,0x8a,0xa8,0xd9,0xc1,0xf6,0xcd,0x0f,0xa7,0xc6,
+0xf9,0x60,0x71,0xca,0xf1,0xbf,0x55,0x56,0xf4,0x5b,0xdb,0xf4,0x8c,0x6c,0xf0,0xc6,
+},
+.inst.nonce = (unsigned char[]){
+0x88,0x5c,0x25,0x39,0x04,0x6a,0xfb,0x14,0x01,0xeb,0x7a,0x5c,0x84,0xdb,0xd9,0xc2,
+},
+.inst.v = (unsigned char[]){
+0x11,0xb6,0xf9,0xc7,0x4e,0x77,0x32,0xa3,0x93,0xe6,0xd3,0x4f,0x4d,0x8d,0x5b,0xb9,
+0x3d,0xf8,0xd0,0x7a,0x52,0xfe,0xb5,0x30,0xe0,0x9e,0x44,0xaa,0xdc,0x90,0x19,0x16,
+0x5e,0x9c,0xf9,0x03,0x87,0xf8,0x0f,0x1a,0x41,0x62,0x16,0x90,0xff,0x29,0x08,0xb7,
+0x28,0x21,0x37,0x09,0x27,0xcb,0xc1,0xd3,0xd6,0x6d,0x47,0xa9,0xc0,0x4c,0x8e,0xd8,
+0x49,0x26,0x39,0xe3,0x8b,0xe7,0x6d,0x30,0x05,0xc1,0xc4,0xa8,0x83,0x73,0x0b,0x55,
+0xa4,0x91,0x4a,0x87,0xc9,0x73,0x31,0xbd,0x06,0xba,0xf0,0x79,0x40,0x95,0x7f,0x62,
+0x82,0xe3,0xcd,0x28,0xa3,0x7d,0xa7,0x55,0xde,0x25,0x0f,0xf1,0x08,0x38,0x85,},
+.inst.c = (unsigned char[]){
+0xb6,0xba,0xbd,0x1c,0xa5,0x4b,0x3c,0x3c,0x7c,0x5b,0xec,0xf6,0xc1,0xa0,0x52,0xa5,
+0x37,0x6e,0x2a,0x63,0x7a,0xe9,0x25,0x1a,0x8a,0xee,0x90,0xa4,0x6e,0x9b,0x0a,0xbf,
+0xe9,0xe1,0xda,0x50,0xd6,0x97,0x17,0x10,0x04,0x3a,0x3f,0xff,0x16,0xef,0x17,0x05,
+0xe4,0x98,0x27,0xd7,0xe9,0x5c,0x4e,0xed,0x90,0x9e,0x34,0xee,0x00,0x39,0x9a,0x96,
+0x22,0x10,0xcb,0x36,0x91,0x33,0xed,0x04,0xcf,0x50,0x33,0xc2,0xa8,0xda,0x69,0x2d,
+0x41,0x8c,0x70,0xec,0x14,0x10,0x62,0x37,0x9c,0xd0,0x84,0x6f,0x1a,0x32,0x72,0x5e,
+0x46,0x4d,0x7b,0x39,0xa1,0x69,0x9e,0x49,0xdc,0xc4,0x02,0x6a,0xe2,0xd8,0x7e,
+},
+.inst.reseed_ctr = 1,
+
+.gen1.add = (unsigned char[]){
+0xcb,0x61,0xc4,0xf7,0x5c,0x01,0xb5,0x78,0xaa,0x23,0x3a,0x0b,0xae,0x48,0x81,0xc0,
+0xa1,0x15,0x27,0xc2,0x2f,0xe7,0xb3,0x4f,0xb6,0xae,0x62,0xee,0xbc,0xfe,0x60,0x85,
+},
+.gen1.v = (unsigned char[]){
+0xc8,0x71,0xb6,0xe3,0xf3,0xc2,0x6e,0xe0,0x10,0x42,0xc0,0x46,0x0f,0x2d,0xae,0x5e,
+0x75,0x66,0xfa,0xdd,0xcd,0xe7,0xda,0x4b,0x6b,0x8c,0xd5,0x4f,0x4b,0x2b,0x23,0xd6,
+0x48,0x7e,0xd3,0x54,0x5e,0x8f,0x26,0x2a,0x45,0x9c,0x56,0x90,0x16,0x18,0x20,0xc4,
+0xd7,0x95,0xe0,0xb1,0xd2,0xc5,0x25,0x5c,0x61,0xe5,0xa0,0x1b,0xa2,0xee,0x46,0x8e,
+0xfe,0x9e,0xdf,0x2a,0x9d,0x68,0x0f,0x37,0x5d,0x37,0xd7,0x2f,0x43,0xf2,0x08,0x3e,
+0x92,0x6d,0x6d,0x78,0xb2,0x21,0x95,0xdd,0xb6,0x4f,0x40,0xbc,0x0c,0x56,0xc4,0x5a,
+0x0d,0x48,0x14,0x19,0xbf,0x2e,0x29,0xca,0xec,0xfc,0xbd,0xca,0x32,0xbc,0x2e,
+},
+.gen1.c = (unsigned char[]){
+0xb6,0xba,0xbd,0x1c,0xa5,0x4b,0x3c,0x3c,0x7c,0x5b,0xec,0xf6,0xc1,0xa0,0x52,0xa5,
+0x37,0x6e,0x2a,0x63,0x7a,0xe9,0x25,0x1a,0x8a,0xee,0x90,0xa4,0x6e,0x9b,0x0a,0xbf,
+0xe9,0xe1,0xda,0x50,0xd6,0x97,0x17,0x10,0x04,0x3a,0x3f,0xff,0x16,0xef,0x17,0x05,
+0xe4,0x98,0x27,0xd7,0xe9,0x5c,0x4e,0xed,0x90,0x9e,0x34,0xee,0x00,0x39,0x9a,0x96,
+0x22,0x10,0xcb,0x36,0x91,0x33,0xed,0x04,0xcf,0x50,0x33,0xc2,0xa8,0xda,0x69,0x2d,
+0x41,0x8c,0x70,0xec,0x14,0x10,0x62,0x37,0x9c,0xd0,0x84,0x6f,0x1a,0x32,0x72,0x5e,
+0x46,0x4d,0x7b,0x39,0xa1,0x69,0x9e,0x49,0xdc,0xc4,0x02,0x6a,0xe2,0xd8,0x7e,
+},
+.gen1.reseed_ctr = 2,
+
+.gen2.add = (unsigned char[]){
+0xc0,0x66,0xfd,0x2e,0xb8,0xe4,0xae,0xa2,0xe7,0x14,0x5e,0xda,0x0c,0xfc,0x8b,0xef,
+0x5e,0xed,0xcc,0x36,0x7b,0x1c,0xb4,0xde,0x7e,0xb2,0xc2,0x75,0x9f,0xa7,0x5b,0xf7,
+},
+.gen2.v = (unsigned char[]){
+0x7f,0x2c,0x74,0x00,0x99,0x0d,0xab,0x1c,0x8c,0x9e,0xad,0x3c,0xd0,0xce,0x01,0x03,
+0xac,0xd5,0x25,0x41,0x48,0xd0,0xff,0x65,0xf6,0x7b,0x65,0xf3,0xb9,0xc6,0x2e,0x96,
+0x32,0x60,0xad,0xa5,0x35,0x26,0x3d,0x3a,0x49,0xd6,0x96,0x8f,0x2d,0x07,0x38,0xf1,
+0xff,0x65,0xdf,0x49,0x81,0xe3,0xf6,0x71,0x0c,0x7e,0x69,0xec,0xc0,0x61,0x16,0xa8,
+0x27,0xa5,0x38,0x37,0x38,0x52,0x56,0xb8,0x2b,0x25,0x7b,0x70,0x33,0x15,0x79,0xb2,
+0x2a,0xbd,0x05,0x55,0x3e,0x2d,0x36,0x14,0x66,0xe4,0x83,0x97,0x2a,0xbe,0x31,0x10,
+0xcd,0x4d,0x09,0x35,0x99,0x9a,0x21,0xd1,0xce,0x3d,0x98,0x0d,0x4a,0x31,0xec,
+},
+.gen2.c = (unsigned char[]){
+0xb6,0xba,0xbd,0x1c,0xa5,0x4b,0x3c,0x3c,0x7c,0x5b,0xec,0xf6,0xc1,0xa0,0x52,0xa5,
+0x37,0x6e,0x2a,0x63,0x7a,0xe9,0x25,0x1a,0x8a,0xee,0x90,0xa4,0x6e,0x9b,0x0a,0xbf,
+0xe9,0xe1,0xda,0x50,0xd6,0x97,0x17,0x10,0x04,0x3a,0x3f,0xff,0x16,0xef,0x17,0x05,
+0xe4,0x98,0x27,0xd7,0xe9,0x5c,0x4e,0xed,0x90,0x9e,0x34,0xee,0x00,0x39,0x9a,0x96,
+0x22,0x10,0xcb,0x36,0x91,0x33,0xed,0x04,0xcf,0x50,0x33,0xc2,0xa8,0xda,0x69,0x2d,
+0x41,0x8c,0x70,0xec,0x14,0x10,0x62,0x37,0x9c,0xd0,0x84,0x6f,0x1a,0x32,0x72,0x5e,
+0x46,0x4d,0x7b,0x39,0xa1,0x69,0x9e,0x49,0xdc,0xc4,0x02,0x6a,0xe2,0xd8,0x7e,
+},
+.gen2.reseed_ctr = 3,
+
+.prnd = (unsigned char[]){
+0x78,0x2c,0x20,0x8e,0xd5,0x80,0x44,0xe7,0x8b,0x5b,0xbb,0xd8,0x77,0x2a,0x3c,0xaf,
+0x25,0xb4,0x7d,0x36,0xaf,0xeb,0x0d,0x34,0x93,0xc4,0x3e,0x01,0xcc,0x66,0xa0,0xca,
+0x2f,0xac,0xed,0x2a,0xb1,0x86,0xbc,0x46,0x82,0x5d,0x98,0x9c,0xf8,0xee,0x7c,0x95,
+0xf8,0xc0,0xb0,0xd2,0xb7,0x6e,0x6c,0x85,0x90,0xe7,0x28,0x34,0xd4,0xc5,0x24,0x45,
+0xae,0xce,0xeb,0x7b,0xf5,0xf5,0xd9,0xac,0x44,0xa1,0x2c,0xbd,0x3f,0xa7,0xf4,0x46,
+0x2f,0x85,0x64,0x52,0xdc,0x4a,0x92,0x91,0x82,0xd2,0x38,0x8a,0xa7,0x63,0x5b,0x96,
+0x98,0xa9,0x12,0x58,0x5d,0xf7,0xf5,0x60,0xad,0xc5,0x08,0x0d,0x53,0xb8,0x2b,0xbd,
+0x7e,0x9e,0x48,0x0b,0x00,0xd1,0xda,0x5b,0xb2,0xd4,0x80,0xca,0xe2,0xba,0x8c,0x67,
+0xd4,0xbf,0x3b,0xfd,0x14,0x6a,0x91,0xd6,0xaa,0xb3,0x9f,0xaa,0xe1,0x60,0x0a,0xf2,
+0xce,0x32,0x04,0xca,0xbf,0x4c,0x1c,0xae,0xe4,0xcf,0xd5,0xe6,0xf8,0xdb,0x19,0x02,
+0x03,0x3f,0x7f,0x8d,0x33,0xbc,0x6e,0x0e,0x5d,0x32,0xa3,0x20,0xba,0x73,0x5d,0x09,
+0x1f,0x30,0x86,0x7b,0x7c,0xb7,0x88,0x0c,0x2e,0x3c,0xe6,0xaa,0xda,0x79,0x66,0x41,
+0x91,0xdf,0x36,0x0d,0x35,0xfe,0x9a,0xe7,0xba,0xbc,0xa4,0x14,0x85,0xb0,0x6a,0xb4,
+0x9d,0xff,0x52,0x87,0x82,0xfb,0xe6,0xf2,0xb0,0xe7,0x49,0x96,0xe9,0xce,0x92,0x72,
+0xd1,0xef,0x39,0x2b,0xe5,0xc1,0x7c,0xc6,0x2c,0x74,0xbe,0x50,0x4e,0x6a,0x87,0x31,
+0xdd,0x95,0x48,0xb0,0xdb,0x27,0xe0,0xb7,0xdb,0x48,0x86,0xf5,0x37,0x88,0x36,0x23,
+},
+},
+{
+.no_reseed = true,
+.pr = false,
+.entropy_len = 256 / 8,
+.nonce_len = 128 / 8,
+.pers_len = 256 / 8,
+.add_len = 0,
+.prnd_len = 2048 / 8,
+
+.inst.entropy = (unsigned char[]){
+0xb5,0x10,0xa6,0x0a,0x5a,0x19,0x00,0x7b,0xa8,0x08,0xe6,0x0b,0x16,0x28,0xed,0x99,
+0x07,0xd1,0xbe,0xf9,0x92,0xd4,0xfc,0x0a,0xbe,0x51,0x50,0x01,0x31,0xcb,0x4c,0xf8,
+},
+.inst.nonce = (unsigned char[]){
+0xeb,0x1b,0xd7,0x83,0xac,0xcc,0x85,0x5e,0xb3,0x20,0xcd,0xe1,0x0b,0x1b,0xe6,0xd0,
+},
+.inst.pers = (unsigned char[]){
+0x7e,0xa1,0x0e,0x96,0xaf,0x90,0x0c,0x25,0xd3,0xbe,0x3b,0x50,0xa0,0xcc,0x71,0xa7,
+0x9f,0xe4,0x14,0xbd,0x4c,0x37,0x39,0x80,0x3f,0x02,0xff,0xe5,0xb2,0x60,0xbf,0xbb,
+},
+.inst.v = (unsigned char[]){
+0x6e,0x10,0x09,0xeb,0x74,0x25,0x4e,0x17,0xbc,0xa3,0x2a,0xb7,0xbc,0x01,0x91,0xba,
+0x70,0x89,0xb7,0x8c,0x4b,0xa4,0xbb,0xab,0xab,0x03,0xfc,0x6c,0x1e,0xa5,0xb7,0xdb,
+0xef,0x37,0xec,0xcd,0x5f,0x70,0x7f,0x99,0x11,0xab,0x57,0xe4,0xd1,0x8d,0x34,0x84,
+0x53,0x42,0x42,0x90,0x07,0x33,0x61,0x5d,0x66,0xf2,0x2b,0x76,0x90,0x1e,0x08,0xcc,
+0x0d,0x86,0xa3,0x89,0xc8,0x6f,0x27,0x12,0xab,0x34,0x05,0x23,0x66,0x36,0x14,0x1d,
+0xdd,0xc8,0xae,0x83,0xaa,0x33,0x77,0x21,0xf5,0x7e,0x23,0x08,0xf8,0x15,0x0a,0x35,
+0x0f,0x07,0xef,0x94,0x68,0x26,0xef,0x80,0xba,0x20,0xfe,0x20,0x23,0xe4,0x39,
+},
+.inst.c = (unsigned char[]){
+0x61,0x67,0x19,0xd5,0xd6,0xa4,0xdf,0xd8,0x39,0x9e,0x41,0xf3,0x67,0x7e,0x12,0xcc,
+0xbd,0x2e,0x3d,0x1e,0x1d,0xc5,0x7b,0xa0,0xb7,0x1d,0x1c,0x61,0x5a,0x50,0x14,0xd7,
+0x33,0x63,0x7f,0x2c,0x6f,0x0a,0x5e,0x97,0xe7,0x78,0x31,0x59,0xbe,0x99,0xf7,0x47,
+0x7a,0x31,0x7a,0x5c,0x72,0x56,0x52,0xcc,0xd6,0x31,0x95,0xd9,0x73,0x6d,0xf9,0xa9,
+0x7e,0x6f,0x59,0x4e,0x57,0x0b,0xad,0x9f,0x99,0x7a,0xa3,0x8b,0xdf,0x51,0x44,0xda,
+0x63,0x61,0xfe,0x9b,0xe2,0x82,0x88,0x20,0x5a,0xbc,0x9d,0x8b,0x41,0x1f,0x5f,0x38,
+0x0a,0x56,0x15,0xce,0xfe,0x6d,0x3e,0x82,0x88,0xda,0x5f,0x43,0x01,0xfb,0x08,
+},
+.inst.reseed_ctr = 1,
+
+.gen1.v = (unsigned char[]){
+0xcf,0x77,0x23,0xc1,0x4a,0xca,0x2d,0xef,0xf6,0x41,0x6c,0xab,0x23,0x7f,0xa4,0x87,
+0x2d,0xb7,0xf4,0xaa,0x69,0x6a,0x37,0x4c,0x62,0x21,0x18,0xcd,0x78,0xf5,0xcc,0xb3,
+0x22,0x9b,0x6b,0xf9,0xce,0x7a,0xde,0x30,0xf9,0x23,0x89,0x3e,0x90,0x27,0x2c,0xa2,
+0x36,0x72,0xbc,0x98,0xda,0xea,0x39,0xca,0x18,0x52,0x1a,0xcc,0xc2,0x56,0x41,0xff,
+0x36,0x00,0xf4,0x40,0x89,0x45,0x24,0x63,0x29,0x31,0x87,0xf2,0x41,0x98,0xca,0x38,
+0x45,0x39,0xdd,0xaa,0xbb,0x5c,0x4b,0x72,0xb5,0x33,0xf1,0x51,0xec,0xcf,0x82,0x53,
+0x6d,0xf2,0xcf,0x82,0x9a,0x69,0x41,0xf7,0x0b,0x95,0x49,0xe4,0xc2,0xd9,0x6e,
+},
+.gen1.c = (unsigned char[]){
+0x61,0x67,0x19,0xd5,0xd6,0xa4,0xdf,0xd8,0x39,0x9e,0x41,0xf3,0x67,0x7e,0x12,0xcc,
+0xbd,0x2e,0x3d,0x1e,0x1d,0xc5,0x7b,0xa0,0xb7,0x1d,0x1c,0x61,0x5a,0x50,0x14,0xd7,
+0x33,0x63,0x7f,0x2c,0x6f,0x0a,0x5e,0x97,0xe7,0x78,0x31,0x59,0xbe,0x99,0xf7,0x47,
+0x7a,0x31,0x7a,0x5c,0x72,0x56,0x52,0xcc,0xd6,0x31,0x95,0xd9,0x73,0x6d,0xf9,0xa9,
+0x7e,0x6f,0x59,0x4e,0x57,0x0b,0xad,0x9f,0x99,0x7a,0xa3,0x8b,0xdf,0x51,0x44,0xda,
+0x63,0x61,0xfe,0x9b,0xe2,0x82,0x88,0x20,0x5a,0xbc,0x9d,0x8b,0x41,0x1f,0x5f,0x38,
+0x0a,0x56,0x15,0xce,0xfe,0x6d,0x3e,0x82,0x88,0xda,0x5f,0x43,0x01,0xfb,0x08,
+},
+.gen1.reseed_ctr = 2,
+
+.gen2.v = (unsigned char[]){
+0x30,0xde,0x3d,0x97,0x21,0x6f,0x0d,0xc8,0x2f,0xdf,0xae,0x9e,0x8a,0xfd,0xb7,0x53,
+0xea,0xe6,0x31,0xc8,0x87,0x2f,0xb2,0xed,0x19,0x3e,0x35,0x2e,0xd3,0x45,0xe1,0x8a,
+0x55,0xfe,0xeb,0x26,0x3d,0x85,0x3c,0xc8,0xe0,0x9b,0xba,0x98,0x4e,0xc1,0x24,0x3f,
+0x77,0x1a,0x2c,0x1a,0x65,0x07,0x99,0x3f,0x08,0xe9,0x48,0x16,0x77,0x03,0x0d,0xa7,
+0x8b,0xc5,0x13,0xcf,0x4d,0xf3,0x3e,0xf5,0xe1,0x61,0x09,0x2e,0xee,0x86,0xfb,0x21,
+0x40,0x70,0x1b,0x20,0xdf,0x82,0xde,0x4c,0x3b,0xf0,0xe7,0x67,0x36,0xf6,0x24,0x82,
+0xc7,0x94,0xff,0xd2,0x99,0x73,0x5f,0x49,0x13,0x23,0x77,0x8e,0xa4,0x72,0x8f,
+},
+.gen2.c = (unsigned char[]){
+0x61,0x67,0x19,0xd5,0xd6,0xa4,0xdf,0xd8,0x39,0x9e,0x41,0xf3,0x67,0x7e,0x12,0xcc,
+0xbd,0x2e,0x3d,0x1e,0x1d,0xc5,0x7b,0xa0,0xb7,0x1d,0x1c,0x61,0x5a,0x50,0x14,0xd7,
+0x33,0x63,0x7f,0x2c,0x6f,0x0a,0x5e,0x97,0xe7,0x78,0x31,0x59,0xbe,0x99,0xf7,0x47,
+0x7a,0x31,0x7a,0x5c,0x72,0x56,0x52,0xcc,0xd6,0x31,0x95,0xd9,0x73,0x6d,0xf9,0xa9,
+0x7e,0x6f,0x59,0x4e,0x57,0x0b,0xad,0x9f,0x99,0x7a,0xa3,0x8b,0xdf,0x51,0x44,0xda,
+0x63,0x61,0xfe,0x9b,0xe2,0x82,0x88,0x20,0x5a,0xbc,0x9d,0x8b,0x41,0x1f,0x5f,0x38,
+0x0a,0x56,0x15,0xce,0xfe,0x6d,0x3e,0x82,0x88,0xda,0x5f,0x43,0x01,0xfb,0x08,
+},
+.gen2.reseed_ctr = 3,
+
+.prnd = (unsigned char[]){
+0x5f,0x03,0xab,0x52,0x9b,0x9e,0xda,0xb5,0x5e,0x75,0xe4,0x89,0xbc,0xeb,0x0a,0xb6,
+0xcb,0x9e,0xc6,0x25,0x5c,0x61,0x96,0xcd,0x07,0x53,0x97,0xb0,0x91,0xc3,0xeb,0x59,
+0x8e,0x31,0x62,0x32,0x0c,0x71,0xe3,0x89,0xe1,0xd9,0xd6,0x2a,0x2d,0xe5,0x99,0x0c,
+0x20,0x97,0x56,0x10,0x84,0xe1,0x3a,0xb4,0xb2,0x97,0x7f,0x99,0xc2,0x3d,0xaf,0x21,
+0x4b,0xbf,0xeb,0x16,0x21,0x67,0xc9,0x33,0x86,0x0f,0xb2,0xcc,0x9f,0x80,0x07,0x9e,
+0x17,0x89,0x39,0x62,0xff,0x03,0xa2,0x6b,0x2b,0x4b,0x83,0x8e,0x6d,0xe9,0xff,0x5e,
+0x9d,0xcf,0xba,0x73,0xac,0xc6,0xee,0x76,0xc4,0x77,0xd1,0xf7,0x00,0x22,0x65,0xe6,
+0x93,0x85,0x0a,0x26,0x0e,0x68,0x61,0x7f,0x13,0xb2,0x47,0x16,0xd8,0xdb,0x42,0xc9,
+0xa8,0xf2,0xe0,0xbd,0x50,0x02,0x28,0x9a,0x86,0xb0,0x2a,0x84,0x5d,0x98,0x86,0xd3,
+0xfd,0x05,0xd8,0xd8,0x5a,0xc7,0x7e,0xa6,0x01,0x92,0xa2,0x90,0x47,0x30,0x3a,0x03,
+0xb5,0x1e,0x0e,0x70,0x8f,0xa0,0x02,0x05,0xb5,0xc0,0x3b,0x67,0xb7,0x78,0x74,0x05,
+0x2c,0xe5,0x6d,0x5c,0xf3,0x8e,0x72,0x6d,0x60,0x8b,0xc0,0xef,0x8f,0xc2,0xa7,0xd2,
+0x77,0x78,0xf4,0x7c,0x68,0x91,0x63,0x7b,0x63,0x1c,0xcc,0x6e,0x36,0xeb,0x89,0x3f,
+0xe0,0x8a,0x5b,0x9f,0x55,0x71,0xbd,0x43,0x2c,0x82,0x6d,0x99,0x69,0x8f,0xd4,0x17,
+0x9b,0xc5,0xcf,0xb0,0xd8,0xea,0x2d,0x55,0x5c,0x36,0xb7,0x05,0x68,0xc2,0x20,0x6b,
+0x18,0xf3,0xbe,0xa1,0x4b,0x39,0x8d,0x2b,0x6a,0x00,0x12,0x2d,0x7a,0x44,0x7e,0xa3,
+},
+},
+{
+.no_reseed = true,
+.pr = false,
+.entropy_len = 256 / 8,
+.nonce_len = 128 / 8,
+.pers_len = 256 / 8,
+.add_len = 256 / 8,
+.prnd_len = 2048 / 8,
+
+.inst.entropy = (unsigned char[]){
+0xb1,0x48,0xb3,0x17,0xa2,0x68,0x62,0x8f,0x04,0xc9,0xa8,0x7a,0x0a,0xc5,0xf9,0x14,
+0x98,0xb8,0x02,0x0f,0x4e,0x48,0x35,0x72,0x0c,0x1a,0x3c,0xc0,0x7b,0x05,0x0f,0xa2,
+},
+.inst.nonce = (unsigned char[]){
+0x2f,0x35,0xe5,0xb6,0x22,0xae,0xef,0xe7,0x56,0x05,0xc2,0x27,0x4e,0xc8,0xc6,0x96,
+},
+.inst.pers = (unsigned char[]){
+0xfc,0x52,0x7a,0x2f,0x16,0xb5,0x3c,0x51,0x3f,0x94,0x85,0x5b,0x35,0xce,0xa6,0x09,
+0x0c,0x30,0x3d,0xcc,0x64,0x2e,0x98,0xed,0x5f,0x32,0x3a,0xba,0x0f,0x35,0xfa,0x27,
+},
+.inst.v = (unsigned char[]){
+0xc0,0xcb,0x7d,0x99,0x92,0xeb,0x7d,0x59,0x7e,0xbe,0x77,0x6d,0x6a,0x88,0x68,0x81,
+0xc1,0x79,0x15,0xeb,0x90,0xb7,0x67,0x2d,0xee,0x5c,0x18,0xcb,0x10,0xd4,0xb9,0xfb,
+0x7b,0x66,0x1d,0x0b,0xa6,0x8f,0x1b,0xef,0x72,0xbe,0xeb,0xc0,0x40,0x98,0x2c,0xe7,
+0xcb,0xb2,0xd0,0xb9,0x0b,0xfd,0x3a,0xce,0x08,0xea,0x37,0xa3,0x3e,0x71,0x41,0x27,
+0x18,0xb1,0xc0,0xe6,0x85,0x63,0xad,0x5b,0x35,0x3a,0x20,0xa5,0x84,0xad,0xf0,0x4c,
+0xfa,0x4a,0x19,0x91,0x7c,0xf3,0x42,0xa1,0x3f,0x9f,0x51,0xbb,0x12,0xf3,0xe2,0x4b,
+0x3b,0x1d,0xf0,0xf7,0x03,0xcb,0xa2,0x09,0x9f,0x63,0x2c,0x63,0x99,0xe7,0x4c,
+},
+.inst.c = (unsigned char[]){
+0x02,0xd6,0x77,0x70,0xe8,0x13,0x7f,0x9b,0x39,0x96,0x09,0x63,0xae,0xa6,0x82,0x73,
+0xe2,0x6c,0x75,0x94,0x5b,0xe1,0x13,0x6a,0xc1,0x4a,0xdd,0xdc,0xa6,0x33,0x90,0x43,
+0xdc,0xab,0x44,0xe7,0xd1,0x2b,0xf1,0x1d,0xc4,0x30,0xa9,0x67,0x26,0xa7,0xa0,0x29,
+0xeb,0x0e,0xc0,0x39,0xe0,0x37,0x6a,0x12,0x45,0x48,0x1a,0xeb,0x7e,0x06,0x8a,0x12,
+0xb7,0x5f,0x55,0xd5,0xad,0x5f,0xe6,0xe5,0xb2,0x37,0xad,0x50,0xbc,0x9e,0x2d,0x91,
+0xb7,0xce,0xaa,0x3a,0x23,0xfb,0xbb,0x04,0x49,0xe1,0x6f,0xdb,0xab,0x57,0xde,0x0a,
+0xef,0xd8,0xd1,0x7f,0x36,0x28,0x1c,0x74,0x25,0x90,0xda,0xf8,0x3c,0x14,0x3d,
+},
+.inst.reseed_ctr = 1,
+
+.gen1.add = (unsigned char[]){
+0x2c,0xc9,0xf1,0x37,0xfc,0xd8,0xc2,0xd5,0x26,0xd7,0x00,0x93,0xfe,0x11,0xf9,0x0a,
+0x0a,0x36,0xbc,0x97,0x64,0xa4,0xc5,0x60,0x90,0x72,0xe1,0x81,0xa2,0x49,0x45,0x16,
+},
+.gen1.v =(unsigned char[]){
+0xc3,0xa1,0xf5,0x0a,0x7a,0xfe,0xfc,0xf4,0xb8,0x54,0x80,0xd1,0x19,0x2e,0xea,0xf5,
+0xa3,0xe5,0x8b,0x7f,0xec,0x98,0x7a,0x98,0xaf,0xa6,0xf6,0xa7,0xb7,0x08,0x4a,0x3f,
+0x58,0x11,0x61,0xf3,0x77,0xbb,0x0d,0x0d,0x36,0xef,0x95,0x27,0x67,0x3f,0xcd,0xf7,
+0xc0,0xa6,0x8e,0x23,0x93,0x29,0x5e,0xdc,0x31,0x2d,0x32,0xc1,0x89,0xf7,0x7c,0xbb,
+0x60,0xbe,0xdc,0x1e,0x7c,0x7a,0x16,0x77,0x81,0x5f,0x06,0x6f,0x70,0x37,0x43,0xfb,
+0xcc,0xbe,0x3b,0x59,0x24,0x35,0x4e,0x7a,0xd0,0x88,0xd1,0xde,0xd4,0x1a,0x70,0x39,
+0xbb,0x52,0x6a,0x91,0xef,0x70,0xe1,0xb1,0xdf,0xc9,0x39,0xc3,0xcc,0x04,0x58,
+} ,
+.gen1.c = (unsigned char[]){
+0x02,0xd6,0x77,0x70,0xe8,0x13,0x7f,0x9b,0x39,0x96,0x09,0x63,0xae,0xa6,0x82,0x73,
+0xe2,0x6c,0x75,0x94,0x5b,0xe1,0x13,0x6a,0xc1,0x4a,0xdd,0xdc,0xa6,0x33,0x90,0x43,
+0xdc,0xab,0x44,0xe7,0xd1,0x2b,0xf1,0x1d,0xc4,0x30,0xa9,0x67,0x26,0xa7,0xa0,0x29,
+0xeb,0x0e,0xc0,0x39,0xe0,0x37,0x6a,0x12,0x45,0x48,0x1a,0xeb,0x7e,0x06,0x8a,0x12,
+0xb7,0x5f,0x55,0xd5,0xad,0x5f,0xe6,0xe5,0xb2,0x37,0xad,0x50,0xbc,0x9e,0x2d,0x91,
+0xb7,0xce,0xaa,0x3a,0x23,0xfb,0xbb,0x04,0x49,0xe1,0x6f,0xdb,0xab,0x57,0xde,0x0a,
+0xef,0xd8,0xd1,0x7f,0x36,0x28,0x1c,0x74,0x25,0x90,0xda,0xf8,0x3c,0x14,0x3d,
+},
+.gen1.reseed_ctr = 2,
+
+.gen2.add = (unsigned char[]){
+0xe4,0x03,0x61,0x24,0x5b,0x91,0x88,0x0e,0x30,0x8f,0xb7,0x77,0xc2,0x8b,0xbf,0xae,
+0xa5,0x98,0x2e,0x45,0xfe,0xcb,0x77,0x57,0xbb,0x1c,0x9d,0xe2,0xdf,0x9d,0xc6,0x12,
+},
+.gen2.v = (unsigned char[]){
+0xc6,0x78,0x6c,0x7b,0x63,0x12,0x7c,0x8f,0xf1,0xea,0x8a,0x34,0xc7,0xd5,0x6d,0x69,
+0x86,0x52,0x01,0x14,0x48,0x79,0x8e,0x03,0x70,0xf1,0xd4,0x84,0x5d,0x3b,0xda,0x83,
+0x34,0xbc,0xa6,0xdb,0x48,0xe6,0xfe,0x2a,0xfb,0x20,0x3e,0x8e,0x8d,0xe7,0x6e,0xe5,
+0x30,0x94,0x36,0x9e,0x68,0xb3,0x2d,0xb7,0xe1,0xf7,0x18,0x53,0xc1,0xa3,0x0b,0x9c,
+0xb5,0x5b,0x06,0x7b,0x9a,0x19,0x87,0xe9,0x18,0x80,0xf2,0xc8,0xdc,0x5d,0x77,0xec,
+0x26,0x7c,0x12,0xcb,0x99,0xeb,0xf4,0xc3,0xf0,0xe1,0x3d,0xa4,0x74,0x45,0xe0,0xec,
+0x23,0x49,0xa7,0x1d,0x34,0x16,0x8e,0x33,0xfe,0xbb,0x65,0x7f,0x8d,0x12,0xc7,
+},
+.gen2.c = (unsigned char[]){
+0x02,0xd6,0x77,0x70,0xe8,0x13,0x7f,0x9b,0x39,0x96,0x09,0x63,0xae,0xa6,0x82,0x73,
+0xe2,0x6c,0x75,0x94,0x5b,0xe1,0x13,0x6a,0xc1,0x4a,0xdd,0xdc,0xa6,0x33,0x90,0x43,
+0xdc,0xab,0x44,0xe7,0xd1,0x2b,0xf1,0x1d,0xc4,0x30,0xa9,0x67,0x26,0xa7,0xa0,0x29,
+0xeb,0x0e,0xc0,0x39,0xe0,0x37,0x6a,0x12,0x45,0x48,0x1a,0xeb,0x7e,0x06,0x8a,0x12,
+0xb7,0x5f,0x55,0xd5,0xad,0x5f,0xe6,0xe5,0xb2,0x37,0xad,0x50,0xbc,0x9e,0x2d,0x91,
+0xb7,0xce,0xaa,0x3a,0x23,0xfb,0xbb,0x04,0x49,0xe1,0x6f,0xdb,0xab,0x57,0xde,0x0a,
+0xef,0xd8,0xd1,0x7f,0x36,0x28,0x1c,0x74,0x25,0x90,0xda,0xf8,0x3c,0x14,0x3d,
+},
+.gen2.reseed_ctr = 3,
+
+.prnd = (unsigned char[]){
+0x66,0xad,0x04,0x8b,0x4d,0x2d,0x00,0x32,0x23,0xc6,0x4d,0xd9,0x82,0x7c,0xc2,0x2e,
+0xd3,0xec,0x8f,0xcb,0x61,0x20,0x9d,0x19,0x96,0x19,0x17,0x75,0x92,0xe9,0xb8,0x92,
+0x26,0xbe,0x30,0xb1,0x93,0x0b,0xdd,0x74,0x9f,0x30,0xed,0x09,0xda,0x52,0xab,0xaa,
+0x2e,0x59,0x9a,0xfa,0xf9,0x19,0x03,0xe7,0xa2,0xb5,0x9f,0xfb,0x8f,0xd4,0x70,0xe6,
+0x60,0x44,0x85,0xa2,0x7c,0x20,0x0d,0x37,0x5f,0xef,0xf6,0x21,0x11,0x85,0x95,0xa7,
+0xa3,0x05,0x7b,0x7e,0x31,0xea,0xdc,0x06,0x87,0xb1,0x00,0x8c,0x3c,0xb2,0xc7,0x43,
+0x5a,0x57,0x04,0xb1,0xa1,0xa6,0xa3,0x48,0x7d,0x60,0xfd,0x14,0x79,0x3c,0x31,0x48,
+0x6a,0xf7,0x65,0xce,0x2c,0xe1,0x82,0xde,0x88,0x11,0x24,0x45,0xdd,0x5f,0xf1,0x1b,
+0x25,0x6c,0xfd,0xa0,0x70,0x18,0xb9,0x5f,0x97,0xed,0xba,0xb4,0xe4,0xc3,0x9c,0xa0,
+0x97,0xc4,0x2f,0x9d,0xce,0x80,0xcd,0x3f,0x32,0x67,0x7f,0x3c,0x22,0x4a,0x86,0xb3,
+0x15,0xd0,0x2e,0x37,0x7d,0xca,0x8f,0x37,0x85,0xe9,0x74,0x8f,0xfd,0xbe,0x3f,0xca,
+0xa3,0xb0,0xc6,0xbf,0x00,0x1b,0x63,0xb5,0x74,0x26,0x83,0x63,0x58,0xe9,0xb3,0x15,
+0xc6,0x71,0x8e,0x0b,0x74,0xfb,0x82,0xb9,0xbf,0x3d,0xf7,0x00,0xa6,0x41,0xab,0x94,
+0x11,0xd1,0xb9,0xfb,0xa4,0x23,0x09,0xa8,0x4b,0xef,0x67,0xa1,0x42,0x04,0xf3,0x16,
+0x0e,0xd1,0x6a,0x54,0x97,0xfe,0x21,0x1a,0xa1,0xf5,0xd3,0xae,0x4b,0x85,0x8b,0x6d,
+0x44,0x5f,0x1d,0x09,0x45,0x43,0xd0,0x10,0x7c,0xe0,0x4e,0xf1,0xd1,0xba,0x33,0xab,
+},
+},
+{
+.no_reseed = false,
+.pr = true,
+.entropy_len = 256 / 8,
+.nonce_len = 128 / 8,
+.pers_len = 0,
+.add_len = 0,
+.prnd_len = 2048 / 8,
+
+.inst.entropy = (unsigned char[]){
+0x73,0xc9,0xb1,0x15,0xb7,0xef,0xb0,0xa6,0x32,0x44,0xd7,0x49,0x3a,0xe5,0x82,0x05,
+0x99,0xd7,0xce,0xe5,0xca,0x05,0x4d,0xb2,0xf7,0x26,0x9b,0xa7,0xf6,0x21,0xbd,0xca,
+},
+.inst.nonce = (unsigned char[]){
+0xc2,0x04,0xe6,0xde,0x78,0x9b,0x03,0x94,0xfb,0xbe,0x66,0x63,0x46,0x6e,0xfc,0xea,
+},
+.inst.v = (unsigned char[]){
+0xf7,0xba,0x3c,0xf1,0x65,0xbe,0x38,0x8f,0x1e,0x05,0x02,0xac,0x63,0x92,0x02,0x21,
+0xd2,0x7c,0x05,0x1e,0x44,0x7e,0xc3,0xd3,0x08,0x91,0x4d,0xa7,0xfe,0x17,0x6c,0xc7,
+0xfb,0x91,0x46,0xdc,0x86,0x0e,0x5a,0x5a,0xda,0x53,0xda,0x7d,0x8b,0xb8,0xf6,0x7a,
+0xc8,0xe2,0x5f,0xe9,0x44,0xd4,0x53,0xf0,0x99,0x75,0x6b,0xc5,0xae,0x58,0xef,0xbf,
+0x80,0x2d,0x07,0x83,0x01,0xf8,0xdf,0xad,0x9c,0x9e,0xd4,0xb3,0x3c,0x56,0x0f,0x43,
+0xe4,0x9b,0xf4,0xfb,0xd3,0x53,0x48,0x00,0xac,0xeb,0xd1,0xf2,0xc3,0x81,0x77,0x2b,
+0x21,0x33,0xe4,0xff,0x46,0x9e,0xa4,0x99,0x65,0xd9,0xc2,0x57,0x58,0xf2,0xab,
+},
+.inst.c = (unsigned char[]){
+0x20,0xc0,0xbc,0xf1,0x5a,0x1e,0xd3,0xb5,0x89,0x0f,0xb3,0xc7,0xc7,0x55,0xfe,0x2f,
+0x57,0x45,0x93,0x0d,0xa0,0xf6,0x53,0x03,0x04,0xe3,0xed,0xfa,0xec,0x45,0x69,0xc8,
+0x79,0x60,0x64,0x7f,0xa1,0xda,0xc7,0x1c,0x31,0x61,0xe4,0xaf,0xde,0x6b,0x87,0xd4,
+0x1f,0x1b,0x1b,0x9a,0xbf,0x7f,0x5b,0x5f,0x63,0xa6,0x7c,0xd6,0xa6,0x05,0xaf,0xf2,
+0x31,0x1d,0x7b,0x46,0xea,0xdd,0xf9,0x75,0x29,0x9a,0x13,0x2c,0xc3,0xc2,0x72,0xcc,
+0x4e,0x6f,0x48,0xe2,0x31,0xcf,0x1c,0x75,0x07,0xbf,0xaf,0x32,0x86,0xcd,0xc9,0x2a,
+0xe9,0x67,0xe4,0x31,0xc5,0xef,0x70,0xb1,0x9e,0x06,0x6b,0x51,0x9f,0xbc,0x3a,
+},
+.inst.reseed_ctr = 1,
+
+.gen1.entropy = (unsigned char[]){
+0xcf,0xce,0xf3,0x77,0x6b,0x37,0x64,0x9a,0x7f,0x6d,0x2b,0x48,0xf4,0x43,0xda,0x79,
+0xa2,0xf2,0xf8,0x1d,0x04,0xf3,0xaf,0x98,0x53,0xa9,0xe6,0x96,0xc4,0x48,0x74,0x40,
+},
+.gen1.v = (unsigned char[]){
+0xda,0xd2,0x1f,0x2d,0x3f,0xda,0x88,0x4e,0x22,0xda,0x80,0x0f,0xaa,0xee,0x0e,0x2e,
+0xb5,0xb0,0x21,0x2f,0x4a,0x37,0x4d,0x7c,0x6f,0x94,0x6e,0x4f,0x7f,0xad,0x8a,0x71,
+0xe9,0x3e,0xb0,0xb8,0xd7,0xea,0xeb,0x55,0x44,0x7c,0x51,0x0c,0xe4,0x41,0xa9,0x9c,
+0x8b,0xf8,0x2b,0xe1,0xa7,0x70,0x8b,0x43,0x43,0xaf,0x52,0xc3,0xad,0x8f,0xbc,0x2f,
+0x29,0x6b,0x29,0xac,0x89,0xeb,0x46,0x9c,0x71,0xa4,0x1f,0x80,0x02,0xdb,0xe4,0x9f,
+0xf2,0xac,0x70,0x93,0xb0,0x61,0xb7,0xf7,0x62,0xa3,0x3b,0xf8,0x4c,0xe7,0x19,0x02,
+0x40,0xe8,0xa3,0xfd,0x9c,0x02,0x66,0x3b,0xcb,0x80,0xdd,0xac,0x63,0xac,0x98,
+},
+.gen1.c = (unsigned char[]){
+0x5d,0x6d,0x9b,0xb3,0x5c,0xf2,0x29,0x19,0xda,0xc5,0x05,0x76,0x96,0x64,0x23,0xbf,
+0xb4,0x62,0x32,0x3d,0x1a,0x04,0x3c,0x00,0xa8,0x56,0x50,0x63,0xfc,0x8a,0x8e,0x2d,
+0x75,0x99,0x26,0xf7,0xb4,0xda,0x65,0x33,0xe0,0x9b,0xe2,0xbe,0xd5,0x33,0x51,0xe4,
+0x68,0xec,0x32,0x50,0x63,0x0f,0x4d,0xd9,0x4e,0xc8,0xa6,0xbb,0x20,0xa2,0x74,0x9b,
+0x18,0x32,0xfc,0x5e,0xa5,0x4f,0xa5,0xed,0xe8,0x70,0x31,0xa6,0xbe,0x21,0xfe,0xa5,
+0x65,0x73,0x7f,0xb7,0xf5,0x07,0xac,0x22,0xbd,0xe3,0x83,0xad,0x69,0xcc,0xe9,0x59,
+0xbd,0xf8,0xea,0xef,0x21,0xf3,0x9e,0xff,0xa5,0x25,0x59,0x6b,0x89,0xf1,0xda,
+},
+.gen1.reseed_ctr = 2,
+
+.gen2.entropy = (unsigned char[]){
+0xd0,0x63,0x8e,0x28,0xca,0xe8,0xd1,0xc0,0xf5,0x72,0x09,0xd6,0x77,0xd8,0x89,0xd1,
+0x95,0xa6,0x72,0x02,0x3c,0xb8,0xad,0xe3,0x9f,0x79,0x49,0x89,0xe1,0xda,0xee,0x34,
+},
+.gen2.v = (unsigned char[]){
+0xb3,0xc0,0x3b,0x5a,0x64,0x2f,0xc9,0x4f,0xb6,0x63,0xc4,0x7c,0xc7,0xbc,0xcf,0x61,
+0x81,0x5d,0x8e,0x94,0xf8,0x2a,0x3b,0x59,0x03,0x17,0xed,0x7e,0xa6,0x02,0xb4,0xde,
+0x8c,0x27,0xdc,0x9e,0x42,0x66,0xa7,0x98,0x57,0xc8,0xbd,0xb9,0x8c,0x84,0x9e,0xd0,
+0x88,0x17,0x86,0x13,0xc4,0xda,0x20,0x99,0x93,0x20,0x42,0x33,0xbb,0xa7,0xc1,0xe8,
+0x0a,0xe5,0xcb,0x6a,0xf9,0x0d,0x6b,0x7f,0x09,0x17,0xf8,0x0b,0x5b,0x0c,0xc8,0x54,
+0x90,0xe3,0xa1,0xce,0x0e,0xe1,0x0f,0xb9,0x53,0x96,0x2a,0xd6,0x40,0x0f,0xf1,0x54,
+0x28,0x6d,0xdf,0x29,0xd9,0xc0,0xa0,0x04,0x7b,0xf0,0x60,0x95,0xc8,0xa1,0x27,
+},
+.gen2.c = (unsigned char[]){
+0x1f,0xff,0x76,0x2e,0x53,0x76,0x82,0x21,0xd1,0xc8,0x64,0xa1,0x8e,0xb4,0x84,0xd4,
+0x69,0x30,0x50,0x11,0xf8,0x9d,0x1a,0x6c,0xca,0x4a,0x21,0x6f,0x64,0x01,0x03,0xe2,
+0x19,0x65,0xbc,0xb2,0x5f,0xed,0x86,0xd4,0x0d,0xdb,0x2f,0xa9,0xbb,0xee,0x7f,0x81,
+0x43,0x1c,0xe4,0xc9,0x98,0x53,0x09,0xd8,0x2a,0xc2,0xf1,0x33,0xa9,0x31,0x6f,0xd3,
+0x42,0xb2,0x64,0x96,0xcb,0xe0,0x89,0x3f,0x53,0x6c,0xbc,0x52,0x8a,0x02,0x11,0x6e,
+0xf7,0xf4,0x47,0x90,0x29,0x0a,0x4a,0x57,0x41,0x7e,0xfb,0xc5,0xd2,0xc7,0xb7,0x48,
+0xad,0x1a,0x4e,0x6e,0x13,0xff,0x32,0xfb,0x83,0x12,0x5b,0x9c,0x0f,0xd6,0x47,
+},
+.gen2.reseed_ctr = 2,
+
+.prnd = (unsigned char []){
+0x04,0x74,0x4d,0x1d,0x42,0x60,0x19,0x95,0xfa,0x3b,0x10,0x1d,0xed,0x3d,0x25,0x31,
+0xcb,0xf4,0x5a,0xfd,0x83,0x12,0x0d,0x58,0xeb,0x26,0x59,0x4a,0x86,0x3b,0xd8,0x31,
+0x83,0x11,0xb0,0x8d,0x3d,0xf4,0xc5,0x71,0xa9,0xc2,0x6d,0xff,0x63,0xa3,0xe9,0x91,
+0x3a,0x9a,0x17,0xa7,0xc4,0x55,0x18,0x6f,0xdf,0xdd,0x90,0xc6,0x64,0xa8,0x4b,0x73,
+0xa1,0x10,0x6a,0x5a,0x82,0xf7,0x41,0xbd,0x4c,0x7a,0x48,0xbd,0x04,0x6c,0x26,0x8d,
+0x89,0x19,0xef,0xc9,0x41,0xf8,0xb4,0x5a,0x3c,0x3d,0x89,0xcf,0x37,0x14,0x1b,0x5c,
+0x41,0xb1,0x0f,0xf5,0x43,0xa6,0x92,0x62,0x72,0xd6,0x23,0xad,0x8e,0xcc,0xd0,0x26,
+0x55,0x20,0x90,0xad,0xcf,0xac,0xb1,0x24,0xf4,0x7c,0x4a,0xd6,0x2b,0xe9,0x0e,0xa5,
+0xa0,0xa7,0x08,0x7d,0x81,0x45,0x84,0x45,0x81,0x3a,0xf8,0x8f,0xfb,0x5a,0x8c,0x35,
+0x19,0xf9,0x77,0x13,0x1c,0xc8,0x51,0xcb,0x44,0x54,0xb0,0xa7,0x56,0xc8,0x37,0x3f,
+0x05,0x23,0x82,0x43,0x5a,0xb9,0x34,0x71,0x8c,0x95,0x51,0x77,0x36,0x33,0x89,0xc0,
+0x6b,0x0b,0x50,0x73,0x47,0x8e,0x84,0xd2,0x53,0xff,0x02,0xa3,0xf1,0xbe,0xf1,0xbb,
+0xf1,0x33,0x8f,0x77,0xf9,0x2f,0x02,0x9f,0x63,0x8a,0x46,0x91,0xc4,0x8c,0x47,0x0d,
+0x30,0xd2,0x30,0xf0,0x07,0xf5,0x45,0xe0,0x22,0xf6,0x6c,0x78,0xa1,0x30,0x69,0x78,
+0x14,0xaa,0x55,0xd2,0x00,0x0a,0x49,0x55,0x3b,0xef,0x35,0xfa,0xb5,0x80,0x8e,0x2f,
+0x3c,0xbb,0x38,0xc4,0x05,0x61,0x1f,0xa8,0x14,0x44,0x12,0x4e,0x3f,0x89,0xe1,0xe8,
+},
+},
+{
+.no_reseed = false,
+.pr = true,
+.entropy_len = 256 / 8,
+.nonce_len = 128 / 8,
+.pers_len = 0,
+.add_len = 256 / 8,
+.prnd_len = 2048 / 8,
+
+.inst.entropy = (unsigned char[]){
+0x7b,0xa8,0x43,0x1c,0x16,0xfb,0x16,0xd1,0x12,0x15,0x09,0xf2,0x25,0xab,0xd5,0xb3,
+0x7a,0x25,0xb0,0xc5,0xc0,0x69,0xb7,0x45,0x4c,0x22,0x66,0x26,0x9c,0xf2,0x6e,0x1b,
+},
+.inst.nonce = (unsigned char[]){
+0x7f,0x04,0x48,0x2b,0x3a,0x14,0xd8,0xfc,0x7a,0x29,0x81,0x6a,0x27,0xca,0x66,0xa2,
+},
+.inst.v = (unsigned char[]){
+0xa3,0x30,0x40,0xd0,0x3d,0x1a,0x6b,0x5e,0xd9,0x31,0x9a,0x37,0xa0,0xac,0x8b,0x63,
+0x91,0x0c,0x2b,0xb0,0x27,0x79,0x5f,0xd7,0x81,0xfb,0x9b,0xbf,0x8a,0xa9,0xdc,0xac,
+0x73,0xb3,0x27,0x6c,0xdf,0x04,0x8d,0x05,0xd7,0x33,0x2c,0x65,0xd0,0x63,0xaf,0xac,
+0x34,0x55,0x88,0x1e,0xf7,0x78,0xfc,0xc5,0xcf,0x12,0xf2,0x5f,0xcf,0x5f,0xe6,0xb3,
+0xd4,0x1c,0xc3,0xf3,0xfb,0x0d,0x9f,0xd9,0x56,0x7d,0xa8,0x10,0x87,0x51,0xe5,0xef,
+0x5b,0x54,0xb9,0xae,0x1e,0x2f,0xb3,0x00,0x58,0x6b,0x9f,0xce,0x2c,0x00,0xaf,0xb0,
+0xf5,0xb1,0x97,0xd0,0x8d,0x16,0x17,0xf5,0x49,0x6b,0x7a,0xdb,0x2c,0x9f,0x2c,
+},
+.inst.c = (unsigned char[]){
+0x8d,0x06,0xa0,0x3f,0x5d,0x2f,0x9a,0x9c,0x40,0xd1,0x6b,0x34,0xa5,0xd3,0x4e,0xa8,
+0xcd,0x00,0x1b,0x79,0x77,0xfc,0xcd,0x67,0x2d,0xde,0x8b,0xff,0xe4,0x87,0xf6,0x3f,
+0x60,0x89,0x9a,0xbf,0x3e,0x57,0xc4,0x2d,0x57,0xba,0x3f,0x00,0xdb,0x41,0x1e,0x57,
+0x13,0x7f,0x14,0x12,0xf9,0x47,0xf3,0xc3,0xb0,0x31,0x56,0x99,0x27,0x1c,0xbf,0xc3,
+0xa8,0xa1,0xf3,0x03,0x26,0x21,0xa0,0xa7,0xdf,0xc4,0x82,0xa9,0xc3,0x6a,0x8c,0x6a,
+0x5a,0x15,0xb0,0x89,0xca,0x69,0xea,0x8d,0xe9,0xa9,0xcb,0x86,0x44,0x79,0x72,0x52,
+0x19,0x32,0xc0,0xe1,0x47,0x45,0x5f,0xf3,0xcc,0x07,0x06,0x05,0x81,0xa7,0xb2,
+},
+.inst.reseed_ctr = 1,
+
+.gen1.add = (unsigned char[]){
+0x64,0x65,0x3b,0x87,0x53,0x59,0xf3,0xab,0x5d,0x96,0xaa,0x49,0x4d,0x44,0x66,0x90,
+0x22,0xb4,0x8c,0xa5,0xc1,0xc1,0xf7,0x6a,0x18,0x14,0xb7,0x65,0x51,0x99,0xdb,0xf3,
+},
+.gen1.entropy = (unsigned char[]){
+0xd0,0x52,0x01,0x36,0x5d,0x2b,0xcc,0xf9,0xa6,0x58,0x04,0xb2,0x3b,0xba,0x82,0xbf,
+0xb6,0x55,0x96,0xd4,0x2f,0xc5,0x1c,0xc5,0x29,0x22,0x08,0x1d,0x6e,0x50,0x74,0xa2,
+},
+.gen1.v = (unsigned char[]){
+0x05,0x3b,0x46,0xee,0x13,0x54,0x25,0xf9,0x99,0x32,0xb0,0x06,0x57,0x22,0x11,0xf3,
+0xb5,0xa1,0x68,0x11,0x11,0x12,0x76,0x99,0xb9,0x26,0x6e,0xc3,0x73,0xed,0xf7,0x83,
+0x60,0xfa,0x5f,0x7e,0xbf,0x3d,0x8b,0x22,0xc3,0xfe,0x78,0x51,0x48,0x83,0x25,0x37,
+0xe7,0x33,0x5f,0x02,0x0b,0x59,0x5a,0x97,0x35,0xeb,0xc5,0xb7,0x26,0x66,0xf6,0xbf,
+0x2b,0x50,0xa2,0x0a,0xe1,0xc0,0x5a,0x68,0xb7,0xfa,0xd6,0x0f,0x36,0x52,0x1c,0x46,
+0x27,0x2b,0xff,0x70,0x7f,0x66,0xbb,0xfa,0x2a,0xb4,0x66,0x6f,0xfc,0x2a,0x56,0x9d,
+0x8e,0xfc,0x30,0x27,0xfb,0x3b,0x48,0x83,0x04,0xfb,0x38,0xfb,0xd6,0x2e,0x16,
+},
+.gen1.c = (unsigned char[]){
+0x60,0xdc,0x33,0x8e,0x05,0x60,0xbe,0x50,0x39,0x6b,0x94,0x57,0xd4,0x55,0x83,0xb3,
+0x03,0x7e,0x2f,0xd0,0x91,0xd4,0xb2,0x1d,0x25,0xbb,0x2d,0xb4,0xde,0x15,0xc5,0xdf,
+0x11,0xe9,0x00,0x84,0x4c,0xca,0x4c,0xe5,0x3f,0x38,0x8e,0x4d,0x9d,0xcb,0xa4,0x3e,
+0x91,0xa8,0xc1,0x15,0xdc,0x0f,0x89,0x9a,0xfc,0x15,0xa6,0xa9,0xda,0x9b,0x73,0x4c,
+0x52,0x18,0x7c,0xf2,0x6a,0xe9,0xc7,0x60,0x93,0xce,0x1e,0x91,0x27,0xf7,0xb8,0x2a,
+0x16,0x42,0x9b,0x4f,0x05,0xde,0xdb,0x89,0x4f,0x1e,0x3f,0x93,0x79,0x52,0x3a,0x6c,
+0x0b,0x06,0xd5,0x4d,0xda,0x25,0x65,0x8e,0xe8,0x49,0x5a,0x0e,0x0a,0x9f,0x91,
+},
+.gen1.reseed_ctr = 2,
+
+.gen2.add = (unsigned char[]){
+0x1e,0x50,0x04,0xc4,0xc2,0xf8,0x50,0xfa,0x6b,0xe2,0xe0,0x17,0x10,0xa4,0xdf,0x0e,
+0x57,0x63,0x00,0xff,0x4f,0xc4,0xde,0x40,0xe9,0xc9,0x13,0x58,0xf2,0x6f,0xd4,0x08,
+},
+.gen2.entropy = (unsigned char[]){
+0x59,0x18,0x5a,0x07,0xb2,0x0d,0xec,0x58,0x57,0xb7,0x9d,0xda,0xb2,0x8d,0x46,0xa5,
+0x2e,0x4b,0x0a,0xad,0x9d,0xf9,0xcd,0xb7,0x76,0x13,0x38,0x54,0xaa,0xc0,0xdb,0x3e,
+},
+.gen2.v = (unsigned char[]){
+0x2e,0x54,0xe1,0x54,0x44,0xb8,0x43,0x9e,0x2e,0x06,0x6c,0xf2,0x3d,0x94,0x88,0x0b,
+0x72,0xe6,0xfd,0x3e,0xb4,0x3c,0xfd,0xa7,0xd8,0x91,0x0a,0xcb,0x89,0xc0,0xbd,0x76,
+0x31,0x21,0x52,0xe6,0x91,0x18,0x9d,0x44,0x75,0x78,0xc2,0x7c,0x7b,0xdf,0xb0,0x7c,
+0x2c,0x4a,0x0e,0x49,0x87,0xe3,0xf7,0x96,0xcd,0xa9,0xa0,0x0f,0x99,0xb9,0x5e,0x3d,
+0xb9,0xa1,0x9a,0xf2,0xdc,0x24,0x1b,0x71,0x4d,0xba,0x0a,0x86,0x14,0xa4,0xa7,0x28,
+0xe5,0xbc,0xb9,0x92,0xf8,0x1e,0x49,0x6c,0xa4,0x68,0x8a,0xdd,0x84,0x37,0x58,0x89,
+0x52,0xbf,0x8b,0x16,0x7c,0xc6,0xdb,0x30,0x81,0x00,0xd8,0xf6,0xa3,0x1c,0x77,
+},
+.gen2.c = (unsigned char[]){
+0x06,0x3f,0x41,0xe9,0x7b,0xe2,0x0f,0xcf,0x7f,0x74,0xa3,0xad,0x28,0x3c,0x6c,0x4e,
+0x77,0xe3,0x43,0x1f,0x4d,0x36,0x09,0x10,0x54,0xa7,0xd3,0xf6,0x4d,0x45,0x07,0xc5,
+0x25,0x66,0x4e,0x2b,0xd4,0x45,0xe2,0xb8,0x2c,0x6a,0xf4,0x37,0xf7,0x4f,0xe8,0x02,
+0x91,0x9c,0x4a,0x09,0x30,0xe8,0x65,0x5e,0xe2,0x0d,0x9c,0x6c,0x7d,0x9c,0x7c,0x2f,
+0xb1,0xab,0xdc,0xa2,0x58,0xb7,0x5d,0x22,0x3e,0xb0,0xfd,0xbc,0xea,0x7e,0x68,0xb8,
+0xa8,0xe6,0x21,0x5f,0xea,0xee,0x03,0xcf,0x1f,0xed,0x7e,0x7c,0x6b,0x2a,0x4f,0xb9,
+0x3e,0x1b,0xdb,0x43,0x97,0x0d,0x6c,0xa2,0xfd,0x97,0x03,0x65,0x05,0x51,0x76,
+},
+.gen2.reseed_ctr = 2,
+
+.prnd = (unsigned char[]){
+0x16,0x23,0x2b,0x52,0x84,0xea,0x1a,0x8a,0xad,0xca,0x65,0x67,0x79,0x08,0xba,0x74,
+0xc9,0x70,0xab,0x6c,0x34,0x6b,0xe4,0xe6,0x78,0x96,0x25,0xc5,0xdc,0x10,0xe5,0xac,
+0xa1,0xe6,0xb8,0x53,0xfe,0x17,0x4b,0xc1,0x16,0xa0,0x58,0x2b,0xa7,0xe0,0x7b,0x20,
+0xf6,0x98,0xea,0xbf,0xb9,0x1c,0x89,0xce,0x5b,0x87,0x23,0x26,0x36,0xbe,0xf1,0x6e,
+0x5a,0x96,0x6d,0x00,0x73,0xd4,0xe9,0x2a,0x89,0x73,0x5c,0x39,0x7d,0xbb,0xdf,0x80,
+0xbc,0xf9,0xc3,0x10,0xa5,0xae,0xc9,0x8a,0xd0,0x77,0x64,0x3a,0xde,0x1d,0x87,0x37,
+0xd4,0x08,0xb7,0x88,0xd9,0x0c,0x6b,0x53,0x8d,0x10,0xda,0x03,0x91,0xd9,0xea,0x87,
+0xe7,0x4a,0x7f,0x8d,0x05,0x27,0xb1,0xd0,0xed,0xf7,0x60,0xc6,0x9a,0xcf,0xac,0xca,
+0xdd,0x29,0xbc,0x69,0xb2,0x74,0xcf,0x08,0xfd,0x2a,0x50,0x6d,0x8d,0x58,0x8b,0x4d,
+0xee,0xfc,0x67,0xa3,0x1a,0xeb,0x43,0x83,0x1c,0x09,0x6e,0x3c,0xa7,0x06,0x6b,0x43,
+0x45,0xb2,0x69,0x16,0xd3,0xc5,0xf8,0x31,0x82,0x40,0x6b,0x44,0x8c,0xea,0x0f,0xb0,
+0xd1,0xc6,0x20,0xd8,0x75,0xa1,0x07,0xa6,0xd8,0xd0,0xd3,0xb1,0x2e,0xab,0xb4,0x04,
+0xe8,0x0c,0x86,0x08,0xe7,0x14,0xac,0x43,0xd6,0xe9,0x62,0xc9,0x7e,0xf2,0x2e,0x88,
+0xc9,0xac,0x66,0x2d,0x48,0x4d,0x24,0xe2,0xa8,0xcf,0x03,0x98,0xe0,0x91,0x85,0xe3,
+0x36,0x80,0xb1,0x25,0x95,0xe9,0x77,0x62,0x37,0x14,0xb3,0xf7,0x09,0xb6,0xfd,0xdc,
+0x18,0x61,0xc5,0x3c,0x4a,0xfd,0xb3,0xfd,0xed,0xf7,0xdc,0x4d,0xcf,0x5b,0xb0,0xe2,
+},
+},
+{
+.no_reseed = false,
+.pr = true,
+.entropy_len = 256 / 8,
+.nonce_len = 128 / 8,
+.pers_len = 256 / 8,
+.add_len = 0,
+.prnd_len = 2048 / 8,
+
+.inst.entropy = (unsigned char []){
+0x62,0xba,0x7f,0x80,0xb7,0x78,0xdf,0x98,0x6a,0x17,0x68,0x7f,0xc2,0xd2,0x41,0xc1,
+0x7d,0x8a,0xe0,0x9d,0x26,0xef,0x1a,0xfe,0x06,0x95,0x7b,0xfc,0x1e,0x94,0x14,0xcd,
+},
+.inst.nonce = (unsigned char []){
+0x1a,0xcd,0x0e,0xd5,0xaa,0xa6,0xb9,0x6a,0xb1,0x7e,0x23,0x20,0x87,0xb7,0x1d,0xe6,
+},
+.inst.pers = (unsigned char []){
+0x5e,0x44,0x97,0x60,0x37,0xe2,0x92,0x13,0x53,0x14,0x1e,0x0e,0xcf,0x0c,0x56,0x20,
+0x6b,0xd8,0x5c,0x05,0x19,0x43,0xe7,0xb8,0x10,0xbd,0x0e,0xf8,0xe5,0xd3,0xa0,0x2a,
+},
+.inst.v = (unsigned char []){
+0x93,0x2b,0xba,0x3b,0x03,0xb0,0x11,0xad,0xef,0x52,0x87,0xc1,0x49,0xc5,0x42,0x57,
+0x03,0x15,0x9f,0x64,0x1a,0xad,0x52,0xf9,0xd9,0x44,0xf4,0x25,0xf5,0x4c,0x49,0x72,
+0xd8,0x7e,0x01,0xe8,0xf2,0x66,0xcc,0x61,0xdc,0xaa,0x0d,0x9d,0x4e,0xc9,0xc6,0xb9,
+0x2b,0x7e,0x6a,0x29,0x63,0xf4,0x53,0x78,0xbf,0x63,0x19,0x27,0x63,0xca,0xcf,0x58,
+0x01,0xc3,0x7d,0x47,0x6e,0xf3,0x9a,0x4b,0x7a,0x2f,0x44,0x13,0x44,0xbe,0x96,0xeb,
+0x72,0x04,0xb3,0xd7,0xd4,0x20,0x2f,0xbf,0x67,0xae,0x8a,0x57,0x1a,0x66,0x61,0xe2,
+0x86,0x34,0x8c,0xaa,0xc9,0x13,0x8b,0x89,0x68,0x7d,0x9f,0x8e,0x94,0x02,0xb6,
+},
+.inst.c = (unsigned char []){
+0x43,0x45,0xf7,0x0e,0x8e,0x44,0x16,0xf0,0x92,0xdd,0xe1,0x9b,0x10,0x74,0x12,0x33,
+0xec,0x6b,0xe1,0x57,0x54,0x47,0xb9,0xb6,0xff,0x3e,0x06,0xc9,0x4c,0x61,0x0d,0xfc,
+0xf7,0xd8,0xc3,0xc8,0x25,0x23,0x38,0x89,0x0f,0x5d,0xf7,0x05,0x4d,0x2e,0x3e,0xc2,
+0xa2,0xf0,0x7f,0x6a,0x01,0x30,0x20,0x6b,0x8b,0x87,0x51,0x7e,0x8f,0x0b,0xec,0xe7,
+0x5c,0x31,0x34,0x78,0x9f,0xea,0x34,0x88,0x04,0xa7,0x27,0x27,0xe9,0xe4,0xe1,0x13,
+0x9e,0xe5,0xf6,0x0e,0x90,0x3c,0x15,0xbc,0x0f,0xed,0xf9,0x09,0xb3,0x0e,0x08,0x8d,
+0xeb,0xa7,0x2f,0x77,0x57,0x21,0xa8,0x15,0x1c,0x30,0x1f,0xda,0xd7,0x01,0x71,
+},
+.inst.reseed_ctr = 1,
+
+.gen1.entropy = (unsigned char []){
+0x7b,0xd0,0xf0,0x37,0x1b,0x81,0x79,0xbc,0x40,0x48,0x10,0xdc,0xcf,0xa9,0xc5,0x53,
+0x2f,0xa7,0xae,0xca,0x7b,0x41,0x5d,0xb7,0xee,0x31,0x7d,0x5a,0x0c,0xf6,0x3c,0xb9,
+},
+.gen1.v = (unsigned char []){
+0x95,0x17,0xc5,0xa2,0x6a,0x1d,0x73,0xf3,0x37,0xbe,0x44,0xc7,0x65,0x63,0x49,0x6f,
+0x9a,0xf2,0xb6,0x75,0x46,0xf4,0x83,0xb1,0x77,0x67,0x99,0xe4,0xc0,0x08,0xe2,0xcf,
+0xfd,0xef,0x37,0x59,0xa8,0x08,0x69,0x76,0xce,0x78,0x13,0x15,0x3c,0x37,0xd3,0x21,
+0x8b,0x4c,0xba,0xe2,0xb6,0x90,0x19,0xc9,0x93,0xa7,0x5d,0x52,0x6e,0xff,0xe0,0x5e,
+0x0c,0x0d,0x65,0x19,0xea,0x42,0x60,0x48,0xbb,0x39,0x79,0x44,0x64,0x59,0x69,0x5c,
+0x53,0x11,0x6b,0x42,0x84,0xa6,0xab,0x41,0xff,0xea,0x18,0xe9,0x7d,0x0d,0xe8,0x7a,
+0xee,0xf1,0x08,0xa0,0xe9,0xd8,0x48,0x93,0x85,0x02,0x98,0xd0,0xa8,0xad,0x6b,
+},
+.gen1.c = (unsigned char []){
+0x76,0x3d,0x01,0xa4,0xef,0xc5,0x04,0xf8,0x40,0x8d,0xc6,0x12,0xbc,0x33,0xc2,0x61,
+0x40,0x24,0x79,0x6e,0x2e,0x56,0x26,0x11,0x3b,0xae,0x91,0xb2,0xc3,0x76,0x6e,0x64,
+0x8a,0x6a,0xac,0x83,0x98,0x89,0xc4,0x8a,0x0c,0xa5,0x1d,0xa8,0xec,0xa3,0x39,0xbb,
+0xee,0x80,0xd0,0xc1,0x62,0x78,0xbd,0x85,0x88,0x10,0x74,0x7b,0x3b,0x9d,0xdb,0x2b,
+0xe0,0x7a,0x5d,0x1e,0xbe,0xb1,0xf4,0x35,0x20,0x45,0x3b,0xb4,0x00,0x87,0x29,0xf1,
+0x69,0x33,0x46,0xd4,0x27,0x27,0x0c,0x37,0x7e,0x09,0x0a,0xb2,0x3f,0x12,0x0a,0xf6,
+0x66,0x50,0x65,0x79,0xa8,0x5b,0x6c,0xd1,0x75,0xea,0x7a,0xfa,0x6e,0x1d,0x74,
+},
+.gen1.reseed_ctr = 2,
+
+.gen2.entropy = (unsigned char []){
+0xe1,0x0b,0xed,0x57,0x82,0xd4,0xe9,0xd1,0x51,0x86,0x67,0x14,0xde,0xe9,0x97,0x97,
+0xb6,0x40,0x9f,0xec,0x81,0xf3,0x14,0xfa,0x22,0xbb,0xe6,0x46,0xcd,0xb9,0x25,0xa9,
+},
+.gen2.v = (unsigned char []){
+0xdc,0x49,0x58,0x39,0x3b,0x4b,0x3e,0xb0,0xc2,0xdc,0x24,0x87,0x55,0xf0,0x20,0xa0,
+0xd7,0xa8,0x9f,0x44,0xd9,0x4e,0xc5,0x3a,0x89,0x1b,0xd4,0x0f,0x2c,0x23,0x22,0xc2,
+0xc1,0x7f,0x5c,0x9b,0x34,0x5d,0xd0,0x27,0x21,0xf7,0xe5,0x06,0x09,0xd7,0x27,0x58,
+0x8a,0x6b,0x4a,0x0b,0x6b,0x98,0xe5,0x87,0xd6,0x96,0x7c,0xa7,0x5b,0xc3,0x84,0x9a,
+0x6b,0xc6,0x3d,0x75,0xe6,0xb5,0x38,0x6c,0x86,0x57,0xf4,0x12,0xc4,0xd1,0x4b,0x9f,
+0x00,0x95,0xa6,0x03,0x86,0x89,0x27,0xa0,0xd2,0x07,0x79,0xdb,0xa9,0x1c,0x20,0xf0,
+0xb7,0xdb,0xc1,0x11,0x6e,0x5a,0x73,0x03,0x3c,0xae,0xbf,0x6c,0xfd,0xae,0xb8,
+},
+.gen2.c = (unsigned char []){
+0xef,0x08,0x9b,0x11,0xdb,0x37,0xf5,0xa7,0xb9,0x6b,0xb4,0x9f,0x7a,0xff,0x41,0x56,
+0x41,0x93,0x33,0x36,0xa9,0x85,0xd4,0x7c,0x3e,0xe6,0x06,0x02,0xbd,0x9f,0xa7,0x0d,
+0x6a,0x46,0x05,0x55,0x05,0xcc,0x31,0x6f,0x0f,0x88,0x59,0x12,0x7c,0x81,0x6c,0x77,
+0x47,0x23,0x16,0x58,0x5d,0x14,0x5d,0xf3,0xc4,0x6f,0xa8,0x14,0x96,0x56,0x06,0x16,
+0x62,0x93,0xd0,0x7f,0x2d,0x1f,0x90,0x63,0x6f,0x68,0xd3,0xe7,0xaa,0x41,0x04,0x7b,
+0x61,0x01,0x28,0x74,0x70,0xce,0x14,0xbc,0x15,0xb7,0x22,0xe4,0xcd,0xd0,0xf5,0x37,
+0xf0,0x76,0xfd,0x02,0x47,0x6d,0x7e,0x9c,0x70,0x4b,0xf1,0xb7,0x31,0xdc,0xb0,
+},
+.gen2.reseed_ctr = 2,
+
+.prnd = (unsigned char []){
+0xde,0x3d,0xdd,0xcb,0xfc,0x99,0xc2,0x25,0x8a,0x98,0xbd,0x04,0x2e,0x57,0x15,0x99,
+0xa3,0x11,0xd8,0x6b,0x5f,0x23,0xfe,0x50,0xe8,0x9a,0x42,0x58,0x8d,0x51,0x60,0x6f,
+0x51,0xb3,0x5e,0xc7,0xd4,0xe7,0x5a,0x49,0x26,0x16,0x35,0x6a,0x63,0x5e,0x7b,0x2d,
+0x3f,0x1e,0xea,0xa5,0xdb,0x19,0xb8,0xfc,0xb7,0xa9,0x4e,0x27,0x4f,0x36,0x9e,0x73,
+0xa6,0x7b,0xc2,0x8a,0x8b,0xf5,0xd4,0x95,0x59,0xfa,0xdc,0xda,0xfd,0x1f,0xaf,0x30,
+0xca,0x52,0x41,0x10,0x12,0xa5,0xe3,0xff,0xb6,0x68,0x65,0xf4,0x1c,0x0c,0x98,0x80,
+0x50,0x61,0x44,0x6e,0x62,0xfe,0x69,0x79,0xbc,0x5d,0x09,0x5f,0x1d,0x87,0x2b,0x96,
+0x37,0x5e,0x33,0x5c,0xde,0x53,0x80,0x31,0x98,0x8f,0xc4,0xec,0x32,0xab,0xe4,0xda,
+0xb5,0xff,0x18,0xf4,0x5f,0xb5,0x12,0x7a,0x14,0x07,0x9f,0x0f,0x0a,0x82,0x51,0x93,
+0x20,0x65,0xb1,0x6a,0xf2,0x8d,0xd4,0xb0,0x62,0x07,0x3d,0xcb,0x0b,0xa1,0xb2,0x04,
+0x95,0x97,0xdf,0x45,0xc1,0x7c,0x0b,0xc0,0x6a,0x23,0xd2,0x4b,0x8f,0xdd,0x66,0x97,
+0x8a,0x24,0x39,0x8b,0x5d,0x42,0x63,0x7c,0xbb,0x53,0xd1,0x98,0xa5,0x6b,0x61,0x93,
+0xb3,0x57,0x52,0x1d,0xb7,0x11,0x7b,0x7b,0x44,0x2e,0x75,0xbf,0x16,0x9e,0x42,0xbb,
+0x07,0x98,0xfa,0x59,0xfa,0xdc,0x19,0xf5,0xd9,0xe1,0x05,0x0a,0x43,0x45,0x35,0x8b,
+0xd7,0xe4,0x0f,0x90,0x96,0x45,0xd8,0x05,0x20,0xa0,0x93,0xb2,0x78,0x90,0xa3,0xd1,
+0x6e,0xd2,0x27,0x79,0x90,0xc3,0xa4,0xb3,0x6a,0x3a,0x0c,0x5f,0x37,0x45,0xec,0x59,
+},
+},
+{
+.no_reseed = false,
+.pr = true,
+.entropy_len = 256 / 8,
+.nonce_len = 128 / 8,
+.pers_len = 256 / 8,
+.add_len = 256 / 8,
+.prnd_len = 2048 / 8,
+
+.inst.entropy = (unsigned char []){
+0x19,0xff,0x49,0x7e,0x90,0x6d,0x08,0x11,0xa0,0xb7,0xf7,0x75,0x86,0x18,0xaf,0xab,
+0x44,0xfc,0xe8,0xed,0x35,0x38,0xab,0xfd,0x10,0x1c,0x58,0x6a,0x9c,0xea,0xf6,0x2d,
+},
+.inst.nonce = (unsigned char []){
+0x49,0x80,0xcb,0x99,0x83,0x87,0x0a,0x35,0xd8,0x00,0xff,0xf9,0x32,0x78,0x40,0xc5,
+},
+.inst.pers = (unsigned char []){
+0x2e,0x34,0xbe,0xa4,0xc1,0x28,0x43,0x4a,0xa2,0x85,0x9c,0xc3,0x39,0x13,0x71,0x6b,
+0xc8,0x05,0xa1,0x83,0xbb,0x17,0x62,0xfc,0x3a,0xb5,0x44,0x89,0xd9,0xbd,0x1c,0x56,
+},
+.inst.v = (unsigned char []){
+0x6c,0xf5,0x7e,0xdf,0x5f,0xec,0x61,0x34,0x5e,0xf8,0xcc,0x5e,0x39,0x1d,0xcc,0x3f,
+0x88,0x0a,0xd5,0x51,0xaa,0xfb,0x16,0x37,0x57,0x4e,0x92,0xc1,0xfa,0x8f,0x3e,0xd8,
+0x15,0x19,0xa0,0xf1,0xe9,0x32,0xa1,0xf8,0xb2,0xa5,0x53,0xb0,0xfa,0xb9,0xf9,0x9e,
+0x99,0x51,0xee,0x49,0x9c,0x59,0xfd,0x23,0xf3,0x1a,0x1b,0x73,0x8f,0x3a,0x54,0x7d,
+0xca,0xb6,0x36,0x8e,0x80,0x2c,0x57,0x89,0x6a,0x4f,0xcf,0xeb,0x3e,0xd0,0xe6,0x26,
+0x02,0x97,0xd6,0x16,0x5f,0xb2,0xe4,0x10,0x88,0x6f,0xe2,0xaf,0x76,0xe5,0x0e,0x20,
+0x23,0xc2,0xf2,0xcd,0xb3,0xf7,0xa8,0x1f,0x48,0x9a,0x76,0xfd,0x46,0x57,0x0e,
+},
+.inst.c = (unsigned char []){
+0x70,0xc9,0xfc,0xe3,0xd5,0x7e,0x39,0x4b,0x6a,0xc5,0xc0,0x04,0x8b,0xfd,0xae,0x4e,
+0xb5,0xa3,0xed,0x6a,0xa2,0xb2,0xfa,0xf5,0xe6,0xc5,0xb7,0xc2,0x9e,0xc6,0x54,0x3c,
+0x47,0xf5,0x0e,0x7b,0xe8,0x49,0x66,0xb5,0xa6,0x73,0x9a,0xa3,0x19,0x1c,0xa3,0xb2,
+0x1b,0xee,0xb4,0x16,0xaa,0x8f,0x7a,0x10,0xd0,0xee,0x15,0x46,0xf5,0x51,0x20,0x3d,
+0xd3,0xca,0xce,0x74,0xb6,0xaf,0x8d,0xce,0xb4,0x82,0xe7,0x53,0x50,0x0f,0xf4,0x17,
+0x65,0xdd,0xde,0xee,0x3a,0x72,0x5d,0x83,0xbf,0x5b,0xc0,0xda,0xff,0x35,0x86,0xc3,
+0xf5,0x75,0x0f,0x76,0xde,0x15,0x3c,0x24,0xda,0x52,0xfe,0xfe,0x50,0xb4,0x24,
+},
+.inst.reseed_ctr = 1,
+
+.gen1.add = (unsigned char []){
+0x47,0xdd,0x5c,0x72,0xea,0x44,0xdb,0xf1,0xd2,0x35,0x04,0x0b,0x18,0xa8,0x21,0xc2,
+0x0f,0xb4,0x0b,0x88,0xc0,0x39,0x1a,0x5c,0x16,0x3f,0x9c,0x90,0x2f,0x6c,0x6e,0xb7,
+},
+.gen1.entropy = (unsigned char []){
+0xbe,0x45,0xca,0x98,0x78,0x24,0x7b,0x00,0x8e,0x5d,0xe8,0xc5,0x88,0xb6,0xcb,0x84,
+0x04,0x8c,0x0d,0x90,0x35,0x7d,0xbd,0xfc,0x98,0xe9,0xe2,0x87,0x91,0x2f,0xdb,0x33,
+},
+.gen1.v = (unsigned char []){
+0x2b,0xec,0x9f,0xc2,0x78,0x1d,0xb4,0xcb,0xfa,0x98,0x50,0x18,0x15,0x5b,0xdf,0x51,
+0x02,0xe3,0x1b,0x0f,0x34,0x0c,0x32,0x9a,0xa0,0xa5,0xca,0x1a,0x70,0xb6,0xc3,0x90,
+0x6a,0x6a,0x8e,0x03,0xba,0x62,0xfd,0x2f,0xd8,0x1d,0xc9,0xc2,0xc0,0xdc,0x86,0xea,
+0x8f,0x8d,0xea,0x1f,0xb5,0x38,0xa0,0xdb,0xf5,0x69,0x8e,0x27,0xcc,0x2d,0x83,0xf8,
+0x0a,0xfb,0x4a,0xfe,0xfc,0x46,0x8c,0xda,0xf6,0xeb,0xce,0x06,0xee,0x35,0xcd,0xd0,
+0x59,0x77,0xb2,0x32,0x53,0x40,0xd1,0x91,0xff,0x03,0xb2,0xc4,0x33,0x90,0x8c,0x31,
+0xf2,0xbc,0x28,0xd6,0x23,0x72,0xaa,0xd9,0x67,0x1d,0xe0,0x59,0x8a,0x35,0x09,
+},
+.gen1.c = (unsigned char []){
+0xcf,0xf7,0xfc,0x70,0x9b,0x81,0x74,0x33,0x71,0x24,0x54,0xd6,0xbc,0xd5,0x74,0xde,
+0xae,0x3f,0x2b,0xc2,0xc2,0x00,0xf0,0x88,0x38,0x8b,0x07,0x37,0xfa,0x0d,0xfd,0x8f,
+0x7c,0x31,0x1b,0x8b,0x67,0xd3,0x7e,0x0a,0x7f,0x2a,0x55,0x1c,0x69,0x86,0x33,0xcd,
+0x4e,0x01,0x56,0x4d,0x36,0x72,0xae,0x9c,0x01,0xdb,0x90,0x6d,0xff,0xc2,0xa4,0xc3,
+0xf0,0x45,0x56,0x38,0xda,0x06,0x60,0x51,0x80,0x00,0x4b,0xb7,0xae,0x1d,0x01,0x86,
+0x19,0xda,0x3d,0xdf,0xab,0xef,0xf7,0x37,0x11,0xe2,0x5c,0xff,0xf0,0x65,0x77,0x2a,
+0xcf,0xa0,0xd6,0x79,0x54,0xbe,0xe4,0x02,0xc0,0x41,0xf6,0xc7,0x82,0x60,0xf3,
+},
+.gen1.reseed_ctr = 2,
+
+.gen2.add = (unsigned char []){
+0xcf,0x20,0x40,0xe9,0x04,0x6a,0x69,0xdd,0x96,0x38,0xde,0x94,0x1f,0x00,0x90,0xb7,
+0x53,0x5c,0x51,0xcf,0xa9,0xf1,0xc7,0xbb,0x2a,0x56,0xa3,0x32,0x32,0x69,0x43,0xd3,
+},
+.gen2.entropy = (unsigned char []){
+0xb8,0x71,0x61,0x1f,0x8f,0xcb,0x8c,0x86,0x0a,0x72,0xc4,0xfd,0x40,0x6d,0x49,0x39,
+0x33,0x5a,0x03,0x1e,0x0d,0xe9,0xf2,0xd4,0x36,0xd4,0x73,0x6b,0x6b,0x06,0x0c,0x2d,
+},
+.gen2.v = (unsigned char []){
+0x59,0x44,0xf8,0xec,0xc9,0xa4,0x4c,0x0f,0x05,0x3f,0xfe,0x7e,0xa3,0x64,0x27,0xfc,
+0xa5,0x6f,0x26,0xa3,0xd0,0x96,0x68,0xff,0x08,0x52,0xde,0x82,0x2c,0xa1,0x1a,0x88,
+0x74,0x68,0xd6,0x36,0x25,0xf1,0xe8,0x6f,0xa8,0xaa,0x2a,0x12,0xc9,0x45,0x59,0xc5,
+0xa4,0x01,0xe1,0x9f,0x8c,0xd5,0x8a,0xd9,0x53,0x60,0x12,0x8b,0x85,0x2f,0xef,0xbe,
+0xbe,0x6f,0x8b,0x9e,0x96,0x7f,0x80,0xd1,0x84,0x9d,0x8b,0xb7,0x9c,0x0e,0x34,0x9b,
+0x74,0x27,0xdf,0x85,0xa5,0x52,0xd5,0x48,0x7f,0xeb,0xd5,0x72,0xc1,0x17,0x8e,0x23,
+0x2b,0x2c,0xd6,0x1b,0x2b,0xf9,0x67,0x45,0xba,0xe5,0xd4,0x60,0x64,0x0b,0x56,
+},
+.gen2.c = (unsigned char []){
+0x34,0x0e,0xb7,0x02,0xa2,0x0b,0x75,0xed,0x0a,0x68,0x57,0x39,0x4d,0xcb,0x10,0xfc,
+0xc2,0xad,0xd4,0xfa,0xf4,0x98,0x94,0xbe,0x67,0xd6,0xf2,0x03,0xf7,0x7b,0x71,0xd0,
+0x35,0xe7,0xa7,0x37,0xee,0x24,0xdc,0x3b,0x6e,0x22,0xb5,0x95,0xf4,0xc0,0x86,0xb9,
+0x2d,0x57,0xab,0x21,0x18,0xb9,0xa5,0x0d,0xad,0x6d,0x1f,0xf4,0xb4,0xfd,0x7b,0x3b,
+0x51,0x09,0x88,0xed,0x49,0x93,0x9e,0xec,0x82,0x2b,0xf9,0x14,0x93,0x61,0x2b,0xe6,
+0x54,0x66,0x5b,0x27,0x8e,0xab,0x9e,0x6d,0x8b,0xeb,0x25,0xf3,0xe2,0x08,0xd8,0xc3,
+0x68,0x60,0x5a,0x39,0x9a,0x94,0x7e,0x13,0xa0,0x02,0xe3,0x67,0xed,0x50,0x3c,
+},
+.gen2.reseed_ctr = 2,
+
+.prnd = (unsigned char []){
+0x2d,0x99,0x0f,0x0d,0xe4,0x3d,0x3a,0x4b,0x29,0x30,0x54,0x2c,0x27,0xad,0x27,0x45,
+0x8e,0x88,0x65,0xca,0x6b,0x8f,0x27,0xfd,0x7a,0x96,0x9c,0xf4,0xe2,0xa0,0x32,0x3e,
+0x38,0xfe,0x6f,0x50,0x5a,0x2d,0xba,0x48,0x8e,0xa6,0xb0,0x43,0x65,0x20,0x9c,0x6d,
+0xb7,0x86,0xcb,0xbf,0x0a,0x7c,0x73,0xb4,0xfd,0x56,0xd2,0x49,0x87,0x71,0x9d,0xb0,
+0xfd,0xba,0x1a,0x3f,0x07,0x14,0x95,0x21,0xdc,0xf5,0xb7,0x75,0x9c,0x61,0x0d,0xa2,
+0x2d,0x15,0x10,0x57,0xac,0xef,0xe7,0x0d,0xf1,0xcc,0xae,0xb6,0x7a,0x97,0x51,0x59,
+0xb8,0x99,0x6a,0xca,0x93,0xd7,0xa4,0x80,0x96,0x92,0x6d,0xb4,0x38,0x1b,0xbc,0xe4,
+0x81,0x27,0x7d,0x7a,0xb2,0x7c,0xbc,0x03,0x88,0xf0,0xb7,0xce,0xdb,0xbf,0xb8,0x42,
+0x1c,0xb1,0xdc,0x5f,0x2a,0x9c,0x67,0x7f,0x62,0xac,0xf9,0x6a,0xb2,0x5e,0x7e,0x40,
+0x6c,0xe8,0x2f,0x5b,0x96,0xbc,0xb4,0x71,0xaf,0xbd,0xf4,0xb3,0xf5,0xa6,0xfb,0xcb,
+0x8d,0xa4,0x5d,0x22,0x58,0xe3,0x50,0xe7,0x7d,0x46,0x33,0xb0,0xc1,0xda,0x69,0x16,
+0x62,0xdd,0x86,0x99,0x09,0xdc,0xfd,0x7c,0x8e,0xd0,0xf5,0x4b,0xa7,0xaf,0x0f,0x9c,
+0x03,0x8e,0xb3,0x2d,0x32,0xb7,0x05,0xe5,0x1b,0x35,0xbb,0x3c,0x2e,0xef,0xf0,0x10,
+0xbb,0x47,0xee,0x32,0x6c,0x23,0x18,0xb5,0xbc,0xda,0x96,0x3c,0x2d,0xad,0x41,0x9c,
+0x59,0x23,0xe3,0x68,0xd9,0xb2,0x8f,0x25,0xb0,0x48,0xa8,0x7b,0xdb,0xa0,0xa9,0x0d,
+0x98,0xc2,0x4c,0x81,0xb6,0xdb,0xde,0x0f,0x58,0x05,0x4a,0x41,0xa8,0x29,0x3a,0x65,
+},
+},
+{
+.no_reseed = false,
+.pr = false,
+.entropy_len = 256 / 8,
+.nonce_len = 128 / 8,
+.pers_len = 0,
+.add_len = 0,
+.prnd_len = 2048 / 8,
+
+.inst.entropy = (unsigned char []){
+0x31,0x44,0xe1,0x7a,0x10,0xc8,0x56,0x12,0x97,0x64,0xf5,0x8f,0xd8,0xe4,0x23,0x10,
+0x20,0x54,0x69,0x96,0xc0,0xbf,0x6c,0xff,0x8e,0x91,0xc2,0x4e,0xe0,0x9b,0xe3,0x33,
+},
+.inst.nonce = (unsigned char []){
+0xb1,0x6f,0xcb,0x1c,0xf0,0xc0,0x10,0xf3,0x1f,0xea,0xb7,0x33,0x58,0x8b,0x8e,0x04,
+},
+.inst.v = (unsigned char []){
+0x3a,0x85,0xca,0x10,0xea,0xc6,0x83,0xd6,0xa9,0x27,0x05,0x94,0xd1,0x7f,0x33,0xa2,
+0x1d,0xad,0x7b,0x9b,0x25,0x9c,0x2a,0x17,0x44,0x62,0xa5,0xe0,0xc9,0x09,0xa1,0x33,
+0xdb,0x84,0xb4,0xee,0x2b,0xdb,0x0f,0x72,0xcd,0xce,0xf7,0xd6,0x28,0x54,0xe5,0x35,
+0x46,0x84,0x52,0x28,0x5d,0xbe,0x8e,0x46,0xbe,0xd3,0x96,0x5d,0xc9,0xc6,0x69,0x52,
+0xde,0xfa,0x48,0x87,0x94,0x93,0xed,0xc0,0x1b,0xc0,0x7e,0xd4,0x97,0x3c,0x11,0x5c,
+0xfd,0xd9,0x94,0x7a,0x70,0x84,0x65,0x35,0x1b,0x78,0xb8,0x04,0x65,0x2e,0xc7,0xcb,
+0xe7,0xf6,0xe2,0xa0,0x91,0x93,0xfa,0x35,0x2f,0xf9,0x91,0xd3,0x8c,0x94,0xac,
+},
+.inst.c = (unsigned char []){
+0x74,0xea,0x43,0x7c,0x49,0x12,0x6f,0xf3,0x61,0xfe,0xab,0x56,0x39,0xa8,0xad,0x31,
+0x8d,0x45,0x5c,0x94,0xb3,0xf9,0x99,0xff,0x16,0x06,0xf5,0x92,0xc2,0x7f,0x8b,0xf0,
+0xbe,0x56,0x2c,0x7b,0xff,0xa2,0x97,0xde,0x85,0x12,0xef,0x44,0xb0,0xdf,0xc8,0xdb,
+0x5c,0xb1,0x7c,0x96,0x92,0xac,0x0d,0x80,0xf0,0x66,0x96,0x1e,0x64,0x26,0x08,0x41,
+0x08,0x08,0x9e,0xee,0x4a,0x75,0x9d,0x53,0x09,0xec,0x86,0x16,0x68,0xdd,0xeb,0x1c,
+0x31,0xce,0xef,0x26,0xed,0xad,0x67,0x8b,0x6f,0x36,0xc3,0xeb,0xcb,0x9c,0x93,0x6c,
+0xaf,0xce,0xe3,0xd9,0xa9,0x6a,0xe6,0x55,0x4e,0x22,0xd4,0x28,0x88,0xab,0x07,
+},
+.inst.reseed_ctr = 1,
+
+.res.entropy = (unsigned char []){
+0xa0,0xb3,0x58,0x4c,0x2c,0x84,0x12,0xf6,0x18,0x40,0x68,0x34,0x40,0x4d,0x1e,0xb0,
+0xce,0x99,0x9b,0xa2,0x89,0x66,0x05,0x4d,0x7e,0x49,0x7e,0x0d,0xb6,0x08,0xb9,0x67,
+},
+.res.v = (unsigned char []){
+0xb3,0x7f,0x9a,0xa3,0x9c,0x5a,0x80,0xdf,0x56,0xc0,0x40,0x40,0x24,0x07,0x96,0x0e,
+0xf6,0xf8,0x89,0x2d,0x1a,0x68,0x8f,0xfc,0x93,0xba,0xd6,0xeb,0xe6,0xaf,0x44,0xd5,
+0x5c,0xcd,0x66,0xc1,0xf4,0x4e,0xb5,0x31,0xe9,0xda,0xc1,0xc9,0x44,0x76,0x81,0xd7,
+0xb2,0x7b,0x2b,0x70,0x3b,0x49,0x00,0x32,0x69,0x6b,0x32,0x33,0x0b,0x5e,0xdd,0x12,
+0x3e,0x5e,0xce,0x7c,0x40,0xef,0xe7,0x0a,0x29,0x82,0x2e,0xa8,0xe4,0xe4,0x54,0xbb,
+0x72,0x08,0x5c,0x6b,0x03,0x7a,0x86,0x52,0xec,0x22,0x7f,0x89,0x9d,0xd0,0x14,0x55,
+0xdb,0x8e,0xe7,0xb6,0xb2,0xe9,0x21,0x14,0xf6,0xf9,0xfb,0x67,0x8e,0x63,0x32,
+},
+.res.c = (unsigned char []){
+0x90,0x8a,0xd8,0x58,0xdb,0x2c,0x5d,0x21,0xfa,0x1c,0xd8,0x60,0x21,0x7b,0xd7,0x5a,
+0xd0,0xba,0x1d,0xf2,0xfd,0x24,0xe3,0x03,0x96,0x4c,0x01,0x11,0x3a,0x0b,0x02,0x4a,
+0x1e,0x53,0x64,0x0d,0x5a,0xe3,0x39,0x04,0x0b,0x43,0x57,0xc1,0xf3,0xc0,0xbe,0x2f,
+0x14,0x60,0x7b,0x13,0x85,0xe9,0x68,0x18,0x3c,0x53,0xec,0xd9,0xa3,0x3d,0xdb,0x04,
+0xb3,0xac,0x36,0xdf,0xc1,0x35,0x3d,0x85,0x71,0x15,0x9a,0x0b,0x31,0xb8,0x1b,0x5d,
+0x3d,0xe2,0x4b,0x8a,0xe6,0x53,0x0c,0x83,0x8f,0xa8,0x71,0x2e,0xa5,0xd4,0xd5,0x87,
+0x63,0xf2,0xbe,0x0a,0xb1,0x98,0x99,0x87,0xc5,0x6b,0xfd,0x31,0x5d,0xf5,0x21,
+},
+.res.reseed_ctr = 1,
+
+.gen1.v = (unsigned char []){
+0x44,0x0a,0x72,0xfc,0x77,0x86,0xde,0x01,0x50,0xdd,0x18,0xa0,0x45,0x83,0x6d,0x69,
+0xc7,0xb2,0xa7,0x20,0x17,0x8d,0x73,0x00,0x2a,0x06,0xd7,0xfd,0x20,0xba,0x47,0x1f,
+0x7b,0x20,0xca,0xcf,0x4f,0x31,0xee,0x35,0xf5,0x1e,0x19,0x8b,0x38,0x37,0x40,0xfb,
+0x34,0x72,0x4a,0x07,0x47,0xe2,0x61,0xc8,0x00,0xfa,0x0f,0x74,0x4b,0xdc,0x84,0x2d,
+0x37,0x19,0x9f,0x6a,0xcf,0x5f,0x4a,0xf0,0x41,0xa6,0x60,0x08,0x78,0xcf,0x72,0xa7,
+0xce,0xaa,0x75,0x0f,0xa1,0xc2,0x35,0x46,0xf9,0x62,0xaf,0xe9,0x7c,0x05,0x56,0x83,
+0xea,0xf5,0x13,0x1d,0x9f,0x9c,0x88,0x2e,0xdb,0x93,0xc5,0x0a,0xdb,0xa9,0x63,
+},
+.gen1.c = (unsigned char []){
+0x90,0x8a,0xd8,0x58,0xdb,0x2c,0x5d,0x21,0xfa,0x1c,0xd8,0x60,0x21,0x7b,0xd7,0x5a,
+0xd0,0xba,0x1d,0xf2,0xfd,0x24,0xe3,0x03,0x96,0x4c,0x01,0x11,0x3a,0x0b,0x02,0x4a,
+0x1e,0x53,0x64,0x0d,0x5a,0xe3,0x39,0x04,0x0b,0x43,0x57,0xc1,0xf3,0xc0,0xbe,0x2f,
+0x14,0x60,0x7b,0x13,0x85,0xe9,0x68,0x18,0x3c,0x53,0xec,0xd9,0xa3,0x3d,0xdb,0x04,
+0xb3,0xac,0x36,0xdf,0xc1,0x35,0x3d,0x85,0x71,0x15,0x9a,0x0b,0x31,0xb8,0x1b,0x5d,
+0x3d,0xe2,0x4b,0x8a,0xe6,0x53,0x0c,0x83,0x8f,0xa8,0x71,0x2e,0xa5,0xd4,0xd5,0x87,
+0x63,0xf2,0xbe,0x0a,0xb1,0x98,0x99,0x87,0xc5,0x6b,0xfd,0x31,0x5d,0xf5,0x21,
+},
+.gen1.reseed_ctr = 2,
+
+.gen2.v = (unsigned char []){
+0xd4,0x95,0x4b,0x55,0x52,0xb3,0x3b,0x23,0x4a,0xf9,0xf1,0x00,0x66,0xff,0x44,0xc4,
+0x98,0x6c,0xc5,0x13,0x14,0xb2,0x56,0x03,0xc0,0x52,0xd9,0x0e,0x5a,0xc5,0x49,0x69,
+0x99,0x74,0x2e,0xdc,0xaa,0x15,0x27,0x3a,0x00,0x61,0x71,0x4d,0x2b,0xf7,0xff,0xb3,
+0x2b,0x70,0x00,0xbf,0xde,0xb1,0x06,0x05,0xf3,0x61,0x74,0xeb,0x33,0xa4,0x8a,0x4c,
+0xc0,0x07,0xc2,0x3b,0xb0,0x35,0x97,0xb4,0xd8,0xa6,0x37,0x3c,0xa7,0x03,0x7e,0x8a,
+0x8f,0xf0,0x8f,0x63,0x77,0x9d,0xa9,0xe6,0x18,0x78,0xb1,0x88,0x6c,0xb0,0x84,0xba,
+0x68,0xce,0xef,0x8a,0xd4,0xe5,0xba,0x77,0x20,0xac,0xbd,0x3b,0x26,0x28,0x22,
+},
+.gen2.c = (unsigned char []){
+0x90,0x8a,0xd8,0x58,0xdb,0x2c,0x5d,0x21,0xfa,0x1c,0xd8,0x60,0x21,0x7b,0xd7,0x5a,
+0xd0,0xba,0x1d,0xf2,0xfd,0x24,0xe3,0x03,0x96,0x4c,0x01,0x11,0x3a,0x0b,0x02,0x4a,
+0x1e,0x53,0x64,0x0d,0x5a,0xe3,0x39,0x04,0x0b,0x43,0x57,0xc1,0xf3,0xc0,0xbe,0x2f,
+0x14,0x60,0x7b,0x13,0x85,0xe9,0x68,0x18,0x3c,0x53,0xec,0xd9,0xa3,0x3d,0xdb,0x04,
+0xb3,0xac,0x36,0xdf,0xc1,0x35,0x3d,0x85,0x71,0x15,0x9a,0x0b,0x31,0xb8,0x1b,0x5d,
+0x3d,0xe2,0x4b,0x8a,0xe6,0x53,0x0c,0x83,0x8f,0xa8,0x71,0x2e,0xa5,0xd4,0xd5,0x87,
+0x63,0xf2,0xbe,0x0a,0xb1,0x98,0x99,0x87,0xc5,0x6b,0xfd,0x31,0x5d,0xf5,0x21,
+},
+.gen2.reseed_ctr = 3,
+
+.prnd = (unsigned char []){
+0xef,0xa3,0x5d,0xd0,0x36,0x2a,0xdb,0x76,0x26,0x45,0x6b,0x36,0xfa,0xc7,0x4d,0x3c,
+0x28,0xd0,0x1d,0x92,0x64,0x20,0x27,0x5a,0x28,0xbe,0xa9,0xc9,0xdd,0x75,0x47,0xc1,
+0x5e,0x79,0x31,0x85,0x2a,0xc1,0x27,0x70,0x76,0x56,0x75,0x35,0x23,0x9c,0x1f,0x42,
+0x9c,0x7f,0x75,0xcf,0x74,0xc2,0x26,0x7d,0xeb,0x6a,0x3e,0x59,0x6c,0xf3,0x26,0x15,
+0x6c,0x79,0x69,0x41,0x28,0x3b,0x8d,0x58,0x3f,0x17,0x1c,0x2f,0x6e,0x33,0x23,0xf7,
+0x55,0x5e,0x1b,0x18,0x1f,0xfd,0xa3,0x05,0x07,0x21,0x0c,0xb1,0xf5,0x89,0xb2,0x3c,
+0xd7,0x18,0x80,0xfd,0x44,0x37,0x0c,0xac,0xf4,0x33,0x75,0xb0,0xdb,0x7e,0x33,0x6f,
+0x12,0xb3,0x09,0xbf,0xd4,0xf6,0x10,0xbb,0x8f,0x20,0xe1,0xa1,0x5e,0x25,0x3a,0x4f,
+0xe5,0x11,0xa0,0x27,0x96,0x8d,0xf0,0xb1,0x05,0xa1,0xd7,0x3a,0xff,0x7c,0x7a,0x82,
+0x6d,0x39,0xf6,0x40,0xdf,0xb8,0xf5,0x22,0x25,0x9e,0xd4,0x02,0x28,0x2e,0x2c,0x2e,
+0x9d,0x3a,0x49,0x8f,0x51,0x72,0x5f,0xe4,0x14,0x1b,0x06,0xda,0x55,0x98,0xa4,0x2a,
+0xc1,0xe0,0x49,0x4e,0x99,0x7d,0x56,0x6a,0x1a,0x39,0xb6,0x76,0xb9,0x6a,0x60,0x03,
+0xa4,0xc5,0xdb,0x84,0xf2,0x46,0x58,0x4e,0xe6,0x5a,0xf7,0x0f,0xf2,0x16,0x02,0x78,
+0x16,0x6d,0xa1,0x6d,0x91,0xc9,0xb8,0xf2,0xde,0xb0,0x27,0x51,0xa1,0x08,0x8a,0xd6,
+0xbe,0x4e,0x80,0xef,0x96,0x6e,0xb7,0x3e,0x66,0xbc,0x87,0xca,0xd8,0x7c,0x77,0xc0,
+0xb3,0x4a,0x21,0xba,0x1d,0xa0,0xba,0x6d,0x16,0xca,0x50,0x46,0xdc,0x4a,0xbd,0xa0,
+},
+},
+{
+.no_reseed = false,
+.pr = false,
+.entropy_len = 256 / 8,
+.nonce_len = 128 / 8,
+.pers_len = 0,
+.add_len = 256 / 8,
+.prnd_len = 2048 / 8,
+
+.inst.entropy = (unsigned char []){
+0xc7,0x3a,0x78,0x20,0xf0,0xf5,0x3e,0x8b,0xbf,0xc3,0xb7,0xb7,0x1d,0x99,0x41,0x43,
+0xcf,0x6e,0x98,0x64,0x2e,0x9e,0xa6,0xd8,0xdf,0x5d,0xcc,0xbc,0x43,0xdb,0x87,0x20,
+},
+.inst.nonce = (unsigned char []){
+0x20,0xcc,0x98,0x34,0xb5,0x88,0xad,0xcb,0x1b,0xbd,0xe6,0x4f,0x0d,0x2a,0x34,0xcb,
+},
+.inst.v =(unsigned char []){
+0x85,0x2d,0x1b,0x4f,0xdd,0x41,0xcd,0x7e,0x0f,0x59,0x7c,0x45,0xc8,0xe4,0xb4,0x01,
+0xa5,0xfe,0xcf,0x92,0x29,0xb6,0x07,0x24,0x51,0xca,0x65,0xb5,0x28,0x98,0x82,0xc6,
+0x86,0xe7,0x91,0x99,0x22,0xce,0x82,0xde,0x2f,0xaa,0xc8,0x3c,0xd4,0xc4,0xed,0xdf,
+0xa2,0xcd,0xcf,0x62,0x44,0xa4,0xd2,0xac,0xdd,0x34,0xc0,0x23,0x21,0x36,0x40,0x9b,
+0xb5,0x0e,0xa2,0x4d,0x0c,0x33,0xfc,0xfd,0x1a,0xaf,0x1c,0xc1,0x10,0xb5,0x35,0x3d,
+0x32,0xe4,0xe6,0xdf,0x59,0xae,0x25,0xec,0x12,0x40,0x00,0xde,0x62,0xfc,0xfa,0x8b,
+0xb4,0xcb,0x3f,0x3b,0x72,0xe2,0xda,0x20,0x66,0xef,0x00,0xcd,0x66,0xd9,0xe9,
+},
+.inst.c = (unsigned char []){
+0xf7,0xb0,0xc9,0xcf,0x2c,0xcf,0x58,0xfd,0x8c,0x8b,0x69,0xda,0xa4,0xcf,0x24,0xa8,
+0x74,0xc9,0x5b,0x57,0xa9,0xf5,0xbe,0x16,0xaa,0xa7,0x1e,0xc3,0x00,0x70,0xac,0x8f,
+0x22,0x2f,0xe2,0x17,0x88,0xfe,0xc1,0x4b,0x8a,0x9a,0xd7,0xad,0x20,0x91,0x2c,0x05,
+0xa6,0xf9,0x45,0x48,0x64,0x67,0x79,0xa1,0x6c,0x78,0x7b,0x13,0x5c,0xe8,0xd0,0x8c,
+0x49,0xf7,0xe2,0x34,0xcb,0xd2,0xc7,0x73,0x35,0x71,0xf5,0xad,0x64,0x79,0xb5,0xfc,
+0x50,0x40,0x34,0x96,0x58,0x1b,0x48,0x61,0xef,0x8e,0xc8,0x48,0xaf,0xfb,0xd2,0x07,
+0x7a,0xb1,0x64,0xfc,0x6b,0xb2,0xdd,0x7b,0x00,0x8a,0x65,0x05,0x04,0xbf,0xd8,
+},
+.inst.reseed_ctr = 1,
+
+.res.entropy = (unsigned char []){
+0x12,0xdd,0x2a,0xca,0x88,0x79,0x04,0x6d,0x23,0x16,0x5c,0x60,0xf8,0xae,0xdc,0x20,
+0x41,0x57,0x83,0xe1,0x56,0xd4,0x2a,0x94,0x34,0x68,0x26,0xaa,0xeb,0x02,0xea,0xcf,
+},
+.res.add = (unsigned char []){
+0x9b,0x59,0xff,0x78,0xa3,0x4e,0xab,0xe0,0x06,0x0c,0x27,0x92,0xca,0x9b,0x49,0xe9,
+0x78,0x1e,0x6b,0x80,0x2b,0xad,0xf7,0xdb,0xde,0x27,0xca,0xae,0xd3,0x34,0x37,0x06,
+},
+.res.v = (unsigned char []){
+0x18,0x1a,0x30,0x23,0x52,0xd9,0xeb,0xf0,0xb6,0x69,0x73,0x0b,0x24,0x41,0xa9,0xf4,
+0xc1,0x6a,0x4b,0x9d,0x25,0xeb,0xc8,0x4e,0xd0,0x1c,0x46,0x0d,0x29,0x3c,0xd3,0xe8,
+0xb7,0xbf,0xf1,0xac,0xa3,0x2b,0x0e,0xa8,0xd2,0x81,0xdf,0x0e,0xf8,0xd1,0xae,0x09,
+0xd4,0xcf,0x97,0x69,0x0c,0x94,0x4f,0x47,0x13,0xad,0xb9,0xed,0xe9,0x07,0x63,0xf3,
+0xed,0x77,0x08,0x1c,0x37,0xc0,0xfc,0x60,0xf8,0xb6,0x0b,0x51,0x08,0xcf,0x62,0x76,
+0xc8,0x0d,0xb1,0x4a,0x82,0xaa,0xef,0x1b,0xf8,0xda,0x03,0x78,0x14,0x45,0xcf,0xcc,
+0x7c,0xdc,0x02,0xb1,0xc7,0xa2,0x74,0x08,0x74,0xdd,0x94,0x81,0x18,0xf7,0xef,
+},
+.res.c = (unsigned char []){
+0x28,0xb6,0x38,0xd6,0x31,0xf0,0x54,0xeb,0xa5,0x62,0x32,0x0e,0x9d,0x15,0x1f,0x90,
+0x58,0x63,0xdd,0x6c,0x04,0xd8,0xba,0x41,0x16,0x7b,0xcf,0x3b,0x02,0x36,0xd4,0xe5,
+0xdd,0xe1,0xdc,0x7b,0xf6,0x90,0xe6,0x1b,0x4a,0x65,0x99,0x7b,0xd9,0xc6,0x7f,0xf9,
+0x08,0xfe,0x7e,0x24,0x43,0xd0,0x1c,0x8e,0xac,0x15,0xb2,0xea,0x5c,0x80,0xba,0x89,
+0xf0,0x9a,0xa9,0xb8,0xa8,0x1d,0x56,0x12,0x4b,0xb7,0x15,0x86,0x81,0x28,0x27,0xf4,
+0x63,0xde,0x90,0x31,0x87,0x27,0x10,0x2d,0xbd,0x5e,0x59,0xca,0x5f,0x1a,0xf7,0x8a,
+0xb7,0x38,0x44,0x69,0x5e,0xee,0x09,0x77,0xb7,0x54,0x85,0x4e,0x52,0x50,0x97,
+},
+.res.reseed_ctr = 1,
+
+.gen1.add = (unsigned char []){
+0xdc,0x74,0xa9,0xe4,0x80,0xa6,0xff,0x6f,0x6b,0xce,0x53,0xab,0x9c,0x7b,0xdd,0xe4,
+0xb1,0x3d,0x70,0xfb,0x51,0x96,0xcd,0xd5,0xe3,0xa0,0x55,0x5c,0xcf,0x06,0xfe,0x91,
+},
+.gen1.v = (unsigned char []){
+0x40,0xd0,0x68,0xf9,0x84,0xca,0x40,0xdc,0x5b,0xcb,0xa5,0x19,0xc1,0x56,0xc9,0x85,
+0x19,0xce,0x29,0x09,0x2a,0xc4,0x82,0x8f,0xe6,0x98,0x15,0x48,0x2b,0x73,0xa8,0xce,
+0x95,0xa1,0xce,0x28,0x99,0xbb,0xf4,0xc4,0x1c,0xe7,0x78,0x8a,0xd2,0x98,0x2e,0x3c,
+0xea,0x32,0x66,0xf4,0xca,0xdc,0x50,0xae,0x52,0x8d,0xc6,0x1a,0xa7,0xc5,0x21,0x48,
+0x98,0x69,0xe3,0xef,0xc6,0xc8,0x2c,0xce,0xfb,0xba,0xb4,0x56,0x73,0xe0,0xf5,0x9d,
+0x56,0x54,0xcf,0x91,0x0f,0xa1,0x46,0xd9,0x84,0xa4,0x2c,0x5f,0x17,0xfb,0x60,0x34,
+0x0c,0x86,0xd0,0xd0,0x7c,0x7e,0x2f,0x2e,0x6d,0xf3,0xcf,0xfd,0x72,0x2a,0x0e,
+},
+.gen1.c = (unsigned char []){
+0x28,0xb6,0x38,0xd6,0x31,0xf0,0x54,0xeb,0xa5,0x62,0x32,0x0e,0x9d,0x15,0x1f,0x90,
+0x58,0x63,0xdd,0x6c,0x04,0xd8,0xba,0x41,0x16,0x7b,0xcf,0x3b,0x02,0x36,0xd4,0xe5,
+0xdd,0xe1,0xdc,0x7b,0xf6,0x90,0xe6,0x1b,0x4a,0x65,0x99,0x7b,0xd9,0xc6,0x7f,0xf9,
+0x08,0xfe,0x7e,0x24,0x43,0xd0,0x1c,0x8e,0xac,0x15,0xb2,0xea,0x5c,0x80,0xba,0x89,
+0xf0,0x9a,0xa9,0xb8,0xa8,0x1d,0x56,0x12,0x4b,0xb7,0x15,0x86,0x81,0x28,0x27,0xf4,
+0x63,0xde,0x90,0x31,0x87,0x27,0x10,0x2d,0xbd,0x5e,0x59,0xca,0x5f,0x1a,0xf7,0x8a,
+0xb7,0x38,0x44,0x69,0x5e,0xee,0x09,0x77,0xb7,0x54,0x85,0x4e,0x52,0x50,0x97,
+},
+.gen1.reseed_ctr = 2,
+
+.gen2.add = (unsigned char []){
+0x8f,0x3f,0x22,0x90,0x11,0x20,0x9b,0x2f,0x39,0x90,0x96,0xaf,0xb0,0x54,0xbc,0xcc,
+0xa6,0xbc,0x46,0xaa,0xee,0x98,0x84,0x58,0x38,0xfb,0x1f,0xb7,0x8b,0x66,0xf3,0xbd,
+},
+.gen2.v = (unsigned char []){
+0x69,0x86,0xa1,0xcf,0xb6,0xba,0x95,0xc8,0x01,0x2d,0xd7,0x28,0x5e,0x6b,0xe9,0x15,
+0x72,0x32,0x06,0x75,0x2f,0x9d,0x3c,0xd0,0xfd,0x13,0xe4,0x83,0x2d,0xaa,0x7d,0xb4,
+0x73,0x83,0xaa,0xa4,0x90,0x4c,0xda,0xdf,0x67,0x4d,0x12,0x06,0xac,0x5e,0xaf,0xa9,
+0x9d,0xe1,0x30,0x4f,0xc0,0xb6,0xa1,0xb5,0xe3,0x2e,0x34,0xa7,0xf4,0x14,0x1e,0x89,
+0x35,0x38,0x78,0xc0,0xd3,0xf6,0xa0,0xba,0x5b,0x9e,0xd4,0x52,0xd6,0x12,0x60,0xde,
+0x9e,0x5a,0xcb,0xf8,0x13,0x44,0x85,0xb3,0xb9,0xe9,0x90,0xf5,0x9f,0x34,0xd4,0xd4,
+0x33,0x07,0xe4,0x0a,0xd0,0xd0,0xa5,0x05,0xef,0xdb,0x24,0xb7,0x2f,0x80,0x7b,
+},
+.gen2.c = (unsigned char []){
+0x28,0xb6,0x38,0xd6,0x31,0xf0,0x54,0xeb,0xa5,0x62,0x32,0x0e,0x9d,0x15,0x1f,0x90,
+0x58,0x63,0xdd,0x6c,0x04,0xd8,0xba,0x41,0x16,0x7b,0xcf,0x3b,0x02,0x36,0xd4,0xe5,
+0xdd,0xe1,0xdc,0x7b,0xf6,0x90,0xe6,0x1b,0x4a,0x65,0x99,0x7b,0xd9,0xc6,0x7f,0xf9,
+0x08,0xfe,0x7e,0x24,0x43,0xd0,0x1c,0x8e,0xac,0x15,0xb2,0xea,0x5c,0x80,0xba,0x89,
+0xf0,0x9a,0xa9,0xb8,0xa8,0x1d,0x56,0x12,0x4b,0xb7,0x15,0x86,0x81,0x28,0x27,0xf4,
+0x63,0xde,0x90,0x31,0x87,0x27,0x10,0x2d,0xbd,0x5e,0x59,0xca,0x5f,0x1a,0xf7,0x8a,
+0xb7,0x38,0x44,0x69,0x5e,0xee,0x09,0x77,0xb7,0x54,0x85,0x4e,0x52,0x50,0x97,
+},
+.gen2.reseed_ctr = 3,
+
+.prnd = (unsigned char []){
+0xe6,0xc9,0x64,0x42,0x58,0x28,0x11,0xec,0x90,0xe5,0x87,0x52,0x5f,0x36,0xc5,0x55,
+0xe2,0xfd,0x63,0x61,0xa0,0xc5,0xb0,0x28,0x49,0x17,0xa4,0xfa,0x6f,0x6e,0x8a,0xce,
+0x83,0xf1,0x1a,0x1f,0xb2,0x6c,0xea,0x66,0x92,0xb2,0x25,0xae,0x7c,0x5b,0xe2,0x86,
+0xdd,0x27,0x47,0x1f,0x32,0x3d,0x7a,0x2e,0x44,0x31,0x72,0x2b,0xb3,0x37,0xb1,0xba,
+0x0e,0x64,0x8e,0xa2,0xe9,0xf0,0x91,0x8b,0x50,0xe9,0x11,0x1f,0x23,0x77,0x63,0x6b,
+0xa6,0x9b,0x0e,0x1c,0xb5,0x29,0x50,0x78,0xd7,0x6c,0x54,0x9c,0x86,0x56,0x94,0x0e,
+0xb1,0x5c,0xa5,0xad,0xed,0x7a,0xdc,0x46,0xe6,0xfa,0x4b,0x86,0x94,0x8f,0x21,0x2f,
+0xea,0x3f,0x3b,0xef,0xde,0xec,0xe8,0xb2,0x0e,0x42,0x0c,0xa8,0x4c,0x76,0x01,0x96,
+0xdd,0xf0,0xb0,0x74,0xdf,0x0a,0x9f,0x09,0x7a,0x5d,0xb8,0xf6,0x12,0x58,0x00,0xf5,
+0xfe,0x74,0x6a,0x62,0xdf,0x12,0x08,0x04,0x2f,0x12,0x55,0xb5,0x24,0x46,0x5a,0x17,
+0xef,0xcf,0x6a,0x53,0x76,0x12,0x96,0x84,0x30,0xe2,0xad,0xcf,0xf3,0x0f,0x74,0x07,
+0xa5,0x1e,0xd7,0x30,0x53,0x34,0x38,0x4e,0x51,0x2e,0x00,0x36,0x42,0xcc,0xa1,0x75,
+0x63,0x68,0x19,0xf0,0x21,0xc7,0x6a,0x2f,0x44,0xe8,0x9e,0x6f,0xe3,0x9c,0xf1,0x64,
+0x47,0x79,0x10,0x37,0x9c,0xd3,0x14,0xf7,0x35,0xc3,0x57,0xf9,0x37,0x9d,0xe2,0x24,
+0x95,0x27,0x6b,0x40,0x1c,0x98,0xff,0xb0,0x9a,0x6d,0xc0,0x3e,0x48,0x4b,0x35,0x5a,
+0x94,0x64,0x51,0x14,0x01,0xee,0xaa,0x05,0xb4,0x55,0x6e,0x73,0xb5,0x52,0x27,0xf8,
+},
+},
+{
+.no_reseed = false,
+.pr = false,
+.entropy_len = 256 / 8,
+.nonce_len = 128 / 8,
+.pers_len = 256 / 8,
+.add_len = 0,
+.prnd_len = 2048 / 8,
+
+.inst.entropy = (unsigned char []){
+0x12,0xc2,0x20,0x31,0xd0,0x3a,0x85,0x0f,0x76,0x96,0xc9,0x27,0xd4,0xdc,0x8d,0xad,
+0x4c,0x3d,0xd7,0x17,0xe6,0x0e,0xe5,0x68,0x1b,0x05,0xdb,0x64,0x26,0xa0,0xe1,0x67,
+},
+.inst.nonce = (unsigned char []){
+0xcd,0x32,0xe3,0xeb,0x3f,0x83,0x34,0xd9,0x69,0x8d,0xec,0x62,0x7b,0x2e,0xaa,0xbe,
+},
+.inst.pers = (unsigned char []){
+0x75,0x63,0x63,0xf6,0x81,0x78,0xda,0xc0,0x9a,0x5c,0x8d,0x64,0xef,0xfb,0xab,0x23,
+0x87,0x3a,0x3b,0xc2,0xdf,0xba,0xc3,0x9b,0x6d,0x47,0xeb,0xf9,0x29,0xad,0x98,0x54,
+},
+.inst.v =(unsigned char []){
+0x29,0x5e,0x0b,0x18,0x92,0x1d,0x33,0xaa,0x64,0xe3,0xde,0xec,0x80,0x04,0x4b,0x41,
+0xac,0x4e,0x49,0x90,0x04,0xc7,0x7b,0x7d,0x1a,0xc0,0x21,0xdd,0x1c,0x4e,0x2e,0x6a,
+0x85,0x2d,0x6a,0xd6,0x27,0x6c,0xe2,0xa9,0x01,0x5f,0xa3,0x1e,0x22,0x34,0x96,0x76,
+0x14,0x3d,0xa2,0x02,0xb7,0x7c,0xc0,0x08,0x26,0xea,0x17,0xec,0x67,0xc0,0xdb,0x12,
+0x75,0xa2,0xd0,0x7c,0x0e,0xae,0x8a,0x87,0xdf,0xbe,0x0f,0xd5,0x34,0x7a,0x2b,0x38,
+0x36,0x40,0x29,0xf4,0x38,0x8e,0x6e,0x32,0xe8,0x53,0xad,0xec,0x3a,0xe4,0x79,0xc4,
+0x07,0x75,0xf7,0xab,0x17,0x08,0x09,0x90,0x57,0x2b,0xac,0x29,0x47,0x7a,0x31,
+},
+.inst.c = (unsigned char []){
+0x24,0x70,0x96,0x11,0x1b,0xa9,0x0f,0x4f,0x56,0x11,0xe2,0x65,0x84,0xa9,0xf1,0x83,
+0xc9,0x60,0xda,0xe8,0x5c,0x57,0x1a,0xa5,0xae,0xfc,0x13,0xe3,0xdd,0x04,0x96,0x8c,
+0x53,0xa3,0xd0,0xb9,0xdd,0x69,0x9a,0xa6,0xf8,0x33,0x0c,0x5d,0xa4,0x44,0x7e,0x30,
+0x5f,0xf8,0xa3,0xdc,0x21,0xbe,0xf0,0x27,0x07,0xc0,0x64,0xa8,0xeb,0xf4,0xa7,0x34,
+0x0c,0xab,0x11,0x33,0x35,0x58,0x97,0xd1,0xea,0xc2,0x0f,0xf7,0xb8,0x10,0x7f,0xce,
+0x28,0xf8,0xef,0x64,0xbf,0x6b,0x39,0x0d,0x58,0x9d,0xec,0x19,0xe7,0x47,0x65,0x03,
+0x73,0x44,0x88,0x72,0x39,0xf3,0x0f,0x4b,0x2b,0x04,0xc8,0x11,0xe6,0x00,0x69,
+},
+.inst.reseed_ctr = 1,
+
+.res.entropy = (unsigned char []){
+0x17,0xed,0x31,0xbd,0xa6,0x4b,0x08,0xec,0xe5,0x0e,0xdf,0x5b,0x91,0xf6,0xa0,0x86,
+0x2e,0x56,0x90,0x18,0x17,0x34,0xa0,0x13,0x4e,0x05,0xe3,0x66,0x64,0x0b,0x7e,0x85,
+},
+.res.v = (unsigned char []){
+0xba,0xa7,0xae,0xbc,0x24,0x31,0x32,0x82,0x49,0x0e,0x40,0xd8,0x90,0x3d,0x2b,0x4c,
+0x23,0xf3,0x0a,0xfc,0x59,0x8d,0x36,0x7f,0xa8,0xb5,0x70,0xc3,0xf9,0xa7,0x92,0x39,
+0x9c,0xeb,0xff,0x96,0xb3,0xf4,0x58,0xd3,0xa8,0xd2,0xd8,0xb9,0xb1,0x40,0xdb,0x40,
+0xd9,0x8d,0xcf,0x5a,0x44,0x8e,0xce,0xb7,0x6d,0x25,0x19,0xd2,0xbf,0xd5,0xef,0x0d,
+0x1c,0x80,0x5f,0x50,0xbc,0xde,0xdb,0x38,0x24,0x8d,0x2e,0xd7,0xcd,0x66,0xab,0x07,
+0xf9,0x7e,0x13,0xd1,0xd2,0x69,0x10,0xb8,0x5f,0x7e,0xec,0x8f,0x1b,0x26,0xdc,0x1f,
+0x3a,0x23,0x02,0x91,0xa7,0x32,0x25,0xe3,0xf2,0xcf,0xb7,0xf4,0xde,0x76,0x24,
+},
+.res.c = (unsigned char []){
+0xd2,0x96,0xd0,0x95,0x7e,0x86,0x06,0xb5,0xe2,0x7b,0x74,0xac,0x72,0x98,0x08,0x60,
+0x4c,0x48,0x35,0x03,0x52,0x53,0x4c,0x3d,0x8b,0x1a,0xc0,0x55,0x1c,0x9e,0xfc,0x80,
+0x8b,0x55,0x7d,0x8f,0x5c,0x7a,0x1b,0x62,0x7b,0x86,0x85,0xb5,0x87,0xa5,0x12,0x1e,
+0x73,0xd5,0xbe,0x13,0x78,0xe8,0xea,0x03,0x5f,0xab,0x8a,0xab,0x96,0x2a,0xf8,0x6d,
+0xc4,0x1f,0xda,0x58,0x8d,0xcc,0xde,0xfc,0xfa,0xaa,0x78,0xde,0x18,0xfc,0x7a,0x50,
+0x63,0xaf,0x35,0xfd,0xb2,0x4e,0xf6,0x04,0xda,0x15,0x3e,0x64,0x87,0x8a,0xaa,0xf6,
+0x37,0x9a,0x95,0xe7,0x63,0x57,0xe6,0xd5,0xfd,0xd4,0x7e,0x07,0x3a,0x0f,0xfe,
+},
+.res.reseed_ctr = 1,
+
+.gen1.v = (unsigned char []){
+0x8d,0x3e,0x7f,0x51,0xa2,0xb7,0x39,0x38,0x2b,0x89,0xb5,0x85,0x02,0xd5,0x33,0xac,
+0x70,0x3b,0x3f,0xff,0xab,0xe0,0x82,0xbd,0x33,0xd0,0x31,0x19,0x16,0x46,0x8e,0xba,
+0x28,0x41,0x7d,0x26,0x10,0x6e,0x74,0x36,0x24,0x59,0x5e,0x6f,0x38,0xe5,0xed,0x9a,
+0xac,0x0e,0x71,0xaa,0xb9,0x38,0xce,0xf1,0x40,0x29,0x43,0xa4,0x47,0x38,0xdd,0xf5,
+0x7b,0x90,0x74,0x21,0x41,0xda,0x08,0x8a,0x32,0x22,0x5c,0x24,0x96,0x82,0x4f,0x7b,
+0xca,0x1d,0xf8,0x3b,0xaa,0x8d,0x04,0xfc,0x7e,0xa7,0x63,0x55,0x22,0x27,0xed,0xec,
+0xd9,0x4c,0x71,0x3d,0x64,0x92,0x6b,0x13,0x7b,0x1c,0xa2,0x01,0x21,0x2f,0x2b,
+},
+.gen1.c = (unsigned char []){
+0xd2,0x96,0xd0,0x95,0x7e,0x86,0x06,0xb5,0xe2,0x7b,0x74,0xac,0x72,0x98,0x08,0x60,
+0x4c,0x48,0x35,0x03,0x52,0x53,0x4c,0x3d,0x8b,0x1a,0xc0,0x55,0x1c,0x9e,0xfc,0x80,
+0x8b,0x55,0x7d,0x8f,0x5c,0x7a,0x1b,0x62,0x7b,0x86,0x85,0xb5,0x87,0xa5,0x12,0x1e,
+0x73,0xd5,0xbe,0x13,0x78,0xe8,0xea,0x03,0x5f,0xab,0x8a,0xab,0x96,0x2a,0xf8,0x6d,
+0xc4,0x1f,0xda,0x58,0x8d,0xcc,0xde,0xfc,0xfa,0xaa,0x78,0xde,0x18,0xfc,0x7a,0x50,
+0x63,0xaf,0x35,0xfd,0xb2,0x4e,0xf6,0x04,0xda,0x15,0x3e,0x64,0x87,0x8a,0xaa,0xf6,
+0x37,0x9a,0x95,0xe7,0x63,0x57,0xe6,0xd5,0xfd,0xd4,0x7e,0x07,0x3a,0x0f,0xfe,
+},
+.gen1.reseed_ctr = 2,
+
+.gen2.v = (unsigned char []){
+0x5f,0xd5,0x4f,0xe7,0x21,0x3d,0x3f,0xee,0x0e,0x05,0x2a,0x31,0x75,0x6d,0x3c,0x0c,
+0xbc,0x83,0x75,0x02,0xfe,0x33,0xce,0xfa,0xbe,0xea,0xf1,0x6e,0x32,0xe5,0x8b,0x3a,
+0xb3,0x96,0xfa,0xb5,0x6c,0xe8,0x8f,0x98,0x9f,0xdf,0xe4,0x24,0xc0,0x8b,0x00,0xb6,
+0x46,0x6e,0x50,0xc6,0x6f,0x3f,0xa1,0x36,0x6f,0x7e,0xa2,0x0d,0x6d,0x4b,0xec,0xf1,
+0x67,0x77,0xff,0x54,0xd6,0xea,0xc0,0xcb,0x8b,0x86,0xb0,0x2f,0x2b,0x88,0x5c,0xc7,
+0x80,0x75,0x0a,0x8c,0xef,0x52,0x5f,0x0f,0xe1,0x25,0x8d,0xf1,0xb4,0xc2,0x53,0x45,
+0x29,0xe6,0x8b,0xe9,0x3e,0xbb,0x30,0xb1,0x61,0x4d,0xb7,0x97,0x80,0xd9,0x9e,
+},
+.gen2.c = (unsigned char []){
+0xd2,0x96,0xd0,0x95,0x7e,0x86,0x06,0xb5,0xe2,0x7b,0x74,0xac,0x72,0x98,0x08,0x60,
+0x4c,0x48,0x35,0x03,0x52,0x53,0x4c,0x3d,0x8b,0x1a,0xc0,0x55,0x1c,0x9e,0xfc,0x80,
+0x8b,0x55,0x7d,0x8f,0x5c,0x7a,0x1b,0x62,0x7b,0x86,0x85,0xb5,0x87,0xa5,0x12,0x1e,
+0x73,0xd5,0xbe,0x13,0x78,0xe8,0xea,0x03,0x5f,0xab,0x8a,0xab,0x96,0x2a,0xf8,0x6d,
+0xc4,0x1f,0xda,0x58,0x8d,0xcc,0xde,0xfc,0xfa,0xaa,0x78,0xde,0x18,0xfc,0x7a,0x50,
+0x63,0xaf,0x35,0xfd,0xb2,0x4e,0xf6,0x04,0xda,0x15,0x3e,0x64,0x87,0x8a,0xaa,0xf6,
+0x37,0x9a,0x95,0xe7,0x63,0x57,0xe6,0xd5,0xfd,0xd4,0x7e,0x07,0x3a,0x0f,0xfe,
+},
+.gen2.reseed_ctr = 3,
+
+.prnd = (unsigned char []){
+0xbc,0x5d,0x8d,0x11,0xbe,0x22,0x67,0x9e,0x33,0xf4,0x03,0x74,0x17,0x57,0x16,0xe6,
+0x7c,0x8b,0x5f,0xe6,0x81,0x9a,0xc5,0x3a,0x9b,0x20,0x8d,0xc0,0x58,0x17,0x04,0x31,
+0xff,0xc2,0x9e,0xbd,0x1a,0x81,0x51,0xca,0xa3,0xe9,0x15,0x6d,0x4c,0x7e,0x89,0xe3,
+0x9c,0x12,0x4f,0x71,0x94,0x09,0x51,0x02,0xe8,0x69,0x31,0x06,0x74,0x47,0x1a,0x7f,
+0x1d,0xad,0x4e,0x58,0xf4,0x78,0x6e,0x96,0xb7,0xaa,0x1a,0xd7,0xa5,0x11,0x59,0x23,
+0xba,0x01,0xd4,0xe7,0xa6,0x0a,0x8f,0x11,0xee,0x9c,0x47,0x26,0x6c,0x0f,0x1a,0xe4,
+0x34,0x16,0x8b,0x7b,0x1f,0xb6,0x1e,0xc0,0xfc,0x29,0x2c,0x6c,0x2d,0x3a,0x87,0x78,
+0xdc,0x7b,0x88,0x16,0x42,0xfb,0x8a,0x3e,0x9f,0xa5,0xff,0x37,0x20,0xf7,0x00,0xff,
+0x89,0x00,0x1d,0x21,0xe9,0x7c,0x61,0xc2,0x46,0xdd,0x4f,0x87,0xbd,0x8a,0x64,0xfb,
+0xcb,0x92,0x01,0x4d,0x52,0xf6,0xe6,0x41,0x83,0xbd,0xca,0x84,0xec,0x25,0xed,0x35,
+0x24,0xb9,0xab,0xc8,0x6d,0xf2,0xbc,0x4d,0xff,0x2b,0x76,0x29,0x98,0x55,0xde,0x61,
+0xb7,0xda,0x7e,0xde,0xc0,0x27,0x89,0x3a,0xb4,0xed,0xd0,0xd6,0xea,0x63,0x48,0xe7,
+0x61,0x0e,0x6d,0x94,0x0a,0xf4,0x22,0x54,0x63,0x88,0x68,0x59,0xea,0x4f,0x5c,0x53,
+0xfe,0xa2,0xc3,0x98,0xac,0x2f,0xe7,0x4a,0x9b,0x31,0x8b,0x11,0x5d,0xd4,0x6b,0xbe,
+0xc6,0x88,0x4f,0x07,0x78,0x35,0xaa,0x95,0x15,0x0e,0xf0,0xb3,0xed,0x34,0xd6,0xd5,
+0xb1,0x44,0xff,0x1c,0x1e,0x23,0x88,0x48,0x3d,0x9b,0x5f,0xca,0x8a,0x2c,0x5b,0xf3,
+},
+},
+{
+.no_reseed = false,
+.pr = false,
+.entropy_len = 256 / 8,
+.nonce_len = 128 / 8,
+.pers_len = 256 / 8,
+.add_len = 256 / 8,
+.prnd_len = 2048 / 8,
+
+.inst.entropy = (unsigned char []){
+0x2c,0x48,0x2c,0xd3,0x92,0xd9,0xb8,0x67,0x7f,0xf3,0x19,0xa7,0xad,0x53,0x9c,0xbd,
+0x8a,0x24,0xeb,0xdc,0x2b,0x8d,0xbc,0xeb,0xbc,0x1d,0x1d,0x0d,0x0b,0xcb,0x69,0x8a,
+},
+.inst.nonce = (unsigned char []){
+0x27,0xcb,0x9f,0xff,0xcc,0xdd,0x7a,0x3b,0x28,0x56,0xfe,0xdd,0x68,0x17,0xf1,0xaa,
+},
+.inst.pers = (unsigned char []){
+0xbe,0x95,0x71,0x17,0x54,0xbe,0xb1,0xb2,0x5a,0x46,0xd5,0x04,0xd1,0x9b,0xbf,0x44,
+0x23,0x2c,0x39,0x53,0x32,0x33,0xf6,0xea,0x84,0x14,0x0c,0xa1,0xd4,0x70,0xfb,0x10,
+},
+.inst.v = (unsigned char []){
+0x36,0xf3,0xe7,0x49,0x11,0x77,0xc5,0xb9,0x1e,0xf4,0xbd,0x81,0x38,0x1b,0xec,0xc9,
+0xfe,0x82,0x64,0x72,0x17,0x75,0x3b,0xf1,0xdf,0xc5,0x2d,0x3d,0x8c,0x56,0x38,0x30,
+0xf3,0xa5,0x98,0xd7,0xe3,0x0d,0x6d,0xd8,0xf6,0x3e,0x37,0x07,0xb2,0x59,0xa9,0x8d,
+0xb5,0x87,0x76,0x79,0x4d,0x32,0xaf,0x6a,0x55,0x5b,0x57,0x72,0x11,0x4d,0xa6,0x22,
+0xf3,0xd2,0xa1,0x9d,0xf2,0x49,0xfc,0x88,0xbf,0x8f,0xaf,0x67,0x95,0xed,0x72,0xc5,
+0x20,0x26,0xfe,0x22,0x84,0xd6,0x0d,0x91,0x69,0x43,0x12,0xd9,0x89,0xf3,0x16,0xd9,
+0xc6,0xe8,0x1b,0xf1,0x91,0x6a,0x00,0x8d,0xcf,0x5f,0x6b,0xe4,0x9b,0x87,0xe3,
+},
+.inst.c = (unsigned char []){
+0xb4,0x92,0x33,0x33,0x00,0x5a,0xb7,0x14,0x0e,0xc1,0x08,0xc1,0x20,0xa9,0x77,0x17,
+0x47,0x23,0x57,0xc2,0x56,0x08,0x85,0x33,0xae,0xed,0x55,0x84,0x41,0x17,0xda,0x6c,
+0x28,0xd1,0x11,0xd7,0x05,0x1c,0x5f,0x6b,0xda,0xee,0xe0,0x73,0x10,0x15,0x10,0xdb,
+0x95,0x14,0xbb,0xb8,0xb0,0xb4,0x36,0x23,0xc2,0xb3,0x7f,0x2f,0x1d,0x3f,0x20,0xa9,
+0xc9,0x2e,0xdb,0x2e,0x7b,0xc1,0x86,0x9e,0x43,0xc9,0x14,0xc1,0x0c,0x32,0xc1,0xbf,
+0x81,0xbd,0xff,0x58,0x4c,0x9b,0x5c,0x47,0x80,0xfb,0xba,0xfa,0xa0,0xca,0x01,0x0a,
+0xfb,0x7e,0x8b,0x05,0x2b,0xe8,0x38,0xf5,0x8c,0x04,0x3e,0x0c,0x2b,0x6a,0xd2,
+},
+.inst.reseed_ctr = 1,
+
+.res.entropy = (unsigned char []){
+0x4f,0x39,0xa2,0xb6,0x30,0x9a,0xf3,0x2a,0x1c,0x72,0x1b,0xd2,0xa3,0x1a,0x97,0x81,
+0x48,0x07,0x64,0x43,0x03,0xb1,0xd1,0x32,0x23,0x93,0x64,0xa3,0x6d,0x26,0x6f,0x10,
+},
+.res.add = (unsigned char []){
+0x94,0x7d,0x7b,0x37,0x2c,0x90,0x9e,0xae,0x57,0xba,0xe6,0x4d,0x7a,0x9b,0xbf,0x75,
+0x23,0x4f,0x5c,0xb0,0x5c,0x09,0x39,0x27,0x03,0x7f,0x63,0x2d,0xd8,0x56,0x76,0x93,
+},
+.res.v = (unsigned char []){
+0xe8,0x80,0xaa,0xd5,0x78,0x88,0xbc,0x81,0xbe,0xb6,0xe1,0x6b,0xdc,0xe7,0x5f,0x6d,
+0xbd,0xd0,0xad,0xab,0x7e,0xb0,0x4a,0xeb,0x62,0xc4,0xd6,0xa4,0x27,0x4c,0x8e,0xaa,
+0xcb,0x9c,0x3a,0x84,0x22,0xa4,0xdf,0x14,0xe6,0x57,0x0a,0x42,0x7b,0x01,0x35,0x61,
+0xfd,0xd6,0x04,0x60,0x29,0x84,0xef,0xa4,0xe3,0xc0,0x17,0xb7,0xa5,0x6e,0x13,0x31,
+0xe8,0xca,0xe2,0x54,0xe4,0x69,0xd2,0x54,0x38,0x70,0x99,0x94,0xbb,0x8b,0x37,0x07,
+0xa5,0x2f,0xed,0xa8,0x6f,0x1b,0x0c,0xbf,0x3b,0x3c,0xa3,0x4a,0x97,0x35,0x7c,0x10,
+0x98,0x6d,0x96,0x71,0x4d,0x2e,0xa2,0x66,0x0b,0xc6,0x71,0x30,0xeb,0xf8,0xe6,
+},
+.res.c = (unsigned char []){
+0xec,0xed,0x12,0x31,0x3f,0x5f,0x03,0xdd,0xd2,0xdc,0x63,0xf0,0x99,0x8e,0xf7,0x23,
+0x28,0x39,0xfe,0xd2,0xdd,0x04,0xd4,0x0f,0x43,0xf5,0x1c,0xb1,0x89,0xc5,0x4a,0xa4,
+0xa0,0x15,0x24,0x62,0xbb,0x45,0x5e,0x89,0x7f,0xe8,0x15,0x0f,0x32,0x31,0x7d,0x6e,
+0xba,0x74,0x84,0xd3,0xb2,0x07,0x89,0xf5,0xd7,0xa7,0x70,0x96,0x80,0xa6,0x90,0xa4,
+0x31,0xdf,0x7d,0xe9,0x18,0xc0,0xa5,0x0e,0x8f,0x3f,0x3f,0x1a,0x4c,0xe0,0xdf,0xfa,
+0x1e,0x74,0xba,0x70,0x85,0x69,0xde,0x35,0xa0,0xcd,0x52,0xed,0x31,0xd2,0x94,0x29,
+0x87,0xd8,0xef,0x52,0xce,0x26,0xa8,0xb2,0x9c,0x0b,0x94,0xa6,0x5a,0xb0,0x65,
+},
+.res.reseed_ctr = 1,
+
+.gen1.add = (unsigned char []){
+0x65,0x1f,0x03,0xa8,0x02,0x34,0x34,0xb2,0xaf,0x28,0xa1,0xfa,0xd9,0x4b,0x31,0x91,
+0x01,0x52,0xd4,0x9a,0x1b,0xbc,0xea,0xe3,0x2b,0xcc,0xd7,0x4d,0xde,0x60,0xd9,0x2f,
+},
+.gen1.v = (unsigned char []){
+0xd5,0x6d,0xbd,0x06,0xb7,0xe7,0xc0,0x5f,0x91,0x93,0x45,0x5c,0x76,0x76,0x56,0x90,
+0xe6,0x0a,0xac,0x7e,0x5b,0xb5,0x1e,0xfa,0xa6,0xb9,0xf3,0x55,0xb1,0x11,0xd9,0x4f,
+0x6b,0xb1,0x5e,0xe6,0xdd,0xea,0x3d,0x9e,0x66,0x3f,0x1f,0x51,0xad,0x32,0xb3,0xb1,
+0x2f,0x75,0xf5,0x94,0xe1,0x94,0xa0,0xeb,0xb8,0xc6,0xbd,0xb9,0x9a,0x42,0x88,0x31,
+0x91,0x95,0xdb,0x4c,0xa3,0xe7,0x50,0x5f,0xa3,0x3a,0xb4,0x5f,0xa1,0x17,0x8f,0x51,
+0xb9,0x66,0x84,0x0b,0x40,0x4e,0xfe,0x35,0xe0,0xbb,0xb3,0x87,0xe4,0x00,0xe8,0xd7,
+0x5b,0x43,0x09,0xef,0x6c,0x3d,0xe2,0x8f,0x80,0x48,0x1e,0x10,0x1c,0xbf,0x3f,
+},
+.gen1.c = (unsigned char []){
+0xec,0xed,0x12,0x31,0x3f,0x5f,0x03,0xdd,0xd2,0xdc,0x63,0xf0,0x99,0x8e,0xf7,0x23,
+0x28,0x39,0xfe,0xd2,0xdd,0x04,0xd4,0x0f,0x43,0xf5,0x1c,0xb1,0x89,0xc5,0x4a,0xa4,
+0xa0,0x15,0x24,0x62,0xbb,0x45,0x5e,0x89,0x7f,0xe8,0x15,0x0f,0x32,0x31,0x7d,0x6e,
+0xba,0x74,0x84,0xd3,0xb2,0x07,0x89,0xf5,0xd7,0xa7,0x70,0x96,0x80,0xa6,0x90,0xa4,
+0x31,0xdf,0x7d,0xe9,0x18,0xc0,0xa5,0x0e,0x8f,0x3f,0x3f,0x1a,0x4c,0xe0,0xdf,0xfa,
+0x1e,0x74,0xba,0x70,0x85,0x69,0xde,0x35,0xa0,0xcd,0x52,0xed,0x31,0xd2,0x94,0x29,
+0x87,0xd8,0xef,0x52,0xce,0x26,0xa8,0xb2,0x9c,0x0b,0x94,0xa6,0x5a,0xb0,0x65,
+},
+.gen1.reseed_ctr = 2,
+
+.gen2.add = (unsigned char []){
+0x93,0x4a,0x97,0xd6,0xee,0x46,0x85,0x25,0x0a,0xc5,0xe5,0x11,0x59,0xe5,0xbc,0xbc,
+0x48,0xa6,0xf9,0x2c,0x7c,0xe7,0xbf,0xd1,0xc6,0x1d,0x0e,0x7b,0x0a,0x0e,0x7f,0x61,
+},
+.gen2.v = (unsigned char []){
+0xc2,0x5a,0xcf,0x37,0xf7,0x46,0xc4,0x3d,0x64,0x6f,0xa9,0x4d,0x10,0x05,0x4d,0xb4,
+0x0e,0x44,0xab,0x51,0x38,0xb9,0xf3,0x09,0xea,0xaf,0x10,0x07,0x3a,0xd7,0x23,0xf4,
+0x0b,0xc6,0x83,0x49,0x99,0x2f,0x9c,0x27,0xe6,0x27,0x34,0x60,0xdf,0x64,0x31,0xa9,
+0xff,0xd8,0x0c,0x15,0xed,0x67,0x40,0xd8,0x72,0xc4,0x64,0x68,0x24,0xee,0x9e,0x36,
+0x2d,0x7a,0xce,0x7c,0xf6,0x5d,0x37,0x31,0x8c,0x2d,0x48,0x30,0x19,0x62,0x78,0x04,
+0x4a,0xd9,0x8b,0x6e,0x0d,0x87,0x99,0xa0,0x55,0x37,0x4d,0x71,0x19,0x34,0xe5,0xbd,
+0xa4,0x51,0xc0,0x82,0x4d,0x51,0xf3,0x83,0x8f,0xf1,0xf7,0x99,0x0e,0xef,0x1a,
+},
+.gen2.c = (unsigned char []){
+0xec,0xed,0x12,0x31,0x3f,0x5f,0x03,0xdd,0xd2,0xdc,0x63,0xf0,0x99,0x8e,0xf7,0x23,
+0x28,0x39,0xfe,0xd2,0xdd,0x04,0xd4,0x0f,0x43,0xf5,0x1c,0xb1,0x89,0xc5,0x4a,0xa4,
+0xa0,0x15,0x24,0x62,0xbb,0x45,0x5e,0x89,0x7f,0xe8,0x15,0x0f,0x32,0x31,0x7d,0x6e,
+0xba,0x74,0x84,0xd3,0xb2,0x07,0x89,0xf5,0xd7,0xa7,0x70,0x96,0x80,0xa6,0x90,0xa4,
+0x31,0xdf,0x7d,0xe9,0x18,0xc0,0xa5,0x0e,0x8f,0x3f,0x3f,0x1a,0x4c,0xe0,0xdf,0xfa,
+0x1e,0x74,0xba,0x70,0x85,0x69,0xde,0x35,0xa0,0xcd,0x52,0xed,0x31,0xd2,0x94,0x29,
+0x87,0xd8,0xef,0x52,0xce,0x26,0xa8,0xb2,0x9c,0x0b,0x94,0xa6,0x5a,0xb0,0x65,
+},
+.gen2.reseed_ctr = 3,
+
+.prnd = (unsigned char []){
+0x77,0xce,0x58,0xaf,0x82,0x2a,0x11,0xf1,0xd6,0xdf,0xb2,0xbe,0x24,0x6a,0xa6,0x54,
+0x9e,0x4c,0x08,0x9e,0x15,0x32,0xae,0xba,0x3e,0x6f,0x13,0xd1,0x96,0x35,0x93,0x0f,
+0x70,0x24,0xf9,0x43,0x99,0xba,0x6c,0x84,0xdf,0xa3,0xcd,0x9c,0x78,0x06,0xd7,0xb7,
+0x69,0xc0,0x96,0xd3,0x34,0x15,0xa5,0x6b,0xe1,0x09,0x66,0x18,0xd5,0xbd,0x80,0xd7,
+0xd6,0x49,0x95,0x0e,0xbc,0xfe,0x74,0x18,0xe9,0xf2,0x33,0xac,0xdb,0xb7,0xc2,0xed,
+0x36,0x81,0xf5,0xdc,0xd0,0x7e,0x74,0x1e,0xec,0xd2,0xa4,0x67,0x5a,0xc8,0xdb,0x7b,
+0xec,0xd2,0xeb,0x77,0xf1,0x64,0xcf,0x5c,0x76,0x72,0xa6,0xe9,0xe6,0x19,0x25,0x4c,
+0x5f,0x23,0x1c,0x85,0x34,0x4c,0x34,0x61,0xfa,0xdb,0x5f,0x19,0x17,0x06,0xda,0xe9,
+0xfc,0x2c,0xb5,0xd6,0x1c,0x8b,0x36,0xb3,0xe1,0xaf,0x3e,0x82,0xce,0xf8,0xe2,0xa9,
+0xca,0x76,0xfa,0xfb,0xaf,0x4d,0x4b,0xf9,0xe0,0xf9,0xb0,0xcd,0x59,0x07,0xd4,0x06,
+0x9e,0x0e,0xf4,0xe1,0xf1,0x1a,0x25,0x99,0x63,0xc9,0xd8,0x28,0x2f,0x36,0xb2,0x7b,
+0x75,0x68,0x39,0x58,0xa1,0x65,0x07,0x3e,0x69,0x2d,0xd9,0x82,0x08,0xd6,0xdc,0x17,
+0xa7,0x91,0xfd,0x9c,0x3d,0xd5,0x45,0x54,0xca,0x6b,0x65,0x67,0x50,0xb7,0x7b,0x19,
+0x61,0xc9,0x17,0xf4,0x86,0xba,0x3d,0xcf,0xfe,0x78,0xde,0x2b,0x34,0x6c,0xd3,0x8b,
+0x4d,0xe2,0x34,0xaf,0x1a,0x35,0x66,0xcc,0xb8,0x6b,0x76,0x14,0xe9,0x9d,0x96,0x62,
+0x4a,0xb3,0x91,0x95,0x23,0xdf,0xe9,0x38,0x1d,0xd5,0x7d,0x4d,0x00,0xf0,0x0b,0x6d,
+},
+},
+};
+
+#ifdef ICA_FIPS
+const size_t AES_ECB_TV_LEN = sizeof(AES_ECB_TV) / sizeof(AES_ECB_TV[0]);
+const size_t AES_CBC_TV_LEN = sizeof(AES_CBC_TV) / sizeof(AES_CBC_TV[0]);
+const size_t AES_CBC_CS_TV_LEN = sizeof(AES_CBC_CS_TV)
+ / sizeof(AES_CBC_CS_TV[0]);
+const size_t AES_CFB_TV_LEN = sizeof(AES_CFB_TV) / sizeof(AES_CFB_TV[0]);
+const size_t AES_OFB_TV_LEN = sizeof(AES_OFB_TV) / sizeof(AES_OFB_TV[0]);
+const size_t AES_CTR_TV_LEN = sizeof(AES_CTR_TV) / sizeof(AES_CTR_TV[0]);
+const size_t AES_CCM_TV_LEN = sizeof(AES_CCM_TV) / sizeof(AES_CCM_TV[0]);
+const size_t AES_GCM_TV_LEN = sizeof(AES_GCM_TV) / sizeof(AES_GCM_TV[0]);
+const size_t AES_XTS_TV_LEN = sizeof(AES_XTS_TV) / sizeof(AES_XTS_TV[0]);
+const size_t AES_CMAC_TV_LEN = sizeof(AES_CMAC_TV) / sizeof(AES_CMAC_TV[0]);
+const size_t DES3_ECB_TV_LEN = sizeof(DES3_ECB_TV) / sizeof(DES3_ECB_TV[0]);
+const size_t DES3_CBC_TV_LEN = sizeof(DES3_CBC_TV) / sizeof(DES3_CBC_TV[0]);
+const size_t DES3_CBC_CS_TV_LEN = sizeof(DES3_CBC_CS_TV)
+ / sizeof(DES3_CBC_CS_TV[0]);
+const size_t DES3_CFB_TV_LEN = sizeof(DES3_CFB_TV) / sizeof(DES3_CFB_TV[0]);
+const size_t DES3_OFB_TV_LEN = sizeof(DES3_OFB_TV) / sizeof(DES3_OFB_TV[0]);
+const size_t DES3_CTR_TV_LEN = sizeof(DES3_CTR_TV) / sizeof(DES3_CTR_TV[0]);
+const size_t DES3_CMAC_TV_LEN = sizeof(DES3_CMAC_TV) / sizeof(DES3_CMAC_TV[0]);
+const size_t RSA_TV_LEN = sizeof(RSA_TV) / sizeof(RSA_TV[0]);
+const size_t SHA1_TV_LEN = sizeof(SHA1_TV) / sizeof(SHA1_TV[0]);
+const size_t SHA224_TV_LEN = sizeof(SHA224_TV) / sizeof(SHA224_TV[0]);
+const size_t SHA256_TV_LEN = sizeof(SHA256_TV) / sizeof(SHA256_TV[0]);
+const size_t SHA384_TV_LEN = sizeof(SHA384_TV) / sizeof(SHA384_TV[0]);
+const size_t SHA512_TV_LEN = sizeof(SHA512_TV) / sizeof(SHA512_TV[0]);
+#endif /* ICA_FIPS */
+const size_t DRBG_SHA512_TV_LEN = sizeof(DRBG_SHA512_TV)
+ / sizeof(DRBG_SHA512_TV[0]);
diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
new file mode 100644
index 0000000..149961d
--- /dev/null
+++ b/src/tests/Makefile.am
@@ -0,0 +1,51 @@
+#OPTS = -O0 -g -Wall -fprofile-arcs -ftest-coverage -fPIC
+#OPTS = -O0 -g -Wall -m31 -D_LINUX_S390_
+
+if DEBUG
+OPTS = -O0 -g -Wall -D_LINUX_S390_ -D_GNU_SOURCE -pthread -fstack-protector-all
+else
+OPTS = -O0 -g -Wall -D_LINUX_S390_ -D_GNU_SOURCE -pthread
+endif
+
+if ICA_FIPS
+OPTS += -DICA_FIPS
+endif
+
+LIBS = -L../.libs
+INCLUDE = -I. -I../include -I../../include
+CC = gcc
+
+TARGETS = icastats_test \
+ libica_des_test libica_3des_test \
+ libica_aes128_test libica_aes192_test libica_aes256_test \
+ libica_sha1_test \
+ libica_sha256_test \
+ libica_rsa_test libica_rsa_key_check_test \
+ libica_rng_test libica_keygen_test \
+ libica_cmac_test \
+ libica_aes_xts_test libica_aes_gcm_test libica_ccm_test \
+ libica_aes_ctr_test libica_aes_ofb_test libica_aes_cfb_test \
+ libica_aes_cbc_test libica_aes_ecb_test \
+ libica_des_ctr_test libica_3des_ctr_test \
+ libica_des_cfb_test libica_3des_cfb_test \
+ libica_des_cbc_test libica_3des_cbc_test \
+ libica_des_ecb_test libica_cbccs_test libica_3des_ecb_test \
+ libica_des_ofb_test libica_3des_ofb_test \
+ libica_get_version \
+ libica_get_functionlist \
+ libica_drbg_test \
+ libica_drbg_birthdays \
+ libica_fips_test
+
+all: $(TARGETS)
+
+# Every target is created from a single .c file.
+%: %.c
+ gcc $(OPTS) -o $@ $^ $(LIBS) $(INCLUDE) -lica -lcrypto
+
+clean:
+ rm -f $(TARGETS)
+
+distclean:
+ rm -f Makefile
+ rm -f $(TARGETS)
diff --git a/src/tests/icastats_test.c b/src/tests/icastats_test.c
new file mode 100644
index 0000000..f277a69
--- /dev/null
+++ b/src/tests/icastats_test.c
@@ -0,0 +1,881 @@
+/* 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. 2014 */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <dirent.h>
+#include <string.h>
+#include <ctype.h>
+#include "ica_api.h"
+#include "s390_crypto.h"
+#include "testcase.h"
+
+#define DATA_LENGHT 32
+#define DES_CIPHER_BLOCK 8
+#define AES_CIPHER_BLOCK 16
+#define RSA_BYTE_LENGHT 128
+
+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,
+};
+
+int hw_flag;
+unsigned int mech_len;
+libica_func_list_element *pmech_list = NULL;
+
+static int handle_ica_error(int rc, char *message);
+static int is_crypto_card_loaded();
+void create_hw_info();
+int check_hw(int algo_id);
+void check_icastats(int algo_id, char *stat);
+void des_tests(unsigned char *iv, unsigned char *cmac, unsigned char *ctr);
+void tdes_tests(unsigned char *iv, unsigned char *cmac, unsigned char *ctr);
+void sha_tests();
+void rsa_tests(ica_adapter_handle_t handle);
+void aes_tests(unsigned char *iv, unsigned char *cmac, unsigned char *ctr);
+
+int main (int argc, char **argv)
+{
+ int rc = 0;
+ ica_adapter_handle_t adapter_handle;
+
+ unsigned char *cmac;
+ unsigned char *ctr;
+ unsigned char *iv;
+
+ set_verbosity(argc, argv);
+
+ if((cmac = malloc(AES_CIPHER_BLOCK*sizeof(char))) == NULL){
+ perror("Error in malloc: ");
+ exit(EXIT_FAILURE);
+ }
+ if((ctr = malloc(AES_CIPHER_BLOCK*sizeof(char))) == NULL){
+ perror("Error in malloc: ");
+ exit(EXIT_FAILURE);
+ }
+
+ if((iv = malloc(AES_CIPHER_BLOCK*sizeof(char))) == NULL){
+ perror("Error in malloc: ");
+ exit(EXIT_FAILURE);
+ }
+
+ /*
+ * Open crypto adapter
+ **/
+ rc = ica_open_adapter(&adapter_handle);
+ if (rc != 0) {
+ V_(printf("ica_open_adapter failed and returned %d (0x%x).\n", rc, rc));
+ }
+
+ create_hw_info();
+
+
+ /*
+ * Reset Counters
+ **/
+ system("icastats -r");
+ rc = ica_random_number_generate(AES_CIPHER_BLOCK, ctr);
+ if (rc)
+ exit(handle_ica_error(rc, "ica_random_number_generate"));
+
+ /*
+ * Check if counter for Random operations has incremneted
+ **/
+ /* ica_random_number_generate uses ica_drbg if available. Otherwise the
+ * old prng code is used. */
+ if (check_hw(SHA512_DRNG) == 1 || check_hw(SHA512) == 1)
+ check_icastats(SHA512_DRNG, "DRBG-SHA-512");
+ else
+ check_icastats(P_RNG, "P_RNG");
+
+ rc = ica_random_number_generate(AES_CIPHER_BLOCK, iv);
+ if (rc)
+ exit(handle_ica_error(rc, "ica_random_number_generate"));
+
+ /*
+ * Check counters for all crypto operations
+ **/
+ des_tests(iv, cmac, ctr);
+ tdes_tests(iv, cmac, ctr);
+ sha_tests();
+ rsa_tests(adapter_handle);
+ aes_tests(iv, cmac, ctr);
+
+ free(cmac);
+ free(ctr);
+ free(iv);
+
+ printf("All icastats tests passed.\n");
+ return 0;
+}
+
+
+int is_crypto_card_loaded()
+{
+ DIR* sysDir;
+ FILE *file;
+ char dev[PATH_MAX] = "/sys/devices/ap/";
+ struct dirent *direntp;
+ char *type = NULL;
+ size_t size;
+ char c;
+
+ if ((sysDir = opendir(dev)) == NULL )
+ return 0;
+
+ while((direntp = readdir(sysDir)) != NULL){
+ if(strstr(direntp->d_name, "card") != 0){
+ snprintf(dev, PATH_MAX, "/sys/devices/ap/%s/type",
+ direntp->d_name);
+
+ if ((file = fopen(dev, "r")) == NULL){
+ closedir(sysDir);
+ return 0;
+ }
+
+ if (getline(&type, &size, file) == -1){
+ fclose(file);
+ closedir(sysDir);
+ return 0;
+ }
+
+ /* ignore \n
+ * looking for CEX??A and CEX??C
+ * Skip type CEX??P cards
+ **/
+ if (type[strlen(type)-2] == 'P'){
+ free(type);
+ type = NULL;
+ fclose(file);
+ continue;
+ }
+ free(type);
+ type = NULL;
+ fclose(file);
+
+ snprintf(dev, PATH_MAX, "/sys/devices/ap/%s/online",
+ direntp->d_name);
+ if ((file = fopen(dev, "r")) == NULL){
+ closedir(sysDir);
+ return 0;
+ }
+ if((c = fgetc(file)) == '1'){
+ fclose(file);
+ return 1;
+ }
+ fclose(file);
+ }
+ }
+ closedir(sysDir);
+ return 0;
+}
+
+/*
+ * Create Hardware Info database
+ **/
+void create_hw_info()
+{
+ if (ica_get_functionlist(NULL, &mech_len) != 0){
+ perror("get_functionlist: ");
+ exit(EXIT_FAILURE);
+ }
+ pmech_list = malloc(sizeof(libica_func_list_element)*mech_len);
+ if (ica_get_functionlist(pmech_list, &mech_len) != 0){
+ perror("get_functionlist: ");
+ free(pmech_list);
+ exit(EXIT_FAILURE);
+ }
+
+ hw_flag = is_crypto_card_loaded();
+}
+
+/*
+ * check if a cryptp operation is supported in hardware
+ **/
+int check_hw(int algo_id)
+{
+ int i;
+ for (i=mech_len-1; i >= 0; i--)
+ if (pmech_list[i].mech_mode_id == algo_id)
+ break;
+ if (i < 0) return -1;
+
+ if(hw_flag){
+ if(pmech_list[i].flags & (ICA_FLAG_SHW | ICA_FLAG_DHW))
+ return 1;
+ else
+ return 0;
+ } else{
+ if(pmech_list[i].flags & ICA_FLAG_SHW)
+ return 1;
+ else
+ return 0;
+ }
+}
+
+/*
+ * Check if icastats has counted correctly
+ **/
+void check_icastats(int algo_id, char *stat)
+{
+ char cmd[256], line[256], *p;
+ FILE *f;
+ int i, hw, rc=-1, counters=0;
+ int hwcounter1=0, hwcounter2=0, swcounter1=0, swcounter2=0;
+
+ hw = check_hw(algo_id);
+ if (hw < 0) return; /* unknown algo_id */
+
+ sprintf(cmd, "icastats | grep '%s'", stat);
+ f = popen(cmd, "r");
+ if (!f) {
+ perror("error in peopen");
+ exit(EXIT_FAILURE);
+ }
+ fgets(line, sizeof(line), f);
+ pclose(f);
+
+ /* remove trailing whitespace from the line */
+ i = strlen(line);
+ while (i > 0 && isspace(line[i-1])) {
+ line[i-1] = 0;
+ i--;
+ }
+
+ p = strstr(line, "|");
+ if (!p) goto out; /* no | in the output. Wrong algo string ? */
+ p++;
+ while (isspace(*p)) p++;
+ hwcounter1 = atoi(p); /* parse 1st hw counter value */
+ counters++;
+ while (*p && !isspace(*p)) p++; /* parse over counter value */
+ while (isspace(*p)) p++;
+ /* now either a | or another counter value follows */
+ if (isdigit(*p)) {
+ hwcounter2 = atoi(p); /* parse 2nd hw counter value */
+ counters++;
+ while (*p && !isspace(*p)) p++; /* parse over counter value */
+ while (isspace(*p)) p++;
+ }
+ /* now there should be a | */
+ if (*p != '|') {
+ V_(fprintf(stderr, "parse error, missing '|' in line '%s'\n", line));
+ goto out;
+ }
+ p++;
+ while (isspace(*p)) p++;
+ swcounter1 = atoi(p); /* parse 1st sw counter value */
+ counters++;
+ while (*p && !isspace(*p)) p++; /* parse over counter value */
+ while (isspace(*p)) p++;
+ /* maybe another counter value follows */
+ if (isdigit(*p)) {
+ swcounter2 = atoi(p); /* parse 2nd sw counter value */
+ counters++;
+ }
+
+ /* counters should be 2 or 4 now */
+ if (counters == 2) {
+ if (hw) {
+ /* hwcounter1 should be > 0 */
+ if (hwcounter1 > 0)
+ rc = 0;
+ else
+ goto out;
+ } else {
+ /* swcounter1 should be > 0 */
+ if (swcounter1 > 0)
+ rc = 0;
+ else
+ goto out;
+ }
+ } else if (counters == 4) {
+ if (hw) {
+ /* hwcounter1 or hwcounter2 should be > 0 */
+ if (hwcounter1 > 0 || hwcounter2 > 0)
+ rc = 0;
+ else
+ goto out;
+ } else {
+ /* swcounter1 or swcounter2 should be > 0 */
+ if (swcounter1 > 0 || swcounter2 > 0)
+ rc = 0;
+ else
+ goto out;
+ }
+ } else {
+ V_(printf("parse error, could not parse 2 or 4 counter values\n"));
+ goto out;
+ }
+out:
+ if (rc == 0) {
+ V_(printf("Test %s SUCCESS.\n", stat));
+ } else {
+ printf("icastats %s test FAILED!\n", stat);
+ V_(printf("icastats line for %s was '%s'\n", stat, line));
+ exit(EXIT_FAILURE);
+ }
+}
+
+static int handle_ica_error(int rc, char *message)
+{
+ printf("Error in %s: ", message);
+ switch (rc) {
+ case 0:
+ V_(printf("OK\n"));
+ break;
+ case EINVAL:
+ V_(printf("Incorrect parameter.\n"));
+ break;
+ case EPERM:
+ V_(printf("Operation not permitted by Hardware.\n"));
+ break;
+ case EIO:
+ V_(printf("I/O error.\n"));
+ break;
+ default:
+ V_(perror(""));
+ }
+ return rc;
+}
+
+
+
+void des_tests(unsigned char *iv, unsigned char *cmac, unsigned char *ctr)
+{
+ int rc = 0;
+ int mode;
+ unsigned char *out_buffer;
+ unsigned char *inp_buffer = plain_data;
+ unsigned char des_key[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ };
+
+#ifdef ICA_FIPS
+ if (ica_fips_status() & ICA_FIPS_MODE) {
+ V_(printf("All icastats DES tests skipped."
+ " (DES not FIPS approved)\n"));
+ return;
+ }
+#endif /* ICA_FIPS */
+
+ if((out_buffer = malloc(DATA_LENGHT*sizeof(char))) == NULL){
+ perror("Error in malloc: ");
+ exit(EXIT_FAILURE);
+ }
+
+
+ system("icastats -r");
+ for(mode = 1; mode >= 0; mode--){
+ rc = ica_des_ecb(inp_buffer, out_buffer, DATA_LENGHT,
+ des_key, mode);
+ if (rc)
+ exit(handle_ica_error(rc, "ica_des_ecb"));
+
+ if(mode == ICA_ENCRYPT)
+ inp_buffer = out_buffer;
+ else if(mode == ICA_DECRYPT)
+ inp_buffer = plain_data;
+ }
+ check_icastats(DES_ECB, "DES ECB");
+
+ system("icastats -r");
+ for(mode = 1; mode >= 0; mode--){
+ rc = ica_des_cbc(inp_buffer, out_buffer, DATA_LENGHT,
+ des_key, iv, mode);
+ if(rc)
+ exit(handle_ica_error(rc, "ica_des_ecb"));
+
+ if(mode == ICA_ENCRYPT)
+ inp_buffer = out_buffer;
+ else if(mode == ICA_DECRYPT)
+ inp_buffer = plain_data;
+ }
+ check_icastats(DES_CBC, "DES CBC");
+
+ system("icastats -r");
+ for(mode = 1; mode >= 0; mode--){
+ rc = ica_des_cfb(inp_buffer, out_buffer, DATA_LENGHT,
+ des_key, iv, DES_CIPHER_BLOCK, mode);
+ if(rc)
+ exit(handle_ica_error(rc, "ica_des_cfb"));
+
+ if(mode == ICA_ENCRYPT)
+ inp_buffer = out_buffer;
+ else if(mode == ICA_DECRYPT)
+ inp_buffer = plain_data;
+ }
+ check_icastats(DES_CFB, "DES CFB");
+
+ system("icastats -r");
+ for(mode = 1; mode >= 0; mode--){
+ rc = ica_des_cmac(inp_buffer, DATA_LENGHT, cmac, DES_CIPHER_BLOCK,
+ des_key, mode);
+ if(rc)
+ exit(handle_ica_error(rc, "ica_des_cmac"));
+ }
+ check_icastats(DES_CMAC, "DES CMAC");
+
+ system("icastats -r");
+ for(mode = 1; mode >= 0; mode--){
+ rc = ica_des_ctr(inp_buffer, out_buffer, DATA_LENGHT, des_key,
+ ctr, DES_CIPHER_BLOCK, mode);
+ if(rc)
+ exit(handle_ica_error(rc, "ica_des_ctr"));
+
+ if(mode == ICA_ENCRYPT)
+ inp_buffer = out_buffer;
+ else if(mode == ICA_DECRYPT)
+ inp_buffer = plain_data;
+ }
+ check_icastats(DES_CTR, "DES CTR");
+
+ system("icastats -r");
+ for(mode = 1; mode >= 0; mode--){
+ rc = ica_des_ofb(inp_buffer, out_buffer, DATA_LENGHT,
+ des_key, iv, mode);
+ if(rc)
+ exit(handle_ica_error(rc, "ica_des_ofb"));
+
+ if(mode == ICA_ENCRYPT)
+ inp_buffer = out_buffer;
+ else if(mode == ICA_DECRYPT)
+ inp_buffer = plain_data;
+ }
+ check_icastats(DES_OFB, "DES OFB");
+
+ free(out_buffer);
+}
+
+void tdes_tests(unsigned char *iv, unsigned char *cmac, unsigned char *ctr)
+{
+ int rc = 0;
+ int mode;
+ unsigned char *out_buffer;
+ unsigned char *inp_buffer = plain_data;
+ unsigned char des_key[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ };
+
+ if((out_buffer = malloc(DATA_LENGHT*sizeof(char))) == NULL){
+ perror("Error in malloc: ");
+ exit(EXIT_FAILURE);
+ }
+
+ system("icastats -r");
+ for(mode = 1; mode >= 0; mode--){
+ rc = ica_3des_ecb(inp_buffer, out_buffer, DATA_LENGHT,
+ des_key, mode);
+ if (rc)
+ exit(handle_ica_error(rc, "ica_3des_ecb"));
+
+ if(mode == ICA_ENCRYPT)
+ inp_buffer = out_buffer;
+ else if(mode == ICA_DECRYPT)
+ inp_buffer = plain_data;
+ }
+ check_icastats(DES3_ECB, "3DES ECB");
+
+ system("icastats -r");
+ for(mode = 1; mode >= 0; mode--){
+ rc = ica_3des_cbc(inp_buffer, out_buffer, DATA_LENGHT,
+ des_key, iv, mode);
+ if(rc)
+ exit(handle_ica_error(rc, "ica_3des_cbc"));
+
+ if(mode == ICA_ENCRYPT)
+ inp_buffer = out_buffer;
+ else if(mode == ICA_DECRYPT)
+ inp_buffer = plain_data;
+ }
+ check_icastats(DES3_CBC, "3DES CBC");
+
+ system("icastats -r");
+ for(mode = 1; mode >= 0; mode--){
+ rc = ica_3des_cfb(inp_buffer, out_buffer, DATA_LENGHT,
+ des_key, iv, DES_CIPHER_BLOCK, mode);
+ if(rc)
+ exit(handle_ica_error(rc, "ica_3des_cfb"));
+
+ if(mode == ICA_ENCRYPT)
+ inp_buffer = out_buffer;
+ else if(mode == ICA_DECRYPT)
+ inp_buffer = plain_data;
+ }
+ check_icastats(DES3_CFB, "3DES CFB");
+
+ system("icastats -r");
+ for(mode = 1; mode >= 0; mode--){
+ rc = ica_3des_cmac(inp_buffer, DATA_LENGHT, cmac, DES_CIPHER_BLOCK,
+ des_key, mode);
+ if(rc)
+ exit(handle_ica_error(rc, "ica_3des_cmac"));
+ }
+ check_icastats(DES3_CMAC, "3DES CMAC");
+
+ system("icastats -r");
+ for(mode = 1; mode >= 0; mode--){
+ rc = ica_3des_ctr(inp_buffer, out_buffer, DATA_LENGHT, des_key,
+ ctr, DES_CIPHER_BLOCK, mode);
+ if(rc)
+ exit(handle_ica_error(rc, "ica_3des_ctr"));
+
+ if(mode == ICA_ENCRYPT)
+ inp_buffer = out_buffer;
+ else if(mode == ICA_DECRYPT)
+ inp_buffer = plain_data;
+ }
+ check_icastats(DES3_CTR, "3DES CTR");
+
+ system("icastats -r");
+ for(mode = 1; mode >= 0; mode--){
+ rc = ica_3des_ofb(inp_buffer, out_buffer, DATA_LENGHT,
+ des_key, iv, mode);
+ if(rc)
+ exit(handle_ica_error(rc, "ica_3des_ofb"));
+
+ if(mode == ICA_ENCRYPT)
+ inp_buffer = out_buffer;
+ else if(mode == ICA_DECRYPT)
+ inp_buffer = plain_data;
+ }
+ check_icastats(DES3_OFB, "3DES OFB");
+
+ free(out_buffer);
+}
+
+void sha_tests()
+{
+ int rc = 0;
+ unsigned char hash[SHA512_HASH_LENGTH];
+
+ sha_context_t sha_context0;
+ sha256_context_t sha_context1;
+ sha512_context_t sha_context2;
+
+
+ system("icastats -r");
+ rc = ica_sha1(SHA_MSG_PART_ONLY, DATA_LENGHT,
+ plain_data, &sha_context0, hash);
+ if(rc)
+ exit(handle_ica_error(rc, "ica_sha1"));
+ check_icastats(SHA1, "SHA-1");
+
+ system("icastats -r");
+ rc = ica_sha224(SHA_MSG_PART_ONLY, DATA_LENGHT,
+ plain_data, &sha_context1, hash);
+ if(rc)
+ exit(handle_ica_error(rc, "ica_sha224"));
+ check_icastats(SHA224, "SHA-224");
+
+ system("icastats -r");
+ rc = ica_sha256(SHA_MSG_PART_ONLY, DATA_LENGHT,
+ plain_data, &sha_context1, hash);
+ if(rc)
+ exit(handle_ica_error(rc, "ica_sha256"));
+ check_icastats(SHA256, "SHA-256");
+
+ system("icastats -r");
+ rc = ica_sha384(SHA_MSG_PART_ONLY, DATA_LENGHT,
+ plain_data, &sha_context2, hash);
+ if(rc)
+ exit(handle_ica_error(rc, "ica_sha384"));
+ check_icastats(SHA384, "SHA-384");
+
+ system("icastats -r");
+ rc = ica_sha512(SHA_MSG_PART_ONLY, DATA_LENGHT,
+ plain_data, &sha_context2, hash);
+ if(rc)
+ exit(handle_ica_error(rc, "ica_sha512"));
+ check_icastats(SHA512, "SHA-512");
+}
+
+void rsa_tests(ica_adapter_handle_t handle)
+{
+
+unsigned char e[] =
+ { 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 n[] =
+ { 0xec, 0x51, 0xab, 0xa1, 0xf8, 0x40, 0x2c, 0x08,
+ 0x2e, 0x24, 0x52, 0x2e, 0x3c, 0x51, 0x6d, 0x98,
+ 0xad, 0xee, 0xc7, 0x7d, 0x00, 0xaf, 0xe1, 0xa8,
+ 0x61, 0xda, 0x32, 0x97, 0xb4, 0x32, 0x97, 0xe3,
+ 0x52, 0xda, 0x28, 0x45, 0x55, 0xc6, 0xb2, 0x46,
+ 0x65, 0x1b, 0x02, 0xcb, 0xbe, 0xf4, 0x2c, 0x6b,
+ 0x2a, 0x5f, 0xe1, 0xdf, 0xe9, 0xe3, 0xbc, 0x47,
+ 0xb7, 0x38, 0xb5, 0xa2, 0x78, 0x9d, 0x15, 0xe2,
+ 0x59, 0x81, 0x77, 0x6b, 0x6b, 0x2e, 0xa9, 0xdb,
+ 0x13, 0x26, 0x9c, 0xca, 0x5e, 0x0a, 0x1f, 0x3c,
+ 0x50, 0x9d, 0xd6, 0x79, 0x59, 0x99, 0x50, 0xe5,
+ 0x68, 0x1a, 0x98, 0xca, 0x11, 0xce, 0x37, 0x63,
+ 0x58, 0x22, 0x40, 0x19, 0x29, 0x72, 0x4c, 0x41,
+ 0x89, 0x0b, 0x56, 0x9e, 0x3e, 0xd5, 0x6d, 0x75,
+ 0x9e, 0x3f, 0x8a, 0x50, 0xf1, 0x0a, 0x59, 0x4a,
+ 0xc3, 0x59, 0x4b, 0xf6, 0xbb, 0xc9, 0xa5, 0x93 };
+
+unsigned char input_data[] =
+ { 0x00, 0x02, 0x08, 0x68, 0x30, 0x9a, 0x32, 0x08,
+ 0x57, 0xb0, 0x28, 0xaa, 0x76, 0x30, 0x3d, 0x84,
+ 0x5f, 0x92, 0x0d, 0x8e, 0x34, 0xe0, 0xd5, 0xcc,
+ 0x36, 0x97, 0xed, 0x00, 0x00, 0x01, 0x02, 0x03,
+ 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
+ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
+ 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
+ 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
+ 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
+ 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43,
+ 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b,
+ 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53,
+ 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b,
+ 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63 };
+
+unsigned char p[] =
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xfb, 0xb7, 0x73, 0x24, 0x42, 0xfe, 0x8f, 0x16,
+ 0xf0, 0x6e, 0x2d, 0x86, 0x22, 0x46, 0x79, 0xd1,
+ 0x58, 0x6f, 0x26, 0x24, 0x17, 0x12, 0xa3, 0x1a,
+ 0xfd, 0xf7, 0x75, 0xd4, 0xcd, 0xf9, 0xde, 0x4b,
+ 0x8c, 0xb7, 0x04, 0x5d, 0xd9, 0x18, 0xc8, 0x26,
+ 0x61, 0x54, 0xe0, 0x92, 0x2f, 0x47, 0xf7, 0x33,
+ 0xc2, 0x17, 0xd8, 0xda, 0xe0, 0x6d, 0xb6, 0x30,
+ 0xd6, 0xdc, 0xf9, 0x6a, 0x4c, 0xa1, 0xa2, 0x4b };
+
+unsigned char q[] =
+ { 0xf0, 0x57, 0x24, 0xf6, 0x2a, 0x5a, 0x6d, 0x8e,
+ 0xb8, 0xc6, 0x6f, 0xd2, 0xbb, 0x36, 0x4f, 0x6d,
+ 0xd8, 0xbc, 0xa7, 0x2f, 0xbd, 0x43, 0xdc, 0x9a,
+ 0x0e, 0x2a, 0x36, 0xb9, 0x21, 0x05, 0xfa, 0x22,
+ 0x6c, 0xe8, 0x22, 0x68, 0x2f, 0x1c, 0xe8, 0x27,
+ 0xc1, 0xed, 0x08, 0x7a, 0x43, 0x70, 0x7b, 0xe3,
+ 0x46, 0x74, 0x02, 0x6e, 0xb2, 0xb1, 0xeb, 0x44,
+ 0x72, 0x86, 0x0d, 0x55, 0x3b, 0xc8, 0xbc, 0xd9 };
+
+unsigned char dp[] =
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xa7, 0xcf, 0xa2, 0x18, 0x2c, 0xa9, 0xb4, 0xb9,
+ 0xf5, 0x9e, 0xc9, 0x04, 0x16, 0xd9, 0xa6, 0x8b,
+ 0x90, 0x4a, 0x19, 0x6d, 0x64, 0xb7, 0x17, 0x67,
+ 0x53, 0xfa, 0x4e, 0x8d, 0xde, 0xa6, 0x94, 0x32,
+ 0x5d, 0xcf, 0x58, 0x3e, 0x90, 0xbb, 0x30, 0x19,
+ 0x96, 0x38, 0x95, 0xb6, 0xca, 0x2f, 0xfa, 0x22,
+ 0x81, 0x65, 0x3b, 0x3c, 0x95, 0x9e, 0x79, 0x75,
+ 0xe4, 0x93, 0x50, 0xf1, 0x88, 0x6b, 0xc1, 0x87 };
+
+unsigned char dq[] =
+ { 0xa0, 0x3a, 0x18, 0xa4, 0x1c, 0x3c, 0x49, 0x09,
+ 0xd0, 0x84, 0x4a, 0x8c, 0x7c, 0xce, 0xdf, 0x9e,
+ 0x90, 0x7d, 0xc4, 0xca, 0x7e, 0x2d, 0x3d, 0xbc,
+ 0x09, 0x71, 0x79, 0xd0, 0xc0, 0xae, 0xa6, 0xc1,
+ 0x9d, 0xf0, 0x16, 0xf0, 0x1f, 0x68, 0x9a, 0xc5,
+ 0x2b, 0xf3, 0x5a, 0xfc, 0x2c, 0xf5, 0xa7, 0xec,
+ 0xd9, 0xa2, 0xac, 0x49, 0xcc, 0x76, 0x9c, 0xd8,
+ 0x4c, 0x59, 0x5e, 0x38, 0xd2, 0x85, 0xd3, 0x3b };
+
+unsigned char qinv[] =
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x83, 0xf1, 0xca, 0x06, 0x58, 0x4a, 0x04, 0x5e,
+ 0x96, 0xb5, 0x30, 0x32, 0x40, 0x36, 0x48, 0xb9,
+ 0x02, 0x0c, 0xe3, 0x37, 0xb7, 0x51, 0xbc, 0x22,
+ 0x26, 0x5d, 0x74, 0x03, 0x47, 0xd3, 0x33, 0x20,
+ 0x8e, 0x75, 0x62, 0xf2, 0x9d, 0x4e, 0xc8, 0x7d,
+ 0x5d, 0x8e, 0xb6, 0xd9, 0x69, 0x4a, 0x9a, 0xe1,
+ 0x36, 0x6e, 0x1c, 0xbe, 0x8a, 0x14, 0xb1, 0x85,
+ 0x39, 0x74, 0x7c, 0x25, 0xd8, 0xa4, 0x4f, 0xde };
+
+ unsigned char *output_data;
+ unsigned char *data = input_data;
+ int rc = 0;
+
+ if((output_data = malloc(RSA_BYTE_LENGHT*sizeof(char))) == NULL){
+ perror("error in malloc: ");
+ exit(EXIT_FAILURE);
+ }
+
+ ica_rsa_key_mod_expo_t mod_expo_key= {RSA_BYTE_LENGHT, n, e};
+ ica_rsa_key_crt_t crt_key = {RSA_BYTE_LENGHT, p, q, dp, dq, qinv};
+
+ system("icastats -r");
+ rc = ica_rsa_mod_expo(handle, data, &mod_expo_key,
+ output_data);
+ if(rc)
+ exit(handle_ica_error(rc, "ica_rsa_key_mod_expo"));
+ check_icastats(RSA_ME, "RSA-ME");
+
+ system("icastats -r");
+ rc = ica_rsa_crt(handle, data, &crt_key,
+ output_data);
+ if(rc)
+ exit(handle_ica_error(rc, "ica_rsa_crt"));
+ check_icastats(RSA_CRT, "RSA-CRT");
+
+ free(output_data);
+}
+
+void aes_tests(unsigned char *iv, unsigned char *cmac, unsigned char *ctr)
+{
+ int rc = 0;
+ int mode;
+ unsigned char *output_buffer, *tag, *nonce;
+ unsigned char *input_buffer = plain_data;
+
+
+
+ unsigned char aes_key[] = {
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
+
+ };
+
+ unsigned char tweak[] = {
+ 0x72, 0xf3, 0xb0, 0x54, 0xcb, 0xdc, 0x2f, 0x9e,
+ 0x3c, 0x5b, 0xc5, 0x51, 0xd4, 0x4d, 0xdb, 0xa0,
+ };
+
+ #define NONCE_LENGHT 10
+
+ if((nonce = malloc(NONCE_LENGHT*sizeof(char))) == NULL){
+ perror("Error in malloc: ");
+ exit(EXIT_FAILURE);
+ }
+
+ if((tag = malloc(AES_CIPHER_BLOCK*sizeof(char))) == NULL){
+ perror("Error in malloc: ");
+ exit(EXIT_FAILURE);
+ }
+
+ if((output_buffer = malloc((DATA_LENGHT+AES_CIPHER_BLOCK)
+ *sizeof(char))) == NULL){
+ perror("Error in malloc: ");
+ exit(EXIT_FAILURE);
+ }
+
+ system("icastats -r");
+ for(mode = 1;mode >= 0;mode--){
+ rc = ica_aes_cbc(input_buffer, output_buffer, DATA_LENGHT,
+ aes_key, AES_KEY_LEN128, iv, mode);
+ if(rc)
+ exit(handle_ica_error(rc, "ica_aes_cbc"));
+ if(mode == ICA_ENCRYPT)
+ input_buffer = output_buffer;
+ else if(mode == ICA_DECRYPT)
+ input_buffer = plain_data;
+ }
+ check_icastats(AES_CBC, "AES CBC");
+
+ system("icastats -r");
+ for(mode = 1;mode >= 0;mode--){
+ rc = ica_aes_cfb(input_buffer, output_buffer, DATA_LENGHT,
+ aes_key, AES_KEY_LEN128, iv, AES_CIPHER_BLOCK,
+ mode);
+ if(rc)
+ exit(handle_ica_error(rc, "ica_aes_cfb"));
+
+ if(mode == ICA_ENCRYPT)
+ input_buffer = output_buffer;
+ else if(mode == ICA_DECRYPT)
+ input_buffer = plain_data;
+ }
+ check_icastats(AES_CFB, "AES CFB");
+
+ system("icastats -r");
+ for(mode = 1;mode >= 0;mode--){
+ rc = ica_aes_cmac(input_buffer, DATA_LENGHT, cmac,
+ AES_CIPHER_BLOCK, aes_key,
+ AES_KEY_LEN128, mode);
+ if(rc)
+ exit(handle_ica_error(rc, "ica_aes_cmac"));
+ }
+ check_icastats(AES_CMAC, "AES CMAC");
+
+ system("icastats -r");
+ for(mode = 1;mode >= 0;mode--){
+ rc = ica_aes_ctr(input_buffer, output_buffer, DATA_LENGHT,
+ aes_key, AES_KEY_LEN128, ctr, AES_CIPHER_BLOCK,
+ mode);
+ if(rc)
+ exit(handle_ica_error(rc, "ica_aes_ctr"));
+
+ if(mode == ICA_ENCRYPT)
+ input_buffer = output_buffer;
+ else if(mode == ICA_DECRYPT)
+ input_buffer = plain_data;
+ }
+ check_icastats(AES_CTR, "AES CTR");
+
+ system("icastats -r");
+ for(mode = 1;mode >= 0;mode--){
+ rc = ica_aes_ecb(input_buffer, output_buffer, DATA_LENGHT,
+ aes_key, AES_KEY_LEN128, mode);
+ if (rc)
+ exit(handle_ica_error(rc, "ica_aes_ecb"));
+
+ if(mode == ICA_ENCRYPT)
+ input_buffer = output_buffer;
+ else if(mode == ICA_DECRYPT)
+ input_buffer = plain_data;
+ }
+ check_icastats(AES_ECB, "AES ECB");
+
+ system("icastats -r");
+ for(mode = 1;mode >= 0;mode--){
+ rc = ica_aes_ofb(input_buffer, output_buffer, DATA_LENGHT,
+ aes_key, AES_KEY_LEN128, iv, mode);
+
+ if(rc)
+ exit(handle_ica_error(rc, "ica_aes_ofb"));
+
+ if(mode == ICA_ENCRYPT)
+ input_buffer = output_buffer;
+ else if(mode == ICA_DECRYPT)
+ input_buffer = plain_data;
+ }
+ check_icastats(AES_OFB, "AES OFB");
+
+ system("icastats -r");
+ for(mode = 1;mode >= 0;mode--){
+ rc = ica_aes_xts(input_buffer, output_buffer, DATA_LENGHT,
+ aes_key, aes_key, AES_KEY_LEN128, tweak, mode);
+
+ if(rc)
+ exit(handle_ica_error(rc, "ica_aes_xts"));
+
+ if(mode == ICA_ENCRYPT)
+ input_buffer = output_buffer;
+ else if(mode == ICA_DECRYPT)
+ input_buffer = plain_data;
+ }
+ check_icastats(AES_XTS, "AES XTS");
+
+ free(tag);
+ free(output_buffer);
+ free(nonce);
+}
+
diff --git a/src/tests/libica_3des_cbc_test.c b/src/tests/libica_3des_cbc_test.c
new file mode 100644
index 0000000..3906fe3
--- /dev/null
+++ b/src/tests/libica_3des_cbc_test.c
@@ -0,0 +1,159 @@
+/* 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"
+#include "testcase.h"
+
+#define NR_RANDOM_TESTS 10000
+
+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)
+{
+ VV_(printf("IV \n"));
+ dump_array(iv, iv_length);
+ VV_(printf("Key \n"));
+ dump_array(key, key_length);
+ VV_(printf("Input Data\n"));
+ dump_array(input_data, data_length);
+ VV_(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) {
+ VV_(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) {
+ VV_(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) {
+ VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n",
+ rc, errno));
+ return rc;
+ }
+ return rc;
+}
+
+int random_3des_cbc(int iteration, unsigned int data_length)
+{
+ unsigned int iv_length = sizeof(ica_des_vector_t);
+ unsigned int key_length = sizeof(ica_des_key_triple_t);
+
+ unsigned char iv[iv_length];
+ unsigned char tmp_iv[iv_length];
+ unsigned char key[key_length];
+ unsigned char input_data[data_length];
+ 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);
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(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) {
+ VV_(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 (!rc) {
+ VV_(printf("Encrypt:\n"));
+ dump_cbc_data(iv, iv_length, key, key_length, input_data,
+ data_length, encrypt);
+ }
+
+ if (rc) {
+ VV_(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) {
+ VV_(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 (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_cbc_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Decryption Result:\n"));
+ dump_array(decrypt, data_length);
+ rc++;
+ }
+ return rc;
+}
+
+/*
+ * Performs ECB,CBC and CFQ tests.
+ */
+int main(int argc, char **argv)
+{
+ int rc = 0;
+ int error_count = 0;
+ int iteration;
+ unsigned int data_length = sizeof(ica_des_vector_t);
+
+ set_verbosity(argc, argv);
+
+ for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) {
+ rc = random_3des_cbc(iteration, data_length);
+ if (rc) {
+ V_(printf("random_3des_cbc failed with rc = %i\n", rc));
+ error_count++;
+ goto out;
+ }
+ data_length += sizeof(ica_des_vector_t);
+ }
+out:
+ if (error_count)
+ printf("%i 3DES-CBC tests failed.\n", error_count);
+ else
+ printf("All 3DES-CBC tests passed.\n");
+
+ return rc;
+}
+
diff --git a/src/tests/libica_3des_cfb_test.c b/src/tests/libica_3des_cfb_test.c
new file mode 100644
index 0000000..7f1996d
--- /dev/null
+++ b/src/tests/libica_3des_cfb_test.c
@@ -0,0 +1,178 @@
+/* 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"
+#include "testcase.h"
+
+#define NR_TESTS 12
+#define NR_RANDOM_TESTS 1000
+
+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)
+{
+ VV_(printf("IV \n"));
+ dump_array(iv, iv_length);
+ VV_(printf("Key \n"));
+ dump_array(key, key_length);
+ VV_(printf("Input Data\n"));
+ dump_array(input_data, data_length);
+ VV_(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) {
+ VV_(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) {
+ VV_(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) {
+ VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n",
+ rc, errno));
+ return rc;
+ }
+ return rc;
+}
+
+int random_des_cfb(int iteration, unsigned int data_length, unsigned int lcfb)
+{
+ unsigned int iv_length = sizeof(ica_des_vector_t);
+ unsigned int key_length = sizeof(ica_des_key_triple_t);
+
+ unsigned char iv[iv_length];
+ unsigned char tmp_iv[iv_length];
+ unsigned char key[key_length];
+ unsigned char input_data[data_length];
+ 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);
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(printf("key length = %i, data length = %i, iv length = %i,"
+ " lcfb = %i\n", key_length, data_length, iv_length, lcfb));
+
+ rc = ica_3des_cfb(input_data, encrypt, data_length, key, tmp_iv, lcfb,
+ 1);
+ if (rc) {
+ VV_(printf("ica_3des_cfb encrypt failed with rc = %i\n", rc));
+ dump_cfb_data(iv, iv_length, key, key_length, input_data,
+ data_length, encrypt);
+ }
+ if (!rc) {
+ VV_(printf("Encrypt:\n"));
+ dump_cfb_data(iv, iv_length, key, key_length, input_data,
+ data_length, encrypt);
+ }
+
+ if (rc) {
+ VV_(printf("3DES OFB test exited after encryption\n"));
+ return rc;
+ }
+
+ memcpy(tmp_iv, iv, iv_length);
+
+ rc = ica_3des_cfb(encrypt, decrypt, data_length, key, tmp_iv,
+ lcfb, 0);
+ if (rc) {
+ VV_(printf("ica_3des_cfb decrypt failed with rc = %i\n", rc));
+ dump_cfb_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ return rc;
+ }
+
+
+ if (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_cfb_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Decryption Result:\n"));
+ dump_array(decrypt, data_length);
+ rc++;
+ }
+ return rc;
+}
+
+int main(int argc, char **argv)
+{
+ int rc = 0;
+ int error_count = 0;
+ int iteration;
+ unsigned int rdata;
+ unsigned int data_length = 1;
+ unsigned int lcfb = 1;
+ unsigned int j;
+
+ set_verbosity(argc, argv);
+
+ for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) {
+ for (j = 1; j <= 2; j++) {
+ if (!(data_length % lcfb)) {
+ rc = random_des_cfb(iteration, data_length, lcfb);
+ if (rc) {
+ V_(printf("random_des_cfb failed with rc = %i\n", rc));
+ error_count++;
+ }
+ }
+ switch (j) {
+ case 1:
+ lcfb = 1;
+ break;
+ case 2:
+ lcfb = 8;
+ break;
+ }
+ }
+ // add a value between 1 and 8 to data_length
+ if (ica_random_number_generate(sizeof(rdata), (unsigned char*) &rdata)) {
+ printf("ica_random_number_generate failed with errnor = %i\n",
+ errno);
+ exit(1);
+ }
+ data_length += (rdata % 8) + 1;
+ }
+ if (error_count)
+ printf("%i 3DES-CFB tests failed.\n", error_count);
+ else
+ printf("All 3DES-CFB tests passed.\n");
+
+ return rc;
+}
+
diff --git a/src/tests/libica_3des_ctr_test.c b/src/tests/libica_3des_ctr_test.c
new file mode 100644
index 0000000..1d9e376
--- /dev/null
+++ b/src/tests/libica_3des_ctr_test.c
@@ -0,0 +1,163 @@
+/* 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"
+#include "testcase.h"
+
+#define NR_RANDOM_TESTS 1000
+
+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)
+{
+ VV_(printf("IV \n"));
+ dump_array(iv, iv_length);
+ VV_(printf("Key \n"));
+ dump_array(key, key_length);
+ VV_(printf("Input Data\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Output Data\n"));
+ dump_array(output_data, data_length);
+}
+
+int random_3des_ctr(int iteration, unsigned int data_length)
+{
+ unsigned int key_length = sizeof(ica_des_key_triple_t);
+ unsigned int iv_length = sizeof(ica_des_vector_t);
+
+ unsigned char iv[iv_length];
+ unsigned char tmp_iv[iv_length];
+ unsigned char key[key_length];
+ unsigned char input_data[data_length];
+ unsigned char encrypt[data_length];
+ unsigned char decrypt[data_length];
+
+ int rc = 0;
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(printf("key length = %i, data length = %i, iv length = %i\n",
+ key_length, data_length, iv_length));
+
+ rc = ica_random_number_generate(data_length, input_data);
+ if (rc) {
+ VV_(printf("random number generate returned rc = %i, errno = %i\n", rc, errno));
+ return rc;
+ }
+ rc = ica_random_number_generate(iv_length, iv);
+ if (rc) {
+ VV_(printf("random number generate returned rc = %i, errno = %i\n", rc, errno));
+ return rc;
+ }
+
+ rc = ica_random_number_generate(key_length, key);
+ if (rc) {
+ VV_(printf("random number generate returned rc = %i, errno = %i\n", rc, errno));
+ return rc;
+ }
+ memcpy(tmp_iv, iv, iv_length);
+
+ rc = ica_3des_ctr(input_data, encrypt, data_length, key, tmp_iv,
+ 32, 1);
+ if (rc) {
+ VV_(printf("ica_3des_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 (!rc) {
+ VV_(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_3des_ctr(encrypt, decrypt, data_length, key, tmp_iv,
+ 32, 0);
+ if (rc) {
+ VV_(printf("ica_3des_ctr decrypt failed with rc = %i\n", rc));
+ dump_ctr_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ return rc;
+ }
+
+
+ if (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_ctr_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Decryption Result:\n"));
+ dump_array(decrypt, data_length);
+ rc++;
+ }
+ return rc;
+}
+
+int main(int argc, char **argv)
+{
+ unsigned int endless = 0;
+ unsigned int data_length = 1;
+ unsigned int rdata;
+ int error_count = 0;
+ int i = 0;
+ int rc = 0;
+
+ set_verbosity(argc, argv);
+ if (argc > 1) {
+ if (strstr(argv[1], "endless"))
+ endless = 1;
+ }
+
+ if (endless) {
+ while (1) {
+ VV_(printf("i = %i\n", i));
+ rc = random_3des_ctr(i, 320);
+ if (rc) {
+ VV_(printf("kat_3des_ctr failed with rc = %i\n",
+ rc));
+ return rc;
+ } else
+ VV_(printf("kat_3des_ctr finished.n"));
+ i++;
+ }
+ } else {
+ for (i = 1; i < NR_RANDOM_TESTS; i++) {
+ rc = random_3des_ctr(i, data_length);
+ if (rc) {
+ VV_(printf("random_3des_ctr failed with rc = %i\n", rc));
+ error_count++;
+ }
+ // add a value between 1 and 8 to data_length
+ if (ica_random_number_generate(sizeof(rdata), (unsigned char*) &rdata)) {
+ printf("ica_random_number_generate failed with errnor = %i\n",
+ errno);
+ exit(1);
+ }
+ data_length += (rdata % 8) + 1;
+ }
+ }
+
+ if (error_count)
+ printf("%i 3DES-CTR tests failed.\n", error_count);
+ else
+ printf("All 3DES-CTR tests passed.\n");
+
+ return rc;
+}
+
diff --git a/src/tests/libica_3des_ecb_test.c b/src/tests/libica_3des_ecb_test.c
new file mode 100644
index 0000000..d907538
--- /dev/null
+++ b/src/tests/libica_3des_ecb_test.c
@@ -0,0 +1,295 @@
+/* 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"
+#include "testcase.h"
+
+#define NR_TESTS 2
+#define NR_RANDOM_TESTS 10000
+
+/* ECB data - 1 for 3DES192 */
+unsigned char NIST_KEY_ECB_E1[] = {
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+ 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
+ 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23,
+};
+
+unsigned char NIST_TEST_DATA_ECB_E1[] = {
+ 0x6B, 0x20, 0x62, 0x72, 0x6F, 0x77, 0x6E, 0x20,
+};
+
+unsigned char NIST_TEST_RESULT_ECB_E1[] = {
+ 0xCC, 0xE2, 0x1C, 0x81, 0x12, 0x25, 0x6F, 0xE6,
+};
+
+/* ECB data - 2 - for 3DES128 */
+unsigned char NIST_KEY_ECB_E2[] = {
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+ 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
+ 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23,
+
+};
+
+unsigned char NIST_TEST_DATA_ECB_E2[] = {
+ 0x54, 0x68, 0x65, 0x20, 0x71, 0x75, 0x66, 0x63,
+ 0x6B, 0x20, 0x62, 0x72, 0x6F, 0x77, 0x6E, 0x20,
+ 0x66, 0x6F, 0x78, 0x20, 0x6A, 0x75, 0x6D, 0x70,
+};
+
+unsigned char NIST_TEST_RESULT_ECB_E2[] = {
+ 0xA8, 0x26, 0xFD, 0x8C, 0xE5, 0x3B, 0x85, 0x5F,
+ 0xCC, 0xE2, 0x1C, 0x81, 0x12, 0x25, 0x6F, 0xE6,
+ 0x68, 0xD5, 0xC0, 0x5D, 0xD9, 0xB6, 0xB9, 0x00,
+};
+
+void dump_ecb_data(unsigned char *key, unsigned int key_length,
+ unsigned char *input_data, unsigned int data_length,
+ unsigned char *output_data)
+{
+ VV_(printf("Key \n"));
+ dump_array(key, key_length);
+ VV_(printf("Input Data\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Output Data\n"));
+ dump_array(output_data, data_length);
+}
+
+void get_sizes(unsigned int *data_length,
+ unsigned int *key_length, unsigned int iteration)
+{
+ switch (iteration) {
+ case 1:
+ *data_length = sizeof(NIST_TEST_DATA_ECB_E1);
+ *key_length = sizeof(NIST_KEY_ECB_E1);
+ break;
+ case 2:
+ *data_length = sizeof(NIST_TEST_DATA_ECB_E2);
+ *key_length = sizeof(NIST_KEY_ECB_E2);
+ break;
+ }
+
+}
+
+void load_test_data(unsigned char *data, unsigned int data_length,
+ unsigned char *result,
+ unsigned char *key, unsigned int key_length,
+ unsigned int iteration)
+{
+ switch (iteration) {
+ case 1:
+ memcpy(data, NIST_TEST_DATA_ECB_E1, data_length);
+ memcpy(result, NIST_TEST_RESULT_ECB_E1, data_length);
+ memcpy(key, NIST_KEY_ECB_E1, key_length);
+ break;
+ case 2:
+ memcpy(data, NIST_TEST_DATA_ECB_E2, data_length);
+ memcpy(result, NIST_TEST_RESULT_ECB_E2, data_length);
+ memcpy(key, NIST_KEY_ECB_E2, key_length);
+ break;
+ }
+
+}
+
+int kat_3des_ecb(int iteration)
+{
+ unsigned int data_length;
+ unsigned int key_length;
+
+ get_sizes(&data_length, &key_length, iteration);
+
+ unsigned char key[key_length];
+ unsigned char input_data[data_length];
+ unsigned char encrypt[data_length];
+ unsigned char decrypt[data_length];
+ unsigned char result[data_length];
+
+ int rc = 0;
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(printf("key length = %i, data length = %i", key_length, data_length));
+
+ load_test_data(input_data, data_length, result, key, key_length,
+ iteration);
+
+ rc = ica_3des_ecb(input_data, encrypt, data_length, key, 1);
+ if (rc) {
+ VV_(printf("ica_3des_ecb encrypt failed with rc = %i\n", rc));
+ dump_ecb_data(key, key_length, input_data,
+ data_length, encrypt);
+ }
+ if (!rc) {
+ VV_(printf("Encrypt:\n"));
+ dump_ecb_data(key, key_length, input_data,
+ data_length, encrypt);
+ }
+
+ if (memcmp(result, encrypt, data_length)) {
+ VV_(printf("Encryption Result does not match the known ciphertext!\n"));
+ VV_(printf("Expected data:\n"));
+ dump_array(result, data_length);
+ VV_(printf("Encryption Result:\n"));
+ dump_array(encrypt, data_length);
+ rc++;
+ }
+
+ if (rc) {
+ VV_(printf("3DES ECB test exited after encryption\n"));
+ return rc;
+ }
+
+ rc = ica_3des_ecb(encrypt, decrypt, data_length, key, 0);
+ if (rc) {
+ VV_(printf("ica_3des_ecb decrypt failed with rc = %i\n", rc));
+ dump_ecb_data(key, key_length, encrypt,
+ data_length, decrypt);
+ return rc;
+ }
+
+
+ if (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_ecb_data(key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(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 *key, unsigned int key_length)
+{
+ int rc;
+
+ rc = ica_random_number_generate(data_length, data);
+ if (rc) {
+ VV_(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) {
+ VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n",
+ rc, errno));
+ return rc;
+ }
+ return rc;
+}
+
+int random_3des_ecb(int iteration, unsigned int data_length)
+{
+ int rc = 0;
+ unsigned int key_length = sizeof(ica_des_key_triple_t);
+ unsigned char input_data[data_length];
+ unsigned char encrypt[data_length];
+ unsigned char decrypt[data_length];
+ unsigned char key[key_length];
+
+ memset(encrypt, 0x00, data_length);
+ memset(decrypt, 0x00, data_length);
+
+ load_random_test_data(input_data, data_length, key, key_length);
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(printf("key length = %i, data length = %i\n", key_length, data_length));
+
+ rc = ica_3des_ecb(input_data, encrypt, data_length, key, 1);
+ if (rc) {
+ VV_(printf("ica_3des_ecb encrypt failed with rc = %i\n", rc));
+ dump_ecb_data(key, key_length, input_data, data_length,
+ encrypt);
+ }
+ if (!rc) {
+ VV_(printf("Encrypt:\n"));
+ dump_ecb_data(key, key_length, input_data,
+ data_length, encrypt);
+ }
+
+ if (rc) {
+ VV_(printf("3DES ECB test exited after encryption\n"));
+ return rc;
+ }
+
+ rc = ica_3des_ecb(encrypt, decrypt, data_length, key, 0);
+ if (rc) {
+ VV_(printf("ica_3des_ecb decrypt failed with rc = %i\n", rc));
+ dump_ecb_data(key, key_length, encrypt,
+ data_length, decrypt);
+ return rc;
+ }
+
+
+ if (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_ecb_data(key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Decryption Result:\n"));
+ dump_array(decrypt, data_length);
+ rc++;
+ return rc;
+ }
+
+ return rc;
+}
+
+/*
+ * Performs ECB and CFQ tests.
+ */
+int main(int argc, char **argv)
+{
+ int rc = 0;
+ int error_count = 0;
+ int iteration;
+ unsigned int data_length = sizeof(ica_des_vector_t);
+
+ set_verbosity(argc, argv);
+
+ for(iteration = 1; iteration <= NR_TESTS; iteration++) {
+ rc = kat_3des_ecb(iteration);
+ if (rc) {
+ V_(printf("kat_3des_ecb failed with rc = %i\n", rc));
+ error_count++;
+ }
+ }
+
+ for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) {
+ rc = random_3des_ecb(iteration, data_length);
+ if (rc) {
+ V_(printf("random_3des_ecb failed with rc = %i\n", rc));
+ error_count++;
+ goto out;
+ }
+ data_length += sizeof(ica_des_vector_t);
+ }
+
+out:
+ if (error_count)
+ printf("%i 3DES-ECB tests failed.\n", error_count);
+ else
+ printf("All 3DES-ECB tests passed.\n");
+
+ return rc;
+}
+
diff --git a/src/tests/libica_3des_ofb_test.c b/src/tests/libica_3des_ofb_test.c
new file mode 100644
index 0000000..7540310
--- /dev/null
+++ b/src/tests/libica_3des_ofb_test.c
@@ -0,0 +1,164 @@
+/* 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"
+#include "testcase.h"
+
+#define NR_RANDOM_TESTS 10000
+
+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)
+{
+ VV_(printf("IV \n"));
+ dump_array(iv, iv_length);
+ VV_(printf("Key \n"));
+ dump_array(key, key_length);
+ VV_(printf("Input Data\n"));
+ dump_array(input_data, data_length);
+ VV_(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) {
+ VV_(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) {
+ VV_(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) {
+ VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n",
+ rc, errno));
+ return rc;
+ }
+ return rc;
+}
+
+int random_3des_ofb(int iteration, unsigned int data_length)
+{
+ unsigned int iv_length = sizeof(ica_des_vector_t);
+ unsigned int key_length = sizeof(ica_des_key_triple_t);
+
+ unsigned char iv[iv_length];
+ unsigned char tmp_iv[iv_length];
+ unsigned char key[key_length];
+ unsigned char input_data[data_length];
+ 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);
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(printf("key length = %i, data length = %i, iv length = %i\n",
+ key_length, data_length, iv_length));
+
+ rc = ica_3des_ofb(input_data, encrypt, data_length, key, tmp_iv, 1);
+ if (rc) {
+ VV_(printf("ica_3des_ofb encrypt failed with rc = %i\n", rc));
+ dump_ofb_data(iv, iv_length, key, key_length, input_data,
+ data_length, encrypt);
+ }
+ if (!rc) {
+ VV_(printf("Encrypt:\n"));
+ dump_ofb_data(iv, iv_length, key, key_length, input_data,
+ data_length, encrypt);
+ }
+
+ if (rc) {
+ VV_(printf("3DES OFB test exited after encryption\n"));
+ return rc;
+ }
+
+ memcpy(tmp_iv, iv, iv_length);
+
+ rc = ica_3des_ofb(encrypt, decrypt, data_length, key, tmp_iv, 0);
+ if (rc) {
+ VV_(printf("ica_3des_ofb decrypt failed with rc = %i\n", rc));
+ dump_ofb_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ return rc;
+ }
+
+
+ if (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_ofb_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Decryption Result:\n"));
+ dump_array(decrypt, data_length);
+ rc++;
+ }
+ return rc;
+}
+
+int main(int argc, char **argv)
+{
+ int rc = 0;
+ int error_count = 0;
+ int iteration;
+ unsigned int rdata;
+ unsigned int data_length = 1;
+
+ set_verbosity(argc, argv);
+
+ for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) {
+ rc = random_3des_ofb(iteration, data_length);
+ if (rc) {
+ V_(printf("random_3des_ofb failed with rc = %i\n", rc));
+ error_count++;
+ goto out;
+ }
+ // add a value between 1 and 8 to data_length
+ if (ica_random_number_generate(sizeof(rdata), (unsigned char*) &rdata)) {
+ V_(printf("ica_random_number_generate failed with errnor = %i\n",
+ errno));
+ exit(1);
+ }
+ data_length += (rdata % 8) + 1;
+ }
+out:
+ if (error_count)
+ printf("%i 3DES-OFB tests failed.\n", error_count);
+ else
+ printf("All 3DES-OFB tests passed.\n");
+
+ return rc;
+}
+
diff --git a/src/tests/libica_3des_test.c b/src/tests/libica_3des_test.c
new file mode 100644
index 0000000..89dc3a5
--- /dev/null
+++ b/src/tests/libica_3des_test.c
@@ -0,0 +1,138 @@
+/* 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 <fcntl.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include "ica_api.h"
+#include "testcase.h"
+
+unsigned char NIST_KEY1[] =
+ { 0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57 };
+
+unsigned char NIST_KEY2[] =
+ { 0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57 };
+
+unsigned char NIST_KEY3[] =
+ { 0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57 };
+
+unsigned char NIST_TEST_DATA[] =
+ { 0x01, 0xa1, 0xd6, 0xd0, 0x39, 0x77, 0x67, 0x42 };
+
+unsigned char NIST_TEST_RESULT[] =
+ { 0x69, 0x0f, 0x5b, 0x0d, 0x9a, 0x26, 0x93, 0x9b };
+
+int test_3des_new_api(int mode)
+{
+ ica_des_vector_t iv;
+ ica_des_key_triple_t key;
+ int rc = 0;
+ unsigned char dec_text[sizeof(NIST_TEST_DATA)],
+ enc_text[sizeof(NIST_TEST_DATA)];
+
+ bzero(dec_text, sizeof(dec_text));
+ bzero(enc_text, sizeof(enc_text));
+ bzero(iv, sizeof(iv));
+ bcopy(NIST_KEY1, key.key1, sizeof(NIST_KEY1));
+ bcopy(NIST_KEY2, key.key2, sizeof(NIST_KEY2));
+ bcopy(NIST_KEY3, key.key3, sizeof(NIST_KEY3));
+
+ VV_(printf("\nOriginal data:\n"));
+ dump_array(NIST_TEST_DATA, sizeof(NIST_TEST_DATA));
+
+ rc = ica_3des_encrypt(mode, sizeof(NIST_TEST_DATA), NIST_TEST_DATA,
+ &iv, &key, enc_text);
+ if (rc != 0) {
+ VV_(printf("ica_3des_encrypt failed with errno %d (0x%x).\n", rc, rc));
+ return rc;
+ }
+
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array(enc_text, sizeof(enc_text));
+ if (memcmp(enc_text, NIST_TEST_RESULT, sizeof NIST_TEST_RESULT) != 0) {
+ VV_(printf("This does NOT match the known result.\n"));
+ return -1;
+ } else {
+ VV_(printf("Yep, it's what it should be.\n"));
+ }
+
+ bzero(iv, sizeof(iv));
+ rc = ica_3des_decrypt(mode, sizeof(enc_text), enc_text,
+ &iv, &key, dec_text);
+ if (rc != 0) {
+ VV_(printf("ica_3des_decrypt failed with errno %d (0x%x).\n", rc, rc));
+ return rc;
+ }
+
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array(dec_text, sizeof(dec_text));
+ if (memcmp(dec_text, NIST_TEST_DATA, sizeof(NIST_TEST_DATA)) != 0) {
+ VV_(printf("This does NOT match the original data.\n"));
+ return -1;
+ } else {
+ VV_(printf("Successful!\n"));
+ }
+
+ return 0;
+}
+
+/*
+ * Performs ECB and CBC tests.
+ */
+int main(int argc, char **argv)
+{
+ unsigned int mode = 0;
+ int rc = 0;
+ int error_count = 0;
+
+ if (argc > 1) {
+ if (strstr(argv[1], "ecb"))
+ mode = MODE_ECB;
+ if (strstr(argv[1], "cbc"))
+ mode = MODE_CBC;
+ V_(printf("mode = %i \n", mode));
+ }
+ if (mode != 0 && mode != MODE_ECB && mode != MODE_CBC) {
+ printf("Usage: %s [ ecb | cbc ]\n", argv[0]);
+ return -1;
+ }
+
+ set_verbosity(argc, argv);
+
+ if (!mode) {
+ /* This is the standard loop that will perform all testcases */
+ mode = 2;
+ while (mode) {
+ rc = test_3des_new_api(mode);
+ if (rc) {
+ error_count++;
+ V_(printf ("test_des_new_api mode = %i failed \n", mode));
+ }
+ else {
+ V_(printf ("test_des_new_api mode = %i finished.\n", mode));
+ }
+
+ mode--;
+ }
+ if (error_count)
+ printf("%i tests failed.\n", error_count);
+ else
+ printf("All tests passed.\n");
+ } else {
+ /* Perform only either in ECB or CBC mode */
+ rc = test_3des_new_api(mode);
+ if (rc)
+ printf ("test_des_new_api mode = %i failed \n", mode);
+ else
+ printf ("test_des_new_api mode = %i finished.\n", mode);
+ }
+
+ return rc;
+}
+
diff --git a/src/tests/libica_aes128_test.c b/src/tests/libica_aes128_test.c
new file mode 100644
index 0000000..bbd598e
--- /dev/null
+++ b/src/tests/libica_aes128_test.c
@@ -0,0 +1,271 @@
+/* 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 */
+#include <fcntl.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include "ica_api.h"
+#include <stdlib.h>
+#include <openssl/aes.h>
+#include "testcase.h"
+
+unsigned char NIST_KEY1[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+};
+
+unsigned char NIST_TEST_DATA[] = {
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+};
+
+unsigned char NIST_TEST_RESULT[] = {
+ 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
+ 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a,
+};
+
+int test_aes128_new_api(int mode)
+{
+ ica_aes_vector_t iv;
+ unsigned char key[AES_KEY_LEN128];
+ int rc = 0;
+ unsigned char dec_text[sizeof(NIST_TEST_DATA)],
+ enc_text[sizeof(NIST_TEST_DATA)];
+
+ bzero(dec_text, sizeof(dec_text));
+ bzero(enc_text, sizeof(enc_text));
+ bzero(iv, sizeof(iv));
+ bcopy(NIST_KEY1, key, sizeof(NIST_KEY1));
+
+ rc = ica_aes_encrypt(mode, sizeof(NIST_TEST_DATA), NIST_TEST_DATA, &iv,
+ AES_KEY_LEN128, key, enc_text);
+ if (rc) {
+ VV_(printf("key \n"));
+ dump_array((unsigned char *) key, sizeof(NIST_KEY1));
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char *) NIST_TEST_DATA, sizeof(NIST_TEST_DATA));
+ VV_(printf("test iv\n"));
+ dump_array((unsigned char *) &iv, sizeof(ica_aes_vector_t));
+ VV_(printf("key\n"));
+ dump_array((unsigned char *) key, AES_KEY_LEN128);
+ VV_(printf("ica_aes_encrypt failed with errno %d (0x%x).\n", rc, rc));
+ return 1;
+ }
+
+ if (memcmp(enc_text, NIST_TEST_RESULT, sizeof(NIST_TEST_RESULT)) != 0) {
+ VV_(printf("key \n"));
+ dump_array((unsigned char *) key, sizeof(NIST_KEY1));
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char *) NIST_TEST_DATA, sizeof(NIST_TEST_DATA));
+ VV_(printf("test iv\n"));
+ dump_array((unsigned char *) &iv, sizeof(ica_aes_vector_t));
+ VV_(printf("key\n"));
+ dump_array((unsigned char *) key, AES_KEY_LEN128);
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char *) enc_text, sizeof(enc_text));
+ VV_(printf("This does NOT match the known result.\n"));
+ return 1;
+ } else {
+ VV_(printf("Yep, it's what it should be.\n"));
+ }
+
+ bzero(iv, sizeof(iv));
+ rc = ica_aes_decrypt(mode, sizeof(enc_text), enc_text, &iv,
+ AES_KEY_LEN128, key, dec_text);
+ if (rc) {
+ VV_(printf("key \n"));
+ dump_array((unsigned char *) key, sizeof(NIST_KEY1));
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char *) NIST_TEST_DATA, sizeof(NIST_TEST_DATA));
+ VV_(printf("test iv\n"));
+ dump_array((unsigned char *) &iv, sizeof(ica_aes_vector_t));
+ VV_(printf("key\n"));
+ dump_array((unsigned char *) key, AES_KEY_LEN128);
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char *) enc_text, sizeof(enc_text));
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array((unsigned char *) dec_text, sizeof(dec_text));
+ VV_(printf("ica_aes_decrypt failed with errno %d (0x%x).\n", rc, rc));
+ return 1;
+ }
+
+ if (memcmp(dec_text, NIST_TEST_DATA, sizeof(NIST_TEST_DATA)) != 0) {
+ VV_(printf("This does NOT match the original data.\n"));
+ return 1;
+ } else {
+ VV_(printf("Successful!\n"));
+ VV_(printf("key \n"));
+ dump_array((unsigned char *) key, sizeof(NIST_KEY1));
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char *) NIST_TEST_DATA, sizeof(NIST_TEST_DATA));
+ VV_(printf("test iv\n"));
+ dump_array((unsigned char *) &iv, sizeof(ica_aes_vector_t));
+ VV_(printf("key\n"));
+ dump_array((unsigned char *) key, AES_KEY_LEN128);
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char *) enc_text, sizeof(enc_text));
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array((unsigned char *) dec_text, sizeof(dec_text));
+ }
+
+// Test 2
+
+ rc = 0;
+ bzero(dec_text, sizeof(dec_text));
+ bzero(enc_text, sizeof(enc_text));
+ bzero(iv, sizeof(iv));
+ bzero(key, sizeof(key));
+
+ unsigned int length = 64;
+ unsigned char *decrypt = malloc(length);
+ unsigned char *encrypt = malloc(length);
+ unsigned char *original = malloc(length);
+ ica_aes_key_len_128_t key2;
+
+ rc = ica_random_number_generate(length, original);
+ if (rc) {
+ VV_(printf("ica_random_number_generate returned rc = %i\n", rc));
+ return rc;
+ }
+
+ rc = ica_random_number_generate(AES_KEY_LEN128, (unsigned char *) &key2);
+ if (rc) {
+ VV_(printf("ica_random_number_generate returned rc = %i\n", rc));
+ return rc;
+ }
+
+ rc = ica_aes_encrypt(mode, length, original, &iv, AES_KEY_LEN128, (unsigned char *) &key2,
+ (unsigned char *) encrypt);
+ if (rc) {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char *) original, length);
+ VV_(printf("KEY: \n"));
+ dump_array((unsigned char *) &key2, AES_KEY_LEN128);
+ VV_(printf("ica_aes_encrypt failed with errno %d (0x%x).\n", rc, rc));
+ return rc;
+ }
+
+ if (memcmp(encrypt, original, length) == 0) {
+ VV_(printf("Encrypt and original are the same.\n"));
+ return 1;
+ }
+
+ bzero(iv, sizeof(iv));
+ rc = ica_aes_decrypt(mode, length, encrypt, &iv, AES_KEY_LEN128,
+ (unsigned char *) &key2, decrypt);
+ if (rc) {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char *) original, length);
+ VV_(printf("KEY: \n"));
+ dump_array((unsigned char *) &key2, AES_KEY_LEN128);
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char *) encrypt, length);
+ VV_(printf("ica_aes_decrypt failed with errno %d (0x%x).\n", rc, rc));
+ goto free;
+ }
+
+ if (memcmp(decrypt, original, length) != 0) {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char *) original, length);
+ VV_(printf("KEY: \n"));
+ dump_array((unsigned char *) &key2, AES_KEY_LEN128);
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char *) encrypt, length);
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array((unsigned char *) decrypt, length);
+ VV_(printf("This does NOT match the original data.\n"));
+ rc = -1;
+ goto free;
+ }
+
+ if(memcmp(decrypt, encrypt, length) == 0) {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char *) original, length);
+ VV_(printf("KEY: \n"));
+ dump_array((unsigned char *) &key2, AES_KEY_LEN128);
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char *) encrypt, length);
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array((unsigned char *) decrypt, length);
+ VV_(printf("decrypt and encrypt are the same\n"));
+ rc = -1;
+ goto free;
+
+ } else {
+ VV_(printf("Successful!\n"));
+ }
+ free:
+ free(original);
+ free(encrypt);
+ free(decrypt);
+
+ return rc;
+}
+
+/*
+ * Performs ECB and CBC tests.
+ */
+int main(int argc, char **argv)
+{
+ unsigned int mode = 0;
+ int rc = 0;
+ int error_count = 0;
+
+ if (argc > 1) {
+ if (strstr(argv[1], "ecb"))
+ mode = MODE_ECB;
+ if (strstr(argv[1], "cbc"))
+ mode = MODE_CBC;
+ }
+
+ if (argc > 2) {
+ if (strstr(argv[2], "ecb"))
+ mode = MODE_ECB;
+ if (strstr(argv[2], "cbc"))
+ mode = MODE_CBC;
+ }
+
+ set_verbosity(argc, argv);
+
+ if (mode != 0 && mode != MODE_ECB && mode != MODE_CBC) {
+ printf("Usage: %s [ ecb | cbc ]\n", argv[0]);
+ return -1;
+ }
+
+ if (!mode) {
+ /* This is the standard loop that will perform all testcases */
+ mode = 2;
+ while (mode) {
+ rc = test_aes128_new_api(mode);
+ if (rc) {
+ error_count++;
+ V_(printf ("test_aes_new_api mode = %i failed \n", mode));
+ }
+ else {
+ V_(printf ("test_aes_new_api mode = %i finished.\n", mode));
+ }
+ mode--;
+ }
+ if (error_count)
+ printf("%i AES-128-ECB/CBC tests failed.\n", error_count);
+ else
+ printf("All AES-128-ECB/CBC tests passed.\n");
+ } else {
+ /* Perform only either in ECB or CBC mode */
+ rc = test_aes128_new_api(mode);
+ if (rc)
+ printf ("test_aes_new_api mode = %i failed \n", mode);
+ else {
+ printf ("test_aes_new_api mode = %i finished.\n", mode);
+ }
+ }
+ return rc;
+}
+
diff --git a/src/tests/libica_aes192_test.c b/src/tests/libica_aes192_test.c
new file mode 100644
index 0000000..8f95c6c
--- /dev/null
+++ b/src/tests/libica_aes192_test.c
@@ -0,0 +1,153 @@
+/* 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 */
+#include <fcntl.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include "ica_api.h"
+#include "testcase.h"
+
+unsigned char NIST_KEY2[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+};
+
+unsigned char NIST_TEST_DATA[] = {
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+};
+
+unsigned char NIST_TEST_RESULT[] = {
+ 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
+ 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91,
+};
+
+int test_aes192_new_api(int mode)
+{
+ ica_aes_vector_t iv;
+ ica_aes_key_len_192_t key;
+ int rc = 0;
+ unsigned char dec_text[sizeof(NIST_TEST_DATA)],
+ enc_text[sizeof(NIST_TEST_DATA)];
+
+ bzero(dec_text, sizeof(dec_text));
+ bzero(enc_text, sizeof(enc_text));
+ bzero(iv, sizeof(iv));
+ bcopy(NIST_KEY2, key, sizeof(NIST_KEY2));
+
+ rc = ica_aes_encrypt(mode, sizeof(NIST_TEST_DATA), NIST_TEST_DATA, &iv,
+ AES_KEY_LEN192, (unsigned char *) &key, enc_text);
+ if (rc) {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char*)NIST_TEST_DATA, sizeof(NIST_TEST_DATA));
+ VV_(printf("ica_aes_encrypt failed with errno %d (0x%x).\n", rc, rc));
+ return rc;
+ }
+
+ if (memcmp(enc_text, NIST_TEST_RESULT, sizeof(NIST_TEST_RESULT)) != 0) {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char*)NIST_TEST_DATA, sizeof(NIST_TEST_DATA));
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char*)enc_text, sizeof(enc_text));
+ VV_(printf("This does NOT match the known result.\n"));
+ return 1;
+ } else {
+ VV_(printf("Yep, it's what it should be.\n"));
+ }
+
+ bzero(iv, sizeof(iv));
+ rc = ica_aes_decrypt(mode, sizeof(enc_text), enc_text, &iv,
+ AES_KEY_LEN192, (unsigned char *) &key, dec_text);
+ if (rc != 0) {
+ VV_(printf("ica_aes_decrypt failed with errno %d (0x%x).\n", rc, rc));
+ return 1;
+ }
+
+ if (memcmp(dec_text, NIST_TEST_DATA, sizeof(NIST_TEST_DATA)) != 0) {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char*)NIST_TEST_DATA, sizeof(NIST_TEST_DATA));
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char*)enc_text, sizeof(enc_text));
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array((unsigned char*)dec_text, sizeof(dec_text));
+ VV_(printf("This does NOT match the original data.\n"));
+ return 1;
+ } else {
+ VV_(printf("Successful!\n"));
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char*)NIST_TEST_DATA, sizeof(NIST_TEST_DATA));
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char*)enc_text, sizeof(enc_text));
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array((unsigned char*)dec_text, sizeof(dec_text));
+ }
+
+ return 0;
+}
+
+/*
+ * Performs ECB and CBC tests.
+ */
+int main(int argc, char **argv)
+{
+ unsigned int mode = 0;
+ int rc = 0;
+ int error_count = 0;
+
+ if (argc > 1) {
+ if (strstr(argv[1], "ecb"))
+ mode = MODE_ECB;
+ if (strstr(argv[1], "cbc"))
+ mode = MODE_CBC;
+ }
+ if (argc > 2) {
+ if (strstr(argv[2], "ecb"))
+ mode = MODE_ECB;
+ if (strstr(argv[2], "cbc"))
+ mode = MODE_CBC;
+ }
+
+ set_verbosity(argc, argv);
+
+ if (mode != 0 && mode != MODE_ECB && mode != MODE_CBC) {
+ printf("Usage: %s [ ecb | cbc ]\n", argv[0]);
+ return -1;
+ }
+
+ if (!mode) {
+ /* This is the standard loop that will perform all testcases */
+ mode = 2;
+ while (mode) {
+ rc = test_aes192_new_api(mode);
+ if (rc) {
+ error_count++;
+ V_(printf ("test_aes_new_api mode = %i failed \n", mode));
+ } else {
+ V_(printf ("test_aes_new_api mode = %i finished.\n", mode));
+ }
+ mode--;
+ }
+ if (error_count)
+ printf("%i AES-192-ECB/CBC tests failed.\n", error_count);
+ else
+ printf("All AES-192-ECB/CBC tests passed.\n");
+ } else {
+ /* Perform only either in ECB or CBC mode */
+ rc = test_aes192_new_api(mode);
+ if (rc)
+ printf ("test_aes_new_api mode = %i failed \n", mode);
+ else {
+ printf ("test_aes_new_api mode = %i finished.\n", mode);
+ }
+ }
+ return rc;
+}
+
diff --git a/src/tests/libica_aes256_test.c b/src/tests/libica_aes256_test.c
new file mode 100644
index 0000000..0b78283
--- /dev/null
+++ b/src/tests/libica_aes256_test.c
@@ -0,0 +1,153 @@
+/* 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 */
+#include <fcntl.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include "ica_api.h"
+#include "testcase.h"
+
+unsigned char NIST_KEY3[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+};
+
+unsigned char NIST_TEST_DATA[] = {
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+};
+
+unsigned char NIST_TEST_RESULT[] = {
+ 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
+ 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89,
+};
+
+int test_aes256_new_api(int mode)
+{
+ ica_aes_vector_t iv;
+ unsigned char key[AES_KEY_LEN256];
+ int rc = 0;
+ unsigned char dec_text[sizeof(NIST_TEST_DATA)],
+ enc_text[sizeof(NIST_TEST_DATA)];
+
+ bzero(dec_text, sizeof(dec_text));
+ bzero(enc_text, sizeof(enc_text));
+ bzero(iv, sizeof(iv));
+ bcopy(NIST_KEY3, key, sizeof(NIST_KEY3));
+
+ rc = ica_aes_encrypt(mode, sizeof(NIST_TEST_DATA), NIST_TEST_DATA, &iv,
+ AES_KEY_LEN256, key, enc_text);
+ if (rc) {
+ VV_(printf("ica_aes_encrypt failed with errno %d (0x%x).\n", rc, rc));
+ return 1;
+ }
+
+ if (memcmp(enc_text, NIST_TEST_RESULT, sizeof(NIST_TEST_RESULT)) != 0) {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char *) NIST_TEST_DATA, sizeof(NIST_TEST_DATA));
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char *) enc_text, sizeof(enc_text));
+ VV_(printf("This does NOT match the known result.\n"));
+ return 1;
+ } else {
+ VV_(printf("Yep, it's what it should be.\n"));
+ }
+
+ bzero(iv, sizeof(iv));
+ rc = ica_aes_decrypt(mode, sizeof(enc_text), enc_text, &iv,
+ AES_KEY_LEN256, key, dec_text);
+ if (rc) {
+ VV_(printf("ica_aes_decrypt failed with errno %d (0x%x).\n", rc, rc));
+ return 1;
+ }
+
+ if (memcmp(dec_text, NIST_TEST_DATA, sizeof(NIST_TEST_DATA)) != 0) {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char *) NIST_TEST_DATA, sizeof(NIST_TEST_DATA));
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char *) enc_text, sizeof(enc_text));
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array((unsigned char *) dec_text, sizeof(dec_text));
+ VV_(printf("This does NOT match the original data.\n"));
+ return 1;
+ } else {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char *) NIST_TEST_DATA, sizeof(NIST_TEST_DATA));
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char *) enc_text, sizeof(enc_text));
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array((unsigned char *) dec_text, sizeof(dec_text));
+ VV_(printf("Successful!\n"));
+ }
+
+ return 0;
+}
+
+/*
+ * Performs ECB and CBC tests.
+ */
+int main(int argc, char **argv)
+{
+ unsigned int mode = 0;
+ int rc = 0;
+ int error_count = 0;
+
+ if (argc > 1) {
+ if (strstr(argv[1], "ecb"))
+ mode = MODE_ECB;
+ if (strstr(argv[1], "cbc"))
+ mode = MODE_CBC;
+ }
+ if (argc > 2) {
+ if (strstr(argv[2], "ecb"))
+ mode = MODE_ECB;
+ if (strstr(argv[2], "cbc"))
+ mode = MODE_CBC;
+ }
+
+ set_verbosity(argc, argv);
+
+ if (mode != 0 && mode != MODE_ECB && mode != MODE_CBC) {
+ printf("Usage: %s [ ecb | cbc ]\n", argv[0]);
+ return -1;
+ }
+
+ if (!mode) {
+ /* This is the standard loop that will perform all testcases */
+ mode = 2;
+ while (mode) {
+ rc = test_aes256_new_api(mode);
+ if (rc) {
+ error_count++;
+ V_(printf ("test_aes_new_api mode = %i failed \n", mode));
+ }
+ else {
+ V_(printf ("test_aes_new_api mode = %i finished.\n", mode));
+ }
+ mode--;
+ }
+ if (error_count)
+ printf("%i AES-256-ECB/CBC tests failed.\n", error_count);
+ else
+ printf("All AES-256-ECB/CBC tests passed.\n");
+ } else {
+ /* Perform only either in ECB or CBC mode */
+ rc = test_aes256_new_api(mode);
+ if (rc)
+ printf("test_aes_new_api mode = %i failed \n", mode);
+ else
+ printf("test_aes_new_api mode = %i finished.\n", mode);
+ }
+
+ return rc;
+}
+
diff --git a/src/tests/libica_aes_cbc_test.c b/src/tests/libica_aes_cbc_test.c
new file mode 100644
index 0000000..8cca50a
--- /dev/null
+++ b/src/tests/libica_aes_cbc_test.c
@@ -0,0 +1,614 @@
+/* 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"
+#include "testcase.h"
+
+#define NR_TESTS 7
+#define NR_RANDOM_TESTS 10000
+
+/* CBC data - 1 for AES128 */
+unsigned char NIST_KEY_CBC_E1[] = {
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
+};
+
+unsigned char NIST_IV_CBC_E1[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+};
+
+unsigned char NIST_EXPECTED_IV_CBC_E1[] = {
+ 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46,
+ 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d,
+};
+
+unsigned char NIST_TEST_DATA_CBC_E1[] = {
+ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+};
+
+unsigned char NIST_TEST_RESULT_CBC_E1[] = {
+ 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46,
+ 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d,
+};
+
+/* CBC data - 2 for AES128 */
+unsigned char NIST_KEY_CBC_E2[] = {
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
+};
+
+unsigned char NIST_IV_CBC_E2[] = {
+ 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46,
+ 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d,
+};
+
+unsigned char NIST_EXPECTED_IV_CBC_E2[] = {
+ 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee,
+ 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2,
+};
+
+unsigned char NIST_TEST_DATA_CBC_E2[] = {
+ 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+ 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
+};
+
+unsigned char NIST_TEST_RESULT_CBC_E2[] = {
+ 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee,
+ 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2,
+};
+
+/* CBC data - 3 - for AES128 */
+unsigned char NIST_KEY_CBC_E3[] = {
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
+
+};
+
+unsigned char NIST_IV_CBC_E3[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+};
+
+unsigned char NIST_EXPECTED_IV_CBC_E3[] = {
+ 0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09,
+ 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7,
+};
+
+unsigned char NIST_TEST_DATA_CBC_E3[] = {
+ 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,
+};
+
+unsigned char NIST_TEST_RESULT_CBC_E3[] = {
+ 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46,
+ 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d,
+ 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee,
+ 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2,
+ 0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b,
+ 0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16,
+ 0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09,
+ 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7,
+};
+
+/* CBC data - 4 - for AES192 */
+unsigned char NIST_KEY_CBC_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_CBC_E4[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+};
+
+unsigned char NIST_EXPECTED_IV_CBC_E4[] = {
+ 0x4f, 0x02, 0x1d, 0xb2, 0x43, 0xbc, 0x63, 0x3d,
+ 0x71, 0x78, 0x18, 0x3a, 0x9f, 0xa0, 0x71, 0xe8,
+};
+
+unsigned char NIST_TEST_DATA_CBC_E4[] = {
+ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+};
+
+unsigned char NIST_TEST_RESULT_CBC_E4[] = {
+ 0x4f, 0x02, 0x1d, 0xb2, 0x43, 0xbc, 0x63, 0x3d,
+ 0x71, 0x78, 0x18, 0x3a, 0x9f, 0xa0, 0x71, 0xe8,
+};
+
+/* CBC data 5 - for AES 192 */
+unsigned char NIST_KEY_CBC_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_CBC_E5[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+};
+
+unsigned char NIST_EXPECTED_IV_CBC_E5[] = {
+ 0x08, 0xb0, 0xe2, 0x79, 0x88, 0x59, 0x88, 0x81,
+ 0xd9, 0x20, 0xa9, 0xe6, 0x4f, 0x56, 0x15, 0xcd,
+};
+
+unsigned char NIST_TEST_DATA_CBC_E5[] = {
+ 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,
+};
+
+unsigned char NIST_TEST_RESULT_CBC_E5[] = {
+ 0x4f, 0x02, 0x1d, 0xb2, 0x43, 0xbc, 0x63, 0x3d,
+ 0x71, 0x78, 0x18, 0x3a, 0x9f, 0xa0, 0x71, 0xe8,
+ 0xb4, 0xd9, 0xad, 0xa9, 0xad, 0x7d, 0xed, 0xf4,
+ 0xe5, 0xe7, 0x38, 0x76, 0x3f, 0x69, 0x14, 0x5a,
+ 0x57, 0x1b, 0x24, 0x20, 0x12, 0xfb, 0x7a, 0xe0,
+ 0x7f, 0xa9, 0xba, 0xac, 0x3d, 0xf1, 0x02, 0xe0,
+ 0x08, 0xb0, 0xe2, 0x79, 0x88, 0x59, 0x88, 0x81,
+ 0xd9, 0x20, 0xa9, 0xe6, 0x4f, 0x56, 0x15, 0xcd,
+};
+
+/* CBC data 6 - for AES 256 */
+unsigned char NIST_KEY_CBC_E6[] = {
+ 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_CBC_E6[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+};
+
+unsigned char NIST_EXPECTED_IV_CBC_E6[] = {
+ 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba,
+ 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
+};
+
+unsigned char NIST_TEST_DATA_CBC_E6[] = {
+ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+};
+
+unsigned char NIST_TEST_RESULT_CBC_E6[] = {
+ 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba,
+ 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
+};
+
+/* CBC data 7 - for AES 256 */
+unsigned char NIST_KEY_CBC_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_CBC_E7[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+};
+
+unsigned char NIST_EXPECTED_IV_CBC_E7[] = {
+ 0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc,
+ 0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b,
+};
+
+unsigned char NIST_TEST_DATA_CBC_E7[] = {
+ 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,
+};
+
+unsigned char NIST_TEST_RESULT_CBC_E7[] = {
+ 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba,
+ 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
+ 0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d,
+ 0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d,
+ 0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf,
+ 0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61,
+ 0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc,
+ 0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b,
+};
+
+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)
+{
+ VV_(printf("IV \n"));
+ dump_array(iv, iv_length);
+ VV_(printf("Key \n"));
+ dump_array(key, key_length);
+ VV_(printf("Input Data\n"));
+ dump_array(input_data, data_length);
+ VV_(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_CBC_E1);
+ *iv_length = sizeof(NIST_IV_CBC_E1);
+ *key_length = sizeof(NIST_KEY_CBC_E1);
+ break;
+ case 2:
+ *data_length = sizeof(NIST_TEST_DATA_CBC_E2);
+ *iv_length = sizeof(NIST_IV_CBC_E2);
+ *key_length = sizeof(NIST_KEY_CBC_E2);
+ break;
+ case 3:
+ *data_length = sizeof(NIST_TEST_DATA_CBC_E3);
+ *iv_length = sizeof(NIST_IV_CBC_E3);
+ *key_length = sizeof(NIST_KEY_CBC_E3);
+ break;
+ case 4:
+ *data_length = sizeof(NIST_TEST_DATA_CBC_E4);
+ *iv_length = sizeof(NIST_IV_CBC_E4);
+ *key_length = sizeof(NIST_KEY_CBC_E4);
+ break;
+ case 5:
+ *data_length = sizeof(NIST_TEST_DATA_CBC_E5);
+ *iv_length = sizeof(NIST_IV_CBC_E5);
+ *key_length = sizeof(NIST_KEY_CBC_E5);
+ break;
+ case 6:
+ *data_length = sizeof(NIST_TEST_DATA_CBC_E6);
+ *iv_length = sizeof(NIST_IV_CBC_E6);
+ *key_length = sizeof(NIST_KEY_CBC_E6);
+ break;
+ case 7:
+ *data_length = sizeof(NIST_TEST_DATA_CBC_E7);
+ *iv_length = sizeof(NIST_IV_CBC_E7);
+ *key_length = sizeof(NIST_KEY_CBC_E7);
+ break;
+ case 8:
+ break;
+ case 9:
+ break;
+ case 10:
+ break;
+ case 11:
+ break;
+ case 12:
+ 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_CBC_E1, data_length);
+ memcpy(result, NIST_TEST_RESULT_CBC_E1, data_length);
+ memcpy(iv, NIST_IV_CBC_E1, iv_length);
+ memcpy(expected_iv, NIST_EXPECTED_IV_CBC_E1, iv_length);
+ memcpy(key, NIST_KEY_CBC_E1, key_length);
+ break;
+ case 2:
+ memcpy(data, NIST_TEST_DATA_CBC_E2, data_length);
+ memcpy(result, NIST_TEST_RESULT_CBC_E2, data_length);
+ memcpy(iv, NIST_IV_CBC_E2, iv_length);
+ memcpy(expected_iv, NIST_EXPECTED_IV_CBC_E2, iv_length);
+ memcpy(key, NIST_KEY_CBC_E2, key_length);
+ break;
+ case 3:
+ memcpy(data, NIST_TEST_DATA_CBC_E3, data_length);
+ memcpy(result, NIST_TEST_RESULT_CBC_E3, data_length);
+ memcpy(iv, NIST_IV_CBC_E3, iv_length);
+ memcpy(expected_iv, NIST_EXPECTED_IV_CBC_E3, iv_length);
+ memcpy(key, NIST_KEY_CBC_E3, key_length);
+ break;
+ case 4:
+ memcpy(data, NIST_TEST_DATA_CBC_E4, data_length);
+ memcpy(result, NIST_TEST_RESULT_CBC_E4, data_length);
+ memcpy(iv, NIST_IV_CBC_E4, iv_length);
+ memcpy(expected_iv, NIST_EXPECTED_IV_CBC_E4, iv_length);
+ memcpy(key, NIST_KEY_CBC_E4, key_length);
+ break;
+ case 5:
+ memcpy(data, NIST_TEST_DATA_CBC_E5, data_length);
+ memcpy(result, NIST_TEST_RESULT_CBC_E5, data_length);
+ memcpy(iv, NIST_IV_CBC_E5, iv_length);
+ memcpy(expected_iv, NIST_EXPECTED_IV_CBC_E5, iv_length);
+ memcpy(key, NIST_KEY_CBC_E5, key_length);
+ break;
+ case 6:
+ memcpy(data, NIST_TEST_DATA_CBC_E6, data_length);
+ memcpy(result, NIST_TEST_RESULT_CBC_E6, data_length);
+ memcpy(iv, NIST_IV_CBC_E6, iv_length);
+ memcpy(expected_iv, NIST_EXPECTED_IV_CBC_E6, iv_length);
+ memcpy(key, NIST_KEY_CBC_E6, key_length);
+ break;
+ case 7:
+ memcpy(data, NIST_TEST_DATA_CBC_E7, data_length);
+ memcpy(result, NIST_TEST_RESULT_CBC_E7, data_length);
+ memcpy(iv, NIST_IV_CBC_E7, iv_length);
+ memcpy(expected_iv, NIST_EXPECTED_IV_CBC_E7, iv_length);
+ memcpy(key, NIST_KEY_CBC_E7, key_length);
+ break;
+ case 8:
+ break;
+ case 9:
+ break;
+ case 10:
+ break;
+ case 11:
+ break;
+ case 12:
+ break;
+ }
+
+}
+
+int kat_aes_cbc(int iteration)
+{
+ unsigned int data_length;
+ unsigned int iv_length;
+ unsigned int key_length;
+
+ get_sizes(&data_length, &iv_length, &key_length, iteration);
+
+ unsigned char iv[iv_length];
+ unsigned char tmp_iv[iv_length];
+ unsigned char expected_iv[iv_length];
+ unsigned char key[key_length];
+ unsigned char input_data[data_length];
+ unsigned char encrypt[data_length];
+ unsigned char decrypt[data_length];
+ unsigned char result[data_length];
+
+ int rc = 0;
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(printf("key length = %i, data length = %i, iv length = %i\n",
+ key_length, data_length, iv_length));
+
+
+ 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_cbc(input_data, encrypt, data_length, key, key_length,
+ tmp_iv, 1);
+ if (rc) {
+ VV_(printf("ica_aes_cbc encrypt failed with rc = %i\n", rc));
+ dump_cbc_data(iv, iv_length, key, key_length, input_data,
+ data_length, encrypt);
+ }
+ if (!rc) {
+ VV_(printf("Encrypt:\n"));
+ dump_cbc_data(iv, iv_length, key, key_length, input_data,
+ data_length, encrypt);
+ }
+
+ if (memcmp(result, encrypt, data_length)) {
+ VV_(printf("Encryption Result does not match the known ciphertext!\n"));
+ VV_(printf("Expected data:\n"));
+ dump_array(result, data_length);
+ VV_(printf("Encryption Result:\n"));
+ dump_array(encrypt, data_length);
+ rc++;
+ }
+
+ if (memcmp(expected_iv, tmp_iv, iv_length)) {
+ VV_(printf("Update of IV does not match the expected IV!\n"));
+ VV_(printf("Expected IV:\n"));
+ dump_array(expected_iv, iv_length);
+ VV_(printf("Updated IV:\n"));
+ dump_array(tmp_iv, iv_length);
+ VV_(printf("Original IV:\n"));
+ dump_array(iv, iv_length);
+ rc++;
+ }
+ if (rc) {
+ VV_(printf("AES CBC test exited after encryption\n"));
+ return rc;
+ }
+
+ memcpy(tmp_iv, iv, iv_length);
+ rc = ica_aes_cbc(encrypt, decrypt, data_length, key, key_length,
+ tmp_iv, 0);
+ if (rc) {
+ VV_(printf("ica_aes_cbc decrypt failed with rc = %i\n", rc));
+ dump_cbc_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ return rc;
+ }
+
+
+ if (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_cbc_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(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) {
+ VV_(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) {
+ VV_(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) {
+ VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n",
+ rc, errno));
+ return rc;
+ }
+ return rc;
+}
+
+int random_aes_cbc(int iteration, 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 = 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);
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(printf("key length = %i, data length = %i, iv length = %i\n",
+ key_length, data_length, iv_length));
+
+ rc = ica_aes_cbc(input_data, encrypt, data_length, key, key_length,
+ tmp_iv, 1);
+ if (rc) {
+ VV_(printf("ica_aes_cbc encrypt failed with rc = %i\n", rc));
+ dump_cbc_data(iv, iv_length, key, key_length, input_data,
+ data_length, encrypt);
+ VV_(printf("Encrypt:\n"));
+ dump_cbc_data(iv, iv_length, key, key_length, input_data,
+ data_length, encrypt);
+ VV_(printf("AES CBC test exited after encryption\n"));
+ return rc;
+ }
+
+ memcpy(tmp_iv, iv, iv_length);
+
+ rc = ica_aes_cbc(encrypt, decrypt, data_length, key, key_length,
+ tmp_iv, 0);
+ if (rc) {
+ VV_(printf("ica_aes_cbc decrypt failed with rc = %i\n", rc));
+ dump_cbc_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ return rc;
+ }
+
+ if (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_cbc_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Decryption Result:\n"));
+ dump_array(decrypt, data_length);
+ rc++;
+ return rc;
+ }
+ key_length += 8;
+ }
+
+ return rc;
+}
+
+int main(int argc, char **argv)
+{
+ int rc = 0;
+ int error_count = 0;
+ int iteration;
+ unsigned int data_length = sizeof(ica_aes_vector_t);
+
+ set_verbosity(argc, argv);
+
+ for(iteration = 1; iteration <= NR_TESTS; iteration++) {
+ rc = kat_aes_cbc(iteration);
+ if (rc) {
+ V_(printf("kat_aes_cbc failed with rc = %i\n", rc));
+ error_count++;
+ } else {
+ V_(printf("kat_aes_cbc finished.n"));
+ }
+ }
+ for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) {
+ rc = random_aes_cbc(iteration, data_length);
+ if (rc) {
+ V_(printf("random_aes_cbc failed with rc = %i\n", rc));
+ error_count++;
+ goto out;
+ } else {
+ V_(printf("random_aes_cbc finished.n"));
+ }
+ data_length += sizeof(ica_aes_vector_t);
+ }
+
+out:
+ if (error_count)
+ printf("%i AES-CBC tests failed.\n", error_count);
+ else {
+ printf("All AES-CBC tests passed.\n");
+ }
+
+ return rc;
+}
+
diff --git a/src/tests/libica_aes_cfb_test.c b/src/tests/libica_aes_cfb_test.c
new file mode 100644
index 0000000..e1ca248
--- /dev/null
+++ b/src/tests/libica_aes_cfb_test.c
@@ -0,0 +1,804 @@
+/* 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"
+#include "testcase.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,
+};
+
+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,
+ 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,
+};
+
+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[] = {
+ 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_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, 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_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, 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_CFB_E11[] = {
+ 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, 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_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_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)
+{
+ VV_(printf("IV \n"));
+ dump_array(iv, iv_length);
+ VV_(printf("Key \n"));
+ dump_array(key, key_length);
+ VV_(printf("Input Data\n"));
+ dump_array(input_data, data_length);
+ VV_(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:
+ *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:
+ 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)
+{
+ unsigned int data_length;
+ unsigned int iv_length;
+ unsigned int key_length;
+
+ get_sizes(&data_length, &iv_length, &key_length, iteration);
+
+ unsigned char iv[iv_length];
+ unsigned char tmp_iv[iv_length];
+ unsigned char expected_iv[iv_length];
+ unsigned char key[key_length];
+ unsigned char input_data[data_length];
+ unsigned char encrypt[data_length];
+ unsigned char decrypt[data_length];
+ unsigned char 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);
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(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) {
+ VV_(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 (!rc) {
+ VV_(printf("Encrypt:\n"));
+ dump_cfb_data(iv, iv_length, key, key_length, input_data,
+ data_length, encrypt);
+ }
+
+ if (memcmp(result, encrypt, data_length)) {
+ VV_(printf("Encryption Result does not match the known ciphertext!\n"));
+ VV_(printf("Expected data:\n"));
+ dump_array(result, data_length);
+ VV_(printf("Encryption Result:\n"));
+ dump_array(encrypt, data_length);
+ rc++;
+ }
+
+ if (memcmp(expected_iv, tmp_iv, iv_length)) {
+ VV_(printf("Update of IV does not match the expected IV!\n"));
+ VV_(printf("Expected IV:\n"));
+ dump_array(expected_iv, iv_length);
+ VV_(printf("Updated IV:\n"));
+ dump_array(tmp_iv, iv_length);
+ VV_(printf("Original IV:\n"));
+ dump_array(iv, iv_length);
+ rc++;
+ }
+ if (rc) {
+ VV_(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,
+ lcfb, 0);
+ else
+ rc = ica_aes_cfb(encrypt, decrypt, data_length, key, key_length,
+ tmp_iv, lcfb, 0);
+ if (rc) {
+ VV_(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 (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_cfb_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(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) {
+ VV_(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) {
+ VV_(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) {
+ VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n",
+ rc, errno));
+ return rc;
+ }
+ return rc;
+}
+
+int random_aes_cfb(int iteration, unsigned int data_length, unsigned int lcfb)
+{
+ 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 key[key_length];
+ unsigned char input_data[data_length];
+ unsigned char encrypt[data_length];
+ unsigned char decrypt[data_length];
+
+ 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);
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(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) {
+ VV_(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 (!rc) {
+ VV_(printf("Encrypt:\n"));
+ dump_cfb_data(iv, iv_length, key, key_length, input_data,
+ data_length, encrypt);
+ }
+
+ if (rc) {
+ VV_(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) {
+ VV_(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 (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_cfb_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Decryption Result:\n"));
+ dump_array(decrypt, data_length);
+ rc++;
+ }
+ }
+ return rc;
+}
+
+int main(int argc, char **argv)
+{
+ unsigned int data_length = 1;
+ unsigned int lcfb = 1;
+ unsigned int j;
+ unsigned int rdata;
+ int rc = 0;
+ int error_count = 0;
+ int iteration;
+
+ set_verbosity(argc, argv);
+
+ for(iteration = 1; iteration <= NR_TESTS; iteration++) {
+ rc = kat_aes_cfb(iteration);
+ if (rc) {
+ V_(printf("kat_aes_cfb failed with rc = %i\n", rc));
+ error_count++;
+ }
+ }
+
+ for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) {
+ for (j = 1; j <= 3; j++) {
+ if (!(data_length % lcfb)) {
+ rc = random_aes_cfb(iteration, data_length, lcfb);
+ if (rc) {
+ V_(printf("random_aes_cfb failed with rc = %i\n", rc));
+ error_count++;
+ }
+ }
+ switch (j) {
+ case 1:
+ lcfb = 1;
+ break;
+ case 2:
+ lcfb = 8;
+ break;
+ case 3:
+ lcfb = 16;
+ break;
+ }
+ }
+ // add a value between 1 and 8 to data_length
+ if (ica_random_number_generate(sizeof(rdata), (unsigned char*) &rdata)) {
+ printf("ica_random_number_generate failed with errnor = %i\n",
+ errno);
+ exit(1);
+ }
+ data_length += (rdata % 8) + 1;
+ }
+ if (error_count)
+ printf("%i AES-CFB tests failed.\n", error_count);
+ else
+ printf("All AES-CFB tests passed.\n");
+
+ return rc;
+}
+
diff --git a/src/tests/libica_aes_ctr_test.c b/src/tests/libica_aes_ctr_test.c
new file mode 100644
index 0000000..8b3cf42
--- /dev/null
+++ b/src/tests/libica_aes_ctr_test.c
@@ -0,0 +1,638 @@
+/* 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"
+#include "testcase.h"
+
+#define NR_TESTS 7
+#define NR_RANDOM_TESTS 1000
+
+/* 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, 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,
+};
+
+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,
+ 0x5a, 0xe4, 0xdf, 0x3e, 0xdb, 0xd5, 0xd3, 0x5e,
+ 0x5b, 0x4f, 0x09, 0x02, 0x0d, 0xb0, 0x3e, 0xab,
+ 0x1e, 0x03, 0x1d, 0xda, 0x2f, 0xbe, 0x03, 0xd1,
+ 0x79, 0x21, 0x70, 0xa0, 0xf3, 0x00, 0x9c, 0xee,
+};
+
+/* CTR data - 3 - for AES192 */
+unsigned char NIST_KEY_CTR_E3[] = {
+ 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_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, 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_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,
+ 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, 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,
+};
+
+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, 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_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, 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,
+};
+
+unsigned char NIST_TEST_RESULT_CTR_E6[] = {
+ 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,
+};
+
+/* 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, 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_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, 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,
+};
+
+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_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)
+{
+ VV_(printf("IV \n"));
+ dump_array(iv, iv_length);
+ VV_(printf("Key \n"));
+ dump_array(key, key_length);
+ VV_(printf("Input Data\n"));
+ dump_array(input_data, data_length);
+ VV_(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:
+ *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;
+ }
+
+}
+
+int random_aes_ctr(int iteration, 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);
+
+ unsigned char iv[iv_length];
+ unsigned char tmp_iv[iv_length];
+ unsigned char key[key_length];
+ unsigned char input_data[data_length];
+ unsigned char encrypt[data_length];
+ unsigned char decrypt[data_length];
+
+ int rc = 0;
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(printf("key length = %i, data length = %i, iv length = %i\n",
+ key_length, data_length, iv_length));
+
+ rc = ica_random_number_generate(data_length, input_data);
+ if (rc) {
+ VV_(printf("random number generate returned rc = %i, errno = %i\n", rc, errno));
+ return rc;
+ }
+ rc = ica_random_number_generate(iv_length, iv);
+ if (rc) {
+ VV_(printf("random number generate returned rc = %i, errno = %i\n", rc, errno));
+ return rc;
+ }
+
+ rc = ica_random_number_generate(key_length, key);
+ if (rc) {
+ VV_(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) {
+ VV_(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 (!rc) {
+ VV_(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) {
+ VV_(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 (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_ctr_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Decryption Result:\n"));
+ dump_array(decrypt, data_length);
+ rc++;
+ }
+ return rc;
+}
+
+int kat_aes_ctr(int iteration)
+{
+ unsigned int data_length;
+ unsigned int iv_length;
+ unsigned int key_length;
+
+ get_sizes(&data_length, &iv_length, &key_length, iteration);
+
+ unsigned char iv[iv_length];
+ unsigned char tmp_iv[iv_length];
+ unsigned char expected_iv[iv_length];
+ unsigned char key[key_length];
+ unsigned char input_data[data_length];
+ unsigned char encrypt[data_length];
+ unsigned char decrypt[data_length];
+ unsigned char result[data_length];
+
+ int rc = 0;
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(printf("key length = %i, data length = %i, iv length = %i\n",
+ key_length, data_length, iv_length));
+
+ 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) {
+ VV_(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 (!rc) {
+ VV_(printf("Encrypt:\n"));
+ dump_ctr_data(iv, iv_length, key, key_length, input_data,
+ data_length, encrypt);
+ }
+
+ if (memcmp(result, encrypt, data_length)) {
+ VV_(printf("Encryption Result does not match the known ciphertext!\n"));
+ VV_(printf("Expected data:\n"));
+ dump_array(result, data_length);
+ VV_(printf("Encryption Result:\n"));
+ dump_array(encrypt, data_length);
+ rc++;
+ }
+
+ if (memcmp(expected_iv, tmp_iv, iv_length)) {
+ VV_(printf("Update of IV does not match the expected IV!\n"));
+ VV_(printf("Expected IV:\n"));
+ dump_array(expected_iv, iv_length);
+ VV_(printf("Updated IV:\n"));
+ dump_array(tmp_iv, iv_length);
+ VV_(printf("Original IV:\n"));
+ dump_array(iv, iv_length);
+ rc++;
+ }
+ if (rc) {
+ VV_(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) {
+ VV_(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 (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_ctr_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Decryption Result:\n"));
+ dump_array(decrypt, data_length);
+ rc++;
+ }
+ return rc;
+}
+
+/*
+ * Perform CTR tests.
+ */
+int main(int argc, char **argv)
+{
+ unsigned int endless = 0;
+ int i = 0;
+ int rc = 0;
+ int error_count = 0;
+ int iteration;
+ unsigned int data_length = 1;
+ unsigned int iv_length = sizeof(ica_aes_vector_t);
+ unsigned int rdata;
+
+ if (argc > 1) {
+ if (strstr(argv[1], "endless"))
+ endless = 1;
+ }
+
+ set_verbosity(argc, argv);
+
+ if (!endless) {
+
+ // not endless mode
+ // run the verification tests with known test vectors
+ for(iteration = 1; iteration <= NR_TESTS; iteration++) {
+ rc = kat_aes_ctr(iteration);
+ if (rc) {
+ V_(printf("kat_aes_ctr failed with rc = %i\n", rc));
+ error_count++;
+ }
+ }
+ // run random tests
+ for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) {
+ rc = random_aes_ctr(iteration, data_length, iv_length);
+ if (rc) {
+ V_(printf("random_aes_ctr failed with rc = %i\n", rc));
+ error_count++;
+ }
+ // add a value between 1 and 8 to data_length
+ if (ica_random_number_generate(sizeof(rdata), (unsigned char*) &rdata)) {
+ printf("ica_random_number_generate failed with errnor = %i\n",
+ errno);
+ exit(1);
+ }
+ data_length += (rdata % 8) + 1;
+ }
+
+ } else {
+ // endless mode
+ while (1) {
+ V_(printf("i = %i\n",i));
+ rc = random_aes_ctr(i, 320, 320);
+ if (rc) {
+ V_(printf("random_aes_ctr failed with rc = %i\n", rc));
+ return rc;
+ }
+ i++;
+ }
+
+ }
+
+ if (error_count)
+ printf("%i AES-CTR tests failed\n", error_count);
+ else
+ printf("All AES-CTR tests passed.\n");
+
+ return rc;
+}
+
diff --git a/src/tests/libica_aes_ecb_test.c b/src/tests/libica_aes_ecb_test.c
new file mode 100644
index 0000000..09830db
--- /dev/null
+++ b/src/tests/libica_aes_ecb_test.c
@@ -0,0 +1,485 @@
+/* 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"
+#include "testcase.h"
+
+#define NR_TESTS 7
+#define NR_RANDOM_TESTS 10000
+
+/* ECB data - 1 for AES128 */
+unsigned char NIST_KEY_ECB_E1[] = {
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
+};
+
+unsigned char NIST_TEST_DATA_ECB_E1[] = {
+ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+};
+
+unsigned char NIST_TEST_RESULT_ECB_E1[] = {
+ 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
+ 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
+};
+
+/* ECB data - 2 for AES128 */
+unsigned char NIST_KEY_ECB_E2[] = {
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
+};
+
+unsigned char NIST_TEST_DATA_ECB_E2[] = {
+ 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+ 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
+};
+
+unsigned char NIST_TEST_RESULT_ECB_E2[] = {
+ 0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d,
+ 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf,
+};
+
+/* ECB data - 3 - for AES128 */
+unsigned char NIST_KEY_ECB_E3[] = {
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
+
+};
+
+unsigned char NIST_TEST_DATA_ECB_E3[] = {
+ 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,
+};
+
+unsigned char NIST_TEST_RESULT_ECB_E3[] = {
+ 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
+ 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
+ 0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d,
+ 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf,
+ 0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23,
+ 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88,
+ 0x7b, 0x0c, 0x78, 0x5e, 0x27, 0xe8, 0xad, 0x3f,
+ 0x82, 0x23, 0x20, 0x71, 0x04, 0x72, 0x5d, 0xd4,
+};
+
+/* ECB data - 4 - for AES192 */
+unsigned char NIST_KEY_ECB_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_TEST_DATA_ECB_E4[] = {
+ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+};
+
+unsigned char NIST_TEST_RESULT_ECB_E4[] = {
+ 0xbd, 0x33, 0x4f, 0x1d, 0x6e, 0x45, 0xf2, 0x5f,
+ 0xf7, 0x12, 0xa2, 0x14, 0x57, 0x1f, 0xa5, 0xcc,
+};
+
+/* ECB data 5 - for AES 192 */
+unsigned char NIST_KEY_ECB_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_TEST_DATA_ECB_E5[] = {
+ 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,
+};
+
+unsigned char NIST_TEST_RESULT_ECB_E5[] = {
+ 0xbd, 0x33, 0x4f, 0x1d, 0x6e, 0x45, 0xf2, 0x5f,
+ 0xf7, 0x12, 0xa2, 0x14, 0x57, 0x1f, 0xa5, 0xcc,
+ 0x97, 0x41, 0x04, 0x84, 0x6d, 0x0a, 0xd3, 0xad,
+ 0x77, 0x34, 0xec, 0xb3, 0xec, 0xee, 0x4e, 0xef,
+ 0xef, 0x7a, 0xfd, 0x22, 0x70, 0xe2, 0xe6, 0x0a,
+ 0xdc, 0xe0, 0xba, 0x2f, 0xac, 0xe6, 0x44, 0x4e,
+ 0x9a, 0x4b, 0x41, 0xba, 0x73, 0x8d, 0x6c, 0x72,
+ 0xfb, 0x16, 0x69, 0x16, 0x03, 0xc1, 0x8e, 0x0e,
+};
+
+/* ECB data 6 - for AES 256 */
+unsigned char NIST_KEY_ECB_E6[] = {
+ 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_TEST_DATA_ECB_E6[] = {
+ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+};
+
+unsigned char NIST_TEST_RESULT_ECB_E6[] = {
+ 0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c,
+ 0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8,
+};
+
+/* ECB data 7 - for AES 256 */
+unsigned char NIST_KEY_ECB_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_TEST_DATA_ECB_E7[] = {
+ 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,
+};
+
+unsigned char NIST_TEST_RESULT_ECB_E7[] = {
+ 0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c,
+ 0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8,
+ 0x59, 0x1c, 0xcb, 0x10, 0xd4, 0x10, 0xed, 0x26,
+ 0xdc, 0x5b, 0xa7, 0x4a, 0x31, 0x36, 0x28, 0x70,
+ 0xb6, 0xed, 0x21, 0xb9, 0x9c, 0xa6, 0xf4, 0xf9,
+ 0xf1, 0x53, 0xe7, 0xb1, 0xbe, 0xaf, 0xed, 0x1d,
+ 0x23, 0x30, 0x4b, 0x7a, 0x39, 0xf9, 0xf3, 0xff,
+ 0x06, 0x7d, 0x8d, 0x8f, 0x9e, 0x24, 0xec, 0xc7,
+};
+
+void dump_ecb_data(unsigned char *key, unsigned int key_length,
+ unsigned char *input_data, unsigned int data_length,
+ unsigned char *output_data)
+{
+ VV_(printf("Key\n"));
+ dump_array(key, key_length);
+ VV_(printf("Input Data\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Output Data\n"));
+ dump_array(output_data, data_length);
+}
+
+void get_sizes(unsigned int *data_length,
+ unsigned int *key_length, unsigned int iteration)
+{
+ switch (iteration) {
+ case 1:
+ *data_length = sizeof(NIST_TEST_DATA_ECB_E1);
+ *key_length = sizeof(NIST_KEY_ECB_E1);
+ break;
+ case 2:
+ *data_length = sizeof(NIST_TEST_DATA_ECB_E2);
+ *key_length = sizeof(NIST_KEY_ECB_E2);
+ break;
+ case 3:
+ *data_length = sizeof(NIST_TEST_DATA_ECB_E3);
+ *key_length = sizeof(NIST_KEY_ECB_E3);
+ break;
+ case 4:
+ *data_length = sizeof(NIST_TEST_DATA_ECB_E4);
+ *key_length = sizeof(NIST_KEY_ECB_E4);
+ break;
+ case 5:
+ *data_length = sizeof(NIST_TEST_DATA_ECB_E5);
+ *key_length = sizeof(NIST_KEY_ECB_E5);
+ break;
+ case 6:
+ *data_length = sizeof(NIST_TEST_DATA_ECB_E6);
+ *key_length = sizeof(NIST_KEY_ECB_E6);
+ break;
+ case 7:
+ *data_length = sizeof(NIST_TEST_DATA_ECB_E7);
+ *key_length = sizeof(NIST_KEY_ECB_E7);
+ break;
+ case 8:
+ break;
+ case 9:
+ break;
+ case 10:
+ break;
+ case 11:
+ break;
+ case 12:
+ break;
+ }
+
+}
+
+void load_test_data(unsigned char *data, unsigned int data_length,
+ unsigned char *result,
+ unsigned char *key, unsigned int key_length,
+ unsigned int iteration)
+{
+ switch (iteration) {
+ case 1:
+ memcpy(data, NIST_TEST_DATA_ECB_E1, data_length);
+ memcpy(result, NIST_TEST_RESULT_ECB_E1, data_length);
+ memcpy(key, NIST_KEY_ECB_E1, key_length);
+ break;
+ case 2:
+ memcpy(data, NIST_TEST_DATA_ECB_E2, data_length);
+ memcpy(result, NIST_TEST_RESULT_ECB_E2, data_length);
+ memcpy(key, NIST_KEY_ECB_E2, key_length);
+ break;
+ case 3:
+ memcpy(data, NIST_TEST_DATA_ECB_E3, data_length);
+ memcpy(result, NIST_TEST_RESULT_ECB_E3, data_length);
+ memcpy(key, NIST_KEY_ECB_E3, key_length);
+ break;
+ case 4:
+ memcpy(data, NIST_TEST_DATA_ECB_E4, data_length);
+ memcpy(result, NIST_TEST_RESULT_ECB_E4, data_length);
+ memcpy(key, NIST_KEY_ECB_E4, key_length);
+ break;
+ case 5:
+ memcpy(data, NIST_TEST_DATA_ECB_E5, data_length);
+ memcpy(result, NIST_TEST_RESULT_ECB_E5, data_length);
+ memcpy(key, NIST_KEY_ECB_E5, key_length);
+ break;
+ case 6:
+ memcpy(data, NIST_TEST_DATA_ECB_E6, data_length);
+ memcpy(result, NIST_TEST_RESULT_ECB_E6, data_length);
+ memcpy(key, NIST_KEY_ECB_E6, key_length);
+ break;
+ case 7:
+ memcpy(data, NIST_TEST_DATA_ECB_E7, data_length);
+ memcpy(result, NIST_TEST_RESULT_ECB_E7, data_length);
+ memcpy(key, NIST_KEY_ECB_E7, key_length);
+ break;
+ case 8:
+ break;
+ case 9:
+ break;
+ case 10:
+ break;
+ case 11:
+ break;
+ case 12:
+ break;
+ }
+
+}
+
+int kat_aes_ecb(int iteration)
+{
+ unsigned int data_length;
+ unsigned int key_length;
+
+ get_sizes(&data_length, &key_length, iteration);
+
+ unsigned char key[key_length];
+ unsigned char input_data[data_length];
+ unsigned char encrypt[data_length];
+ unsigned char decrypt[data_length];
+ unsigned char result[data_length];
+
+ int rc = 0;
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(printf("key length = %i, data length = %i",
+ key_length, data_length));
+
+ load_test_data(input_data, data_length, result, key, key_length,
+ iteration);
+
+ rc = ica_aes_ecb(input_data, encrypt, data_length, key, key_length, 1);
+ if (rc) {
+ VV_(printf("ica_aes_ecb encrypt failed with rc = %i\n", rc));
+ dump_ecb_data(key, key_length, input_data,
+ data_length, encrypt);
+ }
+ if (!rc) {
+ VV_(printf("Encrypt:\n"));
+ dump_ecb_data(key, key_length, input_data,
+ data_length, encrypt);
+ }
+
+ if (memcmp(result, encrypt, data_length)) {
+ VV_(printf("Encryption Result does not match the known ciphertext!\n"));
+ VV_(printf("Expected data:\n"));
+ dump_array(result, data_length);
+ VV_(printf("Encryption Result:\n"));
+ dump_array(encrypt, data_length);
+ rc++;
+ }
+
+ if (rc) {
+ VV_(printf("AES ECB test exited after encryption\n"));
+ return rc;
+ }
+
+ rc = ica_aes_ecb(encrypt, decrypt, data_length, key, key_length, 0);
+ if (rc) {
+ VV_(printf("ica_aes_ecb decrypt failed with rc = %i\n", rc));
+ dump_ecb_data(key, key_length, encrypt,
+ data_length, decrypt);
+ return rc;
+ }
+
+
+ if (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_ecb_data(key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(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 *key, unsigned int key_length)
+{
+ int rc;
+
+ rc = ica_random_number_generate(data_length, data);
+ if (rc) {
+ VV_(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) {
+ VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n",
+ rc, errno));
+ return rc;
+ }
+ return rc;
+}
+
+int random_aes_ecb(int iteration, unsigned int data_length)
+{
+ int i;
+ int rc = 0;
+ unsigned int key_length = AES_KEY_LEN128;
+ 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, key, key_length);
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(printf("key length = %i, data length = %i\n", key_length, data_length));
+ rc = ica_aes_ecb(input_data, encrypt, data_length, key, key_length, 1);
+ if (rc) {
+ VV_(printf("ica_aes_ecb encrypt failed with rc = %i\n", rc));
+ dump_ecb_data(key, key_length, input_data,
+ data_length, encrypt);
+ }
+ if (!rc) {
+ VV_(printf("Encrypt:\n"));
+ dump_ecb_data(key, key_length, input_data,
+ data_length, encrypt);
+ }
+
+ if (rc) {
+ VV_(printf("AES ECB test exited after encryption\n"));
+ return rc;
+ }
+
+ rc = ica_aes_ecb(encrypt, decrypt, data_length, key, key_length, 0);
+ if (rc) {
+ VV_(printf("ica_aes_ecb decrypt failed with rc = %i\n", rc));
+ dump_ecb_data(key, key_length, encrypt,
+ data_length, decrypt);
+ return rc;
+ }
+
+ if (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_ecb_data(key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Decryption Result:\n"));
+ dump_array(decrypt, data_length);
+ rc++;
+ return rc;
+ }
+ key_length += 8;
+ }
+
+ return rc;
+}
+
+/*
+ * Perform CTR tests.
+ */
+int main(int argc, char **argv)
+{
+ int rc = 0;
+ int error_count = 0;
+ int iteration;
+ unsigned int data_length = sizeof(ica_aes_vector_t);
+
+ set_verbosity(argc, argv);
+
+ for(iteration = 1; iteration <= NR_TESTS; iteration++) {
+ rc = kat_aes_ecb(iteration);
+ if (rc) {
+ V_(printf("kat_aes_ecb failed with rc = %i\n", rc));
+ error_count++;
+ }
+
+ }
+ for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) {
+ rc = random_aes_ecb(iteration, data_length);
+ if (rc) {
+ V_(printf("random_aes_ecb failed with rc = %i, %i\n", rc, iteration));
+ error_count++;
+ goto out;
+ }
+ data_length += sizeof(ica_aes_vector_t);
+ }
+
+out:
+ if (error_count)
+ printf("%i AES-ECB tests failed.\n", error_count);
+ else
+ printf("All AES-ECB tests passed.\n");
+
+ return rc;
+}
+
diff --git a/src/tests/libica_aes_gcm_test.c b/src/tests/libica_aes_gcm_test.c
new file mode 100644
index 0000000..bce6100
--- /dev/null
+++ b/src/tests/libica_aes_gcm_test.c
@@ -0,0 +1,1043 @@
+/* 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. 2011 */
+#include <fcntl.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include "ica_api.h"
+#include "testcase.h"
+
+#define NR_TESTS 12
+#define AES_BLOCK_SIZE 16
+
+/* GCM data - 1*/
+unsigned char NIST_KEY_GCM_E1[] = {
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+};
+
+unsigned char NIST_TEST_DATA_GCM_E1[] = {
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55,
+};
+
+unsigned char NIST_AAD_GCM_E1[] = {
+};
+
+unsigned char NIST_IV_GCM_E1[] = {
+ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88,
+};
+
+unsigned char NIST_TAG_GCM_E1[] = {
+ 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
+ 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4,
+};
+
+unsigned char NIST_TEST_RESULT_GCM_E1[] = {
+ 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
+ 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
+ 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
+ 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
+ 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
+ 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
+ 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
+ 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85,
+};
+
+unsigned char NIST_CHUNKS_GCM_E1[] = { 16, 16, 16, 16 };
+
+/* GCM data - 2*/
+unsigned char NIST_KEY_GCM_E2[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+unsigned char NIST_TEST_DATA_GCM_E2[] = {
+};
+
+unsigned char NIST_AAD_GCM_E2[] = {
+};
+
+unsigned char NIST_IV_GCM_E2[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+};
+
+unsigned char NIST_TAG_GCM_E2[] = {
+ 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
+ 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a
+};
+
+unsigned char NIST_TEST_RESULT_GCM_E2[] = {
+};
+
+unsigned char NIST_CHUNKS_GCM_E2[] = { };
+
+/* GCM data - 3*/
+unsigned char NIST_KEY_GCM_E3[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+unsigned char NIST_TEST_DATA_GCM_E3[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+unsigned char NIST_AAD_GCM_E3[] = {
+};
+
+unsigned char NIST_IV_GCM_E3[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+};
+
+unsigned char NIST_TAG_GCM_E3[] = {
+ 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
+ 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf,
+};
+
+unsigned char NIST_TEST_RESULT_GCM_E3[] = {
+ 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
+ 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78,
+};
+
+unsigned char NIST_CHUNKS_GCM_E3[] = { 16 };
+
+/* GCM data - 4*/
+unsigned char NIST_KEY_GCM_E4[] = {
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+};
+
+unsigned char NIST_TEST_DATA_GCM_E4[] = {
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39,
+};
+
+unsigned char NIST_AAD_GCM_E4[] = {
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xab, 0xad, 0xda, 0xd2,
+};
+
+unsigned char NIST_IV_GCM_E4[] = {
+ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88,
+};
+
+unsigned char NIST_TAG_GCM_E4[] = {
+ 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
+ 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47,
+};
+
+unsigned char NIST_TEST_RESULT_GCM_E4[] = {
+ 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
+ 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
+ 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
+ 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
+ 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
+ 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
+ 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
+ 0x3d, 0x58, 0xe0, 0x91,
+};
+
+unsigned char NIST_CHUNKS_GCM_E4[] = { 16, 16, 16, 12 };
+
+/* GCM data - 5 - AES 192 - Test Case 7*/
+unsigned char NIST_KEY_GCM_E5[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+unsigned char NIST_TEST_DATA_GCM_E5[] = {
+};
+
+unsigned char NIST_AAD_GCM_E5[] = {
+};
+
+unsigned char NIST_IV_GCM_E5[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+};
+
+unsigned char NIST_TAG_GCM_E5[] = {
+ 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
+ 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35,
+};
+
+unsigned char NIST_TEST_RESULT_GCM_E5[] = {
+};
+
+unsigned char NIST_CHUNKS_GCM_E5[] = { };
+
+/* GCM data - 6 - AES 192 - Test Case 8*/
+unsigned char NIST_KEY_GCM_E6[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+unsigned char NIST_TEST_DATA_GCM_E6[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+unsigned char NIST_AAD_GCM_E6[] = {
+};
+
+unsigned char NIST_IV_GCM_E6[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+};
+
+unsigned char NIST_TAG_GCM_E6[] = {
+ 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
+ 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb,
+};
+
+unsigned char NIST_TEST_RESULT_GCM_E6[] = {
+ 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
+ 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00,
+};
+
+unsigned char NIST_CHUNKS_GCM_E6[] = { 16 };
+
+/* GCM data - 7 - AES 192 - Test Case 9*/
+unsigned char NIST_KEY_GCM_E7[] = {
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+};
+
+unsigned char NIST_TEST_DATA_GCM_E7[] = {
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55,
+};
+
+unsigned char NIST_AAD_GCM_E7[] = {
+};
+
+unsigned char NIST_IV_GCM_E7[] = {
+ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88,
+};
+
+unsigned char NIST_TAG_GCM_E7[] = {
+ 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
+ 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14,
+};
+
+unsigned char NIST_TEST_RESULT_GCM_E7[] = {
+ 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
+ 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
+ 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
+ 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
+ 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
+ 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
+ 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
+ 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56,
+};
+
+unsigned char NIST_CHUNKS_GCM_E7[] = { 16, 16, 16, 16 };
+
+/* GCM data - 8 - AES 192 - Test Case 10*/
+unsigned char NIST_KEY_GCM_E8[] = {
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+};
+
+unsigned char NIST_TEST_DATA_GCM_E8[] = {
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39,
+};
+
+unsigned char NIST_AAD_GCM_E8[] = {
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xab, 0xad, 0xda, 0xd2,
+};
+
+unsigned char NIST_IV_GCM_E8[] = {
+ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88,
+};
+
+unsigned char NIST_TAG_GCM_E8[] = {
+ 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
+ 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c,
+};
+
+unsigned char NIST_TEST_RESULT_GCM_E8[] = {
+ 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
+ 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
+ 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
+ 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
+ 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
+ 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
+ 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
+ 0xcc, 0xda, 0x27, 0x10,
+};
+
+unsigned char NIST_CHUNKS_GCM_E8[] = { 16, 16, 16, 12 };
+
+/* GCM data - 9 - AES 256 - Test Case 13*/
+unsigned char NIST_KEY_GCM_E9[] = {
+ 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,
+};
+
+unsigned char NIST_TEST_DATA_GCM_E9[] = {
+};
+
+unsigned char NIST_AAD_GCM_E9[] = {
+};
+
+unsigned char NIST_IV_GCM_E9[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+};
+
+unsigned char NIST_TAG_GCM_E9[] = {
+ 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
+ 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b,
+};
+
+unsigned char NIST_TEST_RESULT_GCM_E9[] = {
+};
+
+unsigned char NIST_CHUNKS_GCM_E9[] = { };
+
+/* GCM data - 10 - AES 256 - Test Case 14*/
+unsigned char NIST_KEY_GCM_E10[] = {
+ 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,
+};
+
+unsigned char NIST_TEST_DATA_GCM_E10[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+unsigned char NIST_AAD_GCM_E10[] = {
+};
+
+unsigned char NIST_IV_GCM_E10[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+};
+
+unsigned char NIST_TAG_GCM_E10[] = {
+ 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
+ 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19,
+};
+
+unsigned char NIST_TEST_RESULT_GCM_E10[] = {
+ 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
+ 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18,
+};
+
+unsigned char NIST_CHUNKS_GCM_E10[] = { 16 };
+
+/* GCM data - 11 - AES 256 - Test Case 15*/
+unsigned char NIST_KEY_GCM_E11[] = {
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+};
+
+unsigned char NIST_TEST_DATA_GCM_E11[] = {
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55,
+};
+
+unsigned char NIST_AAD_GCM_E11[] = {
+};
+
+unsigned char NIST_IV_GCM_E11[] = {
+ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88,
+};
+
+unsigned char NIST_TAG_GCM_E11[] = {
+ 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
+ 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c,
+};
+
+unsigned char NIST_TEST_RESULT_GCM_E11[] = {
+ 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
+ 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
+ 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
+ 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
+ 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
+ 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
+ 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
+ 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad,
+};
+
+unsigned char NIST_CHUNKS_GCM_E11[] = { 16, 16, 16, 16 };
+
+/* GCM data */
+unsigned char NIST_KEY_GCM_E12[] = {
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+};
+
+unsigned char NIST_TEST_DATA_GCM_E12[] = {
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39,
+};
+
+unsigned char NIST_AAD_GCM_E12[] = {
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xab, 0xad, 0xda, 0xd2,
+};
+
+unsigned char NIST_IV_GCM_E12[] = {
+ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88,
+};
+
+unsigned char NIST_TAG_GCM_E12[] = {
+ 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
+ 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b,
+};
+
+unsigned char NIST_TEST_RESULT_GCM_E12[] = {
+ 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
+ 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
+ 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
+ 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
+ 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
+ 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
+ 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
+ 0xbc, 0xc9, 0xf6, 0x62,
+};
+
+unsigned char NIST_CHUNKS_GCM_E12[] = { 16, 16, 16, 12 };
+
+void dump_gcm_data(unsigned char *iv, unsigned int iv_length,
+ unsigned char *aad, unsigned int aad_length,
+ unsigned char *key, unsigned int key_length,
+ unsigned char *input_data, unsigned int data_length,
+ unsigned char *output_data,
+ unsigned char *t, unsigned int t_size)
+{
+ VV_(printf("IV \n"));
+ dump_array(iv, iv_length);
+ VV_(printf("AAD \n"));
+ dump_array(aad, aad_length);
+ VV_(printf("Key \n"));
+ dump_array(key, key_length);
+ VV_(printf("Input Data\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Output Data\n"));
+ dump_array(output_data, data_length);
+ VV_(printf("T\n"));
+ dump_array(t, t_size);
+}
+
+void get_sizes(unsigned int *aad_length, unsigned int *data_length,
+ unsigned int *t_length, unsigned int *iv_length,
+ unsigned int *key_length, unsigned int *num_chunks,
+ unsigned int iteration)
+{
+ switch (iteration) {
+ case 1:
+ *aad_length = sizeof(NIST_AAD_GCM_E1);
+ *data_length = sizeof(NIST_TEST_DATA_GCM_E1);
+ *t_length = sizeof(NIST_TAG_GCM_E1);
+ *iv_length = sizeof(NIST_IV_GCM_E1);
+ *key_length = sizeof(NIST_KEY_GCM_E1);
+ *num_chunks = sizeof(NIST_CHUNKS_GCM_E1);
+ break;
+ case 2:
+ *aad_length = sizeof(NIST_AAD_GCM_E2);
+ *data_length = sizeof(NIST_TEST_DATA_GCM_E2);
+ *t_length = sizeof(NIST_TAG_GCM_E2);
+ *iv_length = sizeof(NIST_IV_GCM_E2);
+ *key_length = sizeof(NIST_KEY_GCM_E2);
+ *num_chunks = sizeof(NIST_CHUNKS_GCM_E2);
+ break;
+ case 3:
+ *aad_length = sizeof(NIST_AAD_GCM_E3);
+ *data_length = sizeof(NIST_TEST_DATA_GCM_E3);
+ *t_length = sizeof(NIST_TAG_GCM_E3);
+ *iv_length = sizeof(NIST_IV_GCM_E3);
+ *key_length = sizeof(NIST_KEY_GCM_E3);
+ *num_chunks = sizeof(NIST_CHUNKS_GCM_E3);
+ break;
+ case 4:
+ *aad_length = sizeof(NIST_AAD_GCM_E4);
+ *data_length = sizeof(NIST_TEST_DATA_GCM_E4);
+ *t_length = sizeof(NIST_TAG_GCM_E4);
+ *iv_length = sizeof(NIST_IV_GCM_E4);
+ *key_length = sizeof(NIST_KEY_GCM_E4);
+ *num_chunks = sizeof(NIST_CHUNKS_GCM_E4);
+ break;
+ case 5:
+ *aad_length = sizeof(NIST_AAD_GCM_E5);
+ *data_length = sizeof(NIST_TEST_DATA_GCM_E5);
+ *t_length = sizeof(NIST_TAG_GCM_E5);
+ *iv_length = sizeof(NIST_IV_GCM_E5);
+ *key_length = sizeof(NIST_KEY_GCM_E5);
+ *num_chunks = sizeof(NIST_CHUNKS_GCM_E5);
+ break;
+ case 6:
+ *aad_length = sizeof(NIST_AAD_GCM_E6);
+ *data_length = sizeof(NIST_TEST_DATA_GCM_E6);
+ *t_length = sizeof(NIST_TAG_GCM_E6);
+ *iv_length = sizeof(NIST_IV_GCM_E6);
+ *key_length = sizeof(NIST_KEY_GCM_E6);
+ *num_chunks = sizeof(NIST_CHUNKS_GCM_E6);
+ break;
+ case 7:
+ *aad_length = sizeof(NIST_AAD_GCM_E7);
+ *data_length = sizeof(NIST_TEST_DATA_GCM_E7);
+ *t_length = sizeof(NIST_TAG_GCM_E7);
+ *iv_length = sizeof(NIST_IV_GCM_E7);
+ *key_length = sizeof(NIST_KEY_GCM_E7);
+ *num_chunks = sizeof(NIST_CHUNKS_GCM_E7);
+ break;
+ case 8:
+ *aad_length = sizeof(NIST_AAD_GCM_E8);
+ *data_length = sizeof(NIST_TEST_DATA_GCM_E8);
+ *t_length = sizeof(NIST_TAG_GCM_E8);
+ *iv_length = sizeof(NIST_IV_GCM_E8);
+ *key_length = sizeof(NIST_KEY_GCM_E8);
+ *num_chunks = sizeof(NIST_CHUNKS_GCM_E8);
+ break;
+ case 9:
+ *aad_length = sizeof(NIST_AAD_GCM_E9);
+ *data_length = sizeof(NIST_TEST_DATA_GCM_E9);
+ *t_length = sizeof(NIST_TAG_GCM_E9);
+ *iv_length = sizeof(NIST_IV_GCM_E9);
+ *key_length = sizeof(NIST_KEY_GCM_E9);
+ *num_chunks = sizeof(NIST_CHUNKS_GCM_E9);
+ break;
+ case 10:
+ *aad_length = sizeof(NIST_AAD_GCM_E10);
+ *data_length = sizeof(NIST_TEST_DATA_GCM_E10);
+ *t_length = sizeof(NIST_TAG_GCM_E10);
+ *iv_length = sizeof(NIST_IV_GCM_E10);
+ *key_length = sizeof(NIST_KEY_GCM_E10);
+ *num_chunks = sizeof(NIST_CHUNKS_GCM_E10);
+ break;
+ case 11:
+ *aad_length = sizeof(NIST_AAD_GCM_E11);
+ *data_length = sizeof(NIST_TEST_DATA_GCM_E11);
+ *t_length = sizeof(NIST_TAG_GCM_E11);
+ *iv_length = sizeof(NIST_IV_GCM_E11);
+ *key_length = sizeof(NIST_KEY_GCM_E11);
+ *num_chunks = sizeof(NIST_CHUNKS_GCM_E11);
+ break;
+ case 12:
+ *aad_length = sizeof(NIST_AAD_GCM_E12);
+ *data_length = sizeof(NIST_TEST_DATA_GCM_E12);
+ *t_length = sizeof(NIST_TAG_GCM_E12);
+ *iv_length = sizeof(NIST_IV_GCM_E12);
+ *key_length = sizeof(NIST_KEY_GCM_E12);
+ *num_chunks = sizeof(NIST_CHUNKS_GCM_E12);
+ break;
+ }
+
+}
+
+void load_test_data(unsigned char *aad, unsigned int aad_length,
+ unsigned char *data, unsigned int data_length,
+ unsigned char *result,
+ unsigned char *t, unsigned int t_length,
+ unsigned char *iv, unsigned int iv_length,
+ unsigned char *key, unsigned int key_length,
+ unsigned char *chunks, unsigned int num_chunks,
+ unsigned int iteration)
+{
+ switch (iteration) {
+ case 1:
+ memcpy(iv, NIST_IV_GCM_E1, iv_length);
+ memcpy(aad, NIST_AAD_GCM_E1, aad_length);
+ memcpy(key, NIST_KEY_GCM_E1, key_length);
+ memcpy(data, NIST_TEST_DATA_GCM_E1, data_length);
+ memcpy(result, NIST_TEST_RESULT_GCM_E1, data_length);
+ memcpy(t, NIST_TAG_GCM_E1, t_length);
+ memcpy(chunks, NIST_CHUNKS_GCM_E1, num_chunks);
+ break;
+ case 2:
+ memcpy(iv, NIST_IV_GCM_E2, iv_length);
+ memcpy(aad, NIST_AAD_GCM_E2, aad_length);
+ memcpy(key, NIST_KEY_GCM_E2, key_length);
+ memcpy(data, NIST_TEST_DATA_GCM_E2, data_length);
+ memcpy(result, NIST_TEST_RESULT_GCM_E2, data_length);
+ memcpy(t, NIST_TAG_GCM_E2, t_length);
+ memcpy(chunks, NIST_CHUNKS_GCM_E2, num_chunks);
+ break;
+ case 3:
+ memcpy(iv, NIST_IV_GCM_E3, iv_length);
+ memcpy(aad, NIST_AAD_GCM_E3, aad_length);
+ memcpy(key, NIST_KEY_GCM_E3, key_length);
+ memcpy(data, NIST_TEST_DATA_GCM_E3, data_length);
+ memcpy(result, NIST_TEST_RESULT_GCM_E3, data_length);
+ memcpy(t, NIST_TAG_GCM_E3, t_length);
+ memcpy(chunks, NIST_CHUNKS_GCM_E3, num_chunks);
+ break;
+ case 4:
+ memcpy(iv, NIST_IV_GCM_E4, iv_length);
+ memcpy(aad, NIST_AAD_GCM_E4, aad_length);
+ memcpy(key, NIST_KEY_GCM_E4, key_length);
+ memcpy(data, NIST_TEST_DATA_GCM_E4, data_length);
+ memcpy(result, NIST_TEST_RESULT_GCM_E4, data_length);
+ memcpy(t, NIST_TAG_GCM_E4, t_length);
+ memcpy(chunks, NIST_CHUNKS_GCM_E4, num_chunks);
+ break;
+ case 5:
+ memcpy(iv, NIST_IV_GCM_E5, iv_length);
+ memcpy(aad, NIST_AAD_GCM_E5, aad_length);
+ memcpy(key, NIST_KEY_GCM_E5, key_length);
+ memcpy(data, NIST_TEST_DATA_GCM_E5, data_length);
+ memcpy(result, NIST_TEST_RESULT_GCM_E5, data_length);
+ memcpy(t, NIST_TAG_GCM_E5, t_length);
+ memcpy(chunks, NIST_CHUNKS_GCM_E5, num_chunks);
+ break;
+ case 6:
+ memcpy(iv, NIST_IV_GCM_E6, iv_length);
+ memcpy(aad, NIST_AAD_GCM_E6, aad_length);
+ memcpy(key, NIST_KEY_GCM_E6, key_length);
+ memcpy(data, NIST_TEST_DATA_GCM_E6, data_length);
+ memcpy(result, NIST_TEST_RESULT_GCM_E6, data_length);
+ memcpy(t, NIST_TAG_GCM_E6, t_length);
+ memcpy(chunks, NIST_CHUNKS_GCM_E6, num_chunks);
+ break;
+ case 7:
+ memcpy(iv, NIST_IV_GCM_E7, iv_length);
+ memcpy(aad, NIST_AAD_GCM_E7, aad_length);
+ memcpy(key, NIST_KEY_GCM_E7, key_length);
+ memcpy(data, NIST_TEST_DATA_GCM_E7, data_length);
+ memcpy(result, NIST_TEST_RESULT_GCM_E7, data_length);
+ memcpy(t, NIST_TAG_GCM_E7, t_length);
+ memcpy(chunks, NIST_CHUNKS_GCM_E7, num_chunks);
+ break;
+ case 8:
+ memcpy(iv, NIST_IV_GCM_E8, iv_length);
+ memcpy(aad, NIST_AAD_GCM_E8, aad_length);
+ memcpy(key, NIST_KEY_GCM_E8, key_length);
+ memcpy(data, NIST_TEST_DATA_GCM_E8, data_length);
+ memcpy(result, NIST_TEST_RESULT_GCM_E8, data_length);
+ memcpy(t, NIST_TAG_GCM_E8, t_length);
+ memcpy(chunks, NIST_CHUNKS_GCM_E8, num_chunks);
+ break;
+ case 9:
+ memcpy(iv, NIST_IV_GCM_E9, iv_length);
+ memcpy(aad, NIST_AAD_GCM_E9, aad_length);
+ memcpy(key, NIST_KEY_GCM_E9, key_length);
+ memcpy(data, NIST_TEST_DATA_GCM_E9, data_length);
+ memcpy(result, NIST_TEST_RESULT_GCM_E9, data_length);
+ memcpy(t, NIST_TAG_GCM_E9, t_length);
+ memcpy(chunks, NIST_CHUNKS_GCM_E9, num_chunks);
+ break;
+ case 10:
+ memcpy(iv, NIST_IV_GCM_E10, iv_length);
+ memcpy(aad, NIST_AAD_GCM_E10, aad_length);
+ memcpy(key, NIST_KEY_GCM_E10, key_length);
+ memcpy(data, NIST_TEST_DATA_GCM_E10, data_length);
+ memcpy(result, NIST_TEST_RESULT_GCM_E10, data_length);
+ memcpy(t, NIST_TAG_GCM_E10, t_length);
+ memcpy(chunks, NIST_CHUNKS_GCM_E10, num_chunks);
+ break;
+ case 11:
+ memcpy(iv, NIST_IV_GCM_E11, iv_length);
+ memcpy(aad, NIST_AAD_GCM_E11, aad_length);
+ memcpy(key, NIST_KEY_GCM_E11, key_length);
+ memcpy(data, NIST_TEST_DATA_GCM_E11, data_length);
+ memcpy(result, NIST_TEST_RESULT_GCM_E11, data_length);
+ memcpy(t, NIST_TAG_GCM_E11, t_length);
+ memcpy(chunks, NIST_CHUNKS_GCM_E11, num_chunks);
+ break;
+ case 12:
+ memcpy(iv, NIST_IV_GCM_E12, iv_length);
+ memcpy(aad, NIST_AAD_GCM_E12, aad_length);
+ memcpy(key, NIST_KEY_GCM_E12, key_length);
+ memcpy(data, NIST_TEST_DATA_GCM_E12, data_length);
+ memcpy(result, NIST_TEST_RESULT_GCM_E12, data_length);
+ memcpy(t, NIST_TAG_GCM_E12, t_length);
+ memcpy(chunks, NIST_CHUNKS_GCM_E12, num_chunks);
+ break;
+ }
+
+}
+
+int test_gcm_kat(int iteration)
+{
+ unsigned int aad_length;
+ unsigned int data_length;
+ unsigned int t_length;
+ unsigned int iv_length;
+ unsigned int key_length;
+ unsigned int num_chunks;
+
+ get_sizes(&aad_length, &data_length, &t_length, &iv_length,
+ &key_length, &num_chunks, iteration);
+
+ unsigned char iv[iv_length];
+ unsigned char input_data[data_length];
+ unsigned char encrypt[data_length];
+ unsigned char decrypt[data_length];
+ unsigned char result[data_length];
+ unsigned char aad[aad_length];
+ unsigned char key[key_length];
+ unsigned char t[t_length];
+ unsigned char t_result[t_length];
+ unsigned char chunks[num_chunks];
+
+ int rc = 0;
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(printf("key length = %i, data length = %i, tag length = %i,"
+ "iv length = %i aad_length = %i\n", key_length, data_length,
+ t_length, iv_length, aad_length));
+
+ load_test_data(aad, aad_length, input_data, data_length, result,
+ t_result, t_length, iv, iv_length, key, key_length,
+ chunks, num_chunks, iteration);
+
+ rc = ica_aes_gcm(input_data, data_length,
+ encrypt,
+ iv, iv_length,
+ aad, aad_length,
+ t, t_length,
+ key, key_length,
+ 1);
+ if (rc == EPERM) {
+ VV_(printf("ica_aes_gcm returns with EPERM (%d).\n", rc));
+ VV_(printf("Operation is not permitted on this machine. Test skipped!\n"));
+ return 0;
+ }
+ if (rc) {
+ VV_(printf("ica_aes_gcm encrypt failed with rc = %i\n", rc));
+ dump_gcm_data(iv, iv_length, aad, aad_length, key, key_length,
+ input_data, data_length, encrypt, t, t_length);
+ }
+ if (!rc) {
+ VV_(printf("Encrypt:\n"));
+ dump_gcm_data(iv, iv_length, aad, aad_length, key, key_length,
+ input_data, data_length, encrypt, t,
+ t_length);
+ }
+
+ if (memcmp(result, encrypt, data_length)) {
+ VV_(printf("Encryption Result does not match the known ciphertext!\n"));
+ VV_(printf("Expected data:\n"));
+ dump_array(result, data_length);
+ VV_(printf("Encryption Result:\n"));
+ dump_array(encrypt, data_length);
+ rc++;
+ }
+ if (memcmp(t, t_result, t_length)) {
+ VV_(printf("Tag result does not match the expected tag!\n"));
+ VV_(printf("Expected tag:\n"));
+ dump_array(t_result, t_length);
+ VV_(printf("Tag Result:\n"));
+ dump_array(t, t_length);
+ rc++;
+ }
+ if (rc) {
+ VV_(printf("GCM test exited after encryption\n"));
+ return rc;
+ }
+ rc = ica_aes_gcm(decrypt, data_length,
+ encrypt,
+ iv, iv_length,
+ aad, aad_length,
+ t, t_length,
+ key, key_length,
+ 0);
+ if (rc == EPERM) {
+ VV_(printf("ica_aes_gcm returns with EPERM (%d).\n", rc));
+ VV_(printf("Operation is not permitted on this machine. Test skipped!\n"));
+ return 0;
+ }
+ if (rc) {
+ VV_(printf("ica_aes_gcm decrypt failed with rc = %i\n", rc));
+ dump_gcm_data(iv, iv_length, aad, aad_length, key, key_length,
+ encrypt, data_length, decrypt, t,
+ t_length);
+ }
+
+
+ if (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_gcm_data(iv, iv_length, aad, aad_length, key, key_length,
+ encrypt, data_length, decrypt, t,
+ t_length);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Decryption Result:\n"));
+ dump_array(decrypt, data_length);
+ rc++;
+ }
+ if (memcmp(t, t_result, t_length)) {
+ VV_(printf("Tag result does not match the expected tag!\n"));
+ VV_(printf("Expected tag:\n"));
+ dump_array(t_result, t_length);
+ VV_(printf("Tag Result:\n"));
+ dump_array(t, t_length);
+ rc++;
+ }
+ return rc;
+}
+
+int test_gcm_kat_update(int iteration)
+{
+ unsigned int aad_length;
+ unsigned int aad_length_tmp;
+ unsigned int data_length;
+ unsigned int t_length;
+ unsigned int iv_length;
+ unsigned int key_length;
+ unsigned int num_chunks;
+
+ get_sizes(&aad_length, &data_length, &t_length, &iv_length,
+ &key_length, &num_chunks, iteration);
+
+ unsigned char iv[iv_length];
+ unsigned char input_data[data_length];
+ unsigned char encrypt[data_length];
+ unsigned char decrypt[data_length];
+ unsigned char result[data_length];
+ unsigned char aad[aad_length];
+ unsigned char key[key_length];
+ unsigned char t[t_length];
+ unsigned char t_result[t_length];
+ unsigned char chunks[num_chunks];
+ unsigned int chunk_len;
+ unsigned int offset;
+ unsigned char *chunk_data;
+ unsigned char icb[AES_BLOCK_SIZE];
+ unsigned char ucb[AES_BLOCK_SIZE];
+ unsigned char subkey[AES_BLOCK_SIZE];
+ unsigned char running_tag[AES_BLOCK_SIZE];
+ unsigned int sum_A_len;
+ unsigned int sum_C_len;
+ int rc = 0, i;
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(printf("key length = %i, data length = %i, tag length = %i,"
+ "iv length = %i aad_length = %i\n", key_length, data_length,
+ t_length, iv_length, aad_length));
+
+ load_test_data(aad, aad_length, input_data, data_length, result,
+ t_result, t_length, iv, iv_length, key, key_length,
+ chunks, num_chunks, iteration);
+
+ aad_length_tmp = aad_length;
+ memset(running_tag, 0, AES_BLOCK_SIZE);
+ rc = ica_aes_gcm_initialize(iv, iv_length, key, key_length,
+ icb, ucb, subkey, 1);
+
+ offset = 0;
+ for (i = 0; i < num_chunks; i++) {
+ chunk_len = chunks[i];
+ chunk_data = input_data + offset;
+
+ rc = ica_aes_gcm_intermediate(chunk_data, chunk_len, encrypt + offset,
+ ucb, aad, aad_length,
+ running_tag, AES_BLOCK_SIZE,
+ key, key_length, subkey, 1);
+ /* clear aad_length after first run*/
+ aad_length = 0;
+ offset += chunk_len;
+ }
+ sum_A_len = aad_length_tmp;
+ sum_C_len = offset;
+ rc = ica_aes_gcm_last(icb, sum_A_len, sum_C_len, running_tag,
+ t, t_length, key, key_length, subkey, 1);
+
+ if (rc == EPERM) {
+ VV_(printf("ica_aes_gcm returns with EPERM (%d).\n", rc));
+ VV_(printf("Operation is not permitted on this machine. Test skipped!\n"));
+ return 0;
+ }
+ if (rc) {
+ VV_(printf("ica_aes_gcm encrypt failed with rc = %i\n", rc));
+ dump_gcm_data(iv, iv_length, aad, aad_length, key, key_length,
+ input_data, data_length, encrypt, t, t_length);
+ }
+ if (!rc) {
+ VV_(printf("Encrypt:\n"));
+ dump_gcm_data(iv, iv_length, aad, aad_length, key, key_length,
+ input_data, data_length, encrypt, running_tag,
+ t_length);
+ }
+
+ if (memcmp(result, encrypt, data_length)) {
+ VV_(printf("Encryption Result does not match the known ciphertext!\n"));
+ VV_(printf("Expected data:\n"));
+ dump_array(result, data_length);
+ VV_(printf("Encryption Result:\n"));
+ dump_array(encrypt, data_length);
+ rc++;
+ }
+ if (memcmp(running_tag, t_result, t_length)) {
+ VV_(printf("Tag result does not match the expected tag!\n"));
+ VV_(printf("Expected tag:\n"));
+ dump_array(t_result, t_length);
+ VV_(printf("Tag Result:\n"));
+ dump_array(t, t_length);
+ rc++;
+ }
+ if (rc) {
+ VV_(printf("GCM test exited after encryption\n"));
+ return rc;
+ }
+
+ aad_length = aad_length_tmp;
+ memset(running_tag, 0, AES_BLOCK_SIZE);
+ rc = ica_aes_gcm_initialize(iv, iv_length, key, key_length,
+ icb, ucb, subkey, 0);
+
+ offset = 0;
+ for (i = 0; i < num_chunks; i++) {
+ chunk_len = chunks[i];
+ chunk_data = encrypt + offset;
+
+ rc = ica_aes_gcm_intermediate(decrypt + offset, chunk_len, chunk_data,
+ ucb, aad, aad_length,
+ running_tag, AES_BLOCK_SIZE,
+ key, key_length, subkey, 0);
+
+ /* clear aad_length after first run*/
+ aad_length = 0;
+ offset += chunk_len;
+ }
+ sum_A_len = aad_length_tmp;
+ sum_C_len = offset;
+ rc = ica_aes_gcm_last(icb, sum_A_len, sum_C_len, running_tag,
+ t_result, t_length, key, key_length, subkey, 0);
+
+
+ if (rc == EPERM) {
+ VV_(printf("ica_aes_gcm returns with EPERM (%d).\n", rc));
+ VV_(printf("Operation is not permitted on this machine. Test skipped!\n"));
+ return 0;
+ }
+ if (rc) {
+ VV_(printf("ica_aes_gcm decrypt failed with rc = %i\n", rc));
+ dump_gcm_data(iv, iv_length, aad, aad_length, key, key_length,
+ encrypt, data_length, decrypt, running_tag,
+ t_length);
+ }
+
+
+ if (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_gcm_data(iv, iv_length, aad, aad_length, key, key_length,
+ encrypt, data_length, decrypt, running_tag,
+ t_length);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Decryption Result:\n"));
+ dump_array(decrypt, data_length);
+ rc++;
+ }
+ if (memcmp(running_tag, t_result, t_length)) {
+ VV_(printf("Tag result does not match the expected tag!\n"));
+ VV_(printf("Expected tag:\n"));
+ dump_array(t_result, t_length);
+ VV_(printf("Tag Result:\n"));
+ dump_array(t, t_length);
+ rc++;
+ }
+ return rc;
+}
+
+/*
+ * Performs GCM tests.
+ */
+int main(int argc, char **argv)
+{
+ int rc = 0;
+ int error_count = 0;
+ int iteration;
+
+ set_verbosity(argc, argv);
+
+ for(iteration = 1; iteration <= NR_TESTS; iteration++) {
+ rc = test_gcm_kat(iteration);
+ if (rc) {
+ V_(printf("test_gcm_kat failed with rc = %i\n", rc));
+ error_count++;
+ }
+
+ rc = test_gcm_kat_update(iteration);
+ if (rc) {
+ V_(printf("test_gcm_kat_update failed with rc = %i\n", rc));
+ error_count++;
+ }
+ }
+ if (error_count)
+ printf("%i of %i AES-GCM tests failed.\n", error_count, iteration);
+ else
+ printf("All AES-GCM tests passed.\n");
+ return rc;
+}
diff --git a/src/tests/libica_aes_ofb_test.c b/src/tests/libica_aes_ofb_test.c
new file mode 100644
index 0000000..30ba281
--- /dev/null
+++ b/src/tests/libica_aes_ofb_test.c
@@ -0,0 +1,526 @@
+/* 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"
+#include "testcase.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,
+};
+
+/* 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,
+ 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, 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_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, 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_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,
+};
+
+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)
+{
+ VV_(printf("IV \n"));
+ dump_array(iv, iv_length);
+ VV_(printf("Key \n"));
+ dump_array(key, key_length);
+ VV_(printf("Input Data\n"));
+ dump_array(input_data, data_length);
+ VV_(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);
+ 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)
+{
+ int rc;
+
+ rc = ica_random_number_generate(data_length, data);
+ if (rc) {
+ VV_(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) {
+ VV_(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) {
+ VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n",
+ rc, errno));
+ return rc;
+ }
+ return rc;
+}
+
+int random_aes_ofb(int iteration, 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);
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(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) {
+ VV_(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 (!rc) {
+ VV_(printf("Encrypt:\n"));
+ dump_ofb_data(iv, iv_length, key, key_length, input_data,
+ data_length, encrypt);
+ }
+
+ if (rc) {
+ VV_(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) {
+ VV_(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 (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_ofb_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Decryption Result:\n"));
+ dump_array(decrypt, data_length);
+ rc++;
+ return rc;
+ }
+ key_length += 8;
+ }
+
+ return rc;
+}
+
+int kat_aes_ofb(int iteration)
+{
+ unsigned int data_length;
+ unsigned int iv_length;
+ unsigned int key_length;
+
+ get_sizes(&data_length, &iv_length, &key_length, iteration);
+
+ unsigned char iv[iv_length];
+ unsigned char tmp_iv[iv_length];
+ unsigned char expected_iv[iv_length];
+ unsigned char key[key_length];
+ unsigned char input_data[data_length];
+ unsigned char encrypt[data_length];
+ unsigned char decrypt[data_length];
+ unsigned char result[data_length];
+
+ int rc = 0;
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(printf("key length = %i, data length = %i, iv length = %i\n",
+ key_length, data_length, iv_length));
+
+ 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) {
+ VV_(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 (!rc) {
+ VV_(printf("Encrypt:\n"));
+ dump_ofb_data(iv, iv_length, key, key_length, input_data,
+ data_length, encrypt);
+ }
+
+ if (memcmp(result, encrypt, data_length)) {
+ VV_(printf("Encryption Result does not match the known ciphertext!\n"));
+ VV_(printf("Expected data:\n"));
+ dump_array(result, data_length);
+ VV_(printf("Encryption Result:\n"));
+ dump_array(encrypt, data_length);
+ rc++;
+ }
+
+ if (memcmp(expected_iv, tmp_iv, iv_length)) {
+ VV_(printf("Update of IV does not match the expected IV!\n"));
+ VV_(printf("Expected IV:\n"));
+ dump_array(expected_iv, iv_length);
+ VV_(printf("Updated IV:\n"));
+ dump_array(tmp_iv, iv_length);
+ VV_(printf("Original IV:\n"));
+ dump_array(iv, iv_length);
+ rc++;
+ }
+ if (rc) {
+ VV_(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) {
+ VV_(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 (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_ofb_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Decryption Result:\n"));
+ dump_array(decrypt, data_length);
+ rc++;
+ }
+ return rc;
+}
+
+int main(int argc, char **argv)
+{
+ int rc = 0;
+ int error_count = 0;
+ int iteration;
+ unsigned int rdata;
+ unsigned int data_length = 1;
+
+ set_verbosity(argc, argv);
+
+ for(iteration = 1; iteration <= NR_TESTS; iteration++) {
+ rc = kat_aes_ofb(iteration);
+ if (rc) {
+ V_(printf("kat_aes_ofb failed with rc = %i\n", rc));
+ error_count++;
+ }
+
+ }
+
+ for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) {
+ rc = random_aes_ofb(iteration, data_length);
+ if (rc) {
+ V_(printf("random_aes_ofb failed with rc = %i\n", rc));
+ error_count++;
+ goto out;
+ }
+ // add a value between 1 and 8 to data_length
+ if (ica_random_number_generate(sizeof(rdata), (unsigned char*) &rdata)) {
+ printf("ica_random_number_generate failed with errnor = %i\n",
+ errno);
+ exit(1);
+ }
+ data_length += (rdata % 8) + 1;
+ }
+
+out:
+ if (error_count)
+ printf("%i AES-OFB tests failed.\n", error_count);
+ else
+ printf("All AES-OFB tests passed.\n");
+
+ return rc;
+}
+
diff --git a/src/tests/libica_aes_xts_test.c b/src/tests/libica_aes_xts_test.c
new file mode 100644
index 0000000..c7be0be
--- /dev/null
+++ b/src/tests/libica_aes_xts_test.c
@@ -0,0 +1,644 @@
+/* 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"
+#include "testcase.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, 0xcd, 0xb3,
+ 0xc8, 0x93, 0x09, 0x3c, 0x28, 0xe1, 0xfc, 0x0f,
+ 0x91, 0xf5, 0xca, 0xa3, 0xb6, 0xe0, 0xbc, 0x5a,
+ 0x14, 0xe7, 0x83, 0x21, 0x5c, 0x1d, 0x5b, 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.
+ */
+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, 0xb6, 0x11,
+ 0x14, 0xce, 0xc2, 0xc4, 0x4a, 0x60, 0x92, 0xdd,
+ 0xe9, 0xf7, 0x46, 0xcc, 0x65, 0xae, 0x3b, 0xd4,
+ 0x96, 0x68, 0x64, 0xaa, 0x36, 0x26, 0xd1, 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, 0x65, 0x23,
+ 0xc9, 0x9f, 0x16, 0x44, 0xec, 0xb1, 0xa5, 0xd9,
+ 0xbc, 0x0f, 0x2f, 0x55, 0xfb, 0xe3, 0x24, 0x44,
+ 0x4c, 0x39, 0x0f, 0xae, 0x75, 0x2a, 0xd4, 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, 0x60,
+ 0xa8, 0x14, 0x28, 0xbc, 0x91, 0x40, 0xec, 0xcd,
+ 0x26, 0xed, 0x18, 0x36, 0x8e, 0x24, 0xd4, 0x9b,
+ 0x9c, 0xc5, 0x12, 0x92, 0x9a, 0x88, 0xad, 0x1e,
+ 0x66, 0xc7, 0x63, 0xf4, 0xf5, 0x6b, 0x63, 0xbb,
+ 0x9d, 0xd9, 0x50, 0x8c, 0x5d, 0x4d, 0xf4, 0x65,
+ 0xad, 0x98, 0x82, 0x14, 0x82, 0xfc, 0x71, 0x94,
+ 0xee, 0x23, 0x54, 0xa3, 0xfa, 0xdc, 0xe9, 0x23,
+ 0x18, 0x54, 0x8e, 0x8c, 0xe9, 0x45, 0x20, 0x81,
+ 0x60, 0x49, 0x7b, 0x93, 0x05, 0xd9, 0xab, 0x10,
+ 0x91, 0xab, 0x41, 0xd1, 0xf0, 0x9a, 0x0c, 0x7b,
+ 0xfa, 0xf9, 0xf9, 0x4f, 0xe7, 0xc8, 0xf1, 0xea,
+ 0x96, 0x8f, 0x8f, 0x9a, 0x71, 0x3a, 0xca, 0xde,
+ 0x18, 0xb6, 0x82, 0x32, 0x10, 0x6f, 0xfd, 0x6d,
+ 0x42, 0x81, 0xe9, 0x9e, 0x11, 0xd6, 0xa4, 0x28,
+ 0xb5, 0x16, 0x53, 0xc0, 0xc7, 0xdd, 0xe5, 0xa0,
+ 0xf2, 0x73, 0xe7, 0x4f, 0xf0, 0x15, 0xce, 0x80,
+ 0x27, 0x7d, 0x74, 0x30, 0xf5, 0xda, 0xea, 0x8f,
+ 0x73, 0x40, 0x64, 0x5e, 0x0b, 0xec, 0x25, 0xf4,
+ 0x04, 0x0f, 0xa1, 0x3c, 0x0b, 0x33, 0x06, 0x93,
+ 0xb1, 0x00, 0x83, 0xa8, 0xb9, 0xbc, 0x10, 0x8f,
+ 0xe6, 0x4f, 0x3a, 0x5b, 0x61, 0x3c, 0xbb, 0x56,
+ 0x5a, 0xee, 0x2f, 0x09, 0xf5, 0xb2, 0x04, 0xae,
+ 0xe1, 0x72, 0x28, 0xfe, 0x65, 0x31, 0xc7, 0x0c,
+ 0x0e, 0xc9, 0x47, 0xd2, 0xa5, 0x14, 0x7b, 0x45,
+ 0xc5, 0x1a, 0xc7, 0xdc, 0x8e, 0x85, 0x87, 0x03,
+ 0x87, 0xeb, 0x8d, 0xb6, 0x25, 0x13, 0x68, 0x36,
+ 0x8b, 0xf5, 0xf2, 0x46, 0xb2, 0x95, 0x7d, 0xaf,
+ 0xf7, 0x02, 0xe3, 0x79, 0x02, 0x2e, 0x99, 0x16,
+ 0x17, 0x49, 0xe6, 0xbe, 0x8e, 0xb7, 0x9d, 0x51,
+ 0x97, 0x99, 0xaa, 0xe0, 0x7c, 0x18, 0x31, 0xbd,
+ 0x0e, 0xe7, 0x25, 0x50, 0xb8, 0x53, 0x33, 0xab,
+ 0x9e, 0x96, 0xa5, 0x33, 0xe2, 0x97, 0x25, 0xd7,
+ 0x02, 0x3d, 0x82, 0x1a, 0xbe, 0x1c, 0xe3, 0xa7,
+ 0x44, 0xbe, 0x02, 0xe0, 0x52, 0x56, 0x8f, 0x84,
+ 0xe6, 0xe3, 0xf7, 0x44, 0x42, 0xbb, 0xa5, 0x0d,
+ 0x02, 0xad, 0x2d, 0x6c, 0xa5, 0x8a, 0x69, 0x1f,
+ 0xd2, 0x43, 0x9a, 0xa3, 0xaf, 0x0c, 0x03, 0x3a,
+ 0x68, 0xc4, 0x38, 0xb2, 0xd9, 0xa0, 0xa0, 0x1d,
+ 0x78, 0xc4, 0xf8, 0x7c, 0x50, 0x9f, 0xea, 0x0a,
+ 0x43, 0x5b, 0xe7, 0x1b, 0xa2, 0x37, 0x06, 0xd6,
+ 0x08, 0x2d, 0xcb, 0xa6, 0x26, 0x25, 0x99, 0x9e,
+ 0xce, 0x09, 0xdf, 0xb3, 0xfc, 0xbe, 0x08, 0xeb,
+ 0xb6, 0xf2, 0x15, 0x1e, 0x2f, 0x12, 0xeb, 0xe8,
+ 0xa5, 0xbf, 0x11, 0x62, 0xc2, 0x59, 0xf2, 0x02,
+ 0xc1, 0xba, 0x47, 0x8b, 0x5f, 0x46, 0x8a, 0x28,
+ 0x69, 0xf1, 0xe7, 0x6c, 0xf5, 0xed, 0x38, 0xde,
+ 0x53, 0x86, 0x9a, 0xdc, 0x83, 0x70, 0x9e, 0x21,
+ 0xb3, 0xf8, 0xdc, 0x13, 0xba, 0x3d, 0x6a, 0xa7,
+ 0xf6, 0xb0, 0xcf, 0xb3, 0xe5, 0xa4, 0x3c, 0x23,
+ 0x72, 0xe0, 0xee, 0x60, 0x99, 0x1c, 0xe1, 0xca,
+ 0xd1, 0x22, 0xa3, 0x1d, 0x93, 0x97, 0xe3, 0x0b,
+ 0x92, 0x1f, 0xd2, 0xf6, 0xee, 0x69, 0x6e, 0x68,
+ 0x49, 0xae, 0xee, 0x29, 0xe2, 0xb4, 0x45, 0xc0,
+ 0xfd, 0x9a, 0xde, 0x65, 0x56, 0xc3, 0xc0, 0x69,
+ 0xc5, 0xd6, 0x05, 0x95, 0xab, 0xbd, 0xf5, 0xba,
+ 0xe2, 0xcc, 0xc7, 0x9a, 0x49, 0x6e, 0x83, 0xcc,
+ 0xab, 0x95, 0x74, 0x0e, 0xb8, 0xe4, 0xf2, 0x92,
+ 0x5d, 0xbf, 0x72, 0x97, 0xa8, 0xc9, 0x92, 0x75,
+ 0x6e, 0x62, 0x87, 0x0e, 0xdc, 0xe9, 0x8f, 0x6c,
+ 0xba, 0x1a, 0xa0, 0xd5, 0xb8, 0x6f, 0x09, 0x21,
+ 0x43, 0xb1, 0x6d, 0xa1, 0x44, 0x15, 0x47, 0xd1,
+ 0xd4, 0x2b, 0x80, 0x06, 0xfa, 0xce, 0x69, 0x5b,
+ 0x03, 0xfd, 0xfa, 0xe6, 0x45, 0xf9, 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,
+ 0xfc, 0x08, 0xcf, 0x5a, 0x91, 0x88, 0xb8, 0x2b,
+ 0x84, 0x0a, 0x00, 0x7d, 0x52, 0x72, 0x39, 0xea,
+ 0x3f, 0x0d, 0x7d, 0xd1, 0xf2, 0x51, 0x86, 0xec,
+ 0xae, 0x30, 0x87, 0x7d, 0xad, 0xa7, 0x7f, 0x24,
+ 0x3c, 0xdd, 0xb2, 0xc8, 0x8e, 0x99, 0x04, 0x82,
+ 0x7d, 0x3e, 0x09, 0x82, 0xda, 0x0d, 0x13, 0x91,
+ 0x1d, 0x0e, 0x2d, 0xbb, 0xbb, 0x2d, 0x01, 0x6c,
+ 0xbe, 0x4d, 0x06, 0x76, 0xb1, 0x45, 0x9d, 0xa8,
+ 0xc5, 0x3a, 0x91, 0x45, 0xe8, 0x3c, 0xf4, 0x2f,
+ 0x30, 0x11, 0x2c, 0xa6, 0x5d, 0x77, 0xc8, 0x93,
+ 0x4a, 0x26, 0xee, 0x00, 0x1f, 0x39, 0x0f, 0xfc,
+ 0xc1, 0x87, 0x03, 0x66, 0x2a, 0x8f, 0x71, 0xf9,
+ 0xda, 0x0e, 0x7b, 0x68, 0xb1, 0x04, 0x3c, 0x1c,
+ 0xb5, 0x26, 0x08, 0xcf, 0x0e, 0x69, 0x51, 0x0d,
+ 0x38, 0xc8, 0x0f, 0xa0, 0x0d, 0xe4, 0x3d, 0xef,
+ 0x98, 0x4d, 0xff, 0x2f, 0x32, 0x4e, 0xcf, 0x39,
+ 0x89, 0x44, 0x53, 0xd3, 0xe0, 0x1b, 0x3d, 0x7b,
+ 0x3b, 0xc0, 0x57, 0x04, 0x9d, 0x19, 0x5c, 0x8e,
+ 0xb9, 0x3f, 0xe4, 0xd9, 0x5a, 0x83, 0x00, 0xa5,
+ 0xe6, 0x0a, 0x7c, 0x89, 0xe4, 0x0c, 0x69, 0x16,
+ 0x79, 0xfb, 0xca, 0xfa, 0xd8, 0xeb, 0x41, 0x8f,
+ 0x8d, 0x1f, 0xf7, 0xb9, 0x11, 0x75, 0xf8, 0xeb,
+ 0x3c, 0x6f, 0xf2, 0x87, 0x2d, 0x32, 0xee, 0x4c,
+ 0x57, 0x36, 0x9e, 0x61, 0xb6, 0x6d, 0x16, 0x6f,
+ 0xd0, 0xa4, 0x34, 0x57, 0x47, 0x82, 0x75, 0xfe,
+ 0x14, 0xbf, 0x34, 0x63, 0x8a, 0x9e, 0x4e, 0x1d,
+ 0x25, 0xcc, 0x5a, 0x5f, 0x9e, 0x25, 0x7e, 0x61,
+ 0x7a, 0xdc, 0xdd, 0xe6, 0x5e, 0x25, 0x57, 0x40,
+ 0x53, 0x62, 0xc8, 0x91, 0xe6, 0x54, 0x6a, 0x6d,
+ 0xee, 0xaa, 0x8f, 0xc0, 0x3b, 0x12, 0x2a, 0x55,
+ 0x87, 0x4d, 0x33, 0xe0, 0xa7, 0x73, 0x52, 0x34,
+ 0x68, 0x32, 0x5e, 0xc2, 0x4d, 0x4f, 0xaf, 0xfb,
+ 0x63, 0xc0, 0x52, 0xc8, 0x11, 0xa1, 0xc0, 0x22,
+ 0xba, 0xfc, 0xcb, 0x97, 0x98, 0x8b, 0x7e, 0x45,
+ 0x67, 0xb2, 0x47, 0xd4, 0x04, 0x4b, 0x05, 0x2f,
+ 0xf7, 0x3f, 0x4c, 0x67, 0x1d, 0x27, 0xe0, 0x52,
+ 0xe2, 0xeb, 0xc7, 0x2d, 0x00, 0x57, 0xcb, 0x21,
+ 0x7c, 0x52, 0x59, 0xb6, 0x09, 0x50, 0xe3, 0xc8,
+ 0xb3, 0xd9, 0xe3, 0xe7, 0x63, 0x0f, 0x9e, 0xcb,
+ 0xe5, 0x48, 0xb9, 0xe3, 0x62, 0x20, 0xf3, 0x3c,
+ 0x2b, 0x45, 0x68, 0x30, 0x7c, 0xd0, 0x37, 0x5b,
+ 0xba, 0x13, 0x35, 0xe5, 0x8b, 0xfb, 0xcd, 0xe8,
+ 0x5c, 0xc8, 0x4c, 0x9c, 0x9c, 0x1c, 0xe7, 0x4f,
+ 0x44, 0xb2, 0x8e, 0xa1, 0xb6, 0x97, 0x30, 0x5b,
+ 0xb6, 0xba, 0x3b, 0x46, 0x4e, 0x5a, 0xb7, 0x45,
+ 0x01, 0x29, 0x3e, 0xf9, 0x15, 0x2c, 0x0f, 0x5d,
+ 0x33, 0x07, 0xd2, 0x6a, 0x1f, 0x07, 0x41, 0xc5,
+ 0xe5, 0x72, 0x1a, 0x71, 0x3d, 0x1b, 0x86, 0xc1,
+ 0x80, 0x82, 0x11, 0xf5, 0x7a, 0xad, 0x09, 0xa9,
+ 0x50, 0xb6, 0x86, 0x30, 0xaf, 0xce, 0x4f, 0x0a,
+ 0xd9, 0xf3, 0x2e, 0x67, 0x69, 0xb5, 0xfe, 0x31,
+ 0x92, 0x9c, 0x44, 0x6f, 0x7a, 0x33, 0x55, 0xf4,
+ 0x58, 0x84, 0xc7, 0x48, 0xc9, 0x05, 0x54, 0x15,
+ 0xe6, 0x37, 0xd9, 0xad, 0x87, 0xd9, 0x4c, 0x46,
+ 0x57, 0xb1, 0xad, 0x03, 0x4c, 0xb1, 0x4d, 0x9a,
+ 0x72, 0xea, 0x74, 0x5f, 0xe5, 0x2d, 0x7a, 0x71,
+ 0x1b, 0xa4, 0x1c, 0xa0, 0x35, 0x85, 0x6a, 0x5a,
+ 0x44, 0x89, 0xa4, 0x27, 0x0b, 0xb3, 0x0d, 0x5b,
+ 0x63, 0xf4, 0x9c, 0x05, 0x12, 0xfe, 0xd4, 0xb4
+};
+
+/* XTS data -4- AES256 */
+unsigned char NIST_KEY_XTS_E4[] = {
+ 0x97, 0x09, 0x8b, 0x46, 0x5a, 0x44, 0xca, 0x75,
+ 0xe7, 0xa1, 0xc2, 0xdb, 0xfc, 0x40, 0xb7, 0xa6,
+ 0x1a, 0x20, 0xe3, 0x2c, 0x6d, 0x9d, 0xbf, 0xda,
+ 0x80, 0x72, 0x6f, 0xee, 0x10, 0x54, 0x1b, 0xab,
+ 0x47, 0x54, 0x63, 0xca, 0x07, 0xc1, 0xc1, 0xe4,
+ 0x49, 0x61, 0x73, 0x32, 0x14, 0x68, 0xd1, 0xab,
+ 0x3f, 0xad, 0x8a, 0xd9, 0x1f, 0xcd, 0xc6, 0x2a,
+ 0xbe, 0x07, 0xbf, 0xf8, 0xef, 0x96, 0x1b, 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, 0x49, 0x10,
+ 0xfb, 0x0c, 0x12, 0x0f, 0x41, 0x85, 0x71, 0x21,
+ 0x92, 0x6c, 0x05, 0x2f, 0xd6, 0x5a, 0x27, 0x8c,
+ 0xd2, 0xf0, 0xd9, 0x8d, 0xa5, 0x4e, 0xdf, 0xd5,
+ 0x08, 0x03, 0xa4, 0x2f, 0xbe, 0x6f, 0xd1, 0x33,
+ 0x58, 0x49, 0x00, 0xe8, 0xdc, 0x7a, 0x11, 0x52,
+ 0x39, 0x1f, 0x82, 0x2d, 0x76, 0xa7, 0x56, 0x68,
+ 0xcf, 0xce, 0x7f, 0x8d, 0xde, 0x20, 0x3e, 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, 0x29,
+ 0xe8, 0x73, 0xd6, 0x73, 0x47, 0x9f, 0x51, 0x16,
+ 0x73, 0x4f, 0xe0, 0x3e, 0xe3, 0x29, 0x65, 0xed,
+ 0xc4, 0x79, 0x35, 0xc0, 0xea, 0x99, 0xa0, 0x64,
+ 0xbd, 0x44, 0x4b, 0xec, 0x12, 0x5b, 0x2c, 0x78,
+ 0x9d, 0xb9, 0xde, 0x6d, 0x18, 0x35, 0x92, 0x05,
+ 0x3b, 0x48, 0xa8, 0x77, 0xa9, 0x5a, 0xc2, 0x55,
+ 0x9c, 0x3d, 0xdf, 0xc7, 0xb4, 0xdb, 0x99, 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,
+ 0xfd, 0x00, 0xdd, 0xcb, 0xe1, 0x1e, 0xb9, 0x7e,
+ 0x69, 0x87, 0x83, 0xbf, 0xa4, 0x05, 0x46, 0xe3,
+};
+
+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)
+{
+ VV_(printf("TWEAK \n"));
+ dump_array(tweak, tweak_length);
+ VV_(printf("Key \n"));
+ dump_array(key, key_length);
+ VV_(printf("Input Data\n"));
+ dump_array(input_data, data_length);
+ VV_(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);
+ *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)
+{
+ 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];
+ unsigned char tmp_tweak[tweak_length];
+ unsigned char expected_tweak[tweak_length];
+ unsigned char key[key_length];
+ unsigned char input_data[data_length];
+ unsigned char encrypt[data_length];
+ unsigned char decrypt[data_length];
+ unsigned char 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);
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(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) {
+ VV_(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 (!rc) {
+ VV_(printf("Encrypt:\n"));
+ dump_xts_data(tweak, tweak_length, key, key_length, input_data,
+ data_length, encrypt);
+ }
+
+ if (memcmp(result, encrypt, data_length)) {
+ VV_(printf("Encryption Result does not match the known ciphertext!\n"));
+ VV_(printf("Expected data:\n"));
+ dump_array(result, data_length);
+ VV_(printf("Encryption Result:\n"));
+ dump_array(encrypt, data_length);
+ rc++;
+ }
+
+ if (memcmp(expected_tweak, tmp_tweak, tweak_length)) {
+ VV_(printf("Update of TWEAK does not match the expected TWEAK!\n"));
+ VV_(printf("Expected TWEAK:\n"));
+ dump_array(expected_tweak, tweak_length);
+ VV_(printf("Updated TWEAK:\n"));
+ dump_array(tmp_tweak, tweak_length);
+ VV_(printf("Original TWEAK:\n"));
+ dump_array(tweak, tweak_length);
+ rc++;
+ }
+ if (rc) {
+ VV_(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) {
+ VV_(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;
+ }
+
+
+ if (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_xts_data(tweak, tweak_length, key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(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) {
+ VV_(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) {
+ VV_(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) {
+ VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n",
+ rc, errno));
+ return rc;
+ }
+ return rc;
+}
+
+int random_aes_xts(int iteration, 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);
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(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) {
+ VV_(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 (!rc) {
+ VV_(printf("Encrypt:\n"));
+ dump_xts_data(iv, iv_length, key, key_length, input_data,
+ data_length, encrypt);
+ }
+
+ if (rc) {
+ VV_(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) {
+ VV_(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 (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_xts_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(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)
+{
+ int rc = 0;
+ int error_count = 0;
+ int iteration;
+ unsigned int data_length = sizeof(ica_aes_vector_t);
+
+ set_verbosity(argc, argv);
+
+ for(iteration = 1; iteration <= NR_TESTS; iteration++) {
+ rc = kat_aes_xts(iteration);
+ if (rc) {
+ V_(printf("kat_aes_xts failed with rc = %i\n", rc));
+ error_count++;
+ }
+
+ }
+ for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) {
+ rc = random_aes_xts(iteration, data_length);
+ if (rc) {
+ V_(printf("random_aes_xts failed with rc = %i\n", rc));
+ error_count++;
+ goto out;
+ }
+ data_length += sizeof(ica_aes_vector_t) / 2;
+ }
+
+out:
+ if (error_count)
+ printf("%i AES-XTS tests failed.\n", error_count);
+ else
+ printf("All AES-XTS tests passed.\n");
+
+ return rc;
+}
+
diff --git a/src/tests/libica_cbccs_test.c b/src/tests/libica_cbccs_test.c
new file mode 100644
index 0000000..bd2b088
--- /dev/null
+++ b/src/tests/libica_cbccs_test.c
@@ -0,0 +1,548 @@
+/* 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. 2010 */
+#include <fcntl.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include "ica_api.h"
+#include <stdlib.h>
+#include <openssl/aes.h>
+#include "testcase.h"
+
+/* CBC_CS data */
+unsigned char NIST_KEY[] = {
+ 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20,
+ 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69
+};
+unsigned int key_size[6] = { 24, 24, 24, 32, 32, 32 };
+unsigned char key[6][256] = {
+ {
+ 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20,
+ 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69,
+ 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20
+ },{
+ 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20,
+ 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69,
+ 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20
+ },{
+ 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20,
+ 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69,
+ 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20
+ },{
+ 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20,
+ 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69,
+ 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20,
+ 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69
+ },{
+ 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20,
+ 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69,
+ 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20,
+ 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69
+ },{
+ 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20,
+ 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69,
+ 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20,
+ 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69
+ }
+};
+
+unsigned char key_512[] = {
+ 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20,
+ 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69,
+ 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20,
+ 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69,
+ 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20,
+ 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69
+};
+
+unsigned char NIST_IV[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+unsigned int NIST_TEST_DATA_LENGTH[6] = { 17, 31, 32, 47, 48, 64 };
+unsigned char NIST_TEST_DATA[6][100] = {
+ { 0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20,
+ 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20
+ },{
+ 0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20,
+ 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65,
+ 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c,
+ 0x20, 0x47, 0x61, 0x75, 0x27, 0x73, 0x20
+ },{
+ 0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20,
+ 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65,
+ 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c,
+ 0x20, 0x47, 0x61, 0x75, 0x27, 0x73, 0x20, 0x43
+ },{
+ 0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20,
+ 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65,
+ 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c,
+ 0x20, 0x47, 0x61, 0x75, 0x27, 0x73, 0x20, 0x43,
+ 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x2c, 0x20,
+ 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x2c
+ },{
+ 0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20,
+ 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65,
+ 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c,
+ 0x20, 0x47, 0x61, 0x75, 0x27, 0x73, 0x20, 0x43,
+ 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x2c, 0x20,
+ 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x2c, 0x20
+ },{
+ 0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20,
+ 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65,
+ 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c,
+ 0x20, 0x47, 0x61, 0x75, 0x27, 0x73, 0x20, 0x43,
+ 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x2c, 0x20,
+ 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x2c, 0x20,
+ 0x61, 0x6e, 0x64, 0x20, 0x77, 0x6f, 0x6e, 0x74,
+ 0x6f, 0x6e, 0x20, 0x73, 0x6f, 0x75, 0x70, 0x2e
+ }
+};
+
+unsigned char NIST_TEST_RESULT[6][100] = {
+ {
+ 0xc6, 0x35, 0x35, 0x68, 0xf2, 0xbf, 0x8c, 0xb4,
+ 0xd8, 0xa5, 0x80, 0x36, 0x2d, 0xa7, 0xff, 0x7f, 0x97
+ },{
+ 0xfc, 0x00, 0x78, 0x3e, 0x0e, 0xfd, 0xb2, 0xc1,
+ 0xd4, 0x45, 0xd4, 0xc8, 0xef, 0xf7, 0xed, 0x22,
+ 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
+ 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5
+ },{
+ 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5,
+ 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8,
+ 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
+ 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84
+ },{
+ 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
+ 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84,
+ 0xb3, 0xff, 0xfd, 0x94, 0x0c, 0x16, 0xa1, 0x8c,
+ 0x1b, 0x55, 0x49, 0xd2, 0xf8, 0x38, 0x02, 0x9e,
+ 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5,
+ 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5
+ },{
+ 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
+ 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84,
+ 0x9d, 0xad, 0x8b, 0xbb, 0x96, 0xc4, 0xcd, 0xc0,
+ 0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8,
+ 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5,
+ 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8
+ },{
+ 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
+ 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84,
+ 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5,
+ 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8,
+ 0x48, 0x07, 0xef, 0xe8, 0x36, 0xee, 0x89, 0xa5,
+ 0x26, 0x73, 0x0d, 0xbc, 0x2f, 0x7b, 0xc8, 0x40,
+ 0x9d, 0xad, 0x8b, 0xbb, 0x96, 0xc4, 0xcd, 0xc0,
+ 0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8
+ }
+};
+
+unsigned char NIST_NEXT_IV[6][16] = {
+ {
+ 0xc6, 0x35, 0x35, 0x68, 0xf2, 0xbf, 0x8c, 0xb4,
+ 0xd8, 0xa5, 0x80, 0x36, 0x2d, 0xa7, 0xff, 0x7f
+ },{
+ 0xfc, 0x00, 0x78, 0x3e, 0x0e, 0xfd, 0xb2, 0xc1,
+ 0xd4, 0x45, 0xd4, 0xc8, 0xef, 0xf7, 0xed, 0x22
+ },{
+ 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5,
+ 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8
+ },{
+ 0xb3, 0xff, 0xfd, 0x94, 0x0c, 0x16, 0xa1, 0x8c,
+ 0x1b, 0x55, 0x49, 0xd2, 0xf8, 0x38, 0x02, 0x9e
+ },{
+ 0x9d, 0xad, 0x8b, 0xbb, 0x96, 0xc4, 0xcd, 0xc0,
+ 0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8
+ },{
+ 0x48, 0x07, 0xef, 0xe8, 0x36, 0xee, 0x89, 0xa5,
+ 0x26, 0x73, 0x0d, 0xbc, 0x2f, 0x7b, 0xc8, 0x40
+ }
+};
+
+int compare_decrypt_result_with_expected_result(
+ unsigned char *, unsigned char *,
+ unsigned int, unsigned char *,
+ unsigned int, unsigned char *,
+ unsigned int, char *,
+ unsigned int);
+
+inline int compare_decrypt_result_with_expected_result(
+ unsigned char * decrypt_out,
+ unsigned char * expected_result,
+ unsigned int compare_length,
+ unsigned char * key,
+ unsigned int key_length,
+ unsigned char * iv,
+ unsigned int iv_size,
+ char * out_text,
+ unsigned int test_case_number)
+{
+ if (memcmp(decrypt_out, expected_result, compare_length) != 0) {
+ VV_(printf("This does NOT match the original data.\n"));
+ VV_(printf("Test case number %i for %s with CBC_CS mode failed\n",
+ test_case_number, out_text));
+ VV_(printf("\nkey \n"));
+ dump_array(key, key_length);
+ VV_(printf("\nOriginal data:\n"));
+ dump_array(expected_result, compare_length);
+ VV_(printf("\ntmp iv\n"));
+ dump_array(iv, iv_size);
+ VV_(printf("\nExpected Result:\n"));
+ dump_array(expected_result, compare_length);
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array(decrypt_out, compare_length);
+ return 1;
+ }
+ return 0;
+}
+
+
+int test_3des_new_api(unsigned int mode, unsigned int variant)
+{
+ /* Test 3des */
+ unsigned int iv_size = sizeof(ica_des_vector_t);
+ unsigned char iv[iv_size];
+ unsigned char tmp_iv[iv_size];
+ unsigned char enc_text[100] ,dec_text[100] ;
+ unsigned int number_of_testcases = 6;
+ int rc = 0, i = 0;
+
+ for (i = 0; i < number_of_testcases ; i++) {
+ memcpy(tmp_iv, NIST_IV, iv_size);
+ rc = ica_3des_cbc_cs(NIST_TEST_DATA[i], enc_text,
+ NIST_TEST_DATA_LENGTH[i], key[i],
+ tmp_iv, 1, variant);
+ if (rc) {
+ VV_(printf("key \n"));
+ dump_array(key[i], 8);
+ VV_(printf("\nOriginal data:\n"));
+ dump_array(NIST_TEST_DATA[i],
+ NIST_TEST_DATA_LENGTH[i]);
+ VV_(printf("\ntest iv\n"));
+ dump_array(tmp_iv, iv_size);
+ VV_(printf("\nica_3des_cbc_cs encrypt test %i failed with "
+ "errno %d (0x%x).\n", i, rc, rc));
+ return 1;
+ }
+ memcpy(tmp_iv, NIST_IV, iv_size);
+ memset(dec_text,0,NIST_TEST_DATA_LENGTH[i]);
+ rc = ica_3des_cbc_cs(enc_text, dec_text,
+ NIST_TEST_DATA_LENGTH[i], key[i],
+ tmp_iv, 0, variant);
+ if (rc) {
+ VV_(printf("key \n"));
+ dump_array(key[i], 8);
+ VV_(printf("\nOriginal data:\n"));
+ dump_array(NIST_TEST_DATA[i],
+ NIST_TEST_DATA_LENGTH[i]);
+ VV_(printf("\noriginal iv\n"));
+ dump_array(iv, iv_size);
+ VV_(printf("\ntmp iv\n"));
+ dump_array(tmp_iv, iv_size);
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array(enc_text, NIST_TEST_DATA_LENGTH[i]);
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array(dec_text, NIST_TEST_DATA_LENGTH[i]);
+ VV_(printf("\nica_3des_cbc_cs decrypt test %i failed with "
+ "errno %d (0x%x).\n", i, rc, rc));
+ return 1;
+ }
+ if (compare_decrypt_result_with_expected_result(dec_text,
+ NIST_TEST_DATA[i], NIST_TEST_DATA_LENGTH[i],
+ key[i], 24, tmp_iv, iv_size,
+ (char *) "3DES", i))
+ return 1;
+ else {
+ VV_(printf("Test case number %i for 3DES with CBC_CS mode was "
+ "successful!\n", i));
+ }
+ }
+ return rc;
+}
+int test_des_new_api(unsigned int mode, unsigned int variant)
+{
+ /* Test des */
+ unsigned int iv_size = sizeof(ica_des_vector_t);
+ unsigned char iv[iv_size];
+ unsigned char tmp_iv[iv_size];
+ unsigned char enc_text[100] ,dec_text[100] ;
+ unsigned int number_of_testcases = 6;
+ int rc = 0, i = 0;
+
+#ifdef ICA_FIPS
+ if (ica_fips_status() & ICA_FIPS_MODE) {
+ printf("All DES-CBC-CS tests skipped."
+ " (DES not FIPS approved)\n");
+ return 0;
+ }
+#endif /* ICA_FIPS */
+
+ for (i = 0; i < number_of_testcases ; i++) {
+ memcpy(tmp_iv, NIST_IV, iv_size);
+ rc = ica_des_cbc_cs(NIST_TEST_DATA[i], enc_text,
+ NIST_TEST_DATA_LENGTH[i], key[i],
+ tmp_iv, 1, variant);
+ if (rc) {
+ VV_(printf("key \n"));
+ dump_array(key[i], 8);
+ VV_(printf("\nOriginal data:\n"));
+ dump_array(NIST_TEST_DATA[i],
+ NIST_TEST_DATA_LENGTH[i]);
+ VV_(printf("\ntest iv\n"));
+ dump_array(tmp_iv, iv_size);
+ VV_(printf("\nica_des_cbc_cs encrypt test %i failed with "
+ "errno %d (0x%x).\n", i, rc, rc));
+ return 1;
+ }
+ memcpy(tmp_iv, NIST_IV, iv_size);
+ memset(dec_text,0,NIST_TEST_DATA_LENGTH[i]);
+ rc = ica_des_cbc_cs(enc_text, dec_text,
+ NIST_TEST_DATA_LENGTH[i], key[i],
+ tmp_iv, 0, variant);
+ if (rc) {
+ VV_(printf("key \n"));
+ dump_array(key[i], 8);
+ VV_(printf("\nOriginal data:\n"));
+ dump_array(NIST_TEST_DATA[i],
+ NIST_TEST_DATA_LENGTH[i]);
+ VV_(printf("\noriginal iv\n"));
+ dump_array(iv, iv_size);
+ VV_(printf("\ntmp iv\n"));
+ dump_array(tmp_iv, iv_size);
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array(enc_text, NIST_TEST_DATA_LENGTH[i]);
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array(dec_text, NIST_TEST_DATA_LENGTH[i]);
+ VV_(printf("\nica_des_cbc_cs decrypt test %i failed with "
+ "errno %d (0x%x).\n", i, rc, rc));
+ return 1;
+ }
+ if (compare_decrypt_result_with_expected_result(
+ dec_text, NIST_TEST_DATA[i],
+ NIST_TEST_DATA_LENGTH[i], key[i],
+ (sizeof(key[i]) / 8), tmp_iv, iv_size,
+ (char *) "DES", i))
+ return 1;
+ else {
+ VV_(printf("Test case number %i for DES with CBC_CS mode was "
+ "successful!\n", i));
+ }
+ }
+ return rc;
+}
+int test_aes_new_api(unsigned int mode, unsigned int variant)
+{
+ /* Test with 192 & 256 byte keys */
+ unsigned int iv_size = sizeof(ica_aes_vector_t);
+ unsigned char iv[iv_size];
+ unsigned char tmp_iv[iv_size];
+ char text[2][8] = {
+ { 0x41, 0x45, 0x53, 0x2d, 0x31, 0x39, 0x32, 0x00 },
+ { 0x41, 0x45, 0x53, 0x2d, 0x32, 0x35, 0x36, 0x00 }};
+ unsigned char enc_text[100] ,dec_text[100] ;
+ unsigned int number_of_testcases = 6;
+
+ int rc = 0, i = 0;
+
+ for (i = 0; i < number_of_testcases ; i++) {
+ memcpy(tmp_iv, NIST_IV, iv_size);
+ rc = ica_aes_cbc_cs(NIST_TEST_DATA[i], enc_text,
+ NIST_TEST_DATA_LENGTH[i], key[i],
+ key_size[i], tmp_iv, 1, variant);
+ if (rc) {
+ VV_(printf("key \n"));
+ dump_array(key[i], key_size[i]);
+ VV_(printf("\nOriginal data:\n"));
+ dump_array(NIST_TEST_DATA[i],
+ NIST_TEST_DATA_LENGTH[i]);
+ VV_(printf("\ntest iv\n"));
+ dump_array(tmp_iv, iv_size);
+ VV_(printf("\nica_aes_cbc_cs encrypt test %i failed with "
+ " errno %d (0x%x).\n", i, rc, rc));
+ return 1;
+ }
+ memcpy(tmp_iv, NIST_IV, iv_size);
+ memset(dec_text,0,NIST_TEST_DATA_LENGTH[i]);
+ rc = ica_aes_cbc_cs(enc_text, dec_text,
+ NIST_TEST_DATA_LENGTH[i], key[i],
+ key_size[i], tmp_iv, 0, variant);
+ if (rc) {
+ VV_(printf("key \n"));
+ dump_array(key[i], key_size[i]);
+ VV_(printf("\nOriginal data:\n"));
+ dump_array(NIST_TEST_DATA[i],
+ NIST_TEST_DATA_LENGTH[i]);
+ VV_(printf("\noriginal iv\n"));
+ dump_array(iv, iv_size);
+ VV_(printf("\ntmp iv\n"));
+ dump_array(tmp_iv, iv_size);
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array(enc_text, NIST_TEST_DATA_LENGTH[i]);
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array(dec_text, NIST_TEST_DATA_LENGTH[i]);
+ VV_(printf("\nica_aes_cbc_cs decrypt test %i failed with "
+ "errno %d (0x%x).\n", i, rc, rc));
+ return 1;
+ }
+ if (compare_decrypt_result_with_expected_result(dec_text,
+ NIST_TEST_DATA[i], NIST_TEST_DATA_LENGTH[i],
+ key[i], key_size[i], tmp_iv, iv_size,
+ (i < 3) ? text[0] : text[1], i))
+ return 1;
+ else {
+ VV_(printf("Test case number %i for %s with CBC_CS mode was "
+ "successful!\n", i, (i < 3) ? text[0] : text[1]));
+ }
+ }
+ return rc;
+}
+
+int test_aes128_new_api(unsigned int mode)
+{
+ /* AES128 Known Answer Tests*/
+ unsigned int iv_size = sizeof(ica_aes_vector_t);
+ unsigned int key_size = AES_KEY_LEN128;
+ unsigned char iv[iv_size];
+ unsigned char tmp_iv[iv_size];
+ unsigned char key[key_size];
+ unsigned char enc_text[100] ,dec_text[100] ;
+ unsigned int number_of_testcases = 6;
+ int rc = 0, i = 0;
+
+ memcpy(key, NIST_KEY, sizeof(key));
+ for (i = 0; i < number_of_testcases ; i++) {
+ memcpy(tmp_iv, NIST_IV, iv_size);
+ rc = ica_aes_cbc_cs(NIST_TEST_DATA[i], enc_text,
+ NIST_TEST_DATA_LENGTH[i], key,
+ sizeof(key), tmp_iv, 1, ICA_CBCCS_VARIANT3);
+ if (rc) {
+ VV_(printf("key \n"));
+ dump_array(key, sizeof(key));
+ VV_(printf("\nOriginal data:\n"));
+ dump_array(NIST_TEST_DATA[i],
+ NIST_TEST_DATA_LENGTH[i]);
+ VV_(printf("\ntest iv\n"));
+ dump_array(tmp_iv, iv_size);
+ VV_(printf("\nica_aes_cbc_cs encrypt test %i failed with "
+ "errno %d (0x%x).\n", i, rc, rc));
+ return 1;
+ }
+
+ if (compare_decrypt_result_with_expected_result(enc_text,
+ NIST_TEST_RESULT[i], NIST_TEST_DATA_LENGTH[i],
+ key, sizeof(key), tmp_iv, iv_size,
+ (char *) "AES-128", i))
+ return 1;
+
+ if (compare_decrypt_result_with_expected_result(tmp_iv,
+ NIST_NEXT_IV[i], iv_size,
+ key, sizeof(key), tmp_iv, iv_size,
+ (char *) "AES-128", i))
+ return 1;
+
+ memcpy(tmp_iv, NIST_IV, iv_size);
+ memset(dec_text,0,NIST_TEST_DATA_LENGTH[i]);
+ rc = ica_aes_cbc_cs(enc_text, dec_text,
+ NIST_TEST_DATA_LENGTH[i], key, sizeof(key),
+ tmp_iv, 0, ICA_CBCCS_VARIANT3);
+ if (rc) {
+ VV_(printf("key \n"));
+ dump_array(key, sizeof(key));
+ VV_(printf("\nOriginal data:\n"));
+ dump_array(NIST_TEST_DATA[i],
+ NIST_TEST_DATA_LENGTH[i]);
+ VV_(printf("\noriginal iv\n"));
+ dump_array(iv, iv_size);
+ VV_(printf("\ntmp iv\n"));
+ dump_array(tmp_iv, iv_size);
+ VV_(printf("\nkey\n"));
+ dump_array(key, sizeof(key));
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array(enc_text, NIST_TEST_DATA_LENGTH[i]);
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array(dec_text, NIST_TEST_DATA_LENGTH[i]);
+ VV_(printf("\nica_aes_cbc_cs decrypt test %i failed"
+ "with errno %d (0x%x).\n", i, rc, rc));
+ return 1;
+ }
+
+ if (compare_decrypt_result_with_expected_result(dec_text,
+ NIST_TEST_DATA[i], NIST_TEST_DATA_LENGTH[i],
+ key, sizeof(key), tmp_iv, iv_size,
+ (char *) "AES-128", i))
+ return 1;
+ else {
+ VV_(printf("Test case number %i for AES-128 with CBC_CS "
+ "mode was successful!\n", i));
+ }
+ }
+ return rc;
+}
+
+int main(int argc, char **argv)
+{
+ unsigned int mode;
+ unsigned int variant;
+ int rc, error_count;
+
+ set_verbosity(argc, argv);
+
+ mode = MODE_CBCCS;
+ rc = 0;
+ error_count = 0;
+
+ /* known answer tests for AES128 */
+ rc = test_aes128_new_api(mode);
+ if (rc) {
+ error_count++;
+ printf("test_aes128_new_api for CBC_CS mode with AES-128 "
+ "failed.\n");
+ return rc;
+ }
+
+ for (variant = ICA_CBCCS_VARIANT1;
+ variant <= ICA_CBCCS_VARIANT3;
+ variant++) {
+ VV_(printf("\n--- Test cycle with CBCCS variant %d ---\n", variant));
+ /* AES 192 & 256 test */
+ rc = test_aes_new_api(mode, variant);
+ if (rc) {
+ error_count++;
+ printf("test_aes_new_api for CBC_CS mode with AES (192|256) "
+ "failed.\n");
+ return rc;
+ }
+
+ /* DES tests */
+ rc = test_des_new_api(mode, variant);
+ if (rc) {
+ error_count++;
+ printf("test_des_new_api for CBC_CS mode with DES "
+ "failed.\n");
+ return rc;
+ }
+
+ /* 3DES tests */
+ rc = test_3des_new_api(mode, variant);
+ if (rc) {
+ error_count++;
+ printf("test_des_new_api for CBC_CS mode with 3DES "
+ "failed.\n");
+ return rc;
+ }
+ }
+
+ printf("All CBC-CS tests passed.\n");
+ return rc;
+}
+
diff --git a/src/tests/libica_ccm_test.c b/src/tests/libica_ccm_test.c
new file mode 100644
index 0000000..c1e2b93
--- /dev/null
+++ b/src/tests/libica_ccm_test.c
@@ -0,0 +1,179 @@
+/* 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. 2011 */
+
+#include <fcntl.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ica_api.h"
+#include "testcase.h"
+
+#define BYTE 8
+
+#define NUM_CCM_TESTS 4
+unsigned char input_data[1000000];
+unsigned char parameter_block[32];
+unsigned char *to = parameter_block;
+
+unsigned int key_length[4] = {16, 16, 16, 16};
+unsigned char key[4][16] = {
+{0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f },
+{0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f },
+{0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f },
+{0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f }};
+
+#define CASE3_ASSOC_LEN 256
+/* Number of bytes in string for case 3 */
+
+unsigned int assoc_data_length[4] = {8, 16, 20, 65536};
+unsigned char assoc_data[4][65536] = {
+{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 },
+{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f },
+{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+ 0x10,0x11,0x12,0x13 }};
+unsigned int i = 0;
+unsigned char repeated_string[256] = {
+0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
+0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
+0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
+0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,
+0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
+0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
+0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
+0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
+0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
+0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
+0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,
+0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf,
+0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,
+0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff};
+unsigned int payload_length[4] = {4, 16, 24, 32};
+unsigned char payload[4][32] = {
+{ 0x20,0x21,0x22,0x23 },
+{ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f},
+{ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
+ 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37 },
+{ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f ,
+ 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f }};
+
+unsigned char payload_after_decrypt[4][32] = {
+{ 0x20,0x21,0x22,0x23 },
+{ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f},
+{ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
+ 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37 },
+{ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f ,
+ 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f }};
+unsigned int nonce_length[4] = {7,8,12,13};
+unsigned char nonce[4][13] = {
+{ 0x10,0x11,0x12,0x13,0x14,0x15,0x16},
+{ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17},
+{ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b},
+{ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c}};
+
+unsigned int cbc_mac_length[4] = {4, 6, 8, 14};
+
+unsigned int cipher_text_length[4] = {8, 22, 32, 46};
+unsigned char cipher_text[4][46] = {
+{ 0x71,0x62,0x01,0x5b,0x4d,0xac,0x25,0x5d },
+{ 0xd2,0xa1,0xf0,0xe0,0x51,0xea,0x5f,0x62,0x08,0x1a,0x77,0x92,0x07,0x3d,0x59,0x3d,
+ 0x1f,0xc6,0x4f,0xbf,0xac,0xcd },
+{ 0xe3,0xb2,0x01,0xa9,0xf5,0xb7,0x1a,0x7a,0x9b,0x1c,0xea,0xec,0xcd,0x97,0xe7,0x0b,
+ 0x61,0x76,0xaa,0xd9,0xa4,0x42,0x8a,0xa5,0x48,0x43,0x92,0xfb,0xc1,0xb0,0x99,0x51},
+{0x69,0x91,0x5d,0xad,0x1e,0x84,0xc6,0x37,0x6a,0x68,0xc2,0x96,0x7e,0x4d,0xab,0x61,
+ 0x5a,0xe0,0xfd,0x1f,0xae,0xc4,0x4c,0xc4,0x84,0x82,0x85,0x29,0x46,0x3c,0xcf,0x72,
+ 0xb4,0xac,0x6b,0xec,0x93,0xe8,0x59,0x8e,0x7f,0x0d,0xad,0xbc,0xea,0x5b}
+};
+
+int api_ccm_test(void)
+{
+ unsigned char *out_data;
+ int rc = 0;
+
+ VV_(printf("Test of CCM api\n"));
+ while ( i < 65536 ) { // init big assoc_data
+ memcpy(assoc_data[3] + i, repeated_string, 256);
+ i= i + 256;
+ }
+ for (i = 0; i < NUM_CCM_TESTS; i++) {
+ VV_(printf("\nOriginal data for test %d:\n", i));
+ if (!(out_data = malloc(cipher_text_length[i])))
+ return EINVAL;
+ memset(out_data, 0, cipher_text_length[i]);
+ rc = (ica_aes_ccm(payload[i], payload_length[i],
+ out_data,
+ cbc_mac_length[i],
+ assoc_data[i], assoc_data_length[i],
+ nonce[i], nonce_length[i],
+ key[i], key_length[i],
+ ICA_ENCRYPT));
+ if (rc) {
+ VV_(printf("icaccm encrypt failed with errno %d (0x%x).\n",
+ rc, rc));
+ return rc;
+ }
+ VV_(printf("\nOutput Cipher text for test %d:\n", i));
+ dump_array(out_data, cipher_text_length[i]);
+ VV_(printf("\nExpected Cipher Text for test %d:\n", i));
+ dump_array(cipher_text[i], cipher_text_length[i]);
+
+ if (memcmp(cipher_text[i], out_data, cipher_text_length[i]) != 0) {
+ printf("This does NOT match the known result.\n");
+ return 1;
+ }
+
+ VV_(printf("Yep, that's how it should be encrypted.\n"));
+ // start decrypt / verify
+ memset(payload[i], 0, payload_length[i]);
+ rc = (ica_aes_ccm(out_data, payload_length[i],
+ cipher_text[i], cbc_mac_length[i],
+ assoc_data[i], assoc_data_length[i],
+ nonce[i], nonce_length[i],
+ key[i], key_length[i],
+ ICA_DECRYPT));
+ if (rc) {
+ VV_(printf("icaccm decrypt failed with errno %d (0x%x).\n",
+ rc,rc));
+ return rc;
+ }
+
+ VV_(printf("\nOutput payload for test %d:\n", i));
+ dump_array(out_data, payload_length[i]);
+ VV_(printf("\nExpected payload for test %d:\n", i));
+ dump_array(payload_after_decrypt[i], payload_length[i]);
+
+ if (memcmp(out_data, payload_after_decrypt[i],
+ payload_length[i]) == 0 ) {
+ VV_(printf("Yep, payload matches to original.\n"));
+ } else {
+ VV_(printf("This does NOT match the known result.\n"));
+ return 1;
+ }
+ free(out_data);
+ }
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int rc = 0;
+
+ set_verbosity(argc, argv);
+
+ rc = api_ccm_test();
+ if (rc) {
+ printf("api_ccm_test failed with rc = %i.\n", rc);
+ return rc;
+ }
+ printf("All AES-CCM tests passed.\n");
+ return 0;
+}
+
+
diff --git a/src/tests/libica_cmac_test.c b/src/tests/libica_cmac_test.c
new file mode 100644
index 0000000..b8e5eb5
--- /dev/null
+++ b/src/tests/libica_cmac_test.c
@@ -0,0 +1,307 @@
+/* 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"
+#include "testcase.h"
+
+#define BYTE 8
+
+#define NUM_TESTS 12
+
+#define AES_BLOCK_SIZE 16
+
+unsigned int key_length[12] = {16, 16, 16, 16, 24, 24, 24, 24, 32, 32, 32,
+ 32};
+unsigned char key[12][32] = {{
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15,
+ 0x88, 0x09, 0xcf, 0x4f, 0x3c},{
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15,
+ 0x88, 0x09, 0xcf, 0x4f, 0x3c},{
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15,
+ 0x88, 0x09, 0xcf, 0x4f, 0x3c},{
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15,
+ 0x88, 0x09, 0xcf, 0x4f, 0x3c},{
+ 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10 ,0xf3,
+ 0x2b, 0x80, 0x90, 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c,
+ 0x6b, 0x7b},{
+ 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10 ,0xf3,
+ 0x2b, 0x80, 0x90, 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c,
+ 0x6b, 0x7b},{
+ 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10 ,0xf3,
+ 0x2b, 0x80, 0x90, 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c,
+ 0x6b, 0x7b},{
+ 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10 ,0xf3,
+ 0x2b, 0x80, 0x90, 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c,
+ 0x6b, 0x7b},{
+ 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},{
+ 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},{
+ 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},{
+ 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 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,
+ 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}
+};
+
+unsigned char expected_cmac[12][16] = {{
+ 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28, 0x7f, 0xa3, 0x7d,
+ 0x12, 0x9b, 0x75, 0x67, 0x46},{
+ 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, 0xf7, 0x9b, 0xdd,
+ 0x9d, 0xd0, 0x4a, 0x28, 0x7c},{
+ 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30, 0x30, 0xca, 0x32,
+ 0x61, 0x14, 0x97, 0xc8, 0x27},{
+ 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, 0xfc, 0x49, 0x74,
+ 0x17, 0x79, 0x36, 0x3c, 0xfe},{
+ 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5, 0x31, 0xca, 0xc4,
+ 0x83, 0xde, 0x7a, 0x93, 0x67},{
+ 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90, 0x06, 0x62, 0xf6,
+ 0x5e, 0x61, 0x7c, 0x51, 0x84},{
+ 0x8a, 0x1d, 0xe5, 0xbe, 0x2e, 0xb3, 0x1a, 0xad, 0x08, 0x9a, 0x82,
+ 0xe6, 0xee, 0x90, 0x8b, 0x0e},{
+ 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79, 0x4d, 0x77, 0x58,
+ 0x96, 0x59, 0xf3, 0x9a, 0x11},{
+ 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e, 0xfc, 0x6b, 0x55,
+ 0x1f, 0x46, 0x67, 0xd9, 0x83},{
+ 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82, 0xbd, 0x4b, 0xf2,
+ 0x8d, 0x8c, 0x37, 0xc3, 0x5c},{
+ 0xaa, 0xf3, 0xd8, 0xf1, 0xde, 0x56, 0x40, 0xc2, 0x32, 0xf5, 0xb1,
+ 0x69, 0xb9, 0xc9, 0x11, 0xe6},{
+ 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5, 0x69, 0x6a, 0x2c,
+ 0x05, 0x6c, 0x31, 0x54, 0x10}
+};
+
+unsigned int ica_aes_cmac_chaining(unsigned char *, unsigned long,
+ unsigned char *, unsigned int,
+ unsigned char *, unsigned int,
+ unsigned int);
+
+unsigned int i = 0;
+
+unsigned char *cmac;
+unsigned int cmac_length = 16;
+
+int api_cmac_test(void)
+{
+ int rc = 0;
+
+ VV_(printf("Test of CMAC api\n"));
+ 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) {
+ VV_(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) {
+ VV_(printf("This does NOT match the known result. "
+ "Testcase %i failed\n",i));
+ VV_(printf("\nOutput MAC for test %d:\n", i));
+ dump_array((unsigned char *)cmac, cmac_length);
+ VV_(printf("\nExpected MAC for test %d:\n", i));
+ dump_array((unsigned char *)expected_cmac[i], 16);
+ free(cmac);
+ return 1;
+ }
+ VV_(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) {
+ VV_(printf("ica_aes_cmac verify failed with errno %d (0x%x).\n",
+ rc, rc));
+ free(cmac);
+ return rc;
+ }
+ free(cmac);
+ if (!rc) {
+ VV_(printf("MAC was successful verified. Test %i "
+ "succeeded\n",i));
+ }
+ else {
+ printf("MAC verification failed for test %i "
+ "with RC=%i\n",i,rc);
+ return rc;
+ }
+ }
+ return 0;
+}
+
+
+inline unsigned int ica_aes_cmac_chaining(unsigned char *in,
+ unsigned long in_length,
+ unsigned char *cmac,
+ unsigned int cmac_length,
+ unsigned char *key,
+ unsigned int key_length,
+ unsigned int direction)
+{
+ unsigned char *last_block = NULL;
+ unsigned long tmp_length;
+ unsigned char tmp_iv[AES_BLOCK_SIZE];
+ unsigned int rc;
+
+ memset(tmp_iv, 0x00, AES_BLOCK_SIZE);
+
+ for (last_block = in, tmp_length = in_length;
+ tmp_length > (AES_BLOCK_SIZE);
+ last_block += AES_BLOCK_SIZE, tmp_length -= AES_BLOCK_SIZE) {
+ rc = ica_aes_cmac_intermediate(last_block, AES_BLOCK_SIZE,
+ key, key_length,
+ tmp_iv);
+ if (rc)
+ return rc;
+ }
+
+ return ica_aes_cmac_last(last_block, tmp_length,
+ cmac, cmac_length,
+ key, key_length,
+ tmp_iv,
+ direction);
+}
+
+int api_cmac_chaining_test(void)
+{
+ int rc = 0;
+
+ VV_(printf("Test of CMAC chaining api\n"));
+ for (i = 0 ; i < NUM_TESTS; i++) {
+ if (!(cmac = malloc(cmac_length)))
+ return EINVAL;
+ memset(cmac, 0, cmac_length);
+ rc = ica_aes_cmac_chaining(message[i], mlen[i],
+ cmac, cmac_length,
+ key[i], key_length[i],
+ ICA_ENCRYPT);
+ if (rc) {
+ VV_(printf("ica_aes_cmac chaining generate failed with errno %d (0x%x)."
+ "\n",rc,rc));
+ return rc;
+ }
+ if (memcmp(cmac, expected_cmac[i], cmac_length) != 0) {
+ VV_(printf("This does NOT match the known result. "
+ "Testcase %i failed\n",i));
+ VV_(printf("\nOutput MAC for test %d:\n", i));
+ dump_array((unsigned char *)cmac, cmac_length);
+ VV_(printf("\nExpected MAC for test %d:\n", i));
+ dump_array((unsigned char *)expected_cmac[i], 16);
+ free(cmac);
+ return 1;
+ }
+ VV_(printf("Expected MAC has been generated.\n"));
+ rc = ica_aes_cmac_chaining(message[i], mlen[i],
+ cmac, cmac_length,
+ key[i], key_length[i],
+ ICA_DECRYPT);
+ if (rc) {
+ VV_(printf("ica_aes_cmac verify failed with errno %d (0x%x).\n",
+ rc, rc));
+ free(cmac);
+ return rc;
+ }
+ free(cmac);
+ if (!rc) {
+ VV_(printf("MAC was successful verified. Test %i "
+ "succeeded\n",i));
+ }
+ else {
+ VV_(printf("MAC verification failed for test %i "
+ "with RC=%i\n",i,rc));
+ return rc;
+ }
+ }
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int rc = 0;
+
+ set_verbosity(argc, argv);
+
+ rc = api_cmac_test();
+ if (rc) {
+ printf("api_cmac_test failed with rc = %i\n", rc);
+ return rc;
+ }
+
+ rc = api_cmac_chaining_test();
+ if (rc) {
+ printf("api_cmac_test failed with rc = %i\n", rc);
+ return rc;
+ }
+
+ printf("All CMAC tests passed.\n");
+ return 0;
+}
diff --git a/src/tests/libica_des_cbc_test.c b/src/tests/libica_des_cbc_test.c
new file mode 100644
index 0000000..70d2ff7
--- /dev/null
+++ b/src/tests/libica_des_cbc_test.c
@@ -0,0 +1,320 @@
+/* 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"
+#include "testcase.h"
+
+#define NR_TESTS 1
+#define NR_RANDOM_TESTS 10000
+
+/* CBC data - 1 for DES128 */
+unsigned char NIST_KEY_CBC_E1[] = {
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+};
+
+unsigned char NIST_IV_CBC_E1[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+unsigned char NIST_EXPECTED_IV_CBC_E1[] = {
+ 0x95, 0xf8, 0xa5, 0xe5, 0xdd, 0x31, 0xd9, 0x00,
+};
+
+unsigned char NIST_TEST_DATA_CBC_E1[] = {
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+unsigned char NIST_TEST_RESULT_CBC_E1[] = {
+ 0x95, 0xf8, 0xa5, 0xe5, 0xdd, 0x31, 0xd9, 0x00,
+};
+
+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)
+{
+ VV_(printf("IV \n"));
+ dump_array(iv, iv_length);
+ VV_(printf("Key \n"));
+ dump_array(key, key_length);
+ VV_(printf("Input Data\n"));
+ dump_array(input_data, data_length);
+ VV_(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_CBC_E1);
+ *iv_length = sizeof(NIST_IV_CBC_E1);
+ *key_length = sizeof(NIST_KEY_CBC_E1);
+ 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_CBC_E1, data_length);
+ memcpy(result, NIST_TEST_RESULT_CBC_E1, data_length);
+ memcpy(iv, NIST_IV_CBC_E1, iv_length);
+ memcpy(expected_iv, NIST_EXPECTED_IV_CBC_E1, iv_length);
+ memcpy(key, NIST_KEY_CBC_E1, key_length);
+ break;
+ }
+
+}
+
+int kat_des_cbc(int iteration)
+{
+ unsigned int data_length;
+ unsigned int iv_length;
+ unsigned int key_length;
+
+ get_sizes(&data_length, &iv_length, &key_length, iteration);
+
+ unsigned char iv[iv_length];
+ unsigned char tmp_iv[iv_length];
+ unsigned char expected_iv[iv_length];
+ unsigned char key[key_length];
+ unsigned char input_data[data_length];
+ unsigned char encrypt[data_length];
+ unsigned char decrypt[data_length];
+ unsigned char result[data_length];
+
+ int rc = 0;
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(printf("key length = %i, data length = %i, iv length = %i\n",
+ key_length, data_length, iv_length));
+
+ 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_des_cbc(input_data, encrypt, data_length, key, tmp_iv, 1);
+ if (rc) {
+ VV_(printf("ica_des_cbc encrypt failed with rc = %i\n", rc));
+ dump_cbc_data(iv, iv_length, key, key_length, input_data,
+ data_length, encrypt);
+ }
+ if (!rc) {
+ VV_(printf("Encrypt:\n"));
+ dump_cbc_data(iv, iv_length, key, key_length, input_data,
+ data_length, encrypt);
+ }
+
+ if (memcmp(result, encrypt, data_length)) {
+ VV_(printf("Encryption Result does not match the known ciphertext!\n"));
+ VV_(printf("Expected data:\n"));
+ dump_array(result, data_length);
+ VV_(printf("Encryption Result:\n"));
+ dump_array(encrypt, data_length);
+ rc++;
+ }
+
+ if (memcmp(expected_iv, tmp_iv, iv_length)) {
+ VV_(printf("Update of IV does not match the expected IV!\n"));
+ VV_(printf("Expected IV:\n"));
+ dump_array(expected_iv, iv_length);
+ VV_(printf("Updated IV:\n"));
+ dump_array(tmp_iv, iv_length);
+ VV_(printf("Original IV:\n"));
+ dump_array(iv, iv_length);
+ rc++;
+ }
+ if (rc) {
+ VV_(printf("DES CBC test exited after encryption\n"));
+ return rc;
+ }
+
+ memcpy(tmp_iv, iv, iv_length);
+ rc = ica_des_cbc(encrypt, decrypt, data_length, key, tmp_iv, 0);
+ if (rc) {
+ VV_(printf("ica_des_cbc decrypt failed with rc = %i\n", rc));
+ dump_cbc_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ return rc;
+ }
+
+
+ if (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_cbc_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(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) {
+ VV_(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) {
+ VV_(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) {
+ VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n",
+ rc, errno));
+ return rc;
+ }
+ return rc;
+}
+
+int random_des_cbc(int iteration, unsigned int data_length)
+{
+ unsigned int iv_length = sizeof(ica_des_vector_t);
+ unsigned int key_length = sizeof(ica_des_key_single_t);
+
+ unsigned char iv[iv_length];
+ unsigned char tmp_iv[iv_length];
+ unsigned char key[key_length];
+ unsigned char input_data[data_length];
+ 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);
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(printf("key length = %i, data length = %i, iv length = %i\n",
+ key_length, data_length, iv_length));
+
+ rc = ica_des_cbc(input_data, encrypt, data_length, key, tmp_iv, 1);
+ if (rc) {
+ VV_(printf("ica_des_cbc encrypt failed with rc = %i\n", rc));
+ dump_cbc_data(iv, iv_length, key, key_length, input_data,
+ data_length, encrypt);
+ }
+ if (!rc) {
+ VV_(printf("Encrypt:\n"));
+ dump_cbc_data(iv, iv_length, key, key_length, input_data,
+ data_length, encrypt);
+ }
+
+ if (rc) {
+ VV_(printf("DES CBC test exited after encryption\n"));
+ return rc;
+ }
+
+ memcpy(tmp_iv, iv, iv_length);
+
+ rc = ica_des_cbc(encrypt, decrypt, data_length, key, tmp_iv, 0);
+ if (rc) {
+ VV_(printf("ica_des_cbc decrypt failed with rc = %i\n", rc));
+ dump_cbc_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ return rc;
+ }
+
+
+ if (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_cbc_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Decryption Result:\n"));
+ dump_array(decrypt, data_length);
+ rc++;
+ }
+ return rc;
+}
+
+/*
+ * Performs CBC tests.
+ */
+int main(int argc, char **argv)
+{
+ int rc = 0;
+ int error_count = 0;
+ int iteration;
+ unsigned int data_length = sizeof(ica_des_vector_t);
+
+ set_verbosity(argc, argv);
+
+#ifdef ICA_FIPS
+ if (ica_fips_status() & ICA_FIPS_MODE) {
+ printf("All DES-CBC tests skipped."
+ " (DES not FIPS approved)\n");
+ return 0;
+ }
+#endif /* ICA_FIPS */
+
+ for(iteration = 1; iteration <= NR_TESTS; iteration++) {
+ rc = kat_des_cbc(iteration);
+ if (rc) {
+ V_(printf("kat_des_cbc failed with rc = %i\n", rc));
+ error_count++;
+ }
+
+ }
+
+ for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) {
+ rc = random_des_cbc(iteration, data_length);
+ if (rc) {
+ V_(printf("random_des_cbc failed with rc = %i\n", rc));
+ error_count++;
+ goto out;
+ }
+ data_length += sizeof(ica_des_vector_t);
+ }
+out:
+ if (error_count)
+ printf("%i DES-CBC tests failed.\n", error_count);
+ else
+ printf("All DES-CBC tests passed.\n");
+
+ return rc;
+}
+
diff --git a/src/tests/libica_des_cfb_test.c b/src/tests/libica_des_cfb_test.c
new file mode 100644
index 0000000..20291bd
--- /dev/null
+++ b/src/tests/libica_des_cfb_test.c
@@ -0,0 +1,187 @@
+/* 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"
+#include "testcase.h"
+
+#define NR_TESTS 12
+#define NR_RANDOM_TESTS 1000
+
+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)
+{
+ VV_(printf("IV \n"));
+ dump_array(iv, iv_length);
+ VV_(printf("Key \n"));
+ dump_array(key, key_length);
+ VV_(printf("Input Data\n"));
+ dump_array(input_data, data_length);
+ VV_(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) {
+ VV_(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) {
+ VV_(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) {
+ VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n",
+ rc, errno));
+ return rc;
+ }
+ return rc;
+}
+
+int random_des_cfb(int iteration, unsigned int data_length,
+ unsigned int lcfb)
+{
+ unsigned int iv_length = sizeof(ica_des_vector_t);
+ unsigned int key_length = sizeof(ica_des_key_single_t);
+
+ unsigned char iv[iv_length];
+ unsigned char tmp_iv[iv_length];
+ unsigned char key[key_length];
+ unsigned char input_data[data_length];
+ 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);
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(printf("key length = %i, data length = %i, iv length = %i,"
+ " lcfb = %i\n", key_length, data_length, iv_length, lcfb));
+
+ rc = ica_des_cfb(input_data, encrypt, data_length, key, tmp_iv,
+ lcfb, 1);
+ if (rc) {
+ VV_(printf("ica_des_cfb encrypt failed with rc = %i\n", rc));
+ dump_cfb_data(iv, iv_length, key, key_length, input_data,
+ data_length, encrypt);
+ }
+ if (!rc) {
+ VV_(printf("Encrypt:\n"));
+ dump_cfb_data(iv, iv_length, key, key_length, input_data,
+ data_length, encrypt);
+ }
+
+ if (rc) {
+ VV_(printf("DES OFB test exited after encryption\n"));
+ return rc;
+ }
+
+ memcpy(tmp_iv, iv, iv_length);
+
+ rc = ica_des_cfb(encrypt, decrypt, data_length, key, tmp_iv,
+ lcfb, 0);
+ if (rc) {
+ VV_(printf("ica_des_cfb decrypt failed with rc = %i\n", rc));
+ dump_cfb_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ return rc;
+ }
+
+
+ if (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_cfb_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Decryption Result:\n"));
+ dump_array(decrypt, data_length);
+ rc++;
+ }
+ return rc;
+}
+
+int main(int argc, char **argv)
+{
+ int rc = 0;
+ int error_count = 0;
+ int iteration;
+ unsigned int rdata;
+ unsigned int data_length = 1;
+ unsigned int lcfb = 1;
+ unsigned int j;
+
+ set_verbosity(argc, argv);
+
+#ifdef ICA_FIPS
+ if (ica_fips_status() & ICA_FIPS_MODE) {
+ printf("All DES-CFB tests skipped."
+ " (DES not FIPS approved)\n");
+ return 0;
+ }
+#endif /* ICA_FIPS */
+
+ for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) {
+ for (j = 1; j <= 2; j++) {
+ if (!(data_length % lcfb)) {
+ rc = random_des_cfb(iteration, data_length, lcfb);
+ if (rc) {
+ V_(printf("random_des_cfb failed with rc = %i\n", rc));
+ error_count++;
+ }
+ }
+ switch (j) {
+ case 1:
+ lcfb = 1;
+ break;
+ case 2:
+ lcfb = 8;
+ break;
+ }
+ }
+ // add a value between 1 and 8 to data_length
+ if (ica_random_number_generate(sizeof(rdata), (unsigned char*) &rdata)) {
+ printf("ica_random_number_generate failed with errnor = %i\n",
+ errno);
+ exit(1);
+ }
+ data_length += (rdata % 8) + 1;
+ }
+ if (error_count)
+ printf("%i DES-CFB tests failed.\n", error_count);
+ else
+ printf("All DES-CFB tests passed.\n");
+
+ return rc;
+}
+
diff --git a/src/tests/libica_des_ctr_test.c b/src/tests/libica_des_ctr_test.c
new file mode 100644
index 0000000..b04cf4e
--- /dev/null
+++ b/src/tests/libica_des_ctr_test.c
@@ -0,0 +1,182 @@
+/* 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"
+#include "testcase.h"
+
+#define NR_RANDOM_TESTS 1000
+
+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)
+{
+ VV_(printf("IV \n"));
+ dump_array(iv, iv_length);
+ VV_(printf("Key \n"));
+ dump_array(key, key_length);
+ VV_(printf("Input Data\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Output Data\n"));
+ dump_array(output_data, data_length);
+}
+
+int random_des_ctr(int iteration, 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);
+
+ unsigned char iv[iv_length];
+ unsigned char tmp_iv[iv_length];
+ unsigned char key[key_length];
+ unsigned char input_data[data_length];
+ unsigned char encrypt[data_length];
+ unsigned char decrypt[data_length];
+
+ int rc = 0;
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(printf("key length = %i, data length = %i, iv length = %i\n",
+ key_length, data_length, iv_length));
+
+ rc = ica_random_number_generate(data_length, input_data);
+ if (rc) {
+ VV_(printf("random number generate returned rc = %i, errno = %i\n", rc, errno));
+ return rc;
+ }
+ rc = ica_random_number_generate(iv_length, iv);
+ if (rc) {
+ VV_(printf("random number generate returned rc = %i, errno = %i\n", rc, errno));
+ return rc;
+ }
+
+ rc = ica_random_number_generate(key_length, key);
+ if (rc) {
+ VV_(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) {
+ VV_(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 (!rc) {
+ VV_(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) {
+ VV_(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 (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_ctr_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Decryption Result:\n"));
+ dump_array(decrypt, data_length);
+ rc++;
+ }
+ return rc;
+}
+
+int main(int argc, char **argv)
+{
+ int rc = 0;
+ int error_count = 0;
+ int i = 0;
+ unsigned int endless = 0;
+ unsigned int rdata;
+ unsigned int data_length = 1;
+ unsigned int iv_length = sizeof(ica_des_key_single_t);
+
+#ifdef ICA_FIPS
+ if (ica_fips_status() & ICA_FIPS_MODE) {
+ printf("All DES-CTR tests skipped."
+ " (DES not FIPS approved)\n");
+ return 0;
+ }
+#endif /* ICA_FIPS */
+
+ if (argc > 1) {
+ if (strstr(argv[1], "endless"))
+ endless = 1;
+ }
+
+ set_verbosity(argc, argv);
+
+ if (endless) {
+ while (1) {
+ VV_(printf("i = %i\n", i));
+ rc = random_des_ctr(i, 320, 320);
+ if (rc) {
+ V_(printf("kat_des_ctr failed with rc = %i\n", rc));
+ return rc;
+ }
+ i++;
+ }
+ } else {
+ for (i = 1; i < NR_RANDOM_TESTS; i++) {
+ rc = random_des_ctr(i, data_length, iv_length);
+ if (rc) {
+ V_(printf("random_des_ctr failed with rc = %i\n", rc));
+ error_count++;
+ }
+ 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, data_length, data_length);
+ if (rc) {
+ V_(printf("random_des_ctr failed with rc = %i\n", rc));
+ error_count++;
+ }
+ }
+ // add a value between 1 and 8 to data_length
+ if (ica_random_number_generate(sizeof(rdata), (unsigned char*) &rdata)) {
+ printf("ica_random_number_generate failed with errnor = %i\n",
+ errno);
+ exit(1);
+ }
+ data_length += (rdata % 8) + 1;
+ }
+ }
+
+ if (error_count)
+ printf("%i DES-CTR tests failed.\n", error_count);
+ else
+ printf("All DES-CTR tests passed.\n");
+
+ return rc;
+}
+
diff --git a/src/tests/libica_des_ecb_test.c b/src/tests/libica_des_ecb_test.c
new file mode 100644
index 0000000..6401f66
--- /dev/null
+++ b/src/tests/libica_des_ecb_test.c
@@ -0,0 +1,151 @@
+/* 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"
+#include "testcase.h"
+
+#define NR_RANDOM_TESTS 10000
+
+void dump_ecb_data(unsigned char *key, unsigned int key_length,
+ unsigned char *input_data, unsigned int data_length,
+ unsigned char *output_data)
+{
+ VV_(printf("Key \n"));
+ dump_array(key, key_length);
+ VV_(printf("Input Data\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Output Data\n"));
+ dump_array(output_data, data_length);
+}
+
+int load_random_test_data(unsigned char *data, unsigned int data_length,
+ unsigned char *key, unsigned int key_length)
+{
+ int rc;
+
+ rc = ica_random_number_generate(data_length, data);
+ if (rc) {
+ VV_(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) {
+ VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n",
+ rc, errno));
+ return rc;
+ }
+ return rc;
+}
+
+int random_des_ecb(int iteration, unsigned int data_length)
+{
+ int rc = 0;
+ unsigned int key_length = sizeof(ica_des_key_triple_t);
+ unsigned char input_data[data_length];
+ unsigned char encrypt[data_length];
+ unsigned char decrypt[data_length];
+ unsigned char key[key_length];
+
+ memset(encrypt, 0x00, data_length);
+ memset(decrypt, 0x00, data_length);
+
+ load_random_test_data(input_data, data_length, key, key_length);
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(printf("key length = %i, data length = %i\n", key_length, data_length));
+
+ rc = ica_des_ecb(input_data, encrypt, data_length, key, 1);
+ if (rc) {
+ VV_(printf("ica_des_ecb encrypt failed with rc = %i\n", rc));
+ dump_ecb_data(key, key_length, input_data, data_length,
+ encrypt);
+ }
+ if (!rc) {
+ VV_(printf("Encrypt:\n"));
+ dump_ecb_data(key, key_length, input_data,
+ data_length, encrypt);
+ }
+
+ if (rc) {
+ VV_(printf("3DES ECB test exited after encryption\n"));
+ return rc;
+ }
+
+ rc = ica_des_ecb(encrypt, decrypt, data_length, key, 0);
+ if (rc) {
+ VV_(printf("ica_des_ecb decrypt failed with rc = %i\n", rc));
+ dump_ecb_data(key, key_length, encrypt,
+ data_length, decrypt);
+ return rc;
+ }
+
+
+ if (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_ecb_data(key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Decryption Result:\n"));
+ dump_array(decrypt, data_length);
+ rc++;
+ return rc;
+ }
+
+ return rc;
+}
+
+/*
+ * Performs ECB tests.
+ */
+int main(int argc, char **argv)
+{
+ int rc = 0;
+ int error_count = 0;
+ int iteration;
+ unsigned int data_length = sizeof(ica_des_vector_t);
+
+ set_verbosity(argc, argv);
+
+#ifdef ICA_FIPS
+ if (ica_fips_status() & ICA_FIPS_MODE) {
+ printf("All DES-ECB tests skipped."
+ " (DES not FIPS approved)\n");
+ return 0;
+ }
+#endif /* ICA_FIPS */
+
+ for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) {
+ rc = random_des_ecb(iteration, data_length);
+ if (rc) {
+ V_(printf("random_des_ecb failed with rc = %i\n", rc));
+ error_count++;
+ goto out;
+ }
+ data_length += sizeof(ica_des_vector_t);
+ }
+
+out:
+ if (error_count)
+ printf("%i DES-ECB tests failed.\n", error_count);
+ else
+ printf("All DES-ECB tests passed.\n");
+
+ return rc;
+}
+
diff --git a/src/tests/libica_des_ofb_test.c b/src/tests/libica_des_ofb_test.c
new file mode 100644
index 0000000..b634e22
--- /dev/null
+++ b/src/tests/libica_des_ofb_test.c
@@ -0,0 +1,172 @@
+/* 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"
+#include "testcase.h"
+
+#define NR_RANDOM_TESTS 10000
+
+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)
+{
+ VV_(printf("IV \n"));
+ dump_array(iv, iv_length);
+ VV_(printf("Key \n"));
+ dump_array(key, key_length);
+ VV_(printf("Input Data\n"));
+ dump_array(input_data, data_length);
+ VV_(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) {
+ VV_(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) {
+ VV_(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) {
+ VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n",
+ rc, errno));
+ return rc;
+ }
+ return rc;
+}
+
+int random_des_ofb(int iteration, unsigned int data_length)
+{
+ unsigned int iv_length = sizeof(ica_des_vector_t);
+ unsigned int key_length = sizeof(ica_des_key_single_t);
+
+ unsigned char iv[iv_length];
+ unsigned char tmp_iv[iv_length];
+ unsigned char key[key_length];
+ unsigned char input_data[data_length];
+ 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);
+
+ VV_(printf("Test Parameters for iteration = %i\n", iteration));
+ VV_(printf("key length = %i, data length = %i, iv length = %i\n",
+ key_length, data_length, iv_length));
+
+ rc = ica_des_ofb(input_data, encrypt, data_length, key, tmp_iv, 1);
+ if (rc) {
+ VV_(printf("ica_des_ofb encrypt failed with rc = %i\n", rc));
+ dump_ofb_data(iv, iv_length, key, key_length, input_data,
+ data_length, encrypt);
+ }
+ if (!rc) {
+ VV_(printf("Encrypt:\n"));
+ dump_ofb_data(iv, iv_length, key, key_length, input_data,
+ data_length, encrypt);
+ }
+
+ if (rc) {
+ VV_(printf("DES OFB test exited after encryption\n"));
+ return rc;
+ }
+
+ memcpy(tmp_iv, iv, iv_length);
+
+ rc = ica_des_ofb(encrypt, decrypt, data_length, key, tmp_iv, 0);
+ if (rc) {
+ VV_(printf("ica_des_ofb decrypt failed with rc = %i\n", rc));
+ dump_ofb_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ return rc;
+ }
+
+
+ if (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_ofb_data(iv, iv_length, key, key_length, encrypt,
+ data_length, decrypt);
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ VV_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(input_data, data_length);
+ VV_(printf("Decryption Result:\n"));
+ dump_array(decrypt, data_length);
+ rc++;
+ }
+ return rc;
+}
+
+int main(int argc, char **argv)
+{
+ int rc = 0;
+ int error_count = 0;
+ int iteration;
+ unsigned int rdata;
+ unsigned int data_length = 1;
+
+ set_verbosity(argc, argv);
+
+#ifdef ICA_FIPS
+ if (ica_fips_status() & ICA_FIPS_MODE) {
+ printf("All DES-OFB tests skipped."
+ " (DES not FIPS approved)\n");
+ return 0;
+ }
+#endif /* ICA_FIPS */
+
+ for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) {
+ rc = random_des_ofb(iteration, data_length);
+ if (rc) {
+ V_(printf("random_des_ofb failed with rc = %i\n", rc));
+ error_count++;
+ goto out;
+ }
+ // add a value between 1 and 8 to data_length
+ if (ica_random_number_generate(sizeof(rdata), (unsigned char*) &rdata)) {
+ printf("ica_random_number_generate failed with errnor = %i\n",
+ errno);
+ exit(1);
+ }
+ data_length += (rdata % 8) + 1;
+ }
+out:
+ if (error_count)
+ printf("%i DES-OFB tests failed.\n", error_count);
+ else
+ printf("All DES-OFB tests passed.\n");
+
+ return rc;
+}
+
diff --git a/src/tests/libica_des_test.c b/src/tests/libica_des_test.c
new file mode 100644
index 0000000..abf50da
--- /dev/null
+++ b/src/tests/libica_des_test.c
@@ -0,0 +1,147 @@
+/* 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 <fcntl.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include "ica_api.h"
+#include "testcase.h"
+
+const int cipher_buf_length = 8;
+
+unsigned char NIST_KEY1[] =
+ { 0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57 };
+
+unsigned char NIST_TEST_DATA[] =
+ { 0x01, 0xa1, 0xd6, 0xd0, 0x39, 0x77, 0x67, 0x42 };
+
+unsigned char NIST_TEST_RESULT[] =
+ { 0x69, 0x0f, 0x5b, 0x0d, 0x9a, 0x26, 0x93, 0x9b };
+
+int test_des_new_api(int mode)
+{
+ ica_des_vector_t iv;
+ ica_des_key_single_t key;
+ int rc = 0;
+ unsigned char dec_text[sizeof NIST_TEST_DATA],
+ enc_text[sizeof NIST_TEST_DATA];
+
+ bzero(dec_text, sizeof dec_text);
+ bzero(enc_text, sizeof enc_text);
+ bzero(iv, sizeof iv);
+ bcopy(NIST_KEY1, key, sizeof NIST_KEY1);
+
+ rc = ica_des_encrypt(mode, sizeof NIST_TEST_DATA, NIST_TEST_DATA, &iv,
+ &key, enc_text);
+ if (rc) {
+ VV_(printf("\nOriginal data:\n");
+ dump_array(NIST_TEST_DATA, sizeof NIST_TEST_DATA));
+ VV_(printf("ica_des_encrypt failed with errno %d (0x%x).\n", rc, rc));
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array(enc_text, sizeof enc_text);
+ return rc;
+ }
+
+ if (memcmp(enc_text, NIST_TEST_RESULT, sizeof NIST_TEST_RESULT) != 0) {
+ VV_(printf("This does NOT match the known result.\n"));
+ return -1;
+ } else {
+ VV_(printf("Yep, it's what it should be.\n"));
+ }
+
+ bzero(iv, sizeof iv);
+ rc = ica_des_decrypt(mode, sizeof enc_text, enc_text, &iv, &key,
+ dec_text);
+ if (rc) {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array(NIST_TEST_DATA, sizeof NIST_TEST_DATA);
+ VV_(printf("ica_des_encrypt failed with errno %d (0x%x).\n", rc, rc));
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array(enc_text, sizeof enc_text);
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array(dec_text, sizeof dec_text);
+ VV_(printf("ica_des_decrypt failed with errno %d (0x%x).\n", rc, rc));
+ return rc;
+ }
+
+ if (memcmp(dec_text, NIST_TEST_DATA, sizeof NIST_TEST_DATA) != 0) {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array(NIST_TEST_DATA, sizeof NIST_TEST_DATA);
+ VV_(printf("ica_des_encrypt failed with errno %d (0x%x).\n", rc, rc));
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array(enc_text, sizeof enc_text);
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array(dec_text, sizeof dec_text);
+ VV_(printf("This does NOT match the original data.\n"));
+ return -1;
+ } else {
+ VV_(printf("Successful!\n"));
+ }
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ unsigned int mode = 0;
+ int rc = 0;
+ int error_count = 0;
+
+ set_verbosity(argc, argv);
+
+#ifdef ICA_FIPS
+ if (ica_fips_status() & ICA_FIPS_MODE) {
+ printf("All DES new api tests skipped."
+ " (DES not FIPS approved)\n");
+ return 0;
+ }
+#endif /* ICA_FIPS */
+
+ if (argc > 1) {
+ if (strstr(argv[1], "ecb"))
+ mode = MODE_ECB;
+ if (strstr(argv[1], "cbc"))
+ mode = MODE_CBC;
+ V_(printf("mode = %i \n", mode));
+ }
+
+ if (mode != 0 && mode != MODE_ECB && mode != MODE_CBC) {
+ printf("Usage: %s [ ecb | cbc ]\n", argv[0]);
+ return -1;
+ }
+ if (!mode) {
+ /* This is the standard loop that will perform all testcases */
+ mode = 2;
+ while (mode) {
+ rc = test_des_new_api(mode);
+ if (rc) {
+ error_count++;
+ V_(printf ("test_des_new_api mode = %i failed \n", mode));
+ }
+ else {
+ V_(printf ("test_des_new_api mode = %i finished.\n", mode));
+ }
+ mode--;
+ }
+ if (error_count)
+ printf("%i tests failed.\n", error_count);
+ else
+ printf("All tests passed.\n");
+ } else {
+ /* Perform only either in ECB or CBC mode */
+ rc = test_des_new_api(mode);
+ if (rc)
+ printf ("test_des_new_api mode = %i failed \n", mode);
+ else
+ printf ("test_des_new_api mode = %i finished.\n", mode);
+ }
+ return rc;
+}
+
diff --git a/src/tests/libica_drbg_birthdays.c b/src/tests/libica_drbg_birthdays.c
new file mode 100644
index 0000000..70d4604
--- /dev/null
+++ b/src/tests/libica_drbg_birthdays.c
@@ -0,0 +1,139 @@
+/*
+ * Multithreaded birthday paradox test for a sha512 instantiation of ica_drbg
+ *
+ * usage: ica_drbg_birthdays <rnd_ex1> <rnd_ex2> <rnd_ex3>
+ *
+ * rnd_ex# is the no. of random experiments to be done for test no.#
+ */
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ica_api.h"
+
+/*
+ * no. of people no. of possible birthdays probability of a pair
+ * = THREADS = 2 ^ ( 8 * GEN_BYTES)
+ * --------------------------------------------------------------------------
+ * 19 256 = 2 ^ (8 * 1) 0.5
+ * 301 65536 = 2 ^ (8 * 2) 0.5
+ * 4823 16777216 = 2 ^ (8 * 3) 0.5
+ */
+static const int THREADS[] = {19, 301, 4823};
+static const int GEN_BYTES[] = { 1, 2, 3};
+
+static int test = 0;
+static ica_drbg_t *sh = NULL;
+
+void *thread(void *buffer)
+{
+ int rc;
+
+ rc = ica_drbg_generate(sh, 0, false, NULL, 0, buffer, GEN_BYTES[test]);
+ if(rc){
+ fprintf(stderr, "error: ica_drbg_generate: %s (%d)\n",
+ strerror(rc), rc);
+ exit(1);
+ }
+
+ return NULL;
+}
+
+int main(int argc, char **argv)
+{
+ long rnd_ex[3] = {0}, ex, pair_found;
+ int i, j, rc;
+ bool toggle;
+
+ if(2 > argc || 4 < argc){
+ fprintf(stderr,
+ "usage: ica_drbg_birthdays <rnd_ex1> <rnd_ex2>"
+ " <rnd_ex3>\n");
+ exit(1);
+ }
+ for(i = 1; i < argc; i++)
+ rnd_ex[i - 1] = strtol(argv[i], NULL, 10);
+
+ /* create instantiation */
+ rc = ica_drbg_instantiate(&sh, 0, false, ICA_DRBG_SHA512, NULL, 0);
+ if(rc){
+ fprintf(stderr, "error: ica_drbg_instantiate: %s (%d)\n",
+ strerror(rc), rc);
+ exit(1);
+ }
+
+ printf("Multithreaded birthday paradox test for a sha512 "
+ "instantiation of ica_drbg\n"
+ "(the test result is good, if p is close to 0.5 for a large"
+ " number of random experiments)\n");
+
+ /* perform each of the 3 tests rnd_ex[test] times */
+ for(test = 0; test < 3; test++){
+ if(!rnd_ex[test])
+ continue;
+
+ int status[THREADS[test]];
+ unsigned char buffer[THREADS[test]][GEN_BYTES[test]];
+
+ pair_found = 0;
+
+ printf("%ld random Experiment(s): %d threads, "
+ "%1d bytes/thread generated...\n",
+ rnd_ex[test], THREADS[test], GEN_BYTES[test]);
+ pthread_t threads[THREADS[test]];
+
+ for(ex = 0; ex < rnd_ex[test]; ex++){
+ /* start threads */
+ for(i = 0; i < THREADS[test]; i++){
+ while((rc = pthread_create(&threads[i], NULL,
+ thread, buffer[i])) == EAGAIN)
+ ;
+ if(rc){
+ fprintf(stderr,
+ "error: pthread_create: "
+ "%s (%d)\n",
+ strerror(rc), rc);
+ exit(1);
+ }
+ }
+
+ /* wait for threads */
+ for(i = 0; i < THREADS[test]; i++){
+ if((rc = pthread_join(threads[i],
+ (void**)&status[i]))){
+ fprintf(stderr, "error: pthread_join "
+ "%s (%d)\n",
+ strerror(rc), rc);
+ exit(1);
+ }
+ }
+
+ /* search pairs */
+ toggle = false;
+ for(i = 0; i < THREADS[test]; i++){
+ for(j = 0; j < THREADS[test]; j++){
+ if(i != j && !memcmp(buffer[i],
+ buffer[j], GEN_BYTES[test])){
+ pair_found++;
+ toggle = true;
+ break;
+ }
+ }
+ if(toggle)
+ break;
+ }
+ }
+ printf("... %ld times a pair was found (p = %1.2f).\n",
+ pair_found, (float)pair_found/ex);
+ }
+
+ /* destroy instantiation */
+ rc = ica_drbg_uninstantiate(&sh);
+ if(rc){
+ fprintf(stderr, "error: ica_drbg_uninstantiate: %s (%d)\n",
+ strerror(rc), rc);
+ exit(1);
+ }
+ return 0;
+}
diff --git a/src/tests/libica_drbg_test.c b/src/tests/libica_drbg_test.c
new file mode 100644
index 0000000..ece3806
--- /dev/null
+++ b/src/tests/libica_drbg_test.c
@@ -0,0 +1,623 @@
+/*
+ * 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.
+ *
+ * DRBG conforming to NIST SP800-90A
+ *
+ * Author(s): Patrick Steuer <patrick.steuer@de.ibm.com>
+ *
+ * Copyright IBM Corp. 2015
+ */
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "ica_api.h"
+#include "s390_drbg.h"
+#include "testcase.h"
+
+/*
+ * Known answer test types
+ */
+typedef struct{
+ /* Inputs */
+ ica_drbg_t **sh;
+ int sec;
+ bool pr;
+ ica_drbg_mech_t *const mech;
+ const unsigned char *pers;
+ size_t pers_len;
+ /* Expected return code */
+ int rc;
+}instantiate_test_t;
+
+typedef struct{
+ /* Inputs */
+ ica_drbg_t *sh;
+ bool pr;
+ const unsigned char *add;
+ size_t add_len;
+ /* Expected return code */
+ int rc;
+}reseed_test_t;
+
+typedef struct{
+ /* Inputs */
+ ica_drbg_t *sh;
+ int sec;
+ bool pr;
+ const unsigned char *add;
+ size_t add_len;
+ size_t prnd_len;
+ /* Expected return code */
+ int rc;
+}generate_test_t;
+
+typedef struct{
+ /* Inputs */
+ ica_drbg_t **sh;
+ /* Expected return code */
+ int rc;
+}uninstantiate_test_t;
+
+typedef struct{
+ /* Inputs */
+ void *func;
+ int sec;
+ bool pr;
+ ica_drbg_mech_t *mech;
+ /* Expected return code */
+ int rc;
+}health_test_test_t;
+
+/*
+ * Testcase
+ */
+int main(int argc,
+ char **argv)
+{
+ int i = 0;
+ int failed = 0;
+ int passed = 0;
+ int status = -1;
+ const unsigned char pers[] = {0x7e,0xa1,0x0e,0x96,0xaf,0x90,0x0c,0x25,
+ 0xd3,0xbe,0x3b,0x50,0xa0,0xcc,0x71,0xa7,
+ 0x9f,0xe4,0x14,0xbd,0x4c,0x37,0x39,0x80,
+ 0x3f,0x02,0xff,0xe5,0xb2,0x60,0xbf,0xbb,};
+ const unsigned char add[] = {0xc0,0x66,0xfd,0x2e,0xb8,0xe4,0xae,0xa2,
+ 0xe7,0x14,0x5e,0xda,0x0c,0xfc,0x8b,0xef,
+ 0x5e,0xed,0xcc,0x36,0x7b,0x1c,0xb4,0xde,
+ 0x7e,0xb2,0xc2,0x75,0x9f,0xa7,0x5b,0xf7,};
+ size_t pers_len = sizeof(pers) / sizeof(pers[0]);
+ size_t add_len = sizeof(add) / sizeof(add[0]);
+
+ set_verbosity(argc, argv);
+
+ /*
+ * drbg_sha512 tests
+ */
+
+ /* Instantiate */
+ ica_drbg_t *sh = NULL;
+ ica_drbg_t *sh2 = &(ica_drbg_t){.lock = PTHREAD_MUTEX_INITIALIZER};
+ drbg_recursive_mutex_init(&sh2->lock);
+
+ const instantiate_test_t inst_test[] = {
+ {
+ .mech = ICA_DRBG_SHA512,
+ .sh = &sh,
+ .sec = DRBG_SEC_112,
+ .pr = true,
+ .pers = NULL,
+ .pers_len = 0,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .sh = &sh,
+ .sec = DRBG_SEC_192,
+ .pr = true,
+ .pers = pers,
+ .pers_len = pers_len,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .sh = &sh,
+ .sec = DRBG_SEC_256,
+ .pr = false,
+ .pers = pers,
+ .pers_len = pers_len,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .sh = &sh,
+ .sec = DRBG_SEC_128,
+ .pr = false,
+ .pers = NULL,
+ .pers_len = 0,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .sh = &sh,
+ .sec = DRBG_SEC_256 + 1,
+ .pr = true,
+ .pers = NULL,
+ .pers_len = 0,
+ .rc = ENOTSUP,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .sh = &sh,
+ .sec = DRBG_SEC_112,
+ .pr = false,
+ .pers = pers,
+ .pers_len = ICA_DRBG_SHA512->max_pers_len + 1,
+ .rc = EINVAL,
+ },
+ {
+ .mech = NULL,
+ .sh = &sh,
+ .sec = DRBG_SEC_128,
+ .pr = true,
+ .pers = NULL,
+ .pers_len = 0,
+ .rc = EINVAL,
+ },
+ {
+ .mech = NULL,
+ .sh = NULL,
+ .sec = DRBG_SEC_192,
+ .pr = false,
+ .pers = NULL,
+ .pers_len = 0,
+ .rc = EINVAL,
+ },
+ {
+ .mech = NULL,
+ .sh = &sh2,
+ .sec = DRBG_SEC_256,
+ .pr = true,
+ .pers = pers,
+ .pers_len = pers_len,
+ .rc = EINVAL,
+ },
+ };
+ for(i = 0; i < sizeof(inst_test) / sizeof(inst_test[0]); i++){
+ V_(printf("instantiate function: test no. %d", i));
+ status = ica_drbg_instantiate(inst_test[i].sh,
+ inst_test[i].sec,
+ inst_test[i].pr,
+ inst_test[i].mech,
+ inst_test[i].pers,
+ inst_test[i].pers_len);
+ if(inst_test[i].rc == status){
+ V_(printf(" passed\n"));
+ passed++;
+ }
+ else{
+ V_(printf(" failed\n"));
+ failed++;
+ }
+ ica_drbg_uninstantiate(inst_test[i].sh);
+ }
+
+ /* Reseed */
+ ica_drbg_t *sh_pr_false = NULL;
+ ica_drbg_t *sh_pr_true = NULL;
+ ica_drbg_instantiate(&sh_pr_true, DRBG_SEC_112, true, ICA_DRBG_SHA512,
+ pers, pers_len);
+ ica_drbg_instantiate(&sh_pr_false, DRBG_SEC_112, false,
+ ICA_DRBG_SHA512, pers, pers_len);
+ const reseed_test_t res_test[] = {
+ {
+ .sh = sh_pr_true,
+ .pr = true,
+ .add = NULL,
+ .add_len = 0,
+ .rc = 0,
+ },
+ {
+ .sh = sh_pr_false,
+ .pr = false,
+ .add = add,
+ .add_len = add_len,
+ .rc = 0,
+ },
+ {
+ .sh = sh_pr_true,
+ .pr = true,
+ .add = add,
+ .add_len = ICA_DRBG_SHA512->max_add_len + 1,
+ .rc = EINVAL,
+ },
+ {
+ .sh = NULL,
+ .pr = true,
+ .add = NULL,
+ .add_len = 0,
+ .rc = EINVAL,
+ },
+ {
+ .sh = sh_pr_false,
+ .pr = true,
+ .add = add,
+ .add_len = add_len,
+ .rc = ENOTSUP,
+ },
+ };
+ for(i = 0; i < sizeof(res_test) / sizeof(res_test[0]); i++){
+ V_(printf("reseed function: test no. %d", i));
+ status = ica_drbg_reseed(res_test[i].sh, res_test[i].pr,
+ res_test[i].add, res_test[i].add_len);
+ if(res_test[i].rc == status){
+ V_(printf(" passed\n"));
+ passed++;
+ }
+ else{
+ V_(printf(" failed\n"));
+ failed++;
+ }
+ }
+ ica_drbg_uninstantiate(&sh_pr_true);
+ ica_drbg_uninstantiate(&sh_pr_false);
+
+ /* Generate */
+ sh_pr_false = NULL;
+ sh_pr_true = NULL;
+ ica_drbg_instantiate(&sh_pr_true, DRBG_SEC_192, true, ICA_DRBG_SHA512,
+ pers, pers_len);
+ ica_drbg_instantiate(&sh_pr_false, DRBG_SEC_192, false,
+ ICA_DRBG_SHA512, pers, pers_len);
+
+ const generate_test_t gen_test[] = {
+ {
+ .sh = sh_pr_true,
+ .sec = DRBG_SEC_112,
+ .pr = true,
+ .add = add,
+ .add_len = add_len,
+ .prnd_len = 0,
+ .rc = 0,
+ },
+ {
+ .sh = sh_pr_true,
+ .sec = DRBG_SEC_112,
+ .pr = true,
+ .add = NULL,
+ .add_len = 0,
+ .prnd_len = 256,
+ .rc = 0,
+ },
+ {
+ .sh = sh_pr_false,
+ .sec = DRBG_SEC_192,
+ .pr = false,
+ .add = NULL,
+ .add_len = 0,
+ .prnd_len = ICA_DRBG_SHA512->max_no_of_bytes_per_req,
+ .rc = 0,
+ },
+ {
+ .sh = sh_pr_false,
+ .sec = DRBG_SEC_192,
+ .pr = false,
+ .add = add,
+ .add_len = add_len,
+ .prnd_len = 512,
+ .rc = 0,
+ },
+ {
+ .sh = sh_pr_true,
+ .sec = DRBG_SEC_128,
+ .pr = true,
+ .add = add,
+ .add_len = add_len,
+ .prnd_len = 1024,
+ .rc = 0,
+ },
+ {
+ .sh = sh_pr_false,
+ .sec = DRBG_SEC_256,
+ .pr = false,
+ .add = NULL,
+ .add_len = 0,
+ .prnd_len = 2048,
+ .rc = ENOTSUP,
+ },
+ {
+ .sh = sh_pr_false,
+ .sec = DRBG_SEC_112,
+ .pr = true,
+ .add = add,
+ .add_len = add_len,
+ .prnd_len = 3072,
+ .rc = ENOTSUP,
+ },
+ {
+ .sh = NULL,
+ .sec = DRBG_SEC_112,
+ .pr = true,
+ .add = add,
+ .add_len = add_len,
+ .prnd_len = 128,
+ .rc = EINVAL,
+ },
+ {
+ .sh = sh_pr_true,
+ .sec = DRBG_SEC_128,
+ .pr = false,
+ .add = add,
+ .add_len = ICA_DRBG_SHA512->max_add_len + 1,
+ .prnd_len = 64,
+ .rc = EINVAL,
+ },
+ };
+ for(i = 0; i < sizeof(gen_test) / sizeof(gen_test[0]); i++){
+ V_(printf("generate function: test no. %d", i));
+ size_t prnd_len = gen_test[i].prnd_len;
+ unsigned char prnd[prnd_len];
+ status = ica_drbg_generate(gen_test[i].sh, gen_test[i].sec,
+ gen_test[i].pr, gen_test[i].add,
+ gen_test[i].add_len, prnd,
+ prnd_len);
+ if(gen_test[i].rc == status){
+ V_(printf(" passed\n"));
+ passed++;
+ }
+ else{
+ V_(printf(" failed\n"));
+ failed++;
+ }
+ }
+ ica_drbg_uninstantiate(&sh_pr_true);
+ ica_drbg_uninstantiate(&sh_pr_false);
+
+ /* Uninstantiate */
+ sh = NULL;
+ ica_drbg_instantiate(&sh, DRBG_SEC_256, true, ICA_DRBG_SHA512, pers,
+ pers_len);
+ const uninstantiate_test_t uninst_test[] = {
+ {
+ .sh = &sh,
+ .rc = 0,
+ },
+ {
+ .sh = NULL,
+ .rc = EINVAL,
+ },
+ };
+ for(i = 0; i < sizeof(uninst_test) / sizeof(uninst_test[0]); i++){
+ V_(printf("uninstantiate function: test no. %d", i));
+ status = ica_drbg_uninstantiate(uninst_test[i].sh);
+ if(uninst_test[i].rc == status){
+ V_(printf(" passed\n"));
+ passed++;
+ }
+ else{
+ V_(printf(" failed\n"));
+ failed++;
+ }
+ }
+ ica_drbg_uninstantiate(&sh);
+
+ /* Health test */
+ const health_test_test_t ht_test[] = {
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_instantiate,
+ .sec = DRBG_SEC_112,
+ .pr = true,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_instantiate,
+ .sec = DRBG_SEC_128,
+ .pr = true,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_instantiate,
+ .sec = DRBG_SEC_192,
+ .pr = true,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_instantiate,
+ .sec = DRBG_SEC_256,
+ .pr = true,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_instantiate,
+ .sec = DRBG_SEC_112,
+ .pr = false,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_instantiate,
+ .sec = DRBG_SEC_128,
+ .pr = false,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_instantiate,
+ .sec = DRBG_SEC_192,
+ .pr = false,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_instantiate,
+ .sec = DRBG_SEC_256,
+ .pr = false,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_reseed,
+ .sec = DRBG_SEC_112,
+ .pr = true,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_reseed,
+ .sec = DRBG_SEC_128,
+ .pr = true,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_reseed,
+ .sec = DRBG_SEC_192,
+ .pr = true,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_reseed,
+ .sec = DRBG_SEC_256,
+ .pr = true,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_reseed,
+ .sec = DRBG_SEC_112,
+ .pr = false,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_reseed,
+ .sec = DRBG_SEC_128,
+ .pr = false,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_reseed,
+ .sec = DRBG_SEC_192,
+ .pr = false,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_reseed,
+ .sec = DRBG_SEC_256,
+ .pr = false,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_generate,
+ .sec = DRBG_SEC_112,
+ .pr = true,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_generate,
+ .sec = DRBG_SEC_128,
+ .pr = true,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_generate,
+ .sec = DRBG_SEC_192,
+ .pr = true,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_generate,
+ .sec = DRBG_SEC_256,
+ .pr = true,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_generate,
+ .sec = DRBG_SEC_112,
+ .pr = false,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_generate,
+ .sec = DRBG_SEC_128,
+ .pr = false,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_generate,
+ .sec = DRBG_SEC_192,
+ .pr = false,
+ .rc = 0,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_generate,
+ .sec = DRBG_SEC_256,
+ .pr = false,
+ .rc = 0,
+ },
+ {
+ .mech = NULL,
+ .func = ica_drbg_generate,
+ .sec = DRBG_SEC_256,
+ .pr = false,
+ .rc = EINVAL,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = NULL,
+ .sec = DRBG_SEC_256,
+ .pr = true,
+ .rc = EINVAL,
+ },
+ {
+ .mech = ICA_DRBG_SHA512,
+ .func = ica_drbg_instantiate,
+ .sec = DRBG_SEC_256 + 1,
+ .pr = false,
+ .rc = ENOTSUP,
+ },
+ };
+ for(i = 0; i < sizeof(ht_test) / sizeof(ht_test[0]); i++){
+ V_(printf("health test function: test no. %d", i));
+ status = ica_drbg_health_test(ht_test[i].func, ht_test[i].sec,
+ ht_test[i].pr, ht_test[i].mech);
+ if(ht_test[i].rc == status){
+ V_(printf(" passed\n"));
+ passed++;
+ }
+ else{
+ V_(printf(" failed\n"));
+ failed++;
+ }
+ }
+
+ if(failed)
+ printf("DRBG tests: %d passed, %d failed, %d total\n", passed, failed,
+ passed + failed);
+ else
+ printf("All DRBG tests passed.\n");
+
+ return 0;
+}
diff --git a/src/tests/libica_fips_test.c b/src/tests/libica_fips_test.c
new file mode 100644
index 0000000..6584033
--- /dev/null
+++ b/src/tests/libica_fips_test.c
@@ -0,0 +1,66 @@
+#include <openssl/crypto.h>
+#include <openssl/opensslv.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <openssl/opensslconf.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif /* OPENSSL_FIPS */
+
+#include "ica_api.h"
+
+#define FIPS_FLAG "/proc/sys/crypto/fips_enabled"
+
+int
+main(void)
+{
+ FILE *fd;
+ int fips, rv;
+ char fips_flag;
+
+ printf("Kernel FIPS flag (%s) is ", FIPS_FLAG);
+ if ((fd = fopen(FIPS_FLAG, "r")) != NULL) {
+ if (fread(&fips_flag, sizeof(fips_flag), 1, fd) == 1) {
+ fips_flag -= '0';
+ printf("%d.", fips_flag);
+ } else {
+ printf("not readable.");
+ }
+ fclose(fd);
+ }
+ else {
+ fips_flag = 0;
+ printf("not present.");
+ }
+ printf("\nKernel %s in FIPS mode.\n", fips_flag ?
+ "runs" : "doesn't run");
+
+ printf("Libica has ");
+#ifdef ICA_FIPS
+ fips = ica_fips_status();
+#else
+ fips = 0;
+ printf("no ");
+#endif /* ICA_FIPS */
+ printf("built-in FIPS support.\nLibica %s in FIPS mode.\n",
+ fips & ICA_FIPS_MODE ? "runs" : "doesn't run");
+
+ rv = EXIT_SUCCESS;
+#ifdef ICA_FIPS
+ if ((fips & ICA_FIPS_MODE) != fips_flag) {
+ printf("This shouldn't happen.\n");
+ rv = EXIT_FAILURE;
+ }
+ if (fips & ICA_FIPS_CRYPTOALG) {
+ printf("Libica FIPS powerup test failed.\n");
+ rv = EXIT_FAILURE;
+ }
+#endif /* ICA_FIPS */
+
+ printf("OpenSSL version is '%s'.\n", OPENSSL_VERSION_TEXT);
+ printf("OpenSSL %s in FIPS mode.\n\n", FIPS_mode() ?
+ "runs" : "doesn't run");
+
+ return rv;
+}
diff --git a/src/tests/libica_get_functionlist.c b/src/tests/libica_get_functionlist.c
new file mode 100644
index 0000000..edf0a43
--- /dev/null
+++ b/src/tests/libica_get_functionlist.c
@@ -0,0 +1,68 @@
+/* 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, 2013 */
+
+/*
+ * Test program for libica API call ica_get_version().
+ *
+ * Test 1: invalid input.
+ * Test 2: Valid input.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "ica_api.h"
+#include <string.h>
+#include "testcase.h"
+
+int main(int argc, char **argv)
+{
+ libica_func_list_element* libica_func_list;
+ int rc, x;
+ int failed = 0;
+ unsigned int count;
+
+ set_verbosity(argc, argv);
+
+ //========== Test#1 good case ============
+ V_(printf("Testing libica API ica_get_functionlist().\n"));
+ rc = ica_get_functionlist(NULL, &count);
+ if (rc) {
+ V_(printf("ica_get_functionlist failed with rc=%02x\n", rc));
+ return -1;
+ }
+ V_(printf("Retrieved number of elements: %d\n", count));
+
+ libica_func_list = malloc(sizeof(libica_func_list_element) * count);
+ rc = ica_get_functionlist(libica_func_list, &count);
+ if (rc) {
+ V_(printf("Retrieving function list failed with rc=%02x\n", rc));
+ failed++;
+ }
+ else {
+ for (x=0; x<count; x++) {
+ V_(printf("ID: %d Flags: %d Property: %d\n",
+ libica_func_list[x].mech_mode_id,
+ libica_func_list[x].flags, libica_func_list[x].property));
+ }
+ }
+
+ //========== Test#2 bad parameter ============
+ rc = ica_get_functionlist(NULL, NULL);
+ if (rc != EINVAL) {
+ V_(printf("Operation failed: Expected: %d Actual: %d\n", EINVAL, rc));
+ failed++;
+ }
+
+ if (failed) {
+ printf("ica_get_functionlist tests failed.\n");
+ return 1;
+ } else {
+ printf("All ica_get_functionlist tests passed.\n");
+ return 0;
+ }
+}
diff --git a/src/tests/libica_get_version.c b/src/tests/libica_get_version.c
new file mode 100644
index 0000000..ec1ebc5
--- /dev/null
+++ b/src/tests/libica_get_version.c
@@ -0,0 +1,60 @@
+/* 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 */
+
+/*
+ * Test program for libica API call ica_get_version().
+ *
+ * Test 1: invalid input.
+ * Test 2: Valid input.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "ica_api.h"
+#include <string.h>
+#include "testcase.h"
+
+int main(int argc, char **argv)
+{
+ libica_version_info version_info;
+ int rc;
+ int failed = 0;
+
+ set_verbosity(argc, argv);
+
+ V_(printf("Testing libica API ica_get_version() w/ invalid input (NULL).\n"));
+ rc = ica_get_version(NULL);
+ if (rc == EINVAL) {
+ V_(printf("Test successful\n"));
+ }
+ else {
+ printf("Test failed: rc=%x, expected: %x \n", rc, EINVAL);
+ failed++;
+ }
+
+ V_(printf("Testing libica API ica_get_version_() w/ valid input.\n"));
+ rc = ica_get_version(&version_info);
+ if (rc == 0) {
+ V_(printf("Test successful\n"));
+ V_(printf("Major_version:%d, minor_version %d, fixpack_version %d\n",
+ version_info.major_version, version_info.minor_version,
+ version_info.fixpack_version));
+ }
+ else {
+ V_(printf("Test failed rc=%d, expected: %d \n", rc, 0));
+ failed++;
+ }
+
+ if (failed) {
+ printf("Failed ica_get_version tests: %d\n", failed);
+ return 1;
+ } else {
+ printf("All ica_get_version tests passed.\n");
+ return 0;
+ }
+}
diff --git a/src/tests/libica_keygen_test.c b/src/tests/libica_keygen_test.c
new file mode 100644
index 0000000..e2a0668
--- /dev/null
+++ b/src/tests/libica_keygen_test.c
@@ -0,0 +1,271 @@
+#include <errno.h>
+#include <openssl/crypto.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include <openssl/opensslconf.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif /* OPENSSL_FIPS */
+
+#include "ica_api.h"
+#include "testcase.h"
+
+#define ZERO_PADDING 8
+
+#define BITSTOBYTES(bits) (((bits)+7)/8)
+#define EXPO_TYPE_3 3
+#define EXPO_TYPE_65537 65537
+#define EXPO_TYPE_R 1
+
+/* print error report after function return */
+static void print_error_report(unsigned int rc_sv, int errno_sv,
+ const char *func_name);
+
+extern int errno;
+
+int main(int argc, char **argv)
+{
+ struct timeval start, end;
+ unsigned int rc = 0, rc_test = 0, expo_type = 0, key_bit_length = 0;
+ int argno_expo = 2, argno_key = 1;
+
+ set_verbosity(argc, argv);
+
+ /* first cmd line arg may be verbosity */
+ if (verbosity_ != 0) {
+ argc--;
+ argno_expo++;
+ argno_key++;
+ }
+
+ if(argc < 3){
+ printf( "usage: %s [<verbosity> (-v or -vv)] <key_bit_length>"
+ " (57..4096) <exponent_type> (3, 65537 or r [random])\n",
+ argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ if((0 == (key_bit_length=strtol(argv[argno_key], &argv[argno_key],
+ 10))) || ('\0' != *argv[argno_key]) ){
+ printf( "error - possible values for"
+ " <key_bit_length> are integers"
+ " greater than 0.\n");
+ return EXIT_FAILURE;
+ }
+
+ if(BITSTOBYTES(key_bit_length) < 8){
+ printf("error - <key_bit_length> must be at least 57.\n");
+ return EXIT_FAILURE;
+ }
+
+ if(0 == (strcmp(argv[argno_expo], "3")))
+ expo_type = EXPO_TYPE_3;
+ else if(0 == (strcmp(argv[argno_expo], "65537")))
+ expo_type = EXPO_TYPE_65537;
+ else if(0 == (strcmp(argv[argno_expo], "r")))
+ expo_type = EXPO_TYPE_R;
+ else {
+ printf( "error - possible values for <exponent_type>"
+ " are 3, 65537 or r (random)\n");
+ return EXIT_FAILURE;
+ }
+
+ unsigned char ciphertext[BITSTOBYTES(key_bit_length)],
+ decrypted[BITSTOBYTES(key_bit_length)],
+ plaintext[BITSTOBYTES(key_bit_length)];
+ memset(ciphertext, 0, (size_t) BITSTOBYTES(key_bit_length));
+ memset(decrypted, 0, (size_t) BITSTOBYTES(key_bit_length));
+ memset(plaintext, 0, (size_t) BITSTOBYTES(key_bit_length));
+
+ unsigned char modexpo_public_e[BITSTOBYTES(key_bit_length)];
+ memset(modexpo_public_e, 0, (size_t) BITSTOBYTES(key_bit_length));
+ unsigned char modexpo_public_n[BITSTOBYTES(key_bit_length)];
+ memset(modexpo_public_n, 0, (size_t) BITSTOBYTES(key_bit_length));
+
+ unsigned char crt_private_p[BITSTOBYTES(key_bit_length) / 2 + 1 + ZERO_PADDING];
+ memset(crt_private_p, 0, (size_t) (BITSTOBYTES(key_bit_length) / 2 + 1 + ZERO_PADDING));
+ unsigned char crt_private_q[BITSTOBYTES(key_bit_length) / 2 + 1];
+ memset(crt_private_q, 0, (size_t) (BITSTOBYTES(key_bit_length) / 2 + 1));
+ unsigned char crt_private_dp[BITSTOBYTES(key_bit_length) / 2 + 1 + ZERO_PADDING];
+ memset(crt_private_dp, 0, (size_t) (BITSTOBYTES(key_bit_length) / 2 + 1 + ZERO_PADDING));
+ unsigned char crt_private_dq[BITSTOBYTES(key_bit_length) / 2 + 1];
+ memset(crt_private_dq, 0, (size_t) (BITSTOBYTES(key_bit_length) / 2 + 1));
+ unsigned char crt_private_inv_q[BITSTOBYTES(key_bit_length) / 2 + 1 + ZERO_PADDING];
+ memset(crt_private_inv_q, 0, (size_t) (BITSTOBYTES(key_bit_length) / 2 + 1 + ZERO_PADDING));
+
+ ica_rsa_key_mod_expo_t modexpo_public_key = {
+ .modulus = modexpo_public_n, .exponent = modexpo_public_e,
+ .key_length = BITSTOBYTES(key_bit_length)};
+
+ ica_rsa_key_crt_t crt_private_key = {
+ .p = crt_private_p, .q = crt_private_q, .dp = crt_private_dp,
+ .dq = crt_private_dq, .qInverse = crt_private_inv_q,
+ .key_length = BITSTOBYTES(key_bit_length)};
+
+ ica_adapter_handle_t adapter_handle = 0;
+
+ V_(printf("[TEST RSA CRT]\n"));
+ V_(printf("generate random plaintext...\n"));
+ if((rc = ica_random_number_generate(BITSTOBYTES(key_bit_length) ,plaintext)) != 0){
+ ++rc_test;
+ print_error_report(rc, errno, "ica_random_number_generate");
+ }
+
+ /* make sure that plaintext < modulus */
+ plaintext[0] = 0;
+
+ VV_(printf("plaintext:\n"));
+ dump_array(plaintext, BITSTOBYTES(key_bit_length));
+
+ if((rc = ica_open_adapter(&adapter_handle)) != 0){
+ ++rc_test;
+ print_error_report(rc, errno, "ica_open_adapter");
+ }
+ if(adapter_handle == DRIVER_NOT_LOADED) {
+ V_(printf("adapter handle is %d\n", adapter_handle));
+ }
+
+ switch(expo_type){
+ case EXPO_TYPE_3:
+ *(unsigned long*)((unsigned char *)modexpo_public_key.exponent +
+ modexpo_public_key.key_length -
+ sizeof(unsigned long)) = (unsigned long) EXPO_TYPE_3;
+ break;
+ case EXPO_TYPE_65537:
+ *(unsigned long*)((unsigned char *)modexpo_public_key.exponent +
+ modexpo_public_key.key_length -
+ sizeof(unsigned long)) = (unsigned long) EXPO_TYPE_65537;
+ break;
+ case EXPO_TYPE_R:
+ /* .exponent element is not set here.
+ * if .exponent element is not set, ica_rsa_generate_mod_expo
+ * will randomly generate it */
+ break;
+ default:
+ printf( "error - unknown <exponent_type>\n");
+ return EXIT_FAILURE;
+ }
+
+ V_(printf("generate keys...\n"));
+
+ gettimeofday(&start, NULL);
+ if((rc = ica_rsa_key_generate_crt(adapter_handle,
+ key_bit_length,
+ &modexpo_public_key,
+ &crt_private_key)) != 0){
+ ++rc_test;
+ print_error_report(rc, errno, "ica_rsa_key_generate_crt");
+ }
+ gettimeofday(&end, NULL);
+ V_(printf("RSA CRT Key_gen with key length %d took: %06lu µs.\n",
+ key_bit_length, (end.tv_sec * 1000000 + end.tv_usec)
+ - (start.tv_sec * 1000000 + start.tv_usec)));
+
+ VV_(printf("public key (e,n):\ne =\n"));
+ dump_array(modexpo_public_key.exponent, BITSTOBYTES(key_bit_length));
+ VV_(printf("n =\n"));
+ dump_array(modexpo_public_key.modulus, BITSTOBYTES(key_bit_length));
+ VV_(printf("private key (p,q,dp,dq,q^-1):\np =\n"));
+ dump_array(crt_private_key.p,
+ BITSTOBYTES(key_bit_length) / 2 + 1 + ZERO_PADDING);
+ VV_(printf("q =\n"));
+ dump_array(crt_private_key.q, BITSTOBYTES(key_bit_length) / 2 + 1);
+ VV_(printf("dp =\n"));
+ dump_array(crt_private_key.dp,
+ BITSTOBYTES(key_bit_length) / 2 + 1 +ZERO_PADDING);
+ VV_(printf("dq =\n"));
+ dump_array(crt_private_key.dq, BITSTOBYTES(key_bit_length) / 2 + 1);
+ VV_(printf("q^-1 =\n"));
+ dump_array(crt_private_key.qInverse,
+ BITSTOBYTES(key_bit_length) / 2 + 1 + ZERO_PADDING);
+
+ V_(printf("encrypt...\n"));
+ if((rc = ica_rsa_mod_expo(adapter_handle, plaintext, &modexpo_public_key,
+ ciphertext)) != 0){
+ ++rc_test;
+ print_error_report(rc, errno, "ica_rsa_mod_expo");
+ }
+
+ VV_(printf("ciphertext:\n"));
+ dump_array(ciphertext, BITSTOBYTES(key_bit_length));
+
+ V_(printf("decrypt...\n"));
+ if((rc = ica_rsa_crt(adapter_handle, ciphertext, &crt_private_key,
+ decrypted)) != 0){
+ ++rc_test;
+ print_error_report(rc, errno, "ica_rsa_crt");
+ }
+
+ VV_(printf("result:\n"));
+ dump_array(decrypted, BITSTOBYTES(key_bit_length));
+
+ if((rc = ica_close_adapter(adapter_handle)) != 0){
+ ++rc_test;
+ print_error_report(rc, errno, "ica_close_adapter");
+ }
+
+ V_(printf("compare ciphertext to plaintext...\n"));
+ if(memcmp(plaintext,ciphertext,BITSTOBYTES(key_bit_length)) == 0) {
+ V_(printf("FAILED\nerror - ciphertext equals plaintext.\n"));
+ ++rc_test;
+ }
+
+ V_(printf("compare result to plaintext...\n"));
+ if(memcmp(plaintext,decrypted,BITSTOBYTES(key_bit_length)) != 0) {
+ V_(printf("FAILED\nerror - decryption result doesn't match plaintext.\n"));
+ ++rc_test;
+ }
+
+ if(0 == rc_test)
+ printf("All RSA keygen (%u bit) tests passed.\n",
+ key_bit_length);
+ else {
+ printf("RSA keygen (%u) tests failed: %u errors.",
+ key_bit_length, rc_test);
+ if (FIPS_mode())
+ printf(" (Parameters might be non FIPS conformant.)");
+ printf("\n");
+ }
+
+ return rc_test;
+}
+
+static void print_error_report(unsigned int rc_sv, int errno_sv,
+ const char *func_name)
+{
+ V_(printf("FAILED\nerror - %s returned %u: ", func_name, rc_sv));
+ switch (rc_sv) {
+ case EFAULT:
+ V_(printf("the message authentication failed.\n"));
+ break;
+ case EINVAL:
+ V_(printf("incorrect parameter.\n"));
+ break;
+ case EIO:
+ V_(printf("I/O error.\n"));
+ break;
+ case EPERM:
+ V_(printf("operation not permitted by hardware (CPACF).\n"));
+ break;
+ case ENODEV:
+ V_(printf("no such device.\n"));
+ break;
+ case ENOMEM:
+ V_(printf("not enough memory.\n"));
+ break;
+ default:
+ V_(printf("unknown return code. this shouldn't happen.\n"));
+ }
+
+ V_(printf("errno "));
+ if (0 == errno_sv){
+ V_(printf("not set.\n"));
+ }
+ else{
+ V_(printf("set to %d: %s.\n",
+ errno_sv, strerror(errno_sv)));
+ }
+}
diff --git a/src/tests/libica_rng_test.c b/src/tests/libica_rng_test.c
new file mode 100644
index 0000000..1aac2c0
--- /dev/null
+++ b/src/tests/libica_rng_test.c
@@ -0,0 +1,47 @@
+/* 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"
+#include <string.h>
+#include "testcase.h"
+
+unsigned char R[512];
+
+extern int errno;
+
+int main(int argc, char **argv)
+{
+ int rc;
+ ica_adapter_handle_t adapter_handle;
+
+ set_verbosity(argc, argv);
+
+ rc = ica_open_adapter(&adapter_handle);
+ if (rc != 0) {
+ V_(printf("ica_open_adapter failed and returned %d (0x%x).\n", rc, rc));
+ }
+
+ rc = ica_random_number_generate(sizeof R, R);
+ if (rc != 0) {
+ V_(printf("ica_random_number_generate failed and returned %d (0x%x).\n", rc, rc));
+#ifdef __s390__
+ if (rc == ENODEV) {
+ V_(printf("The usual cause of this on zSeries is that the CPACF instruction is not available.\n"));
+ }
+#endif
+ return -1;
+ }
+
+ dump_array(R, sizeof R);
+ VV_(printf("\nWell, does it look random?\n\n"));
+
+ ica_close_adapter(adapter_handle);
+ return 0;
+}
diff --git a/src/tests/libica_rsa_key_check_test.c b/src/tests/libica_rsa_key_check_test.c
new file mode 100644
index 0000000..4917a02
--- /dev/null
+++ b/src/tests/libica_rsa_key_check_test.c
@@ -0,0 +1,96 @@
+/* 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, 2015 */
+
+#include <fcntl.h>
+#include <memory.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include "ica_api.h"
+#include <sys/time.h>
+#include "libica_rsa_test.h"
+#include "testcase.h"
+
+extern int errno;
+
+int main(int argc, char **argv)
+{
+ int i, rc;
+ struct timeval start,end;
+
+ set_verbosity(argc, argv);
+
+ /* Iterate over keys (1024, 2048 and 4096 bit length */
+ /* privileged keys */
+ for (i = 0; i < 3; i++) {
+ V_(printf("modulus size = %d\n", RSA_BYTE_LENGHT[i]));
+
+ ica_rsa_key_crt_t crt_key = {RSA_BYTE_LENGHT[i], p[i], q[i], dp[i],
+ dq[i], qinv[i]};
+
+ gettimeofday(&start, NULL);
+ rc = ica_rsa_crt_key_check(&crt_key);
+ if(rc){
+ V_(printf("ica_rsa_crt_key_check failed!\n"));
+ }
+
+ gettimeofday(&end, NULL);
+ V_(printf("RSA CRT Key check: key[%d], l=%d (keyset I): %06lu µs.\n",
+ i, RSA_BYTE_LENGHT[i], (end.tv_sec * 1000000 + end.tv_usec)
+ - (start.tv_sec * 1000000 + start.tv_usec)));
+ }
+
+ /* unprivileged keys */
+ for (i = 3; i < 6; i++) {
+ V_(printf("modulus size = %d\n", RSA_BYTE_LENGHT[i]));
+
+ ica_rsa_key_crt_t crt_key = {RSA_BYTE_LENGHT[i], p[i], q[i], dp[i],
+ dq[i], qinv[i]};
+
+ gettimeofday(&start, NULL);
+ rc = ica_rsa_crt_key_check(&crt_key);
+ if(!rc){
+ V_(printf("ica_rsa_crt_key_check failed!\n"));
+ }
+
+ gettimeofday(&end, NULL);
+ V_(printf("RSA CRT key check: key[%d], l=%d (keyset II): %06lu µs.\n",
+ i, RSA_BYTE_LENGHT[i], (end.tv_sec * 1000000 + end.tv_usec)
+ - (start.tv_sec * 1000000 + start.tv_usec)));
+
+ V_(printf("Result of recalculated key part (qInv)\n"));
+ dump_array((unsigned char *)crt_key.qInverse, RSA_BYTE_LENGHT[i]/2);
+ V_(printf("Result of expected key part (qInv)\n"));
+ dump_array((unsigned char *)qinv[i-3], RSA_BYTE_LENGHT[i]/2);
+ if( memcmp(crt_key.qInverse, qinv[i-3], RSA_BYTE_LENGHT[i]/2) != 0) {
+ V_(printf("Calculated 'qInv' do not match. Failure!\n"));
+ return -1;
+ }
+ if( memcmp(crt_key.p, p[i-3], RSA_BYTE_LENGHT[i]/2 + 8) != 0) {
+ V_(printf("Prime 'p' do not match. Failure!\n"));
+ return -1;
+ }
+ if( memcmp(crt_key.q, q[i-3], RSA_BYTE_LENGHT[i]/2) != 0) {
+ V_(printf("Prime 'q' do not match. Failure!\n"));
+ return -1;
+ }
+ if( memcmp(crt_key.dp, dp[i-3], RSA_BYTE_LENGHT[i]/2 + 8) != 0) {
+ V_(printf("Parameter 'dp' do not match. Failure!\n"));
+ return -1;
+ }
+ if( memcmp(crt_key.dq, dq[i-3], RSA_BYTE_LENGHT[i]/2) != 0) {
+ V_(printf("Parameter 'dq' do not match. Failure!\n"));
+ return -1;
+ }
+
+ } // end loop
+
+ printf("All RSA key check tests passed.\n");
+ return 0;
+}
diff --git a/src/tests/libica_rsa_test.c b/src/tests/libica_rsa_test.c
new file mode 100644
index 0000000..1c16764
--- /dev/null
+++ b/src/tests/libica_rsa_test.c
@@ -0,0 +1,120 @@
+/* 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, 2015 */
+
+#include <fcntl.h>
+#include <memory.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include "ica_api.h"
+#include <sys/time.h>
+#include "libica_rsa_test.h"
+#include "testcase.h"
+
+extern int errno;
+
+static int handle_ica_error(int rc, char *message)
+{
+ V_(printf("Error in %s: ", message));
+ switch (rc) {
+ case 0:
+ V_(printf("OK\n"));
+ break;
+ case EINVAL:
+ V_(printf("Incorrect parameter.\n"));
+ break;
+ case EPERM:
+ V_(printf("Operation not permitted by Hardware.\n"));
+ break;
+ case EIO:
+ V_(printf("I/O error.\n"));
+ break;
+ default:
+ V_(perror(""));
+ }
+ return rc;
+}
+
+int main(int argc, char **argv)
+{
+ ica_adapter_handle_t adapter_handle;
+ unsigned char *my_result;
+ unsigned char *my_result2;
+ int i, rc;
+ struct timeval start,end;
+
+ set_verbosity(argc, argv);
+
+ rc = ica_open_adapter(&adapter_handle);
+ if (rc != 0) {
+ V_(printf("ica_open_adapter failed and returned %d (0x%x).\n", rc, rc));
+ }
+
+ /* Iterate over key sizes (1024, 2048 and 4096) */
+ for (i = 0; i < 6; i++) {
+ /* encrypt with public key (ME) */
+ V_(printf("modulus size = %d\n", RSA_BYTE_LENGHT[i]));
+
+ my_result = malloc(RESULT_LENGTH);
+ bzero(my_result, RESULT_LENGTH);
+
+ my_result2 = malloc(RESULT_LENGTH);
+ bzero(my_result2, RESULT_LENGTH);
+
+ ica_rsa_key_mod_expo_t mod_expo_key = {RSA_BYTE_LENGHT[i], n[i], e[i]};
+
+ rc = ica_rsa_mod_expo(adapter_handle, input_data,
+ &mod_expo_key, my_result);
+ if (rc)
+ exit(handle_ica_error(rc, "ica_rsa_key_mod_expo"));
+
+ VV_(printf("\n\n\n\n\n result of encrypt with public key\n"));
+ dump_array(my_result, RSA_BYTE_LENGHT[i]);
+ VV_(printf("Ciphertext \n"));
+ dump_array(ciphertext[i], RSA_BYTE_LENGHT[i]);
+ if (memcmp(my_result,ciphertext[i],RSA_BYTE_LENGHT[i])){
+ printf("Ciphertext mismatch\n");
+ return -1;
+ }
+
+ /* decrypt with private key (CRT) */
+ ica_rsa_key_crt_t crt_key
+ = {RSA_BYTE_LENGHT[i], p[i], q[i], dp[i], dq[i], qinv[i]};
+
+ gettimeofday(&start, NULL);
+
+ rc = ica_rsa_crt(adapter_handle, ciphertext[i], &crt_key, my_result2);
+ if(rc)
+ exit(handle_ica_error(rc, "ica_rsa_crt"));
+
+ gettimeofday(&end, NULL);
+ V_(printf("RSA decrypt with key[%d] (l=%d) took %06lu µs.\n", i,
+ RSA_BYTE_LENGHT[i], (end.tv_sec * 1000000 + end.tv_usec)
+ - (start.tv_sec*1000000+start.tv_usec)));
+
+ VV_(printf("Result of decrypt\n"));
+ dump_array((unsigned char *)my_result2, sizeof(input_data));
+ VV_(printf("original data\n"));
+ dump_array(input_data, sizeof(input_data));
+ if (memcmp(input_data,my_result2,sizeof(input_data)) != 0) {
+ printf("Results do not match. Failure!\n");
+ return -1;
+ }
+
+ } // end loop
+
+ rc = ica_open_adapter(&adapter_handle);
+ if (rc != 0) {
+ printf("ica_close_adapter failed and returned %d (0x%x).\n", rc, rc);
+ }
+
+ printf("All RSA tests passed.\n");
+ return 0;
+}
+
diff --git a/src/tests/libica_rsa_test.h b/src/tests/libica_rsa_test.h
new file mode 100644
index 0000000..f7e2d10
--- /dev/null
+++ b/src/tests/libica_rsa_test.h
@@ -0,0 +1,2175 @@
+/* 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, 2015 */
+
+#define RESULT_LENGTH 4096
+
+int RSA_BYTE_LENGHT[] = {128, 256, 512, 128, 256, 512};
+
+unsigned char e[6][512] =
+ /* 1024,[p>q] */{{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,
+ 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, 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, 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, 0x00, 0x00, 0x00},
+ /* 2048,[p>q] */ {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, 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, 0x01, 0x00, 0x01,
+ 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, 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, 0x00, 0x00},
+ /* 4096,[p>q] */ {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, 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, 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, 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, 0x00, 0x00, 0x00, 0x03},
+ /* 1024,[p<q] */ {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,
+ 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, 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, 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, 0x00, 0x00, 0x00},
+ /* 2048,[p<q] */ {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, 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, 0x01, 0x00, 0x01,
+ 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, 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, 0x00, 0x00},
+ /* 4096,[p<q] */ {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, 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, 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, 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, 0x00, 0x00, 0x00, 0x03}};
+
+unsigned char n[6][512] =
+ /* 1024,[p>q] */{{0xec, 0x51, 0xab, 0xa1, 0xf8, 0x40, 0x2c, 0x08,
+ 0x2e, 0x24, 0x52, 0x2e, 0x3c, 0x51, 0x6d, 0x98,
+ 0xad, 0xee, 0xc7, 0x7d, 0x00, 0xaf, 0xe1, 0xa8,
+ 0x61, 0xda, 0x32, 0x97, 0xb4, 0x32, 0x97, 0xe3,
+ 0x52, 0xda, 0x28, 0x45, 0x55, 0xc6, 0xb2, 0x46,
+ 0x65, 0x1b, 0x02, 0xcb, 0xbe, 0xf4, 0x2c, 0x6b,
+ 0x2a, 0x5f, 0xe1, 0xdf, 0xe9, 0xe3, 0xbc, 0x47,
+ 0xb7, 0x38, 0xb5, 0xa2, 0x78, 0x9d, 0x15, 0xe2,
+ 0x59, 0x81, 0x77, 0x6b, 0x6b, 0x2e, 0xa9, 0xdb,
+ 0x13, 0x26, 0x9c, 0xca, 0x5e, 0x0a, 0x1f, 0x3c,
+ 0x50, 0x9d, 0xd6, 0x79, 0x59, 0x99, 0x50, 0xe5,
+ 0x68, 0x1a, 0x98, 0xca, 0x11, 0xce, 0x37, 0x63,
+ 0x58, 0x22, 0x40, 0x19, 0x29, 0x72, 0x4c, 0x41,
+ 0x89, 0x0b, 0x56, 0x9e, 0x3e, 0xd5, 0x6d, 0x75,
+ 0x9e, 0x3f, 0x8a, 0x50, 0xf1, 0x0a, 0x59, 0x4a,
+ 0xc3, 0x59, 0x4b, 0xf6, 0xbb, 0xc9, 0xa5, 0x93,
+ 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, 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, 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, 0x00, 0x00, 0x00},
+ /* 2048,[p>q] */ {0xdf, 0x27, 0x1f, 0xd2, 0x5f, 0x86, 0x44, 0x49,
+ 0x6b, 0x0c, 0x81, 0xbe, 0x4b, 0xd5, 0x02, 0x97,
+ 0xef, 0x09, 0x9b, 0x00, 0x2a, 0x6f, 0xd6, 0x77,
+ 0x27, 0xeb, 0x44, 0x9c, 0xea, 0x56, 0x6e, 0xd6,
+ 0xa3, 0x98, 0x1a, 0x71, 0x31, 0x2a, 0x14, 0x1c,
+ 0xab, 0xc9, 0x81, 0x5c, 0x12, 0x09, 0xe3, 0x20,
+ 0xa2, 0x5b, 0x32, 0x46, 0x4e, 0x99, 0x99, 0xf1,
+ 0x8c, 0xa1, 0x3a, 0x9f, 0xd3, 0x89, 0x25, 0x58,
+ 0xf9, 0xe0, 0xad, 0xef, 0xdd, 0x36, 0x50, 0xdd,
+ 0x23, 0xa3, 0xf0, 0x36, 0xd6, 0x0f, 0xe3, 0x98,
+ 0x84, 0x37, 0x06, 0xa4, 0x0b, 0x0b, 0x84, 0x62,
+ 0xc8, 0xbe, 0xe3, 0xbc, 0xe1, 0x2f, 0x1f, 0x28,
+ 0x60, 0xc2, 0x44, 0x4c, 0xdc, 0x6a, 0x44, 0x47,
+ 0x6a, 0x75, 0xff, 0x4a, 0xa2, 0x42, 0x73, 0xcc,
+ 0xbe, 0x3b, 0xf8, 0x02, 0x48, 0x46, 0x5f, 0x8f,
+ 0xf8, 0xc3, 0xa7, 0xf3, 0x36, 0x7d, 0xfc, 0x0d,
+ 0xf5, 0xb6, 0x50, 0x9a, 0x4f, 0x82, 0x81, 0x1c,
+ 0xed, 0xd8, 0x1c, 0xda, 0xaa, 0x73, 0xc4, 0x91,
+ 0xda, 0x41, 0x21, 0x70, 0xd5, 0x44, 0xd4, 0xba,
+ 0x96, 0xb9, 0x7f, 0x0a, 0xfc, 0x80, 0x65, 0x49,
+ 0x8d, 0x3a, 0x49, 0xfd, 0x91, 0x09, 0x92, 0xa1,
+ 0xf0, 0x72, 0x5b, 0xe2, 0x4f, 0x46, 0x5c, 0xfe,
+ 0x7e, 0x0e, 0xab, 0xf6, 0x78, 0x99, 0x6c, 0x50,
+ 0xbc, 0x5e, 0x75, 0x24, 0xab, 0xf7, 0x3f, 0x15,
+ 0xe5, 0xbe, 0xf7, 0xd5, 0x18, 0x39, 0x4e, 0x31,
+ 0x38, 0xce, 0x49, 0x44, 0x50, 0x6a, 0xaa, 0xaf,
+ 0x3f, 0x9b, 0x23, 0x6d, 0xca, 0xb8, 0xfc, 0x00,
+ 0xf8, 0x7a, 0xf5, 0x96, 0xfd, 0xc3, 0xd9, 0xd6,
+ 0xc7, 0x5c, 0xd5, 0x08, 0x36, 0x2f, 0xae, 0x2c,
+ 0xbe, 0xdd, 0xcc, 0x4c, 0x74, 0x50, 0xb1, 0x7b,
+ 0x77, 0x6c, 0x07, 0x9e, 0xcc, 0xa1, 0xf2, 0x56,
+ 0x35, 0x1a, 0x43, 0xb9, 0x7d, 0xbe, 0x21, 0x53,
+ 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, 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, 0x00, 0x00},
+ /* 4096,[p>q] */ {0xce, 0xb2, 0x27, 0xcb, 0xd8, 0x0c, 0xc7, 0xfc,
+ 0x52, 0xf5, 0xec, 0xfd, 0xcb, 0x87, 0xa8, 0xaa,
+ 0xba, 0xf3, 0x3b, 0xfd, 0xc1, 0x9a, 0x76, 0x20,
+ 0x8f, 0xeb, 0x22, 0xd7, 0x0c, 0x6e, 0x37, 0x6c,
+ 0xec, 0xa2, 0x98, 0xa1, 0xc0, 0xa6, 0xe6, 0xb1,
+ 0xf7, 0xdc, 0x54, 0x7b, 0x91, 0xf0, 0x9f, 0x39,
+ 0xbc, 0x01, 0xc0, 0x25, 0x7a, 0xcf, 0x61, 0x13,
+ 0xa7, 0xb8, 0x12, 0xf8, 0x4a, 0x7a, 0x7e, 0xb8,
+ 0x3f, 0x2a, 0x40, 0xb5, 0x2a, 0x5b, 0x94, 0xfd,
+ 0x34, 0x19, 0x91, 0xe6, 0x5f, 0x23, 0xb4, 0x07,
+ 0x99, 0x79, 0xd0, 0xf6, 0x22, 0xc7, 0x90, 0x88,
+ 0xfd, 0xef, 0xdb, 0x4f, 0x8a, 0x00, 0xb5, 0x7d,
+ 0xba, 0xc9, 0x14, 0x06, 0xb8, 0xa8, 0x18, 0x8f,
+ 0x52, 0xa3, 0x89, 0x9e, 0xaf, 0xe5, 0x9f, 0x38,
+ 0xac, 0x21, 0x03, 0x0c, 0xa3, 0x76, 0xfb, 0xd3,
+ 0x09, 0x75, 0xc6, 0x36, 0x1d, 0x86, 0x1d, 0x18,
+ 0xbf, 0x5c, 0xe9, 0xdd, 0x21, 0x80, 0x6d, 0xa6,
+ 0xca, 0xf8, 0x7b, 0x91, 0xa0, 0xa8, 0x42, 0x42,
+ 0x0c, 0x91, 0x25, 0xf0, 0xed, 0x46, 0x08, 0xf0,
+ 0xa0, 0x2f, 0xf2, 0x8d, 0x73, 0x53, 0x27, 0x63,
+ 0xca, 0x83, 0xe3, 0x80, 0xc0, 0xf0, 0x8f, 0x9d,
+ 0x8e, 0x45, 0x82, 0xc5, 0xe9, 0x9f, 0x48, 0xf9,
+ 0xec, 0x61, 0xe9, 0x7b, 0x47, 0xfd, 0xeb, 0xe5,
+ 0x01, 0x1b, 0xc5, 0x89, 0xf1, 0xbc, 0x3a, 0xc4,
+ 0x29, 0xc8, 0x2d, 0xb1, 0x85, 0x9b, 0x92, 0x4a,
+ 0x5a, 0xcb, 0x85, 0xe2, 0x7b, 0x15, 0x6f, 0xc2,
+ 0x62, 0xb9, 0x8c, 0x52, 0xa4, 0x13, 0x75, 0x47,
+ 0xfd, 0x6b, 0x0f, 0x59, 0xff, 0x7c, 0xdc, 0xda,
+ 0x09, 0xb8, 0x55, 0x2d, 0x63, 0x52, 0x6e, 0xff,
+ 0xaf, 0x8d, 0xb7, 0x6b, 0x80, 0x6f, 0x04, 0xe4,
+ 0x78, 0x73, 0x93, 0x87, 0x5d, 0xda, 0xd2, 0xc9,
+ 0xe5, 0x6f, 0x0b, 0xee, 0x4e, 0x86, 0x4f, 0xf4,
+ 0xd2, 0x3c, 0xf5, 0x21, 0x84, 0x7c, 0x7d, 0xb0,
+ 0x10, 0xee, 0x98, 0x7d, 0x66, 0x32, 0x19, 0xdc,
+ 0xd7, 0xf0, 0x61, 0x1c, 0xfa, 0x31, 0x14, 0x3f,
+ 0x17, 0xe8, 0xe0, 0xa5, 0xae, 0xb0, 0x8e, 0xcb,
+ 0xa6, 0x73, 0xfa, 0x32, 0xa6, 0xd5, 0x33, 0x22,
+ 0xc0, 0x3e, 0x4e, 0xc6, 0x5e, 0x9f, 0x7f, 0xcf,
+ 0xa8, 0x0d, 0x26, 0xd7, 0xee, 0xfc, 0x97, 0xbb,
+ 0xe2, 0x9a, 0xe2, 0x94, 0x82, 0xc9, 0x89, 0xcf,
+ 0xb8, 0x5d, 0x60, 0x93, 0x10, 0xa1, 0x51, 0x43,
+ 0x89, 0xba, 0x76, 0x84, 0x72, 0x2d, 0x91, 0x49,
+ 0xac, 0xd8, 0xeb, 0xa8, 0xa0, 0x0b, 0xed, 0xef,
+ 0x04, 0x7e, 0x8e, 0x85, 0x88, 0xc3, 0x53, 0x84,
+ 0x2e, 0xea, 0x85, 0xd3, 0x8b, 0x5c, 0xe5, 0xba,
+ 0xab, 0x04, 0xe8, 0xbd, 0xf1, 0x6e, 0x77, 0xbf,
+ 0x40, 0xe8, 0x9c, 0x70, 0xc0, 0xe0, 0x0b, 0x95,
+ 0x0f, 0x40, 0xfb, 0xd8, 0x37, 0x44, 0xf7, 0xfe,
+ 0x38, 0x51, 0x9c, 0x92, 0xfb, 0xc4, 0x65, 0xb5,
+ 0xda, 0xd7, 0xc7, 0x1c, 0xad, 0xb2, 0xe2, 0x5f,
+ 0x22, 0x3e, 0xae, 0x74, 0xd6, 0x77, 0x32, 0xbe,
+ 0x77, 0x42, 0x3d, 0x85, 0x71, 0x3a, 0xa0, 0xfd,
+ 0x31, 0x6f, 0x4e, 0x0b, 0xd5, 0x04, 0x57, 0xb0,
+ 0xb2, 0x2a, 0x54, 0xfa, 0x8e, 0x29, 0x23, 0x8a,
+ 0x66, 0x59, 0x25, 0x1f, 0x0c, 0x68, 0x01, 0x0a,
+ 0x6e, 0xaf, 0x8e, 0xb8, 0xd3, 0xcd, 0x79, 0x9f,
+ 0xb6, 0x58, 0x16, 0x0b, 0x0a, 0x48, 0x16, 0xf1,
+ 0x1c, 0x09, 0x80, 0x38, 0xcb, 0xe9, 0x8e, 0xf3,
+ 0xb6, 0x5b, 0x4c, 0x56, 0x2d, 0x91, 0x52, 0x50,
+ 0x1f, 0xfb, 0x41, 0xd5, 0xb3, 0x6e, 0x94, 0x27,
+ 0x48, 0xd4, 0xfa, 0xaa, 0xac, 0x01, 0x27, 0x34,
+ 0x02, 0x5c, 0xfc, 0xa0, 0xa9, 0x78, 0xeb, 0x5c,
+ 0x09, 0xeb, 0x24, 0x9e, 0x38, 0x69, 0xea, 0xfd,
+ 0x3b, 0x56, 0xa8, 0x73, 0x1d, 0x5b, 0x59, 0x07},
+ /* 1024,[p<q] */ {0xec, 0x51, 0xab, 0xa1, 0xf8, 0x40, 0x2c, 0x08,
+ 0x2e, 0x24, 0x52, 0x2e, 0x3c, 0x51, 0x6d, 0x98,
+ 0xad, 0xee, 0xc7, 0x7d, 0x00, 0xaf, 0xe1, 0xa8,
+ 0x61, 0xda, 0x32, 0x97, 0xb4, 0x32, 0x97, 0xe3,
+ 0x52, 0xda, 0x28, 0x45, 0x55, 0xc6, 0xb2, 0x46,
+ 0x65, 0x1b, 0x02, 0xcb, 0xbe, 0xf4, 0x2c, 0x6b,
+ 0x2a, 0x5f, 0xe1, 0xdf, 0xe9, 0xe3, 0xbc, 0x47,
+ 0xb7, 0x38, 0xb5, 0xa2, 0x78, 0x9d, 0x15, 0xe2,
+ 0x59, 0x81, 0x77, 0x6b, 0x6b, 0x2e, 0xa9, 0xdb,
+ 0x13, 0x26, 0x9c, 0xca, 0x5e, 0x0a, 0x1f, 0x3c,
+ 0x50, 0x9d, 0xd6, 0x79, 0x59, 0x99, 0x50, 0xe5,
+ 0x68, 0x1a, 0x98, 0xca, 0x11, 0xce, 0x37, 0x63,
+ 0x58, 0x22, 0x40, 0x19, 0x29, 0x72, 0x4c, 0x41,
+ 0x89, 0x0b, 0x56, 0x9e, 0x3e, 0xd5, 0x6d, 0x75,
+ 0x9e, 0x3f, 0x8a, 0x50, 0xf1, 0x0a, 0x59, 0x4a,
+ 0xc3, 0x59, 0x4b, 0xf6, 0xbb, 0xc9, 0xa5, 0x93,
+ 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, 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, 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, 0x00, 0x00, 0x00},
+ /* 2048,[p<q] */ {0xdf, 0x27, 0x1f, 0xd2, 0x5f, 0x86, 0x44, 0x49,
+ 0x6b, 0x0c, 0x81, 0xbe, 0x4b, 0xd5, 0x02, 0x97,
+ 0xef, 0x09, 0x9b, 0x00, 0x2a, 0x6f, 0xd6, 0x77,
+ 0x27, 0xeb, 0x44, 0x9c, 0xea, 0x56, 0x6e, 0xd6,
+ 0xa3, 0x98, 0x1a, 0x71, 0x31, 0x2a, 0x14, 0x1c,
+ 0xab, 0xc9, 0x81, 0x5c, 0x12, 0x09, 0xe3, 0x20,
+ 0xa2, 0x5b, 0x32, 0x46, 0x4e, 0x99, 0x99, 0xf1,
+ 0x8c, 0xa1, 0x3a, 0x9f, 0xd3, 0x89, 0x25, 0x58,
+ 0xf9, 0xe0, 0xad, 0xef, 0xdd, 0x36, 0x50, 0xdd,
+ 0x23, 0xa3, 0xf0, 0x36, 0xd6, 0x0f, 0xe3, 0x98,
+ 0x84, 0x37, 0x06, 0xa4, 0x0b, 0x0b, 0x84, 0x62,
+ 0xc8, 0xbe, 0xe3, 0xbc, 0xe1, 0x2f, 0x1f, 0x28,
+ 0x60, 0xc2, 0x44, 0x4c, 0xdc, 0x6a, 0x44, 0x47,
+ 0x6a, 0x75, 0xff, 0x4a, 0xa2, 0x42, 0x73, 0xcc,
+ 0xbe, 0x3b, 0xf8, 0x02, 0x48, 0x46, 0x5f, 0x8f,
+ 0xf8, 0xc3, 0xa7, 0xf3, 0x36, 0x7d, 0xfc, 0x0d,
+ 0xf5, 0xb6, 0x50, 0x9a, 0x4f, 0x82, 0x81, 0x1c,
+ 0xed, 0xd8, 0x1c, 0xda, 0xaa, 0x73, 0xc4, 0x91,
+ 0xda, 0x41, 0x21, 0x70, 0xd5, 0x44, 0xd4, 0xba,
+ 0x96, 0xb9, 0x7f, 0x0a, 0xfc, 0x80, 0x65, 0x49,
+ 0x8d, 0x3a, 0x49, 0xfd, 0x91, 0x09, 0x92, 0xa1,
+ 0xf0, 0x72, 0x5b, 0xe2, 0x4f, 0x46, 0x5c, 0xfe,
+ 0x7e, 0x0e, 0xab, 0xf6, 0x78, 0x99, 0x6c, 0x50,
+ 0xbc, 0x5e, 0x75, 0x24, 0xab, 0xf7, 0x3f, 0x15,
+ 0xe5, 0xbe, 0xf7, 0xd5, 0x18, 0x39, 0x4e, 0x31,
+ 0x38, 0xce, 0x49, 0x44, 0x50, 0x6a, 0xaa, 0xaf,
+ 0x3f, 0x9b, 0x23, 0x6d, 0xca, 0xb8, 0xfc, 0x00,
+ 0xf8, 0x7a, 0xf5, 0x96, 0xfd, 0xc3, 0xd9, 0xd6,
+ 0xc7, 0x5c, 0xd5, 0x08, 0x36, 0x2f, 0xae, 0x2c,
+ 0xbe, 0xdd, 0xcc, 0x4c, 0x74, 0x50, 0xb1, 0x7b,
+ 0x77, 0x6c, 0x07, 0x9e, 0xcc, 0xa1, 0xf2, 0x56,
+ 0x35, 0x1a, 0x43, 0xb9, 0x7d, 0xbe, 0x21, 0x53,
+ 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, 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, 0x00, 0x00},
+ /* 4096,[p<q] */ {0xce, 0xb2, 0x27, 0xcb, 0xd8, 0x0c, 0xc7, 0xfc,
+ 0x52, 0xf5, 0xec, 0xfd, 0xcb, 0x87, 0xa8, 0xaa,
+ 0xba, 0xf3, 0x3b, 0xfd, 0xc1, 0x9a, 0x76, 0x20,
+ 0x8f, 0xeb, 0x22, 0xd7, 0x0c, 0x6e, 0x37, 0x6c,
+ 0xec, 0xa2, 0x98, 0xa1, 0xc0, 0xa6, 0xe6, 0xb1,
+ 0xf7, 0xdc, 0x54, 0x7b, 0x91, 0xf0, 0x9f, 0x39,
+ 0xbc, 0x01, 0xc0, 0x25, 0x7a, 0xcf, 0x61, 0x13,
+ 0xa7, 0xb8, 0x12, 0xf8, 0x4a, 0x7a, 0x7e, 0xb8,
+ 0x3f, 0x2a, 0x40, 0xb5, 0x2a, 0x5b, 0x94, 0xfd,
+ 0x34, 0x19, 0x91, 0xe6, 0x5f, 0x23, 0xb4, 0x07,
+ 0x99, 0x79, 0xd0, 0xf6, 0x22, 0xc7, 0x90, 0x88,
+ 0xfd, 0xef, 0xdb, 0x4f, 0x8a, 0x00, 0xb5, 0x7d,
+ 0xba, 0xc9, 0x14, 0x06, 0xb8, 0xa8, 0x18, 0x8f,
+ 0x52, 0xa3, 0x89, 0x9e, 0xaf, 0xe5, 0x9f, 0x38,
+ 0xac, 0x21, 0x03, 0x0c, 0xa3, 0x76, 0xfb, 0xd3,
+ 0x09, 0x75, 0xc6, 0x36, 0x1d, 0x86, 0x1d, 0x18,
+ 0xbf, 0x5c, 0xe9, 0xdd, 0x21, 0x80, 0x6d, 0xa6,
+ 0xca, 0xf8, 0x7b, 0x91, 0xa0, 0xa8, 0x42, 0x42,
+ 0x0c, 0x91, 0x25, 0xf0, 0xed, 0x46, 0x08, 0xf0,
+ 0xa0, 0x2f, 0xf2, 0x8d, 0x73, 0x53, 0x27, 0x63,
+ 0xca, 0x83, 0xe3, 0x80, 0xc0, 0xf0, 0x8f, 0x9d,
+ 0x8e, 0x45, 0x82, 0xc5, 0xe9, 0x9f, 0x48, 0xf9,
+ 0xec, 0x61, 0xe9, 0x7b, 0x47, 0xfd, 0xeb, 0xe5,
+ 0x01, 0x1b, 0xc5, 0x89, 0xf1, 0xbc, 0x3a, 0xc4,
+ 0x29, 0xc8, 0x2d, 0xb1, 0x85, 0x9b, 0x92, 0x4a,
+ 0x5a, 0xcb, 0x85, 0xe2, 0x7b, 0x15, 0x6f, 0xc2,
+ 0x62, 0xb9, 0x8c, 0x52, 0xa4, 0x13, 0x75, 0x47,
+ 0xfd, 0x6b, 0x0f, 0x59, 0xff, 0x7c, 0xdc, 0xda,
+ 0x09, 0xb8, 0x55, 0x2d, 0x63, 0x52, 0x6e, 0xff,
+ 0xaf, 0x8d, 0xb7, 0x6b, 0x80, 0x6f, 0x04, 0xe4,
+ 0x78, 0x73, 0x93, 0x87, 0x5d, 0xda, 0xd2, 0xc9,
+ 0xe5, 0x6f, 0x0b, 0xee, 0x4e, 0x86, 0x4f, 0xf4,
+ 0xd2, 0x3c, 0xf5, 0x21, 0x84, 0x7c, 0x7d, 0xb0,
+ 0x10, 0xee, 0x98, 0x7d, 0x66, 0x32, 0x19, 0xdc,
+ 0xd7, 0xf0, 0x61, 0x1c, 0xfa, 0x31, 0x14, 0x3f,
+ 0x17, 0xe8, 0xe0, 0xa5, 0xae, 0xb0, 0x8e, 0xcb,
+ 0xa6, 0x73, 0xfa, 0x32, 0xa6, 0xd5, 0x33, 0x22,
+ 0xc0, 0x3e, 0x4e, 0xc6, 0x5e, 0x9f, 0x7f, 0xcf,
+ 0xa8, 0x0d, 0x26, 0xd7, 0xee, 0xfc, 0x97, 0xbb,
+ 0xe2, 0x9a, 0xe2, 0x94, 0x82, 0xc9, 0x89, 0xcf,
+ 0xb8, 0x5d, 0x60, 0x93, 0x10, 0xa1, 0x51, 0x43,
+ 0x89, 0xba, 0x76, 0x84, 0x72, 0x2d, 0x91, 0x49,
+ 0xac, 0xd8, 0xeb, 0xa8, 0xa0, 0x0b, 0xed, 0xef,
+ 0x04, 0x7e, 0x8e, 0x85, 0x88, 0xc3, 0x53, 0x84,
+ 0x2e, 0xea, 0x85, 0xd3, 0x8b, 0x5c, 0xe5, 0xba,
+ 0xab, 0x04, 0xe8, 0xbd, 0xf1, 0x6e, 0x77, 0xbf,
+ 0x40, 0xe8, 0x9c, 0x70, 0xc0, 0xe0, 0x0b, 0x95,
+ 0x0f, 0x40, 0xfb, 0xd8, 0x37, 0x44, 0xf7, 0xfe,
+ 0x38, 0x51, 0x9c, 0x92, 0xfb, 0xc4, 0x65, 0xb5,
+ 0xda, 0xd7, 0xc7, 0x1c, 0xad, 0xb2, 0xe2, 0x5f,
+ 0x22, 0x3e, 0xae, 0x74, 0xd6, 0x77, 0x32, 0xbe,
+ 0x77, 0x42, 0x3d, 0x85, 0x71, 0x3a, 0xa0, 0xfd,
+ 0x31, 0x6f, 0x4e, 0x0b, 0xd5, 0x04, 0x57, 0xb0,
+ 0xb2, 0x2a, 0x54, 0xfa, 0x8e, 0x29, 0x23, 0x8a,
+ 0x66, 0x59, 0x25, 0x1f, 0x0c, 0x68, 0x01, 0x0a,
+ 0x6e, 0xaf, 0x8e, 0xb8, 0xd3, 0xcd, 0x79, 0x9f,
+ 0xb6, 0x58, 0x16, 0x0b, 0x0a, 0x48, 0x16, 0xf1,
+ 0x1c, 0x09, 0x80, 0x38, 0xcb, 0xe9, 0x8e, 0xf3,
+ 0xb6, 0x5b, 0x4c, 0x56, 0x2d, 0x91, 0x52, 0x50,
+ 0x1f, 0xfb, 0x41, 0xd5, 0xb3, 0x6e, 0x94, 0x27,
+ 0x48, 0xd4, 0xfa, 0xaa, 0xac, 0x01, 0x27, 0x34,
+ 0x02, 0x5c, 0xfc, 0xa0, 0xa9, 0x78, 0xeb, 0x5c,
+ 0x09, 0xeb, 0x24, 0x9e, 0x38, 0x69, 0xea, 0xfd,
+ 0x3b, 0x56, 0xa8, 0x73, 0x1d, 0x5b, 0x59, 0x07}};
+
+unsigned char dp[6][264] =
+ /* 1024,[p>q] */{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xa7, 0xcf, 0xa2, 0x18, 0x2c, 0xa9, 0xb4, 0xb9,
+ 0xf5, 0x9e, 0xc9, 0x04, 0x16, 0xd9, 0xa6, 0x8b,
+ 0x90, 0x4a, 0x19, 0x6d, 0x64, 0xb7, 0x17, 0x67,
+ 0x53, 0xfa, 0x4e, 0x8d, 0xde, 0xa6, 0x94, 0x32,
+ 0x5d, 0xcf, 0x58, 0x3e, 0x90, 0xbb, 0x30, 0x19,
+ 0x96, 0x38, 0x95, 0xb6, 0xca, 0x2f, 0xfa, 0x22,
+ 0x81, 0x65, 0x3b, 0x3c, 0x95, 0x9e, 0x79, 0x75,
+ 0xe4, 0x93, 0x50, 0xf1, 0x88, 0x6b, 0xc1, 0x87,
+ 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, 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},
+ /* 2048,[p>q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xed, 0x10, 0x2a, 0xcd, 0xb2, 0x68, 0x71, 0x53,
+ 0x4d, 0x1c, 0x41, 0x4e, 0xca, 0xd9, 0xa4, 0xd7,
+ 0x32, 0xfe, 0x95, 0xb1, 0x0e, 0xea, 0x37, 0x0d,
+ 0xa6, 0x2f, 0x05, 0xde, 0x2c, 0x39, 0x3b, 0x1a,
+ 0x63, 0x33, 0x03, 0xea, 0x74, 0x1b, 0x6b, 0x32,
+ 0x69, 0xc9, 0x7f, 0x70, 0x4b, 0x35, 0x27, 0x02,
+ 0xc9, 0xae, 0x79, 0x92, 0x2f, 0x7b, 0xe8, 0xd1,
+ 0x0d, 0xb6, 0x7f, 0x02, 0x6a, 0x81, 0x45, 0xde,
+ 0x41, 0xb3, 0x0c, 0x0a, 0x42, 0xbf, 0x92, 0x3b,
+ 0xac, 0x5f, 0x75, 0x04, 0xc2, 0x48, 0x60, 0x4b,
+ 0x9f, 0xaa, 0x57, 0xed, 0x6b, 0x32, 0x46, 0xc6,
+ 0xba, 0x15, 0x8e, 0x36, 0xc6, 0x44, 0xf8, 0xb9,
+ 0x54, 0x8f, 0xcf, 0x4f, 0x07, 0xe0, 0x54, 0xa5,
+ 0x6f, 0x76, 0x86, 0x74, 0x05, 0x44, 0x40, 0xbc,
+ 0x0d, 0xcb, 0xbc, 0x9b, 0x52, 0x8f, 0x64, 0xa0,
+ 0x17, 0x06, 0xe0, 0x5b, 0x0b, 0x91, 0x10, 0x6f,
+ 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, 0x00},
+ /* 4096,[p>q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x9c, 0x30, 0x60, 0xcf, 0xaa, 0xed, 0x64, 0xa0,
+ 0xe2, 0xa4, 0x24, 0x0d, 0x59, 0x5f, 0x1b, 0xda,
+ 0x92, 0x6e, 0xc1, 0xb6, 0x77, 0x25, 0x26, 0x93,
+ 0xbc, 0x00, 0xba, 0xc9, 0x1c, 0x22, 0xb4, 0x91,
+ 0x31, 0x92, 0xa9, 0x97, 0xf2, 0xac, 0x68, 0x92,
+ 0x60, 0xca, 0x56, 0xc4, 0xb7, 0xc2, 0x97, 0x7b,
+ 0x5a, 0x2c, 0x99, 0x73, 0xf1, 0x20, 0x7a, 0xe4,
+ 0xa3, 0xe5, 0x9a, 0x45, 0x5f, 0xd7, 0x65, 0x62,
+ 0xbf, 0x85, 0xa1, 0x48, 0xbb, 0x6a, 0xfd, 0xd8,
+ 0x7a, 0xa5, 0x5f, 0x7b, 0xcf, 0xf7, 0x30, 0x2e,
+ 0x52, 0x61, 0x13, 0x81, 0x63, 0x73, 0x85, 0xcb,
+ 0x60, 0xdb, 0x57, 0xb2, 0xfc, 0x55, 0x6a, 0xee,
+ 0x97, 0xf4, 0x0c, 0x76, 0xd7, 0x57, 0xe1, 0x95,
+ 0xd4, 0x02, 0xc7, 0x3f, 0x8c, 0x5f, 0xe3, 0x83,
+ 0x78, 0x58, 0x5e, 0x34, 0x59, 0xfa, 0x64, 0xc8,
+ 0x26, 0x3e, 0xf3, 0x5e, 0x06, 0x96, 0xd0, 0x63,
+ 0xaa, 0x6b, 0xf0, 0x3f, 0x3c, 0x7b, 0xd9, 0x98,
+ 0x0c, 0x97, 0x49, 0xe4, 0x10, 0x5a, 0x6d, 0x57,
+ 0x46, 0x61, 0xd1, 0x78, 0x35, 0x06, 0xf0, 0x5a,
+ 0x68, 0xe1, 0xdd, 0xac, 0x3a, 0x95, 0xfb, 0x4f,
+ 0xd9, 0x46, 0x6b, 0x98, 0x55, 0x6e, 0x4b, 0x39,
+ 0x9f, 0xbb, 0x05, 0x49, 0xbf, 0x53, 0x93, 0xd4,
+ 0x39, 0xcd, 0xed, 0xa2, 0xe9, 0x02, 0x81, 0xd3,
+ 0x69, 0x08, 0x02, 0x7c, 0xa8, 0xc1, 0xd5, 0xa1,
+ 0x58, 0xe3, 0x81, 0xea, 0x8b, 0xd2, 0x23, 0x4c,
+ 0x1c, 0x99, 0x4d, 0x81, 0x8d, 0x82, 0x1e, 0x85,
+ 0xf7, 0xa9, 0xf8, 0xe6, 0x53, 0x8e, 0x85, 0xcb,
+ 0x79, 0xbb, 0x89, 0x49, 0xce, 0x3c, 0x18, 0x5d,
+ 0xa4, 0x3c, 0x8c, 0x13, 0x7c, 0xe2, 0xc6, 0x97,
+ 0xf0, 0xbe, 0xfa, 0xb6, 0x87, 0xbe, 0xc0, 0xed,
+ 0x70, 0x39, 0x8e, 0x0b, 0x23, 0xb9, 0x51, 0x83,
+ 0x38, 0xc8, 0x37, 0x3e, 0x38, 0x7a, 0x82, 0xfb},
+ /* 1024,[p<q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xa0, 0x3a, 0x18, 0xa4, 0x1c, 0x3c, 0x49, 0x09,
+ 0xd0, 0x84, 0x4a, 0x8c, 0x7c, 0xce, 0xdf, 0x9e,
+ 0x90, 0x7d, 0xc4, 0xca, 0x7e, 0x2d, 0x3d, 0xbc,
+ 0x09, 0x71, 0x79, 0xd0, 0xc0, 0xae, 0xa6, 0xc1,
+ 0x9d, 0xf0, 0x16, 0xf0, 0x1f, 0x68, 0x9a, 0xc5,
+ 0x2b, 0xf3, 0x5a, 0xfc, 0x2c, 0xf5, 0xa7, 0xec,
+ 0xd9, 0xa2, 0xac, 0x49, 0xcc, 0x76, 0x9c, 0xd8,
+ 0x4c, 0x59, 0x5e, 0x38, 0xd2, 0x85, 0xd3, 0x3b,
+ 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, 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},
+ /* 2048,[p<q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x68, 0x27, 0x92, 0x4a, 0x85, 0xe8, 0x8b, 0x55,
+ 0xba, 0x00, 0xf8, 0x21, 0x91, 0x28, 0xbd, 0x37,
+ 0x24, 0xc6, 0xb7, 0xd1, 0xdf, 0xe5, 0x62, 0x9e,
+ 0xf1, 0x97, 0x92, 0x5f, 0xec, 0xaf, 0xf5, 0xed,
+ 0xb9, 0xcd, 0xf3, 0xa7, 0xbe, 0xfd, 0x8e, 0xa2,
+ 0xe8, 0xdd, 0x37, 0x07, 0x13, 0x8b, 0x3f, 0xf8,
+ 0x7c, 0x3c, 0x39, 0xc5, 0x7f, 0x43, 0x9e, 0x56,
+ 0x2e, 0x2a, 0xa8, 0x05, 0xa3, 0x9d, 0x7c, 0xd7,
+ 0x99, 0x66, 0xd2, 0xec, 0xe7, 0x84, 0x5f, 0x1d,
+ 0xbc, 0x16, 0xbe, 0xe9, 0x99, 0x99, 0xe4, 0xd0,
+ 0xbf, 0x9e, 0xec, 0xa4, 0x5f, 0xcd, 0xa8, 0xa8,
+ 0x50, 0x00, 0x35, 0xfe, 0x6b, 0x5f, 0x03, 0xbc,
+ 0x2f, 0x6d, 0x1b, 0xfc, 0x4d, 0x4d, 0x0a, 0x37,
+ 0x23, 0x96, 0x1a, 0xf0, 0xcd, 0xce, 0x4a, 0x01,
+ 0xee, 0xc8, 0x2d, 0x7f, 0x54, 0x58, 0xec, 0x19,
+ 0xe7, 0x1b, 0x90, 0xee, 0xef, 0x7d, 0xff, 0x61,
+ 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, 0x00},
+ /* 4096,[p<q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x96, 0x91, 0xf7, 0x52, 0x11, 0xdc, 0x4a, 0x26,
+ 0xf8, 0x51, 0xa6, 0x1a, 0x75, 0xd1, 0xbe, 0x32,
+ 0xe9, 0x34, 0x39, 0x1f, 0xb3, 0x05, 0x58, 0x35,
+ 0xaa, 0x51, 0xf6, 0x53, 0x1e, 0xa5, 0x5f, 0x38,
+ 0x02, 0xa8, 0xdb, 0xa5, 0x58, 0xfc, 0x95, 0x21,
+ 0xa3, 0x6a, 0x1c, 0x4e, 0xd5, 0x64, 0x1a, 0x94,
+ 0xeb, 0xfb, 0xca, 0x56, 0x6e, 0xfc, 0xd7, 0xb1,
+ 0x82, 0x95, 0x8a, 0x8c, 0x17, 0xbd, 0x24, 0xd9,
+ 0xfd, 0xc9, 0x22, 0x3d, 0x52, 0x90, 0x44, 0xf6,
+ 0xfc, 0xb5, 0x63, 0xca, 0xc9, 0x6f, 0x9b, 0xbd,
+ 0x1d, 0x98, 0xe7, 0xe2, 0x5c, 0x5c, 0x89, 0x2f,
+ 0xdd, 0x54, 0x18, 0x78, 0xdb, 0x12, 0xf5, 0xef,
+ 0xfe, 0x4e, 0x1b, 0x9e, 0xaa, 0x3e, 0x77, 0x36,
+ 0x8e, 0xa9, 0x46, 0xb3, 0xa2, 0x45, 0x3c, 0xa4,
+ 0xb3, 0xc4, 0xf1, 0x82, 0xcc, 0x49, 0x6b, 0xaa,
+ 0xf6, 0x41, 0x1d, 0xa0, 0x12, 0x29, 0xfc, 0xcc,
+ 0xbf, 0xf4, 0xd3, 0x90, 0xe5, 0x3e, 0x77, 0x86,
+ 0x35, 0xe6, 0x76, 0xcd, 0x0c, 0xaa, 0x8c, 0xae,
+ 0xe1, 0x07, 0x7a, 0xd3, 0xd4, 0x5c, 0xa4, 0x46,
+ 0xa0, 0x46, 0xb9, 0x04, 0x08, 0x5d, 0xce, 0xc7,
+ 0x78, 0x04, 0x48, 0xde, 0x46, 0xfc, 0x6f, 0xa0,
+ 0xcf, 0x2c, 0x91, 0x87, 0xed, 0xb8, 0x51, 0xd7,
+ 0xb8, 0x0d, 0x88, 0xa3, 0xf2, 0x92, 0xdf, 0x6c,
+ 0x0e, 0x54, 0x84, 0xc0, 0x39, 0xf4, 0xf0, 0xa3,
+ 0x94, 0x42, 0xdd, 0xcb, 0x4d, 0xef, 0x74, 0x37,
+ 0x33, 0xc8, 0x96, 0x01, 0xa3, 0xda, 0x12, 0xdf,
+ 0x33, 0xf5, 0x58, 0x80, 0xc2, 0xdc, 0x8b, 0xcb,
+ 0x40, 0x7d, 0x78, 0xbb, 0x3e, 0x40, 0xa3, 0xbe,
+ 0xd2, 0x94, 0x34, 0xa0, 0x47, 0xd3, 0x3c, 0x62,
+ 0x65, 0x92, 0x5c, 0xdd, 0x3c, 0xa8, 0x4f, 0xc6,
+ 0x05, 0xa7, 0x26, 0x91, 0xd6, 0xf7, 0x8b, 0x41,
+ 0xf3, 0x52, 0x08, 0x3d, 0x95, 0x6e, 0x70, 0xff}};
+
+unsigned char dq[6][256] =
+ /* 1024,[p>q] */{{0xa0, 0x3a, 0x18, 0xa4, 0x1c, 0x3c, 0x49, 0x09,
+ 0xd0, 0x84, 0x4a, 0x8c, 0x7c, 0xce, 0xdf, 0x9e,
+ 0x90, 0x7d, 0xc4, 0xca, 0x7e, 0x2d, 0x3d, 0xbc,
+ 0x09, 0x71, 0x79, 0xd0, 0xc0, 0xae, 0xa6, 0xc1,
+ 0x9d, 0xf0, 0x16, 0xf0, 0x1f, 0x68, 0x9a, 0xc5,
+ 0x2b, 0xf3, 0x5a, 0xfc, 0x2c, 0xf5, 0xa7, 0xec,
+ 0xd9, 0xa2, 0xac, 0x49, 0xcc, 0x76, 0x9c, 0xd8,
+ 0x4c, 0x59, 0x5e, 0x38, 0xd2, 0x85, 0xd3, 0x3b,
+ 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, 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},
+ /* 2048,[p>q] */ {0x68, 0x27, 0x92, 0x4a, 0x85, 0xe8, 0x8b, 0x55,
+ 0xba, 0x00, 0xf8, 0x21, 0x91, 0x28, 0xbd, 0x37,
+ 0x24, 0xc6, 0xb7, 0xd1, 0xdf, 0xe5, 0x62, 0x9e,
+ 0xf1, 0x97, 0x92, 0x5f, 0xec, 0xaf, 0xf5, 0xed,
+ 0xb9, 0xcd, 0xf3, 0xa7, 0xbe, 0xfd, 0x8e, 0xa2,
+ 0xe8, 0xdd, 0x37, 0x07, 0x13, 0x8b, 0x3f, 0xf8,
+ 0x7c, 0x3c, 0x39, 0xc5, 0x7f, 0x43, 0x9e, 0x56,
+ 0x2e, 0x2a, 0xa8, 0x05, 0xa3, 0x9d, 0x7c, 0xd7,
+ 0x99, 0x66, 0xd2, 0xec, 0xe7, 0x84, 0x5f, 0x1d,
+ 0xbc, 0x16, 0xbe, 0xe9, 0x99, 0x99, 0xe4, 0xd0,
+ 0xbf, 0x9e, 0xec, 0xa4, 0x5f, 0xcd, 0xa8, 0xa8,
+ 0x50, 0x00, 0x35, 0xfe, 0x6b, 0x5f, 0x03, 0xbc,
+ 0x2f, 0x6d, 0x1b, 0xfc, 0x4d, 0x4d, 0x0a, 0x37,
+ 0x23, 0x96, 0x1a, 0xf0, 0xcd, 0xce, 0x4a, 0x01,
+ 0xee, 0xc8, 0x2d, 0x7f, 0x54, 0x58, 0xec, 0x19,
+ 0xe7, 0x1b, 0x90, 0xee, 0xef, 0x7d, 0xff, 0x61,
+ 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, 0x00},
+ /* 4096,[p>q] */ {0x96, 0x91, 0xf7, 0x52, 0x11, 0xdc, 0x4a, 0x26,
+ 0xf8, 0x51, 0xa6, 0x1a, 0x75, 0xd1, 0xbe, 0x32,
+ 0xe9, 0x34, 0x39, 0x1f, 0xb3, 0x05, 0x58, 0x35,
+ 0xaa, 0x51, 0xf6, 0x53, 0x1e, 0xa5, 0x5f, 0x38,
+ 0x02, 0xa8, 0xdb, 0xa5, 0x58, 0xfc, 0x95, 0x21,
+ 0xa3, 0x6a, 0x1c, 0x4e, 0xd5, 0x64, 0x1a, 0x94,
+ 0xeb, 0xfb, 0xca, 0x56, 0x6e, 0xfc, 0xd7, 0xb1,
+ 0x82, 0x95, 0x8a, 0x8c, 0x17, 0xbd, 0x24, 0xd9,
+ 0xfd, 0xc9, 0x22, 0x3d, 0x52, 0x90, 0x44, 0xf6,
+ 0xfc, 0xb5, 0x63, 0xca, 0xc9, 0x6f, 0x9b, 0xbd,
+ 0x1d, 0x98, 0xe7, 0xe2, 0x5c, 0x5c, 0x89, 0x2f,
+ 0xdd, 0x54, 0x18, 0x78, 0xdb, 0x12, 0xf5, 0xef,
+ 0xfe, 0x4e, 0x1b, 0x9e, 0xaa, 0x3e, 0x77, 0x36,
+ 0x8e, 0xa9, 0x46, 0xb3, 0xa2, 0x45, 0x3c, 0xa4,
+ 0xb3, 0xc4, 0xf1, 0x82, 0xcc, 0x49, 0x6b, 0xaa,
+ 0xf6, 0x41, 0x1d, 0xa0, 0x12, 0x29, 0xfc, 0xcc,
+ 0xbf, 0xf4, 0xd3, 0x90, 0xe5, 0x3e, 0x77, 0x86,
+ 0x35, 0xe6, 0x76, 0xcd, 0x0c, 0xaa, 0x8c, 0xae,
+ 0xe1, 0x07, 0x7a, 0xd3, 0xd4, 0x5c, 0xa4, 0x46,
+ 0xa0, 0x46, 0xb9, 0x04, 0x08, 0x5d, 0xce, 0xc7,
+ 0x78, 0x04, 0x48, 0xde, 0x46, 0xfc, 0x6f, 0xa0,
+ 0xcf, 0x2c, 0x91, 0x87, 0xed, 0xb8, 0x51, 0xd7,
+ 0xb8, 0x0d, 0x88, 0xa3, 0xf2, 0x92, 0xdf, 0x6c,
+ 0x0e, 0x54, 0x84, 0xc0, 0x39, 0xf4, 0xf0, 0xa3,
+ 0x94, 0x42, 0xdd, 0xcb, 0x4d, 0xef, 0x74, 0x37,
+ 0x33, 0xc8, 0x96, 0x01, 0xa3, 0xda, 0x12, 0xdf,
+ 0x33, 0xf5, 0x58, 0x80, 0xc2, 0xdc, 0x8b, 0xcb,
+ 0x40, 0x7d, 0x78, 0xbb, 0x3e, 0x40, 0xa3, 0xbe,
+ 0xd2, 0x94, 0x34, 0xa0, 0x47, 0xd3, 0x3c, 0x62,
+ 0x65, 0x92, 0x5c, 0xdd, 0x3c, 0xa8, 0x4f, 0xc6,
+ 0x05, 0xa7, 0x26, 0x91, 0xd6, 0xf7, 0x8b, 0x41,
+ 0xf3, 0x52, 0x08, 0x3d, 0x95, 0x6e, 0x70, 0xff},
+ /* 1024,[p<q] */ {0xa7, 0xcf, 0xa2, 0x18, 0x2c, 0xa9, 0xb4, 0xb9,
+ 0xf5, 0x9e, 0xc9, 0x04, 0x16, 0xd9, 0xa6, 0x8b,
+ 0x90, 0x4a, 0x19, 0x6d, 0x64, 0xb7, 0x17, 0x67,
+ 0x53, 0xfa, 0x4e, 0x8d, 0xde, 0xa6, 0x94, 0x32,
+ 0x5d, 0xcf, 0x58, 0x3e, 0x90, 0xbb, 0x30, 0x19,
+ 0x96, 0x38, 0x95, 0xb6, 0xca, 0x2f, 0xfa, 0x22,
+ 0x81, 0x65, 0x3b, 0x3c, 0x95, 0x9e, 0x79, 0x75,
+ 0xe4, 0x93, 0x50, 0xf1, 0x88, 0x6b, 0xc1, 0x87,
+ 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, 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},
+ /* 2048,[p<q] */ {0xed, 0x10, 0x2a, 0xcd, 0xb2, 0x68, 0x71, 0x53,
+ 0x4d, 0x1c, 0x41, 0x4e, 0xca, 0xd9, 0xa4, 0xd7,
+ 0x32, 0xfe, 0x95, 0xb1, 0x0e, 0xea, 0x37, 0x0d,
+ 0xa6, 0x2f, 0x05, 0xde, 0x2c, 0x39, 0x3b, 0x1a,
+ 0x63, 0x33, 0x03, 0xea, 0x74, 0x1b, 0x6b, 0x32,
+ 0x69, 0xc9, 0x7f, 0x70, 0x4b, 0x35, 0x27, 0x02,
+ 0xc9, 0xae, 0x79, 0x92, 0x2f, 0x7b, 0xe8, 0xd1,
+ 0x0d, 0xb6, 0x7f, 0x02, 0x6a, 0x81, 0x45, 0xde,
+ 0x41, 0xb3, 0x0c, 0x0a, 0x42, 0xbf, 0x92, 0x3b,
+ 0xac, 0x5f, 0x75, 0x04, 0xc2, 0x48, 0x60, 0x4b,
+ 0x9f, 0xaa, 0x57, 0xed, 0x6b, 0x32, 0x46, 0xc6,
+ 0xba, 0x15, 0x8e, 0x36, 0xc6, 0x44, 0xf8, 0xb9,
+ 0x54, 0x8f, 0xcf, 0x4f, 0x07, 0xe0, 0x54, 0xa5,
+ 0x6f, 0x76, 0x86, 0x74, 0x05, 0x44, 0x40, 0xbc,
+ 0x0d, 0xcb, 0xbc, 0x9b, 0x52, 0x8f, 0x64, 0xa0,
+ 0x17, 0x06, 0xe0, 0x5b, 0x0b, 0x91, 0x10, 0x6f,
+ 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, 0x00},
+ /* 4096,[p<q] */ {0x9c, 0x30, 0x60, 0xcf, 0xaa, 0xed, 0x64, 0xa0,
+ 0xe2, 0xa4, 0x24, 0x0d, 0x59, 0x5f, 0x1b, 0xda,
+ 0x92, 0x6e, 0xc1, 0xb6, 0x77, 0x25, 0x26, 0x93,
+ 0xbc, 0x00, 0xba, 0xc9, 0x1c, 0x22, 0xb4, 0x91,
+ 0x31, 0x92, 0xa9, 0x97, 0xf2, 0xac, 0x68, 0x92,
+ 0x60, 0xca, 0x56, 0xc4, 0xb7, 0xc2, 0x97, 0x7b,
+ 0x5a, 0x2c, 0x99, 0x73, 0xf1, 0x20, 0x7a, 0xe4,
+ 0xa3, 0xe5, 0x9a, 0x45, 0x5f, 0xd7, 0x65, 0x62,
+ 0xbf, 0x85, 0xa1, 0x48, 0xbb, 0x6a, 0xfd, 0xd8,
+ 0x7a, 0xa5, 0x5f, 0x7b, 0xcf, 0xf7, 0x30, 0x2e,
+ 0x52, 0x61, 0x13, 0x81, 0x63, 0x73, 0x85, 0xcb,
+ 0x60, 0xdb, 0x57, 0xb2, 0xfc, 0x55, 0x6a, 0xee,
+ 0x97, 0xf4, 0x0c, 0x76, 0xd7, 0x57, 0xe1, 0x95,
+ 0xd4, 0x02, 0xc7, 0x3f, 0x8c, 0x5f, 0xe3, 0x83,
+ 0x78, 0x58, 0x5e, 0x34, 0x59, 0xfa, 0x64, 0xc8,
+ 0x26, 0x3e, 0xf3, 0x5e, 0x06, 0x96, 0xd0, 0x63,
+ 0xaa, 0x6b, 0xf0, 0x3f, 0x3c, 0x7b, 0xd9, 0x98,
+ 0x0c, 0x97, 0x49, 0xe4, 0x10, 0x5a, 0x6d, 0x57,
+ 0x46, 0x61, 0xd1, 0x78, 0x35, 0x06, 0xf0, 0x5a,
+ 0x68, 0xe1, 0xdd, 0xac, 0x3a, 0x95, 0xfb, 0x4f,
+ 0xd9, 0x46, 0x6b, 0x98, 0x55, 0x6e, 0x4b, 0x39,
+ 0x9f, 0xbb, 0x05, 0x49, 0xbf, 0x53, 0x93, 0xd4,
+ 0x39, 0xcd, 0xed, 0xa2, 0xe9, 0x02, 0x81, 0xd3,
+ 0x69, 0x08, 0x02, 0x7c, 0xa8, 0xc1, 0xd5, 0xa1,
+ 0x58, 0xe3, 0x81, 0xea, 0x8b, 0xd2, 0x23, 0x4c,
+ 0x1c, 0x99, 0x4d, 0x81, 0x8d, 0x82, 0x1e, 0x85,
+ 0xf7, 0xa9, 0xf8, 0xe6, 0x53, 0x8e, 0x85, 0xcb,
+ 0x79, 0xbb, 0x89, 0x49, 0xce, 0x3c, 0x18, 0x5d,
+ 0xa4, 0x3c, 0x8c, 0x13, 0x7c, 0xe2, 0xc6, 0x97,
+ 0xf0, 0xbe, 0xfa, 0xb6, 0x87, 0xbe, 0xc0, 0xed,
+ 0x70, 0x39, 0x8e, 0x0b, 0x23, 0xb9, 0x51, 0x83,
+ 0x38, 0xc8, 0x37, 0x3e, 0x38, 0x7a, 0x82, 0xfb}};
+
+unsigned char p[6][264] =
+ /* 1024,[p>q] */{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xfb, 0xb7, 0x73, 0x24, 0x42, 0xfe, 0x8f, 0x16,
+ 0xf0, 0x6e, 0x2d, 0x86, 0x22, 0x46, 0x79, 0xd1,
+ 0x58, 0x6f, 0x26, 0x24, 0x17, 0x12, 0xa3, 0x1a,
+ 0xfd, 0xf7, 0x75, 0xd4, 0xcd, 0xf9, 0xde, 0x4b,
+ 0x8c, 0xb7, 0x04, 0x5d, 0xd9, 0x18, 0xc8, 0x26,
+ 0x61, 0x54, 0xe0, 0x92, 0x2f, 0x47, 0xf7, 0x33,
+ 0xc2, 0x17, 0xd8, 0xda, 0xe0, 0x6d, 0xb6, 0x30,
+ 0xd6, 0xdc, 0xf9, 0x6a, 0x4c, 0xa1, 0xa2, 0x4b,
+ 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, 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},
+ /* 2048,[p>q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xf4, 0x4f, 0x5e, 0x42, 0x46, 0x39, 0x1f, 0x48,
+ 0x2b, 0x2f, 0x52, 0x96, 0xe3, 0x60, 0x2e, 0xb3,
+ 0x4a, 0xa1, 0x36, 0x42, 0x77, 0x10, 0xf7, 0xc0,
+ 0x41, 0x6d, 0x40, 0x3f, 0xd6, 0x9d, 0x4b, 0x29,
+ 0x13, 0x0c, 0xfe, 0xbe, 0xf3, 0x4e, 0x88, 0x5a,
+ 0xbd, 0xb1, 0xa8, 0xa0, 0xa5, 0xf0, 0xe9, 0xb5,
+ 0xc3, 0x3e, 0x1f, 0xc3, 0xbf, 0xc2, 0x85, 0xb1,
+ 0xae, 0x17, 0xe4, 0x0c, 0xc6, 0x7a, 0x19, 0x13,
+ 0xdd, 0x56, 0x37, 0x19, 0x81, 0x5e, 0xba, 0xf8,
+ 0x51, 0x4c, 0x2a, 0x7a, 0xa0, 0x01, 0x8e, 0x63,
+ 0xb6, 0xc6, 0x31, 0xdc, 0x31, 0x5a, 0x46, 0x23,
+ 0x57, 0x16, 0x42, 0x3d, 0x11, 0xff, 0x58, 0x03,
+ 0x4e, 0x61, 0x06, 0x45, 0x70, 0x36, 0x06, 0x91,
+ 0x9f, 0x5c, 0x7c, 0xe2, 0x66, 0x0c, 0xd1, 0x48,
+ 0xbd, 0x9e, 0xfc, 0x12, 0x3d, 0x9c, 0x54, 0xb6,
+ 0x70, 0x55, 0x90, 0xd0, 0x06, 0xcf, 0xcf, 0x3f,
+ 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, 0x00},
+ /* 4096,[p>q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xea, 0x48, 0x91, 0x37, 0x80, 0x64, 0x16, 0xf1,
+ 0x53, 0xf6, 0x36, 0x14, 0x06, 0x0e, 0xa9, 0xc7,
+ 0xdb, 0xa6, 0x22, 0x91, 0xb2, 0xb7, 0xb9, 0xdd,
+ 0x9a, 0x01, 0x18, 0x2d, 0xaa, 0x34, 0x0e, 0xd9,
+ 0xca, 0x5b, 0xfe, 0x63, 0xec, 0x02, 0x9c, 0xdb,
+ 0x91, 0x2f, 0x82, 0x27, 0x13, 0xa3, 0xe3, 0x39,
+ 0x07, 0x42, 0xe6, 0x2d, 0xe9, 0xb0, 0xb8, 0x56,
+ 0xf5, 0xd8, 0x67, 0x68, 0x0f, 0xc3, 0x18, 0x14,
+ 0x1f, 0x48, 0x71, 0xed, 0x19, 0x20, 0x7c, 0xc4,
+ 0xb7, 0xf8, 0x0f, 0x39, 0xb7, 0xf2, 0xc8, 0x45,
+ 0x7b, 0x91, 0x9d, 0x42, 0x15, 0x2d, 0x48, 0xb1,
+ 0x11, 0x49, 0x03, 0x8c, 0x7a, 0x80, 0x20, 0x65,
+ 0xe3, 0xee, 0x12, 0xb2, 0x43, 0x03, 0xd2, 0x60,
+ 0xbe, 0x04, 0x2a, 0xdf, 0x52, 0x8f, 0xd5, 0x45,
+ 0x34, 0x84, 0x8d, 0x4e, 0x86, 0xf7, 0x97, 0x2c,
+ 0x39, 0x5e, 0x6d, 0x0d, 0x09, 0xe2, 0x38, 0x95,
+ 0x7f, 0xa1, 0xe8, 0x5e, 0xda, 0xb9, 0xc6, 0x64,
+ 0x12, 0xe2, 0xee, 0xd6, 0x18, 0x87, 0xa4, 0x02,
+ 0xe9, 0x92, 0xba, 0x34, 0x4f, 0x8a, 0x68, 0x87,
+ 0x9d, 0x52, 0xcc, 0x82, 0x57, 0xe0, 0xf8, 0xf7,
+ 0xc5, 0xe9, 0xa1, 0x64, 0x80, 0x25, 0x70, 0xd6,
+ 0x6f, 0x98, 0x87, 0xee, 0x9e, 0xfd, 0x5d, 0xbe,
+ 0x56, 0xb4, 0xe4, 0x74, 0x5d, 0x83, 0xc2, 0xbd,
+ 0x1d, 0x8c, 0x03, 0xba, 0xfd, 0x22, 0xc0, 0x72,
+ 0x05, 0x55, 0x42, 0xdf, 0xd1, 0xbb, 0x34, 0xf2,
+ 0x2a, 0xe5, 0xf4, 0x42, 0x54, 0x43, 0x2d, 0xc8,
+ 0xf3, 0x7e, 0xf5, 0x59, 0x7d, 0x55, 0xc8, 0xb1,
+ 0x36, 0x99, 0x4d, 0xee, 0xb5, 0x5a, 0x24, 0x8c,
+ 0x76, 0x5a, 0xd2, 0x1d, 0x3b, 0x54, 0x29, 0xe3,
+ 0xe9, 0x1e, 0x78, 0x11, 0xcb, 0x9e, 0x21, 0x64,
+ 0x28, 0x56, 0x55, 0x10, 0xb5, 0x95, 0xfa, 0x44,
+ 0xd5, 0x2c, 0x52, 0xdd, 0x54, 0xb7, 0xc4, 0x79},
+ /* 1024,[p<q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xf0, 0x57, 0x24, 0xf6, 0x2a, 0x5a, 0x6d, 0x8e,
+ 0xb8, 0xc6, 0x6f, 0xd2, 0xbb, 0x36, 0x4f, 0x6d,
+ 0xd8, 0xbc, 0xa7, 0x2f, 0xbd, 0x43, 0xdc, 0x9a,
+ 0x0e, 0x2a, 0x36, 0xb9, 0x21, 0x05, 0xfa, 0x22,
+ 0x6c, 0xe8, 0x22, 0x68, 0x2f, 0x1c, 0xe8, 0x27,
+ 0xc1, 0xed, 0x08, 0x7a, 0x43, 0x70, 0x7b, 0xe3,
+ 0x46, 0x74, 0x02, 0x6e, 0xb2, 0xb1, 0xeb, 0x44,
+ 0x72, 0x86, 0x0d, 0x55, 0x3b, 0xc8, 0xbc, 0xd9,
+ 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, 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},
+ /* 2048,[p<q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xe9, 0xd4, 0x98, 0x41, 0xe0, 0xe0, 0xa6, 0xad,
+ 0x0d, 0x51, 0x78, 0x57, 0x13, 0x3e, 0x36, 0xdc,
+ 0x72, 0xc1, 0xbd, 0xd9, 0x0f, 0x91, 0x74, 0xb5,
+ 0x2e, 0x26, 0x57, 0x0f, 0x37, 0x36, 0x40, 0xf1,
+ 0xc1, 0x85, 0xe7, 0xea, 0x8e, 0x2e, 0xd7, 0xf1,
+ 0xe4, 0xeb, 0xb9, 0x51, 0xf7, 0x0a, 0x58, 0x02,
+ 0x36, 0x33, 0xb0, 0x09, 0x7a, 0xec, 0x67, 0xc6,
+ 0xdc, 0xb8, 0x00, 0xfc, 0x1a, 0x67, 0xf9, 0xbb,
+ 0x05, 0x63, 0x61, 0x0f, 0x08, 0xeb, 0xc8, 0x74,
+ 0x6a, 0xd1, 0x29, 0x77, 0x21, 0x36, 0xeb, 0x1d,
+ 0xda, 0xf4, 0x64, 0x36, 0x45, 0x0d, 0x31, 0x83,
+ 0x32, 0xa8, 0x49, 0x82, 0xfe, 0x5d, 0x28, 0xdb,
+ 0xe5, 0xb3, 0xe9, 0x12, 0x40, 0x7c, 0x3e, 0x0e,
+ 0x03, 0x10, 0x0d, 0x87, 0xd4, 0x36, 0xee, 0x40,
+ 0x9e, 0xec, 0x1c, 0xf8, 0x5e, 0x80, 0xab, 0xa0,
+ 0x79, 0xb2, 0xe6, 0x10, 0x6b, 0x97, 0xbc, 0xed,
+ 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, 0x00},
+ /* 4096,[p<q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xe1, 0xda, 0xf2, 0xfb, 0x1a, 0xca, 0x6f, 0x3a,
+ 0x74, 0x7a, 0x79, 0x27, 0xb0, 0xba, 0x9d, 0x4c,
+ 0x5d, 0xce, 0x55, 0xaf, 0x8c, 0x88, 0x04, 0x50,
+ 0x7f, 0x7a, 0xf1, 0x7c, 0xad, 0xf8, 0x0e, 0xd4,
+ 0x03, 0xfd, 0x49, 0x78, 0x05, 0x7a, 0xdf, 0xb2,
+ 0x75, 0x1f, 0x2a, 0x76, 0x40, 0x16, 0x27, 0xdf,
+ 0x61, 0xf9, 0xaf, 0x81, 0xa6, 0x7b, 0x43, 0x8a,
+ 0x43, 0xe0, 0x4f, 0xd2, 0x23, 0x9b, 0xb7, 0x46,
+ 0xfc, 0xad, 0xb3, 0x5b, 0xfb, 0xd8, 0x67, 0x72,
+ 0x7b, 0x10, 0x15, 0xb0, 0x2e, 0x27, 0x69, 0x9b,
+ 0xac, 0x65, 0x5b, 0xd3, 0x8a, 0x8a, 0xcd, 0xc7,
+ 0xcb, 0xfe, 0x24, 0xb5, 0x48, 0x9c, 0x70, 0xe7,
+ 0xfd, 0x75, 0x29, 0x6d, 0xff, 0x5d, 0xb2, 0xd1,
+ 0xd5, 0xfd, 0xea, 0x0d, 0x73, 0x67, 0xda, 0xf7,
+ 0x0d, 0xa7, 0x6a, 0x44, 0x32, 0x6e, 0x21, 0x80,
+ 0x71, 0x61, 0xac, 0x70, 0x1b, 0x3e, 0xfb, 0x33,
+ 0x1f, 0xef, 0x3d, 0x59, 0x57, 0xdd, 0xb3, 0x49,
+ 0x50, 0xd9, 0xb2, 0x33, 0x92, 0xff, 0xd3, 0x06,
+ 0x51, 0x8b, 0x38, 0x3d, 0xbe, 0x8a, 0xf6, 0x69,
+ 0xf0, 0x6a, 0x15, 0x86, 0x0c, 0x8c, 0xb6, 0x2b,
+ 0x34, 0x06, 0x6d, 0x4d, 0x6a, 0x7a, 0xa7, 0x71,
+ 0x36, 0xc2, 0xda, 0x4b, 0xe4, 0x94, 0x7a, 0xc3,
+ 0x94, 0x14, 0x4c, 0xf5, 0xeb, 0xdc, 0x4f, 0x22,
+ 0x15, 0x7e, 0xc7, 0x20, 0x56, 0xef, 0x68, 0xf5,
+ 0x5e, 0x64, 0x4c, 0xb0, 0xf4, 0xe7, 0x2e, 0x52,
+ 0xcd, 0xac, 0xe1, 0x02, 0x75, 0xc7, 0x1c, 0x4e,
+ 0xcd, 0xf0, 0x04, 0xc1, 0x24, 0x4a, 0xd1, 0xb0,
+ 0xe0, 0xbc, 0x35, 0x18, 0xdd, 0x60, 0xf5, 0x9e,
+ 0x3b, 0xde, 0x4e, 0xf0, 0x6b, 0xbc, 0xda, 0x93,
+ 0x98, 0x5b, 0x8b, 0x4b, 0xda, 0xfc, 0x77, 0xa9,
+ 0x08, 0x7a, 0xb9, 0xda, 0xc2, 0x73, 0x50, 0xe2,
+ 0xec, 0xfb, 0x0c, 0x5c, 0x60, 0x25, 0xa9, 0x7f}};
+
+unsigned char q[6][256] =
+ /* 1024,[p>q] */{{0xf0, 0x57, 0x24, 0xf6, 0x2a, 0x5a, 0x6d, 0x8e,
+ 0xb8, 0xc6, 0x6f, 0xd2, 0xbb, 0x36, 0x4f, 0x6d,
+ 0xd8, 0xbc, 0xa7, 0x2f, 0xbd, 0x43, 0xdc, 0x9a,
+ 0x0e, 0x2a, 0x36, 0xb9, 0x21, 0x05, 0xfa, 0x22,
+ 0x6c, 0xe8, 0x22, 0x68, 0x2f, 0x1c, 0xe8, 0x27,
+ 0xc1, 0xed, 0x08, 0x7a, 0x43, 0x70, 0x7b, 0xe3,
+ 0x46, 0x74, 0x02, 0x6e, 0xb2, 0xb1, 0xeb, 0x44,
+ 0x72, 0x86, 0x0d, 0x55, 0x3b, 0xc8, 0xbc, 0xd9,
+ 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, 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},
+ /* 2048,[p>q] */ {0xe9, 0xd4, 0x98, 0x41, 0xe0, 0xe0, 0xa6, 0xad,
+ 0x0d, 0x51, 0x78, 0x57, 0x13, 0x3e, 0x36, 0xdc,
+ 0x72, 0xc1, 0xbd, 0xd9, 0x0f, 0x91, 0x74, 0xb5,
+ 0x2e, 0x26, 0x57, 0x0f, 0x37, 0x36, 0x40, 0xf1,
+ 0xc1, 0x85, 0xe7, 0xea, 0x8e, 0x2e, 0xd7, 0xf1,
+ 0xe4, 0xeb, 0xb9, 0x51, 0xf7, 0x0a, 0x58, 0x02,
+ 0x36, 0x33, 0xb0, 0x09, 0x7a, 0xec, 0x67, 0xc6,
+ 0xdc, 0xb8, 0x00, 0xfc, 0x1a, 0x67, 0xf9, 0xbb,
+ 0x05, 0x63, 0x61, 0x0f, 0x08, 0xeb, 0xc8, 0x74,
+ 0x6a, 0xd1, 0x29, 0x77, 0x21, 0x36, 0xeb, 0x1d,
+ 0xda, 0xf4, 0x64, 0x36, 0x45, 0x0d, 0x31, 0x83,
+ 0x32, 0xa8, 0x49, 0x82, 0xfe, 0x5d, 0x28, 0xdb,
+ 0xe5, 0xb3, 0xe9, 0x12, 0x40, 0x7c, 0x3e, 0x0e,
+ 0x03, 0x10, 0x0d, 0x87, 0xd4, 0x36, 0xee, 0x40,
+ 0x9e, 0xec, 0x1c, 0xf8, 0x5e, 0x80, 0xab, 0xa0,
+ 0x79, 0xb2, 0xe6, 0x10, 0x6b, 0x97, 0xbc, 0xed,
+ 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, 0x00},
+ /* 4096,[p>q] */ {0xe1, 0xda, 0xf2, 0xfb, 0x1a, 0xca, 0x6f, 0x3a,
+ 0x74, 0x7a, 0x79, 0x27, 0xb0, 0xba, 0x9d, 0x4c,
+ 0x5d, 0xce, 0x55, 0xaf, 0x8c, 0x88, 0x04, 0x50,
+ 0x7f, 0x7a, 0xf1, 0x7c, 0xad, 0xf8, 0x0e, 0xd4,
+ 0x03, 0xfd, 0x49, 0x78, 0x05, 0x7a, 0xdf, 0xb2,
+ 0x75, 0x1f, 0x2a, 0x76, 0x40, 0x16, 0x27, 0xdf,
+ 0x61, 0xf9, 0xaf, 0x81, 0xa6, 0x7b, 0x43, 0x8a,
+ 0x43, 0xe0, 0x4f, 0xd2, 0x23, 0x9b, 0xb7, 0x46,
+ 0xfc, 0xad, 0xb3, 0x5b, 0xfb, 0xd8, 0x67, 0x72,
+ 0x7b, 0x10, 0x15, 0xb0, 0x2e, 0x27, 0x69, 0x9b,
+ 0xac, 0x65, 0x5b, 0xd3, 0x8a, 0x8a, 0xcd, 0xc7,
+ 0xcb, 0xfe, 0x24, 0xb5, 0x48, 0x9c, 0x70, 0xe7,
+ 0xfd, 0x75, 0x29, 0x6d, 0xff, 0x5d, 0xb2, 0xd1,
+ 0xd5, 0xfd, 0xea, 0x0d, 0x73, 0x67, 0xda, 0xf7,
+ 0x0d, 0xa7, 0x6a, 0x44, 0x32, 0x6e, 0x21, 0x80,
+ 0x71, 0x61, 0xac, 0x70, 0x1b, 0x3e, 0xfb, 0x33,
+ 0x1f, 0xef, 0x3d, 0x59, 0x57, 0xdd, 0xb3, 0x49,
+ 0x50, 0xd9, 0xb2, 0x33, 0x92, 0xff, 0xd3, 0x06,
+ 0x51, 0x8b, 0x38, 0x3d, 0xbe, 0x8a, 0xf6, 0x69,
+ 0xf0, 0x6a, 0x15, 0x86, 0x0c, 0x8c, 0xb6, 0x2b,
+ 0x34, 0x06, 0x6d, 0x4d, 0x6a, 0x7a, 0xa7, 0x71,
+ 0x36, 0xc2, 0xda, 0x4b, 0xe4, 0x94, 0x7a, 0xc3,
+ 0x94, 0x14, 0x4c, 0xf5, 0xeb, 0xdc, 0x4f, 0x22,
+ 0x15, 0x7e, 0xc7, 0x20, 0x56, 0xef, 0x68, 0xf5,
+ 0x5e, 0x64, 0x4c, 0xb0, 0xf4, 0xe7, 0x2e, 0x52,
+ 0xcd, 0xac, 0xe1, 0x02, 0x75, 0xc7, 0x1c, 0x4e,
+ 0xcd, 0xf0, 0x04, 0xc1, 0x24, 0x4a, 0xd1, 0xb0,
+ 0xe0, 0xbc, 0x35, 0x18, 0xdd, 0x60, 0xf5, 0x9e,
+ 0x3b, 0xde, 0x4e, 0xf0, 0x6b, 0xbc, 0xda, 0x93,
+ 0x98, 0x5b, 0x8b, 0x4b, 0xda, 0xfc, 0x77, 0xa9,
+ 0x08, 0x7a, 0xb9, 0xda, 0xc2, 0x73, 0x50, 0xe2,
+ 0xec, 0xfb, 0x0c, 0x5c, 0x60, 0x25, 0xa9, 0x7f},
+ /* 1024,[p<q] */ {0xfb, 0xb7, 0x73, 0x24, 0x42, 0xfe, 0x8f, 0x16,
+ 0xf0, 0x6e, 0x2d, 0x86, 0x22, 0x46, 0x79, 0xd1,
+ 0x58, 0x6f, 0x26, 0x24, 0x17, 0x12, 0xa3, 0x1a,
+ 0xfd, 0xf7, 0x75, 0xd4, 0xcd, 0xf9, 0xde, 0x4b,
+ 0x8c, 0xb7, 0x04, 0x5d, 0xd9, 0x18, 0xc8, 0x26,
+ 0x61, 0x54, 0xe0, 0x92, 0x2f, 0x47, 0xf7, 0x33,
+ 0xc2, 0x17, 0xd8, 0xda, 0xe0, 0x6d, 0xb6, 0x30,
+ 0xd6, 0xdc, 0xf9, 0x6a, 0x4c, 0xa1, 0xa2, 0x4b,
+ 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, 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},
+ /* 2048,[p<q] */ {0xf4, 0x4f, 0x5e, 0x42, 0x46, 0x39, 0x1f, 0x48,
+ 0x2b, 0x2f, 0x52, 0x96, 0xe3, 0x60, 0x2e, 0xb3,
+ 0x4a, 0xa1, 0x36, 0x42, 0x77, 0x10, 0xf7, 0xc0,
+ 0x41, 0x6d, 0x40, 0x3f, 0xd6, 0x9d, 0x4b, 0x29,
+ 0x13, 0x0c, 0xfe, 0xbe, 0xf3, 0x4e, 0x88, 0x5a,
+ 0xbd, 0xb1, 0xa8, 0xa0, 0xa5, 0xf0, 0xe9, 0xb5,
+ 0xc3, 0x3e, 0x1f, 0xc3, 0xbf, 0xc2, 0x85, 0xb1,
+ 0xae, 0x17, 0xe4, 0x0c, 0xc6, 0x7a, 0x19, 0x13,
+ 0xdd, 0x56, 0x37, 0x19, 0x81, 0x5e, 0xba, 0xf8,
+ 0x51, 0x4c, 0x2a, 0x7a, 0xa0, 0x01, 0x8e, 0x63,
+ 0xb6, 0xc6, 0x31, 0xdc, 0x31, 0x5a, 0x46, 0x23,
+ 0x57, 0x16, 0x42, 0x3d, 0x11, 0xff, 0x58, 0x03,
+ 0x4e, 0x61, 0x06, 0x45, 0x70, 0x36, 0x06, 0x91,
+ 0x9f, 0x5c, 0x7c, 0xe2, 0x66, 0x0c, 0xd1, 0x48,
+ 0xbd, 0x9e, 0xfc, 0x12, 0x3d, 0x9c, 0x54, 0xb6,
+ 0x70, 0x55, 0x90, 0xd0, 0x06, 0xcf, 0xcf, 0x3f,
+ 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, 0x00},
+ /* 4096,[p<q] */ {0xea, 0x48, 0x91, 0x37, 0x80, 0x64, 0x16, 0xf1,
+ 0x53, 0xf6, 0x36, 0x14, 0x06, 0x0e, 0xa9, 0xc7,
+ 0xdb, 0xa6, 0x22, 0x91, 0xb2, 0xb7, 0xb9, 0xdd,
+ 0x9a, 0x01, 0x18, 0x2d, 0xaa, 0x34, 0x0e, 0xd9,
+ 0xca, 0x5b, 0xfe, 0x63, 0xec, 0x02, 0x9c, 0xdb,
+ 0x91, 0x2f, 0x82, 0x27, 0x13, 0xa3, 0xe3, 0x39,
+ 0x07, 0x42, 0xe6, 0x2d, 0xe9, 0xb0, 0xb8, 0x56,
+ 0xf5, 0xd8, 0x67, 0x68, 0x0f, 0xc3, 0x18, 0x14,
+ 0x1f, 0x48, 0x71, 0xed, 0x19, 0x20, 0x7c, 0xc4,
+ 0xb7, 0xf8, 0x0f, 0x39, 0xb7, 0xf2, 0xc8, 0x45,
+ 0x7b, 0x91, 0x9d, 0x42, 0x15, 0x2d, 0x48, 0xb1,
+ 0x11, 0x49, 0x03, 0x8c, 0x7a, 0x80, 0x20, 0x65,
+ 0xe3, 0xee, 0x12, 0xb2, 0x43, 0x03, 0xd2, 0x60,
+ 0xbe, 0x04, 0x2a, 0xdf, 0x52, 0x8f, 0xd5, 0x45,
+ 0x34, 0x84, 0x8d, 0x4e, 0x86, 0xf7, 0x97, 0x2c,
+ 0x39, 0x5e, 0x6d, 0x0d, 0x09, 0xe2, 0x38, 0x95,
+ 0x7f, 0xa1, 0xe8, 0x5e, 0xda, 0xb9, 0xc6, 0x64,
+ 0x12, 0xe2, 0xee, 0xd6, 0x18, 0x87, 0xa4, 0x02,
+ 0xe9, 0x92, 0xba, 0x34, 0x4f, 0x8a, 0x68, 0x87,
+ 0x9d, 0x52, 0xcc, 0x82, 0x57, 0xe0, 0xf8, 0xf7,
+ 0xc5, 0xe9, 0xa1, 0x64, 0x80, 0x25, 0x70, 0xd6,
+ 0x6f, 0x98, 0x87, 0xee, 0x9e, 0xfd, 0x5d, 0xbe,
+ 0x56, 0xb4, 0xe4, 0x74, 0x5d, 0x83, 0xc2, 0xbd,
+ 0x1d, 0x8c, 0x03, 0xba, 0xfd, 0x22, 0xc0, 0x72,
+ 0x05, 0x55, 0x42, 0xdf, 0xd1, 0xbb, 0x34, 0xf2,
+ 0x2a, 0xe5, 0xf4, 0x42, 0x54, 0x43, 0x2d, 0xc8,
+ 0xf3, 0x7e, 0xf5, 0x59, 0x7d, 0x55, 0xc8, 0xb1,
+ 0x36, 0x99, 0x4d, 0xee, 0xb5, 0x5a, 0x24, 0x8c,
+ 0x76, 0x5a, 0xd2, 0x1d, 0x3b, 0x54, 0x29, 0xe3,
+ 0xe9, 0x1e, 0x78, 0x11, 0xcb, 0x9e, 0x21, 0x64,
+ 0x28, 0x56, 0x55, 0x10, 0xb5, 0x95, 0xfa, 0x44,
+ 0xd5, 0x2c, 0x52, 0xdd, 0x54, 0xb7, 0xc4, 0x79}};
+
+unsigned char qinv[6][264] =
+ /* 1024,[p>q] */{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x83, 0xf1, 0xca, 0x06, 0x58, 0x4a, 0x04, 0x5e,
+ 0x96, 0xb5, 0x30, 0x32, 0x40, 0x36, 0x48, 0xb9,
+ 0x02, 0x0c, 0xe3, 0x37, 0xb7, 0x51, 0xbc, 0x22,
+ 0x26, 0x5d, 0x74, 0x03, 0x47, 0xd3, 0x33, 0x20,
+ 0x8e, 0x75, 0x62, 0xf2, 0x9d, 0x4e, 0xc8, 0x7d,
+ 0x5d, 0x8e, 0xb6, 0xd9, 0x69, 0x4a, 0x9a, 0xe1,
+ 0x36, 0x6e, 0x1c, 0xbe, 0x8a, 0x14, 0xb1, 0x85,
+ 0x39, 0x74, 0x7c, 0x25, 0xd8, 0xa4, 0x4f, 0xde,
+ 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, 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},
+ /* 2048,[p>q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x57, 0xb7, 0x38, 0x88, 0xd1, 0x83, 0xa9, 0x9a,
+ 0x63, 0x07, 0x42, 0x22, 0x77, 0x55, 0x1a, 0x3d,
+ 0x9e, 0x18, 0xad, 0xf0, 0x6a, 0x91, 0xe8, 0xb5,
+ 0x5c, 0xef, 0xfe, 0xf9, 0x07, 0x7c, 0x84, 0x96,
+ 0x94, 0x8e, 0xcb, 0x3b, 0x16, 0xb7, 0x81, 0x55,
+ 0xcb, 0x2a, 0x3a, 0x57, 0xc1, 0x19, 0xd3, 0x79,
+ 0x95, 0x1c, 0x01, 0x0a, 0xa6, 0x35, 0xed, 0xcf,
+ 0x62, 0xd8, 0x4c, 0x5a, 0x12, 0x2a, 0x8d, 0x67,
+ 0xab, 0x5f, 0xa9, 0xe5, 0xa4, 0xa8, 0x77, 0x2a,
+ 0x1e, 0x94, 0x3b, 0xaf, 0xc7, 0x0a, 0xe3, 0xa4,
+ 0xc1, 0xf0, 0xf3, 0xa4, 0xdd, 0xff, 0xae, 0xfd,
+ 0x18, 0x92, 0xc8, 0xcb, 0x33, 0xbb, 0x0d, 0x0b,
+ 0x95, 0x90, 0xe9, 0x63, 0xa6, 0x91, 0x10, 0xfb,
+ 0x34, 0xdb, 0x7b, 0x90, 0x6f, 0xc4, 0xba, 0x28,
+ 0x36, 0x99, 0x5a, 0xac, 0x7e, 0x52, 0x74, 0x90,
+ 0xac, 0x95, 0x2a, 0x02, 0x26, 0x8a, 0x4f, 0x18,
+ 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, 0x00},
+ /* 4096,[p>q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x27, 0x0f, 0x83, 0x44, 0x1b, 0x11, 0xce, 0x9f,
+ 0xe6, 0xdf, 0xd5, 0x1b, 0xed, 0x73, 0xea, 0x09,
+ 0x54, 0xcb, 0x47, 0xca, 0x58, 0xfa, 0x04, 0xc7,
+ 0x25, 0x68, 0xf0, 0x25, 0xfd, 0xf1, 0x30, 0x53,
+ 0x03, 0x56, 0xd9, 0x65, 0x65, 0xd4, 0x60, 0xc1,
+ 0x12, 0x90, 0x91, 0xf6, 0x3d, 0xda, 0x97, 0x6b,
+ 0xe8, 0x1b, 0x96, 0x33, 0xfb, 0x94, 0x0a, 0x8f,
+ 0x55, 0xc3, 0xbd, 0x33, 0x7b, 0x5c, 0x6b, 0x00,
+ 0x1a, 0x79, 0x2f, 0xaf, 0x13, 0x82, 0xcd, 0x5f,
+ 0xc7, 0x2a, 0x25, 0xe6, 0x93, 0xb4, 0x13, 0xa5,
+ 0x89, 0x68, 0x42, 0xce, 0xc2, 0xb0, 0xe8, 0xc4,
+ 0x94, 0x65, 0xa4, 0x04, 0x37, 0x5d, 0x49, 0xcf,
+ 0x6d, 0xeb, 0x3b, 0x89, 0x34, 0xbf, 0x78, 0x2e,
+ 0x8a, 0x34, 0x53, 0x21, 0x56, 0x97, 0xfb, 0xda,
+ 0x6b, 0x95, 0x48, 0xa0, 0x4f, 0x55, 0xa4, 0xab,
+ 0xbd, 0x14, 0xc6, 0x7b, 0xb8, 0xca, 0x1b, 0x73,
+ 0xaa, 0x5f, 0x98, 0x90, 0xe5, 0xdd, 0xb3, 0x30,
+ 0xf5, 0x9b, 0xa0, 0xe6, 0x83, 0x0b, 0xc8, 0x6f,
+ 0x70, 0x41, 0x3e, 0x18, 0xd2, 0xea, 0x57, 0xea,
+ 0xc6, 0x76, 0xaa, 0x48, 0x19, 0x1d, 0x3f, 0xff,
+ 0xa4, 0x5f, 0x01, 0x4f, 0x4b, 0x21, 0x14, 0xcf,
+ 0x83, 0x5f, 0xc1, 0xcf, 0xaf, 0x04, 0xe8, 0x8a,
+ 0xab, 0xa2, 0x53, 0xaa, 0x9e, 0x1b, 0x6d, 0x42,
+ 0xa8, 0x2b, 0x51, 0xd9, 0x28, 0x9b, 0xf7, 0xda,
+ 0xf3, 0xd7, 0x6c, 0x71, 0xbd, 0xc2, 0x27, 0x17,
+ 0x8b, 0x04, 0x46, 0xdc, 0xae, 0x79, 0x70, 0x1b,
+ 0xf0, 0x45, 0x93, 0x26, 0x60, 0x24, 0x9a, 0xc7,
+ 0xf2, 0xab, 0x9c, 0xad, 0xf6, 0xaa, 0xab, 0xfa,
+ 0xb2, 0x70, 0xec, 0x34, 0x7f, 0x75, 0x3a, 0x4c,
+ 0x3c, 0x0c, 0xe2, 0xe7, 0xad, 0x43, 0xb2, 0x66,
+ 0xe3, 0x5c, 0x23, 0x0c, 0x48, 0x4a, 0x91, 0x7c,
+ 0xb3, 0x77, 0x5c, 0x57, 0x7d, 0xbc, 0xa8, 0x2d},
+ /* 1024,[p<q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x5b, 0xec, 0x7c, 0x5f, 0x9c, 0xa5, 0x5e,
+ 0xb7, 0xfe, 0xef, 0x67, 0x9e, 0xc4, 0xce, 0xae,
+ 0xc4, 0x4d, 0xc2, 0xd2, 0x8b, 0xbf, 0x7b, 0x36,
+ 0x45, 0x5e, 0x89, 0x89, 0x37, 0xcc, 0x60, 0x83,
+ 0x43, 0x67, 0xac, 0xf3, 0x02, 0xa0, 0xb7, 0x2d,
+ 0x19, 0x57, 0xd8, 0xf0, 0x59, 0x11, 0x91, 0x06,
+ 0x07, 0x50, 0x5c, 0x42, 0xf4, 0xe5, 0xa1, 0xee,
+ 0xc9, 0xa3, 0x0a, 0x40, 0x92, 0xe2, 0xcf, 0x72,
+ 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, 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},
+ /* 2048,[p<q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x95, 0xe0, 0x94, 0xf5, 0xf7, 0x5f, 0x9e, 0x7a,
+ 0xe3, 0xe0, 0x5f, 0x09, 0xb5, 0x77, 0x81, 0x49,
+ 0x64, 0xbf, 0x0d, 0x8d, 0x65, 0xfb, 0x43, 0xf0,
+ 0xa6, 0x4d, 0x6e, 0x42, 0xbc, 0x08, 0x87, 0x21,
+ 0x75, 0x0e, 0x51, 0x53, 0x71, 0xd3, 0xb5, 0xc3,
+ 0x66, 0x72, 0xfb, 0xf9, 0x1f, 0xf6, 0x92, 0xe2,
+ 0xd6, 0x41, 0xd6, 0xf6, 0x46, 0x88, 0x22, 0x4b,
+ 0xd6, 0x46, 0xd7, 0xe6, 0xbc, 0x66, 0xea, 0x6b,
+ 0x15, 0x9d, 0xe9, 0xc3, 0x45, 0x3d, 0xe7, 0x01,
+ 0xb2, 0x3a, 0x2d, 0x59, 0xd1, 0xbb, 0x97, 0x5e,
+ 0x89, 0x13, 0xfe, 0x57, 0xdc, 0x05, 0xc6, 0xbe,
+ 0xf8, 0x34, 0x8c, 0xc5, 0xab, 0x79, 0xd0, 0xf9,
+ 0xf4, 0x58, 0xaf, 0xcd, 0xc8, 0x72, 0x84, 0x18,
+ 0x7b, 0x29, 0xa2, 0xa6, 0xbf, 0x72, 0x57, 0x8a,
+ 0xe1, 0xe9, 0x38, 0x70, 0x35, 0x1e, 0x2a, 0x5f,
+ 0xcf, 0x91, 0x62, 0x30, 0x57, 0xa6, 0x4c, 0xe4,
+ 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, 0x00},
+ /* 4096,[p<q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xbc, 0x33, 0x29, 0x91, 0x3c, 0x49, 0x8a, 0x8c,
+ 0x1f, 0x0c, 0x5e, 0x1b, 0x47, 0x96, 0x98, 0xab,
+ 0xf6, 0xb6, 0xdb, 0xf9, 0xaa, 0x86, 0xad, 0x48,
+ 0x2d, 0x59, 0xf8, 0xf4, 0xbc, 0x8c, 0x2e, 0x4d,
+ 0x52, 0x0e, 0x48, 0x03, 0xc5, 0xb9, 0x83, 0x66,
+ 0x15, 0x45, 0xff, 0x0e, 0x69, 0xe9, 0x31, 0x70,
+ 0xc5, 0x21, 0xfa, 0x8b, 0x64, 0xef, 0x4c, 0x53,
+ 0x32, 0x51, 0xe7, 0x2f, 0x70, 0x52, 0x89, 0xa2,
+ 0x2b, 0xff, 0x88, 0x9d, 0x93, 0x78, 0x33, 0x03,
+ 0x6e, 0x2a, 0xd4, 0x67, 0x3d, 0xb2, 0xa9, 0x5a,
+ 0x23, 0x3d, 0xfc, 0xaf, 0x6d, 0x41, 0x09, 0x47,
+ 0x7c, 0xa4, 0x28, 0x8b, 0x00, 0x8b, 0xc9, 0x48,
+ 0x75, 0x80, 0x4a, 0x68, 0x3a, 0x6d, 0x96, 0x46,
+ 0x37, 0xb9, 0x68, 0x01, 0x6b, 0xeb, 0x6f, 0xa9,
+ 0xf7, 0x95, 0x35, 0x05, 0xcc, 0x06, 0x33, 0x87,
+ 0x90, 0xf0, 0x1a, 0x96, 0xac, 0xa0, 0x74, 0xf4,
+ 0x27, 0xac, 0x98, 0xcc, 0x2d, 0x3a, 0x34, 0x98,
+ 0x6f, 0xe7, 0x10, 0x47, 0xbf, 0x44, 0xbb, 0xf8,
+ 0xfb, 0x81, 0x01, 0x59, 0x1e, 0x5f, 0x76, 0xef,
+ 0x7e, 0x67, 0x3e, 0x0e, 0xc2, 0xec, 0x6b, 0x45,
+ 0x1b, 0xf5, 0x16, 0xe6, 0xfe, 0xa1, 0x40, 0xce,
+ 0x9d, 0x91, 0xed, 0xdb, 0x11, 0x7a, 0xbc, 0x0a,
+ 0xc6, 0x08, 0x74, 0x02, 0x3c, 0xc8, 0x8d, 0x98,
+ 0x3d, 0x43, 0xbf, 0xe1, 0xf6, 0x77, 0x9d, 0xb3,
+ 0x1e, 0xba, 0x68, 0x48, 0x0e, 0xef, 0xa9, 0xa0,
+ 0x5c, 0xb8, 0x1e, 0x4b, 0x9f, 0x06, 0x92, 0x21,
+ 0xbf, 0xa3, 0x6d, 0x26, 0xea, 0x5b, 0xfd, 0xb8,
+ 0x85, 0x2e, 0xfe, 0xf6, 0x94, 0x82, 0xf5, 0x93,
+ 0xe6, 0x1d, 0x12, 0x63, 0xe2, 0x62, 0x0d, 0xe2,
+ 0xe3, 0x86, 0xeb, 0x66, 0x37, 0xf9, 0xaf, 0xe5,
+ 0xaf, 0x77, 0x59, 0x6f, 0x8f, 0x66, 0x64, 0x76,
+ 0x5f, 0x78, 0x47, 0x61, 0xa2, 0x06, 0x94, 0x1d}};
+
+unsigned char input_data[] =
+ {0x00, 0x02, 0x08, 0x68, 0x30, 0x9a, 0x32, 0x08,
+ 0x57, 0xb0, 0x28, 0xaa, 0x76, 0x30, 0x3d, 0x84,
+ 0x5f, 0x92, 0x0d, 0x8e, 0x34, 0xe0, 0xd5, 0xcc,
+ 0x36, 0x97, 0xed, 0x00, 0x00, 0x01, 0x02, 0x03,
+ 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
+ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
+ 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
+ 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
+ 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
+ 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43,
+ 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b,
+ 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53,
+ 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b,
+ 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63};
+
+unsigned char ciphertext[6][512] =
+ /* 1024,[p>q] */{{0xb2, 0xb2, 0x82, 0xd7, 0x2c, 0x6f, 0x53, 0x29,
+ 0xee, 0x4c, 0xd1, 0x77, 0xb7, 0x13, 0xf3, 0x1c,
+ 0x51, 0x60, 0xd8, 0xa9, 0x4e, 0x52, 0x72, 0x43,
+ 0x29, 0xfa, 0x51, 0xaa, 0xd8, 0xbc, 0x31, 0x21,
+ 0xe0, 0xac, 0x9b, 0x4e, 0x00, 0x94, 0xac, 0x91,
+ 0x7f, 0x1e, 0xfd, 0xfb, 0x1c, 0xfa, 0xa8, 0xe8,
+ 0x56, 0x5a, 0x01, 0x17, 0xf1, 0x5f, 0x01, 0xba,
+ 0xcd, 0x77, 0xa1, 0x8c, 0x74, 0x8a, 0xef, 0xfa,
+ 0x64, 0x58, 0x79, 0x13, 0xaa, 0x54, 0x13, 0x2b,
+ 0xaa, 0xe7, 0xc3, 0x50, 0x3b, 0x69, 0x3b, 0x0b,
+ 0x9a, 0xa9, 0x9d, 0x15, 0x8a, 0x06, 0x45, 0x71,
+ 0x40, 0x7a, 0x80, 0x85, 0x4a, 0xbe, 0x68, 0x48,
+ 0x6c, 0xe6, 0xdd, 0x96, 0xb0, 0xdc, 0xf4, 0x23,
+ 0xa8, 0xea, 0x21, 0x9f, 0xbc, 0x6b, 0x15, 0xa4,
+ 0x87, 0x6e, 0x93, 0x56, 0xae, 0xa7, 0x17, 0x4e,
+ 0xd7, 0x14, 0xe4, 0x69, 0x04, 0xd5, 0x2e, 0x62,
+ 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, 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, 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, 0x00, 0x00, 0x00},
+ /* 2048,[p>q] */ {0x6d, 0xdc, 0x9c, 0xba, 0xd4, 0xfa, 0xfe, 0xd0,
+ 0x85, 0xd7, 0x0a, 0xc4, 0x11, 0x02, 0x07, 0x9f,
+ 0x28, 0xd2, 0x1b, 0x1f, 0xcc, 0xbb, 0x6f, 0x66,
+ 0x3a, 0xbe, 0xcb, 0xe6, 0x20, 0xee, 0x90, 0x97,
+ 0x04, 0x2c, 0xfc, 0xb9, 0x5a, 0xd3, 0x66, 0x6a,
+ 0x73, 0x6a, 0x67, 0x27, 0xee, 0x9f, 0x90, 0xcd,
+ 0x5f, 0xce, 0xcf, 0x12, 0x4e, 0x10, 0xf2, 0x2a,
+ 0x23, 0xd1, 0x5e, 0xd4, 0xad, 0xb5, 0xc5, 0x26,
+ 0xd2, 0x2f, 0x04, 0x18, 0xb5, 0xc1, 0x52, 0xeb,
+ 0x7c, 0xd4, 0x5b, 0xe8, 0x21, 0x0a, 0x53, 0x7d,
+ 0xfe, 0x64, 0x02, 0xf1, 0xb4, 0x48, 0xf2, 0x39,
+ 0x17, 0xb7, 0x60, 0x0f, 0x22, 0x7f, 0x04, 0x78,
+ 0xf1, 0x84, 0x51, 0x47, 0xec, 0xff, 0x81, 0x27,
+ 0x47, 0x88, 0x58, 0xfa, 0x26, 0xe7, 0xc3, 0x0e,
+ 0x77, 0x81, 0xa9, 0x06, 0x8d, 0x24, 0x36, 0x58,
+ 0x61, 0xe2, 0x78, 0x37, 0xe8, 0x7c, 0x6d, 0x5b,
+ 0x77, 0xeb, 0x0a, 0x56, 0xe7, 0x25, 0x9f, 0xe8,
+ 0xc0, 0x82, 0xc3, 0xf8, 0xb8, 0x1a, 0xe3, 0x60,
+ 0x65, 0x24, 0x2e, 0x0c, 0xc2, 0x74, 0xcd, 0x2a,
+ 0x03, 0xd1, 0x66, 0x7a, 0x1c, 0xe2, 0x3d, 0xc5,
+ 0xa9, 0x78, 0x5f, 0x32, 0x96, 0x8a, 0xe4, 0x11,
+ 0x97, 0x82, 0xb9, 0x11, 0x48, 0xd5, 0x3f, 0x1b,
+ 0x4d, 0xc5, 0xf7, 0x4e, 0xe7, 0x7d, 0x5a, 0xf3,
+ 0x42, 0xff, 0xf8, 0xf6, 0x8d, 0xd2, 0x22, 0x95,
+ 0xdf, 0xf2, 0x7e, 0xfc, 0x34, 0xf4, 0x6d, 0x8e,
+ 0x37, 0x02, 0x34, 0x30, 0xf8, 0x31, 0xfb, 0xa8,
+ 0x97, 0x74, 0xac, 0xf3, 0x4a, 0x67, 0x4a, 0xee,
+ 0x12, 0xed, 0x9d, 0x19, 0xcd, 0x4a, 0xe2, 0x13,
+ 0x43, 0x25, 0xf7, 0x00, 0xd8, 0xbd, 0x91, 0xc2,
+ 0x38, 0xc4, 0x68, 0xeb, 0xb1, 0x74, 0xd0, 0x8c,
+ 0xdb, 0x76, 0x79, 0xe2, 0xd0, 0x85, 0x0d, 0x03,
+ 0xdc, 0xdc, 0x8e, 0x79, 0x7f, 0xdb, 0xea, 0x36,
+ 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, 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, 0x00, 0x00},
+ /* 4096,[p>q] */ {0xac, 0x34, 0x9f, 0xe1, 0x4d, 0x4a, 0xf8, 0x8f,
+ 0x3a, 0xa0, 0xf5, 0x78, 0xe3, 0x30, 0x7e, 0x80,
+ 0x55, 0x7a, 0x93, 0x96, 0x47, 0xb8, 0x28, 0xc7,
+ 0x34, 0x33, 0xcf, 0x97, 0x90, 0x71, 0xbc, 0xc6,
+ 0x37, 0x13, 0x8b, 0x53, 0x41, 0x51, 0x9a, 0x2e,
+ 0x4a, 0xa0, 0x6b, 0xfc, 0xc6, 0x73, 0x0a, 0x6f,
+ 0x5c, 0x09, 0xee, 0x35, 0x9d, 0xee, 0x2a, 0xbe,
+ 0x88, 0x8a, 0xbf, 0xa0, 0x60, 0xb3, 0x4b, 0x93,
+ 0x37, 0xb7, 0xb9, 0x52, 0xd5, 0x9d, 0x2b, 0xd8,
+ 0x39, 0xfe, 0x04, 0x4a, 0x97, 0x3f, 0x4a, 0xd9,
+ 0x8b, 0x27, 0x71, 0xb3, 0xbe, 0x25, 0x43, 0xd6,
+ 0xba, 0x06, 0x6c, 0x93, 0x09, 0x27, 0xf8, 0x4f,
+ 0x9a, 0x6f, 0x97, 0x23, 0x22, 0x9e, 0x51, 0x53,
+ 0x9a, 0x4c, 0x08, 0x3a, 0x78, 0x22, 0xd5, 0x7f,
+ 0xe9, 0xb1, 0x78, 0xef, 0xdc, 0x7e, 0x0c, 0x67,
+ 0x54, 0x14, 0xdd, 0x15, 0xf5, 0xc5, 0xc6, 0x4c,
+ 0x64, 0xa4, 0x70, 0x97, 0xd5, 0xfd, 0xc6, 0x8a,
+ 0x21, 0x86, 0x70, 0x93, 0xa5, 0xaa, 0x04, 0xa4,
+ 0xa6, 0xfc, 0x8b, 0x51, 0xe8, 0x64, 0x30, 0x9d,
+ 0x5c, 0x44, 0x8d, 0xab, 0xf3, 0x1a, 0x19, 0x56,
+ 0xa7, 0x87, 0xce, 0x0b, 0xb8, 0xd1, 0x84, 0xb1,
+ 0x69, 0x39, 0x34, 0x2d, 0xeb, 0x62, 0xda, 0x46,
+ 0xc8, 0xc0, 0x98, 0x0a, 0x95, 0x43, 0xc8, 0x80,
+ 0xe3, 0x45, 0x89, 0x1e, 0x27, 0x2f, 0x8e, 0x85,
+ 0x9b, 0xf8, 0xc8, 0x76, 0x1e, 0xfa, 0x67, 0x51,
+ 0xcf, 0x4f, 0x8d, 0x07, 0xb9, 0xd6, 0x93, 0xc6,
+ 0xc3, 0xd1, 0xa6, 0x8e, 0x17, 0x94, 0x88, 0x4c,
+ 0x74, 0x48, 0x97, 0x50, 0xd0, 0x1f, 0xb0, 0x6d,
+ 0xf7, 0x2c, 0xc2, 0x01, 0x0e, 0x22, 0xa1, 0xc4,
+ 0x20, 0xfd, 0xb3, 0xde, 0x0d, 0x95, 0x0c, 0xeb,
+ 0xc2, 0x63, 0x37, 0x24, 0xb7, 0xb1, 0x90, 0x6d,
+ 0xb7, 0xda, 0x19, 0x33, 0x59, 0xd7, 0x34, 0x8d,
+ 0x72, 0xd2, 0x13, 0x4d, 0xec, 0xa8, 0xf7, 0xf3,
+ 0x62, 0x6a, 0x8a, 0x37, 0x61, 0x04, 0x57, 0x82,
+ 0x83, 0xa2, 0x5c, 0xc6, 0xd4, 0x9c, 0x29, 0x92,
+ 0xa7, 0xbe, 0xf7, 0xbb, 0x98, 0x23, 0xf8, 0xc4,
+ 0x23, 0xac, 0xbd, 0xa1, 0x6e, 0xfa, 0x45, 0xfd,
+ 0x58, 0xcc, 0x67, 0xba, 0xe3, 0xd5, 0x86, 0x35,
+ 0x75, 0x58, 0x07, 0xe9, 0x42, 0x6b, 0x2f, 0x17,
+ 0xc1, 0x64, 0x10, 0xba, 0x52, 0x37, 0xaf, 0xe0,
+ 0x36, 0x9a, 0x41, 0x06, 0xa1, 0x70, 0x12, 0x27,
+ 0xf7, 0xaa, 0xee, 0x9f, 0x9c, 0x16, 0x5d, 0x30,
+ 0xb0, 0xdd, 0x9c, 0x56, 0x8b, 0x0e, 0xbb, 0xd2,
+ 0xed, 0x36, 0xa7, 0x71, 0x77, 0xb8, 0xd4, 0xcd,
+ 0xb0, 0x38, 0x26, 0x4c, 0x10, 0x5d, 0x14, 0x5b,
+ 0x18, 0xde, 0xec, 0xda, 0x3d, 0xfe, 0x18, 0x02,
+ 0x34, 0x13, 0xdb, 0x1f, 0x74, 0xc4, 0xdd, 0xbc,
+ 0xd2, 0x1a, 0x68, 0xcf, 0x96, 0x9b, 0x4e, 0xaa,
+ 0xdd, 0x47, 0x24, 0xa4, 0x1a, 0x1d, 0x5b, 0xa1,
+ 0x8e, 0xcf, 0x4a, 0x51, 0x0a, 0x7b, 0x24, 0xfc,
+ 0x54, 0x20, 0x31, 0x5a, 0x97, 0x42, 0x9d, 0x36,
+ 0x84, 0x07, 0x89, 0x3e, 0x39, 0x34, 0x5e, 0x40,
+ 0xae, 0xe7, 0xf8, 0x82, 0xd7, 0xb3, 0xa9, 0x25,
+ 0xfe, 0xc5, 0x45, 0xd5, 0xde, 0x6f, 0x02, 0x61,
+ 0x25, 0x12, 0x90, 0xfe, 0xe7, 0x10, 0x1d, 0x60,
+ 0x55, 0xf8, 0xd2, 0xff, 0x26, 0xb3, 0xbb, 0xea,
+ 0xb7, 0x6d, 0x14, 0xd9, 0x54, 0xef, 0xc3, 0x5f,
+ 0x73, 0x46, 0xdc, 0xd1, 0xfa, 0xd8, 0x31, 0xc6,
+ 0xff, 0xd8, 0xc7, 0xf7, 0x84, 0xc0, 0x87, 0x70,
+ 0x97, 0xab, 0xdf, 0xa7, 0x8c, 0x0b, 0xf1, 0xcf,
+ 0x81, 0x2a, 0xce, 0xf2, 0x02, 0xfd, 0x41, 0xb2,
+ 0x54, 0x9f, 0x49, 0x17, 0xe7, 0xbb, 0xa5, 0x37,
+ 0x6e, 0x4d, 0xeb, 0x2b, 0x62, 0x1c, 0x36, 0xb3,
+ 0x01, 0x86, 0x45, 0x82, 0xc1, 0x4f, 0x60, 0x77},
+ /* 1024,[p<q] */ {0xb2, 0xb2, 0x82, 0xd7, 0x2c, 0x6f, 0x53, 0x29,
+ 0xee, 0x4c, 0xd1, 0x77, 0xb7, 0x13, 0xf3, 0x1c,
+ 0x51, 0x60, 0xd8, 0xa9, 0x4e, 0x52, 0x72, 0x43,
+ 0x29, 0xfa, 0x51, 0xaa, 0xd8, 0xbc, 0x31, 0x21,
+ 0xe0, 0xac, 0x9b, 0x4e, 0x00, 0x94, 0xac, 0x91,
+ 0x7f, 0x1e, 0xfd, 0xfb, 0x1c, 0xfa, 0xa8, 0xe8,
+ 0x56, 0x5a, 0x01, 0x17, 0xf1, 0x5f, 0x01, 0xba,
+ 0xcd, 0x77, 0xa1, 0x8c, 0x74, 0x8a, 0xef, 0xfa,
+ 0x64, 0x58, 0x79, 0x13, 0xaa, 0x54, 0x13, 0x2b,
+ 0xaa, 0xe7, 0xc3, 0x50, 0x3b, 0x69, 0x3b, 0x0b,
+ 0x9a, 0xa9, 0x9d, 0x15, 0x8a, 0x06, 0x45, 0x71,
+ 0x40, 0x7a, 0x80, 0x85, 0x4a, 0xbe, 0x68, 0x48,
+ 0x6c, 0xe6, 0xdd, 0x96, 0xb0, 0xdc, 0xf4, 0x23,
+ 0xa8, 0xea, 0x21, 0x9f, 0xbc, 0x6b, 0x15, 0xa4,
+ 0x87, 0x6e, 0x93, 0x56, 0xae, 0xa7, 0x17, 0x4e,
+ 0xd7, 0x14, 0xe4, 0x69, 0x04, 0xd5, 0x2e, 0x62,
+ 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, 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, 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, 0x00, 0x00, 0x00},
+ /* 2048,[p<q] */ {0x6d, 0xdc, 0x9c, 0xba, 0xd4, 0xfa, 0xfe, 0xd0,
+ 0x85, 0xd7, 0x0a, 0xc4, 0x11, 0x02, 0x07, 0x9f,
+ 0x28, 0xd2, 0x1b, 0x1f, 0xcc, 0xbb, 0x6f, 0x66,
+ 0x3a, 0xbe, 0xcb, 0xe6, 0x20, 0xee, 0x90, 0x97,
+ 0x04, 0x2c, 0xfc, 0xb9, 0x5a, 0xd3, 0x66, 0x6a,
+ 0x73, 0x6a, 0x67, 0x27, 0xee, 0x9f, 0x90, 0xcd,
+ 0x5f, 0xce, 0xcf, 0x12, 0x4e, 0x10, 0xf2, 0x2a,
+ 0x23, 0xd1, 0x5e, 0xd4, 0xad, 0xb5, 0xc5, 0x26,
+ 0xd2, 0x2f, 0x04, 0x18, 0xb5, 0xc1, 0x52, 0xeb,
+ 0x7c, 0xd4, 0x5b, 0xe8, 0x21, 0x0a, 0x53, 0x7d,
+ 0xfe, 0x64, 0x02, 0xf1, 0xb4, 0x48, 0xf2, 0x39,
+ 0x17, 0xb7, 0x60, 0x0f, 0x22, 0x7f, 0x04, 0x78,
+ 0xf1, 0x84, 0x51, 0x47, 0xec, 0xff, 0x81, 0x27,
+ 0x47, 0x88, 0x58, 0xfa, 0x26, 0xe7, 0xc3, 0x0e,
+ 0x77, 0x81, 0xa9, 0x06, 0x8d, 0x24, 0x36, 0x58,
+ 0x61, 0xe2, 0x78, 0x37, 0xe8, 0x7c, 0x6d, 0x5b,
+ 0x77, 0xeb, 0x0a, 0x56, 0xe7, 0x25, 0x9f, 0xe8,
+ 0xc0, 0x82, 0xc3, 0xf8, 0xb8, 0x1a, 0xe3, 0x60,
+ 0x65, 0x24, 0x2e, 0x0c, 0xc2, 0x74, 0xcd, 0x2a,
+ 0x03, 0xd1, 0x66, 0x7a, 0x1c, 0xe2, 0x3d, 0xc5,
+ 0xa9, 0x78, 0x5f, 0x32, 0x96, 0x8a, 0xe4, 0x11,
+ 0x97, 0x82, 0xb9, 0x11, 0x48, 0xd5, 0x3f, 0x1b,
+ 0x4d, 0xc5, 0xf7, 0x4e, 0xe7, 0x7d, 0x5a, 0xf3,
+ 0x42, 0xff, 0xf8, 0xf6, 0x8d, 0xd2, 0x22, 0x95,
+ 0xdf, 0xf2, 0x7e, 0xfc, 0x34, 0xf4, 0x6d, 0x8e,
+ 0x37, 0x02, 0x34, 0x30, 0xf8, 0x31, 0xfb, 0xa8,
+ 0x97, 0x74, 0xac, 0xf3, 0x4a, 0x67, 0x4a, 0xee,
+ 0x12, 0xed, 0x9d, 0x19, 0xcd, 0x4a, 0xe2, 0x13,
+ 0x43, 0x25, 0xf7, 0x00, 0xd8, 0xbd, 0x91, 0xc2,
+ 0x38, 0xc4, 0x68, 0xeb, 0xb1, 0x74, 0xd0, 0x8c,
+ 0xdb, 0x76, 0x79, 0xe2, 0xd0, 0x85, 0x0d, 0x03,
+ 0xdc, 0xdc, 0x8e, 0x79, 0x7f, 0xdb, 0xea, 0x36,
+ 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, 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, 0x00, 0x00},
+ /* 4096,[p<q] */ {0xac, 0x34, 0x9f, 0xe1, 0x4d, 0x4a, 0xf8, 0x8f,
+ 0x3a, 0xa0, 0xf5, 0x78, 0xe3, 0x30, 0x7e, 0x80,
+ 0x55, 0x7a, 0x93, 0x96, 0x47, 0xb8, 0x28, 0xc7,
+ 0x34, 0x33, 0xcf, 0x97, 0x90, 0x71, 0xbc, 0xc6,
+ 0x37, 0x13, 0x8b, 0x53, 0x41, 0x51, 0x9a, 0x2e,
+ 0x4a, 0xa0, 0x6b, 0xfc, 0xc6, 0x73, 0x0a, 0x6f,
+ 0x5c, 0x09, 0xee, 0x35, 0x9d, 0xee, 0x2a, 0xbe,
+ 0x88, 0x8a, 0xbf, 0xa0, 0x60, 0xb3, 0x4b, 0x93,
+ 0x37, 0xb7, 0xb9, 0x52, 0xd5, 0x9d, 0x2b, 0xd8,
+ 0x39, 0xfe, 0x04, 0x4a, 0x97, 0x3f, 0x4a, 0xd9,
+ 0x8b, 0x27, 0x71, 0xb3, 0xbe, 0x25, 0x43, 0xd6,
+ 0xba, 0x06, 0x6c, 0x93, 0x09, 0x27, 0xf8, 0x4f,
+ 0x9a, 0x6f, 0x97, 0x23, 0x22, 0x9e, 0x51, 0x53,
+ 0x9a, 0x4c, 0x08, 0x3a, 0x78, 0x22, 0xd5, 0x7f,
+ 0xe9, 0xb1, 0x78, 0xef, 0xdc, 0x7e, 0x0c, 0x67,
+ 0x54, 0x14, 0xdd, 0x15, 0xf5, 0xc5, 0xc6, 0x4c,
+ 0x64, 0xa4, 0x70, 0x97, 0xd5, 0xfd, 0xc6, 0x8a,
+ 0x21, 0x86, 0x70, 0x93, 0xa5, 0xaa, 0x04, 0xa4,
+ 0xa6, 0xfc, 0x8b, 0x51, 0xe8, 0x64, 0x30, 0x9d,
+ 0x5c, 0x44, 0x8d, 0xab, 0xf3, 0x1a, 0x19, 0x56,
+ 0xa7, 0x87, 0xce, 0x0b, 0xb8, 0xd1, 0x84, 0xb1,
+ 0x69, 0x39, 0x34, 0x2d, 0xeb, 0x62, 0xda, 0x46,
+ 0xc8, 0xc0, 0x98, 0x0a, 0x95, 0x43, 0xc8, 0x80,
+ 0xe3, 0x45, 0x89, 0x1e, 0x27, 0x2f, 0x8e, 0x85,
+ 0x9b, 0xf8, 0xc8, 0x76, 0x1e, 0xfa, 0x67, 0x51,
+ 0xcf, 0x4f, 0x8d, 0x07, 0xb9, 0xd6, 0x93, 0xc6,
+ 0xc3, 0xd1, 0xa6, 0x8e, 0x17, 0x94, 0x88, 0x4c,
+ 0x74, 0x48, 0x97, 0x50, 0xd0, 0x1f, 0xb0, 0x6d,
+ 0xf7, 0x2c, 0xc2, 0x01, 0x0e, 0x22, 0xa1, 0xc4,
+ 0x20, 0xfd, 0xb3, 0xde, 0x0d, 0x95, 0x0c, 0xeb,
+ 0xc2, 0x63, 0x37, 0x24, 0xb7, 0xb1, 0x90, 0x6d,
+ 0xb7, 0xda, 0x19, 0x33, 0x59, 0xd7, 0x34, 0x8d,
+ 0x72, 0xd2, 0x13, 0x4d, 0xec, 0xa8, 0xf7, 0xf3,
+ 0x62, 0x6a, 0x8a, 0x37, 0x61, 0x04, 0x57, 0x82,
+ 0x83, 0xa2, 0x5c, 0xc6, 0xd4, 0x9c, 0x29, 0x92,
+ 0xa7, 0xbe, 0xf7, 0xbb, 0x98, 0x23, 0xf8, 0xc4,
+ 0x23, 0xac, 0xbd, 0xa1, 0x6e, 0xfa, 0x45, 0xfd,
+ 0x58, 0xcc, 0x67, 0xba, 0xe3, 0xd5, 0x86, 0x35,
+ 0x75, 0x58, 0x07, 0xe9, 0x42, 0x6b, 0x2f, 0x17,
+ 0xc1, 0x64, 0x10, 0xba, 0x52, 0x37, 0xaf, 0xe0,
+ 0x36, 0x9a, 0x41, 0x06, 0xa1, 0x70, 0x12, 0x27,
+ 0xf7, 0xaa, 0xee, 0x9f, 0x9c, 0x16, 0x5d, 0x30,
+ 0xb0, 0xdd, 0x9c, 0x56, 0x8b, 0x0e, 0xbb, 0xd2,
+ 0xed, 0x36, 0xa7, 0x71, 0x77, 0xb8, 0xd4, 0xcd,
+ 0xb0, 0x38, 0x26, 0x4c, 0x10, 0x5d, 0x14, 0x5b,
+ 0x18, 0xde, 0xec, 0xda, 0x3d, 0xfe, 0x18, 0x02,
+ 0x34, 0x13, 0xdb, 0x1f, 0x74, 0xc4, 0xdd, 0xbc,
+ 0xd2, 0x1a, 0x68, 0xcf, 0x96, 0x9b, 0x4e, 0xaa,
+ 0xdd, 0x47, 0x24, 0xa4, 0x1a, 0x1d, 0x5b, 0xa1,
+ 0x8e, 0xcf, 0x4a, 0x51, 0x0a, 0x7b, 0x24, 0xfc,
+ 0x54, 0x20, 0x31, 0x5a, 0x97, 0x42, 0x9d, 0x36,
+ 0x84, 0x07, 0x89, 0x3e, 0x39, 0x34, 0x5e, 0x40,
+ 0xae, 0xe7, 0xf8, 0x82, 0xd7, 0xb3, 0xa9, 0x25,
+ 0xfe, 0xc5, 0x45, 0xd5, 0xde, 0x6f, 0x02, 0x61,
+ 0x25, 0x12, 0x90, 0xfe, 0xe7, 0x10, 0x1d, 0x60,
+ 0x55, 0xf8, 0xd2, 0xff, 0x26, 0xb3, 0xbb, 0xea,
+ 0xb7, 0x6d, 0x14, 0xd9, 0x54, 0xef, 0xc3, 0x5f,
+ 0x73, 0x46, 0xdc, 0xd1, 0xfa, 0xd8, 0x31, 0xc6,
+ 0xff, 0xd8, 0xc7, 0xf7, 0x84, 0xc0, 0x87, 0x70,
+ 0x97, 0xab, 0xdf, 0xa7, 0x8c, 0x0b, 0xf1, 0xcf,
+ 0x81, 0x2a, 0xce, 0xf2, 0x02, 0xfd, 0x41, 0xb2,
+ 0x54, 0x9f, 0x49, 0x17, 0xe7, 0xbb, 0xa5, 0x37,
+ 0x6e, 0x4d, 0xeb, 0x2b, 0x62, 0x1c, 0x36, 0xb3,
+ 0x01, 0x86, 0x45, 0x82, 0xc1, 0x4f, 0x60, 0x77}};
diff --git a/src/tests/libica_sha1_test.c b/src/tests/libica_sha1_test.c
new file mode 100644
index 0000000..8c696db
--- /dev/null
+++ b/src/tests/libica_sha1_test.c
@@ -0,0 +1,200 @@
+/* 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 <fcntl.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <string.h>
+#include "ica_api.h"
+#include "testcase.h"
+
+#define NUM_FIPS_TESTS 4
+
+unsigned char FIPS_TEST_DATA[NUM_FIPS_TESTS][64] = {
+ // Test 0: NULL
+ { 0x00 },
+ // Test 1: "abc"
+ { 0x61,0x62,0x63 },
+ // Test 2: "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 3: 1,000,000 'a' -- don't actually use this... see the special case
+ // in the loop below.
+ {
+0x61,
+ },
+};
+
+unsigned int FIPS_TEST_DATA_SIZE[NUM_FIPS_TESTS] = {
+ // Test 0: NULL
+ 0,
+ // Test 1: "abc"
+ 3,
+ // Test 2: "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ 56,
+ // Test 3: 1,000,000 'a'
+ 1000000,
+};
+
+unsigned char FIPS_TEST_RESULT[NUM_FIPS_TESTS][SHA_HASH_LENGTH] =
+{
+ // Hash for test 0: NULL
+ {
+0xda,0x39,0xa3,0xee,0x5e,0x6b,0x4b,0x0d,0x32,0x55,0xbf,0xef,0x95,0x60,0x18,0x90,
+0xaf,0xd8,0x07,0x09,
+ },
+ // Hash for test 1: "abc"
+ {
+0xA9,0x99,0x3E,0x36,0x47,0x06,0x81,0x6A,0xBA,0x3E,0x25,0x71,0x78,0x50,0xC2,0x6C,
+0x9C,0xD0,0xD8,0x9D,
+ },
+ // Hash for test 2: "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ {
+0x84,0x98,0x3E,0x44,0x1C,0x3B,0xD2,0x6E,0xBA,0xAE,0x4A,0xA1,0xF9,0x51,0x29,0xE5,
+0xE5,0x46,0x70,0xF1,
+ },
+ // Hash for test 3: 1,000,000 'a'
+ {
+0x34,0xAA,0x97,0x3C,0xD4,0xC4,0xDA,0xA4,0xF6,0x1E,0xEB,0x2B,0xDB,0xAD,0x27,0x31,
+0x65,0x34,0x01,0x6F,
+ },
+};
+
+int new_api_sha_test(void)
+{
+ V_(printf("Test of new sha api\n"));
+ sha_context_t sha_context;
+ int rc = 0, i = 0;
+ unsigned char input_data[1000000];
+ unsigned int output_hash_length = SHA_HASH_LENGTH;
+ unsigned char output_hash[SHA_HASH_LENGTH];
+
+ for (i = 0; i < NUM_FIPS_TESTS; i++) {
+ // Test 3 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 != 3)
+ memcpy(input_data, FIPS_TEST_DATA[i], FIPS_TEST_DATA_SIZE[i]);
+ else
+ memset(input_data, 'a', FIPS_TEST_DATA_SIZE[i]);
+
+ VV_(printf("\nOriginal data for test %d:\n", i));
+ dump_array(input_data, FIPS_TEST_DATA_SIZE[i]);
+
+ rc = ica_sha1(SHA_MSG_PART_ONLY, FIPS_TEST_DATA_SIZE[i], input_data,
+ &sha_context, output_hash);
+
+ if (rc != 0) {
+ V_(printf("icaSha1 failed with errno %d (0x%x).\n", rc, rc));
+ return rc;
+ }
+
+ VV_(printf("\nOutput hash for test %d:\n", i));
+ dump_array(output_hash, output_hash_length);
+ if (memcmp(output_hash, FIPS_TEST_RESULT[i], SHA_HASH_LENGTH) != 0) {
+ VV_(printf("This does NOT match the known result.\n"));
+ }
+ else
+ VV_(printf("Yep, it's what it should be.\n"));
+ }
+
+ // This test is the same as test 3, except that we use the SHA_CONTEXT
+ // and break it into calls of 1024 bytes each.
+ V_(printf("\nOriginal data for test 3(chunks = 1024) is calls of 1024"
+ "'a's at a time\n"));
+ i = FIPS_TEST_DATA_SIZE[3];
+ while (i > 0) {
+ unsigned int sha_message_part;
+ memset(input_data, 'a', 1024);
+
+ if (i == FIPS_TEST_DATA_SIZE[3])
+ 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_sha1(sha_message_part, (i < 1024) ? i : 1024,
+ input_data, &sha_context, output_hash);
+
+ if (rc != 0) {
+ V_(printf("ica_sha1 failed with errno %d (0x%x) on"
+ " iteration %d.\n", rc, rc, i));
+ return rc;
+ }
+ i -= 1024;
+ }
+
+ VV_(printf("\nOutput hash for test 3(chunks = 1024):\n"));
+ dump_array(output_hash, output_hash_length);
+ if (memcmp(output_hash, FIPS_TEST_RESULT[3], SHA_HASH_LENGTH) != 0) {
+ VV_(printf("This does NOT match the known result.\n"));
+ }
+ else {
+ VV_(printf("Yep, it's what it should be.\n"));
+ }
+
+ // This test is the same as test 3, except that we use the SHA_CONTEXT
+ // and break it into calls of 64 bytes each.
+ V_(printf("\nOriginal data for test 3(chunks = 64) is calls of 64 'a's at"
+ "a time\n"));
+ i = FIPS_TEST_DATA_SIZE[3];
+ while (i > 0) {
+ unsigned int sha_message_part;
+ memset(input_data, 'a', 64);
+
+ if (i == FIPS_TEST_DATA_SIZE[3])
+ 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_sha1(sha_message_part, (i < 64) ? i : 64, input_data,
+ &sha_context, output_hash);
+
+ if (rc != 0) {
+ V_(printf("ica_sha1 failed with errno %d (0x%x) on"
+ " iteration %d.\n", rc, rc, i));
+ return rc;
+ }
+ i -= 64;
+ }
+
+ VV_(printf("\nOutput hash for test 3(chunks = 64):\n"));
+ dump_array(output_hash, output_hash_length);
+ if (memcmp(output_hash, FIPS_TEST_RESULT[3], SHA_HASH_LENGTH) != 0) {
+ VV_(printf("This does NOT match the known result.\n"));
+ }
+ else {
+ VV_(printf("Yep, it's what it should be.\n"));
+ }
+
+ printf("All SHA1 tests passed.\n");
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int rc = 0;
+
+ set_verbosity(argc, argv);
+
+ rc = new_api_sha_test();
+ if (rc) {
+ printf("new_api_sha_test failed with rc = %i\n", rc);
+ return rc;
+ }
+
+ return 0;
+}
+
diff --git a/src/tests/libica_sha256_test.c b/src/tests/libica_sha256_test.c
new file mode 100644
index 0000000..57c137a
--- /dev/null
+++ b/src/tests/libica_sha256_test.c
@@ -0,0 +1,190 @@
+/* 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"
+#include "testcase.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 FIPS_TEST_DATA_SIZE[NUM_FIPS_TESTS] = {
+ // Test 0: "abc"
+ 3,
+ // Test 1: "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ 56,
+ // Test 2: 1,000,000 'a'
+ 1000000,
+};
+
+unsigned char FIPS_TEST_RESULT[NUM_FIPS_TESTS][SHA256_HASH_LENGTH] =
+{
+ // 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,
+ },
+};
+
+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 = SHA256_HASH_LENGTH;
+ unsigned char output_hash[SHA256_HASH_LENGTH];
+
+ 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]);
+
+ VV_(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,
+ &sha256_context, output_hash);
+
+ if (rc != 0) {
+ V_(printf("icaSha256 failed with errno %d (0x%x).\n", rc, rc));
+ return rc;
+ }
+
+ VV_(printf("\nOutput hash for test %d:\n", i));
+ dump_array(output_hash, output_hash_length);
+ if (memcmp(output_hash, FIPS_TEST_RESULT[i], SHA256_HASH_LENGTH) != 0) {
+ VV_(printf("This does NOT match the known result.\n"));
+ }
+ else {
+ VV_(printf("Yep, 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.
+ V_(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) {
+ V_(printf("ica_sha256 failed with errno %d (0x%x) on"
+ " iteration %d.\n", rc, rc, i));
+ return rc;
+ }
+ i -= 1024;
+ }
+
+ VV_(printf("\nOutput hash for test 2(chunks = 1024):\n"));
+ dump_array(output_hash, output_hash_length);
+ if (memcmp(output_hash, FIPS_TEST_RESULT[2], SHA256_HASH_LENGTH) != 0) {
+ VV_(printf("This does NOT match the known result.\n"));
+ }
+ else {
+ VV_(printf("Yep, 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.
+ V_(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);
+
+ if (rc != 0) {
+ V_(printf("ica_sha256 failed with errno %d (0x%x) on iteration"
+ " %d.\n", rc, rc, i));
+ return rc;
+ }
+ i -= 64;
+ }
+
+ VV_(printf("\nOutput hash for test 2(chunks = 64):\n"));
+ dump_array(output_hash, output_hash_length);
+ if (memcmp(output_hash, FIPS_TEST_RESULT[2], SHA256_HASH_LENGTH) != 0) {
+ VV_(printf("This does NOT match the known result.\n"));
+ }
+ else {
+ VV_(printf("Yep, it's what it should be.\n"));
+ }
+
+ printf("All SHA256 tests passed.\n");
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int rc = 0;
+
+ set_verbosity(argc, argv);
+
+ rc = new_api_sha256_test();
+ if (rc) {
+ printf("new_api_sha256_test: returned rc = %i\n", rc);
+ return rc;
+ }
+
+ return rc;
+}
diff --git a/src/tests/libica_sha_test/Makefile.am b/src/tests/libica_sha_test/Makefile.am
new file mode 100644
index 0000000..481d6b5
--- /dev/null
+++ b/src/tests/libica_sha_test/Makefile.am
@@ -0,0 +1,26 @@
+OPTS = -O0 -g -Wall -D_LINUX_S390_ -D_GNU_SOURCE
+LIBS = -L../../.libs
+INCLUDE = -I. -I./include -I../../../include
+SOURCES = libica_sha_test.c queue_t.c sha_tests.c read_rsp.c
+CC = gcc
+FILES = libica_sha_test.c~ \
+ libica_sha_test.o \
+ queue_t.c~ \
+ queue_t.o \
+ include/queue_t.h~ \
+ sha_tests.c~ \
+ sha_tests.o \
+ include/sha_tests.h~ \
+ read_rsp.c~ \
+ include/read_rsp.h~ \
+ include/critical_error.h~
+
+all:
+ $(CC) $(OPTS) -o libica_sha_test $(SOURCES) $(LIBS) $(INCLUDE) -lica -lcrypto
+
+clean:
+ rm -f libica_sha_test
+
+distclean:
+ rm -f Makefile
+ rm -f $(FILES)
diff --git a/src/tests/libica_sha_test/include/critical_error.h b/src/tests/libica_sha_test/include/critical_error.h
new file mode 100644
index 0000000..18891a2
--- /dev/null
+++ b/src/tests/libica_sha_test/include/critical_error.h
@@ -0,0 +1,14 @@
+#ifndef CRITICAL_ERROR_H
+#define CRITICAL_ERROR_H
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/* terminate on critical error */
+#define CRITICAL_ERROR(msg) \
+do { \
+ fprintf(stderr, "critical error in %s: " msg "\n",__func__); \
+ exit(EXIT_FAILURE); \
+} while(0)
+
+#endif
diff --git a/src/tests/libica_sha_test/include/queue_t.h b/src/tests/libica_sha_test/include/queue_t.h
new file mode 100644
index 0000000..1ba9295
--- /dev/null
+++ b/src/tests/libica_sha_test/include/queue_t.h
@@ -0,0 +1,33 @@
+#ifndef QUEUE_T_H
+#define QUEUE_T_H
+
+#define NO_TYPE_SET 0
+#define NO_LENGTH_SET 0
+
+/* type: NO_TYPE_SET, SHA1, SHA224, SHA256, SHA384, SHA512
+ * msg_digest_length: SHA1_HASH_LENGTH, SHA224_HASH_LENGHT, SHA256_HASH_LENGTH, SHA384_HASH_LENGTH, SHA512_HASH_LENGTH
+ * */
+typedef struct test_t {
+ unsigned int type;
+ unsigned char *msg;
+ unsigned int msg_length;
+ unsigned char *msg_digest;
+ unsigned int msg_digest_length;
+ struct test_t *next;
+} test_t;
+
+test_t new_test_t(void);
+
+typedef struct queue_t {
+ unsigned int size;
+ unsigned int passed;
+ unsigned int failed;
+ test_t *head;
+ test_t *tail;
+} queue_t;
+
+queue_t new_queue_t(void);
+
+void push(queue_t * queue, test_t test);
+
+#endif
diff --git a/src/tests/libica_sha_test/include/read_rsp.h b/src/tests/libica_sha_test/include/read_rsp.h
new file mode 100644
index 0000000..b4746af
--- /dev/null
+++ b/src/tests/libica_sha_test/include/read_rsp.h
@@ -0,0 +1,14 @@
+#ifndef READ_RSP_H
+#define READ_RSP_H
+
+#include <stdio.h>
+#include "queue_t.h"
+
+#define BUFFER_SIZE 32768
+
+extern queue_t queue;
+
+/* read test data from .rsp file into queue */
+int read_test_data(FILE * test_data);
+
+#endif
diff --git a/src/tests/libica_sha_test/include/sha_tests.h b/src/tests/libica_sha_test/include/sha_tests.h
new file mode 100644
index 0000000..239f3de
--- /dev/null
+++ b/src/tests/libica_sha_test/include/sha_tests.h
@@ -0,0 +1,22 @@
+#ifndef SHA_TESTS_H
+#define SHA_TESTS_H
+
+#include "queue_t.h"
+
+int sha1_old_api_test(test_t * test);
+int sha1_new_api_test(test_t * test);
+
+int sha224_old_api_test(test_t * test);
+int sha224_new_api_test(test_t * test);
+
+int sha256_old_api_test(test_t * test);
+int sha256_new_api_test(test_t * test);
+
+int sha384_old_api_test(test_t * test);
+int sha384_new_api_test(test_t * test);
+
+int sha512_old_api_test(test_t * test);
+int sha512_new_api_test(test_t * test);
+
+int silent;
+#endif
diff --git a/src/tests/libica_sha_test/libica_sha_test.c b/src/tests/libica_sha_test/libica_sha_test.c
new file mode 100644
index 0000000..66144f8
--- /dev/null
+++ b/src/tests/libica_sha_test/libica_sha_test.c
@@ -0,0 +1,118 @@
+/*
+ * usage: libica_sha_test filelist
+ * test for old and new libica api for sha1/224/256/384/512
+ * test vectors are read from .rsp files and put in the queue
+ * the included .rsp files are obtained from nist:
+ * http://csrc.nist.gov/groups/STM/cavp/index.html#03
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "ica_api.h"
+#include "sha_tests.h"
+#include "read_rsp.h"
+#include "queue_t.h"
+#include "critical_error.h"
+#include "../testcase.h"
+
+queue_t queue;
+
+int main(int argc, char *argv[])
+{
+ test_t *curr_test;
+ FILE *test_data;
+ int i, rc;
+
+ /* first cmd line arg may be verbosity */
+ if ((argc >= 2) && (argv[1][0] == '-')) {
+ set_verbosity(2, argv);
+ i = 2;
+ }
+ else
+ i = 1;
+
+ if (argc - i == 0) {
+ printf("error: no input files.\n");
+ return EXIT_FAILURE;
+ }
+
+ queue = new_queue_t();
+
+ /* read test vectors from .rsp file(s) and put on queue */
+ for (; i < argc; i++) {
+ if ((test_data = fopen(argv[i], "r")) != NULL) {
+ VV_(printf("reading test data from %s ... ", argv[i]));
+ if (read_test_data(test_data) == EXIT_SUCCESS) {
+ VV_(printf("done.\n"));
+ }
+ if ((fclose(test_data)) == EOF) {
+ V_(printf("error: couldn't close file %s.\n",
+ argv[i]));
+ }
+ } else {
+ V_(printf("error: couldn't open file %s.\n", argv[i]));
+ }
+ }
+
+ VV_(printf("%u test vectors found.\n", queue.size));
+
+ if (queue.size > 0) {
+ V_(printf("starting tests ...\n\n"));
+ } else {
+ printf("error: no SHA test vectors found.\n");
+ return EXIT_FAILURE;
+ }
+ /* run each test in queue with new and old api */
+ for (curr_test = queue.head, i = 1; curr_test != NULL;
+ curr_test = curr_test->next, i++) {
+ V_(printf("test #%d : %u byte input message, ", i,
+ curr_test->msg_length));
+ switch (curr_test->type) {
+ case SHA1:
+ V_(printf("SHA1 ...\n"));
+ rc = sha1_new_api_test(curr_test);
+ break;
+ case SHA224:
+ V_(printf("SHA224 ...\n"));
+ rc = sha224_new_api_test(curr_test);
+ break;
+ case SHA256:
+ V_(printf("SHA256 ...\n"));
+ rc = sha256_new_api_test(curr_test);
+ break;
+ case SHA384:
+ V_(printf("SHA384 ...\n"));
+ rc = sha384_new_api_test(curr_test);
+ break;
+ case SHA512:
+ V_(printf("SHA512 ...\n"));
+ rc = sha512_new_api_test(curr_test);
+ break;
+ default:
+ CRITICAL_ERROR("Unknown algorithm.\n");
+ rc = -1;
+ break;
+ }
+ if (!rc) {
+ V_(printf("... Passed.\n"));
+ queue.passed++;
+ }
+ else {
+ V_(printf("error: (%x).\n", rc));
+ queue.failed++;
+ }
+
+ }
+ V_(printf("[SHA test case results: tests: %u, passed: %u, failed: %u]\n",
+ queue.passed + queue.failed, queue.passed, queue.failed));
+
+ if (queue.failed == 0) {
+ printf("All SHA tests passed.\n");
+ return EXIT_SUCCESS;
+ }
+ else {
+ printf("SHA tests failed.\n");
+ return EXIT_FAILURE;
+ }
+}
diff --git a/src/tests/libica_sha_test/queue_t.c b/src/tests/libica_sha_test/queue_t.c
new file mode 100644
index 0000000..4df26bc
--- /dev/null
+++ b/src/tests/libica_sha_test/queue_t.c
@@ -0,0 +1,60 @@
+#include <stdlib.h>
+#include <string.h>
+#include "queue_t.h"
+#include "critical_error.h"
+
+test_t new_test_t(void)
+{
+ test_t test;
+
+ test.type = NO_TYPE_SET;
+ test.msg = NULL;
+ test.msg_length = 0;
+ test.msg_digest = NULL;
+ test.msg_digest_length = 0;
+ test.next = NULL;
+
+ return test;
+}
+
+queue_t new_queue_t(void)
+{
+ queue_t queue;
+
+ queue.size = 0;
+ queue.passed = 0;
+ queue.failed = 0;
+ queue.head = NULL;
+ queue.tail = NULL;
+
+ return queue;
+}
+
+void push(queue_t * queue, test_t test)
+{
+ test_t *new_test;
+
+ if ((new_test = (test_t *) malloc(sizeof(test_t))) == NULL)
+ CRITICAL_ERROR("out of memory.");
+
+ new_test->type = test.type;
+ new_test->msg_length = test.msg_length;
+ new_test->msg_digest_length = test.msg_digest_length;
+
+ new_test->msg = (unsigned char *)malloc((size_t) test.msg_length);
+ memcpy(new_test->msg, test.msg, (size_t) test.msg_length);
+
+ new_test->msg_digest =
+ (unsigned char *)malloc((size_t) test.msg_digest_length);
+ memcpy(new_test->msg_digest, test.msg_digest,
+ (size_t) test.msg_digest_length);
+
+ new_test->next = NULL;
+
+ if (queue->head == NULL)
+ queue->head = new_test;
+ else
+ queue->tail->next = new_test;
+ queue->tail = new_test;
+ queue->size++;
+}
diff --git a/src/tests/libica_sha_test/read_rsp.c b/src/tests/libica_sha_test/read_rsp.c
new file mode 100644
index 0000000..ae2c9d6
--- /dev/null
+++ b/src/tests/libica_sha_test/read_rsp.c
@@ -0,0 +1,200 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ica_api.h"
+#include "queue_t.h"
+#include "critical_error.h"
+#include "read_rsp.h"
+
+static int line_to_bytes(char *line, int length);
+
+int read_test_data(FILE * test_data)
+{
+ char buffer[BUFFER_SIZE];
+ enum { MSG_LENGTH, MSG, MSG_DIGEST } search_term;
+
+ test_t tmp_test = new_test_t();
+ unsigned int current_type = NO_TYPE_SET;
+ unsigned int current_msg_digest_length = NO_LENGTH_SET;
+
+ unsigned int line_number = 0;
+
+ char *tmp = NULL;
+ search_term = MSG_LENGTH;
+
+ while (fgets(buffer, (int)sizeof buffer, test_data) != NULL) {
+
+ line_number++;
+
+ /* remove comments */
+ if ((tmp = memchr(buffer, (int)'#', strlen(buffer))) != NULL)
+ memset(tmp, 0, strlen(tmp));
+
+ /* scan for: type/msg_digest_length */
+ if (((sscanf(buffer, "[L = %u]", &current_msg_digest_length))
+ == 1)
+ || (current_type == NO_TYPE_SET)) {
+ if (tmp_test.type != NO_TYPE_SET) {
+ printf
+ ("error:\nincorrect file format [line %u]: test type mustn't change during test definition. closing file.\n",
+ line_number);
+ return EXIT_FAILURE;
+ }
+ switch (current_msg_digest_length) {
+ case NO_LENGTH_SET:
+ continue;
+ case SHA1_HASH_LENGTH:
+ current_type = SHA1;
+ break;
+ case SHA224_HASH_LENGTH:
+ current_type = SHA224;
+ break;
+ case SHA256_HASH_LENGTH:
+ current_type = SHA256;
+ break;
+ case SHA384_HASH_LENGTH:
+ current_type = SHA384;
+ break;
+ case SHA512_HASH_LENGTH:
+ current_type = SHA512;
+ break;
+ default:
+ CRITICAL_ERROR("this shouldn't happen.");
+ break;
+ }
+ }
+
+ /* scan for: 1st msg_length, 2nd msg, 3rd msg_digest. repeat */
+ switch (search_term) {
+ case MSG_LENGTH:
+ if (sscanf(buffer, "Len = %u", &tmp_test.msg_length) ==
+ 1) {
+ if ((tmp_test.msg_length % 8) != 0) {
+ printf
+ ("error:\nincorrect file format [line %u]: message bit-length must be a multiple of 8. closing file.",
+ line_number);
+ return EXIT_FAILURE;
+ }
+ tmp_test.msg_length /= 8;
+ search_term = MSG;
+ }
+ break;
+ case MSG:
+ if (sscanf(buffer, "Msg = %s", buffer) == 1) {
+ if ((int)strlen(buffer) % 2 != 0) {
+ printf
+ ("error:\nincorrect file format [line %u]: message should be bytes. closing file.\n",
+ line_number);
+ return EXIT_FAILURE;
+ }
+ if (line_to_bytes
+ (buffer,
+ (int)strlen(buffer)) == EXIT_FAILURE) {
+ printf
+ ("error:\nincorrect file format [line %u]: message contains characters different from hex values. closing file.\n",
+ line_number);
+ return EXIT_FAILURE;
+ }
+ if ((tmp_test.msg = (unsigned char *)
+ malloc((size_t) tmp_test.msg_length))
+ == NULL)
+ CRITICAL_ERROR("out of memory.");
+ memcpy(tmp_test.msg, buffer,
+ (size_t) tmp_test.msg_length);
+ search_term = MSG_DIGEST;
+ }
+ break;
+ case MSG_DIGEST:
+ if (sscanf(buffer, "MD = %s", buffer)
+ == 1) {
+ if (((int)strlen(buffer) % 2 != 0)
+ || (((int)strlen(buffer) / 2) !=
+ current_msg_digest_length)) {
+ printf
+ ("error:\nincorrect file format [line %u]: message digest length doesn't match test type. closing file.\n",
+ line_number);
+ free(tmp_test.msg);
+ return EXIT_FAILURE;
+ }
+ if (line_to_bytes
+ (buffer,
+ (int)strlen(buffer)) == EXIT_FAILURE) {
+ printf
+ ("error:\nincorrect file format [line %u]: message digest contains characters different from hex values. closing file.\n",
+ line_number);
+ free(tmp_test.msg);
+ return EXIT_FAILURE;
+ }
+ if ((tmp_test.msg_digest = (unsigned char *)
+ malloc((size_t)
+ current_msg_digest_length))
+ == NULL)
+ CRITICAL_ERROR("out of memory.");
+ memcpy(tmp_test.msg_digest, buffer,
+ (size_t) current_msg_digest_length);
+ tmp_test.type = current_type;
+ tmp_test.msg_digest_length =
+ current_msg_digest_length;
+ push(&queue, tmp_test);
+ free(tmp_test.msg);
+ free(tmp_test.msg_digest);
+ tmp_test = new_test_t();
+ search_term = MSG_LENGTH;
+ }
+ break;
+ default:
+ CRITICAL_ERROR("this shouldn't happen.");
+ break;
+ }
+ if (feof(test_data) != 0) {
+ CRITICAL_ERROR("read error.");
+ }
+ }
+ free(tmp_test.msg);
+ free(tmp_test.msg_digest);
+
+ if (feof(test_data) == 0) {
+ printf("error:\ndidn't reach end of file. closing file.\n");
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}
+
+static int line_to_bytes(char *line, int length)
+{
+ int i;
+ unsigned char *bytes;
+ if ((bytes = (unsigned char *)
+ malloc((size_t) (length / 2))) == NULL)
+ CRITICAL_ERROR("out of memory.");
+ for (i = 0; i <= ((length / 2) - 1); i++) {
+ if (line[2 * i] >= 'a' && line[2 * i] <= 'f')
+ line[2 * i] = line[2 * i] - 'a' + (char)10;
+ else if (line[2 * i] >= '0' && line[2 * i] <= '9')
+ line[2 * i] = line[2 * i] - '0';
+ else if (line[2 * i] >= 'A' && line[2 * i] <= 'F')
+ line[2 * i] = line[2 * i] - 'A' + (char)10;
+ else {
+ free(bytes);
+ return EXIT_FAILURE;
+ }
+ bytes[i] = (unsigned char)(line[2 * i] * (char)16);
+ if (line[2 * i + 1] >= 'a' && line[2 * i + 1] <= 'f')
+ line[2 * i + 1] = line[2 * i + 1] - (char)87;
+ else if (line[2 * i + 1] >= '0' && line[2 * i + 1] <= '9')
+ line[2 * i + 1] = line[2 * i + 1] - (char)48;
+ else if (line[2 * i + 1] >= 'A' && line[2 * i + 1] <= 'F')
+ line[2 * i + 1] = line[2 * i + 1] - 'A' + (char)10;
+ else {
+ free(bytes);
+ return EXIT_FAILURE;
+ }
+ bytes[i] += (unsigned char)line[2 * i + 1];
+ }
+ memcpy(line, bytes, (size_t) (length / 2));
+ memset(line + length / 2, 0, (size_t) (length / 2 + 1));
+ free(bytes);
+
+ return EXIT_SUCCESS;
+}
diff --git a/src/tests/libica_sha_test/sha_test_vectors/SHA1.txt b/src/tests/libica_sha_test/sha_test_vectors/SHA1.txt
new file mode 100644
index 0000000..a283e3f
--- /dev/null
+++ b/src/tests/libica_sha_test/sha_test_vectors/SHA1.txt
@@ -0,0 +1,36 @@
+# SHA1 tests
+
+[L = 20]
+
+Len = 0
+Msg = 00
+MD = da39a3ee5e6b4b0d3255bfef95601890afd80709
+
+Len = 8
+Msg = 36
+MD = c1dfd96eea8cc2b62785275bca38ac261256e278
+
+Len = 16
+Msg = 195a
+MD = 0a1c2d555bbe431ad6288af5a54f93e0449c9232
+
+Len = 32
+Msg = 549e959e
+MD = b78bae6d14338ffccfd5d5b5674a275f6ef9c717
+
+Len = 64
+Msg = 7e3d7b3eada98866
+MD = 24a2c34b976305277ce58c2f42d5092031572520
+
+Len = 128
+Msg = 3552694cdf663fd94b224747ac406aaf
+MD = a150de927454202d94e656de4c7c0ca691de955d
+
+Len = 256
+Msg = 0321794b739418c24e7c2e565274791c4be749752ad234ed56cb0a6347430c6b
+MD = b89962c94d60f6a332fd60f6f07d4f032a586b76
+
+Len = 512
+Msg = 45927e32ddf801caf35e18e7b5078b7f5435278212ec6bb99df884f49b327c6486feae46ba187dc1cc9145121e1492e6b06e9007394dc33b7748f86ac3207cfe
+MD = a70cfbfe7563dd0e665c7c6715a96a8d756950c0
+
diff --git a/src/tests/libica_sha_test/sha_test_vectors/SHA224.txt b/src/tests/libica_sha_test/sha_test_vectors/SHA224.txt
new file mode 100644
index 0000000..8d6b1d7
--- /dev/null
+++ b/src/tests/libica_sha_test/sha_test_vectors/SHA224.txt
@@ -0,0 +1,39 @@
+# CAVS 11.0
+# "SHA-224 ShortMsg" information
+# SHA-224 tests are configured for BYTE oriented implementations
+# Generated on Tue Mar 15 08:23:36 2011
+
+[L = 28]
+
+Len = 0
+Msg = 00
+MD = d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f
+
+Len = 8
+Msg = 84
+MD = 3cd36921df5d6963e73739cf4d20211e2d8877c19cff087ade9d0e3a
+
+Len = 16
+Msg = 5c7b
+MD = daff9bce685eb831f97fc1225b03c275a6c112e2d6e76f5faf7a36e6
+
+Len = 32
+Msg = 6084347e
+MD = ae57c0a6d49739ba338adfa53bdae063e5c09122b77604780a8eeaa3
+
+Len = 64
+Msg = 5f77b3664823c33e
+MD = bdf21ff325f754157ccf417f4855360a72e8fd117d28c8fe7da3ea38
+
+Len = 128
+Msg = b776708ffb91b3515ac46598ab9fa796
+MD = 427311b1d7ab2488791c4deeb4251d783fe5f9806bfdfb5188c5443d
+
+Len = 256
+Msg = fe1f0fb02c9011f4c8c5905934ed15136771737ce31c5859e67f235fe594f5f6
+MD = bbeaacc632c2a3db2a9b47f157ab54aa27776c6e74cf0bcaa91b06d5
+
+Len = 512
+Msg = a3310ba064be2e14ad32276e18cd0310c933a6e650c3c754d0243c6c61207865b4b65248f66a08edf6e0832689a9dc3a2e5d2095eeea50bd862bac88c8bd318d
+MD = b2a5586d9cbf0baa999157b4af06d88ae08d7c9faab4bc1a96829d65
+
diff --git a/src/tests/libica_sha_test/sha_test_vectors/SHA256.txt b/src/tests/libica_sha_test/sha_test_vectors/SHA256.txt
new file mode 100644
index 0000000..c8bc15b
--- /dev/null
+++ b/src/tests/libica_sha_test/sha_test_vectors/SHA256.txt
@@ -0,0 +1,39 @@
+# CAVS 11.0
+# "SHA-256 ShortMsg" information
+# SHA-256 tests are configured for BYTE oriented implementations
+# Generated on Tue Mar 15 08:23:38 2011
+
+[L = 32]
+
+Len = 0
+Msg = 00
+MD = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+
+Len = 8
+Msg = d3
+MD = 28969cdfa74a12c82f3bad960b0b000aca2ac329deea5c2328ebc6f2ba9802c1
+
+Len = 16
+Msg = 11af
+MD = 5ca7133fa735326081558ac312c620eeca9970d1e70a4b95533d956f072d1f98
+
+Len = 32
+Msg = 74ba2521
+MD = b16aa56be3880d18cd41e68384cf1ec8c17680c45a02b1575dc1518923ae8b0e
+
+Len = 64
+Msg = 5738c929c4f4ccb6
+MD = 963bb88f27f512777aab6c8b1a02c70ec0ad651d428f870036e1917120fb48bf
+
+Len = 128
+Msg = 0a27847cdc98bd6f62220b046edd762b
+MD = 80c25ec1600587e7f28b18b1b18e3cdc89928e39cab3bc25e4d4a4c139bcedc4
+
+Len = 256
+Msg = 09fc1accc230a205e4a208e64a8f204291f581a12756392da4b8c0cf5ef02b95
+MD = 4f44c1c7fbebb6f9601829f3897bfd650c56fa07844be76489076356ac1886a4
+
+Len = 512
+Msg = 5a86b737eaea8ee976a0a24da63e7ed7eefad18a101c1211e2b3650c5187c2a8a650547208251f6d4237e661c7bf4c77f335390394c37fa1a9f9be836ac28509
+MD = 42e61e174fbb3897d6dd6cef3dd2802fe67b331953b06114a65c772859dfc1aa
+
diff --git a/src/tests/libica_sha_test/sha_test_vectors/SHA384.txt b/src/tests/libica_sha_test/sha_test_vectors/SHA384.txt
new file mode 100644
index 0000000..6f2acb4
--- /dev/null
+++ b/src/tests/libica_sha_test/sha_test_vectors/SHA384.txt
@@ -0,0 +1,43 @@
+# CAVS 11.0
+# "SHA-384 ShortMsg" information
+# SHA-384 tests are configured for BYTE oriented implementations
+# Generated on Tue Mar 15 08:23:39 2011
+
+[L = 48]
+
+Len = 0
+Msg = 00
+MD = 38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b
+
+Len = 8
+Msg = c5
+MD = b52b72da75d0666379e20f9b4a79c33a329a01f06a2fb7865c9062a28c1de860ba432edfd86b4cb1cb8a75b46076e3b1
+
+Len = 16
+Msg = 6ece
+MD = 53d4773da50d8be4145d8f3a7098ff3691a554a29ae6f652cc7121eb8bc96fd2210e06ae2fa2a36c4b3b3497341e70f0
+
+Len = 32
+Msg = 50e3853d
+MD = 936a3c3991716ba4c413bc03de20f5ce1c63703b3a5bdb6ab558c9ff70d537e46eb4a15d9f2c85e68d8678de5682695e
+
+Len = 64
+Msg = de60275bdafce4b1
+MD = a3d861d866c1362423eb21c6bec8e44b74ce993c55baa2b6640567560ebecdaeda07183dbbbd95e0f522caee5ddbdaf0
+
+Len = 128
+Msg = e1bb967b5d379a4aa39050274d09bd93
+MD = 3b04f96965ad2fbabd4df25d5d8c95589d069c312ee48539090b2d7b495d2446c31eb2b8f8ffb3012bdce065323d9f48
+
+Len = 256
+Msg = be01e520e69f04174ccf95455b1c81445298264d9adc4958574a52843d95b8ba
+MD = c5cf54b8e3105b1c7bf7a43754d915b0947f28b6dc94a019182929b5c848e11441c9e4e90c7449f4c3cd12954f0f5d99
+
+Len = 512
+Msg = 93035d3a13ae1b06dd033e764aca0124961da79c366c6c756bc4bcc11850a3a8d120854f34290fff7c8d6d83531dbdd1e81cc4ed4246e00bd4113ef451334daa
+MD = 8d46cc84b6c2deb206aa5c861798798751a26ee74b1daf3a557c41aebd65adc027559f7cd92b255b374c83bd55568b45
+
+Len = 1024
+Msg = 3bf52cc5ee86b9a0190f390a5c0366a560b557000dbe5115fd9ee11630a62769011575f15881198f227876e8fe685a6939bc8b89fd48a34ec5e71e131462b2886794dffa68ccc6d564733e67ffef25e627c6f4b5460796e3bce67bf58ca6e8e555bc916a8531697ac948b90dc8616f25101db90b50c3d3dbc9e21e42ff387187
+MD = 12b6cb35eda92ee37356ddee77781a17b3d90e563824a984faffc6fdd1693bd7626039635563cfc3b9a2b00f9c65eefd
+
diff --git a/src/tests/libica_sha_test/sha_test_vectors/SHA512.txt b/src/tests/libica_sha_test/sha_test_vectors/SHA512.txt
new file mode 100644
index 0000000..2c5b38d
--- /dev/null
+++ b/src/tests/libica_sha_test/sha_test_vectors/SHA512.txt
@@ -0,0 +1,43 @@
+# CAVS 11.0
+# "SHA-512 ShortMsg" information
+# SHA-512 tests are configured for BYTE oriented implementations
+# Generated on Tue Mar 15 08:23:49 2011
+
+[L = 64]
+
+Len = 0
+Msg = 00
+MD = cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e
+
+Len = 8
+Msg = 21
+MD = 3831a6a6155e509dee59a7f451eb35324d8f8f2df6e3708894740f98fdee23889f4de5adb0c5010dfb555cda77c8ab5dc902094c52de3278f35a75ebc25f093a
+
+Len = 16
+Msg = 9083
+MD = 55586ebba48768aeb323655ab6f4298fc9f670964fc2e5f2731e34dfa4b0c09e6e1e12e3d7286b3145c61c2047fb1a2a1297f36da64160b31fa4c8c2cddd2fb4
+
+Len = 32
+Msg = 23be86d5
+MD = 76d42c8eadea35a69990c63a762f330614a4699977f058adb988f406fb0be8f2ea3dce3a2bbd1d827b70b9b299ae6f9e5058ee97b50bd4922d6d37ddc761f8eb
+
+Len = 64
+Msg = 6f8d58b7cab1888c
+MD = a3941def2803c8dfc08f20c06ba7e9a332ae0c67e47ae57365c243ef40059b11be22c91da6a80c2cff0742a8f4bcd941bdee0b861ec872b215433ce8dcf3c031
+
+Len = 128
+Msg = cd67bd4054aaa3baa0db178ce232fd5a
+MD = 0d8521f8f2f3900332d1a1a55c60ba81d04d28dfe8c504b6328ae787925fe0188f2ba91c3a9f0c1653c4bf0ada356455ea36fd31f8e73e3951cad4ebba8c6e04
+
+Len = 256
+Msg = 8ccb08d2a1a282aa8cc99902ecaf0f67a9f21cffe28005cb27fcf129e963f99d
+MD = 4551def2f9127386eea8d4dae1ea8d8e49b2add0509f27ccbce7d9e950ac7db01d5bca579c271b9f2d806730d88f58252fd0c2587851c3ac8a0e72b4e1dc0da6
+
+Len = 512
+Msg = c1ca70ae1279ba0b918157558b4920d6b7fba8a06be515170f202fafd36fb7f79d69fad745dba6150568db1e2b728504113eeac34f527fc82f2200b462ecbf5d
+MD = 046e46623912b3932b8d662ab42583423843206301b58bf20ab6d76fd47f1cbbcf421df536ecd7e56db5354e7e0f98822d2129c197f6f0f222b8ec5231f3967d
+
+Len = 1024
+Msg = fd2203e467574e834ab07c9097ae164532f24be1eb5d88f1af7748ceff0d2c67a21f4e4097f9d3bb4e9fbf97186e0db6db0100230a52b453d421f8ab9c9a6043aa3295ea20d2f06a2f37470d8a99075f1b8a8336f6228cf08b5942fc1fb4299c7d2480e8e82bce175540bdfad7752bc95b577f229515394f3ae5cec870a4b2f8
+MD = a21b1077d52b27ac545af63b32746c6e3c51cb0cb9f281eb9f3580a6d4996d5c9917d2a6e484627a9d5a06fa1b25327a9d710e027387fc3e07d7c4d14c6086cc
+
diff --git a/src/tests/libica_sha_test/sha_tests.c b/src/tests/libica_sha_test/sha_tests.c
new file mode 100644
index 0000000..bb24609
--- /dev/null
+++ b/src/tests/libica_sha_test/sha_tests.c
@@ -0,0 +1,186 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include "ica_api.h"
+#include "queue_t.h"
+#include "sha_tests.h"
+#include "critical_error.h"
+#define VERBOSE_EXTERN
+#include "../testcase.h"
+#undef VERBOSE_EXTERN
+
+
+int sha1_new_api_test(test_t * test)
+{
+
+ sha_context_t sha_context;
+ int rc = 0;
+ unsigned char output[SHA_HASH_LENGTH];
+
+ if (test->msg_digest_length != SHA_HASH_LENGTH)
+ CRITICAL_ERROR("this shouldn't happen.");
+
+ rc = (int)ica_sha1(SHA_MSG_PART_ONLY, test->msg_length, test->msg,
+ &sha_context, output);
+
+ if (rc != 0) {
+ V_(printf("ica_sha1 failed with errno %d (0x%x).\n", rc,
+ (unsigned int)rc));
+ return rc;
+ }
+
+ VV_(printf("message digest (new api)\n"));
+ dump_array(output, SHA_HASH_LENGTH);
+
+ if (memcmp(output, test->msg_digest, SHA_HASH_LENGTH) != 0) {
+ V_(printf("output is not what it should be.\n"));
+ return 2;
+ }
+ return 0;
+}
+
+int sha224_new_api_test(test_t * test)
+{
+ sha256_context_t sha256_context;
+ int rc = 0;
+ unsigned char output[SHA224_HASH_LENGTH];
+
+ if (test->msg_digest_length != SHA224_HASH_LENGTH)
+ CRITICAL_ERROR("this shouldn't happen.");
+
+ rc = (int)ica_sha224(SHA_MSG_PART_ONLY, test->msg_length, test->msg,
+ &sha256_context, output);
+
+ if (rc != 0) {
+ V_(printf("ica_sha224 failed with errno %d (0x%x).\n", rc,
+ (unsigned int)rc));
+ return rc;
+ }
+
+ VV_(printf("message digest (new api)\n"));
+ dump_array(output, SHA224_HASH_LENGTH);
+
+ if (memcmp(output, test->msg_digest, SHA224_HASH_LENGTH) != 0) {
+ V_(printf("output is not what it should be.\n"));
+ return 2;
+ }
+
+ return 0;
+}
+
+int sha256_new_api_test(test_t * test)
+{
+ sha256_context_t sha256_context;
+ int rc = 0;
+ unsigned char output[SHA256_HASH_LENGTH];
+
+ if (test->msg_digest_length != SHA256_HASH_LENGTH)
+ CRITICAL_ERROR("this shouldn't happen.");
+
+ rc = (int)ica_sha256(SHA_MSG_PART_ONLY, test->msg_length, test->msg,
+ &sha256_context, output);
+
+ if (rc != 0) {
+ V_(printf("ica_sha256 failed with errno %d (0x%x).\n", rc,
+ (unsigned int)rc));
+ return rc;
+ }
+
+ VV_(printf("message digest (new api)\n"));
+ dump_array(output, SHA256_HASH_LENGTH);
+
+ if (memcmp(output, test->msg_digest, SHA256_HASH_LENGTH) != 0) {
+ V_(printf("output is not what it should be.\n"));
+ return 2;
+ }
+
+ return 0;
+}
+
+int sha384_new_api_test(test_t * test)
+{
+ sha512_context_t sha512_context;
+ int rc = 0;
+ unsigned char output[SHA384_HASH_LENGTH];
+
+ if (test->msg_digest_length != SHA384_HASH_LENGTH)
+ CRITICAL_ERROR("this shouldn't happen.");
+
+ rc = (int)ica_sha384(SHA_MSG_PART_ONLY, test->msg_length, test->msg,
+ &sha512_context, output);
+
+ if (rc != 0) {
+ V_(printf("ica_sha384 failed with errno %d (0x%x).\n", rc,
+ (unsigned int)rc));
+ return rc;
+ }
+
+ VV_(printf("message digest (new api)\n"));
+ dump_array(output, SHA384_HASH_LENGTH);
+
+ if (memcmp(output, test->msg_digest, SHA384_HASH_LENGTH) != 0) {
+ V_(printf("output is not what it should be.\n"));
+ return 2;
+ }
+
+ return 0;
+}
+
+int sha512_new_api_test(test_t * test)
+{
+ sha512_context_t sha512_context;
+ int rc = 0;
+ unsigned char output[SHA512_HASH_LENGTH];
+
+ if (test->msg_digest_length != SHA512_HASH_LENGTH)
+ CRITICAL_ERROR("this shouldn't happen.");
+
+ rc = (int)ica_sha512(SHA_MSG_PART_ONLY, test->msg_length, test->msg,
+ &sha512_context, output);
+
+ if (rc != 0) {
+ V_(printf("ica_sha512 failed with errno %d (0x%x).\n", rc,
+ (unsigned int)rc));
+ return rc;
+ }
+
+ VV_(printf("message digest (new api)\n"));
+ dump_array(output, SHA512_HASH_LENGTH);
+
+ if (memcmp(output, test->msg_digest, SHA512_HASH_LENGTH) != 0) {
+ V_(printf("output is not what it should be.\n"));
+ return 2;
+ }
+ return 0;
+}
+/*
+static void dump_array(unsigned char *ptr, unsigned int size)
+{
+ unsigned char *ptr_end;
+ unsigned char *h;
+ int i = 1, trunc = 0;
+
+ if (size > 64) {
+ trunc = (int)size - 64;
+ size = 64;
+ }
+ h = ptr;
+ ptr_end = ptr + size;
+ while (h < ptr_end) {
+ printf("0x%02x ", (unsigned int)*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);
+}
+*/
diff --git a/src/tests/suite.run b/src/tests/suite.run
new file mode 100755
index 0000000..bcf74de
--- /dev/null
+++ b/src/tests/suite.run
@@ -0,0 +1,63 @@
+#!/bin/bash
+
+#
+# Libica test suite
+#
+
+verbosity=$1
+
+out="./suite.out"
+
+testcases=(
+"libica_fips_test"
+
+"libica_get_functionlist $verbosity"
+"libica_get_version $verbosity"
+"icastats_test $verbosity"
+
+"libica_drbg_test $verbosity"
+
+"libica_des_ecb_test $verbosity"
+"libica_des_cbc_test $verbosity"
+"libica_des_cfb_test $verbosity"
+"libica_des_ofb_test $verbosity"
+"libica_des_ctr_test $verbosity"
+
+"libica_3des_ecb_test $verbosity"
+"libica_3des_cbc_test $verbosity"
+"libica_3des_cfb_test $verbosity"
+"libica_3des_ofb_test $verbosity"
+"libica_3des_ctr_test $verbosity"
+
+"libica_aes128_test $verbosity"
+"libica_aes192_test $verbosity"
+"libica_aes256_test $verbosity"
+"libica_aes_ecb_test $verbosity"
+"libica_aes_cbc_test $verbosity"
+"libica_aes_cfb_test $verbosity"
+"libica_aes_ofb_test $verbosity"
+"libica_aes_ctr_test $verbosity"
+"libica_aes_gcm_test $verbosity"
+"libica_aes_xts_test $verbosity"
+
+"libica_cbccs_test $verbosity"
+"libica_ccm_test $verbosity"
+"libica_cmac_test $verbosity"
+
+"libica_keygen_test $verbosity 1024 r"
+"libica_keygen_test $verbosity 2048 r"
+"libica_keygen_test $verbosity 3072 r"
+"libica_keygen_test $verbosity 4096 r"
+"libica_rsa_key_check_test $verbosity"
+"libica_rsa_test $verbosity"
+
+"libica_sha_test/libica_sha_test $verbosity libica_sha_test/sha_test_vectors/*"
+)
+
+echo -ne "" &> $out;
+for (( i=1; i <= ${#testcases[@]}; i++ ))
+do
+ echo -ne "Running libica test suite (writing to "$out") ... "$i"/"${#testcases[@]}"\r";
+ ./${testcases[i-1]} >> $out 2>&1;
+done
+echo -ne "\n";
diff --git a/src/tests/testcase.h b/src/tests/testcase.h
new file mode 100644
index 0000000..6d97ae7
--- /dev/null
+++ b/src/tests/testcase.h
@@ -0,0 +1,47 @@
+/*
+ * Testcase infrastructure.
+ */
+#ifndef TESTCASE_H
+#define TESTCASE_H
+
+#include <stddef.h>
+#include <string.h>
+
+#define V_(print) if (verbosity_ >= 1) print
+#define VV_(print) if (verbosity_ >= 2) print
+
+#ifdef VERBOSITY_EXTERN
+extern
+#endif
+int verbosity_; /* default verbosity level: 0 */
+
+static inline void
+set_verbosity(int argc, char *argv[])
+{
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ if (strcasestr(argv[i], "-vv")) {
+ verbosity_ = 2;
+ break;
+ }
+ if (strcasestr(argv[i], "-v")) {
+ verbosity_ = 1;
+ break;
+ }
+ }
+}
+
+static inline void
+dump_array(unsigned char array[], size_t len)
+{
+ size_t i;
+
+ for (i = 1; i <= len; i++) {
+ VV_(printf("0x%02x ", array[i - 1]));
+ if ((i % 8 == 0) || (i == len))
+ VV_(printf("\n"));
+ }
+}
+
+#endif /* TESTCASE_H */