Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2016-2017 Intel Corporation
3 : : */
4 : : #ifdef RTE_EXEC_ENV_FREEBSD
5 : : #define _WITH_GETLINE
6 : : #endif
7 : : #include <ctype.h>
8 : : #include <stdio.h>
9 : : #include <stdlib.h>
10 : :
11 : : #include <rte_malloc.h>
12 : :
13 : : #include "cperf_options.h"
14 : : #include "cperf_test_vectors.h"
15 : : #include "cperf_test_vector_parsing.h"
16 : :
17 : : int
18 : 0 : free_test_vector(struct cperf_test_vector *vector, struct cperf_options *opts)
19 : : {
20 : 0 : if (vector == NULL || opts == NULL)
21 : : return -1;
22 : :
23 : 0 : rte_free(vector->cipher_iv.data);
24 : 0 : rte_free(vector->auth_iv.data);
25 : 0 : rte_free(vector->aad.data);
26 : 0 : rte_free(vector->digest.data);
27 : :
28 : 0 : if (opts->test_file != NULL) {
29 : 0 : rte_free(vector->plaintext.data);
30 : 0 : rte_free(vector->cipher_key.data);
31 : 0 : rte_free(vector->auth_key.data);
32 : 0 : rte_free(vector->ciphertext.data);
33 : 0 : free(opts->test_file);
34 : : }
35 : :
36 : 0 : rte_free(vector);
37 : :
38 : 0 : return 0;
39 : : }
40 : :
41 : : void
42 : 0 : show_test_vector(struct cperf_test_vector *test_vector)
43 : : {
44 : : const uint8_t wrap = 32;
45 : : uint32_t i;
46 : :
47 : 0 : if (test_vector == NULL)
48 : : return;
49 : :
50 : 0 : if (test_vector->plaintext.data) {
51 : : printf("\nplaintext =\n");
52 : 0 : for (i = 0; i < test_vector->plaintext.length; ++i) {
53 : 0 : if ((i % wrap == 0) && (i != 0))
54 : : printf("\n");
55 : 0 : if (i == test_vector->plaintext.length - 1)
56 : 0 : printf("0x%02x",
57 : 0 : test_vector->plaintext.data[i]);
58 : : else
59 : 0 : printf("0x%02x, ",
60 : 0 : test_vector->plaintext.data[i]);
61 : : }
62 : : printf("\n");
63 : : }
64 : :
65 : 0 : if (test_vector->cipher_key.data) {
66 : : printf("\ncipher_key =\n");
67 : 0 : for (i = 0; i < test_vector->cipher_key.length; ++i) {
68 : 0 : if ((i % wrap == 0) && (i != 0))
69 : : printf("\n");
70 : 0 : if (i == (uint32_t)(test_vector->cipher_key.length - 1))
71 : 0 : printf("0x%02x",
72 : 0 : test_vector->cipher_key.data[i]);
73 : : else
74 : 0 : printf("0x%02x, ",
75 : 0 : test_vector->cipher_key.data[i]);
76 : : }
77 : : printf("\n");
78 : : }
79 : :
80 : 0 : if (test_vector->auth_key.data) {
81 : : printf("\nauth_key =\n");
82 : 0 : for (i = 0; i < test_vector->auth_key.length; ++i) {
83 : 0 : if ((i % wrap == 0) && (i != 0))
84 : : printf("\n");
85 : 0 : if (i == (uint32_t)(test_vector->auth_key.length - 1))
86 : 0 : printf("0x%02x", test_vector->auth_key.data[i]);
87 : : else
88 : 0 : printf("0x%02x, ",
89 : 0 : test_vector->auth_key.data[i]);
90 : : }
91 : : printf("\n");
92 : : }
93 : :
94 : 0 : if (test_vector->aead_key.data) {
95 : : printf("\naead_key =\n");
96 : 0 : for (i = 0; i < test_vector->aead_key.length; ++i) {
97 : 0 : if ((i % wrap == 0) && (i != 0))
98 : : printf("\n");
99 : 0 : if (i == (uint32_t)(test_vector->aead_key.length - 1))
100 : 0 : printf("0x%02x", test_vector->aead_key.data[i]);
101 : : else
102 : 0 : printf("0x%02x, ",
103 : 0 : test_vector->aead_key.data[i]);
104 : : }
105 : : printf("\n");
106 : : }
107 : :
108 : 0 : if (test_vector->cipher_iv.data) {
109 : : printf("\ncipher_iv =\n");
110 : 0 : for (i = 0; i < test_vector->cipher_iv.length; ++i) {
111 : 0 : if ((i % wrap == 0) && (i != 0))
112 : : printf("\n");
113 : 0 : if (i == (uint32_t)(test_vector->cipher_iv.length - 1))
114 : 0 : printf("0x%02x", test_vector->cipher_iv.data[i]);
115 : : else
116 : 0 : printf("0x%02x, ", test_vector->cipher_iv.data[i]);
117 : : }
118 : : printf("\n");
119 : : }
120 : :
121 : 0 : if (test_vector->auth_iv.data) {
122 : : printf("\nauth_iv =\n");
123 : 0 : for (i = 0; i < test_vector->auth_iv.length; ++i) {
124 : 0 : if ((i % wrap == 0) && (i != 0))
125 : : printf("\n");
126 : 0 : if (i == (uint32_t)(test_vector->auth_iv.length - 1))
127 : 0 : printf("0x%02x", test_vector->auth_iv.data[i]);
128 : : else
129 : 0 : printf("0x%02x, ", test_vector->auth_iv.data[i]);
130 : : }
131 : : printf("\n");
132 : : }
133 : :
134 : 0 : if (test_vector->aead_iv.data) {
135 : : printf("\naead_iv =\n");
136 : 0 : for (i = 0; i < test_vector->aead_iv.length; ++i) {
137 : 0 : if ((i % wrap == 0) && (i != 0))
138 : : printf("\n");
139 : 0 : if (i == (uint32_t)(test_vector->aead_iv.length - 1))
140 : 0 : printf("0x%02x", test_vector->aead_iv.data[i]);
141 : : else
142 : 0 : printf("0x%02x, ", test_vector->aead_iv.data[i]);
143 : : }
144 : : printf("\n");
145 : : }
146 : :
147 : 0 : if (test_vector->ciphertext.data) {
148 : : printf("\nciphertext =\n");
149 : 0 : for (i = 0; i < test_vector->ciphertext.length; ++i) {
150 : 0 : if ((i % wrap == 0) && (i != 0))
151 : : printf("\n");
152 : 0 : if (i == test_vector->ciphertext.length - 1)
153 : 0 : printf("0x%02x",
154 : 0 : test_vector->ciphertext.data[i]);
155 : : else
156 : 0 : printf("0x%02x, ",
157 : 0 : test_vector->ciphertext.data[i]);
158 : : }
159 : : printf("\n");
160 : : }
161 : :
162 : 0 : if (test_vector->aad.data) {
163 : : printf("\naad =\n");
164 : 0 : for (i = 0; i < test_vector->aad.length; ++i) {
165 : 0 : if ((i % wrap == 0) && (i != 0))
166 : : printf("\n");
167 : 0 : if (i == (uint32_t)(test_vector->aad.length - 1))
168 : 0 : printf("0x%02x", test_vector->aad.data[i]);
169 : : else
170 : 0 : printf("0x%02x, ", test_vector->aad.data[i]);
171 : : }
172 : : printf("\n");
173 : : }
174 : :
175 : 0 : if (test_vector->digest.data) {
176 : : printf("\ndigest =\n");
177 : 0 : for (i = 0; i < test_vector->digest.length; ++i) {
178 : 0 : if ((i % wrap == 0) && (i != 0))
179 : : printf("\n");
180 : 0 : if (i == (uint32_t)(test_vector->digest.length - 1))
181 : 0 : printf("0x%02x", test_vector->digest.data[i]);
182 : : else
183 : 0 : printf("0x%02x, ", test_vector->digest.data[i]);
184 : : }
185 : : printf("\n");
186 : : }
187 : : }
188 : :
189 : : /* trim leading and trailing spaces */
190 : : static char *
191 : 0 : trim_space(char *str)
192 : : {
193 : : char *start, *end;
194 : :
195 : 0 : for (start = str; *start; start++) {
196 : 0 : if (!isspace((unsigned char) start[0]))
197 : : break;
198 : : }
199 : :
200 : 0 : for (end = start + strlen(start); end > start + 1; end--) {
201 : 0 : if (!isspace((unsigned char) end[-1]))
202 : : break;
203 : : }
204 : :
205 : 0 : *end = 0;
206 : :
207 : : /* Shift from "start" to the beginning of the string */
208 : 0 : if (start > str)
209 : 0 : memmove(str, start, (end - start) + 1);
210 : :
211 : 0 : return str;
212 : : }
213 : :
214 : : /* tokenization test values separated by a comma */
215 : : static int
216 : 0 : parse_values(char *tokens, uint8_t **data, uint32_t *data_length)
217 : : {
218 : : uint32_t n_tokens;
219 : : uint32_t data_size = 32;
220 : :
221 : : uint8_t *values, *values_resized;
222 : 0 : char *tok, *error = NULL;
223 : :
224 : 0 : tok = strtok(tokens, CPERF_VALUE_DELIMITER);
225 : 0 : if (tok == NULL)
226 : : return -1;
227 : :
228 : 0 : values = (uint8_t *) rte_zmalloc(NULL, sizeof(uint8_t) * data_size, 0);
229 : 0 : if (values == NULL)
230 : : return -1;
231 : :
232 : : n_tokens = 0;
233 : : while (tok != NULL) {
234 : : values_resized = NULL;
235 : :
236 : 0 : if (n_tokens >= data_size) {
237 : 0 : data_size *= 2;
238 : :
239 : 0 : values_resized = (uint8_t *) rte_realloc(values,
240 : : sizeof(uint8_t) * data_size, 0);
241 : 0 : if (values_resized == NULL) {
242 : 0 : rte_free(values);
243 : 0 : return -1;
244 : : }
245 : : values = values_resized;
246 : : }
247 : :
248 : 0 : values[n_tokens] = (uint8_t) strtoul(tok, &error, 0);
249 : 0 : if ((error == NULL) || (*error != '\0')) {
250 : : printf("Failed with convert '%s'\n", tok);
251 : 0 : rte_free(values);
252 : 0 : return -1;
253 : : }
254 : :
255 : 0 : tok = strtok(NULL, CPERF_VALUE_DELIMITER);
256 : 0 : if (tok == NULL)
257 : : break;
258 : :
259 : 0 : n_tokens++;
260 : : }
261 : :
262 : 0 : values_resized = (uint8_t *) rte_realloc(values,
263 : 0 : sizeof(uint8_t) * (n_tokens + 1), 0);
264 : :
265 : 0 : if (values_resized == NULL) {
266 : 0 : rte_free(values);
267 : 0 : return -1;
268 : : }
269 : :
270 : 0 : *data = values_resized;
271 : 0 : *data_length = n_tokens + 1;
272 : :
273 : 0 : return 0;
274 : : }
275 : :
276 : : /* checks the type of key and assigns data */
277 : : static int
278 : 0 : parse_entry(char *entry, struct cperf_test_vector *vector,
279 : : struct cperf_options *opts, uint8_t tc_found)
280 : : {
281 : : int status;
282 : : uint32_t data_length;
283 : :
284 : 0 : uint8_t *data = NULL;
285 : : char *token, *key_token;
286 : :
287 : 0 : if (entry == NULL) {
288 : : printf("Expected entry value\n");
289 : 0 : return -1;
290 : : }
291 : :
292 : : /* get key */
293 : 0 : token = strtok(entry, CPERF_ENTRY_DELIMITER);
294 : : key_token = token;
295 : : /* get values for key */
296 : 0 : token = strtok(NULL, CPERF_ENTRY_DELIMITER);
297 : :
298 : 0 : if (key_token == NULL || token == NULL) {
299 : : printf("Expected 'key = values' but was '%.40s'..\n", entry);
300 : 0 : return -1;
301 : : }
302 : :
303 : 0 : status = parse_values(token, &data, &data_length);
304 : 0 : if (status)
305 : : return -1;
306 : :
307 : : /* compare keys */
308 : 0 : if (strstr(key_token, "plaintext")) {
309 : 0 : rte_free(vector->plaintext.data);
310 : 0 : vector->plaintext.data = data;
311 : 0 : if (tc_found)
312 : 0 : vector->plaintext.length = data_length;
313 : : else {
314 : 0 : if (opts->max_buffer_size > data_length) {
315 : : printf("Global plaintext shorter than "
316 : : "buffer_sz\n");
317 : 0 : return -1;
318 : : }
319 : 0 : vector->plaintext.length = opts->max_buffer_size;
320 : : }
321 : :
322 : 0 : } else if (strstr(key_token, "cipher_key")) {
323 : 0 : rte_free(vector->cipher_key.data);
324 : 0 : vector->cipher_key.data = data;
325 : 0 : if (tc_found)
326 : 0 : vector->cipher_key.length = data_length;
327 : : else {
328 : 0 : if (opts->cipher_key_sz > data_length) {
329 : : printf("Global cipher_key shorter than "
330 : : "cipher_key_sz\n");
331 : 0 : return -1;
332 : : }
333 : 0 : vector->cipher_key.length = opts->cipher_key_sz;
334 : : }
335 : :
336 : 0 : } else if (strstr(key_token, "auth_key")) {
337 : 0 : rte_free(vector->auth_key.data);
338 : 0 : vector->auth_key.data = data;
339 : 0 : if (tc_found)
340 : 0 : vector->auth_key.length = data_length;
341 : : else {
342 : 0 : if (opts->auth_key_sz > data_length) {
343 : : printf("Global auth_key shorter than "
344 : : "auth_key_sz\n");
345 : 0 : return -1;
346 : : }
347 : 0 : vector->auth_key.length = opts->auth_key_sz;
348 : : }
349 : :
350 : 0 : } else if (strstr(key_token, "aead_key")) {
351 : 0 : rte_free(vector->aead_key.data);
352 : 0 : vector->aead_key.data = data;
353 : 0 : if (tc_found)
354 : 0 : vector->aead_key.length = data_length;
355 : : else {
356 : 0 : if (opts->aead_key_sz > data_length) {
357 : : printf("Global aead_key shorter than "
358 : : "aead_key_sz\n");
359 : 0 : return -1;
360 : : }
361 : 0 : vector->aead_key.length = opts->aead_key_sz;
362 : : }
363 : :
364 : 0 : } else if (strstr(key_token, "cipher_iv")) {
365 : 0 : rte_free(vector->cipher_iv.data);
366 : 0 : vector->cipher_iv.data = data;
367 : 0 : if (tc_found)
368 : 0 : vector->cipher_iv.length = data_length;
369 : : else {
370 : 0 : if (opts->cipher_iv_sz > data_length) {
371 : : printf("Global cipher iv shorter than "
372 : : "cipher_iv_sz\n");
373 : 0 : return -1;
374 : : }
375 : 0 : vector->cipher_iv.length = opts->cipher_iv_sz;
376 : : }
377 : :
378 : 0 : } else if (strstr(key_token, "auth_iv")) {
379 : 0 : rte_free(vector->auth_iv.data);
380 : 0 : vector->auth_iv.data = data;
381 : 0 : if (tc_found)
382 : 0 : vector->auth_iv.length = data_length;
383 : : else {
384 : 0 : if (opts->auth_iv_sz > data_length) {
385 : : printf("Global auth iv shorter than "
386 : : "auth_iv_sz\n");
387 : 0 : return -1;
388 : : }
389 : 0 : vector->auth_iv.length = opts->auth_iv_sz;
390 : : }
391 : :
392 : 0 : } else if (strstr(key_token, "aead_iv")) {
393 : 0 : rte_free(vector->aead_iv.data);
394 : 0 : vector->aead_iv.data = data;
395 : 0 : if (tc_found)
396 : 0 : vector->aead_iv.length = data_length;
397 : : else {
398 : 0 : if (opts->aead_iv_sz > data_length) {
399 : : printf("Global aead iv shorter than "
400 : : "aead_iv_sz\n");
401 : 0 : return -1;
402 : : }
403 : 0 : vector->aead_iv.length = opts->aead_iv_sz;
404 : : }
405 : :
406 : 0 : } else if (strstr(key_token, "ciphertext")) {
407 : 0 : rte_free(vector->ciphertext.data);
408 : 0 : vector->ciphertext.data = data;
409 : 0 : if (tc_found)
410 : 0 : vector->ciphertext.length = data_length;
411 : : else {
412 : 0 : if (opts->max_buffer_size > data_length) {
413 : : printf("Global ciphertext shorter than "
414 : : "buffer_sz\n");
415 : 0 : return -1;
416 : : }
417 : 0 : vector->ciphertext.length = opts->max_buffer_size;
418 : : }
419 : :
420 : 0 : } else if (strstr(key_token, "aad")) {
421 : 0 : rte_free(vector->aad.data);
422 : 0 : vector->aad.data = data;
423 : 0 : vector->aad.phys_addr = rte_malloc_virt2iova(vector->aad.data);
424 : 0 : if (tc_found)
425 : 0 : vector->aad.length = data_length;
426 : : else {
427 : 0 : if (opts->aead_aad_sz > data_length) {
428 : : printf("Global aad shorter than "
429 : : "aead_aad_sz\n");
430 : 0 : return -1;
431 : : }
432 : 0 : vector->aad.length = opts->aead_aad_sz;
433 : : }
434 : :
435 : 0 : } else if (strstr(key_token, "digest")) {
436 : 0 : rte_free(vector->digest.data);
437 : 0 : vector->digest.data = data;
438 : 0 : vector->digest.phys_addr = rte_malloc_virt2iova(
439 : : vector->digest.data);
440 : 0 : if (tc_found)
441 : 0 : vector->digest.length = data_length;
442 : : else {
443 : 0 : if (opts->digest_sz > data_length) {
444 : : printf("Global digest shorter than "
445 : : "digest_sz\n");
446 : 0 : return -1;
447 : : }
448 : 0 : vector->digest.length = opts->digest_sz;
449 : : }
450 : : } else {
451 : 0 : printf("Not valid key: '%s'\n", trim_space(key_token));
452 : 0 : return -1;
453 : : }
454 : :
455 : : return 0;
456 : : }
457 : :
458 : : /* searches in the file for test keys and values */
459 : : static int
460 : 0 : parse_file(struct cperf_test_vector *vector, struct cperf_options *opts)
461 : : {
462 : : uint8_t tc_found = 0;
463 : : uint8_t tc_data_start = 0;
464 : : ssize_t read;
465 : 0 : size_t len = 0;
466 : : int status = 0;
467 : :
468 : : FILE *fp;
469 : 0 : char *line = NULL;
470 : : char *entry = NULL;
471 : :
472 : 0 : fp = fopen(opts->test_file, "r");
473 : 0 : if (fp == NULL) {
474 : 0 : printf("File %s does not exists\n", opts->test_file);
475 : 0 : return -1;
476 : : }
477 : :
478 : 0 : while ((read = getline(&line, &len, fp)) != -1) {
479 : :
480 : : /* ignore comments and new lines */
481 : 0 : if (line[0] == '#' || line[0] == '/' || line[0] == '\n'
482 : : || line[0] == '\r' || line[0] == ' ')
483 : 0 : continue;
484 : :
485 : 0 : trim_space(line);
486 : :
487 : : /* next test case is started */
488 : 0 : if (line[0] == '[' && line[strlen(line) - 1] == ']' && tc_found)
489 : : break;
490 : : /* test case section started, end of global data */
491 : 0 : else if (line[0] == '[' && line[strlen(line) - 1] == ']')
492 : : tc_data_start = 1;
493 : :
494 : : /* test name unspecified, end after global data */
495 : 0 : if (tc_data_start && opts->test_name == NULL)
496 : : break;
497 : : /* searching for a suitable test */
498 : 0 : else if (tc_data_start && tc_found == 0) {
499 : 0 : if (!strcmp(line, opts->test_name)) {
500 : : tc_found = 1;
501 : 0 : continue;
502 : : } else
503 : 0 : continue;
504 : : }
505 : :
506 : : /* buffer for multiline */
507 : 0 : entry = (char *) rte_realloc(entry,
508 : 0 : sizeof(char) * strlen(line) + 1, 0);
509 : 0 : if (entry == NULL)
510 : : return -1;
511 : :
512 : 0 : strcpy(entry, line);
513 : :
514 : : /* check if entry ends with , or = */
515 : 0 : if (entry[strlen(entry) - 1] == ','
516 : 0 : || entry[strlen(entry) - 1] == '=') {
517 : 0 : while ((read = getline(&line, &len, fp)) != -1) {
518 : 0 : trim_space(line);
519 : :
520 : : /* extend entry about length of new line */
521 : 0 : char *entry_extended = (char *) rte_realloc(
522 : : entry, sizeof(char)
523 : 0 : * (strlen(line) + strlen(entry))
524 : : + 1, 0);
525 : :
526 : 0 : if (entry_extended == NULL)
527 : 0 : goto err;
528 : : entry = entry_extended;
529 : : /* entry has been allocated accordingly */
530 : 0 : strcpy(&entry[strlen(entry)], line);
531 : :
532 : 0 : if (entry[strlen(entry) - 1] != ',')
533 : : break;
534 : : }
535 : : }
536 : 0 : status = parse_entry(entry, vector, opts, tc_found);
537 : 0 : if (status) {
538 : : printf("An error occurred while parsing!\n");
539 : 0 : goto err;
540 : : }
541 : : }
542 : :
543 : 0 : if (tc_found == 0 && opts->test_name != NULL) {
544 : : printf("Not found '%s' case in test file\n", opts->test_name);
545 : 0 : goto err;
546 : : }
547 : :
548 : 0 : fclose(fp);
549 : 0 : free(line);
550 : 0 : rte_free(entry);
551 : :
552 : 0 : return 0;
553 : :
554 : 0 : err:
555 : : if (fp)
556 : 0 : fclose(fp);
557 : 0 : free(line);
558 : 0 : rte_free(entry);
559 : :
560 : 0 : return -1;
561 : : }
562 : :
563 : : struct cperf_test_vector*
564 : 0 : cperf_test_vector_get_from_file(struct cperf_options *opts)
565 : : {
566 : : int status;
567 : : struct cperf_test_vector *test_vector = NULL;
568 : :
569 : 0 : if (opts == NULL || opts->test_file == NULL)
570 : : return test_vector;
571 : :
572 : 0 : test_vector = (struct cperf_test_vector *) rte_zmalloc(NULL,
573 : : sizeof(struct cperf_test_vector), 0);
574 : 0 : if (test_vector == NULL)
575 : : return test_vector;
576 : :
577 : : /* filling the vector with data from a file */
578 : 0 : status = parse_file(test_vector, opts);
579 : 0 : if (status) {
580 : 0 : free_test_vector(test_vector, opts);
581 : 0 : return NULL;
582 : : }
583 : :
584 : : /* other values not included in the file */
585 : 0 : test_vector->data.cipher_offset = 0;
586 : 0 : test_vector->data.cipher_length = opts->max_buffer_size;
587 : :
588 : 0 : test_vector->data.auth_offset = 0;
589 : 0 : test_vector->data.auth_length = opts->max_buffer_size;
590 : :
591 : 0 : return test_vector;
592 : : }
|