bad_dtls_test.c revision 306195
1/*
2 * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (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/* On Windows this will include <winsock2.h> and thus it needs to be
33 * included *before* anything that includes <windows.h>. Ick. */
34#include "e_os.h" /* for 'inline' */
35
36#include <openssl/bio.h>
37#include <openssl/crypto.h>
38#include <openssl/evp.h>
39#include <openssl/ssl.h>
40#include <openssl/err.h>
41#include <openssl/rand.h>
42
43/* PACKET functions lifted from OpenSSL 1.1's ssl/packet_locl.h */
44typedef struct {
45    /* Pointer to where we are currently reading from */
46    const unsigned char *curr;
47    /* Number of bytes remaining */
48    size_t remaining;
49} PACKET;
50
51/* Internal unchecked shorthand; don't use outside this file. */
52static inline void packet_forward(PACKET *pkt, size_t len)
53{
54    pkt->curr += len;
55    pkt->remaining -= len;
56}
57
58/*
59 * Returns the number of bytes remaining to be read in the PACKET
60 */
61static inline size_t PACKET_remaining(const PACKET *pkt)
62{
63    return pkt->remaining;
64}
65
66/*
67 * Initialise a PACKET with |len| bytes held in |buf|. This does not make a
68 * copy of the data so |buf| must be present for the whole time that the PACKET
69 * is being used.
70 */
71static inline int PACKET_buf_init(PACKET *pkt,
72                                              const unsigned char *buf,
73                                              size_t len)
74{
75    /* Sanity check for negative values. */
76    if (len > (size_t)65536)
77        return 0;
78
79    pkt->curr = buf;
80    pkt->remaining = len;
81    return 1;
82}
83
84/*
85 * Returns 1 if the packet has length |num| and its contents equal the |num|
86 * bytes read from |ptr|. Returns 0 otherwise (lengths or contents not equal).
87 * If lengths are equal, performs the comparison in constant time.
88 */
89static inline int PACKET_equal(const PACKET *pkt, const void *ptr,
90                                           size_t num)
91{
92    if (PACKET_remaining(pkt) != num)
93        return 0;
94    return CRYPTO_memcmp(pkt->curr, ptr, num) == 0;
95}
96
97/*
98 * Peek ahead at 2 bytes in network order from |pkt| and store the value in
99 * |*data|
100 */
101static inline int PACKET_peek_net_2(const PACKET *pkt,
102                                                unsigned int *data)
103{
104    if (PACKET_remaining(pkt) < 2)
105        return 0;
106
107    *data = ((unsigned int)(*pkt->curr)) << 8;
108    *data |= *(pkt->curr + 1);
109
110    return 1;
111}
112
113/* Equivalent of n2s */
114/* Get 2 bytes in network order from |pkt| and store the value in |*data| */
115static inline int PACKET_get_net_2(PACKET *pkt,
116                                               unsigned int *data)
117{
118    if (!PACKET_peek_net_2(pkt, data))
119        return 0;
120
121    packet_forward(pkt, 2);
122
123    return 1;
124}
125
126/* Peek ahead at 1 byte from |pkt| and store the value in |*data| */
127static inline int PACKET_peek_1(const PACKET *pkt,
128                                            unsigned int *data)
129{
130    if (!PACKET_remaining(pkt))
131        return 0;
132
133    *data = *pkt->curr;
134
135    return 1;
136}
137
138/* Get 1 byte from |pkt| and store the value in |*data| */
139static inline int PACKET_get_1(PACKET *pkt, unsigned int *data)
140{
141    if (!PACKET_peek_1(pkt, data))
142        return 0;
143
144    packet_forward(pkt, 1);
145
146    return 1;
147}
148
149/*
150 * Peek ahead at |len| bytes from the |pkt| and store a pointer to them in
151 * |*data|. This just points at the underlying buffer that |pkt| is using. The
152 * caller should not free this data directly (it will be freed when the
153 * underlying buffer gets freed
154 */
155static inline int PACKET_peek_bytes(const PACKET *pkt,
156                                                const unsigned char **data,
157                                                size_t len)
158{
159    if (PACKET_remaining(pkt) < len)
160        return 0;
161
162    *data = pkt->curr;
163
164    return 1;
165}
166
167/*
168 * Read |len| bytes from the |pkt| and store a pointer to them in |*data|. This
169 * just points at the underlying buffer that |pkt| is using. The caller should
170 * not free this data directly (it will be freed when the underlying buffer gets
171 * freed
172 */
173static inline int PACKET_get_bytes(PACKET *pkt,
174                                               const unsigned char **data,
175                                               size_t len)
176{
177    if (!PACKET_peek_bytes(pkt, data, len))
178        return 0;
179
180    packet_forward(pkt, len);
181
182    return 1;
183}
184
185/* Peek ahead at |len| bytes from |pkt| and copy them to |data| */
186static inline int PACKET_peek_copy_bytes(const PACKET *pkt,
187                                                     unsigned char *data,
188                                                     size_t len)
189{
190    if (PACKET_remaining(pkt) < len)
191        return 0;
192
193    memcpy(data, pkt->curr, len);
194
195    return 1;
196}
197
198/*
199 * Read |len| bytes from |pkt| and copy them to |data|.
200 * The caller is responsible for ensuring that |data| can hold |len| bytes.
201 */
202static inline int PACKET_copy_bytes(PACKET *pkt,
203                                                unsigned char *data,
204                                                size_t len)
205{
206    if (!PACKET_peek_copy_bytes(pkt, data, len))
207        return 0;
208
209    packet_forward(pkt, len);
210
211    return 1;
212}
213
214
215/* Move the current reading position forward |len| bytes */
216static inline int PACKET_forward(PACKET *pkt, size_t len)
217{
218    if (PACKET_remaining(pkt) < len)
219        return 0;
220
221    packet_forward(pkt, len);
222
223    return 1;
224}
225
226/*
227 * Reads a variable-length vector prefixed with a one-byte length, and stores
228 * the contents in |subpkt|. |pkt| can equal |subpkt|.
229 * Data is not copied: the |subpkt| packet will share its underlying buffer with
230 * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|.
231 * Upon failure, the original |pkt| and |subpkt| are not modified.
232 */
233static inline int PACKET_get_length_prefixed_1(PACKET *pkt,
234                                                           PACKET *subpkt)
235{
236    unsigned int length;
237    const unsigned char *data;
238    PACKET tmp = *pkt;
239    if (!PACKET_get_1(&tmp, &length) ||
240        !PACKET_get_bytes(&tmp, &data, (size_t)length)) {
241        return 0;
242    }
243
244    *pkt = tmp;
245    subpkt->curr = data;
246    subpkt->remaining = length;
247
248    return 1;
249}
250
251#define OSSL_NELEM(x)    (sizeof(x)/sizeof(x[0]))
252
253/* For DTLS1_BAD_VER packets the MAC doesn't include the handshake header */
254#define MAC_OFFSET (DTLS1_RT_HEADER_LENGTH + DTLS1_HM_HEADER_LENGTH)
255
256static unsigned char client_random[SSL3_RANDOM_SIZE];
257static unsigned char server_random[SSL3_RANDOM_SIZE];
258
259/* These are all generated locally, sized purely according to our own whim */
260static unsigned char session_id[32];
261static unsigned char master_secret[48];
262static unsigned char cookie[20];
263
264/* We've hard-coded the cipher suite; we know it's 104 bytes */
265static unsigned char key_block[104];
266#define mac_key (key_block + 20)
267#define dec_key (key_block + 40)
268#define enc_key (key_block + 56)
269
270static EVP_MD_CTX handshake_md5;
271static EVP_MD_CTX handshake_sha1;
272
273/* PRF lifted from ssl/t1_enc.c since we can't easily use it directly */
274static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
275                       int sec_len,
276                       const void *seed1, int seed1_len,
277                       const void *seed2, int seed2_len,
278                       const void *seed3, int seed3_len,
279                       unsigned char *out, int olen)
280{
281    int chunk;
282    size_t j;
283    EVP_MD_CTX ctx, ctx_tmp, ctx_init;
284    EVP_PKEY *prf_mac_key;
285    unsigned char A1[EVP_MAX_MD_SIZE];
286    size_t A1_len;
287    int ret = 0;
288
289    chunk = EVP_MD_size(md);
290    OPENSSL_assert(chunk >= 0);
291
292    EVP_MD_CTX_init(&ctx);
293    EVP_MD_CTX_init(&ctx_tmp);
294    EVP_MD_CTX_init(&ctx_init);
295    EVP_MD_CTX_set_flags(&ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
296    prf_mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len);
297    if (!prf_mac_key)
298        goto err;
299    if (!EVP_DigestSignInit(&ctx_init, NULL, md, NULL, prf_mac_key))
300        goto err;
301    if (!EVP_MD_CTX_copy_ex(&ctx, &ctx_init))
302        goto err;
303    if (seed1 && !EVP_DigestSignUpdate(&ctx, seed1, seed1_len))
304        goto err;
305    if (seed2 && !EVP_DigestSignUpdate(&ctx, seed2, seed2_len))
306        goto err;
307    if (seed3 && !EVP_DigestSignUpdate(&ctx, seed3, seed3_len))
308        goto err;
309    if (!EVP_DigestSignFinal(&ctx, A1, &A1_len))
310        goto err;
311
312    for (;;) {
313        /* Reinit mac contexts */
314        if (!EVP_MD_CTX_copy_ex(&ctx, &ctx_init))
315            goto err;
316        if (!EVP_DigestSignUpdate(&ctx, A1, A1_len))
317            goto err;
318        if (olen > chunk && !EVP_MD_CTX_copy_ex(&ctx_tmp, &ctx))
319            goto err;
320        if (seed1 && !EVP_DigestSignUpdate(&ctx, seed1, seed1_len))
321            goto err;
322        if (seed2 && !EVP_DigestSignUpdate(&ctx, seed2, seed2_len))
323            goto err;
324        if (seed3 && !EVP_DigestSignUpdate(&ctx, seed3, seed3_len))
325            goto err;
326
327        if (olen > chunk) {
328            if (!EVP_DigestSignFinal(&ctx, out, &j))
329                goto err;
330            out += j;
331            olen -= j;
332            /* calc the next A1 value */
333            if (!EVP_DigestSignFinal(&ctx_tmp, A1, &A1_len))
334                goto err;
335        } else {                /* last one */
336
337            if (!EVP_DigestSignFinal(&ctx, A1, &A1_len))
338                goto err;
339            memcpy(out, A1, olen);
340            break;
341        }
342    }
343    ret = 1;
344 err:
345    EVP_PKEY_free(prf_mac_key);
346    EVP_MD_CTX_cleanup(&ctx);
347    EVP_MD_CTX_cleanup(&ctx_tmp);
348    EVP_MD_CTX_cleanup(&ctx_init);
349    OPENSSL_cleanse(A1, sizeof(A1));
350    return ret;
351}
352
353/* seed1 through seed5 are virtually concatenated */
354static int do_PRF(const void *seed1, int seed1_len,
355                  const void *seed2, int seed2_len,
356                  const void *seed3, int seed3_len,
357                  unsigned char *out, int olen)
358{
359    unsigned char out2[104];
360    int i, len;
361
362    if (olen > (int)sizeof(out2))
363        return 0;
364
365    len = sizeof(master_secret) / 2;
366
367    if (!tls1_P_hash(EVP_md5(), master_secret, len,
368                     seed1, seed1_len, seed2, seed2_len, seed3,
369                     seed3_len, out, olen))
370        return 0;
371
372    if (!tls1_P_hash(EVP_sha1(), master_secret + len, len,
373                     seed1, seed1_len, seed2, seed2_len, seed3,
374                     seed3_len, out2, olen))
375        return 0;
376
377    for (i = 0; i < olen; i++) {
378        out[i] ^= out2[i];
379    }
380
381    return 1;
382}
383
384static SSL_SESSION *client_session(void)
385{
386    static unsigned char session_asn1[] = {
387        0x30, 0x5F,              /* SEQUENCE, length 0x5F */
388        0x02, 0x01, 0x01,        /* INTEGER, SSL_SESSION_ASN1_VERSION */
389        0x02, 0x02, 0x01, 0x00,  /* INTEGER, DTLS1_BAD_VER */
390        0x04, 0x02, 0x00, 0x2F,  /* OCTET_STRING, AES128-SHA */
391        0x04, 0x20,              /* OCTET_STRING, session id */
392#define SS_SESSID_OFS 15 /* Session ID goes here */
393        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
395        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
396        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397        0x04, 0x30,              /* OCTET_STRING, master secret */
398#define SS_SECRET_OFS 49 /* Master secret goes here */
399        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
400        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
402        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
403        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
404        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405    };
406    const unsigned char *p = session_asn1;
407
408    /* Copy the randomly-generated fields into the above ASN1 */
409    memcpy(session_asn1 + SS_SESSID_OFS, session_id, sizeof(session_id));
410    memcpy(session_asn1 + SS_SECRET_OFS, master_secret, sizeof(master_secret));
411
412    return d2i_SSL_SESSION(NULL, &p, sizeof(session_asn1));
413}
414
415/* Returns 1 for initial ClientHello, 2 for ClientHello with cookie */
416static int validate_client_hello(BIO *wbio)
417{
418    PACKET pkt, pkt2;
419    long len;
420    unsigned char *data;
421    int cookie_found = 0;
422    unsigned int u;
423
424    len = BIO_get_mem_data(wbio, (char **)&data);
425    if (!PACKET_buf_init(&pkt, data, len))
426        return 0;
427
428    /* Check record header type */
429    if (!PACKET_get_1(&pkt, &u) || u != SSL3_RT_HANDSHAKE)
430        return 0;
431    /* Version */
432    if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER)
433        return 0;
434    /* Skip the rest of the record header */
435    if (!PACKET_forward(&pkt, DTLS1_RT_HEADER_LENGTH - 3))
436        return 0;
437
438    /* Check it's a ClientHello */
439    if (!PACKET_get_1(&pkt, &u) || u != SSL3_MT_CLIENT_HELLO)
440        return 0;
441    /* Skip the rest of the handshake message header */
442    if (!PACKET_forward(&pkt, DTLS1_HM_HEADER_LENGTH - 1))
443        return 0;
444
445    /* Check client version */
446    if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER)
447        return 0;
448
449    /* Store random */
450    if (!PACKET_copy_bytes(&pkt, client_random, SSL3_RANDOM_SIZE))
451        return 0;
452
453    /* Check session id length and content */
454    if (!PACKET_get_length_prefixed_1(&pkt, &pkt2) ||
455        !PACKET_equal(&pkt2, session_id, sizeof(session_id)))
456        return 0;
457
458    /* Check cookie */
459    if (!PACKET_get_length_prefixed_1(&pkt, &pkt2))
460        return 0;
461    if (PACKET_remaining(&pkt2)) {
462        if (!PACKET_equal(&pkt2, cookie, sizeof(cookie)))
463            return 0;
464        cookie_found = 1;
465    }
466
467    /* Skip ciphers */
468    if (!PACKET_get_net_2(&pkt, &u) || !PACKET_forward(&pkt, u))
469        return 0;
470
471    /* Skip compression */
472    if (!PACKET_get_1(&pkt, &u) || !PACKET_forward(&pkt, u))
473        return 0;
474
475    /* Skip extensions */
476    if (!PACKET_get_net_2(&pkt, &u) || !PACKET_forward(&pkt, u))
477        return 0;
478
479    /* Now we are at the end */
480    if (PACKET_remaining(&pkt))
481        return 0;
482
483    /* Update handshake MAC for second ClientHello (with cookie) */
484    if (cookie_found && (!EVP_DigestUpdate(&handshake_md5, data + MAC_OFFSET,
485                                           len - MAC_OFFSET) ||
486                         !EVP_DigestUpdate(&handshake_sha1, data + MAC_OFFSET,
487                                           len - MAC_OFFSET)))
488        printf("EVP_DigestUpdate() failed\n");
489
490    (void)BIO_reset(wbio);
491
492    return 1 + cookie_found;
493}
494
495static int send_hello_verify(BIO *rbio)
496{
497    static unsigned char hello_verify[] = {
498        0x16, /* Handshake */
499        0x01, 0x00, /* DTLS1_BAD_VER */
500        0x00, 0x00, /* Epoch 0 */
501        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Seq# 0 */
502        0x00, 0x23, /* Length */
503        0x03, /* Hello Verify */
504        0x00, 0x00, 0x17, /* Length */
505        0x00, 0x00, /* Seq# 0 */
506        0x00, 0x00, 0x00, /* Fragment offset */
507        0x00, 0x00, 0x17, /* Fragment length */
508        0x01, 0x00, /* DTLS1_BAD_VER */
509        0x14, /* Cookie length */
510#define HV_COOKIE_OFS 28 /* Cookie goes here */
511        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
512        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
513        0x00, 0x00, 0x00, 0x00,
514    };
515
516    memcpy(hello_verify + HV_COOKIE_OFS, cookie, sizeof(cookie));
517
518    BIO_write(rbio, hello_verify, sizeof(hello_verify));
519
520    return 1;
521}
522
523static int send_server_hello(BIO *rbio)
524{
525    static unsigned char server_hello[] = {
526        0x16, /* Handshake */
527        0x01, 0x00, /* DTLS1_BAD_VER */
528        0x00, 0x00, /* Epoch 0 */
529        0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* Seq# 1 */
530        0x00, 0x52, /* Length */
531        0x02, /* Server Hello */
532        0x00, 0x00, 0x46, /* Length */
533        0x00, 0x01, /* Seq# */
534        0x00, 0x00, 0x00, /* Fragment offset */
535        0x00, 0x00, 0x46, /* Fragment length */
536        0x01, 0x00, /* DTLS1_BAD_VER */
537#define SH_RANDOM_OFS 27 /* Server random goes here */
538        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
539        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
540        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
541        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
542        0x20, /* Session ID length */
543#define SH_SESSID_OFS 60 /* Session ID goes here */
544        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
545        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
546        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
547        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
548        0x00, 0x2f, /* Cipher suite AES128-SHA */
549        0x00, /* Compression null */
550    };
551    static unsigned char change_cipher_spec[] = {
552        0x14, /* Change Cipher Spec */
553        0x01, 0x00, /* DTLS1_BAD_VER */
554        0x00, 0x00, /* Epoch 0 */
555        0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* Seq# 2 */
556        0x00, 0x03, /* Length */
557        0x01, 0x00, 0x02, /* Message */
558    };
559
560    memcpy(server_hello + SH_RANDOM_OFS, server_random, sizeof(server_random));
561    memcpy(server_hello + SH_SESSID_OFS, session_id, sizeof(session_id));
562
563    if (!EVP_DigestUpdate(&handshake_md5, server_hello + MAC_OFFSET,
564                          sizeof(server_hello) - MAC_OFFSET) ||
565        !EVP_DigestUpdate(&handshake_sha1, server_hello + MAC_OFFSET,
566                          sizeof(server_hello) - MAC_OFFSET))
567        printf("EVP_DigestUpdate() failed\n");
568
569    BIO_write(rbio, server_hello, sizeof(server_hello));
570    BIO_write(rbio, change_cipher_spec, sizeof(change_cipher_spec));
571
572    return 1;
573}
574
575/* Create header, HMAC, pad, encrypt and send a record */
576static int send_record(BIO *rbio, unsigned char type, unsigned long seqnr,
577                       const void *msg, size_t len)
578{
579    /* Note that the order of the record header fields on the wire,
580     * and in the HMAC, is different. So we just keep them in separate
581     * variables and handle them individually. */
582    static unsigned char epoch[2] = { 0x00, 0x01 };
583    static unsigned char seq[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
584    static unsigned char ver[2] = { 0x01, 0x00 }; /* DTLS1_BAD_VER */
585    unsigned char lenbytes[2];
586    HMAC_CTX ctx;
587    EVP_CIPHER_CTX enc_ctx;
588    unsigned char iv[16];
589    unsigned char pad;
590    unsigned char *enc;
591
592#ifdef SIXTY_FOUR_BIT_LONG
593    seq[0] = (seqnr >> 40) & 0xff;
594    seq[1] = (seqnr >> 32) & 0xff;
595#endif
596    seq[2] = (seqnr >> 24) & 0xff;
597    seq[3] = (seqnr >> 16) & 0xff;
598    seq[4] = (seqnr >> 8) & 0xff;
599    seq[5] = seqnr & 0xff;
600
601    pad = 15 - ((len + SHA_DIGEST_LENGTH) % 16);
602    enc = OPENSSL_malloc(len + SHA_DIGEST_LENGTH + 1 + pad);
603    if (enc == NULL)
604        return 0;
605
606    /* Copy record to encryption buffer */
607    memcpy(enc, msg, len);
608
609    /* Append HMAC to data */
610    HMAC_Init(&ctx, mac_key, 20, EVP_sha1());
611    HMAC_Update(&ctx, epoch, 2);
612    HMAC_Update(&ctx, seq, 6);
613    HMAC_Update(&ctx, &type, 1);
614    HMAC_Update(&ctx, ver, 2); /* Version */
615    lenbytes[0] = len >> 8;
616    lenbytes[1] = len & 0xff;
617    HMAC_Update(&ctx, lenbytes, 2); /* Length */
618    HMAC_Update(&ctx, enc, len); /* Finally the data itself */
619    HMAC_Final(&ctx, enc + len, NULL);
620    HMAC_CTX_cleanup(&ctx);
621
622    /* Append padding bytes */
623    len += SHA_DIGEST_LENGTH;
624    do {
625        enc[len++] = pad;
626    } while (len % 16);
627
628    /* Generate IV, and encrypt */
629    RAND_bytes(iv, sizeof(iv));
630    EVP_CIPHER_CTX_init(&enc_ctx);
631    EVP_CipherInit_ex(&enc_ctx, EVP_aes_128_cbc(), NULL, enc_key, iv, 1);
632    EVP_Cipher(&enc_ctx, enc, enc, len);
633    EVP_CIPHER_CTX_cleanup(&enc_ctx);
634
635    /* Finally write header (from fragmented variables), IV and encrypted record */
636    BIO_write(rbio, &type, 1);
637    BIO_write(rbio, ver, 2);
638    BIO_write(rbio, epoch, 2);
639    BIO_write(rbio, seq, 6);
640    lenbytes[0] = (len + sizeof(iv)) >> 8;
641    lenbytes[1] = (len + sizeof(iv)) & 0xff;
642    BIO_write(rbio, lenbytes, 2);
643
644    BIO_write(rbio, iv, sizeof(iv));
645    BIO_write(rbio, enc, len);
646
647    OPENSSL_free(enc);
648    return 1;
649}
650
651static int send_finished(SSL *s, BIO *rbio)
652{
653    static unsigned char finished_msg[DTLS1_HM_HEADER_LENGTH +
654                                      TLS1_FINISH_MAC_LENGTH] = {
655        0x14, /* Finished */
656        0x00, 0x00, 0x0c, /* Length */
657        0x00, 0x03, /* Seq# 3 */
658        0x00, 0x00, 0x00, /* Fragment offset */
659        0x00, 0x00, 0x0c, /* Fragment length */
660        /* Finished MAC (12 bytes) */
661    };
662    unsigned char handshake_hash[EVP_MAX_MD_SIZE * 2];
663
664    /* Derive key material */
665    do_PRF(TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE,
666           server_random, SSL3_RANDOM_SIZE,
667           client_random, SSL3_RANDOM_SIZE,
668           key_block, sizeof(key_block));
669
670    /* Generate Finished MAC */
671    if (!EVP_DigestFinal_ex(&handshake_md5, handshake_hash, NULL) ||
672        !EVP_DigestFinal_ex(&handshake_sha1, handshake_hash + EVP_MD_CTX_size(&handshake_md5), NULL))
673        printf("EVP_DigestFinal_ex() failed\n");
674
675    do_PRF(TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
676           handshake_hash, EVP_MD_CTX_size(&handshake_md5) + EVP_MD_CTX_size(&handshake_sha1),
677           NULL, 0,
678           finished_msg + DTLS1_HM_HEADER_LENGTH, TLS1_FINISH_MAC_LENGTH);
679
680    return send_record(rbio, SSL3_RT_HANDSHAKE, 0,
681                       finished_msg, sizeof(finished_msg));
682}
683
684static int validate_ccs(BIO *wbio)
685{
686    PACKET pkt;
687    long len;
688    unsigned char *data;
689    unsigned int u;
690
691    len = BIO_get_mem_data(wbio, (char **)&data);
692    if (!PACKET_buf_init(&pkt, data, len))
693        return 0;
694
695    /* Check record header type */
696    if (!PACKET_get_1(&pkt, &u) || u != SSL3_RT_CHANGE_CIPHER_SPEC)
697        return 0;
698    /* Version */
699    if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER)
700        return 0;
701    /* Skip the rest of the record header */
702    if (!PACKET_forward(&pkt, DTLS1_RT_HEADER_LENGTH - 3))
703        return 0;
704
705    /* Check ChangeCipherSpec message */
706    if (!PACKET_get_1(&pkt, &u) || u != SSL3_MT_CCS)
707        return 0;
708    /* A DTLS1_BAD_VER ChangeCipherSpec also contains the
709     * handshake sequence number (which is 2 here) */
710    if (!PACKET_get_net_2(&pkt, &u) || u != 0x0002)
711        return 0;
712
713    /* Now check the Finished packet */
714    if (!PACKET_get_1(&pkt, &u) || u != SSL3_RT_HANDSHAKE)
715        return 0;
716    if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER)
717        return 0;
718
719    /* Check epoch is now 1 */
720    if (!PACKET_get_net_2(&pkt, &u) || u != 0x0001)
721        return 0;
722
723    /* That'll do for now. If OpenSSL accepted *our* Finished packet
724     * then it's evidently remembered that DTLS1_BAD_VER doesn't
725     * include the handshake header in the MAC. There's not a lot of
726     * point in implementing decryption here, just to check that it
727     * continues to get it right for one more packet. */
728
729    return 1;
730}
731
732#define NODROP(x) { x##UL, 0 }
733#define DROP(x)   { x##UL, 1 }
734
735static struct {
736    unsigned long seq;
737    int drop;
738} tests[] = {
739    NODROP(1), NODROP(3), NODROP(2),
740    NODROP(0x1234), NODROP(0x1230), NODROP(0x1235),
741    NODROP(0xffff), NODROP(0x10001), NODROP(0xfffe), NODROP(0x10000),
742    DROP(0x10001), DROP(0xff), NODROP(0x100000), NODROP(0x800000), NODROP(0x7fffe1),
743    NODROP(0xffffff), NODROP(0x1000000), NODROP(0xfffffe), DROP(0xffffff), NODROP(0x1000010),
744    NODROP(0xfffffd), NODROP(0x1000011), DROP(0x12), NODROP(0x1000012),
745    NODROP(0x1ffffff), NODROP(0x2000000), DROP(0x1ff00fe), NODROP(0x2000001),
746    NODROP(0x20fffff), NODROP(0x2105500), DROP(0x20ffffe), NODROP(0x21054ff),
747    NODROP(0x211ffff), DROP(0x2110000), NODROP(0x2120000)
748    /* The last test should be NODROP, because a DROP wouldn't get tested. */
749};
750
751int main(int argc, char *argv[])
752{
753    SSL_SESSION *sess;
754    SSL_CTX *ctx;
755    SSL *con;
756    BIO *rbio;
757    BIO *wbio;
758    BIO *err;
759    int testresult = 0;
760    int ret;
761    int i;
762
763    SSL_library_init();
764    SSL_load_error_strings();
765
766    err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
767
768    CRYPTO_malloc_debug_init();
769    CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
770    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
771
772    RAND_bytes(session_id, sizeof(session_id));
773    RAND_bytes(master_secret, sizeof(master_secret));
774    RAND_bytes(cookie, sizeof(cookie));
775    RAND_bytes(server_random + 4, sizeof(server_random) - 4);
776    time((void *)server_random);
777
778    sess = client_session();
779    if (sess == NULL) {
780        printf("Failed to generate SSL_SESSION\n");
781        goto end;
782    }
783
784    if (!EVP_DigestInit_ex(&handshake_md5, EVP_md5(), NULL) ||
785        !EVP_DigestInit_ex(&handshake_sha1, EVP_sha1(), NULL)) {
786        printf("Failed to initialise handshake_md\n");
787        goto end;
788    }
789
790    ctx = SSL_CTX_new(DTLSv1_client_method());
791    if (ctx == NULL) {
792        printf("Failed to allocate SSL_CTX\n");
793        goto end_md;
794    }
795    SSL_CTX_set_options(ctx, SSL_OP_CISCO_ANYCONNECT);
796
797    if (!SSL_CTX_set_cipher_list(ctx, "AES128-SHA")) {
798        printf("SSL_CTX_set_cipher_list() failed\n");
799        goto end_ctx;
800    }
801
802    con = SSL_new(ctx);
803    if (!SSL_set_session(con, sess)) {
804        printf("SSL_set_session() failed\n");
805        goto end_con;
806    }
807    SSL_SESSION_free(sess);
808
809    rbio = BIO_new(BIO_s_mem());
810    wbio = BIO_new(BIO_s_mem());
811
812    BIO_set_nbio(rbio, 1);
813    BIO_set_nbio(wbio, 1);
814
815    SSL_set_bio(con, rbio, wbio);
816    SSL_set_connect_state(con);
817
818    /* Send initial ClientHello */
819    ret = SSL_do_handshake(con);
820    if (ret > 0 || SSL_get_error(con, ret) != SSL_ERROR_WANT_READ) {
821        printf("Unexpected handshake result at initial call!\n");
822        goto end_con;
823    }
824
825    if (validate_client_hello(wbio) != 1) {
826        printf("Initial ClientHello failed validation\n");
827        goto end_con;
828    }
829    if (send_hello_verify(rbio) != 1) {
830        printf("Failed to send HelloVerify\n");
831        goto end_con;
832    }
833    ret = SSL_do_handshake(con);
834    if (ret > 0 || SSL_get_error(con, ret) != SSL_ERROR_WANT_READ) {
835        printf("Unexpected handshake result after HelloVerify!\n");
836        goto end_con;
837    }
838    if (validate_client_hello(wbio) != 2) {
839        printf("Second ClientHello failed validation\n");
840        goto end_con;
841    }
842    if (send_server_hello(rbio) != 1) {
843        printf("Failed to send ServerHello\n");
844        goto end_con;
845    }
846    ret = SSL_do_handshake(con);
847    if (ret > 0 || SSL_get_error(con, ret) != SSL_ERROR_WANT_READ) {
848        printf("Unexpected handshake result after ServerHello!\n");
849        goto end_con;
850    }
851    if (send_finished(con, rbio) != 1) {
852        printf("Failed to send Finished\n");
853        goto end_con;
854    }
855    ret = SSL_do_handshake(con);
856    if (ret < 1) {
857        printf("Handshake not successful after Finished!\n");
858        goto end_con;
859    }
860    if (validate_ccs(wbio) != 1) {
861        printf("Failed to validate client CCS/Finished\n");
862        goto end_con;
863    }
864
865    /* While we're here and crafting packets by hand, we might as well do a
866       bit of a stress test on the DTLS record replay handling. Not Cisco-DTLS
867       specific but useful anyway for the general case. It's been broken
868       before, and in fact was broken even for a basic 0, 2, 1 test case
869       when this test was first added.... */
870    for (i = 0; i < (int)OSSL_NELEM(tests); i++) {
871        unsigned long recv_buf[2];
872
873        if (send_record(rbio, SSL3_RT_APPLICATION_DATA, tests[i].seq,
874                        &tests[i].seq, sizeof(unsigned long)) != 1) {
875            printf("Failed to send data seq #0x%lx (%d)\n",
876                   tests[i].seq, i);
877            goto end_con;
878        }
879
880        if (tests[i].drop)
881            continue;
882
883        ret = SSL_read(con, recv_buf, 2 * sizeof(unsigned long));
884        if (ret != sizeof(unsigned long)) {
885            printf("SSL_read failed or wrong size on seq#0x%lx (%d)\n",
886                   tests[i].seq, i);
887            goto end_con;
888        }
889        if (recv_buf[0] != tests[i].seq) {
890            printf("Wrong data packet received (0x%lx not 0x%lx) at packet %d\n",
891                   recv_buf[0], tests[i].seq, i);
892            goto end_con;
893        }
894    }
895    if (tests[i-1].drop) {
896        printf("Error: last test cannot be DROP()\n");
897        goto end_con;
898    }
899    testresult=1;
900
901 end_con:
902    SSL_free(con);
903 end_ctx:
904    SSL_CTX_free(ctx);
905 end_md:
906    EVP_MD_CTX_cleanup(&handshake_md5);
907    EVP_MD_CTX_cleanup(&handshake_sha1);
908 end:
909    ERR_print_errors_fp(stderr);
910
911    if (!testresult) {
912        printf("Cisco BadDTLS test: FAILED\n");
913    }
914
915    ERR_free_strings();
916    ERR_remove_thread_state(NULL);
917    EVP_cleanup();
918    CRYPTO_cleanup_all_ex_data();
919    CRYPTO_mem_leaks(err);
920    BIO_free(err);
921
922    return testresult?0:1;
923}
924