4 * Copyright(c) 2016-2017 Intel Corporation. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
16 * * Neither the name of Intel Corporation nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #ifdef RTE_EXEC_ENV_BSDAPP
37 #include <rte_malloc.h>
39 #include "cperf_options.h"
40 #include "cperf_test_vectors.h"
41 #include "cperf_test_vector_parsing.h"
44 free_test_vector(struct cperf_test_vector *vector, struct cperf_options *opts)
46 if (vector == NULL || opts == NULL)
49 rte_free(vector->cipher_iv.data);
50 rte_free(vector->auth_iv.data);
51 rte_free(vector->aad.data);
52 rte_free(vector->digest.data);
54 if (opts->test_file != NULL) {
55 rte_free(vector->plaintext.data);
56 rte_free(vector->cipher_key.data);
57 rte_free(vector->auth_key.data);
58 rte_free(vector->ciphertext.data);
67 show_test_vector(struct cperf_test_vector *test_vector)
69 const uint8_t wrap = 32;
72 if (test_vector == NULL)
75 if (test_vector->plaintext.data) {
76 printf("\nplaintext =\n");
77 for (i = 0; i < test_vector->plaintext.length; ++i) {
78 if ((i % wrap == 0) && (i != 0))
80 if (i == test_vector->plaintext.length - 1)
82 test_vector->plaintext.data[i]);
85 test_vector->plaintext.data[i]);
90 if (test_vector->cipher_key.data) {
91 printf("\ncipher_key =\n");
92 for (i = 0; i < test_vector->cipher_key.length; ++i) {
93 if ((i % wrap == 0) && (i != 0))
95 if (i == (uint32_t)(test_vector->cipher_key.length - 1))
97 test_vector->cipher_key.data[i]);
100 test_vector->cipher_key.data[i]);
105 if (test_vector->auth_key.data) {
106 printf("\nauth_key =\n");
107 for (i = 0; i < test_vector->auth_key.length; ++i) {
108 if ((i % wrap == 0) && (i != 0))
110 if (i == (uint32_t)(test_vector->auth_key.length - 1))
111 printf("0x%02x", test_vector->auth_key.data[i]);
114 test_vector->auth_key.data[i]);
119 if (test_vector->cipher_iv.data) {
120 printf("\ncipher_iv =\n");
121 for (i = 0; i < test_vector->cipher_iv.length; ++i) {
122 if ((i % wrap == 0) && (i != 0))
124 if (i == (uint32_t)(test_vector->cipher_iv.length - 1))
125 printf("0x%02x", test_vector->cipher_iv.data[i]);
127 printf("0x%02x, ", test_vector->cipher_iv.data[i]);
132 if (test_vector->auth_iv.data) {
133 printf("\nauth_iv =\n");
134 for (i = 0; i < test_vector->auth_iv.length; ++i) {
135 if ((i % wrap == 0) && (i != 0))
137 if (i == (uint32_t)(test_vector->auth_iv.length - 1))
138 printf("0x%02x", test_vector->auth_iv.data[i]);
140 printf("0x%02x, ", test_vector->auth_iv.data[i]);
145 if (test_vector->ciphertext.data) {
146 printf("\nciphertext =\n");
147 for (i = 0; i < test_vector->ciphertext.length; ++i) {
148 if ((i % wrap == 0) && (i != 0))
150 if (i == test_vector->ciphertext.length - 1)
152 test_vector->ciphertext.data[i]);
155 test_vector->ciphertext.data[i]);
160 if (test_vector->aad.data) {
162 for (i = 0; i < test_vector->aad.length; ++i) {
163 if ((i % wrap == 0) && (i != 0))
165 if (i == (uint32_t)(test_vector->aad.length - 1))
166 printf("0x%02x", test_vector->aad.data[i]);
168 printf("0x%02x, ", test_vector->aad.data[i]);
173 if (test_vector->digest.data) {
174 printf("\ndigest =\n");
175 for (i = 0; i < test_vector->digest.length; ++i) {
176 if ((i % wrap == 0) && (i != 0))
178 if (i == (uint32_t)(test_vector->digest.length - 1))
179 printf("0x%02x", test_vector->digest.data[i]);
181 printf("0x%02x, ", test_vector->digest.data[i]);
187 /* trim leading and trailing spaces */
189 trim_space(char *str)
193 for (start = str; *start; start++) {
194 if (!isspace((unsigned char) start[0]))
198 for (end = start + strlen(start); end > start + 1; end--) {
199 if (!isspace((unsigned char) end[-1]))
205 /* Shift from "start" to the beginning of the string */
207 memmove(str, start, (end - start) + 1);
212 /* tokenization test values separated by a comma */
214 parse_values(char *tokens, uint8_t **data, uint32_t *data_length)
217 uint32_t data_size = 32;
219 uint8_t *values, *values_resized;
220 char *tok, *error = NULL;
222 tok = strtok(tokens, CPERF_VALUE_DELIMITER);
226 values = (uint8_t *) rte_zmalloc(NULL, sizeof(uint8_t) * data_size, 0);
231 while (tok != NULL) {
232 values_resized = NULL;
234 if (n_tokens >= data_size) {
237 values_resized = (uint8_t *) rte_realloc(values,
238 sizeof(uint8_t) * data_size, 0);
239 if (values_resized == NULL) {
243 values = values_resized;
246 values[n_tokens] = (uint8_t) strtoul(tok, &error, 0);
247 if ((error == NULL) || (*error != '\0')) {
248 printf("Failed with convert '%s'\n", tok);
253 tok = strtok(NULL, CPERF_VALUE_DELIMITER);
260 values_resized = (uint8_t *) rte_realloc(values,
261 sizeof(uint8_t) * (n_tokens + 1), 0);
263 if (values_resized == NULL) {
268 *data = values_resized;
269 *data_length = n_tokens + 1;
274 /* checks the type of key and assigns data */
276 parse_entry(char *entry, struct cperf_test_vector *vector,
277 struct cperf_options *opts, uint8_t tc_found)
280 uint32_t data_length;
282 uint8_t *data = NULL;
283 char *token, *key_token;
286 printf("Expected entry value\n");
291 token = strtok(entry, CPERF_ENTRY_DELIMITER);
293 /* get values for key */
294 token = strtok(NULL, CPERF_ENTRY_DELIMITER);
296 if (key_token == NULL || token == NULL) {
297 printf("Expected 'key = values' but was '%.40s'..\n", entry);
301 status = parse_values(token, &data, &data_length);
306 if (strstr(key_token, "plaintext")) {
307 rte_free(vector->plaintext.data);
308 vector->plaintext.data = data;
310 vector->plaintext.length = data_length;
312 if (opts->max_buffer_size > data_length) {
313 printf("Global plaintext shorter than "
317 vector->plaintext.length = opts->max_buffer_size;
320 } else if (strstr(key_token, "cipher_key")) {
321 rte_free(vector->cipher_key.data);
322 vector->cipher_key.data = data;
324 vector->cipher_key.length = data_length;
326 if (opts->cipher_key_sz > data_length) {
327 printf("Global cipher_key shorter than "
331 vector->cipher_key.length = opts->cipher_key_sz;
334 } else if (strstr(key_token, "auth_key")) {
335 rte_free(vector->auth_key.data);
336 vector->auth_key.data = data;
338 vector->auth_key.length = data_length;
340 if (opts->auth_key_sz > data_length) {
341 printf("Global auth_key shorter than "
345 vector->auth_key.length = opts->auth_key_sz;
348 } else if (strstr(key_token, "cipher_iv")) {
349 rte_free(vector->cipher_iv.data);
350 vector->cipher_iv.data = data;
352 vector->cipher_iv.length = data_length;
354 if (opts->cipher_iv_sz > data_length) {
355 printf("Global cipher iv shorter than "
359 vector->cipher_iv.length = opts->cipher_iv_sz;
362 } else if (strstr(key_token, "auth_iv")) {
363 rte_free(vector->auth_iv.data);
364 vector->auth_iv.data = data;
366 vector->auth_iv.length = data_length;
368 if (opts->auth_iv_sz > data_length) {
369 printf("Global auth iv shorter than "
373 vector->auth_iv.length = opts->auth_iv_sz;
376 } else if (strstr(key_token, "ciphertext")) {
377 rte_free(vector->ciphertext.data);
378 vector->ciphertext.data = data;
380 vector->ciphertext.length = data_length;
382 if (opts->max_buffer_size > data_length) {
383 printf("Global ciphertext shorter than "
387 vector->ciphertext.length = opts->max_buffer_size;
390 } else if (strstr(key_token, "aad")) {
391 rte_free(vector->aad.data);
392 vector->aad.data = data;
393 vector->aad.phys_addr = rte_malloc_virt2phy(vector->aad.data);
395 vector->aad.length = data_length;
397 if (opts->aead_aad_sz > data_length) {
398 printf("Global aad shorter than "
402 vector->aad.length = opts->aead_aad_sz;
405 } else if (strstr(key_token, "digest")) {
406 rte_free(vector->digest.data);
407 vector->digest.data = data;
408 vector->digest.phys_addr = rte_malloc_virt2phy(
409 vector->digest.data);
411 vector->digest.length = data_length;
413 if (opts->digest_sz > data_length) {
414 printf("Global digest shorter than "
418 vector->digest.length = opts->digest_sz;
421 printf("Not valid key: '%s'\n", trim_space(key_token));
428 /* searches in the file for test keys and values */
430 parse_file(struct cperf_test_vector *vector, struct cperf_options *opts)
432 uint8_t tc_found = 0;
433 uint8_t tc_data_start = 0;
442 fp = fopen(opts->test_file, "r");
444 printf("File %s does not exists\n", opts->test_file);
448 while ((read = getline(&line, &len, fp)) != -1) {
450 /* ignore comments and new lines */
451 if (line[0] == '#' || line[0] == '/' || line[0] == '\n'
452 || line[0] == '\r' || line[0] == ' ')
457 /* next test case is started */
458 if (line[0] == '[' && line[strlen(line) - 1] == ']' && tc_found)
460 /* test case section started, end of global data */
461 else if (line[0] == '[' && line[strlen(line) - 1] == ']')
464 /* test name unspecified, end after global data */
465 if (tc_data_start && opts->test_name == NULL)
467 /* searching for a suitable test */
468 else if (tc_data_start && tc_found == 0) {
469 if (!strcmp(line, opts->test_name)) {
476 /* buffer for multiline */
477 entry = (char *) rte_realloc(entry,
478 sizeof(char) * strlen(line) + 1, 0);
482 memset(entry, 0, strlen(line) + 1);
483 strncpy(entry, line, strlen(line));
485 /* check if entry ends with , or = */
486 if (entry[strlen(entry) - 1] == ','
487 || entry[strlen(entry) - 1] == '=') {
488 while ((read = getline(&line, &len, fp)) != -1) {
491 /* extend entry about length of new line */
492 char *entry_extended = (char *) rte_realloc(
494 * (strlen(line) + strlen(entry))
497 if (entry_extended == NULL)
499 entry = entry_extended;
501 strncat(entry, line, strlen(line));
503 if (entry[strlen(entry) - 1] != ',')
507 status = parse_entry(entry, vector, opts, tc_found);
509 printf("An error occurred while parsing!\n");
514 if (tc_found == 0 && opts->test_name != NULL) {
515 printf("Not found '%s' case in test file\n", opts->test_name);
536 struct cperf_test_vector*
537 cperf_test_vector_get_from_file(struct cperf_options *opts)
540 struct cperf_test_vector *test_vector = NULL;
542 if (opts == NULL || opts->test_file == NULL)
545 test_vector = (struct cperf_test_vector *) rte_zmalloc(NULL,
546 sizeof(struct cperf_test_vector), 0);
547 if (test_vector == NULL)
550 /* filling the vector with data from a file */
551 status = parse_file(test_vector, opts);
553 free_test_vector(test_vector, opts);
557 /* other values not included in the file */
558 test_vector->data.cipher_offset = 0;
559 test_vector->data.cipher_length = opts->max_buffer_size;
561 test_vector->data.auth_offset = 0;
562 test_vector->data.auth_length = opts->max_buffer_size;