*/
#include <stdio.h>
-#include <openssl/md5.h>
-#include <openssl/sha.h>
#include <openssl/evp.h>
#include "ssl_locl.h"
+#include <openssl/md5.h>
static unsigned char ssl3_pad_1[48]={
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
static int ssl3_handshake_mac(SSL *s, EVP_MD_CTX *in_ctx,
const char *sender, int len, unsigned char *p);
-static void ssl3_generate_key_block(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;
c = os_toascii[c]; /*'A' in ASCII */
#endif
k=0;
+ EVP_MD_CTX_init(&m5);
+ EVP_MD_CTX_init(&s1);
for (i=0; i<num; i+=MD5_DIGEST_LENGTH)
{
k++;
+ if (k > 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; j<k; j++)
buf[j]=c;
c++;
- SHA1_Init( &s1);
- SHA1_Update(&s1,buf,k);
- SHA1_Update(&s1,s->session->master_key,
+ EVP_DigestInit(&s1,EVP_sha1());
+ 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(&s1,smd,NULL);
- MD5_Init( &m5);
- MD5_Update(&m5,s->session->master_key,
+ EVP_DigestInit(&m5,EVP_md5());
+ 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(&m5,smd,NULL);
memcpy(km,smd,(num-i));
}
else
- MD5_Final(km,&m5);
+ EVP_DigestFinal(&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(SSL *s, int which)
const EVP_CIPHER *c;
COMP_METHOD *comp;
const EVP_MD *m;
- MD5_CTX md;
+ EVP_MD_CTX md;
int exp,n,i,j,k,cl;
exp=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
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(&md,EVP_md5());
+ EVP_DigestUpdate(&md,key,j);
+ EVP_DigestUpdate(&md,er1,SSL3_RANDOM_SIZE);
+ EVP_DigestUpdate(&md,er2,SSL3_RANDOM_SIZE);
+ EVP_DigestFinal(&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(&md,EVP_md5());
+ EVP_DigestUpdate(&md,er1,SSL3_RANDOM_SIZE);
+ EVP_DigestUpdate(&md,er2,SSL3_RANDOM_SIZE);
+ EVP_DigestFinal(&md,&(exp_iv[0]),NULL);
iv= &(exp_iv[0]);
}
}
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);
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);
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
/* COMPRESS */
- /* This should be using (bs-1) and bs instead of 7 and 8 */
if ((bs != 1) && send)
{
i=bs-((int)l%bs);
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_DECRYPT_ERROR);
+ 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);
unsigned char md_buf[EVP_MAX_MD_SIZE];
EVP_MD_CTX ctx;
+ EVP_MD_CTX_init(&ctx);
EVP_MD_CTX_copy(&ctx,in_ctx);
n=EVP_MD_CTX_size(&ctx);
EVP_DigestUpdate(&ctx,md_buf,i);
EVP_DigestFinal(&ctx,p,&ret);
- memset(&ctx,0,sizeof(EVP_MD_CTX));
+ EVP_MD_CTX_cleanup(&ctx);
return((int)ret);
}
npad=(48/md_size)*md_size;
/* Chop the digest off the end :-) */
+ EVP_MD_CTX_init(&md_ctx);
EVP_DigestInit( &md_ctx,hash);
EVP_DigestUpdate(&md_ctx,mac_sec,md_size);
EVP_DigestUpdate(&md_ctx,md,md_size);
EVP_DigestFinal( &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 i,ret=0;
unsigned int n;
+ EVP_MD_CTX_init(&ctx);
for (i=0; i<3; i++)
{
EVP_DigestInit(&ctx,s->ctx->sha1);
out+=n;
ret+=n;
}
+ EVP_MD_CTX_cleanup(&ctx);
return(ret);
}