diff options
Diffstat (limited to 'ssl/record/ssl3_record_tls13.c')
-rw-r--r-- | ssl/record/ssl3_record_tls13.c | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/ssl/record/ssl3_record_tls13.c b/ssl/record/ssl3_record_tls13.c index f1e1667b9d..21073b637d 100644 --- a/ssl/record/ssl3_record_tls13.c +++ b/ssl/record/ssl3_record_tls13.c @@ -25,13 +25,14 @@ int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) { EVP_CIPHER_CTX *ctx; - unsigned char iv[EVP_MAX_IV_LENGTH]; - size_t ivlen, taglen, offset, loop; + unsigned char iv[EVP_MAX_IV_LENGTH], recheader[SSL3_RT_HEADER_LENGTH]; + size_t ivlen, taglen, offset, loop, hdrlen; unsigned char *staticiv; unsigned char *seq; int lenu, lenf; SSL3_RECORD *rec = &recs[0]; uint32_t alg_enc; + WPACKET wpkt; if (n_recs != 1) { /* Should not happen */ @@ -143,7 +144,31 @@ int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, sending) <= 0 || (!sending && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, taglen, - rec->data + rec->length) <= 0) + rec->data + rec->length) <= 0)) { + return -1; + } + + /* Set up the AAD */ + if (!WPACKET_init_static_len(&wpkt, recheader, sizeof(recheader), 0) + || !WPACKET_put_bytes_u8(&wpkt, rec->type) + || !WPACKET_put_bytes_u16(&wpkt, rec->rec_version) + || !WPACKET_put_bytes_u16(&wpkt, rec->length + taglen) + || !WPACKET_get_total_written(&wpkt, &hdrlen) + || hdrlen != SSL3_RT_HEADER_LENGTH + || !WPACKET_finish(&wpkt)) { + WPACKET_cleanup(&wpkt); + return -1; + } + + /* + * For CCM we must explicitly set the total plaintext length before we add + * any AAD. + */ + if (((alg_enc & SSL_AESCCM) != 0 + && EVP_CipherUpdate(ctx, NULL, &lenu, NULL, + (unsigned int)rec->length) <= 0) + || EVP_CipherUpdate(ctx, NULL, &lenu, recheader, + sizeof(recheader)) <= 0 || EVP_CipherUpdate(ctx, rec->data, &lenu, rec->input, (unsigned int)rec->length) <= 0 || EVP_CipherFinal_ex(ctx, rec->data + lenu, &lenf) <= 0 |