From 7532071aa3ad7845b53f6943327c75b7c0b3e37c Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Mon, 11 Jul 2011 13:58:59 +0000 Subject: [PATCH] ssl/t1_enc.c: initial support for AEAD ciphers. --- ssl/t1_enc.c | 81 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 65 insertions(+), 16 deletions(-) diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index d180bfc95c..1c14637072 100644 --- a/ssl/t1_enc.c +++ b/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; zwrite_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); } -- 2.25.1