added support for encrypt-then-mac

This commit is contained in:
mathewmarcus 2018-06-24 21:08:05 -05:00
parent 0d0a0b79b7
commit 57fc64ac77
3 changed files with 89 additions and 33 deletions

View file

@ -2467,10 +2467,15 @@ static int decode_extension_encrypt_then_mac(ssl,dir,seg,data)
segment *seg;
Data *data;
{
int l,r;
int l,r,*etm;
etm=&ssl->extensions->encrypt_then_mac;
SSL_DECODE_UINT16(ssl,"extension length",0,data,&l);
data->len-=l;
data->data+=l;
*etm=dir==DIR_I2R?1:*etm==1;
return(0);
}
static int decode_extension_extended_master_secret(ssl,dir,seg,data)
@ -2508,7 +2513,7 @@ decoder extension_decoder[] = {
{
0,
"server_name",
decode_extension_server_name
decode_extension,
},
{
1,

View file

@ -68,6 +68,7 @@ typedef struct d_queue_ {
} r_queue;
typedef struct ssl_extensions_ {
int encrypt_then_mac;
int extended_master_secret;
} ssl_extensions;

View file

@ -94,7 +94,7 @@ char *ciphers[]={
static int tls_check_mac PROTO_LIST((ssl_rec_decoder *d,int ct,
int ver,UCHAR *data,UINT4 datalen,UCHAR *mac));
int ver,UCHAR *data,UINT4 datalen,UCHAR *iv,UINT4 ivlen,UCHAR *mac));
static int fmt_seq PROTO_LIST((UINT4 num,UCHAR *buf));
int ssl_create_rec_decoder(dp,cs,mk,sk,iv)
@ -162,6 +162,7 @@ int ssl_destroy_rec_decoder(dp)
return(0);
}
int ssl_decode_rec_data(ssl,d,ct,version,in,inl,out,outl)
ssl_obj *ssl;
ssl_rec_decoder *d;
@ -174,50 +175,91 @@ int ssl_decode_rec_data(ssl,d,ct,version,in,inl,out,outl)
{
#ifdef OPENSSL
int pad;
int r;
UCHAR *mac;
int r,encpadl;
UCHAR *mac,*iv;
CRDUMP("Ciphertext",in,inl);
/* First decrypt*/
EVP_Cipher(d->evp,out,in,inl);
CRDUMP("Plaintext",out,inl);
*outl=inl;
if(ssl->extensions->encrypt_then_mac){
*outl=inl;
/* Now strip off the padding*/
if(d->cs->block>1){
pad=out[inl-1];
*outl-=(pad+1);
}
/* First strip off the MAC */
*outl-=d->cs->dig_len;
mac=in+(*outl);
/* And the MAC */
*outl-=d->cs->dig_len;
mac=out+(*outl);
CRDUMP("Record data",out,*outl);
encpadl=*outl;
/* Now decrypt */
EVP_Cipher(d->evp,out,in,*outl);
CRDUMP("Plaintext",out,*outl);
/* Now check the MAC */
if(ssl->version==0x300){
if(r=ssl3_check_mac(d,ct,version,out,*outl,mac))
ERETURN(r);
}
else{
/* And then strip off the padding*/
if(d->cs->block>1){
pad=out[*outl-1];
*outl-=(pad+1);
}
/* TLS 1.1 and beyond: remove explicit IV, only used with
* non-stream ciphers. */
if (ssl->version>=0x0302 && ssl->cs->block > 1) {
UINT4 blk = ssl->cs->block;
if (blk <= *outl) {
*outl-=blk;
memmove(out, out+blk, *outl);
*outl-=blk;
memmove(out, out+blk, *outl);
}
else {
DBG((0,"Block size greater than Plaintext!"));
ERETURN(SSL_BAD_MAC);
}
}
if(r=tls_check_mac(d,ct,version,out,*outl,mac))
ERETURN(r);
}
if(r=tls_check_mac(d,ct,version,in+blk,encpadl,in,blk,mac))
ERETURN(r);
}
else
if(r=tls_check_mac(d,ct,version,in,encpadl,NULL,0,mac))
ERETURN(r);
}
else {
/* First decrypt*/
EVP_Cipher(d->evp,out,in,inl);
CRDUMP("Plaintext",out,inl);
*outl=inl;
/* Now strip off the padding*/
if(d->cs->block>1){
pad=out[inl-1];
*outl-=(pad+1);
}
/* And the MAC */
*outl-=d->cs->dig_len;
mac=out+(*outl);
CRDUMP("Record data",out,*outl);
/* Now check the MAC */
if(ssl->version==0x300){
if(r=ssl3_check_mac(d,ct,version,out,*outl,mac))
ERETURN(r);
}
else{
/* TLS 1.1 and beyond: remove explicit IV, only used with
* non-stream ciphers. */
if (ssl->version>=0x0302 && ssl->cs->block > 1) {
UINT4 blk = ssl->cs->block;
if (blk <= *outl) {
*outl-=blk;
memmove(out, out+blk, *outl);
}
else {
DBG((0,"Block size greater than Plaintext!"));
ERETURN(SSL_BAD_MAC);
}
}
if(r=tls_check_mac(d,ct,version,out,*outl,NULL,0,mac))
ERETURN(r);
}
}
#endif
return(0);
}
@ -242,12 +284,14 @@ static int fmt_seq(num,buf)
return(0);
}
static int tls_check_mac(d,ct,ver,data,datalen,mac)
static int tls_check_mac(d,ct,ver,data,datalen,iv,ivlen,mac)
ssl_rec_decoder *d;
int ct;
int ver;
UCHAR *data;
UINT4 datalen;
UCHAR *iv;
UINT4 ivlen;
UCHAR *mac;
{
HMAC_CTX hm;
@ -272,7 +316,13 @@ static int tls_check_mac(d,ct,ver,data,datalen,mac)
buf[1]=LSB(datalen);
HMAC_Update(&hm,buf,2);
HMAC_Update(&hm,data,datalen);
/* for encrypt-then-mac with an explicit IV */
if(ivlen && iv){
HMAC_Update(&hm,iv,ivlen);
HMAC_Update(&hm,data,datalen-ivlen);
}
else
HMAC_Update(&hm,data,datalen);
HMAC_Final(&hm,buf,&l);
if(memcmp(mac,buf,l))