56 lines
2.2 KiB
Diff
56 lines
2.2 KiB
Diff
From: "Daniel P. Berrange" <berrange@redhat.com>
|
|
Date: Tue, 2 May 2017 11:32:43 +0100
|
|
Subject: [PATCH] Fix padding of encrypted data
|
|
|
|
If we are encoding a block of data that is 16 bytes in length,
|
|
we cannot leave it as 16 bytes, we must pad it out to the next
|
|
block boundary, 32 bytes. Without this padding, the decoder will
|
|
incorrectly treat the last byte of plain text as the padding
|
|
length, as it can't distinguish padded from non-padded data.
|
|
|
|
The problem exhibited itself when using a 16 byte passphrase
|
|
for a LUKS volume
|
|
|
|
$ virsh secret-set-value 55806c7d-8e93-456f-829b-607d8c198367 \
|
|
$(echo -n 1234567812345678 | base64)
|
|
Secret value set
|
|
|
|
$ virsh start demo
|
|
error: Failed to start domain demo
|
|
error: internal error: process exited while connecting to monitor: >>>>>>>>>>Len 16
|
|
2017-05-02T10:35:40.016390Z qemu-system-x86_64: -object \
|
|
secret,id=virtio-disk1-luks-secret0,data=SEtNi5vDUeyseMKHwc1c1Q==,\
|
|
keyid=masterKey0,iv=zm7apUB1A6dPcH53VW960Q==,format=base64: \
|
|
Incorrect number of padding bytes (56) found on decrypted data
|
|
|
|
Notice how the padding '56' corresponds to the ordinal value of
|
|
the character '8'.
|
|
|
|
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
|
(cherry picked from commit 71890992daf37ec78b00b4ce873369421dc99731)
|
|
---
|
|
src/util/vircrypto.c | 10 ++++++++--
|
|
1 file changed, 8 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/src/util/vircrypto.c b/src/util/vircrypto.c
|
|
index 03410a1a4..8f1e0b7b7 100644
|
|
--- a/src/util/vircrypto.c
|
|
+++ b/src/util/vircrypto.c
|
|
@@ -152,8 +152,14 @@ virCryptoEncryptDataAESgnutls(gnutls_cipher_algorithm_t gnutls_enc_alg,
|
|
uint8_t *ciphertext;
|
|
size_t ciphertextlen;
|
|
|
|
- /* Allocate a padded buffer, copy in the data */
|
|
- ciphertextlen = VIR_ROUND_UP(datalen, 16);
|
|
+ /* Allocate a padded buffer, copy in the data.
|
|
+ *
|
|
+ * NB, we must *always* have at least 1 byte of
|
|
+ * padding - we can't skip it on multiples of
|
|
+ * 16, otherwise decoder can't distinguish padded
|
|
+ * data from non-padded data. Hence datalen + 1
|
|
+ */
|
|
+ ciphertextlen = VIR_ROUND_UP(datalen + 1, 16);
|
|
if (VIR_ALLOC_N(ciphertext, ciphertextlen) < 0)
|
|
return -1;
|
|
memcpy(ciphertext, data, datalen);
|