diff options
author | Dimitri John Ledkov <xnox@ubuntu.com> | 2016-11-24 16:48:43 +0000 |
---|---|---|
committer | Dimitri John Ledkov <xnox@ubuntu.com> | 2016-11-24 16:48:43 +0000 |
commit | b33f77cf05cb266494ef8dacd21758271e7103a6 (patch) | |
tree | bf5b172d5a7b9bee3877c4fc838cc3ebf9aa308f |
Import libica_3.0.1.orig.tar.gz
[dgit import orig libica_3.0.1.orig.tar.gz]
104 files changed, 34734 insertions, 0 deletions
@@ -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> @@ -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. @@ -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. @@ -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 @@ -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]", ¤t_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 */ |