summaryrefslogtreecommitdiff
path: root/crypto
diff options
context:
space:
mode:
authorDaniel P. Berrange <berrange@redhat.com>2016-08-24 16:28:15 +0100
committerDaniel P. Berrange <berrange@redhat.com>2016-09-12 12:00:06 +0100
commita5d2f44d0d3e7523670e103a8c37faed29ff2b76 (patch)
tree605c0414b74ebd8bdea7a31fde1da0205a056be0 /crypto
parentc2a57aae9a1c3dd7de77daf5478df10379aeeebf (diff)
downloadqemu-a5d2f44d0d3e7523670e103a8c37faed29ff2b76.tar.gz
crypto: ensure XTS is only used with ciphers with 16 byte blocks
The XTS cipher mode needs to be used with a cipher which has a block size of 16 bytes. If a mis-matching block size is used, the code will either corrupt memory beyond the IV array, or not fully encrypt/decrypt the IV. This fixes a memory corruption crash when attempting to use cast5-128 with xts, since the former has an 8 byte block size. A test case is added to ensure the cipher creation fails with such an invalid combination. Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/cipher-gcrypt.c6
-rw-r--r--crypto/cipher-nettle.c12
2 files changed, 13 insertions, 5 deletions
diff --git a/crypto/cipher-gcrypt.c b/crypto/cipher-gcrypt.c
index ede2f70df8..3652aa1e1b 100644
--- a/crypto/cipher-gcrypt.c
+++ b/crypto/cipher-gcrypt.c
@@ -192,6 +192,12 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
}
if (cipher->mode == QCRYPTO_CIPHER_MODE_XTS) {
+ if (ctx->blocksize != XTS_BLOCK_SIZE) {
+ error_setg(errp,
+ "Cipher block size %zu must equal XTS block size %d",
+ ctx->blocksize, XTS_BLOCK_SIZE);
+ goto error;
+ }
ctx->iv = g_new0(uint8_t, ctx->blocksize);
}
diff --git a/crypto/cipher-nettle.c b/crypto/cipher-nettle.c
index 70909fb7fe..0267da5ba6 100644
--- a/crypto/cipher-nettle.c
+++ b/crypto/cipher-nettle.c
@@ -361,6 +361,13 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
goto error;
}
+ if (mode == QCRYPTO_CIPHER_MODE_XTS &&
+ ctx->blocksize != XTS_BLOCK_SIZE) {
+ error_setg(errp, "Cipher block size %zu must equal XTS block size %d",
+ ctx->blocksize, XTS_BLOCK_SIZE);
+ goto error;
+ }
+
ctx->iv = g_new0(uint8_t, ctx->blocksize);
cipher->opaque = ctx;
@@ -456,11 +463,6 @@ int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
break;
case QCRYPTO_CIPHER_MODE_XTS:
- if (ctx->blocksize != XTS_BLOCK_SIZE) {
- error_setg(errp, "Block size must be %d not %zu",
- XTS_BLOCK_SIZE, ctx->blocksize);
- return -1;
- }
xts_decrypt(ctx->ctx, ctx->ctx_tweak,
ctx->alg_encrypt_wrapper, ctx->alg_decrypt_wrapper,
ctx->iv, len, out, in);