From 2945363230c1d76d21327e12995a8789ec9df514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Hor=C3=A1k?= 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 0263d2f..8f7bbdb 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 0a64d4c..0a71832 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 42d9baf..3e13a29 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 49cbb09..76f530f 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 f220205..f756597 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 +#include +#include +#include +#include +#include +#include "ica_api.h" +#include +#include +#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 +#include +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#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.38.1 From 740531ec03c7dd79e185136b0b1970aa1cd1d924 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Hor=C3=A1k?= 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 3e13a29..1bd81bb 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.38.1