common/iavf: support raw packet in protocol header
[dpdk.git] / examples / fips_validation / fips_validation_aes.c
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 #include <rte_cryptodev.h>
10 #include <rte_malloc.h>
11
12 #include "fips_validation.h"
13
14 #define MODE_STR        "AESVS"
15 #define ALGO_STR        "test data for "
16 #define OP_STR          "State"
17 #define KEY_SIZE_STR    "Key Length : "
18
19
20 #define COUNT_STR       "COUNT = "
21 #define KEY_STR         "KEY = "
22 #define IV_STR          "IV = "
23 #define PT_STR          "PLAINTEXT = "
24 #define CT_STR          "CIPHERTEXT = "
25
26 #define OP_ENC_STR      "ENCRYPT"
27 #define OP_DEC_STR      "DECRYPT"
28
29 #define ALGO_JSON_STR           "algorithm"
30 #define TESTTYPE_JSON_STR       "testType"
31 #define DIR_JSON_STR            "direction"
32 #define KEYLEN_JSON_STR         "keyLen"
33
34 #define KEY_JSON_STR    "key"
35 #define IV_JSON_STR     "iv"
36 #define PT_JSON_STR     "pt"
37 #define CT_JSON_STR     "ct"
38
39 #define OP_ENC_JSON_STR "encrypt"
40 #define OP_DEC_JSON_STR "decrypt"
41
42 struct {
43         uint32_t type;
44         const char *desc;
45 } aes_test_types[] = {
46                 {AESAVS_TYPE_GFXBOX, "GFSbox"},
47                 {AESAVS_TYPE_KEYSBOX, "KeySbox"},
48                 {AESAVS_TYPE_VARKEY, "VarKey"},
49                 {AESAVS_TYPE_VARTXT, "VarTxt"},
50                 {TDES_VARIABLE_TEXT, "VARIABLE PLAINTEXT/CIPHERTEXT"},
51                 {TDES_VARIABLE_TEXT, "KAT"},
52                 {AESAVS_TYPE_MMT, "MMT"},
53                 {AESAVS_TYPE_MCT, "MCT"},
54                 {AESAVS_TYPE_AFT, "AFT"},
55 };
56
57 struct aes_test_algo {
58         const char *name;
59         enum rte_crypto_cipher_algorithm algo;
60 } const algo_con[] = {
61                 {"CBC", RTE_CRYPTO_CIPHER_AES_CBC},
62                 {"ECB", RTE_CRYPTO_CIPHER_AES_ECB},
63 };
64
65 static int
66 parse_interim_enc_dec(const char *key,
67                 __rte_unused char *text,
68                 __rte_unused struct fips_val *val)
69 {
70         if (strcmp(key, OP_ENC_STR) == 0)
71                 info.op = FIPS_TEST_ENC_AUTH_GEN;
72         else if (strcmp(key, OP_DEC_STR) == 0)
73                 info.op = FIPS_TEST_DEC_AUTH_VERIF;
74         else
75                 return -1;
76
77         return 0;
78 }
79
80 struct fips_test_callback aes_tests_interim[] = {
81                 {OP_ENC_STR, parse_interim_enc_dec, NULL},
82                 {OP_DEC_STR, parse_interim_enc_dec, NULL},
83                 {NULL, NULL, NULL} /**< end pointer */
84 };
85
86 struct fips_test_callback aes_tests_vectors[] = {
87                 {KEY_STR, parse_uint8_hex_str, &vec.cipher_auth.key},
88                 {IV_STR, parse_uint8_hex_str, &vec.iv},
89                 {PT_STR, parse_uint8_hex_str, &vec.pt},
90                 {CT_STR, parse_uint8_hex_str, &vec.ct},
91                 {NULL, NULL, NULL} /**< end pointer */
92 };
93
94 struct fips_test_callback aes_tests_interim_vectors[] = {
95                 {OP_ENC_STR, parse_interim_enc_dec, NULL},
96                 {OP_DEC_STR, parse_interim_enc_dec, NULL},
97                 {NULL, NULL, NULL} /**< end pointer */
98 };
99
100 struct fips_test_callback aes_writeback_callbacks[] = {
101                 /** First element is used to pass COUNT string */
102                 {COUNT_STR, NULL, NULL},
103                 {IV_STR, writeback_hex_str, &vec.iv},
104                 {KEY_STR, writeback_hex_str, &vec.cipher_auth.key},
105                 {PT_STR, writeback_hex_str, &vec.pt},
106                 {CT_STR, writeback_hex_str, &vec.ct},
107                 {NULL, NULL, NULL} /**< end pointer */
108 };
109
110 #ifdef RTE_HAS_JANSSON
111 struct fips_test_callback aes_dec_json_vectors[] = {
112                 {KEY_JSON_STR, parse_uint8_known_len_hex_str, &vec.cipher_auth.key},
113                 {IV_JSON_STR, parse_uint8_hex_str, &vec.iv},
114                 {CT_JSON_STR, parse_uint8_hex_str, &vec.ct},
115                 {NULL, NULL, NULL} /**< end pointer */
116 };
117
118 struct fips_test_callback aes_interim_json_vectors[] = {
119                 {KEYLEN_JSON_STR, parser_read_uint32_bit_val, &vec.cipher_auth.key},
120                 {NULL, NULL, NULL} /**< end pointer */
121 };
122
123 struct fips_test_callback aes_enc_json_vectors[] = {
124                 {KEY_JSON_STR, parse_uint8_known_len_hex_str, &vec.cipher_auth.key},
125                 {IV_JSON_STR, parse_uint8_hex_str, &vec.iv},
126                 {PT_JSON_STR, parse_uint8_hex_str, &vec.pt},
127                 {NULL, NULL, NULL} /**< end pointer */
128 };
129
130 static int
131 parse_test_aes_json_writeback(struct fips_val *val)
132 {
133         struct fips_val tmp_val;
134         json_t *tcId;
135
136         tcId = json_object_get(json_info.json_test_case, "tcId");
137
138         json_info.json_write_case = json_object();
139         json_object_set(json_info.json_write_case, "tcId", tcId);
140
141         if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
142                 json_t *ct;
143
144                 tmp_val.val = val->val;
145                 tmp_val.len = vec.pt.len;
146
147                 writeback_hex_str("", info.one_line_text, &tmp_val);
148                 ct = json_string(info.one_line_text);
149                 json_object_set_new(json_info.json_write_case, CT_JSON_STR, ct);
150
151                 tmp_val.val = val->val + vec.pt.len;
152                 tmp_val.len = val->len - vec.pt.len;
153
154                 writeback_hex_str("", info.one_line_text, &tmp_val);
155         } else {
156                 if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS) {
157                         tmp_val.val = val->val;
158                         tmp_val.len = vec.ct.len;
159
160                         writeback_hex_str("", info.one_line_text, &tmp_val);
161                         json_object_set_new(json_info.json_write_case, PT_JSON_STR,
162                                                                 json_string(info.one_line_text));
163                 } else {
164                         json_object_set_new(json_info.json_write_case, "testPassed", json_false());
165                 }
166         }
167
168         return 0;
169 }
170
171 static int
172 parse_test_aes_mct_json_writeback(struct fips_val *val)
173 {
174         json_t *tcId, *resArr, *res, *ct, *pt, *key, *iv;
175         struct fips_val tmp_val;
176
177         tcId = json_object_get(json_info.json_test_case, "tcId");
178         if (json_info.json_write_case) {
179                 json_t *wcId;
180
181                 wcId = json_object_get(json_info.json_write_case, "tcId");
182                 if (!json_equal(tcId, wcId)) {
183                         json_info.json_write_case = json_object();
184                         json_object_set(json_info.json_write_case, "tcId", tcId);
185                         json_object_set(json_info.json_write_case, "resultsArray", json_array());
186                 }
187         } else {
188                 json_info.json_write_case = json_object();
189                 json_object_set(json_info.json_write_case, "tcId", tcId);
190                 json_object_set(json_info.json_write_case, "resultsArray", json_array());
191         }
192
193         resArr = json_object_get(json_info.json_write_case, "resultsArray");
194         if (!json_is_array(resArr))
195                 return -EINVAL;
196
197         res = json_object();
198         if (info .op == FIPS_TEST_ENC_AUTH_GEN) {
199                 writeback_hex_str("", info.one_line_text, &vec.cipher_auth.key);
200                 key = json_string(info.one_line_text);
201                 json_object_set_new(res, KEY_JSON_STR, key);
202
203                 writeback_hex_str("", info.one_line_text, &val[2]);
204                 iv = json_string(info.one_line_text);
205                 json_object_set_new(res, IV_JSON_STR, iv);
206
207                 writeback_hex_str("", info.one_line_text, &val[1]);
208                 pt = json_string(info.one_line_text);
209                 json_object_set_new(res, PT_JSON_STR, pt);
210
211                 tmp_val.val = val->val;
212                 tmp_val.len = vec.pt.len;
213
214                 writeback_hex_str("", info.one_line_text, &tmp_val);
215                 ct = json_string(info.one_line_text);
216                 json_object_set_new(res, CT_JSON_STR, ct);
217
218                 tmp_val.val = val->val + vec.pt.len;
219                 tmp_val.len = val->len - vec.pt.len;
220
221                 writeback_hex_str("", info.one_line_text, &tmp_val);
222         } else {
223                 if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS) {
224                         writeback_hex_str("", info.one_line_text, &vec.cipher_auth.key);
225                         key = json_string(info.one_line_text);
226                         json_object_set_new(res, KEY_JSON_STR, key);
227
228                         writeback_hex_str("", info.one_line_text, &val[2]);
229                         iv = json_string(info.one_line_text);
230                         json_object_set_new(res, IV_JSON_STR, iv);
231
232                         tmp_val.val = val->val;
233                         tmp_val.len = vec.ct.len;
234
235                         writeback_hex_str("", info.one_line_text, &tmp_val);
236                         pt = json_string(info.one_line_text);
237                         json_object_set_new(res, PT_JSON_STR, pt);
238
239                         writeback_hex_str("", info.one_line_text, &val[1]);
240                         ct = json_string(info.one_line_text);
241                         json_object_set_new(res, CT_JSON_STR, ct);
242                 } else {
243                         json_object_set_new(json_info.json_write_case, "testPassed", json_false());
244                 }
245         }
246
247         json_array_append_new(resArr, res);
248         return 0;
249 }
250
251 int
252 parse_test_aes_json_init(void)
253 {
254         json_t *type_obj = json_object_get(json_info.json_test_group, TESTTYPE_JSON_STR);
255         json_t *algo_obj = json_object_get(json_info.json_vector_set, ALGO_JSON_STR);
256         const char *type_str = json_string_value(type_obj);
257         const char *algo_str = json_string_value(algo_obj);
258         uint32_t i;
259
260         if (json_info.json_test_group) {
261                 json_t *direction_obj;
262                 const char *direction_str;
263
264                 direction_obj = json_object_get(json_info.json_test_group, DIR_JSON_STR);
265                 direction_str = json_string_value(direction_obj);
266
267                 if (strcmp(direction_str, OP_ENC_JSON_STR) == 0) {
268                         info.op = FIPS_TEST_ENC_AUTH_GEN;
269                         info.callbacks = aes_enc_json_vectors;
270
271                 } else if (strcmp(direction_str, OP_DEC_JSON_STR) == 0) {
272                         info.op = FIPS_TEST_DEC_AUTH_VERIF;
273                         info.callbacks = aes_dec_json_vectors;
274                 } else {
275                         return -EINVAL;
276                 }
277                 info.interim_callbacks = aes_interim_json_vectors;
278         }
279
280         for (i = 0; i < RTE_DIM(aes_test_types); i++)
281                 if (strstr(type_str, aes_test_types[i].desc)) {
282                         info.interim_info.aes_data.test_type =
283                                 aes_test_types[i].type;
284                         break;
285                 }
286
287         if (i >= RTE_DIM(aes_test_types))
288                 return -EINVAL;
289
290         switch (info.interim_info.aes_data.test_type) {
291         case AESAVS_TYPE_MCT:
292                 info.parse_writeback = parse_test_aes_mct_json_writeback;
293                 break;
294         case AESAVS_TYPE_AFT:
295                 info.parse_writeback = parse_test_aes_json_writeback;
296                 break;
297         default:
298                 info.parse_writeback = NULL;
299         }
300
301         if (!info.parse_writeback)
302                 return -EINVAL;
303
304         for (i = 0; i < RTE_DIM(algo_con); i++)
305                 if (strstr(algo_str, algo_con[i].name)) {
306                         info.interim_info.aes_data.cipher_algo =
307                                 (uint32_t)algo_con[i].algo;
308                         break;
309                 }
310
311         if (i >= RTE_DIM(algo_con))
312                 return -EINVAL;
313
314         return 0;
315 }
316 #endif /* RTE_HAS_JANSSON */
317
318 static int
319 parse_test_aes_writeback(struct fips_val *val)
320 {
321         if (info.op == FIPS_TEST_ENC_AUTH_GEN)
322                 fprintf(info.fp_wr, "%s", CT_STR);
323         else
324                 fprintf(info.fp_wr, "%s", PT_STR);
325
326         parse_write_hex_str(val);
327
328         return 0;
329 }
330
331 static int
332 rsp_test_aes_check(struct fips_val *val)
333 {
334         struct fips_val *data;
335
336         if (info.op == FIPS_TEST_ENC_AUTH_GEN)
337                 data = &vec.ct;
338         else
339                 data = &vec.pt;
340
341         if (memcmp(val->val, data->val, val->len) == 0)
342                 fprintf(info.fp_wr, "Success\n");
343         else
344                 fprintf(info.fp_wr, "Failed\n");
345
346         return 0;
347 }
348
349 int
350 parse_test_aes_init(void)
351 {
352         char *tmp;
353         uint32_t i, j;
354
355         for (i = 0; i < info.nb_vec_lines; i++) {
356                 char *line = info.vec[i];
357
358                 tmp = strstr(line, MODE_STR);
359                 if (tmp) {
360                         for (j = 0; j < RTE_DIM(aes_test_types); j++)
361                                 if (strstr(line, aes_test_types[j].desc)) {
362                                         info.interim_info.aes_data.test_type =
363                                                         aes_test_types[j].type;
364                                         break;
365                                 }
366
367                         if (j >= RTE_DIM(aes_test_types))
368                                 return -EINVAL;
369
370                         tmp = strstr(line, ALGO_STR);
371                         if (!tmp)
372                                 return -EINVAL;
373
374                         tmp += strlen(ALGO_STR);
375                         for (j = 0; j < RTE_DIM(algo_con); j++)
376                                 if (strcmp(algo_con[j].name, tmp) == 0) {
377                                         info.interim_info.aes_data.cipher_algo =
378                                                 (uint32_t)algo_con[j].algo;
379                                         break;
380                                 }
381                         if (j >= RTE_DIM(algo_con))
382                                 return -EINVAL;
383
384                         continue;
385                 }
386
387                 tmp = strstr(line, OP_STR);
388                 if (tmp)
389                         continue;
390
391                 tmp = strstr(line, KEY_SIZE_STR);
392                 if (tmp) {
393                         tmp += strlen(KEY_SIZE_STR);
394                         if (parser_read_uint32
395                                         (&info.interim_info.aes_data.key_len,
396                                                         tmp) < 0)
397                                 return -EINVAL;
398
399                         info.interim_info.aes_data.key_len /= 8;
400
401                         continue;
402                 }
403         }
404
405         info.parse_writeback = parse_test_aes_writeback;
406         info.callbacks = aes_tests_vectors;
407         info.interim_callbacks = aes_tests_interim_vectors;
408         info.writeback_callbacks = aes_writeback_callbacks;
409         info.kat_check = rsp_test_aes_check;
410
411         return 0;
412 }