Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Unified Diff: openssl/patches/tls1_change_cipher_state_rewrite.patch

Issue 59083010: third_party/openssl: add ChaCha20+Poly1305 support. Base URL: https://chromium.googlesource.com/chromium/deps/openssl.git@master
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « openssl/patches/neon_runtime.patch ('k') | openssl/patches/use_aead_for_aes_gcm.patch » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
new file mode 100644
index 0000000000000000000000000000000000000000..eab3f7f685629909fc996d9ab9da865952280b36
--- /dev/null
+++ b/openssl/patches/tls1_change_cipher_state_rewrite.patch
@@ -0,0 +1,567 @@
+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
+
« no previous file with comments | « openssl/patches/neon_runtime.patch ('k') | openssl/patches/use_aead_for_aes_gcm.patch » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698