1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2019 Intel Corporation 3 */ 4 5 #include <string.h> 6 #include <time.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 10 #include <rte_malloc.h> 11 #include <rte_cryptodev.h> 12 13 #include "fips_validation.h" 14 15 #define ALGO_PREFIX "[L = " 16 #define MSGLEN_STR "Len = " 17 #define MSG_STR "Msg = " 18 #define MD_STR "MD = " 19 #define SEED_STR "Seed = " 20 #define MCT_STR "Monte" 21 22 #define ALGO_JSON_STR "algorithm" 23 #define TESTTYPE_JSON_STR "testType" 24 25 #define PT_JSON_STR "msg" 26 #define OUTLEN_JSON_STR "outLen" 27 #define MINOUTLEN_JSON_STR "minOutLen" 28 #define MAXOUTLEN_JSON_STR "maxOutLen" 29 30 struct plain_hash_size_conversion { 31 const char *str; 32 uint8_t md_blocks; 33 enum rte_crypto_auth_algorithm algo; 34 } phsc[] = { 35 {"20", 3, RTE_CRYPTO_AUTH_SHA1}, 36 {"28", 3, RTE_CRYPTO_AUTH_SHA224}, 37 {"32", 3, RTE_CRYPTO_AUTH_SHA256}, 38 {"48", 3, RTE_CRYPTO_AUTH_SHA384}, 39 {"64", 3, RTE_CRYPTO_AUTH_SHA512}, 40 {"28", 1, RTE_CRYPTO_AUTH_SHA3_224}, 41 {"32", 1, RTE_CRYPTO_AUTH_SHA3_256}, 42 {"48", 1, RTE_CRYPTO_AUTH_SHA3_384}, 43 {"64", 1, RTE_CRYPTO_AUTH_SHA3_512}, 44 {"16", 1, RTE_CRYPTO_AUTH_SHAKE_128}, 45 {"32", 1, RTE_CRYPTO_AUTH_SHAKE_256}, 46 }; 47 48 int 49 parse_test_sha_hash_size(enum rte_crypto_auth_algorithm algo) 50 { 51 int ret = -EINVAL; 52 uint8_t i; 53 54 for (i = 0; i < RTE_DIM(phsc); i++) { 55 if (phsc[i].algo == algo) { 56 ret = atoi(phsc[i].str); 57 break; 58 } 59 } 60 61 return ret; 62 } 63 64 static int 65 parse_interim_algo(__rte_unused const char *key, 66 char *text, 67 __rte_unused struct fips_val *val) 68 { 69 uint32_t i; 70 71 for (i = 0; i < RTE_DIM(phsc); i++) { 72 if (strstr(text, phsc[i].str)) { 73 info.interim_info.sha_data.algo = phsc[i].algo; 74 info.interim_info.sha_data.md_blocks = phsc[i].md_blocks; 75 parser_read_uint32_val(ALGO_PREFIX, 76 text, &vec.cipher_auth.digest); 77 break; 78 } 79 } 80 81 if (i == RTE_DIM(phsc)) 82 return -1; 83 84 return 0; 85 } 86 87 struct fips_test_callback sha_tests_vectors[] = { 88 {MSGLEN_STR, parser_read_uint32_bit_val, &vec.pt}, 89 {MSG_STR, parse_uint8_known_len_hex_str, &vec.pt}, 90 {SEED_STR, parse_uint8_hex_str, &vec.pt}, 91 {NULL, NULL, NULL} /**< end pointer */ 92 }; 93 94 struct fips_test_callback sha_tests_interim_vectors[] = { 95 {ALGO_PREFIX, parse_interim_algo, NULL}, 96 {NULL, NULL, NULL} /**< end pointer */ 97 }; 98 99 #ifdef USE_JANSSON 100 static int 101 parse_interim_str(const char *key, char *src, struct fips_val *val) 102 { 103 RTE_SET_USED(val); 104 105 if (strcmp(key, MINOUTLEN_JSON_STR) == 0) 106 info.interim_info.sha_data.min_outlen = atoi(src) / 8; 107 else if (strcmp(key, MAXOUTLEN_JSON_STR) == 0) 108 vec.cipher_auth.digest.len = atoi(src) / 8; 109 110 return 0; 111 } 112 113 static struct { 114 uint32_t type; 115 const char *desc; 116 } sha_test_types[] = { 117 {SHA_MCT, "MCT"}, 118 {SHA_AFT, "AFT"}, 119 {SHAKE_VOT, "VOT"}, 120 }; 121 122 static struct plain_hash_algorithms { 123 const char *str; 124 enum rte_crypto_auth_algorithm algo; 125 uint8_t md_blocks; 126 } json_algorithms[] = { 127 {"SHA-1", RTE_CRYPTO_AUTH_SHA1, 3}, 128 {"SHA2-224", RTE_CRYPTO_AUTH_SHA224, 3}, 129 {"SHA2-256", RTE_CRYPTO_AUTH_SHA256, 3}, 130 {"SHA2-384", RTE_CRYPTO_AUTH_SHA384, 3}, 131 {"SHA2-512", RTE_CRYPTO_AUTH_SHA512, 3}, 132 {"SHA3-224", RTE_CRYPTO_AUTH_SHA3_224, 1}, 133 {"SHA3-256", RTE_CRYPTO_AUTH_SHA3_256, 1}, 134 {"SHA3-384", RTE_CRYPTO_AUTH_SHA3_384, 1}, 135 {"SHA3-512", RTE_CRYPTO_AUTH_SHA3_512, 1}, 136 {"SHAKE-128", RTE_CRYPTO_AUTH_SHAKE_128, 1}, 137 {"SHAKE-256", RTE_CRYPTO_AUTH_SHAKE_256, 1}, 138 }; 139 140 struct fips_test_callback sha_tests_json_vectors[] = { 141 {PT_JSON_STR, parse_uint8_hex_str, &vec.pt}, 142 {OUTLEN_JSON_STR, parser_read_uint32_bit_val, &vec.cipher_auth.digest}, 143 {NULL, NULL, NULL} /**< end pointer */ 144 }; 145 146 struct fips_test_callback sha_tests_interim_json_vectors[] = { 147 {MINOUTLEN_JSON_STR, parse_interim_str, NULL}, 148 {MAXOUTLEN_JSON_STR, parse_interim_str, NULL}, 149 {NULL, NULL, NULL} /**< end pointer */ 150 }; 151 #endif /* USE_JANSSON */ 152 153 static int 154 parse_test_sha_writeback(struct fips_val *val) // ! 155 { 156 struct fips_val val_local; 157 158 fprintf(info.fp_wr, "%s", MD_STR); 159 160 val_local.val = val->val + vec.pt.len; 161 val_local.len = vec.cipher_auth.digest.len; 162 163 parse_write_hex_str(&val_local); 164 return 0; 165 } 166 167 static int 168 rsp_test_sha_check(struct fips_val *val) 169 { 170 if (memcmp(val->val + vec.pt.len, vec.cipher_auth.digest.val, 171 vec.cipher_auth.digest.len) == 0) 172 fprintf(info.fp_wr, "Success\n"); 173 else 174 fprintf(info.fp_wr, "Failed\n"); 175 176 return 0; 177 } 178 179 int 180 parse_test_sha_init(void) 181 { 182 uint32_t i; 183 184 info.interim_info.sha_data.test_type = SHA_KAT; 185 for (i = 0; i < info.nb_vec_lines; i++) { 186 char *line = info.vec[i]; 187 if (strstr(line, MCT_STR)) 188 info.interim_info.sha_data.test_type = SHA_MCT; 189 } 190 191 info.op = FIPS_TEST_ENC_AUTH_GEN; 192 info.parse_writeback = parse_test_sha_writeback; 193 info.callbacks = sha_tests_vectors; 194 info.interim_callbacks = sha_tests_interim_vectors; 195 info.writeback_callbacks = NULL; 196 info.kat_check = rsp_test_sha_check; 197 return 0; 198 } 199 200 #ifdef USE_JANSSON 201 static int 202 parse_test_sha_json_writeback(struct fips_val *val) 203 { 204 struct fips_val val_local; 205 json_t *tcId, *md; 206 207 tcId = json_object_get(json_info.json_test_case, "tcId"); 208 209 json_info.json_write_case = json_object(); 210 json_object_set_new(json_info.json_write_case, "tcId", tcId); 211 212 val_local.val = val->val + vec.pt.len; 213 val_local.len = vec.cipher_auth.digest.len; 214 215 writeback_hex_str("", info.one_line_text, &val_local); 216 md = json_string(info.one_line_text); 217 json_object_set_new(json_info.json_write_case, "md", md); 218 219 if (info.interim_info.sha_data.algo == RTE_CRYPTO_AUTH_SHAKE_128 || 220 info.interim_info.sha_data.algo == RTE_CRYPTO_AUTH_SHAKE_256) 221 json_object_set_new(json_info.json_write_case, "outLen", 222 json_integer(vec.cipher_auth.digest.len * 8)); 223 224 return 0; 225 } 226 227 static int 228 parse_test_sha_mct_json_writeback(struct fips_val *val) 229 { 230 json_t *tcId, *md, *resArr, *res; 231 struct fips_val val_local; 232 bool is_shake = false; 233 234 if (info.interim_info.sha_data.algo == RTE_CRYPTO_AUTH_SHAKE_128 || 235 info.interim_info.sha_data.algo == RTE_CRYPTO_AUTH_SHAKE_256) 236 is_shake = true; 237 238 tcId = json_object_get(json_info.json_test_case, "tcId"); 239 if (json_info.json_write_case) { 240 json_t *wcId; 241 242 wcId = json_object_get(json_info.json_write_case, "tcId"); 243 if (!json_equal(tcId, wcId)) { 244 json_info.json_write_case = json_object(); 245 json_object_set_new(json_info.json_write_case, "tcId", tcId); 246 json_object_set_new(json_info.json_write_case, "resultsArray", 247 json_array()); 248 if (is_shake) 249 json_object_set_new(json_info.json_write_case, "outLen", 250 json_integer(0)); 251 } 252 } else { 253 json_info.json_write_case = json_object(); 254 json_object_set_new(json_info.json_write_case, "tcId", tcId); 255 json_object_set_new(json_info.json_write_case, "resultsArray", json_array()); 256 if (is_shake) 257 json_object_set_new(json_info.json_write_case, "outLen", 258 json_integer(0)); 259 } 260 261 resArr = json_object_get(json_info.json_write_case, "resultsArray"); 262 if (!json_is_array(resArr)) 263 return -EINVAL; 264 265 res = json_object(); 266 267 val_local.val = val->val + vec.pt.len; 268 val_local.len = vec.cipher_auth.digest.len; 269 270 writeback_hex_str("", info.one_line_text, &val_local); 271 md = json_string(info.one_line_text); 272 json_object_set_new(res, "md", md); 273 274 if (is_shake) 275 json_object_set_new(res, "outLen", json_integer(vec.cipher_auth.digest.len * 8)); 276 277 json_array_append_new(resArr, res); 278 return 0; 279 } 280 281 int 282 parse_test_sha_json_algorithm(void) 283 { 284 json_t *algorithm_object; 285 const char *algorithm_str; 286 uint32_t i; 287 int sz; 288 289 algorithm_object = json_object_get(json_info.json_vector_set, "algorithm"); 290 algorithm_str = json_string_value(algorithm_object); 291 292 for (i = 0; i < RTE_DIM(json_algorithms); i++) { 293 if (strstr(algorithm_str, json_algorithms[i].str)) { 294 info.interim_info.sha_data.algo = json_algorithms[i].algo; 295 info.interim_info.sha_data.md_blocks = json_algorithms[i].md_blocks; 296 break; 297 } 298 } 299 300 if (i == RTE_DIM(json_algorithms)) 301 return -1; 302 303 if (info.interim_info.sha_data.test_type == SHAKE_VOT) { 304 sz = vec.cipher_auth.digest.len; 305 } else { 306 sz = parse_test_sha_hash_size(info.interim_info.sha_data.algo); 307 vec.cipher_auth.digest.len = sz; 308 } 309 310 if (sz < 0) 311 return -1; 312 313 rte_free(vec.cipher_auth.digest.val); 314 vec.cipher_auth.digest.val = rte_malloc(NULL, sz, 0); 315 if (vec.cipher_auth.digest.val == NULL) 316 return -1; 317 318 return 0; 319 } 320 321 int 322 parse_test_sha_json_test_type(void) 323 { 324 json_t *type_object; 325 const char *type_str; 326 uint32_t i; 327 328 type_object = json_object_get(json_info.json_test_group, TESTTYPE_JSON_STR); 329 type_str = json_string_value(type_object); 330 331 for (i = 0; i < RTE_DIM(sha_test_types); i++) 332 if (strstr(type_str, sha_test_types[i].desc)) { 333 info.interim_info.sha_data.test_type = 334 sha_test_types[i].type; 335 break; 336 } 337 338 if (i == RTE_DIM(sha_test_types)) 339 return -1; 340 341 switch (info.interim_info.sha_data.test_type) { 342 case SHA_MCT: 343 info.parse_writeback = parse_test_sha_mct_json_writeback; 344 break; 345 case SHA_AFT: 346 case SHAKE_VOT: 347 info.parse_writeback = parse_test_sha_json_writeback; 348 break; 349 default: 350 info.parse_writeback = NULL; 351 } 352 353 if (!info.parse_writeback) 354 return -1; 355 356 return 0; 357 } 358 359 int 360 parse_test_sha_json_init(void) 361 { 362 info.op = FIPS_TEST_ENC_AUTH_GEN; 363 info.parse_writeback = parse_test_sha_json_writeback; 364 info.callbacks = sha_tests_json_vectors; 365 info.writeback_callbacks = NULL; 366 info.kat_check = rsp_test_sha_check; 367 info.interim_callbacks = sha_tests_interim_json_vectors; 368 369 if (parse_test_sha_json_test_type() < 0) 370 return -1; 371 372 if (parse_test_sha_json_algorithm() < 0) 373 return -1; 374 375 return 0; 376 } 377 #endif /* USE_JANSSON */ 378