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:
parent
ea7a6802c7
commit
7b40aa4b96
|
@ -18,10 +18,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_QEMU_PRIVATE_XTS
|
|
||||||
#include "crypto/xts.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <gcrypt.h>
|
#include <gcrypt.h>
|
||||||
|
|
||||||
bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
|
bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
|
||||||
|
@ -59,10 +55,6 @@ typedef struct QCryptoCipherGcrypt {
|
||||||
QCryptoCipher base;
|
QCryptoCipher base;
|
||||||
gcry_cipher_hd_t handle;
|
gcry_cipher_hd_t handle;
|
||||||
size_t blocksize;
|
size_t blocksize;
|
||||||
#ifdef CONFIG_QEMU_PRIVATE_XTS
|
|
||||||
gcry_cipher_hd_t tweakhandle;
|
|
||||||
uint8_t iv[XTS_BLOCK_SIZE];
|
|
||||||
#endif
|
|
||||||
} QCryptoCipherGcrypt;
|
} QCryptoCipherGcrypt;
|
||||||
|
|
||||||
|
|
||||||
|
@ -178,90 +170,6 @@ static const struct QCryptoCipherDriver qcrypto_gcrypt_ctr_driver = {
|
||||||
.cipher_free = qcrypto_gcrypt_ctx_free,
|
.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,
|
static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
|
||||||
QCryptoCipherMode mode,
|
QCryptoCipherMode mode,
|
||||||
const uint8_t *key,
|
const uint8_t *key,
|
||||||
|
@ -323,12 +231,7 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
|
||||||
gcrymode = GCRY_CIPHER_MODE_ECB;
|
gcrymode = GCRY_CIPHER_MODE_ECB;
|
||||||
break;
|
break;
|
||||||
case QCRYPTO_CIPHER_MODE_XTS:
|
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;
|
gcrymode = GCRY_CIPHER_MODE_XTS;
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
case QCRYPTO_CIPHER_MODE_CBC:
|
case QCRYPTO_CIPHER_MODE_CBC:
|
||||||
gcrymode = GCRY_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);
|
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) {
|
if (alg == QCRYPTO_CIPHER_ALG_DES_RFB) {
|
||||||
/* We're using standard DES cipher from gcrypt, so we need
|
/* We're using standard DES cipher from gcrypt, so we need
|
||||||
* to munge the key so that the results are the same as the
|
* 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);
|
err = gcry_cipher_setkey(ctx->handle, rfbkey, nkey);
|
||||||
g_free(rfbkey);
|
g_free(rfbkey);
|
||||||
} else {
|
} 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);
|
err = gcry_cipher_setkey(ctx->handle, key, nkey);
|
||||||
}
|
}
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
|
@ -400,9 +276,6 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
|
||||||
return &ctx->base;
|
return &ctx->base;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
#ifdef CONFIG_QEMU_PRIVATE_XTS
|
|
||||||
gcry_cipher_close(ctx->tweakhandle);
|
|
||||||
#endif
|
|
||||||
gcry_cipher_close(ctx->handle);
|
gcry_cipher_close(ctx->handle);
|
||||||
g_free(ctx);
|
g_free(ctx);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
14
meson.build
14
meson.build
|
@ -843,16 +843,7 @@ if (not get_option('gcrypt').auto() or have_system) and not nettle.found()
|
||||||
method: 'config-tool',
|
method: 'config-tool',
|
||||||
required: get_option('gcrypt'),
|
required: get_option('gcrypt'),
|
||||||
kwargs: static_kwargs)
|
kwargs: static_kwargs)
|
||||||
if gcrypt.found() and cc.compiles('''
|
xts = 'gcrypt'
|
||||||
#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
|
|
||||||
# Debian has removed -lgpg-error from libgcrypt-config
|
# Debian has removed -lgpg-error from libgcrypt-config
|
||||||
# as it "spreads unnecessary dependencies" which in
|
# as it "spreads unnecessary dependencies" which in
|
||||||
# turn breaks static builds...
|
# turn breaks static builds...
|
||||||
|
@ -2970,9 +2961,6 @@ summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
|
||||||
summary_info += {'GNUTLS support': gnutls.found()}
|
summary_info += {'GNUTLS support': gnutls.found()}
|
||||||
# TODO: add back version
|
# TODO: add back version
|
||||||
summary_info += {'libgcrypt': gcrypt.found()}
|
summary_info += {'libgcrypt': gcrypt.found()}
|
||||||
if gcrypt.found()
|
|
||||||
summary_info += {' XTS': xts != 'private'}
|
|
||||||
endif
|
|
||||||
# TODO: add back version
|
# TODO: add back version
|
||||||
summary_info += {'nettle': nettle.found()}
|
summary_info += {'nettle': nettle.found()}
|
||||||
if nettle.found()
|
if nettle.found()
|
||||||
|
|
Loading…
Reference in New Issue