From: Daiki Ueno Date: Thu, 1 Aug 2019 16:13:38 +0000 (+0200) Subject: crypto-api: use giovec_t iterator interface for aead_encryptv X-Git-Tag: gnutls_3_6_10~20^2~1 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=9ca7a2b42168d356126e306e25211d43ea3c2e7d;p=thirdparty%2Fgnutls.git crypto-api: use giovec_t iterator interface for aead_encryptv This replaces the macros AUTH_UPDATE and ENCRYPT used in gnutls_aead_cipher_encryptv() with the iov_iter interface. Signed-off-by: Daiki Ueno --- diff --git a/lib/crypto-api.c b/lib/crypto-api.c index 8af3f3b7dc..70107fed0a 100644 --- a/lib/crypto-api.c +++ b/lib/crypto-api.c @@ -31,6 +31,7 @@ #include #include #include "crypto-api.h" +#include "iov.h" typedef struct api_cipher_hd_st { cipher_hd_st ctx_enc; @@ -916,98 +917,6 @@ static int copy_iov(struct iov_store_st *dst, const giovec_t *iov, int iovcnt) } } -#define AUTH_UPDATE_FINAL(ctx) do { \ - if (index) { \ - ret = _gnutls_cipher_auth(ctx, cache, index); \ - if (unlikely(ret < 0)) \ - return gnutls_assert_val(ret); \ - } \ - } while(0) - -#define AUTH_UPDATE(ctx, data, length) do { \ - if (index) { \ - ssize_t left = blocksize - index; \ - if (length < left) { \ - memcpy(cache+index, data, \ - length); \ - index += length; \ - goto __update_done; \ - } else { \ - memcpy(cache+index, data, left); \ - ret = _gnutls_cipher_auth(ctx, cache, blocksize); \ - if (unlikely(ret < 0)) \ - return gnutls_assert_val(ret); \ - data += left; \ - length -= left; \ - } \ - } \ - if (length >= blocksize) { \ - ssize_t to_proc = (length/blocksize)*blocksize; \ - ret = _gnutls_cipher_auth(ctx, data, to_proc); \ - if (unlikely(ret < 0)) \ - return gnutls_assert_val(ret); \ - data += to_proc; \ - length -= to_proc; \ - } \ - if (length) \ - memcpy(cache, data, length); \ - index = length; \ - __update_done: \ - ; \ - } while(0) - -#define ENCRYPT_FINAL(ctx, dst, dst_size) do { \ - if (index) { \ - if (unlikely(dst_size < (ssize_t)index)) \ - return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); \ - ret = _gnutls_cipher_encrypt2(ctx, cache, index, dst, dst_size); \ - if (unlikely(ret < 0)) \ - return gnutls_assert_val(ret); \ - dst += index; \ - dst_size -= index; \ - } \ - } while(0) - -#define ENCRYPT(ctx, data, length, dst, dst_size) do { \ - if (index) { \ - ssize_t left = blocksize - index; \ - if (length < left) { \ - memcpy(cache+index, data, \ - length); \ - index += length; \ - goto __encrypt_done; \ - } else { \ - if (unlikely(dst_size < blocksize)) \ - return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); \ - memcpy(cache+index, data, left); \ - ret = _gnutls_cipher_encrypt2(ctx, cache, blocksize, dst, dst_size); \ - if (unlikely(ret < 0)) \ - return gnutls_assert_val(ret); \ - data += left; \ - length -= left; \ - dst += blocksize; \ - dst_size -= blocksize; \ - } \ - } \ - if (length >= blocksize) { \ - ssize_t to_proc = (length/blocksize)*blocksize; \ - if (unlikely(dst_size < to_proc)) \ - return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); \ - ret = _gnutls_cipher_encrypt2(ctx, data, to_proc, dst, dst_size); \ - if (unlikely(ret < 0)) \ - return gnutls_assert_val(ret); \ - data += to_proc; \ - length -= to_proc; \ - dst += to_proc; \ - dst_size -= to_proc; \ - } \ - if (length) \ - memcpy(cache, data, length); \ - index = length; \ - __encrypt_done: \ - ; \ - } while(0) - /** * gnutls_aead_cipher_encryptv: @@ -1039,14 +948,13 @@ gnutls_aead_cipher_encryptv(gnutls_aead_cipher_hd_t handle, void *ctext, size_t *ctext_len) { api_aead_cipher_hd_st *h = handle; - int ret; + ssize_t ret; uint8_t *dst; - ssize_t dst_size, total = 0, len; + ssize_t dst_size, total = 0; uint8_t *p; - unsigned i; - uint8_t cache[MAX_CIPHER_BLOCK_SIZE]; - unsigned index; ssize_t blocksize = handle->ctx_enc.e->blocksize; + struct iov_iter_st iter; + size_t blocks; /* Limitation: this function provides an optimization under the internally registered * AEAD ciphers. When an AEAD cipher is used registered with gnutls_crypto_register_aead_cipher(), @@ -1088,25 +996,64 @@ gnutls_aead_cipher_encryptv(gnutls_aead_cipher_hd_t handle, if (unlikely(ret < 0)) return gnutls_assert_val(ret); - index = 0; - for (i = 0; i < (unsigned)auth_iovcnt; i++) { - p = auth_iov[i].iov_base; - len = auth_iov[i].iov_len; - AUTH_UPDATE(&handle->ctx_enc, p, len); + ret = _gnutls_iov_iter_init(&iter, auth_iov, auth_iovcnt, blocksize); + if (unlikely(ret < 0)) + return gnutls_assert_val(ret); + while (1) { + ret = _gnutls_iov_iter_next(&iter, &p); + if (unlikely(ret < 0)) + return gnutls_assert_val(ret); + if (ret == 0) + break; + blocks = ret; + ret = _gnutls_cipher_auth(&handle->ctx_enc, p, + blocksize * blocks); + if (unlikely(ret < 0)) + return gnutls_assert_val(ret); + } + if (iter.block_offset > 0) { + ret = _gnutls_cipher_auth(&handle->ctx_enc, + iter.block, iter.block_offset); + if (unlikely(ret < 0)) + return gnutls_assert_val(ret); } - AUTH_UPDATE_FINAL(&handle->ctx_enc); dst = ctext; dst_size = *ctext_len; - index = 0; - for (i = 0; i < (unsigned)iovcnt; i++) { - p = iov[i].iov_base; - len = iov[i].iov_len; - ENCRYPT(&handle->ctx_enc, p, len, dst, dst_size); - total += iov[i].iov_len; + ret = _gnutls_iov_iter_init(&iter, iov, iovcnt, blocksize); + if (unlikely(ret < 0)) + return gnutls_assert_val(ret); + while (1) { + ret = _gnutls_iov_iter_next(&iter, &p); + if (unlikely(ret < 0)) + return gnutls_assert_val(ret); + if (ret == 0) + break; + blocks = ret; + if (unlikely((size_t) dst_size < blocksize * blocks)) + return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); + ret = _gnutls_cipher_encrypt2(&handle->ctx_enc, p, + blocksize * blocks, + dst, dst_size); + if (unlikely(ret < 0)) + return gnutls_assert_val(ret); + DECR_LEN(dst_size, blocksize * blocks); + dst += blocksize * blocks; + total += blocksize * blocks; + } + if (iter.block_offset > 0) { + if (unlikely((size_t) dst_size < iter.block_offset)) + return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); + ret = _gnutls_cipher_encrypt2(&handle->ctx_enc, + iter.block, iter.block_offset, + dst, dst_size); + if (unlikely(ret < 0)) + return gnutls_assert_val(ret); + DECR_LEN(dst_size, iter.block_offset); + dst += iter.block_offset; + total += iter.block_offset; } - ENCRYPT_FINAL(&handle->ctx_enc, dst, dst_size); if ((size_t)dst_size < tag_size) return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);