1527cbf3dSMarko Kovacevic /* SPDX-License-Identifier: BSD-3-Clause 2527cbf3dSMarko Kovacevic * Copyright(c) 2018 Intel Corporation 3527cbf3dSMarko Kovacevic */ 4527cbf3dSMarko Kovacevic 5527cbf3dSMarko Kovacevic #include <string.h> 6527cbf3dSMarko Kovacevic #include <stdio.h> 7527cbf3dSMarko Kovacevic 8527cbf3dSMarko Kovacevic #include <rte_malloc.h> 9527cbf3dSMarko Kovacevic #include <rte_cryptodev.h> 10527cbf3dSMarko Kovacevic 11527cbf3dSMarko Kovacevic #include "fips_validation.h" 12527cbf3dSMarko Kovacevic 13527cbf3dSMarko Kovacevic #define NEW_LINE_STR "#" 14527cbf3dSMarko Kovacevic #define TEST_TYPE_KEY " for CBC" 15*efe3a8dbSMichael Shamis #define TEST_TYPE_ECB_KEY " for ECB" 16527cbf3dSMarko Kovacevic #define TEST_CBCI_KEY " for CBCI" 17527cbf3dSMarko Kovacevic 18527cbf3dSMarko Kovacevic #define ENC_STR "[ENCRYPT]" 19527cbf3dSMarko Kovacevic #define DEC_STR "[DECRYPT]" 20527cbf3dSMarko Kovacevic 21527cbf3dSMarko Kovacevic #define COUNT_STR "COUNT = " 22527cbf3dSMarko Kovacevic #define KEY1_STR "KEY1 = " 23527cbf3dSMarko Kovacevic #define KEY2_STR "KEY2 = " 24527cbf3dSMarko Kovacevic #define KEY3_STR "KEY3 = " 25527cbf3dSMarko Kovacevic 26527cbf3dSMarko Kovacevic #define KEYS_STR "KEYs = " 27527cbf3dSMarko Kovacevic #define IV_STR "IV = " 28527cbf3dSMarko Kovacevic #define PT_STR "PLAINTEXT = " 29527cbf3dSMarko Kovacevic #define CT_STR "CIPHERTEXT = " 30527cbf3dSMarko Kovacevic #define NK_STR "NumKeys = " 31527cbf3dSMarko Kovacevic 32527cbf3dSMarko Kovacevic #define SET_STR " = " 33527cbf3dSMarko Kovacevic 34527cbf3dSMarko Kovacevic #define PLAIN_TEXT 0 35527cbf3dSMarko Kovacevic #define CIPHER_TEXT 1 36527cbf3dSMarko Kovacevic #define KEY_TEXT 2 37527cbf3dSMarko Kovacevic #define IV_TEXT 3 38527cbf3dSMarko Kovacevic 39527cbf3dSMarko Kovacevic #define DEVICE_STR "# Config Info for : " 40527cbf3dSMarko Kovacevic 41527cbf3dSMarko Kovacevic struct { 42527cbf3dSMarko Kovacevic uint32_t type; 43527cbf3dSMarko Kovacevic const char *desc; 44527cbf3dSMarko Kovacevic } test_types[] = { 45527cbf3dSMarko Kovacevic {TDES_INVERSE_PERMUTATION, "INVERSE PERMUTATION"}, 46527cbf3dSMarko Kovacevic {TDES_PERMUTATION, "PERMUTATION OPERATION"}, 47527cbf3dSMarko Kovacevic {TDES_SUBSTITUTION_TABLE, "SUBSTITUTION TABLE"}, 48527cbf3dSMarko Kovacevic {TDES_VARIABLE_KEY, "VARIABLE KEY"}, 49527cbf3dSMarko Kovacevic {TDES_VARIABLE_TEXT, "VARIABLE PLAINTEXT/CIPHERTEXT"}, 50527cbf3dSMarko Kovacevic {TDES_VARIABLE_TEXT, "KAT"}, 51527cbf3dSMarko Kovacevic {TDES_MCT, "Monte Carlo (Modes) Test"}, 52527cbf3dSMarko Kovacevic {TDES_MMT, "Multi block Message Test"}, 53527cbf3dSMarko Kovacevic }; 54527cbf3dSMarko Kovacevic 55527cbf3dSMarko Kovacevic static int 56527cbf3dSMarko Kovacevic writeback_tdes_hex_str(const char *key, char *dst, struct fips_val *val); 57527cbf3dSMarko Kovacevic 58527cbf3dSMarko Kovacevic static int 59527cbf3dSMarko Kovacevic parse_tdes_uint8_hex_str(const char *key, char *src, struct fips_val *val); 60527cbf3dSMarko Kovacevic 61527cbf3dSMarko Kovacevic static int 62527cbf3dSMarko Kovacevic parse_tdes_interim(const char *key, 63527cbf3dSMarko Kovacevic __attribute__((__unused__)) char *text, 64527cbf3dSMarko Kovacevic struct fips_val *val); 65527cbf3dSMarko Kovacevic 66527cbf3dSMarko Kovacevic struct fips_test_callback tdes_tests_vectors[] = { 67527cbf3dSMarko Kovacevic {KEYS_STR, parse_tdes_uint8_hex_str, &vec.cipher_auth.key}, 68527cbf3dSMarko Kovacevic {KEY1_STR, parse_tdes_uint8_hex_str, &vec.cipher_auth.key}, 69527cbf3dSMarko Kovacevic {KEY2_STR, parse_tdes_uint8_hex_str, &vec.cipher_auth.key}, 70527cbf3dSMarko Kovacevic {KEY3_STR, parse_tdes_uint8_hex_str, &vec.cipher_auth.key}, 71527cbf3dSMarko Kovacevic {IV_STR, parse_uint8_hex_str, &vec.iv}, 72527cbf3dSMarko Kovacevic {PT_STR, parse_uint8_hex_str, &vec.pt}, 73527cbf3dSMarko Kovacevic {CT_STR, parse_uint8_hex_str, &vec.ct}, 74527cbf3dSMarko Kovacevic {NULL, NULL, NULL} /**< end pointer */ 75527cbf3dSMarko Kovacevic }; 76527cbf3dSMarko Kovacevic 77527cbf3dSMarko Kovacevic struct fips_test_callback tdes_tests_interim_vectors[] = { 78527cbf3dSMarko Kovacevic {ENC_STR, parse_tdes_interim, NULL}, 79527cbf3dSMarko Kovacevic {DEC_STR, parse_tdes_interim, NULL}, 80527cbf3dSMarko Kovacevic {NULL, NULL, NULL} /**< end pointer */ 81527cbf3dSMarko Kovacevic }; 82527cbf3dSMarko Kovacevic 83527cbf3dSMarko Kovacevic struct fips_test_callback tdes_writeback_callbacks[] = { 84527cbf3dSMarko Kovacevic /** First element is used to pass COUNT string */ 85527cbf3dSMarko Kovacevic {COUNT_STR, NULL, NULL}, 86527cbf3dSMarko Kovacevic {IV_STR, writeback_hex_str, &vec.iv}, 87527cbf3dSMarko Kovacevic {KEY1_STR, writeback_tdes_hex_str, &vec.cipher_auth.key}, 88527cbf3dSMarko Kovacevic {KEY2_STR, writeback_tdes_hex_str, &vec.cipher_auth.key}, 89527cbf3dSMarko Kovacevic {KEY3_STR, writeback_tdes_hex_str, &vec.cipher_auth.key}, 90527cbf3dSMarko Kovacevic {KEYS_STR, writeback_tdes_hex_str, &vec.cipher_auth.key}, 91527cbf3dSMarko Kovacevic {PT_STR, writeback_hex_str, &vec.pt}, 92527cbf3dSMarko Kovacevic {CT_STR, writeback_hex_str, &vec.ct}, 93527cbf3dSMarko Kovacevic {NULL, NULL, NULL} /**< end pointer */ 94527cbf3dSMarko Kovacevic }; 95527cbf3dSMarko Kovacevic 96527cbf3dSMarko Kovacevic static int 97527cbf3dSMarko Kovacevic parse_tdes_interim(const char *key, 98527cbf3dSMarko Kovacevic __attribute__((__unused__)) char *text, 99527cbf3dSMarko Kovacevic __attribute__((__unused__)) struct fips_val *val) 100527cbf3dSMarko Kovacevic { 101527cbf3dSMarko Kovacevic if (strstr(key, ENC_STR)) 102527cbf3dSMarko Kovacevic info.op = FIPS_TEST_ENC_AUTH_GEN; 103527cbf3dSMarko Kovacevic else if (strstr(key, DEC_STR)) 104527cbf3dSMarko Kovacevic info.op = FIPS_TEST_DEC_AUTH_VERIF; 105527cbf3dSMarko Kovacevic else if (strstr(NK_STR, "NumKeys = 1")) 106527cbf3dSMarko Kovacevic info.interim_info.tdes_data.nb_keys = 1; 107527cbf3dSMarko Kovacevic else if (strstr(NK_STR, "NumKeys = 2")) 108527cbf3dSMarko Kovacevic info.interim_info.tdes_data.nb_keys = 2; 109527cbf3dSMarko Kovacevic else if (strstr(NK_STR, "NumKeys = 3")) 110527cbf3dSMarko Kovacevic info.interim_info.tdes_data.nb_keys = 3; 111527cbf3dSMarko Kovacevic else 112527cbf3dSMarko Kovacevic return -EINVAL; 113527cbf3dSMarko Kovacevic 114527cbf3dSMarko Kovacevic return 0; 115527cbf3dSMarko Kovacevic } 116527cbf3dSMarko Kovacevic 117527cbf3dSMarko Kovacevic static int 118527cbf3dSMarko Kovacevic parse_tdes_uint8_hex_str(const char *key, char *src, struct fips_val *val) 119527cbf3dSMarko Kovacevic { 120527cbf3dSMarko Kovacevic uint8_t tmp_key[24] = {0}; 121527cbf3dSMarko Kovacevic uint32_t len, i; 122527cbf3dSMarko Kovacevic 123527cbf3dSMarko Kovacevic src += strlen(key); 124527cbf3dSMarko Kovacevic 125527cbf3dSMarko Kovacevic len = strlen(src) / 2; 126527cbf3dSMarko Kovacevic 127527cbf3dSMarko Kovacevic if (val->val) { 128527cbf3dSMarko Kovacevic memcpy(tmp_key, val->val, val->len); 129527cbf3dSMarko Kovacevic rte_free(val->val); 130527cbf3dSMarko Kovacevic } 131527cbf3dSMarko Kovacevic 132527cbf3dSMarko Kovacevic val->val = rte_zmalloc(NULL, 24, 0); 133527cbf3dSMarko Kovacevic if (!val->val) 134527cbf3dSMarko Kovacevic return -1; 135527cbf3dSMarko Kovacevic 136527cbf3dSMarko Kovacevic memcpy(val->val, tmp_key, 24); 137527cbf3dSMarko Kovacevic 138527cbf3dSMarko Kovacevic if (strstr(key, KEYS_STR)) { 139527cbf3dSMarko Kovacevic for (i = 0; i < len; i++) { 140527cbf3dSMarko Kovacevic char byte[3] = {src[i * 2], src[i * 2 + 1], '\0'}; 141527cbf3dSMarko Kovacevic 142527cbf3dSMarko Kovacevic if (parser_read_uint8_hex(&val->val[i], byte) < 0) 143527cbf3dSMarko Kovacevic goto error_exit; 144527cbf3dSMarko Kovacevic } 145527cbf3dSMarko Kovacevic 146527cbf3dSMarko Kovacevic memcpy(val->val + 8, val->val, 8); 147527cbf3dSMarko Kovacevic memcpy(val->val + 16, val->val, 8); 148527cbf3dSMarko Kovacevic 149527cbf3dSMarko Kovacevic } else if (strstr(key, KEY1_STR)) { 150527cbf3dSMarko Kovacevic for (i = 0; i < len; i++) { 151527cbf3dSMarko Kovacevic char byte[3] = {src[i * 2], src[i * 2 + 1], '\0'}; 152527cbf3dSMarko Kovacevic 153527cbf3dSMarko Kovacevic if (parser_read_uint8_hex(&val->val[i], byte) < 0) 154527cbf3dSMarko Kovacevic goto error_exit; 155527cbf3dSMarko Kovacevic } 156527cbf3dSMarko Kovacevic 157527cbf3dSMarko Kovacevic if (info.interim_info.tdes_data.nb_keys == 2) 158527cbf3dSMarko Kovacevic memcpy(val->val + 16, val->val, 8); 159527cbf3dSMarko Kovacevic 160527cbf3dSMarko Kovacevic } else if (strstr(key, KEY2_STR)) { 161527cbf3dSMarko Kovacevic for (i = 0; i < len; i++) { 162527cbf3dSMarko Kovacevic char byte[3] = {src[i * 2], src[i * 2 + 1], '\0'}; 163527cbf3dSMarko Kovacevic 164527cbf3dSMarko Kovacevic if (parser_read_uint8_hex(&val->val[i + 8], byte) < 0) 165527cbf3dSMarko Kovacevic goto error_exit; 166527cbf3dSMarko Kovacevic } 167527cbf3dSMarko Kovacevic 168527cbf3dSMarko Kovacevic } else if (strstr(key, KEY3_STR)) { 169527cbf3dSMarko Kovacevic for (i = 0; i < len; i++) { 170527cbf3dSMarko Kovacevic char byte[3] = {src[i * 2], src[i * 2 + 1], '\0'}; 171527cbf3dSMarko Kovacevic 172527cbf3dSMarko Kovacevic if (parser_read_uint8_hex(&val->val[i + 16], byte) < 0) 173527cbf3dSMarko Kovacevic goto error_exit; 174527cbf3dSMarko Kovacevic } 175527cbf3dSMarko Kovacevic } else 176527cbf3dSMarko Kovacevic return -EINVAL; 177527cbf3dSMarko Kovacevic 178527cbf3dSMarko Kovacevic val->len = 24; 179527cbf3dSMarko Kovacevic 180527cbf3dSMarko Kovacevic return 0; 181527cbf3dSMarko Kovacevic 182527cbf3dSMarko Kovacevic error_exit: 183527cbf3dSMarko Kovacevic rte_free(val->val); 184527cbf3dSMarko Kovacevic memset(val, 0, sizeof(*val)); 185527cbf3dSMarko Kovacevic return -EINVAL; 186527cbf3dSMarko Kovacevic } 187527cbf3dSMarko Kovacevic 188527cbf3dSMarko Kovacevic static int 189527cbf3dSMarko Kovacevic parse_test_tdes_writeback(struct fips_val *val) 190527cbf3dSMarko Kovacevic { 191527cbf3dSMarko Kovacevic 192527cbf3dSMarko Kovacevic if (info.op == FIPS_TEST_ENC_AUTH_GEN) 193527cbf3dSMarko Kovacevic fprintf(info.fp_wr, "%s", CT_STR); 194527cbf3dSMarko Kovacevic else 195527cbf3dSMarko Kovacevic fprintf(info.fp_wr, "%s", PT_STR); 196527cbf3dSMarko Kovacevic 197527cbf3dSMarko Kovacevic parse_write_hex_str(val); 198527cbf3dSMarko Kovacevic 199527cbf3dSMarko Kovacevic return 0; 200527cbf3dSMarko Kovacevic 201527cbf3dSMarko Kovacevic } 202527cbf3dSMarko Kovacevic 203527cbf3dSMarko Kovacevic static int 204527cbf3dSMarko Kovacevic writeback_tdes_hex_str(const char *key, char *dst, struct fips_val *val) 205527cbf3dSMarko Kovacevic { 20686ce81afSMarko Kovacevic struct fips_val tmp_val = {0}; 207527cbf3dSMarko Kovacevic 208527cbf3dSMarko Kovacevic tmp_val.len = 8; 209527cbf3dSMarko Kovacevic 210527cbf3dSMarko Kovacevic if (strstr(key, KEY1_STR)) 211527cbf3dSMarko Kovacevic tmp_val.val = val->val; 212527cbf3dSMarko Kovacevic else if (strstr(key, KEY2_STR)) 213527cbf3dSMarko Kovacevic tmp_val.val = val->val + 8; 214527cbf3dSMarko Kovacevic else if (strstr(key, KEY3_STR)) 215527cbf3dSMarko Kovacevic tmp_val.val = val->val + 16; 21675b3dddfSChaitanya Babu Talluri else 21775b3dddfSChaitanya Babu Talluri return -EINVAL; 218527cbf3dSMarko Kovacevic 219527cbf3dSMarko Kovacevic return writeback_hex_str(key, dst, &tmp_val); 220527cbf3dSMarko Kovacevic } 221527cbf3dSMarko Kovacevic 222527cbf3dSMarko Kovacevic static int 223527cbf3dSMarko Kovacevic rsp_test_tdes_check(struct fips_val *val) 224527cbf3dSMarko Kovacevic { 225527cbf3dSMarko Kovacevic struct fips_val *data; 226527cbf3dSMarko Kovacevic 227527cbf3dSMarko Kovacevic if (info.op == FIPS_TEST_ENC_AUTH_GEN) 228527cbf3dSMarko Kovacevic data = &vec.ct; 229527cbf3dSMarko Kovacevic else 230527cbf3dSMarko Kovacevic data = &vec.pt; 231527cbf3dSMarko Kovacevic 232527cbf3dSMarko Kovacevic if (memcmp(val->val, data->val, val->len) == 0) 233527cbf3dSMarko Kovacevic fprintf(info.fp_wr, "Success\n"); 234527cbf3dSMarko Kovacevic else 235527cbf3dSMarko Kovacevic fprintf(info.fp_wr, "Failed\n"); 236527cbf3dSMarko Kovacevic 237527cbf3dSMarko Kovacevic return 0; 238527cbf3dSMarko Kovacevic } 239527cbf3dSMarko Kovacevic 240527cbf3dSMarko Kovacevic int 241527cbf3dSMarko Kovacevic parse_test_tdes_init(void) 242527cbf3dSMarko Kovacevic { 243527cbf3dSMarko Kovacevic uint32_t i; 244527cbf3dSMarko Kovacevic 245527cbf3dSMarko Kovacevic for (i = 0; i < info.nb_vec_lines; i++) { 246527cbf3dSMarko Kovacevic char *line = info.vec[i]; 247527cbf3dSMarko Kovacevic uint32_t j; 248527cbf3dSMarko Kovacevic 249527cbf3dSMarko Kovacevic if (strstr(line, TEST_CBCI_KEY)) 250527cbf3dSMarko Kovacevic return -EPERM; 251527cbf3dSMarko Kovacevic 252527cbf3dSMarko Kovacevic for (j = 0; j < RTE_DIM(test_types); j++) 253527cbf3dSMarko Kovacevic if (strstr(line, test_types[j].desc)) { 254527cbf3dSMarko Kovacevic info.interim_info.tdes_data.test_type = 255527cbf3dSMarko Kovacevic test_types[j].type; 256*efe3a8dbSMichael Shamis if (strstr(line, TEST_TYPE_ECB_KEY)) 257*efe3a8dbSMichael Shamis info.interim_info.tdes_data.test_mode = 258*efe3a8dbSMichael Shamis TDES_MODE_ECB; 259*efe3a8dbSMichael Shamis else 260*efe3a8dbSMichael Shamis info.interim_info.tdes_data.test_mode = 261*efe3a8dbSMichael Shamis TDES_MODE_CBC; 262527cbf3dSMarko Kovacevic break; 263527cbf3dSMarko Kovacevic } 264527cbf3dSMarko Kovacevic } 265527cbf3dSMarko Kovacevic 266527cbf3dSMarko Kovacevic info.parse_writeback = parse_test_tdes_writeback; 267527cbf3dSMarko Kovacevic info.callbacks = tdes_tests_vectors; 268527cbf3dSMarko Kovacevic info.interim_callbacks = tdes_tests_interim_vectors; 269527cbf3dSMarko Kovacevic info.writeback_callbacks = tdes_writeback_callbacks; 270527cbf3dSMarko Kovacevic info.kat_check = rsp_test_tdes_check; 271527cbf3dSMarko Kovacevic 272527cbf3dSMarko Kovacevic return 0; 273527cbf3dSMarko Kovacevic } 274