|
|
1d35f3 |
From bbb312749780928cc10b45662c6d7eadcaa98f0b Mon Sep 17 00:00:00 2001
|
|
|
1d35f3 |
From: Daiki Ueno <dueno@redhat.com>
|
|
|
1d35f3 |
Date: Thu, 3 Oct 2019 10:34:18 +0200
|
|
|
1d35f3 |
Subject: [PATCH 1/3] iov: _gnutls_iov_iter_next: return bytes instead of
|
|
|
1d35f3 |
blocks
|
|
|
1d35f3 |
|
|
|
1d35f3 |
This eliminates the need of special handling of final block. Also
|
|
|
1d35f3 |
adds more tests in exceptional cases.
|
|
|
1d35f3 |
|
|
|
1d35f3 |
Signed-off-by: Daiki Ueno <dueno@redhat.com>
|
|
|
1d35f3 |
---
|
|
|
1d35f3 |
lib/crypto-api.c | 82 +++++-------------------------
|
|
|
1d35f3 |
lib/iov.c | 31 +++++++++---
|
|
|
1d35f3 |
tests/iov.c | 126 ++++++++++++++++++++++++++++++++---------------
|
|
|
1d35f3 |
3 files changed, 121 insertions(+), 118 deletions(-)
|
|
|
1d35f3 |
|
|
|
1d35f3 |
diff --git a/lib/crypto-api.c b/lib/crypto-api.c
|
|
|
1d35f3 |
index 09b3d7bfc..41e759b74 100644
|
|
|
1d35f3 |
--- a/lib/crypto-api.c
|
|
|
1d35f3 |
+++ b/lib/crypto-api.c
|
|
|
1d35f3 |
@@ -992,9 +992,9 @@ gnutls_aead_cipher_encryptv(gnutls_aead_cipher_hd_t handle,
|
|
|
1d35f3 |
uint8_t *dst;
|
|
|
1d35f3 |
size_t dst_size, total = 0;
|
|
|
1d35f3 |
uint8_t *p;
|
|
|
1d35f3 |
+ size_t len;
|
|
|
1d35f3 |
size_t blocksize = handle->ctx_enc.e->blocksize;
|
|
|
1d35f3 |
struct iov_iter_st iter;
|
|
|
1d35f3 |
- size_t blocks;
|
|
|
1d35f3 |
|
|
|
1d35f3 |
/* Limitation: this function provides an optimization under the internally registered
|
|
|
1d35f3 |
* AEAD ciphers. When an AEAD cipher is used registered with gnutls_crypto_register_aead_cipher(),
|
|
|
1d35f3 |
@@ -1045,15 +1045,7 @@ gnutls_aead_cipher_encryptv(gnutls_aead_cipher_hd_t handle,
|
|
|
1d35f3 |
return gnutls_assert_val(ret);
|
|
|
1d35f3 |
if (ret == 0)
|
|
|
1d35f3 |
break;
|
|
|
1d35f3 |
- blocks = ret;
|
|
|
1d35f3 |
- ret = _gnutls_cipher_auth(&handle->ctx_enc, p,
|
|
|
1d35f3 |
- blocksize * blocks);
|
|
|
1d35f3 |
- if (unlikely(ret < 0))
|
|
|
1d35f3 |
- return gnutls_assert_val(ret);
|
|
|
1d35f3 |
- }
|
|
|
1d35f3 |
- if (iter.block_offset > 0) {
|
|
|
1d35f3 |
- ret = _gnutls_cipher_auth(&handle->ctx_enc,
|
|
|
1d35f3 |
- iter.block, iter.block_offset);
|
|
|
1d35f3 |
+ ret = _gnutls_cipher_auth(&handle->ctx_enc, p, ret);
|
|
|
1d35f3 |
if (unlikely(ret < 0))
|
|
|
1d35f3 |
return gnutls_assert_val(ret);
|
|
|
1d35f3 |
}
|
|
|
1d35f3 |
@@ -1070,29 +1062,15 @@ gnutls_aead_cipher_encryptv(gnutls_aead_cipher_hd_t handle,
|
|
|
1d35f3 |
return gnutls_assert_val(ret);
|
|
|
1d35f3 |
if (ret == 0)
|
|
|
1d35f3 |
break;
|
|
|
1d35f3 |
- blocks = ret;
|
|
|
1d35f3 |
- if (unlikely(dst_size < blocksize * blocks))
|
|
|
1d35f3 |
- return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
|
|
|
1d35f3 |
- ret = _gnutls_cipher_encrypt2(&handle->ctx_enc, p,
|
|
|
1d35f3 |
- blocksize * blocks,
|
|
|
1d35f3 |
- dst, dst_size);
|
|
|
1d35f3 |
- if (unlikely(ret < 0))
|
|
|
1d35f3 |
- return gnutls_assert_val(ret);
|
|
|
1d35f3 |
- DECR_LEN(dst_size, blocksize * blocks);
|
|
|
1d35f3 |
- dst += blocksize * blocks;
|
|
|
1d35f3 |
- total += blocksize * blocks;
|
|
|
1d35f3 |
- }
|
|
|
1d35f3 |
- if (iter.block_offset > 0) {
|
|
|
1d35f3 |
- if (unlikely(dst_size < iter.block_offset))
|
|
|
1d35f3 |
- return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
|
|
|
1d35f3 |
+ len = ret;
|
|
|
1d35f3 |
ret = _gnutls_cipher_encrypt2(&handle->ctx_enc,
|
|
|
1d35f3 |
- iter.block, iter.block_offset,
|
|
|
1d35f3 |
+ p, len,
|
|
|
1d35f3 |
dst, dst_size);
|
|
|
1d35f3 |
if (unlikely(ret < 0))
|
|
|
1d35f3 |
return gnutls_assert_val(ret);
|
|
|
1d35f3 |
- DECR_LEN(dst_size, iter.block_offset);
|
|
|
1d35f3 |
- dst += iter.block_offset;
|
|
|
1d35f3 |
- total += iter.block_offset;
|
|
|
1d35f3 |
+ DECR_LEN(dst_size, len);
|
|
|
1d35f3 |
+ dst += len;
|
|
|
1d35f3 |
+ total += len;
|
|
|
1d35f3 |
}
|
|
|
1d35f3 |
|
|
|
1d35f3 |
if (dst_size < tag_size)
|
|
|
1d35f3 |
@@ -1137,7 +1115,6 @@ gnutls_aead_cipher_encryptv2(gnutls_aead_cipher_hd_t handle,
|
|
|
1d35f3 |
uint8_t *p;
|
|
|
1d35f3 |
ssize_t blocksize = handle->ctx_enc.e->blocksize;
|
|
|
1d35f3 |
struct iov_iter_st iter;
|
|
|
1d35f3 |
- size_t blocks;
|
|
|
1d35f3 |
size_t _tag_size;
|
|
|
1d35f3 |
|
|
|
1d35f3 |
if (tag_size == NULL || *tag_size == 0)
|
|
|
1d35f3 |
@@ -1220,15 +1197,7 @@ gnutls_aead_cipher_encryptv2(gnutls_aead_cipher_hd_t handle,
|
|
|
1d35f3 |
return gnutls_assert_val(ret);
|
|
|
1d35f3 |
if (ret == 0)
|
|
|
1d35f3 |
break;
|
|
|
1d35f3 |
- blocks = ret;
|
|
|
1d35f3 |
- ret = _gnutls_cipher_auth(&handle->ctx_enc, p,
|
|
|
1d35f3 |
- blocksize * blocks);
|
|
|
1d35f3 |
- if (unlikely(ret < 0))
|
|
|
1d35f3 |
- return gnutls_assert_val(ret);
|
|
|
1d35f3 |
- }
|
|
|
1d35f3 |
- if (iter.block_offset > 0) {
|
|
|
1d35f3 |
- ret = _gnutls_cipher_auth(&handle->ctx_enc,
|
|
|
1d35f3 |
- iter.block, iter.block_offset);
|
|
|
1d35f3 |
+ ret = _gnutls_cipher_auth(&handle->ctx_enc, p, ret);
|
|
|
1d35f3 |
if (unlikely(ret < 0))
|
|
|
1d35f3 |
return gnutls_assert_val(ret);
|
|
|
1d35f3 |
}
|
|
|
1d35f3 |
@@ -1242,17 +1211,7 @@ gnutls_aead_cipher_encryptv2(gnutls_aead_cipher_hd_t handle,
|
|
|
1d35f3 |
return gnutls_assert_val(ret);
|
|
|
1d35f3 |
if (ret == 0)
|
|
|
1d35f3 |
break;
|
|
|
1d35f3 |
- blocks = ret;
|
|
|
1d35f3 |
- ret = _gnutls_cipher_encrypt2(&handle->ctx_enc,
|
|
|
1d35f3 |
- p, blocksize * blocks,
|
|
|
1d35f3 |
- p, blocksize * blocks);
|
|
|
1d35f3 |
- if (unlikely(ret < 0))
|
|
|
1d35f3 |
- return gnutls_assert_val(ret);
|
|
|
1d35f3 |
- }
|
|
|
1d35f3 |
- if (iter.block_offset > 0) {
|
|
|
1d35f3 |
- ret = _gnutls_cipher_encrypt2(&handle->ctx_enc,
|
|
|
1d35f3 |
- iter.block, iter.block_offset,
|
|
|
1d35f3 |
- iter.block, iter.block_offset);
|
|
|
1d35f3 |
+ ret = _gnutls_cipher_encrypt2(&handle->ctx_enc, p, ret, p, ret);
|
|
|
1d35f3 |
if (unlikely(ret < 0))
|
|
|
1d35f3 |
return gnutls_assert_val(ret);
|
|
|
1d35f3 |
}
|
|
|
1d35f3 |
@@ -1296,7 +1255,6 @@ gnutls_aead_cipher_decryptv2(gnutls_aead_cipher_hd_t handle,
|
|
|
1d35f3 |
uint8_t *p;
|
|
|
1d35f3 |
ssize_t blocksize = handle->ctx_enc.e->blocksize;
|
|
|
1d35f3 |
struct iov_iter_st iter;
|
|
|
1d35f3 |
- size_t blocks;
|
|
|
1d35f3 |
uint8_t _tag[MAX_HASH_SIZE];
|
|
|
1d35f3 |
|
|
|
1d35f3 |
if (tag_size == 0)
|
|
|
1d35f3 |
@@ -1370,15 +1328,7 @@ gnutls_aead_cipher_decryptv2(gnutls_aead_cipher_hd_t handle,
|
|
|
1d35f3 |
return gnutls_assert_val(ret);
|
|
|
1d35f3 |
if (ret == 0)
|
|
|
1d35f3 |
break;
|
|
|
1d35f3 |
- blocks = ret;
|
|
|
1d35f3 |
- ret = _gnutls_cipher_auth(&handle->ctx_enc, p,
|
|
|
1d35f3 |
- blocksize * blocks);
|
|
|
1d35f3 |
- if (unlikely(ret < 0))
|
|
|
1d35f3 |
- return gnutls_assert_val(ret);
|
|
|
1d35f3 |
- }
|
|
|
1d35f3 |
- if (iter.block_offset > 0) {
|
|
|
1d35f3 |
- ret = _gnutls_cipher_auth(&handle->ctx_enc,
|
|
|
1d35f3 |
- iter.block, iter.block_offset);
|
|
|
1d35f3 |
+ ret = _gnutls_cipher_auth(&handle->ctx_enc, p, ret);
|
|
|
1d35f3 |
if (unlikely(ret < 0))
|
|
|
1d35f3 |
return gnutls_assert_val(ret);
|
|
|
1d35f3 |
}
|
|
|
1d35f3 |
@@ -1392,17 +1342,7 @@ gnutls_aead_cipher_decryptv2(gnutls_aead_cipher_hd_t handle,
|
|
|
1d35f3 |
return gnutls_assert_val(ret);
|
|
|
1d35f3 |
if (ret == 0)
|
|
|
1d35f3 |
break;
|
|
|
1d35f3 |
- blocks = ret;
|
|
|
1d35f3 |
- ret = _gnutls_cipher_decrypt2(&handle->ctx_enc,
|
|
|
1d35f3 |
- p, blocksize * blocks,
|
|
|
1d35f3 |
- p, blocksize * blocks);
|
|
|
1d35f3 |
- if (unlikely(ret < 0))
|
|
|
1d35f3 |
- return gnutls_assert_val(ret);
|
|
|
1d35f3 |
- }
|
|
|
1d35f3 |
- if (iter.block_offset > 0) {
|
|
|
1d35f3 |
- ret = _gnutls_cipher_decrypt2(&handle->ctx_enc,
|
|
|
1d35f3 |
- iter.block, iter.block_offset,
|
|
|
1d35f3 |
- iter.block, iter.block_offset);
|
|
|
1d35f3 |
+ ret = _gnutls_cipher_decrypt2(&handle->ctx_enc, p, ret, p, ret);
|
|
|
1d35f3 |
if (unlikely(ret < 0))
|
|
|
1d35f3 |
return gnutls_assert_val(ret);
|
|
|
1d35f3 |
}
|
|
|
1d35f3 |
diff --git a/lib/iov.c b/lib/iov.c
|
|
|
1d35f3 |
index 5dc29c54b..17272886c 100644
|
|
|
1d35f3 |
--- a/lib/iov.c
|
|
|
1d35f3 |
+++ b/lib/iov.c
|
|
|
1d35f3 |
@@ -58,8 +58,8 @@ _gnutls_iov_iter_init(struct iov_iter_st *iter,
|
|
|
1d35f3 |
* @data: the return location of extracted data
|
|
|
1d35f3 |
*
|
|
|
1d35f3 |
* Retrieve block(s) pointed by @iter and advance it to the next
|
|
|
1d35f3 |
- * position. It returns the number of consecutive blocks in @data.
|
|
|
1d35f3 |
- * At the end of iteration, 0 is returned.
|
|
|
1d35f3 |
+ * position. It returns the number of bytes in @data. At the end of
|
|
|
1d35f3 |
+ * iteration, 0 is returned.
|
|
|
1d35f3 |
*
|
|
|
1d35f3 |
* If the data stored in @iter is not multiple of the block size, the
|
|
|
1d35f3 |
* remaining data is stored in the "block" field of @iter with the
|
|
|
1d35f3 |
@@ -88,25 +88,30 @@ _gnutls_iov_iter_next(struct iov_iter_st *iter, uint8_t **data)
|
|
|
1d35f3 |
if ((len % iter->block_size) == 0) {
|
|
|
1d35f3 |
iter->iov_index++;
|
|
|
1d35f3 |
iter->iov_offset = 0;
|
|
|
1d35f3 |
- } else
|
|
|
1d35f3 |
- iter->iov_offset +=
|
|
|
1d35f3 |
- len - (len % iter->block_size);
|
|
|
1d35f3 |
+ } else {
|
|
|
1d35f3 |
+ len -= (len % iter->block_size);
|
|
|
1d35f3 |
+ iter->iov_offset += len;
|
|
|
1d35f3 |
+ }
|
|
|
1d35f3 |
|
|
|
1d35f3 |
/* Return the blocks. */
|
|
|
1d35f3 |
*data = p;
|
|
|
1d35f3 |
- return len / iter->block_size;
|
|
|
1d35f3 |
+ return len;
|
|
|
1d35f3 |
}
|
|
|
1d35f3 |
|
|
|
1d35f3 |
/* We can complete one full block to return. */
|
|
|
1d35f3 |
block_left = iter->block_size - iter->block_offset;
|
|
|
1d35f3 |
if (len >= block_left) {
|
|
|
1d35f3 |
memcpy(iter->block + iter->block_offset, p, block_left);
|
|
|
1d35f3 |
- iter->iov_offset += block_left;
|
|
|
1d35f3 |
+ if (len == block_left) {
|
|
|
1d35f3 |
+ iter->iov_index++;
|
|
|
1d35f3 |
+ iter->iov_offset = 0;
|
|
|
1d35f3 |
+ } else
|
|
|
1d35f3 |
+ iter->iov_offset += block_left;
|
|
|
1d35f3 |
iter->block_offset = 0;
|
|
|
1d35f3 |
|
|
|
1d35f3 |
/* Return the filled block. */
|
|
|
1d35f3 |
*data = iter->block;
|
|
|
1d35f3 |
- return 1;
|
|
|
1d35f3 |
+ return iter->block_size;
|
|
|
1d35f3 |
}
|
|
|
1d35f3 |
|
|
|
1d35f3 |
/* Not enough data for a full block, store in temp
|
|
|
1d35f3 |
@@ -116,5 +121,15 @@ _gnutls_iov_iter_next(struct iov_iter_st *iter, uint8_t **data)
|
|
|
1d35f3 |
iter->iov_index++;
|
|
|
1d35f3 |
iter->iov_offset = 0;
|
|
|
1d35f3 |
}
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+ if (iter->block_offset > 0) {
|
|
|
1d35f3 |
+ size_t len = iter->block_offset;
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+ /* Return the incomplete block. */
|
|
|
1d35f3 |
+ *data = iter->block;
|
|
|
1d35f3 |
+ iter->block_offset = 0;
|
|
|
1d35f3 |
+ return len;
|
|
|
1d35f3 |
+ }
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
return 0;
|
|
|
1d35f3 |
}
|
|
|
1d35f3 |
diff --git a/tests/iov.c b/tests/iov.c
|
|
|
1d35f3 |
index eda5583a7..3d116b471 100644
|
|
|
1d35f3 |
--- a/tests/iov.c
|
|
|
1d35f3 |
+++ b/tests/iov.c
|
|
|
1d35f3 |
@@ -32,7 +32,6 @@ struct exp_st {
|
|
|
1d35f3 |
ssize_t ret;
|
|
|
1d35f3 |
size_t iov_index;
|
|
|
1d35f3 |
size_t iov_offset;
|
|
|
1d35f3 |
- size_t block_offset;
|
|
|
1d35f3 |
};
|
|
|
1d35f3 |
|
|
|
1d35f3 |
struct test_st {
|
|
|
1d35f3 |
@@ -42,7 +41,6 @@ struct test_st {
|
|
|
1d35f3 |
size_t block_size;
|
|
|
1d35f3 |
const struct exp_st *exp;
|
|
|
1d35f3 |
size_t expcnt;
|
|
|
1d35f3 |
- size_t remaining;
|
|
|
1d35f3 |
};
|
|
|
1d35f3 |
|
|
|
1d35f3 |
static const giovec_t iov16[] = {
|
|
|
1d35f3 |
@@ -53,40 +51,41 @@ static const giovec_t iov16[] = {
|
|
|
1d35f3 |
};
|
|
|
1d35f3 |
|
|
|
1d35f3 |
static const struct exp_st exp16_64[] = {
|
|
|
1d35f3 |
- {1, 3, 16, 0},
|
|
|
1d35f3 |
- {0, 0, 0, 0}
|
|
|
1d35f3 |
+ {64, 4, 0},
|
|
|
1d35f3 |
+ {0, 0, 0}
|
|
|
1d35f3 |
};
|
|
|
1d35f3 |
|
|
|
1d35f3 |
static const struct exp_st exp16_32[] = {
|
|
|
1d35f3 |
- {1, 1, 16, 0},
|
|
|
1d35f3 |
- {1, 3, 16, 0},
|
|
|
1d35f3 |
- {0, 0, 0, 0}
|
|
|
1d35f3 |
+ {32, 2, 0},
|
|
|
1d35f3 |
+ {32, 4, 0},
|
|
|
1d35f3 |
+ {0, 0, 0}
|
|
|
1d35f3 |
};
|
|
|
1d35f3 |
|
|
|
1d35f3 |
static const struct exp_st exp16_16[] = {
|
|
|
1d35f3 |
- {1, 1, 0, 0},
|
|
|
1d35f3 |
- {1, 2, 0, 0},
|
|
|
1d35f3 |
- {1, 3, 0, 0},
|
|
|
1d35f3 |
- {1, 4, 0, 0},
|
|
|
1d35f3 |
- {0, 0, 0, 0}
|
|
|
1d35f3 |
+ {16, 1, 0},
|
|
|
1d35f3 |
+ {16, 2, 0},
|
|
|
1d35f3 |
+ {16, 3, 0},
|
|
|
1d35f3 |
+ {16, 4, 0},
|
|
|
1d35f3 |
+ {0, 0, 0}
|
|
|
1d35f3 |
};
|
|
|
1d35f3 |
|
|
|
1d35f3 |
static const struct exp_st exp16_4[] = {
|
|
|
1d35f3 |
- {4, 1, 0, 0},
|
|
|
1d35f3 |
- {4, 2, 0, 0},
|
|
|
1d35f3 |
- {4, 3, 0, 0},
|
|
|
1d35f3 |
- {4, 4, 0, 0},
|
|
|
1d35f3 |
- {0, 0, 0, 0}
|
|
|
1d35f3 |
+ {16, 1, 0},
|
|
|
1d35f3 |
+ {16, 2, 0},
|
|
|
1d35f3 |
+ {16, 3, 0},
|
|
|
1d35f3 |
+ {16, 4, 0},
|
|
|
1d35f3 |
+ {0, 0, 0}
|
|
|
1d35f3 |
};
|
|
|
1d35f3 |
|
|
|
1d35f3 |
static const struct exp_st exp16_3[] = {
|
|
|
1d35f3 |
- {5, 0, 15, 0},
|
|
|
1d35f3 |
- {1, 1, 2, 0},
|
|
|
1d35f3 |
- {4, 1, 14, 0},
|
|
|
1d35f3 |
- {1, 2, 1, 0},
|
|
|
1d35f3 |
- {5, 3, 0, 0},
|
|
|
1d35f3 |
- {5, 3, 15, 0},
|
|
|
1d35f3 |
- {0, 0, 0, 1}
|
|
|
1d35f3 |
+ {15, 0, 15},
|
|
|
1d35f3 |
+ {3, 1, 2},
|
|
|
1d35f3 |
+ {12, 1, 14},
|
|
|
1d35f3 |
+ {3, 2, 1},
|
|
|
1d35f3 |
+ {15, 3, 0},
|
|
|
1d35f3 |
+ {15, 3, 15},
|
|
|
1d35f3 |
+ {1, 4, 0},
|
|
|
1d35f3 |
+ {0, 0, 0}
|
|
|
1d35f3 |
};
|
|
|
1d35f3 |
|
|
|
1d35f3 |
static const giovec_t iov8[] = {
|
|
|
1d35f3 |
@@ -97,22 +96,74 @@ static const giovec_t iov8[] = {
|
|
|
1d35f3 |
};
|
|
|
1d35f3 |
|
|
|
1d35f3 |
static const struct exp_st exp8_64[] = {
|
|
|
1d35f3 |
- {0, 0, 0, 32}
|
|
|
1d35f3 |
+ {32, 4, 0},
|
|
|
1d35f3 |
+ {0, 0, 0}
|
|
|
1d35f3 |
+};
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+static const giovec_t iov_odd[] = {
|
|
|
1d35f3 |
+ {(void *) "0", 1},
|
|
|
1d35f3 |
+ {(void *) "012", 3},
|
|
|
1d35f3 |
+ {(void *) "01234", 5},
|
|
|
1d35f3 |
+ {(void *) "0123456", 7},
|
|
|
1d35f3 |
+ {(void *) "012345678", 9},
|
|
|
1d35f3 |
+ {(void *) "01234567890", 11},
|
|
|
1d35f3 |
+ {(void *) "0123456789012", 13},
|
|
|
1d35f3 |
+ {(void *) "012345678901234", 15}
|
|
|
1d35f3 |
+};
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+static const struct exp_st exp_odd_16[] = {
|
|
|
1d35f3 |
+ {16, 4, 0},
|
|
|
1d35f3 |
+ {16, 5, 7},
|
|
|
1d35f3 |
+ {16, 6, 12},
|
|
|
1d35f3 |
+ {16, 8, 0},
|
|
|
1d35f3 |
+ {0, 0, 0}
|
|
|
1d35f3 |
+};
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+static const giovec_t iov_skip[] = {
|
|
|
1d35f3 |
+ {(void *) "0123456789012345", 16},
|
|
|
1d35f3 |
+ {(void *) "01234567", 8},
|
|
|
1d35f3 |
+ {(void *) "", 0},
|
|
|
1d35f3 |
+ {(void *) "", 0},
|
|
|
1d35f3 |
+ {(void *) "0123456789012345", 16}
|
|
|
1d35f3 |
+};
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+static const struct exp_st exp_skip_16[] = {
|
|
|
1d35f3 |
+ {16, 1, 0},
|
|
|
1d35f3 |
+ {16, 4, 8},
|
|
|
1d35f3 |
+ {8, 5, 0},
|
|
|
1d35f3 |
+ {0, 0, 0}
|
|
|
1d35f3 |
+};
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+static const giovec_t iov_empty[] = {
|
|
|
1d35f3 |
+ {(void *) "", 0},
|
|
|
1d35f3 |
+ {(void *) "", 0},
|
|
|
1d35f3 |
+ {(void *) "", 0},
|
|
|
1d35f3 |
+ {(void *) "", 0}
|
|
|
1d35f3 |
+};
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+static const struct exp_st exp_empty_16[] = {
|
|
|
1d35f3 |
+ {0, 0, 0}
|
|
|
1d35f3 |
};
|
|
|
1d35f3 |
|
|
|
1d35f3 |
static const struct test_st tests[] = {
|
|
|
1d35f3 |
{ "16/64", iov16, sizeof(iov16)/sizeof(iov16[0]), 64,
|
|
|
1d35f3 |
- exp16_64, sizeof(exp16_64)/sizeof(exp16_64[0]), 0 },
|
|
|
1d35f3 |
+ exp16_64, sizeof(exp16_64)/sizeof(exp16_64[0]) },
|
|
|
1d35f3 |
{ "16/32", iov16, sizeof(iov16)/sizeof(iov16[0]), 32,
|
|
|
1d35f3 |
- exp16_32, sizeof(exp16_32)/sizeof(exp16_32[0]), 0 },
|
|
|
1d35f3 |
+ exp16_32, sizeof(exp16_32)/sizeof(exp16_32[0]) },
|
|
|
1d35f3 |
{ "16/16", iov16, sizeof(iov16)/sizeof(iov16[0]), 16,
|
|
|
1d35f3 |
- exp16_16, sizeof(exp16_16)/sizeof(exp16_16[0]), 0 },
|
|
|
1d35f3 |
+ exp16_16, sizeof(exp16_16)/sizeof(exp16_16[0]) },
|
|
|
1d35f3 |
{ "16/4", iov16, sizeof(iov16)/sizeof(iov16[0]), 4,
|
|
|
1d35f3 |
- exp16_4, sizeof(exp16_4)/sizeof(exp16_4[0]), 0 },
|
|
|
1d35f3 |
+ exp16_4, sizeof(exp16_4)/sizeof(exp16_4[0]) },
|
|
|
1d35f3 |
{ "16/3", iov16, sizeof(iov16)/sizeof(iov16[0]), 3,
|
|
|
1d35f3 |
- exp16_3, sizeof(exp16_3)/sizeof(exp16_3[0]), 1 },
|
|
|
1d35f3 |
+ exp16_3, sizeof(exp16_3)/sizeof(exp16_3[0]) },
|
|
|
1d35f3 |
{ "8/64", iov8, sizeof(iov8)/sizeof(iov8[0]), 64,
|
|
|
1d35f3 |
- exp8_64, sizeof(exp8_64)/sizeof(exp8_64[0]), 32 }
|
|
|
1d35f3 |
+ exp8_64, sizeof(exp8_64)/sizeof(exp8_64[0]) },
|
|
|
1d35f3 |
+ { "odd/16", iov_odd, sizeof(iov_odd)/sizeof(iov_odd[0]), 16,
|
|
|
1d35f3 |
+ exp_odd_16, sizeof(exp_odd_16)/sizeof(exp_odd_16[0]) },
|
|
|
1d35f3 |
+ { "skip/16", iov_skip, sizeof(iov_skip)/sizeof(iov_skip[0]), 16,
|
|
|
1d35f3 |
+ exp_skip_16, sizeof(exp_skip_16)/sizeof(exp_skip_16[0]) },
|
|
|
1d35f3 |
+ { "empty/16", iov_empty, sizeof(iov_empty)/sizeof(iov_empty[0]), 16,
|
|
|
1d35f3 |
+ exp_empty_16, sizeof(exp_empty_16)/sizeof(exp_empty_16[0]) },
|
|
|
1d35f3 |
};
|
|
|
1d35f3 |
|
|
|
1d35f3 |
void
|
|
|
1d35f3 |
@@ -155,16 +206,13 @@ doit (void)
|
|
|
1d35f3 |
else if (debug)
|
|
|
1d35f3 |
success("iter.iov_offset: %u == %u\n",
|
|
|
1d35f3 |
(unsigned) iter.iov_offset, (unsigned) exp[j].iov_offset);
|
|
|
1d35f3 |
- if (iter.block_offset != exp[j].block_offset)
|
|
|
1d35f3 |
- fail("iter.block_offset: %u != %u\n",
|
|
|
1d35f3 |
- (unsigned) iter.block_offset, (unsigned) exp[j].block_offset);
|
|
|
1d35f3 |
+ if (iter.block_offset != 0)
|
|
|
1d35f3 |
+ fail("iter.block_offset: %u != 0\n",
|
|
|
1d35f3 |
+ (unsigned) iter.block_offset);
|
|
|
1d35f3 |
else if (debug)
|
|
|
1d35f3 |
- success("iter.block_offset: %u == %u\n",
|
|
|
1d35f3 |
- (unsigned) iter.block_offset, (unsigned) exp[j].block_offset);
|
|
|
1d35f3 |
+ success("iter.block_offset: %u == 0\n",
|
|
|
1d35f3 |
+ (unsigned) iter.block_offset);
|
|
|
1d35f3 |
}
|
|
|
1d35f3 |
}
|
|
|
1d35f3 |
- if (iter.block_offset != tests[i].remaining)
|
|
|
1d35f3 |
- fail("remaining: %u != %u\n",
|
|
|
1d35f3 |
- (unsigned) iter.block_offset, (unsigned) tests[i].remaining);
|
|
|
1d35f3 |
}
|
|
|
1d35f3 |
}
|
|
|
1d35f3 |
--
|
|
|
1d35f3 |
2.21.0
|
|
|
1d35f3 |
|
|
|
1d35f3 |
|
|
|
1d35f3 |
From c684814cc456a9792a9183ce77d32d435f29e6b7 Mon Sep 17 00:00:00 2001
|
|
|
1d35f3 |
From: Daiki Ueno <dueno@redhat.com>
|
|
|
1d35f3 |
Date: Tue, 1 Oct 2019 18:14:48 +0200
|
|
|
1d35f3 |
Subject: [PATCH 2/3] iov: add _gnutls_iov_iter_sync to write back cached data
|
|
|
1d35f3 |
to iov
|
|
|
1d35f3 |
|
|
|
1d35f3 |
Signed-off-by: Daiki Ueno <dueno@redhat.com>
|
|
|
1d35f3 |
---
|
|
|
1d35f3 |
lib/iov.c | 59 +++++++++++++++++++++++++++++++++++++++++++++
|
|
|
1d35f3 |
lib/iov.h | 4 +++-
|
|
|
1d35f3 |
lib/libgnutls.map | 1 +
|
|
|
1d35f3 |
tests/iov.c | 61 +++++++++++++++++++++++++++++++++++++++++++----
|
|
|
1d35f3 |
4 files changed, 119 insertions(+), 6 deletions(-)
|
|
|
1d35f3 |
|
|
|
1d35f3 |
diff --git a/lib/iov.c b/lib/iov.c
|
|
|
1d35f3 |
index 17272886c..1cd8d46dd 100644
|
|
|
1d35f3 |
--- a/lib/iov.c
|
|
|
1d35f3 |
+++ b/lib/iov.c
|
|
|
1d35f3 |
@@ -133,3 +133,62 @@ _gnutls_iov_iter_next(struct iov_iter_st *iter, uint8_t **data)
|
|
|
1d35f3 |
|
|
|
1d35f3 |
return 0;
|
|
|
1d35f3 |
}
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+/**
|
|
|
1d35f3 |
+ * _gnutls_iov_iter_sync:
|
|
|
1d35f3 |
+ * @iter: the iterator
|
|
|
1d35f3 |
+ * @data: data returned by _gnutls_iov_iter_next
|
|
|
1d35f3 |
+ * @data_size: size of @data
|
|
|
1d35f3 |
+ *
|
|
|
1d35f3 |
+ * Flush the content of temp buffer (if any) to the data buffer.
|
|
|
1d35f3 |
+ */
|
|
|
1d35f3 |
+int
|
|
|
1d35f3 |
+_gnutls_iov_iter_sync(struct iov_iter_st *iter, const uint8_t *data,
|
|
|
1d35f3 |
+ size_t data_size)
|
|
|
1d35f3 |
+{
|
|
|
1d35f3 |
+ size_t iov_index;
|
|
|
1d35f3 |
+ size_t iov_offset;
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+ /* We didn't return the cached block. */
|
|
|
1d35f3 |
+ if (data != iter->block)
|
|
|
1d35f3 |
+ return 0;
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+ iov_index = iter->iov_index;
|
|
|
1d35f3 |
+ iov_offset = iter->iov_offset;
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+ /* When syncing a cache block we walk backwards because we only have a
|
|
|
1d35f3 |
+ * pointer to were the block ends in the iovec, walking backwards is
|
|
|
1d35f3 |
+ * fine as we are always writing a full block, so the whole content
|
|
|
1d35f3 |
+ * is written in the right places:
|
|
|
1d35f3 |
+ * iovec: |--0--|---1---|--2--|-3-|
|
|
|
1d35f3 |
+ * block: |-----------------------|
|
|
|
1d35f3 |
+ * 1st write |---|
|
|
|
1d35f3 |
+ * 2nd write |-----
|
|
|
1d35f3 |
+ * 3rd write |-------
|
|
|
1d35f3 |
+ * last write |-----
|
|
|
1d35f3 |
+ */
|
|
|
1d35f3 |
+ while (data_size > 0) {
|
|
|
1d35f3 |
+ const giovec_t *iov;
|
|
|
1d35f3 |
+ uint8_t *p;
|
|
|
1d35f3 |
+ size_t to_write;
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+ while (iov_offset == 0) {
|
|
|
1d35f3 |
+ if (unlikely(iov_index == 0))
|
|
|
1d35f3 |
+ return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+ iov_index--;
|
|
|
1d35f3 |
+ iov_offset = iter->iov[iov_index].iov_len;
|
|
|
1d35f3 |
+ }
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+ iov = &iter->iov[iov_index];
|
|
|
1d35f3 |
+ p = iov->iov_base;
|
|
|
1d35f3 |
+ to_write = MIN(data_size, iov_offset);
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+ iov_offset -= to_write;
|
|
|
1d35f3 |
+ data_size -= to_write;
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+ memcpy(p + iov_offset, &iter->block[data_size], to_write);
|
|
|
1d35f3 |
+ }
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+ return 0;
|
|
|
1d35f3 |
+}
|
|
|
1d35f3 |
diff --git a/lib/iov.h b/lib/iov.h
|
|
|
1d35f3 |
index 47fba559a..5b9903460 100644
|
|
|
1d35f3 |
--- a/lib/iov.h
|
|
|
1d35f3 |
+++ b/lib/iov.h
|
|
|
1d35f3 |
@@ -34,7 +34,6 @@ struct iov_iter_st {
|
|
|
1d35f3 |
uint8_t block[MAX_CIPHER_BLOCK_SIZE]; /* incomplete block for reading */
|
|
|
1d35f3 |
size_t block_size; /* actual block size of the cipher */
|
|
|
1d35f3 |
size_t block_offset; /* offset in block */
|
|
|
1d35f3 |
-
|
|
|
1d35f3 |
};
|
|
|
1d35f3 |
|
|
|
1d35f3 |
int _gnutls_iov_iter_init(struct iov_iter_st *iter,
|
|
|
1d35f3 |
@@ -43,4 +42,7 @@ int _gnutls_iov_iter_init(struct iov_iter_st *iter,
|
|
|
1d35f3 |
|
|
|
1d35f3 |
ssize_t _gnutls_iov_iter_next(struct iov_iter_st *iter, uint8_t **data);
|
|
|
1d35f3 |
|
|
|
1d35f3 |
+int _gnutls_iov_iter_sync(struct iov_iter_st *iter, const uint8_t *data,
|
|
|
1d35f3 |
+ size_t data_size);
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
#endif /* GNUTLS_LIB_IOV_H */
|
|
|
1d35f3 |
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
|
|
|
1d35f3 |
index f83a21e9b..d6973f72e 100644
|
|
|
1d35f3 |
--- a/lib/libgnutls.map
|
|
|
1d35f3 |
+++ b/lib/libgnutls.map
|
|
|
1d35f3 |
@@ -1394,4 +1394,5 @@ GNUTLS_PRIVATE_3_4 {
|
|
|
1d35f3 |
# needed by tests/iov:
|
|
|
1d35f3 |
_gnutls_iov_iter_init;
|
|
|
1d35f3 |
_gnutls_iov_iter_next;
|
|
|
1d35f3 |
+ _gnutls_iov_iter_sync;
|
|
|
1d35f3 |
} GNUTLS_3_4;
|
|
|
1d35f3 |
diff --git a/tests/iov.c b/tests/iov.c
|
|
|
1d35f3 |
index 3d116b471..2acd2b5f5 100644
|
|
|
1d35f3 |
--- a/tests/iov.c
|
|
|
1d35f3 |
+++ b/tests/iov.c
|
|
|
1d35f3 |
@@ -44,10 +44,10 @@ struct test_st {
|
|
|
1d35f3 |
};
|
|
|
1d35f3 |
|
|
|
1d35f3 |
static const giovec_t iov16[] = {
|
|
|
1d35f3 |
- {(void *) "0123456789abcdef", 16},
|
|
|
1d35f3 |
- {(void *) "0123456789abcdef", 16},
|
|
|
1d35f3 |
- {(void *) "0123456789abcdef", 16},
|
|
|
1d35f3 |
- {(void *) "0123456789abcdef", 16}
|
|
|
1d35f3 |
+ {(void *) "0123456789012345", 16},
|
|
|
1d35f3 |
+ {(void *) "0123456789012345", 16},
|
|
|
1d35f3 |
+ {(void *) "0123456789012345", 16},
|
|
|
1d35f3 |
+ {(void *) "0123456789012345", 16}
|
|
|
1d35f3 |
};
|
|
|
1d35f3 |
|
|
|
1d35f3 |
static const struct exp_st exp16_64[] = {
|
|
|
1d35f3 |
@@ -166,20 +166,53 @@ static const struct test_st tests[] = {
|
|
|
1d35f3 |
exp_empty_16, sizeof(exp_empty_16)/sizeof(exp_empty_16[0]) },
|
|
|
1d35f3 |
};
|
|
|
1d35f3 |
|
|
|
1d35f3 |
+static void
|
|
|
1d35f3 |
+copy(giovec_t *dst, uint8_t *buffer, const giovec_t *src, size_t iovcnt)
|
|
|
1d35f3 |
+{
|
|
|
1d35f3 |
+ uint8_t *p = buffer;
|
|
|
1d35f3 |
+ size_t i;
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+ for (i = 0; i < iovcnt; i++) {
|
|
|
1d35f3 |
+ dst[i].iov_base = p;
|
|
|
1d35f3 |
+ dst[i].iov_len = src[i].iov_len;
|
|
|
1d35f3 |
+ memcpy(dst[i].iov_base, src[i].iov_base, src[i].iov_len);
|
|
|
1d35f3 |
+ p += src[i].iov_len;
|
|
|
1d35f3 |
+ }
|
|
|
1d35f3 |
+}
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+static void
|
|
|
1d35f3 |
+translate(uint8_t *data, size_t len)
|
|
|
1d35f3 |
+{
|
|
|
1d35f3 |
+ for (; len > 0; len--) {
|
|
|
1d35f3 |
+ uint8_t *p = &data[len - 1];
|
|
|
1d35f3 |
+ if (*p >= '0' && *p <= '9')
|
|
|
1d35f3 |
+ *p = 'A' + *p - '0';
|
|
|
1d35f3 |
+ else if (*p >= 'A' && *p <= 'Z')
|
|
|
1d35f3 |
+ *p = '0' + *p - 'A';
|
|
|
1d35f3 |
+ }
|
|
|
1d35f3 |
+}
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+#define MAX_BUF 1024
|
|
|
1d35f3 |
+#define MAX_IOV 16
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
void
|
|
|
1d35f3 |
doit (void)
|
|
|
1d35f3 |
{
|
|
|
1d35f3 |
+ uint8_t buffer[MAX_BUF];
|
|
|
1d35f3 |
size_t i;
|
|
|
1d35f3 |
|
|
|
1d35f3 |
for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
|
|
|
1d35f3 |
+ giovec_t iov[MAX_IOV];
|
|
|
1d35f3 |
struct iov_iter_st iter;
|
|
|
1d35f3 |
const struct exp_st *exp = tests[i].exp;
|
|
|
1d35f3 |
uint8_t *data;
|
|
|
1d35f3 |
size_t j;
|
|
|
1d35f3 |
|
|
|
1d35f3 |
+ copy(iov, buffer, tests[i].iov, tests[i].iovcnt);
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
success("%s\n", tests[i].name);
|
|
|
1d35f3 |
assert(_gnutls_iov_iter_init(&iter,
|
|
|
1d35f3 |
- tests[i].iov, tests[i].iovcnt,
|
|
|
1d35f3 |
+ iov, tests[i].iovcnt,
|
|
|
1d35f3 |
tests[i].block_size) == 0);
|
|
|
1d35f3 |
for (j = 0; j < tests[i].expcnt; j++) {
|
|
|
1d35f3 |
ssize_t ret;
|
|
|
1d35f3 |
@@ -212,7 +245,25 @@ doit (void)
|
|
|
1d35f3 |
else if (debug)
|
|
|
1d35f3 |
success("iter.block_offset: %u == 0\n",
|
|
|
1d35f3 |
(unsigned) iter.block_offset);
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+ translate(data, ret);
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+ ret = _gnutls_iov_iter_sync(&iter, data, ret);
|
|
|
1d35f3 |
+ if (ret < 0)
|
|
|
1d35f3 |
+ fail("sync failed\n");
|
|
|
1d35f3 |
}
|
|
|
1d35f3 |
}
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+ for (j = 0; j < tests[i].iovcnt; j++) {
|
|
|
1d35f3 |
+ translate(iov[j].iov_base, iov[j].iov_len);
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+ if (memcmp(iov[j].iov_base, tests[i].iov[j].iov_base,
|
|
|
1d35f3 |
+ iov[j].iov_len) != 0)
|
|
|
1d35f3 |
+ fail("iov doesn't match: %*s != %*s\n",
|
|
|
1d35f3 |
+ (int)iov[j].iov_len,
|
|
|
1d35f3 |
+ (char *)iov[j].iov_base,
|
|
|
1d35f3 |
+ (int)tests[i].iov[j].iov_len,
|
|
|
1d35f3 |
+ (char *)tests[i].iov[j].iov_len);
|
|
|
1d35f3 |
+ }
|
|
|
1d35f3 |
}
|
|
|
1d35f3 |
}
|
|
|
1d35f3 |
--
|
|
|
1d35f3 |
2.21.0
|
|
|
1d35f3 |
|
|
|
1d35f3 |
|
|
|
1d35f3 |
From 6df0cf1c0ec727fc237a9b429684c8f2ef5d34b7 Mon Sep 17 00:00:00 2001
|
|
|
1d35f3 |
From: Daiki Ueno <dueno@redhat.com>
|
|
|
1d35f3 |
Date: Tue, 1 Oct 2019 18:15:19 +0200
|
|
|
1d35f3 |
Subject: [PATCH 3/3] gnutls_aead_cipher_{en,de}cryptv2: write back cached data
|
|
|
1d35f3 |
to buffers
|
|
|
1d35f3 |
|
|
|
1d35f3 |
Previously, those functions failed to write the output to the buffers
|
|
|
1d35f3 |
if the buffer length is not multiple of cipher block size. This makes
|
|
|
1d35f3 |
sure that the cached data is always flushed.
|
|
|
1d35f3 |
|
|
|
1d35f3 |
Signed-off-by: Daiki Ueno <dueno@redhat.com>
|
|
|
1d35f3 |
---
|
|
|
1d35f3 |
lib/crypto-api.c | 18 ++++++++++++++++--
|
|
|
1d35f3 |
tests/aead-cipher-vec.c | 14 ++++++++------
|
|
|
1d35f3 |
2 files changed, 24 insertions(+), 8 deletions(-)
|
|
|
1d35f3 |
|
|
|
1d35f3 |
diff --git a/lib/crypto-api.c b/lib/crypto-api.c
|
|
|
1d35f3 |
index 41e759b74..7308d7e7b 100644
|
|
|
1d35f3 |
--- a/lib/crypto-api.c
|
|
|
1d35f3 |
+++ b/lib/crypto-api.c
|
|
|
1d35f3 |
@@ -1113,6 +1113,7 @@ gnutls_aead_cipher_encryptv2(gnutls_aead_cipher_hd_t handle,
|
|
|
1d35f3 |
api_aead_cipher_hd_st *h = handle;
|
|
|
1d35f3 |
ssize_t ret;
|
|
|
1d35f3 |
uint8_t *p;
|
|
|
1d35f3 |
+ size_t len;
|
|
|
1d35f3 |
ssize_t blocksize = handle->ctx_enc.e->blocksize;
|
|
|
1d35f3 |
struct iov_iter_st iter;
|
|
|
1d35f3 |
size_t _tag_size;
|
|
|
1d35f3 |
@@ -1211,7 +1212,13 @@ gnutls_aead_cipher_encryptv2(gnutls_aead_cipher_hd_t handle,
|
|
|
1d35f3 |
return gnutls_assert_val(ret);
|
|
|
1d35f3 |
if (ret == 0)
|
|
|
1d35f3 |
break;
|
|
|
1d35f3 |
- ret = _gnutls_cipher_encrypt2(&handle->ctx_enc, p, ret, p, ret);
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+ len = ret;
|
|
|
1d35f3 |
+ ret = _gnutls_cipher_encrypt2(&handle->ctx_enc, p, len, p, len);
|
|
|
1d35f3 |
+ if (unlikely(ret < 0))
|
|
|
1d35f3 |
+ return gnutls_assert_val(ret);
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+ ret = _gnutls_iov_iter_sync(&iter, p, len);
|
|
|
1d35f3 |
if (unlikely(ret < 0))
|
|
|
1d35f3 |
return gnutls_assert_val(ret);
|
|
|
1d35f3 |
}
|
|
|
1d35f3 |
@@ -1253,6 +1260,7 @@ gnutls_aead_cipher_decryptv2(gnutls_aead_cipher_hd_t handle,
|
|
|
1d35f3 |
api_aead_cipher_hd_st *h = handle;
|
|
|
1d35f3 |
ssize_t ret;
|
|
|
1d35f3 |
uint8_t *p;
|
|
|
1d35f3 |
+ size_t len;
|
|
|
1d35f3 |
ssize_t blocksize = handle->ctx_enc.e->blocksize;
|
|
|
1d35f3 |
struct iov_iter_st iter;
|
|
|
1d35f3 |
uint8_t _tag[MAX_HASH_SIZE];
|
|
|
1d35f3 |
@@ -1342,7 +1350,13 @@ gnutls_aead_cipher_decryptv2(gnutls_aead_cipher_hd_t handle,
|
|
|
1d35f3 |
return gnutls_assert_val(ret);
|
|
|
1d35f3 |
if (ret == 0)
|
|
|
1d35f3 |
break;
|
|
|
1d35f3 |
- ret = _gnutls_cipher_decrypt2(&handle->ctx_enc, p, ret, p, ret);
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+ len = ret;
|
|
|
1d35f3 |
+ ret = _gnutls_cipher_decrypt2(&handle->ctx_enc, p, len, p, len);
|
|
|
1d35f3 |
+ if (unlikely(ret < 0))
|
|
|
1d35f3 |
+ return gnutls_assert_val(ret);
|
|
|
1d35f3 |
+
|
|
|
1d35f3 |
+ ret = _gnutls_iov_iter_sync(&iter, p, len);
|
|
|
1d35f3 |
if (unlikely(ret < 0))
|
|
|
1d35f3 |
return gnutls_assert_val(ret);
|
|
|
1d35f3 |
}
|
|
|
1d35f3 |
diff --git a/tests/aead-cipher-vec.c b/tests/aead-cipher-vec.c
|
|
|
1d35f3 |
index 6c2542cf1..10e3db862 100644
|
|
|
1d35f3 |
--- a/tests/aead-cipher-vec.c
|
|
|
1d35f3 |
+++ b/tests/aead-cipher-vec.c
|
|
|
1d35f3 |
@@ -43,9 +43,9 @@ static void start(const char *name, int algo)
|
|
|
1d35f3 |
uint8_t key16[64];
|
|
|
1d35f3 |
uint8_t iv16[32];
|
|
|
1d35f3 |
uint8_t auth[128];
|
|
|
1d35f3 |
- uint8_t data[128+64];
|
|
|
1d35f3 |
+ uint8_t data[64+56+36];
|
|
|
1d35f3 |
gnutls_datum_t key, iv;
|
|
|
1d35f3 |
- giovec_t iov[2];
|
|
|
1d35f3 |
+ giovec_t iov[3];
|
|
|
1d35f3 |
giovec_t auth_iov[2];
|
|
|
1d35f3 |
uint8_t tag[64];
|
|
|
1d35f3 |
size_t tag_size = 0;
|
|
|
1d35f3 |
@@ -60,13 +60,15 @@ static void start(const char *name, int algo)
|
|
|
1d35f3 |
|
|
|
1d35f3 |
memset(iv.data, 0xff, iv.size);
|
|
|
1d35f3 |
memset(key.data, 0xfe, key.size);
|
|
|
1d35f3 |
- memset(data, 0xfa, 128);
|
|
|
1d35f3 |
+ memset(data, 0xfa, sizeof(data));
|
|
|
1d35f3 |
memset(auth, 0xaa, sizeof(auth));
|
|
|
1d35f3 |
|
|
|
1d35f3 |
iov[0].iov_base = data;
|
|
|
1d35f3 |
iov[0].iov_len = 64;
|
|
|
1d35f3 |
iov[1].iov_base = data + 64;
|
|
|
1d35f3 |
- iov[1].iov_len = 64;
|
|
|
1d35f3 |
+ iov[1].iov_len = 56;
|
|
|
1d35f3 |
+ iov[2].iov_base = data + 64 + 56;
|
|
|
1d35f3 |
+ iov[2].iov_len = 36;
|
|
|
1d35f3 |
|
|
|
1d35f3 |
auth_iov[0].iov_base = auth;
|
|
|
1d35f3 |
auth_iov[0].iov_len = 64;
|
|
|
1d35f3 |
@@ -83,7 +85,7 @@ static void start(const char *name, int algo)
|
|
|
1d35f3 |
ret = gnutls_aead_cipher_encryptv2(ch,
|
|
|
1d35f3 |
iv.data, iv.size,
|
|
|
1d35f3 |
auth_iov, 2,
|
|
|
1d35f3 |
- iov, 2,
|
|
|
1d35f3 |
+ iov, 3,
|
|
|
1d35f3 |
tag, &tag_size);
|
|
|
1d35f3 |
if (ret < 0)
|
|
|
1d35f3 |
fail("could not encrypt data: %s\n", gnutls_strerror(ret));
|
|
|
1d35f3 |
@@ -91,7 +93,7 @@ static void start(const char *name, int algo)
|
|
|
1d35f3 |
ret = gnutls_aead_cipher_decryptv2(ch,
|
|
|
1d35f3 |
iv.data, iv.size,
|
|
|
1d35f3 |
auth_iov, 2,
|
|
|
1d35f3 |
- iov, 2,
|
|
|
1d35f3 |
+ iov, 3,
|
|
|
1d35f3 |
tag, tag_size);
|
|
|
1d35f3 |
if (ret < 0)
|
|
|
1d35f3 |
fail("could not decrypt data: %s\n", gnutls_strerror(ret));
|
|
|
1d35f3 |
--
|
|
|
1d35f3 |
2.21.0
|
|
|
1d35f3 |
|