diff --git a/ssl/d1_both.c b/ssl/d1_both.c index 262299b15..f7947bd98 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 2b82d527d..b07ee3551 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 8186462d4..8ace79a8a 100644 --- a/ssl/d1_pkt.c +++ b/ssl/d1_pkt.c @@ -1472,10 +1472,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 */ @@ -1560,18 +1560,27 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, pseq=p; p+=10; + /* 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; + /* 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; - - wr->data=p + bs; /* make room for IV in case of CBC */ + wr->data=p + eivlen; /* make room for IV in case of CBC */ wr->length=(int)len; wr->input=(unsigned char *)buf; @@ -1599,7 +1608,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; } @@ -1608,15 +1617,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 59d2fbbfa..e418c6428 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -3383,7 +3383,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); @@ -3505,7 +3505,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) { @@ -4085,9 +4085,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 f5597ee64..a19f98569 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -450,6 +450,17 @@ */ #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) +/* Determine if a client can use TLS 1.2 ciphersuites: can't rely on method + * flags because it may not be set to correct version yet. + */ +#define SSL_CLIENT_USE_TLS1_2_CIPHERS(s) \ + ((SSL_IS_DTLS(s) && s->client_version <= DTLS1_2_VERSION) || \ + (!SSL_IS_DTLS(s) && s->client_version >= TLS1_2_VERSION)) /* Mostly for SSLv3 */ #define SSL_PKEY_RSA_ENC 0 @@ -723,6 +734,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 63761e5c7..c35270706 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 35a58a956..b3c7cb5df 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 @@ -1018,8 +1019,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_CLIENT_USE_TLS1_2_CIPHERS(s)) c->mask_ssl = SSL_TLSV1_2; else c->mask_ssl = 0;