Only use explicit IV if cipher is in CBC mode.
[openssl.git] / ssl / t1_enc.c
index 01884906df9e7aff307e5557d98371d6b513174d..34b300161d5fcc97495456cae98de8b393f5a9c5 100644 (file)
@@ -158,7 +158,7 @@ static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
                        const void *seed5, int seed5_len,
                        unsigned char *out, int olen)
        {
-       int chunk,n;
+       int chunk;
        unsigned int j;
        HMAC_CTX ctx;
        HMAC_CTX ctx_tmp;
@@ -188,7 +188,6 @@ static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
        if (!HMAC_Final(&ctx,A1,&A1_len))
                goto err;
 
-       n=0;
        for (;;)
                {
                if (!HMAC_Init_ex(&ctx,NULL,0,NULL,NULL)) /* re-init */
@@ -310,13 +309,13 @@ static int tls1_generate_key_block(SSL *s, unsigned char *km,
 int tls1_change_cipher_state(SSL *s, int which)
        {
        static const unsigned char empty[]="";
-       unsigned char *p,*key_block,*mac_secret;
+       unsigned char *p,*mac_secret;
        unsigned char *exp_label;
        unsigned char tmp1[EVP_MAX_KEY_LENGTH];
        unsigned char tmp2[EVP_MAX_KEY_LENGTH];
        unsigned char iv1[EVP_MAX_IV_LENGTH*2];
        unsigned char iv2[EVP_MAX_IV_LENGTH*2];
-       unsigned char *ms,*key,*iv,*er1,*er2;
+       unsigned char *ms,*key,*iv;
        int client_write;
        EVP_CIPHER_CTX *dd;
        const EVP_CIPHER *c;
@@ -338,7 +337,6 @@ int tls1_change_cipher_state(SSL *s, int which)
 #ifndef OPENSSL_NO_COMP
        comp=s->s3->tmp.new_compression;
 #endif
-       key_block=s->s3->tmp.key_block;
 
 #ifdef KSSL_DEBUG
        printf("tls1_change_cipher_state(which= %d) w/\n", which);
@@ -449,8 +447,6 @@ int tls1_change_cipher_state(SSL *s, int which)
                       cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl;
        /* Was j=(exp)?5:EVP_CIPHER_key_length(c); */
        k=EVP_CIPHER_iv_length(c);
-       er1= &(s->s3->client_random[0]);
-       er2= &(s->s3->server_random[0]);
        if (    (which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
                (which == SSL3_CHANGE_CIPHER_SERVER_READ))
                {
@@ -611,7 +607,8 @@ printf("\nkey block\n");
 { int z; for (z=0; z<num; z++) printf("%02X%c",p1[z],((z+1)%16)?' ':'\n'); }
 #endif
 
-       if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
+       if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)
+               && s->method->version <= TLS1_VERSION)
                {
                /* enable vulnerability countermeasure for CBC ciphers with
                 * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt)
@@ -664,7 +661,8 @@ 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 (s->version >= TLS1_1_VERSION
+                               && EVP_CIPHER_mode(enc) == EVP_CIPH_CBC_MODE)
                                ivlen = EVP_CIPHER_iv_length(enc);
                        else
                                ivlen = 0;
@@ -810,7 +808,8 @@ int tls1_enc(SSL *s, int send)
                                        }
                                }
                        rec->length -=i;
-                       if (s->version >= TLS1_1_VERSION)
+                       if (s->version >= TLS1_1_VERSION
+                               && EVP_CIPHER_CTX_mode(ds) == EVP_CIPH_CBC_MODE)
                                {
                                rec->data += bs;    /* skip the explicit IV */
                                rec->input += bs;
@@ -907,7 +906,7 @@ int tls1_final_finish_mac(SSL *s,
 int tls1_mac(SSL *ssl, unsigned char *md, int send)
        {
        SSL3_RECORD *rec;
-       unsigned char *mac_sec,*seq;
+       unsigned char *seq;
        EVP_MD_CTX *hash;
        size_t md_size;
        int i;
@@ -919,14 +918,12 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
        if (send)
                {
                rec= &(ssl->s3->wrec);
-               mac_sec= &(ssl->s3->write_mac_secret[0]);
                seq= &(ssl->s3->write_sequence[0]);
                hash=ssl->write_hash;
                }
        else
                {
                rec= &(ssl->s3->rrec);
-               mac_sec= &(ssl->s3->read_mac_secret[0]);
                seq= &(ssl->s3->read_sequence[0]);
                hash=ssl->read_hash;
                }
@@ -1076,3 +1073,26 @@ int tls1_alert_code(int code)
                }
        }
 
+int SSL_tls1_key_exporter(SSL *s, unsigned char *label, int label_len,
+                           unsigned char *context, int context_len,
+                           unsigned char *out, int olen)
+       {
+       unsigned char *tmp;
+       int rv;
+
+       tmp = OPENSSL_malloc(olen);
+
+       if (!tmp)
+               return 0;
+       
+       rv = tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+                        label, label_len,
+                        s->s3->client_random,SSL3_RANDOM_SIZE,
+                        s->s3->server_random,SSL3_RANDOM_SIZE,
+                        context, context_len, NULL, 0,
+                        s->session->master_key, s->session->master_key_length,
+                        out, tmp, olen);
+
+       OPENSSL_free(tmp);
+       return rv;
+       }