Added parser to parser required request file which has
different algos required by the fips certification
and to generate the response file needed.

Signed-off-by: Marko Kovacevic <marko.kovace...@intel.com>
---
 test/test/Makefile                           |   3 +
 test/test/test_cryptodev_fips_parse.h        | 156 +++++++++++
 test/test/test_cryptodev_fips_parse_aes.c    | 399 +++++++++++++++++++++++++++
 test/test/test_cryptodev_fips_parse_common.c | 330 ++++++++++++++++++++++
 4 files changed, 888 insertions(+)
 create mode 100644 test/test/test_cryptodev_fips_parse.h
 create mode 100644 test/test/test_cryptodev_fips_parse_aes.c
 create mode 100644 test/test/test_cryptodev_fips_parse_common.c

diff --git a/test/test/Makefile b/test/test/Makefile
index ee74450..9d6abb5 100644
--- a/test/test/Makefile
+++ b/test/test/Makefile
@@ -183,6 +183,9 @@ SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += 
test_cryptodev_blockcipher.c
 SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev.c
 SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_asym.c
 SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_fips.c
+SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_fips_parse_common.c
+SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_fips_parse_aes.c
+
 
 ifeq ($(CONFIG_RTE_COMPRESSDEV_TEST),y)
 SRCS-$(CONFIG_RTE_LIBRTE_COMPRESSDEV) += test_compressdev.c
diff --git a/test/test/test_cryptodev_fips_parse.h 
b/test/test/test_cryptodev_fips_parse.h
new file mode 100644
index 0000000..edb1d41
--- /dev/null
+++ b/test/test/test_cryptodev_fips_parse.h
@@ -0,0 +1,156 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+#ifndef _TEST_CRYPTODEV_FIPS_PARSE_
+#define _TEST_CRYPTODEV_FIPS_PARSE_
+
+#include <rte_cryptodev.h>
+
+#define FIPS_PARSE_ERR(line, fmt, args...)                             \
+       RTE_LOG(ERR, USER1, "[%s] %s() line %u: Error in file line %u " \
+               fmt "\n", "FIPS", __func__, __LINE__, line, ## args)
+
+#define ERR_MSG_SIZE   128
+#define MAX_CASE_LINE  15
+#define MAX_NB_CHAR    1024 /*< maximum number of characters per line */
+#define MAX_NB_TESTS   10240
+#define MAX_BUF_SIZE   2048 /*< maximum plain/cipher text size */
+#define MAX_KEY_LEN    64
+#define MAX_IV_LEN     256
+
+#define POSITIVE_TEST  0
+#define NEGATIVE_TEST  -1
+
+#define REQ_FILE_PERFIX        "req"
+#define RSP_FILE_PERFIX        "rsp"
+#define FAX_FILE_PERFIX        "fax"
+
+#define HEADER_IND     "#"
+#define GEN_TIME_STR   "# Generated on "
+
+enum file_types {
+       FIPS_FILE_TYPE_REQ = 1,
+       FIPS_FILE_TYPE_FAX,
+       FIPS_FILE_TYPE_RSP
+};
+
+struct fips_aes_test_case {
+       char case_desc[MAX_CASE_LINE][MAX_NB_CHAR];
+#define AESAVS_OP_ENC          1
+#define AESAVS_OP_DEC          2
+       enum rte_crypto_cipher_operation test_op;
+       uint8_t key[MAX_KEY_LEN];
+       uint8_t iv[MAX_IV_LEN];
+       uint32_t iv_len;
+       uint8_t plaintext[MAX_BUF_SIZE];
+       uint32_t plaintext_len;
+       uint8_t ciphertext[MAX_BUF_SIZE];
+       uint32_t ciphertext_len;
+       uint32_t count;
+       uint32_t skip_flag;
+};
+
+/* AES TEST DATA */
+struct fips_aes_test_data {
+       enum file_types f_type;
+       char file_header[MAX_CASE_LINE][MAX_NB_CHAR];
+
+/* follow the sequence as test_type_strings declared above */
+#define AESAVS_TYPE_GFXBOX     0
+#define AESAVS_TYPE_KEYSBOX    1
+#define AESAVS_TYPE_VARKEY     2
+#define AESAVS_TYPE_VARTXT     3
+#define AESAVS_TYPE_MMT                4
+#define AESAVS_TYPE_MCT                5
+       uint32_t test_type;
+
+       /* *_algo == 0 means no algo */
+       enum rte_crypto_cipher_algorithm cipher_algo;
+       enum rte_crypto_auth_algorithm auth_algo;
+
+       uint32_t key_len;
+
+       uint32_t nb_test_cases;
+
+       struct fips_aes_test_case test_cases[MAX_NB_TESTS];
+};
+
+/**
+ * INTERNAL APIS, used for other parsers
+ */
+int
+fips_get_file_line(FILE **fp, char *line,  uint32_t max_line_char);
+
+int
+parser_read_uint64(uint64_t *value, const char *p);
+
+int
+parser_read_uint64_hex(uint64_t *value, const char *p);
+
+int
+parser_read_uint32(uint32_t *value, const char *p);
+
+int
+parser_read_uint32_hex(uint32_t *value, const char *p);
+
+int
+parser_read_uint16(uint16_t *value, const char *p);
+
+int
+parser_read_uint16_hex(uint16_t *value, const char *p);
+
+int
+parser_read_uint8(uint8_t *value, const char *p);
+
+int
+parser_read_uint8_hex(uint8_t *value, const char *p);
+
+int
+parse_uint8_hex_str(uint8_t *dst, char *src, uint32_t max_len);
+
+enum file_types
+parse_file_type(const char *path);
+
+int
+fetch_block(FILE **fp, char *line[MAX_CASE_LINE], uint32_t from_line,
+               const char *trigger, uint32_t max_nb_line_char);
+
+void
+copy_block(char dst[][MAX_NB_CHAR], char *src[MAX_CASE_LINE],
+               uint32_t nb_lines, uint32_t max_nb_line_char);
+
+void
+write_block_to_file(FILE *fp, char from[][MAX_NB_CHAR]);
+
+void
+write_uint8_str_to_file(FILE *fp, const uint8_t *from, uint32_t size);
+
+int
+alloc_line_block_mem(char *block[MAX_CASE_LINE], uint32_t max_nb_line_char);
+
+void
+free_line_block_mem(char *block[MAX_CASE_LINE]);
+
+static inline void
+MEMSET_BLOCK(char *line[], uint32_t line_len)
+{
+       uint32_t i;
+
+       for (i = 0; i < MAX_CASE_LINE; i++)
+               memset(line[i], 0, line_len);
+}
+
+
+/**
+ * API to parse one AES FIPS test vector file into struct FIPS_aes_test_data
+ * No init is necessary, this function will memset it for you
+ * No fopen/fclose necessary
+ */
+int
+parse_aes_vectors(struct fips_aes_test_data *aes_test_data, const char *path);
+
+int
+write_aes_vectors(struct fips_aes_test_data *test_data,
+               const char *path_write, const char *device_name);
+
+#endif
diff --git a/test/test/test_cryptodev_fips_parse_aes.c 
b/test/test/test_cryptodev_fips_parse_aes.c
new file mode 100644
index 0000000..552a493
--- /dev/null
+++ b/test/test/test_cryptodev_fips_parse_aes.c
@@ -0,0 +1,399 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <string.h>
+#include <time.h>
+
+#include "test_cryptodev_fips_parse.h"
+
+#define MODE_STR       "AESVS"
+#define ALGO_STR       "test data for "
+#define OP_STR         "State"
+#define KEY_SIZE_STR   "Key Length : "
+#define DEVICE_STR     "# Config info for "
+
+#define COUNT_STR      "COUNT = "
+#define KEY_STR                "KEY = "
+#define IV_STR         "IV = "
+#define PT_STR         "PLAINTEXT = "
+#define CT_STR         "CIPHERTEXT = "
+
+#define OP_ENC_STR     "ENCRYPT"
+#define OP_DEC_STR     "DECRYPT"
+
+#define SKIP_OUTPUT    "FAIL(Not supported)"
+
+const char *aes_test_type_strings[] = {
+               "GFSbox",
+               "KeySbox",
+               "VarKey",
+               "VarTxt",
+               "MMT",
+               "MCT"
+};
+
+struct aes_test_algo_conv {
+       const char *name;
+       enum rte_crypto_cipher_algorithm algo;
+} const algo_convs[] = {
+               {"CBC", RTE_CRYPTO_CIPHER_AES_CBC},
+};
+
+static int
+parse_one_case(struct fips_aes_test_data *test_data, char *lines[],
+               uint32_t nb_lines, enum rte_crypto_cipher_operation op,
+               uint32_t from_line)
+{
+       struct fips_aes_test_case *test_case;
+       uint32_t i;
+       char *tmp;
+       int ret;
+
+       if (test_data->nb_test_cases >= MAX_NB_TESTS)
+               return -ENOMEM;
+
+       test_case = &test_data->test_cases[test_data->nb_test_cases];
+       test_case->test_op = op;
+
+       for (i = 0; i < nb_lines; i++) {
+               char *line = lines[i];
+
+               tmp = strstr(line, COUNT_STR);
+               if (tmp) {
+                       uint32_t count;
+
+                       tmp += strlen(COUNT_STR);
+                       if (parser_read_uint32(&count, tmp) < 0) {
+                               ret = -EINVAL;
+                               goto error_exit;
+                       }
+
+                       test_case->count = count;
+                       continue;
+               }
+
+               /* key */
+               tmp = strstr(line, KEY_STR);
+               if (tmp) {
+                       tmp += strlen(KEY_STR);
+                       ret = parse_uint8_hex_str(test_case->key, tmp, 
MAX_KEY_LEN);
+                       if (ret < 0)
+                               goto error_exit;
+                       continue;
+               }
+
+               /* iv */
+               tmp = strstr(line, IV_STR);
+               if (tmp) {
+                       tmp += strlen(IV_STR);
+
+                       ret = parse_uint8_hex_str(test_case->iv, tmp, 
MAX_IV_LEN);
+                       if (ret < 0)
+                               goto error_exit;
+
+                       test_case->iv_len = ret;
+                       continue;
+               }
+
+               /* plaintext */
+               tmp = strstr(line, PT_STR);
+               if (tmp) {
+                       tmp += strlen(PT_STR);
+
+                       ret = parse_uint8_hex_str(test_case->plaintext, tmp,
+                                       MAX_BUF_SIZE);
+                       if (ret < 0)
+                               goto error_exit;
+
+                       test_case->plaintext_len = ret;
+                       continue;
+               }
+
+               /* ciphertext */
+               tmp = strstr(line, CT_STR);
+               if (tmp) {
+                       tmp += strlen(CT_STR);
+
+                       ret = parse_uint8_hex_str(test_case->ciphertext, tmp,
+                                       MAX_BUF_SIZE);
+                       if (ret < 0)
+                               goto error_exit;
+
+                       test_case->ciphertext_len = ret;
+                       continue;
+               }
+       }
+
+       copy_block(test_case->case_desc, lines, nb_lines, MAX_NB_CHAR);
+       test_data->nb_test_cases++;
+       return 0;
+
+error_exit:
+       FIPS_PARSE_ERR(from_line + i, "Error code %i", ret);
+       memset(test_case, 0, sizeof(*test_case));
+       return ret;
+}
+
+static int
+parse_header(struct fips_aes_test_data *test_data, char *lines[],
+               uint32_t nb_lines)
+{
+       char *tmp;
+       uint32_t i, j;
+
+       for (i = 0; i < nb_lines; i++) {
+               char *line = lines[i];
+
+               tmp = strstr(line, MODE_STR);
+               if (tmp) {
+                       for (j = 0; j < RTE_DIM(aes_test_type_strings); j++)
+                               if (strstr(line, aes_test_type_strings[j])
+                                               != NULL) {
+                                       test_data->test_type = j;
+                                       break;
+                               }
+                       if (j >= RTE_DIM(aes_test_type_strings))
+                               return -EINVAL;
+
+                       tmp = strstr(line, ALGO_STR);
+                       if (!tmp)
+                               return -EINVAL;
+
+                       tmp += strlen(ALGO_STR);
+                       for (j = 0; j < RTE_DIM(algo_convs); j++)
+                               if (strcmp(algo_convs[j].name, tmp) == 0) {
+                                       test_data->cipher_algo =
+                                                       algo_convs[j].algo;
+                                       break;
+                               }
+                       if (j >= RTE_DIM(algo_convs))
+                               return -EINVAL;
+
+                       continue;
+               }
+
+               /* State : <op> {and <op>} Encrypt and Decrypt, we don't care*/
+               tmp = strstr(line, OP_STR);
+               if (tmp)
+                       continue;
+
+               /* Key Length : 128 */
+               tmp = strstr(line, KEY_SIZE_STR);
+               if (tmp) {
+                       tmp += strlen(KEY_SIZE_STR);
+                       if (parser_read_uint32(&test_data->key_len, tmp) < 0)
+                               return -EINVAL;
+
+                       test_data->key_len /= 8;
+                       if (test_data->key_len > MAX_KEY_LEN)
+                               return -EINVAL;
+
+                       continue;
+               }
+       }
+
+       return 0;
+}
+
+int
+parse_aes_vectors(struct fips_aes_test_data *test_data, const char *path)
+{
+       FILE *fp;
+       char *line[MAX_CASE_LINE];
+       uint32_t line_idx = 0;
+       enum rte_crypto_cipher_operation op = RTE_CRYPTO_CIPHER_OP_ENCRYPT;
+       int ret = 0, file_ret = 0;
+       char *tmp;
+
+       fp = fopen(path, "r");
+       if (fp == NULL) {
+               FIPS_PARSE_ERR(0, "Cannot open file %s", path);
+               return -EINVAL;
+       }
+
+       if ((ret = alloc_line_block_mem(line, MAX_NB_CHAR)) < 0)
+               goto error_exit;
+
+       memset(test_data, 0, sizeof(*test_data));
+
+       test_data->f_type = parse_file_type(path);
+       if (test_data->f_type == 0) {
+               FIPS_PARSE_ERR(0, "Cannot get file type %s", path);
+               goto error_exit;
+       }
+
+       while (file_ret != -EOF) {
+               line_idx++;
+
+               file_ret = fips_get_file_line(&fp, line[0], MAX_NB_CHAR);
+               if (file_ret < 0) {
+                       FIPS_PARSE_ERR(line_idx, "Error code %i", ret);
+                       ret = file_ret;
+                       goto error_exit;
+               }
+
+               ret = fetch_block(&fp, line, line_idx, HEADER_IND, MAX_NB_CHAR);
+               if (ret <= 0) {
+                       ret = -EINVAL;
+                       goto error_exit;
+               }
+
+               copy_block(test_data->file_header, line, ret, MAX_NB_CHAR);
+
+               ret = parse_header(test_data, line, ret);
+               if (ret < 0)
+                       goto error_exit;
+               break;
+       }
+
+       MEMSET_BLOCK(line, MAX_NB_CHAR);
+
+       while (file_ret != -EOF) {
+               line_idx++;
+
+               file_ret = fips_get_file_line(&fp, line[0], MAX_NB_CHAR);
+               if (file_ret < 0) {
+                       FIPS_PARSE_ERR(line_idx, "Error code %i", ret);
+                       ret = file_ret;
+                       goto error_exit;
+               }
+
+               if (strlen(line[0]) == 0)
+                       continue;
+
+               tmp = strstr(line[0], OP_ENC_STR);
+               if (tmp) {
+                       op = RTE_CRYPTO_CIPHER_OP_ENCRYPT;
+                       continue;
+               }
+
+               tmp = strstr(line[0], OP_DEC_STR);
+               if (tmp) {
+                       op = RTE_CRYPTO_CIPHER_OP_DECRYPT;
+                       continue;
+               }
+
+               ret = fetch_block(&fp, line, line_idx, COUNT_STR, MAX_NB_CHAR);
+               if (ret > 0) {
+                       uint32_t start_line = line_idx;
+
+                       line_idx += ret;
+                       ret = parse_one_case(test_data, line, ret, op,
+                                       start_line);
+
+                       MEMSET_BLOCK(line, MAX_NB_CHAR);
+               }
+               if (ret < 0)
+                       goto error_exit;
+
+       }
+
+       free_line_block_mem(line);
+       if (fp)
+               fclose(fp);
+
+       return 0;
+error_exit:
+       free_line_block_mem(line);
+       if (fp)
+               fclose(fp);
+       return ret;
+}
+
+int
+write_aes_vectors(struct fips_aes_test_data *test_data,
+               const char *path_write, const char *device_name)
+{
+       FILE *fp;
+       uint32_t i;
+       enum rte_crypto_cipher_operation op = 0xf;
+       time_t t = time(NULL);
+       struct tm *tm_now = localtime(&t);
+
+       if (test_data->f_type != FIPS_FILE_TYPE_REQ) {
+               FIPS_PARSE_ERR(0, "Write only works for REQ test vectors");
+               return 0;
+       }
+
+       fp = fopen(path_write, "w");
+       if (fp == NULL) {
+               FIPS_PARSE_ERR(0, "Cannot open file %s", path_write);
+               return -EINVAL;
+       }
+
+       /* write back header */
+       for (i = 0; i < MAX_CASE_LINE; i++) {
+               char *line = test_data->file_header[i];
+
+               if (strlen(line) == 0)
+                       break;
+
+               if (strstr(line, DEVICE_STR)) {
+                       fprintf(fp, "%s%s\n", DEVICE_STR, device_name);
+                       continue;
+               }
+
+               if (strstr(line, GEN_TIME_STR)) {
+                       fprintf(fp, "%s%s\n", GEN_TIME_STR, asctime(tm_now));
+                       continue;
+               }
+
+               fprintf(fp, "%s\n", line);
+       }
+
+       /* write back test case */
+       for (i = 0; i < test_data->nb_test_cases; i++) {
+               struct fips_aes_test_case *tc = &test_data->test_cases[i];
+
+               if (op != tc->test_op) {
+                       fprintf(fp, "%s\n\n", tc->test_op == 
RTE_CRYPTO_CIPHER_OP_ENCRYPT ?
+                                       "[ENCRYPT]" : "[DECRYPT]");
+                       op = tc->test_op;
+               }
+
+               if (tc->skip_flag)
+                               continue;
+
+               if (test_data->test_type == AESAVS_TYPE_MCT) {
+                       fprintf(fp, "%s%u\n", COUNT_STR, tc->count);
+                       fprintf(fp, "%s", KEY_STR);
+                       write_uint8_str_to_file(fp, tc->key, 
test_data->key_len);
+                       fprintf(fp, "%s", IV_STR);
+                       write_uint8_str_to_file(fp, tc->iv, tc->iv_len);
+                       if (tc->test_op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
+                               fprintf(fp, "%s", PT_STR);
+                               write_uint8_str_to_file(fp, tc->plaintext,
+                                               tc->plaintext_len);
+                               fprintf(fp, "%s", CT_STR);
+                               write_uint8_str_to_file(fp, tc->ciphertext,
+                                               tc->ciphertext_len);
+                       } else {
+                               fprintf(fp, "%s", CT_STR);
+                               write_uint8_str_to_file(fp, tc->ciphertext,
+                                               tc->ciphertext_len);
+                               fprintf(fp, "%s", PT_STR);
+                               write_uint8_str_to_file(fp, tc->plaintext,
+                                               tc->plaintext_len);
+                       }
+               } else {
+                       write_block_to_file(fp, tc->case_desc);
+
+                       if (tc->test_op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
+                               fprintf(fp, "%s", CT_STR);
+                               write_uint8_str_to_file(fp, tc->ciphertext,
+                                               tc->ciphertext_len);
+                       } else {
+                               fprintf(fp, "%s", PT_STR);
+                               write_uint8_str_to_file(fp, tc->plaintext,
+                                               tc->plaintext_len);
+                       }
+               }
+
+               fprintf(fp, "\n");
+       }
+
+       fclose(fp);
+
+       return 0;
+}
diff --git a/test/test/test_cryptodev_fips_parse_common.c 
b/test/test/test_cryptodev_fips_parse_common.c
new file mode 100644
index 0000000..1caa755
--- /dev/null
+++ b/test/test/test_cryptodev_fips_parse_common.c
@@ -0,0 +1,330 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+#include <string.h>
+#include <stdio.h>
+
+#include <rte_cryptodev.h>
+
+#include "test_cryptodev_fips_parse.h"
+
+/*
+ * copy a line in the file to the buffer
+ * if EOF, return -EOF
+ * otherwise return 0
+ */
+int
+fips_get_file_line(FILE **fp, char *line, uint32_t max_line_char)
+{
+       char c;
+       uint32_t loc = 0;
+
+       memset(line, 0, max_line_char);
+
+       while ((c = fgetc(*fp)) != EOF) {
+               if (loc >= max_line_char - 1)
+                       return -ENOMEM;
+
+               if (c == '\n')
+                       return 0;
+
+               line[loc++] = c;
+       }
+
+       return -EOF;
+}
+
+#define skip_white_spaces(pos)                 \
+({                                             \
+       __typeof__(pos) _p = (pos);             \
+       for ( ; isspace(*_p); _p++)             \
+               ;                               \
+       _p;                                     \
+})
+
+int
+parser_read_uint64(uint64_t *value, const char *p)
+{
+       char *next;
+       uint64_t val;
+
+       p = skip_white_spaces(p);
+       if (!isdigit(*p))
+               return -EINVAL;
+
+       val = strtoul(p, &next, 10);
+       if (p == next)
+               return -EINVAL;
+
+       p = next;
+       switch (*p) {
+       case 'T':
+               val *= 1024ULL;
+               /* fall through */
+       case 'G':
+               val *= 1024ULL;
+               /* fall through */
+       case 'M':
+               val *= 1024ULL;
+               /* fall through */
+       case 'k':
+       case 'K':
+               val *= 1024ULL;
+               p++;
+               break;
+       }
+
+       p = skip_white_spaces(p);
+       if (*p != '\0')
+               return -EINVAL;
+
+       *value = val;
+       return 0;
+}
+
+int
+parser_read_uint64_hex(uint64_t *value, const char *p)
+{
+       char *next;
+       uint64_t val;
+
+       p = skip_white_spaces(p);
+
+       val = strtoul(p, &next, 16);
+       if (p == next)
+               return -EINVAL;
+
+       p = skip_white_spaces(next);
+       if (*p != '\0')
+               return -EINVAL;
+
+       *value = val;
+       return 0;
+}
+
+int
+parser_read_uint32(uint32_t *value, const char *p)
+{
+       uint64_t val = 0;
+       int ret = parser_read_uint64(&val, p);
+
+       if (ret < 0)
+               return ret;
+
+       if (val > UINT32_MAX)
+               return -EINVAL;
+
+       *value = val;
+       return 0;
+}
+
+int
+parser_read_uint32_hex(uint32_t *value, const char *p)
+{
+       uint64_t val = 0;
+       int ret = parser_read_uint64_hex(&val, p);
+
+       if (ret < 0)
+               return ret;
+
+       if (val > UINT32_MAX)
+               return -EINVAL;
+
+       *value = val;
+       return 0;
+}
+
+int
+parser_read_uint16(uint16_t *value, const char *p)
+{
+       uint64_t val = 0;
+       int ret = parser_read_uint64(&val, p);
+
+       if (ret < 0)
+               return ret;
+
+       if (val > UINT16_MAX)
+               return -EINVAL;
+
+       *value = val;
+       return 0;
+}
+
+int
+parser_read_uint16_hex(uint16_t *value, const char *p)
+{
+       uint64_t val = 0;
+       int ret = parser_read_uint64_hex(&val, p);
+
+       if (ret < 0)
+               return ret;
+
+       if (val > UINT16_MAX)
+               return -EINVAL;
+
+       *value = val;
+       return 0;
+}
+
+int
+parser_read_uint8(uint8_t *value, const char *p)
+{
+       uint64_t val = 0;
+       int ret = parser_read_uint64(&val, p);
+
+       if (ret < 0)
+               return ret;
+
+       if (val > UINT8_MAX)
+               return -EINVAL;
+
+       *value = val;
+       return 0;
+}
+
+int
+parser_read_uint8_hex(uint8_t *value, const char *p)
+{
+       uint64_t val = 0;
+       int ret = parser_read_uint64_hex(&val, p);
+
+       if (ret < 0)
+               return ret;
+
+       if (val > UINT8_MAX)
+               return -EINVAL;
+
+       *value = val;
+       return 0;
+}
+
+int
+parse_uint8_hex_str(uint8_t *dst, char *src, uint32_t max_len)
+{
+       uint32_t len, j;
+
+       len = strlen(src) / 2;
+       if (len > max_len)
+               return -ENOMEM;
+
+       for (j = 0; j < len; j++) {
+               char byte[3] = {src[j * 2], src[j * 2 + 1], '\0'};
+
+               if (parser_read_uint8_hex(&dst[j], byte) < 0)
+                       return -EINVAL;
+       }
+
+       return len;
+}
+
+enum file_types
+parse_file_type(const char *path)
+{
+       const char *tmp = path + strlen(path) - 3;
+
+       if (strstr(tmp, REQ_FILE_PERFIX))
+               return FIPS_FILE_TYPE_REQ;
+       else if (strstr(tmp, RSP_FILE_PERFIX))
+               return FIPS_FILE_TYPE_RSP;
+       else if (strstr(path, FAX_FILE_PERFIX))
+               return FIPS_FILE_TYPE_FAX;
+
+       return 0;
+}
+
+/* copy block text from file, stop on line with size of 0 or EOF, max
+ * MAX_CASE_LINE lines */
+int
+fetch_block(FILE **fp, char *line[MAX_CASE_LINE], uint32_t from_line,
+               const char *trigger, uint32_t max_nb_line_char)
+{
+       uint32_t i = 1;
+       int ret = 0;
+
+       if (strstr(line[0], trigger) == NULL)
+               return 0;
+
+       while (i < MAX_CASE_LINE && ret != -EOF) {
+               ret = fips_get_file_line(fp, line[i], max_nb_line_char);
+               if (ret < 0) {
+                       FIPS_PARSE_ERR(from_line + i, "Error code %i", ret);
+                       return ret;
+               }
+
+               if (ret == -EOF || strlen(line[i]) == 0)
+                       break;
+
+               i++;
+       }
+
+       return i;
+}
+
+void
+copy_block(char dst[][MAX_NB_CHAR], char *src[MAX_CASE_LINE],
+               uint32_t nb_lines, uint32_t max_nb_line_char)
+{
+       uint32_t i;
+
+       for (i = 0; i < nb_lines; i++)
+               memcpy(dst[i], src[i], max_nb_line_char - 1);
+}
+
+void
+write_block_to_file(FILE *fp, char from[][MAX_NB_CHAR])
+{
+       uint32_t i;
+
+       for (i = 0; i < MAX_CASE_LINE; i++) {
+               if (from[i] == NULL)
+                       break;
+               if (strlen(from[i]) == 0)
+                       break;
+               fprintf(fp, "%s\n", from[i]);
+       }
+}
+
+void
+write_uint8_str_to_file(FILE *fp, const uint8_t *from, uint32_t size)
+{
+       uint32_t i;
+
+       for (i = 0; i < size; i++)
+               fprintf(fp, "%02x", from[i]);
+
+       fprintf(fp, "\n");
+}
+
+int
+alloc_line_block_mem(char *block[MAX_CASE_LINE], uint32_t max_nb_line_char)
+{
+       uint32_t i;
+
+       for (i = 0; i < MAX_CASE_LINE; i++)
+               block[i] = NULL;
+
+       for (i = 0; i < MAX_CASE_LINE; i++) {
+               block[i] = malloc(max_nb_line_char);
+               if (!block[i])
+                       goto error_exit;
+       }
+
+       return 0;
+
+error_exit:
+       for (i = 0; i < MAX_CASE_LINE; i++)
+               if (block[i])
+                       free(block[i]);
+
+       return -ENOMEM;
+}
+
+void
+free_line_block_mem(char *block[MAX_CASE_LINE])
+{
+       uint32_t i;
+
+       for (i = 0; i < MAX_CASE_LINE; i++)
+               if (block[i])
+                       free(block[i]);
+}
-- 
2.9.5

Reply via email to