diff options
author | Matt Caswell <matt@openssl.org> | 2015-01-22 02:47:42 +0000 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2015-01-22 09:52:55 +0000 |
commit | 40720ce3caf44294b5b87a18856b7aef06123314 (patch) | |
tree | 30d57dec407c05fe6ea57275517805e8c79a7dcc /ssl/t1_enc.c | |
parent | 9d03aabea3ead1fe6a194297ddffd4a87f89b93c (diff) |
Run util/openssl-format-source -v -c .
Reviewed-by: Tim Hudson <tjh@openssl.org>
Diffstat (limited to 'ssl/t1_enc.c')
-rw-r--r-- | ssl/t1_enc.c | 1398 |
1 files changed, 730 insertions, 668 deletions
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index c36de5212f..c5e7f236c3 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -5,21 +5,21 @@ * This package is an SSL implementation written * by Eric Young (eay@cryptsoft.com). * The implementation was written so as to conform with Netscapes SSL. - * + * * This library is free for commercial and non-commercial use as long as * the following conditions are aheared to. The following conditions * apply to all code found in this distribution, be it the RC4, RSA, * lhash, DES, etc., code; not just the SSL code. The SSL documentation * included with this distribution is covered by the same copyright terms * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * + * * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. * If this package is used in a product, Eric Young should be given attribution * as the author of the parts of the library used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -34,10 +34,10 @@ * Eric Young (eay@cryptsoft.com)" * The word 'cryptographic' can be left out if the rouines from the library * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from + * 4. If you include any Windows specific code (or a derivative thereof) from * the apps directory (application code) you must include an acknowledgement: * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * + * * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -49,7 +49,7 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * + * * The licence and distribution terms for any publically available version or * derivative of this code cannot be changed. i.e. this code cannot simply be * copied and put under another distribution licence @@ -63,7 +63,7 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in @@ -112,422 +112,452 @@ #include <stdio.h> #include "ssl_locl.h" #ifndef OPENSSL_NO_COMP -#include <openssl/comp.h> +# include <openssl/comp.h> #endif #include <openssl/evp.h> #include <openssl/hmac.h> #include <openssl/md5.h> #ifdef KSSL_DEBUG -#include <openssl/des.h> +# include <openssl/des.h> #endif static void tls1_P_hash(const EVP_MD *md, const unsigned char *sec, - int sec_len, unsigned char *seed, int seed_len, - unsigned char *out, int olen) - { - int chunk; - unsigned int j; - HMAC_CTX ctx; - HMAC_CTX ctx_tmp; - unsigned char A1[EVP_MAX_MD_SIZE]; - unsigned int A1_len; - - chunk=EVP_MD_size(md); - - HMAC_CTX_init(&ctx); - HMAC_CTX_init(&ctx_tmp); - HMAC_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - HMAC_CTX_set_flags(&ctx_tmp, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - HMAC_Init_ex(&ctx,sec,sec_len,md, NULL); - HMAC_Init_ex(&ctx_tmp,sec,sec_len,md, NULL); - HMAC_Update(&ctx,seed,seed_len); - HMAC_Final(&ctx,A1,&A1_len); - - for (;;) - { - HMAC_Init_ex(&ctx,NULL,0,NULL,NULL); /* re-init */ - HMAC_Init_ex(&ctx_tmp,NULL,0,NULL,NULL); /* re-init */ - HMAC_Update(&ctx,A1,A1_len); - HMAC_Update(&ctx_tmp,A1,A1_len); - HMAC_Update(&ctx,seed,seed_len); - - if (olen > chunk) - { - HMAC_Final(&ctx,out,&j); - out+=j; - olen-=j; - /* calc the next A1 value */ - HMAC_Final(&ctx_tmp,A1,&A1_len); - } - else /* last one */ - { - HMAC_Final(&ctx,A1,&A1_len); - memcpy(out,A1,olen); - break; - } - } - HMAC_CTX_cleanup(&ctx); - HMAC_CTX_cleanup(&ctx_tmp); - OPENSSL_cleanse(A1,sizeof(A1)); - } + int sec_len, unsigned char *seed, int seed_len, + unsigned char *out, int olen) +{ + int chunk; + unsigned int j; + HMAC_CTX ctx; + HMAC_CTX ctx_tmp; + unsigned char A1[EVP_MAX_MD_SIZE]; + unsigned int A1_len; + + chunk = EVP_MD_size(md); + + HMAC_CTX_init(&ctx); + HMAC_CTX_init(&ctx_tmp); + HMAC_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + HMAC_CTX_set_flags(&ctx_tmp, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + HMAC_Init_ex(&ctx, sec, sec_len, md, NULL); + HMAC_Init_ex(&ctx_tmp, sec, sec_len, md, NULL); + HMAC_Update(&ctx, seed, seed_len); + HMAC_Final(&ctx, A1, &A1_len); + + for (;;) { + HMAC_Init_ex(&ctx, NULL, 0, NULL, NULL); /* re-init */ + HMAC_Init_ex(&ctx_tmp, NULL, 0, NULL, NULL); /* re-init */ + HMAC_Update(&ctx, A1, A1_len); + HMAC_Update(&ctx_tmp, A1, A1_len); + HMAC_Update(&ctx, seed, seed_len); + + if (olen > chunk) { + HMAC_Final(&ctx, out, &j); + out += j; + olen -= j; + /* calc the next A1 value */ + HMAC_Final(&ctx_tmp, A1, &A1_len); + } else { /* last one */ + + HMAC_Final(&ctx, A1, &A1_len); + memcpy(out, A1, olen); + break; + } + } + HMAC_CTX_cleanup(&ctx); + HMAC_CTX_cleanup(&ctx_tmp); + OPENSSL_cleanse(A1, sizeof(A1)); +} static void tls1_PRF(const EVP_MD *md5, const EVP_MD *sha1, - unsigned char *label, int label_len, - const unsigned char *sec, int slen, unsigned char *out1, - unsigned char *out2, int olen) - { - int len,i; - const unsigned char *S1,*S2; - - len=slen/2; - S1=sec; - S2= &(sec[len]); - len+=(slen&1); /* add for odd, make longer */ - - - tls1_P_hash(md5 ,S1,len,label,label_len,out1,olen); - tls1_P_hash(sha1,S2,len,label,label_len,out2,olen); - - for (i=0; i<olen; i++) - out1[i]^=out2[i]; - } + unsigned char *label, int label_len, + const unsigned char *sec, int slen, unsigned char *out1, + unsigned char *out2, int olen) +{ + int len, i; + const unsigned char *S1, *S2; + + len = slen / 2; + S1 = sec; + S2 = &(sec[len]); + len += (slen & 1); /* add for odd, make longer */ + + tls1_P_hash(md5, S1, len, label, label_len, out1, olen); + tls1_P_hash(sha1, S2, len, label, label_len, out2, olen); + + for (i = 0; i < olen; i++) + out1[i] ^= out2[i]; +} static void tls1_generate_key_block(SSL *s, unsigned char *km, - unsigned char *tmp, int num) - { - unsigned char *p; - unsigned char buf[SSL3_RANDOM_SIZE*2+ - TLS_MD_MAX_CONST_SIZE]; - p=buf; - - memcpy(p,TLS_MD_KEY_EXPANSION_CONST, - TLS_MD_KEY_EXPANSION_CONST_SIZE); - p+=TLS_MD_KEY_EXPANSION_CONST_SIZE; - memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE); - p+=SSL3_RANDOM_SIZE; - memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE); - p+=SSL3_RANDOM_SIZE; - - tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(p-buf), - s->session->master_key,s->session->master_key_length, - km,tmp,num); + unsigned char *tmp, int num) +{ + unsigned char *p; + unsigned char buf[SSL3_RANDOM_SIZE * 2 + TLS_MD_MAX_CONST_SIZE]; + p = buf; + + memcpy(p, TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE); + p += TLS_MD_KEY_EXPANSION_CONST_SIZE; + memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE); + p += SSL3_RANDOM_SIZE; + memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); + p += SSL3_RANDOM_SIZE; + + tls1_PRF(s->ctx->md5, s->ctx->sha1, buf, (int)(p - buf), + 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", - s->session->master_key_length); - { + printf("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]); - } - printf("\n"); } -#endif /* KSSL_DEBUG */ - } + for (i = 0; i < s->session->master_key_length; i++) { + printf("%02X", s->session->master_key[i]); + } + printf("\n"); + } +#endif /* KSSL_DEBUG */ +} int tls1_change_cipher_state(SSL *s, int which) - { - static const unsigned char empty[]=""; - unsigned char *p,*mac_secret; - unsigned char *exp_label,buf[TLS_MD_MAX_CONST_SIZE+ - SSL3_RANDOM_SIZE*2]; - 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; +{ + static const unsigned char empty[] = ""; + unsigned char *p, *mac_secret; + unsigned char *exp_label, buf[TLS_MD_MAX_CONST_SIZE + + SSL3_RANDOM_SIZE * 2]; + 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; + const SSL_COMP *comp; #endif - const EVP_MD *m; - int is_export,n,i,j,k,exp_label_len,cl; - int reuse_dd = 0; + const EVP_MD *m; + int is_export, n, i, j, k, exp_label_len, cl; + int reuse_dd = 0; - is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); - c=s->s3->tmp.new_sym_enc; - m=s->s3->tmp.new_hash; + is_export = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); + c = s->s3->tmp.new_sym_enc; + m = s->s3->tmp.new_hash; #ifndef OPENSSL_NO_COMP - comp=s->s3->tmp.new_compression; + comp = s->s3->tmp.new_compression; #endif #ifdef KSSL_DEBUG - key_block=s->s3->tmp.key_block; - - printf("tls1_change_cipher_state(which= %d) w/\n", which); - printf("\talg= %ld, comp= %p\n", s->s3->tmp.new_cipher->algorithms, - (void *)comp); - printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", (void *)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); - { + key_block = s->s3->tmp.key_block; + + printf("tls1_change_cipher_state(which= %d) w/\n", which); + printf("\talg= %ld, comp= %p\n", s->s3->tmp.new_cipher->algorithms, + (void *)comp); + printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", (void *)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 ki; - for (ki=0; ki<s->s3->tmp.key_block_length; ki++) - printf("%02x", s->s3->tmp.key_block[ki]); printf("\n"); - } -#endif /* KSSL_DEBUG */ - - if (which & SSL3_CC_READ) - { - if (s->enc_read_ctx != NULL) - 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); - dd= s->enc_read_ctx; - s->read_hash=m; + for (ki = 0; ki < s->s3->tmp.key_block_length; ki++) + printf("%02x", s->s3->tmp.key_block[ki]); + printf("\n"); + } +#endif /* KSSL_DEBUG */ + + if (which & SSL3_CC_READ) { + if (s->enc_read_ctx != NULL) + 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); + dd = s->enc_read_ctx; + s->read_hash = m; #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; - } + 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]); - } - else - { - if (s->enc_write_ctx != NULL) - reuse_dd = 1; - 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; - s->write_hash=m; + /* + * 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]); + } else { + if (s->enc_write_ctx != NULL) + reuse_dd = 1; + 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; + s->write_hash = m; #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; - } - } + 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]); - } - - if (reuse_dd) - EVP_CIPHER_CTX_cleanup(dd); - - p=s->s3->tmp.key_block; - i=EVP_MD_size(m); - 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); */ - 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; - } - - 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); + /* + * 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]); + } + + if (reuse_dd) + EVP_CIPHER_CTX_cleanup(dd); + + p = s->s3->tmp.key_block; + i = EVP_MD_size(m); + 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); */ + 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; + } + + 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); #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'); } + 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 :-). - */ - p=buf; - memcpy(p,exp_label,exp_label_len); - p+=exp_label_len; - memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE); - p+=SSL3_RANDOM_SIZE; - memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE); - p+=SSL3_RANDOM_SIZE; - tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(p-buf),key,j, - tmp1,tmp2,EVP_CIPHER_key_length(c)); - key=tmp1; - - if (k > 0) - { - p=buf; - memcpy(p,TLS_MD_IV_BLOCK_CONST, - TLS_MD_IV_BLOCK_CONST_SIZE); - p+=TLS_MD_IV_BLOCK_CONST_SIZE; - memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE); - p+=SSL3_RANDOM_SIZE; - memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE); - p+=SSL3_RANDOM_SIZE; - tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,p-buf,empty,0, - iv1,iv2,k*2); - if (client_write) - iv=iv1; - else - iv= &(iv1[k]); - } - } - - s->session->key_arg_length=0; + 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 :-). + */ + p = buf; + memcpy(p, exp_label, exp_label_len); + p += exp_label_len; + memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); + p += SSL3_RANDOM_SIZE; + memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE); + p += SSL3_RANDOM_SIZE; + tls1_PRF(s->ctx->md5, s->ctx->sha1, buf, (int)(p - buf), key, j, + tmp1, tmp2, EVP_CIPHER_key_length(c)); + key = tmp1; + + if (k > 0) { + p = buf; + memcpy(p, TLS_MD_IV_BLOCK_CONST, TLS_MD_IV_BLOCK_CONST_SIZE); + p += TLS_MD_IV_BLOCK_CONST_SIZE; + memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); + p += SSL3_RANDOM_SIZE; + memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE); + p += SSL3_RANDOM_SIZE; + tls1_PRF(s->ctx->md5, s->ctx->sha1, buf, p - buf, empty, 0, + iv1, iv2, k * 2); + if (client_write) + iv = iv1; + else + iv = &(iv1[k]); + } + } + + s->session->key_arg_length = 0; #ifdef KSSL_DEBUG - { + { int ki; - printf("EVP_CipherInit_ex(dd,c,key=,iv=,which)\n"); - printf("\tkey= "); - for (ki=0; ki<c->key_len; ki++) printf("%02x", key[ki]); - printf("\n"); - printf("\t iv= "); - for (ki=0; ki<c->iv_len; ki++) printf("%02x", iv[ki]); - printf("\n"); - } -#endif /* KSSL_DEBUG */ - - EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE)); + printf("EVP_CipherInit_ex(dd,c,key=,iv=,which)\n"); + printf("\tkey= "); + for (ki = 0; ki < c->key_len; ki++) + printf("%02x", key[ki]); + printf("\n"); + printf("\t iv= "); + for (ki = 0; ki < c->iv_len; ki++) + printf("%02x", iv[ki]); + printf("\n"); + } +#endif /* KSSL_DEBUG */ + + EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE)); #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"); + 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); -err2: - return(0); - } + 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); + err2: + return (0); +} int tls1_setup_key_block(SSL *s) - { - unsigned char *p1,*p2; - const EVP_CIPHER *c; - const EVP_MD *hash; - int num; - SSL_COMP *comp; +{ + unsigned char *p1, *p2; + const EVP_CIPHER *c; + const EVP_MD *hash; + int num; + SSL_COMP *comp; #ifdef KSSL_DEBUG - printf ("tls1_setup_key_block()\n"); -#endif /* KSSL_DEBUG */ - - if (s->s3->tmp.key_block_length != 0) - return(1); + printf("tls1_setup_key_block()\n"); +#endif /* KSSL_DEBUG */ - if (!ssl_cipher_get_evp(s->session,&c,&hash,&comp)) - { - SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE); - return(0); - } + if (s->s3->tmp.key_block_length != 0) + return (1); - s->s3->tmp.new_sym_enc=c; - s->s3->tmp.new_hash=hash; + if (!ssl_cipher_get_evp(s->session, &c, &hash, &comp)) { + SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, SSL_R_CIPHER_OR_HASH_UNAVAILABLE); + return (0); + } - num=EVP_CIPHER_key_length(c)+EVP_MD_size(hash)+EVP_CIPHER_iv_length(c); - num*=2; + s->s3->tmp.new_sym_enc = c; + s->s3->tmp.new_hash = hash; - ssl3_cleanup_key_block(s); + num = + EVP_CIPHER_key_length(c) + EVP_MD_size(hash) + + EVP_CIPHER_iv_length(c); + num *= 2; - if ((p1=(unsigned char *)OPENSSL_malloc(num)) == NULL) - goto err; - if ((p2=(unsigned char *)OPENSSL_malloc(num)) == NULL) - goto err; + ssl3_cleanup_key_block(s); - s->s3->tmp.key_block_length=num; - s->s3->tmp.key_block=p1; + if ((p1 = (unsigned char *)OPENSSL_malloc(num)) == NULL) + goto err; + if ((p2 = (unsigned char *)OPENSSL_malloc(num)) == NULL) + goto err; + s->s3->tmp.key_block_length = num; + s->s3->tmp.key_block = p1; #ifdef TLS_DEBUG -printf("client random\n"); -{ int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) printf("%02X%c",s->s3->client_random[z],((z+1)%16)?' ':'\n'); } -printf("server random\n"); -{ int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) printf("%02X%c",s->s3->server_random[z],((z+1)%16)?' ':'\n'); } -printf("pre-master\n"); -{ int z; for (z=0; z<s->session->master_key_length; z++) printf("%02X%c",s->session->master_key[z],((z+1)%16)?' ':'\n'); } + printf("client random\n"); + { + int z; + for (z = 0; z < SSL3_RANDOM_SIZE; z++) + printf("%02X%c", s->s3->client_random[z], + ((z + 1) % 16) ? ' ' : '\n'); + } + printf("server random\n"); + { + int z; + for (z = 0; z < SSL3_RANDOM_SIZE; z++) + printf("%02X%c", s->s3->server_random[z], + ((z + 1) % 16) ? ' ' : '\n'); + } + printf("pre-master\n"); + { + int z; + for (z = 0; z < s->session->master_key_length; z++) + printf("%02X%c", s->session->master_key[z], + ((z + 1) % 16) ? ' ' : '\n'); + } #endif - tls1_generate_key_block(s,p1,p2,num); - OPENSSL_cleanse(p2,num); - OPENSSL_free(p2); + tls1_generate_key_block(s, p1, p2, num); + OPENSSL_cleanse(p2, num); + OPENSSL_free(p2); #ifdef TLS_DEBUG -printf("\nkey block\n"); -{ int z; for (z=0; z<num; z++) printf("%02X%c",p1[z],((z+1)%16)?' ':'\n'); } + 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)) - { - /* enable vulnerability countermeasure for CBC ciphers with - * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt) - */ - s->s3->need_empty_fragments = 1; - - if (s->session->cipher != NULL) - { - if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_eNULL) - s->s3->need_empty_fragments = 0; - + if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) { + /* + * enable vulnerability countermeasure for CBC ciphers with known-IV + * problem (http://www.openssl.org/~bodo/tls-cbc.txt) + */ + s->s3->need_empty_fragments = 1; + + if (s->session->cipher != NULL) { + if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_eNULL) + s->s3->need_empty_fragments = 0; + #ifndef OPENSSL_NO_RC4 - if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_RC4) - s->s3->need_empty_fragments = 0; + if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_RC4) + s->s3->need_empty_fragments = 0; #endif - } - } - - return(1); -err: - SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE); - return(0); - } + } + } + + return (1); + err: + SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE); + return (0); +} /*- * tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. @@ -540,330 +570,362 @@ err: * an internal error occured. */ int tls1_enc(SSL *s, int send) - { - SSL3_RECORD *rec; - EVP_CIPHER_CTX *ds; - unsigned long l; - int bs,i,j,k,pad=0,ret,mac_size=0; - const EVP_CIPHER *enc; - - if (send) - { - ds=s->enc_write_ctx; - rec= &(s->s3->wrec); - if (s->enc_write_ctx == NULL) - enc=NULL; - else - enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx); - } - else - { - ds=s->enc_read_ctx; - rec= &(s->s3->rrec); - if (s->enc_read_ctx == NULL) - enc=NULL; - else - enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx); - } +{ + SSL3_RECORD *rec; + EVP_CIPHER_CTX *ds; + unsigned long l; + int bs, i, j, k, pad = 0, ret, mac_size = 0; + const EVP_CIPHER *enc; + + if (send) { + ds = s->enc_write_ctx; + rec = &(s->s3->wrec); + if (s->enc_write_ctx == NULL) + enc = NULL; + else + enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx); + } else { + ds = s->enc_read_ctx; + rec = &(s->s3->rrec); + if (s->enc_read_ctx == NULL) + enc = NULL; + else + enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx); + } #ifdef KSSL_DEBUG - printf("tls1_enc(%d)\n", send); -#endif /* KSSL_DEBUG */ - - if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) - { - memmove(rec->data,rec->input,rec->length); - rec->input=rec->data; - ret = 1; - } - else - { - l=rec->length; - bs=EVP_CIPHER_block_size(ds->cipher); - - if ((bs != 1) && send) - { - i=bs-((int)l%bs); - - /* Add weird padding of upto 256 bytes */ - - /* we need to add 'i' padding bytes of value j */ - j=i-1; - if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG) - { - if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) - j++; - } - for (k=(int)l; k<(int)(l+i); k++) - rec->input[k]=j; - l+=i; - rec->length+=i; - } - + printf("tls1_enc(%d)\n", send); +#endif /* KSSL_DEBUG */ + + if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) { + memmove(rec->data, rec->input, rec->length); + rec->input = rec->data; + ret = 1; + } else { + l = rec->length; + bs = EVP_CIPHER_block_size(ds->cipher); + + if ((bs != 1) && send) { + i = bs - ((int)l % bs); + + /* Add weird padding of upto 256 bytes */ + + /* we need to add 'i' padding bytes of value j */ + j = i - 1; + if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG) { + if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) + j++; + } + for (k = (int)l; k < (int)(l + i); k++) + rec->input[k] = j; + l += i; + rec->length += i; + } #ifdef KSSL_DEBUG - { - unsigned long ui; - printf("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", - 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"); - } -#endif /* KSSL_DEBUG */ - - if (!send) - { - if (l == 0 || l%bs != 0) - return 0; - } - - EVP_Cipher(ds,rec->data,rec->input,l); + { + unsigned long ui; + printf("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", + 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"); + } +#endif /* KSSL_DEBUG */ + + if (!send) { + if (l == 0 || l % bs != 0) + return 0; + } + + EVP_Cipher(ds, rec->data, rec->input, l); #ifdef KSSL_DEBUG - { - unsigned long ki; - printf("\trec->data="); - for (ki=0; ki<l; i++) - printf(" %02x", rec->data[ki]); pr |