diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2018-06-02 21:37:00 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2018-06-14 16:36:15 +0200 |
commit | 4f60d9b87ca89005ab3e98387e687dd7b23787ca (patch) | |
tree | c8a8daaab7934548e70f4ea27efa95cc639ca14c /lib/cipher.c | |
parent | 9a714f6047e18a30d0c2de771933e0f297f4b58f (diff) | |
download | gnutls-4f60d9b87ca89005ab3e98387e687dd7b23787ca.tar.gz |
cipher: use gnutls_aead_cipher_encryptv
This eliminates the need of a memory allocation during each
packet encryption when no padding is done.
Relates #458
Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
Diffstat (limited to 'lib/cipher.c')
-rw-r--r-- | lib/cipher.c | 73 |
1 files changed, 46 insertions, 27 deletions
diff --git a/lib/cipher.c b/lib/cipher.c index 2bfae68552..a502a16986 100644 --- a/lib/cipher.c +++ b/lib/cipher.c @@ -67,8 +67,8 @@ static int encrypt_packet_tls13(gnutls_session_t session, uint8_t *cipher_data, size_t cipher_size, gnutls_datum_t *plain, - size_t min_pad, - content_type_t type, + size_t pad_size, + uint8_t type, record_parameters_st *params); /* returns ciphertext which contains the headers too. This also @@ -417,8 +417,8 @@ static int encrypt_packet_tls13(gnutls_session_t session, uint8_t *cipher_data, size_t cipher_size, gnutls_datum_t *plain, - size_t min_pad, - content_type_t type, + size_t pad_size, + uint8_t type, record_parameters_st *params) { int ret; @@ -426,9 +426,10 @@ encrypt_packet_tls13(gnutls_session_t session, const version_entry_st *ver = get_version(session); uint8_t nonce[MAX_CIPHER_IV_SIZE]; unsigned iv_size = 0; - uint8_t *fdata; - ssize_t fdata_size, max; + ssize_t max, total; uint8_t aad[5]; + giovec_t auth_iov[1]; + giovec_t iov[2]; if (unlikely(ver == NULL)) return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); @@ -453,39 +454,57 @@ encrypt_packet_tls13(gnutls_session_t session, max = MAX_RECORD_SEND_SIZE(session); /* make TLS 1.3 form of data */ - fdata_size = plain->size + 1 + min_pad; + total = plain->size + 1 + pad_size; /* check whether padding would exceed max */ - if (fdata_size > max) { + if (total > max) { if (unlikely(max < (ssize_t)plain->size+1)) return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); - min_pad = max - plain->size - 1; - fdata_size = max; + pad_size = max - plain->size - 1; + total = max; } - fdata = gnutls_malloc(fdata_size); - if (fdata == NULL) - return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); - - memcpy(fdata, plain->data, plain->size); - fdata[plain->size] = type; - if (min_pad) - memset(&fdata[plain->size+1], 0, min_pad); - /* create authenticated data header */ aad[0] = GNUTLS_APPLICATION_DATA; aad[1] = 0x03; aad[2] = 0x03; - _gnutls_write_uint16(fdata_size+tag_size, &aad[3]); + _gnutls_write_uint16(total+tag_size, &aad[3]); - ret = gnutls_aead_cipher_encrypt(¶ms->write.ctx.aead, - nonce, iv_size, - aad, sizeof(aad), - tag_size, - fdata, fdata_size, - cipher_data, &cipher_size); - gnutls_free(fdata); + auth_iov[0].iov_base = aad; + auth_iov[0].iov_len = sizeof(aad); + + iov[0].iov_base = plain->data; + iov[0].iov_len = plain->size; + + if (pad_size) { + uint8_t *pad = gnutls_calloc(1, 1+pad_size); + if (pad == NULL) + return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + + pad[0] = type; + + iov[1].iov_base = pad; + iov[1].iov_len = 1+pad_size; + + ret = gnutls_aead_cipher_encryptv(¶ms->write.ctx.aead, + nonce, iv_size, + auth_iov, 1, + tag_size, + iov, 2, + cipher_data, &cipher_size); + gnutls_free(pad); + } else { + iov[1].iov_base = &type; + iov[1].iov_len = 1; + + ret = gnutls_aead_cipher_encryptv(¶ms->write.ctx.aead, + nonce, iv_size, + auth_iov, 1, + tag_size, + iov, 2, + cipher_data, &cipher_size); + } if (ret < 0) return gnutls_assert_val(ret); |