summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2013-03-27 19:54:48 +0000
committerDr. Stephen Henson <steve@openssl.org>2013-03-28 14:14:27 +0000
commit4221c0dd3004117c63b182af5e8ab345b7265902 (patch)
treeacd595e322ae6155ca4fe4d68139f2bd07614854
parentfbbaaccaca32742f09dfb02e5e28dcd20f64a17f (diff)
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.
-rw-r--r--ssl/d1_both.c9
-rw-r--r--ssl/d1_lib.c7
-rw-r--r--ssl/d1_pkt.c46
-rw-r--r--ssl/s3_lib.c8
-rw-r--r--ssl/ssl_locl.h9
-rw-r--r--ssl/t1_enc.c2
-rw-r--r--ssl/t1_lib.c7
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;