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 #ifdef RTE_HAS_JANSSON 10 #include <jansson.h> 11 #endif /* RTE_HAS_JANSSON */ 12 13 #include <rte_cryptodev.h> 14 #include <rte_malloc.h> 15 16 #include "fips_validation.h" 17 18 #define NEW_LINE_STR "#" 19 #define OP_STR "GCM " 20 21 #define PARAM_PREFIX "[" 22 #define KEYLEN_STR "Keylen = " 23 #define IVLEN_STR "IVlen = " 24 #define PTLEN_STR "PTlen = " 25 #define AADLEN_STR "AADlen = " 26 #define TAGLEN_STR "Taglen = " 27 28 #define COUNT_STR "Count = " 29 #define KEY_STR "Key = " 30 #define IV_STR "IV = " 31 #define PT_STR "PT = " 32 #define CT_STR "CT = " 33 #define TAG_STR "Tag = " 34 #define AAD_STR "AAD = " 35 36 #define OP_ENC_STR "Encrypt" 37 #define OP_DEC_STR "Decrypt" 38 /* External/Internal IV generation, specified in file name, following NIST 39 * GCMVS Section 6.1 40 */ 41 #define OP_ENC_EXT_STR "ExtIV" 42 #define OP_ENC_INT_STR "IntIV" 43 44 #define KEYLEN_JSON_STR "keyLen" 45 #define IVLEN_JSON_STR "ivLen" 46 #define PAYLOADLEN_JSON_STR "payloadLen" 47 #define AADLEN_JSON_STR "aadLen" 48 #define TAGLEN_JSON_STR "tagLen" 49 50 #define KEY_JSON_STR "key" 51 #define IV_JSON_STR "iv" 52 #define PT_JSON_STR "pt" 53 #define CT_JSON_STR "ct" 54 #define AAD_JSON_STR "aad" 55 #define TAG_JSON_STR "tag" 56 #define DIR_JSON_STR "direction" 57 58 #define OP_ENC_JSON_STR "encrypt" 59 #define OP_DEC_JSON_STR "decrypt" 60 61 #define IVGEN_JSON_STR "ivGen" 62 #define OP_ENC_EXT_JSON_STR "external" 63 #define OP_ENC_INT_JSON_STR "internal" 64 65 #define NEG_TEST_STR "FAIL" 66 67 /** 68 * GMAC is essentially zero length plaintext and uses AAD as input data. 69 * NIST does not have GMAC specific test vector but using zero length "PTlen" 70 * and uses AAD as input. 71 **/ 72 static int 73 parser_read_gcm_pt_len(const char *key, char *src, 74 __rte_unused struct fips_val *val) 75 { 76 int ret = parser_read_uint32_bit_val(key, src, &vec.pt); 77 78 if (ret < 0) 79 return ret; 80 81 if (vec.pt.len == 0) { 82 info.interim_info.gcm_data.is_gmac = 1; 83 test_ops.prepare_op = prepare_auth_op; 84 test_ops.prepare_xform = prepare_gmac_xform; 85 } else { 86 info.interim_info.gcm_data.is_gmac = 0; 87 test_ops.prepare_op = prepare_aead_op; 88 test_ops.prepare_xform = prepare_gcm_xform; 89 } 90 91 return ret; 92 } 93 94 static int 95 parse_gcm_aad_str(const char *key, char *src, 96 __rte_unused struct fips_val *val) 97 { 98 /* For GMAC test vector, AAD is treated as input */ 99 if (info.interim_info.gcm_data.is_gmac) { 100 vec.pt.len = vec.aead.aad.len; 101 return parse_uint8_known_len_hex_str(key, src, &vec.pt); 102 } else /* gcm */ 103 return parse_uint8_known_len_hex_str(key, src, &vec.aead.aad); 104 } 105 106 static int 107 parse_gcm_pt_ct_str(const char *key, char *src, struct fips_val *val) 108 { 109 /* According to NIST GCMVS section 6.1, IUT should generate IV data */ 110 if (info.interim_info.gcm_data.gen_iv && vec.iv.len) { 111 uint32_t i; 112 113 if (!vec.iv.val) { 114 vec.iv.val = rte_malloc(0, vec.iv.len, 0); 115 if (!vec.iv.val) 116 return -ENOMEM; 117 } 118 119 for (i = 0; i < vec.iv.len; i++) { 120 int random = rand(); 121 vec.iv.val[i] = (uint8_t)random; 122 } 123 } 124 125 /* if PTlen == 0, pt or ct will be handled by AAD later */ 126 if (info.interim_info.gcm_data.is_gmac) 127 return 0; 128 129 return parse_uint8_known_len_hex_str(key, src, val); 130 } 131 132 struct fips_test_callback gcm_dec_vectors[] = { 133 {KEY_STR, parse_uint8_known_len_hex_str, &vec.aead.key}, 134 {IV_STR, parse_uint8_known_len_hex_str, &vec.iv}, 135 {CT_STR, parse_gcm_pt_ct_str, &vec.ct}, 136 {AAD_STR, parse_gcm_aad_str, &vec.aead.aad}, 137 {TAG_STR, parse_uint8_known_len_hex_str, 138 &vec.aead.digest}, 139 {NULL, NULL, NULL} /**< end pointer */ 140 }; 141 142 struct fips_test_callback gcm_interim_vectors[] = { 143 {KEYLEN_STR, parser_read_uint32_bit_val, &vec.aead.key}, 144 {IVLEN_STR, parser_read_uint32_bit_val, &vec.iv}, 145 {PTLEN_STR, parser_read_gcm_pt_len, &vec.pt}, 146 {PTLEN_STR, parser_read_uint32_bit_val, &vec.ct}, 147 /**< The NIST test vectors use 'PTlen' to denote input text 148 * length in case of decrypt & encrypt operations. 149 */ 150 {AADLEN_STR, parser_read_uint32_bit_val, &vec.aead.aad}, 151 {TAGLEN_STR, parser_read_uint32_bit_val, 152 &vec.aead.digest}, 153 {NULL, NULL, NULL} /**< end pointer */ 154 }; 155 156 struct fips_test_callback gcm_enc_vectors[] = { 157 {KEY_STR, parse_uint8_known_len_hex_str, &vec.aead.key}, 158 {IV_STR, parse_uint8_known_len_hex_str, &vec.iv}, 159 {PT_STR, parse_gcm_pt_ct_str, &vec.pt}, 160 {AAD_STR, parse_gcm_aad_str, &vec.aead.aad}, 161 {NULL, NULL, NULL} /**< end pointer */ 162 }; 163 164 #ifdef RTE_HAS_JANSSON 165 struct fips_test_callback gcm_dec_json_vectors[] = { 166 {KEY_JSON_STR, parse_uint8_known_len_hex_str, &vec.aead.key}, 167 {IV_JSON_STR, parse_uint8_known_len_hex_str, &vec.iv}, 168 {CT_JSON_STR, parse_gcm_pt_ct_str, &vec.ct}, 169 {AAD_JSON_STR, parse_gcm_aad_str, &vec.aead.aad}, 170 {TAG_JSON_STR, parse_uint8_known_len_hex_str, 171 &vec.aead.digest}, 172 {NULL, NULL, NULL} /**< end pointer */ 173 }; 174 175 struct fips_test_callback gcm_interim_json_vectors[] = { 176 {KEYLEN_JSON_STR, parser_read_uint32_bit_val, &vec.aead.key}, 177 {IVLEN_JSON_STR, parser_read_uint32_bit_val, &vec.iv}, 178 {PAYLOADLEN_JSON_STR, parser_read_gcm_pt_len, &vec.pt}, 179 {PAYLOADLEN_JSON_STR, parser_read_uint32_bit_val, &vec.ct}, 180 /**< The NIST json test vectors use 'payloadLen' to denote input text 181 * length in case of decrypt & encrypt operations. 182 */ 183 {AADLEN_JSON_STR, parser_read_uint32_bit_val, &vec.aead.aad}, 184 {TAGLEN_JSON_STR, parser_read_uint32_bit_val, 185 &vec.aead.digest}, 186 {NULL, NULL, NULL} /**< end pointer */ 187 }; 188 189 struct fips_test_callback gcm_enc_json_vectors[] = { 190 {KEY_JSON_STR, parse_uint8_known_len_hex_str, &vec.aead.key}, 191 {IV_JSON_STR, parse_uint8_known_len_hex_str, &vec.iv}, 192 {PT_JSON_STR, parse_gcm_pt_ct_str, &vec.pt}, 193 {AAD_JSON_STR, parse_gcm_aad_str, &vec.aead.aad}, 194 {NULL, NULL, NULL} /**< end pointer */ 195 }; 196 #endif /* RTE_HAS_JANSSON */ 197 198 static int 199 parse_test_gcm_writeback(struct fips_val *val) 200 { 201 struct fips_val tmp_val; 202 203 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 204 /* According to NIST GCMVS section 6.1, IUT should provide 205 * generate IV data 206 */ 207 if (info.interim_info.gcm_data.gen_iv) { 208 fprintf(info.fp_wr, "%s", IV_STR); 209 tmp_val.val = vec.iv.val; 210 tmp_val.len = vec.iv.len; 211 212 parse_write_hex_str(&tmp_val); 213 rte_free(vec.iv.val); 214 vec.iv.val = NULL; 215 } 216 217 fprintf(info.fp_wr, "%s", CT_STR); 218 219 if (!info.interim_info.gcm_data.is_gmac) { 220 tmp_val.val = val->val; 221 tmp_val.len = vec.pt.len; 222 223 parse_write_hex_str(&tmp_val); 224 } else 225 fprintf(info.fp_wr, "\n"); 226 227 fprintf(info.fp_wr, "%s", TAG_STR); 228 229 tmp_val.val = val->val + vec.pt.len; 230 tmp_val.len = val->len - vec.pt.len; 231 232 parse_write_hex_str(&tmp_val); 233 } else { 234 if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS) { 235 fprintf(info.fp_wr, "%s", PT_STR); 236 if (!info.interim_info.gcm_data.is_gmac) { 237 tmp_val.val = val->val; 238 tmp_val.len = vec.pt.len; 239 240 parse_write_hex_str(&tmp_val); 241 } else 242 fprintf(info.fp_wr, "\n"); 243 } else 244 fprintf(info.fp_wr, "%s\n", NEG_TEST_STR); 245 } 246 247 return 0; 248 } 249 250 int 251 parse_test_gcm_init(void) 252 { 253 char *tmp; 254 uint32_t i; 255 256 for (i = 0; i < info.nb_vec_lines; i++) { 257 char *line = info.vec[i]; 258 259 tmp = strstr(line, OP_STR); 260 if (tmp) { 261 if (strstr(line, OP_ENC_STR)) { 262 info.op = FIPS_TEST_ENC_AUTH_GEN; 263 info.callbacks = gcm_enc_vectors; 264 if (strstr(info.file_name, OP_ENC_INT_STR)) 265 info.interim_info.gcm_data.gen_iv = 1; 266 } else if (strstr(line, OP_DEC_STR)) { 267 info.op = FIPS_TEST_DEC_AUTH_VERIF; 268 info.callbacks = gcm_dec_vectors; 269 } else 270 return -EINVAL; 271 } 272 } 273 274 info.interim_callbacks = gcm_interim_vectors; 275 info.parse_writeback = parse_test_gcm_writeback; 276 277 return 0; 278 } 279 280 #ifdef RTE_HAS_JANSSON 281 static int 282 parse_test_gcm_json_writeback(struct fips_val *val) 283 { 284 struct fips_val tmp_val; 285 json_t *tcId, *tag; 286 287 tcId = json_object_get(json_info.json_test_case, "tcId"); 288 289 json_info.json_write_case = json_object(); 290 json_object_set(json_info.json_write_case, "tcId", tcId); 291 292 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 293 json_t *ct; 294 295 tmp_val.val = val->val; 296 tmp_val.len = vec.pt.len; 297 298 writeback_hex_str("", info.one_line_text, &tmp_val); 299 ct = json_string(info.one_line_text); 300 json_object_set_new(json_info.json_write_case, CT_JSON_STR, ct); 301 302 if (info.interim_info.gcm_data.gen_iv) { 303 json_t *iv; 304 tmp_val.val = vec.iv.val; 305 tmp_val.len = vec.iv.len; 306 307 writeback_hex_str("", info.one_line_text, &tmp_val); 308 iv = json_string(info.one_line_text); 309 json_object_set_new(json_info.json_write_case, IV_JSON_STR, iv); 310 311 rte_free(vec.iv.val); 312 vec.iv.val = NULL; 313 } 314 315 tmp_val.val = val->val + vec.pt.len; 316 tmp_val.len = val->len - vec.pt.len; 317 318 writeback_hex_str("", info.one_line_text, &tmp_val); 319 tag = json_string(info.one_line_text); 320 json_object_set_new(json_info.json_write_case, TAG_JSON_STR, tag); 321 } else { 322 if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS) { 323 if (!info.interim_info.gcm_data.is_gmac) { 324 tmp_val.val = val->val; 325 tmp_val.len = vec.pt.len; 326 327 writeback_hex_str("", info.one_line_text, &tmp_val); 328 json_object_set_new(json_info.json_write_case, PT_JSON_STR, 329 json_string(info.one_line_text)); 330 } 331 } else { 332 json_object_set_new(json_info.json_write_case, "testPassed", json_false()); 333 } 334 } 335 336 return 0; 337 } 338 339 int 340 parse_test_gcm_json_init(void) 341 { 342 json_t *direction_obj; 343 const char *direction_str; 344 345 direction_obj = json_object_get(json_info.json_test_group, DIR_JSON_STR); 346 direction_str = json_string_value(direction_obj); 347 info.interim_info.gcm_data.gen_iv = 0; 348 349 if (strcmp(direction_str, OP_ENC_JSON_STR) == 0) { 350 json_t *ivGen_obj = json_object_get(json_info.json_test_group, IVGEN_JSON_STR); 351 const char *ivGen_str = json_string_value(ivGen_obj); 352 353 info.op = FIPS_TEST_ENC_AUTH_GEN; 354 info.callbacks = gcm_enc_json_vectors; 355 356 if (strcmp(ivGen_str, OP_ENC_INT_JSON_STR) == 0) 357 info.interim_info.gcm_data.gen_iv = 1; 358 } else if (strcmp(direction_str, OP_DEC_JSON_STR) == 0) { 359 info.op = FIPS_TEST_DEC_AUTH_VERIF; 360 info.callbacks = gcm_dec_json_vectors; 361 } else { 362 return -EINVAL; 363 } 364 info.interim_callbacks = gcm_interim_json_vectors; 365 info.parse_writeback = parse_test_gcm_json_writeback; 366 367 return 0; 368 } 369 370 #endif /* RTE_HAS_JANSSON */ 371