libica/libica-4.1.1-revert-abi.patch

1619 lines
46 KiB
Diff

From 8f05d0eb92956c2e3e6dce529be9292906beeef8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dan=20Hor=C3=A1k?= <dan@danny.cz>
Date: Tue, 22 Mar 2022 12:43:19 +0100
Subject: [libica PATCH 1/2] Revert "Remove deprecated API functions"
This reverts commit 4a3a77232ee85cf9f4eb7ac2d366b613013b9048.
---
include/ica_api.h | 230 ++++++++++++++++++++++++++++++
libica.map | 8 ++
src/ica_api.c | 258 ++++++++++++++++++++++++++++++++++
src/include/s390_crypto.h | 5 -
test/Makefile.am | 11 +-
test/aes_128_test.c | 284 ++++++++++++++++++++++++++++++++++++++
test/aes_192_test.c | 163 ++++++++++++++++++++++
test/aes_256_test.c | 162 ++++++++++++++++++++++
test/des_test.c | 157 +++++++++++++++++++++
test/tdes_test.c | 148 ++++++++++++++++++++
10 files changed, 1418 insertions(+), 8 deletions(-)
create mode 100644 test/aes_128_test.c
create mode 100644 test/aes_192_test.c
create mode 100644 test/aes_256_test.c
create mode 100644 test/des_test.c
create mode 100644 test/tdes_test.c
diff --git a/include/ica_api.h b/include/ica_api.h
index 99e624f..9b3f14b 100644
--- a/include/ica_api.h
+++ b/include/ica_api.h
@@ -1480,6 +1480,227 @@ unsigned int ica_rsa_crt(ica_adapter_handle_t adapter_handle,
ICA_EXPORT
unsigned int ica_rsa_crt_key_check(ica_rsa_key_crt_t *rsa_key);
+/**
+ * @deprecated, use ica_des_ecb() or ica_des_cbc() instead.
+ *
+ * Encrypt data using a single length DES key.
+ * @param mode Specifies the operational mode and must be:
+ * MODE_ECB - Use Electronic Code Book mode
+ * MODE_CBC - Use Cipher Block Chaining mode
+ * @param data_length
+ * Specifies the byte length of the input data. It has to be a multiple of the
+ * cipher block which has a size of 8 byte.
+ * @param input_data
+ * Pointer to the input data data to be encrypted. Must be a multiple of the
+ * cipher to use hw acceleration.
+ * @param iv
+ * Pointer to a valid 8 byte initialization vector when using CBC mode.
+ * @param des_key
+ * Pointer to a single length DES key.
+ * @param output_data
+ * Pointer to the buffer to contain the resulting encrypted data. Must be a
+ * multiple of the cipher block and at least as big as the buffer for
+ * input_data.
+ *
+ * @return 0 if successful.
+ * EINVAL if at least one invalid parameter is given.
+ * EIO if the operation fails. This should never happen.
+ */
+/* XXX next major: remove */
+ICA_EXPORT ICA_DEPRECATED
+unsigned int ica_des_encrypt(unsigned int mode,
+ unsigned int data_length,
+ unsigned char *input_data,
+ ica_des_vector_t *iv,
+ ica_des_key_single_t *des_key,
+ unsigned char *output_data);
+
+/**
+ * @deprecated, use ica_des_ecb() or ica_des_cbc() instead.
+ *
+ * Decrypt data using a single length DES key.
+ * @param mode
+ * Specifies the operational mode and must be:
+ * MODE_ECB - Use Electronic Code Book mode
+ * MODE_CBC - Use Cipher Block Chaining mode
+ * @param data_length
+ * Specifies the byte length of the input data. It has to be a multiple of the
+ * cipher block which has a size of 8 byte.
+ * @param input_data
+ * Pointer to the input data data to be decrypted. Must be a multiple of the
+ * cipher to use hw acceleration.
+ * @param iv
+ * Pointer to a valid 8 byte initialization vector when using CBC mode.
+ * @param des_key
+ * Pointer to a single length DES key.
+ * @param output_data
+ * Pointer to the buffer to contain the resulting decrypted data. Must be a
+ * multiple of the cipher block and at least as big as the buffer for
+ * input_data.
+ *
+ * @return 0 if successful.
+ * EINVAL if at least one invalid parameter is given.
+ * EIO if the operation fails. This should never happen.
+ */
+/* XXX next major: remove */
+ICA_EXPORT ICA_DEPRECATED
+unsigned int ica_des_decrypt(unsigned int mode,
+ unsigned int data_length,
+ unsigned char *input_data,
+ ica_des_vector_t *iv,
+ ica_des_key_single_t *des_key,
+ unsigned char *output_data);
+
+/**
+ * @deprecated, use ica_3des_ecb() or ica_3des_cbc() instead.
+ *
+ * Encrypt data using a triple length DES key.
+ * @param mode
+ * Specifies the operational mode and must be:
+ * MODE_ECB - Use Electronic Code Book mode
+ * MODE_CBC - Use Cipher Block Chaining mode
+ * @param data_length
+ * Specifies the byte length of the input data. It has to be a multiple of the
+ * cipher block which has a size of 8 byte.
+ * @param input_data
+ * Pointer to the input data data to be encrypted. Must be a multiple of the
+ * cipher block to use hw acceleration.
+ * @param iv
+ * Pointer to a valid 8 byte initialization vector when using CBC mode.
+ * @param des_key
+ * Pointer to a triple length DES key.
+ * @param output_data
+ * Pointer to the buffer to contain the resulting encrypted data. Must be a
+ * multiple of the cipher block and at least as big as the buffer for
+ * input_data.
+ *
+ * @return 0 if successful.
+ * EINVAL if at least one invalid parameter is given.
+ * EIO if the operation fails. This should never happen.
+ */
+/* XXX next major: remove */
+ICA_EXPORT ICA_DEPRECATED
+unsigned int ica_3des_encrypt(unsigned int mode,
+ unsigned int data_length,
+ unsigned char *input_data,
+ ica_des_vector_t *iv,
+ ica_des_key_triple_t *des_key,
+ unsigned char *output_data);
+
+/**
+ * @deprecated, use ica_3des_ecb() or ica_3des_cbc() instead.
+ *
+ * Decrypt data using a triple length DES key.
+ * @param mode
+ * Specifies the operational mode and must be:
+ * MODE_ECB - Use Electronic Code Book mode
+ * MODE_CBC - Use Cipher Block Chaining mode
+ * @param data_length
+ * Specifies the byte length of the input data. It has to be a multiple of the
+ * cipher block which has a size of 8 byte.
+ * @param input_data
+ * Pointer to the input data data to be decrypted. Must be a multiple of the
+ * cipher block to use hw acceleration.
+ * @param iv
+ * Pointer to a valid 8 byte initialization vector when using CBC mode.
+ * @param des_key
+ * Pointer to a triple length DES key.
+ * @param output_data
+ * Pointer to the buffer to contain the resulting decrypted data. Must be a
+ * multiple of the cipher block and at least as big as the buffer for
+ * input_data.
+ *
+ * @return 0 if successful.
+ * EINVAL if at least one invalid parameter is given.
+ * EIO if the operation fails. This should never happen.
+ */
+/* XXX next major: remove */
+ICA_EXPORT ICA_DEPRECATED
+unsigned int ica_3des_decrypt(unsigned int mode,
+ unsigned int data_length,
+ unsigned char *input_data,
+ ica_des_vector_t *iv,
+ ica_des_key_triple_t *des_key,
+ unsigned char *output_data);
+
+/**
+ * @deprecated, use ica_aes_ecb() or ica_aes_cbc() instead.
+ *
+ * Encrypt data using AES (key_length is 16, 24, or 32)
+ * @param mode
+ * Specifies the operational mode and must be:
+ * MODE_ECB - Use Electronic Code Book mode
+ * MODE_CBC - Use Cipher Block Chaining mode
+ * @param data_length
+ * Specifies the byte length of the input data. Input data length has to be
+ * a multiple of the AES block length, which is 16 bytes.
+ * @param input_data
+ * Pointer to the input data data to be encrypted. Must be a multiple of the
+ * cipher block to use hw acceleration.
+ * @param iv
+ * Pointer to a valid 16 byte initialization vector when using CBC mode.
+ * @param key_length
+ * Length of the AES key being used.
+ * @param aes_key
+ * Pointer to an AES key.
+ * @param output_data
+ * Pointer to the buffer to contain the resulting encrypted data. Must be a
+ * multiple of the cipher block and at least as big as the buffer for
+ * input_data.
+ *
+ * @return 0 if successful.
+ * EINVAL if at least one invalid parameter is given.
+ * EIO if the operation fails. This should never happen.
+ */
+/* XXX next major: remove */
+ICA_EXPORT ICA_DEPRECATED
+unsigned int ica_aes_encrypt(unsigned int mode,
+ unsigned int data_length,
+ unsigned char *input_data,
+ ica_aes_vector_t *iv,
+ unsigned int key_length,
+ unsigned char *aes_key,
+ unsigned char *output_data);
+
+/**
+ * @deprecated, use ica_aes_ecb() or ica_aes_cbc() instead.
+ *
+ * Decrypt data using AES (key_length is 16, 24, or 32)
+ * @param mode
+ * Specifies the operational mode and must be:
+ * MODE_ECB - Use Electronic Code Book mode
+ * MODE_CBC - Use Cipher Block Chaining mode
+ * @param data_length
+ * Specifies the byte length of the input data. Input data length has to be
+ * a multiple of the AES block length, which is 16 bytes.
+ * @param input_data
+ * Pointer to the input data to be decrypted. Must be a multiple of the
+ * cipher block to use hw acceleration.
+ * @param iv
+ * Pointer to a valid 16 byte initialization vector when using CBC mode.
+ * @param key_length
+ * Length of the AES key being used.
+ * @param aes_key
+ * Pointer to an AES key.
+ * @param output_data
+ * Pointer to the buffer to contain the resulting decrypted data. Must be a
+ * multiple of the cipher block and at least as big as the buffer for
+ * input_data.
+ *
+ * @return 0 if successful.
+ * EINVAL if at least one invalid parameter is given.
+ * EIO if the operation fails. This should never happen.
+ */
+/* XXX next major: remove */
+ICA_EXPORT ICA_DEPRECATED
+unsigned int ica_aes_decrypt(unsigned int mode,
+ unsigned int data_length,
+ unsigned char *input_data,
+ ica_aes_vector_t *iv,
+ unsigned int key_length,
+ unsigned char *aes_key,
+ unsigned char *output_data);
+
/**
* Encrypt or decrypt data with an DES key using Electronic Cook Book (ECB)
* mode as described in NIST Special Publication 800-38A Chapter 6.1.
@@ -3599,6 +3820,15 @@ int ica_get_hw_info(libica_hw_info *hw_info);
ICA_EXPORT
unsigned int ica_get_version(libica_version_info *version_info);
+/* XXX next major: dont export, move to s390_crypto.h */
+ICA_EXPORT ICA_DEPRECATED
+int s390_initialize_functionlist(void);
+
+/* 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);
+
/**
* Return libica build information.
*
diff --git a/libica.map b/libica.map
index 4c4ce1f..df6aef4 100644
--- a/libica.map
+++ b/libica.map
@@ -3,11 +3,15 @@ LIBICA_3.0.0 {
_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;
@@ -19,6 +23,8 @@ LIBICA_3.0.0 {
ica_des_cmac_intermediate;
ica_des_cmac_last;
+ ica_3des_encrypt;
+ ica_3des_decrypt;
ica_3des_ecb;
ica_3des_cbc;
ica_3des_cbc_cs;
@@ -30,6 +36,8 @@ LIBICA_3.0.0 {
ica_3des_cmac_intermediate;
ica_3des_cmac_last;
+ ica_aes_encrypt;
+ ica_aes_decrypt;
ica_aes_ecb;
ica_aes_cbc;
ica_aes_cbc_cs;
diff --git a/src/ica_api.c b/src/ica_api.c
index c9ea1ad..257a8c5 100644
--- a/src/ica_api.c
+++ b/src/ica_api.c
@@ -2452,6 +2452,264 @@ int ica_ed448_key_gen(ICA_ED448_CTX *ctx)
*
******************************************************************************/
+unsigned int ica_des_encrypt(unsigned int mode,
+ unsigned int data_length,
+ unsigned char *input_data,
+ ica_des_vector_t *iv,
+ ica_des_key_single_t *des_key,
+ unsigned char *output_data)
+{
+#ifdef NO_CPACF
+ UNUSED(mode);
+ UNUSED(data_length);
+ UNUSED(input_data);
+ UNUSED(iv);
+ UNUSED(des_key);
+ UNUSED(output_data);
+ return EPERM;
+#else
+#ifdef ICA_FIPS
+ if (fips)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_des_parms(mode, data_length, input_data,
+ (unsigned char *) iv, (unsigned char *) des_key,
+ output_data))
+ return EINVAL;
+
+ if (mode == MODE_ECB) {
+ return s390_des_ecb(DEA_ENCRYPT, data_length,
+ input_data, (unsigned char *) des_key,
+ output_data);
+ } else if (mode == MODE_CBC) {
+ return s390_des_cbc(DEA_ENCRYPT, data_length,
+ input_data, (unsigned char *) iv,
+ (unsigned char *) des_key, output_data);
+ }
+ return EINVAL;
+#endif /* NO_CPACF */
+}
+
+unsigned int ica_des_decrypt(unsigned int mode,
+ unsigned int data_length,
+ unsigned char *input_data,
+ ica_des_vector_t *iv,
+ ica_des_key_single_t *des_key,
+ unsigned char *output_data)
+{
+#ifdef NO_CPACF
+ UNUSED(mode);
+ UNUSED(data_length);
+ UNUSED(input_data);
+ UNUSED(iv);
+ UNUSED(des_key);
+ UNUSED(output_data);
+ return EPERM;
+#else
+#ifdef ICA_FIPS
+ if (fips)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ if (check_des_parms(mode, data_length, input_data,
+ (unsigned char *) iv, (unsigned char *) des_key,
+ output_data))
+ return EINVAL;
+
+ if (mode == MODE_ECB) {
+ return s390_des_ecb(DEA_DECRYPT, data_length,
+ input_data, (unsigned char *) des_key,
+ output_data);
+ } else if (mode == MODE_CBC) {
+ return s390_des_cbc(DEA_DECRYPT, data_length,
+ input_data, (unsigned char *) iv,
+ (unsigned char *) des_key, output_data);
+ }
+ return EINVAL;
+#endif /* NO_CPACF */
+}
+
+unsigned int ica_3des_encrypt(unsigned int mode,
+ unsigned int data_length,
+ unsigned char *input_data,
+ ica_des_vector_t *iv,
+ ica_des_key_triple_t *des_key,
+ unsigned char *output_data)
+{
+#ifdef NO_CPACF
+ UNUSED(mode);
+ UNUSED(data_length);
+ UNUSED(input_data);
+ UNUSED(iv);
+ UNUSED(des_key);
+ UNUSED(output_data);
+ return EPERM;
+#else
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+ if (fips_check_3des_key(des_key))
+ return EINVAL;
+#endif /* ICA_FIPS */
+
+ if (check_des_parms(mode, data_length, input_data,
+ (unsigned char *) iv, (unsigned char *) des_key,
+ output_data))
+ return EINVAL;
+
+ if (mode == MODE_ECB) {
+ return s390_des_ecb(TDEA_192_ENCRYPT, data_length,
+ input_data,(unsigned char *) des_key,
+ output_data);
+ } else if (mode == MODE_CBC) {
+ return s390_des_cbc(TDEA_192_ENCRYPT, data_length,
+ input_data, (unsigned char *) iv,
+ (unsigned char *) des_key, output_data);
+ }
+ return EINVAL;
+#endif /* NO_CPACF */
+}
+
+unsigned int ica_3des_decrypt(unsigned int mode,
+ unsigned int data_length,
+ unsigned char *input_data,
+ ica_des_vector_t *iv,
+ ica_des_key_triple_t *des_key,
+ unsigned char *output_data)
+{
+#ifdef NO_CPACF
+ UNUSED(mode);
+ UNUSED(data_length);
+ UNUSED(input_data);
+ UNUSED(iv);
+ UNUSED(des_key);
+ UNUSED(output_data);
+ return EPERM;
+#else
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+ if (fips_check_3des_key(des_key))
+ return EINVAL;
+#endif /* ICA_FIPS */
+
+ if (check_des_parms(mode, data_length, input_data,
+ (unsigned char *) iv, (unsigned char *) des_key,
+ output_data))
+ return EINVAL;
+
+ if (mode == MODE_ECB) {
+ return s390_des_ecb(TDEA_192_DECRYPT, data_length,
+ input_data, (unsigned char *) des_key,
+ output_data);
+ } else if (mode == MODE_CBC) {
+ return s390_des_cbc(TDEA_192_DECRYPT, data_length,
+ input_data, (unsigned char *) iv,
+ (unsigned char *) des_key, output_data);
+ }
+ return EINVAL;
+#endif /* NO_CPACF */
+}
+
+unsigned int ica_aes_encrypt(unsigned int mode,
+ unsigned int data_length,
+ unsigned char *input_data,
+ ica_aes_vector_t *iv,
+ unsigned int key_length,
+ unsigned char *aes_key,
+ unsigned char *output_data)
+{
+#ifdef NO_CPACF
+ UNUSED(mode);
+ UNUSED(data_length);
+ UNUSED(input_data);
+ UNUSED(iv);
+ UNUSED(key_length);
+ UNUSED(aes_key);
+ UNUSED(output_data);
+ return EPERM;
+#else
+ unsigned int function_code;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ /* check for obvious errors in parms */
+ if (check_aes_parms(mode, data_length, input_data,
+ (unsigned char *) iv, key_length, aes_key,
+ output_data))
+ return EINVAL;
+
+ function_code = aes_directed_fc(key_length, ICA_ENCRYPT);
+
+ switch (mode) {
+ case MODE_CBC:
+ return s390_aes_cbc(function_code, data_length, input_data,
+ (unsigned char *) iv, aes_key,
+ output_data);
+ case MODE_ECB:
+ return s390_aes_ecb(function_code, data_length, input_data,
+ aes_key, output_data);
+ default:
+ return EINVAL;
+ }
+
+ return EINVAL;
+#endif /* NO_CPACF */
+}
+
+unsigned int ica_aes_decrypt(unsigned int mode,
+ unsigned int data_length,
+ unsigned char *input_data,
+ ica_aes_vector_t *iv,
+ unsigned int key_length,
+ unsigned char *aes_key,
+ unsigned char *output_data)
+{
+#ifdef NO_CPACF
+ UNUSED(mode);
+ UNUSED(data_length);
+ UNUSED(input_data);
+ UNUSED(iv);
+ UNUSED(key_length);
+ UNUSED(aes_key);
+ UNUSED(output_data);
+ return EPERM;
+#else
+ unsigned int function_code;
+
+#ifdef ICA_FIPS
+ if (fips >> 1)
+ return EACCES;
+#endif /* ICA_FIPS */
+
+ /* check for obvious errors in parms */
+ if (check_aes_parms(mode, data_length, input_data,
+ (unsigned char *) iv, key_length, aes_key,
+ output_data))
+ return EINVAL;
+
+ function_code = aes_directed_fc(key_length, ICA_DECRYPT);
+
+ switch (mode) {
+ case MODE_CBC:
+ return s390_aes_cbc(function_code, data_length, input_data,
+ (unsigned char *) iv, aes_key,
+ output_data);
+ case MODE_ECB:
+ return s390_aes_ecb(function_code, data_length, input_data,
+ aes_key, output_data);
+ default:
+ return EINVAL;
+ }
+
+ return EINVAL;
+#endif /* NO_CPACF */
+}
+
unsigned int ica_des_ecb(const unsigned char *in_data, unsigned char *out_data,
unsigned long data_length, unsigned char *key,
unsigned int direction)
diff --git a/src/include/s390_crypto.h b/src/include/s390_crypto.h
index f34241f..d708e8f 100644
--- a/src/include/s390_crypto.h
+++ b/src/include/s390_crypto.h
@@ -30,11 +30,6 @@ int s390_get_fips_indicator(libica_fips_indicator_element *fips_list,
unsigned int *fips_list_len);
#endif
-/* major 4.0: no more exported, now internal */
-int s390_initialize_functionlist(void);
-int s390_get_functionlist(libica_func_list_element *pmech_list,
- unsigned int *pmech_list_len);
-
#ifndef OPENSSL_VERSION_PREREQ
#if defined(OPENSSL_VERSION_MAJOR) && defined(OPENSSL_VERSION_MINOR)
#define OPENSSL_VERSION_PREREQ(maj, min) \
diff --git a/test/Makefile.am b/test/Makefile.am
index dddfc90..bc6b9fd 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -7,16 +7,21 @@ get_version_test \
rng_test \
drbg_test \
drbg_birthdays_test.pl \
+des_test \
des_ecb_test \
des_cbc_test \
des_ctr_test \
des_cfb_test \
des_ofb_test \
+tdes_test \
tdes_ecb_test \
tdes_cbc_test \
tdes_ctr_test \
tdes_cfb_test \
tdes_ofb_test \
+aes_128_test \
+aes_192_test \
+aes_256_test \
aes_ecb_test \
aes_cbc_test \
aes_ctr_test \
@@ -72,10 +77,10 @@ get_functionlist_cex_test_SOURCES = get_functionlist_cex_test.c
get_functionlist_cex_test_LDADD = @LIBS@ ${top_builddir}/src/.libs/libica-cex.so -lcrypto -lpthread
check_PROGRAMS = fips_test icastats_test get_functionlist_test \
-get_version_test rng_test drbg_test drbg_birthdays_test \
+get_version_test rng_test drbg_test drbg_birthdays_test des_test \
des_ecb_test des_cbc_test des_ctr_test des_cfb_test des_ofb_test \
-tdes_ecb_test tdes_cbc_test tdes_ctr_test tdes_cfb_test \
-tdes_ofb_test aes_ecb_test \
+tdes_test tdes_ecb_test tdes_cbc_test tdes_ctr_test tdes_cfb_test \
+tdes_ofb_test aes_128_test aes_192_test aes_256_test aes_ecb_test \
aes_cbc_test aes_ctr_test aes_cfb_test aes_ofb_test aes_xts_test \
aes_gcm_test aes_gcm_kma_test cbccs_test ccm_test cmac_test sha_test \
sha1_test sha256_test sha3_224_test sha3_256_test sha3_384_test \
diff --git a/test/aes_128_test.c b/test/aes_128_test.c
new file mode 100644
index 0000000..d5667bb
--- /dev/null
+++ b/test/aes_128_test.c
@@ -0,0 +1,284 @@
+/* This program is released under the Common Public License V1.0
+ *
+ * You should have received a copy of Common Public License V1.0 along with
+ * with this program.
+ */
+
+/* Copyright IBM Corp. 2005, 2009, 2011 */
+#include <fcntl.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include "ica_api.h"
+#include <stdlib.h>
+#include <openssl/aes.h>
+#include "testcase.h"
+
+unsigned char NIST_KEY1[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+};
+
+unsigned char NIST_TEST_DATA[] = {
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+};
+
+unsigned char NIST_TEST_RESULT[] = {
+ 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
+ 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a,
+};
+
+int test_aes128_new_api(int mode)
+{
+ ica_aes_vector_t iv;
+ unsigned char key[AES_KEY_LEN128];
+ int rc = 0;
+ unsigned char dec_text[sizeof(NIST_TEST_DATA)],
+ enc_text[sizeof(NIST_TEST_DATA)];
+
+ bzero(dec_text, sizeof(dec_text));
+ bzero(enc_text, sizeof(enc_text));
+ bzero(iv, sizeof(iv));
+ bcopy(NIST_KEY1, key, sizeof(NIST_KEY1));
+
+ rc = ica_aes_encrypt(mode, sizeof(NIST_TEST_DATA), NIST_TEST_DATA, &iv,
+ AES_KEY_LEN128, key, enc_text);
+ if (rc) {
+ VV_(printf("key \n"));
+ dump_array((unsigned char *) key, sizeof(NIST_KEY1));
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char *) NIST_TEST_DATA, sizeof(NIST_TEST_DATA));
+ VV_(printf("test iv\n"));
+ dump_array((unsigned char *) &iv, sizeof(ica_aes_vector_t));
+ VV_(printf("key\n"));
+ dump_array((unsigned char *) key, AES_KEY_LEN128);
+ VV_(printf("ica_aes_encrypt failed with errno %d (0x%x).\n", rc, rc));
+ return TEST_FAIL;
+ }
+
+ if (memcmp(enc_text, NIST_TEST_RESULT, sizeof(NIST_TEST_RESULT)) != 0) {
+ VV_(printf("key \n"));
+ dump_array((unsigned char *) key, sizeof(NIST_KEY1));
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char *) NIST_TEST_DATA, sizeof(NIST_TEST_DATA));
+ VV_(printf("test iv\n"));
+ dump_array((unsigned char *) &iv, sizeof(ica_aes_vector_t));
+ VV_(printf("key\n"));
+ dump_array((unsigned char *) key, AES_KEY_LEN128);
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char *) enc_text, sizeof(enc_text));
+ VV_(printf("This does NOT match the known result.\n"));
+ return TEST_FAIL;
+ } else {
+ VV_(printf("Yep, it's what it should be.\n"));
+ }
+
+ bzero(iv, sizeof(iv));
+ rc = ica_aes_decrypt(mode, sizeof(enc_text), enc_text, &iv,
+ AES_KEY_LEN128, key, dec_text);
+ if (rc) {
+ VV_(printf("key \n"));
+ dump_array((unsigned char *) key, sizeof(NIST_KEY1));
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char *) NIST_TEST_DATA, sizeof(NIST_TEST_DATA));
+ VV_(printf("test iv\n"));
+ dump_array((unsigned char *) &iv, sizeof(ica_aes_vector_t));
+ VV_(printf("key\n"));
+ dump_array((unsigned char *) key, AES_KEY_LEN128);
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char *) enc_text, sizeof(enc_text));
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array((unsigned char *) dec_text, sizeof(dec_text));
+ VV_(printf("ica_aes_decrypt failed with errno %d (0x%x).\n", rc, rc));
+ return TEST_FAIL;
+ }
+
+ if (memcmp(dec_text, NIST_TEST_DATA, sizeof(NIST_TEST_DATA)) != 0) {
+ VV_(printf("This does NOT match the original data.\n"));
+ return TEST_FAIL;
+ } else {
+ VV_(printf("Successful!\n"));
+ VV_(printf("key \n"));
+ dump_array((unsigned char *) key, sizeof(NIST_KEY1));
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char *) NIST_TEST_DATA, sizeof(NIST_TEST_DATA));
+ VV_(printf("test iv\n"));
+ dump_array((unsigned char *) &iv, sizeof(ica_aes_vector_t));
+ VV_(printf("key\n"));
+ dump_array((unsigned char *) key, AES_KEY_LEN128);
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char *) enc_text, sizeof(enc_text));
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array((unsigned char *) dec_text, sizeof(dec_text));
+ }
+
+// Test 2
+
+ rc = 0;
+ bzero(dec_text, sizeof(dec_text));
+ bzero(enc_text, sizeof(enc_text));
+ bzero(iv, sizeof(iv));
+ bzero(key, sizeof(key));
+
+ unsigned int length = 64;
+ unsigned char *decrypt = malloc(length);
+ unsigned char *encrypt = malloc(length);
+ unsigned char *original = malloc(length);
+ ica_aes_key_len_128_t key2;
+
+ rc = ica_random_number_generate(length, original);
+ if (rc) {
+ VV_(printf("ica_random_number_generate returned rc = %i\n", rc));
+ return TEST_FAIL;
+ }
+
+ rc = ica_random_number_generate(AES_KEY_LEN128, (unsigned char *) &key2);
+ if (rc) {
+ VV_(printf("ica_random_number_generate returned rc = %i\n", rc));
+ return TEST_FAIL;
+ }
+
+ rc = ica_aes_encrypt(mode, length, original, &iv, AES_KEY_LEN128, (unsigned char *) &key2,
+ (unsigned char *) encrypt);
+ if (rc) {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char *) original, length);
+ VV_(printf("KEY: \n"));
+ dump_array((unsigned char *) &key2, AES_KEY_LEN128);
+ VV_(printf("ica_aes_encrypt failed with errno %d (0x%x).\n", rc, rc));
+ return TEST_FAIL;
+ }
+
+ if (memcmp(encrypt, original, length) == 0) {
+ VV_(printf("Encrypt and original are the same.\n"));
+ return TEST_FAIL;
+ }
+
+ bzero(iv, sizeof(iv));
+ rc = ica_aes_decrypt(mode, length, encrypt, &iv, AES_KEY_LEN128,
+ (unsigned char *) &key2, decrypt);
+ if (rc) {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char *) original, length);
+ VV_(printf("KEY: \n"));
+ dump_array((unsigned char *) &key2, AES_KEY_LEN128);
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char *) encrypt, length);
+ VV_(printf("ica_aes_decrypt failed with errno %d (0x%x).\n", rc, rc));
+ goto free;
+ }
+
+ if (memcmp(decrypt, original, length) != 0) {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char *) original, length);
+ VV_(printf("KEY: \n"));
+ dump_array((unsigned char *) &key2, AES_KEY_LEN128);
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char *) encrypt, length);
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array((unsigned char *) decrypt, length);
+ VV_(printf("This does NOT match the original data.\n"));
+ rc = -1;
+ goto free;
+ }
+
+ if(memcmp(decrypt, encrypt, length) == 0) {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char *) original, length);
+ VV_(printf("KEY: \n"));
+ dump_array((unsigned char *) &key2, AES_KEY_LEN128);
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char *) encrypt, length);
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array((unsigned char *) decrypt, length);
+ VV_(printf("decrypt and encrypt are the same\n"));
+ rc = -1;
+ goto free;
+
+ } else {
+ VV_(printf("Successful!\n"));
+ }
+free:
+ free(original);
+ free(encrypt);
+ free(decrypt);
+
+ if (rc)
+ return TEST_FAIL;
+
+ return TEST_SUCC;
+}
+
+/*
+ * Performs ECB and CBC tests.
+ */
+int main(int argc, char **argv)
+{
+#ifdef NO_CPACF
+ UNUSED(argc);
+ UNUSED(argv);
+ printf("Skipping AES-128 test, because CPACF support disabled via config option.\n");
+ return TEST_SKIP;
+#else
+ unsigned int mode = 0;
+ int rc = 0;
+ int error_count = 0;
+
+ if (argc > 1) {
+ if (strstr(argv[1], "ecb"))
+ mode = MODE_ECB;
+ if (strstr(argv[1], "cbc"))
+ mode = MODE_CBC;
+ }
+
+ if (argc > 2) {
+ if (strstr(argv[2], "ecb"))
+ mode = MODE_ECB;
+ if (strstr(argv[2], "cbc"))
+ mode = MODE_CBC;
+ }
+
+ set_verbosity(argc, argv);
+
+ if (mode != 0 && mode != MODE_ECB && mode != MODE_CBC) {
+ printf("Usage: %s [ ecb | cbc ]\n", argv[0]);
+ return TEST_ERR;
+ }
+
+ if (!mode) {
+ /* This is the standard loop that will perform all testcases */
+ mode = 2;
+ while (mode) {
+ rc = test_aes128_new_api(mode);
+ if (rc) {
+ error_count++;
+ V_(printf ("test_aes_new_api mode = %i failed \n", mode));
+ }
+ else {
+ V_(printf ("test_aes_new_api mode = %i finished.\n", mode));
+ }
+ mode--;
+ }
+ if (error_count)
+ printf("%i AES-128-ECB/CBC tests failed.\n", error_count);
+ else
+ printf("All AES-128-ECB/CBC tests passed.\n");
+ } else {
+ /* Perform only either in ECB or CBC mode */
+ rc = test_aes128_new_api(mode);
+ if (rc)
+ printf ("test_aes_new_api mode = %i failed \n", mode);
+ else {
+ printf ("test_aes_new_api mode = %i finished.\n", mode);
+ }
+ }
+
+ if (rc)
+ return TEST_FAIL;
+
+ return TEST_SUCC;
+#endif /* NO_CPACF */
+}
diff --git a/test/aes_192_test.c b/test/aes_192_test.c
new file mode 100644
index 0000000..e803f39
--- /dev/null
+++ b/test/aes_192_test.c
@@ -0,0 +1,163 @@
+/* This program is released under the Common Public License V1.0
+ *
+ * You should have received a copy of Common Public License V1.0 along with
+ * with this program.
+ */
+
+/* Copyright IBM Corp. 2005, 2009, 2011 */
+#include <fcntl.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include "ica_api.h"
+#include "testcase.h"
+
+unsigned char NIST_KEY2[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+};
+
+unsigned char NIST_TEST_DATA[] = {
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+};
+
+unsigned char NIST_TEST_RESULT[] = {
+ 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
+ 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91,
+};
+
+int test_aes192_new_api(int mode)
+{
+ ica_aes_vector_t iv;
+ ica_aes_key_len_192_t key;
+ int rc = 0;
+ unsigned char dec_text[sizeof(NIST_TEST_DATA)],
+ enc_text[sizeof(NIST_TEST_DATA)];
+
+ bzero(dec_text, sizeof(dec_text));
+ bzero(enc_text, sizeof(enc_text));
+ bzero(iv, sizeof(iv));
+ bcopy(NIST_KEY2, key, sizeof(NIST_KEY2));
+
+ rc = ica_aes_encrypt(mode, sizeof(NIST_TEST_DATA), NIST_TEST_DATA, &iv,
+ AES_KEY_LEN192, (unsigned char *) &key, enc_text);
+ if (rc) {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char*)NIST_TEST_DATA, sizeof(NIST_TEST_DATA));
+ VV_(printf("ica_aes_encrypt failed with errno %d (0x%x).\n", rc, rc));
+ return TEST_FAIL;
+ }
+
+ if (memcmp(enc_text, NIST_TEST_RESULT, sizeof(NIST_TEST_RESULT)) != 0) {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char*)NIST_TEST_DATA, sizeof(NIST_TEST_DATA));
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char*)enc_text, sizeof(enc_text));
+ VV_(printf("This does NOT match the known result.\n"));
+ return TEST_FAIL;
+ } else {
+ VV_(printf("Yep, it's what it should be.\n"));
+ }
+
+ bzero(iv, sizeof(iv));
+ rc = ica_aes_decrypt(mode, sizeof(enc_text), enc_text, &iv,
+ AES_KEY_LEN192, (unsigned char *) &key, dec_text);
+ if (rc != 0) {
+ VV_(printf("ica_aes_decrypt failed with errno %d (0x%x).\n", rc, rc));
+ return TEST_FAIL;
+ }
+
+ if (memcmp(dec_text, NIST_TEST_DATA, sizeof(NIST_TEST_DATA)) != 0) {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char*)NIST_TEST_DATA, sizeof(NIST_TEST_DATA));
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char*)enc_text, sizeof(enc_text));
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array((unsigned char*)dec_text, sizeof(dec_text));
+ VV_(printf("This does NOT match the original data.\n"));
+ return TEST_FAIL;
+ } else {
+ VV_(printf("Successful!\n"));
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char*)NIST_TEST_DATA, sizeof(NIST_TEST_DATA));
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char*)enc_text, sizeof(enc_text));
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array((unsigned char*)dec_text, sizeof(dec_text));
+ }
+
+ return TEST_SUCC;
+}
+
+/*
+ * Performs ECB and CBC tests.
+ */
+int main(int argc, char **argv)
+{
+#ifdef NO_CPACF
+ UNUSED(argc);
+ UNUSED(argv);
+ printf("Skipping AES-192 test, because CPACF support disabled via config option.\n");
+ return TEST_SKIP;
+#else
+ unsigned int mode = 0;
+ int rc = 0;
+ int error_count = 0;
+
+ if (argc > 1) {
+ if (strstr(argv[1], "ecb"))
+ mode = MODE_ECB;
+ if (strstr(argv[1], "cbc"))
+ mode = MODE_CBC;
+ }
+ if (argc > 2) {
+ if (strstr(argv[2], "ecb"))
+ mode = MODE_ECB;
+ if (strstr(argv[2], "cbc"))
+ mode = MODE_CBC;
+ }
+
+ set_verbosity(argc, argv);
+
+ if (mode != 0 && mode != MODE_ECB && mode != MODE_CBC) {
+ printf("Usage: %s [ ecb | cbc ]\n", argv[0]);
+ return TEST_ERR;
+ }
+
+ if (!mode) {
+ /* This is the standard loop that will perform all testcases */
+ mode = 2;
+ while (mode) {
+ rc = test_aes192_new_api(mode);
+ if (rc) {
+ error_count++;
+ V_(printf ("test_aes_new_api mode = %i failed \n", mode));
+ } else {
+ V_(printf ("test_aes_new_api mode = %i finished.\n", mode));
+ }
+ mode--;
+ }
+ if (error_count)
+ printf("%i AES-192-ECB/CBC tests failed.\n", error_count);
+ else
+ printf("All AES-192-ECB/CBC tests passed.\n");
+ } else {
+ /* Perform only either in ECB or CBC mode */
+ rc = test_aes192_new_api(mode);
+ if (rc)
+ printf ("test_aes_new_api mode = %i failed \n", mode);
+ else {
+ printf ("test_aes_new_api mode = %i finished.\n", mode);
+ }
+ }
+
+ if (rc)
+ return TEST_FAIL;
+
+ return TEST_SUCC;
+#endif /* NO_CPACF */
+}
diff --git a/test/aes_256_test.c b/test/aes_256_test.c
new file mode 100644
index 0000000..30f01f0
--- /dev/null
+++ b/test/aes_256_test.c
@@ -0,0 +1,162 @@
+/* This program is released under the Common Public License V1.0
+ *
+ * You should have received a copy of Common Public License V1.0 along with
+ * with this program.
+ */
+
+/* Copyright IBM Corp. 2005, 2009, 2011 */
+#include <fcntl.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include "ica_api.h"
+#include "testcase.h"
+
+unsigned char NIST_KEY3[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+};
+
+unsigned char NIST_TEST_DATA[] = {
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+};
+
+unsigned char NIST_TEST_RESULT[] = {
+ 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
+ 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89,
+};
+
+int test_aes256_new_api(int mode)
+{
+ ica_aes_vector_t iv;
+ unsigned char key[AES_KEY_LEN256];
+ int rc = 0;
+ unsigned char dec_text[sizeof(NIST_TEST_DATA)],
+ enc_text[sizeof(NIST_TEST_DATA)];
+
+ bzero(dec_text, sizeof(dec_text));
+ bzero(enc_text, sizeof(enc_text));
+ bzero(iv, sizeof(iv));
+ bcopy(NIST_KEY3, key, sizeof(NIST_KEY3));
+
+ rc = ica_aes_encrypt(mode, sizeof(NIST_TEST_DATA), NIST_TEST_DATA, &iv,
+ AES_KEY_LEN256, key, enc_text);
+ if (rc) {
+ VV_(printf("ica_aes_encrypt failed with errno %d (0x%x).\n", rc, rc));
+ return TEST_FAIL;
+ }
+
+ if (memcmp(enc_text, NIST_TEST_RESULT, sizeof(NIST_TEST_RESULT)) != 0) {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char *) NIST_TEST_DATA, sizeof(NIST_TEST_DATA));
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char *) enc_text, sizeof(enc_text));
+ VV_(printf("This does NOT match the known result.\n"));
+ return TEST_FAIL;
+ } else {
+ VV_(printf("Yep, it's what it should be.\n"));
+ }
+
+ bzero(iv, sizeof(iv));
+ rc = ica_aes_decrypt(mode, sizeof(enc_text), enc_text, &iv,
+ AES_KEY_LEN256, key, dec_text);
+ if (rc) {
+ VV_(printf("ica_aes_decrypt failed with errno %d (0x%x).\n", rc, rc));
+ return TEST_FAIL;
+ }
+
+ if (memcmp(dec_text, NIST_TEST_DATA, sizeof(NIST_TEST_DATA)) != 0) {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char *) NIST_TEST_DATA, sizeof(NIST_TEST_DATA));
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char *) enc_text, sizeof(enc_text));
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array((unsigned char *) dec_text, sizeof(dec_text));
+ VV_(printf("This does NOT match the original data.\n"));
+ return TEST_FAIL;
+ } else {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array((unsigned char *) NIST_TEST_DATA, sizeof(NIST_TEST_DATA));
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array((unsigned char *) enc_text, sizeof(enc_text));
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array((unsigned char *) dec_text, sizeof(dec_text));
+ VV_(printf("Successful!\n"));
+ }
+
+ return TEST_SUCC;
+}
+
+/*
+ * Performs ECB and CBC tests.
+ */
+int main(int argc, char **argv)
+{
+#ifdef NO_CPACF
+ UNUSED(argc);
+ UNUSED(argv);
+ printf("Skipping AES-256 test, because CPACF support disabled via config option.\n");
+ return TEST_SKIP;
+#else
+ unsigned int mode = 0;
+ int rc = 0;
+ int error_count = 0;
+
+ if (argc > 1) {
+ if (strstr(argv[1], "ecb"))
+ mode = MODE_ECB;
+ if (strstr(argv[1], "cbc"))
+ mode = MODE_CBC;
+ }
+ if (argc > 2) {
+ if (strstr(argv[2], "ecb"))
+ mode = MODE_ECB;
+ if (strstr(argv[2], "cbc"))
+ mode = MODE_CBC;
+ }
+
+ set_verbosity(argc, argv);
+
+ if (mode != 0 && mode != MODE_ECB && mode != MODE_CBC) {
+ printf("Usage: %s [ ecb | cbc ]\n", argv[0]);
+ return TEST_ERR;
+ }
+
+ if (!mode) {
+ /* This is the standard loop that will perform all testcases */
+ mode = 2;
+ while (mode) {
+ rc = test_aes256_new_api(mode);
+ if (rc) {
+ error_count++;
+ V_(printf ("test_aes_new_api mode = %i failed \n", mode));
+ }
+ else {
+ V_(printf ("test_aes_new_api mode = %i finished.\n", mode));
+ }
+ mode--;
+ }
+ if (error_count)
+ printf("%i AES-256-ECB/CBC tests failed.\n", error_count);
+ else
+ printf("All AES-256-ECB/CBC tests passed.\n");
+ } else {
+ /* Perform only either in ECB or CBC mode */
+ rc = test_aes256_new_api(mode);
+ if (rc)
+ printf("test_aes_new_api mode = %i failed \n", mode);
+ else
+ printf("test_aes_new_api mode = %i finished.\n", mode);
+ }
+
+ if (rc)
+ return TEST_FAIL;
+
+ return TEST_SUCC;
+#endif /* NO_CPACF */
+}
diff --git a/test/des_test.c b/test/des_test.c
new file mode 100644
index 0000000..c796792
--- /dev/null
+++ b/test/des_test.c
@@ -0,0 +1,157 @@
+/* This program is released under the Common Public License V1.0
+ *
+ * You should have received a copy of Common Public License V1.0 along with
+ * with this program.
+ */
+
+/* Copyright IBM Corp. 2001, 2009, 2011 */
+#include <fcntl.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include "ica_api.h"
+#include "testcase.h"
+
+const int cipher_buf_length = 8;
+
+unsigned char NIST_KEY1[] =
+ { 0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57 };
+
+unsigned char NIST_TEST_DATA[] =
+ { 0x01, 0xa1, 0xd6, 0xd0, 0x39, 0x77, 0x67, 0x42 };
+
+unsigned char NIST_TEST_RESULT[] =
+ { 0x69, 0x0f, 0x5b, 0x0d, 0x9a, 0x26, 0x93, 0x9b };
+
+int test_des_new_api(int mode)
+{
+ ica_des_vector_t iv;
+ ica_des_key_single_t key;
+ int rc = 0;
+ unsigned char dec_text[sizeof NIST_TEST_DATA],
+ enc_text[sizeof NIST_TEST_DATA];
+
+ bzero(dec_text, sizeof dec_text);
+ bzero(enc_text, sizeof enc_text);
+ bzero(iv, sizeof iv);
+ bcopy(NIST_KEY1, key, sizeof NIST_KEY1);
+
+ rc = ica_des_encrypt(mode, sizeof NIST_TEST_DATA, NIST_TEST_DATA, &iv,
+ &key, enc_text);
+ if (rc) {
+ VV_(printf("\nOriginal data:\n");
+ dump_array(NIST_TEST_DATA, sizeof NIST_TEST_DATA));
+ VV_(printf("ica_des_encrypt failed with errno %d (0x%x).\n", rc, rc));
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array(enc_text, sizeof enc_text);
+ return TEST_FAIL;
+ }
+
+ if (memcmp(enc_text, NIST_TEST_RESULT, sizeof NIST_TEST_RESULT) != 0) {
+ VV_(printf("This does NOT match the known result.\n"));
+ return TEST_FAIL;
+ } else {
+ VV_(printf("Yep, it's what it should be.\n"));
+ }
+
+ bzero(iv, sizeof iv);
+ rc = ica_des_decrypt(mode, sizeof enc_text, enc_text, &iv, &key,
+ dec_text);
+ if (rc) {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array(NIST_TEST_DATA, sizeof NIST_TEST_DATA);
+ VV_(printf("ica_des_encrypt failed with errno %d (0x%x).\n", rc, rc));
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array(enc_text, sizeof enc_text);
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array(dec_text, sizeof dec_text);
+ VV_(printf("ica_des_decrypt failed with errno %d (0x%x).\n", rc, rc));
+ return TEST_FAIL;
+ }
+
+ if (memcmp(dec_text, NIST_TEST_DATA, sizeof NIST_TEST_DATA) != 0) {
+ VV_(printf("\nOriginal data:\n"));
+ dump_array(NIST_TEST_DATA, sizeof NIST_TEST_DATA);
+ VV_(printf("ica_des_encrypt failed with errno %d (0x%x).\n", rc, rc));
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array(enc_text, sizeof enc_text);
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array(dec_text, sizeof dec_text);
+ VV_(printf("This does NOT match the original data.\n"));
+ return TEST_FAIL;
+ } else {
+ VV_(printf("Successful!\n"));
+ }
+
+ return TEST_SUCC;
+}
+
+int main(int argc, char **argv)
+{
+#ifdef NO_CPACF
+ UNUSED(argc);
+ UNUSED(argv);
+ printf("Skipping DES test, because CPACF support disabled via config option.\n");
+ return TEST_SKIP;
+#else
+ unsigned int mode = 0;
+ int rc = 0;
+ int error_count = 0;
+
+ set_verbosity(argc, argv);
+
+#ifdef ICA_FIPS
+ if (ica_fips_status() & ICA_FIPS_MODE) {
+ printf("All DES new api tests skipped."
+ " (DES not FIPS approved)\n");
+ return TEST_SKIP;
+ }
+#endif /* ICA_FIPS */
+
+ if (argc > 1) {
+ if (strstr(argv[1], "ecb"))
+ mode = MODE_ECB;
+ if (strstr(argv[1], "cbc"))
+ mode = MODE_CBC;
+ V_(printf("mode = %i \n", mode));
+ }
+
+ if (mode != 0 && mode != MODE_ECB && mode != MODE_CBC) {
+ printf("Usage: %s [ ecb | cbc ]\n", argv[0]);
+ return TEST_ERR;
+ }
+ if (!mode) {
+ /* This is the standard loop that will perform all testcases */
+ mode = 2;
+ while (mode) {
+ rc = test_des_new_api(mode);
+ if (rc) {
+ error_count++;
+ V_(printf ("test_des_new_api mode = %i failed \n", mode));
+ }
+ else {
+ V_(printf ("test_des_new_api mode = %i finished.\n", mode));
+ }
+ mode--;
+ }
+ if (error_count)
+ printf("%i tests failed.\n", error_count);
+ else
+ printf("All tests passed.\n");
+ } else {
+ /* Perform only either in ECB or CBC mode */
+ rc = test_des_new_api(mode);
+ if (rc)
+ printf ("test_des_new_api mode = %i failed \n", mode);
+ else
+ printf ("test_des_new_api mode = %i finished.\n", mode);
+ }
+
+ if (rc)
+ return TEST_FAIL;
+
+ return TEST_SUCC;
+#endif /* NO_CPACF */
+}
diff --git a/test/tdes_test.c b/test/tdes_test.c
new file mode 100644
index 0000000..bfa33c2
--- /dev/null
+++ b/test/tdes_test.c
@@ -0,0 +1,148 @@
+/* This program is released under the Common Public License V1.0
+ *
+ * You should have received a copy of Common Public License V1.0 along with
+ * with this program.
+ */
+
+/* Copyright IBM Corp. 2001, 2009, 2011 */
+#include <fcntl.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include "ica_api.h"
+#include "testcase.h"
+
+unsigned char KEY1[] =
+ { 0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57 };
+
+unsigned char KEY2[] =
+ { 0x8c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57 };
+
+unsigned char KEY3[] =
+ { 0x9c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57 };
+
+unsigned char TEST_DATA[] =
+ { 0x01, 0xa1, 0xd6, 0xd0, 0x39, 0x77, 0x67, 0x42 };
+
+unsigned char TEST_RESULT[] =
+ { 0x90, 0x9c, 0xbc, 0x01, 0xc5, 0x1f, 0x09, 0x60 };
+
+int test_3des_new_api(int mode)
+{
+ ica_des_vector_t iv;
+ ica_des_key_triple_t key;
+ int rc = 0;
+ unsigned char dec_text[sizeof(TEST_DATA)],
+ enc_text[sizeof(TEST_DATA)];
+
+ bzero(dec_text, sizeof(dec_text));
+ bzero(enc_text, sizeof(enc_text));
+ bzero(iv, sizeof(iv));
+ bcopy(KEY1, key.key1, sizeof(KEY1));
+ bcopy(KEY2, key.key2, sizeof(KEY2));
+ bcopy(KEY3, key.key3, sizeof(KEY3));
+
+ VV_(printf("\nOriginal data:\n"));
+ dump_array(TEST_DATA, sizeof(TEST_DATA));
+
+ rc = ica_3des_encrypt(mode, sizeof(TEST_DATA), TEST_DATA,
+ &iv, &key, enc_text);
+ if (rc != 0) {
+ VV_(printf("ica_3des_encrypt failed with errno %d (0x%x).\n", rc, rc));
+ return TEST_FAIL;
+ }
+
+ VV_(printf("\nEncrypted data:\n"));
+ dump_array(enc_text, sizeof(enc_text));
+ if (memcmp(enc_text, TEST_RESULT, sizeof TEST_RESULT) != 0) {
+ VV_(printf("This does NOT match the known result.\n"));
+ return TEST_FAIL;
+ } else {
+ VV_(printf("Yep, it's what it should be.\n"));
+ }
+
+ bzero(iv, sizeof(iv));
+ rc = ica_3des_decrypt(mode, sizeof(enc_text), enc_text,
+ &iv, &key, dec_text);
+ if (rc != 0) {
+ VV_(printf("ica_3des_decrypt failed with errno %d (0x%x).\n", rc, rc));
+ return TEST_FAIL;
+ }
+
+ VV_(printf("\nDecrypted data:\n"));
+ dump_array(dec_text, sizeof(dec_text));
+ if (memcmp(dec_text, TEST_DATA, sizeof(TEST_DATA)) != 0) {
+ VV_(printf("This does NOT match the original data.\n"));
+ return TEST_FAIL;
+ } else {
+ VV_(printf("Successful!\n"));
+ }
+
+ return TEST_SUCC;
+}
+
+/*
+ * Performs ECB and CBC tests.
+ */
+int main(int argc, char **argv)
+{
+#ifdef NO_CPACF
+ UNUSED(argc);
+ UNUSED(argv);
+ printf("Skipping TDES test, because CPACF support disabled via config option.\n");
+ return TEST_SKIP;
+#else
+ unsigned int mode = 0;
+ int rc = 0;
+ int error_count = 0;
+
+ if (argc > 1) {
+ if (strstr(argv[1], "ecb"))
+ mode = MODE_ECB;
+ if (strstr(argv[1], "cbc"))
+ mode = MODE_CBC;
+ V_(printf("mode = %i \n", mode));
+ }
+ if (mode != 0 && mode != MODE_ECB && mode != MODE_CBC) {
+ printf("Usage: %s [ ecb | cbc ]\n", argv[0]);
+ return TEST_ERR;
+ }
+
+ set_verbosity(argc, argv);
+
+ if (!mode) {
+ /* This is the standard loop that will perform all testcases */
+ mode = 2;
+ while (mode) {
+ rc = test_3des_new_api(mode);
+ if (rc) {
+ error_count++;
+ V_(printf ("test_des_new_api mode = %i failed \n", mode));
+ }
+ else {
+ V_(printf ("test_des_new_api mode = %i finished.\n", mode));
+ }
+
+ mode--;
+ }
+ if (error_count)
+ printf("%i tests failed.\n", error_count);
+ else
+ printf("All tests passed.\n");
+ } else {
+ /* Perform only either in ECB or CBC mode */
+ rc = test_3des_new_api(mode);
+ if (rc)
+ printf ("test_des_new_api mode = %i failed \n", mode);
+ else
+ printf ("test_des_new_api mode = %i finished.\n", mode);
+ }
+
+ if (rc || error_count)
+ return TEST_FAIL;
+
+ return TEST_SUCC;
+#endif /* NO_CPACF */
+}
+
--
2.40.1
From 234a63495a2f9d5170d49b8f5d11cd3ac6056fde Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dan=20Hor=C3=A1k?= <dan@danny.cz>
Date: Tue, 25 Oct 2022 13:54:11 +0200
Subject: [libica PATCH 2/2] add back fips_check_3des_key()
Partially revert 56b9ac0669e4d204ecb3f23e5404c2351cca96a2 by adding back
a function that's required by the previously reverted code.
---
src/ica_api.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/ica_api.c b/src/ica_api.c
index 257a8c5..9564610 100644
--- a/src/ica_api.c
+++ b/src/ica_api.c
@@ -93,6 +93,16 @@ void ica_set_stats_mode(int stats_mode)
}
#ifndef NO_CPACF
+#ifdef ICA_FIPS
+static unsigned int fips_check_3des_key(const ica_des_key_triple_t *key) {
+ if (!CRYPTO_memcmp(key->key1, key->key2, DES_KEY_LEN64)
+ | !CRYPTO_memcmp(key->key1, key->key3, DES_KEY_LEN64)
+ | !CRYPTO_memcmp(key->key2, key->key3, DES_KEY_LEN64))
+ return EINVAL;
+
+ return 0;
+}
+#endif
static unsigned int check_des_parms(unsigned int mode,
unsigned long data_length,
--
2.40.1