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