Branch data Line data Source code
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 : 0 : 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 [ # # ]: 0 : if ((td->tls_record_xform.type == RTE_SECURITY_TLS_SESS_TYPE_READ) &&
21 [ # # ]: 0 : td->ar_packet) {
22 [ # # ]: 0 : if (op->status != RTE_CRYPTO_OP_STATUS_ERROR) {
23 : : printf("Anti replay test case failed\n");
24 : 0 : return TEST_FAILED;
25 : : } else {
26 : : return TEST_SUCCESS;
27 : : }
28 : : }
29 : :
30 [ # # ]: 0 : if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS)
31 : : ret = TEST_FAILED;
32 : :
33 : : return ret;
34 : : }
35 : :
36 : : int
37 : 0 : 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 : 0 : return 0;
47 : : }
48 : :
49 : : void
50 [ # # ]: 0 : 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 : 0 : memcpy(td_in->output_text.data, td_out->input_text.data, td_out->input_text.len);
57 : 0 : 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 : 0 : memcpy(td_in->input_text.data, td_out->output_text.data, td_out->output_text.len);
61 : 0 : td_in->input_text.len = td_out->output_text.len;
62 : :
63 : 0 : td_in->tls_record_xform.type = RTE_SECURITY_TLS_SESS_TYPE_READ;
64 : :
65 [ # # ]: 0 : if (td_in->aead) {
66 : 0 : td_in->xform.aead.aead.op = RTE_CRYPTO_AEAD_OP_DECRYPT;
67 : : } else {
68 : 0 : td_in->xform.chain.auth.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
69 : 0 : td_in->xform.chain.cipher.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT;
70 : : }
71 : 0 : }
72 : :
73 : : int
74 : 0 : 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 [ # # ]: 0 : if ((flags->tls_version == RTE_SECURITY_VERSION_TLS_1_3) &&
83 [ # # ]: 0 : (param1->type != RTE_CRYPTO_SYM_XFORM_AEAD))
84 : : return TEST_SKIPPED;
85 : :
86 : 0 : memset(td_array, 0, nb_td * sizeof(*td));
87 : :
88 [ # # ]: 0 : for (i = 0; i < nb_td; i++) {
89 : 0 : td = &td_array[i];
90 : :
91 : : /* Prepare fields based on param */
92 : :
93 [ # # ]: 0 : if (param1->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
94 : : /* Copy template for packet & key fields */
95 [ # # # # ]: 0 : 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 : 0 : td->aead = true;
108 : 0 : td->xform.aead.aead.algo = param1->alg.aead;
109 : 0 : td->xform.aead.aead.key.length = param1->key_length;
110 : 0 : td->xform.aead.aead.digest_length = param1->digest_length;
111 : : } else {
112 : : /* Copy template for packet & key fields */
113 [ # # ]: 0 : 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 : 0 : td->aead = false;
119 : 0 : td->xform.chain.cipher.cipher.algo = param1->alg.cipher;
120 : 0 : td->xform.chain.cipher.cipher.key.length = param1->key_length;
121 : 0 : td->xform.chain.cipher.cipher.iv.length = param1->iv_length;
122 : 0 : td->xform.chain.auth.auth.algo = param2->alg.auth;
123 : 0 : td->xform.chain.auth.auth.key.length = param2->key_length;
124 : 0 : td->xform.chain.auth.auth.digest_length = param2->digest_length;
125 : : }
126 : :
127 [ # # ]: 0 : if (flags->data_walkthrough || flags->zero_len) {
128 : 0 : test_sec_proto_pattern_set(td->input_text.data, data_len);
129 : 0 : td->input_text.len = data_len;
130 : : }
131 : :
132 [ # # ]: 0 : if (flags->content_type == TLS_RECORD_TEST_CONTENT_TYPE_CUSTOM)
133 : 0 : td->app_type = RTE_TLS_TYPE_MAX;
134 [ # # ]: 0 : else if (flags->content_type == TLS_RECORD_TEST_CONTENT_TYPE_HANDSHAKE)
135 : 0 : td->app_type = RTE_TLS_TYPE_HANDSHAKE;
136 : :
137 : 0 : tls_pkt_size = td->input_text.len;
138 : :
139 [ # # ]: 0 : if (!td->aead) {
140 : 0 : mac_len = td->xform.chain.auth.auth.digest_length;
141 : : min_padding = 1;
142 [ # # # ]: 0 : 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 : 0 : case RTE_CRYPTO_CIPHER_AES_CBC:
148 : : roundup_len = 16;
149 : : exp_nonce_len = 16;
150 : 0 : break;
151 : 0 : default:
152 : : roundup_len = 0;
153 : : exp_nonce_len = 0;
154 : 0 : break;
155 : : }
156 : : } else {
157 : 0 : mac_len = td->xform.aead.aead.digest_length;
158 : : min_padding = 0;
159 : : roundup_len = 0;
160 [ # # ]: 0 : 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 [ # # # # ]: 0 : 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 : 0 : 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 : 0 : tls_pkt_size += 1;
174 : 0 : break;
175 : 0 : case RTE_SECURITY_VERSION_DTLS_1_2:
176 : : hdr_len = sizeof(struct rte_dtls_hdr);
177 : 0 : break;
178 : : default:
179 : : return TEST_SKIPPED;
180 : : }
181 : :
182 : 0 : tls_pkt_size += mac_len;
183 : :
184 : : /* Padding */
185 : 0 : tls_pkt_size += min_padding;
186 : :
187 [ # # ]: 0 : if (roundup_len)
188 : 0 : tls_pkt_size = RTE_ALIGN_MUL_CEIL(tls_pkt_size, roundup_len);
189 : :
190 : : /* Explicit nonce */
191 : 0 : tls_pkt_size += exp_nonce_len;
192 : :
193 : : /* Add TLS header */
194 : 0 : tls_pkt_size += hdr_len;
195 : :
196 : 0 : td->output_text.len = tls_pkt_size;
197 : :
198 : : }
199 : : return TEST_SUCCESS;
200 : : }
201 : :
202 : : void
203 : 0 : 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 [ # # ]: 0 : for (i = 0; i < nb_td; i++) {
210 : 0 : memcpy(td_inb[i].output_text.data, td_outb[i].input_text.data,
211 [ # # ]: 0 : td_outb[i].input_text.len);
212 : 0 : 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 [ # # ]: 0 : if (flags->pkt_corruption)
216 : 0 : td_inb[i].input_text.data[0] = ~td_inb[i].input_text.data[0];
217 : :
218 : : /* Clear outbound specific flags */
219 : 0 : td_inb[i].tls_record_xform.options.iv_gen_disable = 0;
220 : : }
221 : :
222 : : RTE_SET_USED(flags);
223 : 0 : }
224 : :
225 : : static int
226 : 0 : test_tls_record_td_verify(uint8_t *output_text, uint32_t len, const struct tls_record_test_data *td,
227 : : bool silent)
228 : : {
229 [ # # ]: 0 : if (len != td->output_text.len) {
230 : : printf("Output length (%d) not matching with expected (%d)\n",
231 : : len, td->output_text.len);
232 : 0 : return TEST_FAILED;
233 : : }
234 : :
235 [ # # ]: 0 : if (memcmp(output_text, td->output_text.data, len)) {
236 [ # # ]: 0 : if (silent)
237 : : return TEST_FAILED;
238 : :
239 : : printf("[%s : %d] %s\n", __func__, __LINE__, "Output text not as expected\n");
240 : :
241 : 0 : rte_hexdump(stdout, "expected", td->output_text.data, len);
242 : 0 : rte_hexdump(stdout, "actual", output_text, len);
243 : 0 : return TEST_FAILED;
244 : : }
245 : :
246 : : return TEST_SUCCESS;
247 : : }
248 : :
249 : : static int
250 [ # # ]: 0 : 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 : 0 : memcpy(&res_d->input_text.data, output_text, len);
257 : 0 : res_d->input_text.len = len;
258 : 0 : res_d->output_text.len = td->input_text.len;
259 : :
260 : 0 : res_d->tls_record_xform.type = RTE_SECURITY_TLS_SESS_TYPE_READ;
261 [ # # ]: 0 : if (res_d->aead) {
262 : 0 : res_d->xform.aead.aead.op = RTE_CRYPTO_AEAD_OP_DECRYPT;
263 : : } else {
264 : 0 : res_d->xform.chain.cipher.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT;
265 : 0 : res_d->xform.chain.auth.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
266 : : }
267 : :
268 : 0 : return TEST_SUCCESS;
269 : : }
270 : :
271 : : static int
272 : 0 : tls_record_hdr_verify(const struct tls_record_test_data *td, const uint8_t *output_text,
273 : : const struct tls_record_test_flags *flags)
274 : : {
275 : : uint16_t length, hdr_len;
276 : : uint8_t content_type;
277 : :
278 [ # # ]: 0 : if (td->tls_record_xform.ver == RTE_SECURITY_VERSION_TLS_1_2) {
279 : : const struct rte_tls_hdr *hdr = (const struct rte_tls_hdr *)output_text;
280 [ # # # # ]: 0 : if (rte_be_to_cpu_16(hdr->version) != RTE_TLS_VERSION_1_2) {
281 [ # # ]: 0 : printf("Incorrect header version [expected - %4x, received - %4x]\n",
282 : : RTE_TLS_VERSION_1_2, rte_be_to_cpu_16(hdr->version));
283 : 0 : return TEST_FAILED;
284 : : }
285 : 0 : content_type = hdr->type;
286 [ # # ]: 0 : length = rte_be_to_cpu_16(hdr->length);
287 : : hdr_len = sizeof(struct rte_tls_hdr);
288 [ # # ]: 0 : } else if (td->tls_record_xform.ver == RTE_SECURITY_VERSION_TLS_1_3) {
289 : : const struct rte_tls_hdr *hdr = (const struct rte_tls_hdr *)output_text;
290 [ # # # # ]: 0 : if (rte_be_to_cpu_16(hdr->version) != RTE_TLS_VERSION_1_2) {
291 [ # # ]: 0 : printf("Incorrect header version [expected - %4x, received - %4x]\n",
292 : : RTE_TLS_VERSION_1_2, rte_be_to_cpu_16(hdr->version));
293 : 0 : return TEST_FAILED;
294 : : }
295 : 0 : content_type = hdr->type;
296 [ # # ]: 0 : length = rte_be_to_cpu_16(hdr->length);
297 : : hdr_len = sizeof(struct rte_tls_hdr);
298 [ # # ]: 0 : } else if (td->tls_record_xform.ver == RTE_SECURITY_VERSION_DTLS_1_2) {
299 : : const struct rte_dtls_hdr *hdr = (const struct rte_dtls_hdr *)output_text;
300 [ # # # # ]: 0 : if (rte_be_to_cpu_16(hdr->version) != RTE_DTLS_VERSION_1_2) {
301 [ # # ]: 0 : printf("Incorrect header version [expected - %4x, received - %4x]\n",
302 : : RTE_DTLS_VERSION_1_2, rte_be_to_cpu_16(hdr->version));
303 : 0 : return TEST_FAILED;
304 : : }
305 : 0 : content_type = hdr->type;
306 [ # # ]: 0 : length = rte_be_to_cpu_16(hdr->length);
307 : : hdr_len = sizeof(struct rte_dtls_hdr);
308 : : } else {
309 : : return TEST_FAILED;
310 : : }
311 : :
312 [ # # ]: 0 : if (td->tls_record_xform.ver == RTE_SECURITY_VERSION_TLS_1_3) {
313 [ # # ]: 0 : if (content_type != RTE_TLS_TYPE_APPDATA) {
314 : 0 : printf("Incorrect content type in packet [expected - %d, received - %d]\n",
315 : 0 : td->app_type, content_type);
316 : 0 : return TEST_FAILED;
317 : : }
318 : : } else {
319 [ # # ]: 0 : if (content_type != td->app_type) {
320 : 0 : printf("Incorrect content type in packet [expected - %d, received - %d]\n",
321 : : td->app_type, content_type);
322 : 0 : return TEST_FAILED;
323 : : }
324 : : }
325 : :
326 [ # # ]: 0 : if (!flags->opt_padding) {
327 [ # # ]: 0 : if (length != td->output_text.len - hdr_len) {
328 : 0 : printf("Incorrect packet length [expected - %d, received - %d]\n",
329 : : td->output_text.len - hdr_len, length);
330 : 0 : return TEST_FAILED;
331 : : }
332 : : } else {
333 : 0 : int pad_len = (flags->opt_padding * 8) > 256 ? 256 : (flags->opt_padding * 8);
334 : 0 : int expect_len = td->output_text.len - hdr_len + pad_len;
335 : :
336 [ # # ]: 0 : if (length - expect_len > 32) {
337 : : printf("Incorrect packet length [expected - %d, received - %d]\n",
338 : : expect_len, length);
339 : 0 : return TEST_FAILED;
340 : : }
341 : :
342 : : }
343 : :
344 : : return TEST_SUCCESS;
345 : : }
346 : :
347 : : int
348 : 0 : test_tls_record_post_process(const struct rte_mbuf *m, const struct tls_record_test_data *td,
349 : : struct tls_record_test_data *res_d, bool silent,
350 : : const struct tls_record_test_flags *flags)
351 : : {
352 : : uint8_t output_text[TEST_SEC_CIPHERTEXT_MAX_LEN];
353 : 0 : uint32_t len = rte_pktmbuf_pkt_len(m), data_len;
354 : : const struct rte_mbuf *seg;
355 : : const uint8_t *output;
356 : : int ret;
357 : :
358 : : memset(output_text, 0, TEST_SEC_CIPHERTEXT_MAX_LEN);
359 : :
360 : : /*
361 : : * Actual data in packet might be less in error cases, hence take minimum of pkt_len and sum
362 : : * of data_len. This is done to run through negative test cases.
363 : : */
364 : : data_len = 0;
365 : : seg = m;
366 [ # # ]: 0 : while (seg) {
367 : 0 : data_len += seg->data_len;
368 : 0 : seg = seg->next;
369 : : }
370 : :
371 : 0 : len = RTE_MIN(len, data_len);
372 [ # # ]: 0 : TEST_ASSERT(len <= TEST_SEC_CIPHERTEXT_MAX_LEN, "Invalid packet length: %u", len);
373 : :
374 : : /* Copy mbuf payload to continuous buffer */
375 : : output = rte_pktmbuf_read(m, 0, len, output_text);
376 [ # # ]: 0 : if (output != output_text) {
377 : : /* Single segment mbuf, copy manually */
378 : 0 : memcpy(output_text, output, len);
379 : : }
380 : :
381 [ # # ]: 0 : if (td->tls_record_xform.type == RTE_SECURITY_TLS_SESS_TYPE_WRITE) {
382 : 0 : ret = tls_record_hdr_verify(td, output_text, flags);
383 [ # # ]: 0 : if (ret != TEST_SUCCESS)
384 : : return ret;
385 : : }
386 : :
387 : : /*
388 : : * In case of known vector tests & all record read (decrypt) tests, res_d provided would be
389 : : * NULL and output data need to be validated against expected. For record read (decrypt),
390 : : * output_text would be plain payload and for record write (encrypt), output_text would TLS
391 : : * record. Validate by comparing against known vectors.
392 : : *
393 : : * In case of combined mode tests, the output_text from TLS write (encrypt) operation (ie,
394 : : * TLS record) would need to be decrypted using a TLS read operation to obtain the plain
395 : : * text. Copy output_text to result data, 'res_d', so that inbound processing can be done.
396 : : */
397 : :
398 [ # # ]: 0 : if (res_d == NULL)
399 : 0 : return test_tls_record_td_verify(output_text, len, td, silent);
400 : : else
401 : 0 : return test_tls_record_res_d_prepare(output_text, len, td, res_d);
402 : : }
|