14aaad299SMarko Kovacevic /* SPDX-License-Identifier: BSD-3-Clause
24aaad299SMarko Kovacevic * Copyright(c) 2018 Intel Corporation
34aaad299SMarko Kovacevic */
44aaad299SMarko Kovacevic
54aaad299SMarko Kovacevic #include <string.h>
64aaad299SMarko Kovacevic #include <time.h>
74aaad299SMarko Kovacevic #include <stdio.h>
84aaad299SMarko Kovacevic
94aaad299SMarko Kovacevic #include <rte_cryptodev.h>
10*d09abf2dSFan Zhang #include <rte_malloc.h>
114aaad299SMarko Kovacevic
124aaad299SMarko Kovacevic #include "fips_validation.h"
134aaad299SMarko Kovacevic
144aaad299SMarko Kovacevic #define NEW_LINE_STR "#"
154aaad299SMarko Kovacevic #define OP_STR "GCM "
164aaad299SMarko Kovacevic
174aaad299SMarko Kovacevic #define PARAM_PREFIX "["
184aaad299SMarko Kovacevic #define KEYLEN_STR "Keylen = "
194aaad299SMarko Kovacevic #define IVLEN_STR "IVlen = "
204aaad299SMarko Kovacevic #define PTLEN_STR "PTlen = "
214aaad299SMarko Kovacevic #define AADLEN_STR "AADlen = "
224aaad299SMarko Kovacevic #define TAGLEN_STR "Taglen = "
234aaad299SMarko Kovacevic
244aaad299SMarko Kovacevic #define COUNT_STR "Count = "
254aaad299SMarko Kovacevic #define KEY_STR "Key = "
264aaad299SMarko Kovacevic #define IV_STR "IV = "
274aaad299SMarko Kovacevic #define PT_STR "PT = "
284aaad299SMarko Kovacevic #define CT_STR "CT = "
294aaad299SMarko Kovacevic #define TAG_STR "Tag = "
304aaad299SMarko Kovacevic #define AAD_STR "AAD = "
314aaad299SMarko Kovacevic
324aaad299SMarko Kovacevic #define OP_ENC_STR "Encrypt"
334aaad299SMarko Kovacevic #define OP_DEC_STR "Decrypt"
34*d09abf2dSFan Zhang /* External/Internal IV generation, specified in file name, following NIST
35*d09abf2dSFan Zhang * GCMVS Section 6.1
36*d09abf2dSFan Zhang */
37*d09abf2dSFan Zhang #define OP_ENC_EXT_STR "ExtIV"
38*d09abf2dSFan Zhang #define OP_ENC_INT_STR "IntIV"
394aaad299SMarko Kovacevic
404aaad299SMarko Kovacevic #define NEG_TEST_STR "FAIL"
414aaad299SMarko Kovacevic
42*d09abf2dSFan Zhang /**
43*d09abf2dSFan Zhang * GMAC is essentially zero length plaintext and uses AAD as input data.
44*d09abf2dSFan Zhang * NIST does not have GMAC specific test vector but using zero length "PTlen"
45*d09abf2dSFan Zhang * and uses AAD as input.
46*d09abf2dSFan Zhang **/
47*d09abf2dSFan Zhang static int
parser_read_gcm_pt_len(const char * key,char * src,__rte_unused struct fips_val * val)48*d09abf2dSFan Zhang parser_read_gcm_pt_len(const char *key, char *src,
49*d09abf2dSFan Zhang __rte_unused struct fips_val *val)
50*d09abf2dSFan Zhang {
51*d09abf2dSFan Zhang int ret = parser_read_uint32_bit_val(key, src, &vec.pt);
52*d09abf2dSFan Zhang
53*d09abf2dSFan Zhang if (ret < 0)
54*d09abf2dSFan Zhang return ret;
55*d09abf2dSFan Zhang
56*d09abf2dSFan Zhang if (vec.pt.len == 0) {
57*d09abf2dSFan Zhang info.interim_info.gcm_data.is_gmac = 1;
58*d09abf2dSFan Zhang test_ops.prepare_op = prepare_auth_op;
59*d09abf2dSFan Zhang test_ops.prepare_xform = prepare_gmac_xform;
60*d09abf2dSFan Zhang } else {
61*d09abf2dSFan Zhang info.interim_info.gcm_data.is_gmac = 0;
62*d09abf2dSFan Zhang test_ops.prepare_op = prepare_aead_op;
63*d09abf2dSFan Zhang test_ops.prepare_xform = prepare_gcm_xform;
64*d09abf2dSFan Zhang }
65*d09abf2dSFan Zhang
66*d09abf2dSFan Zhang return ret;
67*d09abf2dSFan Zhang }
68*d09abf2dSFan Zhang
69*d09abf2dSFan Zhang static int
parse_gcm_aad_str(const char * key,char * src,__rte_unused struct fips_val * val)70*d09abf2dSFan Zhang parse_gcm_aad_str(const char *key, char *src,
71*d09abf2dSFan Zhang __rte_unused struct fips_val *val)
72*d09abf2dSFan Zhang {
73*d09abf2dSFan Zhang /* For GMAC test vector, AAD is treated as input */
74*d09abf2dSFan Zhang if (info.interim_info.gcm_data.is_gmac) {
75*d09abf2dSFan Zhang vec.pt.len = vec.aead.aad.len;
76*d09abf2dSFan Zhang return parse_uint8_known_len_hex_str(key, src, &vec.pt);
77*d09abf2dSFan Zhang } else /* gcm */
78*d09abf2dSFan Zhang return parse_uint8_known_len_hex_str(key, src, &vec.aead.aad);
79*d09abf2dSFan Zhang }
80*d09abf2dSFan Zhang
81*d09abf2dSFan Zhang static int
parse_gcm_pt_ct_str(const char * key,char * src,struct fips_val * val)82*d09abf2dSFan Zhang parse_gcm_pt_ct_str(const char *key, char *src, struct fips_val *val)
83*d09abf2dSFan Zhang {
84*d09abf2dSFan Zhang /* According to NIST GCMVS section 6.1, IUT should generate IV data */
85*d09abf2dSFan Zhang if (info.interim_info.gcm_data.gen_iv && vec.iv.len) {
86*d09abf2dSFan Zhang uint32_t i;
87*d09abf2dSFan Zhang
88*d09abf2dSFan Zhang if (!vec.iv.val) {
89*d09abf2dSFan Zhang vec.iv.val = rte_malloc(0, vec.iv.len, 0);
90*d09abf2dSFan Zhang if (!vec.iv.val)
91*d09abf2dSFan Zhang return -ENOMEM;
92*d09abf2dSFan Zhang }
93*d09abf2dSFan Zhang
94*d09abf2dSFan Zhang for (i = 0; i < vec.iv.len; i++) {
95*d09abf2dSFan Zhang int random = rand();
96*d09abf2dSFan Zhang vec.iv.val[i] = (uint8_t)random;
97*d09abf2dSFan Zhang }
98*d09abf2dSFan Zhang }
99*d09abf2dSFan Zhang
100*d09abf2dSFan Zhang /* if PTlen == 0, pt or ct will be handled by AAD later */
101*d09abf2dSFan Zhang if (info.interim_info.gcm_data.is_gmac)
102*d09abf2dSFan Zhang return 0;
103*d09abf2dSFan Zhang
104*d09abf2dSFan Zhang return parse_uint8_known_len_hex_str(key, src, val);
105*d09abf2dSFan Zhang }
106*d09abf2dSFan Zhang
1074aaad299SMarko Kovacevic struct fips_test_callback gcm_dec_vectors[] = {
10851b9292eSSucharitha Sarananaga {KEY_STR, parse_uint8_known_len_hex_str, &vec.aead.key},
1094aaad299SMarko Kovacevic {IV_STR, parse_uint8_known_len_hex_str, &vec.iv},
110*d09abf2dSFan Zhang {CT_STR, parse_gcm_pt_ct_str, &vec.ct},
111*d09abf2dSFan Zhang {AAD_STR, parse_gcm_aad_str, &vec.aead.aad},
1124aaad299SMarko Kovacevic {TAG_STR, parse_uint8_known_len_hex_str,
11351b9292eSSucharitha Sarananaga &vec.aead.digest},
1144aaad299SMarko Kovacevic {NULL, NULL, NULL} /**< end pointer */
1154aaad299SMarko Kovacevic };
116*d09abf2dSFan Zhang
1174aaad299SMarko Kovacevic struct fips_test_callback gcm_interim_vectors[] = {
11851b9292eSSucharitha Sarananaga {KEYLEN_STR, parser_read_uint32_bit_val, &vec.aead.key},
1194aaad299SMarko Kovacevic {IVLEN_STR, parser_read_uint32_bit_val, &vec.iv},
120*d09abf2dSFan Zhang {PTLEN_STR, parser_read_gcm_pt_len, &vec.pt},
121b1ea86a0SAnoob Joseph {PTLEN_STR, parser_read_uint32_bit_val, &vec.ct},
122b1ea86a0SAnoob Joseph /**< The NIST test vectors use 'PTlen' to denote input text
123b1ea86a0SAnoob Joseph * length in case of decrypt & encrypt operations.
124b1ea86a0SAnoob Joseph */
12551b9292eSSucharitha Sarananaga {AADLEN_STR, parser_read_uint32_bit_val, &vec.aead.aad},
1264aaad299SMarko Kovacevic {TAGLEN_STR, parser_read_uint32_bit_val,
12751b9292eSSucharitha Sarananaga &vec.aead.digest},
1284aaad299SMarko Kovacevic {NULL, NULL, NULL} /**< end pointer */
1294aaad299SMarko Kovacevic };
1304aaad299SMarko Kovacevic
1314aaad299SMarko Kovacevic struct fips_test_callback gcm_enc_vectors[] = {
13251b9292eSSucharitha Sarananaga {KEY_STR, parse_uint8_known_len_hex_str, &vec.aead.key},
1334aaad299SMarko Kovacevic {IV_STR, parse_uint8_known_len_hex_str, &vec.iv},
134*d09abf2dSFan Zhang {PT_STR, parse_gcm_pt_ct_str, &vec.pt},
135*d09abf2dSFan Zhang {AAD_STR, parse_gcm_aad_str, &vec.aead.aad},
1364aaad299SMarko Kovacevic {NULL, NULL, NULL} /**< end pointer */
1374aaad299SMarko Kovacevic };
1384aaad299SMarko Kovacevic
1394aaad299SMarko Kovacevic static int
parse_test_gcm_writeback(struct fips_val * val)1404aaad299SMarko Kovacevic parse_test_gcm_writeback(struct fips_val *val)
1414aaad299SMarko Kovacevic {
1424aaad299SMarko Kovacevic struct fips_val tmp_val;
1434aaad299SMarko Kovacevic
1444aaad299SMarko Kovacevic if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
145*d09abf2dSFan Zhang /* According to NIST GCMVS section 6.1, IUT should provide
146*d09abf2dSFan Zhang * generate IV data
147*d09abf2dSFan Zhang */
148*d09abf2dSFan Zhang if (info.interim_info.gcm_data.gen_iv) {
149*d09abf2dSFan Zhang fprintf(info.fp_wr, "%s", IV_STR);
150*d09abf2dSFan Zhang tmp_val.val = vec.iv.val;
151*d09abf2dSFan Zhang tmp_val.len = vec.iv.len;
152*d09abf2dSFan Zhang
153*d09abf2dSFan Zhang parse_write_hex_str(&tmp_val);
154*d09abf2dSFan Zhang rte_free(vec.iv.val);
155*d09abf2dSFan Zhang vec.iv.val = NULL;
156*d09abf2dSFan Zhang }
157*d09abf2dSFan Zhang
1584aaad299SMarko Kovacevic fprintf(info.fp_wr, "%s", CT_STR);
1594aaad299SMarko Kovacevic
160*d09abf2dSFan Zhang if (!info.interim_info.gcm_data.is_gmac) {
1614aaad299SMarko Kovacevic tmp_val.val = val->val;
1624aaad299SMarko Kovacevic tmp_val.len = vec.pt.len;
1634aaad299SMarko Kovacevic
1644aaad299SMarko Kovacevic parse_write_hex_str(&tmp_val);
165*d09abf2dSFan Zhang } else
166*d09abf2dSFan Zhang fprintf(info.fp_wr, "\n");
1674aaad299SMarko Kovacevic
1684aaad299SMarko Kovacevic fprintf(info.fp_wr, "%s", TAG_STR);
1694aaad299SMarko Kovacevic
1704aaad299SMarko Kovacevic tmp_val.val = val->val + vec.pt.len;
1714aaad299SMarko Kovacevic tmp_val.len = val->len - vec.pt.len;
1724aaad299SMarko Kovacevic
1734aaad299SMarko Kovacevic parse_write_hex_str(&tmp_val);
1744aaad299SMarko Kovacevic } else {
1754aaad299SMarko Kovacevic if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS) {
1764aaad299SMarko Kovacevic fprintf(info.fp_wr, "%s", PT_STR);
177*d09abf2dSFan Zhang if (!info.interim_info.gcm_data.is_gmac) {
1784aaad299SMarko Kovacevic tmp_val.val = val->val;
1794aaad299SMarko Kovacevic tmp_val.len = vec.pt.len;
1804aaad299SMarko Kovacevic
1814aaad299SMarko Kovacevic parse_write_hex_str(&tmp_val);
1824aaad299SMarko Kovacevic } else
183*d09abf2dSFan Zhang fprintf(info.fp_wr, "\n");
184*d09abf2dSFan Zhang } else
1854aaad299SMarko Kovacevic fprintf(info.fp_wr, "%s\n", NEG_TEST_STR);
1864aaad299SMarko Kovacevic }
1874aaad299SMarko Kovacevic
1884aaad299SMarko Kovacevic return 0;
1894aaad299SMarko Kovacevic }
1904aaad299SMarko Kovacevic
1914aaad299SMarko Kovacevic int
parse_test_gcm_init(void)1924aaad299SMarko Kovacevic parse_test_gcm_init(void)
1934aaad299SMarko Kovacevic {
1944aaad299SMarko Kovacevic char *tmp;
1954aaad299SMarko Kovacevic uint32_t i;
1964aaad299SMarko Kovacevic
1974aaad299SMarko Kovacevic
1984aaad299SMarko Kovacevic for (i = 0; i < info.nb_vec_lines; i++) {
1994aaad299SMarko Kovacevic char *line = info.vec[i];
2004aaad299SMarko Kovacevic
2014aaad299SMarko Kovacevic tmp = strstr(line, OP_STR);
2024aaad299SMarko Kovacevic if (tmp) {
2034aaad299SMarko Kovacevic if (strstr(line, OP_ENC_STR)) {
2044aaad299SMarko Kovacevic info.op = FIPS_TEST_ENC_AUTH_GEN;
2054aaad299SMarko Kovacevic info.callbacks = gcm_enc_vectors;
206*d09abf2dSFan Zhang if (strstr(info.file_name, OP_ENC_INT_STR))
207*d09abf2dSFan Zhang info.interim_info.gcm_data.gen_iv = 1;
2084aaad299SMarko Kovacevic } else if (strstr(line, OP_DEC_STR)) {
2094aaad299SMarko Kovacevic info.op = FIPS_TEST_DEC_AUTH_VERIF;
2104aaad299SMarko Kovacevic info.callbacks = gcm_dec_vectors;
2114aaad299SMarko Kovacevic } else
2124aaad299SMarko Kovacevic return -EINVAL;
2134aaad299SMarko Kovacevic }
2144aaad299SMarko Kovacevic }
2154aaad299SMarko Kovacevic
2164aaad299SMarko Kovacevic info.interim_callbacks = gcm_interim_vectors;
2174aaad299SMarko Kovacevic info.parse_writeback = parse_test_gcm_writeback;
2184aaad299SMarko Kovacevic
2194aaad299SMarko Kovacevic return 0;
2204aaad299SMarko Kovacevic }
221