summaryrefslogtreecommitdiff
path: root/crypto/cipher-gcrypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/cipher-gcrypt.c')
-rw-r--r--crypto/cipher-gcrypt.c97
1 files changed, 64 insertions, 33 deletions
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;
}
}