1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2018 Intel Corporation 3 */ 4 5 #include <string.h> 6 #include <time.h> 7 #include <stdio.h> 8 9 #include <rte_cryptodev.h> 10 #include <rte_malloc.h> 11 12 #include "fips_validation.h" 13 14 #define NEW_LINE_STR "#" 15 #define OP_STR "GCM " 16 17 #define PARAM_PREFIX "[" 18 #define KEYLEN_STR "Keylen = " 19 #define IVLEN_STR "IVlen = " 20 #define PTLEN_STR "PTlen = " 21 #define AADLEN_STR "AADlen = " 22 #define TAGLEN_STR "Taglen = " 23 24 #define COUNT_STR "Count = " 25 #define KEY_STR "Key = " 26 #define IV_STR "IV = " 27 #define PT_STR "PT = " 28 #define CT_STR "CT = " 29 #define TAG_STR "Tag = " 30 #define AAD_STR "AAD = " 31 32 #define OP_ENC_STR "Encrypt" 33 #define OP_DEC_STR "Decrypt" 34 /* External/Internal IV generation, specified in file name, following NIST 35 * GCMVS Section 6.1 36 */ 37 #define OP_ENC_EXT_STR "ExtIV" 38 #define OP_ENC_INT_STR "IntIV" 39 40 #define NEG_TEST_STR "FAIL" 41 42 /** 43 * GMAC is essentially zero length plaintext and uses AAD as input data. 44 * NIST does not have GMAC specific test vector but using zero length "PTlen" 45 * and uses AAD as input. 46 **/ 47 static int 48 parser_read_gcm_pt_len(const char *key, char *src, 49 __rte_unused struct fips_val *val) 50 { 51 int ret = parser_read_uint32_bit_val(key, src, &vec.pt); 52 53 if (ret < 0) 54 return ret; 55 56 if (vec.pt.len == 0) { 57 info.interim_info.gcm_data.is_gmac = 1; 58 test_ops.prepare_op = prepare_auth_op; 59 test_ops.prepare_xform = prepare_gmac_xform; 60 } else { 61 info.interim_info.gcm_data.is_gmac = 0; 62 test_ops.prepare_op = prepare_aead_op; 63 test_ops.prepare_xform = prepare_gcm_xform; 64 } 65 66 return ret; 67 } 68 69 static int 70 parse_gcm_aad_str(const char *key, char *src, 71 __rte_unused struct fips_val *val) 72 { 73 /* For GMAC test vector, AAD is treated as input */ 74 if (info.interim_info.gcm_data.is_gmac) { 75 vec.pt.len = vec.aead.aad.len; 76 return parse_uint8_known_len_hex_str(key, src, &vec.pt); 77 } else /* gcm */ 78 return parse_uint8_known_len_hex_str(key, src, &vec.aead.aad); 79 } 80 81 static int 82 parse_gcm_pt_ct_str(const char *key, char *src, struct fips_val *val) 83 { 84 /* According to NIST GCMVS section 6.1, IUT should generate IV data */ 85 if (info.interim_info.gcm_data.gen_iv && vec.iv.len) { 86 uint32_t i; 87 88 if (!vec.iv.val) { 89 vec.iv.val = rte_malloc(0, vec.iv.len, 0); 90 if (!vec.iv.val) 91 return -ENOMEM; 92 } 93 94 for (i = 0; i < vec.iv.len; i++) { 95 int random = rand(); 96 vec.iv.val[i] = (uint8_t)random; 97 } 98 } 99 100 /* if PTlen == 0, pt or ct will be handled by AAD later */ 101 if (info.interim_info.gcm_data.is_gmac) 102 return 0; 103 104 return parse_uint8_known_len_hex_str(key, src, val); 105 } 106 107 struct fips_test_callback gcm_dec_vectors[] = { 108 {KEY_STR, parse_uint8_known_len_hex_str, &vec.aead.key}, 109 {IV_STR, parse_uint8_known_len_hex_str, &vec.iv}, 110 {CT_STR, parse_gcm_pt_ct_str, &vec.ct}, 111 {AAD_STR, parse_gcm_aad_str, &vec.aead.aad}, 112 {TAG_STR, parse_uint8_known_len_hex_str, 113 &vec.aead.digest}, 114 {NULL, NULL, NULL} /**< end pointer */ 115 }; 116 117 struct fips_test_callback gcm_interim_vectors[] = { 118 {KEYLEN_STR, parser_read_uint32_bit_val, &vec.aead.key}, 119 {IVLEN_STR, parser_read_uint32_bit_val, &vec.iv}, 120 {PTLEN_STR, parser_read_gcm_pt_len, &vec.pt}, 121 {PTLEN_STR, parser_read_uint32_bit_val, &vec.ct}, 122 /**< The NIST test vectors use 'PTlen' to denote input text 123 * length in case of decrypt & encrypt operations. 124 */ 125 {AADLEN_STR, parser_read_uint32_bit_val, &vec.aead.aad}, 126 {TAGLEN_STR, parser_read_uint32_bit_val, 127 &vec.aead.digest}, 128 {NULL, NULL, NULL} /**< end pointer */ 129 }; 130 131 struct fips_test_callback gcm_enc_vectors[] = { 132 {KEY_STR, parse_uint8_known_len_hex_str, &vec.aead.key}, 133 {IV_STR, parse_uint8_known_len_hex_str, &vec.iv}, 134 {PT_STR, parse_gcm_pt_ct_str, &vec.pt}, 135 {AAD_STR, parse_gcm_aad_str, &vec.aead.aad}, 136 {NULL, NULL, NULL} /**< end pointer */ 137 }; 138 139 static int 140 parse_test_gcm_writeback(struct fips_val *val) 141 { 142 struct fips_val tmp_val; 143 144 if (info.op == FIPS_TEST_ENC_AUTH_GEN) { 145 /* According to NIST GCMVS section 6.1, IUT should provide 146 * generate IV data 147 */ 148 if (info.interim_info.gcm_data.gen_iv) { 149 fprintf(info.fp_wr, "%s", IV_STR); 150 tmp_val.val = vec.iv.val; 151 tmp_val.len = vec.iv.len; 152 153 parse_write_hex_str(&tmp_val); 154 rte_free(vec.iv.val); 155 vec.iv.val = NULL; 156 } 157 158 fprintf(info.fp_wr, "%s", CT_STR); 159 160 if (!info.interim_info.gcm_data.is_gmac) { 161 tmp_val.val = val->val; 162 tmp_val.len = vec.pt.len; 163 164 parse_write_hex_str(&tmp_val); 165 } else 166 fprintf(info.fp_wr, "\n"); 167 168 fprintf(info.fp_wr, "%s", TAG_STR); 169 170 tmp_val.val = val->val + vec.pt.len; 171 tmp_val.len = val->len - vec.pt.len; 172 173 parse_write_hex_str(&tmp_val); 174 } else { 175 if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS) { 176 fprintf(info.fp_wr, "%s", PT_STR); 177 if (!info.interim_info.gcm_data.is_gmac) { 178 tmp_val.val = val->val; 179 tmp_val.len = vec.pt.len; 180 181 parse_write_hex_str(&tmp_val); 182 } else 183 fprintf(info.fp_wr, "\n"); 184 } else 185 fprintf(info.fp_wr, "%s\n", NEG_TEST_STR); 186 } 187 188 return 0; 189 } 190 191 int 192 parse_test_gcm_init(void) 193 { 194 char *tmp; 195 uint32_t i; 196 197 198 for (i = 0; i < info.nb_vec_lines; i++) { 199 char *line = info.vec[i]; 200 201 tmp = strstr(line, OP_STR); 202 if (tmp) { 203 if (strstr(line, OP_ENC_STR)) { 204 info.op = FIPS_TEST_ENC_AUTH_GEN; 205 info.callbacks = gcm_enc_vectors; 206 if (strstr(info.file_name, OP_ENC_INT_STR)) 207 info.interim_info.gcm_data.gen_iv = 1; 208 } else if (strstr(line, OP_DEC_STR)) { 209 info.op = FIPS_TEST_DEC_AUTH_VERIF; 210 info.callbacks = gcm_dec_vectors; 211 } else 212 return -EINVAL; 213 } 214 } 215 216 info.interim_callbacks = gcm_interim_vectors; 217 info.parse_writeback = parse_test_gcm_writeback; 218 219 return 0; 220 } 221