From 4221c0dd3004117c63b182af5e8ab345b7265902 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Wed, 27 Mar 2013 19:54:48 +0000 Subject: [PATCH] Enable TLS 1.2 ciphers in DTLS 1.2. Port TLS 1.2 GCM code to DTLS. Enable use of TLS 1.2 only ciphers when in DTLS 1.2 mode too. --- ssl/d1_both.c | 9 +++++++-- ssl/d1_lib.c | 7 ++++--- ssl/d1_pkt.c | 46 ++++++++++++++++++++++++---------------------- ssl/s3_lib.c | 8 ++++---- ssl/ssl_locl.h | 9 +++++++++ ssl/t1_enc.c | 2 +- ssl/t1_lib.c | 7 ++++--- 7 files changed, 53 insertions(+), 35 deletions(-) diff --git a/ssl/d1_both.c b/ssl/d1_both.c index 262299b154..f7947bd988 100644 --- a/ssl/d1_both.c +++ b/ssl/d1_both.c @@ -272,12 +272,17 @@ int dtls1_do_write(SSL *s, int type) (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH); if (s->write_hash) - mac_size = EVP_MD_CTX_size(s->write_hash); + { + if (s->enc_write_ctx && EVP_CIPHER_CTX_mode(s->enc_write_ctx) == EVP_CIPH_GCM_MODE) + mac_size = 0; + else + mac_size = EVP_MD_CTX_size(s->write_hash); + } else mac_size = 0; if (s->enc_write_ctx && - (EVP_CIPHER_mode( s->enc_write_ctx->cipher) & EVP_CIPH_CBC_MODE)) + (EVP_CIPHER_CTX_mode(s->enc_write_ctx) == EVP_CIPH_CBC_MODE)) blocksize = 2 * EVP_CIPHER_block_size(s->enc_write_ctx->cipher); else blocksize = 0; diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c index 16bafa3560..ddbb78a199 100644 --- a/ssl/d1_lib.c +++ b/ssl/d1_lib.c @@ -73,7 +73,7 @@ const char dtls1_version_str[]="DTLSv1" OPENSSL_VERSION_PTEXT; int dtls1_listen(SSL *s, struct sockaddr *client); SSL3_ENC_METHOD DTLSv1_enc_data={ - dtls1_enc, + tls1_enc, tls1_mac, tls1_setup_key_block, tls1_generate_master_secret, @@ -92,7 +92,7 @@ SSL3_ENC_METHOD DTLSv1_enc_data={ }; SSL3_ENC_METHOD DTLSv1_2_enc_data={ - dtls1_enc, + tls1_enc, tls1_mac, tls1_setup_key_block, tls1_generate_master_secret, @@ -104,7 +104,8 @@ SSL3_ENC_METHOD DTLSv1_2_enc_data={ TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE, tls1_alert_code, tls1_export_keying_material, - SSL_ENC_FLAG_DTLS|SSL_ENC_FLAG_EXPLICIT_IV|SSL_ENC_FLAG_SIGALGS|SSL_ENC_FLAG_SHA256_PRF, + SSL_ENC_FLAG_DTLS|SSL_ENC_FLAG_EXPLICIT_IV|SSL_ENC_FLAG_SIGALGS + |SSL_ENC_FLAG_SHA256_PRF|SSL_ENC_FLAG_TLS1_2_CIPHERS, DTLS1_HM_HEADER_LENGTH, dtls1_set_handshake_header, dtls1_handshake_write diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c index b7ff9a8705..995e6576e0 100644 --- a/ssl/d1_pkt.c +++ b/ssl/d1_pkt.c @@ -1466,10 +1466,10 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, unsigned char *p,*pseq; int i,mac_size,clear=0; int prefix_len = 0; + int eivlen; SSL3_RECORD *wr; SSL3_BUFFER *wb; SSL_SESSION *sess; - int bs; /* first check if there is a SSL3_BUFFER still being written * out. This will happen with non blocking IO */ @@ -1554,18 +1554,27 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, pseq=p; p+=10; - /* lets setup the record stuff. */ - - /* Make space for the explicit IV in case of CBC. - * (this is a bit of a boundary violation, but what the heck). - */ - if ( s->enc_write_ctx && - (EVP_CIPHER_mode( s->enc_write_ctx->cipher ) & EVP_CIPH_CBC_MODE)) - bs = EVP_CIPHER_block_size(s->enc_write_ctx->cipher); - else - bs = 0; + /* Explicit IV length, block ciphers appropriate version flag */ + if (s->enc_write_ctx) + { + int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx); + if (mode == EVP_CIPH_CBC_MODE) + { + eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx); + if (eivlen <= 1) + eivlen = 0; + } + /* Need explicit part of IV for GCM mode */ + else if (mode == EVP_CIPH_GCM_MODE) + eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN; + else + eivlen = 0; + } + else + eivlen = 0; - wr->data=p + bs; /* make room for IV in case of CBC */ + /* lets setup the record stuff. */ + wr->data=p + eivlen; /* make room for IV in case of CBC */ wr->length=(int)len; wr->input=(unsigned char *)buf; @@ -1593,7 +1602,7 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, if (mac_size != 0) { - if(s->method->ssl3_enc->mac(s,&(p[wr->length + bs]),1) < 0) + if(s->method->ssl3_enc->mac(s,&(p[wr->length + eivlen]),1) < 0) goto err; wr->length+=mac_size; } @@ -1602,15 +1611,8 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, wr->input=p; wr->data=p; - - /* ssl3_enc can only have an error on read */ - if (bs) /* bs != 0 in case of CBC */ - { - RAND_pseudo_bytes(p,bs); - /* master IV and last CBC residue stand for - * the rest of randomness */ - wr->length += bs; - } + if (eivlen) + wr->length += eivlen; s->method->ssl3_enc->enc(s,1); diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index b92d879f3d..7ad8a541fa 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -3372,7 +3372,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) #ifndef OPENSSL_NO_HEARTBEATS case SSL_CTRL_TLS_EXT_SEND_HEARTBEAT: - if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER) + if (SSL_IS_DTLS(s)) ret = dtls1_heartbeat(s); else ret = tls1_heartbeat(s); @@ -3493,7 +3493,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) return ssl_cert_set_cert_store(s->cert, parg, 1, larg); case SSL_CTRL_GET_PEER_SIGNATURE_NID: - if (TLS1_get_version(s) >= TLS1_2_VERSION) + if (SSL_USE_SIGALGS(s)) { if (s->session && s->session->sess_cert) { @@ -4080,9 +4080,9 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, { c=sk_SSL_CIPHER_value(prio,i); - /* Skip TLS v1.2 only ciphersuites if lower than v1.2 */ + /* Skip TLS v1.2 only ciphersuites if not supported */ if ((c->algorithm_ssl & SSL_TLSV1_2) && - (TLS1_get_version(s) < TLS1_2_VERSION)) + !SSL_USE_TLS1_2_CIPHERS(s)) continue; ssl_set_cert_masks(cert,c); diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 13680cbf72..101f4e9761 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -448,6 +448,11 @@ */ #define SSL_USE_SIGALGS(s) \ (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SIGALGS) +/* Allow TLS 1.2 ciphersuites: applies to DTLS 1.2 as well as TLS 1.2: + * may apply to others in future. + */ +#define SSL_USE_TLS1_2_CIPHERS(s) \ + (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS) /* Mostly for SSLv3 */ #define SSL_PKEY_RSA_ENC 0 @@ -713,6 +718,10 @@ typedef struct ssl3_enc_method #define SSL_ENC_FLAG_SHA256_PRF 0x4 /* Is DTLS */ #define SSL_ENC_FLAG_DTLS 0x8 +/* Allow TLS 1.2 ciphersuites: applies to DTLS 1.2 as well as TLS 1.2: + * may apply to others in future. + */ +#define SSL_ENC_FLAG_TLS1_2_CIPHERS 0x10 #ifndef OPENSSL_NO_COMP /* Used for holding the relevant compression methods loaded into SSL_CTX */ diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index 5d46bb24c1..fdd20d9009 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -724,7 +724,7 @@ int tls1_enc(SSL *s, int send) int ivlen; enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx); /* For TLSv1.1 and later explicit IV */ - if (s->version >= TLS1_1_VERSION + if (SSL_USE_EXPLICIT_IV(s) && EVP_CIPHER_mode(enc) == EVP_CIPH_CBC_MODE) ivlen = EVP_CIPHER_iv_length(enc); else diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index b0e91ad3e5..8cb018d65e 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -178,7 +178,8 @@ SSL3_ENC_METHOD TLSv1_2_enc_data={ TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE, tls1_alert_code, tls1_export_keying_material, - SSL_ENC_FLAG_EXPLICIT_IV|SSL_ENC_FLAG_SIGALGS|SSL_ENC_FLAG_SHA256_PRF, + SSL_ENC_FLAG_EXPLICIT_IV|SSL_ENC_FLAG_SIGALGS|SSL_ENC_FLAG_SHA256_PRF + |SSL_ENC_FLAG_TLS1_2_CIPHERS, SSL3_HM_HEADER_LENGTH, ssl3_set_handshake_header, ssl3_handshake_write @@ -1008,8 +1009,8 @@ void ssl_set_client_disabled(SSL *s) int have_rsa = 0, have_dsa = 0, have_ecdsa = 0; c->mask_a = 0; c->mask_k = 0; - /* If less than TLS 1.2 don't allow TLS 1.2 only ciphers */ - if (TLS1_get_client_version(s) < TLS1_2_VERSION) + /* Don't allow TLS 1.2 only ciphers if we don't suppport them */ + if (!SSL_USE_TLS1_2_CIPHERS(s)) c->mask_ssl = SSL_TLSV1_2; else c->mask_ssl = 0; -- 2.34.1