diff options
author | Daiki Ueno <dueno@redhat.com> | 2019-10-01 18:15:19 +0200 |
---|---|---|
committer | Daiki Ueno <dueno@redhat.com> | 2019-10-06 09:00:37 +0200 |
commit | 6df0cf1c0ec727fc237a9b429684c8f2ef5d34b7 (patch) | |
tree | 5de2971b62312b8573c54f0c4befefed27d8d1bc | |
parent | c684814cc456a9792a9183ce77d32d435f29e6b7 (diff) | |
download | gnutls-tmp-iov-fixes.tar.gz |
gnutls_aead_cipher_{en,de}cryptv2: write back cached data to bufferstmp-iov-fixes
Previously, those functions failed to write the output to the buffers
if the buffer length is not multiple of cipher block size. This makes
sure that the cached data is always flushed.
Signed-off-by: Daiki Ueno <dueno@redhat.com>
-rw-r--r-- | lib/crypto-api.c | 18 | ||||
-rw-r--r-- | tests/aead-cipher-vec.c | 14 |
2 files changed, 24 insertions, 8 deletions
diff --git a/lib/crypto-api.c b/lib/crypto-api.c index 41e759b74e..7308d7e7bb 100644 --- a/lib/crypto-api.c +++ b/lib/crypto-api.c @@ -1113,6 +1113,7 @@ gnutls_aead_cipher_encryptv2(gnutls_aead_cipher_hd_t handle, api_aead_cipher_hd_st *h = handle; ssize_t ret; uint8_t *p; + size_t len; ssize_t blocksize = handle->ctx_enc.e->blocksize; struct iov_iter_st iter; size_t _tag_size; @@ -1211,7 +1212,13 @@ gnutls_aead_cipher_encryptv2(gnutls_aead_cipher_hd_t handle, return gnutls_assert_val(ret); if (ret == 0) break; - ret = _gnutls_cipher_encrypt2(&handle->ctx_enc, p, ret, p, ret); + + len = ret; + ret = _gnutls_cipher_encrypt2(&handle->ctx_enc, p, len, p, len); + if (unlikely(ret < 0)) + return gnutls_assert_val(ret); + + ret = _gnutls_iov_iter_sync(&iter, p, len); if (unlikely(ret < 0)) return gnutls_assert_val(ret); } @@ -1253,6 +1260,7 @@ gnutls_aead_cipher_decryptv2(gnutls_aead_cipher_hd_t handle, api_aead_cipher_hd_st *h = handle; ssize_t ret; uint8_t *p; + size_t len; ssize_t blocksize = handle->ctx_enc.e->blocksize; struct iov_iter_st iter; uint8_t _tag[MAX_HASH_SIZE]; @@ -1342,7 +1350,13 @@ gnutls_aead_cipher_decryptv2(gnutls_aead_cipher_hd_t handle, return gnutls_assert_val(ret); if (ret == 0) break; - ret = _gnutls_cipher_decrypt2(&handle->ctx_enc, p, ret, p, ret); + + len = ret; + ret = _gnutls_cipher_decrypt2(&handle->ctx_enc, p, len, p, len); + if (unlikely(ret < 0)) + return gnutls_assert_val(ret); + + ret = _gnutls_iov_iter_sync(&iter, p, len); if (unlikely(ret < 0)) return gnutls_assert_val(ret); } diff --git a/tests/aead-cipher-vec.c b/tests/aead-cipher-vec.c index 6c2542cf10..10e3db8626 100644 --- a/tests/aead-cipher-vec.c +++ b/tests/aead-cipher-vec.c @@ -43,9 +43,9 @@ static void start(const char *name, int algo) uint8_t key16[64]; uint8_t iv16[32]; uint8_t auth[128]; - uint8_t data[128+64]; + uint8_t data[64+56+36]; gnutls_datum_t key, iv; - giovec_t iov[2]; + giovec_t iov[3]; giovec_t auth_iov[2]; uint8_t tag[64]; size_t tag_size = 0; @@ -60,13 +60,15 @@ static void start(const char *name, int algo) memset(iv.data, 0xff, iv.size); memset(key.data, 0xfe, key.size); - memset(data, 0xfa, 128); + memset(data, 0xfa, sizeof(data)); memset(auth, 0xaa, sizeof(auth)); iov[0].iov_base = data; iov[0].iov_len = 64; iov[1].iov_base = data + 64; - iov[1].iov_len = 64; + iov[1].iov_len = 56; + iov[2].iov_base = data + 64 + 56; + iov[2].iov_len = 36; auth_iov[0].iov_base = auth; auth_iov[0].iov_len = 64; @@ -83,7 +85,7 @@ static void start(const char *name, int algo) ret = gnutls_aead_cipher_encryptv2(ch, iv.data, iv.size, auth_iov, 2, - iov, 2, + iov, 3, tag, &tag_size); if (ret < 0) fail("could not encrypt data: %s\n", gnutls_strerror(ret)); @@ -91,7 +93,7 @@ static void start(const char *name, int algo) ret = gnutls_aead_cipher_decryptv2(ch, iv.data, iv.size, auth_iov, 2, - iov, 2, + iov, 3, tag, tag_size); if (ret < 0) fail("could not decrypt data: %s\n", gnutls_strerror(ret)); |