util/find-docs-nits: Recognise SPARSE_ARRAY_OF
[oweals/openssl.git] / test / bad_dtls_test.c
1 /*
2  * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 /*
11  * Unit test for Cisco DTLS1_BAD_VER session resume, as used by
12  * AnyConnect VPN protocol.
13  *
14  * This is designed to exercise the code paths in
15  * http://git.infradead.org/users/dwmw2/openconnect.git/blob/HEAD:/dtls.c
16  * which have frequently been affected by regressions in DTLS1_BAD_VER
17  * support.
18  *
19  * Note that unlike other SSL tests, we don't test against our own SSL
20  * server method. Firstly because we don't have one; we *only* support
21  * DTLS1_BAD_VER as a client. And secondly because even if that were
22  * fixed up it's the wrong thing to test against - because if changes
23  * are made in generic DTLS code which don't take DTLS1_BAD_VER into
24  * account, there's plenty of scope for making those changes such that
25  * they break *both* the client and the server in the same way.
26  *
27  * So we handle the server side manually. In a session resume there isn't
28  * much to be done anyway.
29  */
30 #include <string.h>
31
32 #include <openssl/opensslconf.h>
33 #include <openssl/bio.h>
34 #include <openssl/crypto.h>
35 #include <openssl/evp.h>
36 #include <openssl/ssl.h>
37 #include <openssl/err.h>
38 #include <openssl/rand.h>
39 #include <openssl/kdf.h>
40 #include "../ssl/packet_locl.h"
41 #include "internal/nelem.h"
42 #include "testutil.h"
43
44 /* For DTLS1_BAD_VER packets the MAC doesn't include the handshake header */
45 #define MAC_OFFSET (DTLS1_RT_HEADER_LENGTH + DTLS1_HM_HEADER_LENGTH)
46
47 static unsigned char client_random[SSL3_RANDOM_SIZE];
48 static unsigned char server_random[SSL3_RANDOM_SIZE];
49
50 /* These are all generated locally, sized purely according to our own whim */
51 static unsigned char session_id[32];
52 static unsigned char master_secret[48];
53 static unsigned char cookie[20];
54
55 /* We've hard-coded the cipher suite; we know it's 104 bytes */
56 static unsigned char key_block[104];
57 #define mac_key (key_block + 20)
58 #define dec_key (key_block + 40)
59 #define enc_key (key_block + 56)
60
61 static EVP_MD_CTX *handshake_md;
62
63 static int do_PRF(const void *seed1, int seed1_len,
64                   const void *seed2, int seed2_len,
65                   const void *seed3, int seed3_len,
66                   unsigned char *out, int olen)
67 {
68     EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL);
69     size_t outlen = olen;
70
71     /* No error handling. If it all screws up, the test will fail anyway */
72     EVP_PKEY_derive_init(pctx);
73     EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_md5_sha1());
74     EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, master_secret, sizeof(master_secret));
75     EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed1, seed1_len);
76     EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed2, seed2_len);
77     EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed3, seed3_len);
78     EVP_PKEY_derive(pctx, out, &outlen);
79     EVP_PKEY_CTX_free(pctx);
80     return 1;
81 }
82
83 static SSL_SESSION *client_session(void)
84 {
85     static unsigned char session_asn1[] = {
86         0x30, 0x5F,              /* SEQUENCE, length 0x5F */
87         0x02, 0x01, 0x01,        /* INTEGER, SSL_SESSION_ASN1_VERSION */
88         0x02, 0x02, 0x01, 0x00,  /* INTEGER, DTLS1_BAD_VER */
89         0x04, 0x02, 0x00, 0x2F,  /* OCTET_STRING, AES128-SHA */
90         0x04, 0x20,              /* OCTET_STRING, session id */
91 #define SS_SESSID_OFS 15 /* Session ID goes here */
92         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96         0x04, 0x30,              /* OCTET_STRING, master secret */
97 #define SS_SECRET_OFS 49 /* Master secret goes here */
98         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104     };
105     const unsigned char *p = session_asn1;
106
107     /* Copy the randomly-generated fields into the above ASN1 */
108     memcpy(session_asn1 + SS_SESSID_OFS, session_id, sizeof(session_id));
109     memcpy(session_asn1 + SS_SECRET_OFS, master_secret, sizeof(master_secret));
110
111     return d2i_SSL_SESSION(NULL, &p, sizeof(session_asn1));
112 }
113
114 /* Returns 1 for initial ClientHello, 2 for ClientHello with cookie */
115 static int validate_client_hello(BIO *wbio)
116 {
117     PACKET pkt, pkt2;
118     long len;
119     unsigned char *data;
120     int cookie_found = 0;
121     unsigned int u = 0;
122
123     len = BIO_get_mem_data(wbio, (char **)&data);
124     if (!PACKET_buf_init(&pkt, data, len))
125         return 0;
126
127     /* Check record header type */
128     if (!PACKET_get_1(&pkt, &u) || u != SSL3_RT_HANDSHAKE)
129         return 0;
130     /* Version */
131     if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER)
132         return 0;
133     /* Skip the rest of the record header */
134     if (!PACKET_forward(&pkt, DTLS1_RT_HEADER_LENGTH - 3))
135         return 0;
136
137     /* Check it's a ClientHello */
138     if (!PACKET_get_1(&pkt, &u) || u != SSL3_MT_CLIENT_HELLO)
139         return 0;
140     /* Skip the rest of the handshake message header */
141     if (!PACKET_forward(&pkt, DTLS1_HM_HEADER_LENGTH - 1))
142         return 0;
143
144     /* Check client version */
145     if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER)
146         return 0;
147
148     /* Store random */
149     if (!PACKET_copy_bytes(&pkt, client_random, SSL3_RANDOM_SIZE))
150         return 0;
151
152     /* Check session id length and content */
153     if (!PACKET_get_length_prefixed_1(&pkt, &pkt2) ||
154         !PACKET_equal(&pkt2, session_id, sizeof(session_id)))
155         return 0;
156
157     /* Check cookie */
158     if (!PACKET_get_length_prefixed_1(&pkt, &pkt2))
159         return 0;
160     if (PACKET_remaining(&pkt2)) {
161         if (!PACKET_equal(&pkt2, cookie, sizeof(cookie)))
162             return 0;
163         cookie_found = 1;
164     }
165
166     /* Skip ciphers */
167     if (!PACKET_get_net_2(&pkt, &u) || !PACKET_forward(&pkt, u))
168         return 0;
169
170     /* Skip compression */
171     if (!PACKET_get_1(&pkt, &u) || !PACKET_forward(&pkt, u))
172         return 0;
173
174     /* Skip extensions */
175     if (!PACKET_get_net_2(&pkt, &u) || !PACKET_forward(&pkt, u))
176         return 0;
177
178     /* Now we are at the end */
179     if (PACKET_remaining(&pkt))
180         return 0;
181
182     /* Update handshake MAC for second ClientHello (with cookie) */
183     if (cookie_found && !EVP_DigestUpdate(handshake_md, data + MAC_OFFSET,
184                                           len - MAC_OFFSET))
185         return 0;
186
187     (void)BIO_reset(wbio);
188
189     return 1 + cookie_found;
190 }
191
192 static int send_hello_verify(BIO *rbio)
193 {
194     static unsigned char hello_verify[] = {
195         0x16, /* Handshake */
196         0x01, 0x00, /* DTLS1_BAD_VER */
197         0x00, 0x00, /* Epoch 0 */
198         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Seq# 0 */
199         0x00, 0x23, /* Length */
200         0x03, /* Hello Verify */
201         0x00, 0x00, 0x17, /* Length */
202         0x00, 0x00, /* Seq# 0 */
203         0x00, 0x00, 0x00, /* Fragment offset */
204         0x00, 0x00, 0x17, /* Fragment length */
205         0x01, 0x00, /* DTLS1_BAD_VER */
206         0x14, /* Cookie length */
207 #define HV_COOKIE_OFS 28 /* Cookie goes here */
208         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210         0x00, 0x00, 0x00, 0x00,
211     };
212
213     memcpy(hello_verify + HV_COOKIE_OFS, cookie, sizeof(cookie));
214
215     BIO_write(rbio, hello_verify, sizeof(hello_verify));
216
217     return 1;
218 }
219
220 static int send_server_hello(BIO *rbio)
221 {
222     static unsigned char server_hello[] = {
223         0x16, /* Handshake */
224         0x01, 0x00, /* DTLS1_BAD_VER */
225         0x00, 0x00, /* Epoch 0 */
226         0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* Seq# 1 */
227         0x00, 0x52, /* Length */
228         0x02, /* Server Hello */
229         0x00, 0x00, 0x46, /* Length */
230         0x00, 0x01, /* Seq# */
231         0x00, 0x00, 0x00, /* Fragment offset */
232         0x00, 0x00, 0x46, /* Fragment length */
233         0x01, 0x00, /* DTLS1_BAD_VER */
234 #define SH_RANDOM_OFS 27 /* Server random goes here */
235         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
236         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
238         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
239         0x20, /* Session ID length */
240 #define SH_SESSID_OFS 60 /* Session ID goes here */
241         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
242         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
243         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
245         0x00, 0x2f, /* Cipher suite AES128-SHA */
246         0x00, /* Compression null */
247     };
248     static unsigned char change_cipher_spec[] = {
249         0x14, /* Change Cipher Spec */
250         0x01, 0x00, /* DTLS1_BAD_VER */
251         0x00, 0x00, /* Epoch 0 */
252         0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* Seq# 2 */
253         0x00, 0x03, /* Length */
254         0x01, 0x00, 0x02, /* Message */
255     };
256
257     memcpy(server_hello + SH_RANDOM_OFS, server_random, sizeof(server_random));
258     memcpy(server_hello + SH_SESSID_OFS, session_id, sizeof(session_id));
259
260     if (!EVP_DigestUpdate(handshake_md, server_hello + MAC_OFFSET,
261                           sizeof(server_hello) - MAC_OFFSET))
262         return 0;
263
264     BIO_write(rbio, server_hello, sizeof(server_hello));
265     BIO_write(rbio, change_cipher_spec, sizeof(change_cipher_spec));
266
267     return 1;
268 }
269
270 /* Create header, HMAC, pad, encrypt and send a record */
271 static int send_record(BIO *rbio, unsigned char type, uint64_t seqnr,
272                        const void *msg, size_t len)
273 {
274     /* Note that the order of the record header fields on the wire,
275      * and in the HMAC, is different. So we just keep them in separate
276      * variables and handle them individually. */
277     static unsigned char epoch[2] = { 0x00, 0x01 };
278     static unsigned char seq[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
279     static unsigned char ver[2] = { 0x01, 0x00 }; /* DTLS1_BAD_VER */
280     unsigned char lenbytes[2];
281     HMAC_CTX *ctx;
282     EVP_CIPHER_CTX *enc_ctx;
283     unsigned char iv[16];
284     unsigned char pad;
285     unsigned char *enc;
286
287     seq[0] = (seqnr >> 40) & 0xff;
288     seq[1] = (seqnr >> 32) & 0xff;
289     seq[2] = (seqnr >> 24) & 0xff;
290     seq[3] = (seqnr >> 16) & 0xff;
291     seq[4] = (seqnr >> 8) & 0xff;
292     seq[5] = seqnr & 0xff;
293
294     pad = 15 - ((len + SHA_DIGEST_LENGTH) % 16);
295     enc = OPENSSL_malloc(len + SHA_DIGEST_LENGTH + 1 + pad);
296     if (enc == NULL)
297         return 0;
298
299     /* Copy record to encryption buffer */
300     memcpy(enc, msg, len);
301
302     /* Append HMAC to data */
303     ctx = HMAC_CTX_new();
304     HMAC_Init_ex(ctx, mac_key, 20, EVP_sha1(), NULL);
305     HMAC_Update(ctx, epoch, 2);
306     HMAC_Update(ctx, seq, 6);
307     HMAC_Update(ctx, &type, 1);
308     HMAC_Update(ctx, ver, 2); /* Version */
309     lenbytes[0] = (unsigned char)(len >> 8);
310     lenbytes[1] = (unsigned char)(len);
311     HMAC_Update(ctx, lenbytes, 2); /* Length */
312     HMAC_Update(ctx, enc, len); /* Finally the data itself */
313     HMAC_Final(ctx, enc + len, NULL);
314     HMAC_CTX_free(ctx);
315
316     /* Append padding bytes */
317     len += SHA_DIGEST_LENGTH;
318     do {
319         enc[len++] = pad;
320     } while (len % 16);
321
322     /* Generate IV, and encrypt */
323     RAND_bytes(iv, sizeof(iv));
324     enc_ctx = EVP_CIPHER_CTX_new();
325     EVP_CipherInit_ex(enc_ctx, EVP_aes_128_cbc(), NULL, enc_key, iv, 1);
326     EVP_Cipher(enc_ctx, enc, enc, len);
327     EVP_CIPHER_CTX_free(enc_ctx);
328
329     /* Finally write header (from fragmented variables), IV and encrypted record */
330     BIO_write(rbio, &type, 1);
331     BIO_write(rbio, ver, 2);
332     BIO_write(rbio, epoch, 2);
333     BIO_write(rbio, seq, 6);
334     lenbytes[0] = (unsigned char)((len + sizeof(iv)) >> 8);
335     lenbytes[1] = (unsigned char)(len + sizeof(iv));
336     BIO_write(rbio, lenbytes, 2);
337
338     BIO_write(rbio, iv, sizeof(iv));
339     BIO_write(rbio, enc, len);
340
341     OPENSSL_free(enc);
342     return 1;
343 }
344
345 static int send_finished(SSL *s, BIO *rbio)
346 {
347     static unsigned char finished_msg[DTLS1_HM_HEADER_LENGTH +
348                                       TLS1_FINISH_MAC_LENGTH] = {
349         0x14, /* Finished */
350         0x00, 0x00, 0x0c, /* Length */
351         0x00, 0x03, /* Seq# 3 */
352         0x00, 0x00, 0x00, /* Fragment offset */
353         0x00, 0x00, 0x0c, /* Fragment length */
354         /* Finished MAC (12 bytes) */
355     };
356     unsigned char handshake_hash[EVP_MAX_MD_SIZE];
357
358     /* Derive key material */
359     do_PRF(TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE,
360            server_random, SSL3_RANDOM_SIZE,
361            client_random, SSL3_RANDOM_SIZE,
362            key_block, sizeof(key_block));
363
364     /* Generate Finished MAC */
365     if (!EVP_DigestFinal_ex(handshake_md, handshake_hash, NULL))
366         return 0;
367
368     do_PRF(TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
369            handshake_hash, EVP_MD_CTX_size(handshake_md),
370            NULL, 0,
371            finished_msg + DTLS1_HM_HEADER_LENGTH, TLS1_FINISH_MAC_LENGTH);
372
373     return send_record(rbio, SSL3_RT_HANDSHAKE, 0,
374                        finished_msg, sizeof(finished_msg));
375 }
376
377 static int validate_ccs(BIO *wbio)
378 {
379     PACKET pkt;
380     long len;
381     unsigned char *data;
382     unsigned int u;
383
384     len = BIO_get_mem_data(wbio, (char **)&data);
385     if (!PACKET_buf_init(&pkt, data, len))
386         return 0;
387
388     /* Check record header type */
389     if (!PACKET_get_1(&pkt, &u) || u != SSL3_RT_CHANGE_CIPHER_SPEC)
390         return 0;
391     /* Version */
392     if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER)
393         return 0;
394     /* Skip the rest of the record header */
395     if (!PACKET_forward(&pkt, DTLS1_RT_HEADER_LENGTH - 3))
396         return 0;
397
398     /* Check ChangeCipherSpec message */
399     if (!PACKET_get_1(&pkt, &u) || u != SSL3_MT_CCS)
400         return 0;
401     /* A DTLS1_BAD_VER ChangeCipherSpec also contains the
402      * handshake sequence number (which is 2 here) */
403     if (!PACKET_get_net_2(&pkt, &u) || u != 0x0002)
404         return 0;
405
406     /* Now check the Finished packet */
407     if (!PACKET_get_1(&pkt, &u) || u != SSL3_RT_HANDSHAKE)
408         return 0;
409     if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER)
410         return 0;
411
412     /* Check epoch is now 1 */
413     if (!PACKET_get_net_2(&pkt, &u) || u != 0x0001)
414         return 0;
415
416     /* That'll do for now. If OpenSSL accepted *our* Finished packet
417      * then it's evidently remembered that DTLS1_BAD_VER doesn't
418      * include the handshake header in the MAC. There's not a lot of
419      * point in implementing decryption here, just to check that it
420      * continues to get it right for one more packet. */
421
422     return 1;
423 }
424
425 #define NODROP(x) { x##UL, 0 }
426 #define DROP(x)   { x##UL, 1 }
427
428 static struct {
429     uint64_t seq;
430     int drop;
431 } tests[] = {
432     NODROP(1), NODROP(3), NODROP(2),
433     NODROP(0x1234), NODROP(0x1230), NODROP(0x1235),
434     NODROP(0xffff), NODROP(0x10001), NODROP(0xfffe), NODROP(0x10000),
435     DROP(0x10001), DROP(0xff), NODROP(0x100000), NODROP(0x800000), NODROP(0x7fffe1),
436     NODROP(0xffffff), NODROP(0x1000000), NODROP(0xfffffe), DROP(0xffffff), NODROP(0x1000010),
437     NODROP(0xfffffd), NODROP(0x1000011), DROP(0x12), NODROP(0x1000012),
438     NODROP(0x1ffffff), NODROP(0x2000000), DROP(0x1ff00fe), NODROP(0x2000001),
439     NODROP(0x20fffff), NODROP(0x2105500), DROP(0x20ffffe), NODROP(0x21054ff),
440     NODROP(0x211ffff), DROP(0x2110000), NODROP(0x2120000)
441     /* The last test should be NODROP, because a DROP wouldn't get tested. */
442 };
443
444 static int test_bad_dtls(void)
445 {
446     SSL_SESSION *sess = NULL;
447     SSL_CTX *ctx = NULL;
448     SSL *con = NULL;
449     BIO *rbio = NULL;
450     BIO *wbio = NULL;
451     time_t now = 0;
452     int testresult = 0;
453     int ret;
454     int i;
455
456     RAND_bytes(session_id, sizeof(session_id));
457     RAND_bytes(master_secret, sizeof(master_secret));
458     RAND_bytes(cookie, sizeof(cookie));
459     RAND_bytes(server_random + 4, sizeof(server_random) - 4);
460
461     now = time(NULL);
462     memcpy(server_random, &now, sizeof(now));
463
464     sess = client_session();
465     if (!TEST_ptr(sess))
466         goto end;
467
468     handshake_md = EVP_MD_CTX_new();
469     if (!TEST_ptr(handshake_md)
470             || !TEST_true(EVP_DigestInit_ex(handshake_md, EVP_md5_sha1(),
471                                             NULL)))
472         goto end;
473
474     ctx = SSL_CTX_new(DTLS_client_method());
475     if (!TEST_ptr(ctx)
476             || !TEST_true(SSL_CTX_set_min_proto_version(ctx, DTLS1_BAD_VER))
477             || !TEST_true(SSL_CTX_set_max_proto_version(ctx, DTLS1_BAD_VER))
478             || !TEST_true(SSL_CTX_set_cipher_list(ctx, "AES128-SHA")))
479         goto end;
480
481     con = SSL_new(ctx);
482     if (!TEST_ptr(con)
483             || !TEST_true(SSL_set_session(con, sess)))
484         goto end;
485     SSL_SESSION_free(sess);
486
487     rbio = BIO_new(BIO_s_mem());
488     wbio = BIO_new(BIO_s_mem());
489
490     if (!TEST_ptr(rbio)
491             || !TEST_ptr(wbio))
492         goto end;
493
494     SSL_set_bio(con, rbio, wbio);
495
496     if (!TEST_true(BIO_up_ref(rbio))) {
497         /*
498          * We can't up-ref but we assigned ownership to con, so we shouldn't
499          * free in the "end" block
500          */
501         rbio = wbio = NULL;
502         goto end;
503     }
504
505     if (!TEST_true(BIO_up_ref(wbio))) {
506         wbio = NULL;
507         goto end;
508     }
509
510     SSL_set_connect_state(con);
511
512     /* Send initial ClientHello */
513     ret = SSL_do_handshake(con);
514     if (!TEST_int_le(ret, 0)
515             || !TEST_int_eq(SSL_get_error(con, ret), SSL_ERROR_WANT_READ)
516             || !TEST_int_eq(validate_client_hello(wbio), 1)
517             || !TEST_true(send_hello_verify(rbio)))
518         goto end;
519
520     ret = SSL_do_handshake(con);
521     if (!TEST_int_le(ret, 0)
522             || !TEST_int_eq(SSL_get_error(con, ret), SSL_ERROR_WANT_READ)
523             || !TEST_int_eq(validate_client_hello(wbio), 2)
524             || !TEST_true(send_server_hello(rbio)))
525         goto end;
526
527     ret = SSL_do_handshake(con);
528     if (!TEST_int_le(ret, 0)
529             || !TEST_int_eq(SSL_get_error(con, ret), SSL_ERROR_WANT_READ)
530             || !TEST_true(send_finished(con, rbio)))
531         goto end;
532
533     ret = SSL_do_handshake(con);
534     if (!TEST_int_gt(ret, 0)
535             || !TEST_true(validate_ccs(wbio)))
536         goto end;
537
538     /* While we're here and crafting packets by hand, we might as well do a
539        bit of a stress test on the DTLS record replay handling. Not Cisco-DTLS
540        specific but useful anyway for the general case. It's been broken
541        before, and in fact was broken even for a basic 0, 2, 1 test case
542        when this test was first added.... */
543     for (i = 0; i < (int)OSSL_NELEM(tests); i++) {
544         uint64_t recv_buf[2];
545
546         if (!TEST_true(send_record(rbio, SSL3_RT_APPLICATION_DATA, tests[i].seq,
547                                    &tests[i].seq, sizeof(uint64_t)))) {
548             TEST_error("Failed to send data seq #0x%x%08x (%d)\n",
549                        (unsigned int)(tests[i].seq >> 32), (unsigned int)tests[i].seq, i);
550             goto end;
551         }
552
553         if (tests[i].drop)
554             continue;
555
556         ret = SSL_read(con, recv_buf, 2 * sizeof(uint64_t));
557         if (!TEST_int_eq(ret, (int)sizeof(uint64_t))) {
558             TEST_error("SSL_read failed or wrong size on seq#0x%x%08x (%d)\n",
559                        (unsigned int)(tests[i].seq >> 32), (unsigned int)tests[i].seq, i);
560             goto end;
561         }
562         if (!TEST_true(recv_buf[0] == tests[i].seq))
563             goto end;
564     }
565
566     /* The last test cannot be DROP() */
567     if (!TEST_false(tests[i-1].drop))
568         goto end;
569
570     testresult = 1;
571
572  end:
573     BIO_free(rbio);
574     BIO_free(wbio);
575     SSL_free(con);
576     SSL_CTX_free(ctx);
577     EVP_MD_CTX_free(handshake_md);
578
579     return testresult;
580 }
581
582 int setup_tests(void)
583 {
584     ADD_TEST(test_bad_dtls);
585     return 1;
586 }