summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri John Ledkov <xnox@ubuntu.com>2017-10-04 11:06:10 +0100
committerDimitri John Ledkov <xnox@ubuntu.com>2017-10-04 11:06:10 +0100
commitbb459e4a2f162a86f4c0dc9bdfb7841f03335a9d (patch)
treecdc52a332e2d4ca2fabe6b81f1f848441c254fe4
parentdd5b9f9525f2c4762577d855b76bbe652500771b (diff)
New upstream release LP: #1718379debian/3.2.0-1archive/debian/3.2.0-1
* New upstream release LP: #1718379 * Add breaks on libopencryptoki0 and openssl-ibmca, whilst ABI is the same, the symbols are now versioned and tagged by upstream.
-rw-r--r--ChangeLog3
-rw-r--r--configure.ac (renamed from configure.in)8
-rw-r--r--debian/changelog8
-rw-r--r--debian/control1
-rw-r--r--debian/libica3.symbols152
-rw-r--r--debian/patches/test-suite.patch20
-rw-r--r--include/ica_api.h199
-rw-r--r--libica.map109
-rw-r--r--libica.spec4
-rw-r--r--src/Makefile.am2
-rw-r--r--src/ica_api.c163
-rw-r--r--src/include/s390_aes.h8
-rw-r--r--src/include/s390_gcm.h162
-rw-r--r--src/tests/Makefile.am2
-rw-r--r--src/tests/gcm_kats.h553
-rw-r--r--src/tests/libica_aes_gcm_kma_test.c731
-rw-r--r--src/tests/libica_aes_gcm_test.c1217
-rwxr-xr-xsrc/tests/suite.run4
18 files changed, 2487 insertions, 859 deletions
diff --git a/ChangeLog b/ChangeLog
index 0e35035..e79aa76 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+v3.2.0
+ - [FEATURE] New AES-GCM interface.
+ - [UPDATE] Add symbol versioning.
v3.1.1
- [PATCH] Various bug fixes related to old and new AES-GCM implementations.
- [UPDATE] Add SHA3 test cases. Improved and extended test suite.
diff --git a/configure.in b/configure.ac
index 52c9f44..19140a3 100644
--- a/configure.in
+++ b/configure.ac
@@ -1,7 +1,7 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
-AC_INIT(libica, 3.1.1, steuer@linux.vnet.ibm.com)
+AC_INIT(libica, 3.2.0, steuer@linux.vnet.ibm.com)
cmdline_CFLAGS="$CFLAGS"
@@ -35,7 +35,7 @@ case "$target" in
;;
*)
AC_CHECK_HEADER(linux/icaioctl.h, ,
- AC_MSG_ERROR([*** Unable to find linux/icaioctl.h]))
+ AC_MSG_ERROR([*** Unable to find linux/icaioctl.h]))
;;
esac
@@ -60,10 +60,10 @@ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
case $target in
*s390x*)
- CFLAGS="$CFLAGS -D_LINUX_S390X_ -D_LINUX_S390_ -Wall -fvisibility=hidden"
+ CFLAGS="$CFLAGS -D_LINUX_S390X_ -D_LINUX_S390_ -Wall -fvisibility=hidden -Wl,--version-script=../libica.map"
;;
*s390*)
- CFLAGS="$CFLAGS -D_LINUX_S390_ -m31 -Wall"
+ CFLAGS="$CFLAGS -D_LINUX_S390_ -m31 -Wall -fvisibility=hidden -Wl,--version-script=../libica.map"
;;
esac
diff --git a/debian/changelog b/debian/changelog
index ca8e2b4..0cb4e28 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+libica (3.2.0-1) unstable; urgency=medium
+
+ * New upstream release LP: #1718379
+ * Add breaks on libopencryptoki0 and openssl-ibmca, whilst ABI is the
+ same, the symbols are now versioned and tagged by upstream.
+
+ -- Dimitri John Ledkov <xnox@ubuntu.com> Wed, 04 Oct 2017 10:33:24 +0100
+
libica (3.1.1-1) unstable; urgency=medium
* New upstream release LP: #1716348
diff --git a/debian/control b/debian/control
index 5ade58c..0a95e11 100644
--- a/debian/control
+++ b/debian/control
@@ -21,6 +21,7 @@ Package: libica3
Architecture: s390 s390x
Multi-Arch: same
Depends: ${shlibs:Depends}, ${misc:Depends}
+Breaks: openssl-ibmca (<< 1.4.0-1ubuntu1~), libopencryptoki0 (<< 3.7.0+dfsg-5~)
Description: hardware cryptography support for IBM System z hardware
libica library provides hardware acceleration for cryptographic
functions and is part of the openCryptoki project.
diff --git a/debian/libica3.symbols b/debian/libica3.symbols
index bf8338b..bc347ed 100644
--- a/debian/libica3.symbols
+++ b/debian/libica3.symbols
@@ -1,72 +1,82 @@
libica.so.3 libica3 #MINVER#
- ICA_DRBG_SHA512@Base 3.0.1
- ica_3des_cbc@Base 3.0.1
- ica_3des_cbc_cs@Base 3.0.1
- ica_3des_cfb@Base 3.0.1
- ica_3des_cmac@Base 3.0.1
- ica_3des_cmac_intermediate@Base 3.0.1
- ica_3des_cmac_last@Base 3.0.1
- ica_3des_ctr@Base 3.0.1
- ica_3des_ctrlist@Base 3.0.1
- ica_3des_decrypt@Base 3.0.1
- ica_3des_ecb@Base 3.0.1
- ica_3des_encrypt@Base 3.0.1
- ica_3des_ofb@Base 3.0.1
- ica_aes_cbc@Base 3.0.1
- ica_aes_cbc_cs@Base 3.0.1
- ica_aes_ccm@Base 3.0.1
- ica_aes_cfb@Base 3.0.1
- ica_aes_cmac@Base 3.0.1
- ica_aes_cmac_intermediate@Base 3.0.1
- ica_aes_cmac_last@Base 3.0.1
- ica_aes_ctr@Base 3.0.1
- ica_aes_ctrlist@Base 3.0.1
- ica_aes_decrypt@Base 3.0.1
- ica_aes_ecb@Base 3.0.1
- ica_aes_encrypt@Base 3.0.1
- ica_aes_gcm@Base 3.0.1
- ica_aes_gcm_initialize@Base 3.0.1
- ica_aes_gcm_intermediate@Base 3.0.1
- ica_aes_gcm_last@Base 3.0.1
- ica_aes_ofb@Base 3.0.1
- ica_aes_xts@Base 3.0.1
- ica_close_adapter@Base 3.0.1
- ica_des_cbc@Base 3.0.1
- ica_des_cbc_cs@Base 3.0.1
- ica_des_cfb@Base 3.0.1
- ica_des_cmac@Base 3.0.1
- ica_des_cmac_intermediate@Base 3.0.1
- ica_des_cmac_last@Base 3.0.1
- ica_des_ctr@Base 3.0.1
- ica_des_ctrlist@Base 3.0.1
- ica_des_decrypt@Base 3.0.1
- ica_des_ecb@Base 3.0.1
- ica_des_encrypt@Base 3.0.1
- ica_des_ofb@Base 3.0.1
- ica_drbg_generate@Base 3.0.1
- ica_drbg_health_test@Base 3.0.1
- ica_drbg_instantiate@Base 3.0.1
- ica_drbg_reseed@Base 3.0.1
- ica_drbg_uninstantiate@Base 3.0.1
- ica_get_functionlist@Base 3.0.1
- ica_get_version@Base 3.0.1
- ica_open_adapter@Base 3.0.1
- ica_random_number_generate@Base 3.0.1
- ica_rsa_crt@Base 3.0.1
- ica_rsa_crt_key_check@Base 3.0.1
- ica_rsa_key_generate_crt@Base 3.0.1
- ica_rsa_key_generate_mod_expo@Base 3.0.1
- ica_rsa_mod_expo@Base 3.0.1
- ica_sha1@Base 3.0.1
- ica_sha224@Base 3.0.1
- ica_sha256@Base 3.0.1
- ica_sha384@Base 3.0.1
- ica_sha3_224@Base 3.1.1-1
- ica_sha3_256@Base 3.1.1-1
- ica_sha3_384@Base 3.1.1-1
- ica_sha3_512@Base 3.1.1-1
- ica_sha512@Base 3.0.1
- ica_shake_128@Base 3.1.1-1
- ica_shake_256@Base 3.1.1-1
- s390_get_functionlist@Base 3.0.1
- s390_initialize_functionlist@Base 3.0.1
+ ICA_DRBG_SHA512@LIBICA_3.0.0 3.2.0-1
+ LIBICA_3.0.0@LIBICA_3.0.0 3.2.0-1
+ LIBICA_3.0.0_FIPS@LIBICA_3.0.0_FIPS 3.2.0-1
+ LIBICA_3.1.0@LIBICA_3.1.0 3.2.0-1
+ LIBICA_3.2.0@LIBICA_3.2.0 3.2.0-1
+ ica_3des_cbc@LIBICA_3.0.0 3.2.0-1
+ ica_3des_cbc_cs@LIBICA_3.0.0 3.2.0-1
+ ica_3des_cfb@LIBICA_3.0.0 3.2.0-1
+ ica_3des_cmac@LIBICA_3.0.0 3.2.0-1
+ ica_3des_cmac_intermediate@LIBICA_3.0.0 3.2.0-1
+ ica_3des_cmac_last@LIBICA_3.0.0 3.2.0-1
+ ica_3des_ctr@LIBICA_3.0.0 3.2.0-1
+ ica_3des_ctrlist@LIBICA_3.0.0 3.2.0-1
+ ica_3des_decrypt@LIBICA_3.0.0 3.2.0-1
+ ica_3des_ecb@LIBICA_3.0.0 3.2.0-1
+ ica_3des_encrypt@LIBICA_3.0.0 3.2.0-1
+ ica_3des_ofb@LIBICA_3.0.0 3.2.0-1
+ ica_aes_cbc@LIBICA_3.0.0 3.2.0-1
+ ica_aes_cbc_cs@LIBICA_3.0.0 3.2.0-1
+ ica_aes_ccm@LIBICA_3.0.0 3.2.0-1
+ ica_aes_cfb@LIBICA_3.0.0 3.2.0-1
+ ica_aes_cmac@LIBICA_3.0.0 3.2.0-1
+ ica_aes_cmac_intermediate@LIBICA_3.0.0 3.2.0-1
+ ica_aes_cmac_last@LIBICA_3.0.0 3.2.0-1
+ ica_aes_ctr@LIBICA_3.0.0 3.2.0-1
+ ica_aes_ctrlist@LIBICA_3.0.0 3.2.0-1
+ ica_aes_decrypt@LIBICA_3.0.0 3.2.0-1
+ ica_aes_ecb@LIBICA_3.0.0 3.2.0-1
+ ica_aes_encrypt@LIBICA_3.0.0 3.2.0-1
+ ica_aes_gcm@LIBICA_3.0.0 3.2.0-1
+ ica_aes_gcm_initialize@LIBICA_3.0.0 3.2.0-1
+ ica_aes_gcm_intermediate@LIBICA_3.0.0 3.2.0-1
+ ica_aes_gcm_kma_ctx_free@LIBICA_3.2.0 3.2.0-1
+ ica_aes_gcm_kma_ctx_new@LIBICA_3.2.0 3.2.0-1
+ ica_aes_gcm_kma_get_tag@LIBICA_3.2.0 3.2.0-1
+ ica_aes_gcm_kma_init@LIBICA_3.2.0 3.2.0-1
+ ica_aes_gcm_kma_update@LIBICA_3.2.0 3.2.0-1
+ ica_aes_gcm_kma_verify_tag@LIBICA_3.2.0 3.2.0-1
+ ica_aes_gcm_last@LIBICA_3.0.0 3.2.0-1
+ ica_aes_ofb@LIBICA_3.0.0 3.2.0-1
+ ica_aes_xts@LIBICA_3.0.0 3.2.0-1
+ ica_close_adapter@LIBICA_3.0.0 3.2.0-1
+ ica_des_cbc@LIBICA_3.0.0 3.2.0-1
+ ica_des_cbc_cs@LIBICA_3.0.0 3.2.0-1
+ ica_des_cfb@LIBICA_3.0.0 3.2.0-1
+ ica_des_cmac@LIBICA_3.0.0 3.2.0-1
+ ica_des_cmac_intermediate@LIBICA_3.0.0 3.2.0-1
+ ica_des_cmac_last@LIBICA_3.0.0 3.2.0-1
+ ica_des_ctr@LIBICA_3.0.0 3.2.0-1
+ ica_des_ctrlist@LIBICA_3.0.0 3.2.0-1
+ ica_des_decrypt@LIBICA_3.0.0 3.2.0-1
+ ica_des_ecb@LIBICA_3.0.0 3.2.0-1
+ ica_des_encrypt@LIBICA_3.0.0 3.2.0-1
+ ica_des_ofb@LIBICA_3.0.0 3.2.0-1
+ ica_drbg_generate@LIBICA_3.0.0 3.2.0-1
+ ica_drbg_health_test@LIBICA_3.0.0 3.2.0-1
+ ica_drbg_instantiate@LIBICA_3.0.0 3.2.0-1
+ ica_drbg_reseed@LIBICA_3.0.0 3.2.0-1
+ ica_drbg_uninstantiate@LIBICA_3.0.0 3.2.0-1
+ ica_get_functionlist@LIBICA_3.0.0 3.2.0-1
+ ica_get_version@LIBICA_3.0.0 3.2.0-1
+ ica_open_adapter@LIBICA_3.0.0 3.2.0-1
+ ica_random_number_generate@LIBICA_3.0.0 3.2.0-1
+ ica_rsa_crt@LIBICA_3.0.0 3.2.0-1
+ ica_rsa_crt_key_check@LIBICA_3.0.0 3.2.0-1
+ ica_rsa_key_generate_crt@LIBICA_3.0.0 3.2.0-1
+ ica_rsa_key_generate_mod_expo@LIBICA_3.0.0 3.2.0-1
+ ica_rsa_mod_expo@LIBICA_3.0.0 3.2.0-1
+ ica_sha1@LIBICA_3.0.0 3.2.0-1
+ ica_sha224@LIBICA_3.0.0 3.2.0-1
+ ica_sha256@LIBICA_3.0.0 3.2.0-1
+ ica_sha384@LIBICA_3.0.0 3.2.0-1
+ ica_sha3_224@LIBICA_3.1.0 3.2.0-1
+ ica_sha3_256@LIBICA_3.1.0 3.2.0-1
+ ica_sha3_384@LIBICA_3.1.0 3.2.0-1
+ ica_sha3_512@LIBICA_3.1.0 3.2.0-1
+ ica_sha512@LIBICA_3.0.0 3.2.0-1
+ ica_shake_128@LIBICA_3.1.0 3.2.0-1
+ ica_shake_256@LIBICA_3.1.0 3.2.0-1
+ s390_get_functionlist@LIBICA_3.0.0 3.2.0-1
+ s390_initialize_functionlist@LIBICA_3.0.0 3.2.0-1
diff --git a/debian/patches/test-suite.patch b/debian/patches/test-suite.patch
index a2c9d53..83d5171 100644
--- a/debian/patches/test-suite.patch
+++ b/debian/patches/test-suite.patch
@@ -7,7 +7,14 @@
#
# Libica test suite
-@@ -13,7 +15,6 @@
+@@ -6,14 +8,11 @@
+
+ verbosity=$1
+
+-out="./suite.out"
+-
+ testcases=(
+ "libica_fips_test"
"libica_get_functionlist $verbosity"
"libica_get_version $verbosity"
@@ -15,7 +22,7 @@
"libica_drbg_test $verbosity"
-@@ -44,10 +45,10 @@
+@@ -45,10 +44,10 @@
"libica_ccm_test $verbosity"
"libica_cmac_test $verbosity"
@@ -30,12 +37,17 @@
"libica_rsa_key_check_test $verbosity"
"libica_rsa_test $verbosity"
-@@ -57,7 +58,7 @@
- echo -ne "" &> $out;
+@@ -63,12 +62,9 @@
+ "libica_sha_test/libica_sha_test $verbosity -sha3 libica_sha_test/sha3_test_vectors/*"
+ )
+
+-echo -ne "" &> $out;
for (( i=1; i <= ${#testcases[@]}; i++ ))
do
- echo -ne "Running libica test suite (writing to "$out") ... "$i"/"${#testcases[@]}"\r";
+- echo "Running '${testcases[i-1]}' ..." >> $out;
- ./${testcases[i-1]} >> $out 2>&1;
+- echo -ne "... done\n\n" >> $out;
+ ./${testcases[i-1]} 2>&1;
done
+./icastats_test 2>&1 || :
diff --git a/include/ica_api.h b/include/ica_api.h
index 61b24f7..094a81b 100644
--- a/include/ica_api.h
+++ b/include/ica_api.h
@@ -856,6 +856,7 @@ unsigned int ica_rsa_crt_key_check(ica_rsa_key_crt_t *rsa_key);
* EINVAL if at least one invalid parameter is given.
* EIO if the operation fails. This should never happen.
*/
+/* XXX next major: remove */
ICA_EXPORT ICA_DEPRECATED
unsigned int ica_des_encrypt(unsigned int mode,
unsigned int data_length,
@@ -891,6 +892,7 @@ unsigned int ica_des_encrypt(unsigned int mode,
* EINVAL if at least one invalid parameter is given.
* EIO if the operation fails. This should never happen.
*/
+/* XXX next major: remove */
ICA_EXPORT ICA_DEPRECATED
unsigned int ica_des_decrypt(unsigned int mode,
unsigned int data_length,
@@ -926,6 +928,7 @@ unsigned int ica_des_decrypt(unsigned int mode,
* EINVAL if at least one invalid parameter is given.
* EIO if the operation fails. This should never happen.
*/
+/* XXX next major: remove */
ICA_EXPORT ICA_DEPRECATED
unsigned int ica_3des_encrypt(unsigned int mode,
unsigned int data_length,
@@ -961,6 +964,7 @@ unsigned int ica_3des_encrypt(unsigned int mode,
* EINVAL if at least one invalid parameter is given.
* EIO if the operation fails. This should never happen.
*/
+/* XXX next major: remove */
ICA_EXPORT ICA_DEPRECATED
unsigned int ica_3des_decrypt(unsigned int mode,
unsigned int data_length,
@@ -998,6 +1002,7 @@ unsigned int ica_3des_decrypt(unsigned int mode,
* EINVAL if at least one invalid parameter is given.
* EIO if the operation fails. This should never happen.
*/
+/* XXX next major: remove */
ICA_EXPORT ICA_DEPRECATED
unsigned int ica_aes_encrypt(unsigned int mode,
unsigned int data_length,
@@ -1036,6 +1041,7 @@ unsigned int ica_aes_encrypt(unsigned int mode,
* EINVAL if at least one invalid parameter is given.
* EIO if the operation fails. This should never happen.
*/
+/* XXX next major: remove */
ICA_EXPORT ICA_DEPRECATED
unsigned int ica_aes_decrypt(unsigned int mode,
unsigned int data_length,
@@ -2812,6 +2818,193 @@ unsigned int ica_aes_gcm_last(unsigned char *icb, unsigned long aad_length,
unsigned char *key, unsigned int key_length,
unsigned char *subkey, unsigned int direction);
+/*******************************************************************************
+ *
+ * New gcm API based on KMA.
+ */
+
+
+typedef struct kma_ctx_t kma_ctx;
+
+/**
+ * Allocate a gcm context. This context is used by ica_aes_gcm_kma_init(),
+ * ica_aes_gcm_kma_update(), ica_aes_gcm_kma_get_tag(), and
+ * ica_aes_gcm_kma_verify_tag(). It must be freed by
+ * ica_aes_gcm_kma_ctx_free() when no longer needed.
+ *
+ * @return Pointer to opaque kma_ctx structure if success.
+ * NULL if no memory could be allocated.
+ */
+ICA_EXPORT
+kma_ctx* ica_aes_gcm_kma_ctx_new();
+
+/**
+ * Initialize the GCM context.
+ *
+ * @param direction
+ * 0 or 1:
+ * 0 when initialized for decryption.
+ * 1 when initialized for encryption.
+ *
+ * @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 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 ctx
+ * Pointer to a previously allocated gcm context. This buffer is internally used
+ * as a working area by all other ica_aes_gcm_kma API functions and must not be
+ * changed by the application. The ctx must be established by calling ica_aes_gcm_ctx_new()
+ * before any call to any other ica_aes_gcm_kma function, and must be freed by calling
+ * ica_aes_gcm_ctx_free() after the last call to any ica_aes_gcm_kma 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
+int ica_aes_gcm_kma_init(unsigned int direction,
+ const unsigned char *iv, unsigned int iv_length,
+ const unsigned char *key, unsigned int key_length,
+ kma_ctx* ctx);
+
+/**
+ * Perform encryption or decryption with authentication, depending on the
+ * direction specified in ica_aes_gcm_kma_init().
+ *
+ * @param in_data
+ * Pointer to a readable buffer of size greater than or equal to data_length bytes.
+ * If direction equals 1 the in_data must contain a payload message of size
+ * data_length that will be encrypted and authenticated.
+ * If direction equals 0 the in_data buffer must contain an encrypted message
+ * that will be decrypted and verified.
+ *
+ * @param out_data
+ * Pointer to a writable buffer of size greater than or equal to data_length bytes.
+ * If direction equals 1 then the encrypted message from in_data will be written to
+ * that buffer.
+ * If direction equals 0 then the decrypted message from in_data will be written to
+ * that buffer.
+ *
+ * @param data_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.
+ *
+ * @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 end_of_aad
+ * 0 or 1:
+ * 0 The application indicates that the current aad is not the last aad chunk. In
+ * this case, the aad_length must be a multiple of the AES block size (16 bytes).
+ * 1 The application indicates that the current aad is a single or last aad chunk,
+ * or the last aad chunk has been provided in an earlier call to ica_aes_gcm_kma.
+ * In this case, aad_length can have any non-negative value.
+ * When both, end_of_aad and end_of_data are specified, the process ends.
+ *
+ * @param end_of_data
+ * 0 or 1:
+ * 0 The application indicates that the current in_data is not the last in_data chunk.
+ * In this case, the data_length must be a multiple of the AES block size (16 bytes).
+ * 1 The application indicates that the current in_data is a single or last in_data
+ * chunk. In this case, aad_length can have any non-negative value. When both, end_of_aad
+ * and end_of_data are specified, the process ends.
+ *
+ * @param ctx
+ * Pointer to gcm context.
+ *
+ * @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
+int ica_aes_gcm_kma_update(const unsigned char *in_data,
+ unsigned char *out_data, unsigned long data_length,
+ const unsigned char *aad, unsigned long aad_length,
+ unsigned int end_of_aad, unsigned int end_of_data,
+ kma_ctx* ctx);
+
+/**
+ * Obtain the calculated authentication tag after an encryption process.
+ *
+ * @param tag
+ * Pointer to a writable buffer to return the calculated authentication tag.
+ *
+ * @param tag_length
+ * Length in bytes of the message authentication code tag. Valid tag lengths
+ * are 4, 8, 12, 13, 14, 15, and 16.
+ *
+ * @param ctx
+ * Pointer to gcm context.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given
+ * EFAULT if direction is 0.
+ */
+ICA_EXPORT
+int ica_aes_gcm_kma_get_tag(unsigned char *tag, unsigned int tag_length,
+ const kma_ctx* ctx);
+
+/**
+ * Verify if the specifed known authentication tag is identical to the
+ * calculated tag after a decryption process.
+ *
+ * @param known_tag
+ * Pointer to a readable buffer containing a known authentication tag.
+ *
+ * @param tag_length
+ * Length in bytes of the message authentication code tag. Valid tag lengths
+ * are 4, 8, 12, 13, 14, 15, and 16.
+ *
+ * @param ctx
+ * Pointer to gcm context.
+ *
+ * @return 0 on success
+ * EINVAL if at least one invalid parameter is given or direction is 1.
+ * EFAULT if the verification of the message authentication code fails.
+ */
+ICA_EXPORT
+int ica_aes_gcm_kma_verify_tag(const unsigned char* known_tag, unsigned int tag_length,
+ const kma_ctx* ctx);
+
+/**
+ * Free gcm context.
+ *
+ * @param ctx
+ * Pointer to gcm context.
+ */
+ICA_EXPORT
+void ica_aes_gcm_kma_ctx_free(kma_ctx* ctx);
+
+
+ /**
+ *
+ * End of new gcm API based on KMA.
+ *
+ ******************************************************************************/
+
/**
* Return libica version information.
* @param version_info
@@ -2825,10 +3018,12 @@ unsigned int ica_aes_gcm_last(unsigned char *icb, unsigned long aad_length,
ICA_EXPORT
unsigned int ica_get_version(libica_version_info *version_info);
-ICA_EXPORT
+/* XXX next major: dont export, move to s390_crypto.h */
+ICA_EXPORT ICA_DEPRECATED
int s390_initialize_functionlist(void);
-ICA_EXPORT
+/* XXX next major: dont export, move to s390_crypto.h */
+ICA_EXPORT ICA_DEPRECATED
int s390_get_functionlist(libica_func_list_element *pmech_list,
unsigned int *pmech_list_len);
diff --git a/libica.map b/libica.map
new file mode 100644
index 0000000..f3e1ff8
--- /dev/null
+++ b/libica.map
@@ -0,0 +1,109 @@
+LIBICA_3.0.0 {
+ global:
+ _fini;
+ _init;
+
+ s390_initialize_functionlist;
+ s390_get_functionlist;
+ ica_get_functionlist;
+ ica_get_version;
+
+ ica_random_number_generate;
+
+ ica_des_encrypt;
+ ica_des_decrypt;
+ ica_des_ecb;
+ ica_des_cbc;
+ ica_des_cbc_cs;
+ ica_des_ctr;
+ ica_des_ctrlist;
+ ica_des_cfb;
+ ica_des_ofb;
+ ica_des_cmac;
+ ica_des_cmac_intermediate;
+ ica_des_cmac_last;
+
+ ica_3des_encrypt;
+ ica_3des_decrypt;
+ ica_3des_ecb;
+ ica_3des_cbc;
+ ica_3des_cbc_cs;
+ ica_3des_ctr;
+ ica_3des_ctrlist;
+ ica_3des_cfb;
+ ica_3des_ofb;
+ ica_3des_cmac;
+ ica_3des_cmac_intermediate;
+ ica_3des_cmac_last;
+
+ ica_aes_encrypt;
+ ica_aes_decrypt;
+ ica_aes_ecb;
+ ica_aes_cbc;
+ ica_aes_cbc_cs;
+ ica_aes_ctr;
+ ica_aes_ctrlist;
+ ica_aes_cfb;
+ ica_aes_ofb;
+ ica_aes_xts;
+ ica_aes_ccm;
+ ica_aes_gcm;
+ ica_aes_gcm_initialize;
+ ica_aes_gcm_intermediate;
+ ica_aes_gcm_last;
+ ica_aes_cmac;
+ ica_aes_cmac_intermediate;
+ ica_aes_cmac_last;
+
+ ica_sha1;
+ ica_sha224;
+ ica_sha256;
+ ica_sha384;
+ ica_sha512;
+
+ ica_open_adapter;
+ ica_close_adapter;
+
+ ica_rsa_key_generate_mod_expo;
+ ica_rsa_key_generate_crt;
+ ica_rsa_mod_expo;
+ ica_rsa_crt;
+ ica_rsa_crt_key_check;
+
+ ICA_DRBG_SHA512;
+ ica_drbg_instantiate;
+ ica_drbg_generate;
+ ica_drbg_reseed;
+ ica_drbg_uninstantiate;
+ ica_drbg_health_test;
+ local: *;
+};
+
+LIBICA_3.0.0_FIPS {
+ global:
+ ica_fips_powerup_tests;
+ ica_fips_status;
+} LIBICA_3.0.0;
+
+LIBICA_3.1.0 {
+ global:
+ ica_sha3_224;
+ ica_sha3_256;
+ ica_sha3_384;
+ ica_sha3_512;
+
+ ica_shake_128;
+ ica_shake_256;
+ local: *;
+} LIBICA_3.0.0;
+
+LIBICA_3.2.0 {
+ global:
+ ica_aes_gcm_kma_ctx_new;
+ ica_aes_gcm_kma_init;
+ ica_aes_gcm_kma_update;
+ ica_aes_gcm_kma_get_tag;
+ ica_aes_gcm_kma_verify_tag;
+ ica_aes_gcm_kma_ctx_free;
+ local: *;
+} LIBICA_3.1.0;
diff --git a/libica.spec b/libica.spec
index 08f1804..e00977d 100644
--- a/libica.spec
+++ b/libica.spec
@@ -1,5 +1,5 @@
Name: libica
-Version: 3.1.1
+Version: 3.2.0
Release: 1%{?dist}
Summary: Interface library to the ICA device driver
@@ -62,6 +62,8 @@ rm -rf $RPM_BUILD_ROOT
%{_includedir}/ica_api.h
%changelog
+* Tue Sep 19 2017 Patrick Steuer <steuer@linux.vnet.ibm.com>
+- Version v3.2.0
* Fri Sep 08 2017 Patrick Steuer <steuer@linux.vnet.ibm.com>
- Version v3.1.1
* Wed Jun 27 2017 Patrick Steuer <steuer@linux.vnet.ibm.com>
diff --git a/src/Makefile.am b/src/Makefile.am
index cabf221..e86fc65 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2,7 +2,7 @@ INCLUDES = -I ./include -I ../include
lib_LTLIBRARIES = libica.la
-libica_la_LDFLAGS = -version-number 3:1:1 $(PACKAGE_VERSION) -lrt -lcrypto
+libica_la_LDFLAGS = -version-number 3:2:0 $(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 \
diff --git a/src/ica_api.c b/src/ica_api.c
index f9cdb81..e349413 100644
--- a/src/ica_api.c
+++ b/src/ica_api.c
@@ -2150,6 +2150,169 @@ unsigned int ica_aes_gcm_last( unsigned char *icb,
return 0;
}
+/*************************************************************************************
+ *
+ * GCM(2) API
+ */
+
+kma_ctx* ica_aes_gcm_kma_ctx_new(void)
+{
+ kma_ctx* ctx = malloc(sizeof(kma_ctx));
+ if (!ctx)
+ return NULL;
+
+ memset(ctx, 0, sizeof(kma_ctx));
+
+ return ctx;
+}
+
+int ica_aes_gcm_kma_init(unsigned int direction,
+ const unsigned char *iv, unsigned int iv_length,
+ const unsigned char *key, unsigned int key_length,
+ kma_ctx* ctx)
+{
+ int rc = 0;
+ unsigned long function_code = aes_directed_fc(key_length, direction);
+
+ /* Check for obvious errors */
+ if (!ctx || !key || iv_length == 0 || !is_valid_aes_key_length(key_length) ||
+ !is_valid_direction(direction)) {
+ return EINVAL;
+ }
+
+ memset(ctx, 0, sizeof(kma_ctx));
+ ctx->version = 0x00;
+ ctx->direction = direction;
+ ctx->key_length = key_length;
+ ctx->iv = (unsigned char*)iv;
+ ctx->iv_length = iv_length;
+ memcpy(&(ctx->key), key, key_length);
+
+ /* Calculate subkey_h and j0 depending on iv_length */
+ if (*s390_kma_functions[function_code].enabled && iv_length == GCM_RECOMMENDED_IV_LENGTH) {
+ /* let KMA provide the subkey_h, j0 = iv || 00000001 */
+ memcpy(&(ctx->j0), iv, iv_length);
+ ctx->cv = 1;
+ unsigned int* cv = (unsigned int*)&(ctx->j0[GCM_RECOMMENDED_IV_LENGTH]);
+ *cv = 1;
+ } else {
+ /* Calculate subkey H and initial counter, based on iv */
+ rc = s390_aes_ecb(UNDIRECTED_FC(function_code),
+ AES_BLOCK_SIZE, zero_block,
+ (unsigned char*)key, (unsigned char*)&(ctx->subkey_h));
+ if (rc)
+ return rc;
+ __compute_j0(iv, iv_length, (const unsigned char*)&(ctx->subkey_h),
+ (unsigned char*)&(ctx->j0));
+ unsigned int *cv = (unsigned int*)&(ctx->j0[GCM_RECOMMENDED_IV_LENGTH]);
+ ctx->cv = *cv;
+ ctx->subkey_provided = 1;
+ }
+
+ return rc;
+}
+
+int ica_aes_gcm_kma_update(const unsigned char *in_data,
+ unsigned char *out_data, unsigned long data_length,
+ const unsigned char *aad, unsigned long aad_length,
+ unsigned int end_of_aad, unsigned int end_of_data,
+ kma_ctx* ctx)
+{
+ unsigned int function_code = aes_directed_fc(ctx->key_length, ctx->direction);
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (data_length > 0 && (!in_data || !out_data))
+ return EFAULT;
+
+ if (!(*s390_kma_functions[function_code].enabled)) {
+
+ if (end_of_aad && end_of_data && !ctx->intermediate) {
+ ctx->done = 1;
+ return s390_aes_gcm_simulate_kma_full(in_data, out_data, data_length,
+ aad, aad_length, ctx);
+ } else {
+ ctx->intermediate = 1;
+ return s390_aes_gcm_simulate_kma_intermediate(in_data, out_data, data_length,
+ aad, aad_length, ctx);
+ }
+
+ } else {
+
+ return s390_aes_gcm_kma(in_data, out_data, data_length,
+ aad, aad_length, end_of_aad, end_of_data, ctx);
+ }
+}
+
+int ica_aes_gcm_kma_get_tag(unsigned char *tag, unsigned int tag_length, const kma_ctx* ctx)
+{
+ int rc=0;
+ unsigned int function_code = aes_directed_fc(ctx->key_length, ctx->direction);
+
+ if (!ctx || !tag || !is_valid_tag_length(tag_length))
+ return EINVAL;
+
+ if (ctx->direction == ICA_DECRYPT)
+ return EFAULT;
+
+ if (!(*s390_kma_functions[function_code].enabled) && !ctx->done) {
+ rc = s390_gcm_last(function_code, (unsigned char*)ctx->j0,
+ ctx->total_aad_length, ctx->total_input_length,
+ (unsigned char*)ctx->tag, AES_BLOCK_SIZE,
+ (unsigned char*)ctx->key, (unsigned char*)ctx->subkey_h);
+ if (rc)
+ return rc;
+ }
+
+ memcpy(tag, ctx->tag, tag_length);
+
+ return 0;
+}
+
+int ica_aes_gcm_kma_verify_tag(const unsigned char* known_tag, unsigned int tag_length, const kma_ctx* ctx)
+{
+ int rc;
+ unsigned int function_code = aes_directed_fc(ctx->key_length, ctx->direction);
+
+ if (!ctx || !known_tag || !is_valid_tag_length(tag_length))
+ return EINVAL;
+
+ if (ctx->direction == ICA_ENCRYPT)
+ return EFAULT;
+
+ if (!(*s390_kma_functions[function_code].enabled) && !ctx->done) {
+ rc = s390_gcm_last(function_code, (unsigned char*)ctx->j0,
+ ctx->total_aad_length, ctx->total_input_length,
+ (unsigned char*)ctx->tag, AES_BLOCK_SIZE,
+ (unsigned char*)ctx->key, (unsigned char*)ctx->subkey_h);
+ if (rc)
+ return rc;
+ }
+
+ if (CRYPTO_memcmp(ctx->tag, known_tag, tag_length) != 0)
+ return EFAULT;
+
+ return 0;
+}
+
+void ica_aes_gcm_kma_ctx_free(kma_ctx* ctx)
+{
+ if (!ctx)
+ return;
+
+ OPENSSL_cleanse((void *)ctx, sizeof(kma_ctx));
+
+ free(ctx);
+}
+
+/**
+ * End of GCM(2) API
+ *
+ ***************************************************************************************/
+
unsigned int ica_get_version(libica_version_info *version_info)
{
#ifdef VERSION
diff --git a/src/include/s390_aes.h b/src/include/s390_aes.h
index 610aeb1..477f975 100644
--- a/src/include/s390_aes.h
+++ b/src/include/s390_aes.h
@@ -76,10 +76,10 @@ static inline int s390_aes_gcm_hw(unsigned int function_code,
if (ctr) {
memcpy(&parm_block.cv, &ctr[GCM_RECOMMENDED_IV_LENGTH], sizeof(int));
- memcpy(&parm_block.j0, ctr, GCM_RECOMMENDED_IV_LENGTH);
- unsigned int* cv;
- cv = (unsigned int*)&(parm_block.j0[GCM_RECOMMENDED_IV_LENGTH]);
- *cv = 1;
+ memcpy(&parm_block.j0, ctr, AES_BLOCK_SIZE); //GCM_RECOMMENDED_IV_LENGTH);
+ //unsigned int* cv;
+ //cv = (unsigned int*)&(parm_block.j0[GCM_RECOMMENDED_IV_LENGTH]);
+ //*cv = 1;
}
if (j0)
diff --git a/src/include/s390_gcm.h b/src/include/s390_gcm.h
index 3236d46..4f1d853 100644
--- a/src/include/s390_gcm.h
+++ b/src/include/s390_gcm.h
@@ -43,6 +43,32 @@ struct pad_meta {
uint64_t length_b;
} __attribute__((packed));
+/**
+ * GCM context struct
+ */
+struct kma_ctx_t {
+ unsigned char reserved[12];
+ uint32_t cv;
+ ica_aes_vector_t tag;
+ ica_aes_vector_t subkey_h;
+ uint64_t total_aad_length;
+ uint64_t total_input_length;
+ ica_aes_vector_t j0;
+ ica_aes_key_len_256_t key;
+ // Above this line: KMA parmblock, never change!
+ uint32_t version; /* 0x00 */
+ uint32_t direction;
+ uint32_t key_length;
+ uint32_t subkey_provided;
+ // Below this line: KMA simulation via MSA 4
+ unsigned char* iv;
+ uint32_t iv_length;
+ ica_aes_vector_t ucb;
+ uint32_t done;
+ uint32_t intermediate;
+ uint32_t first_time;
+} __attribute__((packed));
+
static inline int s390_ghash_hw(unsigned int fc,
const unsigned char *in_data,
unsigned long data_length,
@@ -591,4 +617,140 @@ static inline int s390_gcm_last(unsigned int function_code, unsigned char *icb,
tag, tag_length, 1, 1);
}
}
+
+static inline int is_valid_aes_key_length(unsigned int key_length)
+{
+ switch (key_length) {
+ case 16:
+ case 24:
+ case 32:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static inline int is_valid_direction(unsigned int direction)
+{
+ switch (direction) {
+ case ICA_ENCRYPT:
+ case ICA_DECRYPT:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static inline int is_valid_tag_length(unsigned int tag_length)
+{
+ switch (tag_length) {
+ case 4:
+ case 8:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ case 16:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static inline int s390_aes_gcm_simulate_kma_intermediate(const unsigned char *in_data,
+ unsigned char *out_data, unsigned long data_length,
+ const unsigned char *aad, unsigned long aad_length,
+ kma_ctx* ctx)
+{
+ int rc;
+ unsigned int function_code = aes_directed_fc(ctx->key_length, ctx->direction);
+
+ /* Add one to first counter value for MSA 4 code path. */
+ if (!ctx->first_time) {
+ memcpy(&(ctx->ucb), ctx->j0, AES_BLOCK_SIZE);
+ inc_ctr(ctx->ucb);
+ ctx->first_time = 1;
+ }
+
+ if (ctx->direction == ICA_ENCRYPT) {
+ rc = s390_gcm_intermediate(function_code, (unsigned char*)in_data, data_length, out_data,
+ (unsigned char*)&(ctx->ucb), (unsigned char*)aad, aad_length,
+ ctx->tag, AES_BLOCK_SIZE, (unsigned char*)ctx->key, (unsigned char*)ctx->subkey_h);
+ } else {
+ rc = s390_gcm_intermediate(function_code, out_data, data_length, (unsigned char*)in_data,
+ (unsigned char*)&(ctx->ucb), (unsigned char*)aad, aad_length,
+ ctx->tag, AES_BLOCK_SIZE, (unsigned char*)ctx->key, (unsigned char*)ctx->subkey_h);
+ }
+
+ if (rc)
+ return rc;
+
+ ctx->total_aad_length += aad_length;
+ ctx->total_input_length += data_length;
+
+ return 0;
+}
+
+static inline int s390_aes_gcm_simulate_kma_full(const unsigned char *in_data,
+ unsigned char *out_data, unsigned long data_length,
+ const unsigned char *aad, unsigned long aad_length,
+ kma_ctx* ctx)
+{
+ unsigned int function_code = aes_directed_fc(ctx->key_length, ctx->direction);
+
+ if (ctx->direction == ICA_ENCRYPT) {
+ return s390_gcm(function_code, (unsigned char*)in_data, data_length, out_data,
+ ctx->iv, ctx->iv_length, aad, aad_length,
+ ctx->tag, AES_BLOCK_SIZE, ctx->key);
+ } else {
+ return s390_gcm(function_code, out_data, data_length, (unsigned char*)in_data,
+ ctx->iv, ctx->iv_length, aad, aad_length,
+ ctx->tag, AES_BLOCK_SIZE, ctx->key);
+ }
+}
+
+static inline int s390_aes_gcm_kma(const unsigned char *in_data,
+ unsigned char *out_data, unsigned long data_length,
+ const unsigned char *aad, unsigned long aad_length,
+ unsigned int end_of_aad, unsigned int end_of_data,
+ kma_ctx* ctx)
+{
+ unsigned int function_code = aes_directed_fc(ctx->key_length, ctx->direction);
+ unsigned int hw_fc = 0;
+ int rc;
+
+ /* Set hardware function code */
+ if (*s390_kma_functions[function_code].enabled) {
+ hw_fc = s390_kma_functions[function_code].hw_fc;
+ if (ctx->subkey_provided)
+ hw_fc = hw_fc | HS_FLAG;
+ if (end_of_aad)
+ hw_fc = hw_fc | LAAD_FLAG;
+ if (end_of_data)
+ hw_fc = hw_fc | LPC_FLAG;
+ } else {
+ return EPERM;
+ }
+
+ if (!aad)
+ aad_length = 0;
+
+ if (!in_data || !out_data)
+ data_length = 0;
+
+ /* Actual lengths needed by KMA */
+ ctx->total_aad_length += aad_length*8;
+ ctx->total_input_length += data_length*8;
+
+ /* Call KMA */
+ rc = s390_kma(hw_fc, ctx,
+ out_data, in_data, data_length,
+ aad, aad_length);
+
+ if (rc >= 0) {
+ ctx->subkey_provided = 1;
+ return 0;
+ } else
+ return EIO;
+}
#endif
diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
index a140cc1..1126ded 100644
--- a/src/tests/Makefile.am
+++ b/src/tests/Makefile.am
@@ -23,7 +23,7 @@ TARGETS = icastats_test \
libica_shake_128_test libica_shake_256_test \
libica_rsa_test libica_rsa_key_check_test \
libica_rng_test libica_keygen_test \
- libica_cmac_test \
+ libica_cmac_test libica_aes_gcm_kma_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 \
diff --git a/src/tests/gcm_kats.h b/src/tests/gcm_kats.h
new file mode 100644
index 0000000..1fea8c0
--- /dev/null
+++ b/src/tests/gcm_kats.h
@@ -0,0 +1,553 @@
+/*
+ * GCM test vectors.
+ */
+#ifndef GCM_KATS_H
+#define GCM_KATS_H
+
+#include <stddef.h>
+#include <string.h>
+
+#define AES_BLOCK_SIZE 16
+#define MAX_ARRAY_SIZE 128
+#define NUM_GCM_TESTS (sizeof(gcm_kats)/sizeof(gcm_kat_t))
+
+typedef struct {
+ unsigned char key[MAX_ARRAY_SIZE];
+ unsigned int keylen;
+ unsigned char data[MAX_ARRAY_SIZE];
+ unsigned int datalen;
+ unsigned char aad[MAX_ARRAY_SIZE];
+ unsigned int aadlen;
+ unsigned char iv[MAX_ARRAY_SIZE];
+ unsigned int ivlen;
+ unsigned char tag[MAX_ARRAY_SIZE];
+ unsigned int taglen;
+ unsigned char result[MAX_ARRAY_SIZE];
+ unsigned int chunks[MAX_ARRAY_SIZE];
+ unsigned int num_chunks;
+} gcm_kat_t;
+
+static gcm_kat_t gcm_kats[] = {
+ /* GCM data - 0 */
+ {{0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c,0x6d,0x6a,0x8f,0x94,0x67,0x30,0x83,0x08,},
+ .keylen = 16,
+ {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,},
+ .datalen = 64,
+ {},
+ .aadlen = 0,
+ {0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad,0xde,0xca,0xf8,0x88,},
+ .ivlen = 12,
+ {0x4d,0x5c,0x2a,0xf3,0x27,0xcd,0x64,0xa6,0x2c,0xf3,0x5a,0xbd,0x2b,0xa6,0xfa,0xb4,},
+ .taglen = 16,
+ {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,},
+ {16,16,16,16},
+ 4,
+ },
+ /* GCM data - 1 */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
+ .keylen = 16,
+ {},
+ .datalen = 0,
+ {},
+ .aadlen = 0,
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
+ .ivlen = 12,
+ {0x58,0xe2,0xfc,0xce,0xfa,0x7e,0x30,0x61,0x36,0x7f,0x1d,0x57,0xa4,0xe7,0x45,0x5a},
+ .taglen = 16,
+ {},
+ {},
+ .num_chunks = 0,
+ },
+ /* GCM data - 2 */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
+ .keylen = 16,
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
+ .datalen = 16,
+ {},
+ .aadlen = 0,
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
+ .ivlen = 12,
+ {0xab,0x6e,0x47,0xd4,0x2c,0xec,0x13,0xbd,0xf5,0x3a,0x67,0xb2,0x12,0x57,0xbd,0xdf,},
+ .taglen = 16,
+ {0x03,0x88,0xda,0xce,0x60,0xb6,0xa3,0x92,0xf3,0x28,0xc2,0xb9,0x71,0xb2,0xfe,0x78,},
+ {16},
+ .num_chunks = 1,
+ },
+ /* GCM data - 3 */
+ {{0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c,0x6d,0x6a,0x8f,0x94,0x67,0x30,0x83,0x08,},
+ .keylen = 16,
+ {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,},
+ .datalen = 60,
+ {0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,
+ 0xab,0xad,0xda,0xd2,},
+ .aadlen = 20,
+ {0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad,0xde,0xca,0xf8,0x88,},
+ .ivlen = 12,
+ {0x5b,0xc9,0x4f,0xbc,0x32,0x21,0xa5,0xdb,0x94,0xfa,0xe9,0x5a,0xe7,0x12,0x1a,0x47,},
+ .taglen = 16,
+ {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,},
+ {16,16,16,12},
+ .num_chunks = 4,
+ },
+ /* GCM data - 4 - AES 192 - Test Case 7 */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
+ .keylen = 24,
+ {},
+ .datalen = 0,
+ {},
+ .aadlen = 0,
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
+ .ivlen = 12,
+ {0xcd,0x33,0xb2,0x8a,0xc7,0x73,0xf7,0x4b,0xa0,0x0e,0xd1,0xf3,0x12,0x57,0x24,0x35,},
+ .taglen = 16,
+ {},
+ {},
+ .num_chunks = 0,
+ },
+ /* GCM data - 5 - AES 192 - Test Case 8 */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
+ .keylen = 24,
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
+ .datalen = 16,
+ {},
+ .aadlen = 0,
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
+ .ivlen = 12,
+ {0x2f,0xf5,0x8d,0x80,0x03,0x39,0x27,0xab,0x8e,0xf4,0xd4,0x58,0x75,0x14,0xf0,0xfb,},
+ .taglen = 16,
+ {0x98,0xe7,0x24,0x7c,0x07,0xf0,0xfe,0x41,0x1c,0x26,0x7e,0x43,0x84,0xb0,0xf6,0x00,},
+ {16},
+ .num_chunks = 1,
+ },
+ /* GCM data - 6 - AES 192 - Test Case 9 */
+ {{0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c,0x6d,0x6a,0x8f,0x94,0x67,0x30,0x83,0x08,
+ 0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c,},
+ .keylen = 24,
+ {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,},
+ .datalen = 64,
+ {},
+ .aadlen = 0,
+ {0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad,0xde,0xca,0xf8,0x88,},
+ .ivlen = 12,
+ {0x99,0x24,0xa7,0xc8,0x58,0x73,0x36,0xbf,0xb1,0x18,0x02,0x4d,0xb8,0x67,0x4a,0x14,},
+ .taglen = 16,
+ {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,},
+ {16,16,16,16},
+ .num_chunks = 4,
+ },
+ /* GCM data - 7 - AES 192 - Test Case 10 */
+ {{0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c,0x6d,0x6a,0x8f,0x94,0x67,0x30,0x83,0x08,
+ 0xfe,0xff,0xe9,0x92,0x86,0x65,0x73,0x1c,},
+ .keylen = 24,
+ {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,},
+ .datalen = 60,
+ {0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,
+ 0xab,0xad,0xda,0xd2,},
+ .aadlen = 20,
+ {0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad,0xde,0xca,0xf8,0x88,},
+ .ivlen = 12,
+ {0x25,0x19,0x49,0x8e,0x80,0xf1,0x47,0x8f,0x37,0xba,0x55,0xbd,0x6d,0x27,0x61,0x8c,},
+ .taglen = 16,
+ {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,},
+ {16,16,16,12},
+ .num_chunks = 4,
+ },
+ /* GCM data - 8 - AES 256 - Test Case 13 */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
+ .keylen = 32,
+ {},
+ .datalen = 0,
+ {},
+ .aadlen = 0,
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
+ .ivlen = 12,
+ {0x53,0x0f,0x8a,0xfb,0xc7,0x45,0x36,0xb9,0xa9,0x63,0xb4,0xf1,0xc4,0xcb,0x73,0x8b,},
+ .taglen = 16,
+ {},
+ {},
+ .num_chunks = 0,
+ },
+ /* GCM data - 9 - AES 256 - Test Case 14 */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
+ .keylen = 32,
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
+ .datalen = 16,
+ {},
+ .aadlen = 0,
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
+ .ivlen = 12,
+ {0xd0,0xd1,0xc8,0xa7,0x99,0x99,0x6b,0xf0,0x26,0x5b,0x98,0xb5,0xd4,0x8a,0xb9,0x19,},
+ .taglen = 16,
+ {0xce,0xa7,0x40,0x3d,0x4d,0x60,0x6b,0x6e,0x07,0x4e,0xc5,0xd3,0xba,0xf3,0x9d,0x18,},
+ {16},
+ .num_chunks = 1,
+ },
+ /* GCM data - 10 - AES 256 - Test Case 15 */
+ {{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,},
+ .keylen = 32,
+ {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,},
+ .datalen = 64,
+ {},
+ .aadlen = 0,
+ {0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad,0xde,0xca,0xf8,0x88,},
+ .ivlen = 12,
+ {0xb0,0x94,0xda,0xc5,0xd9,0x34,0x71,0xbd,0xec,0x1a,0x50,0x22,0x70,0xe3,0xcc,0x6c,},
+ .taglen = 16,
+ {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,},
+ {16,16,16,16},
+ .num_chunks = 4,
+ },
+ /* GCM data - 11 */
+ {{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,},
+ .keylen = 32,
+ {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,},
+ .datalen = 60,
+ {0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,
+ 0xab,0xad,0xda,0xd2,},
+ .aadlen = 20,
+ {0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad,0xde,0xca,0xf8,0x88,},
+ .ivlen = 12,
+ {0x76,0xfc,0x6e,0xce,0x0f,0x4e,0x17,0x68,0xcd,0xdf,0x88,0x53,0xbb,0x2d,0x55,0x1b,},
+ .taglen = 16,
+ {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,},
+ {16,16,16,12},
+ .num_chunks = 4,
+ },
+ /**
+ * GCM data - 12
+ *
+ * [Keylen = 128]
+ * [IVlen = 96]
+ * [PTlen = 0]
+ * [AADlen = 0]
+ * [Taglen = 128]
+ */
+ {{0x11,0x75,0x4c,0xd7,0x2a,0xec,0x30,0x9b,0xf5,0x2f,0x76,0x87,0x21,0x2e,0x89,0x57,},
+ .keylen = 16,
+ {},
+ .datalen = 0,
+ {},
+ .aadlen = 0,
+ {0x3c,0x81,0x9d,0x9a,0x9b,0xed,0x08,0x76,0x15,0x03,0x0b,0x65,},
+ .ivlen = 12,
+ {0x25,0x03,0x27,0xc6,0x74,0xaa,0xf4,0x77,0xae,0xf2,0x67,0x57,0x48,0xcf,0x69,0x71},
+ .taglen = 16,
+ {},
+ {},
+ .num_chunks = 0,
+ },
+ /**
+ * GCM data - 13
+ *
+ * [Keylen = 128]
+ * [IVlen = 96]
+ * [PTlen = 0]
+ * [AADlen = 0]
+ * [Taglen = 120]
+ */
+ {{0x27,0x2f,0x16,0xed,0xb8,0x1a,0x7a,0xbb,0xea,0x88,0x73,0x57,0xa5,0x8c,0x19,0x17,},
+ .keylen = 16,
+ {},
+ .datalen = 0,
+ {},
+ .aadlen = 0,
+ {0x79,0x4e,0xc5,0x88,0x17,0x6c,0x70,0x3d,0x3d,0x2a,0x7a,0x07,},
+ .ivlen = 12,
+ {0xb6,0xe6,0xf1,0x97,0x16,0x8f,0x50,0x49,0xae,0xda,0x32,0xda,0xfb,0xda,0xeb,},
+ .taglen = 15,
+ {},
+ {},
+ .num_chunks = 0,
+ },
+ /**
+ * GCM data - 14
+ *
+ * [Keylen = 128]
+ * [IVlen = 96]
+ * [PTlen = 0]
+ * [AADlen = 0]
+ * [Taglen = 32]
+ */
+ {{0x88,0x4e,0xb6,0x36,0xa2,0x77,0xec,0xc4,0xc3,0x4a,0x43,0xcc,0x59,0x07,0x5c,0xa9,},
+ .keylen = 16,
+ {},
+ .datalen = 0,
+ {},
+ .aadlen = 0,
+ {0x44,0xe8,0x01,0x9f,0x40,0x26,0xff,0x0c,0x1f,0x8b,0x3e,0x2f,},
+ .ivlen = 12,
+ {0x05,0x4d,0x06,0x3f,},
+ .taglen = 4,
+ {},
+ {},
+ .num_chunks = 0,
+ },
+ /**
+ * GCM data - 15
+ *
+ * [Keylen = 128]
+ * [IVlen = 1024]
+ * [PTlen = 104]
+ * [AADlen = 128]
+ * [Taglen = 64]
+ */
+ {{0x7e,0x95,0x06,0x6b,0x60,0x09,0x3f,0x66,0x17,0x54,0x93,0xd1,0x41,0x35,0x9d,0xbd,},
+ .keylen = 16,
+ {0x5e,0xa1,0x31,0x2e,0x26,0xc9,0x5b,0xcf,0x00,0x5b,0x61,0x74,0x23,},
+ .datalen = 13,
+ {0x66,0x0c,0x28,0xa4,0x60,0xfa,0x93,0xe1,0x12,0xaa,0xc6,0xce,0xb5,0x4a,0x80,0xa2,},
+ .aadlen = 16,
+ {0x40,0x57,0xda,0x04,0xc7,0x73,0x36,0x1c,0x33,0xbe,0x7f,0x10,0xd7,0xba,0x70,0x8b,
+ 0x22,0x78,0x50,0x3f,0xd7,0xb0,0xa6,0xdd,0x13,0x0a,0x96,0x29,0x52,0xb8,0x88,0x7d,
+ 0x6a,0x41,0x20,0x74,0xc1,0x57,0x2e,0xb0,0xc5,0x3e,0xdf,0x81,0xee,0x70,0x1c,0xab,
+ 0xc6,0x05,0x52,0xac,0xeb,0x0f,0x66,0x26,0x97,0xd3,0xb2,0xac,0xc0,0x37,0xea,0xb9,
+ 0x44,0x52,0x42,0xbf,0xf4,0x49,0x66,0x06,0xb8,0xcf,0xbf,0x2d,0x3c,0x72,0x87,0x4b,
+ 0x76,0x9b,0x9b,0x63,0x23,0x4b,0x64,0xd4,0x29,0x82,0x9f,0x46,0x73,0x05,0xac,0xab,
+ 0x4a,0xe8,0xd4,0x5c,0x8f,0x7c,0x4f,0x5b,0x57,0x71,0xcb,0x7c,0xbd,0xcc,0xc8,0xc7,
+ 0x27,0x3a,0x4a,0x20,0x38,0x46,0x4f,0xad,0xfd,0xf7,0x33,0xb6,0x31,0x17,0x90,0x17,},
+ .ivlen = 128,
+ {0x4f,0xd9,0x46,0x71,0xab,0xde,0x61,0x6e,},
+ .taglen = 8,
+ {0x55,0x17,0xfb,0xa3,0x76,0xab,0x16,0xc7,0xe2,0xad,0x16,0xc1,0xe2,},
+ {13},
+ .num_chunks = 1,
+ },
+ /**
+ * GCM data - 16
+ *
+ * [Keylen = 128]
+ * [IVlen = 8]
+ * [PTlen = 0]
+ * [AADlen = 160]
+ * [Taglen = 104]
+ */
+ {{0xf8,0x41,0x3d,0x62,0x4e,0x64,0xc2,0x08,0x1b,0xc7,0xc2,0x42,0x37,0xed,0x8a,0x8d,},
+ .keylen = 16,
+ {},
+ .datalen = 0,
+ {0x9a,0x24,0xf2,0xb8,0xed,0xe8,0x25,0xe7,0xd3,0x13,0xd3,0x92,0x3d,0x21,0x71,0x34,
+ 0xe2,0x04,0x64,0x8e,},
+ .aadlen = 20,
+ {0x53,},
+ .ivlen = 1,
+ {0xbf,0x0d,0x41,0x82,0xf1,0x2e,0x33,0x99,0x9e,0x8f,0x0e,0xf4,0xd4,},
+ .taglen = 13,
+ {},
+ {},
+ .num_chunks = 0,
+ },
+ /**
+ * GCM data - 17
+ *
+ * [Keylen = 128]
+ * [IVlen = 8]
+ * [PTlen = 104]
+ * [AADlen = 0]
+ * [Taglen = 64]
+ */
+ {{0xc8,0xed,0x6f,0x0c,0x45,0xa9,0xcb,0xff,0x8d,0x44,0x76,0x02,0xa0,0x7c,0x53,0xcb,},
+ .keylen = 16,
+ {0xc0,0xaf,0xd5,0xca,0xe5,0x5d,0xf1,0xd3,0x4c,0x5f,0xcc,0xb2,0xa4,},
+ .datalen = 13,
+ {},
+ .aadlen = 0,
+ {0xb5,},
+ .ivlen = 1,
+ {0x9b,0xc7,0x8d,0x50,0x93,0x7a,0x38,0x57,},
+ .taglen = 8,
+ {0xf2,0x2c,0x87,0x72,0xaf,0x42,0x17,0x9e,0xc1,0xb3,0xfe,0x08,0x69,},
+ {13},
+ .num_chunks = 1,
+ },
+ /**
+ * GCM data - 18
+ *
+ * [Keylen = 128]
+ * [IVlen = 1024]
+ * [PTlen = 128]
+ * [AADlen = 720]
+ * [Taglen = 104]
+ */
+ {{0x67,0x8d,0xb3,0xb4,0x19,0xa5,0xfd,0xb0,0x9d,0x24,0x2d,0x10,0x6c,0xdb,0xfd,0xd8,},
+ .keylen = 16,
+ {0x94,0xca,0xf0,0x0f,0xa4,0xcd,0xba,0x64,0xc0,0x3f,0x15,0x8f,0xa2,0x5a,0x64,0xc7,},
+ .datalen = 16,
+ {0x62,0xfa,0x1b,0xe1,0x03,0x69,0xe1,0x96,0xe4,0x09,0xd0,0x79,0xce,0x92,0xd0,0x21,
+ 0x46,0x76,0xaf,0x43,0x43,0x08,0xce,0x73,0x1c,0x98,0xcc,0xaa,0x08,0x1d,0x4d,0x46,
+ 0x0a,0x78,0x5c,0xcb,0xed,0xfa,0x5e,0x90,0x48,0x21,0x4f,0x2a,0x49,0x0d,0x5d,0x62,
+ 0x49,0x50,0xc2,0xf8,0x76,0x85,0x8d,0xe3,0x44,0xbe,0xce,0x62,0x91,0x18,0x48,0x25,
+ 0x04,0x02,0xa5,0xf8,0x54,0xfc,0xe8,0x9c,0x47,0x39,0x79,0x39,0xc3,0xac,0x82,0xe3,
+ 0x5b,0xd7,0x20,0xc6,0x7a,0xa8,0x65,0x9f,0x54,0x63,},
+ .aadlen = 90,
+ {0x8b,0x75,0xc4,0x66,0x77,0x1b,0x86,0xde,0xa8,0xa0,0x23,0x4b,0x59,0xc3,0xf9,0xd3,
+ 0x76,0xe7,0x86,0x21,0x0e,0x94,0x5c,0x75,0x1b,0x9f,0x7a,0xc9,0x35,0x4d,0x4b,0x69,
+ 0xf4,0xa2,0x88,0x86,0xd9,0x0a,0xb2,0xa0,0x77,0xf5,0x86,0x02,0x0f,0x8c,0x27,0x7d,
+ 0x1b,0x6d,0x52,0x56,0xc9,0x8b,0x17,0xf8,0x4c,0x55,0x38,0x62,0x07,0xb6,0x9d,0x4c,
+ 0xd3,0xd1,0x4e,0x83,0xbc,0x22,0xd7,0x4a,0xfb,0xfc,0xca,0x47,0x08,0x74,0xeb,0x42,
+ 0xb9,0xf1,0xc6,0xa7,0xf8,0xaa,0x1c,0x36,0x30,0x33,0x95,0x04,0x97,0x71,0x5a,0xb6,
+ 0x93,0xb1,0xdb,0xca,0xf7,0x7f,0x00,0xad,0x45,0x80,0x2c,0x27,0x03,0x74,0x1c,0x2d,
+ 0x9e,0x6e,0x18,0x69,0x1b,0xf9,0x2d,0x28,0x46,0xbd,0xa1,0xc4,0xd5,0x7a,0x31,0xf0,},
+ .ivlen = 128,
+ {0xc4,0x80,0x65,0x98,0x81,0x7e,0x31,0xa0,0xe3,0x3a,0x96,0x79,0x66,},
+ .taglen = 13,
+ {0xb0,0xf8,0x1c,0xbc,0xc7,0x55,0x46,0xc6,0xcf,0xc3,0x3a,0x28,0x86,0x7b,0x26,0x57,},
+ {16},
+ .num_chunks = 1,
+ },
+ /**
+ * GCM data - 19
+ *
+ * [Keylen = 128]
+ * [IVlen = 8]
+ * [PTlen = 408]
+ * [AADlen = 720]
+ * [Taglen = 104]
+ */
+ {{0xc1,0xff,0x59,0x80,0x55,0xf8,0xb3,0xb8,0x3f,0xdf,0xd7,0xba,0xe5,0x7e,0x10,0x18,},
+ .keylen = 16,
+ {0x97,0xc4,0x68,0xcf,0x16,0xfe,0x00,0x9a,0xb8,0x1c,0x32,0xfc,0x91,0x1a,0xd9,0xda,
+ 0xe9,0x68,0xf5,0x9e,0x2f,0x77,0x34,0xbb,0xbc,0x8e,0x63,0xf4,0xb1,0x8a,0x5c,0x61,
+ 0x36,0x7d,0x30,0x0e,0xd2,0x45,0xfc,0x45,0xfe,0x08,0x6d,0x6b,0xe5,0x6b,0x35,0xf6,
+ 0x9d,0xe4,0x89,},
+ .datalen = 51,
+ {0xd9,0x94,0x86,0xf5,0xc7,0xf2,0xc5,0x34,0x11,0x82,0x7b,0xa3,0xb5,0x14,0x55,0x66,
+ 0x17,0xf7,0x9b,0x16,0x73,0x6f,0x93,0x70,0x7f,0xdb,0x16,0xa2,0x36,0xd4,0x1e,0x84,
+ 0xf6,0x8d,0x55,0x5d,0x11,0x6b,0x25,0x42,0xbc,0xf0,0x27,0xa0,0x4c,0x70,0x00,0xbc,
+ 0x7e,0xd5,0xb1,0xf2,0x83,0x92,0x2d,0x0c,0x1f,0x5d,0xbf,0x2b,0x72,0xf4,0x58,0x2f,
+ 0xac,0x0e,0x3f,0x20,0x1d,0x2d,0x08,0x0f,0x27,0xfa,0xcb,0x06,0xc5,0x6b,0x9c,0x93,
+ 0x84,0x96,0x13,0x1c,0x3f,0xb6,0x49,0xf5,0xf4,0x64,},
+ .aadlen = 90,
+ {0x0a,},
+ .ivlen = 1,
+ {0xc2,0x9d,0xdd,0xc9,0x48,0x00,0xfb,0xf7,0xae,0x43,0x0d,0x59,0x01,},
+ .taglen = 13,
+ {0x4e,0x0e,0x6a,0x45,0x39,0xf9,0x4d,0xc1,0x9c,0xaa,0x15,0xd1,0x4f,0x8f,0xb7,0x2f,
+ 0x0b,0xc8,0xa4,0xd5,0xea,0xf0,0xe1,0x73,0xfa,0x04,0x0d,0xe7,0x8c,0x06,0x39,0x2c,
+ 0xb4,0x51,0x70,0xde,0xef,0xd3,0x8e,0x02,0x53,0xdd,0xb7,0xda,0xc9,0x3b,0xc4,0x9e,
+ 0xd4,0x19,0x04,},
+ {16,32,3},
+ .num_chunks = 3,
+ },
+ /**
+ * GCM data - 20 : same as 19, but different chunks
+ *
+ * [Keylen = 128]
+ * [IVlen = 8]
+ * [PTlen = 408]
+ * [AADlen = 720]
+ * [Taglen = 104]
+ */
+ {{0xc1,0xff,0x59,0x80,0x55,0xf8,0xb3,0xb8,0x3f,0xdf,0xd7,0xba,0xe5,0x7e,0x10,0x18,},
+ .keylen = 16,
+ {0x97,0xc4,0x68,0xcf,0x16,0xfe,0x00,0x9a,0xb8,0x1c,0x32,0xfc,0x91,0x1a,0xd9,0xda,
+ 0xe9,0x68,0xf5,0x9e,0x2f,0x77,0x34,0xbb,0xbc,0x8e,0x63,0xf4,0xb1,0x8a,0x5c,0x61,
+ 0x36,0x7d,0x30,0x0e,0xd2,0x45,0xfc,0x45,0xfe,0x08,0x6d,0x6b,0xe5,0x6b,0x35,0xf6,
+ 0x9d,0xe4,0x89,},
+ .datalen = 51,
+ {0xd9,0x94,0x86,0xf5,0xc7,0xf2,0xc5,0x34,0x11,0x82,0x7b,0xa3,0xb5,0x14,0x55,0x66,
+ 0x17,0xf7,0x9b,0x16,0x73,0x6f,0x93,0x70,0x7f,0xdb,0x16,0xa2,0x36,0xd4,0x1e,0x84,
+ 0xf6,0x8d,0x55,0x5d,0x11,0x6b,0x25,0x42,0xbc,0xf0,0x27,0xa0,0x4c,0x70,0x00,0xbc,
+ 0x7e,0xd5,0xb1,0xf2,0x83,0x92,0x2d,0x0c,0x1f,0x5d,0xbf,0x2b,0x72,0xf4,0x58,0x2f,
+ 0xac,0x0e,0x3f,0x20,0x1d,0x2d,0x08,0x0f,0x27,0xfa,0xcb,0x06,0xc5,0x6b,0x9c,0x93,
+ 0x84,0x96,0x13,0x1c,0x3f,0xb6,0x49,0xf5,0xf4,0x64,},
+ .aadlen = 90,
+ {0x0a,},
+ .ivlen = 1,
+ {0xc2,0x9d,0xdd,0xc9,0x48,0x00,0xfb,0xf7,0xae,0x43,0x0d,0x59,0x01,},
+ .taglen = 13,
+ {0x4e,0x0e,0x6a,0x45,0x39,0xf9,0x4d,0xc1,0x9c,0xaa,0x15,0xd1,0x4f,0x8f,0xb7,0x2f,
+ 0x0b,0xc8,0xa4,0xd5,0xea,0xf0,0xe1,0x73,0xfa,0x04,0x0d,0xe7,0x8c,0x06,0x39,0x2c,
+ 0xb4,0x51,0x70,0xde,0xef,0xd3,0x8e,0x02,0x53,0xdd,0xb7,0xda,0xc9,0x3b,0xc4,0x9e,
+ 0xd4,0x19,0x04,},
+ {16,35},
+ .num_chunks = 2,
+ },
+ /* GCM data - 21 : same as 11, but different chunks */
+ {{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,},
+ .keylen = 32,
+ {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,},
+ .datalen = 60,
+ {0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,0xfe,0xed,0xfa,0xce,0xde,0xad,0xbe,0xef,
+ 0xab,0xad,0xda,0xd2,},
+ .aadlen = 20,
+ {0xca,0xfe,0xba,0xbe,0xfa,0xce,0xdb,0xad,0xde,0xca,0xf8,0x88,},
+ .ivlen = 12,
+ {0x76,0xfc,0x6e,0xce,0x0f,0x4e,0x17,0x68,0xcd,0xdf,0x88,0x53,0xbb,0x2d,0x55,0x1b,},
+ .taglen = 16,
+ {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,},
+ {32,28},
+ .num_chunks = 2,
+ },
+};
+
+static inline 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);
+}
+
+#endif /* GCM_KATS_H */
diff --git a/src/tests/libica_aes_gcm_kma_test.c b/src/tests/libica_aes_gcm_kma_test.c
new file mode 100644
index 0000000..a30e44c
--- /dev/null
+++ b/src/tests/libica_aes_gcm_kma_test.c
@@ -0,0 +1,731 @@
+/* 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. 2017 */
+#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"
+#include "gcm_kats.h"
+
+
+int test_gcm_kat(int iteration)
+{
+ unsigned int aad_length = gcm_kats[iteration].aadlen;
+ unsigned int data_length = gcm_kats[iteration].datalen;
+ unsigned int t_length = gcm_kats[iteration].taglen;
+ unsigned int iv_length = gcm_kats[iteration].ivlen;
+ unsigned int key_length = gcm_kats[iteration].keylen;
+
+ unsigned char* iv = (unsigned char*)&(gcm_kats[iteration].iv);
+ unsigned char* input_data = (unsigned char*)&(gcm_kats[iteration].data);
+ unsigned char* result = (unsigned char*)&(gcm_kats[iteration].result);
+ unsigned char* aad = (unsigned char*)&(gcm_kats[iteration].aad);
+ unsigned char* key = (unsigned char*)&(gcm_kats[iteration].key);
+ unsigned char* t_result = (unsigned char*)&(gcm_kats[iteration].tag);
+ unsigned char encrypt[data_length];
+ unsigned char decrypt[data_length];
+ unsigned char t[t_length];
+
+ 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));
+
+ /* Allocate context */
+ kma_ctx* ctx = ica_aes_gcm_kma_ctx_new();
+ if (!ctx) {
+ V_(printf("Error: Cannot create gcm context.\n"));
+ return 1;
+ }
+
+ /* Initialize context for encrypt */
+ rc = ica_aes_gcm_kma_init(ICA_ENCRYPT, iv, iv_length, key, key_length, ctx);
+ if (rc) {
+ V_(printf("Error: Cannot initialize gcm context.\n"));
+ return 1;
+ }
+
+ /* Update for encrypt */
+ rc = ica_aes_gcm_kma_update(input_data, encrypt, data_length, aad, aad_length, 1, 1, ctx);
+
+ 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) {
+ V_(printf("ica_aes_gcm_kma encrypt failed with rc = %i\n", rc));
+ }
+
+ if (memcmp(result, encrypt, data_length)) {
+ V_(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++;
+ }
+
+ rc = ica_aes_gcm_kma_get_tag(t, t_length, ctx);
+ if (memcmp(t, t_result, t_length)) {
+ V_(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;
+ }
+
+ /* Initialize context for decrypt */
+ rc = ica_aes_gcm_kma_init(ICA_DECRYPT, iv, iv_length, key, key_length, ctx);
+ if (rc) {
+ V_(printf("Error: Cannot initialize gcm context for decrypt. \n"));
+ return 1;
+ }
+
+ /* Update for decrypt */
+ rc = ica_aes_gcm_kma_update(encrypt, decrypt, data_length, aad, aad_length, 1, 1, ctx);
+
+ 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_kma decrypt failed with rc = %i\n", rc));
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ V_(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++;
+ }
+
+ rc = ica_aes_gcm_kma_verify_tag(t_result, t_length, ctx);
+ if (rc == EFAULT) {
+ V_(printf("Tag result does not match the expected tag!\n"));
+ rc++;
+ }
+
+ ica_aes_gcm_kma_ctx_free(ctx);
+
+ return rc;
+}
+
+int test_gcm_kat_update(int iteration)
+{
+ unsigned int aad_length_tmp;
+ unsigned int aad_length = gcm_kats[iteration].aadlen;
+ unsigned int data_length = gcm_kats[iteration].datalen;
+ unsigned int t_length = gcm_kats[iteration].taglen;
+ unsigned int iv_length = gcm_kats[iteration].ivlen;
+ unsigned int key_length = gcm_kats[iteration].keylen;
+ unsigned int num_chunks = gcm_kats[iteration].num_chunks;
+
+ unsigned char* iv = (unsigned char*)&(gcm_kats[iteration].iv);
+ unsigned char* input_data = (unsigned char*)&(gcm_kats[iteration].data);
+ unsigned char* aad = (unsigned char*)&(gcm_kats[iteration].aad);
+ unsigned char* key = (unsigned char*)&(gcm_kats[iteration].key);
+ unsigned char* result = (unsigned char*)&(gcm_kats[iteration].result);
+ unsigned char* t_result = (unsigned char*)&(gcm_kats[iteration].tag);
+ unsigned int chunk_len;
+ unsigned int offset;
+ unsigned char *chunk_data;
+ unsigned char encrypt[data_length];
+ unsigned char decrypt[data_length];
+ unsigned char t[t_length];
+ 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));
+
+ aad_length_tmp = aad_length;
+
+ /* Allocate context */
+ kma_ctx* ctx = ica_aes_gcm_kma_ctx_new();
+ if (!ctx) {
+ V_(printf("Error: Cannot create gcm context. \n"));
+ return 1;
+ }
+
+ /* Initialize context for encrypt */
+ rc = ica_aes_gcm_kma_init(ICA_ENCRYPT, iv, iv_length, key, key_length, ctx);
+ if (rc) {
+ V_(printf("Error: Cannot initialize gcm context. \n"));
+ return 1;
+ }
+
+ /* Encrypt */
+ offset = 0;
+ if (num_chunks > 0) {
+
+ for (i = 0; i < num_chunks; i++) {
+
+ chunk_len = gcm_kats[iteration].chunks[i];
+ chunk_data = input_data + offset;
+
+ /* Encrypt */
+ rc = ica_aes_gcm_kma_update(chunk_data, encrypt+offset, chunk_len,
+ aad, aad_length,
+ 1, /* end_of_aad */
+ i == num_chunks-1 ? 1 : 0,
+ ctx);
+ if (rc)
+ break;
+
+ /* clear aad_length after first run*/
+ aad_length = 0;
+ offset += chunk_len;
+ }
+
+ } else {
+
+ rc = ica_aes_gcm_kma_update(input_data, encrypt, 0,
+ aad, aad_length,
+ 1, /* end_of_aad */
+ 1, /* end_of_data */
+ ctx);
+ }
+
+ 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) {
+ V_(printf("ica_aes_gcm_kma encrypt failed with rc = %i\n", rc));
+ }
+
+ if (memcmp(result, encrypt, data_length)) {
+ V_(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++;
+ }
+
+ rc = ica_aes_gcm_kma_get_tag(t, t_length, ctx);
+ if (memcmp(t, t_result, t_length)) {
+ V_(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;
+ }
+
+ /* Decrypt */
+ aad_length = aad_length_tmp;
+ offset = 0;
+
+ /* Initialize context for decrypt */
+ rc = ica_aes_gcm_kma_init(ICA_DECRYPT, iv, iv_length, key, key_length, ctx);
+ if (rc) {
+ V_(printf("Error: Cannot initialize gcm context for decrypt. \n"));
+ return 1;
+ }
+
+ if (num_chunks > 0) {
+
+ for (i = 0; i < num_chunks; i++) {
+ chunk_len = gcm_kats[iteration].chunks[i];
+ chunk_data = encrypt + offset;
+
+ rc = ica_aes_gcm_kma_update(chunk_data,
+ decrypt+offset, chunk_len,
+ aad, aad_length,
+ 1, /* end_of_aad */
+ i == num_chunks-1 ? 1 : 0,
+ ctx);
+
+ if (rc)
+ break;
+
+ /* clear aad_length after first run*/
+ aad_length = 0;
+ offset += chunk_len;
+ }
+
+ } else {
+
+ rc = ica_aes_gcm_kma_update(input_data, decrypt, 0,
+ aad, aad_length,
+ 1, /* end_of_aad */
+ 1, /* end_of_data */
+ ctx);
+ }
+
+ 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));
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ V_(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++;
+ }
+
+ rc = ica_aes_gcm_kma_verify_tag(t_result, t_length, ctx);
+ if (rc == EFAULT) {
+ V_(printf("Tag result does not match the expected tag!\n"));
+ rc++;
+ }
+
+ ica_aes_gcm_kma_ctx_free(ctx);
+
+ return rc;
+}
+
+int test_gcm_kat_update_aad(int iteration)
+{
+ unsigned int aad_length_tmp;
+ unsigned int aad_length = gcm_kats[iteration].aadlen;
+ unsigned int data_length = gcm_kats[iteration].datalen;
+ unsigned int t_length = gcm_kats[iteration].taglen;
+ unsigned int iv_length = gcm_kats[iteration].ivlen;
+ unsigned int key_length = gcm_kats[iteration].keylen;
+ unsigned int num_chunks = gcm_kats[iteration].num_chunks;
+
+ unsigned char* iv = (unsigned char*)&(gcm_kats[iteration].iv);
+ unsigned char* input_data = (unsigned char*)&(gcm_kats[iteration].data);
+ unsigned char encrypt[data_length];
+ unsigned char decrypt[data_length];
+ unsigned char* result = (unsigned char*)&(gcm_kats[iteration].result);
+ unsigned char* aad = (unsigned char*)&(gcm_kats[iteration].aad);
+ unsigned char* key = (unsigned char*)&(gcm_kats[iteration].key);
+ unsigned char t[t_length];
+ unsigned char* t_result = (unsigned char*)&(gcm_kats[iteration].tag);
+ unsigned int chunk_len;
+ unsigned int data_offset;
+ unsigned int aad_offset;
+ unsigned char *chunk_data;
+ 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));
+
+ aad_length_tmp = aad_length;
+
+ /* Allocate context */
+ kma_ctx* ctx = ica_aes_gcm_kma_ctx_new();
+ if (!ctx) {
+ V_(printf("Error: Cannot create gcm context. \n"));
+ return 1;
+ }
+
+ /* Initialize context for encrypt */
+ rc = ica_aes_gcm_kma_init(ICA_ENCRYPT, iv, iv_length, key, key_length, ctx);
+ if (rc) {
+ V_(printf("Error: Cannot initialize gcm context. \n"));
+ return 1;
+ }
+
+ /* Process 16-byte aad chunks in advance */
+ unsigned int aad_chunklen = 0;
+ unsigned int aad_restlen = 0;
+ aad_offset = 0;
+ while (aad_length >= 16) {
+
+ aad_chunklen = aad_length > 16 ? 16 : aad_length;
+ aad_restlen = aad_length > 16 ? aad_length - 16 : 0;
+
+ rc = ica_aes_gcm_kma_update(input_data, encrypt, 0,
+ aad+aad_offset, aad_chunklen,
+ 0, /* end_of_aad */
+ 0, /* end_of_data */
+ ctx);
+
+ aad_length = aad_restlen;
+ aad_offset += aad_chunklen;
+ }
+
+ /* Encrypt data if any, and process last aad if any */
+ data_offset = 0;
+ if (num_chunks > 0) {
+
+ for (i = 0; i < num_chunks; i++) {
+ chunk_len = gcm_kats[iteration].chunks[i];
+ chunk_data = input_data + data_offset;
+
+ rc = ica_aes_gcm_kma_update(chunk_data,
+ encrypt+data_offset, chunk_len,
+ aad+aad_offset, aad_length,
+ 1, /* end_of_aad */
+ i == num_chunks-1 ? 1 : 0,
+ ctx);
+
+ /* clear aad_length after first run*/
+ aad_length = 0;
+ data_offset += chunk_len;
+ }
+
+ } else {
+
+ rc = ica_aes_gcm_kma_update(input_data, encrypt, 0,
+ aad+aad_offset, aad_length,
+ 1, /* end_of_aad */
+ 1, /* end_of_data */
+ ctx);
+ }
+
+ 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) {
+ V_(printf("ica_aes_gcm_kma encrypt failed with rc = %i\n", rc));
+ }
+
+ if (memcmp(result, encrypt, data_length)) {
+ V_(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++;
+ }
+
+ rc = ica_aes_gcm_kma_get_tag(t, t_length, ctx);
+ if (memcmp(t, t_result, t_length)) {
+ V_(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;
+ }
+
+ /* Decryption */
+ aad_length = aad_length_tmp;
+ data_offset = 0;
+
+ /* 5. Initialize context for decrypt */
+ rc = ica_aes_gcm_kma_init(ICA_DECRYPT, iv, iv_length, key, key_length, ctx);
+ if (rc) {
+ V_(printf("Error: Cannot initialize gcm context for decrypt. \n"));
+ return 1;
+ }
+
+ if (num_chunks > 0) {
+
+ for (i = 0; i < num_chunks; i++) {
+ chunk_len = gcm_kats[iteration].chunks[i];
+ chunk_data = encrypt + data_offset;
+
+ rc = ica_aes_gcm_kma_update(chunk_data, decrypt+data_offset, chunk_len,
+ aad, aad_length,
+ 1, /* end_of_aad */
+ i == num_chunks-1 ? 1 : 0,
+ ctx);
+
+ /* clear aad_length after first run*/
+ aad_length = 0;
+ data_offset += chunk_len;
+ }
+
+ } else {
+
+ rc = ica_aes_gcm_kma_update(input_data, decrypt, 0,
+ aad, aad_length,
+ 1, /* end_of_aad */
+ 1, /* end_of_data */
+ ctx);
+ }
+
+ 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));
+ }
+
+ if (memcmp(decrypt, input_data, data_length)) {
+ V_(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++;
+ }
+
+ rc = ica_aes_gcm_kma_verify_tag(t_result, t_length, ctx);
+ if (rc == EFAULT) {
+ V_(printf("Tag result does not match the expected tag!\n"));
+ rc++;
+ }
+
+ ica_aes_gcm_kma_ctx_free(ctx);
+
+ return rc;
+}
+
+int test_gcm_kat_update_in_place(int iteration)
+{
+ unsigned int aad_length_tmp;
+ unsigned int aad_length = gcm_kats[iteration].aadlen;
+ unsigned int data_length = gcm_kats[iteration].datalen;
+ unsigned int t_length = gcm_kats[iteration].taglen;
+ unsigned int iv_length = gcm_kats[iteration].ivlen;
+ unsigned int key_length = gcm_kats[iteration].keylen;
+ unsigned int num_chunks = gcm_kats[iteration].num_chunks;
+
+ unsigned char* iv = (unsigned char*)&(gcm_kats[iteration].iv);
+ unsigned char* input_data = (unsigned char*)&(gcm_kats[iteration].data);
+ unsigned char* result = (unsigned char*)&(gcm_kats[iteration].result);
+ unsigned char* aad = (unsigned char*)&(gcm_kats[iteration].aad);
+ unsigned char* key = (unsigned char*)&(gcm_kats[iteration].key);
+ unsigned char* t_result = (unsigned char*)&(gcm_kats[iteration].tag);
+ unsigned int chunk_len;
+ unsigned int offset;
+ unsigned char *chunk_data;
+ unsigned char save_input[MAX_ARRAY_SIZE];
+ unsigned char t[t_length];
+ 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));
+
+ aad_length_tmp = aad_length;
+
+ /* Allocate context */
+ kma_ctx* ctx = ica_aes_gcm_kma_ctx_new();
+ if (!ctx) {
+ V_(printf("Error: Cannot create gcm context. \n"));
+ return 1;
+ }
+
+ /* Initialize context for encrypt */
+ rc = ica_aes_gcm_kma_init(ICA_ENCRYPT, iv, iv_length, key, key_length, ctx);
+ if (rc) {
+ V_(printf("Error: Cannot initialize gcm context. \n"));
+ return 1;
+ }
+
+ /* Encrypt */
+ memcpy(save_input, input_data, data_length);
+ offset = 0;
+ if (num_chunks > 0) {
+
+ for (i = 0; i < num_chunks; i++) {
+
+ chunk_len = gcm_kats[iteration].chunks[i];
+ chunk_data = input_data + offset;
+
+ /* Encrypt */
+ rc = ica_aes_gcm_kma_update(chunk_data, chunk_data, chunk_len,
+ aad, aad_length,
+ 1, /* end_of_aad */
+ i == num_chunks-1 ? 1 : 0,
+ ctx);
+
+ /* clear aad_length after first run*/
+ aad_length = 0;
+ offset += chunk_len;
+ }
+
+ } else {
+
+ rc = ica_aes_gcm_kma_update(input_data, input_data, 0,
+ aad, aad_length,
+ 1, /* end_of_aad */
+ 1, /* end_of_data */
+ ctx);
+ }
+
+ 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) {
+ V_(printf("ica_aes_gcm_kma encrypt failed with rc = %i\n", rc));
+ }
+
+ if (memcmp(result, input_data, data_length)) {
+ V_(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(input_data, data_length);
+ rc++;
+ }
+
+ rc = ica_aes_gcm_kma_get_tag(t, t_length, ctx);
+ if (memcmp(t, t_result, t_length)) {
+ V_(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;
+ }
+
+ /* Decryption */
+ aad_length = aad_length_tmp;
+ offset = 0;
+
+ /* 4. Initialize context for decrypt */
+ rc = ica_aes_gcm_kma_init(ICA_DECRYPT, iv, iv_length, key, key_length, ctx);
+ if (rc) {
+ V_(printf("Error: Cannot initialize gcm context for decrypt. \n"));
+ return 1;
+ }
+
+ if (num_chunks > 0) {
+
+ for (i = 0; i < num_chunks; i++) {
+ chunk_len = gcm_kats[iteration].chunks[i];
+ chunk_data = input_data + offset;
+
+ rc = ica_aes_gcm_kma_update(chunk_data, chunk_data , chunk_len,
+ aad, aad_length,
+ 1, /* end_of_aad */
+ i == num_chunks-1 ? 1 : 0,
+ ctx);
+
+ /* clear aad_length after first run*/
+ aad_length = 0;
+ offset += chunk_len;
+ }
+
+ } else {
+
+ rc = ica_aes_gcm_kma_update(input_data, input_data, 0,
+ aad, aad_length,
+ 1, /* end_of_aad */
+ 1, /* end_of_data */
+ ctx);
+ }
+
+ 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));
+ }
+
+ if (memcmp(save_input, input_data, data_length)) {
+ V_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(save_input, data_length);
+ VV_(printf("Decryption Result:\n"));
+ dump_array(input_data, data_length);
+ rc++;
+ }
+
+ rc = ica_aes_gcm_kma_verify_tag(t_result, t_length, ctx);
+ if (rc == EFAULT) {
+ V_(printf("Tag result does not match the expected tag!\n"));
+ rc++;
+ }
+
+ ica_aes_gcm_kma_ctx_free(ctx);
+
+ 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 = 0; iteration < NUM_GCM_TESTS; iteration++) {
+
+ rc = test_gcm_kat(iteration);
+ if (rc) {
+ V_(printf("test_gcm_kat %i failed with rc = %i\n", iteration, rc));
+ error_count++;
+ }
+
+ rc = test_gcm_kat_update(iteration);
+ if (rc) {
+ V_(printf("test_gcm_kat_update %i failed with rc = %i\n", iteration, rc));
+ error_count++;
+ }
+
+ rc = test_gcm_kat_update_aad(iteration);
+ if (rc) {
+ V_(printf("test_gcm_kat_update_aad %i failed with rc = %i\n", iteration, rc));
+ error_count++;
+ }
+
+ rc = test_gcm_kat_update_in_place(iteration);
+ if (rc) {
+ V_(printf("test_gcm_kat_update_in_place %i failed with rc = %i\n", iteration, rc));
+ error_count++;
+ }
+ }
+
+ if (error_count)
+ printf("%i of %li AES-GCM-KMA tests failed.\n", error_count, NUM_GCM_TESTS*4);
+ else
+ printf("All AES-GCM-KMA tests passed.\n");
+ return rc;
+}
diff --git a/src/tests/libica_aes_gcm_test.c b/src/tests/libica_aes_gcm_test.c
index bce6100..410dbde 100644
--- a/src/tests/libica_aes_gcm_test.c
+++ b/src/tests/libica_aes_gcm_test.c
@@ -13,734 +13,26 @@
#include <stdlib.h>
#include "ica_api.h"
#include "testcase.h"
+#include "gcm_kats.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 int aad_length = gcm_kats[iteration].aadlen;
+ unsigned int data_length = gcm_kats[iteration].datalen;
+ unsigned int t_length = gcm_kats[iteration].taglen;
+ unsigned int iv_length = gcm_kats[iteration].ivlen;
+ unsigned int key_length = gcm_kats[iteration].keylen;
+
+ unsigned char* iv = (unsigned char*)&(gcm_kats[iteration].iv);
+ unsigned char* input_data = (unsigned char*)&(gcm_kats[iteration].data);
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* result = (unsigned char*)&(gcm_kats[iteration].result);
+ unsigned char* aad = (unsigned char*)&(gcm_kats[iteration].aad);
+ unsigned char* key = (unsigned char*)&(gcm_kats[iteration].key);
unsigned char t[t_length];
- unsigned char t_result[t_length];
- unsigned char chunks[num_chunks];
+ unsigned char* t_result = (unsigned char*)&(gcm_kats[iteration].tag);
int rc = 0;
@@ -749,24 +41,20 @@ int test_gcm_kat(int iteration)
"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);
+ ICA_ENCRYPT);
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));
+ V_(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);
}
@@ -778,7 +66,7 @@ int test_gcm_kat(int iteration)
}
if (memcmp(result, encrypt, data_length)) {
- VV_(printf("Encryption Result does not match the known ciphertext!\n"));
+ V_(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"));
@@ -786,7 +74,7 @@ int test_gcm_kat(int iteration)
rc++;
}
if (memcmp(t, t_result, t_length)) {
- VV_(printf("Tag result does not match the expected tag!\n"));
+ V_(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"));
@@ -803,7 +91,7 @@ int test_gcm_kat(int iteration)
aad, aad_length,
t, t_length,
key, key_length,
- 0);
+ ICA_DECRYPT);
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"));
@@ -825,7 +113,7 @@ int test_gcm_kat(int iteration)
}
if (memcmp(decrypt, input_data, data_length)) {
- VV_(printf("Decryption Result does not match the original data!\n"));
+ V_(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"));
@@ -833,7 +121,7 @@ int test_gcm_kat(int iteration)
rc++;
}
if (memcmp(t, t_result, t_length)) {
- VV_(printf("Tag result does not match the expected tag!\n"));
+ V_(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"));
@@ -845,27 +133,198 @@ int test_gcm_kat(int iteration)
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;
+ unsigned int aad_length = gcm_kats[iteration].aadlen;
+ unsigned int data_length = gcm_kats[iteration].datalen;
+ unsigned int t_length = gcm_kats[iteration].taglen;
+ unsigned int iv_length = gcm_kats[iteration].ivlen;
+ unsigned int key_length = gcm_kats[iteration].keylen;
+ unsigned int num_chunks = gcm_kats[iteration].num_chunks;
+
+ unsigned char* iv = (unsigned char*)&(gcm_kats[iteration].iv);
+ unsigned char* input_data = (unsigned char*)&(gcm_kats[iteration].data);
+ unsigned char encrypt[data_length];
+ unsigned char decrypt[data_length];
+ unsigned char* result = (unsigned char*)&(gcm_kats[iteration].result);
+ unsigned char* aad = (unsigned char*)&(gcm_kats[iteration].aad);
+ unsigned char* key = (unsigned char*)&(gcm_kats[iteration].key);
+ unsigned char t[t_length];
+ unsigned char* t_result = (unsigned char*)&(gcm_kats[iteration].tag);
+ 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;
- get_sizes(&aad_length, &data_length, &t_length, &iv_length,
- &key_length, &num_chunks, iteration);
+ 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));
- unsigned char iv[iv_length];
- unsigned char input_data[data_length];
+ 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, ICA_ENCRYPT);
+
+ if (num_chunks == 0 && aad_length > 0) {
+ rc = ica_aes_gcm_intermediate(input_data, 0, encrypt,
+ ucb, aad, aad_length,
+ running_tag, AES_BLOCK_SIZE,
+ key, key_length, subkey, ICA_ENCRYPT);
+ }
+
+ offset = 0;
+ for (i = 0; i < num_chunks; i++) {
+ chunk_len = gcm_kats[iteration].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, ICA_ENCRYPT);
+ /* 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, ICA_ENCRYPT);
+
+ 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)) {
+ V_(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)) {
+ V_(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, ICA_DECRYPT);
+
+ if (num_chunks == 0 && aad_length > 0) {
+ rc = ica_aes_gcm_intermediate(input_data, 0, encrypt,
+ ucb, aad, aad_length,
+ running_tag, AES_BLOCK_SIZE,
+ key, key_length, subkey, ICA_DECRYPT);
+ }
+
+ offset = 0;
+ for (i = 0; i < num_chunks; i++) {
+ chunk_len = gcm_kats[iteration].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, ICA_DECRYPT);
+
+ /* 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, ICA_DECRYPT);
+
+
+ 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)) {
+ V_(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)) {
+ V_(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(running_tag, t_length);
+ rc++;
+ }
+
+ return rc;
+}
+
+int test_gcm_kat_update_aad(int iteration)
+{
+ unsigned int aad_length_tmp;
+ unsigned int aad_length = gcm_kats[iteration].aadlen;
+ unsigned int data_length = gcm_kats[iteration].datalen;
+ unsigned int t_length = gcm_kats[iteration].taglen;
+ unsigned int iv_length = gcm_kats[iteration].ivlen;
+ unsigned int key_length = gcm_kats[iteration].keylen;
+ unsigned int num_chunks = gcm_kats[iteration].num_chunks;
+
+ unsigned char* iv = (unsigned char*)&(gcm_kats[iteration].iv);
+ unsigned char* input_data = (unsigned char*)&(gcm_kats[iteration].data);
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* result = (unsigned char*)&(gcm_kats[iteration].result);
+ unsigned char* aad = (unsigned char*)&(gcm_kats[iteration].aad);
+ unsigned char* key = (unsigned char*)&(gcm_kats[iteration].key);
unsigned char t[t_length];
- unsigned char t_result[t_length];
- unsigned char chunks[num_chunks];
+ unsigned char* t_result = (unsigned char*)&(gcm_kats[iteration].tag);
unsigned int chunk_len;
unsigned int offset;
unsigned char *chunk_data;
@@ -875,6 +334,7 @@ int test_gcm_kat_update(int iteration)
unsigned char running_tag[AES_BLOCK_SIZE];
unsigned int sum_A_len;
unsigned int sum_C_len;
+ unsigned int aad_offset;
int rc = 0, i;
VV_(printf("Test Parameters for iteration = %i\n", iteration));
@@ -882,24 +342,48 @@ int test_gcm_kat_update(int iteration)
"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);
+ icb, ucb, subkey, ICA_ENCRYPT);
+
+ /* 1. Process 16-byte aad chunks in advance */
+ unsigned int aad_chunklen = 0;
+ unsigned int aad_restlen = 0;
+ aad_offset = 0;
+ while (aad_length >= 16) {
+
+ aad_chunklen = aad_length > 16 ? 16 : aad_length;
+ aad_restlen = aad_length > 16 ? aad_length - 16 : 0;
+
+ rc = ica_aes_gcm_intermediate(input_data, 0, encrypt,
+ ucb, aad+aad_offset, aad_chunklen,
+ running_tag, AES_BLOCK_SIZE,
+ key, key_length, subkey, ICA_ENCRYPT);
+ aad_length = aad_restlen;
+ aad_offset += aad_chunklen;
+ }
+
+ /* 2. Process rest of aad if no data available */
+ if (num_chunks == 0 && aad_length > 0) {
+ rc = ica_aes_gcm_intermediate(input_data, 0, encrypt,
+ ucb, aad+aad_offset, aad_length,
+ running_tag, AES_BLOCK_SIZE,
+ key, key_length, subkey, ICA_ENCRYPT);
+ }
+
+ /* 3. Process rest of aad and data */
offset = 0;
for (i = 0; i < num_chunks; i++) {
- chunk_len = chunks[i];
+
+ chunk_len = gcm_kats[iteration].chunks[i];
chunk_data = input_data + offset;
rc = ica_aes_gcm_intermediate(chunk_data, chunk_len, encrypt + offset,
- ucb, aad, aad_length,
+ ucb, aad+aad_offset, aad_length,
running_tag, AES_BLOCK_SIZE,
- key, key_length, subkey, 1);
+ key, key_length, subkey, ICA_ENCRYPT);
/* clear aad_length after first run*/
aad_length = 0;
offset += chunk_len;
@@ -907,7 +391,7 @@ int test_gcm_kat_update(int iteration)
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);
+ t, t_length, key, key_length, subkey, ICA_ENCRYPT);
if (rc == EPERM) {
VV_(printf("ica_aes_gcm returns with EPERM (%d).\n", rc));
@@ -927,7 +411,7 @@ int test_gcm_kat_update(int iteration)
}
if (memcmp(result, encrypt, data_length)) {
- VV_(printf("Encryption Result does not match the known ciphertext!\n"));
+ V_(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"));
@@ -935,7 +419,7 @@ int test_gcm_kat_update(int iteration)
rc++;
}
if (memcmp(running_tag, t_result, t_length)) {
- VV_(printf("Tag result does not match the expected tag!\n"));
+ V_(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"));
@@ -947,20 +431,28 @@ int test_gcm_kat_update(int iteration)
return rc;
}
+ /* Decrypt */
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);
+ icb, ucb, subkey, ICA_DECRYPT);
+
+ if (num_chunks == 0 && aad_length > 0) {
+ rc = ica_aes_gcm_intermediate(input_data, 0, encrypt,
+ ucb, aad, aad_length,
+ running_tag, AES_BLOCK_SIZE,
+ key, key_length, subkey, ICA_DECRYPT);
+ }
offset = 0;
for (i = 0; i < num_chunks; i++) {
- chunk_len = chunks[i];
+ chunk_len = gcm_kats[iteration].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);
+ key, key_length, subkey, ICA_DECRYPT);
/* clear aad_length after first run*/
aad_length = 0;
@@ -969,7 +461,7 @@ int test_gcm_kat_update(int iteration)
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);
+ t_result, t_length, key, key_length, subkey, ICA_DECRYPT);
if (rc == EPERM) {
@@ -993,7 +485,7 @@ int test_gcm_kat_update(int iteration)
}
if (memcmp(decrypt, input_data, data_length)) {
- VV_(printf("Decryption Result does not match the original data!\n"));
+ V_(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"));
@@ -1001,13 +493,188 @@ int test_gcm_kat_update(int iteration)
rc++;
}
if (memcmp(running_tag, t_result, t_length)) {
- VV_(printf("Tag result does not match the expected tag!\n"));
+ V_(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(running_tag, t_length);
+ rc++;
+ }
+ return rc;
+}
+
+int test_gcm_kat_update_in_place(int iteration)
+{
+ unsigned int aad_length_tmp;
+ unsigned int aad_length = gcm_kats[iteration].aadlen;
+ unsigned int data_length = gcm_kats[iteration].datalen;
+ unsigned int t_length = gcm_kats[iteration].taglen;
+ unsigned int iv_length = gcm_kats[iteration].ivlen;
+ unsigned int key_length = gcm_kats[iteration].keylen;
+ unsigned int num_chunks = gcm_kats[iteration].num_chunks;
+
+ unsigned char* iv = (unsigned char*)&(gcm_kats[iteration].iv);
+ unsigned char* input_data = (unsigned char*)&(gcm_kats[iteration].data);
+ unsigned char* result = (unsigned char*)&(gcm_kats[iteration].result);
+ unsigned char* aad = (unsigned char*)&(gcm_kats[iteration].aad);
+ unsigned char* key = (unsigned char*)&(gcm_kats[iteration].key);
+ unsigned char t[t_length];
+ unsigned char* t_result = (unsigned char*)&(gcm_kats[iteration].tag);
+ 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;
+ unsigned char save_input[MAX_ARRAY_SIZE];
+ 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));
+
+ 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, ICA_ENCRYPT);
+
+ memcpy(save_input, input_data, data_length);
+ if (num_chunks == 0 && aad_length > 0) {
+ rc = ica_aes_gcm_intermediate(input_data, 0, input_data,
+ ucb, aad, aad_length,
+ running_tag, AES_BLOCK_SIZE,
+ key, key_length, subkey, ICA_ENCRYPT);
+ }
+
+ offset = 0;
+ for (i = 0; i < num_chunks; i++) {
+ chunk_len = gcm_kats[iteration].chunks[i];
+ chunk_data = input_data + offset;
+
+ rc = ica_aes_gcm_intermediate(chunk_data, chunk_len, chunk_data,
+ ucb, aad, aad_length,
+ running_tag, AES_BLOCK_SIZE,
+ key, key_length, subkey, ICA_ENCRYPT);
+ /* 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, ICA_ENCRYPT);
+
+ 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, input_data, t, t_length);
+ }
+ if (!rc) {
+ VV_(printf("Encrypt:\n"));
+ dump_gcm_data(iv, iv_length, aad, aad_length, key, key_length,
+ save_input, data_length, input_data, running_tag,
+ t_length);
+ }
+
+
+ if (memcmp(result, input_data, data_length)) {
+ V_(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(input_data, data_length);
+ rc++;
+ }
+ if (memcmp(running_tag, t_result, t_length)) {
+ V_(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, ICA_DECRYPT);
+
+ if (num_chunks == 0 && aad_length > 0) {
+ rc = ica_aes_gcm_intermediate(input_data, 0, input_data,
+ ucb, aad, aad_length,
+ running_tag, AES_BLOCK_SIZE,
+ key, key_length, subkey, ICA_DECRYPT);
+ }
+
+ offset = 0;
+ for (i = 0; i < num_chunks; i++) {
+ chunk_len = gcm_kats[iteration].chunks[i];
+ chunk_data = input_data + offset;
+
+ rc = ica_aes_gcm_intermediate(chunk_data, chunk_len, chunk_data,
+ ucb, aad, aad_length,
+ running_tag, AES_BLOCK_SIZE,
+ key, key_length, subkey, ICA_DECRYPT);
+
+ /* 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, ICA_DECRYPT);
+
+
+ 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,
+ input_data, data_length, input_data, running_tag,
+ t_length);
+ }
+
+
+ if (!rc) {
+ VV_(printf("Decrypt:\n"));
+ dump_gcm_data(iv, iv_length, aad, aad_length, key, key_length,
+ input_data, data_length, save_input, running_tag,
+ t_length);
+ }
+
+ if (memcmp(save_input, input_data, data_length)) {
+ V_(printf("Decryption Result does not match the original data!\n"));
+ VV_(printf("Original data:\n"));
+ dump_array(save_input, data_length);
+ VV_(printf("Decryption Result:\n"));
+ dump_array(input_data, data_length);
+ rc++;
+ }
+ if (memcmp(running_tag, t_result, t_length)) {
+ V_(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(running_tag, t_length);
+ rc++;
+ }
return rc;
}
@@ -1022,21 +689,35 @@ int main(int argc, char **argv)
set_verbosity(argc, argv);
- for(iteration = 1; iteration <= NR_TESTS; iteration++) {
+ for(iteration = 0; iteration < NUM_GCM_TESTS; iteration++) {
+
rc = test_gcm_kat(iteration);
if (rc) {
- V_(printf("test_gcm_kat failed with rc = %i\n", rc));
+ V_(printf("test_gcm_kat %i failed with rc = %i\n", iteration, rc));
error_count++;
}
rc = test_gcm_kat_update(iteration);
if (rc) {
- V_(printf("test_gcm_kat_update failed with rc = %i\n", rc));
+ V_(printf("test_gcm_kat_update %i failed with rc = %i\n", iteration, rc));
+ error_count++;
+ }
+
+ rc = test_gcm_kat_update_aad(iteration);
+ if (rc) {
+ V_(printf("test_gcm_kat_update_aad %i failed with rc = %i\n", iteration, rc));
+ error_count++;
+ }
+
+ rc = test_gcm_kat_update_in_place(iteration);
+ if (rc) {
+ V_(printf("test_gcm_kat_update_in_place %i failed with rc = %i\n", iteration, rc));
error_count++;
}
}
+
if (error_count)
- printf("%i of %i AES-GCM tests failed.\n", error_count, iteration);
+ printf("%i of %li AES-GCM tests failed.\n", error_count, NUM_GCM_TESTS*4);
else
printf("All AES-GCM tests passed.\n");
return rc;
diff --git a/src/tests/suite.run b/src/tests/suite.run
index 23128c5..ceeba5c 100755
--- a/src/tests/suite.run
+++ b/src/tests/suite.run
@@ -8,8 +8,6 @@ set -e
verbosity=$1
-out="./suite.out"
-
testcases=(
"libica_fips_test"
@@ -39,6 +37,7 @@ testcases=(
"libica_aes_ofb_test $verbosity"
"libica_aes_ctr_test $verbosity"
"libica_aes_gcm_test $verbosity"
+"libica_aes_gcm_kma_test $verbosity"
"libica_aes_xts_test $verbosity"
"libica_cbccs_test $verbosity"
@@ -63,7 +62,6 @@ testcases=(
"libica_sha_test/libica_sha_test $verbosity -sha3 libica_sha_test/sha3_test_vectors/*"
)
-echo -ne "" &> $out;
for (( i=1; i <= ${#testcases[@]}; i++ ))
do
./${testcases[i-1]} 2>&1;