diff options
Diffstat (limited to 'src/tests')
55 files changed, 14591 insertions, 0 deletions
diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am new file mode 100644 index 0000000..149961d --- /dev/null +++ b/src/tests/Makefile.am @@ -0,0 +1,51 @@ +#OPTS = -O0 -g -Wall -fprofile-arcs -ftest-coverage -fPIC +#OPTS = -O0 -g -Wall -m31 -D_LINUX_S390_ + +if DEBUG +OPTS = -O0 -g -Wall -D_LINUX_S390_ -D_GNU_SOURCE -pthread -fstack-protector-all +else +OPTS = -O0 -g -Wall -D_LINUX_S390_ -D_GNU_SOURCE -pthread +endif + +if ICA_FIPS +OPTS += -DICA_FIPS +endif + +LIBS = -L../.libs +INCLUDE = -I. -I../include -I../../include +CC = gcc + +TARGETS = icastats_test \ + libica_des_test libica_3des_test \ + libica_aes128_test libica_aes192_test libica_aes256_test \ + libica_sha1_test \ + libica_sha256_test \ + libica_rsa_test libica_rsa_key_check_test \ + libica_rng_test libica_keygen_test \ + libica_cmac_test \ + libica_aes_xts_test libica_aes_gcm_test libica_ccm_test \ + libica_aes_ctr_test libica_aes_ofb_test libica_aes_cfb_test \ + libica_aes_cbc_test libica_aes_ecb_test \ + libica_des_ctr_test libica_3des_ctr_test \ + libica_des_cfb_test libica_3des_cfb_test \ + libica_des_cbc_test libica_3des_cbc_test \ + libica_des_ecb_test libica_cbccs_test libica_3des_ecb_test \ + libica_des_ofb_test libica_3des_ofb_test \ + libica_get_version \ + libica_get_functionlist \ + libica_drbg_test \ + libica_drbg_birthdays \ + libica_fips_test + +all: $(TARGETS) + +# Every target is created from a single .c file. +%: %.c + gcc $(OPTS) -o $@ $^ $(LIBS) $(INCLUDE) -lica -lcrypto + +clean: + rm -f $(TARGETS) + +distclean: + rm -f Makefile + rm -f $(TARGETS) diff --git a/src/tests/icastats_test.c b/src/tests/icastats_test.c new file mode 100644 index 0000000..f277a69 --- /dev/null +++ b/src/tests/icastats_test.c @@ -0,0 +1,881 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + **/ + +/* Copyright IBM Corp. 2014 */ + + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <dirent.h> +#include <string.h> +#include <ctype.h> +#include "ica_api.h" +#include "s390_crypto.h" +#include "testcase.h" + +#define DATA_LENGHT 32 +#define DES_CIPHER_BLOCK 8 +#define AES_CIPHER_BLOCK 16 +#define RSA_BYTE_LENGHT 128 + +unsigned char plain_data[] = { + 0x55, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x6c, 0x69, + 0x62, 0x69, 0x63, 0x61, 0x20, 0x69, 0x73, 0x20, + 0x73, 0x6d, 0x61, 0x72, 0x74, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x65, 0x61, 0x73, 0x79, 0x21, 0x00, +}; + +int hw_flag; +unsigned int mech_len; +libica_func_list_element *pmech_list = NULL; + +static int handle_ica_error(int rc, char *message); +static int is_crypto_card_loaded(); +void create_hw_info(); +int check_hw(int algo_id); +void check_icastats(int algo_id, char *stat); +void des_tests(unsigned char *iv, unsigned char *cmac, unsigned char *ctr); +void tdes_tests(unsigned char *iv, unsigned char *cmac, unsigned char *ctr); +void sha_tests(); +void rsa_tests(ica_adapter_handle_t handle); +void aes_tests(unsigned char *iv, unsigned char *cmac, unsigned char *ctr); + +int main (int argc, char **argv) +{ + int rc = 0; + ica_adapter_handle_t adapter_handle; + + unsigned char *cmac; + unsigned char *ctr; + unsigned char *iv; + + set_verbosity(argc, argv); + + if((cmac = malloc(AES_CIPHER_BLOCK*sizeof(char))) == NULL){ + perror("Error in malloc: "); + exit(EXIT_FAILURE); + } + if((ctr = malloc(AES_CIPHER_BLOCK*sizeof(char))) == NULL){ + perror("Error in malloc: "); + exit(EXIT_FAILURE); + } + + if((iv = malloc(AES_CIPHER_BLOCK*sizeof(char))) == NULL){ + perror("Error in malloc: "); + exit(EXIT_FAILURE); + } + + /* + * Open crypto adapter + **/ + rc = ica_open_adapter(&adapter_handle); + if (rc != 0) { + V_(printf("ica_open_adapter failed and returned %d (0x%x).\n", rc, rc)); + } + + create_hw_info(); + + + /* + * Reset Counters + **/ + system("icastats -r"); + rc = ica_random_number_generate(AES_CIPHER_BLOCK, ctr); + if (rc) + exit(handle_ica_error(rc, "ica_random_number_generate")); + + /* + * Check if counter for Random operations has incremneted + **/ + /* ica_random_number_generate uses ica_drbg if available. Otherwise the + * old prng code is used. */ + if (check_hw(SHA512_DRNG) == 1 || check_hw(SHA512) == 1) + check_icastats(SHA512_DRNG, "DRBG-SHA-512"); + else + check_icastats(P_RNG, "P_RNG"); + + rc = ica_random_number_generate(AES_CIPHER_BLOCK, iv); + if (rc) + exit(handle_ica_error(rc, "ica_random_number_generate")); + + /* + * Check counters for all crypto operations + **/ + des_tests(iv, cmac, ctr); + tdes_tests(iv, cmac, ctr); + sha_tests(); + rsa_tests(adapter_handle); + aes_tests(iv, cmac, ctr); + + free(cmac); + free(ctr); + free(iv); + + printf("All icastats tests passed.\n"); + return 0; +} + + +int is_crypto_card_loaded() +{ + DIR* sysDir; + FILE *file; + char dev[PATH_MAX] = "/sys/devices/ap/"; + struct dirent *direntp; + char *type = NULL; + size_t size; + char c; + + if ((sysDir = opendir(dev)) == NULL ) + return 0; + + while((direntp = readdir(sysDir)) != NULL){ + if(strstr(direntp->d_name, "card") != 0){ + snprintf(dev, PATH_MAX, "/sys/devices/ap/%s/type", + direntp->d_name); + + if ((file = fopen(dev, "r")) == NULL){ + closedir(sysDir); + return 0; + } + + if (getline(&type, &size, file) == -1){ + fclose(file); + closedir(sysDir); + return 0; + } + + /* ignore \n + * looking for CEX??A and CEX??C + * Skip type CEX??P cards + **/ + if (type[strlen(type)-2] == 'P'){ + free(type); + type = NULL; + fclose(file); + continue; + } + free(type); + type = NULL; + fclose(file); + + snprintf(dev, PATH_MAX, "/sys/devices/ap/%s/online", + direntp->d_name); + if ((file = fopen(dev, "r")) == NULL){ + closedir(sysDir); + return 0; + } + if((c = fgetc(file)) == '1'){ + fclose(file); + return 1; + } + fclose(file); + } + } + closedir(sysDir); + return 0; +} + +/* + * Create Hardware Info database + **/ +void create_hw_info() +{ + if (ica_get_functionlist(NULL, &mech_len) != 0){ + perror("get_functionlist: "); + exit(EXIT_FAILURE); + } + pmech_list = malloc(sizeof(libica_func_list_element)*mech_len); + if (ica_get_functionlist(pmech_list, &mech_len) != 0){ + perror("get_functionlist: "); + free(pmech_list); + exit(EXIT_FAILURE); + } + + hw_flag = is_crypto_card_loaded(); +} + +/* + * check if a cryptp operation is supported in hardware + **/ +int check_hw(int algo_id) +{ + int i; + for (i=mech_len-1; i >= 0; i--) + if (pmech_list[i].mech_mode_id == algo_id) + break; + if (i < 0) return -1; + + if(hw_flag){ + if(pmech_list[i].flags & (ICA_FLAG_SHW | ICA_FLAG_DHW)) + return 1; + else + return 0; + } else{ + if(pmech_list[i].flags & ICA_FLAG_SHW) + return 1; + else + return 0; + } +} + +/* + * Check if icastats has counted correctly + **/ +void check_icastats(int algo_id, char *stat) +{ + char cmd[256], line[256], *p; + FILE *f; + int i, hw, rc=-1, counters=0; + int hwcounter1=0, hwcounter2=0, swcounter1=0, swcounter2=0; + + hw = check_hw(algo_id); + if (hw < 0) return; /* unknown algo_id */ + + sprintf(cmd, "icastats | grep '%s'", stat); + f = popen(cmd, "r"); + if (!f) { + perror("error in peopen"); + exit(EXIT_FAILURE); + } + fgets(line, sizeof(line), f); + pclose(f); + + /* remove trailing whitespace from the line */ + i = strlen(line); + while (i > 0 && isspace(line[i-1])) { + line[i-1] = 0; + i--; + } + + p = strstr(line, "|"); + if (!p) goto out; /* no | in the output. Wrong algo string ? */ + p++; + while (isspace(*p)) p++; + hwcounter1 = atoi(p); /* parse 1st hw counter value */ + counters++; + while (*p && !isspace(*p)) p++; /* parse over counter value */ + while (isspace(*p)) p++; + /* now either a | or another counter value follows */ + if (isdigit(*p)) { + hwcounter2 = atoi(p); /* parse 2nd hw counter value */ + counters++; + while (*p && !isspace(*p)) p++; /* parse over counter value */ + while (isspace(*p)) p++; + } + /* now there should be a | */ + if (*p != '|') { + V_(fprintf(stderr, "parse error, missing '|' in line '%s'\n", line)); + goto out; + } + p++; + while (isspace(*p)) p++; + swcounter1 = atoi(p); /* parse 1st sw counter value */ + counters++; + while (*p && !isspace(*p)) p++; /* parse over counter value */ + while (isspace(*p)) p++; + /* maybe another counter value follows */ + if (isdigit(*p)) { + swcounter2 = atoi(p); /* parse 2nd sw counter value */ + counters++; + } + + /* counters should be 2 or 4 now */ + if (counters == 2) { + if (hw) { + /* hwcounter1 should be > 0 */ + if (hwcounter1 > 0) + rc = 0; + else + goto out; + } else { + /* swcounter1 should be > 0 */ + if (swcounter1 > 0) + rc = 0; + else + goto out; + } + } else if (counters == 4) { + if (hw) { + /* hwcounter1 or hwcounter2 should be > 0 */ + if (hwcounter1 > 0 || hwcounter2 > 0) + rc = 0; + else + goto out; + } else { + /* swcounter1 or swcounter2 should be > 0 */ + if (swcounter1 > 0 || swcounter2 > 0) + rc = 0; + else + goto out; + } + } else { + V_(printf("parse error, could not parse 2 or 4 counter values\n")); + goto out; + } +out: + if (rc == 0) { + V_(printf("Test %s SUCCESS.\n", stat)); + } else { + printf("icastats %s test FAILED!\n", stat); + V_(printf("icastats line for %s was '%s'\n", stat, line)); + exit(EXIT_FAILURE); + } +} + +static int handle_ica_error(int rc, char *message) +{ + printf("Error in %s: ", message); + switch (rc) { + case 0: + V_(printf("OK\n")); + break; + case EINVAL: + V_(printf("Incorrect parameter.\n")); + break; + case EPERM: + V_(printf("Operation not permitted by Hardware.\n")); + break; + case EIO: + V_(printf("I/O error.\n")); + break; + default: + V_(perror("")); + } + return rc; +} + + + +void des_tests(unsigned char *iv, unsigned char *cmac, unsigned char *ctr) +{ + int rc = 0; + int mode; + unsigned char *out_buffer; + unsigned char *inp_buffer = plain_data; + unsigned char des_key[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + }; + +#ifdef ICA_FIPS + if (ica_fips_status() & ICA_FIPS_MODE) { + V_(printf("All icastats DES tests skipped." + " (DES not FIPS approved)\n")); + return; + } +#endif /* ICA_FIPS */ + + if((out_buffer = malloc(DATA_LENGHT*sizeof(char))) == NULL){ + perror("Error in malloc: "); + exit(EXIT_FAILURE); + } + + + system("icastats -r"); + for(mode = 1; mode >= 0; mode--){ + rc = ica_des_ecb(inp_buffer, out_buffer, DATA_LENGHT, + des_key, mode); + if (rc) + exit(handle_ica_error(rc, "ica_des_ecb")); + + if(mode == ICA_ENCRYPT) + inp_buffer = out_buffer; + else if(mode == ICA_DECRYPT) + inp_buffer = plain_data; + } + check_icastats(DES_ECB, "DES ECB"); + + system("icastats -r"); + for(mode = 1; mode >= 0; mode--){ + rc = ica_des_cbc(inp_buffer, out_buffer, DATA_LENGHT, + des_key, iv, mode); + if(rc) + exit(handle_ica_error(rc, "ica_des_ecb")); + + if(mode == ICA_ENCRYPT) + inp_buffer = out_buffer; + else if(mode == ICA_DECRYPT) + inp_buffer = plain_data; + } + check_icastats(DES_CBC, "DES CBC"); + + system("icastats -r"); + for(mode = 1; mode >= 0; mode--){ + rc = ica_des_cfb(inp_buffer, out_buffer, DATA_LENGHT, + des_key, iv, DES_CIPHER_BLOCK, mode); + if(rc) + exit(handle_ica_error(rc, "ica_des_cfb")); + + if(mode == ICA_ENCRYPT) + inp_buffer = out_buffer; + else if(mode == ICA_DECRYPT) + inp_buffer = plain_data; + } + check_icastats(DES_CFB, "DES CFB"); + + system("icastats -r"); + for(mode = 1; mode >= 0; mode--){ + rc = ica_des_cmac(inp_buffer, DATA_LENGHT, cmac, DES_CIPHER_BLOCK, + des_key, mode); + if(rc) + exit(handle_ica_error(rc, "ica_des_cmac")); + } + check_icastats(DES_CMAC, "DES CMAC"); + + system("icastats -r"); + for(mode = 1; mode >= 0; mode--){ + rc = ica_des_ctr(inp_buffer, out_buffer, DATA_LENGHT, des_key, + ctr, DES_CIPHER_BLOCK, mode); + if(rc) + exit(handle_ica_error(rc, "ica_des_ctr")); + + if(mode == ICA_ENCRYPT) + inp_buffer = out_buffer; + else if(mode == ICA_DECRYPT) + inp_buffer = plain_data; + } + check_icastats(DES_CTR, "DES CTR"); + + system("icastats -r"); + for(mode = 1; mode >= 0; mode--){ + rc = ica_des_ofb(inp_buffer, out_buffer, DATA_LENGHT, + des_key, iv, mode); + if(rc) + exit(handle_ica_error(rc, "ica_des_ofb")); + + if(mode == ICA_ENCRYPT) + inp_buffer = out_buffer; + else if(mode == ICA_DECRYPT) + inp_buffer = plain_data; + } + check_icastats(DES_OFB, "DES OFB"); + + free(out_buffer); +} + +void tdes_tests(unsigned char *iv, unsigned char *cmac, unsigned char *ctr) +{ + int rc = 0; + int mode; + unsigned char *out_buffer; + unsigned char *inp_buffer = plain_data; + unsigned char des_key[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + }; + + if((out_buffer = malloc(DATA_LENGHT*sizeof(char))) == NULL){ + perror("Error in malloc: "); + exit(EXIT_FAILURE); + } + + system("icastats -r"); + for(mode = 1; mode >= 0; mode--){ + rc = ica_3des_ecb(inp_buffer, out_buffer, DATA_LENGHT, + des_key, mode); + if (rc) + exit(handle_ica_error(rc, "ica_3des_ecb")); + + if(mode == ICA_ENCRYPT) + inp_buffer = out_buffer; + else if(mode == ICA_DECRYPT) + inp_buffer = plain_data; + } + check_icastats(DES3_ECB, "3DES ECB"); + + system("icastats -r"); + for(mode = 1; mode >= 0; mode--){ + rc = ica_3des_cbc(inp_buffer, out_buffer, DATA_LENGHT, + des_key, iv, mode); + if(rc) + exit(handle_ica_error(rc, "ica_3des_cbc")); + + if(mode == ICA_ENCRYPT) + inp_buffer = out_buffer; + else if(mode == ICA_DECRYPT) + inp_buffer = plain_data; + } + check_icastats(DES3_CBC, "3DES CBC"); + + system("icastats -r"); + for(mode = 1; mode >= 0; mode--){ + rc = ica_3des_cfb(inp_buffer, out_buffer, DATA_LENGHT, + des_key, iv, DES_CIPHER_BLOCK, mode); + if(rc) + exit(handle_ica_error(rc, "ica_3des_cfb")); + + if(mode == ICA_ENCRYPT) + inp_buffer = out_buffer; + else if(mode == ICA_DECRYPT) + inp_buffer = plain_data; + } + check_icastats(DES3_CFB, "3DES CFB"); + + system("icastats -r"); + for(mode = 1; mode >= 0; mode--){ + rc = ica_3des_cmac(inp_buffer, DATA_LENGHT, cmac, DES_CIPHER_BLOCK, + des_key, mode); + if(rc) + exit(handle_ica_error(rc, "ica_3des_cmac")); + } + check_icastats(DES3_CMAC, "3DES CMAC"); + + system("icastats -r"); + for(mode = 1; mode >= 0; mode--){ + rc = ica_3des_ctr(inp_buffer, out_buffer, DATA_LENGHT, des_key, + ctr, DES_CIPHER_BLOCK, mode); + if(rc) + exit(handle_ica_error(rc, "ica_3des_ctr")); + + if(mode == ICA_ENCRYPT) + inp_buffer = out_buffer; + else if(mode == ICA_DECRYPT) + inp_buffer = plain_data; + } + check_icastats(DES3_CTR, "3DES CTR"); + + system("icastats -r"); + for(mode = 1; mode >= 0; mode--){ + rc = ica_3des_ofb(inp_buffer, out_buffer, DATA_LENGHT, + des_key, iv, mode); + if(rc) + exit(handle_ica_error(rc, "ica_3des_ofb")); + + if(mode == ICA_ENCRYPT) + inp_buffer = out_buffer; + else if(mode == ICA_DECRYPT) + inp_buffer = plain_data; + } + check_icastats(DES3_OFB, "3DES OFB"); + + free(out_buffer); +} + +void sha_tests() +{ + int rc = 0; + unsigned char hash[SHA512_HASH_LENGTH]; + + sha_context_t sha_context0; + sha256_context_t sha_context1; + sha512_context_t sha_context2; + + + system("icastats -r"); + rc = ica_sha1(SHA_MSG_PART_ONLY, DATA_LENGHT, + plain_data, &sha_context0, hash); + if(rc) + exit(handle_ica_error(rc, "ica_sha1")); + check_icastats(SHA1, "SHA-1"); + + system("icastats -r"); + rc = ica_sha224(SHA_MSG_PART_ONLY, DATA_LENGHT, + plain_data, &sha_context1, hash); + if(rc) + exit(handle_ica_error(rc, "ica_sha224")); + check_icastats(SHA224, "SHA-224"); + + system("icastats -r"); + rc = ica_sha256(SHA_MSG_PART_ONLY, DATA_LENGHT, + plain_data, &sha_context1, hash); + if(rc) + exit(handle_ica_error(rc, "ica_sha256")); + check_icastats(SHA256, "SHA-256"); + + system("icastats -r"); + rc = ica_sha384(SHA_MSG_PART_ONLY, DATA_LENGHT, + plain_data, &sha_context2, hash); + if(rc) + exit(handle_ica_error(rc, "ica_sha384")); + check_icastats(SHA384, "SHA-384"); + + system("icastats -r"); + rc = ica_sha512(SHA_MSG_PART_ONLY, DATA_LENGHT, + plain_data, &sha_context2, hash); + if(rc) + exit(handle_ica_error(rc, "ica_sha512")); + check_icastats(SHA512, "SHA-512"); +} + +void rsa_tests(ica_adapter_handle_t handle) +{ + +unsigned char e[] = + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 }; + +unsigned char n[] = + { 0xec, 0x51, 0xab, 0xa1, 0xf8, 0x40, 0x2c, 0x08, + 0x2e, 0x24, 0x52, 0x2e, 0x3c, 0x51, 0x6d, 0x98, + 0xad, 0xee, 0xc7, 0x7d, 0x00, 0xaf, 0xe1, 0xa8, + 0x61, 0xda, 0x32, 0x97, 0xb4, 0x32, 0x97, 0xe3, + 0x52, 0xda, 0x28, 0x45, 0x55, 0xc6, 0xb2, 0x46, + 0x65, 0x1b, 0x02, 0xcb, 0xbe, 0xf4, 0x2c, 0x6b, + 0x2a, 0x5f, 0xe1, 0xdf, 0xe9, 0xe3, 0xbc, 0x47, + 0xb7, 0x38, 0xb5, 0xa2, 0x78, 0x9d, 0x15, 0xe2, + 0x59, 0x81, 0x77, 0x6b, 0x6b, 0x2e, 0xa9, 0xdb, + 0x13, 0x26, 0x9c, 0xca, 0x5e, 0x0a, 0x1f, 0x3c, + 0x50, 0x9d, 0xd6, 0x79, 0x59, 0x99, 0x50, 0xe5, + 0x68, 0x1a, 0x98, 0xca, 0x11, 0xce, 0x37, 0x63, + 0x58, 0x22, 0x40, 0x19, 0x29, 0x72, 0x4c, 0x41, + 0x89, 0x0b, 0x56, 0x9e, 0x3e, 0xd5, 0x6d, 0x75, + 0x9e, 0x3f, 0x8a, 0x50, 0xf1, 0x0a, 0x59, 0x4a, + 0xc3, 0x59, 0x4b, 0xf6, 0xbb, 0xc9, 0xa5, 0x93 }; + +unsigned char input_data[] = + { 0x00, 0x02, 0x08, 0x68, 0x30, 0x9a, 0x32, 0x08, + 0x57, 0xb0, 0x28, 0xaa, 0x76, 0x30, 0x3d, 0x84, + 0x5f, 0x92, 0x0d, 0x8e, 0x34, 0xe0, 0xd5, 0xcc, + 0x36, 0x97, 0xed, 0x00, 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, + 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63 }; + +unsigned char p[] = + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfb, 0xb7, 0x73, 0x24, 0x42, 0xfe, 0x8f, 0x16, + 0xf0, 0x6e, 0x2d, 0x86, 0x22, 0x46, 0x79, 0xd1, + 0x58, 0x6f, 0x26, 0x24, 0x17, 0x12, 0xa3, 0x1a, + 0xfd, 0xf7, 0x75, 0xd4, 0xcd, 0xf9, 0xde, 0x4b, + 0x8c, 0xb7, 0x04, 0x5d, 0xd9, 0x18, 0xc8, 0x26, + 0x61, 0x54, 0xe0, 0x92, 0x2f, 0x47, 0xf7, 0x33, + 0xc2, 0x17, 0xd8, 0xda, 0xe0, 0x6d, 0xb6, 0x30, + 0xd6, 0xdc, 0xf9, 0x6a, 0x4c, 0xa1, 0xa2, 0x4b }; + +unsigned char q[] = + { 0xf0, 0x57, 0x24, 0xf6, 0x2a, 0x5a, 0x6d, 0x8e, + 0xb8, 0xc6, 0x6f, 0xd2, 0xbb, 0x36, 0x4f, 0x6d, + 0xd8, 0xbc, 0xa7, 0x2f, 0xbd, 0x43, 0xdc, 0x9a, + 0x0e, 0x2a, 0x36, 0xb9, 0x21, 0x05, 0xfa, 0x22, + 0x6c, 0xe8, 0x22, 0x68, 0x2f, 0x1c, 0xe8, 0x27, + 0xc1, 0xed, 0x08, 0x7a, 0x43, 0x70, 0x7b, 0xe3, + 0x46, 0x74, 0x02, 0x6e, 0xb2, 0xb1, 0xeb, 0x44, + 0x72, 0x86, 0x0d, 0x55, 0x3b, 0xc8, 0xbc, 0xd9 }; + +unsigned char dp[] = + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa7, 0xcf, 0xa2, 0x18, 0x2c, 0xa9, 0xb4, 0xb9, + 0xf5, 0x9e, 0xc9, 0x04, 0x16, 0xd9, 0xa6, 0x8b, + 0x90, 0x4a, 0x19, 0x6d, 0x64, 0xb7, 0x17, 0x67, + 0x53, 0xfa, 0x4e, 0x8d, 0xde, 0xa6, 0x94, 0x32, + 0x5d, 0xcf, 0x58, 0x3e, 0x90, 0xbb, 0x30, 0x19, + 0x96, 0x38, 0x95, 0xb6, 0xca, 0x2f, 0xfa, 0x22, + 0x81, 0x65, 0x3b, 0x3c, 0x95, 0x9e, 0x79, 0x75, + 0xe4, 0x93, 0x50, 0xf1, 0x88, 0x6b, 0xc1, 0x87 }; + +unsigned char dq[] = + { 0xa0, 0x3a, 0x18, 0xa4, 0x1c, 0x3c, 0x49, 0x09, + 0xd0, 0x84, 0x4a, 0x8c, 0x7c, 0xce, 0xdf, 0x9e, + 0x90, 0x7d, 0xc4, 0xca, 0x7e, 0x2d, 0x3d, 0xbc, + 0x09, 0x71, 0x79, 0xd0, 0xc0, 0xae, 0xa6, 0xc1, + 0x9d, 0xf0, 0x16, 0xf0, 0x1f, 0x68, 0x9a, 0xc5, + 0x2b, 0xf3, 0x5a, 0xfc, 0x2c, 0xf5, 0xa7, 0xec, + 0xd9, 0xa2, 0xac, 0x49, 0xcc, 0x76, 0x9c, 0xd8, + 0x4c, 0x59, 0x5e, 0x38, 0xd2, 0x85, 0xd3, 0x3b }; + +unsigned char qinv[] = + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x83, 0xf1, 0xca, 0x06, 0x58, 0x4a, 0x04, 0x5e, + 0x96, 0xb5, 0x30, 0x32, 0x40, 0x36, 0x48, 0xb9, + 0x02, 0x0c, 0xe3, 0x37, 0xb7, 0x51, 0xbc, 0x22, + 0x26, 0x5d, 0x74, 0x03, 0x47, 0xd3, 0x33, 0x20, + 0x8e, 0x75, 0x62, 0xf2, 0x9d, 0x4e, 0xc8, 0x7d, + 0x5d, 0x8e, 0xb6, 0xd9, 0x69, 0x4a, 0x9a, 0xe1, + 0x36, 0x6e, 0x1c, 0xbe, 0x8a, 0x14, 0xb1, 0x85, + 0x39, 0x74, 0x7c, 0x25, 0xd8, 0xa4, 0x4f, 0xde }; + + unsigned char *output_data; + unsigned char *data = input_data; + int rc = 0; + + if((output_data = malloc(RSA_BYTE_LENGHT*sizeof(char))) == NULL){ + perror("error in malloc: "); + exit(EXIT_FAILURE); + } + + ica_rsa_key_mod_expo_t mod_expo_key= {RSA_BYTE_LENGHT, n, e}; + ica_rsa_key_crt_t crt_key = {RSA_BYTE_LENGHT, p, q, dp, dq, qinv}; + + system("icastats -r"); + rc = ica_rsa_mod_expo(handle, data, &mod_expo_key, + output_data); + if(rc) + exit(handle_ica_error(rc, "ica_rsa_key_mod_expo")); + check_icastats(RSA_ME, "RSA-ME"); + + system("icastats -r"); + rc = ica_rsa_crt(handle, data, &crt_key, + output_data); + if(rc) + exit(handle_ica_error(rc, "ica_rsa_crt")); + check_icastats(RSA_CRT, "RSA-CRT"); + + free(output_data); +} + +void aes_tests(unsigned char *iv, unsigned char *cmac, unsigned char *ctr) +{ + int rc = 0; + int mode; + unsigned char *output_buffer, *tag, *nonce; + unsigned char *input_buffer = plain_data; + + + + unsigned char aes_key[] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, + + }; + + unsigned char tweak[] = { + 0x72, 0xf3, 0xb0, 0x54, 0xcb, 0xdc, 0x2f, 0x9e, + 0x3c, 0x5b, 0xc5, 0x51, 0xd4, 0x4d, 0xdb, 0xa0, + }; + + #define NONCE_LENGHT 10 + + if((nonce = malloc(NONCE_LENGHT*sizeof(char))) == NULL){ + perror("Error in malloc: "); + exit(EXIT_FAILURE); + } + + if((tag = malloc(AES_CIPHER_BLOCK*sizeof(char))) == NULL){ + perror("Error in malloc: "); + exit(EXIT_FAILURE); + } + + if((output_buffer = malloc((DATA_LENGHT+AES_CIPHER_BLOCK) + *sizeof(char))) == NULL){ + perror("Error in malloc: "); + exit(EXIT_FAILURE); + } + + system("icastats -r"); + for(mode = 1;mode >= 0;mode--){ + rc = ica_aes_cbc(input_buffer, output_buffer, DATA_LENGHT, + aes_key, AES_KEY_LEN128, iv, mode); + if(rc) + exit(handle_ica_error(rc, "ica_aes_cbc")); + if(mode == ICA_ENCRYPT) + input_buffer = output_buffer; + else if(mode == ICA_DECRYPT) + input_buffer = plain_data; + } + check_icastats(AES_CBC, "AES CBC"); + + system("icastats -r"); + for(mode = 1;mode >= 0;mode--){ + rc = ica_aes_cfb(input_buffer, output_buffer, DATA_LENGHT, + aes_key, AES_KEY_LEN128, iv, AES_CIPHER_BLOCK, + mode); + if(rc) + exit(handle_ica_error(rc, "ica_aes_cfb")); + + if(mode == ICA_ENCRYPT) + input_buffer = output_buffer; + else if(mode == ICA_DECRYPT) + input_buffer = plain_data; + } + check_icastats(AES_CFB, "AES CFB"); + + system("icastats -r"); + for(mode = 1;mode >= 0;mode--){ + rc = ica_aes_cmac(input_buffer, DATA_LENGHT, cmac, + AES_CIPHER_BLOCK, aes_key, + AES_KEY_LEN128, mode); + if(rc) + exit(handle_ica_error(rc, "ica_aes_cmac")); + } + check_icastats(AES_CMAC, "AES CMAC"); + + system("icastats -r"); + for(mode = 1;mode >= 0;mode--){ + rc = ica_aes_ctr(input_buffer, output_buffer, DATA_LENGHT, + aes_key, AES_KEY_LEN128, ctr, AES_CIPHER_BLOCK, + mode); + if(rc) + exit(handle_ica_error(rc, "ica_aes_ctr")); + + if(mode == ICA_ENCRYPT) + input_buffer = output_buffer; + else if(mode == ICA_DECRYPT) + input_buffer = plain_data; + } + check_icastats(AES_CTR, "AES CTR"); + + system("icastats -r"); + for(mode = 1;mode >= 0;mode--){ + rc = ica_aes_ecb(input_buffer, output_buffer, DATA_LENGHT, + aes_key, AES_KEY_LEN128, mode); + if (rc) + exit(handle_ica_error(rc, "ica_aes_ecb")); + + if(mode == ICA_ENCRYPT) + input_buffer = output_buffer; + else if(mode == ICA_DECRYPT) + input_buffer = plain_data; + } + check_icastats(AES_ECB, "AES ECB"); + + system("icastats -r"); + for(mode = 1;mode >= 0;mode--){ + rc = ica_aes_ofb(input_buffer, output_buffer, DATA_LENGHT, + aes_key, AES_KEY_LEN128, iv, mode); + + if(rc) + exit(handle_ica_error(rc, "ica_aes_ofb")); + + if(mode == ICA_ENCRYPT) + input_buffer = output_buffer; + else if(mode == ICA_DECRYPT) + input_buffer = plain_data; + } + check_icastats(AES_OFB, "AES OFB"); + + system("icastats -r"); + for(mode = 1;mode >= 0;mode--){ + rc = ica_aes_xts(input_buffer, output_buffer, DATA_LENGHT, + aes_key, aes_key, AES_KEY_LEN128, tweak, mode); + + if(rc) + exit(handle_ica_error(rc, "ica_aes_xts")); + + if(mode == ICA_ENCRYPT) + input_buffer = output_buffer; + else if(mode == ICA_DECRYPT) + input_buffer = plain_data; + } + check_icastats(AES_XTS, "AES XTS"); + + free(tag); + free(output_buffer); + free(nonce); +} + diff --git a/src/tests/libica_3des_cbc_test.c b/src/tests/libica_3des_cbc_test.c new file mode 100644 index 0000000..3906fe3 --- /dev/null +++ b/src/tests/libica_3des_cbc_test.c @@ -0,0 +1,159 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2010, 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include "ica_api.h" +#include "testcase.h" + +#define NR_RANDOM_TESTS 10000 + +void dump_cbc_data(unsigned char *iv, unsigned int iv_length, + unsigned char *key, unsigned int key_length, + unsigned char *input_data, unsigned int data_length, + unsigned char *output_data) +{ + VV_(printf("IV \n")); + dump_array(iv, iv_length); + VV_(printf("Key \n")); + dump_array(key, key_length); + VV_(printf("Input Data\n")); + dump_array(input_data, data_length); + VV_(printf("Output Data\n")); + dump_array(output_data, data_length); +} + +int load_random_test_data(unsigned char *data, unsigned int data_length, + unsigned char *iv, unsigned int iv_length, + unsigned char *key, unsigned int key_length) +{ + int rc; + rc = ica_random_number_generate(data_length, data); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + rc = ica_random_number_generate(iv_length, iv); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + rc = ica_random_number_generate(key_length, key); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + return rc; +} + +int random_3des_cbc(int iteration, unsigned int data_length) +{ + unsigned int iv_length = sizeof(ica_des_vector_t); + unsigned int key_length = sizeof(ica_des_key_triple_t); + + unsigned char iv[iv_length]; + unsigned char tmp_iv[iv_length]; + unsigned char key[key_length]; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + + int rc = 0; + memset(encrypt, 0x00, data_length); + memset(decrypt, 0x00, data_length); + + load_random_test_data(input_data, data_length, iv, iv_length, key, + key_length); + memcpy(tmp_iv, iv, iv_length); + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i, iv length = %i\n", + key_length, data_length, iv_length)); + + rc = ica_3des_cbc(input_data, encrypt, data_length, key, tmp_iv, 1); + if (rc) { + VV_(printf("ica_3des_cbc encrypt failed with rc = %i\n", rc)); + dump_cbc_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_cbc_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + + if (rc) { + VV_(printf("3DES CBC test exited after encryption\n")); + return rc; + } + + memcpy(tmp_iv, iv, iv_length); + + rc = ica_3des_cbc(encrypt, decrypt, data_length, key, tmp_iv, + 0); + if (rc) { + VV_(printf("ica_3des_cbc decrypt failed with rc = %i\n", rc)); + dump_cbc_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_cbc_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + } + return rc; +} + +/* + * Performs ECB,CBC and CFQ tests. + */ +int main(int argc, char **argv) +{ + int rc = 0; + int error_count = 0; + int iteration; + unsigned int data_length = sizeof(ica_des_vector_t); + + set_verbosity(argc, argv); + + for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) { + rc = random_3des_cbc(iteration, data_length); + if (rc) { + V_(printf("random_3des_cbc failed with rc = %i\n", rc)); + error_count++; + goto out; + } + data_length += sizeof(ica_des_vector_t); + } +out: + if (error_count) + printf("%i 3DES-CBC tests failed.\n", error_count); + else + printf("All 3DES-CBC tests passed.\n"); + + return rc; +} + diff --git a/src/tests/libica_3des_cfb_test.c b/src/tests/libica_3des_cfb_test.c new file mode 100644 index 0000000..7f1996d --- /dev/null +++ b/src/tests/libica_3des_cfb_test.c @@ -0,0 +1,178 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2010, 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include "ica_api.h" +#include "testcase.h" + +#define NR_TESTS 12 +#define NR_RANDOM_TESTS 1000 + +void dump_cfb_data(unsigned char *iv, unsigned int iv_length, + unsigned char *key, unsigned int key_length, + unsigned char *input_data, unsigned int data_length, + unsigned char *output_data) +{ + VV_(printf("IV \n")); + dump_array(iv, iv_length); + VV_(printf("Key \n")); + dump_array(key, key_length); + VV_(printf("Input Data\n")); + dump_array(input_data, data_length); + VV_(printf("Output Data\n")); + dump_array(output_data, data_length); +} + +int load_random_test_data(unsigned char *data, unsigned int data_length, + unsigned char *iv, unsigned int iv_length, + unsigned char *key, unsigned int key_length) +{ + int rc; + + rc = ica_random_number_generate(data_length, data); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + rc = ica_random_number_generate(iv_length, iv); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + rc = ica_random_number_generate(key_length, key); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + return rc; +} + +int random_des_cfb(int iteration, unsigned int data_length, unsigned int lcfb) +{ + unsigned int iv_length = sizeof(ica_des_vector_t); + unsigned int key_length = sizeof(ica_des_key_triple_t); + + unsigned char iv[iv_length]; + unsigned char tmp_iv[iv_length]; + unsigned char key[key_length]; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + + int rc = 0; + memset(encrypt, 0x00, data_length); + memset(decrypt, 0x00, data_length); + + load_random_test_data(input_data, data_length, iv, iv_length, key, + key_length); + memcpy(tmp_iv, iv, iv_length); + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i, iv length = %i," + " lcfb = %i\n", key_length, data_length, iv_length, lcfb)); + + rc = ica_3des_cfb(input_data, encrypt, data_length, key, tmp_iv, lcfb, + 1); + if (rc) { + VV_(printf("ica_3des_cfb encrypt failed with rc = %i\n", rc)); + dump_cfb_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_cfb_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + + if (rc) { + VV_(printf("3DES OFB test exited after encryption\n")); + return rc; + } + + memcpy(tmp_iv, iv, iv_length); + + rc = ica_3des_cfb(encrypt, decrypt, data_length, key, tmp_iv, + lcfb, 0); + if (rc) { + VV_(printf("ica_3des_cfb decrypt failed with rc = %i\n", rc)); + dump_cfb_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_cfb_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + } + return rc; +} + +int main(int argc, char **argv) +{ + int rc = 0; + int error_count = 0; + int iteration; + unsigned int rdata; + unsigned int data_length = 1; + unsigned int lcfb = 1; + unsigned int j; + + set_verbosity(argc, argv); + + for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) { + for (j = 1; j <= 2; j++) { + if (!(data_length % lcfb)) { + rc = random_des_cfb(iteration, data_length, lcfb); + if (rc) { + V_(printf("random_des_cfb failed with rc = %i\n", rc)); + error_count++; + } + } + switch (j) { + case 1: + lcfb = 1; + break; + case 2: + lcfb = 8; + break; + } + } + // add a value between 1 and 8 to data_length + if (ica_random_number_generate(sizeof(rdata), (unsigned char*) &rdata)) { + printf("ica_random_number_generate failed with errnor = %i\n", + errno); + exit(1); + } + data_length += (rdata % 8) + 1; + } + if (error_count) + printf("%i 3DES-CFB tests failed.\n", error_count); + else + printf("All 3DES-CFB tests passed.\n"); + + return rc; +} + diff --git a/src/tests/libica_3des_ctr_test.c b/src/tests/libica_3des_ctr_test.c new file mode 100644 index 0000000..1d9e376 --- /dev/null +++ b/src/tests/libica_3des_ctr_test.c @@ -0,0 +1,163 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2010, 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include "ica_api.h" +#include "testcase.h" + +#define NR_RANDOM_TESTS 1000 + +void dump_ctr_data(unsigned char *iv, unsigned int iv_length, + unsigned char *key, unsigned int key_length, + unsigned char *input_data, unsigned int data_length, + unsigned char *output_data) +{ + VV_(printf("IV \n")); + dump_array(iv, iv_length); + VV_(printf("Key \n")); + dump_array(key, key_length); + VV_(printf("Input Data\n")); + dump_array(input_data, data_length); + VV_(printf("Output Data\n")); + dump_array(output_data, data_length); +} + +int random_3des_ctr(int iteration, unsigned int data_length) +{ + unsigned int key_length = sizeof(ica_des_key_triple_t); + unsigned int iv_length = sizeof(ica_des_vector_t); + + unsigned char iv[iv_length]; + unsigned char tmp_iv[iv_length]; + unsigned char key[key_length]; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + + int rc = 0; + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i, iv length = %i\n", + key_length, data_length, iv_length)); + + rc = ica_random_number_generate(data_length, input_data); + if (rc) { + VV_(printf("random number generate returned rc = %i, errno = %i\n", rc, errno)); + return rc; + } + rc = ica_random_number_generate(iv_length, iv); + if (rc) { + VV_(printf("random number generate returned rc = %i, errno = %i\n", rc, errno)); + return rc; + } + + rc = ica_random_number_generate(key_length, key); + if (rc) { + VV_(printf("random number generate returned rc = %i, errno = %i\n", rc, errno)); + return rc; + } + memcpy(tmp_iv, iv, iv_length); + + rc = ica_3des_ctr(input_data, encrypt, data_length, key, tmp_iv, + 32, 1); + if (rc) { + VV_(printf("ica_3des_ctr encrypt failed with rc = %i\n", rc)); + dump_ctr_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + return rc; + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_ctr_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + + memcpy(tmp_iv, iv, iv_length); + rc = ica_3des_ctr(encrypt, decrypt, data_length, key, tmp_iv, + 32, 0); + if (rc) { + VV_(printf("ica_3des_ctr decrypt failed with rc = %i\n", rc)); + dump_ctr_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_ctr_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + } + return rc; +} + +int main(int argc, char **argv) +{ + unsigned int endless = 0; + unsigned int data_length = 1; + unsigned int rdata; + int error_count = 0; + int i = 0; + int rc = 0; + + set_verbosity(argc, argv); + if (argc > 1) { + if (strstr(argv[1], "endless")) + endless = 1; + } + + if (endless) { + while (1) { + VV_(printf("i = %i\n", i)); + rc = random_3des_ctr(i, 320); + if (rc) { + VV_(printf("kat_3des_ctr failed with rc = %i\n", + rc)); + return rc; + } else + VV_(printf("kat_3des_ctr finished.n")); + i++; + } + } else { + for (i = 1; i < NR_RANDOM_TESTS; i++) { + rc = random_3des_ctr(i, data_length); + if (rc) { + VV_(printf("random_3des_ctr failed with rc = %i\n", rc)); + error_count++; + } + // add a value between 1 and 8 to data_length + if (ica_random_number_generate(sizeof(rdata), (unsigned char*) &rdata)) { + printf("ica_random_number_generate failed with errnor = %i\n", + errno); + exit(1); + } + data_length += (rdata % 8) + 1; + } + } + + if (error_count) + printf("%i 3DES-CTR tests failed.\n", error_count); + else + printf("All 3DES-CTR tests passed.\n"); + + return rc; +} + diff --git a/src/tests/libica_3des_ecb_test.c b/src/tests/libica_3des_ecb_test.c new file mode 100644 index 0000000..d907538 --- /dev/null +++ b/src/tests/libica_3des_ecb_test.c @@ -0,0 +1,295 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2010, 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include "ica_api.h" +#include "testcase.h" + +#define NR_TESTS 2 +#define NR_RANDOM_TESTS 10000 + +/* ECB data - 1 for 3DES192 */ +unsigned char NIST_KEY_ECB_E1[] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, + 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, +}; + +unsigned char NIST_TEST_DATA_ECB_E1[] = { + 0x6B, 0x20, 0x62, 0x72, 0x6F, 0x77, 0x6E, 0x20, +}; + +unsigned char NIST_TEST_RESULT_ECB_E1[] = { + 0xCC, 0xE2, 0x1C, 0x81, 0x12, 0x25, 0x6F, 0xE6, +}; + +/* ECB data - 2 - for 3DES128 */ +unsigned char NIST_KEY_ECB_E2[] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, + 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, + +}; + +unsigned char NIST_TEST_DATA_ECB_E2[] = { + 0x54, 0x68, 0x65, 0x20, 0x71, 0x75, 0x66, 0x63, + 0x6B, 0x20, 0x62, 0x72, 0x6F, 0x77, 0x6E, 0x20, + 0x66, 0x6F, 0x78, 0x20, 0x6A, 0x75, 0x6D, 0x70, +}; + +unsigned char NIST_TEST_RESULT_ECB_E2[] = { + 0xA8, 0x26, 0xFD, 0x8C, 0xE5, 0x3B, 0x85, 0x5F, + 0xCC, 0xE2, 0x1C, 0x81, 0x12, 0x25, 0x6F, 0xE6, + 0x68, 0xD5, 0xC0, 0x5D, 0xD9, 0xB6, 0xB9, 0x00, +}; + +void dump_ecb_data(unsigned char *key, unsigned int key_length, + unsigned char *input_data, unsigned int data_length, + unsigned char *output_data) +{ + VV_(printf("Key \n")); + dump_array(key, key_length); + VV_(printf("Input Data\n")); + dump_array(input_data, data_length); + VV_(printf("Output Data\n")); + dump_array(output_data, data_length); +} + +void get_sizes(unsigned int *data_length, + unsigned int *key_length, unsigned int iteration) +{ + switch (iteration) { + case 1: + *data_length = sizeof(NIST_TEST_DATA_ECB_E1); + *key_length = sizeof(NIST_KEY_ECB_E1); + break; + case 2: + *data_length = sizeof(NIST_TEST_DATA_ECB_E2); + *key_length = sizeof(NIST_KEY_ECB_E2); + break; + } + +} + +void load_test_data(unsigned char *data, unsigned int data_length, + unsigned char *result, + unsigned char *key, unsigned int key_length, + unsigned int iteration) +{ + switch (iteration) { + case 1: + memcpy(data, NIST_TEST_DATA_ECB_E1, data_length); + memcpy(result, NIST_TEST_RESULT_ECB_E1, data_length); + memcpy(key, NIST_KEY_ECB_E1, key_length); + break; + case 2: + memcpy(data, NIST_TEST_DATA_ECB_E2, data_length); + memcpy(result, NIST_TEST_RESULT_ECB_E2, data_length); + memcpy(key, NIST_KEY_ECB_E2, key_length); + break; + } + +} + +int kat_3des_ecb(int iteration) +{ + unsigned int data_length; + unsigned int key_length; + + get_sizes(&data_length, &key_length, iteration); + + unsigned char key[key_length]; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + unsigned char result[data_length]; + + int rc = 0; + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i", key_length, data_length)); + + load_test_data(input_data, data_length, result, key, key_length, + iteration); + + rc = ica_3des_ecb(input_data, encrypt, data_length, key, 1); + if (rc) { + VV_(printf("ica_3des_ecb encrypt failed with rc = %i\n", rc)); + dump_ecb_data(key, key_length, input_data, + data_length, encrypt); + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_ecb_data(key, key_length, input_data, + data_length, encrypt); + } + + if (memcmp(result, encrypt, data_length)) { + VV_(printf("Encryption Result does not match the known ciphertext!\n")); + VV_(printf("Expected data:\n")); + dump_array(result, data_length); + VV_(printf("Encryption Result:\n")); + dump_array(encrypt, data_length); + rc++; + } + + if (rc) { + VV_(printf("3DES ECB test exited after encryption\n")); + return rc; + } + + rc = ica_3des_ecb(encrypt, decrypt, data_length, key, 0); + if (rc) { + VV_(printf("ica_3des_ecb decrypt failed with rc = %i\n", rc)); + dump_ecb_data(key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_ecb_data(key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + } + return rc; +} + +int load_random_test_data(unsigned char *data, unsigned int data_length, + unsigned char *key, unsigned int key_length) +{ + int rc; + + rc = ica_random_number_generate(data_length, data); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + rc = ica_random_number_generate(key_length, key); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + return rc; +} + +int random_3des_ecb(int iteration, unsigned int data_length) +{ + int rc = 0; + unsigned int key_length = sizeof(ica_des_key_triple_t); + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + unsigned char key[key_length]; + + memset(encrypt, 0x00, data_length); + memset(decrypt, 0x00, data_length); + + load_random_test_data(input_data, data_length, key, key_length); + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i\n", key_length, data_length)); + + rc = ica_3des_ecb(input_data, encrypt, data_length, key, 1); + if (rc) { + VV_(printf("ica_3des_ecb encrypt failed with rc = %i\n", rc)); + dump_ecb_data(key, key_length, input_data, data_length, + encrypt); + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_ecb_data(key, key_length, input_data, + data_length, encrypt); + } + + if (rc) { + VV_(printf("3DES ECB test exited after encryption\n")); + return rc; + } + + rc = ica_3des_ecb(encrypt, decrypt, data_length, key, 0); + if (rc) { + VV_(printf("ica_3des_ecb decrypt failed with rc = %i\n", rc)); + dump_ecb_data(key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_ecb_data(key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + return rc; + } + + return rc; +} + +/* + * Performs ECB and CFQ tests. + */ +int main(int argc, char **argv) +{ + int rc = 0; + int error_count = 0; + int iteration; + unsigned int data_length = sizeof(ica_des_vector_t); + + set_verbosity(argc, argv); + + for(iteration = 1; iteration <= NR_TESTS; iteration++) { + rc = kat_3des_ecb(iteration); + if (rc) { + V_(printf("kat_3des_ecb failed with rc = %i\n", rc)); + error_count++; + } + } + + for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) { + rc = random_3des_ecb(iteration, data_length); + if (rc) { + V_(printf("random_3des_ecb failed with rc = %i\n", rc)); + error_count++; + goto out; + } + data_length += sizeof(ica_des_vector_t); + } + +out: + if (error_count) + printf("%i 3DES-ECB tests failed.\n", error_count); + else + printf("All 3DES-ECB tests passed.\n"); + + return rc; +} + diff --git a/src/tests/libica_3des_ofb_test.c b/src/tests/libica_3des_ofb_test.c new file mode 100644 index 0000000..7540310 --- /dev/null +++ b/src/tests/libica_3des_ofb_test.c @@ -0,0 +1,164 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2010, 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include "ica_api.h" +#include "testcase.h" + +#define NR_RANDOM_TESTS 10000 + +void dump_ofb_data(unsigned char *iv, unsigned int iv_length, + unsigned char *key, unsigned int key_length, + unsigned char *input_data, unsigned int data_length, + unsigned char *output_data) +{ + VV_(printf("IV \n")); + dump_array(iv, iv_length); + VV_(printf("Key \n")); + dump_array(key, key_length); + VV_(printf("Input Data\n")); + dump_array(input_data, data_length); + VV_(printf("Output Data\n")); + dump_array(output_data, data_length); +} + +int load_random_test_data(unsigned char *data, unsigned int data_length, + unsigned char *iv, unsigned int iv_length, + unsigned char *key, unsigned int key_length) +{ + int rc; + + rc = ica_random_number_generate(data_length, data); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + rc = ica_random_number_generate(iv_length, iv); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + rc = ica_random_number_generate(key_length, key); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + return rc; +} + +int random_3des_ofb(int iteration, unsigned int data_length) +{ + unsigned int iv_length = sizeof(ica_des_vector_t); + unsigned int key_length = sizeof(ica_des_key_triple_t); + + unsigned char iv[iv_length]; + unsigned char tmp_iv[iv_length]; + unsigned char key[key_length]; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + + int rc = 0; + + memset(encrypt, 0x00, data_length); + memset(decrypt, 0x00, data_length); + + load_random_test_data(input_data, data_length, iv, iv_length, key, + key_length); + memcpy(tmp_iv, iv, iv_length); + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i, iv length = %i\n", + key_length, data_length, iv_length)); + + rc = ica_3des_ofb(input_data, encrypt, data_length, key, tmp_iv, 1); + if (rc) { + VV_(printf("ica_3des_ofb encrypt failed with rc = %i\n", rc)); + dump_ofb_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_ofb_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + + if (rc) { + VV_(printf("3DES OFB test exited after encryption\n")); + return rc; + } + + memcpy(tmp_iv, iv, iv_length); + + rc = ica_3des_ofb(encrypt, decrypt, data_length, key, tmp_iv, 0); + if (rc) { + VV_(printf("ica_3des_ofb decrypt failed with rc = %i\n", rc)); + dump_ofb_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_ofb_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + } + return rc; +} + +int main(int argc, char **argv) +{ + int rc = 0; + int error_count = 0; + int iteration; + unsigned int rdata; + unsigned int data_length = 1; + + set_verbosity(argc, argv); + + for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) { + rc = random_3des_ofb(iteration, data_length); + if (rc) { + V_(printf("random_3des_ofb failed with rc = %i\n", rc)); + error_count++; + goto out; + } + // add a value between 1 and 8 to data_length + if (ica_random_number_generate(sizeof(rdata), (unsigned char*) &rdata)) { + V_(printf("ica_random_number_generate failed with errnor = %i\n", + errno)); + exit(1); + } + data_length += (rdata % 8) + 1; + } +out: + if (error_count) + printf("%i 3DES-OFB tests failed.\n", error_count); + else + printf("All 3DES-OFB tests passed.\n"); + + return rc; +} + diff --git a/src/tests/libica_3des_test.c b/src/tests/libica_3des_test.c new file mode 100644 index 0000000..89dc3a5 --- /dev/null +++ b/src/tests/libica_3des_test.c @@ -0,0 +1,138 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2001, 2009, 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include "ica_api.h" +#include "testcase.h" + +unsigned char NIST_KEY1[] = + { 0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57 }; + +unsigned char NIST_KEY2[] = + { 0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57 }; + +unsigned char NIST_KEY3[] = + { 0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57 }; + +unsigned char NIST_TEST_DATA[] = + { 0x01, 0xa1, 0xd6, 0xd0, 0x39, 0x77, 0x67, 0x42 }; + +unsigned char NIST_TEST_RESULT[] = + { 0x69, 0x0f, 0x5b, 0x0d, 0x9a, 0x26, 0x93, 0x9b }; + +int test_3des_new_api(int mode) +{ + ica_des_vector_t iv; + ica_des_key_triple_t key; + int rc = 0; + unsigned char dec_text[sizeof(NIST_TEST_DATA)], + enc_text[sizeof(NIST_TEST_DATA)]; + + bzero(dec_text, sizeof(dec_text)); + bzero(enc_text, sizeof(enc_text)); + bzero(iv, sizeof(iv)); + bcopy(NIST_KEY1, key.key1, sizeof(NIST_KEY1)); + bcopy(NIST_KEY2, key.key2, sizeof(NIST_KEY2)); + bcopy(NIST_KEY3, key.key3, sizeof(NIST_KEY3)); + + VV_(printf("\nOriginal data:\n")); + dump_array(NIST_TEST_DATA, sizeof(NIST_TEST_DATA)); + + rc = ica_3des_encrypt(mode, sizeof(NIST_TEST_DATA), NIST_TEST_DATA, + &iv, &key, enc_text); + if (rc != 0) { + VV_(printf("ica_3des_encrypt failed with errno %d (0x%x).\n", rc, rc)); + return rc; + } + + VV_(printf("\nEncrypted data:\n")); + dump_array(enc_text, sizeof(enc_text)); + if (memcmp(enc_text, NIST_TEST_RESULT, sizeof NIST_TEST_RESULT) != 0) { + VV_(printf("This does NOT match the known result.\n")); + return -1; + } else { + VV_(printf("Yep, it's what it should be.\n")); + } + + bzero(iv, sizeof(iv)); + rc = ica_3des_decrypt(mode, sizeof(enc_text), enc_text, + &iv, &key, dec_text); + if (rc != 0) { + VV_(printf("ica_3des_decrypt failed with errno %d (0x%x).\n", rc, rc)); + return rc; + } + + VV_(printf("\nDecrypted data:\n")); + dump_array(dec_text, sizeof(dec_text)); + if (memcmp(dec_text, NIST_TEST_DATA, sizeof(NIST_TEST_DATA)) != 0) { + VV_(printf("This does NOT match the original data.\n")); + return -1; + } else { + VV_(printf("Successful!\n")); + } + + return 0; +} + +/* + * Performs ECB and CBC tests. + */ +int main(int argc, char **argv) +{ + unsigned int mode = 0; + int rc = 0; + int error_count = 0; + + if (argc > 1) { + if (strstr(argv[1], "ecb")) + mode = MODE_ECB; + if (strstr(argv[1], "cbc")) + mode = MODE_CBC; + V_(printf("mode = %i \n", mode)); + } + if (mode != 0 && mode != MODE_ECB && mode != MODE_CBC) { + printf("Usage: %s [ ecb | cbc ]\n", argv[0]); + return -1; + } + + set_verbosity(argc, argv); + + if (!mode) { + /* This is the standard loop that will perform all testcases */ + mode = 2; + while (mode) { + rc = test_3des_new_api(mode); + if (rc) { + error_count++; + V_(printf ("test_des_new_api mode = %i failed \n", mode)); + } + else { + V_(printf ("test_des_new_api mode = %i finished.\n", mode)); + } + + mode--; + } + if (error_count) + printf("%i tests failed.\n", error_count); + else + printf("All tests passed.\n"); + } else { + /* Perform only either in ECB or CBC mode */ + rc = test_3des_new_api(mode); + if (rc) + printf ("test_des_new_api mode = %i failed \n", mode); + else + printf ("test_des_new_api mode = %i finished.\n", mode); + } + + return rc; +} + diff --git a/src/tests/libica_aes128_test.c b/src/tests/libica_aes128_test.c new file mode 100644 index 0000000..bbd598e --- /dev/null +++ b/src/tests/libica_aes128_test.c @@ -0,0 +1,271 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2005, 2009, 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <unistd.h> +#include "ica_api.h" +#include <stdlib.h> +#include <openssl/aes.h> +#include "testcase.h" + +unsigned char NIST_KEY1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, +}; + +unsigned char NIST_TEST_DATA[] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, +}; + +unsigned char NIST_TEST_RESULT[] = { + 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, + 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a, +}; + +int test_aes128_new_api(int mode) +{ + ica_aes_vector_t iv; + unsigned char key[AES_KEY_LEN128]; + int rc = 0; + unsigned char dec_text[sizeof(NIST_TEST_DATA)], + enc_text[sizeof(NIST_TEST_DATA)]; + + bzero(dec_text, sizeof(dec_text)); + bzero(enc_text, sizeof(enc_text)); + bzero(iv, sizeof(iv)); + bcopy(NIST_KEY1, key, sizeof(NIST_KEY1)); + + rc = ica_aes_encrypt(mode, sizeof(NIST_TEST_DATA), NIST_TEST_DATA, &iv, + AES_KEY_LEN128, key, enc_text); + if (rc) { + VV_(printf("key \n")); + dump_array((unsigned char *) key, sizeof(NIST_KEY1)); + VV_(printf("\nOriginal data:\n")); + dump_array((unsigned char *) NIST_TEST_DATA, sizeof(NIST_TEST_DATA)); + VV_(printf("test iv\n")); + dump_array((unsigned char *) &iv, sizeof(ica_aes_vector_t)); + VV_(printf("key\n")); + dump_array((unsigned char *) key, AES_KEY_LEN128); + VV_(printf("ica_aes_encrypt failed with errno %d (0x%x).\n", rc, rc)); + return 1; + } + + if (memcmp(enc_text, NIST_TEST_RESULT, sizeof(NIST_TEST_RESULT)) != 0) { + VV_(printf("key \n")); + dump_array((unsigned char *) key, sizeof(NIST_KEY1)); + VV_(printf("\nOriginal data:\n")); + dump_array((unsigned char *) NIST_TEST_DATA, sizeof(NIST_TEST_DATA)); + VV_(printf("test iv\n")); + dump_array((unsigned char *) &iv, sizeof(ica_aes_vector_t)); + VV_(printf("key\n")); + dump_array((unsigned char *) key, AES_KEY_LEN128); + VV_(printf("\nEncrypted data:\n")); + dump_array((unsigned char *) enc_text, sizeof(enc_text)); + VV_(printf("This does NOT match the known result.\n")); + return 1; + } else { + VV_(printf("Yep, it's what it should be.\n")); + } + + bzero(iv, sizeof(iv)); + rc = ica_aes_decrypt(mode, sizeof(enc_text), enc_text, &iv, + AES_KEY_LEN128, key, dec_text); + if (rc) { + VV_(printf("key \n")); + dump_array((unsigned char *) key, sizeof(NIST_KEY1)); + VV_(printf("\nOriginal data:\n")); + dump_array((unsigned char *) NIST_TEST_DATA, sizeof(NIST_TEST_DATA)); + VV_(printf("test iv\n")); + dump_array((unsigned char *) &iv, sizeof(ica_aes_vector_t)); + VV_(printf("key\n")); + dump_array((unsigned char *) key, AES_KEY_LEN128); + VV_(printf("\nEncrypted data:\n")); + dump_array((unsigned char *) enc_text, sizeof(enc_text)); + VV_(printf("\nDecrypted data:\n")); + dump_array((unsigned char *) dec_text, sizeof(dec_text)); + VV_(printf("ica_aes_decrypt failed with errno %d (0x%x).\n", rc, rc)); + return 1; + } + + if (memcmp(dec_text, NIST_TEST_DATA, sizeof(NIST_TEST_DATA)) != 0) { + VV_(printf("This does NOT match the original data.\n")); + return 1; + } else { + VV_(printf("Successful!\n")); + VV_(printf("key \n")); + dump_array((unsigned char *) key, sizeof(NIST_KEY1)); + VV_(printf("\nOriginal data:\n")); + dump_array((unsigned char *) NIST_TEST_DATA, sizeof(NIST_TEST_DATA)); + VV_(printf("test iv\n")); + dump_array((unsigned char *) &iv, sizeof(ica_aes_vector_t)); + VV_(printf("key\n")); + dump_array((unsigned char *) key, AES_KEY_LEN128); + VV_(printf("\nEncrypted data:\n")); + dump_array((unsigned char *) enc_text, sizeof(enc_text)); + VV_(printf("\nDecrypted data:\n")); + dump_array((unsigned char *) dec_text, sizeof(dec_text)); + } + +// Test 2 + + rc = 0; + bzero(dec_text, sizeof(dec_text)); + bzero(enc_text, sizeof(enc_text)); + bzero(iv, sizeof(iv)); + bzero(key, sizeof(key)); + + unsigned int length = 64; + unsigned char *decrypt = malloc(length); + unsigned char *encrypt = malloc(length); + unsigned char *original = malloc(length); + ica_aes_key_len_128_t key2; + + rc = ica_random_number_generate(length, original); + if (rc) { + VV_(printf("ica_random_number_generate returned rc = %i\n", rc)); + return rc; + } + + rc = ica_random_number_generate(AES_KEY_LEN128, (unsigned char *) &key2); + if (rc) { + VV_(printf("ica_random_number_generate returned rc = %i\n", rc)); + return rc; + } + + rc = ica_aes_encrypt(mode, length, original, &iv, AES_KEY_LEN128, (unsigned char *) &key2, + (unsigned char *) encrypt); + if (rc) { + VV_(printf("\nOriginal data:\n")); + dump_array((unsigned char *) original, length); + VV_(printf("KEY: \n")); + dump_array((unsigned char *) &key2, AES_KEY_LEN128); + VV_(printf("ica_aes_encrypt failed with errno %d (0x%x).\n", rc, rc)); + return rc; + } + + if (memcmp(encrypt, original, length) == 0) { + VV_(printf("Encrypt and original are the same.\n")); + return 1; + } + + bzero(iv, sizeof(iv)); + rc = ica_aes_decrypt(mode, length, encrypt, &iv, AES_KEY_LEN128, + (unsigned char *) &key2, decrypt); + if (rc) { + VV_(printf("\nOriginal data:\n")); + dump_array((unsigned char *) original, length); + VV_(printf("KEY: \n")); + dump_array((unsigned char *) &key2, AES_KEY_LEN128); + VV_(printf("\nEncrypted data:\n")); + dump_array((unsigned char *) encrypt, length); + VV_(printf("ica_aes_decrypt failed with errno %d (0x%x).\n", rc, rc)); + goto free; + } + + if (memcmp(decrypt, original, length) != 0) { + VV_(printf("\nOriginal data:\n")); + dump_array((unsigned char *) original, length); + VV_(printf("KEY: \n")); + dump_array((unsigned char *) &key2, AES_KEY_LEN128); + VV_(printf("\nEncrypted data:\n")); + dump_array((unsigned char *) encrypt, length); + VV_(printf("\nDecrypted data:\n")); + dump_array((unsigned char *) decrypt, length); + VV_(printf("This does NOT match the original data.\n")); + rc = -1; + goto free; + } + + if(memcmp(decrypt, encrypt, length) == 0) { + VV_(printf("\nOriginal data:\n")); + dump_array((unsigned char *) original, length); + VV_(printf("KEY: \n")); + dump_array((unsigned char *) &key2, AES_KEY_LEN128); + VV_(printf("\nEncrypted data:\n")); + dump_array((unsigned char *) encrypt, length); + VV_(printf("\nDecrypted data:\n")); + dump_array((unsigned char *) decrypt, length); + VV_(printf("decrypt and encrypt are the same\n")); + rc = -1; + goto free; + + } else { + VV_(printf("Successful!\n")); + } + free: + free(original); + free(encrypt); + free(decrypt); + + return rc; +} + +/* + * Performs ECB and CBC tests. + */ +int main(int argc, char **argv) +{ + unsigned int mode = 0; + int rc = 0; + int error_count = 0; + + if (argc > 1) { + if (strstr(argv[1], "ecb")) + mode = MODE_ECB; + if (strstr(argv[1], "cbc")) + mode = MODE_CBC; + } + + if (argc > 2) { + if (strstr(argv[2], "ecb")) + mode = MODE_ECB; + if (strstr(argv[2], "cbc")) + mode = MODE_CBC; + } + + set_verbosity(argc, argv); + + if (mode != 0 && mode != MODE_ECB && mode != MODE_CBC) { + printf("Usage: %s [ ecb | cbc ]\n", argv[0]); + return -1; + } + + if (!mode) { + /* This is the standard loop that will perform all testcases */ + mode = 2; + while (mode) { + rc = test_aes128_new_api(mode); + if (rc) { + error_count++; + V_(printf ("test_aes_new_api mode = %i failed \n", mode)); + } + else { + V_(printf ("test_aes_new_api mode = %i finished.\n", mode)); + } + mode--; + } + if (error_count) + printf("%i AES-128-ECB/CBC tests failed.\n", error_count); + else + printf("All AES-128-ECB/CBC tests passed.\n"); + } else { + /* Perform only either in ECB or CBC mode */ + rc = test_aes128_new_api(mode); + if (rc) + printf ("test_aes_new_api mode = %i failed \n", mode); + else { + printf ("test_aes_new_api mode = %i finished.\n", mode); + } + } + return rc; +} + diff --git a/src/tests/libica_aes192_test.c b/src/tests/libica_aes192_test.c new file mode 100644 index 0000000..8f95c6c --- /dev/null +++ b/src/tests/libica_aes192_test.c @@ -0,0 +1,153 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2005, 2009, 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include "ica_api.h" +#include "testcase.h" + +unsigned char NIST_KEY2[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, +}; + +unsigned char NIST_TEST_DATA[] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, +}; + +unsigned char NIST_TEST_RESULT[] = { + 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, + 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91, +}; + +int test_aes192_new_api(int mode) +{ + ica_aes_vector_t iv; + ica_aes_key_len_192_t key; + int rc = 0; + unsigned char dec_text[sizeof(NIST_TEST_DATA)], + enc_text[sizeof(NIST_TEST_DATA)]; + + bzero(dec_text, sizeof(dec_text)); + bzero(enc_text, sizeof(enc_text)); + bzero(iv, sizeof(iv)); + bcopy(NIST_KEY2, key, sizeof(NIST_KEY2)); + + rc = ica_aes_encrypt(mode, sizeof(NIST_TEST_DATA), NIST_TEST_DATA, &iv, + AES_KEY_LEN192, (unsigned char *) &key, enc_text); + if (rc) { + VV_(printf("\nOriginal data:\n")); + dump_array((unsigned char*)NIST_TEST_DATA, sizeof(NIST_TEST_DATA)); + VV_(printf("ica_aes_encrypt failed with errno %d (0x%x).\n", rc, rc)); + return rc; + } + + if (memcmp(enc_text, NIST_TEST_RESULT, sizeof(NIST_TEST_RESULT)) != 0) { + VV_(printf("\nOriginal data:\n")); + dump_array((unsigned char*)NIST_TEST_DATA, sizeof(NIST_TEST_DATA)); + VV_(printf("\nEncrypted data:\n")); + dump_array((unsigned char*)enc_text, sizeof(enc_text)); + VV_(printf("This does NOT match the known result.\n")); + return 1; + } else { + VV_(printf("Yep, it's what it should be.\n")); + } + + bzero(iv, sizeof(iv)); + rc = ica_aes_decrypt(mode, sizeof(enc_text), enc_text, &iv, + AES_KEY_LEN192, (unsigned char *) &key, dec_text); + if (rc != 0) { + VV_(printf("ica_aes_decrypt failed with errno %d (0x%x).\n", rc, rc)); + return 1; + } + + if (memcmp(dec_text, NIST_TEST_DATA, sizeof(NIST_TEST_DATA)) != 0) { + VV_(printf("\nOriginal data:\n")); + dump_array((unsigned char*)NIST_TEST_DATA, sizeof(NIST_TEST_DATA)); + VV_(printf("\nEncrypted data:\n")); + dump_array((unsigned char*)enc_text, sizeof(enc_text)); + VV_(printf("\nDecrypted data:\n")); + dump_array((unsigned char*)dec_text, sizeof(dec_text)); + VV_(printf("This does NOT match the original data.\n")); + return 1; + } else { + VV_(printf("Successful!\n")); + VV_(printf("\nOriginal data:\n")); + dump_array((unsigned char*)NIST_TEST_DATA, sizeof(NIST_TEST_DATA)); + VV_(printf("\nEncrypted data:\n")); + dump_array((unsigned char*)enc_text, sizeof(enc_text)); + VV_(printf("\nDecrypted data:\n")); + dump_array((unsigned char*)dec_text, sizeof(dec_text)); + } + + return 0; +} + +/* + * Performs ECB and CBC tests. + */ +int main(int argc, char **argv) +{ + unsigned int mode = 0; + int rc = 0; + int error_count = 0; + + if (argc > 1) { + if (strstr(argv[1], "ecb")) + mode = MODE_ECB; + if (strstr(argv[1], "cbc")) + mode = MODE_CBC; + } + if (argc > 2) { + if (strstr(argv[2], "ecb")) + mode = MODE_ECB; + if (strstr(argv[2], "cbc")) + mode = MODE_CBC; + } + + set_verbosity(argc, argv); + + if (mode != 0 && mode != MODE_ECB && mode != MODE_CBC) { + printf("Usage: %s [ ecb | cbc ]\n", argv[0]); + return -1; + } + + if (!mode) { + /* This is the standard loop that will perform all testcases */ + mode = 2; + while (mode) { + rc = test_aes192_new_api(mode); + if (rc) { + error_count++; + V_(printf ("test_aes_new_api mode = %i failed \n", mode)); + } else { + V_(printf ("test_aes_new_api mode = %i finished.\n", mode)); + } + mode--; + } + if (error_count) + printf("%i AES-192-ECB/CBC tests failed.\n", error_count); + else + printf("All AES-192-ECB/CBC tests passed.\n"); + } else { + /* Perform only either in ECB or CBC mode */ + rc = test_aes192_new_api(mode); + if (rc) + printf ("test_aes_new_api mode = %i failed \n", mode); + else { + printf ("test_aes_new_api mode = %i finished.\n", mode); + } + } + return rc; +} + diff --git a/src/tests/libica_aes256_test.c b/src/tests/libica_aes256_test.c new file mode 100644 index 0000000..0b78283 --- /dev/null +++ b/src/tests/libica_aes256_test.c @@ -0,0 +1,153 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2005, 2009, 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include "ica_api.h" +#include "testcase.h" + +unsigned char NIST_KEY3[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, +}; + +unsigned char NIST_TEST_DATA[] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, +}; + +unsigned char NIST_TEST_RESULT[] = { + 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, + 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89, +}; + +int test_aes256_new_api(int mode) +{ + ica_aes_vector_t iv; + unsigned char key[AES_KEY_LEN256]; + int rc = 0; + unsigned char dec_text[sizeof(NIST_TEST_DATA)], + enc_text[sizeof(NIST_TEST_DATA)]; + + bzero(dec_text, sizeof(dec_text)); + bzero(enc_text, sizeof(enc_text)); + bzero(iv, sizeof(iv)); + bcopy(NIST_KEY3, key, sizeof(NIST_KEY3)); + + rc = ica_aes_encrypt(mode, sizeof(NIST_TEST_DATA), NIST_TEST_DATA, &iv, + AES_KEY_LEN256, key, enc_text); + if (rc) { + VV_(printf("ica_aes_encrypt failed with errno %d (0x%x).\n", rc, rc)); + return 1; + } + + if (memcmp(enc_text, NIST_TEST_RESULT, sizeof(NIST_TEST_RESULT)) != 0) { + VV_(printf("\nOriginal data:\n")); + dump_array((unsigned char *) NIST_TEST_DATA, sizeof(NIST_TEST_DATA)); + VV_(printf("\nEncrypted data:\n")); + dump_array((unsigned char *) enc_text, sizeof(enc_text)); + VV_(printf("This does NOT match the known result.\n")); + return 1; + } else { + VV_(printf("Yep, it's what it should be.\n")); + } + + bzero(iv, sizeof(iv)); + rc = ica_aes_decrypt(mode, sizeof(enc_text), enc_text, &iv, + AES_KEY_LEN256, key, dec_text); + if (rc) { + VV_(printf("ica_aes_decrypt failed with errno %d (0x%x).\n", rc, rc)); + return 1; + } + + if (memcmp(dec_text, NIST_TEST_DATA, sizeof(NIST_TEST_DATA)) != 0) { + VV_(printf("\nOriginal data:\n")); + dump_array((unsigned char *) NIST_TEST_DATA, sizeof(NIST_TEST_DATA)); + VV_(printf("\nEncrypted data:\n")); + dump_array((unsigned char *) enc_text, sizeof(enc_text)); + VV_(printf("\nDecrypted data:\n")); + dump_array((unsigned char *) dec_text, sizeof(dec_text)); + VV_(printf("This does NOT match the original data.\n")); + return 1; + } else { + VV_(printf("\nOriginal data:\n")); + dump_array((unsigned char *) NIST_TEST_DATA, sizeof(NIST_TEST_DATA)); + VV_(printf("\nEncrypted data:\n")); + dump_array((unsigned char *) enc_text, sizeof(enc_text)); + VV_(printf("\nDecrypted data:\n")); + dump_array((unsigned char *) dec_text, sizeof(dec_text)); + VV_(printf("Successful!\n")); + } + + return 0; +} + +/* + * Performs ECB and CBC tests. + */ +int main(int argc, char **argv) +{ + unsigned int mode = 0; + int rc = 0; + int error_count = 0; + + if (argc > 1) { + if (strstr(argv[1], "ecb")) + mode = MODE_ECB; + if (strstr(argv[1], "cbc")) + mode = MODE_CBC; + } + if (argc > 2) { + if (strstr(argv[2], "ecb")) + mode = MODE_ECB; + if (strstr(argv[2], "cbc")) + mode = MODE_CBC; + } + + set_verbosity(argc, argv); + + if (mode != 0 && mode != MODE_ECB && mode != MODE_CBC) { + printf("Usage: %s [ ecb | cbc ]\n", argv[0]); + return -1; + } + + if (!mode) { + /* This is the standard loop that will perform all testcases */ + mode = 2; + while (mode) { + rc = test_aes256_new_api(mode); + if (rc) { + error_count++; + V_(printf ("test_aes_new_api mode = %i failed \n", mode)); + } + else { + V_(printf ("test_aes_new_api mode = %i finished.\n", mode)); + } + mode--; + } + if (error_count) + printf("%i AES-256-ECB/CBC tests failed.\n", error_count); + else + printf("All AES-256-ECB/CBC tests passed.\n"); + } else { + /* Perform only either in ECB or CBC mode */ + rc = test_aes256_new_api(mode); + if (rc) + printf("test_aes_new_api mode = %i failed \n", mode); + else + printf("test_aes_new_api mode = %i finished.\n", mode); + } + + return rc; +} + diff --git a/src/tests/libica_aes_cbc_test.c b/src/tests/libica_aes_cbc_test.c new file mode 100644 index 0000000..8cca50a --- /dev/null +++ b/src/tests/libica_aes_cbc_test.c @@ -0,0 +1,614 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2010, 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include "ica_api.h" +#include "testcase.h" + +#define NR_TESTS 7 +#define NR_RANDOM_TESTS 10000 + +/* CBC data - 1 for AES128 */ +unsigned char NIST_KEY_CBC_E1[] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, +}; + +unsigned char NIST_IV_CBC_E1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, +}; + +unsigned char NIST_EXPECTED_IV_CBC_E1[] = { + 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, + 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d, +}; + +unsigned char NIST_TEST_DATA_CBC_E1[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, +}; + +unsigned char NIST_TEST_RESULT_CBC_E1[] = { + 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, + 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d, +}; + +/* CBC data - 2 for AES128 */ +unsigned char NIST_KEY_CBC_E2[] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, +}; + +unsigned char NIST_IV_CBC_E2[] = { + 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, + 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d, +}; + +unsigned char NIST_EXPECTED_IV_CBC_E2[] = { + 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee, + 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2, +}; + +unsigned char NIST_TEST_DATA_CBC_E2[] = { + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, +}; + +unsigned char NIST_TEST_RESULT_CBC_E2[] = { + 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee, + 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2, +}; + +/* CBC data - 3 - for AES128 */ +unsigned char NIST_KEY_CBC_E3[] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, + +}; + +unsigned char NIST_IV_CBC_E3[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, +}; + +unsigned char NIST_EXPECTED_IV_CBC_E3[] = { + 0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09, + 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7, +}; + +unsigned char NIST_TEST_DATA_CBC_E3[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10, +}; + +unsigned char NIST_TEST_RESULT_CBC_E3[] = { + 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, + 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d, + 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee, + 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2, + 0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b, + 0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16, + 0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09, + 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7, +}; + +/* CBC data - 4 - for AES192 */ +unsigned char NIST_KEY_CBC_E4[] = { + 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, + 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b, +}; + +unsigned char NIST_IV_CBC_E4[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, +}; + +unsigned char NIST_EXPECTED_IV_CBC_E4[] = { + 0x4f, 0x02, 0x1d, 0xb2, 0x43, 0xbc, 0x63, 0x3d, + 0x71, 0x78, 0x18, 0x3a, 0x9f, 0xa0, 0x71, 0xe8, +}; + +unsigned char NIST_TEST_DATA_CBC_E4[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, +}; + +unsigned char NIST_TEST_RESULT_CBC_E4[] = { + 0x4f, 0x02, 0x1d, 0xb2, 0x43, 0xbc, 0x63, 0x3d, + 0x71, 0x78, 0x18, 0x3a, 0x9f, 0xa0, 0x71, 0xe8, +}; + +/* CBC data 5 - for AES 192 */ +unsigned char NIST_KEY_CBC_E5[] = { + 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, + 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b, +}; + +unsigned char NIST_IV_CBC_E5[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, +}; + +unsigned char NIST_EXPECTED_IV_CBC_E5[] = { + 0x08, 0xb0, 0xe2, 0x79, 0x88, 0x59, 0x88, 0x81, + 0xd9, 0x20, 0xa9, 0xe6, 0x4f, 0x56, 0x15, 0xcd, +}; + +unsigned char NIST_TEST_DATA_CBC_E5[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10, +}; + +unsigned char NIST_TEST_RESULT_CBC_E5[] = { + 0x4f, 0x02, 0x1d, 0xb2, 0x43, 0xbc, 0x63, 0x3d, + 0x71, 0x78, 0x18, 0x3a, 0x9f, 0xa0, 0x71, 0xe8, + 0xb4, 0xd9, 0xad, 0xa9, 0xad, 0x7d, 0xed, 0xf4, + 0xe5, 0xe7, 0x38, 0x76, 0x3f, 0x69, 0x14, 0x5a, + 0x57, 0x1b, 0x24, 0x20, 0x12, 0xfb, 0x7a, 0xe0, + 0x7f, 0xa9, 0xba, 0xac, 0x3d, 0xf1, 0x02, 0xe0, + 0x08, 0xb0, 0xe2, 0x79, 0x88, 0x59, 0x88, 0x81, + 0xd9, 0x20, 0xa9, 0xe6, 0x4f, 0x56, 0x15, 0xcd, +}; + +/* CBC data 6 - for AES 256 */ +unsigned char NIST_KEY_CBC_E6[] = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4, +}; + +unsigned char NIST_IV_CBC_E6[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, +}; + +unsigned char NIST_EXPECTED_IV_CBC_E6[] = { + 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba, + 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6, +}; + +unsigned char NIST_TEST_DATA_CBC_E6[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, +}; + +unsigned char NIST_TEST_RESULT_CBC_E6[] = { + 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba, + 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6, +}; + +/* CBC data 7 - for AES 256 */ +unsigned char NIST_KEY_CBC_E7[] = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4, +}; + +unsigned char NIST_IV_CBC_E7[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, +}; + +unsigned char NIST_EXPECTED_IV_CBC_E7[] = { + 0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc, + 0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b, +}; + +unsigned char NIST_TEST_DATA_CBC_E7[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10, +}; + +unsigned char NIST_TEST_RESULT_CBC_E7[] = { + 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba, + 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6, + 0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d, + 0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d, + 0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf, + 0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61, + 0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc, + 0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b, +}; + +void dump_cbc_data(unsigned char *iv, unsigned int iv_length, + unsigned char *key, unsigned int key_length, + unsigned char *input_data, unsigned int data_length, + unsigned char *output_data) +{ + VV_(printf("IV \n")); + dump_array(iv, iv_length); + VV_(printf("Key \n")); + dump_array(key, key_length); + VV_(printf("Input Data\n")); + dump_array(input_data, data_length); + VV_(printf("Output Data\n")); + dump_array(output_data, data_length); +} + +void get_sizes(unsigned int *data_length, unsigned int *iv_length, + unsigned int *key_length, unsigned int iteration) +{ + switch (iteration) { + case 1: + *data_length = sizeof(NIST_TEST_DATA_CBC_E1); + *iv_length = sizeof(NIST_IV_CBC_E1); + *key_length = sizeof(NIST_KEY_CBC_E1); + break; + case 2: + *data_length = sizeof(NIST_TEST_DATA_CBC_E2); + *iv_length = sizeof(NIST_IV_CBC_E2); + *key_length = sizeof(NIST_KEY_CBC_E2); + break; + case 3: + *data_length = sizeof(NIST_TEST_DATA_CBC_E3); + *iv_length = sizeof(NIST_IV_CBC_E3); + *key_length = sizeof(NIST_KEY_CBC_E3); + break; + case 4: + *data_length = sizeof(NIST_TEST_DATA_CBC_E4); + *iv_length = sizeof(NIST_IV_CBC_E4); + *key_length = sizeof(NIST_KEY_CBC_E4); + break; + case 5: + *data_length = sizeof(NIST_TEST_DATA_CBC_E5); + *iv_length = sizeof(NIST_IV_CBC_E5); + *key_length = sizeof(NIST_KEY_CBC_E5); + break; + case 6: + *data_length = sizeof(NIST_TEST_DATA_CBC_E6); + *iv_length = sizeof(NIST_IV_CBC_E6); + *key_length = sizeof(NIST_KEY_CBC_E6); + break; + case 7: + *data_length = sizeof(NIST_TEST_DATA_CBC_E7); + *iv_length = sizeof(NIST_IV_CBC_E7); + *key_length = sizeof(NIST_KEY_CBC_E7); + break; + case 8: + break; + case 9: + break; + case 10: + break; + case 11: + break; + case 12: + break; + } + +} + +void load_test_data(unsigned char *data, unsigned int data_length, + unsigned char *result, + unsigned char *iv, unsigned char *expected_iv, + unsigned int iv_length, + unsigned char *key, unsigned int key_length, + unsigned int iteration) +{ + switch (iteration) { + case 1: + memcpy(data, NIST_TEST_DATA_CBC_E1, data_length); + memcpy(result, NIST_TEST_RESULT_CBC_E1, data_length); + memcpy(iv, NIST_IV_CBC_E1, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CBC_E1, iv_length); + memcpy(key, NIST_KEY_CBC_E1, key_length); + break; + case 2: + memcpy(data, NIST_TEST_DATA_CBC_E2, data_length); + memcpy(result, NIST_TEST_RESULT_CBC_E2, data_length); + memcpy(iv, NIST_IV_CBC_E2, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CBC_E2, iv_length); + memcpy(key, NIST_KEY_CBC_E2, key_length); + break; + case 3: + memcpy(data, NIST_TEST_DATA_CBC_E3, data_length); + memcpy(result, NIST_TEST_RESULT_CBC_E3, data_length); + memcpy(iv, NIST_IV_CBC_E3, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CBC_E3, iv_length); + memcpy(key, NIST_KEY_CBC_E3, key_length); + break; + case 4: + memcpy(data, NIST_TEST_DATA_CBC_E4, data_length); + memcpy(result, NIST_TEST_RESULT_CBC_E4, data_length); + memcpy(iv, NIST_IV_CBC_E4, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CBC_E4, iv_length); + memcpy(key, NIST_KEY_CBC_E4, key_length); + break; + case 5: + memcpy(data, NIST_TEST_DATA_CBC_E5, data_length); + memcpy(result, NIST_TEST_RESULT_CBC_E5, data_length); + memcpy(iv, NIST_IV_CBC_E5, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CBC_E5, iv_length); + memcpy(key, NIST_KEY_CBC_E5, key_length); + break; + case 6: + memcpy(data, NIST_TEST_DATA_CBC_E6, data_length); + memcpy(result, NIST_TEST_RESULT_CBC_E6, data_length); + memcpy(iv, NIST_IV_CBC_E6, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CBC_E6, iv_length); + memcpy(key, NIST_KEY_CBC_E6, key_length); + break; + case 7: + memcpy(data, NIST_TEST_DATA_CBC_E7, data_length); + memcpy(result, NIST_TEST_RESULT_CBC_E7, data_length); + memcpy(iv, NIST_IV_CBC_E7, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CBC_E7, iv_length); + memcpy(key, NIST_KEY_CBC_E7, key_length); + break; + case 8: + break; + case 9: + break; + case 10: + break; + case 11: + break; + case 12: + break; + } + +} + +int kat_aes_cbc(int iteration) +{ + unsigned int data_length; + unsigned int iv_length; + unsigned int key_length; + + get_sizes(&data_length, &iv_length, &key_length, iteration); + + unsigned char iv[iv_length]; + unsigned char tmp_iv[iv_length]; + unsigned char expected_iv[iv_length]; + unsigned char key[key_length]; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + unsigned char result[data_length]; + + int rc = 0; + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i, iv length = %i\n", + key_length, data_length, iv_length)); + + + load_test_data(input_data, data_length, result, iv, expected_iv, + iv_length, key, key_length, iteration); + memcpy(tmp_iv, iv, iv_length); + + rc = ica_aes_cbc(input_data, encrypt, data_length, key, key_length, + tmp_iv, 1); + if (rc) { + VV_(printf("ica_aes_cbc encrypt failed with rc = %i\n", rc)); + dump_cbc_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_cbc_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + + if (memcmp(result, encrypt, data_length)) { + VV_(printf("Encryption Result does not match the known ciphertext!\n")); + VV_(printf("Expected data:\n")); + dump_array(result, data_length); + VV_(printf("Encryption Result:\n")); + dump_array(encrypt, data_length); + rc++; + } + + if (memcmp(expected_iv, tmp_iv, iv_length)) { + VV_(printf("Update of IV does not match the expected IV!\n")); + VV_(printf("Expected IV:\n")); + dump_array(expected_iv, iv_length); + VV_(printf("Updated IV:\n")); + dump_array(tmp_iv, iv_length); + VV_(printf("Original IV:\n")); + dump_array(iv, iv_length); + rc++; + } + if (rc) { + VV_(printf("AES CBC test exited after encryption\n")); + return rc; + } + + memcpy(tmp_iv, iv, iv_length); + rc = ica_aes_cbc(encrypt, decrypt, data_length, key, key_length, + tmp_iv, 0); + if (rc) { + VV_(printf("ica_aes_cbc decrypt failed with rc = %i\n", rc)); + dump_cbc_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_cbc_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + } + return rc; +} + +int load_random_test_data(unsigned char *data, unsigned int data_length, + unsigned char *iv, unsigned int iv_length, + unsigned char *key, unsigned int key_length) +{ + int rc; + + rc = ica_random_number_generate(data_length, data); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + rc = ica_random_number_generate(iv_length, iv); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + rc = ica_random_number_generate(key_length, key); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + return rc; +} + +int random_aes_cbc(int iteration, unsigned int data_length) +{ + int i; + int rc = 0; + unsigned int iv_length = sizeof(ica_aes_vector_t); + unsigned int key_length = AES_KEY_LEN128; + unsigned char iv[iv_length]; + unsigned char tmp_iv[iv_length]; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + + for (i = 1; i <= 2; i++) { + unsigned char key[key_length]; + + memset(encrypt, 0x00, data_length); + memset(decrypt, 0x00, data_length); + + load_random_test_data(input_data, data_length, iv, iv_length, key, + key_length); + memcpy(tmp_iv, iv, iv_length); + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i, iv length = %i\n", + key_length, data_length, iv_length)); + + rc = ica_aes_cbc(input_data, encrypt, data_length, key, key_length, + tmp_iv, 1); + if (rc) { + VV_(printf("ica_aes_cbc encrypt failed with rc = %i\n", rc)); + dump_cbc_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + VV_(printf("Encrypt:\n")); + dump_cbc_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + VV_(printf("AES CBC test exited after encryption\n")); + return rc; + } + + memcpy(tmp_iv, iv, iv_length); + + rc = ica_aes_cbc(encrypt, decrypt, data_length, key, key_length, + tmp_iv, 0); + if (rc) { + VV_(printf("ica_aes_cbc decrypt failed with rc = %i\n", rc)); + dump_cbc_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_cbc_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + return rc; + } + key_length += 8; + } + + return rc; +} + +int main(int argc, char **argv) +{ + int rc = 0; + int error_count = 0; + int iteration; + unsigned int data_length = sizeof(ica_aes_vector_t); + + set_verbosity(argc, argv); + + for(iteration = 1; iteration <= NR_TESTS; iteration++) { + rc = kat_aes_cbc(iteration); + if (rc) { + V_(printf("kat_aes_cbc failed with rc = %i\n", rc)); + error_count++; + } else { + V_(printf("kat_aes_cbc finished.n")); + } + } + for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) { + rc = random_aes_cbc(iteration, data_length); + if (rc) { + V_(printf("random_aes_cbc failed with rc = %i\n", rc)); + error_count++; + goto out; + } else { + V_(printf("random_aes_cbc finished.n")); + } + data_length += sizeof(ica_aes_vector_t); + } + +out: + if (error_count) + printf("%i AES-CBC tests failed.\n", error_count); + else { + printf("All AES-CBC tests passed.\n"); + } + + return rc; +} + diff --git a/src/tests/libica_aes_cfb_test.c b/src/tests/libica_aes_cfb_test.c new file mode 100644 index 0000000..e1ca248 --- /dev/null +++ b/src/tests/libica_aes_cfb_test.c @@ -0,0 +1,804 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2010, 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include "ica_api.h" +#include "testcase.h" + +#define NR_TESTS 12 +#define NR_RANDOM_TESTS 1000 + +/* CFB128 data -1- AES128 */ +unsigned char NIST_KEY_CFB_E1[] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, +}; + +unsigned char NIST_IV_CFB_E1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, +}; + +unsigned char NIST_EXPECTED_IV_CFB_E1[] = { + 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20, + 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a, +}; + +unsigned char NIST_TEST_DATA_CFB_E1[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, +}; + +unsigned char NIST_TEST_RESULT_CFB_E1[] = { + 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20, + 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a, +}; + +unsigned int NIST_LCFB_E1 = 128 / 8; + +/* CFB128 data -2- AES128 */ +unsigned char NIST_KEY_CFB_E2[] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, +}; + +unsigned char NIST_IV_CFB_E2[] = { + 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20, + 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a, +}; + +unsigned char NIST_EXPECTED_IV_CFB_E2[] = { + 0xc8, 0xa6, 0x45, 0x37, 0xa0, 0xb3, 0xa9, 0x3f, + 0xcd, 0xe3, 0xcd, 0xad, 0x9f, 0x1c, 0xe5, 0x8b, +}; + +unsigned char NIST_TEST_DATA_CFB_E2[] = { + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, +}; + +unsigned char NIST_TEST_RESULT_CFB_E2[] = { + 0xc8, 0xa6, 0x45, 0x37, 0xa0, 0xb3, 0xa9, 0x3f, + 0xcd, 0xe3, 0xcd, 0xad, 0x9f, 0x1c, 0xe5, 0x8b, +}; + +unsigned int NIST_LCFB_E2 = 128 / 8; + +/* CFB8 data -3- AES128 */ +unsigned char NIST_KEY_CFB_E3[] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, +}; + +unsigned char NIST_IV_CFB_E3[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, +}; + +unsigned char NIST_EXPECTED_IV_CFB_E3[] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x3b, +}; +unsigned char NIST_TEST_DATA_CFB_E3[] = { + 0x6b, +}; + +unsigned char NIST_TEST_RESULT_CFB_E3[] = { + 0x3b, +}; +unsigned int NIST_LCFB_E3 = 8 / 8; + +/* CFB8 data -4- AES128 */ +unsigned char NIST_KEY_CFB_E4[] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, +}; + +unsigned char NIST_IV_CFB_E4[] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x3b, +}; + +unsigned char NIST_EXPECTED_IV_CFB_E4[] = { + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x3b, 0x79, +}; +unsigned char NIST_TEST_DATA_CFB_E4[] = { + 0xc1, +}; + +unsigned char NIST_TEST_RESULT_CFB_E4[] = { + 0x79, +}; + +unsigned int NIST_LCFB_E4 = 8 / 8; + + +/* CFB 128 data -5- for AES192 */ +unsigned char NIST_KEY_CFB_E5[] = { + 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, + 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b, +}; + +unsigned char NIST_IV_CFB_E5[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, +}; + +unsigned char NIST_EXPECTED_IV_CFB_E5[] = { + 0xcd, 0xc8, 0x0d, 0x6f, 0xdd, 0xf1, 0x8c, 0xab, + 0x34, 0xc2, 0x59, 0x09, 0xc9, 0x9a, 0x41, 0x74, +}; + +unsigned char NIST_TEST_DATA_CFB_E5[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, +}; + +unsigned char NIST_TEST_RESULT_CFB_E5[] = { + 0xcd, 0xc8, 0x0d, 0x6f, 0xdd, 0xf1, 0x8c, 0xab, + 0x34, 0xc2, 0x59, 0x09, 0xc9, 0x9a, 0x41, 0x74, +}; + +unsigned int NIST_LCFB_E5 = 128 / 8; + +/* CFB 128 data -6- for AES192 */ +unsigned char NIST_KEY_CFB_E6[] = { + 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, + 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b, +}; + +unsigned char NIST_IV_CFB_E6[] = { + 0xcd, 0xc8, 0x0d, 0x6f, 0xdd, 0xf1, 0x8c, 0xab, + 0x34, 0xc2, 0x59, 0x09, 0xc9, 0x9a, 0x41, 0x74, +}; + +unsigned char NIST_EXPECTED_IV_CFB_E6[] = { + 0x67, 0xce, 0x7f, 0x7f, 0x81, 0x17, 0x36, 0x21, + 0x96, 0x1a, 0x2b, 0x70, 0x17, 0x1d, 0x3d, 0x7a, +}; + +unsigned char NIST_TEST_DATA_CFB_E6[] = { + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, +}; + +unsigned char NIST_TEST_RESULT_CFB_E6[] = { + 0x67, 0xce, 0x7f, 0x7f, 0x81, 0x17, 0x36, 0x21, + 0x96, 0x1a, 0x2b, 0x70, 0x17, 0x1d, 0x3d, 0x7a, +}; + +unsigned int NIST_LCFB_E6 = 128 / 8; + +/* CFB 128 data -7- for AES192 */ +unsigned char NIST_KEY_CFB_E7[] = { + 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, + 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b, +}; + +unsigned char NIST_IV_CFB_E7[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, +}; + +unsigned char NIST_EXPECTED_IV_CFB_E7[] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xcd, +}; + +unsigned char NIST_TEST_DATA_CFB_E7[] = { + 0x6b, +}; + +unsigned char NIST_TEST_RESULT_CFB_E7[] = { + 0xcd, +}; + +unsigned int NIST_LCFB_E7 = 8 / 8; + +/* CFB 128 data -8- for AES192 */ +unsigned char NIST_KEY_CFB_E8[] = { + 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, + 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b, +}; + +unsigned char NIST_IV_CFB_E8[] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xcd, +}; + +unsigned char NIST_EXPECTED_IV_CFB_E8[] = { + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xcd, 0xa2, +}; + +unsigned char NIST_TEST_DATA_CFB_E8[] = { + 0xc1, +}; + +unsigned char NIST_TEST_RESULT_CFB_E8[] = { + 0xa2, +}; + +unsigned int NIST_LCFB_E8 = 8 / 8; + + + +/* CFB128 data -9- for AES256 */ +unsigned char NIST_KEY_CFB_E9[] = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4, +}; + +unsigned char NIST_IV_CFB_E9[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, +}; + +unsigned char NIST_EXPECTED_IV_CFB_E9[] = { + 0xdc, 0x7e, 0x84, 0xbf, 0xda, 0x79, 0x16, 0x4b, + 0x7e, 0xcd, 0x84, 0x86, 0x98, 0x5d, 0x38, 0x60, +}; + +unsigned char NIST_TEST_DATA_CFB_E9[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, +}; + +unsigned char NIST_TEST_RESULT_CFB_E9[] = { + 0xdc, 0x7e, 0x84, 0xbf, 0xda, 0x79, 0x16, 0x4b, + 0x7e, 0xcd, 0x84, 0x86, 0x98, 0x5d, 0x38, 0x60, +}; + +unsigned int NIST_LCFB_E9 = 128 / 8; + +/* CFB128 data -10- for AES256 */ +unsigned char NIST_KEY_CFB_E10[] = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4, +}; + +unsigned char NIST_IV_CFB_E10[] = { + 0xdc, 0x7e, 0x84, 0xbf, 0xda, 0x79, 0x16, 0x4b, + 0x7e, 0xcd, 0x84, 0x86, 0x98, 0x5d, 0x38, 0x60, +}; + +unsigned char NIST_EXPECTED_IV_CFB_E10[] = { + 0x39, 0xff, 0xed, 0x14, 0x3b, 0x28, 0xb1, 0xc8, + 0x32, 0x11, 0x3c, 0x63, 0x31, 0xe5, 0x40, 0x7b, +}; + +unsigned char NIST_TEST_DATA_CFB_E10[] = { + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, +}; + +unsigned char NIST_TEST_RESULT_CFB_E10[] = { + 0x39, 0xff, 0xed, 0x14, 0x3b, 0x28, 0xb1, 0xc8, + 0x32, 0x11, 0x3c, 0x63, 0x31, 0xe5, 0x40, 0x7b, +}; + +unsigned int NIST_LCFB_E10 = 128 / 8; + +/* CFB8 data -11- for AES256 */ +unsigned char NIST_KEY_CFB_E11[] = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4, +}; + +unsigned char NIST_IV_CFB_E11[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, +}; + +unsigned char NIST_EXPECTED_IV_CFB_E11[] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xdc, +}; + +unsigned char NIST_TEST_DATA_CFB_E11[] = { + 0x6b, +}; + +unsigned char NIST_TEST_RESULT_CFB_E11[] = { + 0xdc, +}; + +unsigned int NIST_LCFB_E11 = 8 / 8; + +/* CFB8 data -12- for AES256 */ +unsigned char NIST_KEY_CFB_E12[] = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4, +}; + +unsigned char NIST_IV_CFB_E12[] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xdc, +}; + +unsigned char NIST_EXPECTED_IV_CFB_E12[] = { + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xdc, 0x1f, +}; + +unsigned char NIST_TEST_DATA_CFB_E12[] = { + 0xc1, +}; + +unsigned char NIST_TEST_RESULT_CFB_E12[] = { + 0x1f, +}; + +unsigned int NIST_LCFB_E12 = 8 / 8; + +void dump_cfb_data(unsigned char *iv, unsigned int iv_length, + unsigned char *key, unsigned int key_length, + unsigned char *input_data, unsigned int data_length, + unsigned char *output_data) +{ + VV_(printf("IV \n")); + dump_array(iv, iv_length); + VV_(printf("Key \n")); + dump_array(key, key_length); + VV_(printf("Input Data\n")); + dump_array(input_data, data_length); + VV_(printf("Output Data\n")); + dump_array(output_data, data_length); +} + +void get_sizes(unsigned int *data_length, unsigned int *iv_length, + unsigned int *key_length, unsigned int iteration) +{ + switch (iteration) { + case 1: + *data_length = sizeof(NIST_TEST_DATA_CFB_E1); + *iv_length = sizeof(NIST_IV_CFB_E1); + *key_length = sizeof(NIST_KEY_CFB_E1); + break; + case 2: + *data_length = sizeof(NIST_TEST_DATA_CFB_E2); + *iv_length = sizeof(NIST_IV_CFB_E2); + *key_length = sizeof(NIST_KEY_CFB_E2); + break; + case 3: + *data_length = sizeof(NIST_TEST_DATA_CFB_E3); + *iv_length = sizeof(NIST_IV_CFB_E3); + *key_length = sizeof(NIST_KEY_CFB_E3); + break; + case 4: + *data_length = sizeof(NIST_TEST_DATA_CFB_E4); + *iv_length = sizeof(NIST_IV_CFB_E4); + *key_length = sizeof(NIST_KEY_CFB_E4); + break; + case 5: + *data_length = sizeof(NIST_TEST_DATA_CFB_E5); + *iv_length = sizeof(NIST_IV_CFB_E5); + *key_length = sizeof(NIST_KEY_CFB_E5); + break; + case 6: + *data_length = sizeof(NIST_TEST_DATA_CFB_E6); + *iv_length = sizeof(NIST_IV_CFB_E6); + *key_length = sizeof(NIST_KEY_CFB_E6); + break; + case 7: + *data_length = sizeof(NIST_TEST_DATA_CFB_E7); + *iv_length = sizeof(NIST_IV_CFB_E7); + *key_length = sizeof(NIST_KEY_CFB_E7); + break; + case 8: + *data_length = sizeof(NIST_TEST_DATA_CFB_E8); + *iv_length = sizeof(NIST_IV_CFB_E8); + *key_length = sizeof(NIST_KEY_CFB_E8); + break; + case 9: + *data_length = sizeof(NIST_TEST_DATA_CFB_E9); + *iv_length = sizeof(NIST_IV_CFB_E9); + *key_length = sizeof(NIST_KEY_CFB_E9); + break; + case 10: + *data_length = sizeof(NIST_TEST_DATA_CFB_E10); + *iv_length = sizeof(NIST_IV_CFB_E10); + *key_length = sizeof(NIST_KEY_CFB_E10); + break; + case 11: + *data_length = sizeof(NIST_TEST_DATA_CFB_E11); + *iv_length = sizeof(NIST_IV_CFB_E11); + *key_length = sizeof(NIST_KEY_CFB_E11); + break; + case 12: + *data_length = sizeof(NIST_TEST_DATA_CFB_E12); + *iv_length = sizeof(NIST_IV_CFB_E12); + *key_length = sizeof(NIST_KEY_CFB_E12); + break; + } + +} + +void load_test_data(unsigned char *data, unsigned int data_length, + unsigned char *result, + unsigned char *iv, unsigned char *expected_iv, + unsigned int iv_length, + unsigned char *key, unsigned int key_length, + unsigned int *lcfb, unsigned int iteration) +{ + switch (iteration) { + case 1: + memcpy(data, NIST_TEST_DATA_CFB_E1, data_length); + memcpy(result, NIST_TEST_RESULT_CFB_E1, data_length); + memcpy(iv, NIST_IV_CFB_E1, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E1, iv_length); + memcpy(key, NIST_KEY_CFB_E1, key_length); + *lcfb = NIST_LCFB_E1; + break; + case 2: + memcpy(data, NIST_TEST_DATA_CFB_E2, data_length); + memcpy(result, NIST_TEST_RESULT_CFB_E2, data_length); + memcpy(iv, NIST_IV_CFB_E2, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E2, iv_length); + memcpy(key, NIST_KEY_CFB_E2, key_length); + *lcfb = NIST_LCFB_E2; + break; + case 3: + memcpy(data, NIST_TEST_DATA_CFB_E3, data_length); + memcpy(result, NIST_TEST_RESULT_CFB_E3, data_length); + memcpy(iv, NIST_IV_CFB_E3, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E3, iv_length); + memcpy(key, NIST_KEY_CFB_E3, key_length); + *lcfb = NIST_LCFB_E3; + break; + case 4: + memcpy(data, NIST_TEST_DATA_CFB_E4, data_length); + memcpy(result, NIST_TEST_RESULT_CFB_E4, data_length); + memcpy(iv, NIST_IV_CFB_E4, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E4, iv_length); + memcpy(key, NIST_KEY_CFB_E4, key_length); + *lcfb = NIST_LCFB_E4; + break; + case 5: + memcpy(data, NIST_TEST_DATA_CFB_E5, data_length); + memcpy(result, NIST_TEST_RESULT_CFB_E5, data_length); + memcpy(iv, NIST_IV_CFB_E5, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E5, iv_length); + memcpy(key, NIST_KEY_CFB_E5, key_length); + *lcfb = NIST_LCFB_E5; + break; + case 6: + memcpy(data, NIST_TEST_DATA_CFB_E6, data_length); + memcpy(result, NIST_TEST_RESULT_CFB_E6, data_length); + memcpy(iv, NIST_IV_CFB_E6, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E6, iv_length); + memcpy(key, NIST_KEY_CFB_E6, key_length); + *lcfb = NIST_LCFB_E6; + break; + case 7: + memcpy(data, NIST_TEST_DATA_CFB_E7, data_length); + memcpy(result, NIST_TEST_RESULT_CFB_E7, data_length); + memcpy(iv, NIST_IV_CFB_E7, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E7, iv_length); + memcpy(key, NIST_KEY_CFB_E7, key_length); + *lcfb = NIST_LCFB_E7; + break; + case 8: + memcpy(data, NIST_TEST_DATA_CFB_E8, data_length); + memcpy(result, NIST_TEST_RESULT_CFB_E8, data_length); + memcpy(iv, NIST_IV_CFB_E8, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E8, iv_length); + memcpy(key, NIST_KEY_CFB_E8, key_length); + *lcfb = NIST_LCFB_E8; + break; + case 9: + memcpy(data, NIST_TEST_DATA_CFB_E9, data_length); + memcpy(result, NIST_TEST_RESULT_CFB_E9, data_length); + memcpy(iv, NIST_IV_CFB_E9, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E9, iv_length); + memcpy(key, NIST_KEY_CFB_E9, key_length); + *lcfb = NIST_LCFB_E9; + break; + case 10: + memcpy(data, NIST_TEST_DATA_CFB_E10, data_length); + memcpy(result, NIST_TEST_RESULT_CFB_E10, data_length); + memcpy(iv, NIST_IV_CFB_E10, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E10, iv_length); + memcpy(key, NIST_KEY_CFB_E10, key_length); + *lcfb = NIST_LCFB_E10; + break; + case 11: + memcpy(data, NIST_TEST_DATA_CFB_E11, data_length); + memcpy(result, NIST_TEST_RESULT_CFB_E11, data_length); + memcpy(iv, NIST_IV_CFB_E11, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E11, iv_length); + memcpy(key, NIST_KEY_CFB_E11, key_length); + *lcfb = NIST_LCFB_E11; + break; + case 12: + memcpy(data, NIST_TEST_DATA_CFB_E12, data_length); + memcpy(result, NIST_TEST_RESULT_CFB_E12, data_length); + memcpy(iv, NIST_IV_CFB_E12, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CFB_E12, iv_length); + memcpy(key, NIST_KEY_CFB_E12, key_length); + *lcfb = NIST_LCFB_E12; + break; + } + +} + +int kat_aes_cfb(int iteration) +{ + unsigned int data_length; + unsigned int iv_length; + unsigned int key_length; + + get_sizes(&data_length, &iv_length, &key_length, iteration); + + unsigned char iv[iv_length]; + unsigned char tmp_iv[iv_length]; + unsigned char expected_iv[iv_length]; + unsigned char key[key_length]; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + unsigned char result[data_length]; + + int rc = 0; + unsigned int lcfb; + + memset(encrypt, 0x00, data_length); + memset(decrypt, 0x00, data_length); + + load_test_data(input_data, data_length, result, iv, expected_iv, + iv_length, key, key_length, &lcfb, iteration); + memcpy(tmp_iv, iv, iv_length); + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i, iv length = %i," + " lcfb = %i\n", key_length, data_length, iv_length, lcfb)); + if (iteration == 3) + rc = ica_aes_cfb(input_data, encrypt, lcfb, key, key_length, tmp_iv, + lcfb, 1); + else + rc = ica_aes_cfb(input_data, encrypt, data_length, key, key_length, + tmp_iv, lcfb, 1); + if (rc) { + VV_(printf("ica_aes_cfb encrypt failed with rc = %i\n", rc)); + dump_cfb_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_cfb_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + + if (memcmp(result, encrypt, data_length)) { + VV_(printf("Encryption Result does not match the known ciphertext!\n")); + VV_(printf("Expected data:\n")); + dump_array(result, data_length); + VV_(printf("Encryption Result:\n")); + dump_array(encrypt, data_length); + rc++; + } + + if (memcmp(expected_iv, tmp_iv, iv_length)) { + VV_(printf("Update of IV does not match the expected IV!\n")); + VV_(printf("Expected IV:\n")); + dump_array(expected_iv, iv_length); + VV_(printf("Updated IV:\n")); + dump_array(tmp_iv, iv_length); + VV_(printf("Original IV:\n")); + dump_array(iv, iv_length); + rc++; + } + if (rc) { + VV_(printf("AES OFB test exited after encryption\n")); + return rc; + } + + memcpy(tmp_iv, iv, iv_length); + if (iteration == 3) + rc = ica_aes_cfb(encrypt, decrypt, lcfb, key, key_length, tmp_iv, + lcfb, 0); + else + rc = ica_aes_cfb(encrypt, decrypt, data_length, key, key_length, + tmp_iv, lcfb, 0); + if (rc) { + VV_(printf("ica_aes_cfb decrypt failed with rc = %i\n", rc)); + dump_cfb_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_cfb_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + } + return rc; +} + +int load_random_test_data(unsigned char *data, unsigned int data_length, + unsigned char *iv, unsigned int iv_length, + unsigned char *key, unsigned int key_length) +{ + int rc; + + rc = ica_random_number_generate(data_length, data); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + rc = ica_random_number_generate(iv_length, iv); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + rc = ica_random_number_generate(key_length, key); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + return rc; +} + +int random_aes_cfb(int iteration, unsigned int data_length, unsigned int lcfb) +{ + unsigned int iv_length = sizeof(ica_aes_vector_t); + unsigned int key_length = AES_KEY_LEN128; + + unsigned char iv[iv_length]; + unsigned char tmp_iv[iv_length]; + unsigned char key[key_length]; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + + int rc = 0; + + for (key_length = AES_KEY_LEN128; key_length <= AES_KEY_LEN256; key_length += 8) { + memset(encrypt, 0x00, data_length); + memset(decrypt, 0x00, data_length); + + load_random_test_data(input_data, data_length, iv, iv_length, key, + key_length); + memcpy(tmp_iv, iv, iv_length); + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i, iv length = %i," + " lcfb = %i\n", key_length, data_length, iv_length, lcfb)); + rc = ica_aes_cfb(input_data, encrypt, data_length, key, key_length, + tmp_iv, lcfb, 1); + if (rc) { + VV_(printf("ica_aes_cfb encrypt failed with rc = %i\n", rc)); + dump_cfb_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_cfb_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + + if (rc) { + VV_(printf("AES OFB test exited after encryption\n")); + return rc; + } + + memcpy(tmp_iv, iv, iv_length); + + rc = ica_aes_cfb(encrypt, decrypt, data_length, key, key_length, + tmp_iv, lcfb, 0); + if (rc) { + VV_(printf("ica_aes_cfb decrypt failed with rc = %i\n", rc)); + dump_cfb_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_cfb_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + } + } + return rc; +} + +int main(int argc, char **argv) +{ + unsigned int data_length = 1; + unsigned int lcfb = 1; + unsigned int j; + unsigned int rdata; + int rc = 0; + int error_count = 0; + int iteration; + + set_verbosity(argc, argv); + + for(iteration = 1; iteration <= NR_TESTS; iteration++) { + rc = kat_aes_cfb(iteration); + if (rc) { + V_(printf("kat_aes_cfb failed with rc = %i\n", rc)); + error_count++; + } + } + + for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) { + for (j = 1; j <= 3; j++) { + if (!(data_length % lcfb)) { + rc = random_aes_cfb(iteration, data_length, lcfb); + if (rc) { + V_(printf("random_aes_cfb failed with rc = %i\n", rc)); + error_count++; + } + } + switch (j) { + case 1: + lcfb = 1; + break; + case 2: + lcfb = 8; + break; + case 3: + lcfb = 16; + break; + } + } + // add a value between 1 and 8 to data_length + if (ica_random_number_generate(sizeof(rdata), (unsigned char*) &rdata)) { + printf("ica_random_number_generate failed with errnor = %i\n", + errno); + exit(1); + } + data_length += (rdata % 8) + 1; + } + if (error_count) + printf("%i AES-CFB tests failed.\n", error_count); + else + printf("All AES-CFB tests passed.\n"); + + return rc; +} + diff --git a/src/tests/libica_aes_ctr_test.c b/src/tests/libica_aes_ctr_test.c new file mode 100644 index 0000000..8b3cf42 --- /dev/null +++ b/src/tests/libica_aes_ctr_test.c @@ -0,0 +1,638 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2010, 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include "ica_api.h" +#include "testcase.h" + +#define NR_TESTS 7 +#define NR_RANDOM_TESTS 1000 + +/* CTR data - 1 for AES128 */ +unsigned char NIST_KEY_CTR_E1[] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, +}; + +unsigned char NIST_IV_CTR_E1[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +unsigned char NIST_EXPECTED_IV_CTR_E1[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xff, 0x00, +}; + +unsigned char NIST_TEST_DATA_CTR_E1[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, +}; + +unsigned char NIST_TEST_RESULT_CTR_E1[] = { + 0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26, + 0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce, +}; + +/* CTR data - 2 for AES128 */ +unsigned char NIST_KEY_CTR_E2[] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, +}; + +unsigned char NIST_IV_CTR_E2[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +unsigned char NIST_EXPECTED_IV_CTR_E2[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xff, 0x03, +}; + +unsigned char NIST_TEST_DATA_CTR_E2[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10, +}; + +unsigned char NIST_TEST_RESULT_CTR_E2[] = { + 0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26, + 0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce, + 0x98, 0x06, 0xf6, 0x6b, 0x79, 0x70, 0xfd, 0xff, + 0x86, 0x17, 0x18, 0x7b, 0xb9, 0xff, 0xfd, 0xff, + 0x5a, 0xe4, 0xdf, 0x3e, 0xdb, 0xd5, 0xd3, 0x5e, + 0x5b, 0x4f, 0x09, 0x02, 0x0d, 0xb0, 0x3e, 0xab, + 0x1e, 0x03, 0x1d, 0xda, 0x2f, 0xbe, 0x03, 0xd1, + 0x79, 0x21, 0x70, 0xa0, 0xf3, 0x00, 0x9c, 0xee, +}; + +/* CTR data - 3 - for AES192 */ +unsigned char NIST_KEY_CTR_E3[] = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4, +}; + +unsigned char NIST_IV_CTR_E3[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +unsigned char NIST_EXPECTED_IV_CTR_E3[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xff, 0x00, +}; + +unsigned char NIST_TEST_DATA_CTR_E3[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, +}; + +unsigned char NIST_TEST_RESULT_CTR_E3[] = { + 0x60, 0x1e, 0xc3, 0x13, 0x77, 0x57, 0x89, 0xa5, + 0xb7, 0xa7, 0xf5, 0x04, 0xbb, 0xf3, 0xd2, 0x28, +}; + +/* CTR data - 4 - for AES192 */ +unsigned char NIST_KEY_CTR_E4[] = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4, +}; + +unsigned char NIST_IV_CTR_E4[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xff, 0x00, +}; + +unsigned char NIST_EXPECTED_IV_CTR_E4[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xff, 0x01, +}; + +unsigned char NIST_TEST_DATA_CTR_E4[] = { + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, +}; + +unsigned char NIST_TEST_RESULT_CTR_E4[] = { + 0xf4, 0x43, 0xe3, 0xca, 0x4d, 0x62, 0xb5, 0x9a, + 0xca, 0x84, 0xe9, 0x90, 0xca, 0xca, 0xf5, 0xc5, +}; + +/* CTR data 5 - for AES 256 */ +unsigned char NIST_KEY_CTR_E5[] = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4, +}; + +unsigned char NIST_IV_CTR_E5[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +unsigned char NIST_EXPECTED_IV_CTR_E5[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xff, 0x03, +}; + +unsigned char NIST_TEST_DATA_CTR_E5[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10, +}; + +unsigned char NIST_TEST_RESULT_CTR_E5[] = { + 0x60, 0x1e, 0xc3, 0x13, 0x77, 0x57, 0x89, 0xa5, + 0xb7, 0xa7, 0xf5, 0x04, 0xbb, 0xf3, 0xd2, 0x28, + 0xf4, 0x43, 0xe3, 0xca, 0x4d, 0x62, 0xb5, 0x9a, + 0xca, 0x84, 0xe9, 0x90, 0xca, 0xca, 0xf5, 0xc5, + 0x2b, 0x09, 0x30, 0xda, 0xa2, 0x3d, 0xe9, 0x4c, + 0xe8, 0x70, 0x17, 0xba, 0x2d, 0x84, 0x98, 0x8d, + 0xdf, 0xc9, 0xc5, 0x8d, 0xb6, 0x7a, 0xad, 0xa6, + 0x13, 0xc2, 0xdd, 0x08, 0x45, 0x79, 0x41, 0xa6, +}; + +/* CTR data 6 - for AES 256. + * Data is != BLOCK_SIZE */ +unsigned char NIST_KEY_CTR_E6[] = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4, +}; + +unsigned char NIST_IV_CTR_E6[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +unsigned char NIST_EXPECTED_IV_CTR_E6[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xff, 0x03, +}; + +unsigned char NIST_TEST_DATA_CTR_E6[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, +}; + +unsigned char NIST_TEST_RESULT_CTR_E6[] = { + 0x60, 0x1e, 0xc3, 0x13, 0x77, 0x57, 0x89, 0xa5, + 0xb7, 0xa7, 0xf5, 0x04, 0xbb, 0xf3, 0xd2, 0x28, + 0xf4, 0x43, 0xe3, 0xca, 0x4d, 0x62, 0xb5, 0x9a, + 0xca, 0x84, 0xe9, 0x90, 0xca, 0xca, 0xf5, 0xc5, + 0x2b, 0x09, 0x30, 0xda, 0xa2, 0x3d, 0xe9, 0x4c, + 0xe8, 0x70, 0x17, 0xba, 0x2d, 0x84, 0x98, 0x8d, + 0xdf, 0xc9, 0xc5, 0x8d, 0xb6, 0x7a, 0xad, 0xa6, +}; + +/* CTR data 7 - for AES 256 + * Counter as big as the data. Therefore the counter + * should not be updated. Because it is already pre + * computed. */ +unsigned char NIST_KEY_CTR_E7[] = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4, +}; + +unsigned char NIST_IV_CTR_E7[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xff, 0x00, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xff, 0x01, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xff, 0x02, +}; + +unsigned char NIST_EXPECTED_IV_CTR_E7[] = { + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xff, 0x00, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xff, 0x01, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xff, 0x02, +}; + +unsigned char NIST_TEST_DATA_CTR_E7[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10, +}; + +unsigned char NIST_TEST_RESULT_CTR_E7[] = { + 0x60, 0x1e, 0xc3, 0x13, 0x77, 0x57, 0x89, 0xa5, + 0xb7, 0xa7, 0xf5, 0x04, 0xbb, 0xf3, 0xd2, 0x28, + 0xf4, 0x43, 0xe3, 0xca, 0x4d, 0x62, 0xb5, 0x9a, + 0xca, 0x84, 0xe9, 0x90, 0xca, 0xca, 0xf5, 0xc5, + 0x2b, 0x09, 0x30, 0xda, 0xa2, 0x3d, 0xe9, 0x4c, + 0xe8, 0x70, 0x17, 0xba, 0x2d, 0x84, 0x98, 0x8d, + 0xdf, 0xc9, 0xc5, 0x8d, 0xb6, 0x7a, 0xad, 0xa6, + 0x13, 0xc2, 0xdd, 0x08, 0x45, 0x79, 0x41, 0xa6, +}; + +void dump_ctr_data(unsigned char *iv, unsigned int iv_length, + unsigned char *key, unsigned int key_length, + unsigned char *input_data, unsigned int data_length, + unsigned char *output_data) +{ + VV_(printf("IV \n")); + dump_array(iv, iv_length); + VV_(printf("Key \n")); + dump_array(key, key_length); + VV_(printf("Input Data\n")); + dump_array(input_data, data_length); + VV_(printf("Output Data\n")); + dump_array(output_data, data_length); +} + +void get_sizes(unsigned int *data_length, unsigned int *iv_length, + unsigned int *key_length, unsigned int iteration) +{ + switch (iteration) { + case 1: + *data_length = sizeof(NIST_TEST_DATA_CTR_E1); + *iv_length = sizeof(NIST_IV_CTR_E1); + *key_length = sizeof(NIST_KEY_CTR_E1); + break; + case 2: + *data_length = sizeof(NIST_TEST_DATA_CTR_E2); + *iv_length = sizeof(NIST_IV_CTR_E2); + *key_length = sizeof(NIST_KEY_CTR_E2); + break; + case 3: + *data_length = sizeof(NIST_TEST_DATA_CTR_E3); + *iv_length = sizeof(NIST_IV_CTR_E3); + *key_length = sizeof(NIST_KEY_CTR_E3); + break; + case 4: + *data_length = sizeof(NIST_TEST_DATA_CTR_E4); + *iv_length = sizeof(NIST_IV_CTR_E4); + *key_length = sizeof(NIST_KEY_CTR_E4); + break; + case 5: + *data_length = sizeof(NIST_TEST_DATA_CTR_E5); + *iv_length = sizeof(NIST_IV_CTR_E5); + *key_length = sizeof(NIST_KEY_CTR_E5); + break; + case 6: + *data_length = sizeof(NIST_TEST_DATA_CTR_E6); + *iv_length = sizeof(NIST_IV_CTR_E6); + *key_length = sizeof(NIST_KEY_CTR_E6); + break; + case 7: + *data_length = sizeof(NIST_TEST_DATA_CTR_E7); + *iv_length = sizeof(NIST_IV_CTR_E7); + *key_length = sizeof(NIST_KEY_CTR_E7); + break; + } + +} + +void load_test_data(unsigned char *data, unsigned int data_length, + unsigned char *result, + unsigned char *iv, unsigned char *expected_iv, + unsigned int iv_length, + unsigned char *key, unsigned int key_length, + unsigned int iteration) +{ + switch (iteration) { + case 1: + memcpy(data, NIST_TEST_DATA_CTR_E1, data_length); + memcpy(result, NIST_TEST_RESULT_CTR_E1, data_length); + memcpy(iv, NIST_IV_CTR_E1, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CTR_E1, iv_length); + memcpy(key, NIST_KEY_CTR_E1, key_length); + break; + case 2: + memcpy(data, NIST_TEST_DATA_CTR_E2, data_length); + memcpy(result, NIST_TEST_RESULT_CTR_E2, data_length); + memcpy(iv, NIST_IV_CTR_E2, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CTR_E2, iv_length); + memcpy(key, NIST_KEY_CTR_E2, key_length); + break; + case 3: + memcpy(data, NIST_TEST_DATA_CTR_E3, data_length); + memcpy(result, NIST_TEST_RESULT_CTR_E3, data_length); + memcpy(iv, NIST_IV_CTR_E3, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CTR_E3, iv_length); + memcpy(key, NIST_KEY_CTR_E3, key_length); + break; + case 4: + memcpy(data, NIST_TEST_DATA_CTR_E4, data_length); + memcpy(result, NIST_TEST_RESULT_CTR_E4, data_length); + memcpy(iv, NIST_IV_CTR_E4, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CTR_E4, iv_length); + memcpy(key, NIST_KEY_CTR_E4, key_length); + break; + case 5: + memcpy(data, NIST_TEST_DATA_CTR_E5, data_length); + memcpy(result, NIST_TEST_RESULT_CTR_E5, data_length); + memcpy(iv, NIST_IV_CTR_E5, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CTR_E5, iv_length); + memcpy(key, NIST_KEY_CTR_E5, key_length); + break; + case 6: + memcpy(data, NIST_TEST_DATA_CTR_E6, data_length); + memcpy(result, NIST_TEST_RESULT_CTR_E6, data_length); + memcpy(iv, NIST_IV_CTR_E6, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CTR_E6, iv_length); + memcpy(key, NIST_KEY_CTR_E6, key_length); + break; + case 7: + memcpy(data, NIST_TEST_DATA_CTR_E7, data_length); + memcpy(result, NIST_TEST_RESULT_CTR_E7, data_length); + memcpy(iv, NIST_IV_CTR_E7, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CTR_E7, iv_length); + memcpy(key, NIST_KEY_CTR_E7, key_length); + break; + } + +} + +int random_aes_ctr(int iteration, unsigned int data_length, unsigned int iv_length) +{ + unsigned int key_length = AES_KEY_LEN256; + + if (data_length % sizeof(ica_aes_vector_t)) + iv_length = sizeof(ica_aes_vector_t); + + unsigned char iv[iv_length]; + unsigned char tmp_iv[iv_length]; + unsigned char key[key_length]; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + + int rc = 0; + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i, iv length = %i\n", + key_length, data_length, iv_length)); + + rc = ica_random_number_generate(data_length, input_data); + if (rc) { + VV_(printf("random number generate returned rc = %i, errno = %i\n", rc, errno)); + return rc; + } + rc = ica_random_number_generate(iv_length, iv); + if (rc) { + VV_(printf("random number generate returned rc = %i, errno = %i\n", rc, errno)); + return rc; + } + + rc = ica_random_number_generate(key_length, key); + if (rc) { + VV_(printf("random number generate returned rc = %i, errno = %i\n", rc, errno)); + return rc; + } + memcpy(tmp_iv, iv, iv_length); + + rc = ica_aes_ctr(input_data, encrypt, data_length, key, key_length, + tmp_iv, 32, 1); + if (rc) { + VV_(printf("ica_aes_ctr encrypt failed with rc = %i\n", rc)); + dump_ctr_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + return rc; + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_ctr_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + + memcpy(tmp_iv, iv, iv_length); + rc = ica_aes_ctr(encrypt, decrypt, data_length, key, key_length, + tmp_iv, 32, 0); + if (rc) { + VV_(printf("ica_aes_ctr decrypt failed with rc = %i\n", rc)); + dump_ctr_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_ctr_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + } + return rc; +} + +int kat_aes_ctr(int iteration) +{ + unsigned int data_length; + unsigned int iv_length; + unsigned int key_length; + + get_sizes(&data_length, &iv_length, &key_length, iteration); + + unsigned char iv[iv_length]; + unsigned char tmp_iv[iv_length]; + unsigned char expected_iv[iv_length]; + unsigned char key[key_length]; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + unsigned char result[data_length]; + + int rc = 0; + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i, iv length = %i\n", + key_length, data_length, iv_length)); + + load_test_data(input_data, data_length, result, iv, expected_iv, + iv_length, key, key_length, iteration); + memcpy(tmp_iv, iv, iv_length); + + if (iv_length == 16) + rc = ica_aes_ctr(input_data, encrypt, data_length, key, key_length, + tmp_iv, 32, 1); + else + rc = ica_aes_ctrlist(input_data, encrypt, data_length, key, key_length, + tmp_iv, 1); + if (rc) { + VV_(printf("ica_aes_ctr encrypt failed with rc = %i\n", rc)); + dump_ctr_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_ctr_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + + if (memcmp(result, encrypt, data_length)) { + VV_(printf("Encryption Result does not match the known ciphertext!\n")); + VV_(printf("Expected data:\n")); + dump_array(result, data_length); + VV_(printf("Encryption Result:\n")); + dump_array(encrypt, data_length); + rc++; + } + + if (memcmp(expected_iv, tmp_iv, iv_length)) { + VV_(printf("Update of IV does not match the expected IV!\n")); + VV_(printf("Expected IV:\n")); + dump_array(expected_iv, iv_length); + VV_(printf("Updated IV:\n")); + dump_array(tmp_iv, iv_length); + VV_(printf("Original IV:\n")); + dump_array(iv, iv_length); + rc++; + } + if (rc) { + VV_(printf("AES CTR test exited after encryption\n")); + return rc; + } + + memcpy(tmp_iv, iv, iv_length); + rc = ica_aes_ctr(encrypt, decrypt, data_length, key, key_length, + tmp_iv, 32,0); + if (rc) { + VV_(printf("ica_aes_ctr decrypt failed with rc = %i\n", rc)); + dump_ctr_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_ctr_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + } + return rc; +} + +/* + * Perform CTR tests. + */ +int main(int argc, char **argv) +{ + unsigned int endless = 0; + int i = 0; + int rc = 0; + int error_count = 0; + int iteration; + unsigned int data_length = 1; + unsigned int iv_length = sizeof(ica_aes_vector_t); + unsigned int rdata; + + if (argc > 1) { + if (strstr(argv[1], "endless")) + endless = 1; + } + + set_verbosity(argc, argv); + + if (!endless) { + + // not endless mode + // run the verification tests with known test vectors + for(iteration = 1; iteration <= NR_TESTS; iteration++) { + rc = kat_aes_ctr(iteration); + if (rc) { + V_(printf("kat_aes_ctr failed with rc = %i\n", rc)); + error_count++; + } + } + // run random tests + for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) { + rc = random_aes_ctr(iteration, data_length, iv_length); + if (rc) { + V_(printf("random_aes_ctr failed with rc = %i\n", rc)); + error_count++; + } + // add a value between 1 and 8 to data_length + if (ica_random_number_generate(sizeof(rdata), (unsigned char*) &rdata)) { + printf("ica_random_number_generate failed with errnor = %i\n", + errno); + exit(1); + } + data_length += (rdata % 8) + 1; + } + + } else { + // endless mode + while (1) { + V_(printf("i = %i\n",i)); + rc = random_aes_ctr(i, 320, 320); + if (rc) { + V_(printf("random_aes_ctr failed with rc = %i\n", rc)); + return rc; + } + i++; + } + + } + + if (error_count) + printf("%i AES-CTR tests failed\n", error_count); + else + printf("All AES-CTR tests passed.\n"); + + return rc; +} + diff --git a/src/tests/libica_aes_ecb_test.c b/src/tests/libica_aes_ecb_test.c new file mode 100644 index 0000000..09830db --- /dev/null +++ b/src/tests/libica_aes_ecb_test.c @@ -0,0 +1,485 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2010, 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include "ica_api.h" +#include "testcase.h" + +#define NR_TESTS 7 +#define NR_RANDOM_TESTS 10000 + +/* ECB data - 1 for AES128 */ +unsigned char NIST_KEY_ECB_E1[] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, +}; + +unsigned char NIST_TEST_DATA_ECB_E1[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, +}; + +unsigned char NIST_TEST_RESULT_ECB_E1[] = { + 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, + 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97, +}; + +/* ECB data - 2 for AES128 */ +unsigned char NIST_KEY_ECB_E2[] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, +}; + +unsigned char NIST_TEST_DATA_ECB_E2[] = { + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, +}; + +unsigned char NIST_TEST_RESULT_ECB_E2[] = { + 0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, + 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf, +}; + +/* ECB data - 3 - for AES128 */ +unsigned char NIST_KEY_ECB_E3[] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, + +}; + +unsigned char NIST_TEST_DATA_ECB_E3[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10, +}; + +unsigned char NIST_TEST_RESULT_ECB_E3[] = { + 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, + 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97, + 0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, + 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf, + 0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, + 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88, + 0x7b, 0x0c, 0x78, 0x5e, 0x27, 0xe8, 0xad, 0x3f, + 0x82, 0x23, 0x20, 0x71, 0x04, 0x72, 0x5d, 0xd4, +}; + +/* ECB data - 4 - for AES192 */ +unsigned char NIST_KEY_ECB_E4[] = { + 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, + 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b, +}; + +unsigned char NIST_TEST_DATA_ECB_E4[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, +}; + +unsigned char NIST_TEST_RESULT_ECB_E4[] = { + 0xbd, 0x33, 0x4f, 0x1d, 0x6e, 0x45, 0xf2, 0x5f, + 0xf7, 0x12, 0xa2, 0x14, 0x57, 0x1f, 0xa5, 0xcc, +}; + +/* ECB data 5 - for AES 192 */ +unsigned char NIST_KEY_ECB_E5[] = { + 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, + 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b, +}; + +unsigned char NIST_TEST_DATA_ECB_E5[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10, +}; + +unsigned char NIST_TEST_RESULT_ECB_E5[] = { + 0xbd, 0x33, 0x4f, 0x1d, 0x6e, 0x45, 0xf2, 0x5f, + 0xf7, 0x12, 0xa2, 0x14, 0x57, 0x1f, 0xa5, 0xcc, + 0x97, 0x41, 0x04, 0x84, 0x6d, 0x0a, 0xd3, 0xad, + 0x77, 0x34, 0xec, 0xb3, 0xec, 0xee, 0x4e, 0xef, + 0xef, 0x7a, 0xfd, 0x22, 0x70, 0xe2, 0xe6, 0x0a, + 0xdc, 0xe0, 0xba, 0x2f, 0xac, 0xe6, 0x44, 0x4e, + 0x9a, 0x4b, 0x41, 0xba, 0x73, 0x8d, 0x6c, 0x72, + 0xfb, 0x16, 0x69, 0x16, 0x03, 0xc1, 0x8e, 0x0e, +}; + +/* ECB data 6 - for AES 256 */ +unsigned char NIST_KEY_ECB_E6[] = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4, +}; + +unsigned char NIST_TEST_DATA_ECB_E6[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, +}; + +unsigned char NIST_TEST_RESULT_ECB_E6[] = { + 0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c, + 0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8, +}; + +/* ECB data 7 - for AES 256 */ +unsigned char NIST_KEY_ECB_E7[] = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4, +}; + +unsigned char NIST_TEST_DATA_ECB_E7[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10, +}; + +unsigned char NIST_TEST_RESULT_ECB_E7[] = { + 0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c, + 0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8, + 0x59, 0x1c, 0xcb, 0x10, 0xd4, 0x10, 0xed, 0x26, + 0xdc, 0x5b, 0xa7, 0x4a, 0x31, 0x36, 0x28, 0x70, + 0xb6, 0xed, 0x21, 0xb9, 0x9c, 0xa6, 0xf4, 0xf9, + 0xf1, 0x53, 0xe7, 0xb1, 0xbe, 0xaf, 0xed, 0x1d, + 0x23, 0x30, 0x4b, 0x7a, 0x39, 0xf9, 0xf3, 0xff, + 0x06, 0x7d, 0x8d, 0x8f, 0x9e, 0x24, 0xec, 0xc7, +}; + +void dump_ecb_data(unsigned char *key, unsigned int key_length, + unsigned char *input_data, unsigned int data_length, + unsigned char *output_data) +{ + VV_(printf("Key\n")); + dump_array(key, key_length); + VV_(printf("Input Data\n")); + dump_array(input_data, data_length); + VV_(printf("Output Data\n")); + dump_array(output_data, data_length); +} + +void get_sizes(unsigned int *data_length, + unsigned int *key_length, unsigned int iteration) +{ + switch (iteration) { + case 1: + *data_length = sizeof(NIST_TEST_DATA_ECB_E1); + *key_length = sizeof(NIST_KEY_ECB_E1); + break; + case 2: + *data_length = sizeof(NIST_TEST_DATA_ECB_E2); + *key_length = sizeof(NIST_KEY_ECB_E2); + break; + case 3: + *data_length = sizeof(NIST_TEST_DATA_ECB_E3); + *key_length = sizeof(NIST_KEY_ECB_E3); + break; + case 4: + *data_length = sizeof(NIST_TEST_DATA_ECB_E4); + *key_length = sizeof(NIST_KEY_ECB_E4); + break; + case 5: + *data_length = sizeof(NIST_TEST_DATA_ECB_E5); + *key_length = sizeof(NIST_KEY_ECB_E5); + break; + case 6: + *data_length = sizeof(NIST_TEST_DATA_ECB_E6); + *key_length = sizeof(NIST_KEY_ECB_E6); + break; + case 7: + *data_length = sizeof(NIST_TEST_DATA_ECB_E7); + *key_length = sizeof(NIST_KEY_ECB_E7); + break; + case 8: + break; + case 9: + break; + case 10: + break; + case 11: + break; + case 12: + break; + } + +} + +void load_test_data(unsigned char *data, unsigned int data_length, + unsigned char *result, + unsigned char *key, unsigned int key_length, + unsigned int iteration) +{ + switch (iteration) { + case 1: + memcpy(data, NIST_TEST_DATA_ECB_E1, data_length); + memcpy(result, NIST_TEST_RESULT_ECB_E1, data_length); + memcpy(key, NIST_KEY_ECB_E1, key_length); + break; + case 2: + memcpy(data, NIST_TEST_DATA_ECB_E2, data_length); + memcpy(result, NIST_TEST_RESULT_ECB_E2, data_length); + memcpy(key, NIST_KEY_ECB_E2, key_length); + break; + case 3: + memcpy(data, NIST_TEST_DATA_ECB_E3, data_length); + memcpy(result, NIST_TEST_RESULT_ECB_E3, data_length); + memcpy(key, NIST_KEY_ECB_E3, key_length); + break; + case 4: + memcpy(data, NIST_TEST_DATA_ECB_E4, data_length); + memcpy(result, NIST_TEST_RESULT_ECB_E4, data_length); + memcpy(key, NIST_KEY_ECB_E4, key_length); + break; + case 5: + memcpy(data, NIST_TEST_DATA_ECB_E5, data_length); + memcpy(result, NIST_TEST_RESULT_ECB_E5, data_length); + memcpy(key, NIST_KEY_ECB_E5, key_length); + break; + case 6: + memcpy(data, NIST_TEST_DATA_ECB_E6, data_length); + memcpy(result, NIST_TEST_RESULT_ECB_E6, data_length); + memcpy(key, NIST_KEY_ECB_E6, key_length); + break; + case 7: + memcpy(data, NIST_TEST_DATA_ECB_E7, data_length); + memcpy(result, NIST_TEST_RESULT_ECB_E7, data_length); + memcpy(key, NIST_KEY_ECB_E7, key_length); + break; + case 8: + break; + case 9: + break; + case 10: + break; + case 11: + break; + case 12: + break; + } + +} + +int kat_aes_ecb(int iteration) +{ + unsigned int data_length; + unsigned int key_length; + + get_sizes(&data_length, &key_length, iteration); + + unsigned char key[key_length]; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + unsigned char result[data_length]; + + int rc = 0; + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i", + key_length, data_length)); + + load_test_data(input_data, data_length, result, key, key_length, + iteration); + + rc = ica_aes_ecb(input_data, encrypt, data_length, key, key_length, 1); + if (rc) { + VV_(printf("ica_aes_ecb encrypt failed with rc = %i\n", rc)); + dump_ecb_data(key, key_length, input_data, + data_length, encrypt); + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_ecb_data(key, key_length, input_data, + data_length, encrypt); + } + + if (memcmp(result, encrypt, data_length)) { + VV_(printf("Encryption Result does not match the known ciphertext!\n")); + VV_(printf("Expected data:\n")); + dump_array(result, data_length); + VV_(printf("Encryption Result:\n")); + dump_array(encrypt, data_length); + rc++; + } + + if (rc) { + VV_(printf("AES ECB test exited after encryption\n")); + return rc; + } + + rc = ica_aes_ecb(encrypt, decrypt, data_length, key, key_length, 0); + if (rc) { + VV_(printf("ica_aes_ecb decrypt failed with rc = %i\n", rc)); + dump_ecb_data(key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_ecb_data(key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + } + return rc; +} + +int load_random_test_data(unsigned char *data, unsigned int data_length, + unsigned char *key, unsigned int key_length) +{ + int rc; + + rc = ica_random_number_generate(data_length, data); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + rc = ica_random_number_generate(key_length, key); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + return rc; +} + +int random_aes_ecb(int iteration, unsigned int data_length) +{ + int i; + int rc = 0; + unsigned int key_length = AES_KEY_LEN128; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + + for (i = 1; i <= 2; i++) { + unsigned char key[key_length]; + + memset(encrypt, 0x00, data_length); + memset(decrypt, 0x00, data_length); + + load_random_test_data(input_data, data_length, key, key_length); + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i\n", key_length, data_length)); + rc = ica_aes_ecb(input_data, encrypt, data_length, key, key_length, 1); + if (rc) { + VV_(printf("ica_aes_ecb encrypt failed with rc = %i\n", rc)); + dump_ecb_data(key, key_length, input_data, + data_length, encrypt); + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_ecb_data(key, key_length, input_data, + data_length, encrypt); + } + + if (rc) { + VV_(printf("AES ECB test exited after encryption\n")); + return rc; + } + + rc = ica_aes_ecb(encrypt, decrypt, data_length, key, key_length, 0); + if (rc) { + VV_(printf("ica_aes_ecb decrypt failed with rc = %i\n", rc)); + dump_ecb_data(key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_ecb_data(key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + return rc; + } + key_length += 8; + } + + return rc; +} + +/* + * Perform CTR tests. + */ +int main(int argc, char **argv) +{ + int rc = 0; + int error_count = 0; + int iteration; + unsigned int data_length = sizeof(ica_aes_vector_t); + + set_verbosity(argc, argv); + + for(iteration = 1; iteration <= NR_TESTS; iteration++) { + rc = kat_aes_ecb(iteration); + if (rc) { + V_(printf("kat_aes_ecb failed with rc = %i\n", rc)); + error_count++; + } + + } + for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) { + rc = random_aes_ecb(iteration, data_length); + if (rc) { + V_(printf("random_aes_ecb failed with rc = %i, %i\n", rc, iteration)); + error_count++; + goto out; + } + data_length += sizeof(ica_aes_vector_t); + } + +out: + if (error_count) + printf("%i AES-ECB tests failed.\n", error_count); + else + printf("All AES-ECB tests passed.\n"); + + return rc; +} + diff --git a/src/tests/libica_aes_gcm_test.c b/src/tests/libica_aes_gcm_test.c new file mode 100644 index 0000000..bce6100 --- /dev/null +++ b/src/tests/libica_aes_gcm_test.c @@ -0,0 +1,1043 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* (C) COPYRIGHT International Business Machines Corp. 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include "ica_api.h" +#include "testcase.h" + +#define NR_TESTS 12 +#define AES_BLOCK_SIZE 16 + +/* GCM data - 1*/ +unsigned char NIST_KEY_GCM_E1[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, +}; + +unsigned char NIST_TEST_DATA_GCM_E1[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, +}; + +unsigned char NIST_AAD_GCM_E1[] = { +}; + +unsigned char NIST_IV_GCM_E1[] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88, +}; + +unsigned char NIST_TAG_GCM_E1[] = { + 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, + 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4, +}; + +unsigned char NIST_TEST_RESULT_GCM_E1[] = { + 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85, +}; + +unsigned char NIST_CHUNKS_GCM_E1[] = { 16, 16, 16, 16 }; + +/* GCM data - 2*/ +unsigned char NIST_KEY_GCM_E2[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +unsigned char NIST_TEST_DATA_GCM_E2[] = { +}; + +unsigned char NIST_AAD_GCM_E2[] = { +}; + +unsigned char NIST_IV_GCM_E2[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; + +unsigned char NIST_TAG_GCM_E2[] = { + 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, + 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a +}; + +unsigned char NIST_TEST_RESULT_GCM_E2[] = { +}; + +unsigned char NIST_CHUNKS_GCM_E2[] = { }; + +/* GCM data - 3*/ +unsigned char NIST_KEY_GCM_E3[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +unsigned char NIST_TEST_DATA_GCM_E3[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +unsigned char NIST_AAD_GCM_E3[] = { +}; + +unsigned char NIST_IV_GCM_E3[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; + +unsigned char NIST_TAG_GCM_E3[] = { + 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, + 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf, +}; + +unsigned char NIST_TEST_RESULT_GCM_E3[] = { + 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, + 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78, +}; + +unsigned char NIST_CHUNKS_GCM_E3[] = { 16 }; + +/* GCM data - 4*/ +unsigned char NIST_KEY_GCM_E4[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, +}; + +unsigned char NIST_TEST_DATA_GCM_E4[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, +}; + +unsigned char NIST_AAD_GCM_E4[] = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, +}; + +unsigned char NIST_IV_GCM_E4[] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88, +}; + +unsigned char NIST_TAG_GCM_E4[] = { + 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, + 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47, +}; + +unsigned char NIST_TEST_RESULT_GCM_E4[] = { + 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91, +}; + +unsigned char NIST_CHUNKS_GCM_E4[] = { 16, 16, 16, 12 }; + +/* GCM data - 5 - AES 192 - Test Case 7*/ +unsigned char NIST_KEY_GCM_E5[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +unsigned char NIST_TEST_DATA_GCM_E5[] = { +}; + +unsigned char NIST_AAD_GCM_E5[] = { +}; + +unsigned char NIST_IV_GCM_E5[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; + +unsigned char NIST_TAG_GCM_E5[] = { + 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b, + 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35, +}; + +unsigned char NIST_TEST_RESULT_GCM_E5[] = { +}; + +unsigned char NIST_CHUNKS_GCM_E5[] = { }; + +/* GCM data - 6 - AES 192 - Test Case 8*/ +unsigned char NIST_KEY_GCM_E6[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +unsigned char NIST_TEST_DATA_GCM_E6[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +unsigned char NIST_AAD_GCM_E6[] = { +}; + +unsigned char NIST_IV_GCM_E6[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; + +unsigned char NIST_TAG_GCM_E6[] = { + 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, + 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb, +}; + +unsigned char NIST_TEST_RESULT_GCM_E6[] = { + 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41, + 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00, +}; + +unsigned char NIST_CHUNKS_GCM_E6[] = { 16 }; + +/* GCM data - 7 - AES 192 - Test Case 9*/ +unsigned char NIST_KEY_GCM_E7[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, +}; + +unsigned char NIST_TEST_DATA_GCM_E7[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, +}; + +unsigned char NIST_AAD_GCM_E7[] = { +}; + +unsigned char NIST_IV_GCM_E7[] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88, +}; + +unsigned char NIST_TAG_GCM_E7[] = { + 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf, + 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14, +}; + +unsigned char NIST_TEST_RESULT_GCM_E7[] = { + 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, + 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, + 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, + 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, + 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, + 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, + 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, + 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56, +}; + +unsigned char NIST_CHUNKS_GCM_E7[] = { 16, 16, 16, 16 }; + +/* GCM data - 8 - AES 192 - Test Case 10*/ +unsigned char NIST_KEY_GCM_E8[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, +}; + +unsigned char NIST_TEST_DATA_GCM_E8[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, +}; + +unsigned char NIST_AAD_GCM_E8[] = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, +}; + +unsigned char NIST_IV_GCM_E8[] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88, +}; + +unsigned char NIST_TAG_GCM_E8[] = { + 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f, + 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c, +}; + +unsigned char NIST_TEST_RESULT_GCM_E8[] = { + 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, + 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, + 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, + 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, + 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, + 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, + 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, + 0xcc, 0xda, 0x27, 0x10, +}; + +unsigned char NIST_CHUNKS_GCM_E8[] = { 16, 16, 16, 12 }; + +/* GCM data - 9 - AES 256 - Test Case 13*/ +unsigned char NIST_KEY_GCM_E9[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +unsigned char NIST_TEST_DATA_GCM_E9[] = { +}; + +unsigned char NIST_AAD_GCM_E9[] = { +}; + +unsigned char NIST_IV_GCM_E9[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; + +unsigned char NIST_TAG_GCM_E9[] = { + 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, + 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b, +}; + +unsigned char NIST_TEST_RESULT_GCM_E9[] = { +}; + +unsigned char NIST_CHUNKS_GCM_E9[] = { }; + +/* GCM data - 10 - AES 256 - Test Case 14*/ +unsigned char NIST_KEY_GCM_E10[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +unsigned char NIST_TEST_DATA_GCM_E10[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +unsigned char NIST_AAD_GCM_E10[] = { +}; + +unsigned char NIST_IV_GCM_E10[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; + +unsigned char NIST_TAG_GCM_E10[] = { + 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, + 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19, +}; + +unsigned char NIST_TEST_RESULT_GCM_E10[] = { + 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, + 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18, +}; + +unsigned char NIST_CHUNKS_GCM_E10[] = { 16 }; + +/* GCM data - 11 - AES 256 - Test Case 15*/ +unsigned char NIST_KEY_GCM_E11[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, +}; + +unsigned char NIST_TEST_DATA_GCM_E11[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, +}; + +unsigned char NIST_AAD_GCM_E11[] = { +}; + +unsigned char NIST_IV_GCM_E11[] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88, +}; + +unsigned char NIST_TAG_GCM_E11[] = { + 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, + 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c, +}; + +unsigned char NIST_TEST_RESULT_GCM_E11[] = { + 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, + 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad, +}; + +unsigned char NIST_CHUNKS_GCM_E11[] = { 16, 16, 16, 16 }; + +/* GCM data */ +unsigned char NIST_KEY_GCM_E12[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, +}; + +unsigned char NIST_TEST_DATA_GCM_E12[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, +}; + +unsigned char NIST_AAD_GCM_E12[] = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2, +}; + +unsigned char NIST_IV_GCM_E12[] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88, +}; + +unsigned char NIST_TAG_GCM_E12[] = { + 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68, + 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b, +}; + +unsigned char NIST_TEST_RESULT_GCM_E12[] = { + 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, + 0xbc, 0xc9, 0xf6, 0x62, +}; + +unsigned char NIST_CHUNKS_GCM_E12[] = { 16, 16, 16, 12 }; + +void dump_gcm_data(unsigned char *iv, unsigned int iv_length, + unsigned char *aad, unsigned int aad_length, + unsigned char *key, unsigned int key_length, + unsigned char *input_data, unsigned int data_length, + unsigned char *output_data, + unsigned char *t, unsigned int t_size) +{ + VV_(printf("IV \n")); + dump_array(iv, iv_length); + VV_(printf("AAD \n")); + dump_array(aad, aad_length); + VV_(printf("Key \n")); + dump_array(key, key_length); + VV_(printf("Input Data\n")); + dump_array(input_data, data_length); + VV_(printf("Output Data\n")); + dump_array(output_data, data_length); + VV_(printf("T\n")); + dump_array(t, t_size); +} + +void get_sizes(unsigned int *aad_length, unsigned int *data_length, + unsigned int *t_length, unsigned int *iv_length, + unsigned int *key_length, unsigned int *num_chunks, + unsigned int iteration) +{ + switch (iteration) { + case 1: + *aad_length = sizeof(NIST_AAD_GCM_E1); + *data_length = sizeof(NIST_TEST_DATA_GCM_E1); + *t_length = sizeof(NIST_TAG_GCM_E1); + *iv_length = sizeof(NIST_IV_GCM_E1); + *key_length = sizeof(NIST_KEY_GCM_E1); + *num_chunks = sizeof(NIST_CHUNKS_GCM_E1); + break; + case 2: + *aad_length = sizeof(NIST_AAD_GCM_E2); + *data_length = sizeof(NIST_TEST_DATA_GCM_E2); + *t_length = sizeof(NIST_TAG_GCM_E2); + *iv_length = sizeof(NIST_IV_GCM_E2); + *key_length = sizeof(NIST_KEY_GCM_E2); + *num_chunks = sizeof(NIST_CHUNKS_GCM_E2); + break; + case 3: + *aad_length = sizeof(NIST_AAD_GCM_E3); + *data_length = sizeof(NIST_TEST_DATA_GCM_E3); + *t_length = sizeof(NIST_TAG_GCM_E3); + *iv_length = sizeof(NIST_IV_GCM_E3); + *key_length = sizeof(NIST_KEY_GCM_E3); + *num_chunks = sizeof(NIST_CHUNKS_GCM_E3); + break; + case 4: + *aad_length = sizeof(NIST_AAD_GCM_E4); + *data_length = sizeof(NIST_TEST_DATA_GCM_E4); + *t_length = sizeof(NIST_TAG_GCM_E4); + *iv_length = sizeof(NIST_IV_GCM_E4); + *key_length = sizeof(NIST_KEY_GCM_E4); + *num_chunks = sizeof(NIST_CHUNKS_GCM_E4); + break; + case 5: + *aad_length = sizeof(NIST_AAD_GCM_E5); + *data_length = sizeof(NIST_TEST_DATA_GCM_E5); + *t_length = sizeof(NIST_TAG_GCM_E5); + *iv_length = sizeof(NIST_IV_GCM_E5); + *key_length = sizeof(NIST_KEY_GCM_E5); + *num_chunks = sizeof(NIST_CHUNKS_GCM_E5); + break; + case 6: + *aad_length = sizeof(NIST_AAD_GCM_E6); + *data_length = sizeof(NIST_TEST_DATA_GCM_E6); + *t_length = sizeof(NIST_TAG_GCM_E6); + *iv_length = sizeof(NIST_IV_GCM_E6); + *key_length = sizeof(NIST_KEY_GCM_E6); + *num_chunks = sizeof(NIST_CHUNKS_GCM_E6); + break; + case 7: + *aad_length = sizeof(NIST_AAD_GCM_E7); + *data_length = sizeof(NIST_TEST_DATA_GCM_E7); + *t_length = sizeof(NIST_TAG_GCM_E7); + *iv_length = sizeof(NIST_IV_GCM_E7); + *key_length = sizeof(NIST_KEY_GCM_E7); + *num_chunks = sizeof(NIST_CHUNKS_GCM_E7); + break; + case 8: + *aad_length = sizeof(NIST_AAD_GCM_E8); + *data_length = sizeof(NIST_TEST_DATA_GCM_E8); + *t_length = sizeof(NIST_TAG_GCM_E8); + *iv_length = sizeof(NIST_IV_GCM_E8); + *key_length = sizeof(NIST_KEY_GCM_E8); + *num_chunks = sizeof(NIST_CHUNKS_GCM_E8); + break; + case 9: + *aad_length = sizeof(NIST_AAD_GCM_E9); + *data_length = sizeof(NIST_TEST_DATA_GCM_E9); + *t_length = sizeof(NIST_TAG_GCM_E9); + *iv_length = sizeof(NIST_IV_GCM_E9); + *key_length = sizeof(NIST_KEY_GCM_E9); + *num_chunks = sizeof(NIST_CHUNKS_GCM_E9); + break; + case 10: + *aad_length = sizeof(NIST_AAD_GCM_E10); + *data_length = sizeof(NIST_TEST_DATA_GCM_E10); + *t_length = sizeof(NIST_TAG_GCM_E10); + *iv_length = sizeof(NIST_IV_GCM_E10); + *key_length = sizeof(NIST_KEY_GCM_E10); + *num_chunks = sizeof(NIST_CHUNKS_GCM_E10); + break; + case 11: + *aad_length = sizeof(NIST_AAD_GCM_E11); + *data_length = sizeof(NIST_TEST_DATA_GCM_E11); + *t_length = sizeof(NIST_TAG_GCM_E11); + *iv_length = sizeof(NIST_IV_GCM_E11); + *key_length = sizeof(NIST_KEY_GCM_E11); + *num_chunks = sizeof(NIST_CHUNKS_GCM_E11); + break; + case 12: + *aad_length = sizeof(NIST_AAD_GCM_E12); + *data_length = sizeof(NIST_TEST_DATA_GCM_E12); + *t_length = sizeof(NIST_TAG_GCM_E12); + *iv_length = sizeof(NIST_IV_GCM_E12); + *key_length = sizeof(NIST_KEY_GCM_E12); + *num_chunks = sizeof(NIST_CHUNKS_GCM_E12); + break; + } + +} + +void load_test_data(unsigned char *aad, unsigned int aad_length, + unsigned char *data, unsigned int data_length, + unsigned char *result, + unsigned char *t, unsigned int t_length, + unsigned char *iv, unsigned int iv_length, + unsigned char *key, unsigned int key_length, + unsigned char *chunks, unsigned int num_chunks, + unsigned int iteration) +{ + switch (iteration) { + case 1: + memcpy(iv, NIST_IV_GCM_E1, iv_length); + memcpy(aad, NIST_AAD_GCM_E1, aad_length); + memcpy(key, NIST_KEY_GCM_E1, key_length); + memcpy(data, NIST_TEST_DATA_GCM_E1, data_length); + memcpy(result, NIST_TEST_RESULT_GCM_E1, data_length); + memcpy(t, NIST_TAG_GCM_E1, t_length); + memcpy(chunks, NIST_CHUNKS_GCM_E1, num_chunks); + break; + case 2: + memcpy(iv, NIST_IV_GCM_E2, iv_length); + memcpy(aad, NIST_AAD_GCM_E2, aad_length); + memcpy(key, NIST_KEY_GCM_E2, key_length); + memcpy(data, NIST_TEST_DATA_GCM_E2, data_length); + memcpy(result, NIST_TEST_RESULT_GCM_E2, data_length); + memcpy(t, NIST_TAG_GCM_E2, t_length); + memcpy(chunks, NIST_CHUNKS_GCM_E2, num_chunks); + break; + case 3: + memcpy(iv, NIST_IV_GCM_E3, iv_length); + memcpy(aad, NIST_AAD_GCM_E3, aad_length); + memcpy(key, NIST_KEY_GCM_E3, key_length); + memcpy(data, NIST_TEST_DATA_GCM_E3, data_length); + memcpy(result, NIST_TEST_RESULT_GCM_E3, data_length); + memcpy(t, NIST_TAG_GCM_E3, t_length); + memcpy(chunks, NIST_CHUNKS_GCM_E3, num_chunks); + break; + case 4: + memcpy(iv, NIST_IV_GCM_E4, iv_length); + memcpy(aad, NIST_AAD_GCM_E4, aad_length); + memcpy(key, NIST_KEY_GCM_E4, key_length); + memcpy(data, NIST_TEST_DATA_GCM_E4, data_length); + memcpy(result, NIST_TEST_RESULT_GCM_E4, data_length); + memcpy(t, NIST_TAG_GCM_E4, t_length); + memcpy(chunks, NIST_CHUNKS_GCM_E4, num_chunks); + break; + case 5: + memcpy(iv, NIST_IV_GCM_E5, iv_length); + memcpy(aad, NIST_AAD_GCM_E5, aad_length); + memcpy(key, NIST_KEY_GCM_E5, key_length); + memcpy(data, NIST_TEST_DATA_GCM_E5, data_length); + memcpy(result, NIST_TEST_RESULT_GCM_E5, data_length); + memcpy(t, NIST_TAG_GCM_E5, t_length); + memcpy(chunks, NIST_CHUNKS_GCM_E5, num_chunks); + break; + case 6: + memcpy(iv, NIST_IV_GCM_E6, iv_length); + memcpy(aad, NIST_AAD_GCM_E6, aad_length); + memcpy(key, NIST_KEY_GCM_E6, key_length); + memcpy(data, NIST_TEST_DATA_GCM_E6, data_length); + memcpy(result, NIST_TEST_RESULT_GCM_E6, data_length); + memcpy(t, NIST_TAG_GCM_E6, t_length); + memcpy(chunks, NIST_CHUNKS_GCM_E6, num_chunks); + break; + case 7: + memcpy(iv, NIST_IV_GCM_E7, iv_length); + memcpy(aad, NIST_AAD_GCM_E7, aad_length); + memcpy(key, NIST_KEY_GCM_E7, key_length); + memcpy(data, NIST_TEST_DATA_GCM_E7, data_length); + memcpy(result, NIST_TEST_RESULT_GCM_E7, data_length); + memcpy(t, NIST_TAG_GCM_E7, t_length); + memcpy(chunks, NIST_CHUNKS_GCM_E7, num_chunks); + break; + case 8: + memcpy(iv, NIST_IV_GCM_E8, iv_length); + memcpy(aad, NIST_AAD_GCM_E8, aad_length); + memcpy(key, NIST_KEY_GCM_E8, key_length); + memcpy(data, NIST_TEST_DATA_GCM_E8, data_length); + memcpy(result, NIST_TEST_RESULT_GCM_E8, data_length); + memcpy(t, NIST_TAG_GCM_E8, t_length); + memcpy(chunks, NIST_CHUNKS_GCM_E8, num_chunks); + break; + case 9: + memcpy(iv, NIST_IV_GCM_E9, iv_length); + memcpy(aad, NIST_AAD_GCM_E9, aad_length); + memcpy(key, NIST_KEY_GCM_E9, key_length); + memcpy(data, NIST_TEST_DATA_GCM_E9, data_length); + memcpy(result, NIST_TEST_RESULT_GCM_E9, data_length); + memcpy(t, NIST_TAG_GCM_E9, t_length); + memcpy(chunks, NIST_CHUNKS_GCM_E9, num_chunks); + break; + case 10: + memcpy(iv, NIST_IV_GCM_E10, iv_length); + memcpy(aad, NIST_AAD_GCM_E10, aad_length); + memcpy(key, NIST_KEY_GCM_E10, key_length); + memcpy(data, NIST_TEST_DATA_GCM_E10, data_length); + memcpy(result, NIST_TEST_RESULT_GCM_E10, data_length); + memcpy(t, NIST_TAG_GCM_E10, t_length); + memcpy(chunks, NIST_CHUNKS_GCM_E10, num_chunks); + break; + case 11: + memcpy(iv, NIST_IV_GCM_E11, iv_length); + memcpy(aad, NIST_AAD_GCM_E11, aad_length); + memcpy(key, NIST_KEY_GCM_E11, key_length); + memcpy(data, NIST_TEST_DATA_GCM_E11, data_length); + memcpy(result, NIST_TEST_RESULT_GCM_E11, data_length); + memcpy(t, NIST_TAG_GCM_E11, t_length); + memcpy(chunks, NIST_CHUNKS_GCM_E11, num_chunks); + break; + case 12: + memcpy(iv, NIST_IV_GCM_E12, iv_length); + memcpy(aad, NIST_AAD_GCM_E12, aad_length); + memcpy(key, NIST_KEY_GCM_E12, key_length); + memcpy(data, NIST_TEST_DATA_GCM_E12, data_length); + memcpy(result, NIST_TEST_RESULT_GCM_E12, data_length); + memcpy(t, NIST_TAG_GCM_E12, t_length); + memcpy(chunks, NIST_CHUNKS_GCM_E12, num_chunks); + break; + } + +} + +int test_gcm_kat(int iteration) +{ + unsigned int aad_length; + unsigned int data_length; + unsigned int t_length; + unsigned int iv_length; + unsigned int key_length; + unsigned int num_chunks; + + get_sizes(&aad_length, &data_length, &t_length, &iv_length, + &key_length, &num_chunks, iteration); + + unsigned char iv[iv_length]; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + unsigned char result[data_length]; + unsigned char aad[aad_length]; + unsigned char key[key_length]; + unsigned char t[t_length]; + unsigned char t_result[t_length]; + unsigned char chunks[num_chunks]; + + int rc = 0; + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i, tag length = %i," + "iv length = %i aad_length = %i\n", key_length, data_length, + t_length, iv_length, aad_length)); + + load_test_data(aad, aad_length, input_data, data_length, result, + t_result, t_length, iv, iv_length, key, key_length, + chunks, num_chunks, iteration); + + rc = ica_aes_gcm(input_data, data_length, + encrypt, + iv, iv_length, + aad, aad_length, + t, t_length, + key, key_length, + 1); + if (rc == EPERM) { + VV_(printf("ica_aes_gcm returns with EPERM (%d).\n", rc)); + VV_(printf("Operation is not permitted on this machine. Test skipped!\n")); + return 0; + } + if (rc) { + VV_(printf("ica_aes_gcm encrypt failed with rc = %i\n", rc)); + dump_gcm_data(iv, iv_length, aad, aad_length, key, key_length, + input_data, data_length, encrypt, t, t_length); + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_gcm_data(iv, iv_length, aad, aad_length, key, key_length, + input_data, data_length, encrypt, t, + t_length); + } + + if (memcmp(result, encrypt, data_length)) { + VV_(printf("Encryption Result does not match the known ciphertext!\n")); + VV_(printf("Expected data:\n")); + dump_array(result, data_length); + VV_(printf("Encryption Result:\n")); + dump_array(encrypt, data_length); + rc++; + } + if (memcmp(t, t_result, t_length)) { + VV_(printf("Tag result does not match the expected tag!\n")); + VV_(printf("Expected tag:\n")); + dump_array(t_result, t_length); + VV_(printf("Tag Result:\n")); + dump_array(t, t_length); + rc++; + } + if (rc) { + VV_(printf("GCM test exited after encryption\n")); + return rc; + } + rc = ica_aes_gcm(decrypt, data_length, + encrypt, + iv, iv_length, + aad, aad_length, + t, t_length, + key, key_length, + 0); + if (rc == EPERM) { + VV_(printf("ica_aes_gcm returns with EPERM (%d).\n", rc)); + VV_(printf("Operation is not permitted on this machine. Test skipped!\n")); + return 0; + } + if (rc) { + VV_(printf("ica_aes_gcm decrypt failed with rc = %i\n", rc)); + dump_gcm_data(iv, iv_length, aad, aad_length, key, key_length, + encrypt, data_length, decrypt, t, + t_length); + } + + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_gcm_data(iv, iv_length, aad, aad_length, key, key_length, + encrypt, data_length, decrypt, t, + t_length); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + } + if (memcmp(t, t_result, t_length)) { + VV_(printf("Tag result does not match the expected tag!\n")); + VV_(printf("Expected tag:\n")); + dump_array(t_result, t_length); + VV_(printf("Tag Result:\n")); + dump_array(t, t_length); + rc++; + } + return rc; +} + +int test_gcm_kat_update(int iteration) +{ + unsigned int aad_length; + unsigned int aad_length_tmp; + unsigned int data_length; + unsigned int t_length; + unsigned int iv_length; + unsigned int key_length; + unsigned int num_chunks; + + get_sizes(&aad_length, &data_length, &t_length, &iv_length, + &key_length, &num_chunks, iteration); + + unsigned char iv[iv_length]; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + unsigned char result[data_length]; + unsigned char aad[aad_length]; + unsigned char key[key_length]; + unsigned char t[t_length]; + unsigned char t_result[t_length]; + unsigned char chunks[num_chunks]; + unsigned int chunk_len; + unsigned int offset; + unsigned char *chunk_data; + unsigned char icb[AES_BLOCK_SIZE]; + unsigned char ucb[AES_BLOCK_SIZE]; + unsigned char subkey[AES_BLOCK_SIZE]; + unsigned char running_tag[AES_BLOCK_SIZE]; + unsigned int sum_A_len; + unsigned int sum_C_len; + int rc = 0, i; + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i, tag length = %i," + "iv length = %i aad_length = %i\n", key_length, data_length, + t_length, iv_length, aad_length)); + + load_test_data(aad, aad_length, input_data, data_length, result, + t_result, t_length, iv, iv_length, key, key_length, + chunks, num_chunks, iteration); + + aad_length_tmp = aad_length; + memset(running_tag, 0, AES_BLOCK_SIZE); + rc = ica_aes_gcm_initialize(iv, iv_length, key, key_length, + icb, ucb, subkey, 1); + + offset = 0; + for (i = 0; i < num_chunks; i++) { + chunk_len = chunks[i]; + chunk_data = input_data + offset; + + rc = ica_aes_gcm_intermediate(chunk_data, chunk_len, encrypt + offset, + ucb, aad, aad_length, + running_tag, AES_BLOCK_SIZE, + key, key_length, subkey, 1); + /* clear aad_length after first run*/ + aad_length = 0; + offset += chunk_len; + } + sum_A_len = aad_length_tmp; + sum_C_len = offset; + rc = ica_aes_gcm_last(icb, sum_A_len, sum_C_len, running_tag, + t, t_length, key, key_length, subkey, 1); + + if (rc == EPERM) { + VV_(printf("ica_aes_gcm returns with EPERM (%d).\n", rc)); + VV_(printf("Operation is not permitted on this machine. Test skipped!\n")); + return 0; + } + if (rc) { + VV_(printf("ica_aes_gcm encrypt failed with rc = %i\n", rc)); + dump_gcm_data(iv, iv_length, aad, aad_length, key, key_length, + input_data, data_length, encrypt, t, t_length); + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_gcm_data(iv, iv_length, aad, aad_length, key, key_length, + input_data, data_length, encrypt, running_tag, + t_length); + } + + if (memcmp(result, encrypt, data_length)) { + VV_(printf("Encryption Result does not match the known ciphertext!\n")); + VV_(printf("Expected data:\n")); + dump_array(result, data_length); + VV_(printf("Encryption Result:\n")); + dump_array(encrypt, data_length); + rc++; + } + if (memcmp(running_tag, t_result, t_length)) { + VV_(printf("Tag result does not match the expected tag!\n")); + VV_(printf("Expected tag:\n")); + dump_array(t_result, t_length); + VV_(printf("Tag Result:\n")); + dump_array(t, t_length); + rc++; + } + if (rc) { + VV_(printf("GCM test exited after encryption\n")); + return rc; + } + + aad_length = aad_length_tmp; + memset(running_tag, 0, AES_BLOCK_SIZE); + rc = ica_aes_gcm_initialize(iv, iv_length, key, key_length, + icb, ucb, subkey, 0); + + offset = 0; + for (i = 0; i < num_chunks; i++) { + chunk_len = chunks[i]; + chunk_data = encrypt + offset; + + rc = ica_aes_gcm_intermediate(decrypt + offset, chunk_len, chunk_data, + ucb, aad, aad_length, + running_tag, AES_BLOCK_SIZE, + key, key_length, subkey, 0); + + /* clear aad_length after first run*/ + aad_length = 0; + offset += chunk_len; + } + sum_A_len = aad_length_tmp; + sum_C_len = offset; + rc = ica_aes_gcm_last(icb, sum_A_len, sum_C_len, running_tag, + t_result, t_length, key, key_length, subkey, 0); + + + if (rc == EPERM) { + VV_(printf("ica_aes_gcm returns with EPERM (%d).\n", rc)); + VV_(printf("Operation is not permitted on this machine. Test skipped!\n")); + return 0; + } + if (rc) { + VV_(printf("ica_aes_gcm decrypt failed with rc = %i\n", rc)); + dump_gcm_data(iv, iv_length, aad, aad_length, key, key_length, + encrypt, data_length, decrypt, running_tag, + t_length); + } + + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_gcm_data(iv, iv_length, aad, aad_length, key, key_length, + encrypt, data_length, decrypt, running_tag, + t_length); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + } + if (memcmp(running_tag, t_result, t_length)) { + VV_(printf("Tag result does not match the expected tag!\n")); + VV_(printf("Expected tag:\n")); + dump_array(t_result, t_length); + VV_(printf("Tag Result:\n")); + dump_array(t, t_length); + rc++; + } + return rc; +} + +/* + * Performs GCM tests. + */ +int main(int argc, char **argv) +{ + int rc = 0; + int error_count = 0; + int iteration; + + set_verbosity(argc, argv); + + for(iteration = 1; iteration <= NR_TESTS; iteration++) { + rc = test_gcm_kat(iteration); + if (rc) { + V_(printf("test_gcm_kat failed with rc = %i\n", rc)); + error_count++; + } + + rc = test_gcm_kat_update(iteration); + if (rc) { + V_(printf("test_gcm_kat_update failed with rc = %i\n", rc)); + error_count++; + } + } + if (error_count) + printf("%i of %i AES-GCM tests failed.\n", error_count, iteration); + else + printf("All AES-GCM tests passed.\n"); + return rc; +} diff --git a/src/tests/libica_aes_ofb_test.c b/src/tests/libica_aes_ofb_test.c new file mode 100644 index 0000000..30ba281 --- /dev/null +++ b/src/tests/libica_aes_ofb_test.c @@ -0,0 +1,526 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2010, 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include "ica_api.h" +#include "testcase.h" + +#define NR_TESTS 6 +#define NR_RANDOM_TESTS 10000 + +/* OFB data - 1 for AES128 */ +unsigned char NIST_KEY_OFB_E1[] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, +}; + +unsigned char NIST_IV_OFB_E1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, +}; + +unsigned char NIST_EXPECTED_IV_OFB_E1[] = { + 0x50, 0xfe, 0x67, 0xcc, 0x99, 0x6d, 0x32, 0xb6, + 0xda, 0x09, 0x37, 0xe9, 0x9b, 0xaf, 0xec, 0x60, +}; + +unsigned char NIST_TEST_DATA_OFB_E1[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, +}; + +unsigned char NIST_TEST_RESULT_OFB_E1[] = { + 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20, + 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a, +}; + +/* OFB data - 2 for AES128 */ +unsigned char NIST_KEY_OFB_E2[] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, +}; + +unsigned char NIST_IV_OFB_E2[] = { + 0x50, 0xfe, 0x67, 0xcc, 0x99, 0x6d, 0x32, 0xb6, + 0xda, 0x09, 0x37, 0xe9, 0x9b, 0xaf, 0xec, 0x60, +}; + +unsigned char NIST_EXPECTED_IV_OFB_E2[] = { + 0xd9, 0xa4, 0xda, 0xda, 0x08, 0x92, 0x23, 0x9f, + 0x6b, 0x8b, 0x3d, 0x76, 0x80, 0xe1, 0x56, 0x74, +}; + +unsigned char NIST_TEST_DATA_OFB_E2[] = { + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, +}; + +unsigned char NIST_TEST_RESULT_OFB_E2[] = { + 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03, + 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25, +}; + +/* OFB data - 3 - for AES192 */ +unsigned char NIST_KEY_OFB_E3[] = { + 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, + 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b, +}; + +unsigned char NIST_IV_OFB_E3[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, +}; + +unsigned char NIST_EXPECTED_IV_OFB_E3[] = { + 0xa6, 0x09, 0xb3, 0x8d, 0xf3, 0xb1, 0x13, 0x3d, + 0xdd, 0xff, 0x27, 0x18, 0xba, 0x09, 0x56, 0x5e, +}; + +unsigned char NIST_TEST_DATA_OFB_E3[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, +}; + +unsigned char NIST_TEST_RESULT_OFB_E3[] = { + 0xcd, 0xc8, 0x0d, 0x6f, 0xdd, 0xf1, 0x8c, 0xab, + 0x34, 0xc2, 0x59, 0x09, 0xc9, 0x9a, 0x41, 0x74, +}; + +/* OFB data - 4 - for AES192 */ +unsigned char NIST_KEY_OFB_E4[] = { + 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, + 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b, +}; + +unsigned char NIST_IV_OFB_E4[] = { + 0xa6, 0x09, 0xb3, 0x8d, 0xf3, 0xb1, 0x13, 0x3d, + 0xdd, 0xff, 0x27, 0x18, 0xba, 0x09, 0x56, 0x5e, +}; + +unsigned char NIST_EXPECTED_IV_OFB_E4[] = { + 0x52, 0xef, 0x01, 0xda, 0x52, 0x60, 0x2f, 0xe0, + 0x97, 0x5f, 0x78, 0xac, 0x84, 0xbf, 0x8a, 0x50, +}; + +unsigned char NIST_TEST_DATA_OFB_E4[] = { + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, +}; + +unsigned char NIST_TEST_RESULT_OFB_E4[] = { + 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c, + 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01, +}; + +/* OFB data 5 - for AES 256 */ +unsigned char NIST_KEY_OFB_E5[] = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4, +}; + +unsigned char NIST_IV_OFB_E5[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, +}; + +unsigned char NIST_EXPECTED_IV_OFB_E5[] = { + 0xb7, 0xbf, 0x3a, 0x5d, 0xf4, 0x39, 0x89, 0xdd, + 0x97, 0xf0, 0xfa, 0x97, 0xeb, 0xce, 0x2f, 0x4a, +}; + +unsigned char NIST_TEST_DATA_OFB_E5[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, +}; + +unsigned char NIST_TEST_RESULT_OFB_E5[] = { + 0xdc, 0x7e, 0x84, 0xbf, 0xda, 0x79, 0x16, 0x4b, + 0x7e, 0xcd, 0x84, 0x86, 0x98, 0x5d, 0x38, 0x60, +}; + +/* OFB data 6 - for AES 256 */ +unsigned char NIST_KEY_OFB_E6[] = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4, +}; + +unsigned char NIST_IV_OFB_E6[] = { + 0xb7, 0xbf, 0x3a, 0x5d, 0xf4, 0x39, 0x89, 0xdd, + 0x97, 0xf0, 0xfa, 0x97, 0xeb, 0xce, 0x2f, 0x4a, +}; + +unsigned char NIST_EXPECTED_IV_OFB_E6[] = { + 0xe1, 0xc6, 0x56, 0x30, 0x5e, 0xd1, 0xa7, 0xa6, + 0x56, 0x38, 0x05, 0x74, 0x6f, 0xe0, 0x3e, 0xdc, +}; + +unsigned char NIST_TEST_DATA_OFB_E6[] = { + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, +}; + +unsigned char NIST_TEST_RESULT_OFB_E6[] = { + 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a, + 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d, +}; + +void dump_ofb_data(unsigned char *iv, unsigned int iv_length, + unsigned char *key, unsigned int key_length, + unsigned char *input_data, unsigned int data_length, + unsigned char *output_data) +{ + VV_(printf("IV \n")); + dump_array(iv, iv_length); + VV_(printf("Key \n")); + dump_array(key, key_length); + VV_(printf("Input Data\n")); + dump_array(input_data, data_length); + VV_(printf("Output Data\n")); + dump_array(output_data, data_length); +} + +void get_sizes(unsigned int *data_length, unsigned int *iv_length, + unsigned int *key_length, unsigned int iteration) +{ + switch (iteration) { + case 1: + *data_length = sizeof(NIST_TEST_DATA_OFB_E1); + *iv_length = sizeof(NIST_IV_OFB_E1); + *key_length = sizeof(NIST_KEY_OFB_E1); + break; + case 2: + *data_length = sizeof(NIST_TEST_DATA_OFB_E2); + *iv_length = sizeof(NIST_IV_OFB_E2); + *key_length = sizeof(NIST_KEY_OFB_E2); + break; + case 3: + *data_length = sizeof(NIST_TEST_DATA_OFB_E3); + *iv_length = sizeof(NIST_IV_OFB_E3); + *key_length = sizeof(NIST_KEY_OFB_E3); + break; + case 4: + *data_length = sizeof(NIST_TEST_DATA_OFB_E4); + *iv_length = sizeof(NIST_IV_OFB_E4); + *key_length = sizeof(NIST_KEY_OFB_E4); + break; + case 5: + *data_length = sizeof(NIST_TEST_DATA_OFB_E5); + *iv_length = sizeof(NIST_IV_OFB_E5); + *key_length = sizeof(NIST_KEY_OFB_E5); + break; + case 6: + *data_length = sizeof(NIST_TEST_DATA_OFB_E6); + *iv_length = sizeof(NIST_IV_OFB_E6); + *key_length = sizeof(NIST_KEY_OFB_E6); + break; + } + +} + +void load_test_data(unsigned char *data, unsigned int data_length, + unsigned char *result, + unsigned char *iv, unsigned char *expected_iv, + unsigned int iv_length, + unsigned char *key, unsigned int key_length, + unsigned int iteration) +{ + switch (iteration) { + case 1: + memcpy(data, NIST_TEST_DATA_OFB_E1, data_length); + memcpy(result, NIST_TEST_RESULT_OFB_E1, data_length); + memcpy(iv, NIST_IV_OFB_E1, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_OFB_E1, iv_length); + memcpy(key, NIST_KEY_OFB_E1, key_length); + break; + case 2: + memcpy(data, NIST_TEST_DATA_OFB_E2, data_length); + memcpy(result, NIST_TEST_RESULT_OFB_E2, data_length); + memcpy(iv, NIST_IV_OFB_E2, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_OFB_E2, iv_length); + memcpy(key, NIST_KEY_OFB_E2, key_length); + break; + case 3: + memcpy(data, NIST_TEST_DATA_OFB_E3, data_length); + memcpy(result, NIST_TEST_RESULT_OFB_E3, data_length); + memcpy(iv, NIST_IV_OFB_E3, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_OFB_E3, iv_length); + memcpy(key, NIST_KEY_OFB_E3, key_length); + break; + case 4: + memcpy(data, NIST_TEST_DATA_OFB_E4, data_length); + memcpy(result, NIST_TEST_RESULT_OFB_E4, data_length); + memcpy(iv, NIST_IV_OFB_E4, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_OFB_E4, iv_length); + memcpy(key, NIST_KEY_OFB_E4, key_length); + break; + case 5: + memcpy(data, NIST_TEST_DATA_OFB_E5, data_length); + memcpy(result, NIST_TEST_RESULT_OFB_E5, data_length); + memcpy(iv, NIST_IV_OFB_E5, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_OFB_E5, iv_length); + memcpy(key, NIST_KEY_OFB_E5, key_length); + break; + case 6: + memcpy(data, NIST_TEST_DATA_OFB_E6, data_length); + memcpy(result, NIST_TEST_RESULT_OFB_E6, data_length); + memcpy(iv, NIST_IV_OFB_E6, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_OFB_E6, iv_length); + memcpy(key, NIST_KEY_OFB_E6, key_length); + break; + } + +} + +int load_random_test_data(unsigned char *data, unsigned int data_length, + unsigned char *iv, unsigned int iv_length, + unsigned char *key, unsigned int key_length) +{ + int rc; + + rc = ica_random_number_generate(data_length, data); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + rc = ica_random_number_generate(iv_length, iv); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + rc = ica_random_number_generate(key_length, key); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + return rc; +} + +int random_aes_ofb(int iteration, unsigned int data_length) +{ + int i; + int rc = 0; + unsigned int iv_length = sizeof(ica_aes_vector_t); + unsigned int key_length = AES_KEY_LEN128; + unsigned char iv[iv_length]; + unsigned char tmp_iv[iv_length]; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + + for (i = 0; i <= 2; i++) { + unsigned char key[key_length]; + + memset(encrypt, 0x00, data_length); + memset(decrypt, 0x00, data_length); + + load_random_test_data(input_data, data_length, iv, iv_length, key, + key_length); + memcpy(tmp_iv, iv, iv_length); + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i, iv length = %i\n", + key_length, data_length, iv_length)); + rc = ica_aes_ofb(input_data, encrypt, data_length, key, key_length, + tmp_iv, 1); + if (rc) { + VV_(printf("ica_aes_ofb encrypt failed with rc = %i\n", rc)); + dump_ofb_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_ofb_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + + if (rc) { + VV_(printf("AES OFB test exited after encryption\n")); + return rc; + } + + memcpy(tmp_iv, iv, iv_length); + + rc = ica_aes_ofb(encrypt, decrypt, data_length, key, key_length, + tmp_iv, 0); + if (rc) { + VV_(printf("ica_aes_ofb decrypt failed with rc = %i\n", rc)); + dump_ofb_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_ofb_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + return rc; + } + key_length += 8; + } + + return rc; +} + +int kat_aes_ofb(int iteration) +{ + unsigned int data_length; + unsigned int iv_length; + unsigned int key_length; + + get_sizes(&data_length, &iv_length, &key_length, iteration); + + unsigned char iv[iv_length]; + unsigned char tmp_iv[iv_length]; + unsigned char expected_iv[iv_length]; + unsigned char key[key_length]; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + unsigned char result[data_length]; + + int rc = 0; + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i, iv length = %i\n", + key_length, data_length, iv_length)); + + load_test_data(input_data, data_length, result, iv, expected_iv, + iv_length, key, key_length, iteration); + memcpy(tmp_iv, iv, iv_length); + + rc = ica_aes_ofb(input_data, encrypt, data_length, key, key_length, + tmp_iv, 1); + if (rc) { + VV_(printf("ica_aes_ofb encrypt failed with rc = %i\n", rc)); + dump_ofb_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_ofb_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + + if (memcmp(result, encrypt, data_length)) { + VV_(printf("Encryption Result does not match the known ciphertext!\n")); + VV_(printf("Expected data:\n")); + dump_array(result, data_length); + VV_(printf("Encryption Result:\n")); + dump_array(encrypt, data_length); + rc++; + } + + if (memcmp(expected_iv, tmp_iv, iv_length)) { + VV_(printf("Update of IV does not match the expected IV!\n")); + VV_(printf("Expected IV:\n")); + dump_array(expected_iv, iv_length); + VV_(printf("Updated IV:\n")); + dump_array(tmp_iv, iv_length); + VV_(printf("Original IV:\n")); + dump_array(iv, iv_length); + rc++; + } + if (rc) { + VV_(printf("AES OFB test exited after encryption\n")); + return rc; + } + + memcpy(tmp_iv, iv, iv_length); + rc = ica_aes_ofb(encrypt, decrypt, data_length, key, key_length, + tmp_iv, 0); + if (rc) { + VV_(printf("ica_aes_ofb decrypt failed with rc = %i\n", rc)); + dump_ofb_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_ofb_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + } + return rc; +} + +int main(int argc, char **argv) +{ + int rc = 0; + int error_count = 0; + int iteration; + unsigned int rdata; + unsigned int data_length = 1; + + set_verbosity(argc, argv); + + for(iteration = 1; iteration <= NR_TESTS; iteration++) { + rc = kat_aes_ofb(iteration); + if (rc) { + V_(printf("kat_aes_ofb failed with rc = %i\n", rc)); + error_count++; + } + + } + + for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) { + rc = random_aes_ofb(iteration, data_length); + if (rc) { + V_(printf("random_aes_ofb failed with rc = %i\n", rc)); + error_count++; + goto out; + } + // add a value between 1 and 8 to data_length + if (ica_random_number_generate(sizeof(rdata), (unsigned char*) &rdata)) { + printf("ica_random_number_generate failed with errnor = %i\n", + errno); + exit(1); + } + data_length += (rdata % 8) + 1; + } + +out: + if (error_count) + printf("%i AES-OFB tests failed.\n", error_count); + else + printf("All AES-OFB tests passed.\n"); + + return rc; +} + diff --git a/src/tests/libica_aes_xts_test.c b/src/tests/libica_aes_xts_test.c new file mode 100644 index 0000000..c7be0be --- /dev/null +++ b/src/tests/libica_aes_xts_test.c @@ -0,0 +1,644 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2010, 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include "ica_api.h" +#include "testcase.h" + +#define NR_TESTS 5 +#define NR_RANDOM_TESTS 20000 + +/* XTS data -1- AES128 */ +unsigned char NIST_KEY_XTS_E1[] = { + 0x46, 0xe6, 0xed, 0x9e, 0xf4, 0x2d, 0xcd, 0xb3, + 0xc8, 0x93, 0x09, 0x3c, 0x28, 0xe1, 0xfc, 0x0f, + 0x91, 0xf5, 0xca, 0xa3, 0xb6, 0xe0, 0xbc, 0x5a, + 0x14, 0xe7, 0x83, 0x21, 0x5c, 0x1d, 0x5b, 0x61, +}; + +unsigned char NIST_TWEAK_XTS_E1[] = { + 0x72, 0xf3, 0xb0, 0x54, 0xcb, 0xdc, 0x2f, 0x9e, + 0x3c, 0x5b, 0xc5, 0x51, 0xd4, 0x4d, 0xdb, 0xa0, +}; + +/* TWEAK should not be updated, so the exptected tweak is the same as the + * original TWEAK. + */ +unsigned char NIST_EXPECTED_TWEAK_XTS_E1[] = { + 0x72, 0xf3, 0xb0, 0x54, 0xcb, 0xdc, 0x2f, 0x9e, + 0x3c, 0x5b, 0xc5, 0x51, 0xd4, 0x4d, 0xdb, 0xa0, +}; + +unsigned char NIST_TEST_DATA_XTS_E1[] = { + 0xe3, 0x77, 0x8d, 0x68, 0xe7, 0x30, 0xef, 0x94, + 0x5b, 0x4a, 0xe3, 0xbc, 0x5b, 0x93, 0x6b, 0xdd, +}; + +unsigned char NIST_TEST_RESULT_XTS_E1[] = { + 0x97, 0x40, 0x9f, 0x1f, 0x71, 0xae, 0x45, 0x21, + 0xcb, 0x49, 0xa3, 0x29, 0x73, 0xde, 0x4d, 0x05, +}; + +/* XTS data -2- AES128 */ +unsigned char NIST_KEY_XTS_E2[] = { + 0x93, 0x56, 0xcd, 0xad, 0x25, 0x1a, 0xb6, 0x11, + 0x14, 0xce, 0xc2, 0xc4, 0x4a, 0x60, 0x92, 0xdd, + 0xe9, 0xf7, 0x46, 0xcc, 0x65, 0xae, 0x3b, 0xd4, + 0x96, 0x68, 0x64, 0xaa, 0x36, 0x26, 0xd1, 0x88, +}; + +unsigned char NIST_TWEAK_XTS_E2[] = { + 0x68, 0x88, 0x27, 0x83, 0x65, 0x24, 0x36, 0xc4, + 0x85, 0x7a, 0x88, 0xc0, 0xc3, 0x73, 0x41, 0x7e, +}; + +unsigned char NIST_EXPECTED_TWEAK_XTS_E2[] = { + 0x68, 0x88, 0x27, 0x83, 0x65, 0x24, 0x36, 0xc4, + 0x85, 0x7a, 0x88, 0xc0, 0xc3, 0x73, 0x41, 0x7e, +}; + +unsigned char NIST_TEST_DATA_XTS_E2[] = { + 0xce, 0x17, 0x6b, 0xdd, 0xe3, 0x39, 0x50, 0x5b, + 0xa1, 0x5d, 0xea, 0x36, 0xd2, 0x8c, 0xe8, 0x7d, +}; + +unsigned char NIST_TEST_RESULT_XTS_E2[] = { + 0x22, 0xf5, 0xf9, 0x37, 0xdf, 0xb3, 0x9e, 0x5b, + 0x74, 0x25, 0xed, 0x86, 0x3d, 0x31, 0x0b, 0xe1, +}; + +/* XTS data -3- AES128 */ +unsigned char NIST_KEY_XTS_E3[] = { + 0x63, 0xf3, 0x6e, 0x9c, 0x39, 0x7c, 0x65, 0x23, + 0xc9, 0x9f, 0x16, 0x44, 0xec, 0xb1, 0xa5, 0xd9, + 0xbc, 0x0f, 0x2f, 0x55, 0xfb, 0xe3, 0x24, 0x44, + 0x4c, 0x39, 0x0f, 0xae, 0x75, 0x2a, 0xd4, 0xd7, +}; + +unsigned char NIST_TWEAK_XTS_E3[] = { + 0xcd, 0xb1, 0xbd, 0x34, 0x86, 0xf3, 0x53, 0xcc, + 0x16, 0x0a, 0x84, 0x0b, 0xea, 0xdf, 0x03, 0x29, +}; + +unsigned char NIST_EXPECTED_TWEAK_XTS_E3[] = { + 0xcd, 0xb1, 0xbd, 0x34, 0x86, 0xf3, 0x53, 0xcc, + 0x16, 0x0a, 0x84, 0x0b, 0xea, 0xdf, 0x03, 0x29, +}; + +unsigned char NIST_TEST_DATA_XTS_E3[] = { + 0x9a, 0x01, 0x49, 0x88, 0x8b, 0xf7, 0x61, 0x60, + 0xa8, 0x14, 0x28, 0xbc, 0x91, 0x40, 0xec, 0xcd, + 0x26, 0xed, 0x18, 0x36, 0x8e, 0x24, 0xd4, 0x9b, + 0x9c, 0xc5, 0x12, 0x92, 0x9a, 0x88, 0xad, 0x1e, + 0x66, 0xc7, 0x63, 0xf4, 0xf5, 0x6b, 0x63, 0xbb, + 0x9d, 0xd9, 0x50, 0x8c, 0x5d, 0x4d, 0xf4, 0x65, + 0xad, 0x98, 0x82, 0x14, 0x82, 0xfc, 0x71, 0x94, + 0xee, 0x23, 0x54, 0xa3, 0xfa, 0xdc, 0xe9, 0x23, + 0x18, 0x54, 0x8e, 0x8c, 0xe9, 0x45, 0x20, 0x81, + 0x60, 0x49, 0x7b, 0x93, 0x05, 0xd9, 0xab, 0x10, + 0x91, 0xab, 0x41, 0xd1, 0xf0, 0x9a, 0x0c, 0x7b, + 0xfa, 0xf9, 0xf9, 0x4f, 0xe7, 0xc8, 0xf1, 0xea, + 0x96, 0x8f, 0x8f, 0x9a, 0x71, 0x3a, 0xca, 0xde, + 0x18, 0xb6, 0x82, 0x32, 0x10, 0x6f, 0xfd, 0x6d, + 0x42, 0x81, 0xe9, 0x9e, 0x11, 0xd6, 0xa4, 0x28, + 0xb5, 0x16, 0x53, 0xc0, 0xc7, 0xdd, 0xe5, 0xa0, + 0xf2, 0x73, 0xe7, 0x4f, 0xf0, 0x15, 0xce, 0x80, + 0x27, 0x7d, 0x74, 0x30, 0xf5, 0xda, 0xea, 0x8f, + 0x73, 0x40, 0x64, 0x5e, 0x0b, 0xec, 0x25, 0xf4, + 0x04, 0x0f, 0xa1, 0x3c, 0x0b, 0x33, 0x06, 0x93, + 0xb1, 0x00, 0x83, 0xa8, 0xb9, 0xbc, 0x10, 0x8f, + 0xe6, 0x4f, 0x3a, 0x5b, 0x61, 0x3c, 0xbb, 0x56, + 0x5a, 0xee, 0x2f, 0x09, 0xf5, 0xb2, 0x04, 0xae, + 0xe1, 0x72, 0x28, 0xfe, 0x65, 0x31, 0xc7, 0x0c, + 0x0e, 0xc9, 0x47, 0xd2, 0xa5, 0x14, 0x7b, 0x45, + 0xc5, 0x1a, 0xc7, 0xdc, 0x8e, 0x85, 0x87, 0x03, + 0x87, 0xeb, 0x8d, 0xb6, 0x25, 0x13, 0x68, 0x36, + 0x8b, 0xf5, 0xf2, 0x46, 0xb2, 0x95, 0x7d, 0xaf, + 0xf7, 0x02, 0xe3, 0x79, 0x02, 0x2e, 0x99, 0x16, + 0x17, 0x49, 0xe6, 0xbe, 0x8e, 0xb7, 0x9d, 0x51, + 0x97, 0x99, 0xaa, 0xe0, 0x7c, 0x18, 0x31, 0xbd, + 0x0e, 0xe7, 0x25, 0x50, 0xb8, 0x53, 0x33, 0xab, + 0x9e, 0x96, 0xa5, 0x33, 0xe2, 0x97, 0x25, 0xd7, + 0x02, 0x3d, 0x82, 0x1a, 0xbe, 0x1c, 0xe3, 0xa7, + 0x44, 0xbe, 0x02, 0xe0, 0x52, 0x56, 0x8f, 0x84, + 0xe6, 0xe3, 0xf7, 0x44, 0x42, 0xbb, 0xa5, 0x0d, + 0x02, 0xad, 0x2d, 0x6c, 0xa5, 0x8a, 0x69, 0x1f, + 0xd2, 0x43, 0x9a, 0xa3, 0xaf, 0x0c, 0x03, 0x3a, + 0x68, 0xc4, 0x38, 0xb2, 0xd9, 0xa0, 0xa0, 0x1d, + 0x78, 0xc4, 0xf8, 0x7c, 0x50, 0x9f, 0xea, 0x0a, + 0x43, 0x5b, 0xe7, 0x1b, 0xa2, 0x37, 0x06, 0xd6, + 0x08, 0x2d, 0xcb, 0xa6, 0x26, 0x25, 0x99, 0x9e, + 0xce, 0x09, 0xdf, 0xb3, 0xfc, 0xbe, 0x08, 0xeb, + 0xb6, 0xf2, 0x15, 0x1e, 0x2f, 0x12, 0xeb, 0xe8, + 0xa5, 0xbf, 0x11, 0x62, 0xc2, 0x59, 0xf2, 0x02, + 0xc1, 0xba, 0x47, 0x8b, 0x5f, 0x46, 0x8a, 0x28, + 0x69, 0xf1, 0xe7, 0x6c, 0xf5, 0xed, 0x38, 0xde, + 0x53, 0x86, 0x9a, 0xdc, 0x83, 0x70, 0x9e, 0x21, + 0xb3, 0xf8, 0xdc, 0x13, 0xba, 0x3d, 0x6a, 0xa7, + 0xf6, 0xb0, 0xcf, 0xb3, 0xe5, 0xa4, 0x3c, 0x23, + 0x72, 0xe0, 0xee, 0x60, 0x99, 0x1c, 0xe1, 0xca, + 0xd1, 0x22, 0xa3, 0x1d, 0x93, 0x97, 0xe3, 0x0b, + 0x92, 0x1f, 0xd2, 0xf6, 0xee, 0x69, 0x6e, 0x68, + 0x49, 0xae, 0xee, 0x29, 0xe2, 0xb4, 0x45, 0xc0, + 0xfd, 0x9a, 0xde, 0x65, 0x56, 0xc3, 0xc0, 0x69, + 0xc5, 0xd6, 0x05, 0x95, 0xab, 0xbd, 0xf5, 0xba, + 0xe2, 0xcc, 0xc7, 0x9a, 0x49, 0x6e, 0x83, 0xcc, + 0xab, 0x95, 0x74, 0x0e, 0xb8, 0xe4, 0xf2, 0x92, + 0x5d, 0xbf, 0x72, 0x97, 0xa8, 0xc9, 0x92, 0x75, + 0x6e, 0x62, 0x87, 0x0e, 0xdc, 0xe9, 0x8f, 0x6c, + 0xba, 0x1a, 0xa0, 0xd5, 0xb8, 0x6f, 0x09, 0x21, + 0x43, 0xb1, 0x6d, 0xa1, 0x44, 0x15, 0x47, 0xd1, + 0xd4, 0x2b, 0x80, 0x06, 0xfa, 0xce, 0x69, 0x5b, + 0x03, 0xfd, 0xfa, 0xe6, 0x45, 0xf9, 0x5b, 0xd6, +}; + +unsigned char NIST_TEST_RESULT_XTS_E3[] = { + 0x0e, 0xee, 0xf2, 0x8c, 0xa1, 0x59, 0xb8, 0x05, + 0xf5, 0xc2, 0x15, 0x61, 0x05, 0x51, 0x67, 0x8a, + 0xb7, 0x72, 0xf2, 0x79, 0x37, 0x4f, 0xb1, 0x40, + 0xab, 0x55, 0x07, 0x68, 0xdb, 0x42, 0xcf, 0x6c, + 0xb7, 0x36, 0x37, 0x64, 0x19, 0x34, 0x19, 0x5f, + 0xfc, 0x08, 0xcf, 0x5a, 0x91, 0x88, 0xb8, 0x2b, + 0x84, 0x0a, 0x00, 0x7d, 0x52, 0x72, 0x39, 0xea, + 0x3f, 0x0d, 0x7d, 0xd1, 0xf2, 0x51, 0x86, 0xec, + 0xae, 0x30, 0x87, 0x7d, 0xad, 0xa7, 0x7f, 0x24, + 0x3c, 0xdd, 0xb2, 0xc8, 0x8e, 0x99, 0x04, 0x82, + 0x7d, 0x3e, 0x09, 0x82, 0xda, 0x0d, 0x13, 0x91, + 0x1d, 0x0e, 0x2d, 0xbb, 0xbb, 0x2d, 0x01, 0x6c, + 0xbe, 0x4d, 0x06, 0x76, 0xb1, 0x45, 0x9d, 0xa8, + 0xc5, 0x3a, 0x91, 0x45, 0xe8, 0x3c, 0xf4, 0x2f, + 0x30, 0x11, 0x2c, 0xa6, 0x5d, 0x77, 0xc8, 0x93, + 0x4a, 0x26, 0xee, 0x00, 0x1f, 0x39, 0x0f, 0xfc, + 0xc1, 0x87, 0x03, 0x66, 0x2a, 0x8f, 0x71, 0xf9, + 0xda, 0x0e, 0x7b, 0x68, 0xb1, 0x04, 0x3c, 0x1c, + 0xb5, 0x26, 0x08, 0xcf, 0x0e, 0x69, 0x51, 0x0d, + 0x38, 0xc8, 0x0f, 0xa0, 0x0d, 0xe4, 0x3d, 0xef, + 0x98, 0x4d, 0xff, 0x2f, 0x32, 0x4e, 0xcf, 0x39, + 0x89, 0x44, 0x53, 0xd3, 0xe0, 0x1b, 0x3d, 0x7b, + 0x3b, 0xc0, 0x57, 0x04, 0x9d, 0x19, 0x5c, 0x8e, + 0xb9, 0x3f, 0xe4, 0xd9, 0x5a, 0x83, 0x00, 0xa5, + 0xe6, 0x0a, 0x7c, 0x89, 0xe4, 0x0c, 0x69, 0x16, + 0x79, 0xfb, 0xca, 0xfa, 0xd8, 0xeb, 0x41, 0x8f, + 0x8d, 0x1f, 0xf7, 0xb9, 0x11, 0x75, 0xf8, 0xeb, + 0x3c, 0x6f, 0xf2, 0x87, 0x2d, 0x32, 0xee, 0x4c, + 0x57, 0x36, 0x9e, 0x61, 0xb6, 0x6d, 0x16, 0x6f, + 0xd0, 0xa4, 0x34, 0x57, 0x47, 0x82, 0x75, 0xfe, + 0x14, 0xbf, 0x34, 0x63, 0x8a, 0x9e, 0x4e, 0x1d, + 0x25, 0xcc, 0x5a, 0x5f, 0x9e, 0x25, 0x7e, 0x61, + 0x7a, 0xdc, 0xdd, 0xe6, 0x5e, 0x25, 0x57, 0x40, + 0x53, 0x62, 0xc8, 0x91, 0xe6, 0x54, 0x6a, 0x6d, + 0xee, 0xaa, 0x8f, 0xc0, 0x3b, 0x12, 0x2a, 0x55, + 0x87, 0x4d, 0x33, 0xe0, 0xa7, 0x73, 0x52, 0x34, + 0x68, 0x32, 0x5e, 0xc2, 0x4d, 0x4f, 0xaf, 0xfb, + 0x63, 0xc0, 0x52, 0xc8, 0x11, 0xa1, 0xc0, 0x22, + 0xba, 0xfc, 0xcb, 0x97, 0x98, 0x8b, 0x7e, 0x45, + 0x67, 0xb2, 0x47, 0xd4, 0x04, 0x4b, 0x05, 0x2f, + 0xf7, 0x3f, 0x4c, 0x67, 0x1d, 0x27, 0xe0, 0x52, + 0xe2, 0xeb, 0xc7, 0x2d, 0x00, 0x57, 0xcb, 0x21, + 0x7c, 0x52, 0x59, 0xb6, 0x09, 0x50, 0xe3, 0xc8, + 0xb3, 0xd9, 0xe3, 0xe7, 0x63, 0x0f, 0x9e, 0xcb, + 0xe5, 0x48, 0xb9, 0xe3, 0x62, 0x20, 0xf3, 0x3c, + 0x2b, 0x45, 0x68, 0x30, 0x7c, 0xd0, 0x37, 0x5b, + 0xba, 0x13, 0x35, 0xe5, 0x8b, 0xfb, 0xcd, 0xe8, + 0x5c, 0xc8, 0x4c, 0x9c, 0x9c, 0x1c, 0xe7, 0x4f, + 0x44, 0xb2, 0x8e, 0xa1, 0xb6, 0x97, 0x30, 0x5b, + 0xb6, 0xba, 0x3b, 0x46, 0x4e, 0x5a, 0xb7, 0x45, + 0x01, 0x29, 0x3e, 0xf9, 0x15, 0x2c, 0x0f, 0x5d, + 0x33, 0x07, 0xd2, 0x6a, 0x1f, 0x07, 0x41, 0xc5, + 0xe5, 0x72, 0x1a, 0x71, 0x3d, 0x1b, 0x86, 0xc1, + 0x80, 0x82, 0x11, 0xf5, 0x7a, 0xad, 0x09, 0xa9, + 0x50, 0xb6, 0x86, 0x30, 0xaf, 0xce, 0x4f, 0x0a, + 0xd9, 0xf3, 0x2e, 0x67, 0x69, 0xb5, 0xfe, 0x31, + 0x92, 0x9c, 0x44, 0x6f, 0x7a, 0x33, 0x55, 0xf4, + 0x58, 0x84, 0xc7, 0x48, 0xc9, 0x05, 0x54, 0x15, + 0xe6, 0x37, 0xd9, 0xad, 0x87, 0xd9, 0x4c, 0x46, + 0x57, 0xb1, 0xad, 0x03, 0x4c, 0xb1, 0x4d, 0x9a, + 0x72, 0xea, 0x74, 0x5f, 0xe5, 0x2d, 0x7a, 0x71, + 0x1b, 0xa4, 0x1c, 0xa0, 0x35, 0x85, 0x6a, 0x5a, + 0x44, 0x89, 0xa4, 0x27, 0x0b, 0xb3, 0x0d, 0x5b, + 0x63, 0xf4, 0x9c, 0x05, 0x12, 0xfe, 0xd4, 0xb4 +}; + +/* XTS data -4- AES256 */ +unsigned char NIST_KEY_XTS_E4[] = { + 0x97, 0x09, 0x8b, 0x46, 0x5a, 0x44, 0xca, 0x75, + 0xe7, 0xa1, 0xc2, 0xdb, 0xfc, 0x40, 0xb7, 0xa6, + 0x1a, 0x20, 0xe3, 0x2c, 0x6d, 0x9d, 0xbf, 0xda, + 0x80, 0x72, 0x6f, 0xee, 0x10, 0x54, 0x1b, 0xab, + 0x47, 0x54, 0x63, 0xca, 0x07, 0xc1, 0xc1, 0xe4, + 0x49, 0x61, 0x73, 0x32, 0x14, 0x68, 0xd1, 0xab, + 0x3f, 0xad, 0x8a, 0xd9, 0x1f, 0xcd, 0xc6, 0x2a, + 0xbe, 0x07, 0xbf, 0xf8, 0xef, 0x96, 0x1b, 0x6b, +}; + +unsigned char NIST_TWEAK_XTS_E4[] = { + 0x15, 0x60, 0x1e, 0x2e, 0x35, 0x85, 0x10, 0xa0, + 0x9d, 0xdc, 0xa4, 0xea, 0x17, 0x51, 0xf4, 0x3c, +}; + +unsigned char NIST_EXPECTED_TWEAK_XTS_E4[] = { + 0x15, 0x60, 0x1e, 0x2e, 0x35, 0x85, 0x10, 0xa0, + 0x9d, 0xdc, 0xa4, 0xea, 0x17, 0x51, 0xf4, 0x3c, +}; + +unsigned char NIST_TEST_DATA_XTS_E4[] = { + 0xd1, 0x9c, 0xfb, 0x38, 0x3b, 0xaf, 0x87, 0x2e, + 0x6f, 0x12, 0x16, 0x87, 0x45, 0x1d, 0xe1, 0x5c, +}; + +unsigned char NIST_TEST_RESULT_XTS_E4[] = { + 0xeb, 0x22, 0x26, 0x9b, 0x14, 0x90, 0x50, 0x27, + 0xdc, 0x73, 0xc4, 0xa4, 0x0f, 0x93, 0x80, 0x69, +}; + + +/* XTS data -5- AES256 */ +unsigned char NIST_KEY_XTS_E5[] = { + 0xfb, 0xf0, 0x77, 0x6e, 0x7d, 0xbe, 0x49, 0x10, + 0xfb, 0x0c, 0x12, 0x0f, 0x41, 0x85, 0x71, 0x21, + 0x92, 0x6c, 0x05, 0x2f, 0xd6, 0x5a, 0x27, 0x8c, + 0xd2, 0xf0, 0xd9, 0x8d, 0xa5, 0x4e, 0xdf, 0xd5, + 0x08, 0x03, 0xa4, 0x2f, 0xbe, 0x6f, 0xd1, 0x33, + 0x58, 0x49, 0x00, 0xe8, 0xdc, 0x7a, 0x11, 0x52, + 0x39, 0x1f, 0x82, 0x2d, 0x76, 0xa7, 0x56, 0x68, + 0xcf, 0xce, 0x7f, 0x8d, 0xde, 0x20, 0x3e, 0xc8, +}; + +unsigned char NIST_TWEAK_XTS_E5[] = { + 0x39, 0x5b, 0x6a, 0xcf, 0x9a, 0xdc, 0xd2, 0x91, + 0xc2, 0xc9, 0x48, 0x86, 0x36, 0x33, 0xaf, 0xf8, +}; + +unsigned char NIST_EXPECTED_TWEAK_XTS_E5[] = { + 0x39, 0x5b, 0x6a, 0xcf, 0x9a, 0xdc, 0xd2, 0x91, + 0xc2, 0xc9, 0x48, 0x86, 0x36, 0x33, 0xaf, 0xf8, +}; + +unsigned char NIST_TEST_DATA_XTS_E5[] = { + 0x3e, 0x2e, 0x26, 0x9d, 0x78, 0x3a, 0x2b, 0x29, + 0xe8, 0x73, 0xd6, 0x73, 0x47, 0x9f, 0x51, 0x16, + 0x73, 0x4f, 0xe0, 0x3e, 0xe3, 0x29, 0x65, 0xed, + 0xc4, 0x79, 0x35, 0xc0, 0xea, 0x99, 0xa0, 0x64, + 0xbd, 0x44, 0x4b, 0xec, 0x12, 0x5b, 0x2c, 0x78, + 0x9d, 0xb9, 0xde, 0x6d, 0x18, 0x35, 0x92, 0x05, + 0x3b, 0x48, 0xa8, 0x77, 0xa9, 0x5a, 0xc2, 0x55, + 0x9c, 0x3d, 0xdf, 0xc7, 0xb4, 0xdb, 0x99, 0x07, +}; + +unsigned char NIST_TEST_RESULT_XTS_E5[] = { + 0x4c, 0x70, 0xbd, 0xbb, 0x77, 0x30, 0x2b, 0x7f, + 0x1f, 0xdd, 0xca, 0x50, 0xdc, 0x70, 0x73, 0x1e, + 0x00, 0x8a, 0x26, 0x55, 0xd2, 0x2a, 0xd0, 0x20, + 0x0c, 0x11, 0x1f, 0xd3, 0x2a, 0x67, 0x5a, 0x7e, + 0x09, 0x97, 0x11, 0x43, 0x6f, 0x98, 0xd2, 0x1c, + 0x72, 0x77, 0x2e, 0x0d, 0xd7, 0x67, 0x2f, 0xf5, + 0xfd, 0x00, 0xdd, 0xcb, 0xe1, 0x1e, 0xb9, 0x7e, + 0x69, 0x87, 0x83, 0xbf, 0xa4, 0x05, 0x46, 0xe3, +}; + +void dump_xts_data(unsigned char *tweak, unsigned int tweak_length, + unsigned char *key, unsigned int key_length, + unsigned char *input_data, unsigned int data_length, + unsigned char *output_data) +{ + VV_(printf("TWEAK \n")); + dump_array(tweak, tweak_length); + VV_(printf("Key \n")); + dump_array(key, key_length); + VV_(printf("Input Data\n")); + dump_array(input_data, data_length); + VV_(printf("Output Data\n")); + dump_array(output_data, data_length); +} + +void get_sizes(unsigned int *data_length, unsigned int *tweak_length, + unsigned int *key_length, unsigned int iteration) +{ + switch (iteration) { + case 1: + *data_length = sizeof(NIST_TEST_DATA_XTS_E1); + *tweak_length = sizeof(NIST_TWEAK_XTS_E1); + *key_length = sizeof(NIST_KEY_XTS_E1); + break; + case 2: + *data_length = sizeof(NIST_TEST_DATA_XTS_E2); + *tweak_length = sizeof(NIST_TWEAK_XTS_E2); + *key_length = sizeof(NIST_KEY_XTS_E2); + break; + case 3: + *data_length = sizeof(NIST_TEST_DATA_XTS_E3); + *tweak_length = sizeof(NIST_TWEAK_XTS_E3); + *key_length = sizeof(NIST_KEY_XTS_E3); + break; + case 4: + *data_length = sizeof(NIST_TEST_DATA_XTS_E4); + *tweak_length = sizeof(NIST_TWEAK_XTS_E4); + *key_length = sizeof(NIST_KEY_XTS_E4); + break; + case 5: + *data_length = sizeof(NIST_TEST_DATA_XTS_E5); + *tweak_length = sizeof(NIST_TWEAK_XTS_E5); + *key_length = sizeof(NIST_KEY_XTS_E5); + break; + } + +} + +void load_test_data(unsigned char *data, unsigned int data_length, + unsigned char *result, + unsigned char *tweak, unsigned char *expected_tweak, + unsigned int tweak_length, + unsigned char *key, unsigned int key_length, + unsigned int iteration) +{ + switch (iteration) { + case 1: + memcpy(data, NIST_TEST_DATA_XTS_E1, data_length); + memcpy(result, NIST_TEST_RESULT_XTS_E1, data_length); + memcpy(tweak, NIST_TWEAK_XTS_E1, tweak_length); + memcpy(expected_tweak, NIST_EXPECTED_TWEAK_XTS_E1, + tweak_length); + memcpy(key, NIST_KEY_XTS_E1, key_length); + break; + case 2: + memcpy(data, NIST_TEST_DATA_XTS_E2, data_length); + memcpy(result, NIST_TEST_RESULT_XTS_E2, data_length); + memcpy(tweak, NIST_TWEAK_XTS_E2, tweak_length); + memcpy(expected_tweak, NIST_EXPECTED_TWEAK_XTS_E2, + tweak_length); + memcpy(key, NIST_KEY_XTS_E2, key_length); + break; + case 3: + memcpy(data, NIST_TEST_DATA_XTS_E3, data_length); + memcpy(result, NIST_TEST_RESULT_XTS_E3, data_length); + memcpy(tweak, NIST_TWEAK_XTS_E3, tweak_length); + memcpy(expected_tweak, NIST_EXPECTED_TWEAK_XTS_E3, + tweak_length); + memcpy(key, NIST_KEY_XTS_E3, key_length); + break; + case 4: + memcpy(data, NIST_TEST_DATA_XTS_E4, data_length); + memcpy(result, NIST_TEST_RESULT_XTS_E4, data_length); + memcpy(tweak, NIST_TWEAK_XTS_E4, tweak_length); + memcpy(expected_tweak, NIST_EXPECTED_TWEAK_XTS_E4, + tweak_length); + memcpy(key, NIST_KEY_XTS_E4, key_length); + break; + case 5: + memcpy(data, NIST_TEST_DATA_XTS_E5, data_length); + memcpy(result, NIST_TEST_RESULT_XTS_E5, data_length); + memcpy(tweak, NIST_TWEAK_XTS_E5, tweak_length); + memcpy(expected_tweak, NIST_EXPECTED_TWEAK_XTS_E5, + tweak_length); + memcpy(key, NIST_KEY_XTS_E5, key_length); + break; + } + +} + +int kat_aes_xts(int iteration) +{ + unsigned int data_length; + unsigned int tweak_length; + unsigned int key_length; + + get_sizes(&data_length, &tweak_length, &key_length, iteration); + + unsigned char tweak[tweak_length]; + unsigned char tmp_tweak[tweak_length]; + unsigned char expected_tweak[tweak_length]; + unsigned char key[key_length]; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + unsigned char result[data_length]; + + int rc = 0; + + memset(encrypt, 0x00, data_length); + memset(decrypt, 0x00, data_length); + + load_test_data(input_data, data_length, result, tweak, expected_tweak, + tweak_length, key, key_length, iteration); + memcpy(tmp_tweak, tweak, tweak_length); + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i, tweak length = %i,", + key_length, data_length, tweak_length)); + rc = ica_aes_xts(input_data, encrypt, data_length, + key, key+(key_length/2), (key_length/2), + tmp_tweak, 1); + if (rc) { + VV_(printf("ica_aes_xts encrypt failed with rc = %i\n", rc)); + dump_xts_data(tweak, tweak_length, key, key_length, input_data, + data_length, encrypt); + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_xts_data(tweak, tweak_length, key, key_length, input_data, + data_length, encrypt); + } + + if (memcmp(result, encrypt, data_length)) { + VV_(printf("Encryption Result does not match the known ciphertext!\n")); + VV_(printf("Expected data:\n")); + dump_array(result, data_length); + VV_(printf("Encryption Result:\n")); + dump_array(encrypt, data_length); + rc++; + } + + if (memcmp(expected_tweak, tmp_tweak, tweak_length)) { + VV_(printf("Update of TWEAK does not match the expected TWEAK!\n")); + VV_(printf("Expected TWEAK:\n")); + dump_array(expected_tweak, tweak_length); + VV_(printf("Updated TWEAK:\n")); + dump_array(tmp_tweak, tweak_length); + VV_(printf("Original TWEAK:\n")); + dump_array(tweak, tweak_length); + rc++; + } + if (rc) { + VV_(printf("AES XTS test exited after encryption\n")); + return rc; + } + + memcpy(tmp_tweak, tweak, tweak_length); + rc = ica_aes_xts(encrypt, decrypt, data_length, + key, key+(key_length/2), (key_length/2), + tmp_tweak, 0); + if (rc) { + VV_(printf("ica_aes_xts decrypt failed with rc = %i\n", rc)); + dump_xts_data(tweak, tweak_length, key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_xts_data(tweak, tweak_length, key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + } + return rc; +} + +int load_random_test_data(unsigned char *data, unsigned int data_length, + unsigned char *iv, unsigned int iv_length, + unsigned char *key, unsigned int key_length) +{ + int rc; + + rc = ica_random_number_generate(data_length, data); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + rc = ica_random_number_generate(iv_length, iv); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + rc = ica_random_number_generate(key_length, key); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + return rc; +} + +int random_aes_xts(int iteration, unsigned int data_length) +{ + int i; + int rc = 0; + unsigned int iv_length = sizeof(ica_aes_vector_t); + unsigned int key_length = AES_KEY_LEN128 * 2; + unsigned char iv[iv_length]; + unsigned char tmp_iv[iv_length]; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + + for (i = 1; i <= 2; i++) { + unsigned char key[key_length]; + + memset(encrypt, 0x00, data_length); + memset(decrypt, 0x00, data_length); + + load_random_test_data(input_data, data_length, iv, iv_length, key, + key_length); + memcpy(tmp_iv, iv, iv_length); + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i, iv length = %i\n", + key_length, data_length, iv_length)); + rc = ica_aes_xts(input_data, encrypt, data_length, + key, key+(key_length/2), (key_length/2), + tmp_iv, 1); + if (rc) { + VV_(printf("ica_aes_xts encrypt failed with rc = %i\n", rc)); + dump_xts_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_xts_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + + if (rc) { + VV_(printf("AES XTS test exited after encryption\n")); + return rc; + } + + memcpy(tmp_iv, iv, iv_length); + + rc = ica_aes_xts(encrypt, decrypt, data_length, + key, key+(key_length/2), (key_length/2), + tmp_iv, 0); + if (rc) { + VV_(printf("ica_aes_xts decrypt failed with rc = %i\n", rc)); + dump_xts_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_xts_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + return rc; + } + key_length = AES_KEY_LEN256 * 2; + } + + return rc; +} + +int main(int argc, char **argv) +{ + int rc = 0; + int error_count = 0; + int iteration; + unsigned int data_length = sizeof(ica_aes_vector_t); + + set_verbosity(argc, argv); + + for(iteration = 1; iteration <= NR_TESTS; iteration++) { + rc = kat_aes_xts(iteration); + if (rc) { + V_(printf("kat_aes_xts failed with rc = %i\n", rc)); + error_count++; + } + + } + for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) { + rc = random_aes_xts(iteration, data_length); + if (rc) { + V_(printf("random_aes_xts failed with rc = %i\n", rc)); + error_count++; + goto out; + } + data_length += sizeof(ica_aes_vector_t) / 2; + } + +out: + if (error_count) + printf("%i AES-XTS tests failed.\n", error_count); + else + printf("All AES-XTS tests passed.\n"); + + return rc; +} + diff --git a/src/tests/libica_cbccs_test.c b/src/tests/libica_cbccs_test.c new file mode 100644 index 0000000..bd2b088 --- /dev/null +++ b/src/tests/libica_cbccs_test.c @@ -0,0 +1,548 @@ +/* This program is released under the Common Public License V1.0 +* +* You should have received a copy of Common Public License V1.0 along with +* with this program. +*/ + +/* (C) COPYRIGHT International Business Machines Corp. 2010 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <unistd.h> +#include "ica_api.h" +#include <stdlib.h> +#include <openssl/aes.h> +#include "testcase.h" + +/* CBC_CS data */ +unsigned char NIST_KEY[] = { + 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, + 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69 +}; +unsigned int key_size[6] = { 24, 24, 24, 32, 32, 32 }; +unsigned char key[6][256] = { + { + 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, + 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69, + 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20 + },{ + 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, + 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69, + 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20 + },{ + 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, + 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69, + 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20 + },{ + 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, + 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69, + 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, + 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69 + },{ + 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, + 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69, + 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, + 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69 + },{ + 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, + 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69, + 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, + 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69 + } +}; + +unsigned char key_512[] = { + 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, + 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69, + 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, + 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69, + 0x63, 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x20, + 0x74, 0x65, 0x72, 0x69, 0x79, 0x61, 0x6b, 0x69 +}; + +unsigned char NIST_IV[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +unsigned int NIST_TEST_DATA_LENGTH[6] = { 17, 31, 32, 47, 48, 64 }; +unsigned char NIST_TEST_DATA[6][100] = { + { 0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, + 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20 + },{ + 0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, + 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x20, 0x47, 0x61, 0x75, 0x27, 0x73, 0x20 + },{ + 0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, + 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x20, 0x47, 0x61, 0x75, 0x27, 0x73, 0x20, 0x43 + },{ + 0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, + 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x20, 0x47, 0x61, 0x75, 0x27, 0x73, 0x20, 0x43, + 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x2c, 0x20, + 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x2c + },{ + 0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, + 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x20, 0x47, 0x61, 0x75, 0x27, 0x73, 0x20, 0x43, + 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x2c, 0x20, + 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x2c, 0x20 + },{ + 0x49, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, + 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x20, 0x47, 0x61, 0x75, 0x27, 0x73, 0x20, 0x43, + 0x68, 0x69, 0x63, 0x6b, 0x65, 0x6e, 0x2c, 0x20, + 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x2c, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x77, 0x6f, 0x6e, 0x74, + 0x6f, 0x6e, 0x20, 0x73, 0x6f, 0x75, 0x70, 0x2e + } +}; + +unsigned char NIST_TEST_RESULT[6][100] = { + { + 0xc6, 0x35, 0x35, 0x68, 0xf2, 0xbf, 0x8c, 0xb4, + 0xd8, 0xa5, 0x80, 0x36, 0x2d, 0xa7, 0xff, 0x7f, 0x97 + },{ + 0xfc, 0x00, 0x78, 0x3e, 0x0e, 0xfd, 0xb2, 0xc1, + 0xd4, 0x45, 0xd4, 0xc8, 0xef, 0xf7, 0xed, 0x22, + 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, + 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5 + },{ + 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5, + 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8, + 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, + 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84 + },{ + 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, + 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84, + 0xb3, 0xff, 0xfd, 0x94, 0x0c, 0x16, 0xa1, 0x8c, + 0x1b, 0x55, 0x49, 0xd2, 0xf8, 0x38, 0x02, 0x9e, + 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5, + 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5 + },{ + 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, + 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84, + 0x9d, 0xad, 0x8b, 0xbb, 0x96, 0xc4, 0xcd, 0xc0, + 0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8, + 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5, + 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8 + },{ + 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, + 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84, + 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5, + 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8, + 0x48, 0x07, 0xef, 0xe8, 0x36, 0xee, 0x89, 0xa5, + 0x26, 0x73, 0x0d, 0xbc, 0x2f, 0x7b, 0xc8, 0x40, + 0x9d, 0xad, 0x8b, 0xbb, 0x96, 0xc4, 0xcd, 0xc0, + 0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8 + } +}; + +unsigned char NIST_NEXT_IV[6][16] = { + { + 0xc6, 0x35, 0x35, 0x68, 0xf2, 0xbf, 0x8c, 0xb4, + 0xd8, 0xa5, 0x80, 0x36, 0x2d, 0xa7, 0xff, 0x7f + },{ + 0xfc, 0x00, 0x78, 0x3e, 0x0e, 0xfd, 0xb2, 0xc1, + 0xd4, 0x45, 0xd4, 0xc8, 0xef, 0xf7, 0xed, 0x22 + },{ + 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5, + 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8 + },{ + 0xb3, 0xff, 0xfd, 0x94, 0x0c, 0x16, 0xa1, 0x8c, + 0x1b, 0x55, 0x49, 0xd2, 0xf8, 0x38, 0x02, 0x9e + },{ + 0x9d, 0xad, 0x8b, 0xbb, 0x96, 0xc4, 0xcd, 0xc0, + 0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8 + },{ + 0x48, 0x07, 0xef, 0xe8, 0x36, 0xee, 0x89, 0xa5, + 0x26, 0x73, 0x0d, 0xbc, 0x2f, 0x7b, 0xc8, 0x40 + } +}; + +int compare_decrypt_result_with_expected_result( + unsigned char *, unsigned char *, + unsigned int, unsigned char *, + unsigned int, unsigned char *, + unsigned int, char *, + unsigned int); + +inline int compare_decrypt_result_with_expected_result( + unsigned char * decrypt_out, + unsigned char * expected_result, + unsigned int compare_length, + unsigned char * key, + unsigned int key_length, + unsigned char * iv, + unsigned int iv_size, + char * out_text, + unsigned int test_case_number) +{ + if (memcmp(decrypt_out, expected_result, compare_length) != 0) { + VV_(printf("This does NOT match the original data.\n")); + VV_(printf("Test case number %i for %s with CBC_CS mode failed\n", + test_case_number, out_text)); + VV_(printf("\nkey \n")); + dump_array(key, key_length); + VV_(printf("\nOriginal data:\n")); + dump_array(expected_result, compare_length); + VV_(printf("\ntmp iv\n")); + dump_array(iv, iv_size); + VV_(printf("\nExpected Result:\n")); + dump_array(expected_result, compare_length); + VV_(printf("\nDecrypted data:\n")); + dump_array(decrypt_out, compare_length); + return 1; + } + return 0; +} + + +int test_3des_new_api(unsigned int mode, unsigned int variant) +{ + /* Test 3des */ + unsigned int iv_size = sizeof(ica_des_vector_t); + unsigned char iv[iv_size]; + unsigned char tmp_iv[iv_size]; + unsigned char enc_text[100] ,dec_text[100] ; + unsigned int number_of_testcases = 6; + int rc = 0, i = 0; + + for (i = 0; i < number_of_testcases ; i++) { + memcpy(tmp_iv, NIST_IV, iv_size); + rc = ica_3des_cbc_cs(NIST_TEST_DATA[i], enc_text, + NIST_TEST_DATA_LENGTH[i], key[i], + tmp_iv, 1, variant); + if (rc) { + VV_(printf("key \n")); + dump_array(key[i], 8); + VV_(printf("\nOriginal data:\n")); + dump_array(NIST_TEST_DATA[i], + NIST_TEST_DATA_LENGTH[i]); + VV_(printf("\ntest iv\n")); + dump_array(tmp_iv, iv_size); + VV_(printf("\nica_3des_cbc_cs encrypt test %i failed with " + "errno %d (0x%x).\n", i, rc, rc)); + return 1; + } + memcpy(tmp_iv, NIST_IV, iv_size); + memset(dec_text,0,NIST_TEST_DATA_LENGTH[i]); + rc = ica_3des_cbc_cs(enc_text, dec_text, + NIST_TEST_DATA_LENGTH[i], key[i], + tmp_iv, 0, variant); + if (rc) { + VV_(printf("key \n")); + dump_array(key[i], 8); + VV_(printf("\nOriginal data:\n")); + dump_array(NIST_TEST_DATA[i], + NIST_TEST_DATA_LENGTH[i]); + VV_(printf("\noriginal iv\n")); + dump_array(iv, iv_size); + VV_(printf("\ntmp iv\n")); + dump_array(tmp_iv, iv_size); + VV_(printf("\nEncrypted data:\n")); + dump_array(enc_text, NIST_TEST_DATA_LENGTH[i]); + VV_(printf("\nDecrypted data:\n")); + dump_array(dec_text, NIST_TEST_DATA_LENGTH[i]); + VV_(printf("\nica_3des_cbc_cs decrypt test %i failed with " + "errno %d (0x%x).\n", i, rc, rc)); + return 1; + } + if (compare_decrypt_result_with_expected_result(dec_text, + NIST_TEST_DATA[i], NIST_TEST_DATA_LENGTH[i], + key[i], 24, tmp_iv, iv_size, + (char *) "3DES", i)) + return 1; + else { + VV_(printf("Test case number %i for 3DES with CBC_CS mode was " + "successful!\n", i)); + } + } + return rc; +} +int test_des_new_api(unsigned int mode, unsigned int variant) +{ + /* Test des */ + unsigned int iv_size = sizeof(ica_des_vector_t); + unsigned char iv[iv_size]; + unsigned char tmp_iv[iv_size]; + unsigned char enc_text[100] ,dec_text[100] ; + unsigned int number_of_testcases = 6; + int rc = 0, i = 0; + +#ifdef ICA_FIPS + if (ica_fips_status() & ICA_FIPS_MODE) { + printf("All DES-CBC-CS tests skipped." + " (DES not FIPS approved)\n"); + return 0; + } +#endif /* ICA_FIPS */ + + for (i = 0; i < number_of_testcases ; i++) { + memcpy(tmp_iv, NIST_IV, iv_size); + rc = ica_des_cbc_cs(NIST_TEST_DATA[i], enc_text, + NIST_TEST_DATA_LENGTH[i], key[i], + tmp_iv, 1, variant); + if (rc) { + VV_(printf("key \n")); + dump_array(key[i], 8); + VV_(printf("\nOriginal data:\n")); + dump_array(NIST_TEST_DATA[i], + NIST_TEST_DATA_LENGTH[i]); + VV_(printf("\ntest iv\n")); + dump_array(tmp_iv, iv_size); + VV_(printf("\nica_des_cbc_cs encrypt test %i failed with " + "errno %d (0x%x).\n", i, rc, rc)); + return 1; + } + memcpy(tmp_iv, NIST_IV, iv_size); + memset(dec_text,0,NIST_TEST_DATA_LENGTH[i]); + rc = ica_des_cbc_cs(enc_text, dec_text, + NIST_TEST_DATA_LENGTH[i], key[i], + tmp_iv, 0, variant); + if (rc) { + VV_(printf("key \n")); + dump_array(key[i], 8); + VV_(printf("\nOriginal data:\n")); + dump_array(NIST_TEST_DATA[i], + NIST_TEST_DATA_LENGTH[i]); + VV_(printf("\noriginal iv\n")); + dump_array(iv, iv_size); + VV_(printf("\ntmp iv\n")); + dump_array(tmp_iv, iv_size); + VV_(printf("\nEncrypted data:\n")); + dump_array(enc_text, NIST_TEST_DATA_LENGTH[i]); + VV_(printf("\nDecrypted data:\n")); + dump_array(dec_text, NIST_TEST_DATA_LENGTH[i]); + VV_(printf("\nica_des_cbc_cs decrypt test %i failed with " + "errno %d (0x%x).\n", i, rc, rc)); + return 1; + } + if (compare_decrypt_result_with_expected_result( + dec_text, NIST_TEST_DATA[i], + NIST_TEST_DATA_LENGTH[i], key[i], + (sizeof(key[i]) / 8), tmp_iv, iv_size, + (char *) "DES", i)) + return 1; + else { + VV_(printf("Test case number %i for DES with CBC_CS mode was " + "successful!\n", i)); + } + } + return rc; +} +int test_aes_new_api(unsigned int mode, unsigned int variant) +{ + /* Test with 192 & 256 byte keys */ + unsigned int iv_size = sizeof(ica_aes_vector_t); + unsigned char iv[iv_size]; + unsigned char tmp_iv[iv_size]; + char text[2][8] = { + { 0x41, 0x45, 0x53, 0x2d, 0x31, 0x39, 0x32, 0x00 }, + { 0x41, 0x45, 0x53, 0x2d, 0x32, 0x35, 0x36, 0x00 }}; + unsigned char enc_text[100] ,dec_text[100] ; + unsigned int number_of_testcases = 6; + + int rc = 0, i = 0; + + for (i = 0; i < number_of_testcases ; i++) { + memcpy(tmp_iv, NIST_IV, iv_size); + rc = ica_aes_cbc_cs(NIST_TEST_DATA[i], enc_text, + NIST_TEST_DATA_LENGTH[i], key[i], + key_size[i], tmp_iv, 1, variant); + if (rc) { + VV_(printf("key \n")); + dump_array(key[i], key_size[i]); + VV_(printf("\nOriginal data:\n")); + dump_array(NIST_TEST_DATA[i], + NIST_TEST_DATA_LENGTH[i]); + VV_(printf("\ntest iv\n")); + dump_array(tmp_iv, iv_size); + VV_(printf("\nica_aes_cbc_cs encrypt test %i failed with " + " errno %d (0x%x).\n", i, rc, rc)); + return 1; + } + memcpy(tmp_iv, NIST_IV, iv_size); + memset(dec_text,0,NIST_TEST_DATA_LENGTH[i]); + rc = ica_aes_cbc_cs(enc_text, dec_text, + NIST_TEST_DATA_LENGTH[i], key[i], + key_size[i], tmp_iv, 0, variant); + if (rc) { + VV_(printf("key \n")); + dump_array(key[i], key_size[i]); + VV_(printf("\nOriginal data:\n")); + dump_array(NIST_TEST_DATA[i], + NIST_TEST_DATA_LENGTH[i]); + VV_(printf("\noriginal iv\n")); + dump_array(iv, iv_size); + VV_(printf("\ntmp iv\n")); + dump_array(tmp_iv, iv_size); + VV_(printf("\nEncrypted data:\n")); + dump_array(enc_text, NIST_TEST_DATA_LENGTH[i]); + VV_(printf("\nDecrypted data:\n")); + dump_array(dec_text, NIST_TEST_DATA_LENGTH[i]); + VV_(printf("\nica_aes_cbc_cs decrypt test %i failed with " + "errno %d (0x%x).\n", i, rc, rc)); + return 1; + } + if (compare_decrypt_result_with_expected_result(dec_text, + NIST_TEST_DATA[i], NIST_TEST_DATA_LENGTH[i], + key[i], key_size[i], tmp_iv, iv_size, + (i < 3) ? text[0] : text[1], i)) + return 1; + else { + VV_(printf("Test case number %i for %s with CBC_CS mode was " + "successful!\n", i, (i < 3) ? text[0] : text[1])); + } + } + return rc; +} + +int test_aes128_new_api(unsigned int mode) +{ + /* AES128 Known Answer Tests*/ + unsigned int iv_size = sizeof(ica_aes_vector_t); + unsigned int key_size = AES_KEY_LEN128; + unsigned char iv[iv_size]; + unsigned char tmp_iv[iv_size]; + unsigned char key[key_size]; + unsigned char enc_text[100] ,dec_text[100] ; + unsigned int number_of_testcases = 6; + int rc = 0, i = 0; + + memcpy(key, NIST_KEY, sizeof(key)); + for (i = 0; i < number_of_testcases ; i++) { + memcpy(tmp_iv, NIST_IV, iv_size); + rc = ica_aes_cbc_cs(NIST_TEST_DATA[i], enc_text, + NIST_TEST_DATA_LENGTH[i], key, + sizeof(key), tmp_iv, 1, ICA_CBCCS_VARIANT3); + if (rc) { + VV_(printf("key \n")); + dump_array(key, sizeof(key)); + VV_(printf("\nOriginal data:\n")); + dump_array(NIST_TEST_DATA[i], + NIST_TEST_DATA_LENGTH[i]); + VV_(printf("\ntest iv\n")); + dump_array(tmp_iv, iv_size); + VV_(printf("\nica_aes_cbc_cs encrypt test %i failed with " + "errno %d (0x%x).\n", i, rc, rc)); + return 1; + } + + if (compare_decrypt_result_with_expected_result(enc_text, + NIST_TEST_RESULT[i], NIST_TEST_DATA_LENGTH[i], + key, sizeof(key), tmp_iv, iv_size, + (char *) "AES-128", i)) + return 1; + + if (compare_decrypt_result_with_expected_result(tmp_iv, + NIST_NEXT_IV[i], iv_size, + key, sizeof(key), tmp_iv, iv_size, + (char *) "AES-128", i)) + return 1; + + memcpy(tmp_iv, NIST_IV, iv_size); + memset(dec_text,0,NIST_TEST_DATA_LENGTH[i]); + rc = ica_aes_cbc_cs(enc_text, dec_text, + NIST_TEST_DATA_LENGTH[i], key, sizeof(key), + tmp_iv, 0, ICA_CBCCS_VARIANT3); + if (rc) { + VV_(printf("key \n")); + dump_array(key, sizeof(key)); + VV_(printf("\nOriginal data:\n")); + dump_array(NIST_TEST_DATA[i], + NIST_TEST_DATA_LENGTH[i]); + VV_(printf("\noriginal iv\n")); + dump_array(iv, iv_size); + VV_(printf("\ntmp iv\n")); + dump_array(tmp_iv, iv_size); + VV_(printf("\nkey\n")); + dump_array(key, sizeof(key)); + VV_(printf("\nEncrypted data:\n")); + dump_array(enc_text, NIST_TEST_DATA_LENGTH[i]); + VV_(printf("\nDecrypted data:\n")); + dump_array(dec_text, NIST_TEST_DATA_LENGTH[i]); + VV_(printf("\nica_aes_cbc_cs decrypt test %i failed" + "with errno %d (0x%x).\n", i, rc, rc)); + return 1; + } + + if (compare_decrypt_result_with_expected_result(dec_text, + NIST_TEST_DATA[i], NIST_TEST_DATA_LENGTH[i], + key, sizeof(key), tmp_iv, iv_size, + (char *) "AES-128", i)) + return 1; + else { + VV_(printf("Test case number %i for AES-128 with CBC_CS " + "mode was successful!\n", i)); + } + } + return rc; +} + +int main(int argc, char **argv) +{ + unsigned int mode; + unsigned int variant; + int rc, error_count; + + set_verbosity(argc, argv); + + mode = MODE_CBCCS; + rc = 0; + error_count = 0; + + /* known answer tests for AES128 */ + rc = test_aes128_new_api(mode); + if (rc) { + error_count++; + printf("test_aes128_new_api for CBC_CS mode with AES-128 " + "failed.\n"); + return rc; + } + + for (variant = ICA_CBCCS_VARIANT1; + variant <= ICA_CBCCS_VARIANT3; + variant++) { + VV_(printf("\n--- Test cycle with CBCCS variant %d ---\n", variant)); + /* AES 192 & 256 test */ + rc = test_aes_new_api(mode, variant); + if (rc) { + error_count++; + printf("test_aes_new_api for CBC_CS mode with AES (192|256) " + "failed.\n"); + return rc; + } + + /* DES tests */ + rc = test_des_new_api(mode, variant); + if (rc) { + error_count++; + printf("test_des_new_api for CBC_CS mode with DES " + "failed.\n"); + return rc; + } + + /* 3DES tests */ + rc = test_3des_new_api(mode, variant); + if (rc) { + error_count++; + printf("test_des_new_api for CBC_CS mode with 3DES " + "failed.\n"); + return rc; + } + } + + printf("All CBC-CS tests passed.\n"); + return rc; +} + diff --git a/src/tests/libica_ccm_test.c b/src/tests/libica_ccm_test.c new file mode 100644 index 0000000..c1e2b93 --- /dev/null +++ b/src/tests/libica_ccm_test.c @@ -0,0 +1,179 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* (C) COPYRIGHT International Business Machines Corp. 2011 */ + +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "ica_api.h" +#include "testcase.h" + +#define BYTE 8 + +#define NUM_CCM_TESTS 4 +unsigned char input_data[1000000]; +unsigned char parameter_block[32]; +unsigned char *to = parameter_block; + +unsigned int key_length[4] = {16, 16, 16, 16}; +unsigned char key[4][16] = { +{0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f }, +{0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f }, +{0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f }, +{0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f }}; + +#define CASE3_ASSOC_LEN 256 +/* Number of bytes in string for case 3 */ + +unsigned int assoc_data_length[4] = {8, 16, 20, 65536}; +unsigned char assoc_data[4][65536] = { +{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 }, +{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f }, +{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x10,0x11,0x12,0x13 }}; +unsigned int i = 0; +unsigned char repeated_string[256] = { +0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, +0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, +0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, +0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, +0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, +0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, +0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, +0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f, +0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f, +0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, +0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf, +0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf, +0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf, +0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf, +0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef, +0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff}; +unsigned int payload_length[4] = {4, 16, 24, 32}; +unsigned char payload[4][32] = { +{ 0x20,0x21,0x22,0x23 }, +{ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, +{ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37 }, +{ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f , + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f }}; + +unsigned char payload_after_decrypt[4][32] = { +{ 0x20,0x21,0x22,0x23 }, +{ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, +{ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37 }, +{ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f , + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f }}; +unsigned int nonce_length[4] = {7,8,12,13}; +unsigned char nonce[4][13] = { +{ 0x10,0x11,0x12,0x13,0x14,0x15,0x16}, +{ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17}, +{ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b}, +{ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c}}; + +unsigned int cbc_mac_length[4] = {4, 6, 8, 14}; + +unsigned int cipher_text_length[4] = {8, 22, 32, 46}; +unsigned char cipher_text[4][46] = { +{ 0x71,0x62,0x01,0x5b,0x4d,0xac,0x25,0x5d }, +{ 0xd2,0xa1,0xf0,0xe0,0x51,0xea,0x5f,0x62,0x08,0x1a,0x77,0x92,0x07,0x3d,0x59,0x3d, + 0x1f,0xc6,0x4f,0xbf,0xac,0xcd }, +{ 0xe3,0xb2,0x01,0xa9,0xf5,0xb7,0x1a,0x7a,0x9b,0x1c,0xea,0xec,0xcd,0x97,0xe7,0x0b, + 0x61,0x76,0xaa,0xd9,0xa4,0x42,0x8a,0xa5,0x48,0x43,0x92,0xfb,0xc1,0xb0,0x99,0x51}, +{0x69,0x91,0x5d,0xad,0x1e,0x84,0xc6,0x37,0x6a,0x68,0xc2,0x96,0x7e,0x4d,0xab,0x61, + 0x5a,0xe0,0xfd,0x1f,0xae,0xc4,0x4c,0xc4,0x84,0x82,0x85,0x29,0x46,0x3c,0xcf,0x72, + 0xb4,0xac,0x6b,0xec,0x93,0xe8,0x59,0x8e,0x7f,0x0d,0xad,0xbc,0xea,0x5b} +}; + +int api_ccm_test(void) +{ + unsigned char *out_data; + int rc = 0; + + VV_(printf("Test of CCM api\n")); + while ( i < 65536 ) { // init big assoc_data + memcpy(assoc_data[3] + i, repeated_string, 256); + i= i + 256; + } + for (i = 0; i < NUM_CCM_TESTS; i++) { + VV_(printf("\nOriginal data for test %d:\n", i)); + if (!(out_data = malloc(cipher_text_length[i]))) + return EINVAL; + memset(out_data, 0, cipher_text_length[i]); + rc = (ica_aes_ccm(payload[i], payload_length[i], + out_data, + cbc_mac_length[i], + assoc_data[i], assoc_data_length[i], + nonce[i], nonce_length[i], + key[i], key_length[i], + ICA_ENCRYPT)); + if (rc) { + VV_(printf("icaccm encrypt failed with errno %d (0x%x).\n", + rc, rc)); + return rc; + } + VV_(printf("\nOutput Cipher text for test %d:\n", i)); + dump_array(out_data, cipher_text_length[i]); + VV_(printf("\nExpected Cipher Text for test %d:\n", i)); + dump_array(cipher_text[i], cipher_text_length[i]); + + if (memcmp(cipher_text[i], out_data, cipher_text_length[i]) != 0) { + printf("This does NOT match the known result.\n"); + return 1; + } + + VV_(printf("Yep, that's how it should be encrypted.\n")); + // start decrypt / verify + memset(payload[i], 0, payload_length[i]); + rc = (ica_aes_ccm(out_data, payload_length[i], + cipher_text[i], cbc_mac_length[i], + assoc_data[i], assoc_data_length[i], + nonce[i], nonce_length[i], + key[i], key_length[i], + ICA_DECRYPT)); + if (rc) { + VV_(printf("icaccm decrypt failed with errno %d (0x%x).\n", + rc,rc)); + return rc; + } + + VV_(printf("\nOutput payload for test %d:\n", i)); + dump_array(out_data, payload_length[i]); + VV_(printf("\nExpected payload for test %d:\n", i)); + dump_array(payload_after_decrypt[i], payload_length[i]); + + if (memcmp(out_data, payload_after_decrypt[i], + payload_length[i]) == 0 ) { + VV_(printf("Yep, payload matches to original.\n")); + } else { + VV_(printf("This does NOT match the known result.\n")); + return 1; + } + free(out_data); + } + return 0; +} + +int main(int argc, char **argv) +{ + int rc = 0; + + set_verbosity(argc, argv); + + rc = api_ccm_test(); + if (rc) { + printf("api_ccm_test failed with rc = %i.\n", rc); + return rc; + } + printf("All AES-CCM tests passed.\n"); + return 0; +} + + diff --git a/src/tests/libica_cmac_test.c b/src/tests/libica_cmac_test.c new file mode 100644 index 0000000..b8e5eb5 --- /dev/null +++ b/src/tests/libica_cmac_test.c @@ -0,0 +1,307 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2010, 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "ica_api.h" +#include "testcase.h" + +#define BYTE 8 + +#define NUM_TESTS 12 + +#define AES_BLOCK_SIZE 16 + +unsigned int key_length[12] = {16, 16, 16, 16, 24, 24, 24, 24, 32, 32, 32, + 32}; +unsigned char key[12][32] = {{ + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, + 0x88, 0x09, 0xcf, 0x4f, 0x3c},{ + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, + 0x88, 0x09, 0xcf, 0x4f, 0x3c},{ + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, + 0x88, 0x09, 0xcf, 0x4f, 0x3c},{ + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, + 0x88, 0x09, 0xcf, 0x4f, 0x3c},{ + 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10 ,0xf3, + 0x2b, 0x80, 0x90, 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, + 0x6b, 0x7b},{ + 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10 ,0xf3, + 0x2b, 0x80, 0x90, 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, + 0x6b, 0x7b},{ + 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10 ,0xf3, + 0x2b, 0x80, 0x90, 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, + 0x6b, 0x7b},{ + 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10 ,0xf3, + 0x2b, 0x80, 0x90, 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, + 0x6b, 0x7b},{ + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, + 0xf0, 0x85, 0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, + 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4},{ + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, + 0xf0, 0x85, 0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, + 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4},{ + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, + 0xf0, 0x85, 0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, + 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4},{ + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, + 0xf0, 0x85, 0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, + 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4} +}; + +unsigned char last_block[3][16] = {{ + 0x7d, 0xf7, 0x6b, 0x0c, 0x1a, 0xb8, 0x99, 0xb3, 0x3e, 0x42, 0xf0, + 0x47, 0xb9, 0x1b, 0x54, 0x6f},{ + 0x22, 0x45, 0x2d, 0x8e, 0x49, 0xa8, 0xa5, 0x93, 0x9f, 0x73, 0x21, + 0xce, 0xea, 0x6d, 0x51, 0x4b},{ + 0xe5, 0x68, 0xf6, 0x81, 0x94, 0xcf, 0x76, 0xd6, 0x17, 0x4d, 0x4c, + 0xc0, 0x43, 0x10, 0xa8, 0x54} +}; + +unsigned long mlen[12] = { 0, 16, 40, 64, 0,16, 40, 64, 0, 16, 40, 64}; +unsigned char message[12][512] = {{ + 0x00},{ + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, + 0x11, 0x73, 0x93, 0x17, 0x2a},{ + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, + 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, + 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf ,0x8e, 0x51, 0x30, + 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11},{ + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, + 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, + 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 0x30, + 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, + 0x1a, 0x0a, 0x52, 0xef, 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, + 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10},{ + 0x00},{ + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, + 0x11, 0x73, 0x93, 0x17, 0x2a},{ + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, + 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, + 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf ,0x8e, 0x51, 0x30, + 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11},{ + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, + 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, + 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 0x30, + 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, + 0x1a, 0x0a, 0x52, 0xef, 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, + 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10},{ + 0x00},{ + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, + 0x11, 0x73, 0x93, 0x17, 0x2a},{ + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, + 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, + 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf ,0x8e, 0x51, 0x30, + 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11},{ + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, + 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, + 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 0x30, + 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, + 0x1a, 0x0a, 0x52, 0xef, 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, + 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10} +}; + +unsigned char expected_cmac[12][16] = {{ + 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28, 0x7f, 0xa3, 0x7d, + 0x12, 0x9b, 0x75, 0x67, 0x46},{ + 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, 0xf7, 0x9b, 0xdd, + 0x9d, 0xd0, 0x4a, 0x28, 0x7c},{ + 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30, 0x30, 0xca, 0x32, + 0x61, 0x14, 0x97, 0xc8, 0x27},{ + 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, 0xfc, 0x49, 0x74, + 0x17, 0x79, 0x36, 0x3c, 0xfe},{ + 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5, 0x31, 0xca, 0xc4, + 0x83, 0xde, 0x7a, 0x93, 0x67},{ + 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90, 0x06, 0x62, 0xf6, + 0x5e, 0x61, 0x7c, 0x51, 0x84},{ + 0x8a, 0x1d, 0xe5, 0xbe, 0x2e, 0xb3, 0x1a, 0xad, 0x08, 0x9a, 0x82, + 0xe6, 0xee, 0x90, 0x8b, 0x0e},{ + 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79, 0x4d, 0x77, 0x58, + 0x96, 0x59, 0xf3, 0x9a, 0x11},{ + 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e, 0xfc, 0x6b, 0x55, + 0x1f, 0x46, 0x67, 0xd9, 0x83},{ + 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82, 0xbd, 0x4b, 0xf2, + 0x8d, 0x8c, 0x37, 0xc3, 0x5c},{ + 0xaa, 0xf3, 0xd8, 0xf1, 0xde, 0x56, 0x40, 0xc2, 0x32, 0xf5, 0xb1, + 0x69, 0xb9, 0xc9, 0x11, 0xe6},{ + 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5, 0x69, 0x6a, 0x2c, + 0x05, 0x6c, 0x31, 0x54, 0x10} +}; + +unsigned int ica_aes_cmac_chaining(unsigned char *, unsigned long, + unsigned char *, unsigned int, + unsigned char *, unsigned int, + unsigned int); + +unsigned int i = 0; + +unsigned char *cmac; +unsigned int cmac_length = 16; + +int api_cmac_test(void) +{ + int rc = 0; + + VV_(printf("Test of CMAC api\n")); + for (i = 0 ; i < NUM_TESTS; i++) { + if (!(cmac = malloc(cmac_length))) + return EINVAL; + memset(cmac, 0, cmac_length); + rc = (ica_aes_cmac(message[i], mlen[i], + cmac, cmac_length, + key[i], key_length[i], + ICA_ENCRYPT)); + if (rc) { + VV_(printf("ica_aes_cmac generate failed with errno %d (0x%x)." + "\n",rc,rc)); + return rc; + } + if (memcmp(cmac, expected_cmac[i], cmac_length) != 0) { + VV_(printf("This does NOT match the known result. " + "Testcase %i failed\n",i)); + VV_(printf("\nOutput MAC for test %d:\n", i)); + dump_array((unsigned char *)cmac, cmac_length); + VV_(printf("\nExpected MAC for test %d:\n", i)); + dump_array((unsigned char *)expected_cmac[i], 16); + free(cmac); + return 1; + } + VV_(printf("Expected MAC has been generated.\n")); + rc = (ica_aes_cmac(message[i], mlen[i], + cmac, cmac_length, + key[i], key_length[i], + ICA_DECRYPT)); + if (rc) { + VV_(printf("ica_aes_cmac verify failed with errno %d (0x%x).\n", + rc, rc)); + free(cmac); + return rc; + } + free(cmac); + if (!rc) { + VV_(printf("MAC was successful verified. Test %i " + "succeeded\n",i)); + } + else { + printf("MAC verification failed for test %i " + "with RC=%i\n",i,rc); + return rc; + } + } + return 0; +} + + +inline unsigned int ica_aes_cmac_chaining(unsigned char *in, + unsigned long in_length, + unsigned char *cmac, + unsigned int cmac_length, + unsigned char *key, + unsigned int key_length, + unsigned int direction) +{ + unsigned char *last_block = NULL; + unsigned long tmp_length; + unsigned char tmp_iv[AES_BLOCK_SIZE]; + unsigned int rc; + + memset(tmp_iv, 0x00, AES_BLOCK_SIZE); + + for (last_block = in, tmp_length = in_length; + tmp_length > (AES_BLOCK_SIZE); + last_block += AES_BLOCK_SIZE, tmp_length -= AES_BLOCK_SIZE) { + rc = ica_aes_cmac_intermediate(last_block, AES_BLOCK_SIZE, + key, key_length, + tmp_iv); + if (rc) + return rc; + } + + return ica_aes_cmac_last(last_block, tmp_length, + cmac, cmac_length, + key, key_length, + tmp_iv, + direction); +} + +int api_cmac_chaining_test(void) +{ + int rc = 0; + + VV_(printf("Test of CMAC chaining api\n")); + for (i = 0 ; i < NUM_TESTS; i++) { + if (!(cmac = malloc(cmac_length))) + return EINVAL; + memset(cmac, 0, cmac_length); + rc = ica_aes_cmac_chaining(message[i], mlen[i], + cmac, cmac_length, + key[i], key_length[i], + ICA_ENCRYPT); + if (rc) { + VV_(printf("ica_aes_cmac chaining generate failed with errno %d (0x%x)." + "\n",rc,rc)); + return rc; + } + if (memcmp(cmac, expected_cmac[i], cmac_length) != 0) { + VV_(printf("This does NOT match the known result. " + "Testcase %i failed\n",i)); + VV_(printf("\nOutput MAC for test %d:\n", i)); + dump_array((unsigned char *)cmac, cmac_length); + VV_(printf("\nExpected MAC for test %d:\n", i)); + dump_array((unsigned char *)expected_cmac[i], 16); + free(cmac); + return 1; + } + VV_(printf("Expected MAC has been generated.\n")); + rc = ica_aes_cmac_chaining(message[i], mlen[i], + cmac, cmac_length, + key[i], key_length[i], + ICA_DECRYPT); + if (rc) { + VV_(printf("ica_aes_cmac verify failed with errno %d (0x%x).\n", + rc, rc)); + free(cmac); + return rc; + } + free(cmac); + if (!rc) { + VV_(printf("MAC was successful verified. Test %i " + "succeeded\n",i)); + } + else { + VV_(printf("MAC verification failed for test %i " + "with RC=%i\n",i,rc)); + return rc; + } + } + return 0; +} + +int main(int argc, char **argv) +{ + int rc = 0; + + set_verbosity(argc, argv); + + rc = api_cmac_test(); + if (rc) { + printf("api_cmac_test failed with rc = %i\n", rc); + return rc; + } + + rc = api_cmac_chaining_test(); + if (rc) { + printf("api_cmac_test failed with rc = %i\n", rc); + return rc; + } + + printf("All CMAC tests passed.\n"); + return 0; +} diff --git a/src/tests/libica_des_cbc_test.c b/src/tests/libica_des_cbc_test.c new file mode 100644 index 0000000..70d2ff7 --- /dev/null +++ b/src/tests/libica_des_cbc_test.c @@ -0,0 +1,320 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2010, 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include "ica_api.h" +#include "testcase.h" + +#define NR_TESTS 1 +#define NR_RANDOM_TESTS 10000 + +/* CBC data - 1 for DES128 */ +unsigned char NIST_KEY_CBC_E1[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +}; + +unsigned char NIST_IV_CBC_E1[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +unsigned char NIST_EXPECTED_IV_CBC_E1[] = { + 0x95, 0xf8, 0xa5, 0xe5, 0xdd, 0x31, 0xd9, 0x00, +}; + +unsigned char NIST_TEST_DATA_CBC_E1[] = { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +unsigned char NIST_TEST_RESULT_CBC_E1[] = { + 0x95, 0xf8, 0xa5, 0xe5, 0xdd, 0x31, 0xd9, 0x00, +}; + +void dump_cbc_data(unsigned char *iv, unsigned int iv_length, + unsigned char *key, unsigned int key_length, + unsigned char *input_data, unsigned int data_length, + unsigned char *output_data) +{ + VV_(printf("IV \n")); + dump_array(iv, iv_length); + VV_(printf("Key \n")); + dump_array(key, key_length); + VV_(printf("Input Data\n")); + dump_array(input_data, data_length); + VV_(printf("Output Data\n")); + dump_array(output_data, data_length); +} + +void get_sizes(unsigned int *data_length, unsigned int *iv_length, + unsigned int *key_length, unsigned int iteration) +{ + switch (iteration) { + case 1: + *data_length = sizeof(NIST_TEST_DATA_CBC_E1); + *iv_length = sizeof(NIST_IV_CBC_E1); + *key_length = sizeof(NIST_KEY_CBC_E1); + break; + } + +} + +void load_test_data(unsigned char *data, unsigned int data_length, + unsigned char *result, + unsigned char *iv, unsigned char *expected_iv, + unsigned int iv_length, + unsigned char *key, unsigned int key_length, + unsigned int iteration) +{ + switch (iteration) { + case 1: + memcpy(data, NIST_TEST_DATA_CBC_E1, data_length); + memcpy(result, NIST_TEST_RESULT_CBC_E1, data_length); + memcpy(iv, NIST_IV_CBC_E1, iv_length); + memcpy(expected_iv, NIST_EXPECTED_IV_CBC_E1, iv_length); + memcpy(key, NIST_KEY_CBC_E1, key_length); + break; + } + +} + +int kat_des_cbc(int iteration) +{ + unsigned int data_length; + unsigned int iv_length; + unsigned int key_length; + + get_sizes(&data_length, &iv_length, &key_length, iteration); + + unsigned char iv[iv_length]; + unsigned char tmp_iv[iv_length]; + unsigned char expected_iv[iv_length]; + unsigned char key[key_length]; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + unsigned char result[data_length]; + + int rc = 0; + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i, iv length = %i\n", + key_length, data_length, iv_length)); + + load_test_data(input_data, data_length, result, iv, expected_iv, + iv_length, key, key_length, iteration); + memcpy(tmp_iv, iv, iv_length); + + rc = ica_des_cbc(input_data, encrypt, data_length, key, tmp_iv, 1); + if (rc) { + VV_(printf("ica_des_cbc encrypt failed with rc = %i\n", rc)); + dump_cbc_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_cbc_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + + if (memcmp(result, encrypt, data_length)) { + VV_(printf("Encryption Result does not match the known ciphertext!\n")); + VV_(printf("Expected data:\n")); + dump_array(result, data_length); + VV_(printf("Encryption Result:\n")); + dump_array(encrypt, data_length); + rc++; + } + + if (memcmp(expected_iv, tmp_iv, iv_length)) { + VV_(printf("Update of IV does not match the expected IV!\n")); + VV_(printf("Expected IV:\n")); + dump_array(expected_iv, iv_length); + VV_(printf("Updated IV:\n")); + dump_array(tmp_iv, iv_length); + VV_(printf("Original IV:\n")); + dump_array(iv, iv_length); + rc++; + } + if (rc) { + VV_(printf("DES CBC test exited after encryption\n")); + return rc; + } + + memcpy(tmp_iv, iv, iv_length); + rc = ica_des_cbc(encrypt, decrypt, data_length, key, tmp_iv, 0); + if (rc) { + VV_(printf("ica_des_cbc decrypt failed with rc = %i\n", rc)); + dump_cbc_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_cbc_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + } + return rc; +} + +int load_random_test_data(unsigned char *data, unsigned int data_length, + unsigned char *iv, unsigned int iv_length, + unsigned char *key, unsigned int key_length) +{ + int rc; + + rc = ica_random_number_generate(data_length, data); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + rc = ica_random_number_generate(iv_length, iv); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + rc = ica_random_number_generate(key_length, key); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + return rc; +} + +int random_des_cbc(int iteration, unsigned int data_length) +{ + unsigned int iv_length = sizeof(ica_des_vector_t); + unsigned int key_length = sizeof(ica_des_key_single_t); + + unsigned char iv[iv_length]; + unsigned char tmp_iv[iv_length]; + unsigned char key[key_length]; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + + int rc = 0; + memset(encrypt, 0x00, data_length); + memset(decrypt, 0x00, data_length); + + load_random_test_data(input_data, data_length, iv, iv_length, key, + key_length); + memcpy(tmp_iv, iv, iv_length); + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i, iv length = %i\n", + key_length, data_length, iv_length)); + + rc = ica_des_cbc(input_data, encrypt, data_length, key, tmp_iv, 1); + if (rc) { + VV_(printf("ica_des_cbc encrypt failed with rc = %i\n", rc)); + dump_cbc_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_cbc_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + + if (rc) { + VV_(printf("DES CBC test exited after encryption\n")); + return rc; + } + + memcpy(tmp_iv, iv, iv_length); + + rc = ica_des_cbc(encrypt, decrypt, data_length, key, tmp_iv, 0); + if (rc) { + VV_(printf("ica_des_cbc decrypt failed with rc = %i\n", rc)); + dump_cbc_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_cbc_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + } + return rc; +} + +/* + * Performs CBC tests. + */ +int main(int argc, char **argv) +{ + int rc = 0; + int error_count = 0; + int iteration; + unsigned int data_length = sizeof(ica_des_vector_t); + + set_verbosity(argc, argv); + +#ifdef ICA_FIPS + if (ica_fips_status() & ICA_FIPS_MODE) { + printf("All DES-CBC tests skipped." + " (DES not FIPS approved)\n"); + return 0; + } +#endif /* ICA_FIPS */ + + for(iteration = 1; iteration <= NR_TESTS; iteration++) { + rc = kat_des_cbc(iteration); + if (rc) { + V_(printf("kat_des_cbc failed with rc = %i\n", rc)); + error_count++; + } + + } + + for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) { + rc = random_des_cbc(iteration, data_length); + if (rc) { + V_(printf("random_des_cbc failed with rc = %i\n", rc)); + error_count++; + goto out; + } + data_length += sizeof(ica_des_vector_t); + } +out: + if (error_count) + printf("%i DES-CBC tests failed.\n", error_count); + else + printf("All DES-CBC tests passed.\n"); + + return rc; +} + diff --git a/src/tests/libica_des_cfb_test.c b/src/tests/libica_des_cfb_test.c new file mode 100644 index 0000000..20291bd --- /dev/null +++ b/src/tests/libica_des_cfb_test.c @@ -0,0 +1,187 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2010, 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include "ica_api.h" +#include "testcase.h" + +#define NR_TESTS 12 +#define NR_RANDOM_TESTS 1000 + +void dump_cfb_data(unsigned char *iv, unsigned int iv_length, + unsigned char *key, unsigned int key_length, + unsigned char *input_data, unsigned int data_length, + unsigned char *output_data) +{ + VV_(printf("IV \n")); + dump_array(iv, iv_length); + VV_(printf("Key \n")); + dump_array(key, key_length); + VV_(printf("Input Data\n")); + dump_array(input_data, data_length); + VV_(printf("Output Data\n")); + dump_array(output_data, data_length); +} + +int load_random_test_data(unsigned char *data, unsigned int data_length, + unsigned char *iv, unsigned int iv_length, + unsigned char *key, unsigned int key_length) +{ + int rc; + + rc = ica_random_number_generate(data_length, data); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + rc = ica_random_number_generate(iv_length, iv); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + rc = ica_random_number_generate(key_length, key); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + return rc; +} + +int random_des_cfb(int iteration, unsigned int data_length, + unsigned int lcfb) +{ + unsigned int iv_length = sizeof(ica_des_vector_t); + unsigned int key_length = sizeof(ica_des_key_single_t); + + unsigned char iv[iv_length]; + unsigned char tmp_iv[iv_length]; + unsigned char key[key_length]; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + + int rc = 0; + memset(encrypt, 0x00, data_length); + memset(decrypt, 0x00, data_length); + + load_random_test_data(input_data, data_length, iv, iv_length, key, + key_length); + memcpy(tmp_iv, iv, iv_length); + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i, iv length = %i," + " lcfb = %i\n", key_length, data_length, iv_length, lcfb)); + + rc = ica_des_cfb(input_data, encrypt, data_length, key, tmp_iv, + lcfb, 1); + if (rc) { + VV_(printf("ica_des_cfb encrypt failed with rc = %i\n", rc)); + dump_cfb_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_cfb_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + + if (rc) { + VV_(printf("DES OFB test exited after encryption\n")); + return rc; + } + + memcpy(tmp_iv, iv, iv_length); + + rc = ica_des_cfb(encrypt, decrypt, data_length, key, tmp_iv, + lcfb, 0); + if (rc) { + VV_(printf("ica_des_cfb decrypt failed with rc = %i\n", rc)); + dump_cfb_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_cfb_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + } + return rc; +} + +int main(int argc, char **argv) +{ + int rc = 0; + int error_count = 0; + int iteration; + unsigned int rdata; + unsigned int data_length = 1; + unsigned int lcfb = 1; + unsigned int j; + + set_verbosity(argc, argv); + +#ifdef ICA_FIPS + if (ica_fips_status() & ICA_FIPS_MODE) { + printf("All DES-CFB tests skipped." + " (DES not FIPS approved)\n"); + return 0; + } +#endif /* ICA_FIPS */ + + for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) { + for (j = 1; j <= 2; j++) { + if (!(data_length % lcfb)) { + rc = random_des_cfb(iteration, data_length, lcfb); + if (rc) { + V_(printf("random_des_cfb failed with rc = %i\n", rc)); + error_count++; + } + } + switch (j) { + case 1: + lcfb = 1; + break; + case 2: + lcfb = 8; + break; + } + } + // add a value between 1 and 8 to data_length + if (ica_random_number_generate(sizeof(rdata), (unsigned char*) &rdata)) { + printf("ica_random_number_generate failed with errnor = %i\n", + errno); + exit(1); + } + data_length += (rdata % 8) + 1; + } + if (error_count) + printf("%i DES-CFB tests failed.\n", error_count); + else + printf("All DES-CFB tests passed.\n"); + + return rc; +} + diff --git a/src/tests/libica_des_ctr_test.c b/src/tests/libica_des_ctr_test.c new file mode 100644 index 0000000..b04cf4e --- /dev/null +++ b/src/tests/libica_des_ctr_test.c @@ -0,0 +1,182 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2010, 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include "ica_api.h" +#include "testcase.h" + +#define NR_RANDOM_TESTS 1000 + +void dump_ctr_data(unsigned char *iv, unsigned int iv_length, + unsigned char *key, unsigned int key_length, + unsigned char *input_data, unsigned int data_length, + unsigned char *output_data) +{ + VV_(printf("IV \n")); + dump_array(iv, iv_length); + VV_(printf("Key \n")); + dump_array(key, key_length); + VV_(printf("Input Data\n")); + dump_array(input_data, data_length); + VV_(printf("Output Data\n")); + dump_array(output_data, data_length); +} + +int random_des_ctr(int iteration, unsigned int data_length, unsigned int iv_length) +{ + unsigned int key_length = sizeof(ica_des_key_single_t); + + if (data_length % sizeof(ica_des_vector_t)) + iv_length = sizeof(ica_des_vector_t); + + unsigned char iv[iv_length]; + unsigned char tmp_iv[iv_length]; + unsigned char key[key_length]; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + + int rc = 0; + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i, iv length = %i\n", + key_length, data_length, iv_length)); + + rc = ica_random_number_generate(data_length, input_data); + if (rc) { + VV_(printf("random number generate returned rc = %i, errno = %i\n", rc, errno)); + return rc; + } + rc = ica_random_number_generate(iv_length, iv); + if (rc) { + VV_(printf("random number generate returned rc = %i, errno = %i\n", rc, errno)); + return rc; + } + + rc = ica_random_number_generate(key_length, key); + if (rc) { + VV_(printf("random number generate returned rc = %i, errno = %i\n", rc, errno)); + return rc; + } + memcpy(tmp_iv, iv, iv_length); + + rc = ica_des_ctr(input_data, encrypt, data_length, key, tmp_iv, + 32,1); + if (rc) { + VV_(printf("ica_des_ctr encrypt failed with rc = %i\n", rc)); + dump_ctr_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + return rc; + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_ctr_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + + memcpy(tmp_iv, iv, iv_length); + rc = ica_des_ctr(encrypt, decrypt, data_length, key, tmp_iv, + 32, 0); + if (rc) { + VV_(printf("ica_des_ctr decrypt failed with rc = %i\n", rc)); + dump_ctr_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_ctr_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + } + return rc; +} + +int main(int argc, char **argv) +{ + int rc = 0; + int error_count = 0; + int i = 0; + unsigned int endless = 0; + unsigned int rdata; + unsigned int data_length = 1; + unsigned int iv_length = sizeof(ica_des_key_single_t); + +#ifdef ICA_FIPS + if (ica_fips_status() & ICA_FIPS_MODE) { + printf("All DES-CTR tests skipped." + " (DES not FIPS approved)\n"); + return 0; + } +#endif /* ICA_FIPS */ + + if (argc > 1) { + if (strstr(argv[1], "endless")) + endless = 1; + } + + set_verbosity(argc, argv); + + if (endless) { + while (1) { + VV_(printf("i = %i\n", i)); + rc = random_des_ctr(i, 320, 320); + if (rc) { + V_(printf("kat_des_ctr failed with rc = %i\n", rc)); + return rc; + } + i++; + } + } else { + for (i = 1; i < NR_RANDOM_TESTS; i++) { + rc = random_des_ctr(i, data_length, iv_length); + if (rc) { + V_(printf("random_des_ctr failed with rc = %i\n", rc)); + error_count++; + } + if (!(data_length % sizeof(ica_des_key_single_t))) { + /* Always when the full block size is reached use a + * counter with the same size as the data */ + rc = random_des_ctr(i, data_length, data_length); + if (rc) { + V_(printf("random_des_ctr failed with rc = %i\n", rc)); + error_count++; + } + } + // add a value between 1 and 8 to data_length + if (ica_random_number_generate(sizeof(rdata), (unsigned char*) &rdata)) { + printf("ica_random_number_generate failed with errnor = %i\n", + errno); + exit(1); + } + data_length += (rdata % 8) + 1; + } + } + + if (error_count) + printf("%i DES-CTR tests failed.\n", error_count); + else + printf("All DES-CTR tests passed.\n"); + + return rc; +} + diff --git a/src/tests/libica_des_ecb_test.c b/src/tests/libica_des_ecb_test.c new file mode 100644 index 0000000..6401f66 --- /dev/null +++ b/src/tests/libica_des_ecb_test.c @@ -0,0 +1,151 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2010, 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include "ica_api.h" +#include "testcase.h" + +#define NR_RANDOM_TESTS 10000 + +void dump_ecb_data(unsigned char *key, unsigned int key_length, + unsigned char *input_data, unsigned int data_length, + unsigned char *output_data) +{ + VV_(printf("Key \n")); + dump_array(key, key_length); + VV_(printf("Input Data\n")); + dump_array(input_data, data_length); + VV_(printf("Output Data\n")); + dump_array(output_data, data_length); +} + +int load_random_test_data(unsigned char *data, unsigned int data_length, + unsigned char *key, unsigned int key_length) +{ + int rc; + + rc = ica_random_number_generate(data_length, data); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + rc = ica_random_number_generate(key_length, key); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + return rc; +} + +int random_des_ecb(int iteration, unsigned int data_length) +{ + int rc = 0; + unsigned int key_length = sizeof(ica_des_key_triple_t); + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + unsigned char key[key_length]; + + memset(encrypt, 0x00, data_length); + memset(decrypt, 0x00, data_length); + + load_random_test_data(input_data, data_length, key, key_length); + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i\n", key_length, data_length)); + + rc = ica_des_ecb(input_data, encrypt, data_length, key, 1); + if (rc) { + VV_(printf("ica_des_ecb encrypt failed with rc = %i\n", rc)); + dump_ecb_data(key, key_length, input_data, data_length, + encrypt); + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_ecb_data(key, key_length, input_data, + data_length, encrypt); + } + + if (rc) { + VV_(printf("3DES ECB test exited after encryption\n")); + return rc; + } + + rc = ica_des_ecb(encrypt, decrypt, data_length, key, 0); + if (rc) { + VV_(printf("ica_des_ecb decrypt failed with rc = %i\n", rc)); + dump_ecb_data(key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_ecb_data(key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + return rc; + } + + return rc; +} + +/* + * Performs ECB tests. + */ +int main(int argc, char **argv) +{ + int rc = 0; + int error_count = 0; + int iteration; + unsigned int data_length = sizeof(ica_des_vector_t); + + set_verbosity(argc, argv); + +#ifdef ICA_FIPS + if (ica_fips_status() & ICA_FIPS_MODE) { + printf("All DES-ECB tests skipped." + " (DES not FIPS approved)\n"); + return 0; + } +#endif /* ICA_FIPS */ + + for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) { + rc = random_des_ecb(iteration, data_length); + if (rc) { + V_(printf("random_des_ecb failed with rc = %i\n", rc)); + error_count++; + goto out; + } + data_length += sizeof(ica_des_vector_t); + } + +out: + if (error_count) + printf("%i DES-ECB tests failed.\n", error_count); + else + printf("All DES-ECB tests passed.\n"); + + return rc; +} + diff --git a/src/tests/libica_des_ofb_test.c b/src/tests/libica_des_ofb_test.c new file mode 100644 index 0000000..b634e22 --- /dev/null +++ b/src/tests/libica_des_ofb_test.c @@ -0,0 +1,172 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2010, 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include "ica_api.h" +#include "testcase.h" + +#define NR_RANDOM_TESTS 10000 + +void dump_ofb_data(unsigned char *iv, unsigned int iv_length, + unsigned char *key, unsigned int key_length, + unsigned char *input_data, unsigned int data_length, + unsigned char *output_data) +{ + VV_(printf("IV \n")); + dump_array(iv, iv_length); + VV_(printf("Key \n")); + dump_array(key, key_length); + VV_(printf("Input Data\n")); + dump_array(input_data, data_length); + VV_(printf("Output Data\n")); + dump_array(output_data, data_length); +} + +int load_random_test_data(unsigned char *data, unsigned int data_length, + unsigned char *iv, unsigned int iv_length, + unsigned char *key, unsigned int key_length) +{ + int rc; + + rc = ica_random_number_generate(data_length, data); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + rc = ica_random_number_generate(iv_length, iv); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + rc = ica_random_number_generate(key_length, key); + if (rc) { + VV_(printf("ica_random_number_generate with rc = %i errnor = %i\n", + rc, errno)); + return rc; + } + return rc; +} + +int random_des_ofb(int iteration, unsigned int data_length) +{ + unsigned int iv_length = sizeof(ica_des_vector_t); + unsigned int key_length = sizeof(ica_des_key_single_t); + + unsigned char iv[iv_length]; + unsigned char tmp_iv[iv_length]; + unsigned char key[key_length]; + unsigned char input_data[data_length]; + unsigned char encrypt[data_length]; + unsigned char decrypt[data_length]; + + int rc = 0; + + memset(encrypt, 0x00, data_length); + memset(decrypt, 0x00, data_length); + + load_random_test_data(input_data, data_length, iv, iv_length, key, + key_length); + memcpy(tmp_iv, iv, iv_length); + + VV_(printf("Test Parameters for iteration = %i\n", iteration)); + VV_(printf("key length = %i, data length = %i, iv length = %i\n", + key_length, data_length, iv_length)); + + rc = ica_des_ofb(input_data, encrypt, data_length, key, tmp_iv, 1); + if (rc) { + VV_(printf("ica_des_ofb encrypt failed with rc = %i\n", rc)); + dump_ofb_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + if (!rc) { + VV_(printf("Encrypt:\n")); + dump_ofb_data(iv, iv_length, key, key_length, input_data, + data_length, encrypt); + } + + if (rc) { + VV_(printf("DES OFB test exited after encryption\n")); + return rc; + } + + memcpy(tmp_iv, iv, iv_length); + + rc = ica_des_ofb(encrypt, decrypt, data_length, key, tmp_iv, 0); + if (rc) { + VV_(printf("ica_des_ofb decrypt failed with rc = %i\n", rc)); + dump_ofb_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + return rc; + } + + + if (!rc) { + VV_(printf("Decrypt:\n")); + dump_ofb_data(iv, iv_length, key, key_length, encrypt, + data_length, decrypt); + } + + if (memcmp(decrypt, input_data, data_length)) { + VV_(printf("Decryption Result does not match the original data!\n")); + VV_(printf("Original data:\n")); + dump_array(input_data, data_length); + VV_(printf("Decryption Result:\n")); + dump_array(decrypt, data_length); + rc++; + } + return rc; +} + +int main(int argc, char **argv) +{ + int rc = 0; + int error_count = 0; + int iteration; + unsigned int rdata; + unsigned int data_length = 1; + + set_verbosity(argc, argv); + +#ifdef ICA_FIPS + if (ica_fips_status() & ICA_FIPS_MODE) { + printf("All DES-OFB tests skipped." + " (DES not FIPS approved)\n"); + return 0; + } +#endif /* ICA_FIPS */ + + for(iteration = 1; iteration <= NR_RANDOM_TESTS; iteration++) { + rc = random_des_ofb(iteration, data_length); + if (rc) { + V_(printf("random_des_ofb failed with rc = %i\n", rc)); + error_count++; + goto out; + } + // add a value between 1 and 8 to data_length + if (ica_random_number_generate(sizeof(rdata), (unsigned char*) &rdata)) { + printf("ica_random_number_generate failed with errnor = %i\n", + errno); + exit(1); + } + data_length += (rdata % 8) + 1; + } +out: + if (error_count) + printf("%i DES-OFB tests failed.\n", error_count); + else + printf("All DES-OFB tests passed.\n"); + + return rc; +} + diff --git a/src/tests/libica_des_test.c b/src/tests/libica_des_test.c new file mode 100644 index 0000000..abf50da --- /dev/null +++ b/src/tests/libica_des_test.c @@ -0,0 +1,147 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2001, 2009, 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include "ica_api.h" +#include "testcase.h" + +const int cipher_buf_length = 8; + +unsigned char NIST_KEY1[] = + { 0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57 }; + +unsigned char NIST_TEST_DATA[] = + { 0x01, 0xa1, 0xd6, 0xd0, 0x39, 0x77, 0x67, 0x42 }; + +unsigned char NIST_TEST_RESULT[] = + { 0x69, 0x0f, 0x5b, 0x0d, 0x9a, 0x26, 0x93, 0x9b }; + +int test_des_new_api(int mode) +{ + ica_des_vector_t iv; + ica_des_key_single_t key; + int rc = 0; + unsigned char dec_text[sizeof NIST_TEST_DATA], + enc_text[sizeof NIST_TEST_DATA]; + + bzero(dec_text, sizeof dec_text); + bzero(enc_text, sizeof enc_text); + bzero(iv, sizeof iv); + bcopy(NIST_KEY1, key, sizeof NIST_KEY1); + + rc = ica_des_encrypt(mode, sizeof NIST_TEST_DATA, NIST_TEST_DATA, &iv, + &key, enc_text); + if (rc) { + VV_(printf("\nOriginal data:\n"); + dump_array(NIST_TEST_DATA, sizeof NIST_TEST_DATA)); + VV_(printf("ica_des_encrypt failed with errno %d (0x%x).\n", rc, rc)); + VV_(printf("\nEncrypted data:\n")); + dump_array(enc_text, sizeof enc_text); + return rc; + } + + if (memcmp(enc_text, NIST_TEST_RESULT, sizeof NIST_TEST_RESULT) != 0) { + VV_(printf("This does NOT match the known result.\n")); + return -1; + } else { + VV_(printf("Yep, it's what it should be.\n")); + } + + bzero(iv, sizeof iv); + rc = ica_des_decrypt(mode, sizeof enc_text, enc_text, &iv, &key, + dec_text); + if (rc) { + VV_(printf("\nOriginal data:\n")); + dump_array(NIST_TEST_DATA, sizeof NIST_TEST_DATA); + VV_(printf("ica_des_encrypt failed with errno %d (0x%x).\n", rc, rc)); + VV_(printf("\nEncrypted data:\n")); + dump_array(enc_text, sizeof enc_text); + VV_(printf("\nDecrypted data:\n")); + dump_array(dec_text, sizeof dec_text); + VV_(printf("ica_des_decrypt failed with errno %d (0x%x).\n", rc, rc)); + return rc; + } + + if (memcmp(dec_text, NIST_TEST_DATA, sizeof NIST_TEST_DATA) != 0) { + VV_(printf("\nOriginal data:\n")); + dump_array(NIST_TEST_DATA, sizeof NIST_TEST_DATA); + VV_(printf("ica_des_encrypt failed with errno %d (0x%x).\n", rc, rc)); + VV_(printf("\nEncrypted data:\n")); + dump_array(enc_text, sizeof enc_text); + VV_(printf("\nDecrypted data:\n")); + dump_array(dec_text, sizeof dec_text); + VV_(printf("This does NOT match the original data.\n")); + return -1; + } else { + VV_(printf("Successful!\n")); + } + + return 0; +} + +int main(int argc, char **argv) +{ + unsigned int mode = 0; + int rc = 0; + int error_count = 0; + + set_verbosity(argc, argv); + +#ifdef ICA_FIPS + if (ica_fips_status() & ICA_FIPS_MODE) { + printf("All DES new api tests skipped." + " (DES not FIPS approved)\n"); + return 0; + } +#endif /* ICA_FIPS */ + + if (argc > 1) { + if (strstr(argv[1], "ecb")) + mode = MODE_ECB; + if (strstr(argv[1], "cbc")) + mode = MODE_CBC; + V_(printf("mode = %i \n", mode)); + } + + if (mode != 0 && mode != MODE_ECB && mode != MODE_CBC) { + printf("Usage: %s [ ecb | cbc ]\n", argv[0]); + return -1; + } + if (!mode) { + /* This is the standard loop that will perform all testcases */ + mode = 2; + while (mode) { + rc = test_des_new_api(mode); + if (rc) { + error_count++; + V_(printf ("test_des_new_api mode = %i failed \n", mode)); + } + else { + V_(printf ("test_des_new_api mode = %i finished.\n", mode)); + } + mode--; + } + if (error_count) + printf("%i tests failed.\n", error_count); + else + printf("All tests passed.\n"); + } else { + /* Perform only either in ECB or CBC mode */ + rc = test_des_new_api(mode); + if (rc) + printf ("test_des_new_api mode = %i failed \n", mode); + else + printf ("test_des_new_api mode = %i finished.\n", mode); + } + return rc; +} + diff --git a/src/tests/libica_drbg_birthdays.c b/src/tests/libica_drbg_birthdays.c new file mode 100644 index 0000000..70d4604 --- /dev/null +++ b/src/tests/libica_drbg_birthdays.c @@ -0,0 +1,139 @@ +/* + * Multithreaded birthday paradox test for a sha512 instantiation of ica_drbg + * + * usage: ica_drbg_birthdays <rnd_ex1> <rnd_ex2> <rnd_ex3> + * + * rnd_ex# is the no. of random experiments to be done for test no.# + */ +#include <errno.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "ica_api.h" + +/* + * no. of people no. of possible birthdays probability of a pair + * = THREADS = 2 ^ ( 8 * GEN_BYTES) + * -------------------------------------------------------------------------- + * 19 256 = 2 ^ (8 * 1) 0.5 + * 301 65536 = 2 ^ (8 * 2) 0.5 + * 4823 16777216 = 2 ^ (8 * 3) 0.5 + */ +static const int THREADS[] = {19, 301, 4823}; +static const int GEN_BYTES[] = { 1, 2, 3}; + +static int test = 0; +static ica_drbg_t *sh = NULL; + +void *thread(void *buffer) +{ + int rc; + + rc = ica_drbg_generate(sh, 0, false, NULL, 0, buffer, GEN_BYTES[test]); + if(rc){ + fprintf(stderr, "error: ica_drbg_generate: %s (%d)\n", + strerror(rc), rc); + exit(1); + } + + return NULL; +} + +int main(int argc, char **argv) +{ + long rnd_ex[3] = {0}, ex, pair_found; + int i, j, rc; + bool toggle; + + if(2 > argc || 4 < argc){ + fprintf(stderr, + "usage: ica_drbg_birthdays <rnd_ex1> <rnd_ex2>" + " <rnd_ex3>\n"); + exit(1); + } + for(i = 1; i < argc; i++) + rnd_ex[i - 1] = strtol(argv[i], NULL, 10); + + /* create instantiation */ + rc = ica_drbg_instantiate(&sh, 0, false, ICA_DRBG_SHA512, NULL, 0); + if(rc){ + fprintf(stderr, "error: ica_drbg_instantiate: %s (%d)\n", + strerror(rc), rc); + exit(1); + } + + printf("Multithreaded birthday paradox test for a sha512 " + "instantiation of ica_drbg\n" + "(the test result is good, if p is close to 0.5 for a large" + " number of random experiments)\n"); + + /* perform each of the 3 tests rnd_ex[test] times */ + for(test = 0; test < 3; test++){ + if(!rnd_ex[test]) + continue; + + int status[THREADS[test]]; + unsigned char buffer[THREADS[test]][GEN_BYTES[test]]; + + pair_found = 0; + + printf("%ld random Experiment(s): %d threads, " + "%1d bytes/thread generated...\n", + rnd_ex[test], THREADS[test], GEN_BYTES[test]); + pthread_t threads[THREADS[test]]; + + for(ex = 0; ex < rnd_ex[test]; ex++){ + /* start threads */ + for(i = 0; i < THREADS[test]; i++){ + while((rc = pthread_create(&threads[i], NULL, + thread, buffer[i])) == EAGAIN) + ; + if(rc){ + fprintf(stderr, + "error: pthread_create: " + "%s (%d)\n", + strerror(rc), rc); + exit(1); + } + } + + /* wait for threads */ + for(i = 0; i < THREADS[test]; i++){ + if((rc = pthread_join(threads[i], + (void**)&status[i]))){ + fprintf(stderr, "error: pthread_join " + "%s (%d)\n", + strerror(rc), rc); + exit(1); + } + } + + /* search pairs */ + toggle = false; + for(i = 0; i < THREADS[test]; i++){ + for(j = 0; j < THREADS[test]; j++){ + if(i != j && !memcmp(buffer[i], + buffer[j], GEN_BYTES[test])){ + pair_found++; + toggle = true; + break; + } + } + if(toggle) + break; + } + } + printf("... %ld times a pair was found (p = %1.2f).\n", + pair_found, (float)pair_found/ex); + } + + /* destroy instantiation */ + rc = ica_drbg_uninstantiate(&sh); + if(rc){ + fprintf(stderr, "error: ica_drbg_uninstantiate: %s (%d)\n", + strerror(rc), rc); + exit(1); + } + return 0; +} diff --git a/src/tests/libica_drbg_test.c b/src/tests/libica_drbg_test.c new file mode 100644 index 0000000..ece3806 --- /dev/null +++ b/src/tests/libica_drbg_test.c @@ -0,0 +1,623 @@ +/* + * This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + * + * DRBG conforming to NIST SP800-90A + * + * Author(s): Patrick Steuer <patrick.steuer@de.ibm.com> + * + * Copyright IBM Corp. 2015 + */ + +#include <errno.h> +#include <stdbool.h> +#include <stdio.h> +#include <string.h> + +#include "ica_api.h" +#include "s390_drbg.h" +#include "testcase.h" + +/* + * Known answer test types + */ +typedef struct{ + /* Inputs */ + ica_drbg_t **sh; + int sec; + bool pr; + ica_drbg_mech_t *const mech; + const unsigned char *pers; + size_t pers_len; + /* Expected return code */ + int rc; +}instantiate_test_t; + +typedef struct{ + /* Inputs */ + ica_drbg_t *sh; + bool pr; + const unsigned char *add; + size_t add_len; + /* Expected return code */ + int rc; +}reseed_test_t; + +typedef struct{ + /* Inputs */ + ica_drbg_t *sh; + int sec; + bool pr; + const unsigned char *add; + size_t add_len; + size_t prnd_len; + /* Expected return code */ + int rc; +}generate_test_t; + +typedef struct{ + /* Inputs */ + ica_drbg_t **sh; + /* Expected return code */ + int rc; +}uninstantiate_test_t; + +typedef struct{ + /* Inputs */ + void *func; + int sec; + bool pr; + ica_drbg_mech_t *mech; + /* Expected return code */ + int rc; +}health_test_test_t; + +/* + * Testcase + */ +int main(int argc, + char **argv) +{ + int i = 0; + int failed = 0; + int passed = 0; + int status = -1; + const unsigned char pers[] = {0x7e,0xa1,0x0e,0x96,0xaf,0x90,0x0c,0x25, + 0xd3,0xbe,0x3b,0x50,0xa0,0xcc,0x71,0xa7, + 0x9f,0xe4,0x14,0xbd,0x4c,0x37,0x39,0x80, + 0x3f,0x02,0xff,0xe5,0xb2,0x60,0xbf,0xbb,}; + const unsigned char add[] = {0xc0,0x66,0xfd,0x2e,0xb8,0xe4,0xae,0xa2, + 0xe7,0x14,0x5e,0xda,0x0c,0xfc,0x8b,0xef, + 0x5e,0xed,0xcc,0x36,0x7b,0x1c,0xb4,0xde, + 0x7e,0xb2,0xc2,0x75,0x9f,0xa7,0x5b,0xf7,}; + size_t pers_len = sizeof(pers) / sizeof(pers[0]); + size_t add_len = sizeof(add) / sizeof(add[0]); + + set_verbosity(argc, argv); + + /* + * drbg_sha512 tests + */ + + /* Instantiate */ + ica_drbg_t *sh = NULL; + ica_drbg_t *sh2 = &(ica_drbg_t){.lock = PTHREAD_MUTEX_INITIALIZER}; + drbg_recursive_mutex_init(&sh2->lock); + + const instantiate_test_t inst_test[] = { + { + .mech = ICA_DRBG_SHA512, + .sh = &sh, + .sec = DRBG_SEC_112, + .pr = true, + .pers = NULL, + .pers_len = 0, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .sh = &sh, + .sec = DRBG_SEC_192, + .pr = true, + .pers = pers, + .pers_len = pers_len, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .sh = &sh, + .sec = DRBG_SEC_256, + .pr = false, + .pers = pers, + .pers_len = pers_len, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .sh = &sh, + .sec = DRBG_SEC_128, + .pr = false, + .pers = NULL, + .pers_len = 0, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .sh = &sh, + .sec = DRBG_SEC_256 + 1, + .pr = true, + .pers = NULL, + .pers_len = 0, + .rc = ENOTSUP, + }, + { + .mech = ICA_DRBG_SHA512, + .sh = &sh, + .sec = DRBG_SEC_112, + .pr = false, + .pers = pers, + .pers_len = ICA_DRBG_SHA512->max_pers_len + 1, + .rc = EINVAL, + }, + { + .mech = NULL, + .sh = &sh, + .sec = DRBG_SEC_128, + .pr = true, + .pers = NULL, + .pers_len = 0, + .rc = EINVAL, + }, + { + .mech = NULL, + .sh = NULL, + .sec = DRBG_SEC_192, + .pr = false, + .pers = NULL, + .pers_len = 0, + .rc = EINVAL, + }, + { + .mech = NULL, + .sh = &sh2, + .sec = DRBG_SEC_256, + .pr = true, + .pers = pers, + .pers_len = pers_len, + .rc = EINVAL, + }, + }; + for(i = 0; i < sizeof(inst_test) / sizeof(inst_test[0]); i++){ + V_(printf("instantiate function: test no. %d", i)); + status = ica_drbg_instantiate(inst_test[i].sh, + inst_test[i].sec, + inst_test[i].pr, + inst_test[i].mech, + inst_test[i].pers, + inst_test[i].pers_len); + if(inst_test[i].rc == status){ + V_(printf(" passed\n")); + passed++; + } + else{ + V_(printf(" failed\n")); + failed++; + } + ica_drbg_uninstantiate(inst_test[i].sh); + } + + /* Reseed */ + ica_drbg_t *sh_pr_false = NULL; + ica_drbg_t *sh_pr_true = NULL; + ica_drbg_instantiate(&sh_pr_true, DRBG_SEC_112, true, ICA_DRBG_SHA512, + pers, pers_len); + ica_drbg_instantiate(&sh_pr_false, DRBG_SEC_112, false, + ICA_DRBG_SHA512, pers, pers_len); + const reseed_test_t res_test[] = { + { + .sh = sh_pr_true, + .pr = true, + .add = NULL, + .add_len = 0, + .rc = 0, + }, + { + .sh = sh_pr_false, + .pr = false, + .add = add, + .add_len = add_len, + .rc = 0, + }, + { + .sh = sh_pr_true, + .pr = true, + .add = add, + .add_len = ICA_DRBG_SHA512->max_add_len + 1, + .rc = EINVAL, + }, + { + .sh = NULL, + .pr = true, + .add = NULL, + .add_len = 0, + .rc = EINVAL, + }, + { + .sh = sh_pr_false, + .pr = true, + .add = add, + .add_len = add_len, + .rc = ENOTSUP, + }, + }; + for(i = 0; i < sizeof(res_test) / sizeof(res_test[0]); i++){ + V_(printf("reseed function: test no. %d", i)); + status = ica_drbg_reseed(res_test[i].sh, res_test[i].pr, + res_test[i].add, res_test[i].add_len); + if(res_test[i].rc == status){ + V_(printf(" passed\n")); + passed++; + } + else{ + V_(printf(" failed\n")); + failed++; + } + } + ica_drbg_uninstantiate(&sh_pr_true); + ica_drbg_uninstantiate(&sh_pr_false); + + /* Generate */ + sh_pr_false = NULL; + sh_pr_true = NULL; + ica_drbg_instantiate(&sh_pr_true, DRBG_SEC_192, true, ICA_DRBG_SHA512, + pers, pers_len); + ica_drbg_instantiate(&sh_pr_false, DRBG_SEC_192, false, + ICA_DRBG_SHA512, pers, pers_len); + + const generate_test_t gen_test[] = { + { + .sh = sh_pr_true, + .sec = DRBG_SEC_112, + .pr = true, + .add = add, + .add_len = add_len, + .prnd_len = 0, + .rc = 0, + }, + { + .sh = sh_pr_true, + .sec = DRBG_SEC_112, + .pr = true, + .add = NULL, + .add_len = 0, + .prnd_len = 256, + .rc = 0, + }, + { + .sh = sh_pr_false, + .sec = DRBG_SEC_192, + .pr = false, + .add = NULL, + .add_len = 0, + .prnd_len = ICA_DRBG_SHA512->max_no_of_bytes_per_req, + .rc = 0, + }, + { + .sh = sh_pr_false, + .sec = DRBG_SEC_192, + .pr = false, + .add = add, + .add_len = add_len, + .prnd_len = 512, + .rc = 0, + }, + { + .sh = sh_pr_true, + .sec = DRBG_SEC_128, + .pr = true, + .add = add, + .add_len = add_len, + .prnd_len = 1024, + .rc = 0, + }, + { + .sh = sh_pr_false, + .sec = DRBG_SEC_256, + .pr = false, + .add = NULL, + .add_len = 0, + .prnd_len = 2048, + .rc = ENOTSUP, + }, + { + .sh = sh_pr_false, + .sec = DRBG_SEC_112, + .pr = true, + .add = add, + .add_len = add_len, + .prnd_len = 3072, + .rc = ENOTSUP, + }, + { + .sh = NULL, + .sec = DRBG_SEC_112, + .pr = true, + .add = add, + .add_len = add_len, + .prnd_len = 128, + .rc = EINVAL, + }, + { + .sh = sh_pr_true, + .sec = DRBG_SEC_128, + .pr = false, + .add = add, + .add_len = ICA_DRBG_SHA512->max_add_len + 1, + .prnd_len = 64, + .rc = EINVAL, + }, + }; + for(i = 0; i < sizeof(gen_test) / sizeof(gen_test[0]); i++){ + V_(printf("generate function: test no. %d", i)); + size_t prnd_len = gen_test[i].prnd_len; + unsigned char prnd[prnd_len]; + status = ica_drbg_generate(gen_test[i].sh, gen_test[i].sec, + gen_test[i].pr, gen_test[i].add, + gen_test[i].add_len, prnd, + prnd_len); + if(gen_test[i].rc == status){ + V_(printf(" passed\n")); + passed++; + } + else{ + V_(printf(" failed\n")); + failed++; + } + } + ica_drbg_uninstantiate(&sh_pr_true); + ica_drbg_uninstantiate(&sh_pr_false); + + /* Uninstantiate */ + sh = NULL; + ica_drbg_instantiate(&sh, DRBG_SEC_256, true, ICA_DRBG_SHA512, pers, + pers_len); + const uninstantiate_test_t uninst_test[] = { + { + .sh = &sh, + .rc = 0, + }, + { + .sh = NULL, + .rc = EINVAL, + }, + }; + for(i = 0; i < sizeof(uninst_test) / sizeof(uninst_test[0]); i++){ + V_(printf("uninstantiate function: test no. %d", i)); + status = ica_drbg_uninstantiate(uninst_test[i].sh); + if(uninst_test[i].rc == status){ + V_(printf(" passed\n")); + passed++; + } + else{ + V_(printf(" failed\n")); + failed++; + } + } + ica_drbg_uninstantiate(&sh); + + /* Health test */ + const health_test_test_t ht_test[] = { + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_instantiate, + .sec = DRBG_SEC_112, + .pr = true, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_instantiate, + .sec = DRBG_SEC_128, + .pr = true, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_instantiate, + .sec = DRBG_SEC_192, + .pr = true, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_instantiate, + .sec = DRBG_SEC_256, + .pr = true, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_instantiate, + .sec = DRBG_SEC_112, + .pr = false, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_instantiate, + .sec = DRBG_SEC_128, + .pr = false, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_instantiate, + .sec = DRBG_SEC_192, + .pr = false, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_instantiate, + .sec = DRBG_SEC_256, + .pr = false, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_reseed, + .sec = DRBG_SEC_112, + .pr = true, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_reseed, + .sec = DRBG_SEC_128, + .pr = true, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_reseed, + .sec = DRBG_SEC_192, + .pr = true, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_reseed, + .sec = DRBG_SEC_256, + .pr = true, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_reseed, + .sec = DRBG_SEC_112, + .pr = false, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_reseed, + .sec = DRBG_SEC_128, + .pr = false, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_reseed, + .sec = DRBG_SEC_192, + .pr = false, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_reseed, + .sec = DRBG_SEC_256, + .pr = false, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_generate, + .sec = DRBG_SEC_112, + .pr = true, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_generate, + .sec = DRBG_SEC_128, + .pr = true, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_generate, + .sec = DRBG_SEC_192, + .pr = true, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_generate, + .sec = DRBG_SEC_256, + .pr = true, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_generate, + .sec = DRBG_SEC_112, + .pr = false, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_generate, + .sec = DRBG_SEC_128, + .pr = false, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_generate, + .sec = DRBG_SEC_192, + .pr = false, + .rc = 0, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_generate, + .sec = DRBG_SEC_256, + .pr = false, + .rc = 0, + }, + { + .mech = NULL, + .func = ica_drbg_generate, + .sec = DRBG_SEC_256, + .pr = false, + .rc = EINVAL, + }, + { + .mech = ICA_DRBG_SHA512, + .func = NULL, + .sec = DRBG_SEC_256, + .pr = true, + .rc = EINVAL, + }, + { + .mech = ICA_DRBG_SHA512, + .func = ica_drbg_instantiate, + .sec = DRBG_SEC_256 + 1, + .pr = false, + .rc = ENOTSUP, + }, + }; + for(i = 0; i < sizeof(ht_test) / sizeof(ht_test[0]); i++){ + V_(printf("health test function: test no. %d", i)); + status = ica_drbg_health_test(ht_test[i].func, ht_test[i].sec, + ht_test[i].pr, ht_test[i].mech); + if(ht_test[i].rc == status){ + V_(printf(" passed\n")); + passed++; + } + else{ + V_(printf(" failed\n")); + failed++; + } + } + + if(failed) + printf("DRBG tests: %d passed, %d failed, %d total\n", passed, failed, + passed + failed); + else + printf("All DRBG tests passed.\n"); + + return 0; +} diff --git a/src/tests/libica_fips_test.c b/src/tests/libica_fips_test.c new file mode 100644 index 0000000..6584033 --- /dev/null +++ b/src/tests/libica_fips_test.c @@ -0,0 +1,66 @@ +#include <openssl/crypto.h> +#include <openssl/opensslv.h> +#include <stdio.h> +#include <stdlib.h> + +#include <openssl/opensslconf.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif /* OPENSSL_FIPS */ + +#include "ica_api.h" + +#define FIPS_FLAG "/proc/sys/crypto/fips_enabled" + +int +main(void) +{ + FILE *fd; + int fips, rv; + char fips_flag; + + printf("Kernel FIPS flag (%s) is ", FIPS_FLAG); + if ((fd = fopen(FIPS_FLAG, "r")) != NULL) { + if (fread(&fips_flag, sizeof(fips_flag), 1, fd) == 1) { + fips_flag -= '0'; + printf("%d.", fips_flag); + } else { + printf("not readable."); + } + fclose(fd); + } + else { + fips_flag = 0; + printf("not present."); + } + printf("\nKernel %s in FIPS mode.\n", fips_flag ? + "runs" : "doesn't run"); + + printf("Libica has "); +#ifdef ICA_FIPS + fips = ica_fips_status(); +#else + fips = 0; + printf("no "); +#endif /* ICA_FIPS */ + printf("built-in FIPS support.\nLibica %s in FIPS mode.\n", + fips & ICA_FIPS_MODE ? "runs" : "doesn't run"); + + rv = EXIT_SUCCESS; +#ifdef ICA_FIPS + if ((fips & ICA_FIPS_MODE) != fips_flag) { + printf("This shouldn't happen.\n"); + rv = EXIT_FAILURE; + } + if (fips & ICA_FIPS_CRYPTOALG) { + printf("Libica FIPS powerup test failed.\n"); + rv = EXIT_FAILURE; + } +#endif /* ICA_FIPS */ + + printf("OpenSSL version is '%s'.\n", OPENSSL_VERSION_TEXT); + printf("OpenSSL %s in FIPS mode.\n\n", FIPS_mode() ? + "runs" : "doesn't run"); + + return rv; +} diff --git a/src/tests/libica_get_functionlist.c b/src/tests/libica_get_functionlist.c new file mode 100644 index 0000000..edf0a43 --- /dev/null +++ b/src/tests/libica_get_functionlist.c @@ -0,0 +1,68 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2010, 2013 */ + +/* + * Test program for libica API call ica_get_version(). + * + * Test 1: invalid input. + * Test 2: Valid input. + */ +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include "ica_api.h" +#include <string.h> +#include "testcase.h" + +int main(int argc, char **argv) +{ + libica_func_list_element* libica_func_list; + int rc, x; + int failed = 0; + unsigned int count; + + set_verbosity(argc, argv); + + //========== Test#1 good case ============ + V_(printf("Testing libica API ica_get_functionlist().\n")); + rc = ica_get_functionlist(NULL, &count); + if (rc) { + V_(printf("ica_get_functionlist failed with rc=%02x\n", rc)); + return -1; + } + V_(printf("Retrieved number of elements: %d\n", count)); + + libica_func_list = malloc(sizeof(libica_func_list_element) * count); + rc = ica_get_functionlist(libica_func_list, &count); + if (rc) { + V_(printf("Retrieving function list failed with rc=%02x\n", rc)); + failed++; + } + else { + for (x=0; x<count; x++) { + V_(printf("ID: %d Flags: %d Property: %d\n", + libica_func_list[x].mech_mode_id, + libica_func_list[x].flags, libica_func_list[x].property)); + } + } + + //========== Test#2 bad parameter ============ + rc = ica_get_functionlist(NULL, NULL); + if (rc != EINVAL) { + V_(printf("Operation failed: Expected: %d Actual: %d\n", EINVAL, rc)); + failed++; + } + + if (failed) { + printf("ica_get_functionlist tests failed.\n"); + return 1; + } else { + printf("All ica_get_functionlist tests passed.\n"); + return 0; + } +} diff --git a/src/tests/libica_get_version.c b/src/tests/libica_get_version.c new file mode 100644 index 0000000..ec1ebc5 --- /dev/null +++ b/src/tests/libica_get_version.c @@ -0,0 +1,60 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2010, 2011 */ + +/* + * Test program for libica API call ica_get_version(). + * + * Test 1: invalid input. + * Test 2: Valid input. + */ +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include "ica_api.h" +#include <string.h> +#include "testcase.h" + +int main(int argc, char **argv) +{ + libica_version_info version_info; + int rc; + int failed = 0; + + set_verbosity(argc, argv); + + V_(printf("Testing libica API ica_get_version() w/ invalid input (NULL).\n")); + rc = ica_get_version(NULL); + if (rc == EINVAL) { + V_(printf("Test successful\n")); + } + else { + printf("Test failed: rc=%x, expected: %x \n", rc, EINVAL); + failed++; + } + + V_(printf("Testing libica API ica_get_version_() w/ valid input.\n")); + rc = ica_get_version(&version_info); + if (rc == 0) { + V_(printf("Test successful\n")); + V_(printf("Major_version:%d, minor_version %d, fixpack_version %d\n", + version_info.major_version, version_info.minor_version, + version_info.fixpack_version)); + } + else { + V_(printf("Test failed rc=%d, expected: %d \n", rc, 0)); + failed++; + } + + if (failed) { + printf("Failed ica_get_version tests: %d\n", failed); + return 1; + } else { + printf("All ica_get_version tests passed.\n"); + return 0; + } +} diff --git a/src/tests/libica_keygen_test.c b/src/tests/libica_keygen_test.c new file mode 100644 index 0000000..e2a0668 --- /dev/null +++ b/src/tests/libica_keygen_test.c @@ -0,0 +1,271 @@ +#include <errno.h> +#include <openssl/crypto.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/time.h> + +#include <openssl/opensslconf.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif /* OPENSSL_FIPS */ + +#include "ica_api.h" +#include "testcase.h" + +#define ZERO_PADDING 8 + +#define BITSTOBYTES(bits) (((bits)+7)/8) +#define EXPO_TYPE_3 3 +#define EXPO_TYPE_65537 65537 +#define EXPO_TYPE_R 1 + +/* print error report after function return */ +static void print_error_report(unsigned int rc_sv, int errno_sv, + const char *func_name); + +extern int errno; + +int main(int argc, char **argv) +{ + struct timeval start, end; + unsigned int rc = 0, rc_test = 0, expo_type = 0, key_bit_length = 0; + int argno_expo = 2, argno_key = 1; + + set_verbosity(argc, argv); + + /* first cmd line arg may be verbosity */ + if (verbosity_ != 0) { + argc--; + argno_expo++; + argno_key++; + } + + if(argc < 3){ + printf( "usage: %s [<verbosity> (-v or -vv)] <key_bit_length>" + " (57..4096) <exponent_type> (3, 65537 or r [random])\n", + argv[0]); + return EXIT_FAILURE; + } + + if((0 == (key_bit_length=strtol(argv[argno_key], &argv[argno_key], + 10))) || ('\0' != *argv[argno_key]) ){ + printf( "error - possible values for" + " <key_bit_length> are integers" + " greater than 0.\n"); + return EXIT_FAILURE; + } + + if(BITSTOBYTES(key_bit_length) < 8){ + printf("error - <key_bit_length> must be at least 57.\n"); + return EXIT_FAILURE; + } + + if(0 == (strcmp(argv[argno_expo], "3"))) + expo_type = EXPO_TYPE_3; + else if(0 == (strcmp(argv[argno_expo], "65537"))) + expo_type = EXPO_TYPE_65537; + else if(0 == (strcmp(argv[argno_expo], "r"))) + expo_type = EXPO_TYPE_R; + else { + printf( "error - possible values for <exponent_type>" + " are 3, 65537 or r (random)\n"); + return EXIT_FAILURE; + } + + unsigned char ciphertext[BITSTOBYTES(key_bit_length)], + decrypted[BITSTOBYTES(key_bit_length)], + plaintext[BITSTOBYTES(key_bit_length)]; + memset(ciphertext, 0, (size_t) BITSTOBYTES(key_bit_length)); + memset(decrypted, 0, (size_t) BITSTOBYTES(key_bit_length)); + memset(plaintext, 0, (size_t) BITSTOBYTES(key_bit_length)); + + unsigned char modexpo_public_e[BITSTOBYTES(key_bit_length)]; + memset(modexpo_public_e, 0, (size_t) BITSTOBYTES(key_bit_length)); + unsigned char modexpo_public_n[BITSTOBYTES(key_bit_length)]; + memset(modexpo_public_n, 0, (size_t) BITSTOBYTES(key_bit_length)); + + unsigned char crt_private_p[BITSTOBYTES(key_bit_length) / 2 + 1 + ZERO_PADDING]; + memset(crt_private_p, 0, (size_t) (BITSTOBYTES(key_bit_length) / 2 + 1 + ZERO_PADDING)); + unsigned char crt_private_q[BITSTOBYTES(key_bit_length) / 2 + 1]; + memset(crt_private_q, 0, (size_t) (BITSTOBYTES(key_bit_length) / 2 + 1)); + unsigned char crt_private_dp[BITSTOBYTES(key_bit_length) / 2 + 1 + ZERO_PADDING]; + memset(crt_private_dp, 0, (size_t) (BITSTOBYTES(key_bit_length) / 2 + 1 + ZERO_PADDING)); + unsigned char crt_private_dq[BITSTOBYTES(key_bit_length) / 2 + 1]; + memset(crt_private_dq, 0, (size_t) (BITSTOBYTES(key_bit_length) / 2 + 1)); + unsigned char crt_private_inv_q[BITSTOBYTES(key_bit_length) / 2 + 1 + ZERO_PADDING]; + memset(crt_private_inv_q, 0, (size_t) (BITSTOBYTES(key_bit_length) / 2 + 1 + ZERO_PADDING)); + + ica_rsa_key_mod_expo_t modexpo_public_key = { + .modulus = modexpo_public_n, .exponent = modexpo_public_e, + .key_length = BITSTOBYTES(key_bit_length)}; + + ica_rsa_key_crt_t crt_private_key = { + .p = crt_private_p, .q = crt_private_q, .dp = crt_private_dp, + .dq = crt_private_dq, .qInverse = crt_private_inv_q, + .key_length = BITSTOBYTES(key_bit_length)}; + + ica_adapter_handle_t adapter_handle = 0; + + V_(printf("[TEST RSA CRT]\n")); + V_(printf("generate random plaintext...\n")); + if((rc = ica_random_number_generate(BITSTOBYTES(key_bit_length) ,plaintext)) != 0){ + ++rc_test; + print_error_report(rc, errno, "ica_random_number_generate"); + } + + /* make sure that plaintext < modulus */ + plaintext[0] = 0; + + VV_(printf("plaintext:\n")); + dump_array(plaintext, BITSTOBYTES(key_bit_length)); + + if((rc = ica_open_adapter(&adapter_handle)) != 0){ + ++rc_test; + print_error_report(rc, errno, "ica_open_adapter"); + } + if(adapter_handle == DRIVER_NOT_LOADED) { + V_(printf("adapter handle is %d\n", adapter_handle)); + } + + switch(expo_type){ + case EXPO_TYPE_3: + *(unsigned long*)((unsigned char *)modexpo_public_key.exponent + + modexpo_public_key.key_length - + sizeof(unsigned long)) = (unsigned long) EXPO_TYPE_3; + break; + case EXPO_TYPE_65537: + *(unsigned long*)((unsigned char *)modexpo_public_key.exponent + + modexpo_public_key.key_length - + sizeof(unsigned long)) = (unsigned long) EXPO_TYPE_65537; + break; + case EXPO_TYPE_R: + /* .exponent element is not set here. + * if .exponent element is not set, ica_rsa_generate_mod_expo + * will randomly generate it */ + break; + default: + printf( "error - unknown <exponent_type>\n"); + return EXIT_FAILURE; + } + + V_(printf("generate keys...\n")); + + gettimeofday(&start, NULL); + if((rc = ica_rsa_key_generate_crt(adapter_handle, + key_bit_length, + &modexpo_public_key, + &crt_private_key)) != 0){ + ++rc_test; + print_error_report(rc, errno, "ica_rsa_key_generate_crt"); + } + gettimeofday(&end, NULL); + V_(printf("RSA CRT Key_gen with key length %d took: %06lu µs.\n", + key_bit_length, (end.tv_sec * 1000000 + end.tv_usec) + - (start.tv_sec * 1000000 + start.tv_usec))); + + VV_(printf("public key (e,n):\ne =\n")); + dump_array(modexpo_public_key.exponent, BITSTOBYTES(key_bit_length)); + VV_(printf("n =\n")); + dump_array(modexpo_public_key.modulus, BITSTOBYTES(key_bit_length)); + VV_(printf("private key (p,q,dp,dq,q^-1):\np =\n")); + dump_array(crt_private_key.p, + BITSTOBYTES(key_bit_length) / 2 + 1 + ZERO_PADDING); + VV_(printf("q =\n")); + dump_array(crt_private_key.q, BITSTOBYTES(key_bit_length) / 2 + 1); + VV_(printf("dp =\n")); + dump_array(crt_private_key.dp, + BITSTOBYTES(key_bit_length) / 2 + 1 +ZERO_PADDING); + VV_(printf("dq =\n")); + dump_array(crt_private_key.dq, BITSTOBYTES(key_bit_length) / 2 + 1); + VV_(printf("q^-1 =\n")); + dump_array(crt_private_key.qInverse, + BITSTOBYTES(key_bit_length) / 2 + 1 + ZERO_PADDING); + + V_(printf("encrypt...\n")); + if((rc = ica_rsa_mod_expo(adapter_handle, plaintext, &modexpo_public_key, + ciphertext)) != 0){ + ++rc_test; + print_error_report(rc, errno, "ica_rsa_mod_expo"); + } + + VV_(printf("ciphertext:\n")); + dump_array(ciphertext, BITSTOBYTES(key_bit_length)); + + V_(printf("decrypt...\n")); + if((rc = ica_rsa_crt(adapter_handle, ciphertext, &crt_private_key, + decrypted)) != 0){ + ++rc_test; + print_error_report(rc, errno, "ica_rsa_crt"); + } + + VV_(printf("result:\n")); + dump_array(decrypted, BITSTOBYTES(key_bit_length)); + + if((rc = ica_close_adapter(adapter_handle)) != 0){ + ++rc_test; + print_error_report(rc, errno, "ica_close_adapter"); + } + + V_(printf("compare ciphertext to plaintext...\n")); + if(memcmp(plaintext,ciphertext,BITSTOBYTES(key_bit_length)) == 0) { + V_(printf("FAILED\nerror - ciphertext equals plaintext.\n")); + ++rc_test; + } + + V_(printf("compare result to plaintext...\n")); + if(memcmp(plaintext,decrypted,BITSTOBYTES(key_bit_length)) != 0) { + V_(printf("FAILED\nerror - decryption result doesn't match plaintext.\n")); + ++rc_test; + } + + if(0 == rc_test) + printf("All RSA keygen (%u bit) tests passed.\n", + key_bit_length); + else { + printf("RSA keygen (%u) tests failed: %u errors.", + key_bit_length, rc_test); + if (FIPS_mode()) + printf(" (Parameters might be non FIPS conformant.)"); + printf("\n"); + } + + return rc_test; +} + +static void print_error_report(unsigned int rc_sv, int errno_sv, + const char *func_name) +{ + V_(printf("FAILED\nerror - %s returned %u: ", func_name, rc_sv)); + switch (rc_sv) { + case EFAULT: + V_(printf("the message authentication failed.\n")); + break; + case EINVAL: + V_(printf("incorrect parameter.\n")); + break; + case EIO: + V_(printf("I/O error.\n")); + break; + case EPERM: + V_(printf("operation not permitted by hardware (CPACF).\n")); + break; + case ENODEV: + V_(printf("no such device.\n")); + break; + case ENOMEM: + V_(printf("not enough memory.\n")); + break; + default: + V_(printf("unknown return code. this shouldn't happen.\n")); + } + + V_(printf("errno ")); + if (0 == errno_sv){ + V_(printf("not set.\n")); + } + else{ + V_(printf("set to %d: %s.\n", + errno_sv, strerror(errno_sv))); + } +} diff --git a/src/tests/libica_rng_test.c b/src/tests/libica_rng_test.c new file mode 100644 index 0000000..1aac2c0 --- /dev/null +++ b/src/tests/libica_rng_test.c @@ -0,0 +1,47 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2010, 2011 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include "ica_api.h" +#include <string.h> +#include "testcase.h" + +unsigned char R[512]; + +extern int errno; + +int main(int argc, char **argv) +{ + int rc; + ica_adapter_handle_t adapter_handle; + + set_verbosity(argc, argv); + + rc = ica_open_adapter(&adapter_handle); + if (rc != 0) { + V_(printf("ica_open_adapter failed and returned %d (0x%x).\n", rc, rc)); + } + + rc = ica_random_number_generate(sizeof R, R); + if (rc != 0) { + V_(printf("ica_random_number_generate failed and returned %d (0x%x).\n", rc, rc)); +#ifdef __s390__ + if (rc == ENODEV) { + V_(printf("The usual cause of this on zSeries is that the CPACF instruction is not available.\n")); + } +#endif + return -1; + } + + dump_array(R, sizeof R); + VV_(printf("\nWell, does it look random?\n\n")); + + ica_close_adapter(adapter_handle); + return 0; +} diff --git a/src/tests/libica_rsa_key_check_test.c b/src/tests/libica_rsa_key_check_test.c new file mode 100644 index 0000000..4917a02 --- /dev/null +++ b/src/tests/libica_rsa_key_check_test.c @@ -0,0 +1,96 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2001, 2015 */ + +#include <fcntl.h> +#include <memory.h> +#include <sys/errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include "ica_api.h" +#include <sys/time.h> +#include "libica_rsa_test.h" +#include "testcase.h" + +extern int errno; + +int main(int argc, char **argv) +{ + int i, rc; + struct timeval start,end; + + set_verbosity(argc, argv); + + /* Iterate over keys (1024, 2048 and 4096 bit length */ + /* privileged keys */ + for (i = 0; i < 3; i++) { + V_(printf("modulus size = %d\n", RSA_BYTE_LENGHT[i])); + + ica_rsa_key_crt_t crt_key = {RSA_BYTE_LENGHT[i], p[i], q[i], dp[i], + dq[i], qinv[i]}; + + gettimeofday(&start, NULL); + rc = ica_rsa_crt_key_check(&crt_key); + if(rc){ + V_(printf("ica_rsa_crt_key_check failed!\n")); + } + + gettimeofday(&end, NULL); + V_(printf("RSA CRT Key check: key[%d], l=%d (keyset I): %06lu µs.\n", + i, RSA_BYTE_LENGHT[i], (end.tv_sec * 1000000 + end.tv_usec) + - (start.tv_sec * 1000000 + start.tv_usec))); + } + + /* unprivileged keys */ + for (i = 3; i < 6; i++) { + V_(printf("modulus size = %d\n", RSA_BYTE_LENGHT[i])); + + ica_rsa_key_crt_t crt_key = {RSA_BYTE_LENGHT[i], p[i], q[i], dp[i], + dq[i], qinv[i]}; + + gettimeofday(&start, NULL); + rc = ica_rsa_crt_key_check(&crt_key); + if(!rc){ + V_(printf("ica_rsa_crt_key_check failed!\n")); + } + + gettimeofday(&end, NULL); + V_(printf("RSA CRT key check: key[%d], l=%d (keyset II): %06lu µs.\n", + i, RSA_BYTE_LENGHT[i], (end.tv_sec * 1000000 + end.tv_usec) + - (start.tv_sec * 1000000 + start.tv_usec))); + + V_(printf("Result of recalculated key part (qInv)\n")); + dump_array((unsigned char *)crt_key.qInverse, RSA_BYTE_LENGHT[i]/2); + V_(printf("Result of expected key part (qInv)\n")); + dump_array((unsigned char *)qinv[i-3], RSA_BYTE_LENGHT[i]/2); + if( memcmp(crt_key.qInverse, qinv[i-3], RSA_BYTE_LENGHT[i]/2) != 0) { + V_(printf("Calculated 'qInv' do not match. Failure!\n")); + return -1; + } + if( memcmp(crt_key.p, p[i-3], RSA_BYTE_LENGHT[i]/2 + 8) != 0) { + V_(printf("Prime 'p' do not match. Failure!\n")); + return -1; + } + if( memcmp(crt_key.q, q[i-3], RSA_BYTE_LENGHT[i]/2) != 0) { + V_(printf("Prime 'q' do not match. Failure!\n")); + return -1; + } + if( memcmp(crt_key.dp, dp[i-3], RSA_BYTE_LENGHT[i]/2 + 8) != 0) { + V_(printf("Parameter 'dp' do not match. Failure!\n")); + return -1; + } + if( memcmp(crt_key.dq, dq[i-3], RSA_BYTE_LENGHT[i]/2) != 0) { + V_(printf("Parameter 'dq' do not match. Failure!\n")); + return -1; + } + + } // end loop + + printf("All RSA key check tests passed.\n"); + return 0; +} diff --git a/src/tests/libica_rsa_test.c b/src/tests/libica_rsa_test.c new file mode 100644 index 0000000..1c16764 --- /dev/null +++ b/src/tests/libica_rsa_test.c @@ -0,0 +1,120 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2001, 2015 */ + +#include <fcntl.h> +#include <memory.h> +#include <sys/errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include "ica_api.h" +#include <sys/time.h> +#include "libica_rsa_test.h" +#include "testcase.h" + +extern int errno; + +static int handle_ica_error(int rc, char *message) +{ + V_(printf("Error in %s: ", message)); + switch (rc) { + case 0: + V_(printf("OK\n")); + break; + case EINVAL: + V_(printf("Incorrect parameter.\n")); + break; + case EPERM: + V_(printf("Operation not permitted by Hardware.\n")); + break; + case EIO: + V_(printf("I/O error.\n")); + break; + default: + V_(perror("")); + } + return rc; +} + +int main(int argc, char **argv) +{ + ica_adapter_handle_t adapter_handle; + unsigned char *my_result; + unsigned char *my_result2; + int i, rc; + struct timeval start,end; + + set_verbosity(argc, argv); + + rc = ica_open_adapter(&adapter_handle); + if (rc != 0) { + V_(printf("ica_open_adapter failed and returned %d (0x%x).\n", rc, rc)); + } + + /* Iterate over key sizes (1024, 2048 and 4096) */ + for (i = 0; i < 6; i++) { + /* encrypt with public key (ME) */ + V_(printf("modulus size = %d\n", RSA_BYTE_LENGHT[i])); + + my_result = malloc(RESULT_LENGTH); + bzero(my_result, RESULT_LENGTH); + + my_result2 = malloc(RESULT_LENGTH); + bzero(my_result2, RESULT_LENGTH); + + ica_rsa_key_mod_expo_t mod_expo_key = {RSA_BYTE_LENGHT[i], n[i], e[i]}; + + rc = ica_rsa_mod_expo(adapter_handle, input_data, + &mod_expo_key, my_result); + if (rc) + exit(handle_ica_error(rc, "ica_rsa_key_mod_expo")); + + VV_(printf("\n\n\n\n\n result of encrypt with public key\n")); + dump_array(my_result, RSA_BYTE_LENGHT[i]); + VV_(printf("Ciphertext \n")); + dump_array(ciphertext[i], RSA_BYTE_LENGHT[i]); + if (memcmp(my_result,ciphertext[i],RSA_BYTE_LENGHT[i])){ + printf("Ciphertext mismatch\n"); + return -1; + } + + /* decrypt with private key (CRT) */ + ica_rsa_key_crt_t crt_key + = {RSA_BYTE_LENGHT[i], p[i], q[i], dp[i], dq[i], qinv[i]}; + + gettimeofday(&start, NULL); + + rc = ica_rsa_crt(adapter_handle, ciphertext[i], &crt_key, my_result2); + if(rc) + exit(handle_ica_error(rc, "ica_rsa_crt")); + + gettimeofday(&end, NULL); + V_(printf("RSA decrypt with key[%d] (l=%d) took %06lu µs.\n", i, + RSA_BYTE_LENGHT[i], (end.tv_sec * 1000000 + end.tv_usec) + - (start.tv_sec*1000000+start.tv_usec))); + + VV_(printf("Result of decrypt\n")); + dump_array((unsigned char *)my_result2, sizeof(input_data)); + VV_(printf("original data\n")); + dump_array(input_data, sizeof(input_data)); + if (memcmp(input_data,my_result2,sizeof(input_data)) != 0) { + printf("Results do not match. Failure!\n"); + return -1; + } + + } // end loop + + rc = ica_open_adapter(&adapter_handle); + if (rc != 0) { + printf("ica_close_adapter failed and returned %d (0x%x).\n", rc, rc); + } + + printf("All RSA tests passed.\n"); + return 0; +} + diff --git a/src/tests/libica_rsa_test.h b/src/tests/libica_rsa_test.h new file mode 100644 index 0000000..f7e2d10 --- /dev/null +++ b/src/tests/libica_rsa_test.h @@ -0,0 +1,2175 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2001, 2015 */ + +#define RESULT_LENGTH 4096 + +int RSA_BYTE_LENGHT[] = {128, 256, 512, 128, 256, 512}; + +unsigned char e[6][512] = + /* 1024,[p>q] */{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 2048,[p>q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 4096,[p>q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}, + /* 1024,[p<q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 2048,[p<q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 4096,[p<q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}}; + +unsigned char n[6][512] = + /* 1024,[p>q] */{{0xec, 0x51, 0xab, 0xa1, 0xf8, 0x40, 0x2c, 0x08, + 0x2e, 0x24, 0x52, 0x2e, 0x3c, 0x51, 0x6d, 0x98, + 0xad, 0xee, 0xc7, 0x7d, 0x00, 0xaf, 0xe1, 0xa8, + 0x61, 0xda, 0x32, 0x97, 0xb4, 0x32, 0x97, 0xe3, + 0x52, 0xda, 0x28, 0x45, 0x55, 0xc6, 0xb2, 0x46, + 0x65, 0x1b, 0x02, 0xcb, 0xbe, 0xf4, 0x2c, 0x6b, + 0x2a, 0x5f, 0xe1, 0xdf, 0xe9, 0xe3, 0xbc, 0x47, + 0xb7, 0x38, 0xb5, 0xa2, 0x78, 0x9d, 0x15, 0xe2, + 0x59, 0x81, 0x77, 0x6b, 0x6b, 0x2e, 0xa9, 0xdb, + 0x13, 0x26, 0x9c, 0xca, 0x5e, 0x0a, 0x1f, 0x3c, + 0x50, 0x9d, 0xd6, 0x79, 0x59, 0x99, 0x50, 0xe5, + 0x68, 0x1a, 0x98, 0xca, 0x11, 0xce, 0x37, 0x63, + 0x58, 0x22, 0x40, 0x19, 0x29, 0x72, 0x4c, 0x41, + 0x89, 0x0b, 0x56, 0x9e, 0x3e, 0xd5, 0x6d, 0x75, + 0x9e, 0x3f, 0x8a, 0x50, 0xf1, 0x0a, 0x59, 0x4a, + 0xc3, 0x59, 0x4b, 0xf6, 0xbb, 0xc9, 0xa5, 0x93, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 2048,[p>q] */ {0xdf, 0x27, 0x1f, 0xd2, 0x5f, 0x86, 0x44, 0x49, + 0x6b, 0x0c, 0x81, 0xbe, 0x4b, 0xd5, 0x02, 0x97, + 0xef, 0x09, 0x9b, 0x00, 0x2a, 0x6f, 0xd6, 0x77, + 0x27, 0xeb, 0x44, 0x9c, 0xea, 0x56, 0x6e, 0xd6, + 0xa3, 0x98, 0x1a, 0x71, 0x31, 0x2a, 0x14, 0x1c, + 0xab, 0xc9, 0x81, 0x5c, 0x12, 0x09, 0xe3, 0x20, + 0xa2, 0x5b, 0x32, 0x46, 0x4e, 0x99, 0x99, 0xf1, + 0x8c, 0xa1, 0x3a, 0x9f, 0xd3, 0x89, 0x25, 0x58, + 0xf9, 0xe0, 0xad, 0xef, 0xdd, 0x36, 0x50, 0xdd, + 0x23, 0xa3, 0xf0, 0x36, 0xd6, 0x0f, 0xe3, 0x98, + 0x84, 0x37, 0x06, 0xa4, 0x0b, 0x0b, 0x84, 0x62, + 0xc8, 0xbe, 0xe3, 0xbc, 0xe1, 0x2f, 0x1f, 0x28, + 0x60, 0xc2, 0x44, 0x4c, 0xdc, 0x6a, 0x44, 0x47, + 0x6a, 0x75, 0xff, 0x4a, 0xa2, 0x42, 0x73, 0xcc, + 0xbe, 0x3b, 0xf8, 0x02, 0x48, 0x46, 0x5f, 0x8f, + 0xf8, 0xc3, 0xa7, 0xf3, 0x36, 0x7d, 0xfc, 0x0d, + 0xf5, 0xb6, 0x50, 0x9a, 0x4f, 0x82, 0x81, 0x1c, + 0xed, 0xd8, 0x1c, 0xda, 0xaa, 0x73, 0xc4, 0x91, + 0xda, 0x41, 0x21, 0x70, 0xd5, 0x44, 0xd4, 0xba, + 0x96, 0xb9, 0x7f, 0x0a, 0xfc, 0x80, 0x65, 0x49, + 0x8d, 0x3a, 0x49, 0xfd, 0x91, 0x09, 0x92, 0xa1, + 0xf0, 0x72, 0x5b, 0xe2, 0x4f, 0x46, 0x5c, 0xfe, + 0x7e, 0x0e, 0xab, 0xf6, 0x78, 0x99, 0x6c, 0x50, + 0xbc, 0x5e, 0x75, 0x24, 0xab, 0xf7, 0x3f, 0x15, + 0xe5, 0xbe, 0xf7, 0xd5, 0x18, 0x39, 0x4e, 0x31, + 0x38, 0xce, 0x49, 0x44, 0x50, 0x6a, 0xaa, 0xaf, + 0x3f, 0x9b, 0x23, 0x6d, 0xca, 0xb8, 0xfc, 0x00, + 0xf8, 0x7a, 0xf5, 0x96, 0xfd, 0xc3, 0xd9, 0xd6, + 0xc7, 0x5c, 0xd5, 0x08, 0x36, 0x2f, 0xae, 0x2c, + 0xbe, 0xdd, 0xcc, 0x4c, 0x74, 0x50, 0xb1, 0x7b, + 0x77, 0x6c, 0x07, 0x9e, 0xcc, 0xa1, 0xf2, 0x56, + 0x35, 0x1a, 0x43, 0xb9, 0x7d, 0xbe, 0x21, 0x53, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 4096,[p>q] */ {0xce, 0xb2, 0x27, 0xcb, 0xd8, 0x0c, 0xc7, 0xfc, + 0x52, 0xf5, 0xec, 0xfd, 0xcb, 0x87, 0xa8, 0xaa, + 0xba, 0xf3, 0x3b, 0xfd, 0xc1, 0x9a, 0x76, 0x20, + 0x8f, 0xeb, 0x22, 0xd7, 0x0c, 0x6e, 0x37, 0x6c, + 0xec, 0xa2, 0x98, 0xa1, 0xc0, 0xa6, 0xe6, 0xb1, + 0xf7, 0xdc, 0x54, 0x7b, 0x91, 0xf0, 0x9f, 0x39, + 0xbc, 0x01, 0xc0, 0x25, 0x7a, 0xcf, 0x61, 0x13, + 0xa7, 0xb8, 0x12, 0xf8, 0x4a, 0x7a, 0x7e, 0xb8, + 0x3f, 0x2a, 0x40, 0xb5, 0x2a, 0x5b, 0x94, 0xfd, + 0x34, 0x19, 0x91, 0xe6, 0x5f, 0x23, 0xb4, 0x07, + 0x99, 0x79, 0xd0, 0xf6, 0x22, 0xc7, 0x90, 0x88, + 0xfd, 0xef, 0xdb, 0x4f, 0x8a, 0x00, 0xb5, 0x7d, + 0xba, 0xc9, 0x14, 0x06, 0xb8, 0xa8, 0x18, 0x8f, + 0x52, 0xa3, 0x89, 0x9e, 0xaf, 0xe5, 0x9f, 0x38, + 0xac, 0x21, 0x03, 0x0c, 0xa3, 0x76, 0xfb, 0xd3, + 0x09, 0x75, 0xc6, 0x36, 0x1d, 0x86, 0x1d, 0x18, + 0xbf, 0x5c, 0xe9, 0xdd, 0x21, 0x80, 0x6d, 0xa6, + 0xca, 0xf8, 0x7b, 0x91, 0xa0, 0xa8, 0x42, 0x42, + 0x0c, 0x91, 0x25, 0xf0, 0xed, 0x46, 0x08, 0xf0, + 0xa0, 0x2f, 0xf2, 0x8d, 0x73, 0x53, 0x27, 0x63, + 0xca, 0x83, 0xe3, 0x80, 0xc0, 0xf0, 0x8f, 0x9d, + 0x8e, 0x45, 0x82, 0xc5, 0xe9, 0x9f, 0x48, 0xf9, + 0xec, 0x61, 0xe9, 0x7b, 0x47, 0xfd, 0xeb, 0xe5, + 0x01, 0x1b, 0xc5, 0x89, 0xf1, 0xbc, 0x3a, 0xc4, + 0x29, 0xc8, 0x2d, 0xb1, 0x85, 0x9b, 0x92, 0x4a, + 0x5a, 0xcb, 0x85, 0xe2, 0x7b, 0x15, 0x6f, 0xc2, + 0x62, 0xb9, 0x8c, 0x52, 0xa4, 0x13, 0x75, 0x47, + 0xfd, 0x6b, 0x0f, 0x59, 0xff, 0x7c, 0xdc, 0xda, + 0x09, 0xb8, 0x55, 0x2d, 0x63, 0x52, 0x6e, 0xff, + 0xaf, 0x8d, 0xb7, 0x6b, 0x80, 0x6f, 0x04, 0xe4, + 0x78, 0x73, 0x93, 0x87, 0x5d, 0xda, 0xd2, 0xc9, + 0xe5, 0x6f, 0x0b, 0xee, 0x4e, 0x86, 0x4f, 0xf4, + 0xd2, 0x3c, 0xf5, 0x21, 0x84, 0x7c, 0x7d, 0xb0, + 0x10, 0xee, 0x98, 0x7d, 0x66, 0x32, 0x19, 0xdc, + 0xd7, 0xf0, 0x61, 0x1c, 0xfa, 0x31, 0x14, 0x3f, + 0x17, 0xe8, 0xe0, 0xa5, 0xae, 0xb0, 0x8e, 0xcb, + 0xa6, 0x73, 0xfa, 0x32, 0xa6, 0xd5, 0x33, 0x22, + 0xc0, 0x3e, 0x4e, 0xc6, 0x5e, 0x9f, 0x7f, 0xcf, + 0xa8, 0x0d, 0x26, 0xd7, 0xee, 0xfc, 0x97, 0xbb, + 0xe2, 0x9a, 0xe2, 0x94, 0x82, 0xc9, 0x89, 0xcf, + 0xb8, 0x5d, 0x60, 0x93, 0x10, 0xa1, 0x51, 0x43, + 0x89, 0xba, 0x76, 0x84, 0x72, 0x2d, 0x91, 0x49, + 0xac, 0xd8, 0xeb, 0xa8, 0xa0, 0x0b, 0xed, 0xef, + 0x04, 0x7e, 0x8e, 0x85, 0x88, 0xc3, 0x53, 0x84, + 0x2e, 0xea, 0x85, 0xd3, 0x8b, 0x5c, 0xe5, 0xba, + 0xab, 0x04, 0xe8, 0xbd, 0xf1, 0x6e, 0x77, 0xbf, + 0x40, 0xe8, 0x9c, 0x70, 0xc0, 0xe0, 0x0b, 0x95, + 0x0f, 0x40, 0xfb, 0xd8, 0x37, 0x44, 0xf7, 0xfe, + 0x38, 0x51, 0x9c, 0x92, 0xfb, 0xc4, 0x65, 0xb5, + 0xda, 0xd7, 0xc7, 0x1c, 0xad, 0xb2, 0xe2, 0x5f, + 0x22, 0x3e, 0xae, 0x74, 0xd6, 0x77, 0x32, 0xbe, + 0x77, 0x42, 0x3d, 0x85, 0x71, 0x3a, 0xa0, 0xfd, + 0x31, 0x6f, 0x4e, 0x0b, 0xd5, 0x04, 0x57, 0xb0, + 0xb2, 0x2a, 0x54, 0xfa, 0x8e, 0x29, 0x23, 0x8a, + 0x66, 0x59, 0x25, 0x1f, 0x0c, 0x68, 0x01, 0x0a, + 0x6e, 0xaf, 0x8e, 0xb8, 0xd3, 0xcd, 0x79, 0x9f, + 0xb6, 0x58, 0x16, 0x0b, 0x0a, 0x48, 0x16, 0xf1, + 0x1c, 0x09, 0x80, 0x38, 0xcb, 0xe9, 0x8e, 0xf3, + 0xb6, 0x5b, 0x4c, 0x56, 0x2d, 0x91, 0x52, 0x50, + 0x1f, 0xfb, 0x41, 0xd5, 0xb3, 0x6e, 0x94, 0x27, + 0x48, 0xd4, 0xfa, 0xaa, 0xac, 0x01, 0x27, 0x34, + 0x02, 0x5c, 0xfc, 0xa0, 0xa9, 0x78, 0xeb, 0x5c, + 0x09, 0xeb, 0x24, 0x9e, 0x38, 0x69, 0xea, 0xfd, + 0x3b, 0x56, 0xa8, 0x73, 0x1d, 0x5b, 0x59, 0x07}, + /* 1024,[p<q] */ {0xec, 0x51, 0xab, 0xa1, 0xf8, 0x40, 0x2c, 0x08, + 0x2e, 0x24, 0x52, 0x2e, 0x3c, 0x51, 0x6d, 0x98, + 0xad, 0xee, 0xc7, 0x7d, 0x00, 0xaf, 0xe1, 0xa8, + 0x61, 0xda, 0x32, 0x97, 0xb4, 0x32, 0x97, 0xe3, + 0x52, 0xda, 0x28, 0x45, 0x55, 0xc6, 0xb2, 0x46, + 0x65, 0x1b, 0x02, 0xcb, 0xbe, 0xf4, 0x2c, 0x6b, + 0x2a, 0x5f, 0xe1, 0xdf, 0xe9, 0xe3, 0xbc, 0x47, + 0xb7, 0x38, 0xb5, 0xa2, 0x78, 0x9d, 0x15, 0xe2, + 0x59, 0x81, 0x77, 0x6b, 0x6b, 0x2e, 0xa9, 0xdb, + 0x13, 0x26, 0x9c, 0xca, 0x5e, 0x0a, 0x1f, 0x3c, + 0x50, 0x9d, 0xd6, 0x79, 0x59, 0x99, 0x50, 0xe5, + 0x68, 0x1a, 0x98, 0xca, 0x11, 0xce, 0x37, 0x63, + 0x58, 0x22, 0x40, 0x19, 0x29, 0x72, 0x4c, 0x41, + 0x89, 0x0b, 0x56, 0x9e, 0x3e, 0xd5, 0x6d, 0x75, + 0x9e, 0x3f, 0x8a, 0x50, 0xf1, 0x0a, 0x59, 0x4a, + 0xc3, 0x59, 0x4b, 0xf6, 0xbb, 0xc9, 0xa5, 0x93, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 2048,[p<q] */ {0xdf, 0x27, 0x1f, 0xd2, 0x5f, 0x86, 0x44, 0x49, + 0x6b, 0x0c, 0x81, 0xbe, 0x4b, 0xd5, 0x02, 0x97, + 0xef, 0x09, 0x9b, 0x00, 0x2a, 0x6f, 0xd6, 0x77, + 0x27, 0xeb, 0x44, 0x9c, 0xea, 0x56, 0x6e, 0xd6, + 0xa3, 0x98, 0x1a, 0x71, 0x31, 0x2a, 0x14, 0x1c, + 0xab, 0xc9, 0x81, 0x5c, 0x12, 0x09, 0xe3, 0x20, + 0xa2, 0x5b, 0x32, 0x46, 0x4e, 0x99, 0x99, 0xf1, + 0x8c, 0xa1, 0x3a, 0x9f, 0xd3, 0x89, 0x25, 0x58, + 0xf9, 0xe0, 0xad, 0xef, 0xdd, 0x36, 0x50, 0xdd, + 0x23, 0xa3, 0xf0, 0x36, 0xd6, 0x0f, 0xe3, 0x98, + 0x84, 0x37, 0x06, 0xa4, 0x0b, 0x0b, 0x84, 0x62, + 0xc8, 0xbe, 0xe3, 0xbc, 0xe1, 0x2f, 0x1f, 0x28, + 0x60, 0xc2, 0x44, 0x4c, 0xdc, 0x6a, 0x44, 0x47, + 0x6a, 0x75, 0xff, 0x4a, 0xa2, 0x42, 0x73, 0xcc, + 0xbe, 0x3b, 0xf8, 0x02, 0x48, 0x46, 0x5f, 0x8f, + 0xf8, 0xc3, 0xa7, 0xf3, 0x36, 0x7d, 0xfc, 0x0d, + 0xf5, 0xb6, 0x50, 0x9a, 0x4f, 0x82, 0x81, 0x1c, + 0xed, 0xd8, 0x1c, 0xda, 0xaa, 0x73, 0xc4, 0x91, + 0xda, 0x41, 0x21, 0x70, 0xd5, 0x44, 0xd4, 0xba, + 0x96, 0xb9, 0x7f, 0x0a, 0xfc, 0x80, 0x65, 0x49, + 0x8d, 0x3a, 0x49, 0xfd, 0x91, 0x09, 0x92, 0xa1, + 0xf0, 0x72, 0x5b, 0xe2, 0x4f, 0x46, 0x5c, 0xfe, + 0x7e, 0x0e, 0xab, 0xf6, 0x78, 0x99, 0x6c, 0x50, + 0xbc, 0x5e, 0x75, 0x24, 0xab, 0xf7, 0x3f, 0x15, + 0xe5, 0xbe, 0xf7, 0xd5, 0x18, 0x39, 0x4e, 0x31, + 0x38, 0xce, 0x49, 0x44, 0x50, 0x6a, 0xaa, 0xaf, + 0x3f, 0x9b, 0x23, 0x6d, 0xca, 0xb8, 0xfc, 0x00, + 0xf8, 0x7a, 0xf5, 0x96, 0xfd, 0xc3, 0xd9, 0xd6, + 0xc7, 0x5c, 0xd5, 0x08, 0x36, 0x2f, 0xae, 0x2c, + 0xbe, 0xdd, 0xcc, 0x4c, 0x74, 0x50, 0xb1, 0x7b, + 0x77, 0x6c, 0x07, 0x9e, 0xcc, 0xa1, 0xf2, 0x56, + 0x35, 0x1a, 0x43, 0xb9, 0x7d, 0xbe, 0x21, 0x53, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 4096,[p<q] */ {0xce, 0xb2, 0x27, 0xcb, 0xd8, 0x0c, 0xc7, 0xfc, + 0x52, 0xf5, 0xec, 0xfd, 0xcb, 0x87, 0xa8, 0xaa, + 0xba, 0xf3, 0x3b, 0xfd, 0xc1, 0x9a, 0x76, 0x20, + 0x8f, 0xeb, 0x22, 0xd7, 0x0c, 0x6e, 0x37, 0x6c, + 0xec, 0xa2, 0x98, 0xa1, 0xc0, 0xa6, 0xe6, 0xb1, + 0xf7, 0xdc, 0x54, 0x7b, 0x91, 0xf0, 0x9f, 0x39, + 0xbc, 0x01, 0xc0, 0x25, 0x7a, 0xcf, 0x61, 0x13, + 0xa7, 0xb8, 0x12, 0xf8, 0x4a, 0x7a, 0x7e, 0xb8, + 0x3f, 0x2a, 0x40, 0xb5, 0x2a, 0x5b, 0x94, 0xfd, + 0x34, 0x19, 0x91, 0xe6, 0x5f, 0x23, 0xb4, 0x07, + 0x99, 0x79, 0xd0, 0xf6, 0x22, 0xc7, 0x90, 0x88, + 0xfd, 0xef, 0xdb, 0x4f, 0x8a, 0x00, 0xb5, 0x7d, + 0xba, 0xc9, 0x14, 0x06, 0xb8, 0xa8, 0x18, 0x8f, + 0x52, 0xa3, 0x89, 0x9e, 0xaf, 0xe5, 0x9f, 0x38, + 0xac, 0x21, 0x03, 0x0c, 0xa3, 0x76, 0xfb, 0xd3, + 0x09, 0x75, 0xc6, 0x36, 0x1d, 0x86, 0x1d, 0x18, + 0xbf, 0x5c, 0xe9, 0xdd, 0x21, 0x80, 0x6d, 0xa6, + 0xca, 0xf8, 0x7b, 0x91, 0xa0, 0xa8, 0x42, 0x42, + 0x0c, 0x91, 0x25, 0xf0, 0xed, 0x46, 0x08, 0xf0, + 0xa0, 0x2f, 0xf2, 0x8d, 0x73, 0x53, 0x27, 0x63, + 0xca, 0x83, 0xe3, 0x80, 0xc0, 0xf0, 0x8f, 0x9d, + 0x8e, 0x45, 0x82, 0xc5, 0xe9, 0x9f, 0x48, 0xf9, + 0xec, 0x61, 0xe9, 0x7b, 0x47, 0xfd, 0xeb, 0xe5, + 0x01, 0x1b, 0xc5, 0x89, 0xf1, 0xbc, 0x3a, 0xc4, + 0x29, 0xc8, 0x2d, 0xb1, 0x85, 0x9b, 0x92, 0x4a, + 0x5a, 0xcb, 0x85, 0xe2, 0x7b, 0x15, 0x6f, 0xc2, + 0x62, 0xb9, 0x8c, 0x52, 0xa4, 0x13, 0x75, 0x47, + 0xfd, 0x6b, 0x0f, 0x59, 0xff, 0x7c, 0xdc, 0xda, + 0x09, 0xb8, 0x55, 0x2d, 0x63, 0x52, 0x6e, 0xff, + 0xaf, 0x8d, 0xb7, 0x6b, 0x80, 0x6f, 0x04, 0xe4, + 0x78, 0x73, 0x93, 0x87, 0x5d, 0xda, 0xd2, 0xc9, + 0xe5, 0x6f, 0x0b, 0xee, 0x4e, 0x86, 0x4f, 0xf4, + 0xd2, 0x3c, 0xf5, 0x21, 0x84, 0x7c, 0x7d, 0xb0, + 0x10, 0xee, 0x98, 0x7d, 0x66, 0x32, 0x19, 0xdc, + 0xd7, 0xf0, 0x61, 0x1c, 0xfa, 0x31, 0x14, 0x3f, + 0x17, 0xe8, 0xe0, 0xa5, 0xae, 0xb0, 0x8e, 0xcb, + 0xa6, 0x73, 0xfa, 0x32, 0xa6, 0xd5, 0x33, 0x22, + 0xc0, 0x3e, 0x4e, 0xc6, 0x5e, 0x9f, 0x7f, 0xcf, + 0xa8, 0x0d, 0x26, 0xd7, 0xee, 0xfc, 0x97, 0xbb, + 0xe2, 0x9a, 0xe2, 0x94, 0x82, 0xc9, 0x89, 0xcf, + 0xb8, 0x5d, 0x60, 0x93, 0x10, 0xa1, 0x51, 0x43, + 0x89, 0xba, 0x76, 0x84, 0x72, 0x2d, 0x91, 0x49, + 0xac, 0xd8, 0xeb, 0xa8, 0xa0, 0x0b, 0xed, 0xef, + 0x04, 0x7e, 0x8e, 0x85, 0x88, 0xc3, 0x53, 0x84, + 0x2e, 0xea, 0x85, 0xd3, 0x8b, 0x5c, 0xe5, 0xba, + 0xab, 0x04, 0xe8, 0xbd, 0xf1, 0x6e, 0x77, 0xbf, + 0x40, 0xe8, 0x9c, 0x70, 0xc0, 0xe0, 0x0b, 0x95, + 0x0f, 0x40, 0xfb, 0xd8, 0x37, 0x44, 0xf7, 0xfe, + 0x38, 0x51, 0x9c, 0x92, 0xfb, 0xc4, 0x65, 0xb5, + 0xda, 0xd7, 0xc7, 0x1c, 0xad, 0xb2, 0xe2, 0x5f, + 0x22, 0x3e, 0xae, 0x74, 0xd6, 0x77, 0x32, 0xbe, + 0x77, 0x42, 0x3d, 0x85, 0x71, 0x3a, 0xa0, 0xfd, + 0x31, 0x6f, 0x4e, 0x0b, 0xd5, 0x04, 0x57, 0xb0, + 0xb2, 0x2a, 0x54, 0xfa, 0x8e, 0x29, 0x23, 0x8a, + 0x66, 0x59, 0x25, 0x1f, 0x0c, 0x68, 0x01, 0x0a, + 0x6e, 0xaf, 0x8e, 0xb8, 0xd3, 0xcd, 0x79, 0x9f, + 0xb6, 0x58, 0x16, 0x0b, 0x0a, 0x48, 0x16, 0xf1, + 0x1c, 0x09, 0x80, 0x38, 0xcb, 0xe9, 0x8e, 0xf3, + 0xb6, 0x5b, 0x4c, 0x56, 0x2d, 0x91, 0x52, 0x50, + 0x1f, 0xfb, 0x41, 0xd5, 0xb3, 0x6e, 0x94, 0x27, + 0x48, 0xd4, 0xfa, 0xaa, 0xac, 0x01, 0x27, 0x34, + 0x02, 0x5c, 0xfc, 0xa0, 0xa9, 0x78, 0xeb, 0x5c, + 0x09, 0xeb, 0x24, 0x9e, 0x38, 0x69, 0xea, 0xfd, + 0x3b, 0x56, 0xa8, 0x73, 0x1d, 0x5b, 0x59, 0x07}}; + +unsigned char dp[6][264] = + /* 1024,[p>q] */{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa7, 0xcf, 0xa2, 0x18, 0x2c, 0xa9, 0xb4, 0xb9, + 0xf5, 0x9e, 0xc9, 0x04, 0x16, 0xd9, 0xa6, 0x8b, + 0x90, 0x4a, 0x19, 0x6d, 0x64, 0xb7, 0x17, 0x67, + 0x53, 0xfa, 0x4e, 0x8d, 0xde, 0xa6, 0x94, 0x32, + 0x5d, 0xcf, 0x58, 0x3e, 0x90, 0xbb, 0x30, 0x19, + 0x96, 0x38, 0x95, 0xb6, 0xca, 0x2f, 0xfa, 0x22, + 0x81, 0x65, 0x3b, 0x3c, 0x95, 0x9e, 0x79, 0x75, + 0xe4, 0x93, 0x50, 0xf1, 0x88, 0x6b, 0xc1, 0x87, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 2048,[p>q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xed, 0x10, 0x2a, 0xcd, 0xb2, 0x68, 0x71, 0x53, + 0x4d, 0x1c, 0x41, 0x4e, 0xca, 0xd9, 0xa4, 0xd7, + 0x32, 0xfe, 0x95, 0xb1, 0x0e, 0xea, 0x37, 0x0d, + 0xa6, 0x2f, 0x05, 0xde, 0x2c, 0x39, 0x3b, 0x1a, + 0x63, 0x33, 0x03, 0xea, 0x74, 0x1b, 0x6b, 0x32, + 0x69, 0xc9, 0x7f, 0x70, 0x4b, 0x35, 0x27, 0x02, + 0xc9, 0xae, 0x79, 0x92, 0x2f, 0x7b, 0xe8, 0xd1, + 0x0d, 0xb6, 0x7f, 0x02, 0x6a, 0x81, 0x45, 0xde, + 0x41, 0xb3, 0x0c, 0x0a, 0x42, 0xbf, 0x92, 0x3b, + 0xac, 0x5f, 0x75, 0x04, 0xc2, 0x48, 0x60, 0x4b, + 0x9f, 0xaa, 0x57, 0xed, 0x6b, 0x32, 0x46, 0xc6, + 0xba, 0x15, 0x8e, 0x36, 0xc6, 0x44, 0xf8, 0xb9, + 0x54, 0x8f, 0xcf, 0x4f, 0x07, 0xe0, 0x54, 0xa5, + 0x6f, 0x76, 0x86, 0x74, 0x05, 0x44, 0x40, 0xbc, + 0x0d, 0xcb, 0xbc, 0x9b, 0x52, 0x8f, 0x64, 0xa0, + 0x17, 0x06, 0xe0, 0x5b, 0x0b, 0x91, 0x10, 0x6f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 4096,[p>q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x30, 0x60, 0xcf, 0xaa, 0xed, 0x64, 0xa0, + 0xe2, 0xa4, 0x24, 0x0d, 0x59, 0x5f, 0x1b, 0xda, + 0x92, 0x6e, 0xc1, 0xb6, 0x77, 0x25, 0x26, 0x93, + 0xbc, 0x00, 0xba, 0xc9, 0x1c, 0x22, 0xb4, 0x91, + 0x31, 0x92, 0xa9, 0x97, 0xf2, 0xac, 0x68, 0x92, + 0x60, 0xca, 0x56, 0xc4, 0xb7, 0xc2, 0x97, 0x7b, + 0x5a, 0x2c, 0x99, 0x73, 0xf1, 0x20, 0x7a, 0xe4, + 0xa3, 0xe5, 0x9a, 0x45, 0x5f, 0xd7, 0x65, 0x62, + 0xbf, 0x85, 0xa1, 0x48, 0xbb, 0x6a, 0xfd, 0xd8, + 0x7a, 0xa5, 0x5f, 0x7b, 0xcf, 0xf7, 0x30, 0x2e, + 0x52, 0x61, 0x13, 0x81, 0x63, 0x73, 0x85, 0xcb, + 0x60, 0xdb, 0x57, 0xb2, 0xfc, 0x55, 0x6a, 0xee, + 0x97, 0xf4, 0x0c, 0x76, 0xd7, 0x57, 0xe1, 0x95, + 0xd4, 0x02, 0xc7, 0x3f, 0x8c, 0x5f, 0xe3, 0x83, + 0x78, 0x58, 0x5e, 0x34, 0x59, 0xfa, 0x64, 0xc8, + 0x26, 0x3e, 0xf3, 0x5e, 0x06, 0x96, 0xd0, 0x63, + 0xaa, 0x6b, 0xf0, 0x3f, 0x3c, 0x7b, 0xd9, 0x98, + 0x0c, 0x97, 0x49, 0xe4, 0x10, 0x5a, 0x6d, 0x57, + 0x46, 0x61, 0xd1, 0x78, 0x35, 0x06, 0xf0, 0x5a, + 0x68, 0xe1, 0xdd, 0xac, 0x3a, 0x95, 0xfb, 0x4f, + 0xd9, 0x46, 0x6b, 0x98, 0x55, 0x6e, 0x4b, 0x39, + 0x9f, 0xbb, 0x05, 0x49, 0xbf, 0x53, 0x93, 0xd4, + 0x39, 0xcd, 0xed, 0xa2, 0xe9, 0x02, 0x81, 0xd3, + 0x69, 0x08, 0x02, 0x7c, 0xa8, 0xc1, 0xd5, 0xa1, + 0x58, 0xe3, 0x81, 0xea, 0x8b, 0xd2, 0x23, 0x4c, + 0x1c, 0x99, 0x4d, 0x81, 0x8d, 0x82, 0x1e, 0x85, + 0xf7, 0xa9, 0xf8, 0xe6, 0x53, 0x8e, 0x85, 0xcb, + 0x79, 0xbb, 0x89, 0x49, 0xce, 0x3c, 0x18, 0x5d, + 0xa4, 0x3c, 0x8c, 0x13, 0x7c, 0xe2, 0xc6, 0x97, + 0xf0, 0xbe, 0xfa, 0xb6, 0x87, 0xbe, 0xc0, 0xed, + 0x70, 0x39, 0x8e, 0x0b, 0x23, 0xb9, 0x51, 0x83, + 0x38, 0xc8, 0x37, 0x3e, 0x38, 0x7a, 0x82, 0xfb}, + /* 1024,[p<q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0x3a, 0x18, 0xa4, 0x1c, 0x3c, 0x49, 0x09, + 0xd0, 0x84, 0x4a, 0x8c, 0x7c, 0xce, 0xdf, 0x9e, + 0x90, 0x7d, 0xc4, 0xca, 0x7e, 0x2d, 0x3d, 0xbc, + 0x09, 0x71, 0x79, 0xd0, 0xc0, 0xae, 0xa6, 0xc1, + 0x9d, 0xf0, 0x16, 0xf0, 0x1f, 0x68, 0x9a, 0xc5, + 0x2b, 0xf3, 0x5a, 0xfc, 0x2c, 0xf5, 0xa7, 0xec, + 0xd9, 0xa2, 0xac, 0x49, 0xcc, 0x76, 0x9c, 0xd8, + 0x4c, 0x59, 0x5e, 0x38, 0xd2, 0x85, 0xd3, 0x3b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 2048,[p<q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x27, 0x92, 0x4a, 0x85, 0xe8, 0x8b, 0x55, + 0xba, 0x00, 0xf8, 0x21, 0x91, 0x28, 0xbd, 0x37, + 0x24, 0xc6, 0xb7, 0xd1, 0xdf, 0xe5, 0x62, 0x9e, + 0xf1, 0x97, 0x92, 0x5f, 0xec, 0xaf, 0xf5, 0xed, + 0xb9, 0xcd, 0xf3, 0xa7, 0xbe, 0xfd, 0x8e, 0xa2, + 0xe8, 0xdd, 0x37, 0x07, 0x13, 0x8b, 0x3f, 0xf8, + 0x7c, 0x3c, 0x39, 0xc5, 0x7f, 0x43, 0x9e, 0x56, + 0x2e, 0x2a, 0xa8, 0x05, 0xa3, 0x9d, 0x7c, 0xd7, + 0x99, 0x66, 0xd2, 0xec, 0xe7, 0x84, 0x5f, 0x1d, + 0xbc, 0x16, 0xbe, 0xe9, 0x99, 0x99, 0xe4, 0xd0, + 0xbf, 0x9e, 0xec, 0xa4, 0x5f, 0xcd, 0xa8, 0xa8, + 0x50, 0x00, 0x35, 0xfe, 0x6b, 0x5f, 0x03, 0xbc, + 0x2f, 0x6d, 0x1b, 0xfc, 0x4d, 0x4d, 0x0a, 0x37, + 0x23, 0x96, 0x1a, 0xf0, 0xcd, 0xce, 0x4a, 0x01, + 0xee, 0xc8, 0x2d, 0x7f, 0x54, 0x58, 0xec, 0x19, + 0xe7, 0x1b, 0x90, 0xee, 0xef, 0x7d, 0xff, 0x61, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 4096,[p<q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x96, 0x91, 0xf7, 0x52, 0x11, 0xdc, 0x4a, 0x26, + 0xf8, 0x51, 0xa6, 0x1a, 0x75, 0xd1, 0xbe, 0x32, + 0xe9, 0x34, 0x39, 0x1f, 0xb3, 0x05, 0x58, 0x35, + 0xaa, 0x51, 0xf6, 0x53, 0x1e, 0xa5, 0x5f, 0x38, + 0x02, 0xa8, 0xdb, 0xa5, 0x58, 0xfc, 0x95, 0x21, + 0xa3, 0x6a, 0x1c, 0x4e, 0xd5, 0x64, 0x1a, 0x94, + 0xeb, 0xfb, 0xca, 0x56, 0x6e, 0xfc, 0xd7, 0xb1, + 0x82, 0x95, 0x8a, 0x8c, 0x17, 0xbd, 0x24, 0xd9, + 0xfd, 0xc9, 0x22, 0x3d, 0x52, 0x90, 0x44, 0xf6, + 0xfc, 0xb5, 0x63, 0xca, 0xc9, 0x6f, 0x9b, 0xbd, + 0x1d, 0x98, 0xe7, 0xe2, 0x5c, 0x5c, 0x89, 0x2f, + 0xdd, 0x54, 0x18, 0x78, 0xdb, 0x12, 0xf5, 0xef, + 0xfe, 0x4e, 0x1b, 0x9e, 0xaa, 0x3e, 0x77, 0x36, + 0x8e, 0xa9, 0x46, 0xb3, 0xa2, 0x45, 0x3c, 0xa4, + 0xb3, 0xc4, 0xf1, 0x82, 0xcc, 0x49, 0x6b, 0xaa, + 0xf6, 0x41, 0x1d, 0xa0, 0x12, 0x29, 0xfc, 0xcc, + 0xbf, 0xf4, 0xd3, 0x90, 0xe5, 0x3e, 0x77, 0x86, + 0x35, 0xe6, 0x76, 0xcd, 0x0c, 0xaa, 0x8c, 0xae, + 0xe1, 0x07, 0x7a, 0xd3, 0xd4, 0x5c, 0xa4, 0x46, + 0xa0, 0x46, 0xb9, 0x04, 0x08, 0x5d, 0xce, 0xc7, + 0x78, 0x04, 0x48, 0xde, 0x46, 0xfc, 0x6f, 0xa0, + 0xcf, 0x2c, 0x91, 0x87, 0xed, 0xb8, 0x51, 0xd7, + 0xb8, 0x0d, 0x88, 0xa3, 0xf2, 0x92, 0xdf, 0x6c, + 0x0e, 0x54, 0x84, 0xc0, 0x39, 0xf4, 0xf0, 0xa3, + 0x94, 0x42, 0xdd, 0xcb, 0x4d, 0xef, 0x74, 0x37, + 0x33, 0xc8, 0x96, 0x01, 0xa3, 0xda, 0x12, 0xdf, + 0x33, 0xf5, 0x58, 0x80, 0xc2, 0xdc, 0x8b, 0xcb, + 0x40, 0x7d, 0x78, 0xbb, 0x3e, 0x40, 0xa3, 0xbe, + 0xd2, 0x94, 0x34, 0xa0, 0x47, 0xd3, 0x3c, 0x62, + 0x65, 0x92, 0x5c, 0xdd, 0x3c, 0xa8, 0x4f, 0xc6, + 0x05, 0xa7, 0x26, 0x91, 0xd6, 0xf7, 0x8b, 0x41, + 0xf3, 0x52, 0x08, 0x3d, 0x95, 0x6e, 0x70, 0xff}}; + +unsigned char dq[6][256] = + /* 1024,[p>q] */{{0xa0, 0x3a, 0x18, 0xa4, 0x1c, 0x3c, 0x49, 0x09, + 0xd0, 0x84, 0x4a, 0x8c, 0x7c, 0xce, 0xdf, 0x9e, + 0x90, 0x7d, 0xc4, 0xca, 0x7e, 0x2d, 0x3d, 0xbc, + 0x09, 0x71, 0x79, 0xd0, 0xc0, 0xae, 0xa6, 0xc1, + 0x9d, 0xf0, 0x16, 0xf0, 0x1f, 0x68, 0x9a, 0xc5, + 0x2b, 0xf3, 0x5a, 0xfc, 0x2c, 0xf5, 0xa7, 0xec, + 0xd9, 0xa2, 0xac, 0x49, 0xcc, 0x76, 0x9c, 0xd8, + 0x4c, 0x59, 0x5e, 0x38, 0xd2, 0x85, 0xd3, 0x3b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 2048,[p>q] */ {0x68, 0x27, 0x92, 0x4a, 0x85, 0xe8, 0x8b, 0x55, + 0xba, 0x00, 0xf8, 0x21, 0x91, 0x28, 0xbd, 0x37, + 0x24, 0xc6, 0xb7, 0xd1, 0xdf, 0xe5, 0x62, 0x9e, + 0xf1, 0x97, 0x92, 0x5f, 0xec, 0xaf, 0xf5, 0xed, + 0xb9, 0xcd, 0xf3, 0xa7, 0xbe, 0xfd, 0x8e, 0xa2, + 0xe8, 0xdd, 0x37, 0x07, 0x13, 0x8b, 0x3f, 0xf8, + 0x7c, 0x3c, 0x39, 0xc5, 0x7f, 0x43, 0x9e, 0x56, + 0x2e, 0x2a, 0xa8, 0x05, 0xa3, 0x9d, 0x7c, 0xd7, + 0x99, 0x66, 0xd2, 0xec, 0xe7, 0x84, 0x5f, 0x1d, + 0xbc, 0x16, 0xbe, 0xe9, 0x99, 0x99, 0xe4, 0xd0, + 0xbf, 0x9e, 0xec, 0xa4, 0x5f, 0xcd, 0xa8, 0xa8, + 0x50, 0x00, 0x35, 0xfe, 0x6b, 0x5f, 0x03, 0xbc, + 0x2f, 0x6d, 0x1b, 0xfc, 0x4d, 0x4d, 0x0a, 0x37, + 0x23, 0x96, 0x1a, 0xf0, 0xcd, 0xce, 0x4a, 0x01, + 0xee, 0xc8, 0x2d, 0x7f, 0x54, 0x58, 0xec, 0x19, + 0xe7, 0x1b, 0x90, 0xee, 0xef, 0x7d, 0xff, 0x61, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 4096,[p>q] */ {0x96, 0x91, 0xf7, 0x52, 0x11, 0xdc, 0x4a, 0x26, + 0xf8, 0x51, 0xa6, 0x1a, 0x75, 0xd1, 0xbe, 0x32, + 0xe9, 0x34, 0x39, 0x1f, 0xb3, 0x05, 0x58, 0x35, + 0xaa, 0x51, 0xf6, 0x53, 0x1e, 0xa5, 0x5f, 0x38, + 0x02, 0xa8, 0xdb, 0xa5, 0x58, 0xfc, 0x95, 0x21, + 0xa3, 0x6a, 0x1c, 0x4e, 0xd5, 0x64, 0x1a, 0x94, + 0xeb, 0xfb, 0xca, 0x56, 0x6e, 0xfc, 0xd7, 0xb1, + 0x82, 0x95, 0x8a, 0x8c, 0x17, 0xbd, 0x24, 0xd9, + 0xfd, 0xc9, 0x22, 0x3d, 0x52, 0x90, 0x44, 0xf6, + 0xfc, 0xb5, 0x63, 0xca, 0xc9, 0x6f, 0x9b, 0xbd, + 0x1d, 0x98, 0xe7, 0xe2, 0x5c, 0x5c, 0x89, 0x2f, + 0xdd, 0x54, 0x18, 0x78, 0xdb, 0x12, 0xf5, 0xef, + 0xfe, 0x4e, 0x1b, 0x9e, 0xaa, 0x3e, 0x77, 0x36, + 0x8e, 0xa9, 0x46, 0xb3, 0xa2, 0x45, 0x3c, 0xa4, + 0xb3, 0xc4, 0xf1, 0x82, 0xcc, 0x49, 0x6b, 0xaa, + 0xf6, 0x41, 0x1d, 0xa0, 0x12, 0x29, 0xfc, 0xcc, + 0xbf, 0xf4, 0xd3, 0x90, 0xe5, 0x3e, 0x77, 0x86, + 0x35, 0xe6, 0x76, 0xcd, 0x0c, 0xaa, 0x8c, 0xae, + 0xe1, 0x07, 0x7a, 0xd3, 0xd4, 0x5c, 0xa4, 0x46, + 0xa0, 0x46, 0xb9, 0x04, 0x08, 0x5d, 0xce, 0xc7, + 0x78, 0x04, 0x48, 0xde, 0x46, 0xfc, 0x6f, 0xa0, + 0xcf, 0x2c, 0x91, 0x87, 0xed, 0xb8, 0x51, 0xd7, + 0xb8, 0x0d, 0x88, 0xa3, 0xf2, 0x92, 0xdf, 0x6c, + 0x0e, 0x54, 0x84, 0xc0, 0x39, 0xf4, 0xf0, 0xa3, + 0x94, 0x42, 0xdd, 0xcb, 0x4d, 0xef, 0x74, 0x37, + 0x33, 0xc8, 0x96, 0x01, 0xa3, 0xda, 0x12, 0xdf, + 0x33, 0xf5, 0x58, 0x80, 0xc2, 0xdc, 0x8b, 0xcb, + 0x40, 0x7d, 0x78, 0xbb, 0x3e, 0x40, 0xa3, 0xbe, + 0xd2, 0x94, 0x34, 0xa0, 0x47, 0xd3, 0x3c, 0x62, + 0x65, 0x92, 0x5c, 0xdd, 0x3c, 0xa8, 0x4f, 0xc6, + 0x05, 0xa7, 0x26, 0x91, 0xd6, 0xf7, 0x8b, 0x41, + 0xf3, 0x52, 0x08, 0x3d, 0x95, 0x6e, 0x70, 0xff}, + /* 1024,[p<q] */ {0xa7, 0xcf, 0xa2, 0x18, 0x2c, 0xa9, 0xb4, 0xb9, + 0xf5, 0x9e, 0xc9, 0x04, 0x16, 0xd9, 0xa6, 0x8b, + 0x90, 0x4a, 0x19, 0x6d, 0x64, 0xb7, 0x17, 0x67, + 0x53, 0xfa, 0x4e, 0x8d, 0xde, 0xa6, 0x94, 0x32, + 0x5d, 0xcf, 0x58, 0x3e, 0x90, 0xbb, 0x30, 0x19, + 0x96, 0x38, 0x95, 0xb6, 0xca, 0x2f, 0xfa, 0x22, + 0x81, 0x65, 0x3b, 0x3c, 0x95, 0x9e, 0x79, 0x75, + 0xe4, 0x93, 0x50, 0xf1, 0x88, 0x6b, 0xc1, 0x87, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 2048,[p<q] */ {0xed, 0x10, 0x2a, 0xcd, 0xb2, 0x68, 0x71, 0x53, + 0x4d, 0x1c, 0x41, 0x4e, 0xca, 0xd9, 0xa4, 0xd7, + 0x32, 0xfe, 0x95, 0xb1, 0x0e, 0xea, 0x37, 0x0d, + 0xa6, 0x2f, 0x05, 0xde, 0x2c, 0x39, 0x3b, 0x1a, + 0x63, 0x33, 0x03, 0xea, 0x74, 0x1b, 0x6b, 0x32, + 0x69, 0xc9, 0x7f, 0x70, 0x4b, 0x35, 0x27, 0x02, + 0xc9, 0xae, 0x79, 0x92, 0x2f, 0x7b, 0xe8, 0xd1, + 0x0d, 0xb6, 0x7f, 0x02, 0x6a, 0x81, 0x45, 0xde, + 0x41, 0xb3, 0x0c, 0x0a, 0x42, 0xbf, 0x92, 0x3b, + 0xac, 0x5f, 0x75, 0x04, 0xc2, 0x48, 0x60, 0x4b, + 0x9f, 0xaa, 0x57, 0xed, 0x6b, 0x32, 0x46, 0xc6, + 0xba, 0x15, 0x8e, 0x36, 0xc6, 0x44, 0xf8, 0xb9, + 0x54, 0x8f, 0xcf, 0x4f, 0x07, 0xe0, 0x54, 0xa5, + 0x6f, 0x76, 0x86, 0x74, 0x05, 0x44, 0x40, 0xbc, + 0x0d, 0xcb, 0xbc, 0x9b, 0x52, 0x8f, 0x64, 0xa0, + 0x17, 0x06, 0xe0, 0x5b, 0x0b, 0x91, 0x10, 0x6f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 4096,[p<q] */ {0x9c, 0x30, 0x60, 0xcf, 0xaa, 0xed, 0x64, 0xa0, + 0xe2, 0xa4, 0x24, 0x0d, 0x59, 0x5f, 0x1b, 0xda, + 0x92, 0x6e, 0xc1, 0xb6, 0x77, 0x25, 0x26, 0x93, + 0xbc, 0x00, 0xba, 0xc9, 0x1c, 0x22, 0xb4, 0x91, + 0x31, 0x92, 0xa9, 0x97, 0xf2, 0xac, 0x68, 0x92, + 0x60, 0xca, 0x56, 0xc4, 0xb7, 0xc2, 0x97, 0x7b, + 0x5a, 0x2c, 0x99, 0x73, 0xf1, 0x20, 0x7a, 0xe4, + 0xa3, 0xe5, 0x9a, 0x45, 0x5f, 0xd7, 0x65, 0x62, + 0xbf, 0x85, 0xa1, 0x48, 0xbb, 0x6a, 0xfd, 0xd8, + 0x7a, 0xa5, 0x5f, 0x7b, 0xcf, 0xf7, 0x30, 0x2e, + 0x52, 0x61, 0x13, 0x81, 0x63, 0x73, 0x85, 0xcb, + 0x60, 0xdb, 0x57, 0xb2, 0xfc, 0x55, 0x6a, 0xee, + 0x97, 0xf4, 0x0c, 0x76, 0xd7, 0x57, 0xe1, 0x95, + 0xd4, 0x02, 0xc7, 0x3f, 0x8c, 0x5f, 0xe3, 0x83, + 0x78, 0x58, 0x5e, 0x34, 0x59, 0xfa, 0x64, 0xc8, + 0x26, 0x3e, 0xf3, 0x5e, 0x06, 0x96, 0xd0, 0x63, + 0xaa, 0x6b, 0xf0, 0x3f, 0x3c, 0x7b, 0xd9, 0x98, + 0x0c, 0x97, 0x49, 0xe4, 0x10, 0x5a, 0x6d, 0x57, + 0x46, 0x61, 0xd1, 0x78, 0x35, 0x06, 0xf0, 0x5a, + 0x68, 0xe1, 0xdd, 0xac, 0x3a, 0x95, 0xfb, 0x4f, + 0xd9, 0x46, 0x6b, 0x98, 0x55, 0x6e, 0x4b, 0x39, + 0x9f, 0xbb, 0x05, 0x49, 0xbf, 0x53, 0x93, 0xd4, + 0x39, 0xcd, 0xed, 0xa2, 0xe9, 0x02, 0x81, 0xd3, + 0x69, 0x08, 0x02, 0x7c, 0xa8, 0xc1, 0xd5, 0xa1, + 0x58, 0xe3, 0x81, 0xea, 0x8b, 0xd2, 0x23, 0x4c, + 0x1c, 0x99, 0x4d, 0x81, 0x8d, 0x82, 0x1e, 0x85, + 0xf7, 0xa9, 0xf8, 0xe6, 0x53, 0x8e, 0x85, 0xcb, + 0x79, 0xbb, 0x89, 0x49, 0xce, 0x3c, 0x18, 0x5d, + 0xa4, 0x3c, 0x8c, 0x13, 0x7c, 0xe2, 0xc6, 0x97, + 0xf0, 0xbe, 0xfa, 0xb6, 0x87, 0xbe, 0xc0, 0xed, + 0x70, 0x39, 0x8e, 0x0b, 0x23, 0xb9, 0x51, 0x83, + 0x38, 0xc8, 0x37, 0x3e, 0x38, 0x7a, 0x82, 0xfb}}; + +unsigned char p[6][264] = + /* 1024,[p>q] */{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfb, 0xb7, 0x73, 0x24, 0x42, 0xfe, 0x8f, 0x16, + 0xf0, 0x6e, 0x2d, 0x86, 0x22, 0x46, 0x79, 0xd1, + 0x58, 0x6f, 0x26, 0x24, 0x17, 0x12, 0xa3, 0x1a, + 0xfd, 0xf7, 0x75, 0xd4, 0xcd, 0xf9, 0xde, 0x4b, + 0x8c, 0xb7, 0x04, 0x5d, 0xd9, 0x18, 0xc8, 0x26, + 0x61, 0x54, 0xe0, 0x92, 0x2f, 0x47, 0xf7, 0x33, + 0xc2, 0x17, 0xd8, 0xda, 0xe0, 0x6d, 0xb6, 0x30, + 0xd6, 0xdc, 0xf9, 0x6a, 0x4c, 0xa1, 0xa2, 0x4b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 2048,[p>q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf4, 0x4f, 0x5e, 0x42, 0x46, 0x39, 0x1f, 0x48, + 0x2b, 0x2f, 0x52, 0x96, 0xe3, 0x60, 0x2e, 0xb3, + 0x4a, 0xa1, 0x36, 0x42, 0x77, 0x10, 0xf7, 0xc0, + 0x41, 0x6d, 0x40, 0x3f, 0xd6, 0x9d, 0x4b, 0x29, + 0x13, 0x0c, 0xfe, 0xbe, 0xf3, 0x4e, 0x88, 0x5a, + 0xbd, 0xb1, 0xa8, 0xa0, 0xa5, 0xf0, 0xe9, 0xb5, + 0xc3, 0x3e, 0x1f, 0xc3, 0xbf, 0xc2, 0x85, 0xb1, + 0xae, 0x17, 0xe4, 0x0c, 0xc6, 0x7a, 0x19, 0x13, + 0xdd, 0x56, 0x37, 0x19, 0x81, 0x5e, 0xba, 0xf8, + 0x51, 0x4c, 0x2a, 0x7a, 0xa0, 0x01, 0x8e, 0x63, + 0xb6, 0xc6, 0x31, 0xdc, 0x31, 0x5a, 0x46, 0x23, + 0x57, 0x16, 0x42, 0x3d, 0x11, 0xff, 0x58, 0x03, + 0x4e, 0x61, 0x06, 0x45, 0x70, 0x36, 0x06, 0x91, + 0x9f, 0x5c, 0x7c, 0xe2, 0x66, 0x0c, 0xd1, 0x48, + 0xbd, 0x9e, 0xfc, 0x12, 0x3d, 0x9c, 0x54, 0xb6, + 0x70, 0x55, 0x90, 0xd0, 0x06, 0xcf, 0xcf, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 4096,[p>q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xea, 0x48, 0x91, 0x37, 0x80, 0x64, 0x16, 0xf1, + 0x53, 0xf6, 0x36, 0x14, 0x06, 0x0e, 0xa9, 0xc7, + 0xdb, 0xa6, 0x22, 0x91, 0xb2, 0xb7, 0xb9, 0xdd, + 0x9a, 0x01, 0x18, 0x2d, 0xaa, 0x34, 0x0e, 0xd9, + 0xca, 0x5b, 0xfe, 0x63, 0xec, 0x02, 0x9c, 0xdb, + 0x91, 0x2f, 0x82, 0x27, 0x13, 0xa3, 0xe3, 0x39, + 0x07, 0x42, 0xe6, 0x2d, 0xe9, 0xb0, 0xb8, 0x56, + 0xf5, 0xd8, 0x67, 0x68, 0x0f, 0xc3, 0x18, 0x14, + 0x1f, 0x48, 0x71, 0xed, 0x19, 0x20, 0x7c, 0xc4, + 0xb7, 0xf8, 0x0f, 0x39, 0xb7, 0xf2, 0xc8, 0x45, + 0x7b, 0x91, 0x9d, 0x42, 0x15, 0x2d, 0x48, 0xb1, + 0x11, 0x49, 0x03, 0x8c, 0x7a, 0x80, 0x20, 0x65, + 0xe3, 0xee, 0x12, 0xb2, 0x43, 0x03, 0xd2, 0x60, + 0xbe, 0x04, 0x2a, 0xdf, 0x52, 0x8f, 0xd5, 0x45, + 0x34, 0x84, 0x8d, 0x4e, 0x86, 0xf7, 0x97, 0x2c, + 0x39, 0x5e, 0x6d, 0x0d, 0x09, 0xe2, 0x38, 0x95, + 0x7f, 0xa1, 0xe8, 0x5e, 0xda, 0xb9, 0xc6, 0x64, + 0x12, 0xe2, 0xee, 0xd6, 0x18, 0x87, 0xa4, 0x02, + 0xe9, 0x92, 0xba, 0x34, 0x4f, 0x8a, 0x68, 0x87, + 0x9d, 0x52, 0xcc, 0x82, 0x57, 0xe0, 0xf8, 0xf7, + 0xc5, 0xe9, 0xa1, 0x64, 0x80, 0x25, 0x70, 0xd6, + 0x6f, 0x98, 0x87, 0xee, 0x9e, 0xfd, 0x5d, 0xbe, + 0x56, 0xb4, 0xe4, 0x74, 0x5d, 0x83, 0xc2, 0xbd, + 0x1d, 0x8c, 0x03, 0xba, 0xfd, 0x22, 0xc0, 0x72, + 0x05, 0x55, 0x42, 0xdf, 0xd1, 0xbb, 0x34, 0xf2, + 0x2a, 0xe5, 0xf4, 0x42, 0x54, 0x43, 0x2d, 0xc8, + 0xf3, 0x7e, 0xf5, 0x59, 0x7d, 0x55, 0xc8, 0xb1, + 0x36, 0x99, 0x4d, 0xee, 0xb5, 0x5a, 0x24, 0x8c, + 0x76, 0x5a, 0xd2, 0x1d, 0x3b, 0x54, 0x29, 0xe3, + 0xe9, 0x1e, 0x78, 0x11, 0xcb, 0x9e, 0x21, 0x64, + 0x28, 0x56, 0x55, 0x10, 0xb5, 0x95, 0xfa, 0x44, + 0xd5, 0x2c, 0x52, 0xdd, 0x54, 0xb7, 0xc4, 0x79}, + /* 1024,[p<q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0x57, 0x24, 0xf6, 0x2a, 0x5a, 0x6d, 0x8e, + 0xb8, 0xc6, 0x6f, 0xd2, 0xbb, 0x36, 0x4f, 0x6d, + 0xd8, 0xbc, 0xa7, 0x2f, 0xbd, 0x43, 0xdc, 0x9a, + 0x0e, 0x2a, 0x36, 0xb9, 0x21, 0x05, 0xfa, 0x22, + 0x6c, 0xe8, 0x22, 0x68, 0x2f, 0x1c, 0xe8, 0x27, + 0xc1, 0xed, 0x08, 0x7a, 0x43, 0x70, 0x7b, 0xe3, + 0x46, 0x74, 0x02, 0x6e, 0xb2, 0xb1, 0xeb, 0x44, + 0x72, 0x86, 0x0d, 0x55, 0x3b, 0xc8, 0xbc, 0xd9, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 2048,[p<q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe9, 0xd4, 0x98, 0x41, 0xe0, 0xe0, 0xa6, 0xad, + 0x0d, 0x51, 0x78, 0x57, 0x13, 0x3e, 0x36, 0xdc, + 0x72, 0xc1, 0xbd, 0xd9, 0x0f, 0x91, 0x74, 0xb5, + 0x2e, 0x26, 0x57, 0x0f, 0x37, 0x36, 0x40, 0xf1, + 0xc1, 0x85, 0xe7, 0xea, 0x8e, 0x2e, 0xd7, 0xf1, + 0xe4, 0xeb, 0xb9, 0x51, 0xf7, 0x0a, 0x58, 0x02, + 0x36, 0x33, 0xb0, 0x09, 0x7a, 0xec, 0x67, 0xc6, + 0xdc, 0xb8, 0x00, 0xfc, 0x1a, 0x67, 0xf9, 0xbb, + 0x05, 0x63, 0x61, 0x0f, 0x08, 0xeb, 0xc8, 0x74, + 0x6a, 0xd1, 0x29, 0x77, 0x21, 0x36, 0xeb, 0x1d, + 0xda, 0xf4, 0x64, 0x36, 0x45, 0x0d, 0x31, 0x83, + 0x32, 0xa8, 0x49, 0x82, 0xfe, 0x5d, 0x28, 0xdb, + 0xe5, 0xb3, 0xe9, 0x12, 0x40, 0x7c, 0x3e, 0x0e, + 0x03, 0x10, 0x0d, 0x87, 0xd4, 0x36, 0xee, 0x40, + 0x9e, 0xec, 0x1c, 0xf8, 0x5e, 0x80, 0xab, 0xa0, + 0x79, 0xb2, 0xe6, 0x10, 0x6b, 0x97, 0xbc, 0xed, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 4096,[p<q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe1, 0xda, 0xf2, 0xfb, 0x1a, 0xca, 0x6f, 0x3a, + 0x74, 0x7a, 0x79, 0x27, 0xb0, 0xba, 0x9d, 0x4c, + 0x5d, 0xce, 0x55, 0xaf, 0x8c, 0x88, 0x04, 0x50, + 0x7f, 0x7a, 0xf1, 0x7c, 0xad, 0xf8, 0x0e, 0xd4, + 0x03, 0xfd, 0x49, 0x78, 0x05, 0x7a, 0xdf, 0xb2, + 0x75, 0x1f, 0x2a, 0x76, 0x40, 0x16, 0x27, 0xdf, + 0x61, 0xf9, 0xaf, 0x81, 0xa6, 0x7b, 0x43, 0x8a, + 0x43, 0xe0, 0x4f, 0xd2, 0x23, 0x9b, 0xb7, 0x46, + 0xfc, 0xad, 0xb3, 0x5b, 0xfb, 0xd8, 0x67, 0x72, + 0x7b, 0x10, 0x15, 0xb0, 0x2e, 0x27, 0x69, 0x9b, + 0xac, 0x65, 0x5b, 0xd3, 0x8a, 0x8a, 0xcd, 0xc7, + 0xcb, 0xfe, 0x24, 0xb5, 0x48, 0x9c, 0x70, 0xe7, + 0xfd, 0x75, 0x29, 0x6d, 0xff, 0x5d, 0xb2, 0xd1, + 0xd5, 0xfd, 0xea, 0x0d, 0x73, 0x67, 0xda, 0xf7, + 0x0d, 0xa7, 0x6a, 0x44, 0x32, 0x6e, 0x21, 0x80, + 0x71, 0x61, 0xac, 0x70, 0x1b, 0x3e, 0xfb, 0x33, + 0x1f, 0xef, 0x3d, 0x59, 0x57, 0xdd, 0xb3, 0x49, + 0x50, 0xd9, 0xb2, 0x33, 0x92, 0xff, 0xd3, 0x06, + 0x51, 0x8b, 0x38, 0x3d, 0xbe, 0x8a, 0xf6, 0x69, + 0xf0, 0x6a, 0x15, 0x86, 0x0c, 0x8c, 0xb6, 0x2b, + 0x34, 0x06, 0x6d, 0x4d, 0x6a, 0x7a, 0xa7, 0x71, + 0x36, 0xc2, 0xda, 0x4b, 0xe4, 0x94, 0x7a, 0xc3, + 0x94, 0x14, 0x4c, 0xf5, 0xeb, 0xdc, 0x4f, 0x22, + 0x15, 0x7e, 0xc7, 0x20, 0x56, 0xef, 0x68, 0xf5, + 0x5e, 0x64, 0x4c, 0xb0, 0xf4, 0xe7, 0x2e, 0x52, + 0xcd, 0xac, 0xe1, 0x02, 0x75, 0xc7, 0x1c, 0x4e, + 0xcd, 0xf0, 0x04, 0xc1, 0x24, 0x4a, 0xd1, 0xb0, + 0xe0, 0xbc, 0x35, 0x18, 0xdd, 0x60, 0xf5, 0x9e, + 0x3b, 0xde, 0x4e, 0xf0, 0x6b, 0xbc, 0xda, 0x93, + 0x98, 0x5b, 0x8b, 0x4b, 0xda, 0xfc, 0x77, 0xa9, + 0x08, 0x7a, 0xb9, 0xda, 0xc2, 0x73, 0x50, 0xe2, + 0xec, 0xfb, 0x0c, 0x5c, 0x60, 0x25, 0xa9, 0x7f}}; + +unsigned char q[6][256] = + /* 1024,[p>q] */{{0xf0, 0x57, 0x24, 0xf6, 0x2a, 0x5a, 0x6d, 0x8e, + 0xb8, 0xc6, 0x6f, 0xd2, 0xbb, 0x36, 0x4f, 0x6d, + 0xd8, 0xbc, 0xa7, 0x2f, 0xbd, 0x43, 0xdc, 0x9a, + 0x0e, 0x2a, 0x36, 0xb9, 0x21, 0x05, 0xfa, 0x22, + 0x6c, 0xe8, 0x22, 0x68, 0x2f, 0x1c, 0xe8, 0x27, + 0xc1, 0xed, 0x08, 0x7a, 0x43, 0x70, 0x7b, 0xe3, + 0x46, 0x74, 0x02, 0x6e, 0xb2, 0xb1, 0xeb, 0x44, + 0x72, 0x86, 0x0d, 0x55, 0x3b, 0xc8, 0xbc, 0xd9, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 2048,[p>q] */ {0xe9, 0xd4, 0x98, 0x41, 0xe0, 0xe0, 0xa6, 0xad, + 0x0d, 0x51, 0x78, 0x57, 0x13, 0x3e, 0x36, 0xdc, + 0x72, 0xc1, 0xbd, 0xd9, 0x0f, 0x91, 0x74, 0xb5, + 0x2e, 0x26, 0x57, 0x0f, 0x37, 0x36, 0x40, 0xf1, + 0xc1, 0x85, 0xe7, 0xea, 0x8e, 0x2e, 0xd7, 0xf1, + 0xe4, 0xeb, 0xb9, 0x51, 0xf7, 0x0a, 0x58, 0x02, + 0x36, 0x33, 0xb0, 0x09, 0x7a, 0xec, 0x67, 0xc6, + 0xdc, 0xb8, 0x00, 0xfc, 0x1a, 0x67, 0xf9, 0xbb, + 0x05, 0x63, 0x61, 0x0f, 0x08, 0xeb, 0xc8, 0x74, + 0x6a, 0xd1, 0x29, 0x77, 0x21, 0x36, 0xeb, 0x1d, + 0xda, 0xf4, 0x64, 0x36, 0x45, 0x0d, 0x31, 0x83, + 0x32, 0xa8, 0x49, 0x82, 0xfe, 0x5d, 0x28, 0xdb, + 0xe5, 0xb3, 0xe9, 0x12, 0x40, 0x7c, 0x3e, 0x0e, + 0x03, 0x10, 0x0d, 0x87, 0xd4, 0x36, 0xee, 0x40, + 0x9e, 0xec, 0x1c, 0xf8, 0x5e, 0x80, 0xab, 0xa0, + 0x79, 0xb2, 0xe6, 0x10, 0x6b, 0x97, 0xbc, 0xed, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 4096,[p>q] */ {0xe1, 0xda, 0xf2, 0xfb, 0x1a, 0xca, 0x6f, 0x3a, + 0x74, 0x7a, 0x79, 0x27, 0xb0, 0xba, 0x9d, 0x4c, + 0x5d, 0xce, 0x55, 0xaf, 0x8c, 0x88, 0x04, 0x50, + 0x7f, 0x7a, 0xf1, 0x7c, 0xad, 0xf8, 0x0e, 0xd4, + 0x03, 0xfd, 0x49, 0x78, 0x05, 0x7a, 0xdf, 0xb2, + 0x75, 0x1f, 0x2a, 0x76, 0x40, 0x16, 0x27, 0xdf, + 0x61, 0xf9, 0xaf, 0x81, 0xa6, 0x7b, 0x43, 0x8a, + 0x43, 0xe0, 0x4f, 0xd2, 0x23, 0x9b, 0xb7, 0x46, + 0xfc, 0xad, 0xb3, 0x5b, 0xfb, 0xd8, 0x67, 0x72, + 0x7b, 0x10, 0x15, 0xb0, 0x2e, 0x27, 0x69, 0x9b, + 0xac, 0x65, 0x5b, 0xd3, 0x8a, 0x8a, 0xcd, 0xc7, + 0xcb, 0xfe, 0x24, 0xb5, 0x48, 0x9c, 0x70, 0xe7, + 0xfd, 0x75, 0x29, 0x6d, 0xff, 0x5d, 0xb2, 0xd1, + 0xd5, 0xfd, 0xea, 0x0d, 0x73, 0x67, 0xda, 0xf7, + 0x0d, 0xa7, 0x6a, 0x44, 0x32, 0x6e, 0x21, 0x80, + 0x71, 0x61, 0xac, 0x70, 0x1b, 0x3e, 0xfb, 0x33, + 0x1f, 0xef, 0x3d, 0x59, 0x57, 0xdd, 0xb3, 0x49, + 0x50, 0xd9, 0xb2, 0x33, 0x92, 0xff, 0xd3, 0x06, + 0x51, 0x8b, 0x38, 0x3d, 0xbe, 0x8a, 0xf6, 0x69, + 0xf0, 0x6a, 0x15, 0x86, 0x0c, 0x8c, 0xb6, 0x2b, + 0x34, 0x06, 0x6d, 0x4d, 0x6a, 0x7a, 0xa7, 0x71, + 0x36, 0xc2, 0xda, 0x4b, 0xe4, 0x94, 0x7a, 0xc3, + 0x94, 0x14, 0x4c, 0xf5, 0xeb, 0xdc, 0x4f, 0x22, + 0x15, 0x7e, 0xc7, 0x20, 0x56, 0xef, 0x68, 0xf5, + 0x5e, 0x64, 0x4c, 0xb0, 0xf4, 0xe7, 0x2e, 0x52, + 0xcd, 0xac, 0xe1, 0x02, 0x75, 0xc7, 0x1c, 0x4e, + 0xcd, 0xf0, 0x04, 0xc1, 0x24, 0x4a, 0xd1, 0xb0, + 0xe0, 0xbc, 0x35, 0x18, 0xdd, 0x60, 0xf5, 0x9e, + 0x3b, 0xde, 0x4e, 0xf0, 0x6b, 0xbc, 0xda, 0x93, + 0x98, 0x5b, 0x8b, 0x4b, 0xda, 0xfc, 0x77, 0xa9, + 0x08, 0x7a, 0xb9, 0xda, 0xc2, 0x73, 0x50, 0xe2, + 0xec, 0xfb, 0x0c, 0x5c, 0x60, 0x25, 0xa9, 0x7f}, + /* 1024,[p<q] */ {0xfb, 0xb7, 0x73, 0x24, 0x42, 0xfe, 0x8f, 0x16, + 0xf0, 0x6e, 0x2d, 0x86, 0x22, 0x46, 0x79, 0xd1, + 0x58, 0x6f, 0x26, 0x24, 0x17, 0x12, 0xa3, 0x1a, + 0xfd, 0xf7, 0x75, 0xd4, 0xcd, 0xf9, 0xde, 0x4b, + 0x8c, 0xb7, 0x04, 0x5d, 0xd9, 0x18, 0xc8, 0x26, + 0x61, 0x54, 0xe0, 0x92, 0x2f, 0x47, 0xf7, 0x33, + 0xc2, 0x17, 0xd8, 0xda, 0xe0, 0x6d, 0xb6, 0x30, + 0xd6, 0xdc, 0xf9, 0x6a, 0x4c, 0xa1, 0xa2, 0x4b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 2048,[p<q] */ {0xf4, 0x4f, 0x5e, 0x42, 0x46, 0x39, 0x1f, 0x48, + 0x2b, 0x2f, 0x52, 0x96, 0xe3, 0x60, 0x2e, 0xb3, + 0x4a, 0xa1, 0x36, 0x42, 0x77, 0x10, 0xf7, 0xc0, + 0x41, 0x6d, 0x40, 0x3f, 0xd6, 0x9d, 0x4b, 0x29, + 0x13, 0x0c, 0xfe, 0xbe, 0xf3, 0x4e, 0x88, 0x5a, + 0xbd, 0xb1, 0xa8, 0xa0, 0xa5, 0xf0, 0xe9, 0xb5, + 0xc3, 0x3e, 0x1f, 0xc3, 0xbf, 0xc2, 0x85, 0xb1, + 0xae, 0x17, 0xe4, 0x0c, 0xc6, 0x7a, 0x19, 0x13, + 0xdd, 0x56, 0x37, 0x19, 0x81, 0x5e, 0xba, 0xf8, + 0x51, 0x4c, 0x2a, 0x7a, 0xa0, 0x01, 0x8e, 0x63, + 0xb6, 0xc6, 0x31, 0xdc, 0x31, 0x5a, 0x46, 0x23, + 0x57, 0x16, 0x42, 0x3d, 0x11, 0xff, 0x58, 0x03, + 0x4e, 0x61, 0x06, 0x45, 0x70, 0x36, 0x06, 0x91, + 0x9f, 0x5c, 0x7c, 0xe2, 0x66, 0x0c, 0xd1, 0x48, + 0xbd, 0x9e, 0xfc, 0x12, 0x3d, 0x9c, 0x54, 0xb6, + 0x70, 0x55, 0x90, 0xd0, 0x06, 0xcf, 0xcf, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 4096,[p<q] */ {0xea, 0x48, 0x91, 0x37, 0x80, 0x64, 0x16, 0xf1, + 0x53, 0xf6, 0x36, 0x14, 0x06, 0x0e, 0xa9, 0xc7, + 0xdb, 0xa6, 0x22, 0x91, 0xb2, 0xb7, 0xb9, 0xdd, + 0x9a, 0x01, 0x18, 0x2d, 0xaa, 0x34, 0x0e, 0xd9, + 0xca, 0x5b, 0xfe, 0x63, 0xec, 0x02, 0x9c, 0xdb, + 0x91, 0x2f, 0x82, 0x27, 0x13, 0xa3, 0xe3, 0x39, + 0x07, 0x42, 0xe6, 0x2d, 0xe9, 0xb0, 0xb8, 0x56, + 0xf5, 0xd8, 0x67, 0x68, 0x0f, 0xc3, 0x18, 0x14, + 0x1f, 0x48, 0x71, 0xed, 0x19, 0x20, 0x7c, 0xc4, + 0xb7, 0xf8, 0x0f, 0x39, 0xb7, 0xf2, 0xc8, 0x45, + 0x7b, 0x91, 0x9d, 0x42, 0x15, 0x2d, 0x48, 0xb1, + 0x11, 0x49, 0x03, 0x8c, 0x7a, 0x80, 0x20, 0x65, + 0xe3, 0xee, 0x12, 0xb2, 0x43, 0x03, 0xd2, 0x60, + 0xbe, 0x04, 0x2a, 0xdf, 0x52, 0x8f, 0xd5, 0x45, + 0x34, 0x84, 0x8d, 0x4e, 0x86, 0xf7, 0x97, 0x2c, + 0x39, 0x5e, 0x6d, 0x0d, 0x09, 0xe2, 0x38, 0x95, + 0x7f, 0xa1, 0xe8, 0x5e, 0xda, 0xb9, 0xc6, 0x64, + 0x12, 0xe2, 0xee, 0xd6, 0x18, 0x87, 0xa4, 0x02, + 0xe9, 0x92, 0xba, 0x34, 0x4f, 0x8a, 0x68, 0x87, + 0x9d, 0x52, 0xcc, 0x82, 0x57, 0xe0, 0xf8, 0xf7, + 0xc5, 0xe9, 0xa1, 0x64, 0x80, 0x25, 0x70, 0xd6, + 0x6f, 0x98, 0x87, 0xee, 0x9e, 0xfd, 0x5d, 0xbe, + 0x56, 0xb4, 0xe4, 0x74, 0x5d, 0x83, 0xc2, 0xbd, + 0x1d, 0x8c, 0x03, 0xba, 0xfd, 0x22, 0xc0, 0x72, + 0x05, 0x55, 0x42, 0xdf, 0xd1, 0xbb, 0x34, 0xf2, + 0x2a, 0xe5, 0xf4, 0x42, 0x54, 0x43, 0x2d, 0xc8, + 0xf3, 0x7e, 0xf5, 0x59, 0x7d, 0x55, 0xc8, 0xb1, + 0x36, 0x99, 0x4d, 0xee, 0xb5, 0x5a, 0x24, 0x8c, + 0x76, 0x5a, 0xd2, 0x1d, 0x3b, 0x54, 0x29, 0xe3, + 0xe9, 0x1e, 0x78, 0x11, 0xcb, 0x9e, 0x21, 0x64, + 0x28, 0x56, 0x55, 0x10, 0xb5, 0x95, 0xfa, 0x44, + 0xd5, 0x2c, 0x52, 0xdd, 0x54, 0xb7, 0xc4, 0x79}}; + +unsigned char qinv[6][264] = + /* 1024,[p>q] */{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x83, 0xf1, 0xca, 0x06, 0x58, 0x4a, 0x04, 0x5e, + 0x96, 0xb5, 0x30, 0x32, 0x40, 0x36, 0x48, 0xb9, + 0x02, 0x0c, 0xe3, 0x37, 0xb7, 0x51, 0xbc, 0x22, + 0x26, 0x5d, 0x74, 0x03, 0x47, 0xd3, 0x33, 0x20, + 0x8e, 0x75, 0x62, 0xf2, 0x9d, 0x4e, 0xc8, 0x7d, + 0x5d, 0x8e, 0xb6, 0xd9, 0x69, 0x4a, 0x9a, 0xe1, + 0x36, 0x6e, 0x1c, 0xbe, 0x8a, 0x14, 0xb1, 0x85, + 0x39, 0x74, 0x7c, 0x25, 0xd8, 0xa4, 0x4f, 0xde, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 2048,[p>q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x57, 0xb7, 0x38, 0x88, 0xd1, 0x83, 0xa9, 0x9a, + 0x63, 0x07, 0x42, 0x22, 0x77, 0x55, 0x1a, 0x3d, + 0x9e, 0x18, 0xad, 0xf0, 0x6a, 0x91, 0xe8, 0xb5, + 0x5c, 0xef, 0xfe, 0xf9, 0x07, 0x7c, 0x84, 0x96, + 0x94, 0x8e, 0xcb, 0x3b, 0x16, 0xb7, 0x81, 0x55, + 0xcb, 0x2a, 0x3a, 0x57, 0xc1, 0x19, 0xd3, 0x79, + 0x95, 0x1c, 0x01, 0x0a, 0xa6, 0x35, 0xed, 0xcf, + 0x62, 0xd8, 0x4c, 0x5a, 0x12, 0x2a, 0x8d, 0x67, + 0xab, 0x5f, 0xa9, 0xe5, 0xa4, 0xa8, 0x77, 0x2a, + 0x1e, 0x94, 0x3b, 0xaf, 0xc7, 0x0a, 0xe3, 0xa4, + 0xc1, 0xf0, 0xf3, 0xa4, 0xdd, 0xff, 0xae, 0xfd, + 0x18, 0x92, 0xc8, 0xcb, 0x33, 0xbb, 0x0d, 0x0b, + 0x95, 0x90, 0xe9, 0x63, 0xa6, 0x91, 0x10, 0xfb, + 0x34, 0xdb, 0x7b, 0x90, 0x6f, 0xc4, 0xba, 0x28, + 0x36, 0x99, 0x5a, 0xac, 0x7e, 0x52, 0x74, 0x90, + 0xac, 0x95, 0x2a, 0x02, 0x26, 0x8a, 0x4f, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 4096,[p>q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x27, 0x0f, 0x83, 0x44, 0x1b, 0x11, 0xce, 0x9f, + 0xe6, 0xdf, 0xd5, 0x1b, 0xed, 0x73, 0xea, 0x09, + 0x54, 0xcb, 0x47, 0xca, 0x58, 0xfa, 0x04, 0xc7, + 0x25, 0x68, 0xf0, 0x25, 0xfd, 0xf1, 0x30, 0x53, + 0x03, 0x56, 0xd9, 0x65, 0x65, 0xd4, 0x60, 0xc1, + 0x12, 0x90, 0x91, 0xf6, 0x3d, 0xda, 0x97, 0x6b, + 0xe8, 0x1b, 0x96, 0x33, 0xfb, 0x94, 0x0a, 0x8f, + 0x55, 0xc3, 0xbd, 0x33, 0x7b, 0x5c, 0x6b, 0x00, + 0x1a, 0x79, 0x2f, 0xaf, 0x13, 0x82, 0xcd, 0x5f, + 0xc7, 0x2a, 0x25, 0xe6, 0x93, 0xb4, 0x13, 0xa5, + 0x89, 0x68, 0x42, 0xce, 0xc2, 0xb0, 0xe8, 0xc4, + 0x94, 0x65, 0xa4, 0x04, 0x37, 0x5d, 0x49, 0xcf, + 0x6d, 0xeb, 0x3b, 0x89, 0x34, 0xbf, 0x78, 0x2e, + 0x8a, 0x34, 0x53, 0x21, 0x56, 0x97, 0xfb, 0xda, + 0x6b, 0x95, 0x48, 0xa0, 0x4f, 0x55, 0xa4, 0xab, + 0xbd, 0x14, 0xc6, 0x7b, 0xb8, 0xca, 0x1b, 0x73, + 0xaa, 0x5f, 0x98, 0x90, 0xe5, 0xdd, 0xb3, 0x30, + 0xf5, 0x9b, 0xa0, 0xe6, 0x83, 0x0b, 0xc8, 0x6f, + 0x70, 0x41, 0x3e, 0x18, 0xd2, 0xea, 0x57, 0xea, + 0xc6, 0x76, 0xaa, 0x48, 0x19, 0x1d, 0x3f, 0xff, + 0xa4, 0x5f, 0x01, 0x4f, 0x4b, 0x21, 0x14, 0xcf, + 0x83, 0x5f, 0xc1, 0xcf, 0xaf, 0x04, 0xe8, 0x8a, + 0xab, 0xa2, 0x53, 0xaa, 0x9e, 0x1b, 0x6d, 0x42, + 0xa8, 0x2b, 0x51, 0xd9, 0x28, 0x9b, 0xf7, 0xda, + 0xf3, 0xd7, 0x6c, 0x71, 0xbd, 0xc2, 0x27, 0x17, + 0x8b, 0x04, 0x46, 0xdc, 0xae, 0x79, 0x70, 0x1b, + 0xf0, 0x45, 0x93, 0x26, 0x60, 0x24, 0x9a, 0xc7, + 0xf2, 0xab, 0x9c, 0xad, 0xf6, 0xaa, 0xab, 0xfa, + 0xb2, 0x70, 0xec, 0x34, 0x7f, 0x75, 0x3a, 0x4c, + 0x3c, 0x0c, 0xe2, 0xe7, 0xad, 0x43, 0xb2, 0x66, + 0xe3, 0x5c, 0x23, 0x0c, 0x48, 0x4a, 0x91, 0x7c, + 0xb3, 0x77, 0x5c, 0x57, 0x7d, 0xbc, 0xa8, 0x2d}, + /* 1024,[p<q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x72, 0x5b, 0xec, 0x7c, 0x5f, 0x9c, 0xa5, 0x5e, + 0xb7, 0xfe, 0xef, 0x67, 0x9e, 0xc4, 0xce, 0xae, + 0xc4, 0x4d, 0xc2, 0xd2, 0x8b, 0xbf, 0x7b, 0x36, + 0x45, 0x5e, 0x89, 0x89, 0x37, 0xcc, 0x60, 0x83, + 0x43, 0x67, 0xac, 0xf3, 0x02, 0xa0, 0xb7, 0x2d, + 0x19, 0x57, 0xd8, 0xf0, 0x59, 0x11, 0x91, 0x06, + 0x07, 0x50, 0x5c, 0x42, 0xf4, 0xe5, 0xa1, 0xee, + 0xc9, 0xa3, 0x0a, 0x40, 0x92, 0xe2, 0xcf, 0x72, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 2048,[p<q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x95, 0xe0, 0x94, 0xf5, 0xf7, 0x5f, 0x9e, 0x7a, + 0xe3, 0xe0, 0x5f, 0x09, 0xb5, 0x77, 0x81, 0x49, + 0x64, 0xbf, 0x0d, 0x8d, 0x65, 0xfb, 0x43, 0xf0, + 0xa6, 0x4d, 0x6e, 0x42, 0xbc, 0x08, 0x87, 0x21, + 0x75, 0x0e, 0x51, 0x53, 0x71, 0xd3, 0xb5, 0xc3, + 0x66, 0x72, 0xfb, 0xf9, 0x1f, 0xf6, 0x92, 0xe2, + 0xd6, 0x41, 0xd6, 0xf6, 0x46, 0x88, 0x22, 0x4b, + 0xd6, 0x46, 0xd7, 0xe6, 0xbc, 0x66, 0xea, 0x6b, + 0x15, 0x9d, 0xe9, 0xc3, 0x45, 0x3d, 0xe7, 0x01, + 0xb2, 0x3a, 0x2d, 0x59, 0xd1, 0xbb, 0x97, 0x5e, + 0x89, 0x13, 0xfe, 0x57, 0xdc, 0x05, 0xc6, 0xbe, + 0xf8, 0x34, 0x8c, 0xc5, 0xab, 0x79, 0xd0, 0xf9, + 0xf4, 0x58, 0xaf, 0xcd, 0xc8, 0x72, 0x84, 0x18, + 0x7b, 0x29, 0xa2, 0xa6, 0xbf, 0x72, 0x57, 0x8a, + 0xe1, 0xe9, 0x38, 0x70, 0x35, 0x1e, 0x2a, 0x5f, + 0xcf, 0x91, 0x62, 0x30, 0x57, 0xa6, 0x4c, 0xe4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 4096,[p<q] */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xbc, 0x33, 0x29, 0x91, 0x3c, 0x49, 0x8a, 0x8c, + 0x1f, 0x0c, 0x5e, 0x1b, 0x47, 0x96, 0x98, 0xab, + 0xf6, 0xb6, 0xdb, 0xf9, 0xaa, 0x86, 0xad, 0x48, + 0x2d, 0x59, 0xf8, 0xf4, 0xbc, 0x8c, 0x2e, 0x4d, + 0x52, 0x0e, 0x48, 0x03, 0xc5, 0xb9, 0x83, 0x66, + 0x15, 0x45, 0xff, 0x0e, 0x69, 0xe9, 0x31, 0x70, + 0xc5, 0x21, 0xfa, 0x8b, 0x64, 0xef, 0x4c, 0x53, + 0x32, 0x51, 0xe7, 0x2f, 0x70, 0x52, 0x89, 0xa2, + 0x2b, 0xff, 0x88, 0x9d, 0x93, 0x78, 0x33, 0x03, + 0x6e, 0x2a, 0xd4, 0x67, 0x3d, 0xb2, 0xa9, 0x5a, + 0x23, 0x3d, 0xfc, 0xaf, 0x6d, 0x41, 0x09, 0x47, + 0x7c, 0xa4, 0x28, 0x8b, 0x00, 0x8b, 0xc9, 0x48, + 0x75, 0x80, 0x4a, 0x68, 0x3a, 0x6d, 0x96, 0x46, + 0x37, 0xb9, 0x68, 0x01, 0x6b, 0xeb, 0x6f, 0xa9, + 0xf7, 0x95, 0x35, 0x05, 0xcc, 0x06, 0x33, 0x87, + 0x90, 0xf0, 0x1a, 0x96, 0xac, 0xa0, 0x74, 0xf4, + 0x27, 0xac, 0x98, 0xcc, 0x2d, 0x3a, 0x34, 0x98, + 0x6f, 0xe7, 0x10, 0x47, 0xbf, 0x44, 0xbb, 0xf8, + 0xfb, 0x81, 0x01, 0x59, 0x1e, 0x5f, 0x76, 0xef, + 0x7e, 0x67, 0x3e, 0x0e, 0xc2, 0xec, 0x6b, 0x45, + 0x1b, 0xf5, 0x16, 0xe6, 0xfe, 0xa1, 0x40, 0xce, + 0x9d, 0x91, 0xed, 0xdb, 0x11, 0x7a, 0xbc, 0x0a, + 0xc6, 0x08, 0x74, 0x02, 0x3c, 0xc8, 0x8d, 0x98, + 0x3d, 0x43, 0xbf, 0xe1, 0xf6, 0x77, 0x9d, 0xb3, + 0x1e, 0xba, 0x68, 0x48, 0x0e, 0xef, 0xa9, 0xa0, + 0x5c, 0xb8, 0x1e, 0x4b, 0x9f, 0x06, 0x92, 0x21, + 0xbf, 0xa3, 0x6d, 0x26, 0xea, 0x5b, 0xfd, 0xb8, + 0x85, 0x2e, 0xfe, 0xf6, 0x94, 0x82, 0xf5, 0x93, + 0xe6, 0x1d, 0x12, 0x63, 0xe2, 0x62, 0x0d, 0xe2, + 0xe3, 0x86, 0xeb, 0x66, 0x37, 0xf9, 0xaf, 0xe5, + 0xaf, 0x77, 0x59, 0x6f, 0x8f, 0x66, 0x64, 0x76, + 0x5f, 0x78, 0x47, 0x61, 0xa2, 0x06, 0x94, 0x1d}}; + +unsigned char input_data[] = + {0x00, 0x02, 0x08, 0x68, 0x30, 0x9a, 0x32, 0x08, + 0x57, 0xb0, 0x28, 0xaa, 0x76, 0x30, 0x3d, 0x84, + 0x5f, 0x92, 0x0d, 0x8e, 0x34, 0xe0, 0xd5, 0xcc, + 0x36, 0x97, 0xed, 0x00, 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, + 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63}; + +unsigned char ciphertext[6][512] = + /* 1024,[p>q] */{{0xb2, 0xb2, 0x82, 0xd7, 0x2c, 0x6f, 0x53, 0x29, + 0xee, 0x4c, 0xd1, 0x77, 0xb7, 0x13, 0xf3, 0x1c, + 0x51, 0x60, 0xd8, 0xa9, 0x4e, 0x52, 0x72, 0x43, + 0x29, 0xfa, 0x51, 0xaa, 0xd8, 0xbc, 0x31, 0x21, + 0xe0, 0xac, 0x9b, 0x4e, 0x00, 0x94, 0xac, 0x91, + 0x7f, 0x1e, 0xfd, 0xfb, 0x1c, 0xfa, 0xa8, 0xe8, + 0x56, 0x5a, 0x01, 0x17, 0xf1, 0x5f, 0x01, 0xba, + 0xcd, 0x77, 0xa1, 0x8c, 0x74, 0x8a, 0xef, 0xfa, + 0x64, 0x58, 0x79, 0x13, 0xaa, 0x54, 0x13, 0x2b, + 0xaa, 0xe7, 0xc3, 0x50, 0x3b, 0x69, 0x3b, 0x0b, + 0x9a, 0xa9, 0x9d, 0x15, 0x8a, 0x06, 0x45, 0x71, + 0x40, 0x7a, 0x80, 0x85, 0x4a, 0xbe, 0x68, 0x48, + 0x6c, 0xe6, 0xdd, 0x96, 0xb0, 0xdc, 0xf4, 0x23, + 0xa8, 0xea, 0x21, 0x9f, 0xbc, 0x6b, 0x15, 0xa4, + 0x87, 0x6e, 0x93, 0x56, 0xae, 0xa7, 0x17, 0x4e, + 0xd7, 0x14, 0xe4, 0x69, 0x04, 0xd5, 0x2e, 0x62, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 2048,[p>q] */ {0x6d, 0xdc, 0x9c, 0xba, 0xd4, 0xfa, 0xfe, 0xd0, + 0x85, 0xd7, 0x0a, 0xc4, 0x11, 0x02, 0x07, 0x9f, + 0x28, 0xd2, 0x1b, 0x1f, 0xcc, 0xbb, 0x6f, 0x66, + 0x3a, 0xbe, 0xcb, 0xe6, 0x20, 0xee, 0x90, 0x97, + 0x04, 0x2c, 0xfc, 0xb9, 0x5a, 0xd3, 0x66, 0x6a, + 0x73, 0x6a, 0x67, 0x27, 0xee, 0x9f, 0x90, 0xcd, + 0x5f, 0xce, 0xcf, 0x12, 0x4e, 0x10, 0xf2, 0x2a, + 0x23, 0xd1, 0x5e, 0xd4, 0xad, 0xb5, 0xc5, 0x26, + 0xd2, 0x2f, 0x04, 0x18, 0xb5, 0xc1, 0x52, 0xeb, + 0x7c, 0xd4, 0x5b, 0xe8, 0x21, 0x0a, 0x53, 0x7d, + 0xfe, 0x64, 0x02, 0xf1, 0xb4, 0x48, 0xf2, 0x39, + 0x17, 0xb7, 0x60, 0x0f, 0x22, 0x7f, 0x04, 0x78, + 0xf1, 0x84, 0x51, 0x47, 0xec, 0xff, 0x81, 0x27, + 0x47, 0x88, 0x58, 0xfa, 0x26, 0xe7, 0xc3, 0x0e, + 0x77, 0x81, 0xa9, 0x06, 0x8d, 0x24, 0x36, 0x58, + 0x61, 0xe2, 0x78, 0x37, 0xe8, 0x7c, 0x6d, 0x5b, + 0x77, 0xeb, 0x0a, 0x56, 0xe7, 0x25, 0x9f, 0xe8, + 0xc0, 0x82, 0xc3, 0xf8, 0xb8, 0x1a, 0xe3, 0x60, + 0x65, 0x24, 0x2e, 0x0c, 0xc2, 0x74, 0xcd, 0x2a, + 0x03, 0xd1, 0x66, 0x7a, 0x1c, 0xe2, 0x3d, 0xc5, + 0xa9, 0x78, 0x5f, 0x32, 0x96, 0x8a, 0xe4, 0x11, + 0x97, 0x82, 0xb9, 0x11, 0x48, 0xd5, 0x3f, 0x1b, + 0x4d, 0xc5, 0xf7, 0x4e, 0xe7, 0x7d, 0x5a, 0xf3, + 0x42, 0xff, 0xf8, 0xf6, 0x8d, 0xd2, 0x22, 0x95, + 0xdf, 0xf2, 0x7e, 0xfc, 0x34, 0xf4, 0x6d, 0x8e, + 0x37, 0x02, 0x34, 0x30, 0xf8, 0x31, 0xfb, 0xa8, + 0x97, 0x74, 0xac, 0xf3, 0x4a, 0x67, 0x4a, 0xee, + 0x12, 0xed, 0x9d, 0x19, 0xcd, 0x4a, 0xe2, 0x13, + 0x43, 0x25, 0xf7, 0x00, 0xd8, 0xbd, 0x91, 0xc2, + 0x38, 0xc4, 0x68, 0xeb, 0xb1, 0x74, 0xd0, 0x8c, + 0xdb, 0x76, 0x79, 0xe2, 0xd0, 0x85, 0x0d, 0x03, + 0xdc, 0xdc, 0x8e, 0x79, 0x7f, 0xdb, 0xea, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 4096,[p>q] */ {0xac, 0x34, 0x9f, 0xe1, 0x4d, 0x4a, 0xf8, 0x8f, + 0x3a, 0xa0, 0xf5, 0x78, 0xe3, 0x30, 0x7e, 0x80, + 0x55, 0x7a, 0x93, 0x96, 0x47, 0xb8, 0x28, 0xc7, + 0x34, 0x33, 0xcf, 0x97, 0x90, 0x71, 0xbc, 0xc6, + 0x37, 0x13, 0x8b, 0x53, 0x41, 0x51, 0x9a, 0x2e, + 0x4a, 0xa0, 0x6b, 0xfc, 0xc6, 0x73, 0x0a, 0x6f, + 0x5c, 0x09, 0xee, 0x35, 0x9d, 0xee, 0x2a, 0xbe, + 0x88, 0x8a, 0xbf, 0xa0, 0x60, 0xb3, 0x4b, 0x93, + 0x37, 0xb7, 0xb9, 0x52, 0xd5, 0x9d, 0x2b, 0xd8, + 0x39, 0xfe, 0x04, 0x4a, 0x97, 0x3f, 0x4a, 0xd9, + 0x8b, 0x27, 0x71, 0xb3, 0xbe, 0x25, 0x43, 0xd6, + 0xba, 0x06, 0x6c, 0x93, 0x09, 0x27, 0xf8, 0x4f, + 0x9a, 0x6f, 0x97, 0x23, 0x22, 0x9e, 0x51, 0x53, + 0x9a, 0x4c, 0x08, 0x3a, 0x78, 0x22, 0xd5, 0x7f, + 0xe9, 0xb1, 0x78, 0xef, 0xdc, 0x7e, 0x0c, 0x67, + 0x54, 0x14, 0xdd, 0x15, 0xf5, 0xc5, 0xc6, 0x4c, + 0x64, 0xa4, 0x70, 0x97, 0xd5, 0xfd, 0xc6, 0x8a, + 0x21, 0x86, 0x70, 0x93, 0xa5, 0xaa, 0x04, 0xa4, + 0xa6, 0xfc, 0x8b, 0x51, 0xe8, 0x64, 0x30, 0x9d, + 0x5c, 0x44, 0x8d, 0xab, 0xf3, 0x1a, 0x19, 0x56, + 0xa7, 0x87, 0xce, 0x0b, 0xb8, 0xd1, 0x84, 0xb1, + 0x69, 0x39, 0x34, 0x2d, 0xeb, 0x62, 0xda, 0x46, + 0xc8, 0xc0, 0x98, 0x0a, 0x95, 0x43, 0xc8, 0x80, + 0xe3, 0x45, 0x89, 0x1e, 0x27, 0x2f, 0x8e, 0x85, + 0x9b, 0xf8, 0xc8, 0x76, 0x1e, 0xfa, 0x67, 0x51, + 0xcf, 0x4f, 0x8d, 0x07, 0xb9, 0xd6, 0x93, 0xc6, + 0xc3, 0xd1, 0xa6, 0x8e, 0x17, 0x94, 0x88, 0x4c, + 0x74, 0x48, 0x97, 0x50, 0xd0, 0x1f, 0xb0, 0x6d, + 0xf7, 0x2c, 0xc2, 0x01, 0x0e, 0x22, 0xa1, 0xc4, + 0x20, 0xfd, 0xb3, 0xde, 0x0d, 0x95, 0x0c, 0xeb, + 0xc2, 0x63, 0x37, 0x24, 0xb7, 0xb1, 0x90, 0x6d, + 0xb7, 0xda, 0x19, 0x33, 0x59, 0xd7, 0x34, 0x8d, + 0x72, 0xd2, 0x13, 0x4d, 0xec, 0xa8, 0xf7, 0xf3, + 0x62, 0x6a, 0x8a, 0x37, 0x61, 0x04, 0x57, 0x82, + 0x83, 0xa2, 0x5c, 0xc6, 0xd4, 0x9c, 0x29, 0x92, + 0xa7, 0xbe, 0xf7, 0xbb, 0x98, 0x23, 0xf8, 0xc4, + 0x23, 0xac, 0xbd, 0xa1, 0x6e, 0xfa, 0x45, 0xfd, + 0x58, 0xcc, 0x67, 0xba, 0xe3, 0xd5, 0x86, 0x35, + 0x75, 0x58, 0x07, 0xe9, 0x42, 0x6b, 0x2f, 0x17, + 0xc1, 0x64, 0x10, 0xba, 0x52, 0x37, 0xaf, 0xe0, + 0x36, 0x9a, 0x41, 0x06, 0xa1, 0x70, 0x12, 0x27, + 0xf7, 0xaa, 0xee, 0x9f, 0x9c, 0x16, 0x5d, 0x30, + 0xb0, 0xdd, 0x9c, 0x56, 0x8b, 0x0e, 0xbb, 0xd2, + 0xed, 0x36, 0xa7, 0x71, 0x77, 0xb8, 0xd4, 0xcd, + 0xb0, 0x38, 0x26, 0x4c, 0x10, 0x5d, 0x14, 0x5b, + 0x18, 0xde, 0xec, 0xda, 0x3d, 0xfe, 0x18, 0x02, + 0x34, 0x13, 0xdb, 0x1f, 0x74, 0xc4, 0xdd, 0xbc, + 0xd2, 0x1a, 0x68, 0xcf, 0x96, 0x9b, 0x4e, 0xaa, + 0xdd, 0x47, 0x24, 0xa4, 0x1a, 0x1d, 0x5b, 0xa1, + 0x8e, 0xcf, 0x4a, 0x51, 0x0a, 0x7b, 0x24, 0xfc, + 0x54, 0x20, 0x31, 0x5a, 0x97, 0x42, 0x9d, 0x36, + 0x84, 0x07, 0x89, 0x3e, 0x39, 0x34, 0x5e, 0x40, + 0xae, 0xe7, 0xf8, 0x82, 0xd7, 0xb3, 0xa9, 0x25, + 0xfe, 0xc5, 0x45, 0xd5, 0xde, 0x6f, 0x02, 0x61, + 0x25, 0x12, 0x90, 0xfe, 0xe7, 0x10, 0x1d, 0x60, + 0x55, 0xf8, 0xd2, 0xff, 0x26, 0xb3, 0xbb, 0xea, + 0xb7, 0x6d, 0x14, 0xd9, 0x54, 0xef, 0xc3, 0x5f, + 0x73, 0x46, 0xdc, 0xd1, 0xfa, 0xd8, 0x31, 0xc6, + 0xff, 0xd8, 0xc7, 0xf7, 0x84, 0xc0, 0x87, 0x70, + 0x97, 0xab, 0xdf, 0xa7, 0x8c, 0x0b, 0xf1, 0xcf, + 0x81, 0x2a, 0xce, 0xf2, 0x02, 0xfd, 0x41, 0xb2, + 0x54, 0x9f, 0x49, 0x17, 0xe7, 0xbb, 0xa5, 0x37, + 0x6e, 0x4d, 0xeb, 0x2b, 0x62, 0x1c, 0x36, 0xb3, + 0x01, 0x86, 0x45, 0x82, 0xc1, 0x4f, 0x60, 0x77}, + /* 1024,[p<q] */ {0xb2, 0xb2, 0x82, 0xd7, 0x2c, 0x6f, 0x53, 0x29, + 0xee, 0x4c, 0xd1, 0x77, 0xb7, 0x13, 0xf3, 0x1c, + 0x51, 0x60, 0xd8, 0xa9, 0x4e, 0x52, 0x72, 0x43, + 0x29, 0xfa, 0x51, 0xaa, 0xd8, 0xbc, 0x31, 0x21, + 0xe0, 0xac, 0x9b, 0x4e, 0x00, 0x94, 0xac, 0x91, + 0x7f, 0x1e, 0xfd, 0xfb, 0x1c, 0xfa, 0xa8, 0xe8, + 0x56, 0x5a, 0x01, 0x17, 0xf1, 0x5f, 0x01, 0xba, + 0xcd, 0x77, 0xa1, 0x8c, 0x74, 0x8a, 0xef, 0xfa, + 0x64, 0x58, 0x79, 0x13, 0xaa, 0x54, 0x13, 0x2b, + 0xaa, 0xe7, 0xc3, 0x50, 0x3b, 0x69, 0x3b, 0x0b, + 0x9a, 0xa9, 0x9d, 0x15, 0x8a, 0x06, 0x45, 0x71, + 0x40, 0x7a, 0x80, 0x85, 0x4a, 0xbe, 0x68, 0x48, + 0x6c, 0xe6, 0xdd, 0x96, 0xb0, 0xdc, 0xf4, 0x23, + 0xa8, 0xea, 0x21, 0x9f, 0xbc, 0x6b, 0x15, 0xa4, + 0x87, 0x6e, 0x93, 0x56, 0xae, 0xa7, 0x17, 0x4e, + 0xd7, 0x14, 0xe4, 0x69, 0x04, 0xd5, 0x2e, 0x62, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 2048,[p<q] */ {0x6d, 0xdc, 0x9c, 0xba, 0xd4, 0xfa, 0xfe, 0xd0, + 0x85, 0xd7, 0x0a, 0xc4, 0x11, 0x02, 0x07, 0x9f, + 0x28, 0xd2, 0x1b, 0x1f, 0xcc, 0xbb, 0x6f, 0x66, + 0x3a, 0xbe, 0xcb, 0xe6, 0x20, 0xee, 0x90, 0x97, + 0x04, 0x2c, 0xfc, 0xb9, 0x5a, 0xd3, 0x66, 0x6a, + 0x73, 0x6a, 0x67, 0x27, 0xee, 0x9f, 0x90, 0xcd, + 0x5f, 0xce, 0xcf, 0x12, 0x4e, 0x10, 0xf2, 0x2a, + 0x23, 0xd1, 0x5e, 0xd4, 0xad, 0xb5, 0xc5, 0x26, + 0xd2, 0x2f, 0x04, 0x18, 0xb5, 0xc1, 0x52, 0xeb, + 0x7c, 0xd4, 0x5b, 0xe8, 0x21, 0x0a, 0x53, 0x7d, + 0xfe, 0x64, 0x02, 0xf1, 0xb4, 0x48, 0xf2, 0x39, + 0x17, 0xb7, 0x60, 0x0f, 0x22, 0x7f, 0x04, 0x78, + 0xf1, 0x84, 0x51, 0x47, 0xec, 0xff, 0x81, 0x27, + 0x47, 0x88, 0x58, 0xfa, 0x26, 0xe7, 0xc3, 0x0e, + 0x77, 0x81, 0xa9, 0x06, 0x8d, 0x24, 0x36, 0x58, + 0x61, 0xe2, 0x78, 0x37, 0xe8, 0x7c, 0x6d, 0x5b, + 0x77, 0xeb, 0x0a, 0x56, 0xe7, 0x25, 0x9f, 0xe8, + 0xc0, 0x82, 0xc3, 0xf8, 0xb8, 0x1a, 0xe3, 0x60, + 0x65, 0x24, 0x2e, 0x0c, 0xc2, 0x74, 0xcd, 0x2a, + 0x03, 0xd1, 0x66, 0x7a, 0x1c, 0xe2, 0x3d, 0xc5, + 0xa9, 0x78, 0x5f, 0x32, 0x96, 0x8a, 0xe4, 0x11, + 0x97, 0x82, 0xb9, 0x11, 0x48, 0xd5, 0x3f, 0x1b, + 0x4d, 0xc5, 0xf7, 0x4e, 0xe7, 0x7d, 0x5a, 0xf3, + 0x42, 0xff, 0xf8, 0xf6, 0x8d, 0xd2, 0x22, 0x95, + 0xdf, 0xf2, 0x7e, 0xfc, 0x34, 0xf4, 0x6d, 0x8e, + 0x37, 0x02, 0x34, 0x30, 0xf8, 0x31, 0xfb, 0xa8, + 0x97, 0x74, 0xac, 0xf3, 0x4a, 0x67, 0x4a, 0xee, + 0x12, 0xed, 0x9d, 0x19, 0xcd, 0x4a, 0xe2, 0x13, + 0x43, 0x25, 0xf7, 0x00, 0xd8, 0xbd, 0x91, 0xc2, + 0x38, 0xc4, 0x68, 0xeb, 0xb1, 0x74, 0xd0, 0x8c, + 0xdb, 0x76, 0x79, 0xe2, 0xd0, 0x85, 0x0d, 0x03, + 0xdc, 0xdc, 0x8e, 0x79, 0x7f, 0xdb, 0xea, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + /* 4096,[p<q] */ {0xac, 0x34, 0x9f, 0xe1, 0x4d, 0x4a, 0xf8, 0x8f, + 0x3a, 0xa0, 0xf5, 0x78, 0xe3, 0x30, 0x7e, 0x80, + 0x55, 0x7a, 0x93, 0x96, 0x47, 0xb8, 0x28, 0xc7, + 0x34, 0x33, 0xcf, 0x97, 0x90, 0x71, 0xbc, 0xc6, + 0x37, 0x13, 0x8b, 0x53, 0x41, 0x51, 0x9a, 0x2e, + 0x4a, 0xa0, 0x6b, 0xfc, 0xc6, 0x73, 0x0a, 0x6f, + 0x5c, 0x09, 0xee, 0x35, 0x9d, 0xee, 0x2a, 0xbe, + 0x88, 0x8a, 0xbf, 0xa0, 0x60, 0xb3, 0x4b, 0x93, + 0x37, 0xb7, 0xb9, 0x52, 0xd5, 0x9d, 0x2b, 0xd8, + 0x39, 0xfe, 0x04, 0x4a, 0x97, 0x3f, 0x4a, 0xd9, + 0x8b, 0x27, 0x71, 0xb3, 0xbe, 0x25, 0x43, 0xd6, + 0xba, 0x06, 0x6c, 0x93, 0x09, 0x27, 0xf8, 0x4f, + 0x9a, 0x6f, 0x97, 0x23, 0x22, 0x9e, 0x51, 0x53, + 0x9a, 0x4c, 0x08, 0x3a, 0x78, 0x22, 0xd5, 0x7f, + 0xe9, 0xb1, 0x78, 0xef, 0xdc, 0x7e, 0x0c, 0x67, + 0x54, 0x14, 0xdd, 0x15, 0xf5, 0xc5, 0xc6, 0x4c, + 0x64, 0xa4, 0x70, 0x97, 0xd5, 0xfd, 0xc6, 0x8a, + 0x21, 0x86, 0x70, 0x93, 0xa5, 0xaa, 0x04, 0xa4, + 0xa6, 0xfc, 0x8b, 0x51, 0xe8, 0x64, 0x30, 0x9d, + 0x5c, 0x44, 0x8d, 0xab, 0xf3, 0x1a, 0x19, 0x56, + 0xa7, 0x87, 0xce, 0x0b, 0xb8, 0xd1, 0x84, 0xb1, + 0x69, 0x39, 0x34, 0x2d, 0xeb, 0x62, 0xda, 0x46, + 0xc8, 0xc0, 0x98, 0x0a, 0x95, 0x43, 0xc8, 0x80, + 0xe3, 0x45, 0x89, 0x1e, 0x27, 0x2f, 0x8e, 0x85, + 0x9b, 0xf8, 0xc8, 0x76, 0x1e, 0xfa, 0x67, 0x51, + 0xcf, 0x4f, 0x8d, 0x07, 0xb9, 0xd6, 0x93, 0xc6, + 0xc3, 0xd1, 0xa6, 0x8e, 0x17, 0x94, 0x88, 0x4c, + 0x74, 0x48, 0x97, 0x50, 0xd0, 0x1f, 0xb0, 0x6d, + 0xf7, 0x2c, 0xc2, 0x01, 0x0e, 0x22, 0xa1, 0xc4, + 0x20, 0xfd, 0xb3, 0xde, 0x0d, 0x95, 0x0c, 0xeb, + 0xc2, 0x63, 0x37, 0x24, 0xb7, 0xb1, 0x90, 0x6d, + 0xb7, 0xda, 0x19, 0x33, 0x59, 0xd7, 0x34, 0x8d, + 0x72, 0xd2, 0x13, 0x4d, 0xec, 0xa8, 0xf7, 0xf3, + 0x62, 0x6a, 0x8a, 0x37, 0x61, 0x04, 0x57, 0x82, + 0x83, 0xa2, 0x5c, 0xc6, 0xd4, 0x9c, 0x29, 0x92, + 0xa7, 0xbe, 0xf7, 0xbb, 0x98, 0x23, 0xf8, 0xc4, + 0x23, 0xac, 0xbd, 0xa1, 0x6e, 0xfa, 0x45, 0xfd, + 0x58, 0xcc, 0x67, 0xba, 0xe3, 0xd5, 0x86, 0x35, + 0x75, 0x58, 0x07, 0xe9, 0x42, 0x6b, 0x2f, 0x17, + 0xc1, 0x64, 0x10, 0xba, 0x52, 0x37, 0xaf, 0xe0, + 0x36, 0x9a, 0x41, 0x06, 0xa1, 0x70, 0x12, 0x27, + 0xf7, 0xaa, 0xee, 0x9f, 0x9c, 0x16, 0x5d, 0x30, + 0xb0, 0xdd, 0x9c, 0x56, 0x8b, 0x0e, 0xbb, 0xd2, + 0xed, 0x36, 0xa7, 0x71, 0x77, 0xb8, 0xd4, 0xcd, + 0xb0, 0x38, 0x26, 0x4c, 0x10, 0x5d, 0x14, 0x5b, + 0x18, 0xde, 0xec, 0xda, 0x3d, 0xfe, 0x18, 0x02, + 0x34, 0x13, 0xdb, 0x1f, 0x74, 0xc4, 0xdd, 0xbc, + 0xd2, 0x1a, 0x68, 0xcf, 0x96, 0x9b, 0x4e, 0xaa, + 0xdd, 0x47, 0x24, 0xa4, 0x1a, 0x1d, 0x5b, 0xa1, + 0x8e, 0xcf, 0x4a, 0x51, 0x0a, 0x7b, 0x24, 0xfc, + 0x54, 0x20, 0x31, 0x5a, 0x97, 0x42, 0x9d, 0x36, + 0x84, 0x07, 0x89, 0x3e, 0x39, 0x34, 0x5e, 0x40, + 0xae, 0xe7, 0xf8, 0x82, 0xd7, 0xb3, 0xa9, 0x25, + 0xfe, 0xc5, 0x45, 0xd5, 0xde, 0x6f, 0x02, 0x61, + 0x25, 0x12, 0x90, 0xfe, 0xe7, 0x10, 0x1d, 0x60, + 0x55, 0xf8, 0xd2, 0xff, 0x26, 0xb3, 0xbb, 0xea, + 0xb7, 0x6d, 0x14, 0xd9, 0x54, 0xef, 0xc3, 0x5f, + 0x73, 0x46, 0xdc, 0xd1, 0xfa, 0xd8, 0x31, 0xc6, + 0xff, 0xd8, 0xc7, 0xf7, 0x84, 0xc0, 0x87, 0x70, + 0x97, 0xab, 0xdf, 0xa7, 0x8c, 0x0b, 0xf1, 0xcf, + 0x81, 0x2a, 0xce, 0xf2, 0x02, 0xfd, 0x41, 0xb2, + 0x54, 0x9f, 0x49, 0x17, 0xe7, 0xbb, 0xa5, 0x37, + 0x6e, 0x4d, 0xeb, 0x2b, 0x62, 0x1c, 0x36, 0xb3, + 0x01, 0x86, 0x45, 0x82, 0xc1, 0x4f, 0x60, 0x77}}; diff --git a/src/tests/libica_sha1_test.c b/src/tests/libica_sha1_test.c new file mode 100644 index 0000000..8c696db --- /dev/null +++ b/src/tests/libica_sha1_test.c @@ -0,0 +1,200 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2001, 2009, 2011 */ + +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include "ica_api.h" +#include "testcase.h" + +#define NUM_FIPS_TESTS 4 + +unsigned char FIPS_TEST_DATA[NUM_FIPS_TESTS][64] = { + // Test 0: NULL + { 0x00 }, + // Test 1: "abc" + { 0x61,0x62,0x63 }, + // Test 2: "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + { +0x61,0x62,0x63,0x64,0x62,0x63,0x64,0x65,0x63,0x64,0x65,0x66,0x64,0x65,0x66,0x67, +0x65,0x66,0x67,0x68,0x66,0x67,0x68,0x69,0x67,0x68,0x69,0x6a,0x68,0x69,0x6a,0x6b, +0x69,0x6a,0x6b,0x6c,0x6a,0x6b,0x6c,0x6d,0x6b,0x6c,0x6d,0x6e,0x6c,0x6d,0x6e,0x6f, +0x6d,0x6e,0x6f,0x70,0x6e,0x6f,0x70,0x71, + }, + // Test 3: 1,000,000 'a' -- don't actually use this... see the special case + // in the loop below. + { +0x61, + }, +}; + +unsigned int FIPS_TEST_DATA_SIZE[NUM_FIPS_TESTS] = { + // Test 0: NULL + 0, + // Test 1: "abc" + 3, + // Test 2: "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + 56, + // Test 3: 1,000,000 'a' + 1000000, +}; + +unsigned char FIPS_TEST_RESULT[NUM_FIPS_TESTS][SHA_HASH_LENGTH] = +{ + // Hash for test 0: NULL + { +0xda,0x39,0xa3,0xee,0x5e,0x6b,0x4b,0x0d,0x32,0x55,0xbf,0xef,0x95,0x60,0x18,0x90, +0xaf,0xd8,0x07,0x09, + }, + // Hash for test 1: "abc" + { +0xA9,0x99,0x3E,0x36,0x47,0x06,0x81,0x6A,0xBA,0x3E,0x25,0x71,0x78,0x50,0xC2,0x6C, +0x9C,0xD0,0xD8,0x9D, + }, + // Hash for test 2: "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + { +0x84,0x98,0x3E,0x44,0x1C,0x3B,0xD2,0x6E,0xBA,0xAE,0x4A,0xA1,0xF9,0x51,0x29,0xE5, +0xE5,0x46,0x70,0xF1, + }, + // Hash for test 3: 1,000,000 'a' + { +0x34,0xAA,0x97,0x3C,0xD4,0xC4,0xDA,0xA4,0xF6,0x1E,0xEB,0x2B,0xDB,0xAD,0x27,0x31, +0x65,0x34,0x01,0x6F, + }, +}; + +int new_api_sha_test(void) +{ + V_(printf("Test of new sha api\n")); + sha_context_t sha_context; + int rc = 0, i = 0; + unsigned char input_data[1000000]; + unsigned int output_hash_length = SHA_HASH_LENGTH; + unsigned char output_hash[SHA_HASH_LENGTH]; + + for (i = 0; i < NUM_FIPS_TESTS; i++) { + // Test 3 is a special one, because we want to keep the size of the + // executable down, so we build it special, instead of using a static + if (i != 3) + memcpy(input_data, FIPS_TEST_DATA[i], FIPS_TEST_DATA_SIZE[i]); + else + memset(input_data, 'a', FIPS_TEST_DATA_SIZE[i]); + + VV_(printf("\nOriginal data for test %d:\n", i)); + dump_array(input_data, FIPS_TEST_DATA_SIZE[i]); + + rc = ica_sha1(SHA_MSG_PART_ONLY, FIPS_TEST_DATA_SIZE[i], input_data, + &sha_context, output_hash); + + if (rc != 0) { + V_(printf("icaSha1 failed with errno %d (0x%x).\n", rc, rc)); + return rc; + } + + VV_(printf("\nOutput hash for test %d:\n", i)); + dump_array(output_hash, output_hash_length); + if (memcmp(output_hash, FIPS_TEST_RESULT[i], SHA_HASH_LENGTH) != 0) { + VV_(printf("This does NOT match the known result.\n")); + } + else + VV_(printf("Yep, it's what it should be.\n")); + } + + // This test is the same as test 3, except that we use the SHA_CONTEXT + // and break it into calls of 1024 bytes each. + V_(printf("\nOriginal data for test 3(chunks = 1024) is calls of 1024" + "'a's at a time\n")); + i = FIPS_TEST_DATA_SIZE[3]; + while (i > 0) { + unsigned int sha_message_part; + memset(input_data, 'a', 1024); + + if (i == FIPS_TEST_DATA_SIZE[3]) + sha_message_part = SHA_MSG_PART_FIRST; + else if (i <= 1024) + sha_message_part = SHA_MSG_PART_FINAL; + else + sha_message_part = SHA_MSG_PART_MIDDLE; + + rc = ica_sha1(sha_message_part, (i < 1024) ? i : 1024, + input_data, &sha_context, output_hash); + + if (rc != 0) { + V_(printf("ica_sha1 failed with errno %d (0x%x) on" + " iteration %d.\n", rc, rc, i)); + return rc; + } + i -= 1024; + } + + VV_(printf("\nOutput hash for test 3(chunks = 1024):\n")); + dump_array(output_hash, output_hash_length); + if (memcmp(output_hash, FIPS_TEST_RESULT[3], SHA_HASH_LENGTH) != 0) { + VV_(printf("This does NOT match the known result.\n")); + } + else { + VV_(printf("Yep, it's what it should be.\n")); + } + + // This test is the same as test 3, except that we use the SHA_CONTEXT + // and break it into calls of 64 bytes each. + V_(printf("\nOriginal data for test 3(chunks = 64) is calls of 64 'a's at" + "a time\n")); + i = FIPS_TEST_DATA_SIZE[3]; + while (i > 0) { + unsigned int sha_message_part; + memset(input_data, 'a', 64); + + if (i == FIPS_TEST_DATA_SIZE[3]) + sha_message_part = SHA_MSG_PART_FIRST; + else if (i <= 64) + sha_message_part = SHA_MSG_PART_FINAL; + else + sha_message_part = SHA_MSG_PART_MIDDLE; + + rc = ica_sha1(sha_message_part, (i < 64) ? i : 64, input_data, + &sha_context, output_hash); + + if (rc != 0) { + V_(printf("ica_sha1 failed with errno %d (0x%x) on" + " iteration %d.\n", rc, rc, i)); + return rc; + } + i -= 64; + } + + VV_(printf("\nOutput hash for test 3(chunks = 64):\n")); + dump_array(output_hash, output_hash_length); + if (memcmp(output_hash, FIPS_TEST_RESULT[3], SHA_HASH_LENGTH) != 0) { + VV_(printf("This does NOT match the known result.\n")); + } + else { + VV_(printf("Yep, it's what it should be.\n")); + } + + printf("All SHA1 tests passed.\n"); + + return 0; +} + +int main(int argc, char **argv) +{ + int rc = 0; + + set_verbosity(argc, argv); + + rc = new_api_sha_test(); + if (rc) { + printf("new_api_sha_test failed with rc = %i\n", rc); + return rc; + } + + return 0; +} + diff --git a/src/tests/libica_sha256_test.c b/src/tests/libica_sha256_test.c new file mode 100644 index 0000000..57c137a --- /dev/null +++ b/src/tests/libica_sha256_test.c @@ -0,0 +1,190 @@ +/* This program is released under the Common Public License V1.0 + * + * You should have received a copy of Common Public License V1.0 along with + * with this program. + */ + +/* Copyright IBM Corp. 2005, 2009, 2011 */ +/* (C) COPYRIGHT International Business Machines Corp. 2005, 2009 */ +#include <fcntl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <string.h> +#include "ica_api.h" +#include "testcase.h" + +#define NUM_FIPS_TESTS 3 + +unsigned char FIPS_TEST_DATA[NUM_FIPS_TESTS][64] = { + // Test 0: "abc" + { 0x61,0x62,0x63 }, + // Test 1: "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + { +0x61,0x62,0x63,0x64,0x62,0x63,0x64,0x65,0x63,0x64,0x65,0x66,0x64,0x65,0x66,0x67, +0x65,0x66,0x67,0x68,0x66,0x67,0x68,0x69,0x67,0x68,0x69,0x6a,0x68,0x69,0x6a,0x6b, +0x69,0x6a,0x6b,0x6c,0x6a,0x6b,0x6c,0x6d,0x6b,0x6c,0x6d,0x6e,0x6c,0x6d,0x6e,0x6f, +0x6d,0x6e,0x6f,0x70,0x6e,0x6f,0x70,0x71, + }, + // Test 2: 1,000,000 'a' -- don't actually use this... see the special case + // in the loop below. + { +0x61, + }, +}; + +unsigned int FIPS_TEST_DATA_SIZE[NUM_FIPS_TESTS] = { + // Test 0: "abc" + 3, + // Test 1: "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + 56, + // Test 2: 1,000,000 'a' + 1000000, +}; + +unsigned char FIPS_TEST_RESULT[NUM_FIPS_TESTS][SHA256_HASH_LENGTH] = +{ + // Hash for test 0: "abc" + { +0xBA,0x78,0x16,0xBF,0x8F,0x01,0xCF,0xEA,0x41,0x41,0x40,0xDE,0x5D,0xAE,0x22,0x23, +0xB0,0x03,0x61,0xA3,0x96,0x17,0x7A,0x9C,0xB4,0x10,0xFF,0x61,0xF2,0x00,0x15,0xAD, + }, + // Hash for test 1: "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + { +0x24,0x8D,0x6A,0x61,0xD2,0x06,0x38,0xB8,0xE5,0xC0,0x26,0x93,0x0C,0x3E,0x60,0x39, +0xA3,0x3C,0xE4,0x59,0x64,0xFF,0x21,0x67,0xF6,0xEC,0xED,0xD4,0x19,0xDB,0x06,0xC1, + }, + // Hash for test 2: 1,000,000 'a' + { +0xCD,0xC7,0x6E,0x5C,0x99,0x14,0xFB,0x92,0x81,0xA1,0xC7,0xE2,0x84,0xD7,0x3E,0x67, +0xF1,0x80,0x9A,0x48,0xA4,0x97,0x20,0x0E,0x04,0x6D,0x39,0xCC,0xC7,0x11,0x2C,0xD0, + }, +}; + +int new_api_sha256_test(void) +{ + sha256_context_t sha256_context; + int rc = 0, i = 0; + unsigned char input_data[1000000]; + unsigned int output_hash_length = SHA256_HASH_LENGTH; + unsigned char output_hash[SHA256_HASH_LENGTH]; + + for (i = 0; i < NUM_FIPS_TESTS; i++) { + // Test 2 is a special one, because we want to keep the size of the + // executable down, so we build it special, instead of using a static + if (i != 2) + memcpy(input_data, FIPS_TEST_DATA[i], FIPS_TEST_DATA_SIZE[i]); + else + memset(input_data, 'a', FIPS_TEST_DATA_SIZE[i]); + + VV_(printf("\nOriginal data for test %d:\n", i)); + dump_array(input_data, FIPS_TEST_DATA_SIZE[i]); + + rc = ica_sha256(SHA_MSG_PART_ONLY, FIPS_TEST_DATA_SIZE[i], input_data, + &sha256_context, output_hash); + + if (rc != 0) { + V_(printf("icaSha256 failed with errno %d (0x%x).\n", rc, rc)); + return rc; + } + + VV_(printf("\nOutput hash for test %d:\n", i)); + dump_array(output_hash, output_hash_length); + if (memcmp(output_hash, FIPS_TEST_RESULT[i], SHA256_HASH_LENGTH) != 0) { + VV_(printf("This does NOT match the known result.\n")); + } + else { + VV_(printf("Yep, it's what it should be.\n")); + } + } + + // This test is the same as test 2, except that we use the SHA256_CONTEXT and + // break it into calls of 1024 bytes each. + V_(printf("\nOriginal data for test 2(chunks = 1024) is calls of 1024" + " 'a's at a time\n")); + i = FIPS_TEST_DATA_SIZE[2]; + while (i > 0) { + unsigned int sha_message_part; + memset(input_data, 'a', 1024); + + if (i == FIPS_TEST_DATA_SIZE[2]) + sha_message_part = SHA_MSG_PART_FIRST; + else if (i <= 1024) + sha_message_part = SHA_MSG_PART_FINAL; + else + sha_message_part = SHA_MSG_PART_MIDDLE; + + rc = ica_sha256(sha_message_part, (i < 1024) ? i : 1024, + input_data, &sha256_context, output_hash); + + if (rc != 0) { + V_(printf("ica_sha256 failed with errno %d (0x%x) on" + " iteration %d.\n", rc, rc, i)); + return rc; + } + i -= 1024; + } + + VV_(printf("\nOutput hash for test 2(chunks = 1024):\n")); + dump_array(output_hash, output_hash_length); + if (memcmp(output_hash, FIPS_TEST_RESULT[2], SHA256_HASH_LENGTH) != 0) { + VV_(printf("This does NOT match the known result.\n")); + } + else { + VV_(printf("Yep, it's what it should be.\n")); + } + + // This test is the same as test 2, except that we use the + // SHA256_CONTEXT and break it into calls of 64 bytes each. + V_(printf("\nOriginal data for test 2(chunks = 64) is calls of 64 'a's at" + " a time\n")); + i = FIPS_TEST_DATA_SIZE[2]; + while (i > 0) { + unsigned int sha_message_part; + memset(input_data, 'a', 64); + + if (i == FIPS_TEST_DATA_SIZE[2]) + sha_message_part = SHA_MSG_PART_FIRST; + else if (i <= 64) + sha_message_part = SHA_MSG_PART_FINAL; + else + sha_message_part = SHA_MSG_PART_MIDDLE; + + rc = ica_sha256(sha_message_part, (i < 64) ? i : 64, + input_data, &sha256_context, output_hash); + + if (rc != 0) { + V_(printf("ica_sha256 failed with errno %d (0x%x) on iteration" + " %d.\n", rc, rc, i)); + return rc; + } + i -= 64; + } + + VV_(printf("\nOutput hash for test 2(chunks = 64):\n")); + dump_array(output_hash, output_hash_length); + if (memcmp(output_hash, FIPS_TEST_RESULT[2], SHA256_HASH_LENGTH) != 0) { + VV_(printf("This does NOT match the known result.\n")); + } + else { + VV_(printf("Yep, it's what it should be.\n")); + } + + printf("All SHA256 tests passed.\n"); + + return 0; +} + +int main(int argc, char **argv) +{ + int rc = 0; + + set_verbosity(argc, argv); + + rc = new_api_sha256_test(); + if (rc) { + printf("new_api_sha256_test: returned rc = %i\n", rc); + return rc; + } + + return rc; +} diff --git a/src/tests/libica_sha_test/Makefile.am b/src/tests/libica_sha_test/Makefile.am new file mode 100644 index 0000000..481d6b5 --- /dev/null +++ b/src/tests/libica_sha_test/Makefile.am @@ -0,0 +1,26 @@ +OPTS = -O0 -g -Wall -D_LINUX_S390_ -D_GNU_SOURCE +LIBS = -L../../.libs +INCLUDE = -I. -I./include -I../../../include +SOURCES = libica_sha_test.c queue_t.c sha_tests.c read_rsp.c +CC = gcc +FILES = libica_sha_test.c~ \ + libica_sha_test.o \ + queue_t.c~ \ + queue_t.o \ + include/queue_t.h~ \ + sha_tests.c~ \ + sha_tests.o \ + include/sha_tests.h~ \ + read_rsp.c~ \ + include/read_rsp.h~ \ + include/critical_error.h~ + +all: + $(CC) $(OPTS) -o libica_sha_test $(SOURCES) $(LIBS) $(INCLUDE) -lica -lcrypto + +clean: + rm -f libica_sha_test + +distclean: + rm -f Makefile + rm -f $(FILES) diff --git a/src/tests/libica_sha_test/include/critical_error.h b/src/tests/libica_sha_test/include/critical_error.h new file mode 100644 index 0000000..18891a2 --- /dev/null +++ b/src/tests/libica_sha_test/include/critical_error.h @@ -0,0 +1,14 @@ +#ifndef CRITICAL_ERROR_H +#define CRITICAL_ERROR_H + +#include <stdio.h> +#include <stdlib.h> + +/* terminate on critical error */ +#define CRITICAL_ERROR(msg) \ +do { \ + fprintf(stderr, "critical error in %s: " msg "\n",__func__); \ + exit(EXIT_FAILURE); \ +} while(0) + +#endif diff --git a/src/tests/libica_sha_test/include/queue_t.h b/src/tests/libica_sha_test/include/queue_t.h new file mode 100644 index 0000000..1ba9295 --- /dev/null +++ b/src/tests/libica_sha_test/include/queue_t.h @@ -0,0 +1,33 @@ +#ifndef QUEUE_T_H +#define QUEUE_T_H + +#define NO_TYPE_SET 0 +#define NO_LENGTH_SET 0 + +/* type: NO_TYPE_SET, SHA1, SHA224, SHA256, SHA384, SHA512 + * msg_digest_length: SHA1_HASH_LENGTH, SHA224_HASH_LENGHT, SHA256_HASH_LENGTH, SHA384_HASH_LENGTH, SHA512_HASH_LENGTH + * */ +typedef struct test_t { + unsigned int type; + unsigned char *msg; + unsigned int msg_length; + unsigned char *msg_digest; + unsigned int msg_digest_length; + struct test_t *next; +} test_t; + +test_t new_test_t(void); + +typedef struct queue_t { + unsigned int size; + unsigned int passed; + unsigned int failed; + test_t *head; + test_t *tail; +} queue_t; + +queue_t new_queue_t(void); + +void push(queue_t * queue, test_t test); + +#endif diff --git a/src/tests/libica_sha_test/include/read_rsp.h b/src/tests/libica_sha_test/include/read_rsp.h new file mode 100644 index 0000000..b4746af --- /dev/null +++ b/src/tests/libica_sha_test/include/read_rsp.h @@ -0,0 +1,14 @@ +#ifndef READ_RSP_H +#define READ_RSP_H + +#include <stdio.h> +#include "queue_t.h" + +#define BUFFER_SIZE 32768 + +extern queue_t queue; + +/* read test data from .rsp file into queue */ +int read_test_data(FILE * test_data); + +#endif diff --git a/src/tests/libica_sha_test/include/sha_tests.h b/src/tests/libica_sha_test/include/sha_tests.h new file mode 100644 index 0000000..239f3de --- /dev/null +++ b/src/tests/libica_sha_test/include/sha_tests.h @@ -0,0 +1,22 @@ +#ifndef SHA_TESTS_H +#define SHA_TESTS_H + +#include "queue_t.h" + +int sha1_old_api_test(test_t * test); +int sha1_new_api_test(test_t * test); + +int sha224_old_api_test(test_t * test); +int sha224_new_api_test(test_t * test); + +int sha256_old_api_test(test_t * test); +int sha256_new_api_test(test_t * test); + +int sha384_old_api_test(test_t * test); +int sha384_new_api_test(test_t * test); + +int sha512_old_api_test(test_t * test); +int sha512_new_api_test(test_t * test); + +int silent; +#endif diff --git a/src/tests/libica_sha_test/libica_sha_test.c b/src/tests/libica_sha_test/libica_sha_test.c new file mode 100644 index 0000000..66144f8 --- /dev/null +++ b/src/tests/libica_sha_test/libica_sha_test.c @@ -0,0 +1,118 @@ +/* + * usage: libica_sha_test filelist + * test for old and new libica api for sha1/224/256/384/512 + * test vectors are read from .rsp files and put in the queue + * the included .rsp files are obtained from nist: + * http://csrc.nist.gov/groups/STM/cavp/index.html#03 + */ + +#include <stdlib.h> +#include <string.h> + +#include "ica_api.h" +#include "sha_tests.h" +#include "read_rsp.h" +#include "queue_t.h" +#include "critical_error.h" +#include "../testcase.h" + +queue_t queue; + +int main(int argc, char *argv[]) +{ + test_t *curr_test; + FILE *test_data; + int i, rc; + + /* first cmd line arg may be verbosity */ + if ((argc >= 2) && (argv[1][0] == '-')) { + set_verbosity(2, argv); + i = 2; + } + else + i = 1; + + if (argc - i == 0) { + printf("error: no input files.\n"); + return EXIT_FAILURE; + } + + queue = new_queue_t(); + + /* read test vectors from .rsp file(s) and put on queue */ + for (; i < argc; i++) { + if ((test_data = fopen(argv[i], "r")) != NULL) { + VV_(printf("reading test data from %s ... ", argv[i])); + if (read_test_data(test_data) == EXIT_SUCCESS) { + VV_(printf("done.\n")); + } + if ((fclose(test_data)) == EOF) { + V_(printf("error: couldn't close file %s.\n", + argv[i])); + } + } else { + V_(printf("error: couldn't open file %s.\n", argv[i])); + } + } + + VV_(printf("%u test vectors found.\n", queue.size)); + + if (queue.size > 0) { + V_(printf("starting tests ...\n\n")); + } else { + printf("error: no SHA test vectors found.\n"); + return EXIT_FAILURE; + } + /* run each test in queue with new and old api */ + for (curr_test = queue.head, i = 1; curr_test != NULL; + curr_test = curr_test->next, i++) { + V_(printf("test #%d : %u byte input message, ", i, + curr_test->msg_length)); + switch (curr_test->type) { + case SHA1: + V_(printf("SHA1 ...\n")); + rc = sha1_new_api_test(curr_test); + break; + case SHA224: + V_(printf("SHA224 ...\n")); + rc = sha224_new_api_test(curr_test); + break; + case SHA256: + V_(printf("SHA256 ...\n")); + rc = sha256_new_api_test(curr_test); + break; + case SHA384: + V_(printf("SHA384 ...\n")); + rc = sha384_new_api_test(curr_test); + break; + case SHA512: + V_(printf("SHA512 ...\n")); + rc = sha512_new_api_test(curr_test); + break; + default: + CRITICAL_ERROR("Unknown algorithm.\n"); + rc = -1; + break; + } + if (!rc) { + V_(printf("... Passed.\n")); + queue.passed++; + } + else { + V_(printf("error: (%x).\n", rc)); + queue.failed++; + } + + } + V_(printf("[SHA test case results: tests: %u, passed: %u, failed: %u]\n", + queue.passed + queue.failed, queue.passed, queue.failed)); + + if (queue.failed == 0) { + printf("All SHA tests passed.\n"); + return EXIT_SUCCESS; + } + else { + printf("SHA tests failed.\n"); + return EXIT_FAILURE; + } +} diff --git a/src/tests/libica_sha_test/queue_t.c b/src/tests/libica_sha_test/queue_t.c new file mode 100644 index 0000000..4df26bc --- /dev/null +++ b/src/tests/libica_sha_test/queue_t.c @@ -0,0 +1,60 @@ +#include <stdlib.h> +#include <string.h> +#include "queue_t.h" +#include "critical_error.h" + +test_t new_test_t(void) +{ + test_t test; + + test.type = NO_TYPE_SET; + test.msg = NULL; + test.msg_length = 0; + test.msg_digest = NULL; + test.msg_digest_length = 0; + test.next = NULL; + + return test; +} + +queue_t new_queue_t(void) +{ + queue_t queue; + + queue.size = 0; + queue.passed = 0; + queue.failed = 0; + queue.head = NULL; + queue.tail = NULL; + + return queue; +} + +void push(queue_t * queue, test_t test) +{ + test_t *new_test; + + if ((new_test = (test_t *) malloc(sizeof(test_t))) == NULL) + CRITICAL_ERROR("out of memory."); + + new_test->type = test.type; + new_test->msg_length = test.msg_length; + new_test->msg_digest_length = test.msg_digest_length; + + new_test->msg = (unsigned char *)malloc((size_t) test.msg_length); + memcpy(new_test->msg, test.msg, (size_t) test.msg_length); + + new_test->msg_digest = + (unsigned char *)malloc((size_t) test.msg_digest_length); + memcpy(new_test->msg_digest, test.msg_digest, + (size_t) test.msg_digest_length); + + new_test->next = NULL; + + if (queue->head == NULL) + queue->head = new_test; + else + queue->tail->next = new_test; + queue->tail = new_test; + queue->size++; +} diff --git a/src/tests/libica_sha_test/read_rsp.c b/src/tests/libica_sha_test/read_rsp.c new file mode 100644 index 0000000..ae2c9d6 --- /dev/null +++ b/src/tests/libica_sha_test/read_rsp.c @@ -0,0 +1,200 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "ica_api.h" +#include "queue_t.h" +#include "critical_error.h" +#include "read_rsp.h" + +static int line_to_bytes(char *line, int length); + +int read_test_data(FILE * test_data) +{ + char buffer[BUFFER_SIZE]; + enum { MSG_LENGTH, MSG, MSG_DIGEST } search_term; + + test_t tmp_test = new_test_t(); + unsigned int current_type = NO_TYPE_SET; + unsigned int current_msg_digest_length = NO_LENGTH_SET; + + unsigned int line_number = 0; + + char *tmp = NULL; + search_term = MSG_LENGTH; + + while (fgets(buffer, (int)sizeof buffer, test_data) != NULL) { + + line_number++; + + /* remove comments */ + if ((tmp = memchr(buffer, (int)'#', strlen(buffer))) != NULL) + memset(tmp, 0, strlen(tmp)); + + /* scan for: type/msg_digest_length */ + if (((sscanf(buffer, "[L = %u]", ¤t_msg_digest_length)) + == 1) + || (current_type == NO_TYPE_SET)) { + if (tmp_test.type != NO_TYPE_SET) { + printf + ("error:\nincorrect file format [line %u]: test type mustn't change during test definition. closing file.\n", + line_number); + return EXIT_FAILURE; + } + switch (current_msg_digest_length) { + case NO_LENGTH_SET: + continue; + case SHA1_HASH_LENGTH: + current_type = SHA1; + break; + case SHA224_HASH_LENGTH: + current_type = SHA224; + break; + case SHA256_HASH_LENGTH: + current_type = SHA256; + break; + case SHA384_HASH_LENGTH: + current_type = SHA384; + break; + case SHA512_HASH_LENGTH: + current_type = SHA512; + break; + default: + CRITICAL_ERROR("this shouldn't happen."); + break; + } + } + + /* scan for: 1st msg_length, 2nd msg, 3rd msg_digest. repeat */ + switch (search_term) { + case MSG_LENGTH: + if (sscanf(buffer, "Len = %u", &tmp_test.msg_length) == + 1) { + if ((tmp_test.msg_length % 8) != 0) { + printf + ("error:\nincorrect file format [line %u]: message bit-length must be a multiple of 8. closing file.", + line_number); + return EXIT_FAILURE; + } + tmp_test.msg_length /= 8; + search_term = MSG; + } + break; + case MSG: + if (sscanf(buffer, "Msg = %s", buffer) == 1) { + if ((int)strlen(buffer) % 2 != 0) { + printf + ("error:\nincorrect file format [line %u]: message should be bytes. closing file.\n", + line_number); + return EXIT_FAILURE; + } + if (line_to_bytes + (buffer, + (int)strlen(buffer)) == EXIT_FAILURE) { + printf + ("error:\nincorrect file format [line %u]: message contains characters different from hex values. closing file.\n", + line_number); + return EXIT_FAILURE; + } + if ((tmp_test.msg = (unsigned char *) + malloc((size_t) tmp_test.msg_length)) + == NULL) + CRITICAL_ERROR("out of memory."); + memcpy(tmp_test.msg, buffer, + (size_t) tmp_test.msg_length); + search_term = MSG_DIGEST; + } + break; + case MSG_DIGEST: + if (sscanf(buffer, "MD = %s", buffer) + == 1) { + if (((int)strlen(buffer) % 2 != 0) + || (((int)strlen(buffer) / 2) != + current_msg_digest_length)) { + printf + ("error:\nincorrect file format [line %u]: message digest length doesn't match test type. closing file.\n", + line_number); + free(tmp_test.msg); + return EXIT_FAILURE; + } + if (line_to_bytes + (buffer, + (int)strlen(buffer)) == EXIT_FAILURE) { + printf + ("error:\nincorrect file format [line %u]: message digest contains characters different from hex values. closing file.\n", + line_number); + free(tmp_test.msg); + return EXIT_FAILURE; + } + if ((tmp_test.msg_digest = (unsigned char *) + malloc((size_t) + current_msg_digest_length)) + == NULL) + CRITICAL_ERROR("out of memory."); + memcpy(tmp_test.msg_digest, buffer, + (size_t) current_msg_digest_length); + tmp_test.type = current_type; + tmp_test.msg_digest_length = + current_msg_digest_length; + push(&queue, tmp_test); + free(tmp_test.msg); + free(tmp_test.msg_digest); + tmp_test = new_test_t(); + search_term = MSG_LENGTH; + } + break; + default: + CRITICAL_ERROR("this shouldn't happen."); + break; + } + if (feof(test_data) != 0) { + CRITICAL_ERROR("read error."); + } + } + free(tmp_test.msg); + free(tmp_test.msg_digest); + + if (feof(test_data) == 0) { + printf("error:\ndidn't reach end of file. closing file.\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +static int line_to_bytes(char *line, int length) +{ + int i; + unsigned char *bytes; + if ((bytes = (unsigned char *) + malloc((size_t) (length / 2))) == NULL) + CRITICAL_ERROR("out of memory."); + for (i = 0; i <= ((length / 2) - 1); i++) { + if (line[2 * i] >= 'a' && line[2 * i] <= 'f') + line[2 * i] = line[2 * i] - 'a' + (char)10; + else if (line[2 * i] >= '0' && line[2 * i] <= '9') + line[2 * i] = line[2 * i] - '0'; + else if (line[2 * i] >= 'A' && line[2 * i] <= 'F') + line[2 * i] = line[2 * i] - 'A' + (char)10; + else { + free(bytes); + return EXIT_FAILURE; + } + bytes[i] = (unsigned char)(line[2 * i] * (char)16); + if (line[2 * i + 1] >= 'a' && line[2 * i + 1] <= 'f') + line[2 * i + 1] = line[2 * i + 1] - (char)87; + else if (line[2 * i + 1] >= '0' && line[2 * i + 1] <= '9') + line[2 * i + 1] = line[2 * i + 1] - (char)48; + else if (line[2 * i + 1] >= 'A' && line[2 * i + 1] <= 'F') + line[2 * i + 1] = line[2 * i + 1] - 'A' + (char)10; + else { + free(bytes); + return EXIT_FAILURE; + } + bytes[i] += (unsigned char)line[2 * i + 1]; + } + memcpy(line, bytes, (size_t) (length / 2)); + memset(line + length / 2, 0, (size_t) (length / 2 + 1)); + free(bytes); + + return EXIT_SUCCESS; +} diff --git a/src/tests/libica_sha_test/sha_test_vectors/SHA1.txt b/src/tests/libica_sha_test/sha_test_vectors/SHA1.txt new file mode 100644 index 0000000..a283e3f --- /dev/null +++ b/src/tests/libica_sha_test/sha_test_vectors/SHA1.txt @@ -0,0 +1,36 @@ +# SHA1 tests
+
+[L = 20]
+
+Len = 0
+Msg = 00
+MD = da39a3ee5e6b4b0d3255bfef95601890afd80709
+
+Len = 8
+Msg = 36
+MD = c1dfd96eea8cc2b62785275bca38ac261256e278
+
+Len = 16
+Msg = 195a
+MD = 0a1c2d555bbe431ad6288af5a54f93e0449c9232
+
+Len = 32
+Msg = 549e959e
+MD = b78bae6d14338ffccfd5d5b5674a275f6ef9c717
+
+Len = 64
+Msg = 7e3d7b3eada98866
+MD = 24a2c34b976305277ce58c2f42d5092031572520
+
+Len = 128
+Msg = 3552694cdf663fd94b224747ac406aaf
+MD = a150de927454202d94e656de4c7c0ca691de955d
+
+Len = 256
+Msg = 0321794b739418c24e7c2e565274791c4be749752ad234ed56cb0a6347430c6b
+MD = b89962c94d60f6a332fd60f6f07d4f032a586b76
+
+Len = 512
+Msg = 45927e32ddf801caf35e18e7b5078b7f5435278212ec6bb99df884f49b327c6486feae46ba187dc1cc9145121e1492e6b06e9007394dc33b7748f86ac3207cfe
+MD = a70cfbfe7563dd0e665c7c6715a96a8d756950c0
+
diff --git a/src/tests/libica_sha_test/sha_test_vectors/SHA224.txt b/src/tests/libica_sha_test/sha_test_vectors/SHA224.txt new file mode 100644 index 0000000..8d6b1d7 --- /dev/null +++ b/src/tests/libica_sha_test/sha_test_vectors/SHA224.txt @@ -0,0 +1,39 @@ +# CAVS 11.0
+# "SHA-224 ShortMsg" information
+# SHA-224 tests are configured for BYTE oriented implementations
+# Generated on Tue Mar 15 08:23:36 2011
+
+[L = 28]
+
+Len = 0
+Msg = 00
+MD = d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f
+
+Len = 8
+Msg = 84
+MD = 3cd36921df5d6963e73739cf4d20211e2d8877c19cff087ade9d0e3a
+
+Len = 16
+Msg = 5c7b
+MD = daff9bce685eb831f97fc1225b03c275a6c112e2d6e76f5faf7a36e6
+
+Len = 32
+Msg = 6084347e
+MD = ae57c0a6d49739ba338adfa53bdae063e5c09122b77604780a8eeaa3
+
+Len = 64
+Msg = 5f77b3664823c33e
+MD = bdf21ff325f754157ccf417f4855360a72e8fd117d28c8fe7da3ea38
+
+Len = 128
+Msg = b776708ffb91b3515ac46598ab9fa796
+MD = 427311b1d7ab2488791c4deeb4251d783fe5f9806bfdfb5188c5443d
+
+Len = 256
+Msg = fe1f0fb02c9011f4c8c5905934ed15136771737ce31c5859e67f235fe594f5f6
+MD = bbeaacc632c2a3db2a9b47f157ab54aa27776c6e74cf0bcaa91b06d5
+
+Len = 512
+Msg = a3310ba064be2e14ad32276e18cd0310c933a6e650c3c754d0243c6c61207865b4b65248f66a08edf6e0832689a9dc3a2e5d2095eeea50bd862bac88c8bd318d
+MD = b2a5586d9cbf0baa999157b4af06d88ae08d7c9faab4bc1a96829d65
+
diff --git a/src/tests/libica_sha_test/sha_test_vectors/SHA256.txt b/src/tests/libica_sha_test/sha_test_vectors/SHA256.txt new file mode 100644 index 0000000..c8bc15b --- /dev/null +++ b/src/tests/libica_sha_test/sha_test_vectors/SHA256.txt @@ -0,0 +1,39 @@ +# CAVS 11.0
+# "SHA-256 ShortMsg" information
+# SHA-256 tests are configured for BYTE oriented implementations
+# Generated on Tue Mar 15 08:23:38 2011
+
+[L = 32]
+
+Len = 0
+Msg = 00
+MD = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+
+Len = 8
+Msg = d3
+MD = 28969cdfa74a12c82f3bad960b0b000aca2ac329deea5c2328ebc6f2ba9802c1
+
+Len = 16
+Msg = 11af
+MD = 5ca7133fa735326081558ac312c620eeca9970d1e70a4b95533d956f072d1f98
+
+Len = 32
+Msg = 74ba2521
+MD = b16aa56be3880d18cd41e68384cf1ec8c17680c45a02b1575dc1518923ae8b0e
+
+Len = 64
+Msg = 5738c929c4f4ccb6
+MD = 963bb88f27f512777aab6c8b1a02c70ec0ad651d428f870036e1917120fb48bf
+
+Len = 128
+Msg = 0a27847cdc98bd6f62220b046edd762b
+MD = 80c25ec1600587e7f28b18b1b18e3cdc89928e39cab3bc25e4d4a4c139bcedc4
+
+Len = 256
+Msg = 09fc1accc230a205e4a208e64a8f204291f581a12756392da4b8c0cf5ef02b95
+MD = 4f44c1c7fbebb6f9601829f3897bfd650c56fa07844be76489076356ac1886a4
+
+Len = 512
+Msg = 5a86b737eaea8ee976a0a24da63e7ed7eefad18a101c1211e2b3650c5187c2a8a650547208251f6d4237e661c7bf4c77f335390394c37fa1a9f9be836ac28509
+MD = 42e61e174fbb3897d6dd6cef3dd2802fe67b331953b06114a65c772859dfc1aa
+
diff --git a/src/tests/libica_sha_test/sha_test_vectors/SHA384.txt b/src/tests/libica_sha_test/sha_test_vectors/SHA384.txt new file mode 100644 index 0000000..6f2acb4 --- /dev/null +++ b/src/tests/libica_sha_test/sha_test_vectors/SHA384.txt @@ -0,0 +1,43 @@ +# CAVS 11.0
+# "SHA-384 ShortMsg" information
+# SHA-384 tests are configured for BYTE oriented implementations
+# Generated on Tue Mar 15 08:23:39 2011
+
+[L = 48]
+
+Len = 0
+Msg = 00
+MD = 38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b
+
+Len = 8
+Msg = c5
+MD = b52b72da75d0666379e20f9b4a79c33a329a01f06a2fb7865c9062a28c1de860ba432edfd86b4cb1cb8a75b46076e3b1
+
+Len = 16
+Msg = 6ece
+MD = 53d4773da50d8be4145d8f3a7098ff3691a554a29ae6f652cc7121eb8bc96fd2210e06ae2fa2a36c4b3b3497341e70f0
+
+Len = 32
+Msg = 50e3853d
+MD = 936a3c3991716ba4c413bc03de20f5ce1c63703b3a5bdb6ab558c9ff70d537e46eb4a15d9f2c85e68d8678de5682695e
+
+Len = 64
+Msg = de60275bdafce4b1
+MD = a3d861d866c1362423eb21c6bec8e44b74ce993c55baa2b6640567560ebecdaeda07183dbbbd95e0f522caee5ddbdaf0
+
+Len = 128
+Msg = e1bb967b5d379a4aa39050274d09bd93
+MD = 3b04f96965ad2fbabd4df25d5d8c95589d069c312ee48539090b2d7b495d2446c31eb2b8f8ffb3012bdce065323d9f48
+
+Len = 256
+Msg = be01e520e69f04174ccf95455b1c81445298264d9adc4958574a52843d95b8ba
+MD = c5cf54b8e3105b1c7bf7a43754d915b0947f28b6dc94a019182929b5c848e11441c9e4e90c7449f4c3cd12954f0f5d99
+
+Len = 512
+Msg = 93035d3a13ae1b06dd033e764aca0124961da79c366c6c756bc4bcc11850a3a8d120854f34290fff7c8d6d83531dbdd1e81cc4ed4246e00bd4113ef451334daa
+MD = 8d46cc84b6c2deb206aa5c861798798751a26ee74b1daf3a557c41aebd65adc027559f7cd92b255b374c83bd55568b45
+
+Len = 1024
+Msg = 3bf52cc5ee86b9a0190f390a5c0366a560b557000dbe5115fd9ee11630a62769011575f15881198f227876e8fe685a6939bc8b89fd48a34ec5e71e131462b2886794dffa68ccc6d564733e67ffef25e627c6f4b5460796e3bce67bf58ca6e8e555bc916a8531697ac948b90dc8616f25101db90b50c3d3dbc9e21e42ff387187
+MD = 12b6cb35eda92ee37356ddee77781a17b3d90e563824a984faffc6fdd1693bd7626039635563cfc3b9a2b00f9c65eefd
+
diff --git a/src/tests/libica_sha_test/sha_test_vectors/SHA512.txt b/src/tests/libica_sha_test/sha_test_vectors/SHA512.txt new file mode 100644 index 0000000..2c5b38d --- /dev/null +++ b/src/tests/libica_sha_test/sha_test_vectors/SHA512.txt @@ -0,0 +1,43 @@ +# CAVS 11.0
+# "SHA-512 ShortMsg" information
+# SHA-512 tests are configured for BYTE oriented implementations
+# Generated on Tue Mar 15 08:23:49 2011
+
+[L = 64]
+
+Len = 0
+Msg = 00
+MD = cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e
+
+Len = 8
+Msg = 21
+MD = 3831a6a6155e509dee59a7f451eb35324d8f8f2df6e3708894740f98fdee23889f4de5adb0c5010dfb555cda77c8ab5dc902094c52de3278f35a75ebc25f093a
+
+Len = 16
+Msg = 9083
+MD = 55586ebba48768aeb323655ab6f4298fc9f670964fc2e5f2731e34dfa4b0c09e6e1e12e3d7286b3145c61c2047fb1a2a1297f36da64160b31fa4c8c2cddd2fb4
+
+Len = 32
+Msg = 23be86d5
+MD = 76d42c8eadea35a69990c63a762f330614a4699977f058adb988f406fb0be8f2ea3dce3a2bbd1d827b70b9b299ae6f9e5058ee97b50bd4922d6d37ddc761f8eb
+
+Len = 64
+Msg = 6f8d58b7cab1888c
+MD = a3941def2803c8dfc08f20c06ba7e9a332ae0c67e47ae57365c243ef40059b11be22c91da6a80c2cff0742a8f4bcd941bdee0b861ec872b215433ce8dcf3c031
+
+Len = 128
+Msg = cd67bd4054aaa3baa0db178ce232fd5a
+MD = 0d8521f8f2f3900332d1a1a55c60ba81d04d28dfe8c504b6328ae787925fe0188f2ba91c3a9f0c1653c4bf0ada356455ea36fd31f8e73e3951cad4ebba8c6e04
+
+Len = 256
+Msg = 8ccb08d2a1a282aa8cc99902ecaf0f67a9f21cffe28005cb27fcf129e963f99d
+MD = 4551def2f9127386eea8d4dae1ea8d8e49b2add0509f27ccbce7d9e950ac7db01d5bca579c271b9f2d806730d88f58252fd0c2587851c3ac8a0e72b4e1dc0da6
+
+Len = 512
+Msg = c1ca70ae1279ba0b918157558b4920d6b7fba8a06be515170f202fafd36fb7f79d69fad745dba6150568db1e2b728504113eeac34f527fc82f2200b462ecbf5d
+MD = 046e46623912b3932b8d662ab42583423843206301b58bf20ab6d76fd47f1cbbcf421df536ecd7e56db5354e7e0f98822d2129c197f6f0f222b8ec5231f3967d
+
+Len = 1024
+Msg = fd2203e467574e834ab07c9097ae164532f24be1eb5d88f1af7748ceff0d2c67a21f4e4097f9d3bb4e9fbf97186e0db6db0100230a52b453d421f8ab9c9a6043aa3295ea20d2f06a2f37470d8a99075f1b8a8336f6228cf08b5942fc1fb4299c7d2480e8e82bce175540bdfad7752bc95b577f229515394f3ae5cec870a4b2f8
+MD = a21b1077d52b27ac545af63b32746c6e3c51cb0cb9f281eb9f3580a6d4996d5c9917d2a6e484627a9d5a06fa1b25327a9d710e027387fc3e07d7c4d14c6086cc
+
diff --git a/src/tests/libica_sha_test/sha_tests.c b/src/tests/libica_sha_test/sha_tests.c new file mode 100644 index 0000000..bb24609 --- /dev/null +++ b/src/tests/libica_sha_test/sha_tests.c @@ -0,0 +1,186 @@ +#include <stdio.h> +#include <stdlib.h> +#include <sys/errno.h> +#include <fcntl.h> +#include <string.h> +#include "ica_api.h" +#include "queue_t.h" +#include "sha_tests.h" +#include "critical_error.h" +#define VERBOSE_EXTERN +#include "../testcase.h" +#undef VERBOSE_EXTERN + + +int sha1_new_api_test(test_t * test) +{ + + sha_context_t sha_context; + int rc = 0; + unsigned char output[SHA_HASH_LENGTH]; + + if (test->msg_digest_length != SHA_HASH_LENGTH) + CRITICAL_ERROR("this shouldn't happen."); + + rc = (int)ica_sha1(SHA_MSG_PART_ONLY, test->msg_length, test->msg, + &sha_context, output); + + if (rc != 0) { + V_(printf("ica_sha1 failed with errno %d (0x%x).\n", rc, + (unsigned int)rc)); + return rc; + } + + VV_(printf("message digest (new api)\n")); + dump_array(output, SHA_HASH_LENGTH); + + if (memcmp(output, test->msg_digest, SHA_HASH_LENGTH) != 0) { + V_(printf("output is not what it should be.\n")); + return 2; + } + return 0; +} + +int sha224_new_api_test(test_t * test) +{ + sha256_context_t sha256_context; + int rc = 0; + unsigned char output[SHA224_HASH_LENGTH]; + + if (test->msg_digest_length != SHA224_HASH_LENGTH) + CRITICAL_ERROR("this shouldn't happen."); + + rc = (int)ica_sha224(SHA_MSG_PART_ONLY, test->msg_length, test->msg, + &sha256_context, output); + + if (rc != 0) { + V_(printf("ica_sha224 failed with errno %d (0x%x).\n", rc, + (unsigned int)rc)); + return rc; + } + + VV_(printf("message digest (new api)\n")); + dump_array(output, SHA224_HASH_LENGTH); + + if (memcmp(output, test->msg_digest, SHA224_HASH_LENGTH) != 0) { + V_(printf("output is not what it should be.\n")); + return 2; + } + + return 0; +} + +int sha256_new_api_test(test_t * test) +{ + sha256_context_t sha256_context; + int rc = 0; + unsigned char output[SHA256_HASH_LENGTH]; + + if (test->msg_digest_length != SHA256_HASH_LENGTH) + CRITICAL_ERROR("this shouldn't happen."); + + rc = (int)ica_sha256(SHA_MSG_PART_ONLY, test->msg_length, test->msg, + &sha256_context, output); + + if (rc != 0) { + V_(printf("ica_sha256 failed with errno %d (0x%x).\n", rc, + (unsigned int)rc)); + return rc; + } + + VV_(printf("message digest (new api)\n")); + dump_array(output, SHA256_HASH_LENGTH); + + if (memcmp(output, test->msg_digest, SHA256_HASH_LENGTH) != 0) { + V_(printf("output is not what it should be.\n")); + return 2; + } + + return 0; +} + +int sha384_new_api_test(test_t * test) +{ + sha512_context_t sha512_context; + int rc = 0; + unsigned char output[SHA384_HASH_LENGTH]; + + if (test->msg_digest_length != SHA384_HASH_LENGTH) + CRITICAL_ERROR("this shouldn't happen."); + + rc = (int)ica_sha384(SHA_MSG_PART_ONLY, test->msg_length, test->msg, + &sha512_context, output); + + if (rc != 0) { + V_(printf("ica_sha384 failed with errno %d (0x%x).\n", rc, + (unsigned int)rc)); + return rc; + } + + VV_(printf("message digest (new api)\n")); + dump_array(output, SHA384_HASH_LENGTH); + + if (memcmp(output, test->msg_digest, SHA384_HASH_LENGTH) != 0) { + V_(printf("output is not what it should be.\n")); + return 2; + } + + return 0; +} + +int sha512_new_api_test(test_t * test) +{ + sha512_context_t sha512_context; + int rc = 0; + unsigned char output[SHA512_HASH_LENGTH]; + + if (test->msg_digest_length != SHA512_HASH_LENGTH) + CRITICAL_ERROR("this shouldn't happen."); + + rc = (int)ica_sha512(SHA_MSG_PART_ONLY, test->msg_length, test->msg, + &sha512_context, output); + + if (rc != 0) { + V_(printf("ica_sha512 failed with errno %d (0x%x).\n", rc, + (unsigned int)rc)); + return rc; + } + + VV_(printf("message digest (new api)\n")); + dump_array(output, SHA512_HASH_LENGTH); + + if (memcmp(output, test->msg_digest, SHA512_HASH_LENGTH) != 0) { + V_(printf("output is not what it should be.\n")); + return 2; + } + return 0; +} +/* +static void dump_array(unsigned char *ptr, unsigned int size) +{ + unsigned char *ptr_end; + unsigned char *h; + int i = 1, trunc = 0; + + if (size > 64) { + trunc = (int)size - 64; + size = 64; + } + h = ptr; + ptr_end = ptr + size; + while (h < ptr_end) { + printf("0x%02x ", (unsigned int)*h); + h++; + if (i == 8) { + if (h != ptr_end) + printf("\n"); + i = 1; + } else { + ++i; + } + } + printf("\n"); + if (trunc > 0) + printf("... %d bytes not printed\n", trunc); +} +*/ diff --git a/src/tests/suite.run b/src/tests/suite.run new file mode 100755 index 0000000..bcf74de --- /dev/null +++ b/src/tests/suite.run @@ -0,0 +1,63 @@ +#!/bin/bash + +# +# Libica test suite +# + +verbosity=$1 + +out="./suite.out" + +testcases=( +"libica_fips_test" + +"libica_get_functionlist $verbosity" +"libica_get_version $verbosity" +"icastats_test $verbosity" + +"libica_drbg_test $verbosity" + +"libica_des_ecb_test $verbosity" +"libica_des_cbc_test $verbosity" +"libica_des_cfb_test $verbosity" +"libica_des_ofb_test $verbosity" +"libica_des_ctr_test $verbosity" + +"libica_3des_ecb_test $verbosity" +"libica_3des_cbc_test $verbosity" +"libica_3des_cfb_test $verbosity" +"libica_3des_ofb_test $verbosity" +"libica_3des_ctr_test $verbosity" + +"libica_aes128_test $verbosity" +"libica_aes192_test $verbosity" +"libica_aes256_test $verbosity" +"libica_aes_ecb_test $verbosity" +"libica_aes_cbc_test $verbosity" +"libica_aes_cfb_test $verbosity" +"libica_aes_ofb_test $verbosity" +"libica_aes_ctr_test $verbosity" +"libica_aes_gcm_test $verbosity" +"libica_aes_xts_test $verbosity" + +"libica_cbccs_test $verbosity" +"libica_ccm_test $verbosity" +"libica_cmac_test $verbosity" + +"libica_keygen_test $verbosity 1024 r" +"libica_keygen_test $verbosity 2048 r" +"libica_keygen_test $verbosity 3072 r" +"libica_keygen_test $verbosity 4096 r" +"libica_rsa_key_check_test $verbosity" +"libica_rsa_test $verbosity" + +"libica_sha_test/libica_sha_test $verbosity libica_sha_test/sha_test_vectors/*" +) + +echo -ne "" &> $out; +for (( i=1; i <= ${#testcases[@]}; i++ )) +do + echo -ne "Running libica test suite (writing to "$out") ... "$i"/"${#testcases[@]}"\r"; + ./${testcases[i-1]} >> $out 2>&1; +done +echo -ne "\n"; diff --git a/src/tests/testcase.h b/src/tests/testcase.h new file mode 100644 index 0000000..6d97ae7 --- /dev/null +++ b/src/tests/testcase.h @@ -0,0 +1,47 @@ +/* + * Testcase infrastructure. + */ +#ifndef TESTCASE_H +#define TESTCASE_H + +#include <stddef.h> +#include <string.h> + +#define V_(print) if (verbosity_ >= 1) print +#define VV_(print) if (verbosity_ >= 2) print + +#ifdef VERBOSITY_EXTERN +extern +#endif +int verbosity_; /* default verbosity level: 0 */ + +static inline void +set_verbosity(int argc, char *argv[]) +{ + int i; + + for (i = 1; i < argc; i++) { + if (strcasestr(argv[i], "-vv")) { + verbosity_ = 2; + break; + } + if (strcasestr(argv[i], "-v")) { + verbosity_ = 1; + break; + } + } +} + +static inline void +dump_array(unsigned char array[], size_t len) +{ + size_t i; + + for (i = 1; i <= len; i++) { + VV_(printf("0x%02x ", array[i - 1])); + if ((i % 8 == 0) || (i == len)) + VV_(printf("\n")); + } +} + +#endif /* TESTCASE_H */ |