1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2018 Intel Corporation 3 */ 4 5 #include <string.h> 6 #include <time.h> 7 #include <stdio.h> 8 9 #include <rte_cryptodev.h> 10 #include <rte_malloc.h> 11 12 #include "fips_validation.h" 13 14 #define MODE_STR "AESVS" 15 #define ALGO_STR "test data for " 16 #define OP_STR "State" 17 #define KEY_SIZE_STR "Key Length : " 18 19 20 #define COUNT_STR "COUNT = " 21 #define KEY_STR "KEY = " 22 #define IV_STR "IV = " 23 #define PT_STR "PLAINTEXT = " 24 #define CT_STR "CIPHERTEXT = " 25 26 #define OP_ENC_STR "ENCRYPT" 27 #define OP_DEC_STR "DECRYPT" 28 29 #define ALGO_JSON_STR "algorithm" 30 #define TESTTYPE_JSON_STR "testType" 31 #define DIR_JSON_STR "direction" 32 #define KEYLEN_JSON_STR "keyLen" 33 #define OVERFLOW_JSON_STR "overflow" 34 35 #define KEY_JSON_STR "key" 36 #define PAYLOADLEN_JSON_STR "payloadLen" 37 #define IV_JSON_STR "iv" 38 #define PT_JSON_STR "pt" 39 #define CT_JSON_STR "ct" 40 41 #define OP_ENC_JSON_STR "encrypt" 42 #define OP_DEC_JSON_STR "decrypt" 43 44 struct { 45 uint32_t type; 46 const char *desc; 47 } aes_test_types[] = { 48 {AESAVS_TYPE_GFXBOX, "GFSbox"}, 49 {AESAVS_TYPE_KEYSBOX, "KeySbox"}, 50 {AESAVS_TYPE_VARKEY, "VarKey"}, 51 {AESAVS_TYPE_VARTXT, "VarTxt"}, 52 {TDES_VARIABLE_TEXT, "VARIABLE PLAINTEXT/CIPHERTEXT"}, 53 {TDES_VARIABLE_TEXT, "KAT"}, 54 {AESAVS_TYPE_MMT, "MMT"}, 55 {AESAVS_TYPE_MCT, "MCT"}, 56 {AESAVS_TYPE_AFT, "AFT"}, 57 {AESAVS_TYPE_CTR, "CTR"}, 58 }; 59 60 struct aes_test_algo { 61 const char *name; 62 enum rte_crypto_cipher_algorithm algo; 63 } const algo_con[] = { 64 {"CBC", RTE_CRYPTO_CIPHER_AES_CBC}, 65 {"ECB", RTE_CRYPTO_CIPHER_AES_ECB}, 66 {"CTR", RTE_CRYPTO_CIPHER_AES_CTR}, 67 }; 68 69 static int 70 parse_interim_enc_dec(const char *key, 71 __rte_unused char *text, 72 __rte_unused struct fips_val *val) 73 { 74 if (strcmp(key, OP_ENC_STR) == 0) 75 info.op = FIPS_TEST_ENC_AUTH_GEN; 76 else if (strcmp(key, OP_DEC_STR) == 0) 77 info.op = FIPS_TEST_DEC_AUTH_VERIF; 78 else 79 return -1; 80 81 return 0; 82 } 83 84 struct fips_test_callback aes_tests_interim[] = { 85 {OP_ENC_STR, parse_interim_enc_dec, NULL}, 86 {OP_DEC_STR, parse_interim_enc_dec, NULL}, 87 {NULL, NULL, NULL} /**< end pointer */ 88 }; 89 90 struct fips_test_callback aes_tests_vectors[] = { 91 {KEY_STR, parse_uint8_hex_str, &vec.cipher_auth.key}, 92 {IV_STR, parse_uint8_hex_str, &vec.iv}, 93 {PT_STR, parse_uint8_hex_str, &vec.pt}, 94 {CT_STR, parse_uint8_hex_str, &vec.ct}, 95 {NULL, NULL, NULL} /**< end pointer */ 96 }; 97 98 struct fips_test_callback aes_tests_interim_vectors[] = { 99 {OP_ENC_STR, parse_interim_enc_dec, NULL}, 100 {OP_DEC_STR, parse_interim_enc_dec, NULL}, 101 {NULL, NULL, NULL} /**< end pointer */ 102 }; 103 104 struct fips_test_callback aes_writeback_callbacks[] = { 105 /** First element is used to pass COUNT string */ 106 {COUNT_STR, NULL, NULL}, 107 {IV_STR, writeback_hex_str, &vec.iv}, 108 {KEY_STR, writeback_hex_str, &vec.cipher_auth.key}, 109 {PT_STR, writeback_hex_str, &vec.pt}, 110 {CT_STR, writeback_hex_str, &vec.ct}, 111 {NULL, NULL, NULL} /**< end pointer */ 112 }; 113 114 #ifdef USE_JANSSON 115 struct fips_test_callback aes_dec_json_vectors[] = { 116 {KEY_JSON_STR, parse_uint8_known_len_hex_str, &vec.cipher_auth.key}, 117 {IV_JSON_STR, parse_uint8_hex_str, &vec.iv}, 118 {CT_JSON_STR, parse_uint8_hex_str, &vec.ct}, 119 {NULL, NULL, NULL} /**< end pointer */ 120 }; 121 122 struct fips_test_callback aes_interim_json_vectors[] = { 123 {KEYLEN_JSON_STR, parser_read_uint32_bit_val, &vec.cipher_auth.key}, 124 {NULL, NULL, NULL} /**< end pointer */ 125 }; 126 127 struct fips_test_callback aes_enc_json_vectors[] = { 128 {KEY_JSON_STR, parse_uint8_known_len_hex_str, &vec.cipher_auth.key}, 129 {IV_JSON_STR, parse_uint8_hex_str, &vec.iv}, 130 {PT_JSON_STR, parse_uint8_hex_str, &vec.pt}, 131 {NULL, NULL, NULL} /**< end pointer */ 132 }; 133 134 static int 135 parse_test_aes_json_writeback(struct fips_val *val) 136 { 137 struct fips_val tmp_val; 138 json_t *tcId; 139 140 tcId = json_object_get(json_info.json_test_case, "tcId"); 141 142 json_info.json_write_case = json_object(); 143 json_object_set(json_info.json_write_case, "tcId", tcId); 144 145 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 146 json_t *ct; 147 148 tmp_val.val = val->val; 149 tmp_val.len = vec.pt.len; 150 151 writeback_hex_str("", info.one_line_text, &tmp_val); 152 ct = json_string(info.one_line_text); 153 json_object_set_new(json_info.json_write_case, CT_JSON_STR, ct); 154 155 tmp_val.val = val->val + vec.pt.len; 156 tmp_val.len = val->len - vec.pt.len; 157 158 writeback_hex_str("", info.one_line_text, &tmp_val); 159 } else { 160 if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS) { 161 tmp_val.val = val->val; 162 tmp_val.len = vec.ct.len; 163 164 writeback_hex_str("", info.one_line_text, &tmp_val); 165 json_object_set_new(json_info.json_write_case, PT_JSON_STR, 166 json_string(info.one_line_text)); 167 } else { 168 json_object_set_new(json_info.json_write_case, "testPassed", json_false()); 169 } 170 } 171 172 return 0; 173 } 174 175 static int 176 parse_test_aes_mct_json_writeback(struct fips_val *val) 177 { 178 json_t *tcId, *resArr, *res, *ct, *pt, *key, *iv; 179 struct fips_val tmp_val; 180 181 tcId = json_object_get(json_info.json_test_case, "tcId"); 182 if (json_info.json_write_case) { 183 json_t *wcId; 184 185 wcId = json_object_get(json_info.json_write_case, "tcId"); 186 if (!json_equal(tcId, wcId)) { 187 json_info.json_write_case = json_object(); 188 json_object_set(json_info.json_write_case, "tcId", tcId); 189 json_object_set(json_info.json_write_case, "resultsArray", json_array()); 190 } 191 } else { 192 json_info.json_write_case = json_object(); 193 json_object_set(json_info.json_write_case, "tcId", tcId); 194 json_object_set(json_info.json_write_case, "resultsArray", json_array()); 195 } 196 197 resArr = json_object_get(json_info.json_write_case, "resultsArray"); 198 if (!json_is_array(resArr)) 199 return -EINVAL; 200 201 res = json_object(); 202 if (info .op == FIPS_TEST_ENC_AUTH_GEN) { 203 writeback_hex_str("", info.one_line_text, &vec.cipher_auth.key); 204 key = json_string(info.one_line_text); 205 json_object_set_new(res, KEY_JSON_STR, key); 206 207 writeback_hex_str("", info.one_line_text, &val[2]); 208 iv = json_string(info.one_line_text); 209 json_object_set_new(res, IV_JSON_STR, iv); 210 211 writeback_hex_str("", info.one_line_text, &val[1]); 212 pt = json_string(info.one_line_text); 213 json_object_set_new(res, PT_JSON_STR, pt); 214 215 tmp_val.val = val->val; 216 tmp_val.len = vec.pt.len; 217 218 writeback_hex_str("", info.one_line_text, &tmp_val); 219 ct = json_string(info.one_line_text); 220 json_object_set_new(res, CT_JSON_STR, ct); 221 222 tmp_val.val = val->val + vec.pt.len; 223 tmp_val.len = val->len - vec.pt.len; 224 225 writeback_hex_str("", info.one_line_text, &tmp_val); 226 } else { 227 if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS) { 228 writeback_hex_str("", info.one_line_text, &vec.cipher_auth.key); 229 key = json_string(info.one_line_text); 230 json_object_set_new(res, KEY_JSON_STR, key); 231 232 writeback_hex_str("", info.one_line_text, &val[2]); 233 iv = json_string(info.one_line_text); 234 json_object_set_new(res, IV_JSON_STR, iv); 235 236 tmp_val.val = val->val; 237 tmp_val.len = vec.ct.len; 238 239 writeback_hex_str("", info.one_line_text, &tmp_val); 240 pt = json_string(info.one_line_text); 241 json_object_set_new(res, PT_JSON_STR, pt); 242 243 writeback_hex_str("", info.one_line_text, &val[1]); 244 ct = json_string(info.one_line_text); 245 json_object_set_new(res, CT_JSON_STR, ct); 246 } else { 247 json_object_set_new(json_info.json_write_case, "testPassed", json_false()); 248 } 249 } 250 251 json_array_append_new(resArr, res); 252 return 0; 253 } 254 255 int 256 parse_test_aes_json_init(void) 257 { 258 json_t *type_obj = json_object_get(json_info.json_test_group, TESTTYPE_JSON_STR); 259 json_t *algo_obj = json_object_get(json_info.json_vector_set, ALGO_JSON_STR); 260 const char *type_str = json_string_value(type_obj); 261 const char *algo_str = json_string_value(algo_obj); 262 uint32_t i; 263 264 if (json_info.json_test_group) { 265 json_t *direction_obj; 266 const char *direction_str; 267 268 direction_obj = json_object_get(json_info.json_test_group, DIR_JSON_STR); 269 direction_str = json_string_value(direction_obj); 270 271 if (strcmp(direction_str, OP_ENC_JSON_STR) == 0) { 272 info.op = FIPS_TEST_ENC_AUTH_GEN; 273 info.callbacks = aes_enc_json_vectors; 274 275 } else if (strcmp(direction_str, OP_DEC_JSON_STR) == 0) { 276 info.op = FIPS_TEST_DEC_AUTH_VERIF; 277 info.callbacks = aes_dec_json_vectors; 278 } else { 279 return -EINVAL; 280 } 281 info.interim_callbacks = aes_interim_json_vectors; 282 } 283 284 for (i = 0; i < RTE_DIM(aes_test_types); i++) 285 if (strstr(type_str, aes_test_types[i].desc)) { 286 info.interim_info.aes_data.test_type = 287 aes_test_types[i].type; 288 break; 289 } 290 291 if (i >= RTE_DIM(aes_test_types)) 292 return -EINVAL; 293 294 switch (info.interim_info.aes_data.test_type) { 295 case AESAVS_TYPE_MCT: 296 info.parse_writeback = parse_test_aes_mct_json_writeback; 297 break; 298 case AESAVS_TYPE_CTR: 299 case AESAVS_TYPE_AFT: 300 info.parse_writeback = parse_test_aes_json_writeback; 301 break; 302 default: 303 info.parse_writeback = NULL; 304 } 305 306 if (!info.parse_writeback) 307 return -EINVAL; 308 309 for (i = 0; i < RTE_DIM(algo_con); i++) 310 if (strstr(algo_str, algo_con[i].name)) { 311 info.interim_info.aes_data.cipher_algo = 312 (uint32_t)algo_con[i].algo; 313 break; 314 } 315 316 if (i >= RTE_DIM(algo_con)) 317 return -EINVAL; 318 319 return 0; 320 } 321 #endif /* USE_JANSSON */ 322 323 static int 324 parse_test_aes_writeback(struct fips_val *val) 325 { 326 if (info.op == FIPS_TEST_ENC_AUTH_GEN) 327 fprintf(info.fp_wr, "%s", CT_STR); 328 else 329 fprintf(info.fp_wr, "%s", PT_STR); 330 331 parse_write_hex_str(val); 332 333 return 0; 334 } 335 336 static int 337 rsp_test_aes_check(struct fips_val *val) 338 { 339 struct fips_val *data; 340 341 if (info.op == FIPS_TEST_ENC_AUTH_GEN) 342 data = &vec.ct; 343 else 344 data = &vec.pt; 345 346 if (memcmp(val->val, data->val, val->len) == 0) 347 fprintf(info.fp_wr, "Success\n"); 348 else 349 fprintf(info.fp_wr, "Failed\n"); 350 351 return 0; 352 } 353 354 int 355 parse_test_aes_init(void) 356 { 357 char *tmp; 358 uint32_t i, j; 359 360 for (i = 0; i < info.nb_vec_lines; i++) { 361 char *line = info.vec[i]; 362 363 tmp = strstr(line, MODE_STR); 364 if (tmp) { 365 for (j = 0; j < RTE_DIM(aes_test_types); j++) 366 if (strstr(line, aes_test_types[j].desc)) { 367 info.interim_info.aes_data.test_type = 368 aes_test_types[j].type; 369 break; 370 } 371 372 if (j >= RTE_DIM(aes_test_types)) 373 return -EINVAL; 374 375 tmp = strstr(line, ALGO_STR); 376 if (!tmp) 377 return -EINVAL; 378 379 tmp += strlen(ALGO_STR); 380 for (j = 0; j < RTE_DIM(algo_con); j++) 381 if (strcmp(algo_con[j].name, tmp) == 0) { 382 info.interim_info.aes_data.cipher_algo = 383 (uint32_t)algo_con[j].algo; 384 break; 385 } 386 if (j >= RTE_DIM(algo_con)) 387 return -EINVAL; 388 389 continue; 390 } 391 392 tmp = strstr(line, OP_STR); 393 if (tmp) 394 continue; 395 396 tmp = strstr(line, KEY_SIZE_STR); 397 if (tmp) { 398 tmp += strlen(KEY_SIZE_STR); 399 if (parser_read_uint32 400 (&info.interim_info.aes_data.key_len, 401 tmp) < 0) 402 return -EINVAL; 403 404 info.interim_info.aes_data.key_len /= 8; 405 406 continue; 407 } 408 } 409 410 info.parse_writeback = parse_test_aes_writeback; 411 info.callbacks = aes_tests_vectors; 412 info.interim_callbacks = aes_tests_interim_vectors; 413 info.writeback_callbacks = aes_writeback_callbacks; 414 info.kat_check = rsp_test_aes_check; 415 416 return 0; 417 } 418