Enable TLS 1.2 ciphers in DTLS 1.2.
authorDr. Stephen Henson <steve@openssl.org>
Wed, 27 Mar 2013 19:54:48 +0000 (19:54 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Thu, 28 Mar 2013 14:14:27 +0000 (14:14 +0000)
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
ssl/d1_lib.c
ssl/d1_pkt.c
ssl/s3_lib.c
ssl/ssl_locl.h
ssl/t1_enc.c
ssl/t1_lib.c

index 262299b..f7947bd 100644 (file)
@@ -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;
index 16bafa3..ddbb78a 100644 (file)
@@ -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   
index b7ff9a8..995e657 100644 (file)
@@ -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);
 
index b92d879..7ad8a54 100644 (file)
@@ -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);
index 13680cb..101f4e9 100644 (file)
  */
 #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 */
index 5d46bb2..fdd20d9 100644 (file)
@@ -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
index b0e91ad..8cb018d 100644 (file)
@@ -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;