/kdns/dpdk-17.02/app/test-crypto-perf/cperf_test_vector_parsing.c

https://github.com/tiglabs/containerdns · C · 507 lines · 412 code · 77 blank · 18 comment · 187 complexity · b1828d81ba4d6a32eda22a35ed5a5b4d MD5 · raw file

  1. #ifdef RTE_EXEC_ENV_BSDAPP
  2. #define _WITH_GETLINE
  3. #endif
  4. #include <stdio.h>
  5. #include <rte_malloc.h>
  6. #include "cperf_options.h"
  7. #include "cperf_test_vectors.h"
  8. #include "cperf_test_vector_parsing.h"
  9. int
  10. free_test_vector(struct cperf_test_vector *vector, struct cperf_options *opts)
  11. {
  12. if (vector == NULL || opts == NULL)
  13. return -1;
  14. rte_free(vector->iv.data);
  15. rte_free(vector->aad.data);
  16. rte_free(vector->digest.data);
  17. if (opts->test_file != NULL) {
  18. rte_free(vector->plaintext.data);
  19. rte_free(vector->cipher_key.data);
  20. rte_free(vector->auth_key.data);
  21. rte_free(vector->ciphertext.data);
  22. }
  23. rte_free(vector);
  24. return 0;
  25. }
  26. void
  27. show_test_vector(struct cperf_test_vector *test_vector)
  28. {
  29. const uint8_t wrap = 32;
  30. uint32_t i;
  31. if (test_vector == NULL)
  32. return;
  33. if (test_vector->plaintext.data) {
  34. printf("\nplaintext =\n");
  35. for (i = 0; i < test_vector->plaintext.length; ++i) {
  36. if ((i % wrap == 0) && (i != 0))
  37. printf("\n");
  38. if (i == test_vector->plaintext.length - 1)
  39. printf("0x%02x",
  40. test_vector->plaintext.data[i]);
  41. else
  42. printf("0x%02x, ",
  43. test_vector->plaintext.data[i]);
  44. }
  45. printf("\n");
  46. }
  47. if (test_vector->cipher_key.data) {
  48. printf("\ncipher_key =\n");
  49. for (i = 0; i < test_vector->cipher_key.length; ++i) {
  50. if ((i % wrap == 0) && (i != 0))
  51. printf("\n");
  52. if (i == (uint32_t)(test_vector->cipher_key.length - 1))
  53. printf("0x%02x",
  54. test_vector->cipher_key.data[i]);
  55. else
  56. printf("0x%02x, ",
  57. test_vector->cipher_key.data[i]);
  58. }
  59. printf("\n");
  60. }
  61. if (test_vector->auth_key.data) {
  62. printf("\nauth_key =\n");
  63. for (i = 0; i < test_vector->auth_key.length; ++i) {
  64. if ((i % wrap == 0) && (i != 0))
  65. printf("\n");
  66. if (i == (uint32_t)(test_vector->auth_key.length - 1))
  67. printf("0x%02x", test_vector->auth_key.data[i]);
  68. else
  69. printf("0x%02x, ",
  70. test_vector->auth_key.data[i]);
  71. }
  72. printf("\n");
  73. }
  74. if (test_vector->iv.data) {
  75. printf("\niv =\n");
  76. for (i = 0; i < test_vector->iv.length; ++i) {
  77. if ((i % wrap == 0) && (i != 0))
  78. printf("\n");
  79. if (i == (uint32_t)(test_vector->iv.length - 1))
  80. printf("0x%02x", test_vector->iv.data[i]);
  81. else
  82. printf("0x%02x, ", test_vector->iv.data[i]);
  83. }
  84. printf("\n");
  85. }
  86. if (test_vector->ciphertext.data) {
  87. printf("\nciphertext =\n");
  88. for (i = 0; i < test_vector->ciphertext.length; ++i) {
  89. if ((i % wrap == 0) && (i != 0))
  90. printf("\n");
  91. if (i == test_vector->ciphertext.length - 1)
  92. printf("0x%02x",
  93. test_vector->ciphertext.data[i]);
  94. else
  95. printf("0x%02x, ",
  96. test_vector->ciphertext.data[i]);
  97. }
  98. printf("\n");
  99. }
  100. if (test_vector->aad.data) {
  101. printf("\naad =\n");
  102. for (i = 0; i < test_vector->aad.length; ++i) {
  103. if ((i % wrap == 0) && (i != 0))
  104. printf("\n");
  105. if (i == (uint32_t)(test_vector->aad.length - 1))
  106. printf("0x%02x", test_vector->aad.data[i]);
  107. else
  108. printf("0x%02x, ", test_vector->aad.data[i]);
  109. }
  110. printf("\n");
  111. }
  112. if (test_vector->digest.data) {
  113. printf("\ndigest =\n");
  114. for (i = 0; i < test_vector->digest.length; ++i) {
  115. if ((i % wrap == 0) && (i != 0))
  116. printf("\n");
  117. if (i == (uint32_t)(test_vector->digest.length - 1))
  118. printf("0x%02x", test_vector->digest.data[i]);
  119. else
  120. printf("0x%02x, ", test_vector->digest.data[i]);
  121. }
  122. printf("\n");
  123. }
  124. }
  125. /* trim leading and trailing spaces */
  126. static char *
  127. trim_space(char *str)
  128. {
  129. char *start, *end;
  130. for (start = str; *start; start++) {
  131. if (!isspace((unsigned char) start[0]))
  132. break;
  133. }
  134. for (end = start + strlen(start); end > start + 1; end--) {
  135. if (!isspace((unsigned char) end[-1]))
  136. break;
  137. }
  138. *end = 0;
  139. /* Shift from "start" to the beginning of the string */
  140. if (start > str)
  141. memmove(str, start, (end - start) + 1);
  142. return str;
  143. }
  144. /* tokenization test values separated by a comma */
  145. static int
  146. parse_values(char *tokens, uint8_t **data, uint32_t *data_length)
  147. {
  148. uint32_t n_tokens;
  149. uint32_t data_size = 32;
  150. uint8_t *values, *values_resized;
  151. char *tok, *error = NULL;
  152. tok = strtok(tokens, CPERF_VALUE_DELIMITER);
  153. if (tok == NULL)
  154. return -1;
  155. values = (uint8_t *) rte_zmalloc(NULL, sizeof(uint8_t) * data_size, 0);
  156. if (values == NULL)
  157. return -1;
  158. n_tokens = 0;
  159. while (tok != NULL) {
  160. values_resized = NULL;
  161. if (n_tokens >= data_size) {
  162. data_size *= 2;
  163. values_resized = (uint8_t *) rte_realloc(values,
  164. sizeof(uint8_t) * data_size, 0);
  165. if (values_resized == NULL) {
  166. rte_free(values);
  167. return -1;
  168. }
  169. values = values_resized;
  170. }
  171. values[n_tokens] = (uint8_t) strtoul(tok, &error, 0);
  172. if ((error == NULL) || (*error != '\0')) {
  173. printf("Failed with convert '%s'\n", tok);
  174. rte_free(values);
  175. return -1;
  176. }
  177. tok = strtok(NULL, CPERF_VALUE_DELIMITER);
  178. if (tok == NULL)
  179. break;
  180. n_tokens++;
  181. }
  182. values_resized = (uint8_t *) rte_realloc(values,
  183. sizeof(uint8_t) * (n_tokens + 1), 0);
  184. if (values_resized == NULL) {
  185. rte_free(values);
  186. return -1;
  187. }
  188. *data = values_resized;
  189. *data_length = n_tokens + 1;
  190. return 0;
  191. }
  192. /* checks the type of key and assigns data */
  193. static int
  194. parse_entry(char *entry, struct cperf_test_vector *vector,
  195. struct cperf_options *opts, uint8_t tc_found)
  196. {
  197. int status;
  198. uint32_t data_length;
  199. uint8_t *data = NULL;
  200. char *token, *key_token;
  201. if (entry == NULL) {
  202. printf("Expected entry value\n");
  203. return -1;
  204. }
  205. /* get key */
  206. token = strtok(entry, CPERF_ENTRY_DELIMITER);
  207. key_token = token;
  208. /* get values for key */
  209. token = strtok(NULL, CPERF_ENTRY_DELIMITER);
  210. if (key_token == NULL || token == NULL) {
  211. printf("Expected 'key = values' but was '%.40s'..\n", entry);
  212. return -1;
  213. }
  214. status = parse_values(token, &data, &data_length);
  215. if (status)
  216. return -1;
  217. /* compare keys */
  218. if (strstr(key_token, "plaintext")) {
  219. rte_free(vector->plaintext.data);
  220. vector->plaintext.data = data;
  221. if (tc_found)
  222. vector->plaintext.length = data_length;
  223. else {
  224. if (opts->buffer_sz > data_length) {
  225. printf("Global plaintext shorter than "
  226. "buffer_sz\n");
  227. return -1;
  228. }
  229. vector->plaintext.length = opts->buffer_sz;
  230. }
  231. } else if (strstr(key_token, "cipher_key")) {
  232. rte_free(vector->cipher_key.data);
  233. vector->cipher_key.data = data;
  234. if (tc_found)
  235. vector->cipher_key.length = data_length;
  236. else {
  237. if (opts->cipher_key_sz > data_length) {
  238. printf("Global cipher_key shorter than "
  239. "cipher_key_sz\n");
  240. return -1;
  241. }
  242. vector->cipher_key.length = opts->cipher_key_sz;
  243. }
  244. } else if (strstr(key_token, "auth_key")) {
  245. rte_free(vector->auth_key.data);
  246. vector->auth_key.data = data;
  247. if (tc_found)
  248. vector->auth_key.length = data_length;
  249. else {
  250. if (opts->auth_key_sz > data_length) {
  251. printf("Global auth_key shorter than "
  252. "auth_key_sz\n");
  253. return -1;
  254. }
  255. vector->auth_key.length = opts->auth_key_sz;
  256. }
  257. } else if (strstr(key_token, "iv")) {
  258. rte_free(vector->iv.data);
  259. vector->iv.data = data;
  260. vector->iv.phys_addr = rte_malloc_virt2phy(vector->iv.data);
  261. if (tc_found)
  262. vector->iv.length = data_length;
  263. else {
  264. if (opts->cipher_iv_sz > data_length) {
  265. printf("Global iv shorter than "
  266. "cipher_iv_sz\n");
  267. return -1;
  268. }
  269. vector->iv.length = opts->cipher_iv_sz;
  270. }
  271. } else if (strstr(key_token, "ciphertext")) {
  272. rte_free(vector->ciphertext.data);
  273. vector->ciphertext.data = data;
  274. if (tc_found)
  275. vector->ciphertext.length = data_length;
  276. else {
  277. if (opts->buffer_sz > data_length) {
  278. printf("Global ciphertext shorter than "
  279. "buffer_sz\n");
  280. return -1;
  281. }
  282. vector->ciphertext.length = opts->buffer_sz;
  283. }
  284. } else if (strstr(key_token, "aad")) {
  285. rte_free(vector->aad.data);
  286. vector->aad.data = data;
  287. vector->aad.phys_addr = rte_malloc_virt2phy(vector->aad.data);
  288. if (tc_found)
  289. vector->aad.length = data_length;
  290. else {
  291. if (opts->auth_aad_sz > data_length) {
  292. printf("Global aad shorter than "
  293. "auth_aad_sz\n");
  294. return -1;
  295. }
  296. vector->aad.length = opts->auth_aad_sz;
  297. }
  298. } else if (strstr(key_token, "digest")) {
  299. rte_free(vector->digest.data);
  300. vector->digest.data = data;
  301. vector->digest.phys_addr = rte_malloc_virt2phy(
  302. vector->digest.data);
  303. if (tc_found)
  304. vector->digest.length = data_length;
  305. else {
  306. if (opts->auth_digest_sz > data_length) {
  307. printf("Global digest shorter than "
  308. "auth_digest_sz\n");
  309. return -1;
  310. }
  311. vector->digest.length = opts->auth_digest_sz;
  312. }
  313. } else {
  314. printf("Not valid key: '%s'\n", trim_space(key_token));
  315. return -1;
  316. }
  317. return 0;
  318. }
  319. /* searches in the file for test keys and values */
  320. static int
  321. parse_file(struct cperf_test_vector *vector, struct cperf_options *opts)
  322. {
  323. uint8_t tc_found = 0;
  324. uint8_t tc_data_start = 0;
  325. ssize_t read;
  326. size_t len = 0;
  327. int status = 0;
  328. FILE *fp;
  329. char *line = NULL;
  330. char *entry = NULL;
  331. fp = fopen(opts->test_file, "r");
  332. if (fp == NULL) {
  333. printf("File %s does not exists\n", opts->test_file);
  334. return -1;
  335. }
  336. while ((read = getline(&line, &len, fp)) != -1) {
  337. /* ignore comments and new lines */
  338. if (line[0] == '#' || line[0] == '/' || line[0] == '\n'
  339. || line[0] == '\r' || line[0] == ' ')
  340. continue;
  341. trim_space(line);
  342. /* next test case is started */
  343. if (line[0] == '[' && line[strlen(line) - 1] == ']' && tc_found)
  344. break;
  345. /* test case section started, end of global data */
  346. else if (line[0] == '[' && line[strlen(line) - 1] == ']')
  347. tc_data_start = 1;
  348. /* test name unspecified, end after global data */
  349. if (tc_data_start && opts->test_name == NULL)
  350. break;
  351. /* searching for a suitable test */
  352. else if (tc_data_start && tc_found == 0) {
  353. if (!strcmp(line, opts->test_name)) {
  354. tc_found = 1;
  355. continue;
  356. } else
  357. continue;
  358. }
  359. /* buffer for multiline */
  360. entry = (char *) rte_realloc(entry,
  361. sizeof(char) * strlen(line) + 1, 0);
  362. if (entry == NULL)
  363. return -1;
  364. memset(entry, 0, strlen(line) + 1);
  365. strncpy(entry, line, strlen(line));
  366. /* check if entry ends with , or = */
  367. if (entry[strlen(entry) - 1] == ','
  368. || entry[strlen(entry) - 1] == '=') {
  369. while ((read = getline(&line, &len, fp)) != -1) {
  370. trim_space(line);
  371. /* extend entry about length of new line */
  372. char *entry_extended = (char *) rte_realloc(
  373. entry, sizeof(char)
  374. * (strlen(line) + strlen(entry))
  375. + 1, 0);
  376. if (entry_extended == NULL)
  377. goto err;
  378. entry = entry_extended;
  379. strncat(entry, line, strlen(line));
  380. if (entry[strlen(entry) - 1] != ',')
  381. break;
  382. }
  383. }
  384. status = parse_entry(entry, vector, opts, tc_found);
  385. if (status) {
  386. printf("An error occurred while parsing!\n");
  387. goto err;
  388. }
  389. }
  390. if (tc_found == 0 && opts->test_name != NULL) {
  391. printf("Not found '%s' case in test file\n", opts->test_name);
  392. goto err;
  393. }
  394. fclose(fp);
  395. free(line);
  396. rte_free(entry);
  397. return 0;
  398. err:
  399. if (fp)
  400. fclose(fp);
  401. if (line)
  402. free(line);
  403. if (entry)
  404. rte_free(entry);
  405. return -1;
  406. }
  407. struct cperf_test_vector*
  408. cperf_test_vector_get_from_file(struct cperf_options *opts)
  409. {
  410. int status;
  411. struct cperf_test_vector *test_vector = NULL;
  412. if (opts == NULL || opts->test_file == NULL)
  413. return test_vector;
  414. test_vector = (struct cperf_test_vector *) rte_zmalloc(NULL,
  415. sizeof(struct cperf_test_vector), 0);
  416. if (test_vector == NULL)
  417. return test_vector;
  418. /* filling the vector with data from a file */
  419. status = parse_file(test_vector, opts);
  420. if (status) {
  421. free_test_vector(test_vector, opts);
  422. return NULL;
  423. }
  424. /* other values not included in the file */
  425. test_vector->data.cipher_offset = 0;
  426. test_vector->data.cipher_length = opts->buffer_sz;
  427. test_vector->data.auth_offset = 0;
  428. test_vector->data.auth_length = opts->buffer_sz;
  429. return test_vector;
  430. }