1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(C) 2023 Marvell. 3 */ 4 5 #include <rte_crypto.h> 6 #include <rte_dtls.h> 7 #include <rte_tls.h> 8 9 #include "test.h" 10 #include "test_cryptodev_security_tls_record.h" 11 #include "test_cryptodev_security_tls_record_test_vectors.h" 12 #include "test_security_proto.h" 13 14 int 15 test_tls_record_status_check(struct rte_crypto_op *op, 16 const struct tls_record_test_data *td) 17 { 18 int ret = TEST_SUCCESS; 19 20 if ((td->tls_record_xform.type == RTE_SECURITY_TLS_SESS_TYPE_READ) && 21 td->ar_packet) { 22 if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) { 23 printf("Anti replay test case failed\n"); 24 return TEST_FAILED; 25 } else { 26 return TEST_SUCCESS; 27 } 28 } 29 30 if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) 31 ret = TEST_FAILED; 32 33 return ret; 34 } 35 36 int 37 test_tls_record_sec_caps_verify(struct rte_security_tls_record_xform *tls_record_xform, 38 const struct rte_security_capability *sec_cap, bool silent) 39 { 40 /* Verify security capabilities */ 41 42 RTE_SET_USED(tls_record_xform); 43 RTE_SET_USED(sec_cap); 44 RTE_SET_USED(silent); 45 46 return 0; 47 } 48 49 void 50 test_tls_record_td_read_from_write(const struct tls_record_test_data *td_out, 51 struct tls_record_test_data *td_in) 52 { 53 memcpy(td_in, td_out, sizeof(*td_in)); 54 55 /* Populate output text of td_in with input text of td_out */ 56 memcpy(td_in->output_text.data, td_out->input_text.data, td_out->input_text.len); 57 td_in->output_text.len = td_out->input_text.len; 58 59 /* Populate input text of td_in with output text of td_out */ 60 memcpy(td_in->input_text.data, td_out->output_text.data, td_out->output_text.len); 61 td_in->input_text.len = td_out->output_text.len; 62 63 td_in->tls_record_xform.type = RTE_SECURITY_TLS_SESS_TYPE_READ; 64 65 if (td_in->aead) { 66 td_in->xform.aead.aead.op = RTE_CRYPTO_AEAD_OP_DECRYPT; 67 } else { 68 td_in->xform.chain.auth.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; 69 td_in->xform.chain.cipher.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT; 70 } 71 } 72 73 int 74 test_tls_record_td_prepare(const struct crypto_param *param1, const struct crypto_param *param2, 75 const struct tls_record_test_flags *flags, 76 struct tls_record_test_data *td_array, 77 int nb_td, unsigned int data_len) 78 { 79 int i, min_padding, hdr_len, tls_pkt_size, mac_len = 0, exp_nonce_len = 0, roundup_len = 0; 80 struct tls_record_test_data *td = NULL; 81 82 if ((flags->tls_version == RTE_SECURITY_VERSION_TLS_1_3) && 83 (param1->type != RTE_CRYPTO_SYM_XFORM_AEAD)) 84 return TEST_SKIPPED; 85 86 memset(td_array, 0, nb_td * sizeof(*td)); 87 88 for (i = 0; i < nb_td; i++) { 89 td = &td_array[i]; 90 91 /* Prepare fields based on param */ 92 93 if (param1->type == RTE_CRYPTO_SYM_XFORM_AEAD) { 94 /* Copy template for packet & key fields */ 95 switch (flags->tls_version) { 96 case RTE_SECURITY_VERSION_TLS_1_2: 97 memcpy(td, &tls_test_data_aes_128_gcm_v1, sizeof(*td)); 98 break; 99 case RTE_SECURITY_VERSION_DTLS_1_2: 100 memcpy(td, &dtls_test_data_aes_128_gcm, sizeof(*td)); 101 break; 102 case RTE_SECURITY_VERSION_TLS_1_3: 103 memcpy(td, &tls13_test_data_aes_128_gcm, sizeof(*td)); 104 break; 105 } 106 107 td->aead = true; 108 td->xform.aead.aead.algo = param1->alg.aead; 109 td->xform.aead.aead.key.length = param1->key_length; 110 td->xform.aead.aead.digest_length = param1->digest_length; 111 } else { 112 /* Copy template for packet & key fields */ 113 if (flags->tls_version == RTE_SECURITY_VERSION_DTLS_1_2) 114 memcpy(td, &dtls_test_data_aes_128_cbc_sha1_hmac, sizeof(*td)); 115 else 116 memcpy(td, &tls_test_data_aes_128_cbc_sha1_hmac, sizeof(*td)); 117 118 td->aead = false; 119 td->xform.chain.cipher.cipher.algo = param1->alg.cipher; 120 td->xform.chain.cipher.cipher.key.length = param1->key_length; 121 td->xform.chain.cipher.cipher.iv.length = param1->iv_length; 122 td->xform.chain.auth.auth.algo = param2->alg.auth; 123 td->xform.chain.auth.auth.key.length = param2->key_length; 124 td->xform.chain.auth.auth.digest_length = param2->digest_length; 125 } 126 127 if (flags->data_walkthrough || flags->zero_len) { 128 test_sec_proto_pattern_set(td->input_text.data, data_len); 129 td->input_text.len = data_len; 130 } 131 132 if (flags->content_type == TLS_RECORD_TEST_CONTENT_TYPE_CUSTOM) 133 td->app_type = RTE_TLS_TYPE_MAX; 134 else if (flags->content_type == TLS_RECORD_TEST_CONTENT_TYPE_HANDSHAKE) 135 td->app_type = RTE_TLS_TYPE_HANDSHAKE; 136 137 tls_pkt_size = td->input_text.len; 138 139 if (!td->aead) { 140 mac_len = td->xform.chain.auth.auth.digest_length; 141 min_padding = 1; 142 switch (td->xform.chain.cipher.cipher.algo) { 143 case RTE_CRYPTO_CIPHER_3DES_CBC: 144 roundup_len = 8; 145 exp_nonce_len = 8; 146 break; 147 case RTE_CRYPTO_CIPHER_AES_CBC: 148 roundup_len = 16; 149 exp_nonce_len = 16; 150 break; 151 default: 152 roundup_len = 0; 153 exp_nonce_len = 0; 154 break; 155 } 156 } else { 157 mac_len = td->xform.aead.aead.digest_length; 158 min_padding = 0; 159 roundup_len = 0; 160 if (td->tls_record_xform.ver == RTE_SECURITY_VERSION_TLS_1_3) 161 exp_nonce_len = 0; 162 else 163 exp_nonce_len = 8; 164 } 165 166 switch (td->tls_record_xform.ver) { 167 case RTE_SECURITY_VERSION_TLS_1_2: 168 hdr_len = sizeof(struct rte_tls_hdr); 169 break; 170 case RTE_SECURITY_VERSION_TLS_1_3: 171 hdr_len = sizeof(struct rte_tls_hdr); 172 /* Add 1 byte for content type in packet */ 173 tls_pkt_size += 1; 174 break; 175 case RTE_SECURITY_VERSION_DTLS_1_2: 176 hdr_len = sizeof(struct rte_dtls_hdr); 177 break; 178 default: 179 return TEST_SKIPPED; 180 } 181 182 tls_pkt_size += mac_len; 183 184 /* Padding */ 185 tls_pkt_size += min_padding; 186 187 if (roundup_len) 188 tls_pkt_size = RTE_ALIGN_MUL_CEIL(tls_pkt_size, roundup_len); 189 190 /* Explicit nonce */ 191 tls_pkt_size += exp_nonce_len; 192 193 /* Add TLS header */ 194 tls_pkt_size += hdr_len; 195 196 td->output_text.len = tls_pkt_size; 197 198 } 199 return TEST_SUCCESS; 200 } 201 202 void 203 test_tls_record_td_update(struct tls_record_test_data td_inb[], 204 const struct tls_record_test_data td_outb[], int nb_td, 205 const struct tls_record_test_flags *flags) 206 { 207 int i; 208 209 for (i = 0; i < nb_td; i++) { 210 memcpy(td_inb[i].output_text.data, td_outb[i].input_text.data, 211 td_outb[i].input_text.len); 212 td_inb[i].output_text.len = td_outb->input_text.len; 213 214 /* Corrupt the content type in the TLS header of encrypted packet */ 215 if (flags->pkt_corruption) 216 td_inb[i].input_text.data[0] = ~td_inb[i].input_text.data[0]; 217 218 /* Clear outbound specific flags */ 219 td_inb[i].tls_record_xform.options.iv_gen_disable = 0; 220 } 221 222 RTE_SET_USED(flags); 223 } 224 225 static int 226 test_tls_record_td_verify(uint8_t *output_text, uint32_t len, const struct tls_record_test_data *td, 227 bool silent) 228 { 229 if (len != td->output_text.len) { 230 printf("Output length (%d) not matching with expected (%d)\n", 231 len, td->output_text.len); 232 return TEST_FAILED; 233 } 234 235 if (memcmp(output_text, td->output_text.data, len)) { 236 if (silent) 237 return TEST_FAILED; 238 239 printf("[%s : %d] %s\n", __func__, __LINE__, "Output text not as expected\n"); 240 241 rte_hexdump(stdout, "expected", td->output_text.data, len); 242 rte_hexdump(stdout, "actual", output_text, len); 243 return TEST_FAILED; 244 } 245 246 return TEST_SUCCESS; 247 } 248 249 static int 250 test_tls_record_res_d_prepare(const uint8_t *output_text, uint32_t len, 251 const struct tls_record_test_data *td, 252 struct tls_record_test_data *res_d) 253 { 254 memcpy(res_d, td, sizeof(*res_d)); 255 256 memcpy(&res_d->input_text.data, output_text, len); 257 res_d->input_text.len = len; 258 res_d->output_text.len = td->input_text.len; 259 260 res_d->tls_record_xform.type = RTE_SECURITY_TLS_SESS_TYPE_READ; 261 if (res_d->aead) { 262 res_d->xform.aead.aead.op = RTE_CRYPTO_AEAD_OP_DECRYPT; 263 } else { 264 res_d->xform.chain.cipher.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT; 265 res_d->xform.chain.auth.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; 266 } 267 268 return TEST_SUCCESS; 269 } 270 271 static int 272 tls_record_hdr_verify(const struct tls_record_test_data *td, const uint8_t *output_text) 273 { 274 uint16_t length, hdr_len; 275 uint8_t content_type; 276 277 if (td->tls_record_xform.ver == RTE_SECURITY_VERSION_TLS_1_2) { 278 const struct rte_tls_hdr *hdr = (const struct rte_tls_hdr *)output_text; 279 if (rte_be_to_cpu_16(hdr->version) != RTE_TLS_VERSION_1_2) { 280 printf("Incorrect header version [expected - %4x, received - %4x]\n", 281 RTE_TLS_VERSION_1_2, rte_be_to_cpu_16(hdr->version)); 282 return TEST_FAILED; 283 } 284 content_type = hdr->type; 285 length = rte_be_to_cpu_16(hdr->length); 286 hdr_len = sizeof(struct rte_tls_hdr); 287 } else if (td->tls_record_xform.ver == RTE_SECURITY_VERSION_TLS_1_3) { 288 const struct rte_tls_hdr *hdr = (const struct rte_tls_hdr *)output_text; 289 if (rte_be_to_cpu_16(hdr->version) != RTE_TLS_VERSION_1_2) { 290 printf("Incorrect header version [expected - %4x, received - %4x]\n", 291 RTE_TLS_VERSION_1_2, rte_be_to_cpu_16(hdr->version)); 292 return TEST_FAILED; 293 } 294 content_type = hdr->type; 295 length = rte_be_to_cpu_16(hdr->length); 296 hdr_len = sizeof(struct rte_tls_hdr); 297 } else if (td->tls_record_xform.ver == RTE_SECURITY_VERSION_DTLS_1_2) { 298 const struct rte_dtls_hdr *hdr = (const struct rte_dtls_hdr *)output_text; 299 if (rte_be_to_cpu_16(hdr->version) != RTE_DTLS_VERSION_1_2) { 300 printf("Incorrect header version [expected - %4x, received - %4x]\n", 301 RTE_DTLS_VERSION_1_2, rte_be_to_cpu_16(hdr->version)); 302 return TEST_FAILED; 303 } 304 content_type = hdr->type; 305 length = rte_be_to_cpu_16(hdr->length); 306 hdr_len = sizeof(struct rte_dtls_hdr); 307 } else { 308 return TEST_FAILED; 309 } 310 311 if (td->tls_record_xform.ver == RTE_SECURITY_VERSION_TLS_1_3) { 312 if (content_type != RTE_TLS_TYPE_APPDATA) { 313 printf("Incorrect content type in packet [expected - %d, received - %d]\n", 314 td->app_type, content_type); 315 return TEST_FAILED; 316 } 317 } else { 318 if (content_type != td->app_type) { 319 printf("Incorrect content type in packet [expected - %d, received - %d]\n", 320 td->app_type, content_type); 321 return TEST_FAILED; 322 } 323 } 324 325 if (length != td->output_text.len - hdr_len) { 326 printf("Incorrect packet length [expected - %d, received - %d]\n", 327 td->output_text.len - hdr_len, length); 328 return TEST_FAILED; 329 } 330 331 return TEST_SUCCESS; 332 } 333 334 int 335 test_tls_record_post_process(const struct rte_mbuf *m, const struct tls_record_test_data *td, 336 struct tls_record_test_data *res_d, bool silent) 337 { 338 uint8_t output_text[TEST_SEC_CIPHERTEXT_MAX_LEN]; 339 uint32_t len = rte_pktmbuf_pkt_len(m), data_len; 340 const struct rte_mbuf *seg; 341 const uint8_t *output; 342 int ret; 343 344 memset(output_text, 0, TEST_SEC_CIPHERTEXT_MAX_LEN); 345 346 /* 347 * Actual data in packet might be less in error cases, hence take minimum of pkt_len and sum 348 * of data_len. This is done to run through negative test cases. 349 */ 350 data_len = 0; 351 seg = m; 352 while (seg) { 353 data_len += seg->data_len; 354 seg = seg->next; 355 } 356 357 len = RTE_MIN(len, data_len); 358 TEST_ASSERT(len <= TEST_SEC_CIPHERTEXT_MAX_LEN, "Invalid packet length: %u", len); 359 360 /* Copy mbuf payload to continuous buffer */ 361 output = rte_pktmbuf_read(m, 0, len, output_text); 362 if (output != output_text) { 363 /* Single segment mbuf, copy manually */ 364 memcpy(output_text, output, len); 365 } 366 367 if (td->tls_record_xform.type == RTE_SECURITY_TLS_SESS_TYPE_WRITE) { 368 ret = tls_record_hdr_verify(td, output_text); 369 if (ret != TEST_SUCCESS) 370 return ret; 371 } 372 373 /* 374 * In case of known vector tests & all record read (decrypt) tests, res_d provided would be 375 * NULL and output data need to be validated against expected. For record read (decrypt), 376 * output_text would be plain payload and for record write (encrypt), output_text would TLS 377 * record. Validate by comparing against known vectors. 378 * 379 * In case of combined mode tests, the output_text from TLS write (encrypt) operation (ie, 380 * TLS record) would need to be decrypted using a TLS read operation to obtain the plain 381 * text. Copy output_text to result data, 'res_d', so that inbound processing can be done. 382 */ 383 384 if (res_d == NULL) 385 return test_tls_record_td_verify(output_text, len, td, silent); 386 else 387 return test_tls_record_res_d_prepare(output_text, len, td, res_d); 388 } 389