X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fs3_enc.c;h=6d9f986d58e003b6ee614636b5aedd99680ae283;hp=ea8e39ef0662d9fd183828d2a5c61d4d2431efec;hb=bfaa8a89e1b81fec52cc3fe15d507d838faac467;hpb=e03ddfae7ea7c27193d3f7c0eaa1d01704647d77 diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c index ea8e39ef06..6d9f986d58 100644 --- a/ssl/s3_enc.c +++ b/ssl/s3_enc.c @@ -57,8 +57,9 @@ */ #include -#include "evp.h" +#include #include "ssl_locl.h" +#include static unsigned char ssl3_pad_1[48]={ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, @@ -76,82 +77,92 @@ static unsigned char ssl3_pad_2[48]={ 0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c, 0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c }; -#ifndef NO_PROTO static int ssl3_handshake_mac(SSL *s, EVP_MD_CTX *in_ctx, - unsigned char *sender, int len, unsigned char *p); -#else -static int ssl3_handshake_mac(); -#endif + const char *sender, int len, unsigned char *p); -static void ssl3_generate_key_block(s,km,num) -SSL *s; -unsigned char *km; -int num; +static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) { - MD5_CTX m5; - SHA_CTX s1; - unsigned char buf[8],smd[SHA_DIGEST_LENGTH]; + EVP_MD_CTX m5; + EVP_MD_CTX s1; + unsigned char buf[16],smd[SHA_DIGEST_LENGTH]; unsigned char c='A'; int i,j,k; +#ifdef CHARSET_EBCDIC + c = os_toascii[c]; /*'A' in ASCII */ +#endif k=0; + EVP_MD_CTX_init(&m5); + EVP_MD_CTX_init(&s1); for (i=0; i sizeof buf) + { + /* bug: 'buf' is too small for this ciphersuite */ + SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR); + return 0; + } + for (j=0; jsession->master_key, + EVP_DigestInit_ex(&s1,EVP_sha1(), NULL); + EVP_DigestUpdate(&s1,buf,k); + EVP_DigestUpdate(&s1,s->session->master_key, s->session->master_key_length); - SHA1_Update(&s1,s->s3->server_random,SSL3_RANDOM_SIZE); - SHA1_Update(&s1,s->s3->client_random,SSL3_RANDOM_SIZE); - SHA1_Final( smd,&s1); + EVP_DigestUpdate(&s1,s->s3->server_random,SSL3_RANDOM_SIZE); + EVP_DigestUpdate(&s1,s->s3->client_random,SSL3_RANDOM_SIZE); + EVP_DigestFinal_ex(&s1,smd,NULL); - MD5_Init( &m5); - MD5_Update(&m5,s->session->master_key, + EVP_DigestInit_ex(&m5,EVP_md5(), NULL); + EVP_DigestUpdate(&m5,s->session->master_key, s->session->master_key_length); - MD5_Update(&m5,smd,SHA_DIGEST_LENGTH); + EVP_DigestUpdate(&m5,smd,SHA_DIGEST_LENGTH); if ((i+MD5_DIGEST_LENGTH) > num) { - MD5_Final(smd,&m5); + EVP_DigestFinal_ex(&m5,smd,NULL); memcpy(km,smd,(num-i)); } else - MD5_Final(km,&m5); + EVP_DigestFinal_ex(&m5,km,NULL); km+=MD5_DIGEST_LENGTH; } memset(smd,0,SHA_DIGEST_LENGTH); + EVP_MD_CTX_cleanup(&m5); + EVP_MD_CTX_cleanup(&s1); + return 1; } -int ssl3_change_cipher_state(s,which) -SSL *s; -int which; +int ssl3_change_cipher_state(SSL *s, int which) { unsigned char *p,*key_block,*mac_secret; unsigned char exp_key[EVP_MAX_KEY_LENGTH]; unsigned char exp_iv[EVP_MAX_KEY_LENGTH]; unsigned char *ms,*key,*iv,*er1,*er2; EVP_CIPHER_CTX *dd; - EVP_CIPHER *c; + const EVP_CIPHER *c; COMP_METHOD *comp; - EVP_MD *m; - MD5_CTX md; - int exp,n,i,j,k; + const EVP_MD *m; + EVP_MD_CTX md; + int exp,n,i,j,k,cl; + int reuse_dd = 0; - exp=(s->s3->tmp.new_cipher->algorithms & SSL_EXPORT)?1:0; + exp=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); c=s->s3->tmp.new_sym_enc; m=s->s3->tmp.new_hash; - comp=s->s3->tmp.new_compression; + if (s->s3->tmp.new_compression == NULL) + comp=NULL; + else + comp=s->s3->tmp.new_compression->method; key_block=s->s3->tmp.key_block; if (which & SSL3_CC_READ) { - if ((s->enc_read_ctx == NULL) && - ((s->enc_read_ctx=(EVP_CIPHER_CTX *) - Malloc(sizeof(EVP_CIPHER_CTX))) == NULL)) + if (s->enc_read_ctx != NULL) + reuse_dd = 1; + else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) goto err; dd= s->enc_read_ctx; s->read_hash=m; @@ -169,8 +180,9 @@ int which; SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR); goto err2; } - s->s3->rrec.comp=(unsigned char *) - Malloc(SSL3_RT_MAX_PLAIN_LENGTH); + if (s->s3->rrec.comp == NULL) + s->s3->rrec.comp=(unsigned char *) + OPENSSL_malloc(SSL3_RT_MAX_PLAIN_LENGTH); if (s->s3->rrec.comp == NULL) goto err; } @@ -179,9 +191,9 @@ int which; } else { - if ((s->enc_write_ctx == NULL) && - ((s->enc_write_ctx=(EVP_CIPHER_CTX *) - Malloc(sizeof(EVP_CIPHER_CTX))) == NULL)) + if (s->enc_write_ctx != NULL) + reuse_dd = 1; + else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) goto err; dd= s->enc_write_ctx; s->write_hash=m; @@ -204,12 +216,16 @@ int which; mac_secret= &(s->s3->write_mac_secret[0]); } + if (reuse_dd) + EVP_CIPHER_CTX_cleanup(dd); EVP_CIPHER_CTX_init(dd); p=s->s3->tmp.key_block; i=EVP_MD_size(m); - // Should be j=exp?min(5,EVP_CIPHER_key_length(c)):EVP_CIPHER_key_length(c); ?? - Ben 30/12/98 - j=(exp)?5:EVP_CIPHER_key_length(c); + cl=EVP_CIPHER_key_length(c); + j=exp ? (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)) @@ -232,39 +248,41 @@ int which; if (n > s->s3->tmp.key_block_length) { - SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,SSL_R_INTERNAL_ERROR); + SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR); goto err2; } + EVP_MD_CTX_init(&md); memcpy(mac_secret,ms,i); if (exp) { /* In here I set both the read and write key/iv to the * same value since only the correct one will be used :-). */ - MD5_Init(&md); - MD5_Update(&md,key,j); - MD5_Update(&md,er1,SSL3_RANDOM_SIZE); - MD5_Update(&md,er2,SSL3_RANDOM_SIZE); - MD5_Final(&(exp_key[0]),&md); + EVP_DigestInit_ex(&md,EVP_md5(), NULL); + EVP_DigestUpdate(&md,key,j); + EVP_DigestUpdate(&md,er1,SSL3_RANDOM_SIZE); + EVP_DigestUpdate(&md,er2,SSL3_RANDOM_SIZE); + EVP_DigestFinal_ex(&md,&(exp_key[0]),NULL); key= &(exp_key[0]); if (k > 0) { - MD5_Init(&md); - MD5_Update(&md,er1,SSL3_RANDOM_SIZE); - MD5_Update(&md,er2,SSL3_RANDOM_SIZE); - MD5_Final(&(exp_iv[0]),&md); + EVP_DigestInit_ex(&md,EVP_md5(), NULL); + EVP_DigestUpdate(&md,er1,SSL3_RANDOM_SIZE); + EVP_DigestUpdate(&md,er2,SSL3_RANDOM_SIZE); + EVP_DigestFinal_ex(&md,&(exp_iv[0]),NULL); iv= &(exp_iv[0]); } } s->session->key_arg_length=0; - EVP_CipherInit(dd,c,key,iv,(which & SSL3_CC_WRITE)); + EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE)); memset(&(exp_key[0]),0,sizeof(exp_key)); memset(&(exp_iv[0]),0,sizeof(exp_iv)); + EVP_MD_CTX_cleanup(&md); return(1); err: SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE); @@ -272,18 +290,18 @@ err2: return(0); } -int ssl3_setup_key_block(s) -SSL *s; +int ssl3_setup_key_block(SSL *s) { unsigned char *p; - EVP_CIPHER *c; - EVP_MD *hash; - int num,exp; + const EVP_CIPHER *c; + const EVP_MD *hash; + int num; + SSL_COMP *comp; if (s->s3->tmp.key_block_length != 0) return(1); - if (!ssl_cipher_get_evp(s->session->cipher,&c,&hash)) + if (!ssl_cipher_get_evp(s->session,&c,&hash,&comp)) { SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE); return(0); @@ -291,55 +309,45 @@ SSL *s; s->s3->tmp.new_sym_enc=c; s->s3->tmp.new_hash=hash; -#ifdef ZLIB - s->s3->tmp.new_compression=COMP_zlib(); -#endif -/* s->s3->tmp.new_compression=COMP_rle(); */ -/* s->session->compress_meth= xxxxx */ - - exp=(s->session->cipher->algorithms & SSL_EXPORT)?1:0; + s->s3->tmp.new_compression=comp; num=EVP_CIPHER_key_length(c)+EVP_MD_size(hash)+EVP_CIPHER_iv_length(c); num*=2; ssl3_cleanup_key_block(s); - if ((p=(unsigned char *)Malloc(num)) == NULL) + if ((p=OPENSSL_malloc(num)) == NULL) goto err; s->s3->tmp.key_block_length=num; s->s3->tmp.key_block=p; - ssl3_generate_key_block(s,p,num); + return ssl3_generate_key_block(s,p,num); - return(1); err: SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE); return(0); } -void ssl3_cleanup_key_block(s) -SSL *s; +void ssl3_cleanup_key_block(SSL *s) { if (s->s3->tmp.key_block != NULL) { memset(s->s3->tmp.key_block,0, s->s3->tmp.key_block_length); - Free(s->s3->tmp.key_block); + OPENSSL_free(s->s3->tmp.key_block); s->s3->tmp.key_block=NULL; } s->s3->tmp.key_block_length=0; } -int ssl3_enc(s,send) -SSL *s; -int send; +int ssl3_enc(SSL *s, int send) { SSL3_RECORD *rec; EVP_CIPHER_CTX *ds; unsigned long l; int bs,i; - EVP_CIPHER *enc; + const EVP_CIPHER *enc; if (send) { @@ -363,7 +371,7 @@ int send; if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) { - memcpy(rec->data,rec->input,rec->length); + memmove(rec->data,rec->input,rec->length); rec->input=rec->data; } else @@ -373,7 +381,6 @@ int send; /* COMPRESS */ - /* This should be using (bs-1) and bs instead of 7 and 8 */ if ((bs != 1) && send) { i=bs-((int)l%bs); @@ -383,17 +390,31 @@ int send; rec->length+=i; rec->input[l-1]=(i-1); } - + + if (!send) + { + if (l == 0 || l%bs != 0) + { + SSLerr(SSL_F_SSL3_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED); + return 0; + } + } + EVP_Cipher(ds,rec->data,rec->input,l); if ((bs != 1) && !send) { i=rec->data[l-1]+1; + /* SSL 3.0 bounds the number of padding bytes by the block size; + * padding bytes (except that last) are arbitrary */ if (i > bs) { - SSLerr(SSL_F_SSL3_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); - ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPT_ERROR); - return(0); + /* Incorrect padding. SSLerr() and ssl3_alert are done + * by caller: we don't want to reveal whether this is + * a decryption error or a MAC verification failure + * (see http://www.openssl.org/~bodo/tls-cbc.txt) */ + return -1; } rec->length-=i; } @@ -401,36 +422,25 @@ int send; return(1); } -void ssl3_init_finished_mac(s) -SSL *s; +void ssl3_init_finished_mac(SSL *s) { - EVP_DigestInit(&(s->s3->finish_dgst1),s->ctx->md5); - EVP_DigestInit(&(s->s3->finish_dgst2),s->ctx->sha1); + EVP_DigestInit_ex(&(s->s3->finish_dgst1),s->ctx->md5, NULL); + EVP_DigestInit_ex(&(s->s3->finish_dgst2),s->ctx->sha1, NULL); } -void ssl3_finish_mac(s,buf,len) -SSL *s; -unsigned char *buf; -int len; +void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len) { EVP_DigestUpdate(&(s->s3->finish_dgst1),buf,len); EVP_DigestUpdate(&(s->s3->finish_dgst2),buf,len); } -int ssl3_cert_verify_mac(s,ctx,p) -SSL *s; -EVP_MD_CTX *ctx; -unsigned char *p; +int ssl3_cert_verify_mac(SSL *s, EVP_MD_CTX *ctx, unsigned char *p) { return(ssl3_handshake_mac(s,ctx,NULL,0,p)); } -int ssl3_final_finish_mac(s,ctx1,ctx2,sender,len,p) -SSL *s; -EVP_MD_CTX *ctx1,*ctx2; -unsigned char *sender; -int len; -unsigned char *p; +int ssl3_final_finish_mac(SSL *s, EVP_MD_CTX *ctx1, EVP_MD_CTX *ctx2, + const char *sender, int len, unsigned char *p) { int ret; @@ -440,12 +450,8 @@ unsigned char *p; return(ret); } -static int ssl3_handshake_mac(s,in_ctx,sender,len,p) -SSL *s; -EVP_MD_CTX *in_ctx; -unsigned char *sender; -int len; -unsigned char *p; +static int ssl3_handshake_mac(SSL *s, EVP_MD_CTX *in_ctx, + const char *sender, int len, unsigned char *p) { unsigned int ret; int npad,n; @@ -453,7 +459,8 @@ unsigned char *p; unsigned char md_buf[EVP_MAX_MD_SIZE]; EVP_MD_CTX ctx; - memcpy(&ctx,in_ctx,sizeof(EVP_MD_CTX)); + EVP_MD_CTX_init(&ctx); + EVP_MD_CTX_copy_ex(&ctx,in_ctx); n=EVP_MD_CTX_size(&ctx); npad=(48/n)*n; @@ -463,29 +470,26 @@ unsigned char *p; EVP_DigestUpdate(&ctx,s->session->master_key, s->session->master_key_length); EVP_DigestUpdate(&ctx,ssl3_pad_1,npad); - EVP_DigestFinal(&ctx,md_buf,&i); + EVP_DigestFinal_ex(&ctx,md_buf,&i); - EVP_DigestInit(&ctx,EVP_MD_CTX_type(&ctx)); + EVP_DigestInit_ex(&ctx,EVP_MD_CTX_md(&ctx), NULL); EVP_DigestUpdate(&ctx,s->session->master_key, s->session->master_key_length); EVP_DigestUpdate(&ctx,ssl3_pad_2,npad); EVP_DigestUpdate(&ctx,md_buf,i); - EVP_DigestFinal(&ctx,p,&ret); + EVP_DigestFinal_ex(&ctx,p,&ret); - memset(&ctx,0,sizeof(EVP_MD_CTX)); + EVP_MD_CTX_cleanup(&ctx); return((int)ret); } -int ssl3_mac(ssl,md,send) -SSL *ssl; -unsigned char *md; -int send; +int ssl3_mac(SSL *ssl, unsigned char *md, int send) { SSL3_RECORD *rec; unsigned char *mac_sec,*seq; EVP_MD_CTX md_ctx; - EVP_MD *hash; + const EVP_MD *hash; unsigned char *p,rec_char; unsigned int md_size; int npad,i; @@ -509,8 +513,9 @@ int send; npad=(48/md_size)*md_size; /* Chop the digest off the end :-) */ + EVP_MD_CTX_init(&md_ctx); - EVP_DigestInit( &md_ctx,hash); + EVP_DigestInit_ex( &md_ctx,hash, NULL); EVP_DigestUpdate(&md_ctx,mac_sec,md_size); EVP_DigestUpdate(&md_ctx,ssl3_pad_1,npad); EVP_DigestUpdate(&md_ctx,seq,8); @@ -520,59 +525,68 @@ int send; s2n(rec->length,p); EVP_DigestUpdate(&md_ctx,md,2); EVP_DigestUpdate(&md_ctx,rec->input,rec->length); - EVP_DigestFinal( &md_ctx,md,NULL); + EVP_DigestFinal_ex( &md_ctx,md,NULL); - EVP_DigestInit( &md_ctx,hash); + EVP_DigestInit_ex( &md_ctx,hash, NULL); EVP_DigestUpdate(&md_ctx,mac_sec,md_size); EVP_DigestUpdate(&md_ctx,ssl3_pad_2,npad); EVP_DigestUpdate(&md_ctx,md,md_size); - EVP_DigestFinal( &md_ctx,md,&md_size); + EVP_DigestFinal_ex( &md_ctx,md,&md_size); + + EVP_MD_CTX_cleanup(&md_ctx); for (i=7; i>=0; i--) - if (++seq[i]) break; + { + ++seq[i]; + if (seq[i] != 0) break; + } return(md_size); } -int ssl3_generate_master_secret(s,out,p,len) -SSL *s; -unsigned char *out; -unsigned char *p; -int len; +int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, + int len) { - static unsigned char *salt[3]={ - (unsigned char *)"A", - (unsigned char *)"BB", - (unsigned char *)"CCC", + static const unsigned char *salt[3]={ +#ifndef CHARSET_EBCDIC + (const unsigned char *)"A", + (const unsigned char *)"BB", + (const unsigned char *)"CCC", +#else + (const unsigned char *)"\x41", + (const unsigned char *)"\x42\x42", + (const unsigned char *)"\x43\x43\x43", +#endif }; unsigned char buf[EVP_MAX_MD_SIZE]; EVP_MD_CTX ctx; int i,ret=0; unsigned int n; + EVP_MD_CTX_init(&ctx); for (i=0; i<3; i++) { - EVP_DigestInit(&ctx,s->ctx->sha1); - EVP_DigestUpdate(&ctx,salt[i],strlen((char *)salt[i])); + EVP_DigestInit_ex(&ctx,s->ctx->sha1, NULL); + EVP_DigestUpdate(&ctx,salt[i],strlen((const char *)salt[i])); EVP_DigestUpdate(&ctx,p,len); EVP_DigestUpdate(&ctx,&(s->s3->client_random[0]), SSL3_RANDOM_SIZE); EVP_DigestUpdate(&ctx,&(s->s3->server_random[0]), SSL3_RANDOM_SIZE); - EVP_DigestFinal(&ctx,buf,&n); + EVP_DigestFinal_ex(&ctx,buf,&n); - EVP_DigestInit(&ctx,s->ctx->md5); + EVP_DigestInit_ex(&ctx,s->ctx->md5, NULL); EVP_DigestUpdate(&ctx,p,len); EVP_DigestUpdate(&ctx,buf,n); - EVP_DigestFinal(&ctx,out,&n); + EVP_DigestFinal_ex(&ctx,out,&n); out+=n; ret+=n; } + EVP_MD_CTX_cleanup(&ctx); return(ret); } -int ssl3_alert_code(code) -int code; +int ssl3_alert_code(int code) { switch (code) { @@ -594,11 +608,11 @@ int code; case SSL_AD_ACCESS_DENIED: return(SSL3_AD_HANDSHAKE_FAILURE); case SSL_AD_DECODE_ERROR: return(SSL3_AD_HANDSHAKE_FAILURE); case SSL_AD_DECRYPT_ERROR: return(SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_EXPORT_RESTRICION: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_EXPORT_RESTRICTION: return(SSL3_AD_HANDSHAKE_FAILURE); case SSL_AD_PROTOCOL_VERSION: return(SSL3_AD_HANDSHAKE_FAILURE); case SSL_AD_INSUFFICIENT_SECURITY:return(SSL3_AD_HANDSHAKE_FAILURE); case SSL_AD_INTERNAL_ERROR: return(SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_USER_CANCLED: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_USER_CANCELLED: return(SSL3_AD_HANDSHAKE_FAILURE); case SSL_AD_NO_RENEGOTIATION: return(-1); /* Don't send it :-) */ default: return(-1); }