{
int chunk;
size_t j;
- EVP_MD_CTX ctx, ctx_tmp;
+ EVP_MD_CTX ctx, ctx_tmp, ctx_init;
EVP_PKEY *mac_key;
unsigned char A1[EVP_MAX_MD_SIZE];
size_t A1_len;
EVP_MD_CTX_init(&ctx);
EVP_MD_CTX_init(&ctx_tmp);
- EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
- EVP_MD_CTX_set_flags(&ctx_tmp, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+ EVP_MD_CTX_init(&ctx_init);
+ EVP_MD_CTX_set_flags(&ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len);
if (!mac_key)
goto err;
- if (!EVP_DigestSignInit(&ctx,NULL,md, NULL, mac_key))
+ if (!EVP_DigestSignInit(&ctx_init,NULL,md, NULL, mac_key))
goto err;
- if (!EVP_DigestSignInit(&ctx_tmp,NULL,md, NULL, mac_key))
+ if (!EVP_MD_CTX_copy_ex(&ctx,&ctx_init))
goto err;
if (seed1 && !EVP_DigestSignUpdate(&ctx,seed1,seed1_len))
goto err;
for (;;)
{
/* Reinit mac contexts */
- if (!EVP_DigestSignInit(&ctx,NULL,md, NULL, mac_key))
- goto err;
- if (!EVP_DigestSignInit(&ctx_tmp,NULL,md, NULL, mac_key))
+ if (!EVP_MD_CTX_copy_ex(&ctx,&ctx_init))
goto err;
if (!EVP_DigestSignUpdate(&ctx,A1,A1_len))
goto err;
- if (!EVP_DigestSignUpdate(&ctx_tmp,A1,A1_len))
+ if (olen>chunk && !EVP_MD_CTX_copy_ex(&ctx_tmp,&ctx))
goto err;
if (seed1 && !EVP_DigestSignUpdate(&ctx,seed1,seed1_len))
goto err;
EVP_PKEY_free(mac_key);
EVP_MD_CTX_cleanup(&ctx);
EVP_MD_CTX_cleanup(&ctx_tmp);
+ EVP_MD_CTX_cleanup(&ctx_init);
OPENSSL_cleanse(A1,sizeof(A1));
return ret;
}
s->session->master_key,s->session->master_key_length,
km,tmp,num);
#ifdef KSSL_DEBUG
- printf("tls1_generate_key_block() ==> %d byte master_key =\n\t",
+ fprintf(stderr,"tls1_generate_key_block() ==> %d byte master_key =\n\t",
s->session->master_key_length);
{
int i;
for (i=0; i < s->session->master_key_length; i++)
{
- printf("%02X", s->session->master_key[i]);
+ fprintf(stderr,"%02X", s->session->master_key[i]);
}
- printf("\n"); }
+ fprintf(stderr,"\n"); }
#endif /* KSSL_DEBUG */
return ret;
}
-/* 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)
+int tls1_change_cipher_state(SSL *s, int which)
{
- 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;
+ 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;
EVP_MD_CTX *mac_ctx;
- char is_aead_cipher;
+ EVP_PKEY *mac_key;
+ int is_export,n,i,j,k,exp_label_len,cl;
+ int reuse_dd = 0;
- 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];
+ 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
- if (is_read)
+#ifdef KSSL_DEBUG
+ fprintf(stderr,"tls1_change_cipher_state(which= %d) w/\n", which);
+ fprintf(stderr,"\talg= %ld/%ld, comp= %p\n",
+ s->s3->tmp.new_cipher->algorithm_mkey,
+ s->s3->tmp.new_cipher->algorithm_auth,
+ comp);
+ fprintf(stderr,"\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c);
+ fprintf(stderr,"\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n",
+ c->nid,c->block_size,c->key_len,c->iv_len);
+ fprintf(stderr,"\tkey_block: len= %d, data= ", s->s3->tmp.key_block_length);
+ {
+ int i;
+ for (i=0; i<s->s3->tmp.key_block_length; i++)
+ fprintf(stderr,"%02x", s->s3->tmp.key_block[i]); fprintf(stderr,"\n");
+ }
+#endif /* KSSL_DEBUG */
+
+ if (which & SSL3_CC_READ)
{
if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM;
s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM;
if (s->enc_read_ctx != NULL)
- EVP_CIPHER_CTX_cleanup(s->enc_read_ctx);
+ reuse_dd = 1;
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);
-
- 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
- s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM;
-
- if (s->enc_write_ctx != NULL)
- 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);
-
- cipher_ctx = s->enc_write_ctx;
- mac_ctx = ssl_replace_hash(&s->write_hash, NULL);
-
- memcpy(s->s3->write_mac_secret, mac_secret, mac_secret_len);
- s->s3->write_mac_secret_size = mac_secret_len;
- }
-
- 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),
- 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 (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 /* 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 = &export_iv1[iv_len];
- }
- }
-
- /* 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 (!is_aead_cipher)
- {
- 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);
- }
-
- 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 (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. */
+ dd= s->enc_read_ctx;
+ mac_ctx=ssl_replace_hash(&s->read_hash,NULL);
#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;
+ s->expand=NULL;
}
if (comp != NULL)
{
if (s->expand == NULL)
{
SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
- return 0;
+ goto err2;
}
if (s->s3->rrec.comp == NULL)
- s->s3->rrec.comp =
- (unsigned char *)OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH);
+ 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);
}
else
{
+ if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
+ s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM;
+ else
+ s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM;
+ if (s->enc_write_ctx != NULL && !SSL_IS_DTLS(s))
+ reuse_dd = 1;
+ else if ((s->enc_write_ctx=EVP_CIPHER_CTX_new()) == NULL)
+ goto err;
+ dd= s->enc_write_ctx;
+ if (SSL_IS_DTLS(s))
+ {
+ mac_ctx = EVP_MD_CTX_create();
+ if (!mac_ctx)
+ goto err;
+ s->write_hash = mac_ctx;
+ }
+ else
+ 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;
+ s->compress=NULL;
}
if (comp != NULL)
{
- s->compress = COMP_CTX_new(comp->method);
+ 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;
+ 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);
}
-#endif /* OPENSSL_NO_COMP */
- /* Reset sequence number to zero. */
- memset(is_read ? s->s3->read_sequence : s->s3->write_sequence, 0, 8);
+ if (reuse_dd)
+ EVP_CIPHER_CTX_cleanup(dd);
- /* key_arg is used for SSLv2. We don't need it for TLS. */
- s->session->key_arg_length = 0;
+ p=s->s3->tmp.key_block;
+ i=*mac_secret_size=s->s3->tmp.new_mac_secret_size;
- 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;
+ 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
- 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)
+ k=EVP_CIPHER_iv_length(c);
+ if ( (which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
+ (which == SSL3_CHANGE_CIPHER_SERVER_READ))
{
- mac_secret = client_write_mac_secret;
- key = client_write_key;
- iv = client_write_iv;
+ 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
{
- mac_secret = server_write_mac_secret;
- key = server_write_key;
- iv = server_write_iv;
+ 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;
}
- if (key_data - s->s3->tmp.key_block != s->s3->tmp.key_block_length)
+ if (n > s->s3->tmp.key_block_length)
{
SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR);
- return 0;
+ goto err2;
}
- 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;
+ 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 :-).
+ */
+ 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;
+
+ if (k > 0)
+ {
+ 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;
+ else
+ iv= &(iv1[k]);
+ }
+ }
+
+ s->session->key_arg_length=0;
+#ifdef KSSL_DEBUG
+ {
+ int i;
+ fprintf(stderr,"EVP_CipherInit_ex(dd,c,key=,iv=,which)\n");
+ fprintf(stderr,"\tkey= "); for (i=0; i<c->key_len; i++) fprintf(stderr,"%02x", key[i]);
+ fprintf(stderr,"\n");
+ fprintf(stderr,"\t iv= "); for (i=0; i<c->iv_len; i++) fprintf(stderr,"%02x", iv[i]);
+ fprintf(stderr,"\n");
}
+#endif /* KSSL_DEBUG */
+
+ if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE)
+ {
+ 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);
+ }
+ else
+ EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE));
+
+ /* 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 OPENSSL_SSL_TRACE_CRYPTO
if (s->msg_callback)
{
int wh = which & SSL3_CC_WRITE ? TLS1_RT_CRYPTO_WRITE : 0;
- if (mac_secret_len)
+ if (*mac_secret_size)
s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_MAC,
- mac_secret, mac_secret_len,
+ mac_secret, *mac_secret_size,
s, s->msg_callback_arg);
- if (key_len)
+ if (c->key_len)
s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_KEY,
- key, key_len,
+ key, c->key_len,
s, s->msg_callback_arg);
- if (iv_len)
+ if (k)
{
- if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE)
+ if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE)
wh |= TLS1_RT_CRYPTO_FIXED_IV;
else
wh |= TLS1_RT_CRYPTO_IV;
- s->msg_callback(2, s->version, wh, iv, iv_len,
+ s->msg_callback(2, s->version, wh, iv, k,
s, s->msg_callback_arg);
}
}
#endif
- return 1;
+#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);
err:
- SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE);
- return 0;
+ SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE);
+err2:
+ return(0);
}
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");
+ fprintf(stderr,"tls1_setup_key_block()\n");
#endif /* KSSL_DEBUG */
if (s->s3->tmp.key_block_length != 0)
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+iv_len;
+ num=EVP_CIPHER_key_length(c)+mac_secret_size+EVP_CIPHER_iv_length(c);
num*=2;
ssl3_cleanup_key_block(s);
return(ret);
}
-/* tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively.
+/*-
+ * tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively.
*
* Returns:
* 0: (in non-constant time) if the record is publically invalid (i.e. too
}
#ifdef KSSL_DEBUG
- printf("tls1_enc(%d)\n", send);
+ fprintf(stderr,"tls1_enc(%d)\n", send);
#endif /* KSSL_DEBUG */
if ((s->session == NULL) || (ds == NULL) || (enc == NULL))
#ifdef KSSL_DEBUG
{
unsigned long ui;
- printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
+ fprintf(stderr,"EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
ds,rec->data,rec->input,l);
- printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
+ fprintf(stderr,"\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%lu %lu], %d iv_len\n",
ds->buf_len, ds->cipher->key_len,
DES_KEY_SZ, DES_SCHEDULE_SZ,
ds->cipher->iv_len);
- printf("\t\tIV: ");
- for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
- printf("\n");
- printf("\trec->input=");
- for (ui=0; ui<l; ui++) printf(" %02x", rec->input[ui]);
- printf("\n");
+ fprintf(stderr,"\t\tIV: ");
+ for (i=0; i<ds->cipher->iv_len; i++) fprintf(stderr,"%02X", ds->iv[i]);
+ fprintf(stderr,"\n");
+ fprintf(stderr,"\trec->input=");
+ for (ui=0; ui<l; ui++) fprintf(stderr," %02x", rec->input[ui]);
+ fprintf(stderr,"\n");
}
#endif /* KSSL_DEBUG */
#ifdef KSSL_DEBUG
{
unsigned long i;
- printf("\trec->data=");
+ fprintf(stderr,"\trec->data=");
for (i=0; i<l; i++)
- printf(" %02x", rec->data[i]); printf("\n");
+ fprintf(stderr," %02x", rec->data[i]); fprintf(stderr,"\n");
}
#endif /* KSSL_DEBUG */
if (mask & ssl_get_algorithm2(s))
{
int hashsize = EVP_MD_size(md);
- if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
+ EVP_MD_CTX *hdgst = s->s3->handshake_dgst[idx];
+ if (!hdgst || hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
{
/* internal error: 'buf' is too small for this cipersuite! */
err = 1;
}
else
{
- EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]);
- EVP_DigestFinal_ex(&ctx,q,&i);
- if (i != (unsigned int)hashsize) /* can't really happen */
+ if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
+ !EVP_DigestFinal_ex(&ctx,q,&i) ||
+ (i != (unsigned int)hashsize))
err = 1;
- q+=i;
+ q+=hashsize;
}
}
}
}
else
{
- EVP_MD_CTX_copy(&hmac,hash);
+ if (!EVP_MD_CTX_copy(&hmac,hash))
+ return -1;
mac_ctx = &hmac;
}
* timing-side channel information about how many blocks of
* data we are hashing because that gives an attacker a
* timing-oracle. */
+ /* Final param == not SSLv3 */
ssl3_cbc_digest_record(
mac_ctx,
md, &md_size,
rec->length + md_size, orig_len,
ssl->s3->read_mac_secret,
ssl->s3->read_mac_secret_size,
- 0 /* not SSLv3 */);
+ 0);
}
else
{
if (!stream_mac)
EVP_MD_CTX_cleanup(&hmac);
#ifdef TLS_DEBUG
-printf("sec=");
-{unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",mac_sec[z]); printf("\n"); }
-printf("seq=");
-{int z; for (z=0; z<8; z++) printf("%02X ",seq[z]); printf("\n"); }
-printf("buf=");
-{int z; for (z=0; z<5; z++) printf("%02X ",buf[z]); printf("\n"); }
-printf("rec=");
-{unsigned int z; for (z=0; z<rec->length; z++) printf("%02X ",buf[z]); printf("\n"); }
+fprintf(stderr,"seq=");
+{int z; for (z=0; z<8; z++) fprintf(stderr,"%02X ",seq[z]); fprintf(stderr,"\n"); }
+fprintf(stderr,"rec=");
+{unsigned int z; for (z=0; z<rec->length; z++) fprintf(stderr,"%02X ",rec->data[z]); fprintf(stderr,"\n"); }
#endif
if (!SSL_IS_DTLS(ssl))
}
#ifdef TLS_DEBUG
-{unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",md[z]); printf("\n"); }
+{unsigned int z; for (z=0; z<md_size; z++) fprintf(stderr,"%02X ",md[z]); fprintf(stderr,"\n"); }
#endif
return(md_size);
}
#ifdef KSSL_DEBUG
- printf ("tls1_generate_master_secret(%p,%p, %p, %d)\n", s,out, p,len);
+ fprintf(stderr,"tls1_generate_master_secret(%p,%p, %p, %d)\n", s,out, p,len);
#endif /* KSSL_DEBUG */
#ifdef TLSEXT_TYPE_opaque_prf_input
#endif
#ifdef KSSL_DEBUG
- printf ("tls1_generate_master_secret() complete\n");
+ fprintf(stderr,"tls1_generate_master_secret() complete\n");
#endif /* KSSL_DEBUG */
return(SSL3_MASTER_SECRET_SIZE);
}
int rv;
#ifdef KSSL_DEBUG
- printf ("tls1_export_keying_material(%p,%p,%d,%s,%d,%p,%d)\n", s, out, olen, label, llen, p, plen);
+ fprintf(stderr,"tls1_export_keying_material(%p,%p,%lu,%s,%lu,%p,%lu)\n", s, out, olen, label, llen, context, contextlen);
#endif /* KSSL_DEBUG */
buff = OPENSSL_malloc(olen);
if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST,
TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) goto err1;
- rv = tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+ rv = tls1_PRF(ssl_get_algorithm2(s),
val, vallen,
NULL, 0,
NULL, 0,
out,buff,olen);
#ifdef KSSL_DEBUG
- printf ("tls1_export_keying_material() complete\n");
+ fprintf(stderr,"tls1_export_keying_material() complete\n");
#endif /* KSSL_DEBUG */
goto ret;
err1:
case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE);
case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(TLS1_AD_BAD_CERTIFICATE_HASH_VALUE);
case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
+ case SSL_AD_INAPPROPRIATE_FALLBACK:return(TLS1_AD_INAPPROPRIATE_FALLBACK);
#if 0 /* not appropriate for TLS, not used for DTLS */
case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return
(DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);