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