diff options
-rwxr-xr-x | configure | 22 | ||||
-rw-r--r-- | crypto/Makefile.objs | 2 | ||||
-rw-r--r-- | crypto/cipher-gcrypt.c | 97 | ||||
-rw-r--r-- | tests/Makefile.include | 2 |
4 files changed, 88 insertions, 35 deletions
@@ -474,6 +474,8 @@ gnutls="" nettle="" gcrypt="" gcrypt_hmac="no" +gcrypt_xts="no" +qemu_private_xts="yes" auth_pam="" vte="" virglrenderer="" @@ -2911,6 +2913,18 @@ EOF if compile_prog "$gcrypt_cflags" "$gcrypt_libs" ; then gcrypt_hmac=yes fi + cat > $TMPC << EOF +#include <gcrypt.h> +int main(void) { + gcry_cipher_hd_t handle; + gcry_cipher_open(&handle, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_XTS, 0); + return 0; +} +EOF + if compile_prog "$gcrypt_cflags" "$gcrypt_libs" ; then + gcrypt_xts=yes + qemu_private_xts=no + fi elif test "$gcrypt" = "yes"; then feature_not_found "gcrypt" "Install gcrypt devel >= 1.5.0" else @@ -6326,6 +6340,11 @@ echo "VTE support $vte $(echo_version $vte $vteversion)" echo "TLS priority $tls_priority" echo "GNUTLS support $gnutls" echo "libgcrypt $gcrypt" +if test "$gcrypt" = "yes" +then + echo " hmac $gcrypt_hmac" + echo " XTS $gcrypt_xts" +fi echo "nettle $nettle $(echo_version $nettle $nettle_version)" echo "libtasn1 $tasn1" echo "PAM $auth_pam" @@ -6804,6 +6823,9 @@ if test "$nettle" = "yes" ; then echo "CONFIG_NETTLE=y" >> $config_host_mak echo "CONFIG_NETTLE_VERSION_MAJOR=${nettle_version%%.*}" >> $config_host_mak fi +if test "$qemu_private_xts" = "yes" ; then + echo "CONFIG_QEMU_PRIVATE_XTS=y" >> $config_host_mak +fi if test "$tasn1" = "yes" ; then echo "CONFIG_TASN1=y" >> $config_host_mak fi diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs index 7fe2fa9da2..cdb01f9de9 100644 --- a/crypto/Makefile.objs +++ b/crypto/Makefile.objs @@ -31,7 +31,7 @@ crypto-obj-y += ivgen-essiv.o crypto-obj-y += ivgen-plain.o crypto-obj-y += ivgen-plain64.o crypto-obj-y += afsplit.o -crypto-obj-y += xts.o +crypto-obj-$(CONFIG_QEMU_PRIVATE_XTS) += xts.o crypto-obj-y += block.o crypto-obj-y += block-qcow.o crypto-obj-y += block-luks.o diff --git a/crypto/cipher-gcrypt.c b/crypto/cipher-gcrypt.c index 5cece9b244..2864099527 100644 --- a/crypto/cipher-gcrypt.c +++ b/crypto/cipher-gcrypt.c @@ -19,7 +19,9 @@ */ #include "qemu/osdep.h" +#ifdef CONFIG_QEMU_PRIVATE_XTS #include "crypto/xts.h" +#endif #include "cipherpriv.h" #include <gcrypt.h> @@ -59,10 +61,12 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg, typedef struct QCryptoCipherGcrypt QCryptoCipherGcrypt; struct QCryptoCipherGcrypt { gcry_cipher_hd_t handle; - gcry_cipher_hd_t tweakhandle; size_t blocksize; +#ifdef CONFIG_QEMU_PRIVATE_XTS + gcry_cipher_hd_t tweakhandle; /* Initialization vector or Counter */ uint8_t *iv; +#endif }; static void @@ -74,10 +78,12 @@ qcrypto_gcrypt_cipher_free_ctx(QCryptoCipherGcrypt *ctx, } gcry_cipher_close(ctx->handle); +#ifdef CONFIG_QEMU_PRIVATE_XTS if (mode == QCRYPTO_CIPHER_MODE_XTS) { gcry_cipher_close(ctx->tweakhandle); } g_free(ctx->iv); +#endif g_free(ctx); } @@ -94,8 +100,14 @@ static QCryptoCipherGcrypt *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, switch (mode) { case QCRYPTO_CIPHER_MODE_ECB: + gcrymode = GCRY_CIPHER_MODE_ECB; + break; case QCRYPTO_CIPHER_MODE_XTS: +#ifdef CONFIG_QEMU_PRIVATE_XTS gcrymode = GCRY_CIPHER_MODE_ECB; +#else + gcrymode = GCRY_CIPHER_MODE_XTS; +#endif break; case QCRYPTO_CIPHER_MODE_CBC: gcrymode = GCRY_CIPHER_MODE_CBC; @@ -172,6 +184,7 @@ static QCryptoCipherGcrypt *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, gcry_strerror(err)); goto error; } +#ifdef CONFIG_QEMU_PRIVATE_XTS if (mode == QCRYPTO_CIPHER_MODE_XTS) { err = gcry_cipher_open(&ctx->tweakhandle, gcryalg, gcrymode, 0); if (err != 0) { @@ -180,6 +193,7 @@ static QCryptoCipherGcrypt *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, goto error; } } +#endif if (alg == QCRYPTO_CIPHER_ALG_DES_RFB) { /* We're using standard DES cipher from gcrypt, so we need @@ -191,6 +205,7 @@ static QCryptoCipherGcrypt *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, g_free(rfbkey); ctx->blocksize = 8; } else { +#ifdef CONFIG_QEMU_PRIVATE_XTS if (mode == QCRYPTO_CIPHER_MODE_XTS) { nkey /= 2; err = gcry_cipher_setkey(ctx->handle, key, nkey); @@ -201,8 +216,11 @@ static QCryptoCipherGcrypt *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, } err = gcry_cipher_setkey(ctx->tweakhandle, key + nkey, nkey); } else { +#endif err = gcry_cipher_setkey(ctx->handle, key, nkey); +#ifdef CONFIG_QEMU_PRIVATE_XTS } +#endif if (err != 0) { error_setg(errp, "Cannot set key: %s", gcry_strerror(err)); @@ -228,6 +246,7 @@ static QCryptoCipherGcrypt *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, } } +#ifdef CONFIG_QEMU_PRIVATE_XTS if (mode == QCRYPTO_CIPHER_MODE_XTS) { if (ctx->blocksize != XTS_BLOCK_SIZE) { error_setg(errp, @@ -237,6 +256,7 @@ static QCryptoCipherGcrypt *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, } ctx->iv = g_new0(uint8_t, ctx->blocksize); } +#endif return ctx; @@ -253,6 +273,7 @@ qcrypto_gcrypt_cipher_ctx_free(QCryptoCipher *cipher) } +#ifdef CONFIG_QEMU_PRIVATE_XTS static void qcrypto_gcrypt_xts_encrypt(const void *ctx, size_t length, uint8_t *dst, @@ -272,6 +293,7 @@ static void qcrypto_gcrypt_xts_decrypt(const void *ctx, err = gcry_cipher_decrypt((gcry_cipher_hd_t)ctx, dst, length, src, length); g_assert(err == 0); } +#endif static int qcrypto_gcrypt_cipher_encrypt(QCryptoCipher *cipher, @@ -289,20 +311,23 @@ qcrypto_gcrypt_cipher_encrypt(QCryptoCipher *cipher, return -1; } +#ifdef CONFIG_QEMU_PRIVATE_XTS if (cipher->mode == QCRYPTO_CIPHER_MODE_XTS) { xts_encrypt(ctx->handle, ctx->tweakhandle, qcrypto_gcrypt_xts_encrypt, qcrypto_gcrypt_xts_decrypt, ctx->iv, len, out, in); - } else { - err = gcry_cipher_encrypt(ctx->handle, - out, len, - in, len); - if (err != 0) { - error_setg(errp, "Cannot encrypt data: %s", - gcry_strerror(err)); - return -1; - } + return 0; + } +#endif + + err = gcry_cipher_encrypt(ctx->handle, + out, len, + in, len); + if (err != 0) { + error_setg(errp, "Cannot encrypt data: %s", + gcry_strerror(err)); + return -1; } return 0; @@ -325,20 +350,23 @@ qcrypto_gcrypt_cipher_decrypt(QCryptoCipher *cipher, return -1; } +#ifdef CONFIG_QEMU_PRIVATE_XTS if (cipher->mode == QCRYPTO_CIPHER_MODE_XTS) { xts_decrypt(ctx->handle, ctx->tweakhandle, qcrypto_gcrypt_xts_encrypt, qcrypto_gcrypt_xts_decrypt, ctx->iv, len, out, in); - } else { - err = gcry_cipher_decrypt(ctx->handle, - out, len, - in, len); - if (err != 0) { - error_setg(errp, "Cannot decrypt data: %s", - gcry_strerror(err)); - return -1; - } + return 0; + } +#endif + + err = gcry_cipher_decrypt(ctx->handle, + out, len, + in, len); + if (err != 0) { + error_setg(errp, "Cannot decrypt data: %s", + gcry_strerror(err)); + return -1; } return 0; @@ -358,24 +386,27 @@ qcrypto_gcrypt_cipher_setiv(QCryptoCipher *cipher, return -1; } +#ifdef CONFIG_QEMU_PRIVATE_XTS if (ctx->iv) { memcpy(ctx->iv, iv, niv); - } else { - if (cipher->mode == QCRYPTO_CIPHER_MODE_CTR) { - err = gcry_cipher_setctr(ctx->handle, iv, niv); - if (err != 0) { - error_setg(errp, "Cannot set Counter: %s", + return 0; + } +#endif + + if (cipher->mode == QCRYPTO_CIPHER_MODE_CTR) { + err = gcry_cipher_setctr(ctx->handle, iv, niv); + if (err != 0) { + error_setg(errp, "Cannot set Counter: %s", gcry_strerror(err)); - return -1; - } - } else { - gcry_cipher_reset(ctx->handle); - err = gcry_cipher_setiv(ctx->handle, iv, niv); - if (err != 0) { - error_setg(errp, "Cannot set IV: %s", + return -1; + } + } else { + gcry_cipher_reset(ctx->handle); + err = gcry_cipher_setiv(ctx->handle, iv, niv); + if (err != 0) { + error_setg(errp, "Cannot set IV: %s", gcry_strerror(err)); - return -1; - } + return -1; } } diff --git a/tests/Makefile.include b/tests/Makefile.include index 09e5b410dc..4efdd0cd6e 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -140,7 +140,7 @@ check-unit-y += tests/test-base64$(EXESUF) check-unit-$(call land,$(CONFIG_BLOCK),$(if $(CONFIG_NETTLE),y,$(CONFIG_GCRYPT))) += tests/test-crypto-pbkdf$(EXESUF) check-unit-$(CONFIG_BLOCK) += tests/test-crypto-ivgen$(EXESUF) check-unit-$(CONFIG_BLOCK) += tests/test-crypto-afsplit$(EXESUF) -check-unit-$(CONFIG_BLOCK) += tests/test-crypto-xts$(EXESUF) +check-unit-$(if $(CONFIG_BLOCK),$(CONFIG_QEMU_PRIVATE_XTS)) += tests/test-crypto-xts$(EXESUF) check-unit-$(CONFIG_BLOCK) += tests/test-crypto-block$(EXESUF) check-unit-y += tests/test-logging$(EXESUF) check-unit-$(call land,$(CONFIG_BLOCK),$(CONFIG_REPLICATION)) += tests/test-replication$(EXESUF) |