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