1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Intel Corporation
11 #endif /* RTE_HAS_JANSSON */
13 #include <rte_cryptodev.h>
14 #include <rte_malloc.h>
16 #include "fips_validation.h"
18 #define NEW_LINE_STR "#"
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 = "
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 = "
36 #define OP_ENC_STR "Encrypt"
37 #define OP_DEC_STR "Decrypt"
38 /* External/Internal IV generation, specified in file name, following NIST
41 #define OP_ENC_EXT_STR "ExtIV"
42 #define OP_ENC_INT_STR "IntIV"
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"
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"
58 #define OP_ENC_JSON_STR "encrypt"
59 #define OP_DEC_JSON_STR "decrypt"
61 #define IVGEN_JSON_STR "ivGen"
62 #define OP_ENC_EXT_JSON_STR "external"
63 #define OP_ENC_INT_JSON_STR "internal"
65 #define NEG_TEST_STR "FAIL"
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.
73 parser_read_gcm_pt_len(const char *key, char *src,
74 __rte_unused struct fips_val *val)
76 int ret = parser_read_uint32_bit_val(key, src, &vec.pt);
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;
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;
95 parse_gcm_aad_str(const char *key, char *src,
96 __rte_unused struct fips_val *val)
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);
103 return parse_uint8_known_len_hex_str(key, src, &vec.aead.aad);
107 parse_gcm_pt_ct_str(const char *key, char *src, struct fips_val *val)
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) {
114 vec.iv.val = rte_malloc(0, vec.iv.len, 0);
119 for (i = 0; i < vec.iv.len; i++) {
121 vec.iv.val[i] = (uint8_t)random;
125 /* if PTlen == 0, pt or ct will be handled by AAD later */
126 if (info.interim_info.gcm_data.is_gmac)
129 return parse_uint8_known_len_hex_str(key, src, val);
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,
139 {NULL, NULL, NULL} /**< end pointer */
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.
150 {AADLEN_STR, parser_read_uint32_bit_val, &vec.aead.aad},
151 {TAGLEN_STR, parser_read_uint32_bit_val,
153 {NULL, NULL, NULL} /**< end pointer */
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 */
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,
172 {NULL, NULL, NULL} /**< end pointer */
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.
183 {AADLEN_JSON_STR, parser_read_uint32_bit_val, &vec.aead.aad},
184 {TAGLEN_JSON_STR, parser_read_uint32_bit_val,
186 {NULL, NULL, NULL} /**< end pointer */
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 */
196 #endif /* RTE_HAS_JANSSON */
199 parse_test_gcm_writeback(struct fips_val *val)
201 struct fips_val tmp_val;
203 if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
204 /* According to NIST GCMVS section 6.1, IUT should provide
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;
212 parse_write_hex_str(&tmp_val);
213 rte_free(vec.iv.val);
217 fprintf(info.fp_wr, "%s", CT_STR);
219 if (!info.interim_info.gcm_data.is_gmac) {
220 tmp_val.val = val->val;
221 tmp_val.len = vec.pt.len;
223 parse_write_hex_str(&tmp_val);
225 fprintf(info.fp_wr, "\n");
227 fprintf(info.fp_wr, "%s", TAG_STR);
229 tmp_val.val = val->val + vec.pt.len;
230 tmp_val.len = val->len - vec.pt.len;
232 parse_write_hex_str(&tmp_val);
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;
240 parse_write_hex_str(&tmp_val);
242 fprintf(info.fp_wr, "\n");
244 fprintf(info.fp_wr, "%s\n", NEG_TEST_STR);
251 parse_test_gcm_init(void)
256 for (i = 0; i < info.nb_vec_lines; i++) {
257 char *line = info.vec[i];
259 tmp = strstr(line, OP_STR);
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;
274 info.interim_callbacks = gcm_interim_vectors;
275 info.parse_writeback = parse_test_gcm_writeback;
280 #ifdef RTE_HAS_JANSSON
282 parse_test_gcm_json_writeback(struct fips_val *val)
284 struct fips_val tmp_val;
287 tcId = json_object_get(json_info.json_test_case, "tcId");
289 json_info.json_write_case = json_object();
290 json_object_set(json_info.json_write_case, "tcId", tcId);
292 if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
295 tmp_val.val = val->val;
296 tmp_val.len = vec.pt.len;
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);
302 if (info.interim_info.gcm_data.gen_iv) {
304 tmp_val.val = vec.iv.val;
305 tmp_val.len = vec.iv.len;
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);
311 rte_free(vec.iv.val);
315 tmp_val.val = val->val + vec.pt.len;
316 tmp_val.len = val->len - vec.pt.len;
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);
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;
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));
332 json_object_set_new(json_info.json_write_case, "testPassed", json_false());
340 parse_test_gcm_json_init(void)
342 json_t *direction_obj;
343 const char *direction_str;
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;
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);
353 info.op = FIPS_TEST_ENC_AUTH_GEN;
354 info.callbacks = gcm_enc_json_vectors;
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;
364 info.interim_callbacks = gcm_interim_json_vectors;
365 info.parse_writeback = parse_test_gcm_json_writeback;
370 #endif /* RTE_HAS_JANSSON */