crypto: drop custom XTS support in gcrypt driver

The XTS cipher mode was introduced in gcrypt 1.8.0, which
matches QEMU's current minimum version.

Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrangé 2021-06-29 17:11:59 +01:00
parent ea7a6802c7
commit 7b40aa4b96
2 changed files with 1 additions and 140 deletions

View File

@ -18,10 +18,6 @@
*
*/
#ifdef CONFIG_QEMU_PRIVATE_XTS
#include "crypto/xts.h"
#endif
#include <gcrypt.h>
bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
@ -59,10 +55,6 @@ typedef struct QCryptoCipherGcrypt {
QCryptoCipher base;
gcry_cipher_hd_t handle;
size_t blocksize;
#ifdef CONFIG_QEMU_PRIVATE_XTS
gcry_cipher_hd_t tweakhandle;
uint8_t iv[XTS_BLOCK_SIZE];
#endif
} QCryptoCipherGcrypt;
@ -178,90 +170,6 @@ static const struct QCryptoCipherDriver qcrypto_gcrypt_ctr_driver = {
.cipher_free = qcrypto_gcrypt_ctx_free,
};
#ifdef CONFIG_QEMU_PRIVATE_XTS
static void qcrypto_gcrypt_xts_ctx_free(QCryptoCipher *cipher)
{
QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
gcry_cipher_close(ctx->tweakhandle);
qcrypto_gcrypt_ctx_free(cipher);
}
static void qcrypto_gcrypt_xts_wrape(const void *ctx, size_t length,
uint8_t *dst, const uint8_t *src)
{
gcry_error_t err;
err = gcry_cipher_encrypt((gcry_cipher_hd_t)ctx, dst, length, src, length);
g_assert(err == 0);
}
static void qcrypto_gcrypt_xts_wrapd(const void *ctx, size_t length,
uint8_t *dst, const uint8_t *src)
{
gcry_error_t err;
err = gcry_cipher_decrypt((gcry_cipher_hd_t)ctx, dst, length, src, length);
g_assert(err == 0);
}
static int qcrypto_gcrypt_xts_encrypt(QCryptoCipher *cipher, const void *in,
void *out, size_t len, Error **errp)
{
QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
if (len & (ctx->blocksize - 1)) {
error_setg(errp, "Length %zu must be a multiple of block size %zu",
len, ctx->blocksize);
return -1;
}
xts_encrypt(ctx->handle, ctx->tweakhandle,
qcrypto_gcrypt_xts_wrape, qcrypto_gcrypt_xts_wrapd,
ctx->iv, len, out, in);
return 0;
}
static int qcrypto_gcrypt_xts_decrypt(QCryptoCipher *cipher, const void *in,
void *out, size_t len, Error **errp)
{
QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
if (len & (ctx->blocksize - 1)) {
error_setg(errp, "Length %zu must be a multiple of block size %zu",
len, ctx->blocksize);
return -1;
}
xts_decrypt(ctx->handle, ctx->tweakhandle,
qcrypto_gcrypt_xts_wrape, qcrypto_gcrypt_xts_wrapd,
ctx->iv, len, out, in);
return 0;
}
static int qcrypto_gcrypt_xts_setiv(QCryptoCipher *cipher,
const uint8_t *iv, size_t niv,
Error **errp)
{
QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
if (niv != ctx->blocksize) {
error_setg(errp, "Expected IV size %zu not %zu",
ctx->blocksize, niv);
return -1;
}
memcpy(ctx->iv, iv, niv);
return 0;
}
static const struct QCryptoCipherDriver qcrypto_gcrypt_xts_driver = {
.cipher_encrypt = qcrypto_gcrypt_xts_encrypt,
.cipher_decrypt = qcrypto_gcrypt_xts_decrypt,
.cipher_setiv = qcrypto_gcrypt_xts_setiv,
.cipher_free = qcrypto_gcrypt_xts_ctx_free,
};
#endif /* CONFIG_QEMU_PRIVATE_XTS */
static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode,
const uint8_t *key,
@ -323,12 +231,7 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
gcrymode = GCRY_CIPHER_MODE_ECB;
break;
case QCRYPTO_CIPHER_MODE_XTS:
#ifdef CONFIG_QEMU_PRIVATE_XTS
drv = &qcrypto_gcrypt_xts_driver;
gcrymode = GCRY_CIPHER_MODE_ECB;
#else
gcrymode = GCRY_CIPHER_MODE_XTS;
#endif
break;
case QCRYPTO_CIPHER_MODE_CBC:
gcrymode = GCRY_CIPHER_MODE_CBC;
@ -354,23 +257,6 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
}
ctx->blocksize = gcry_cipher_get_algo_blklen(gcryalg);
#ifdef CONFIG_QEMU_PRIVATE_XTS
if (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;
}
err = gcry_cipher_open(&ctx->tweakhandle, gcryalg, gcrymode, 0);
if (err != 0) {
error_setg(errp, "Cannot initialize cipher: %s",
gcry_strerror(err));
goto error;
}
}
#endif
if (alg == QCRYPTO_CIPHER_ALG_DES_RFB) {
/* We're using standard DES cipher from gcrypt, so we need
* to munge the key so that the results are the same as the
@ -380,16 +266,6 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
err = gcry_cipher_setkey(ctx->handle, rfbkey, nkey);
g_free(rfbkey);
} else {
#ifdef CONFIG_QEMU_PRIVATE_XTS
if (mode == QCRYPTO_CIPHER_MODE_XTS) {
nkey /= 2;
err = gcry_cipher_setkey(ctx->tweakhandle, key + nkey, nkey);
if (err != 0) {
error_setg(errp, "Cannot set key: %s", gcry_strerror(err));
goto error;
}
}
#endif
err = gcry_cipher_setkey(ctx->handle, key, nkey);
}
if (err != 0) {
@ -400,9 +276,6 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
return &ctx->base;
error:
#ifdef CONFIG_QEMU_PRIVATE_XTS
gcry_cipher_close(ctx->tweakhandle);
#endif
gcry_cipher_close(ctx->handle);
g_free(ctx);
return NULL;

View File

@ -843,16 +843,7 @@ if (not get_option('gcrypt').auto() or have_system) and not nettle.found()
method: 'config-tool',
required: get_option('gcrypt'),
kwargs: static_kwargs)
if gcrypt.found() and cc.compiles('''
#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;
}
''', dependencies: gcrypt)
xts = 'gcrypt'
endif
xts = 'gcrypt'
# Debian has removed -lgpg-error from libgcrypt-config
# as it "spreads unnecessary dependencies" which in
# turn breaks static builds...
@ -2970,9 +2961,6 @@ summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
summary_info += {'GNUTLS support': gnutls.found()}
# TODO: add back version
summary_info += {'libgcrypt': gcrypt.found()}
if gcrypt.found()
summary_info += {' XTS': xts != 'private'}
endif
# TODO: add back version
summary_info += {'nettle': nettle.found()}
if nettle.found()