1527cbf3dSMarko Kovacevic /* SPDX-License-Identifier: BSD-3-Clause
2527cbf3dSMarko Kovacevic  * Copyright(c) 2018 Intel Corporation
3527cbf3dSMarko Kovacevic  */
4527cbf3dSMarko Kovacevic 
5527cbf3dSMarko Kovacevic #include <string.h>
6527cbf3dSMarko Kovacevic #include <stdio.h>
7527cbf3dSMarko Kovacevic 
8527cbf3dSMarko Kovacevic #include <rte_malloc.h>
9527cbf3dSMarko Kovacevic #include <rte_cryptodev.h>
10527cbf3dSMarko Kovacevic 
11527cbf3dSMarko Kovacevic #include "fips_validation.h"
12527cbf3dSMarko Kovacevic 
13527cbf3dSMarko Kovacevic #define NEW_LINE_STR	"#"
14527cbf3dSMarko Kovacevic #define TEST_TYPE_KEY	" for CBC"
15527cbf3dSMarko Kovacevic #define TEST_CBCI_KEY	" for CBCI"
16527cbf3dSMarko Kovacevic 
17527cbf3dSMarko Kovacevic #define ENC_STR		"[ENCRYPT]"
18527cbf3dSMarko Kovacevic #define DEC_STR		"[DECRYPT]"
19527cbf3dSMarko Kovacevic 
20527cbf3dSMarko Kovacevic #define COUNT_STR	"COUNT = "
21527cbf3dSMarko Kovacevic #define KEY1_STR	"KEY1 = "
22527cbf3dSMarko Kovacevic #define KEY2_STR	"KEY2 = "
23527cbf3dSMarko Kovacevic #define KEY3_STR	"KEY3 = "
24527cbf3dSMarko Kovacevic 
25527cbf3dSMarko Kovacevic #define KEYS_STR	"KEYs = "
26527cbf3dSMarko Kovacevic #define IV_STR		"IV = "
27527cbf3dSMarko Kovacevic #define PT_STR		"PLAINTEXT = "
28527cbf3dSMarko Kovacevic #define CT_STR		"CIPHERTEXT = "
29527cbf3dSMarko Kovacevic #define NK_STR		"NumKeys = "
30527cbf3dSMarko Kovacevic 
31527cbf3dSMarko Kovacevic #define SET_STR		" = "
32527cbf3dSMarko Kovacevic 
33527cbf3dSMarko Kovacevic #define PLAIN_TEXT	0
34527cbf3dSMarko Kovacevic #define CIPHER_TEXT	1
35527cbf3dSMarko Kovacevic #define KEY_TEXT	2
36527cbf3dSMarko Kovacevic #define IV_TEXT		3
37527cbf3dSMarko Kovacevic 
38527cbf3dSMarko Kovacevic #define DEVICE_STR	"# Config Info for : "
39527cbf3dSMarko Kovacevic 
40527cbf3dSMarko Kovacevic struct {
41527cbf3dSMarko Kovacevic 	uint32_t type;
42527cbf3dSMarko Kovacevic 	const char *desc;
43527cbf3dSMarko Kovacevic } test_types[] = {
44527cbf3dSMarko Kovacevic 		{TDES_INVERSE_PERMUTATION, "INVERSE PERMUTATION"},
45527cbf3dSMarko Kovacevic 		{TDES_PERMUTATION, "PERMUTATION OPERATION"},
46527cbf3dSMarko Kovacevic 		{TDES_SUBSTITUTION_TABLE, "SUBSTITUTION TABLE"},
47527cbf3dSMarko Kovacevic 		{TDES_VARIABLE_KEY, "VARIABLE KEY"},
48527cbf3dSMarko Kovacevic 		{TDES_VARIABLE_TEXT, "VARIABLE PLAINTEXT/CIPHERTEXT"},
49527cbf3dSMarko Kovacevic 		{TDES_VARIABLE_TEXT, "KAT"},
50527cbf3dSMarko Kovacevic 		{TDES_MCT, "Monte Carlo (Modes) Test"},
51527cbf3dSMarko Kovacevic 		{TDES_MMT, "Multi block Message Test"},
52527cbf3dSMarko Kovacevic };
53527cbf3dSMarko Kovacevic 
54527cbf3dSMarko Kovacevic static int
55527cbf3dSMarko Kovacevic writeback_tdes_hex_str(const char *key, char *dst, struct fips_val *val);
56527cbf3dSMarko Kovacevic 
57527cbf3dSMarko Kovacevic static int
58527cbf3dSMarko Kovacevic parse_tdes_uint8_hex_str(const char *key, char *src, struct fips_val *val);
59527cbf3dSMarko Kovacevic 
60527cbf3dSMarko Kovacevic static int
61527cbf3dSMarko Kovacevic parse_tdes_interim(const char *key,
62527cbf3dSMarko Kovacevic 		__attribute__((__unused__)) char *text,
63527cbf3dSMarko Kovacevic 		struct fips_val *val);
64527cbf3dSMarko Kovacevic 
65527cbf3dSMarko Kovacevic struct fips_test_callback tdes_tests_vectors[] = {
66527cbf3dSMarko Kovacevic 		{KEYS_STR, parse_tdes_uint8_hex_str, &vec.cipher_auth.key},
67527cbf3dSMarko Kovacevic 		{KEY1_STR, parse_tdes_uint8_hex_str, &vec.cipher_auth.key},
68527cbf3dSMarko Kovacevic 		{KEY2_STR, parse_tdes_uint8_hex_str, &vec.cipher_auth.key},
69527cbf3dSMarko Kovacevic 		{KEY3_STR, parse_tdes_uint8_hex_str, &vec.cipher_auth.key},
70527cbf3dSMarko Kovacevic 		{IV_STR, parse_uint8_hex_str, &vec.iv},
71527cbf3dSMarko Kovacevic 		{PT_STR, parse_uint8_hex_str, &vec.pt},
72527cbf3dSMarko Kovacevic 		{CT_STR, parse_uint8_hex_str, &vec.ct},
73527cbf3dSMarko Kovacevic 		{NULL, NULL, NULL} /**< end pointer */
74527cbf3dSMarko Kovacevic };
75527cbf3dSMarko Kovacevic 
76527cbf3dSMarko Kovacevic struct fips_test_callback tdes_tests_interim_vectors[] = {
77527cbf3dSMarko Kovacevic 		{ENC_STR, parse_tdes_interim, NULL},
78527cbf3dSMarko Kovacevic 		{DEC_STR, parse_tdes_interim, NULL},
79527cbf3dSMarko Kovacevic 		{NULL, NULL, NULL} /**< end pointer */
80527cbf3dSMarko Kovacevic };
81527cbf3dSMarko Kovacevic 
82527cbf3dSMarko Kovacevic struct fips_test_callback tdes_writeback_callbacks[] = {
83527cbf3dSMarko Kovacevic 		/** First element is used to pass COUNT string */
84527cbf3dSMarko Kovacevic 		{COUNT_STR, NULL, NULL},
85527cbf3dSMarko Kovacevic 		{IV_STR, writeback_hex_str, &vec.iv},
86527cbf3dSMarko Kovacevic 		{KEY1_STR, writeback_tdes_hex_str, &vec.cipher_auth.key},
87527cbf3dSMarko Kovacevic 		{KEY2_STR, writeback_tdes_hex_str, &vec.cipher_auth.key},
88527cbf3dSMarko Kovacevic 		{KEY3_STR, writeback_tdes_hex_str, &vec.cipher_auth.key},
89527cbf3dSMarko Kovacevic 		{KEYS_STR, writeback_tdes_hex_str, &vec.cipher_auth.key},
90527cbf3dSMarko Kovacevic 		{PT_STR, writeback_hex_str, &vec.pt},
91527cbf3dSMarko Kovacevic 		{CT_STR, writeback_hex_str, &vec.ct},
92527cbf3dSMarko Kovacevic 		{NULL, NULL, NULL} /**< end pointer */
93527cbf3dSMarko Kovacevic };
94527cbf3dSMarko Kovacevic 
95527cbf3dSMarko Kovacevic static int
96527cbf3dSMarko Kovacevic parse_tdes_interim(const char *key,
97527cbf3dSMarko Kovacevic 		__attribute__((__unused__)) char *text,
98527cbf3dSMarko Kovacevic 		__attribute__((__unused__)) struct fips_val *val)
99527cbf3dSMarko Kovacevic {
100527cbf3dSMarko Kovacevic 	if (strstr(key, ENC_STR))
101527cbf3dSMarko Kovacevic 		info.op = FIPS_TEST_ENC_AUTH_GEN;
102527cbf3dSMarko Kovacevic 	else if (strstr(key, DEC_STR))
103527cbf3dSMarko Kovacevic 		info.op = FIPS_TEST_DEC_AUTH_VERIF;
104527cbf3dSMarko Kovacevic 	else if (strstr(NK_STR, "NumKeys = 1"))
105527cbf3dSMarko Kovacevic 		info.interim_info.tdes_data.nb_keys = 1;
106527cbf3dSMarko Kovacevic 	else if (strstr(NK_STR, "NumKeys = 2"))
107527cbf3dSMarko Kovacevic 		info.interim_info.tdes_data.nb_keys = 2;
108527cbf3dSMarko Kovacevic 	else if (strstr(NK_STR, "NumKeys = 3"))
109527cbf3dSMarko Kovacevic 		info.interim_info.tdes_data.nb_keys = 3;
110527cbf3dSMarko Kovacevic 	else
111527cbf3dSMarko Kovacevic 		return -EINVAL;
112527cbf3dSMarko Kovacevic 
113527cbf3dSMarko Kovacevic 	return 0;
114527cbf3dSMarko Kovacevic }
115527cbf3dSMarko Kovacevic 
116527cbf3dSMarko Kovacevic static int
117527cbf3dSMarko Kovacevic parse_tdes_uint8_hex_str(const char *key, char *src, struct fips_val *val)
118527cbf3dSMarko Kovacevic {
119527cbf3dSMarko Kovacevic 	uint8_t tmp_key[24] = {0};
120527cbf3dSMarko Kovacevic 	uint32_t len, i;
121527cbf3dSMarko Kovacevic 
122527cbf3dSMarko Kovacevic 	src += strlen(key);
123527cbf3dSMarko Kovacevic 
124527cbf3dSMarko Kovacevic 	len = strlen(src) / 2;
125527cbf3dSMarko Kovacevic 
126527cbf3dSMarko Kovacevic 	if (val->val) {
127527cbf3dSMarko Kovacevic 		memcpy(tmp_key, val->val, val->len);
128527cbf3dSMarko Kovacevic 		rte_free(val->val);
129527cbf3dSMarko Kovacevic 	}
130527cbf3dSMarko Kovacevic 
131527cbf3dSMarko Kovacevic 	val->val = rte_zmalloc(NULL, 24, 0);
132527cbf3dSMarko Kovacevic 	if (!val->val)
133527cbf3dSMarko Kovacevic 		return -1;
134527cbf3dSMarko Kovacevic 
135527cbf3dSMarko Kovacevic 	memcpy(val->val, tmp_key, 24);
136527cbf3dSMarko Kovacevic 
137527cbf3dSMarko Kovacevic 	if (strstr(key, KEYS_STR)) {
138527cbf3dSMarko Kovacevic 		for (i = 0; i < len; i++) {
139527cbf3dSMarko Kovacevic 			char byte[3] = {src[i * 2], src[i * 2 + 1], '\0'};
140527cbf3dSMarko Kovacevic 
141527cbf3dSMarko Kovacevic 			if (parser_read_uint8_hex(&val->val[i], byte) < 0)
142527cbf3dSMarko Kovacevic 				goto error_exit;
143527cbf3dSMarko Kovacevic 		}
144527cbf3dSMarko Kovacevic 
145527cbf3dSMarko Kovacevic 		memcpy(val->val + 8, val->val, 8);
146527cbf3dSMarko Kovacevic 		memcpy(val->val + 16, val->val, 8);
147527cbf3dSMarko Kovacevic 
148527cbf3dSMarko Kovacevic 	} else if (strstr(key, KEY1_STR)) {
149527cbf3dSMarko Kovacevic 		for (i = 0; i < len; i++) {
150527cbf3dSMarko Kovacevic 			char byte[3] = {src[i * 2], src[i * 2 + 1], '\0'};
151527cbf3dSMarko Kovacevic 
152527cbf3dSMarko Kovacevic 			if (parser_read_uint8_hex(&val->val[i], byte) < 0)
153527cbf3dSMarko Kovacevic 				goto error_exit;
154527cbf3dSMarko Kovacevic 		}
155527cbf3dSMarko Kovacevic 
156527cbf3dSMarko Kovacevic 		if (info.interim_info.tdes_data.nb_keys == 2)
157527cbf3dSMarko Kovacevic 			memcpy(val->val + 16, val->val, 8);
158527cbf3dSMarko Kovacevic 
159527cbf3dSMarko Kovacevic 	} else if (strstr(key, KEY2_STR)) {
160527cbf3dSMarko Kovacevic 		for (i = 0; i < len; i++) {
161527cbf3dSMarko Kovacevic 			char byte[3] = {src[i * 2], src[i * 2 + 1], '\0'};
162527cbf3dSMarko Kovacevic 
163527cbf3dSMarko Kovacevic 			if (parser_read_uint8_hex(&val->val[i + 8], byte) < 0)
164527cbf3dSMarko Kovacevic 				goto error_exit;
165527cbf3dSMarko Kovacevic 		}
166527cbf3dSMarko Kovacevic 
167527cbf3dSMarko Kovacevic 	} else if (strstr(key, KEY3_STR)) {
168527cbf3dSMarko Kovacevic 		for (i = 0; i < len; i++) {
169527cbf3dSMarko Kovacevic 			char byte[3] = {src[i * 2], src[i * 2 + 1], '\0'};
170527cbf3dSMarko Kovacevic 
171527cbf3dSMarko Kovacevic 			if (parser_read_uint8_hex(&val->val[i + 16], byte) < 0)
172527cbf3dSMarko Kovacevic 				goto error_exit;
173527cbf3dSMarko Kovacevic 		}
174527cbf3dSMarko Kovacevic 	} else
175527cbf3dSMarko Kovacevic 		return -EINVAL;
176527cbf3dSMarko Kovacevic 
177527cbf3dSMarko Kovacevic 	val->len = 24;
178527cbf3dSMarko Kovacevic 
179527cbf3dSMarko Kovacevic 	return 0;
180527cbf3dSMarko Kovacevic 
181527cbf3dSMarko Kovacevic error_exit:
182527cbf3dSMarko Kovacevic 	rte_free(val->val);
183527cbf3dSMarko Kovacevic 	memset(val, 0, sizeof(*val));
184527cbf3dSMarko Kovacevic 	return -EINVAL;
185527cbf3dSMarko Kovacevic }
186527cbf3dSMarko Kovacevic 
187527cbf3dSMarko Kovacevic static int
188527cbf3dSMarko Kovacevic parse_test_tdes_writeback(struct fips_val *val)
189527cbf3dSMarko Kovacevic {
190527cbf3dSMarko Kovacevic 
191527cbf3dSMarko Kovacevic 	if (info.op == FIPS_TEST_ENC_AUTH_GEN)
192527cbf3dSMarko Kovacevic 		fprintf(info.fp_wr, "%s", CT_STR);
193527cbf3dSMarko Kovacevic 	else
194527cbf3dSMarko Kovacevic 		fprintf(info.fp_wr, "%s", PT_STR);
195527cbf3dSMarko Kovacevic 
196527cbf3dSMarko Kovacevic 	parse_write_hex_str(val);
197527cbf3dSMarko Kovacevic 
198527cbf3dSMarko Kovacevic 	return 0;
199527cbf3dSMarko Kovacevic 
200527cbf3dSMarko Kovacevic }
201527cbf3dSMarko Kovacevic 
202527cbf3dSMarko Kovacevic static int
203527cbf3dSMarko Kovacevic writeback_tdes_hex_str(const char *key, char *dst, struct fips_val *val)
204527cbf3dSMarko Kovacevic {
205*86ce81afSMarko Kovacevic 	struct fips_val tmp_val = {0};
206527cbf3dSMarko Kovacevic 
207527cbf3dSMarko Kovacevic 	tmp_val.len = 8;
208527cbf3dSMarko Kovacevic 
209527cbf3dSMarko Kovacevic 	if (strstr(key, KEY1_STR))
210527cbf3dSMarko Kovacevic 		tmp_val.val = val->val;
211527cbf3dSMarko Kovacevic 	else if (strstr(key, KEY2_STR))
212527cbf3dSMarko Kovacevic 		tmp_val.val = val->val + 8;
213527cbf3dSMarko Kovacevic 	else if (strstr(key, KEY3_STR))
214527cbf3dSMarko Kovacevic 		tmp_val.val = val->val + 16;
215527cbf3dSMarko Kovacevic 
216527cbf3dSMarko Kovacevic 	return writeback_hex_str(key, dst, &tmp_val);
217527cbf3dSMarko Kovacevic }
218527cbf3dSMarko Kovacevic 
219527cbf3dSMarko Kovacevic static int
220527cbf3dSMarko Kovacevic rsp_test_tdes_check(struct fips_val *val)
221527cbf3dSMarko Kovacevic {
222527cbf3dSMarko Kovacevic 	struct fips_val *data;
223527cbf3dSMarko Kovacevic 
224527cbf3dSMarko Kovacevic 	if (info.op == FIPS_TEST_ENC_AUTH_GEN)
225527cbf3dSMarko Kovacevic 		data = &vec.ct;
226527cbf3dSMarko Kovacevic 	else
227527cbf3dSMarko Kovacevic 		data = &vec.pt;
228527cbf3dSMarko Kovacevic 
229527cbf3dSMarko Kovacevic 	if (memcmp(val->val, data->val, val->len) == 0)
230527cbf3dSMarko Kovacevic 		fprintf(info.fp_wr, "Success\n");
231527cbf3dSMarko Kovacevic 	else
232527cbf3dSMarko Kovacevic 		fprintf(info.fp_wr, "Failed\n");
233527cbf3dSMarko Kovacevic 
234527cbf3dSMarko Kovacevic 	return 0;
235527cbf3dSMarko Kovacevic }
236527cbf3dSMarko Kovacevic 
237527cbf3dSMarko Kovacevic int
238527cbf3dSMarko Kovacevic parse_test_tdes_init(void)
239527cbf3dSMarko Kovacevic {
240527cbf3dSMarko Kovacevic 	uint32_t i;
241527cbf3dSMarko Kovacevic 
242527cbf3dSMarko Kovacevic 	for (i = 0; i < info.nb_vec_lines; i++) {
243527cbf3dSMarko Kovacevic 		char *line = info.vec[i];
244527cbf3dSMarko Kovacevic 		uint32_t j;
245527cbf3dSMarko Kovacevic 
246527cbf3dSMarko Kovacevic 		if (strstr(line, TEST_CBCI_KEY))
247527cbf3dSMarko Kovacevic 			return -EPERM;
248527cbf3dSMarko Kovacevic 
249527cbf3dSMarko Kovacevic 		for (j = 0; j < RTE_DIM(test_types); j++)
250527cbf3dSMarko Kovacevic 			if (strstr(line, test_types[j].desc)) {
251527cbf3dSMarko Kovacevic 				info.interim_info.tdes_data.test_type =
252527cbf3dSMarko Kovacevic 						test_types[j].type;
253527cbf3dSMarko Kovacevic 				break;
254527cbf3dSMarko Kovacevic 			}
255527cbf3dSMarko Kovacevic 	}
256527cbf3dSMarko Kovacevic 
257527cbf3dSMarko Kovacevic 	info.parse_writeback = parse_test_tdes_writeback;
258527cbf3dSMarko Kovacevic 	info.callbacks = tdes_tests_vectors;
259527cbf3dSMarko Kovacevic 	info.interim_callbacks = tdes_tests_interim_vectors;
260527cbf3dSMarko Kovacevic 	info.writeback_callbacks = tdes_writeback_callbacks;
261527cbf3dSMarko Kovacevic 	info.kat_check = rsp_test_tdes_check;
262527cbf3dSMarko Kovacevic 
263527cbf3dSMarko Kovacevic 	return 0;
264527cbf3dSMarko Kovacevic }
265