Back-port TLS AEAD framework [from HEAD].
This commit is contained in:
parent
7bd8bf58bb
commit
90f3e4cf05
@ -361,6 +361,7 @@ struct evp_cipher_st
|
||||
* as finalisation.
|
||||
*/
|
||||
#define EVP_CIPH_FLAG_CUSTOM_CIPHER 0x100000
|
||||
#define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000
|
||||
|
||||
/* ctrl() values */
|
||||
|
||||
@ -383,6 +384,14 @@ struct evp_cipher_st
|
||||
#define EVP_CTRL_CCM_SET_TAG EVP_CTRL_GCM_SET_TAG
|
||||
#define EVP_CTRL_CCM_SET_L 0x14
|
||||
#define EVP_CTRL_CCM_SET_MSGLEN 0x15
|
||||
/* AEAD cipher deduces payload length and returns number of bytes
|
||||
* required to store MAC and eventual padding. Subsequent call to
|
||||
* EVP_Cipher even appends/verifies MAC.
|
||||
*/
|
||||
#define EVP_CTRL_AEAD_TLS1_AAD 0x16
|
||||
/* Used by composite AEAD ciphers, no-op in GCM, CCM... */
|
||||
#define EVP_CTRL_AEAD_SET_MAC_KEY 0x17
|
||||
|
||||
|
||||
typedef struct evp_cipher_info_st
|
||||
{
|
||||
|
@ -583,8 +583,29 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
|
||||
if (mac_secret_size!=NULL) *mac_secret_size = ssl_mac_secret_size[i];
|
||||
}
|
||||
|
||||
if ((*enc != NULL) && (*md != NULL) && (!mac_pkey_type||*mac_pkey_type != NID_undef))
|
||||
if ((*enc != NULL) &&
|
||||
(*md != NULL || (EVP_CIPHER_flags(*enc)&EVP_CIPH_FLAG_AEAD_CIPHER)) &&
|
||||
(!mac_pkey_type||*mac_pkey_type != NID_undef))
|
||||
{
|
||||
const EVP_CIPHER *evp;
|
||||
|
||||
if (s->ssl_version >= TLS1_VERSION &&
|
||||
c->algorithm_enc == SSL_RC4 &&
|
||||
c->algorithm_mac == SSL_MD5 &&
|
||||
(evp=EVP_get_cipherbyname("RC4-HMAC-MD5")))
|
||||
*enc = evp, *md = NULL;
|
||||
else if (s->ssl_version >= TLS1_VERSION &&
|
||||
c->algorithm_enc == SSL_AES128 &&
|
||||
c->algorithm_mac == SSL_SHA1 &&
|
||||
(evp=EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA1")))
|
||||
*enc = evp, *md = NULL;
|
||||
else if (s->ssl_version >= TLS1_VERSION &&
|
||||
c->algorithm_enc == SSL_AES256 &&
|
||||
c->algorithm_mac == SSL_SHA1 &&
|
||||
(evp=EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA1")))
|
||||
*enc = evp, *md = NULL;
|
||||
return(1);
|
||||
}
|
||||
else
|
||||
return(0);
|
||||
}
|
||||
|
81
ssl/t1_enc.c
81
ssl/t1_enc.c
@ -369,7 +369,7 @@ int tls1_change_cipher_state(SSL *s, int which)
|
||||
{
|
||||
if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
|
||||
s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM;
|
||||
else
|
||||
else
|
||||
s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM;
|
||||
|
||||
if (s->enc_read_ctx != NULL)
|
||||
@ -485,10 +485,14 @@ int tls1_change_cipher_state(SSL *s, int which)
|
||||
}
|
||||
|
||||
memcpy(mac_secret,ms,i);
|
||||
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);
|
||||
|
||||
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'); }
|
||||
@ -536,6 +540,12 @@ printf("which = %04X\nmac key=",which);
|
||||
#endif /* KSSL_DEBUG */
|
||||
|
||||
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 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'); }
|
||||
@ -652,14 +662,14 @@ int tls1_enc(SSL *s, int send)
|
||||
SSL3_RECORD *rec;
|
||||
EVP_CIPHER_CTX *ds;
|
||||
unsigned long l;
|
||||
int bs,i,ii,j,k,n=0;
|
||||
int bs,i,ii,j,k,pad=0;
|
||||
const EVP_CIPHER *enc;
|
||||
|
||||
if (send)
|
||||
{
|
||||
if (EVP_MD_CTX_md(s->write_hash))
|
||||
{
|
||||
n=EVP_MD_CTX_size(s->write_hash);
|
||||
int n=EVP_MD_CTX_size(s->write_hash);
|
||||
OPENSSL_assert(n >= 0);
|
||||
}
|
||||
ds=s->enc_write_ctx;
|
||||
@ -679,12 +689,12 @@ int tls1_enc(SSL *s, int send)
|
||||
if (ivlen > 1)
|
||||
{
|
||||
if ( rec->data != rec->input)
|
||||
/* we can't write into the input stream:
|
||||
* Can this ever happen?? (steve)
|
||||
*/
|
||||
fprintf(stderr,
|
||||
"%s:%d: rec->data != rec->input\n",
|
||||
__FILE__, __LINE__);
|
||||
/* we can't write into the input stream:
|
||||
* Can this ever happen?? (steve)
|
||||
*/
|
||||
fprintf(stderr,
|
||||
"%s:%d: rec->data != rec->input\n",
|
||||
__FILE__, __LINE__);
|
||||
else if (RAND_bytes(rec->input, ivlen) <= 0)
|
||||
return -1;
|
||||
}
|
||||
@ -694,7 +704,7 @@ int tls1_enc(SSL *s, int send)
|
||||
{
|
||||
if (EVP_MD_CTX_md(s->read_hash))
|
||||
{
|
||||
n=EVP_MD_CTX_size(s->read_hash);
|
||||
int n=EVP_MD_CTX_size(s->read_hash);
|
||||
OPENSSL_assert(n >= 0);
|
||||
}
|
||||
ds=s->enc_read_ctx;
|
||||
@ -720,7 +730,43 @@ int tls1_enc(SSL *s, int send)
|
||||
l=rec->length;
|
||||
bs=EVP_CIPHER_block_size(ds->cipher);
|
||||
|
||||
if ((bs != 1) && send)
|
||||
if (EVP_CIPHER_flags(ds->cipher)&EVP_CIPH_FLAG_AEAD_CIPHER)
|
||||
{
|
||||
unsigned char buf[13],*seq;
|
||||
|
||||
seq = send?s->s3->write_sequence:s->s3->read_sequence;
|
||||
|
||||
if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER)
|
||||
{
|
||||
unsigned char dtlsseq[9],*p=dtlsseq;
|
||||
|
||||
s2n(send?s->d1->w_epoch:s->d1->r_epoch,p);
|
||||
memcpy(p,&seq[2],6);
|
||||
memcpy(buf,dtlsseq,8);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(buf,seq,8);
|
||||
for (i=7; i>=0; i--) /* increment */
|
||||
{
|
||||
++seq[i];
|
||||
if (seq[i] != 0) break;
|
||||
}
|
||||
}
|
||||
|
||||
buf[8]=rec->type;
|
||||
buf[9]=(unsigned char)(s->version>>8);
|
||||
buf[10]=(unsigned char)(s->version);
|
||||
buf[11]=rec->length>>8;
|
||||
buf[12]=rec->length&0xff;
|
||||
pad=EVP_CIPHER_CTX_ctrl(ds,EVP_CTRL_AEAD_TLS1_AAD,13,buf);
|
||||
if (send)
|
||||
{
|
||||
l+=pad;
|
||||
rec->length+=pad;
|
||||
}
|
||||
}
|
||||
else if ((bs != 1) && send)
|
||||
{
|
||||
i=bs-((int)l%bs);
|
||||
|
||||
@ -769,7 +815,8 @@ int tls1_enc(SSL *s, int send)
|
||||
}
|
||||
}
|
||||
|
||||
EVP_Cipher(ds,rec->data,rec->input,l);
|
||||
if (!EVP_Cipher(ds,rec->data,rec->input,l))
|
||||
return -1; /* AEAD can fail to verify MAC */
|
||||
|
||||
#ifdef KSSL_DEBUG
|
||||
{
|
||||
@ -828,6 +875,8 @@ int tls1_enc(SSL *s, int send)
|
||||
rec->length -= bs;
|
||||
}
|
||||
}
|
||||
if (pad && !send)
|
||||
rec->length -= pad;
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user