Index: openssl/patches/tls1_change_cipher_state_rewrite.patch |
diff --git a/openssl/patches/tls1_change_cipher_state_rewrite.patch b/openssl/patches/tls1_change_cipher_state_rewrite.patch |
deleted file mode 100644 |
index eab3f7f685629909fc996d9ab9da865952280b36..0000000000000000000000000000000000000000 |
--- a/openssl/patches/tls1_change_cipher_state_rewrite.patch |
+++ /dev/null |
@@ -1,567 +0,0 @@ |
-From d7f9af2d2682bc41e7bf1d669cda60f04630b04d Mon Sep 17 00:00:00 2001 |
-From: Adam Langley <agl@chromium.org> |
-Date: Thu, 25 Jul 2013 14:57:38 -0400 |
-Subject: [PATCH 39/50] tls1_change_cipher_state_rewrite |
- |
-The previous version of the function made adding AEAD changes very |
-difficult. This change should be a semantic no-op - it should be purely |
-a cleanup. |
---- |
- ssl/ssl.h | 1 + |
- ssl/ssl_err.c | 2 +- |
- ssl/t1_enc.c | 445 +++++++++++++++++++++++++++++++--------------------------- |
- 3 files changed, 240 insertions(+), 208 deletions(-) |
- |
-diff --git a/ssl/ssl.h b/ssl/ssl.h |
-index 68e5648..672f3eb 100644 |
---- a/ssl/ssl.h |
-+++ b/ssl/ssl.h |
-@@ -2439,6 +2439,7 @@ void ERR_load_SSL_strings(void); |
- #define SSL_F_SSL_WRITE 208 |
- #define SSL_F_TLS1_CERT_VERIFY_MAC 286 |
- #define SSL_F_TLS1_CHANGE_CIPHER_STATE 209 |
-+#define SSL_F_TLS1_CHANGE_CIPHER_STATE_CIPHER 338 |
- #define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT 274 |
- #define SSL_F_TLS1_ENC 210 |
- #define SSL_F_TLS1_EXPORT_KEYING_MATERIAL 314 |
-diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c |
-index fc98e6c..97b2a0d 100644 |
---- a/ssl/ssl_err.c |
-+++ b/ssl/ssl_err.c |
-@@ -280,7 +280,7 @@ static ERR_STRING_DATA SSL_str_functs[]= |
- {ERR_FUNC(SSL_F_SSL_VERIFY_CERT_CHAIN), "SSL_VERIFY_CERT_CHAIN"}, |
- {ERR_FUNC(SSL_F_SSL_WRITE), "SSL_write"}, |
- {ERR_FUNC(SSL_F_TLS1_CERT_VERIFY_MAC), "tls1_cert_verify_mac"}, |
--{ERR_FUNC(SSL_F_TLS1_CHANGE_CIPHER_STATE), "TLS1_CHANGE_CIPHER_STATE"}, |
-+{ERR_FUNC(SSL_F_TLS1_CHANGE_CIPHER_STATE_CIPHER), "TLS1_CHANGE_CIPHER_STATE_CIPHER"}, |
- {ERR_FUNC(SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT), "TLS1_CHECK_SERVERHELLO_TLSEXT"}, |
- {ERR_FUNC(SSL_F_TLS1_ENC), "TLS1_ENC"}, |
- {ERR_FUNC(SSL_F_TLS1_EXPORT_KEYING_MATERIAL), "TLS1_EXPORT_KEYING_MATERIAL"}, |
-diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c |
-index 3649544..e1f91ba 100644 |
---- a/ssl/t1_enc.c |
-+++ b/ssl/t1_enc.c |
-@@ -316,56 +316,30 @@ static int tls1_generate_key_block(SSL *s, unsigned char *km, |
- return ret; |
- } |
- |
--int tls1_change_cipher_state(SSL *s, int which) |
-+/* tls1_change_cipher_state_cipher performs the work needed to switch cipher |
-+ * states when using EVP_CIPHER. The argument |is_read| is true iff this |
-+ * function is being called due to reading, as opposed to writing, a |
-+ * ChangeCipherSpec message. In order to support export ciphersuites, |
-+ * use_client_keys indicates whether the key material provided is in the |
-+ * "client write" direction. */ |
-+static int tls1_change_cipher_state_cipher( |
-+ SSL *s, char is_read, char use_client_keys, |
-+ const unsigned char *mac_secret, unsigned mac_secret_len, |
-+ const unsigned char *key, unsigned key_len, |
-+ const unsigned char *iv, unsigned iv_len) |
- { |
-- static const unsigned char empty[]=""; |
-- 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; |
-- int client_write; |
-- EVP_CIPHER_CTX *dd; |
-- const EVP_CIPHER *c; |
--#ifndef OPENSSL_NO_COMP |
-- const SSL_COMP *comp; |
--#endif |
-- const EVP_MD *m; |
-- int mac_type; |
-- int *mac_secret_size; |
-+ const EVP_CIPHER *cipher = s->s3->tmp.new_sym_enc; |
-+ const char is_export = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) != 0; |
-+ EVP_CIPHER_CTX *cipher_ctx; |
- EVP_MD_CTX *mac_ctx; |
-- EVP_PKEY *mac_key; |
-- int is_export,n,i,j,k,exp_label_len,cl; |
-- int reuse_dd = 0; |
-+ char is_aead_cipher; |
- |
-- is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); |
-- c=s->s3->tmp.new_sym_enc; |
-- m=s->s3->tmp.new_hash; |
-- mac_type = s->s3->tmp.new_mac_pkey_type; |
--#ifndef OPENSSL_NO_COMP |
-- comp=s->s3->tmp.new_compression; |
--#endif |
-+ unsigned char export_tmp1[EVP_MAX_KEY_LENGTH]; |
-+ unsigned char export_tmp2[EVP_MAX_KEY_LENGTH]; |
-+ unsigned char export_iv1[EVP_MAX_IV_LENGTH * 2]; |
-+ unsigned char export_iv2[EVP_MAX_IV_LENGTH * 2]; |
- |
--#ifdef KSSL_DEBUG |
-- printf("tls1_change_cipher_state(which= %d) w/\n", which); |
-- printf("\talg= %ld/%ld, comp= %p\n", |
-- s->s3->tmp.new_cipher->algorithm_mkey, |
-- s->s3->tmp.new_cipher->algorithm_auth, |
-- comp); |
-- printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c); |
-- printf("\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n", |
-- c->nid,c->block_size,c->key_len,c->iv_len); |
-- printf("\tkey_block: len= %d, data= ", s->s3->tmp.key_block_length); |
-- { |
-- int i; |
-- for (i=0; i<s->s3->tmp.key_block_length; i++) |
-- printf("%02x", s->s3->tmp.key_block[i]); printf("\n"); |
-- } |
--#endif /* KSSL_DEBUG */ |
-- |
-- if (which & SSL3_CC_READ) |
-+ if (is_read) |
- { |
- if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) |
- s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM; |
-@@ -373,206 +347,257 @@ int tls1_change_cipher_state(SSL *s, int which) |
- s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; |
- |
- if (s->enc_read_ctx != NULL) |
-- reuse_dd = 1; |
-+ EVP_CIPHER_CTX_cleanup(s->enc_read_ctx); |
- else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) |
- goto err; |
- else |
- /* make sure it's intialized in case we exit later with an error */ |
- EVP_CIPHER_CTX_init(s->enc_read_ctx); |
-- dd= s->enc_read_ctx; |
-- mac_ctx=ssl_replace_hash(&s->read_hash,NULL); |
--#ifndef OPENSSL_NO_COMP |
-- if (s->expand != NULL) |
-- { |
-- COMP_CTX_free(s->expand); |
-- s->expand=NULL; |
-- } |
-- if (comp != NULL) |
-- { |
-- s->expand=COMP_CTX_new(comp->method); |
-- if (s->expand == NULL) |
-- { |
-- SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR); |
-- goto err2; |
-- } |
-- if (s->s3->rrec.comp == NULL) |
-- s->s3->rrec.comp=(unsigned char *) |
-- OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH); |
-- if (s->s3->rrec.comp == NULL) |
-- goto err; |
-- } |
--#endif |
-- /* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */ |
-- if (s->version != DTLS1_VERSION) |
-- memset(&(s->s3->read_sequence[0]),0,8); |
-- mac_secret= &(s->s3->read_mac_secret[0]); |
-- mac_secret_size=&(s->s3->read_mac_secret_size); |
-+ |
-+ cipher_ctx = s->enc_read_ctx; |
-+ mac_ctx = ssl_replace_hash(&s->read_hash, NULL); |
-+ |
-+ memcpy(s->s3->read_mac_secret, mac_secret, mac_secret_len); |
-+ s->s3->read_mac_secret_size = mac_secret_len; |
- } |
- else |
- { |
- if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) |
- s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; |
-- else |
-+ else |
- s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; |
-+ |
- if (s->enc_write_ctx != NULL) |
-- reuse_dd = 1; |
-+ EVP_CIPHER_CTX_cleanup(s->enc_write_ctx); |
- else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) |
- goto err; |
- else |
- /* make sure it's intialized in case we exit later with an error */ |
- EVP_CIPHER_CTX_init(s->enc_write_ctx); |
-- dd= s->enc_write_ctx; |
-- mac_ctx = ssl_replace_hash(&s->write_hash,NULL); |
--#ifndef OPENSSL_NO_COMP |
-- if (s->compress != NULL) |
-- { |
-- COMP_CTX_free(s->compress); |
-- s->compress=NULL; |
-- } |
-- if (comp != NULL) |
-- { |
-- s->compress=COMP_CTX_new(comp->method); |
-- if (s->compress == NULL) |
-- { |
-- SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR); |
-- goto err2; |
-- } |
-- } |
--#endif |
-- /* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */ |
-- if (s->version != DTLS1_VERSION) |
-- memset(&(s->s3->write_sequence[0]),0,8); |
-- mac_secret= &(s->s3->write_mac_secret[0]); |
-- mac_secret_size = &(s->s3->write_mac_secret_size); |
-- } |
-- |
-- if (reuse_dd) |
-- EVP_CIPHER_CTX_cleanup(dd); |
- |
-- p=s->s3->tmp.key_block; |
-- i=*mac_secret_size=s->s3->tmp.new_mac_secret_size; |
-+ cipher_ctx = s->enc_write_ctx; |
-+ mac_ctx = ssl_replace_hash(&s->write_hash, NULL); |
- |
-- cl=EVP_CIPHER_key_length(c); |
-- j=is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? |
-- cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; |
-- /* Was j=(exp)?5:EVP_CIPHER_key_length(c); */ |
-- /* If GCM mode only part of IV comes from PRF */ |
-- if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) |
-- k = EVP_GCM_TLS_FIXED_IV_LEN; |
-- else |
-- k=EVP_CIPHER_iv_length(c); |
-- if ( (which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || |
-- (which == SSL3_CHANGE_CIPHER_SERVER_READ)) |
-- { |
-- ms= &(p[ 0]); n=i+i; |
-- key= &(p[ n]); n+=j+j; |
-- iv= &(p[ n]); n+=k+k; |
-- exp_label=(unsigned char *)TLS_MD_CLIENT_WRITE_KEY_CONST; |
-- exp_label_len=TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE; |
-- client_write=1; |
-- } |
-- else |
-- { |
-- n=i; |
-- ms= &(p[ n]); n+=i+j; |
-- key= &(p[ n]); n+=j+k; |
-- iv= &(p[ n]); n+=k; |
-- exp_label=(unsigned char *)TLS_MD_SERVER_WRITE_KEY_CONST; |
-- exp_label_len=TLS_MD_SERVER_WRITE_KEY_CONST_SIZE; |
-- client_write=0; |
-+ memcpy(s->s3->write_mac_secret, mac_secret, mac_secret_len); |
-+ s->s3->write_mac_secret_size = mac_secret_len; |
- } |
- |
-- if (n > s->s3->tmp.key_block_length) |
-- { |
-- SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR); |
-- goto err2; |
-- } |
-- |
-- memcpy(mac_secret,ms,i); |
-- |
-- if (!(EVP_CIPHER_flags(c)&EVP_CIPH_FLAG_AEAD_CIPHER)) |
-- { |
-- mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, |
-- mac_secret,*mac_secret_size); |
-- EVP_DigestSignInit(mac_ctx,NULL,m,NULL,mac_key); |
-- EVP_PKEY_free(mac_key); |
-- } |
--#ifdef TLS_DEBUG |
--printf("which = %04X\nmac key=",which); |
--{ int z; for (z=0; z<i; z++) printf("%02X%c",ms[z],((z+1)%16)?' ':'\n'); } |
--#endif |
- if (is_export) |
- { |
- /* In here I set both the read and write key/iv to the |
- * same value since only the correct one will be used :-). |
- */ |
-+ const unsigned char *label; |
-+ unsigned label_len; |
-+ |
-+ if (use_client_keys) |
-+ { |
-+ label = (const unsigned char*) TLS_MD_CLIENT_WRITE_KEY_CONST; |
-+ label_len = TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE; |
-+ } |
-+ else |
-+ { |
-+ label = (const unsigned char*) TLS_MD_SERVER_WRITE_KEY_CONST; |
-+ label_len = TLS_MD_SERVER_WRITE_KEY_CONST_SIZE; |
-+ } |
-+ |
- if (!tls1_PRF(ssl_get_algorithm2(s), |
-- exp_label,exp_label_len, |
-- s->s3->client_random,SSL3_RANDOM_SIZE, |
-- s->s3->server_random,SSL3_RANDOM_SIZE, |
-- NULL,0,NULL,0, |
-- key,j,tmp1,tmp2,EVP_CIPHER_key_length(c))) |
-- goto err2; |
-- key=tmp1; |
-+ label, label_len, |
-+ s->s3->client_random, SSL3_RANDOM_SIZE, |
-+ s->s3->server_random, SSL3_RANDOM_SIZE, |
-+ NULL, 0, NULL, 0, |
-+ key /* secret */, key_len /* secret length */, |
-+ export_tmp1 /* output */, |
-+ export_tmp2 /* scratch space */, |
-+ EVP_CIPHER_key_length(s->s3->tmp.new_sym_enc) /* output length */)) |
-+ return 0; |
-+ key = export_tmp1; |
- |
-- if (k > 0) |
-+ if (iv_len > 0) |
- { |
-+ static const unsigned char empty[] = ""; |
-+ |
- if (!tls1_PRF(ssl_get_algorithm2(s), |
-- TLS_MD_IV_BLOCK_CONST,TLS_MD_IV_BLOCK_CONST_SIZE, |
-- s->s3->client_random,SSL3_RANDOM_SIZE, |
-- s->s3->server_random,SSL3_RANDOM_SIZE, |
-- NULL,0,NULL,0, |
-- empty,0,iv1,iv2,k*2)) |
-- goto err2; |
-- if (client_write) |
-- iv=iv1; |
-+ TLS_MD_IV_BLOCK_CONST, TLS_MD_IV_BLOCK_CONST_SIZE, |
-+ s->s3->client_random, SSL3_RANDOM_SIZE, |
-+ s->s3->server_random, SSL3_RANDOM_SIZE, |
-+ NULL, 0, NULL, 0, |
-+ empty /* secret */ ,0 /* secret length */, |
-+ export_iv1 /* output */, |
-+ export_iv2 /* scratch space */, |
-+ iv_len * 2 /* output length */)) |
-+ return 0; |
-+ |
-+ if (use_client_keys) |
-+ iv = export_iv1; |
- else |
-- iv= &(iv1[k]); |
-+ iv = &export_iv1[iv_len]; |
- } |
- } |
- |
-- s->session->key_arg_length=0; |
--#ifdef KSSL_DEBUG |
-- { |
-- int i; |
-- printf("EVP_CipherInit_ex(dd,c,key=,iv=,which)\n"); |
-- printf("\tkey= "); for (i=0; i<c->key_len; i++) printf("%02x", key[i]); |
-- printf("\n"); |
-- printf("\t iv= "); for (i=0; i<c->iv_len; i++) printf("%02x", iv[i]); |
-- printf("\n"); |
-- } |
--#endif /* KSSL_DEBUG */ |
-+ /* is_aead_cipher indicates whether the EVP_CIPHER implements an AEAD |
-+ * interface. This is different from the newer EVP_AEAD interface. */ |
-+ is_aead_cipher = (EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) != 0; |
- |
-- if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) |
-+ if (!is_aead_cipher) |
- { |
-- EVP_CipherInit_ex(dd,c,NULL,key,NULL,(which & SSL3_CC_WRITE)); |
-- EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GCM_SET_IV_FIXED, k, iv); |
-+ EVP_PKEY *mac_key = |
-+ EVP_PKEY_new_mac_key(s->s3->tmp.new_mac_pkey_type, |
-+ NULL, mac_secret, mac_secret_len); |
-+ if (!mac_key) |
-+ return 0; |
-+ EVP_DigestSignInit(mac_ctx, NULL, s->s3->tmp.new_hash, NULL, mac_key); |
-+ EVP_PKEY_free(mac_key); |
- } |
-- else |
-- EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE)); |
-+ |
-+ if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE) |
-+ { |
-+ EVP_CipherInit_ex(cipher_ctx, cipher, NULL /* engine */, key, |
-+ NULL /* iv */, !is_read); |
-+ EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_GCM_SET_IV_FIXED, iv_len, (void*) iv); |
-+ } |
-+ else |
-+ EVP_CipherInit_ex(cipher_ctx, cipher, NULL /* engine */, key, iv, !is_read); |
- |
- /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */ |
-- if ((EVP_CIPHER_flags(c)&EVP_CIPH_FLAG_AEAD_CIPHER) && *mac_secret_size) |
-- EVP_CIPHER_CTX_ctrl(dd,EVP_CTRL_AEAD_SET_MAC_KEY, |
-- *mac_secret_size,mac_secret); |
-- |
--#ifdef TLS_DEBUG |
--printf("which = %04X\nkey=",which); |
--{ int z; for (z=0; z<EVP_CIPHER_key_length(c); z++) printf("%02X%c",key[z],((z+1)%16)?' ':'\n'); } |
--printf("\niv="); |
--{ int z; for (z=0; z<k; z++) printf("%02X%c",iv[z],((z+1)%16)?' ':'\n'); } |
--printf("\n"); |
--#endif |
-- |
-- OPENSSL_cleanse(tmp1,sizeof(tmp1)); |
-- OPENSSL_cleanse(tmp2,sizeof(tmp1)); |
-- OPENSSL_cleanse(iv1,sizeof(iv1)); |
-- OPENSSL_cleanse(iv2,sizeof(iv2)); |
-- return(1); |
-+ if (is_aead_cipher && mac_secret_len > 0) |
-+ EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_AEAD_SET_MAC_KEY, |
-+ mac_secret_len, (void*) mac_secret); |
-+ |
-+ if (is_export) |
-+ { |
-+ OPENSSL_cleanse(export_tmp1, sizeof(export_tmp1)); |
-+ OPENSSL_cleanse(export_tmp2, sizeof(export_tmp1)); |
-+ OPENSSL_cleanse(export_iv1, sizeof(export_iv1)); |
-+ OPENSSL_cleanse(export_iv2, sizeof(export_iv2)); |
-+ } |
-+ |
-+ return 1; |
-+ |
-+err: |
-+ SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE_CIPHER, ERR_R_MALLOC_FAILURE); |
-+ return 0; |
-+ } |
-+ |
-+int tls1_change_cipher_state(SSL *s, int which) |
-+ { |
-+ /* is_read is true if we have just read a ChangeCipherSpec message - |
-+ * i.e. we need to update the read cipherspec. Otherwise we have just |
-+ * written one. */ |
-+ const char is_read = (which & SSL3_CC_READ) != 0; |
-+ /* use_client_keys is true if we wish to use the keys for the "client |
-+ * write" direction. This is the case if we're a client sending a |
-+ * ChangeCipherSpec, or a server reading a client's ChangeCipherSpec. */ |
-+ const char use_client_keys = which == SSL3_CHANGE_CIPHER_CLIENT_WRITE || |
-+ which == SSL3_CHANGE_CIPHER_SERVER_READ; |
-+ const unsigned char *client_write_mac_secret, *server_write_mac_secret, *mac_secret; |
-+ const unsigned char *client_write_key, *server_write_key, *key; |
-+ const unsigned char *client_write_iv, *server_write_iv, *iv; |
-+ const EVP_CIPHER *cipher = s->s3->tmp.new_sym_enc; |
-+ unsigned key_len, iv_len, mac_secret_len; |
-+ const unsigned char *key_data; |
-+ const char is_export = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) != 0; |
-+ |
-+ /* Update compression contexts. */ |
-+#ifndef OPENSSL_NO_COMP |
-+ const SSL_COMP *comp = s->s3->tmp.new_compression; |
-+ |
-+ if (is_read) |
-+ { |
-+ if (s->expand != NULL) |
-+ { |
-+ COMP_CTX_free(s->expand); |
-+ s->expand = NULL; |
-+ } |
-+ if (comp != NULL) |
-+ { |
-+ s->expand=COMP_CTX_new(comp->method); |
-+ if (s->expand == NULL) |
-+ { |
-+ SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR); |
-+ return 0; |
-+ } |
-+ if (s->s3->rrec.comp == NULL) |
-+ s->s3->rrec.comp = |
-+ (unsigned char *)OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH); |
-+ if (s->s3->rrec.comp == NULL) |
-+ goto err; |
-+ } |
-+ } |
-+ else |
-+ { |
-+ if (s->compress != NULL) |
-+ { |
-+ COMP_CTX_free(s->compress); |
-+ s->compress = NULL; |
-+ } |
-+ if (comp != NULL) |
-+ { |
-+ s->compress = COMP_CTX_new(comp->method); |
-+ if (s->compress == NULL) |
-+ { |
-+ SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR); |
-+ return 0; |
-+ } |
-+ } |
-+ } |
-+#endif /* OPENSSL_NO_COMP */ |
-+ |
-+ /* Reset sequence number to zero. */ |
-+ memset(is_read ? s->s3->read_sequence : s->s3->write_sequence, 0, 8); |
-+ |
-+ /* key_arg is used for SSLv2. We don't need it for TLS. */ |
-+ s->session->key_arg_length = 0; |
-+ |
-+ mac_secret_len = s->s3->tmp.new_mac_secret_size; |
-+ |
-+ key_len = EVP_CIPHER_key_length(cipher); |
-+ if (is_export && key_len > SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) |
-+ key_len = SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher); |
-+ |
-+ if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE) |
-+ iv_len = EVP_GCM_TLS_FIXED_IV_LEN; |
-+ else |
-+ iv_len = EVP_CIPHER_iv_length(cipher); |
-+ |
-+ key_data = s->s3->tmp.key_block; |
-+ client_write_mac_secret = key_data; key_data += mac_secret_len; |
-+ server_write_mac_secret = key_data; key_data += mac_secret_len; |
-+ client_write_key = key_data; key_data += key_len; |
-+ server_write_key = key_data; key_data += key_len; |
-+ client_write_iv = key_data; key_data += iv_len; |
-+ server_write_iv = key_data; key_data += iv_len; |
-+ |
-+ if (use_client_keys) |
-+ { |
-+ mac_secret = client_write_mac_secret; |
-+ key = client_write_key; |
-+ iv = client_write_iv; |
-+ } |
-+ else |
-+ { |
-+ mac_secret = server_write_mac_secret; |
-+ key = server_write_key; |
-+ iv = server_write_iv; |
-+ } |
-+ |
-+ if (key_data - s->s3->tmp.key_block != s->s3->tmp.key_block_length) |
-+ { |
-+ SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR); |
-+ return 0; |
-+ } |
-+ |
-+ if (!tls1_change_cipher_state_cipher(s, is_read, use_client_keys, |
-+ mac_secret, mac_secret_len, |
-+ key, key_len, |
-+ iv, iv_len)) { |
-+ return 0; |
-+ } |
-+ |
-+ return 1; |
- err: |
-- SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE); |
--err2: |
-- return(0); |
-+ SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); |
-+ return 0; |
- } |
- |
- int tls1_setup_key_block(SSL *s) |
-@@ -584,6 +609,7 @@ int tls1_setup_key_block(SSL *s) |
- SSL_COMP *comp; |
- int mac_type= NID_undef,mac_secret_size=0; |
- int ret=0; |
-+ int iv_len; |
- |
- #ifdef KSSL_DEBUG |
- printf ("tls1_setup_key_block()\n"); |
-@@ -598,11 +624,16 @@ int tls1_setup_key_block(SSL *s) |
- return(0); |
- } |
- |
-+ if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) |
-+ iv_len = EVP_GCM_TLS_FIXED_IV_LEN; |
-+ else |
-+ iv_len = EVP_CIPHER_iv_length(c); |
-+ |
- s->s3->tmp.new_sym_enc=c; |
- s->s3->tmp.new_hash=hash; |
- s->s3->tmp.new_mac_pkey_type = mac_type; |
- s->s3->tmp.new_mac_secret_size = mac_secret_size; |
-- num=EVP_CIPHER_key_length(c)+mac_secret_size+EVP_CIPHER_iv_length(c); |
-+ num=EVP_CIPHER_key_length(c)+mac_secret_size+iv_len; |
- num*=2; |
- |
- ssl3_cleanup_key_block(s); |
--- |
-1.8.4.1 |
- |