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 /* Corrupt a byte in the last but one block */ 219 if (flags->padding_corruption) { 220 int offset = td_inb[i].input_text.len - TLS_RECORD_PAD_CORRUPT_OFFSET; 221 222 td_inb[i].input_text.data[offset] = ~td_inb[i].input_text.data[offset]; 223 } 224 225 /* Clear outbound specific flags */ 226 td_inb[i].tls_record_xform.options.iv_gen_disable = 0; 227 } 228 229 RTE_SET_USED(flags); 230 } 231 232 static int 233 test_tls_record_td_verify(uint8_t *output_text, uint32_t len, const struct tls_record_test_data *td, 234 bool silent) 235 { 236 if (len != td->output_text.len) { 237 printf("Output length (%d) not matching with expected (%d)\n", 238 len, td->output_text.len); 239 return TEST_FAILED; 240 } 241 242 if (memcmp(output_text, td->output_text.data, len)) { 243 if (silent) 244 return TEST_FAILED; 245 246 printf("[%s : %d] %s\n", __func__, __LINE__, "Output text not as expected\n"); 247 248 rte_hexdump(stdout, "expected", td->output_text.data, len); 249 rte_hexdump(stdout, "actual", output_text, len); 250 return TEST_FAILED; 251 } 252 253 return TEST_SUCCESS; 254 } 255 256 static int 257 test_tls_record_res_d_prepare(const uint8_t *output_text, uint32_t len, 258 const struct tls_record_test_data *td, 259 struct tls_record_test_data *res_d) 260 { 261 memcpy(res_d, td, sizeof(*res_d)); 262 263 memcpy(&res_d->input_text.data, output_text, len); 264 res_d->input_text.len = len; 265 res_d->output_text.len = td->input_text.len; 266 267 res_d->tls_record_xform.type = RTE_SECURITY_TLS_SESS_TYPE_READ; 268 if (res_d->aead) { 269 res_d->xform.aead.aead.op = RTE_CRYPTO_AEAD_OP_DECRYPT; 270 } else { 271 res_d->xform.chain.cipher.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT; 272 res_d->xform.chain.auth.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; 273 } 274 275 return TEST_SUCCESS; 276 } 277 278 static int 279 tls_record_hdr_verify(const struct tls_record_test_data *td, const uint8_t *output_text, 280 const struct tls_record_test_flags *flags) 281 { 282 uint16_t length, hdr_len; 283 uint8_t content_type; 284 285 if (td->tls_record_xform.ver == RTE_SECURITY_VERSION_TLS_1_2) { 286 const struct rte_tls_hdr *hdr = (const struct rte_tls_hdr *)output_text; 287 if (rte_be_to_cpu_16(hdr->version) != RTE_TLS_VERSION_1_2) { 288 printf("Incorrect header version [expected - %4x, received - %4x]\n", 289 RTE_TLS_VERSION_1_2, rte_be_to_cpu_16(hdr->version)); 290 return TEST_FAILED; 291 } 292 content_type = hdr->type; 293 length = rte_be_to_cpu_16(hdr->length); 294 hdr_len = sizeof(struct rte_tls_hdr); 295 } else if (td->tls_record_xform.ver == RTE_SECURITY_VERSION_TLS_1_3) { 296 const struct rte_tls_hdr *hdr = (const struct rte_tls_hdr *)output_text; 297 if (rte_be_to_cpu_16(hdr->version) != RTE_TLS_VERSION_1_2) { 298 printf("Incorrect header version [expected - %4x, received - %4x]\n", 299 RTE_TLS_VERSION_1_2, rte_be_to_cpu_16(hdr->version)); 300 return TEST_FAILED; 301 } 302 content_type = hdr->type; 303 length = rte_be_to_cpu_16(hdr->length); 304 hdr_len = sizeof(struct rte_tls_hdr); 305 } else if (td->tls_record_xform.ver == RTE_SECURITY_VERSION_DTLS_1_2) { 306 const struct rte_dtls_hdr *hdr = (const struct rte_dtls_hdr *)output_text; 307 if (rte_be_to_cpu_16(hdr->version) != RTE_DTLS_VERSION_1_2) { 308 printf("Incorrect header version [expected - %4x, received - %4x]\n", 309 RTE_DTLS_VERSION_1_2, rte_be_to_cpu_16(hdr->version)); 310 return TEST_FAILED; 311 } 312 content_type = hdr->type; 313 length = rte_be_to_cpu_16(hdr->length); 314 hdr_len = sizeof(struct rte_dtls_hdr); 315 } else { 316 return TEST_FAILED; 317 } 318 319 if (td->tls_record_xform.ver == RTE_SECURITY_VERSION_TLS_1_3) { 320 if (content_type != RTE_TLS_TYPE_APPDATA) { 321 printf("Incorrect content type in packet [expected - %d, received - %d]\n", 322 td->app_type, content_type); 323 return TEST_FAILED; 324 } 325 } else { 326 if (content_type != td->app_type) { 327 printf("Incorrect content type in packet [expected - %d, received - %d]\n", 328 td->app_type, content_type); 329 return TEST_FAILED; 330 } 331 } 332 333 if (!flags->opt_padding) { 334 if (length != td->output_text.len - hdr_len) { 335 printf("Incorrect packet length [expected - %d, received - %d]\n", 336 td->output_text.len - hdr_len, length); 337 return TEST_FAILED; 338 } 339 } else { 340 int pad_len = (flags->opt_padding * 8) > 256 ? 256 : (flags->opt_padding * 8); 341 int expect_len = td->output_text.len - hdr_len + pad_len; 342 343 if (length - expect_len > 32) { 344 printf("Incorrect packet length [expected - %d, received - %d]\n", 345 expect_len, length); 346 return TEST_FAILED; 347 } 348 349 } 350 351 return TEST_SUCCESS; 352 } 353 354 int 355 test_tls_record_post_process(const struct rte_mbuf *m, const struct tls_record_test_data *td, 356 struct tls_record_test_data *res_d, bool silent, 357 const struct tls_record_test_flags *flags) 358 { 359 uint8_t output_text[TEST_SEC_CIPHERTEXT_MAX_LEN]; 360 uint32_t len = rte_pktmbuf_pkt_len(m), data_len; 361 const struct rte_mbuf *seg; 362 const uint8_t *output; 363 int ret; 364 365 memset(output_text, 0, TEST_SEC_CIPHERTEXT_MAX_LEN); 366 367 /* 368 * Actual data in packet might be less in error cases, hence take minimum of pkt_len and sum 369 * of data_len. This is done to run through negative test cases. 370 */ 371 data_len = 0; 372 seg = m; 373 while (seg) { 374 data_len += seg->data_len; 375 seg = seg->next; 376 } 377 378 len = RTE_MIN(len, data_len); 379 TEST_ASSERT(len <= TEST_SEC_CIPHERTEXT_MAX_LEN, "Invalid packet length: %u", len); 380 381 /* Copy mbuf payload to continuous buffer */ 382 output = rte_pktmbuf_read(m, 0, len, output_text); 383 if (output != output_text) { 384 /* Single segment mbuf, copy manually */ 385 memcpy(output_text, output, len); 386 } 387 388 if (td->tls_record_xform.type == RTE_SECURITY_TLS_SESS_TYPE_WRITE) { 389 ret = tls_record_hdr_verify(td, output_text, flags); 390 if (ret != TEST_SUCCESS) 391 return ret; 392 } 393 394 /* 395 * In case of known vector tests & all record read (decrypt) tests, res_d provided would be 396 * NULL and output data need to be validated against expected. For record read (decrypt), 397 * output_text would be plain payload and for record write (encrypt), output_text would TLS 398 * record. Validate by comparing against known vectors. 399 * 400 * In case of combined mode tests, the output_text from TLS write (encrypt) operation (ie, 401 * TLS record) would need to be decrypted using a TLS read operation to obtain the plain 402 * text. Copy output_text to result data, 'res_d', so that inbound processing can be done. 403 */ 404 405 if (res_d == NULL) 406 return test_tls_record_td_verify(output_text, len, td, silent); 407 else 408 return test_tls_record_res_d_prepare(output_text, len, td, res_d); 409 } 410