14aaad299SMarko Kovacevic /* SPDX-License-Identifier: BSD-3-Clause
24aaad299SMarko Kovacevic  * Copyright(c) 2018 Intel Corporation
34aaad299SMarko Kovacevic  */
44aaad299SMarko Kovacevic 
54aaad299SMarko Kovacevic #include <string.h>
64aaad299SMarko Kovacevic #include <time.h>
74aaad299SMarko Kovacevic #include <stdio.h>
84aaad299SMarko Kovacevic 
94aaad299SMarko Kovacevic #include <rte_cryptodev.h>
10*d09abf2dSFan Zhang #include <rte_malloc.h>
114aaad299SMarko Kovacevic 
124aaad299SMarko Kovacevic #include "fips_validation.h"
134aaad299SMarko Kovacevic 
144aaad299SMarko Kovacevic #define NEW_LINE_STR	"#"
154aaad299SMarko Kovacevic #define OP_STR		"GCM "
164aaad299SMarko Kovacevic 
174aaad299SMarko Kovacevic #define PARAM_PREFIX	"["
184aaad299SMarko Kovacevic #define KEYLEN_STR	"Keylen = "
194aaad299SMarko Kovacevic #define IVLEN_STR	"IVlen = "
204aaad299SMarko Kovacevic #define PTLEN_STR	"PTlen = "
214aaad299SMarko Kovacevic #define AADLEN_STR	"AADlen = "
224aaad299SMarko Kovacevic #define TAGLEN_STR	"Taglen = "
234aaad299SMarko Kovacevic 
244aaad299SMarko Kovacevic #define COUNT_STR	"Count = "
254aaad299SMarko Kovacevic #define KEY_STR		"Key = "
264aaad299SMarko Kovacevic #define IV_STR		"IV = "
274aaad299SMarko Kovacevic #define PT_STR		"PT = "
284aaad299SMarko Kovacevic #define CT_STR		"CT = "
294aaad299SMarko Kovacevic #define TAG_STR		"Tag = "
304aaad299SMarko Kovacevic #define AAD_STR		"AAD = "
314aaad299SMarko Kovacevic 
324aaad299SMarko Kovacevic #define OP_ENC_STR	"Encrypt"
334aaad299SMarko Kovacevic #define OP_DEC_STR	"Decrypt"
34*d09abf2dSFan Zhang /* External/Internal IV generation, specified in file name, following NIST
35*d09abf2dSFan Zhang  * GCMVS Section 6.1
36*d09abf2dSFan Zhang  */
37*d09abf2dSFan Zhang #define OP_ENC_EXT_STR	"ExtIV"
38*d09abf2dSFan Zhang #define OP_ENC_INT_STR	"IntIV"
394aaad299SMarko Kovacevic 
404aaad299SMarko Kovacevic #define NEG_TEST_STR	"FAIL"
414aaad299SMarko Kovacevic 
42*d09abf2dSFan Zhang /**
43*d09abf2dSFan Zhang  * GMAC is essentially zero length plaintext and uses AAD as input data.
44*d09abf2dSFan Zhang  * NIST does not have GMAC specific test vector but using zero length "PTlen"
45*d09abf2dSFan Zhang  * and uses AAD as input.
46*d09abf2dSFan Zhang  **/
47*d09abf2dSFan Zhang static int
parser_read_gcm_pt_len(const char * key,char * src,__rte_unused struct fips_val * val)48*d09abf2dSFan Zhang parser_read_gcm_pt_len(const char *key, char *src,
49*d09abf2dSFan Zhang 		__rte_unused struct fips_val *val)
50*d09abf2dSFan Zhang {
51*d09abf2dSFan Zhang 	int ret = parser_read_uint32_bit_val(key, src, &vec.pt);
52*d09abf2dSFan Zhang 
53*d09abf2dSFan Zhang 	if (ret < 0)
54*d09abf2dSFan Zhang 		return ret;
55*d09abf2dSFan Zhang 
56*d09abf2dSFan Zhang 	if (vec.pt.len == 0) {
57*d09abf2dSFan Zhang 		info.interim_info.gcm_data.is_gmac = 1;
58*d09abf2dSFan Zhang 		test_ops.prepare_op = prepare_auth_op;
59*d09abf2dSFan Zhang 		test_ops.prepare_xform = prepare_gmac_xform;
60*d09abf2dSFan Zhang 	} else {
61*d09abf2dSFan Zhang 		info.interim_info.gcm_data.is_gmac = 0;
62*d09abf2dSFan Zhang 		test_ops.prepare_op = prepare_aead_op;
63*d09abf2dSFan Zhang 		test_ops.prepare_xform = prepare_gcm_xform;
64*d09abf2dSFan Zhang 	}
65*d09abf2dSFan Zhang 
66*d09abf2dSFan Zhang 	return ret;
67*d09abf2dSFan Zhang }
68*d09abf2dSFan Zhang 
69*d09abf2dSFan Zhang static int
parse_gcm_aad_str(const char * key,char * src,__rte_unused struct fips_val * val)70*d09abf2dSFan Zhang parse_gcm_aad_str(const char *key, char *src,
71*d09abf2dSFan Zhang 		__rte_unused struct fips_val *val)
72*d09abf2dSFan Zhang {
73*d09abf2dSFan Zhang 	/* For GMAC test vector, AAD is treated as input */
74*d09abf2dSFan Zhang 	if (info.interim_info.gcm_data.is_gmac) {
75*d09abf2dSFan Zhang 		vec.pt.len = vec.aead.aad.len;
76*d09abf2dSFan Zhang 		return parse_uint8_known_len_hex_str(key, src, &vec.pt);
77*d09abf2dSFan Zhang 	} else /* gcm */
78*d09abf2dSFan Zhang 		return parse_uint8_known_len_hex_str(key, src, &vec.aead.aad);
79*d09abf2dSFan Zhang }
80*d09abf2dSFan Zhang 
81*d09abf2dSFan Zhang static int
parse_gcm_pt_ct_str(const char * key,char * src,struct fips_val * val)82*d09abf2dSFan Zhang parse_gcm_pt_ct_str(const char *key, char *src, struct fips_val *val)
83*d09abf2dSFan Zhang {
84*d09abf2dSFan Zhang 	/* According to NIST GCMVS section 6.1, IUT should generate IV data */
85*d09abf2dSFan Zhang 	if (info.interim_info.gcm_data.gen_iv && vec.iv.len) {
86*d09abf2dSFan Zhang 		uint32_t i;
87*d09abf2dSFan Zhang 
88*d09abf2dSFan Zhang 		if (!vec.iv.val) {
89*d09abf2dSFan Zhang 			vec.iv.val = rte_malloc(0, vec.iv.len, 0);
90*d09abf2dSFan Zhang 			if (!vec.iv.val)
91*d09abf2dSFan Zhang 				return -ENOMEM;
92*d09abf2dSFan Zhang 		}
93*d09abf2dSFan Zhang 
94*d09abf2dSFan Zhang 		for (i = 0; i < vec.iv.len; i++) {
95*d09abf2dSFan Zhang 			int random = rand();
96*d09abf2dSFan Zhang 			vec.iv.val[i] = (uint8_t)random;
97*d09abf2dSFan Zhang 		}
98*d09abf2dSFan Zhang 	}
99*d09abf2dSFan Zhang 
100*d09abf2dSFan Zhang 	/* if PTlen == 0, pt or ct will be handled by AAD later */
101*d09abf2dSFan Zhang 	if (info.interim_info.gcm_data.is_gmac)
102*d09abf2dSFan Zhang 		return 0;
103*d09abf2dSFan Zhang 
104*d09abf2dSFan Zhang 	return parse_uint8_known_len_hex_str(key, src, val);
105*d09abf2dSFan Zhang }
106*d09abf2dSFan Zhang 
1074aaad299SMarko Kovacevic struct fips_test_callback gcm_dec_vectors[] = {
10851b9292eSSucharitha Sarananaga 		{KEY_STR, parse_uint8_known_len_hex_str, &vec.aead.key},
1094aaad299SMarko Kovacevic 		{IV_STR, parse_uint8_known_len_hex_str, &vec.iv},
110*d09abf2dSFan Zhang 		{CT_STR, parse_gcm_pt_ct_str, &vec.ct},
111*d09abf2dSFan Zhang 		{AAD_STR, parse_gcm_aad_str, &vec.aead.aad},
1124aaad299SMarko Kovacevic 		{TAG_STR, parse_uint8_known_len_hex_str,
11351b9292eSSucharitha Sarananaga 				&vec.aead.digest},
1144aaad299SMarko Kovacevic 		{NULL, NULL, NULL} /**< end pointer */
1154aaad299SMarko Kovacevic };
116*d09abf2dSFan Zhang 
1174aaad299SMarko Kovacevic struct fips_test_callback gcm_interim_vectors[] = {
11851b9292eSSucharitha Sarananaga 		{KEYLEN_STR, parser_read_uint32_bit_val, &vec.aead.key},
1194aaad299SMarko Kovacevic 		{IVLEN_STR, parser_read_uint32_bit_val, &vec.iv},
120*d09abf2dSFan Zhang 		{PTLEN_STR, parser_read_gcm_pt_len, &vec.pt},
121b1ea86a0SAnoob Joseph 		{PTLEN_STR, parser_read_uint32_bit_val, &vec.ct},
122b1ea86a0SAnoob Joseph 		/**< The NIST test vectors use 'PTlen' to denote input text
123b1ea86a0SAnoob Joseph 		 *  length in case of decrypt & encrypt operations.
124b1ea86a0SAnoob Joseph 		 */
12551b9292eSSucharitha Sarananaga 		{AADLEN_STR, parser_read_uint32_bit_val, &vec.aead.aad},
1264aaad299SMarko Kovacevic 		{TAGLEN_STR, parser_read_uint32_bit_val,
12751b9292eSSucharitha Sarananaga 				&vec.aead.digest},
1284aaad299SMarko Kovacevic 		{NULL, NULL, NULL} /**< end pointer */
1294aaad299SMarko Kovacevic };
1304aaad299SMarko Kovacevic 
1314aaad299SMarko Kovacevic struct fips_test_callback gcm_enc_vectors[] = {
13251b9292eSSucharitha Sarananaga 		{KEY_STR, parse_uint8_known_len_hex_str, &vec.aead.key},
1334aaad299SMarko Kovacevic 		{IV_STR, parse_uint8_known_len_hex_str, &vec.iv},
134*d09abf2dSFan Zhang 		{PT_STR, parse_gcm_pt_ct_str, &vec.pt},
135*d09abf2dSFan Zhang 		{AAD_STR, parse_gcm_aad_str, &vec.aead.aad},
1364aaad299SMarko Kovacevic 		{NULL, NULL, NULL} /**< end pointer */
1374aaad299SMarko Kovacevic };
1384aaad299SMarko Kovacevic 
1394aaad299SMarko Kovacevic static int
parse_test_gcm_writeback(struct fips_val * val)1404aaad299SMarko Kovacevic parse_test_gcm_writeback(struct fips_val *val)
1414aaad299SMarko Kovacevic {
1424aaad299SMarko Kovacevic 	struct fips_val tmp_val;
1434aaad299SMarko Kovacevic 
1444aaad299SMarko Kovacevic 	if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
145*d09abf2dSFan Zhang 		/* According to NIST GCMVS section 6.1, IUT should provide
146*d09abf2dSFan Zhang 		 * generate IV data
147*d09abf2dSFan Zhang 		 */
148*d09abf2dSFan Zhang 		if (info.interim_info.gcm_data.gen_iv) {
149*d09abf2dSFan Zhang 			fprintf(info.fp_wr, "%s", IV_STR);
150*d09abf2dSFan Zhang 			tmp_val.val = vec.iv.val;
151*d09abf2dSFan Zhang 			tmp_val.len = vec.iv.len;
152*d09abf2dSFan Zhang 
153*d09abf2dSFan Zhang 			parse_write_hex_str(&tmp_val);
154*d09abf2dSFan Zhang 			rte_free(vec.iv.val);
155*d09abf2dSFan Zhang 			vec.iv.val = NULL;
156*d09abf2dSFan Zhang 		}
157*d09abf2dSFan Zhang 
1584aaad299SMarko Kovacevic 		fprintf(info.fp_wr, "%s", CT_STR);
1594aaad299SMarko Kovacevic 
160*d09abf2dSFan Zhang 		if (!info.interim_info.gcm_data.is_gmac) {
1614aaad299SMarko Kovacevic 			tmp_val.val = val->val;
1624aaad299SMarko Kovacevic 			tmp_val.len = vec.pt.len;
1634aaad299SMarko Kovacevic 
1644aaad299SMarko Kovacevic 			parse_write_hex_str(&tmp_val);
165*d09abf2dSFan Zhang 		} else
166*d09abf2dSFan Zhang 			fprintf(info.fp_wr, "\n");
1674aaad299SMarko Kovacevic 
1684aaad299SMarko Kovacevic 		fprintf(info.fp_wr, "%s", TAG_STR);
1694aaad299SMarko Kovacevic 
1704aaad299SMarko Kovacevic 		tmp_val.val = val->val + vec.pt.len;
1714aaad299SMarko Kovacevic 		tmp_val.len = val->len - vec.pt.len;
1724aaad299SMarko Kovacevic 
1734aaad299SMarko Kovacevic 		parse_write_hex_str(&tmp_val);
1744aaad299SMarko Kovacevic 	} else {
1754aaad299SMarko Kovacevic 		if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS) {
1764aaad299SMarko Kovacevic 			fprintf(info.fp_wr, "%s", PT_STR);
177*d09abf2dSFan Zhang 			if (!info.interim_info.gcm_data.is_gmac) {
1784aaad299SMarko Kovacevic 				tmp_val.val = val->val;
1794aaad299SMarko Kovacevic 				tmp_val.len = vec.pt.len;
1804aaad299SMarko Kovacevic 
1814aaad299SMarko Kovacevic 				parse_write_hex_str(&tmp_val);
1824aaad299SMarko Kovacevic 			} else
183*d09abf2dSFan Zhang 				fprintf(info.fp_wr, "\n");
184*d09abf2dSFan Zhang 		} else
1854aaad299SMarko Kovacevic 			fprintf(info.fp_wr, "%s\n", NEG_TEST_STR);
1864aaad299SMarko Kovacevic 	}
1874aaad299SMarko Kovacevic 
1884aaad299SMarko Kovacevic 	return 0;
1894aaad299SMarko Kovacevic }
1904aaad299SMarko Kovacevic 
1914aaad299SMarko Kovacevic int
parse_test_gcm_init(void)1924aaad299SMarko Kovacevic parse_test_gcm_init(void)
1934aaad299SMarko Kovacevic {
1944aaad299SMarko Kovacevic 	char *tmp;
1954aaad299SMarko Kovacevic 	uint32_t i;
1964aaad299SMarko Kovacevic 
1974aaad299SMarko Kovacevic 
1984aaad299SMarko Kovacevic 	for (i = 0; i < info.nb_vec_lines; i++) {
1994aaad299SMarko Kovacevic 		char *line = info.vec[i];
2004aaad299SMarko Kovacevic 
2014aaad299SMarko Kovacevic 		tmp = strstr(line, OP_STR);
2024aaad299SMarko Kovacevic 		if (tmp) {
2034aaad299SMarko Kovacevic 			if (strstr(line, OP_ENC_STR)) {
2044aaad299SMarko Kovacevic 				info.op = FIPS_TEST_ENC_AUTH_GEN;
2054aaad299SMarko Kovacevic 				info.callbacks = gcm_enc_vectors;
206*d09abf2dSFan Zhang 				if (strstr(info.file_name, OP_ENC_INT_STR))
207*d09abf2dSFan Zhang 					info.interim_info.gcm_data.gen_iv = 1;
2084aaad299SMarko Kovacevic 			} else if (strstr(line, OP_DEC_STR)) {
2094aaad299SMarko Kovacevic 				info.op = FIPS_TEST_DEC_AUTH_VERIF;
2104aaad299SMarko Kovacevic 				info.callbacks = gcm_dec_vectors;
2114aaad299SMarko Kovacevic 			} else
2124aaad299SMarko Kovacevic 				return -EINVAL;
2134aaad299SMarko Kovacevic 		}
2144aaad299SMarko Kovacevic 	}
2154aaad299SMarko Kovacevic 
2164aaad299SMarko Kovacevic 	info.interim_callbacks = gcm_interim_vectors;
2174aaad299SMarko Kovacevic 	info.parse_writeback = parse_test_gcm_writeback;
2184aaad299SMarko Kovacevic 
2194aaad299SMarko Kovacevic 	return 0;
2204aaad299SMarko Kovacevic }
221