* [PULL 01/17] tests: fix output message formatting for crypto benchmarks
2020-09-10 10:06 [PULL 00/17] Crypto next patches Daniel P. Berrangé
@ 2020-09-10 10:06 ` Daniel P. Berrangé
2020-09-10 10:06 ` [PULL 02/17] crypto: Assume blocksize is a power of 2 Daniel P. Berrangé
` (16 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Daniel P. Berrangé @ 2020-09-10 10:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Daniel P. Berrangé
The output was changed from g_print to g_test_message in
commit 24441f912e67233d9c52ce6b459ed75de2484525
Author: Marc-André Lureau <marcandre.lureau@redhat.com>
Date: Fri Aug 28 15:07:30 2020 +0400
tests: do not print benchmark output to stdout
As this makes the TAP output invalid. Use g_test_message().
The functions do not result in equivalent output. The g_print
statements were putting all the information on a single line
for ease of interpretation. The change to g_test_message split
the output across many lines making it painful to read.
The opportunity is used to tweak the information printed to be
more consistent across tests.
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
tests/benchmark-crypto-cipher.c | 12 ++++++++----
tests/benchmark-crypto-hash.c | 4 +++-
tests/benchmark-crypto-hmac.c | 7 +++----
3 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/tests/benchmark-crypto-cipher.c b/tests/benchmark-crypto-cipher.c
index 1936aa4ae0..c04f0a0fba 100644
--- a/tests/benchmark-crypto-cipher.c
+++ b/tests/benchmark-crypto-cipher.c
@@ -70,8 +70,10 @@ static void test_cipher_speed(size_t chunk_size,
}
g_test_timer_elapsed();
- g_test_message("Enc chunk %zu bytes ", chunk_size);
- g_test_message("%.2f MB/sec ", (double)total / MiB / g_test_timer_last());
+ g_test_message("enc(%s-%s) chunk %zu bytes %.2f MB/sec ",
+ QCryptoCipherAlgorithm_str(alg),
+ QCryptoCipherMode_str(mode),
+ chunk_size, (double)total / MiB / g_test_timer_last());
g_test_timer_start();
remain = total;
@@ -85,8 +87,10 @@ static void test_cipher_speed(size_t chunk_size,
}
g_test_timer_elapsed();
- g_test_message("Dec chunk %zu bytes ", chunk_size);
- g_test_message("%.2f MB/sec ", (double)total / MiB / g_test_timer_last());
+ g_test_message("dec(%s-%s) chunk %zu bytes %.2f MB/sec ",
+ QCryptoCipherAlgorithm_str(alg),
+ QCryptoCipherMode_str(mode),
+ chunk_size, (double)total / MiB / g_test_timer_last());
qcrypto_cipher_free(cipher);
g_free(plaintext);
diff --git a/tests/benchmark-crypto-hash.c b/tests/benchmark-crypto-hash.c
index 598111e75a..927b00bb4d 100644
--- a/tests/benchmark-crypto-hash.c
+++ b/tests/benchmark-crypto-hash.c
@@ -48,7 +48,9 @@ static void test_hash_speed(const void *opaque)
}
g_test_timer_elapsed();
- g_test_message("%.2f MB/sec ", (double)total / MiB / g_test_timer_last());
+ g_test_message("hash(%s): chunk %zu bytes %.2f MB/sec",
+ QCryptoHashAlgorithm_str(opts->alg),
+ opts->chunk_size, total / g_test_timer_last());
g_free(out);
g_free(in);
diff --git a/tests/benchmark-crypto-hmac.c b/tests/benchmark-crypto-hmac.c
index f9fa22df95..5cca636789 100644
--- a/tests/benchmark-crypto-hmac.c
+++ b/tests/benchmark-crypto-hmac.c
@@ -55,10 +55,9 @@ static void test_hmac_speed(const void *opaque)
} while (g_test_timer_elapsed() < 5.0);
total /= MiB;
- g_test_message("hmac(sha256): ");
- g_test_message("Testing chunk_size %zu bytes ", chunk_size);
- g_test_message("done: %.2f MB in %.2f secs: ", total, g_test_timer_last());
- g_test_message("%.2f MB/sec\n", total / g_test_timer_last());
+ g_test_message("hmac(%s): chunk %zu bytes %.2f MB/sec",
+ QCryptoHashAlgorithm_str(QCRYPTO_HASH_ALG_SHA256),
+ chunk_size, total / g_test_timer_last());
g_free(out);
g_free(in);
--
2.26.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PULL 02/17] crypto: Assume blocksize is a power of 2
2020-09-10 10:06 [PULL 00/17] Crypto next patches Daniel P. Berrangé
2020-09-10 10:06 ` [PULL 01/17] tests: fix output message formatting for crypto benchmarks Daniel P. Berrangé
@ 2020-09-10 10:06 ` Daniel P. Berrangé
2020-09-10 10:06 ` [PULL 03/17] crypto: Rename cipher include files to .c.inc Daniel P. Berrangé
` (15 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Daniel P. Berrangé @ 2020-09-10 10:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson, Daniel P. Berrangé
From: Richard Henderson <richard.henderson@linaro.org>
The check in the encode/decode path using full division has a
noticeable amount of overhead. By asserting the blocksize is
a power of 2, we can reduce this check to a mask.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
crypto/cipher-builtin.c | 4 ++--
crypto/cipher-gcrypt.c | 5 +++--
crypto/cipher-nettle.c | 5 +++--
crypto/cipher.c | 1 +
4 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/crypto/cipher-builtin.c b/crypto/cipher-builtin.c
index 35cf7820d9..6eafd39da0 100644
--- a/crypto/cipher-builtin.c
+++ b/crypto/cipher-builtin.c
@@ -484,7 +484,7 @@ qcrypto_builtin_cipher_encrypt(QCryptoCipher *cipher,
{
QCryptoCipherBuiltin *ctxt = cipher->opaque;
- if (len % ctxt->blocksize) {
+ if (len & (ctxt->blocksize - 1)) {
error_setg(errp, "Length %zu must be a multiple of block size %zu",
len, ctxt->blocksize);
return -1;
@@ -503,7 +503,7 @@ qcrypto_builtin_cipher_decrypt(QCryptoCipher *cipher,
{
QCryptoCipherBuiltin *ctxt = cipher->opaque;
- if (len % ctxt->blocksize) {
+ if (len & (ctxt->blocksize - 1)) {
error_setg(errp, "Length %zu must be a multiple of block size %zu",
len, ctxt->blocksize);
return -1;
diff --git a/crypto/cipher-gcrypt.c b/crypto/cipher-gcrypt.c
index 2864099527..81e4745bff 100644
--- a/crypto/cipher-gcrypt.c
+++ b/crypto/cipher-gcrypt.c
@@ -245,6 +245,7 @@ static QCryptoCipherGcrypt *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
g_assert_not_reached();
}
}
+ g_assert(is_power_of_2(ctx->blocksize));
#ifdef CONFIG_QEMU_PRIVATE_XTS
if (mode == QCRYPTO_CIPHER_MODE_XTS) {
@@ -305,7 +306,7 @@ qcrypto_gcrypt_cipher_encrypt(QCryptoCipher *cipher,
QCryptoCipherGcrypt *ctx = cipher->opaque;
gcry_error_t err;
- if (len % ctx->blocksize) {
+ if (len & (ctx->blocksize - 1)) {
error_setg(errp, "Length %zu must be a multiple of block size %zu",
len, ctx->blocksize);
return -1;
@@ -344,7 +345,7 @@ qcrypto_gcrypt_cipher_decrypt(QCryptoCipher *cipher,
QCryptoCipherGcrypt *ctx = cipher->opaque;
gcry_error_t err;
- if (len % ctx->blocksize) {
+ if (len & (ctx->blocksize - 1)) {
error_setg(errp, "Length %zu must be a multiple of block size %zu",
len, ctx->blocksize);
return -1;
diff --git a/crypto/cipher-nettle.c b/crypto/cipher-nettle.c
index 7e9a4cc199..0677fdfd33 100644
--- a/crypto/cipher-nettle.c
+++ b/crypto/cipher-nettle.c
@@ -576,6 +576,7 @@ static QCryptoCipherNettle *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
QCryptoCipherAlgorithm_str(alg));
goto error;
}
+ g_assert(is_power_of_2(ctx->blocksize));
if (mode == QCRYPTO_CIPHER_MODE_XTS &&
ctx->blocksize != XTS_BLOCK_SIZE) {
@@ -613,7 +614,7 @@ qcrypto_nettle_cipher_encrypt(QCryptoCipher *cipher,
{
QCryptoCipherNettle *ctx = cipher->opaque;
- if (len % ctx->blocksize) {
+ if (len & (ctx->blocksize - 1)) {
error_setg(errp, "Length %zu must be a multiple of block size %zu",
len, ctx->blocksize);
return -1;
@@ -666,7 +667,7 @@ qcrypto_nettle_cipher_decrypt(QCryptoCipher *cipher,
{
QCryptoCipherNettle *ctx = cipher->opaque;
- if (len % ctx->blocksize) {
+ if (len & (ctx->blocksize - 1)) {
error_setg(errp, "Length %zu must be a multiple of block size %zu",
len, ctx->blocksize);
return -1;
diff --git a/crypto/cipher.c b/crypto/cipher.c
index e5adb56271..2722dc7d87 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -19,6 +19,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/host-utils.h"
#include "qapi/error.h"
#include "crypto/cipher.h"
#include "cipherpriv.h"
--
2.26.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PULL 03/17] crypto: Rename cipher include files to .c.inc
2020-09-10 10:06 [PULL 00/17] Crypto next patches Daniel P. Berrangé
2020-09-10 10:06 ` [PULL 01/17] tests: fix output message formatting for crypto benchmarks Daniel P. Berrangé
2020-09-10 10:06 ` [PULL 02/17] crypto: Assume blocksize is a power of 2 Daniel P. Berrangé
@ 2020-09-10 10:06 ` Daniel P. Berrangé
2020-09-10 10:06 ` [PULL 04/17] crypto: Remove redundant includes Daniel P. Berrangé
` (14 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Daniel P. Berrangé @ 2020-09-10 10:06 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Daniel P. Berrangé, Philippe Mathieu-Daudé
From: Richard Henderson <richard.henderson@linaro.org>
QEMU standard procedure for included c files is to use *.c.inc.
E.g. there are a different set of checks that are applied.
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
crypto/{cipher-builtin.c => cipher-builtin.c.inc} | 0
crypto/{cipher-gcrypt.c => cipher-gcrypt.c.inc} | 0
crypto/{cipher-nettle.c => cipher-nettle.c.inc} | 0
crypto/cipher.c | 6 +++---
4 files changed, 3 insertions(+), 3 deletions(-)
rename crypto/{cipher-builtin.c => cipher-builtin.c.inc} (100%)
rename crypto/{cipher-gcrypt.c => cipher-gcrypt.c.inc} (100%)
rename crypto/{cipher-nettle.c => cipher-nettle.c.inc} (100%)
diff --git a/crypto/cipher-builtin.c b/crypto/cipher-builtin.c.inc
similarity index 100%
rename from crypto/cipher-builtin.c
rename to crypto/cipher-builtin.c.inc
diff --git a/crypto/cipher-gcrypt.c b/crypto/cipher-gcrypt.c.inc
similarity index 100%
rename from crypto/cipher-gcrypt.c
rename to crypto/cipher-gcrypt.c.inc
diff --git a/crypto/cipher-nettle.c b/crypto/cipher-nettle.c.inc
similarity index 100%
rename from crypto/cipher-nettle.c
rename to crypto/cipher-nettle.c.inc
diff --git a/crypto/cipher.c b/crypto/cipher.c
index 2722dc7d87..005b5da4de 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -151,11 +151,11 @@ qcrypto_cipher_munge_des_rfb_key(const uint8_t *key,
#endif /* CONFIG_GCRYPT || CONFIG_NETTLE */
#ifdef CONFIG_GCRYPT
-#include "cipher-gcrypt.c"
+#include "cipher-gcrypt.c.inc"
#elif defined CONFIG_NETTLE
-#include "cipher-nettle.c"
+#include "cipher-nettle.c.inc"
#else
-#include "cipher-builtin.c"
+#include "cipher-builtin.c.inc"
#endif
QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
--
2.26.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PULL 04/17] crypto: Remove redundant includes
2020-09-10 10:06 [PULL 00/17] Crypto next patches Daniel P. Berrangé
` (2 preceding siblings ...)
2020-09-10 10:06 ` [PULL 03/17] crypto: Rename cipher include files to .c.inc Daniel P. Berrangé
@ 2020-09-10 10:06 ` Daniel P. Berrangé
2020-09-10 10:06 ` [PULL 05/17] crypto/nettle: Fix xts_encrypt arguments Daniel P. Berrangé
` (13 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Daniel P. Berrangé @ 2020-09-10 10:06 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Daniel P. Berrangé, Philippe Mathieu-Daudé
From: Richard Henderson <richard.henderson@linaro.org>
Both qemu/osdep.h and cipherpriv.h have already been
included by the parent cipher.c.
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
crypto/cipher-builtin.c.inc | 2 --
crypto/cipher-gcrypt.c.inc | 2 --
crypto/cipher-nettle.c.inc | 2 --
3 files changed, 6 deletions(-)
diff --git a/crypto/cipher-builtin.c.inc b/crypto/cipher-builtin.c.inc
index 6eafd39da0..56d45b0227 100644
--- a/crypto/cipher-builtin.c.inc
+++ b/crypto/cipher-builtin.c.inc
@@ -18,11 +18,9 @@
*
*/
-#include "qemu/osdep.h"
#include "crypto/aes.h"
#include "crypto/desrfb.h"
#include "crypto/xts.h"
-#include "cipherpriv.h"
typedef struct QCryptoCipherBuiltinAESContext QCryptoCipherBuiltinAESContext;
struct QCryptoCipherBuiltinAESContext {
diff --git a/crypto/cipher-gcrypt.c.inc b/crypto/cipher-gcrypt.c.inc
index 81e4745bff..a62839914b 100644
--- a/crypto/cipher-gcrypt.c.inc
+++ b/crypto/cipher-gcrypt.c.inc
@@ -18,11 +18,9 @@
*
*/
-#include "qemu/osdep.h"
#ifdef CONFIG_QEMU_PRIVATE_XTS
#include "crypto/xts.h"
#endif
-#include "cipherpriv.h"
#include <gcrypt.h>
diff --git a/crypto/cipher-nettle.c.inc b/crypto/cipher-nettle.c.inc
index 0677fdfd33..256931a823 100644
--- a/crypto/cipher-nettle.c.inc
+++ b/crypto/cipher-nettle.c.inc
@@ -18,11 +18,9 @@
*
*/
-#include "qemu/osdep.h"
#ifdef CONFIG_QEMU_PRIVATE_XTS
#include "crypto/xts.h"
#endif
-#include "cipherpriv.h"
#include <nettle/nettle-types.h>
#include <nettle/aes.h>
--
2.26.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PULL 05/17] crypto/nettle: Fix xts_encrypt arguments
2020-09-10 10:06 [PULL 00/17] Crypto next patches Daniel P. Berrangé
` (3 preceding siblings ...)
2020-09-10 10:06 ` [PULL 04/17] crypto: Remove redundant includes Daniel P. Berrangé
@ 2020-09-10 10:06 ` Daniel P. Berrangé
2020-09-10 10:06 ` [PULL 06/17] crypto: Move QCryptoCipherDriver typedef to crypto/cipher.h Daniel P. Berrangé
` (12 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Daniel P. Berrangé @ 2020-09-10 10:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson, Daniel P. Berrangé
From: Richard Henderson <richard.henderson@linaro.org>
The fourth argument to xts_encrypt should be the decrypt
callback; we were accidentally passing encrypt twice.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
crypto/cipher-nettle.c.inc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/crypto/cipher-nettle.c.inc b/crypto/cipher-nettle.c.inc
index 256931a823..0404cfc6da 100644
--- a/crypto/cipher-nettle.c.inc
+++ b/crypto/cipher-nettle.c.inc
@@ -632,7 +632,7 @@ qcrypto_nettle_cipher_encrypt(QCryptoCipher *cipher,
case QCRYPTO_CIPHER_MODE_XTS:
#ifdef CONFIG_QEMU_PRIVATE_XTS
xts_encrypt(ctx->ctx, ctx->ctx_tweak,
- ctx->alg_encrypt_wrapper, ctx->alg_encrypt_wrapper,
+ ctx->alg_encrypt_wrapper, ctx->alg_decrypt_wrapper,
ctx->iv, len, out, in);
#else
xts_encrypt_message(ctx->ctx, ctx->ctx_tweak,
--
2.26.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PULL 06/17] crypto: Move QCryptoCipherDriver typedef to crypto/cipher.h
2020-09-10 10:06 [PULL 00/17] Crypto next patches Daniel P. Berrangé
` (4 preceding siblings ...)
2020-09-10 10:06 ` [PULL 05/17] crypto/nettle: Fix xts_encrypt arguments Daniel P. Berrangé
@ 2020-09-10 10:06 ` Daniel P. Berrangé
2020-09-10 10:06 ` [PULL 07/17] crypto: Use the correct const type for driver Daniel P. Berrangé
` (11 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Daniel P. Berrangé @ 2020-09-10 10:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson, Daniel P. Berrangé
From: Richard Henderson <richard.henderson@linaro.org>
Allow the use in QCryptoCipher to be properly typed with
the opaque struct pointer.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
crypto/cipherpriv.h | 2 --
include/crypto/cipher.h | 1 +
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/crypto/cipherpriv.h b/crypto/cipherpriv.h
index 0823239f41..9228c9fc3a 100644
--- a/crypto/cipherpriv.h
+++ b/crypto/cipherpriv.h
@@ -17,8 +17,6 @@
#include "qapi/qapi-types-crypto.h"
-typedef struct QCryptoCipherDriver QCryptoCipherDriver;
-
struct QCryptoCipherDriver {
int (*cipher_encrypt)(QCryptoCipher *cipher,
const void *in,
diff --git a/include/crypto/cipher.h b/include/crypto/cipher.h
index 5928e5ecc7..8a42a683a4 100644
--- a/include/crypto/cipher.h
+++ b/include/crypto/cipher.h
@@ -24,6 +24,7 @@
#include "qapi/qapi-types-crypto.h"
typedef struct QCryptoCipher QCryptoCipher;
+typedef struct QCryptoCipherDriver QCryptoCipherDriver;
/* See also "QCryptoCipherAlgorithm" and "QCryptoCipherMode"
* enums defined in qapi/crypto.json */
--
2.26.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PULL 07/17] crypto: Use the correct const type for driver
2020-09-10 10:06 [PULL 00/17] Crypto next patches Daniel P. Berrangé
` (5 preceding siblings ...)
2020-09-10 10:06 ` [PULL 06/17] crypto: Move QCryptoCipherDriver typedef to crypto/cipher.h Daniel P. Berrangé
@ 2020-09-10 10:06 ` Daniel P. Berrangé
2020-09-10 10:06 ` [PULL 08/17] crypto: Allocate QCryptoCipher with the subclass Daniel P. Berrangé
` (10 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Daniel P. Berrangé @ 2020-09-10 10:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson, Daniel P. Berrangé
From: Richard Henderson <richard.henderson@linaro.org>
This allows the in memory structures to be read-only.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
crypto/cipher-afalg.c | 2 +-
crypto/cipher-builtin.c.inc | 2 +-
crypto/cipher-gcrypt.c.inc | 2 +-
crypto/cipher-nettle.c.inc | 2 +-
crypto/cipher.c | 12 ++++++------
crypto/cipherpriv.h | 2 +-
include/crypto/cipher.h | 2 +-
7 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/crypto/cipher-afalg.c b/crypto/cipher-afalg.c
index cd72284690..5c7c44761b 100644
--- a/crypto/cipher-afalg.c
+++ b/crypto/cipher-afalg.c
@@ -218,7 +218,7 @@ static void qcrypto_afalg_comm_ctx_free(QCryptoCipher *cipher)
qcrypto_afalg_comm_free(cipher->opaque);
}
-struct QCryptoCipherDriver qcrypto_cipher_afalg_driver = {
+const struct QCryptoCipherDriver qcrypto_cipher_afalg_driver = {
.cipher_encrypt = qcrypto_afalg_cipher_encrypt,
.cipher_decrypt = qcrypto_afalg_cipher_decrypt,
.cipher_setiv = qcrypto_afalg_cipher_setiv,
diff --git a/crypto/cipher-builtin.c.inc b/crypto/cipher-builtin.c.inc
index 56d45b0227..156f32f1c7 100644
--- a/crypto/cipher-builtin.c.inc
+++ b/crypto/cipher-builtin.c.inc
@@ -522,7 +522,7 @@ qcrypto_builtin_cipher_setiv(QCryptoCipher *cipher,
}
-static struct QCryptoCipherDriver qcrypto_cipher_lib_driver = {
+static const struct QCryptoCipherDriver qcrypto_cipher_lib_driver = {
.cipher_encrypt = qcrypto_builtin_cipher_encrypt,
.cipher_decrypt = qcrypto_builtin_cipher_decrypt,
.cipher_setiv = qcrypto_builtin_cipher_setiv,
diff --git a/crypto/cipher-gcrypt.c.inc b/crypto/cipher-gcrypt.c.inc
index a62839914b..18850fadb9 100644
--- a/crypto/cipher-gcrypt.c.inc
+++ b/crypto/cipher-gcrypt.c.inc
@@ -413,7 +413,7 @@ qcrypto_gcrypt_cipher_setiv(QCryptoCipher *cipher,
}
-static struct QCryptoCipherDriver qcrypto_cipher_lib_driver = {
+static const struct QCryptoCipherDriver qcrypto_cipher_lib_driver = {
.cipher_encrypt = qcrypto_gcrypt_cipher_encrypt,
.cipher_decrypt = qcrypto_gcrypt_cipher_decrypt,
.cipher_setiv = qcrypto_gcrypt_cipher_setiv,
diff --git a/crypto/cipher-nettle.c.inc b/crypto/cipher-nettle.c.inc
index 0404cfc6da..6ecce5e8ea 100644
--- a/crypto/cipher-nettle.c.inc
+++ b/crypto/cipher-nettle.c.inc
@@ -724,7 +724,7 @@ qcrypto_nettle_cipher_setiv(QCryptoCipher *cipher,
}
-static struct QCryptoCipherDriver qcrypto_cipher_lib_driver = {
+static const struct QCryptoCipherDriver qcrypto_cipher_lib_driver = {
.cipher_encrypt = qcrypto_nettle_cipher_encrypt,
.cipher_decrypt = qcrypto_nettle_cipher_decrypt,
.cipher_setiv = qcrypto_nettle_cipher_setiv,
diff --git a/crypto/cipher.c b/crypto/cipher.c
index 005b5da4de..3ca4a7e662 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -165,7 +165,7 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
{
QCryptoCipher *cipher;
void *ctx = NULL;
- QCryptoCipherDriver *drv = NULL;
+ const QCryptoCipherDriver *drv = NULL;
#ifdef CONFIG_AF_ALG
ctx = qcrypto_afalg_cipher_ctx_new(alg, mode, key, nkey, NULL);
@@ -187,7 +187,7 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
cipher->alg = alg;
cipher->mode = mode;
cipher->opaque = ctx;
- cipher->driver = (void *)drv;
+ cipher->driver = drv;
return cipher;
}
@@ -199,7 +199,7 @@ int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
size_t len,
Error **errp)
{
- QCryptoCipherDriver *drv = cipher->driver;
+ const QCryptoCipherDriver *drv = cipher->driver;
return drv->cipher_encrypt(cipher, in, out, len, errp);
}
@@ -210,7 +210,7 @@ int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
size_t len,
Error **errp)
{
- QCryptoCipherDriver *drv = cipher->driver;
+ const QCryptoCipherDriver *drv = cipher->driver;
return drv->cipher_decrypt(cipher, in, out, len, errp);
}
@@ -219,14 +219,14 @@ int qcrypto_cipher_setiv(QCryptoCipher *cipher,
const uint8_t *iv, size_t niv,
Error **errp)
{
- QCryptoCipherDriver *drv = cipher->driver;
+ const QCryptoCipherDriver *drv = cipher->driver;
return drv->cipher_setiv(cipher, iv, niv, errp);
}
void qcrypto_cipher_free(QCryptoCipher *cipher)
{
- QCryptoCipherDriver *drv;
+ const QCryptoCipherDriver *drv;
if (cipher) {
drv = cipher->driver;
drv->cipher_free(cipher);
diff --git a/crypto/cipherpriv.h b/crypto/cipherpriv.h
index 9228c9fc3a..b73be33bd2 100644
--- a/crypto/cipherpriv.h
+++ b/crypto/cipherpriv.h
@@ -47,7 +47,7 @@ qcrypto_afalg_cipher_ctx_new(QCryptoCipherAlgorithm alg,
const uint8_t *key,
size_t nkey, Error **errp);
-extern struct QCryptoCipherDriver qcrypto_cipher_afalg_driver;
+extern const struct QCryptoCipherDriver qcrypto_cipher_afalg_driver;
#endif
diff --git a/include/crypto/cipher.h b/include/crypto/cipher.h
index 8a42a683a4..cc57179a4d 100644
--- a/include/crypto/cipher.h
+++ b/include/crypto/cipher.h
@@ -81,7 +81,7 @@ struct QCryptoCipher {
QCryptoCipherAlgorithm alg;
QCryptoCipherMode mode;
void *opaque;
- void *driver;
+ const QCryptoCipherDriver *driver;
};
/**
--
2.26.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PULL 08/17] crypto: Allocate QCryptoCipher with the subclass
2020-09-10 10:06 [PULL 00/17] Crypto next patches Daniel P. Berrangé
` (6 preceding siblings ...)
2020-09-10 10:06 ` [PULL 07/17] crypto: Use the correct const type for driver Daniel P. Berrangé
@ 2020-09-10 10:06 ` Daniel P. Berrangé
2020-09-10 10:06 ` [PULL 09/17] crypto: Move cipher->driver init to qcrypto_*_cipher_ctx_new Daniel P. Berrangé
` (9 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Daniel P. Berrangé @ 2020-09-10 10:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson, Daniel P. Berrangé
From: Richard Henderson <richard.henderson@linaro.org>
Merge the allocation of "opaque" into the allocation of "cipher".
This is step one in reducing the indirection in these classes.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
crypto/afalgpriv.h | 3 ++
crypto/cipher-afalg.c | 20 ++++++-----
crypto/cipher-builtin.c.inc | 68 +++++++++++++++++++------------------
crypto/cipher-gcrypt.c.inc | 23 +++++++------
crypto/cipher-nettle.c.inc | 24 +++++++------
crypto/cipher.c | 20 ++++-------
crypto/cipherpriv.h | 2 +-
include/crypto/cipher.h | 1 -
8 files changed, 84 insertions(+), 77 deletions(-)
diff --git a/crypto/afalgpriv.h b/crypto/afalgpriv.h
index f6550b5c51..5a2393f1b7 100644
--- a/crypto/afalgpriv.h
+++ b/crypto/afalgpriv.h
@@ -15,6 +15,7 @@
#define QCRYPTO_AFALGPRIV_H
#include <linux/if_alg.h>
+#include "crypto/cipher.h"
#define SALG_TYPE_LEN_MAX 14
#define SALG_NAME_LEN_MAX 64
@@ -32,6 +33,8 @@
typedef struct QCryptoAFAlg QCryptoAFAlg;
struct QCryptoAFAlg {
+ QCryptoCipher base;
+
int tfmfd;
int opfd;
struct msghdr *msg;
diff --git a/crypto/cipher-afalg.c b/crypto/cipher-afalg.c
index 5c7c44761b..86e5249bd6 100644
--- a/crypto/cipher-afalg.c
+++ b/crypto/cipher-afalg.c
@@ -58,7 +58,7 @@ qcrypto_afalg_cipher_format_name(QCryptoCipherAlgorithm alg,
return name;
}
-QCryptoAFAlg *
+QCryptoCipher *
qcrypto_afalg_cipher_ctx_new(QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode,
const uint8_t *key,
@@ -109,7 +109,7 @@ qcrypto_afalg_cipher_ctx_new(QCryptoCipherAlgorithm alg,
}
afalg->cmsg = CMSG_FIRSTHDR(afalg->msg);
- return afalg;
+ return &afalg->base;
}
static int
@@ -117,9 +117,9 @@ qcrypto_afalg_cipher_setiv(QCryptoCipher *cipher,
const uint8_t *iv,
size_t niv, Error **errp)
{
+ QCryptoAFAlg *afalg = container_of(cipher, QCryptoAFAlg, base);
struct af_alg_iv *alg_iv;
size_t expect_niv;
- QCryptoAFAlg *afalg = cipher->opaque;
expect_niv = qcrypto_cipher_get_iv_len(cipher->alg, cipher->mode);
if (niv != expect_niv) {
@@ -200,8 +200,9 @@ qcrypto_afalg_cipher_encrypt(QCryptoCipher *cipher,
const void *in, void *out,
size_t len, Error **errp)
{
- return qcrypto_afalg_cipher_op(cipher->opaque, in, out,
- len, true, errp);
+ QCryptoAFAlg *afalg = container_of(cipher, QCryptoAFAlg, base);
+
+ return qcrypto_afalg_cipher_op(afalg, in, out, len, true, errp);
}
static int
@@ -209,13 +210,16 @@ qcrypto_afalg_cipher_decrypt(QCryptoCipher *cipher,
const void *in, void *out,
size_t len, Error **errp)
{
- return qcrypto_afalg_cipher_op(cipher->opaque, in, out,
- len, false, errp);
+ QCryptoAFAlg *afalg = container_of(cipher, QCryptoAFAlg, base);
+
+ return qcrypto_afalg_cipher_op(afalg, in, out, len, false, errp);
}
static void qcrypto_afalg_comm_ctx_free(QCryptoCipher *cipher)
{
- qcrypto_afalg_comm_free(cipher->opaque);
+ QCryptoAFAlg *afalg = container_of(cipher, QCryptoAFAlg, base);
+
+ qcrypto_afalg_comm_free(afalg);
}
const struct QCryptoCipherDriver qcrypto_cipher_afalg_driver = {
diff --git a/crypto/cipher-builtin.c.inc b/crypto/cipher-builtin.c.inc
index 156f32f1c7..6a03e23040 100644
--- a/crypto/cipher-builtin.c.inc
+++ b/crypto/cipher-builtin.c.inc
@@ -41,6 +41,8 @@ struct QCryptoCipherBuiltinDESRFB {
typedef struct QCryptoCipherBuiltin QCryptoCipherBuiltin;
struct QCryptoCipherBuiltin {
+ QCryptoCipher base;
+
union {
QCryptoCipherBuiltinAES aes;
QCryptoCipherBuiltinDESRFB desrfb;
@@ -65,10 +67,7 @@ struct QCryptoCipherBuiltin {
static void qcrypto_cipher_free_aes(QCryptoCipher *cipher)
{
- QCryptoCipherBuiltin *ctxt = cipher->opaque;
-
- g_free(ctxt);
- cipher->opaque = NULL;
+ g_free(cipher);
}
@@ -152,7 +151,8 @@ static int qcrypto_cipher_encrypt_aes(QCryptoCipher *cipher,
size_t len,
Error **errp)
{
- QCryptoCipherBuiltin *ctxt = cipher->opaque;
+ QCryptoCipherBuiltin *ctxt
+ = container_of(cipher, QCryptoCipherBuiltin, base);
switch (cipher->mode) {
case QCRYPTO_CIPHER_MODE_ECB:
@@ -186,7 +186,8 @@ static int qcrypto_cipher_decrypt_aes(QCryptoCipher *cipher,
size_t len,
Error **errp)
{
- QCryptoCipherBuiltin *ctxt = cipher->opaque;
+ QCryptoCipherBuiltin *ctxt
+ = container_of(cipher, QCryptoCipherBuiltin, base);
switch (cipher->mode) {
case QCRYPTO_CIPHER_MODE_ECB:
@@ -217,7 +218,9 @@ static int qcrypto_cipher_setiv_aes(QCryptoCipher *cipher,
const uint8_t *iv, size_t niv,
Error **errp)
{
- QCryptoCipherBuiltin *ctxt = cipher->opaque;
+ QCryptoCipherBuiltin *ctxt
+ = container_of(cipher, QCryptoCipherBuiltin, base);
+
if (niv != AES_BLOCK_SIZE) {
error_setg(errp, "IV must be %d bytes not %zu",
AES_BLOCK_SIZE, niv);
@@ -232,7 +235,7 @@ static int qcrypto_cipher_setiv_aes(QCryptoCipher *cipher,
-static QCryptoCipherBuiltin *
+static QCryptoCipher *
qcrypto_cipher_init_aes(QCryptoCipherMode mode,
const uint8_t *key, size_t nkey,
Error **errp)
@@ -289,7 +292,7 @@ qcrypto_cipher_init_aes(QCryptoCipherMode mode,
ctxt->encrypt = qcrypto_cipher_encrypt_aes;
ctxt->decrypt = qcrypto_cipher_decrypt_aes;
- return ctxt;
+ return &ctxt->base;
error:
g_free(ctxt);
@@ -299,11 +302,11 @@ qcrypto_cipher_init_aes(QCryptoCipherMode mode,
static void qcrypto_cipher_free_des_rfb(QCryptoCipher *cipher)
{
- QCryptoCipherBuiltin *ctxt = cipher->opaque;
+ QCryptoCipherBuiltin *ctxt
+ = container_of(cipher, QCryptoCipherBuiltin, base);
g_free(ctxt->state.desrfb.key);
g_free(ctxt);
- cipher->opaque = NULL;
}
@@ -313,7 +316,8 @@ static int qcrypto_cipher_encrypt_des_rfb(QCryptoCipher *cipher,
size_t len,
Error **errp)
{
- QCryptoCipherBuiltin *ctxt = cipher->opaque;
+ QCryptoCipherBuiltin *ctxt
+ = container_of(cipher, QCryptoCipherBuiltin, base);
size_t i;
if (len % 8) {
@@ -338,7 +342,8 @@ static int qcrypto_cipher_decrypt_des_rfb(QCryptoCipher *cipher,
size_t len,
Error **errp)
{
- QCryptoCipherBuiltin *ctxt = cipher->opaque;
+ QCryptoCipherBuiltin *ctxt
+ = container_of(cipher, QCryptoCipherBuiltin, base);
size_t i;
if (len % 8) {
@@ -366,7 +371,7 @@ static int qcrypto_cipher_setiv_des_rfb(QCryptoCipher *cipher,
}
-static QCryptoCipherBuiltin *
+static QCryptoCipher *
qcrypto_cipher_init_des_rfb(QCryptoCipherMode mode,
const uint8_t *key, size_t nkey,
Error **errp)
@@ -391,7 +396,7 @@ qcrypto_cipher_init_des_rfb(QCryptoCipherMode mode,
ctxt->encrypt = qcrypto_cipher_encrypt_des_rfb;
ctxt->decrypt = qcrypto_cipher_decrypt_des_rfb;
- return ctxt;
+ return &ctxt->base;
}
@@ -421,14 +426,12 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
}
-static QCryptoCipherBuiltin *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
- QCryptoCipherMode mode,
- const uint8_t *key,
- size_t nkey,
- Error **errp)
+static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
+ QCryptoCipherMode mode,
+ const uint8_t *key,
+ size_t nkey,
+ Error **errp)
{
- QCryptoCipherBuiltin *ctxt;
-
switch (mode) {
case QCRYPTO_CIPHER_MODE_ECB:
case QCRYPTO_CIPHER_MODE_CBC:
@@ -446,29 +449,25 @@ static QCryptoCipherBuiltin *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
switch (alg) {
case QCRYPTO_CIPHER_ALG_DES_RFB:
- ctxt = qcrypto_cipher_init_des_rfb(mode, key, nkey, errp);
- break;
+ return qcrypto_cipher_init_des_rfb(mode, key, nkey, errp);
case QCRYPTO_CIPHER_ALG_AES_128:
case QCRYPTO_CIPHER_ALG_AES_192:
case QCRYPTO_CIPHER_ALG_AES_256:
- ctxt = qcrypto_cipher_init_aes(mode, key, nkey, errp);
- break;
+ return qcrypto_cipher_init_aes(mode, key, nkey, errp);
default:
error_setg(errp,
"Unsupported cipher algorithm %s",
QCryptoCipherAlgorithm_str(alg));
return NULL;
}
-
- return ctxt;
}
static void
qcrypto_builtin_cipher_ctx_free(QCryptoCipher *cipher)
{
- QCryptoCipherBuiltin *ctxt;
+ QCryptoCipherBuiltin *ctxt
+ = container_of(cipher, QCryptoCipherBuiltin, base);
- ctxt = cipher->opaque;
ctxt->free(cipher);
}
@@ -480,7 +479,8 @@ qcrypto_builtin_cipher_encrypt(QCryptoCipher *cipher,
size_t len,
Error **errp)
{
- QCryptoCipherBuiltin *ctxt = cipher->opaque;
+ QCryptoCipherBuiltin *ctxt
+ = container_of(cipher, QCryptoCipherBuiltin, base);
if (len & (ctxt->blocksize - 1)) {
error_setg(errp, "Length %zu must be a multiple of block size %zu",
@@ -499,7 +499,8 @@ qcrypto_builtin_cipher_decrypt(QCryptoCipher *cipher,
size_t len,
Error **errp)
{
- QCryptoCipherBuiltin *ctxt = cipher->opaque;
+ QCryptoCipherBuiltin *ctxt
+ = container_of(cipher, QCryptoCipherBuiltin, base);
if (len & (ctxt->blocksize - 1)) {
error_setg(errp, "Length %zu must be a multiple of block size %zu",
@@ -516,7 +517,8 @@ qcrypto_builtin_cipher_setiv(QCryptoCipher *cipher,
const uint8_t *iv, size_t niv,
Error **errp)
{
- QCryptoCipherBuiltin *ctxt = cipher->opaque;
+ QCryptoCipherBuiltin *ctxt
+ = container_of(cipher, QCryptoCipherBuiltin, base);
return ctxt->setiv(cipher, iv, niv, errp);
}
diff --git a/crypto/cipher-gcrypt.c.inc b/crypto/cipher-gcrypt.c.inc
index 18850fadb9..3b3c85e265 100644
--- a/crypto/cipher-gcrypt.c.inc
+++ b/crypto/cipher-gcrypt.c.inc
@@ -58,6 +58,7 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
typedef struct QCryptoCipherGcrypt QCryptoCipherGcrypt;
struct QCryptoCipherGcrypt {
+ QCryptoCipher base;
gcry_cipher_hd_t handle;
size_t blocksize;
#ifdef CONFIG_QEMU_PRIVATE_XTS
@@ -86,11 +87,11 @@ qcrypto_gcrypt_cipher_free_ctx(QCryptoCipherGcrypt *ctx,
}
-static QCryptoCipherGcrypt *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
- QCryptoCipherMode mode,
- const uint8_t *key,
- size_t nkey,
- Error **errp)
+static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
+ QCryptoCipherMode mode,
+ const uint8_t *key,
+ size_t nkey,
+ Error **errp)
{
QCryptoCipherGcrypt *ctx;
gcry_error_t err;
@@ -257,7 +258,7 @@ static QCryptoCipherGcrypt *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
}
#endif
- return ctx;
+ return &ctx->base;
error:
qcrypto_gcrypt_cipher_free_ctx(ctx, mode);
@@ -268,7 +269,9 @@ static QCryptoCipherGcrypt *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
static void
qcrypto_gcrypt_cipher_ctx_free(QCryptoCipher *cipher)
{
- qcrypto_gcrypt_cipher_free_ctx(cipher->opaque, cipher->mode);
+ QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
+
+ qcrypto_gcrypt_cipher_free_ctx(ctx, cipher->mode);
}
@@ -301,7 +304,7 @@ qcrypto_gcrypt_cipher_encrypt(QCryptoCipher *cipher,
size_t len,
Error **errp)
{
- QCryptoCipherGcrypt *ctx = cipher->opaque;
+ QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
gcry_error_t err;
if (len & (ctx->blocksize - 1)) {
@@ -340,7 +343,7 @@ qcrypto_gcrypt_cipher_decrypt(QCryptoCipher *cipher,
size_t len,
Error **errp)
{
- QCryptoCipherGcrypt *ctx = cipher->opaque;
+ QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
gcry_error_t err;
if (len & (ctx->blocksize - 1)) {
@@ -376,7 +379,7 @@ qcrypto_gcrypt_cipher_setiv(QCryptoCipher *cipher,
const uint8_t *iv, size_t niv,
Error **errp)
{
- QCryptoCipherGcrypt *ctx = cipher->opaque;
+ QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
gcry_error_t err;
if (niv != ctx->blocksize) {
diff --git a/crypto/cipher-nettle.c.inc b/crypto/cipher-nettle.c.inc
index 6ecce5e8ea..d8371d1f37 100644
--- a/crypto/cipher-nettle.c.inc
+++ b/crypto/cipher-nettle.c.inc
@@ -294,6 +294,8 @@ static void twofish_decrypt_wrapper(const void *ctx, size_t length,
typedef struct QCryptoCipherNettle QCryptoCipherNettle;
struct QCryptoCipherNettle {
+ QCryptoCipher base;
+
/* Primary cipher context for all modes */
void *ctx;
/* Second cipher context for XTS mode only */
@@ -355,11 +357,11 @@ qcrypto_nettle_cipher_free_ctx(QCryptoCipherNettle *ctx)
}
-static QCryptoCipherNettle *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
- QCryptoCipherMode mode,
- const uint8_t *key,
- size_t nkey,
- Error **errp)
+static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
+ QCryptoCipherMode mode,
+ const uint8_t *key,
+ size_t nkey,
+ Error **errp)
{
QCryptoCipherNettle *ctx;
uint8_t *rfbkey;
@@ -585,7 +587,7 @@ static QCryptoCipherNettle *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
ctx->iv = g_new0(uint8_t, ctx->blocksize);
- return ctx;
+ return &ctx->base;
error:
qcrypto_nettle_cipher_free_ctx(ctx);
@@ -596,9 +598,8 @@ static QCryptoCipherNettle *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
static void
qcrypto_nettle_cipher_ctx_free(QCryptoCipher *cipher)
{
- QCryptoCipherNettle *ctx;
+ QCryptoCipherNettle *ctx = container_of(cipher, QCryptoCipherNettle, base);
- ctx = cipher->opaque;
qcrypto_nettle_cipher_free_ctx(ctx);
}
@@ -610,7 +611,7 @@ qcrypto_nettle_cipher_encrypt(QCryptoCipher *cipher,
size_t len,
Error **errp)
{
- QCryptoCipherNettle *ctx = cipher->opaque;
+ QCryptoCipherNettle *ctx = container_of(cipher, QCryptoCipherNettle, base);
if (len & (ctx->blocksize - 1)) {
error_setg(errp, "Length %zu must be a multiple of block size %zu",
@@ -663,7 +664,7 @@ qcrypto_nettle_cipher_decrypt(QCryptoCipher *cipher,
size_t len,
Error **errp)
{
- QCryptoCipherNettle *ctx = cipher->opaque;
+ QCryptoCipherNettle *ctx = container_of(cipher, QCryptoCipherNettle, base);
if (len & (ctx->blocksize - 1)) {
error_setg(errp, "Length %zu must be a multiple of block size %zu",
@@ -713,7 +714,8 @@ qcrypto_nettle_cipher_setiv(QCryptoCipher *cipher,
const uint8_t *iv, size_t niv,
Error **errp)
{
- QCryptoCipherNettle *ctx = cipher->opaque;
+ QCryptoCipherNettle *ctx = container_of(cipher, QCryptoCipherNettle, base);
+
if (niv != ctx->blocksize) {
error_setg(errp, "Expected IV size %zu not %zu",
ctx->blocksize, niv);
diff --git a/crypto/cipher.c b/crypto/cipher.c
index 3ca4a7e662..737fc0735d 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -163,30 +163,27 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
const uint8_t *key, size_t nkey,
Error **errp)
{
- QCryptoCipher *cipher;
- void *ctx = NULL;
+ QCryptoCipher *cipher = NULL;
const QCryptoCipherDriver *drv = NULL;
#ifdef CONFIG_AF_ALG
- ctx = qcrypto_afalg_cipher_ctx_new(alg, mode, key, nkey, NULL);
- if (ctx) {
+ cipher = qcrypto_afalg_cipher_ctx_new(alg, mode, key, nkey, NULL);
+ if (cipher) {
drv = &qcrypto_cipher_afalg_driver;
}
#endif
- if (!ctx) {
- ctx = qcrypto_cipher_ctx_new(alg, mode, key, nkey, errp);
- if (!ctx) {
+ if (!cipher) {
+ cipher = qcrypto_cipher_ctx_new(alg, mode, key, nkey, errp);
+ if (!cipher) {
return NULL;
}
drv = &qcrypto_cipher_lib_driver;
}
- cipher = g_new0(QCryptoCipher, 1);
cipher->alg = alg;
cipher->mode = mode;
- cipher->opaque = ctx;
cipher->driver = drv;
return cipher;
@@ -226,10 +223,7 @@ int qcrypto_cipher_setiv(QCryptoCipher *cipher,
void qcrypto_cipher_free(QCryptoCipher *cipher)
{
- const QCryptoCipherDriver *drv;
if (cipher) {
- drv = cipher->driver;
- drv->cipher_free(cipher);
- g_free(cipher);
+ cipher->driver->cipher_free(cipher);
}
}
diff --git a/crypto/cipherpriv.h b/crypto/cipherpriv.h
index b73be33bd2..437b109b5e 100644
--- a/crypto/cipherpriv.h
+++ b/crypto/cipherpriv.h
@@ -41,7 +41,7 @@ struct QCryptoCipherDriver {
#include "afalgpriv.h"
-extern QCryptoAFAlg *
+extern QCryptoCipher *
qcrypto_afalg_cipher_ctx_new(QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode,
const uint8_t *key,
diff --git a/include/crypto/cipher.h b/include/crypto/cipher.h
index cc57179a4d..083e12a7d9 100644
--- a/include/crypto/cipher.h
+++ b/include/crypto/cipher.h
@@ -80,7 +80,6 @@ typedef struct QCryptoCipherDriver QCryptoCipherDriver;
struct QCryptoCipher {
QCryptoCipherAlgorithm alg;
QCryptoCipherMode mode;
- void *opaque;
const QCryptoCipherDriver *driver;
};
--
2.26.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PULL 09/17] crypto: Move cipher->driver init to qcrypto_*_cipher_ctx_new
2020-09-10 10:06 [PULL 00/17] Crypto next patches Daniel P. Berrangé
` (7 preceding siblings ...)
2020-09-10 10:06 ` [PULL 08/17] crypto: Allocate QCryptoCipher with the subclass Daniel P. Berrangé
@ 2020-09-10 10:06 ` Daniel P. Berrangé
2020-09-10 10:06 ` [PULL 10/17] crypto: Constify cipher data tables Daniel P. Berrangé
` (8 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Daniel P. Berrangé @ 2020-09-10 10:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson, Daniel P. Berrangé
From: Richard Henderson <richard.henderson@linaro.org>
The class vtable should be set by the class initializer.
This will also allow additional subclassing, reducing the
amount of indirection in the hierarchy.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
crypto/cipher-afalg.c | 5 ++++-
crypto/cipher-builtin.c.inc | 4 ++++
crypto/cipher-gcrypt.c.inc | 2 ++
crypto/cipher-nettle.c.inc | 3 +++
crypto/cipher.c | 7 -------
crypto/cipherpriv.h | 2 --
6 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/crypto/cipher-afalg.c b/crypto/cipher-afalg.c
index 86e5249bd6..052355a8a9 100644
--- a/crypto/cipher-afalg.c
+++ b/crypto/cipher-afalg.c
@@ -58,6 +58,8 @@ qcrypto_afalg_cipher_format_name(QCryptoCipherAlgorithm alg,
return name;
}
+static const struct QCryptoCipherDriver qcrypto_cipher_afalg_driver;
+
QCryptoCipher *
qcrypto_afalg_cipher_ctx_new(QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode,
@@ -109,6 +111,7 @@ qcrypto_afalg_cipher_ctx_new(QCryptoCipherAlgorithm alg,
}
afalg->cmsg = CMSG_FIRSTHDR(afalg->msg);
+ afalg->base.driver = &qcrypto_cipher_afalg_driver;
return &afalg->base;
}
@@ -222,7 +225,7 @@ static void qcrypto_afalg_comm_ctx_free(QCryptoCipher *cipher)
qcrypto_afalg_comm_free(afalg);
}
-const struct QCryptoCipherDriver qcrypto_cipher_afalg_driver = {
+static const struct QCryptoCipherDriver qcrypto_cipher_afalg_driver = {
.cipher_encrypt = qcrypto_afalg_cipher_encrypt,
.cipher_decrypt = qcrypto_afalg_cipher_decrypt,
.cipher_setiv = qcrypto_afalg_cipher_setiv,
diff --git a/crypto/cipher-builtin.c.inc b/crypto/cipher-builtin.c.inc
index 6a03e23040..1444139f36 100644
--- a/crypto/cipher-builtin.c.inc
+++ b/crypto/cipher-builtin.c.inc
@@ -22,6 +22,8 @@
#include "crypto/desrfb.h"
#include "crypto/xts.h"
+static const struct QCryptoCipherDriver qcrypto_cipher_lib_driver;
+
typedef struct QCryptoCipherBuiltinAESContext QCryptoCipherBuiltinAESContext;
struct QCryptoCipherBuiltinAESContext {
AES_KEY enc;
@@ -292,6 +294,7 @@ qcrypto_cipher_init_aes(QCryptoCipherMode mode,
ctxt->encrypt = qcrypto_cipher_encrypt_aes;
ctxt->decrypt = qcrypto_cipher_decrypt_aes;
+ ctxt->base.driver = &qcrypto_cipher_lib_driver;
return &ctxt->base;
error:
@@ -396,6 +399,7 @@ qcrypto_cipher_init_des_rfb(QCryptoCipherMode mode,
ctxt->encrypt = qcrypto_cipher_encrypt_des_rfb;
ctxt->decrypt = qcrypto_cipher_decrypt_des_rfb;
+ ctxt->base.driver = &qcrypto_cipher_lib_driver;
return &ctxt->base;
}
diff --git a/crypto/cipher-gcrypt.c.inc b/crypto/cipher-gcrypt.c.inc
index 3b3c85e265..7a1fbc9745 100644
--- a/crypto/cipher-gcrypt.c.inc
+++ b/crypto/cipher-gcrypt.c.inc
@@ -24,6 +24,7 @@
#include <gcrypt.h>
+static const struct QCryptoCipherDriver qcrypto_cipher_lib_driver;
bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode)
@@ -258,6 +259,7 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
}
#endif
+ ctx->base.driver = &qcrypto_cipher_lib_driver;
return &ctx->base;
error:
diff --git a/crypto/cipher-nettle.c.inc b/crypto/cipher-nettle.c.inc
index d8371d1f37..36d57ef430 100644
--- a/crypto/cipher-nettle.c.inc
+++ b/crypto/cipher-nettle.c.inc
@@ -34,6 +34,8 @@
#include <nettle/xts.h>
#endif
+static const struct QCryptoCipherDriver qcrypto_cipher_lib_driver;
+
typedef void (*QCryptoCipherNettleFuncWrapper)(const void *ctx,
size_t length,
uint8_t *dst,
@@ -587,6 +589,7 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
ctx->iv = g_new0(uint8_t, ctx->blocksize);
+ ctx->base.driver = &qcrypto_cipher_lib_driver;
return &ctx->base;
error:
diff --git a/crypto/cipher.c b/crypto/cipher.c
index 737fc0735d..3711b552fa 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -164,13 +164,9 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
Error **errp)
{
QCryptoCipher *cipher = NULL;
- const QCryptoCipherDriver *drv = NULL;
#ifdef CONFIG_AF_ALG
cipher = qcrypto_afalg_cipher_ctx_new(alg, mode, key, nkey, NULL);
- if (cipher) {
- drv = &qcrypto_cipher_afalg_driver;
- }
#endif
if (!cipher) {
@@ -178,13 +174,10 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
if (!cipher) {
return NULL;
}
-
- drv = &qcrypto_cipher_lib_driver;
}
cipher->alg = alg;
cipher->mode = mode;
- cipher->driver = drv;
return cipher;
}
diff --git a/crypto/cipherpriv.h b/crypto/cipherpriv.h
index 437b109b5e..396527857d 100644
--- a/crypto/cipherpriv.h
+++ b/crypto/cipherpriv.h
@@ -47,8 +47,6 @@ qcrypto_afalg_cipher_ctx_new(QCryptoCipherAlgorithm alg,
const uint8_t *key,
size_t nkey, Error **errp);
-extern const struct QCryptoCipherDriver qcrypto_cipher_afalg_driver;
-
#endif
#endif
--
2.26.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PULL 10/17] crypto: Constify cipher data tables
2020-09-10 10:06 [PULL 00/17] Crypto next patches Daniel P. Berrangé
` (8 preceding siblings ...)
2020-09-10 10:06 ` [PULL 09/17] crypto: Move cipher->driver init to qcrypto_*_cipher_ctx_new Daniel P. Berrangé
@ 2020-09-10 10:06 ` Daniel P. Berrangé
2020-09-10 10:06 ` [PULL 11/17] crypto/builtin: Remove odd-sized AES block handling Daniel P. Berrangé
` (7 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Daniel P. Berrangé @ 2020-09-10 10:06 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Daniel P. Berrangé, Philippe Mathieu-Daudé
From: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
crypto/cipher.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/crypto/cipher.c b/crypto/cipher.c
index 3711b552fa..068b2fb867 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -25,7 +25,7 @@
#include "cipherpriv.h"
-static size_t alg_key_len[QCRYPTO_CIPHER_ALG__MAX] = {
+static const size_t alg_key_len[QCRYPTO_CIPHER_ALG__MAX] = {
[QCRYPTO_CIPHER_ALG_AES_128] = 16,
[QCRYPTO_CIPHER_ALG_AES_192] = 24,
[QCRYPTO_CIPHER_ALG_AES_256] = 32,
@@ -40,7 +40,7 @@ static size_t alg_key_len[QCRYPTO_CIPHER_ALG__MAX] = {
[QCRYPTO_CIPHER_ALG_TWOFISH_256] = 32,
};
-static size_t alg_block_len[QCRYPTO_CIPHER_ALG__MAX] = {
+static const size_t alg_block_len[QCRYPTO_CIPHER_ALG__MAX] = {
[QCRYPTO_CIPHER_ALG_AES_128] = 16,
[QCRYPTO_CIPHER_ALG_AES_192] = 16,
[QCRYPTO_CIPHER_ALG_AES_256] = 16,
@@ -55,7 +55,7 @@ static size_t alg_block_len[QCRYPTO_CIPHER_ALG__MAX] = {
[QCRYPTO_CIPHER_ALG_TWOFISH_256] = 16,
};
-static bool mode_need_iv[QCRYPTO_CIPHER_MODE__MAX] = {
+static const bool mode_need_iv[QCRYPTO_CIPHER_MODE__MAX] = {
[QCRYPTO_CIPHER_MODE_ECB] = false,
[QCRYPTO_CIPHER_MODE_CBC] = true,
[QCRYPTO_CIPHER_MODE_XTS] = true,
--
2.26.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PULL 11/17] crypto/builtin: Remove odd-sized AES block handling
2020-09-10 10:06 [PULL 00/17] Crypto next patches Daniel P. Berrangé
` (9 preceding siblings ...)
2020-09-10 10:06 ` [PULL 10/17] crypto: Constify cipher data tables Daniel P. Berrangé
@ 2020-09-10 10:06 ` Daniel P. Berrangé
2020-09-10 10:06 ` [PULL 12/17] crypto/builtin: Merge qcrypto_cipher_aes_{ecb, xts}_{en, de}crypt Daniel P. Berrangé
` (6 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Daniel P. Berrangé @ 2020-09-10 10:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson, Daniel P. Berrangé
From: Richard Henderson <richard.henderson@linaro.org>
We verified that the data block is properly sized modulo
AES_BLOCK_SIZE within qcrypto_builtin_cipher_{en,de}crypt.
Therefore we will never have to handle odd sized blocks.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
crypto/cipher-builtin.c.inc | 40 +++++++++++--------------------------
1 file changed, 12 insertions(+), 28 deletions(-)
diff --git a/crypto/cipher-builtin.c.inc b/crypto/cipher-builtin.c.inc
index 1444139f36..e2ae5d090c 100644
--- a/crypto/cipher-builtin.c.inc
+++ b/crypto/cipher-builtin.c.inc
@@ -80,21 +80,13 @@ static void qcrypto_cipher_aes_ecb_encrypt(const AES_KEY *key,
{
const uint8_t *inptr = in;
uint8_t *outptr = out;
+
+ /* We have already verified that len % AES_BLOCK_SIZE == 0. */
while (len) {
- if (len > AES_BLOCK_SIZE) {
- AES_encrypt(inptr, outptr, key);
- inptr += AES_BLOCK_SIZE;
- outptr += AES_BLOCK_SIZE;
- len -= AES_BLOCK_SIZE;
- } else {
- uint8_t tmp1[AES_BLOCK_SIZE], tmp2[AES_BLOCK_SIZE];
- memcpy(tmp1, inptr, len);
- /* Fill with 0 to avoid valgrind uninitialized reads */
- memset(tmp1 + len, 0, sizeof(tmp1) - len);
- AES_encrypt(tmp1, tmp2, key);
- memcpy(outptr, tmp2, len);
- len = 0;
- }
+ AES_encrypt(inptr, outptr, key);
+ inptr += AES_BLOCK_SIZE;
+ outptr += AES_BLOCK_SIZE;
+ len -= AES_BLOCK_SIZE;
}
}
@@ -106,21 +98,13 @@ static void qcrypto_cipher_aes_ecb_decrypt(const AES_KEY *key,
{
const uint8_t *inptr = in;
uint8_t *outptr = out;
+
+ /* We have already verified that len % AES_BLOCK_SIZE == 0. */
while (len) {
- if (len > AES_BLOCK_SIZE) {
- AES_decrypt(inptr, outptr, key);
- inptr += AES_BLOCK_SIZE;
- outptr += AES_BLOCK_SIZE;
- len -= AES_BLOCK_SIZE;
- } else {
- uint8_t tmp1[AES_BLOCK_SIZE], tmp2[AES_BLOCK_SIZE];
- memcpy(tmp1, inptr, len);
- /* Fill with 0 to avoid valgrind uninitialized reads */
- memset(tmp1 + len, 0, sizeof(tmp1) - len);
- AES_decrypt(tmp1, tmp2, key);
- memcpy(outptr, tmp2, len);
- len = 0;
- }
+ AES_decrypt(inptr, outptr, key);
+ inptr += AES_BLOCK_SIZE;
+ outptr += AES_BLOCK_SIZE;
+ len -= AES_BLOCK_SIZE;
}
}
--
2.26.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PULL 12/17] crypto/builtin: Merge qcrypto_cipher_aes_{ecb, xts}_{en, de}crypt
2020-09-10 10:06 [PULL 00/17] Crypto next patches Daniel P. Berrangé
` (10 preceding siblings ...)
2020-09-10 10:06 ` [PULL 11/17] crypto/builtin: Remove odd-sized AES block handling Daniel P. Berrangé
@ 2020-09-10 10:06 ` Daniel P. Berrangé
2020-09-10 10:06 ` [PULL 13/17] crypto/builtin: Move AES_cbc_encrypt into cipher-builtin.inc.c Daniel P. Berrangé
` (5 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Daniel P. Berrangé @ 2020-09-10 10:06 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Daniel P. Berrangé, Philippe Mathieu-Daudé
From: Richard Henderson <richard.henderson@linaro.org>
There's no real reason we need two separate helper functions here.
Standardize on the function signature required for xts_encrypt.
Rename to do_aes_{en,de}crypt_ecb, since the helper does not
itself do anything with respect to xts.
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
crypto/cipher-builtin.c.inc | 73 +++++++++++--------------------------
1 file changed, 22 insertions(+), 51 deletions(-)
diff --git a/crypto/cipher-builtin.c.inc b/crypto/cipher-builtin.c.inc
index e2ae5d090c..8e21f2673f 100644
--- a/crypto/cipher-builtin.c.inc
+++ b/crypto/cipher-builtin.c.inc
@@ -72,65 +72,38 @@ static void qcrypto_cipher_free_aes(QCryptoCipher *cipher)
g_free(cipher);
}
-
-static void qcrypto_cipher_aes_ecb_encrypt(const AES_KEY *key,
- const void *in,
- void *out,
- size_t len)
+static void do_aes_encrypt_ecb(const void *vctx,
+ size_t len,
+ uint8_t *out,
+ const uint8_t *in)
{
- const uint8_t *inptr = in;
- uint8_t *outptr = out;
+ const QCryptoCipherBuiltinAESContext *ctx = vctx;
/* We have already verified that len % AES_BLOCK_SIZE == 0. */
while (len) {
- AES_encrypt(inptr, outptr, key);
- inptr += AES_BLOCK_SIZE;
- outptr += AES_BLOCK_SIZE;
+ AES_encrypt(in, out, &ctx->enc);
+ in += AES_BLOCK_SIZE;
+ out += AES_BLOCK_SIZE;
len -= AES_BLOCK_SIZE;
}
}
-
-static void qcrypto_cipher_aes_ecb_decrypt(const AES_KEY *key,
- const void *in,
- void *out,
- size_t len)
+static void do_aes_decrypt_ecb(const void *vctx,
+ size_t len,
+ uint8_t *out,
+ const uint8_t *in)
{
- const uint8_t *inptr = in;
- uint8_t *outptr = out;
+ const QCryptoCipherBuiltinAESContext *ctx = vctx;
/* We have already verified that len % AES_BLOCK_SIZE == 0. */
while (len) {
- AES_decrypt(inptr, outptr, key);
- inptr += AES_BLOCK_SIZE;
- outptr += AES_BLOCK_SIZE;
+ AES_decrypt(in, out, &ctx->dec);
+ in += AES_BLOCK_SIZE;
+ out += AES_BLOCK_SIZE;
len -= AES_BLOCK_SIZE;
}
}
-
-static void qcrypto_cipher_aes_xts_encrypt(const void *ctx,
- size_t length,
- uint8_t *dst,
- const uint8_t *src)
-{
- const QCryptoCipherBuiltinAESContext *aesctx = ctx;
-
- qcrypto_cipher_aes_ecb_encrypt(&aesctx->enc, src, dst, length);
-}
-
-
-static void qcrypto_cipher_aes_xts_decrypt(const void *ctx,
- size_t length,
- uint8_t *dst,
- const uint8_t *src)
-{
- const QCryptoCipherBuiltinAESContext *aesctx = ctx;
-
- qcrypto_cipher_aes_ecb_decrypt(&aesctx->dec, src, dst, length);
-}
-
-
static int qcrypto_cipher_encrypt_aes(QCryptoCipher *cipher,
const void *in,
void *out,
@@ -142,8 +115,7 @@ static int qcrypto_cipher_encrypt_aes(QCryptoCipher *cipher,
switch (cipher->mode) {
case QCRYPTO_CIPHER_MODE_ECB:
- qcrypto_cipher_aes_ecb_encrypt(&ctxt->state.aes.key.enc,
- in, out, len);
+ do_aes_encrypt_ecb(&ctxt->state.aes.key, len, out, in);
break;
case QCRYPTO_CIPHER_MODE_CBC:
AES_cbc_encrypt(in, out, len,
@@ -153,8 +125,8 @@ static int qcrypto_cipher_encrypt_aes(QCryptoCipher *cipher,
case QCRYPTO_CIPHER_MODE_XTS:
xts_encrypt(&ctxt->state.aes.key,
&ctxt->state.aes.key_tweak,
- qcrypto_cipher_aes_xts_encrypt,
- qcrypto_cipher_aes_xts_decrypt,
+ do_aes_encrypt_ecb,
+ do_aes_decrypt_ecb,
ctxt->state.aes.iv,
len, out, in);
break;
@@ -177,8 +149,7 @@ static int qcrypto_cipher_decrypt_aes(QCryptoCipher *cipher,
switch (cipher->mode) {
case QCRYPTO_CIPHER_MODE_ECB:
- qcrypto_cipher_aes_ecb_decrypt(&ctxt->state.aes.key.dec,
- in, out, len);
+ do_aes_decrypt_ecb(&ctxt->state.aes.key, len, out, in);
break;
case QCRYPTO_CIPHER_MODE_CBC:
AES_cbc_encrypt(in, out, len,
@@ -188,8 +159,8 @@ static int qcrypto_cipher_decrypt_aes(QCryptoCipher *cipher,
case QCRYPTO_CIPHER_MODE_XTS:
xts_decrypt(&ctxt->state.aes.key,
&ctxt->state.aes.key_tweak,
- qcrypto_cipher_aes_xts_encrypt,
- qcrypto_cipher_aes_xts_decrypt,
+ do_aes_encrypt_ecb,
+ do_aes_decrypt_ecb,
ctxt->state.aes.iv,
len, out, in);
break;
--
2.26.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PULL 13/17] crypto/builtin: Move AES_cbc_encrypt into cipher-builtin.inc.c
2020-09-10 10:06 [PULL 00/17] Crypto next patches Daniel P. Berrangé
` (11 preceding siblings ...)
2020-09-10 10:06 ` [PULL 12/17] crypto/builtin: Merge qcrypto_cipher_aes_{ecb, xts}_{en, de}crypt Daniel P. Berrangé
@ 2020-09-10 10:06 ` Daniel P. Berrangé
2020-09-10 10:06 ` [PULL 14/17] crypto/builtin: Split and simplify AES_encrypt_cbc Daniel P. Berrangé
` (4 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Daniel P. Berrangé @ 2020-09-10 10:06 UTC (permalink / raw)
To: qemu-devel
Cc: Richard Henderson, Daniel P. Berrangé, Philippe Mathieu-Daudé
From: Richard Henderson <richard.henderson@linaro.org>
By making the function private, we will be able to make further
simplifications. Re-indent the migrated code and fix the missing
braces for CODING_STYLE.
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
crypto/aes.c | 51 ---------------------------------
crypto/cipher-builtin.c.inc | 56 +++++++++++++++++++++++++++++++++++++
include/crypto/aes.h | 4 ---
3 files changed, 56 insertions(+), 55 deletions(-)
diff --git a/crypto/aes.c b/crypto/aes.c
index 0f6a195af8..159800df65 100644
--- a/crypto/aes.c
+++ b/crypto/aes.c
@@ -1599,54 +1599,3 @@ void AES_decrypt(const unsigned char *in, unsigned char *out,
}
#endif /* AES_ASM */
-
-void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
- const unsigned long length, const AES_KEY *key,
- unsigned char *ivec, const int enc)
-{
-
- unsigned long n;
- unsigned long len = length;
- unsigned char tmp[AES_BLOCK_SIZE];
-
- assert(in && out && key && ivec);
-
- if (enc) {
- while (len >= AES_BLOCK_SIZE) {
- for(n=0; n < AES_BLOCK_SIZE; ++n)
- tmp[n] = in[n] ^ ivec[n];
- AES_encrypt(tmp, out, key);
- memcpy(ivec, out, AES_BLOCK_SIZE);
- len -= AES_BLOCK_SIZE;
- in += AES_BLOCK_SIZE;
- out += AES_BLOCK_SIZE;
- }
- if (len) {
- for(n=0; n < len; ++n)
- tmp[n] = in[n] ^ ivec[n];
- for(n=len; n < AES_BLOCK_SIZE; ++n)
- tmp[n] = ivec[n];
- AES_encrypt(tmp, tmp, key);
- memcpy(out, tmp, AES_BLOCK_SIZE);
- memcpy(ivec, tmp, AES_BLOCK_SIZE);
- }
- } else {
- while (len >= AES_BLOCK_SIZE) {
- memcpy(tmp, in, AES_BLOCK_SIZE);
- AES_decrypt(in, out, key);
- for(n=0; n < AES_BLOCK_SIZE; ++n)
- out[n] ^= ivec[n];
- memcpy(ivec, tmp, AES_BLOCK_SIZE);
- len -= AES_BLOCK_SIZE;
- in += AES_BLOCK_SIZE;
- out += AES_BLOCK_SIZE;
- }
- if (len) {
- memcpy(tmp, in, AES_BLOCK_SIZE);
- AES_decrypt(tmp, tmp, key);
- for(n=0; n < len; ++n)
- out[n] = tmp[n] ^ ivec[n];
- memcpy(ivec, tmp, AES_BLOCK_SIZE);
- }
- }
-}
diff --git a/crypto/cipher-builtin.c.inc b/crypto/cipher-builtin.c.inc
index 8e21f2673f..61baad265a 100644
--- a/crypto/cipher-builtin.c.inc
+++ b/crypto/cipher-builtin.c.inc
@@ -104,6 +104,62 @@ static void do_aes_decrypt_ecb(const void *vctx,
}
}
+static void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ const unsigned long length, const AES_KEY *key,
+ unsigned char *ivec, const int enc)
+{
+ unsigned long n;
+ unsigned long len = length;
+ unsigned char tmp[AES_BLOCK_SIZE];
+
+ assert(in && out && key && ivec);
+
+ if (enc) {
+ while (len >= AES_BLOCK_SIZE) {
+ for (n = 0; n < AES_BLOCK_SIZE; ++n) {
+ tmp[n] = in[n] ^ ivec[n];
+ }
+ AES_encrypt(tmp, out, key);
+ memcpy(ivec, out, AES_BLOCK_SIZE);
+ len -= AES_BLOCK_SIZE;
+ in += AES_BLOCK_SIZE;
+ out += AES_BLOCK_SIZE;
+ }
+ if (len) {
+ for (n = 0; n < len; ++n) {
+ tmp[n] = in[n] ^ ivec[n];
+ }
+ for (n = len; n < AES_BLOCK_SIZE; ++n) {
+ tmp[n] = ivec[n];
+ }
+ AES_encrypt(tmp, tmp, key);
+ memcpy(out, tmp, AES_BLOCK_SIZE);
+ memcpy(ivec, tmp, AES_BLOCK_SIZE);
+ }
+ } else {
+ while (len >= AES_BLOCK_SIZE) {
+ memcpy(tmp, in, AES_BLOCK_SIZE);
+ AES_decrypt(in, out, key);
+ for (n = 0; n < AES_BLOCK_SIZE; ++n) {
+ out[n] ^= ivec[n];
+ }
+ memcpy(ivec, tmp, AES_BLOCK_SIZE);
+ len -= AES_BLOCK_SIZE;
+ in += AES_BLOCK_SIZE;
+ out += AES_BLOCK_SIZE;
+ }
+ if (len) {
+ memcpy(tmp, in, AES_BLOCK_SIZE);
+ AES_decrypt(tmp, tmp, key);
+ for (n = 0; n < len; ++n) {
+ out[n] = tmp[n] ^ ivec[n];
+ }
+ memcpy(ivec, tmp, AES_BLOCK_SIZE);
+ }
+ }
+}
+
+
static int qcrypto_cipher_encrypt_aes(QCryptoCipher *cipher,
const void *in,
void *out,
diff --git a/include/crypto/aes.h b/include/crypto/aes.h
index 12fb321b89..ba297d6a73 100644
--- a/include/crypto/aes.h
+++ b/include/crypto/aes.h
@@ -16,7 +16,6 @@ typedef struct aes_key_st AES_KEY;
#define AES_set_decrypt_key QEMU_AES_set_decrypt_key
#define AES_encrypt QEMU_AES_encrypt
#define AES_decrypt QEMU_AES_decrypt
-#define AES_cbc_encrypt QEMU_AES_cbc_encrypt
int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
@@ -27,9 +26,6 @@ void AES_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
void AES_decrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
-void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
- const unsigned long length, const AES_KEY *key,
- unsigned char *ivec, const int enc);
extern const uint8_t AES_sbox[256];
extern const uint8_t AES_isbox[256];
--
2.26.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PULL 14/17] crypto/builtin: Split and simplify AES_encrypt_cbc
2020-09-10 10:06 [PULL 00/17] Crypto next patches Daniel P. Berrangé
` (12 preceding siblings ...)
2020-09-10 10:06 ` [PULL 13/17] crypto/builtin: Move AES_cbc_encrypt into cipher-builtin.inc.c Daniel P. Berrangé
@ 2020-09-10 10:06 ` Daniel P. Berrangé
2020-09-10 10:06 ` [PULL 15/17] crypto/builtin: Split QCryptoCipherBuiltin into subclasses Daniel P. Berrangé
` (3 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Daniel P. Berrangé @ 2020-09-10 10:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson, Daniel P. Berrangé
From: Richard Henderson <richard.henderson@linaro.org>
Split into encrypt/decrypt functions, dropping the "enc" argument.
Now that the function is private to this file, we know that "len"
is a multiple of AES_BLOCK_SIZE. So drop the odd block size code.
Name the functions do_aes_*crypt_cbc to match the *_ecb functions.
Reorder and re-type the arguments to match as well.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
crypto/cipher-builtin.c.inc | 99 ++++++++++++++++---------------------
1 file changed, 43 insertions(+), 56 deletions(-)
diff --git a/crypto/cipher-builtin.c.inc b/crypto/cipher-builtin.c.inc
index 61baad265a..b1fe3b08c3 100644
--- a/crypto/cipher-builtin.c.inc
+++ b/crypto/cipher-builtin.c.inc
@@ -104,61 +104,50 @@ static void do_aes_decrypt_ecb(const void *vctx,
}
}
-static void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
- const unsigned long length, const AES_KEY *key,
- unsigned char *ivec, const int enc)
+static void do_aes_encrypt_cbc(const AES_KEY *key,
+ size_t len,
+ uint8_t *out,
+ const uint8_t *in,
+ uint8_t *ivec)
{
- unsigned long n;
- unsigned long len = length;
- unsigned char tmp[AES_BLOCK_SIZE];
-
- assert(in && out && key && ivec);
-
- if (enc) {
- while (len >= AES_BLOCK_SIZE) {
- for (n = 0; n < AES_BLOCK_SIZE; ++n) {
- tmp[n] = in[n] ^ ivec[n];
- }
- AES_encrypt(tmp, out, key);
- memcpy(ivec, out, AES_BLOCK_SIZE);
- len -= AES_BLOCK_SIZE;
- in += AES_BLOCK_SIZE;
- out += AES_BLOCK_SIZE;
- }
- if (len) {
- for (n = 0; n < len; ++n) {
- tmp[n] = in[n] ^ ivec[n];
- }
- for (n = len; n < AES_BLOCK_SIZE; ++n) {
- tmp[n] = ivec[n];
- }
- AES_encrypt(tmp, tmp, key);
- memcpy(out, tmp, AES_BLOCK_SIZE);
- memcpy(ivec, tmp, AES_BLOCK_SIZE);
- }
- } else {
- while (len >= AES_BLOCK_SIZE) {
- memcpy(tmp, in, AES_BLOCK_SIZE);
- AES_decrypt(in, out, key);
- for (n = 0; n < AES_BLOCK_SIZE; ++n) {
- out[n] ^= ivec[n];
- }
- memcpy(ivec, tmp, AES_BLOCK_SIZE);
- len -= AES_BLOCK_SIZE;
- in += AES_BLOCK_SIZE;
- out += AES_BLOCK_SIZE;
- }
- if (len) {
- memcpy(tmp, in, AES_BLOCK_SIZE);
- AES_decrypt(tmp, tmp, key);
- for (n = 0; n < len; ++n) {
- out[n] = tmp[n] ^ ivec[n];
- }
- memcpy(ivec, tmp, AES_BLOCK_SIZE);
+ uint8_t tmp[AES_BLOCK_SIZE];
+ size_t n;
+
+ /* We have already verified that len % AES_BLOCK_SIZE == 0. */
+ while (len) {
+ for (n = 0; n < AES_BLOCK_SIZE; ++n) {
+ tmp[n] = in[n] ^ ivec[n];
}
+ AES_encrypt(tmp, out, key);
+ memcpy(ivec, out, AES_BLOCK_SIZE);
+ len -= AES_BLOCK_SIZE;
+ in += AES_BLOCK_SIZE;
+ out += AES_BLOCK_SIZE;
}
}
+static void do_aes_decrypt_cbc(const AES_KEY *key,
+ size_t len,
+ uint8_t *out,
+ const uint8_t *in,
+ uint8_t *ivec)
+{
+ uint8_t tmp[AES_BLOCK_SIZE];
+ size_t n;
+
+ /* We have already verified that len % AES_BLOCK_SIZE == 0. */
+ while (len) {
+ memcpy(tmp, in, AES_BLOCK_SIZE);
+ AES_decrypt(in, out, key);
+ for (n = 0; n < AES_BLOCK_SIZE; ++n) {
+ out[n] ^= ivec[n];
+ }
+ memcpy(ivec, tmp, AES_BLOCK_SIZE);
+ len -= AES_BLOCK_SIZE;
+ in += AES_BLOCK_SIZE;
+ out += AES_BLOCK_SIZE;
+ }
+}
static int qcrypto_cipher_encrypt_aes(QCryptoCipher *cipher,
const void *in,
@@ -174,9 +163,8 @@ static int qcrypto_cipher_encrypt_aes(QCryptoCipher *cipher,
do_aes_encrypt_ecb(&ctxt->state.aes.key, len, out, in);
break;
case QCRYPTO_CIPHER_MODE_CBC:
- AES_cbc_encrypt(in, out, len,
- &ctxt->state.aes.key.enc,
- ctxt->state.aes.iv, 1);
+ do_aes_encrypt_cbc(&ctxt->state.aes.key.enc, len, out, in,
+ ctxt->state.aes.iv);
break;
case QCRYPTO_CIPHER_MODE_XTS:
xts_encrypt(&ctxt->state.aes.key,
@@ -208,9 +196,8 @@ static int qcrypto_cipher_decrypt_aes(QCryptoCipher *cipher,
do_aes_decrypt_ecb(&ctxt->state.aes.key, len, out, in);
break;
case QCRYPTO_CIPHER_MODE_CBC:
- AES_cbc_encrypt(in, out, len,
- &ctxt->state.aes.key.dec,
- ctxt->state.aes.iv, 0);
+ do_aes_decrypt_cbc(&ctxt->state.aes.key.dec, len, out, in,
+ ctxt->state.aes.iv);
break;
case QCRYPTO_CIPHER_MODE_XTS:
xts_decrypt(&ctxt->state.aes.key,
--
2.26.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PULL 15/17] crypto/builtin: Split QCryptoCipherBuiltin into subclasses
2020-09-10 10:06 [PULL 00/17] Crypto next patches Daniel P. Berrangé
` (13 preceding siblings ...)
2020-09-10 10:06 ` [PULL 14/17] crypto/builtin: Split and simplify AES_encrypt_cbc Daniel P. Berrangé
@ 2020-09-10 10:06 ` Daniel P. Berrangé
2020-09-10 10:06 ` [PULL 16/17] crypto/nettle: Split QCryptoCipherNettle " Daniel P. Berrangé
` (2 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Daniel P. Berrangé @ 2020-09-10 10:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson, Daniel P. Berrangé
From: Richard Henderson <richard.henderson@linaro.org>
We had a second set of function pointers in QCryptoCipherBuiltin,
which are redundant with QCryptoCipherDriver. Split the AES and
DES implementations to avoid one level of indirection.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
crypto/cipher-builtin.c.inc | 519 +++++++++++++++---------------------
1 file changed, 210 insertions(+), 309 deletions(-)
diff --git a/crypto/cipher-builtin.c.inc b/crypto/cipher-builtin.c.inc
index b1fe3b08c3..7597cf4a10 100644
--- a/crypto/cipher-builtin.c.inc
+++ b/crypto/cipher-builtin.c.inc
@@ -22,56 +22,45 @@
#include "crypto/desrfb.h"
#include "crypto/xts.h"
-static const struct QCryptoCipherDriver qcrypto_cipher_lib_driver;
-
typedef struct QCryptoCipherBuiltinAESContext QCryptoCipherBuiltinAESContext;
struct QCryptoCipherBuiltinAESContext {
AES_KEY enc;
AES_KEY dec;
};
+
typedef struct QCryptoCipherBuiltinAES QCryptoCipherBuiltinAES;
struct QCryptoCipherBuiltinAES {
+ QCryptoCipher base;
QCryptoCipherBuiltinAESContext key;
QCryptoCipherBuiltinAESContext key_tweak;
uint8_t iv[AES_BLOCK_SIZE];
};
-typedef struct QCryptoCipherBuiltinDESRFB QCryptoCipherBuiltinDESRFB;
-struct QCryptoCipherBuiltinDESRFB {
- uint8_t *key;
- size_t nkey;
-};
-typedef struct QCryptoCipherBuiltin QCryptoCipherBuiltin;
-struct QCryptoCipherBuiltin {
- QCryptoCipher base;
-
- union {
- QCryptoCipherBuiltinAES aes;
- QCryptoCipherBuiltinDESRFB desrfb;
- } state;
- size_t blocksize;
- void (*free)(QCryptoCipher *cipher);
- int (*setiv)(QCryptoCipher *cipher,
- const uint8_t *iv, size_t niv,
- Error **errp);
- int (*encrypt)(QCryptoCipher *cipher,
- const void *in,
- void *out,
- size_t len,
- Error **errp);
- int (*decrypt)(QCryptoCipher *cipher,
- const void *in,
- void *out,
- size_t len,
- Error **errp);
-};
+static inline bool qcrypto_length_check(size_t len, size_t blocksize,
+ Error **errp)
+{
+ if (unlikely(len & (blocksize - 1))) {
+ error_setg(errp, "Length %zu must be a multiple of block size %zu",
+ len, blocksize);
+ return false;
+ }
+ return true;
+}
-static void qcrypto_cipher_free_aes(QCryptoCipher *cipher)
+static void qcrypto_cipher_ctx_free(QCryptoCipher *cipher)
{
g_free(cipher);
}
+static int qcrypto_cipher_no_setiv(QCryptoCipher *cipher,
+ const uint8_t *iv, size_t niv,
+ Error **errp)
+{
+ error_setg(errp, "Setting IV is not supported");
+ return -1;
+}
+
static void do_aes_encrypt_ecb(const void *vctx,
size_t len,
uint8_t *out,
@@ -149,185 +138,154 @@ static void do_aes_decrypt_cbc(const AES_KEY *key,
}
}
-static int qcrypto_cipher_encrypt_aes(QCryptoCipher *cipher,
- const void *in,
- void *out,
- size_t len,
- Error **errp)
+static int qcrypto_cipher_aes_encrypt_ecb(QCryptoCipher *cipher,
+ const void *in, void *out,
+ size_t len, Error **errp)
{
- QCryptoCipherBuiltin *ctxt
- = container_of(cipher, QCryptoCipherBuiltin, base);
+ QCryptoCipherBuiltinAES *ctx
+ = container_of(cipher, QCryptoCipherBuiltinAES, base);
- switch (cipher->mode) {
- case QCRYPTO_CIPHER_MODE_ECB:
- do_aes_encrypt_ecb(&ctxt->state.aes.key, len, out, in);
- break;
- case QCRYPTO_CIPHER_MODE_CBC:
- do_aes_encrypt_cbc(&ctxt->state.aes.key.enc, len, out, in,
- ctxt->state.aes.iv);
- break;
- case QCRYPTO_CIPHER_MODE_XTS:
- xts_encrypt(&ctxt->state.aes.key,
- &ctxt->state.aes.key_tweak,
- do_aes_encrypt_ecb,
- do_aes_decrypt_ecb,
- ctxt->state.aes.iv,
- len, out, in);
- break;
- default:
- g_assert_not_reached();
+ if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) {
+ return -1;
}
-
+ do_aes_encrypt_ecb(&ctx->key, len, out, in);
return 0;
}
-
-static int qcrypto_cipher_decrypt_aes(QCryptoCipher *cipher,
- const void *in,
- void *out,
- size_t len,
- Error **errp)
+static int qcrypto_cipher_aes_decrypt_ecb(QCryptoCipher *cipher,
+ const void *in, void *out,
+ size_t len, Error **errp)
{
- QCryptoCipherBuiltin *ctxt
- = container_of(cipher, QCryptoCipherBuiltin, base);
+ QCryptoCipherBuiltinAES *ctx
+ = container_of(cipher, QCryptoCipherBuiltinAES, base);
- switch (cipher->mode) {
- case QCRYPTO_CIPHER_MODE_ECB:
- do_aes_decrypt_ecb(&ctxt->state.aes.key, len, out, in);
- break;
- case QCRYPTO_CIPHER_MODE_CBC:
- do_aes_decrypt_cbc(&ctxt->state.aes.key.dec, len, out, in,
- ctxt->state.aes.iv);
- break;
- case QCRYPTO_CIPHER_MODE_XTS:
- xts_decrypt(&ctxt->state.aes.key,
- &ctxt->state.aes.key_tweak,
- do_aes_encrypt_ecb,
- do_aes_decrypt_ecb,
- ctxt->state.aes.iv,
- len, out, in);
- break;
- default:
- g_assert_not_reached();
+ if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) {
+ return -1;
}
-
+ do_aes_decrypt_ecb(&ctx->key, len, out, in);
return 0;
}
-static int qcrypto_cipher_setiv_aes(QCryptoCipher *cipher,
- const uint8_t *iv, size_t niv,
- Error **errp)
+static int qcrypto_cipher_aes_encrypt_cbc(QCryptoCipher *cipher,
+ const void *in, void *out,
+ size_t len, Error **errp)
{
- QCryptoCipherBuiltin *ctxt
- = container_of(cipher, QCryptoCipherBuiltin, base);
+ QCryptoCipherBuiltinAES *ctx
+ = container_of(cipher, QCryptoCipherBuiltinAES, base);
- if (niv != AES_BLOCK_SIZE) {
- error_setg(errp, "IV must be %d bytes not %zu",
- AES_BLOCK_SIZE, niv);
+ if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) {
return -1;
}
-
- memcpy(ctxt->state.aes.iv, iv, AES_BLOCK_SIZE);
-
+ do_aes_encrypt_cbc(&ctx->key.enc, len, out, in, ctx->iv);
return 0;
}
+static int qcrypto_cipher_aes_decrypt_cbc(QCryptoCipher *cipher,
+ const void *in, void *out,
+ size_t len, Error **errp)
+{
+ QCryptoCipherBuiltinAES *ctx
+ = container_of(cipher, QCryptoCipherBuiltinAES, base);
+ if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) {
+ return -1;
+ }
+ do_aes_decrypt_cbc(&ctx->key.dec, len, out, in, ctx->iv);
+ return 0;
+}
-
-static QCryptoCipher *
-qcrypto_cipher_init_aes(QCryptoCipherMode mode,
- const uint8_t *key, size_t nkey,
- Error **errp)
+static int qcrypto_cipher_aes_encrypt_xts(QCryptoCipher *cipher,
+ const void *in, void *out,
+ size_t len, Error **errp)
{
- QCryptoCipherBuiltin *ctxt;
+ QCryptoCipherBuiltinAES *ctx
+ = container_of(cipher, QCryptoCipherBuiltinAES, base);
- if (mode != QCRYPTO_CIPHER_MODE_CBC &&
- mode != QCRYPTO_CIPHER_MODE_ECB &&
- mode != QCRYPTO_CIPHER_MODE_XTS) {
- error_setg(errp, "Unsupported cipher mode %s",
- QCryptoCipherMode_str(mode));
- return NULL;
+ if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) {
+ return -1;
}
+ xts_encrypt(&ctx->key, &ctx->key_tweak,
+ do_aes_encrypt_ecb, do_aes_decrypt_ecb,
+ ctx->iv, len, out, in);
+ return 0;
+}
- ctxt = g_new0(QCryptoCipherBuiltin, 1);
+static int qcrypto_cipher_aes_decrypt_xts(QCryptoCipher *cipher,
+ const void *in, void *out,
+ size_t len, Error **errp)
+{
+ QCryptoCipherBuiltinAES *ctx
+ = container_of(cipher, QCryptoCipherBuiltinAES, base);
- if (mode == QCRYPTO_CIPHER_MODE_XTS) {
- if (AES_set_encrypt_key(key, nkey * 4, &ctxt->state.aes.key.enc) != 0) {
- error_setg(errp, "Failed to set encryption key");
- goto error;
- }
+ if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) {
+ return -1;
+ }
+ xts_decrypt(&ctx->key, &ctx->key_tweak,
+ do_aes_encrypt_ecb, do_aes_decrypt_ecb,
+ ctx->iv, len, out, in);
+ return 0;
+}
- if (AES_set_decrypt_key(key, nkey * 4, &ctxt->state.aes.key.dec) != 0) {
- error_setg(errp, "Failed to set decryption key");
- goto error;
- }
- if (AES_set_encrypt_key(key + (nkey / 2), nkey * 4,
- &ctxt->state.aes.key_tweak.enc) != 0) {
- error_setg(errp, "Failed to set encryption key");
- goto error;
- }
-
- if (AES_set_decrypt_key(key + (nkey / 2), nkey * 4,
- &ctxt->state.aes.key_tweak.dec) != 0) {
- error_setg(errp, "Failed to set decryption key");
- goto error;
- }
- } else {
- if (AES_set_encrypt_key(key, nkey * 8, &ctxt->state.aes.key.enc) != 0) {
- error_setg(errp, "Failed to set encryption key");
- goto error;
- }
+static int qcrypto_cipher_aes_setiv(QCryptoCipher *cipher, const uint8_t *iv,
+ size_t niv, Error **errp)
+{
+ QCryptoCipherBuiltinAES *ctx
+ = container_of(cipher, QCryptoCipherBuiltinAES, base);
- if (AES_set_decrypt_key(key, nkey * 8, &ctxt->state.aes.key.dec) != 0) {
- error_setg(errp, "Failed to set decryption key");
- goto error;
- }
+ if (niv != AES_BLOCK_SIZE) {
+ error_setg(errp, "IV must be %d bytes not %zu",
+ AES_BLOCK_SIZE, niv);
+ return -1;
}
- ctxt->blocksize = AES_BLOCK_SIZE;
- ctxt->free = qcrypto_cipher_free_aes;
- ctxt->setiv = qcrypto_cipher_setiv_aes;
- ctxt->encrypt = qcrypto_cipher_encrypt_aes;
- ctxt->decrypt = qcrypto_cipher_decrypt_aes;
+ memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
+ return 0;
+}
- ctxt->base.driver = &qcrypto_cipher_lib_driver;
- return &ctxt->base;
+static const struct QCryptoCipherDriver qcrypto_cipher_aes_driver_ecb = {
+ .cipher_encrypt = qcrypto_cipher_aes_encrypt_ecb,
+ .cipher_decrypt = qcrypto_cipher_aes_decrypt_ecb,
+ .cipher_setiv = qcrypto_cipher_no_setiv,
+ .cipher_free = qcrypto_cipher_ctx_free,
+};
- error:
- g_free(ctxt);
- return NULL;
-}
+static const struct QCryptoCipherDriver qcrypto_cipher_aes_driver_cbc = {
+ .cipher_encrypt = qcrypto_cipher_aes_encrypt_cbc,
+ .cipher_decrypt = qcrypto_cipher_aes_decrypt_cbc,
+ .cipher_setiv = qcrypto_cipher_aes_setiv,
+ .cipher_free = qcrypto_cipher_ctx_free,
+};
+static const struct QCryptoCipherDriver qcrypto_cipher_aes_driver_xts = {
+ .cipher_encrypt = qcrypto_cipher_aes_encrypt_xts,
+ .cipher_decrypt = qcrypto_cipher_aes_decrypt_xts,
+ .cipher_setiv = qcrypto_cipher_aes_setiv,
+ .cipher_free = qcrypto_cipher_ctx_free,
+};
-static void qcrypto_cipher_free_des_rfb(QCryptoCipher *cipher)
-{
- QCryptoCipherBuiltin *ctxt
- = container_of(cipher, QCryptoCipherBuiltin, base);
- g_free(ctxt->state.desrfb.key);
- g_free(ctxt);
-}
+typedef struct QCryptoCipherBuiltinDESRFB QCryptoCipherBuiltinDESRFB;
+struct QCryptoCipherBuiltinDESRFB {
+ QCryptoCipher base;
+ /* C.f. alg_key_len[QCRYPTO_CIPHER_ALG_DES_RFB] */
+ uint8_t key[8];
+};
static int qcrypto_cipher_encrypt_des_rfb(QCryptoCipher *cipher,
- const void *in,
- void *out,
- size_t len,
- Error **errp)
+ const void *in, void *out,
+ size_t len, Error **errp)
{
- QCryptoCipherBuiltin *ctxt
- = container_of(cipher, QCryptoCipherBuiltin, base);
+ QCryptoCipherBuiltinDESRFB *ctx
+ = container_of(cipher, QCryptoCipherBuiltinDESRFB, base);
size_t i;
- if (len % 8) {
- error_setg(errp, "Buffer size must be multiple of 8 not %zu",
- len);
+ if (!qcrypto_length_check(len, 8, errp)) {
return -1;
}
- deskey(ctxt->state.desrfb.key, EN0);
+ deskey(ctx->key, EN0);
for (i = 0; i < len; i += 8) {
des((void *)in + i, out + i);
@@ -336,24 +294,19 @@ static int qcrypto_cipher_encrypt_des_rfb(QCryptoCipher *cipher,
return 0;
}
-
static int qcrypto_cipher_decrypt_des_rfb(QCryptoCipher *cipher,
- const void *in,
- void *out,
- size_t len,
- Error **errp)
+ const void *in, void *out,
+ size_t len, Error **errp)
{
- QCryptoCipherBuiltin *ctxt
- = container_of(cipher, QCryptoCipherBuiltin, base);
+ QCryptoCipherBuiltinDESRFB *ctx
+ = container_of(cipher, QCryptoCipherBuiltinDESRFB, base);
size_t i;
- if (len % 8) {
- error_setg(errp, "Buffer size must be multiple of 8 not %zu",
- len);
+ if (!qcrypto_length_check(len, 8, errp)) {
return -1;
}
- deskey(ctxt->state.desrfb.key, DE1);
+ deskey(ctx->key, DE1);
for (i = 0; i < len; i += 8) {
des((void *)in + i, out + i);
@@ -362,173 +315,121 @@ static int qcrypto_cipher_decrypt_des_rfb(QCryptoCipher *cipher,
return 0;
}
-
-static int qcrypto_cipher_setiv_des_rfb(QCryptoCipher *cipher,
- const uint8_t *iv, size_t niv,
- Error **errp)
-{
- error_setg(errp, "Setting IV is not supported");
- return -1;
-}
-
-
-static QCryptoCipher *
-qcrypto_cipher_init_des_rfb(QCryptoCipherMode mode,
- const uint8_t *key, size_t nkey,
- Error **errp)
-{
- QCryptoCipherBuiltin *ctxt;
-
- if (mode != QCRYPTO_CIPHER_MODE_ECB) {
- error_setg(errp, "Unsupported cipher mode %s",
- QCryptoCipherMode_str(mode));
- return NULL;
- }
-
- ctxt = g_new0(QCryptoCipherBuiltin, 1);
-
- ctxt->state.desrfb.key = g_new0(uint8_t, nkey);
- memcpy(ctxt->state.desrfb.key, key, nkey);
- ctxt->state.desrfb.nkey = nkey;
-
- ctxt->blocksize = 8;
- ctxt->free = qcrypto_cipher_free_des_rfb;
- ctxt->setiv = qcrypto_cipher_setiv_des_rfb;
- ctxt->encrypt = qcrypto_cipher_encrypt_des_rfb;
- ctxt->decrypt = qcrypto_cipher_decrypt_des_rfb;
-
- ctxt->base.driver = &qcrypto_cipher_lib_driver;
- return &ctxt->base;
-}
-
+static const struct QCryptoCipherDriver qcrypto_cipher_des_rfb_driver = {
+ .cipher_encrypt = qcrypto_cipher_encrypt_des_rfb,
+ .cipher_decrypt = qcrypto_cipher_decrypt_des_rfb,
+ .cipher_setiv = qcrypto_cipher_no_setiv,
+ .cipher_free = qcrypto_cipher_ctx_free,
+};
bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode)
{
switch (alg) {
case QCRYPTO_CIPHER_ALG_DES_RFB:
+ return mode == QCRYPTO_CIPHER_MODE_ECB;
case QCRYPTO_CIPHER_ALG_AES_128:
case QCRYPTO_CIPHER_ALG_AES_192:
case QCRYPTO_CIPHER_ALG_AES_256:
+ switch (mode) {
+ case QCRYPTO_CIPHER_MODE_ECB:
+ case QCRYPTO_CIPHER_MODE_CBC:
+ case QCRYPTO_CIPHER_MODE_XTS:
+ return true;
+ default:
+ return false;
+ }
break;
default:
return false;
}
-
- switch (mode) {
- case QCRYPTO_CIPHER_MODE_ECB:
- case QCRYPTO_CIPHER_MODE_CBC:
- case QCRYPTO_CIPHER_MODE_XTS:
- return true;
- case QCRYPTO_CIPHER_MODE_CTR:
- return false;
- default:
- return false;
- }
}
-
static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode,
const uint8_t *key,
size_t nkey,
Error **errp)
{
- switch (mode) {
- case QCRYPTO_CIPHER_MODE_ECB:
- case QCRYPTO_CIPHER_MODE_CBC:
- case QCRYPTO_CIPHER_MODE_XTS:
- break;
- default:
- error_setg(errp, "Unsupported cipher mode %s",
- QCryptoCipherMode_str(mode));
- return NULL;
- }
-
if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) {
return NULL;
}
switch (alg) {
case QCRYPTO_CIPHER_ALG_DES_RFB:
- return qcrypto_cipher_init_des_rfb(mode, key, nkey, errp);
+ if (mode == QCRYPTO_CIPHER_MODE_ECB) {
+ QCryptoCipherBuiltinDESRFB *ctx;
+
+ ctx = g_new0(QCryptoCipherBuiltinDESRFB, 1);
+ ctx->base.driver = &qcrypto_cipher_des_rfb_driver;
+ memcpy(ctx->key, key, sizeof(ctx->key));
+
+ return &ctx->base;
+ }
+ goto bad_mode;
+
case QCRYPTO_CIPHER_ALG_AES_128:
case QCRYPTO_CIPHER_ALG_AES_192:
case QCRYPTO_CIPHER_ALG_AES_256:
- return qcrypto_cipher_init_aes(mode, key, nkey, errp);
+ {
+ QCryptoCipherBuiltinAES *ctx;
+ const QCryptoCipherDriver *drv;
+
+ switch (mode) {
+ case QCRYPTO_CIPHER_MODE_ECB:
+ drv = &qcrypto_cipher_aes_driver_ecb;
+ break;
+ case QCRYPTO_CIPHER_MODE_CBC:
+ drv = &qcrypto_cipher_aes_driver_cbc;
+ break;
+ case QCRYPTO_CIPHER_MODE_XTS:
+ drv = &qcrypto_cipher_aes_driver_xts;
+ break;
+ default:
+ goto bad_mode;
+ }
+
+ ctx = g_new0(QCryptoCipherBuiltinAES, 1);
+ ctx->base.driver = drv;
+
+ if (mode == QCRYPTO_CIPHER_MODE_XTS) {
+ nkey /= 2;
+ if (AES_set_encrypt_key(key + nkey, nkey * 8,
+ &ctx->key_tweak.enc)) {
+ error_setg(errp, "Failed to set encryption key");
+ goto error;
+ }
+ if (AES_set_decrypt_key(key + nkey, nkey * 8,
+ &ctx->key_tweak.dec)) {
+ error_setg(errp, "Failed to set decryption key");
+ goto error;
+ }
+ }
+ if (AES_set_encrypt_key(key, nkey * 8, &ctx->key.enc)) {
+ error_setg(errp, "Failed to set encryption key");
+ goto error;
+ }
+ if (AES_set_decrypt_key(key, nkey * 8, &ctx->key.dec)) {
+ error_setg(errp, "Failed to set decryption key");
+ goto error;
+ }
+
+ return &ctx->base;
+
+ error:
+ g_free(ctx);
+ return NULL;
+ }
+
default:
error_setg(errp,
"Unsupported cipher algorithm %s",
QCryptoCipherAlgorithm_str(alg));
return NULL;
}
-}
-
-static void
-qcrypto_builtin_cipher_ctx_free(QCryptoCipher *cipher)
-{
- QCryptoCipherBuiltin *ctxt
- = container_of(cipher, QCryptoCipherBuiltin, base);
-
- ctxt->free(cipher);
-}
-
-static int
-qcrypto_builtin_cipher_encrypt(QCryptoCipher *cipher,
- const void *in,
- void *out,
- size_t len,
- Error **errp)
-{
- QCryptoCipherBuiltin *ctxt
- = container_of(cipher, QCryptoCipherBuiltin, base);
-
- if (len & (ctxt->blocksize - 1)) {
- error_setg(errp, "Length %zu must be a multiple of block size %zu",
- len, ctxt->blocksize);
- return -1;
- }
-
- return ctxt->encrypt(cipher, in, out, len, errp);
-}
-
-
-static int
-qcrypto_builtin_cipher_decrypt(QCryptoCipher *cipher,
- const void *in,
- void *out,
- size_t len,
- Error **errp)
-{
- QCryptoCipherBuiltin *ctxt
- = container_of(cipher, QCryptoCipherBuiltin, base);
-
- if (len & (ctxt->blocksize - 1)) {
- error_setg(errp, "Length %zu must be a multiple of block size %zu",
- len, ctxt->blocksize);
- return -1;
- }
-
- return ctxt->decrypt(cipher, in, out, len, errp);
-}
-
-
-static int
-qcrypto_builtin_cipher_setiv(QCryptoCipher *cipher,
- const uint8_t *iv, size_t niv,
- Error **errp)
-{
- QCryptoCipherBuiltin *ctxt
- = container_of(cipher, QCryptoCipherBuiltin, base);
-
- return ctxt->setiv(cipher, iv, niv, errp);
+ bad_mode:
+ error_setg(errp, "Unsupported cipher mode %s",
+ QCryptoCipherMode_str(mode));
+ return NULL;
}
-
-
-static const struct QCryptoCipherDriver qcrypto_cipher_lib_driver = {
- .cipher_encrypt = qcrypto_builtin_cipher_encrypt,
- .cipher_decrypt = qcrypto_builtin_cipher_decrypt,
- .cipher_setiv = qcrypto_builtin_cipher_setiv,
- .cipher_free = qcrypto_builtin_cipher_ctx_free,
-};
--
2.26.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PULL 16/17] crypto/nettle: Split QCryptoCipherNettle into subclasses
2020-09-10 10:06 [PULL 00/17] Crypto next patches Daniel P. Berrangé
` (14 preceding siblings ...)
2020-09-10 10:06 ` [PULL 15/17] crypto/builtin: Split QCryptoCipherBuiltin into subclasses Daniel P. Berrangé
@ 2020-09-10 10:06 ` Daniel P. Berrangé
2020-09-10 10:06 ` [PULL 17/17] crypto/gcrypt: Split QCryptoCipherGcrypt " Daniel P. Berrangé
2020-09-12 21:53 ` [PULL 00/17] Crypto next patches Peter Maydell
17 siblings, 0 replies; 19+ messages in thread
From: Daniel P. Berrangé @ 2020-09-10 10:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson, Daniel P. Berrangé
From: Richard Henderson <richard.henderson@linaro.org>
Use separate classes for each cipher entry point: des_rfb, des3,
aes128, aes192, aes256, cast128, serpent, and twofish.
Generate wrappers for XTS only for CONFIG_QEMU_PRIVATE_XTS.
This eliminates unreachable wrappers for DES_RFB, DES3 and
CAST128, which have blocksizes that do not allow XTS mode.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
crypto/cipher-nettle.c.inc | 999 +++++++++++++++++++------------------
1 file changed, 511 insertions(+), 488 deletions(-)
diff --git a/crypto/cipher-nettle.c.inc b/crypto/cipher-nettle.c.inc
index 36d57ef430..cac771e4ff 100644
--- a/crypto/cipher-nettle.c.inc
+++ b/crypto/cipher-nettle.c.inc
@@ -34,8 +34,6 @@
#include <nettle/xts.h>
#endif
-static const struct QCryptoCipherDriver qcrypto_cipher_lib_driver;
-
typedef void (*QCryptoCipherNettleFuncWrapper)(const void *ctx,
size_t length,
uint8_t *dst,
@@ -45,6 +43,7 @@ typedef void (*QCryptoCipherNettleFuncWrapper)(const void *ctx,
typedef nettle_crypt_func * QCryptoCipherNettleFuncNative;
typedef void * cipher_ctx_t;
typedef unsigned cipher_length_t;
+#define CONST_CTX
#define cast5_set_key cast128_set_key
@@ -73,64 +72,215 @@ typedef unsigned cipher_length_t;
typedef nettle_cipher_func * QCryptoCipherNettleFuncNative;
typedef const void * cipher_ctx_t;
typedef size_t cipher_length_t;
+#define CONST_CTX const
#endif
-typedef struct QCryptoNettleAES128 {
- struct aes128_ctx enc;
- struct aes128_ctx dec;
-} QCryptoNettleAES128;
-
-typedef struct QCryptoNettleAES192 {
- struct aes192_ctx enc;
- struct aes192_ctx dec;
-} QCryptoNettleAES192;
-
-typedef struct QCryptoNettleAES256 {
- struct aes256_ctx enc;
- struct aes256_ctx dec;
-} QCryptoNettleAES256;
-
-static void aes128_encrypt_native(cipher_ctx_t ctx, cipher_length_t length,
- uint8_t *dst, const uint8_t *src)
+static inline bool qcrypto_length_check(size_t len, size_t blocksize,
+ Error **errp)
{
- const QCryptoNettleAES128 *aesctx = ctx;
- aes128_encrypt(&aesctx->enc, length, dst, src);
+ if (unlikely(len & (blocksize - 1))) {
+ error_setg(errp, "Length %zu must be a multiple of block size %zu",
+ len, blocksize);
+ return false;
+ }
+ return true;
}
-static void aes128_decrypt_native(cipher_ctx_t ctx, cipher_length_t length,
- uint8_t *dst, const uint8_t *src)
-{
- const QCryptoNettleAES128 *aesctx = ctx;
- aes128_decrypt(&aesctx->dec, length, dst, src);
-}
-static void aes192_encrypt_native(cipher_ctx_t ctx, cipher_length_t length,
- uint8_t *dst, const uint8_t *src)
+static void qcrypto_cipher_ctx_free(QCryptoCipher *ctx)
{
- const QCryptoNettleAES192 *aesctx = ctx;
- aes192_encrypt(&aesctx->enc, length, dst, src);
+ g_free(ctx);
}
-static void aes192_decrypt_native(cipher_ctx_t ctx, cipher_length_t length,
- uint8_t *dst, const uint8_t *src)
-{
- const QCryptoNettleAES192 *aesctx = ctx;
- aes192_decrypt(&aesctx->dec, length, dst, src);
-}
+static int qcrypto_cipher_no_setiv(QCryptoCipher *cipher,
+ const uint8_t *iv, size_t niv,
+ Error **errp)
+{
+ error_setg(errp, "Setting IV is not supported");
+ return -1;
+}
+
+
+#define DEFINE_SETIV(NAME, TYPE, BLEN) \
+static int NAME##_setiv(QCryptoCipher *cipher, const uint8_t *iv, \
+ size_t niv, Error **errp) \
+{ \
+ TYPE *ctx = container_of(cipher, TYPE, base); \
+ if (niv != BLEN) { \
+ error_setg(errp, "Expected IV size %d not %zu", BLEN, niv); \
+ return -1; \
+ } \
+ memcpy(ctx->iv, iv, niv); \
+ return 0; \
+}
+
+
+#define DEFINE_ECB(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \
+static int NAME##_encrypt_ecb(QCryptoCipher *cipher, const void *in, \
+ void *out, size_t len, Error **errp) \
+{ \
+ TYPE *ctx = container_of(cipher, TYPE, base); \
+ if (!qcrypto_length_check(len, BLEN, errp)) { \
+ return -1; \
+ } \
+ ENCRYPT(&ctx->key, len, out, in); \
+ return 0; \
+} \
+static int NAME##_decrypt_ecb(QCryptoCipher *cipher, const void *in, \
+ void *out, size_t len, Error **errp) \
+{ \
+ TYPE *ctx = container_of(cipher, TYPE, base); \
+ if (!qcrypto_length_check(len, BLEN, errp)) { \
+ return -1; \
+ } \
+ DECRYPT(&ctx->key, len, out, in); \
+ return 0; \
+} \
+static const struct QCryptoCipherDriver NAME##_driver_ecb = { \
+ .cipher_encrypt = NAME##_encrypt_ecb, \
+ .cipher_decrypt = NAME##_decrypt_ecb, \
+ .cipher_setiv = qcrypto_cipher_no_setiv, \
+ .cipher_free = qcrypto_cipher_ctx_free, \
+};
-static void aes256_encrypt_native(cipher_ctx_t ctx, cipher_length_t length,
- uint8_t *dst, const uint8_t *src)
-{
- const QCryptoNettleAES256 *aesctx = ctx;
- aes256_encrypt(&aesctx->enc, length, dst, src);
-}
-static void aes256_decrypt_native(cipher_ctx_t ctx, cipher_length_t length,
- uint8_t *dst, const uint8_t *src)
-{
- const QCryptoNettleAES256 *aesctx = ctx;
- aes256_decrypt(&aesctx->dec, length, dst, src);
+#define DEFINE_CBC(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \
+static int NAME##_encrypt_cbc(QCryptoCipher *cipher, const void *in, \
+ void *out, size_t len, Error **errp) \
+{ \
+ TYPE *ctx = container_of(cipher, TYPE, base); \
+ if (!qcrypto_length_check(len, BLEN, errp)) { \
+ return -1; \
+ } \
+ cbc_encrypt(&ctx->key, ENCRYPT, BLEN, ctx->iv, len, out, in); \
+ return 0; \
+} \
+static int NAME##_decrypt_cbc(QCryptoCipher *cipher, const void *in, \
+ void *out, size_t len, Error **errp) \
+{ \
+ TYPE *ctx = container_of(cipher, TYPE, base); \
+ if (!qcrypto_length_check(len, BLEN, errp)) { \
+ return -1; \
+ } \
+ cbc_decrypt(&ctx->key, DECRYPT, BLEN, ctx->iv, len, out, in); \
+ return 0; \
+} \
+static const struct QCryptoCipherDriver NAME##_driver_cbc = { \
+ .cipher_encrypt = NAME##_encrypt_cbc, \
+ .cipher_decrypt = NAME##_decrypt_cbc, \
+ .cipher_setiv = NAME##_setiv, \
+ .cipher_free = qcrypto_cipher_ctx_free, \
+};
+
+
+#define DEFINE_CTR(NAME, TYPE, BLEN, ENCRYPT) \
+static int NAME##_encrypt_ctr(QCryptoCipher *cipher, const void *in, \
+ void *out, size_t len, Error **errp) \
+{ \
+ TYPE *ctx = container_of(cipher, TYPE, base); \
+ if (!qcrypto_length_check(len, BLEN, errp)) { \
+ return -1; \
+ } \
+ ctr_crypt(&ctx->key, ENCRYPT, BLEN, ctx->iv, len, out, in); \
+ return 0; \
+} \
+static const struct QCryptoCipherDriver NAME##_driver_ctr = { \
+ .cipher_encrypt = NAME##_encrypt_ctr, \
+ .cipher_decrypt = NAME##_encrypt_ctr, \
+ .cipher_setiv = NAME##_setiv, \
+ .cipher_free = qcrypto_cipher_ctx_free, \
+};
+
+
+#ifdef CONFIG_QEMU_PRIVATE_XTS
+#define DEFINE__XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \
+static void NAME##_xts_wrape(const void *ctx, size_t length, \
+ uint8_t *dst, const uint8_t *src) \
+{ \
+ ENCRYPT((cipher_ctx_t)ctx, length, dst, src); \
+} \
+static void NAME##_xts_wrapd(const void *ctx, size_t length, \
+ uint8_t *dst, const uint8_t *src) \
+{ \
+ DECRYPT((cipher_ctx_t)ctx, length, dst, src); \
+} \
+static int NAME##_encrypt_xts(QCryptoCipher *cipher, const void *in, \
+ void *out, size_t len, Error **errp) \
+{ \
+ TYPE *ctx = container_of(cipher, TYPE, base); \
+ if (!qcrypto_length_check(len, BLEN, errp)) { \
+ return -1; \
+ } \
+ xts_encrypt(&ctx->key, &ctx->key_xts, \
+ NAME##_xts_wrape, NAME##_xts_wrapd, \
+ ctx->iv, len, out, in); \
+ return 0; \
+} \
+static int NAME##_decrypt_xts(QCryptoCipher *cipher, const void *in, \
+ void *out, size_t len, Error **errp) \
+{ \
+ TYPE *ctx = container_of(cipher, TYPE, base); \
+ if (!qcrypto_length_check(len, BLEN, errp)) { \
+ return -1; \
+ } \
+ xts_decrypt(&ctx->key, &ctx->key_xts, \
+ NAME##_xts_wrape, NAME##_xts_wrapd, \
+ ctx->iv, len, out, in); \
+ return 0; \
+}
+#else
+#define DEFINE__XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \
+static int NAME##_encrypt_xts(QCryptoCipher *cipher, const void *in, \
+ void *out, size_t len, Error **errp) \
+{ \
+ TYPE *ctx = container_of(cipher, TYPE, base); \
+ if (!qcrypto_length_check(len, BLEN, errp)) { \
+ return -1; \
+ } \
+ xts_encrypt_message(&ctx->key, &ctx->key_xts, ENCRYPT, \
+ ctx->iv, len, out, in); \
+ return 0; \
+} \
+static int NAME##_decrypt_xts(QCryptoCipher *cipher, const void *in, \
+ void *out, size_t len, Error **errp) \
+{ \
+ TYPE *ctx = container_of(cipher, TYPE, base); \
+ if (!qcrypto_length_check(len, BLEN, errp)) { \
+ return -1; \
+ } \
+ xts_decrypt_message(&ctx->key, &ctx->key_xts, DECRYPT, ENCRYPT, \
+ ctx->iv, len, out, in); \
+ return 0; \
}
+#endif
+
+#define DEFINE_XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \
+ QEMU_BUILD_BUG_ON(BLEN != XTS_BLOCK_SIZE); \
+ DEFINE__XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \
+static const struct QCryptoCipherDriver NAME##_driver_xts = { \
+ .cipher_encrypt = NAME##_encrypt_xts, \
+ .cipher_decrypt = NAME##_decrypt_xts, \
+ .cipher_setiv = NAME##_setiv, \
+ .cipher_free = qcrypto_cipher_ctx_free, \
+};
+
+
+#define DEFINE_ECB_CBC_CTR(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \
+ DEFINE_SETIV(NAME, TYPE, BLEN) \
+ DEFINE_ECB(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \
+ DEFINE_CBC(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \
+ DEFINE_CTR(NAME, TYPE, BLEN, ENCRYPT)
+
+#define DEFINE_ECB_CBC_CTR_XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \
+ DEFINE_ECB_CBC_CTR(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \
+ DEFINE_XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT)
+
+
+typedef struct QCryptoNettleDESRFB {
+ QCryptoCipher base;
+ struct des_ctx key;
+ uint8_t iv[DES_BLOCK_SIZE];
+} QCryptoNettleDESRFB;
static void des_encrypt_native(cipher_ctx_t ctx, cipher_length_t length,
uint8_t *dst, const uint8_t *src)
@@ -144,6 +294,16 @@ static void des_decrypt_native(cipher_ctx_t ctx, cipher_length_t length,
des_decrypt(ctx, length, dst, src);
}
+DEFINE_ECB_CBC_CTR(qcrypto_nettle_des_rfb, QCryptoNettleDESRFB,
+ DES_BLOCK_SIZE, des_encrypt_native, des_decrypt_native)
+
+
+typedef struct QCryptoNettleDES3 {
+ QCryptoCipher base;
+ struct des3_ctx key;
+ uint8_t iv[DES3_BLOCK_SIZE];
+} QCryptoNettleDES3;
+
static void des3_encrypt_native(cipher_ctx_t ctx, cipher_length_t length,
uint8_t *dst, const uint8_t *src)
{
@@ -156,161 +316,157 @@ static void des3_decrypt_native(cipher_ctx_t ctx, cipher_length_t length,
des3_decrypt(ctx, length, dst, src);
}
-static void cast128_encrypt_native(cipher_ctx_t ctx, cipher_length_t length,
- uint8_t *dst, const uint8_t *src)
-{
- cast128_encrypt(ctx, length, dst, src);
-}
+DEFINE_ECB_CBC_CTR(qcrypto_nettle_des3, QCryptoNettleDES3, DES3_BLOCK_SIZE,
+ des3_encrypt_native, des3_decrypt_native)
-static void cast128_decrypt_native(cipher_ctx_t ctx, cipher_length_t length,
- uint8_t *dst, const uint8_t *src)
-{
- cast128_decrypt(ctx, length, dst, src);
-}
-static void serpent_encrypt_native(cipher_ctx_t ctx, cipher_length_t length,
- uint8_t *dst, const uint8_t *src)
-{
- serpent_encrypt(ctx, length, dst, src);
-}
+typedef struct QCryptoNettleAES128 {
+ QCryptoCipher base;
+ uint8_t iv[AES_BLOCK_SIZE];
+ /* First key from pair is encode, second key is decode. */
+ struct aes128_ctx key[2], key_xts[2];
+} QCryptoNettleAES128;
-static void serpent_decrypt_native(cipher_ctx_t ctx, cipher_length_t length,
- uint8_t *dst, const uint8_t *src)
+static void aes128_encrypt_native(cipher_ctx_t ctx, cipher_length_t length,
+ uint8_t *dst, const uint8_t *src)
{
- serpent_decrypt(ctx, length, dst, src);
+ CONST_CTX struct aes128_ctx *keys = ctx;
+ aes128_encrypt(&keys[0], length, dst, src);
}
-static void twofish_encrypt_native(cipher_ctx_t ctx, cipher_length_t length,
- uint8_t *dst, const uint8_t *src)
+static void aes128_decrypt_native(cipher_ctx_t ctx, cipher_length_t length,
+ uint8_t *dst, const uint8_t *src)
{
- twofish_encrypt(ctx, length, dst, src);
+ CONST_CTX struct aes128_ctx *keys = ctx;
+ aes128_decrypt(&keys[1], length, dst, src);
}
-static void twofish_decrypt_native(cipher_ctx_t ctx, cipher_length_t length,
- uint8_t *dst, const uint8_t *src)
-{
- twofish_decrypt(ctx, length, dst, src);
-}
+DEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_aes128,
+ QCryptoNettleAES128, AES_BLOCK_SIZE,
+ aes128_encrypt_native, aes128_decrypt_native)
-static void aes128_encrypt_wrapper(const void *ctx, size_t length,
- uint8_t *dst, const uint8_t *src)
-{
- const QCryptoNettleAES128 *aesctx = ctx;
- aes128_encrypt(&aesctx->enc, length, dst, src);
-}
-static void aes128_decrypt_wrapper(const void *ctx, size_t length,
- uint8_t *dst, const uint8_t *src)
-{
- const QCryptoNettleAES128 *aesctx = ctx;
- aes128_decrypt(&aesctx->dec, length, dst, src);
-}
+typedef struct QCryptoNettleAES192 {
+ QCryptoCipher base;
+ uint8_t iv[AES_BLOCK_SIZE];
+ /* First key from pair is encode, second key is decode. */
+ struct aes192_ctx key[2], key_xts[2];
+} QCryptoNettleAES192;
-static void aes192_encrypt_wrapper(const void *ctx, size_t length,
- uint8_t *dst, const uint8_t *src)
+static void aes192_encrypt_native(cipher_ctx_t ctx, cipher_length_t length,
+ uint8_t *dst, const uint8_t *src)
{
- const QCryptoNettleAES192 *aesctx = ctx;
- aes192_encrypt(&aesctx->enc, length, dst, src);
+ CONST_CTX struct aes192_ctx *keys = ctx;
+ aes192_encrypt(&keys[0], length, dst, src);
}
-static void aes192_decrypt_wrapper(const void *ctx, size_t length,
- uint8_t *dst, const uint8_t *src)
+static void aes192_decrypt_native(cipher_ctx_t ctx, cipher_length_t length,
+ uint8_t *dst, const uint8_t *src)
{
- const QCryptoNettleAES192 *aesctx = ctx;
- aes192_decrypt(&aesctx->dec, length, dst, src);
+ CONST_CTX struct aes192_ctx *keys = ctx;
+ aes192_decrypt(&keys[1], length, dst, src);
}
-static void aes256_encrypt_wrapper(const void *ctx, size_t length,
- uint8_t *dst, const uint8_t *src)
-{
- const QCryptoNettleAES256 *aesctx = ctx;
- aes256_encrypt(&aesctx->enc, length, dst, src);
-}
+DEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_aes192,
+ QCryptoNettleAES192, AES_BLOCK_SIZE,
+ aes192_encrypt_native, aes192_decrypt_native)
-static void aes256_decrypt_wrapper(const void *ctx, size_t length,
- uint8_t *dst, const uint8_t *src)
-{
- const QCryptoNettleAES256 *aesctx = ctx;
- aes256_decrypt(&aesctx->dec, length, dst, src);
-}
-static void des_encrypt_wrapper(const void *ctx, size_t length,
- uint8_t *dst, const uint8_t *src)
-{
- des_encrypt(ctx, length, dst, src);
-}
+typedef struct QCryptoNettleAES256 {
+ QCryptoCipher base;
+ uint8_t iv[AES_BLOCK_SIZE];
+ /* First key from pair is encode, second key is decode. */
+ struct aes256_ctx key[2], key_xts[2];
+} QCryptoNettleAES256;
-static void des_decrypt_wrapper(const void *ctx, size_t length,
- uint8_t *dst, const uint8_t *src)
+static void aes256_encrypt_native(cipher_ctx_t ctx, cipher_length_t length,
+ uint8_t *dst, const uint8_t *src)
{
- des_decrypt(ctx, length, dst, src);
+ CONST_CTX struct aes256_ctx *keys = ctx;
+ aes256_encrypt(&keys[0], length, dst, src);
}
-static void des3_encrypt_wrapper(const void *ctx, size_t length,
- uint8_t *dst, const uint8_t *src)
+static void aes256_decrypt_native(cipher_ctx_t ctx, cipher_length_t length,
+ uint8_t *dst, const uint8_t *src)
{
- des3_encrypt(ctx, length, dst, src);
+ CONST_CTX struct aes256_ctx *keys = ctx;
+ aes256_decrypt(&keys[1], length, dst, src);
}
-static void des3_decrypt_wrapper(const void *ctx, size_t length,
- uint8_t *dst, const uint8_t *src)
-{
- des3_decrypt(ctx, length, dst, src);
-}
+DEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_aes256,
+ QCryptoNettleAES256, AES_BLOCK_SIZE,
+ aes256_encrypt_native, aes256_decrypt_native)
-static void cast128_encrypt_wrapper(const void *ctx, size_t length,
- uint8_t *dst, const uint8_t *src)
+
+typedef struct QCryptoNettleCAST128 {
+ QCryptoCipher base;
+ uint8_t iv[CAST128_BLOCK_SIZE];
+ struct cast128_ctx key, key_xts;
+} QCryptoNettleCAST128;
+
+static void cast128_encrypt_native(cipher_ctx_t ctx, cipher_length_t length,
+ uint8_t *dst, const uint8_t *src)
{
cast128_encrypt(ctx, length, dst, src);
}
-static void cast128_decrypt_wrapper(const void *ctx, size_t length,
- uint8_t *dst, const uint8_t *src)
+static void cast128_decrypt_native(cipher_ctx_t ctx, cipher_length_t length,
+ uint8_t *dst, const uint8_t *src)
{
cast128_decrypt(ctx, length, dst, src);
}
-static void serpent_encrypt_wrapper(const void *ctx, size_t length,
- uint8_t *dst, const uint8_t *src)
+DEFINE_ECB_CBC_CTR(qcrypto_nettle_cast128,
+ QCryptoNettleCAST128, CAST128_BLOCK_SIZE,
+ cast128_encrypt_native, cast128_decrypt_native)
+
+
+typedef struct QCryptoNettleSerpent {
+ QCryptoCipher base;
+ uint8_t iv[SERPENT_BLOCK_SIZE];
+ struct serpent_ctx key, key_xts;
+} QCryptoNettleSerpent;
+
+
+static void serpent_encrypt_native(cipher_ctx_t ctx, cipher_length_t length,
+ uint8_t *dst, const uint8_t *src)
{
serpent_encrypt(ctx, length, dst, src);
}
-static void serpent_decrypt_wrapper(const void *ctx, size_t length,
- uint8_t *dst, const uint8_t *src)
+static void serpent_decrypt_native(cipher_ctx_t ctx, cipher_length_t length,
+ uint8_t *dst, const uint8_t *src)
{
serpent_decrypt(ctx, length, dst, src);
}
-static void twofish_encrypt_wrapper(const void *ctx, size_t length,
- uint8_t *dst, const uint8_t *src)
+DEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_serpent,
+ QCryptoNettleSerpent, SERPENT_BLOCK_SIZE,
+ serpent_encrypt_native, serpent_decrypt_native)
+
+
+typedef struct QCryptoNettleTwofish {
+ QCryptoCipher base;
+ uint8_t iv[TWOFISH_BLOCK_SIZE];
+ struct twofish_ctx key, key_xts;
+} QCryptoNettleTwofish;
+
+static void twofish_encrypt_native(cipher_ctx_t ctx, cipher_length_t length,
+ uint8_t *dst, const uint8_t *src)
{
twofish_encrypt(ctx, length, dst, src);
}
-static void twofish_decrypt_wrapper(const void *ctx, size_t length,
- uint8_t *dst, const uint8_t *src)
+static void twofish_decrypt_native(cipher_ctx_t ctx, cipher_length_t length,
+ uint8_t *dst, const uint8_t *src)
{
twofish_decrypt(ctx, length, dst, src);
}
-typedef struct QCryptoCipherNettle QCryptoCipherNettle;
-struct QCryptoCipherNettle {
- QCryptoCipher base;
+DEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_twofish,
+ QCryptoNettleTwofish, TWOFISH_BLOCK_SIZE,
+ twofish_encrypt_native, twofish_decrypt_native)
- /* Primary cipher context for all modes */
- void *ctx;
- /* Second cipher context for XTS mode only */
- void *ctx_tweak;
- /* Cipher callbacks for both contexts */
- QCryptoCipherNettleFuncNative alg_encrypt_native;
- QCryptoCipherNettleFuncNative alg_decrypt_native;
- QCryptoCipherNettleFuncWrapper alg_encrypt_wrapper;
- QCryptoCipherNettleFuncWrapper alg_decrypt_wrapper;
- /* Initialization vector or Counter */
- uint8_t *iv;
- size_t blocksize;
-};
bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode)
@@ -344,30 +500,12 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
}
}
-
-static void
-qcrypto_nettle_cipher_free_ctx(QCryptoCipherNettle *ctx)
-{
- if (!ctx) {
- return;
- }
-
- g_free(ctx->iv);
- g_free(ctx->ctx);
- g_free(ctx->ctx_tweak);
- g_free(ctx);
-}
-
-
static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode,
const uint8_t *key,
size_t nkey,
Error **errp)
{
- QCryptoCipherNettle *ctx;
- uint8_t *rfbkey;
-
switch (mode) {
case QCRYPTO_CIPHER_MODE_ECB:
case QCRYPTO_CIPHER_MODE_CBC:
@@ -375,363 +513,248 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
case QCRYPTO_CIPHER_MODE_CTR:
break;
default:
- error_setg(errp, "Unsupported cipher mode %s",
- QCryptoCipherMode_str(mode));
- return NULL;
+ goto bad_cipher_mode;
}
if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) {
return NULL;
}
- ctx = g_new0(QCryptoCipherNettle, 1);
-
switch (alg) {
case QCRYPTO_CIPHER_ALG_DES_RFB:
- ctx->ctx = g_new0(struct des_ctx, 1);
- rfbkey = qcrypto_cipher_munge_des_rfb_key(key, nkey);
- des_set_key(ctx->ctx, rfbkey);
- g_free(rfbkey);
-
- ctx->alg_encrypt_native = des_encrypt_native;
- ctx->alg_decrypt_native = des_decrypt_native;
- ctx->alg_encrypt_wrapper = des_encrypt_wrapper;
- ctx->alg_decrypt_wrapper = des_decrypt_wrapper;
-
- ctx->blocksize = DES_BLOCK_SIZE;
- break;
+ {
+ QCryptoNettleDESRFB *ctx;
+ const QCryptoCipherDriver *drv;
+ uint8_t *rfbkey;
+
+ switch (mode) {
+ case QCRYPTO_CIPHER_MODE_ECB:
+ drv = &qcrypto_nettle_des_rfb_driver_ecb;
+ break;
+ case QCRYPTO_CIPHER_MODE_CBC:
+ drv = &qcrypto_nettle_des_rfb_driver_cbc;
+ break;
+ case QCRYPTO_CIPHER_MODE_CTR:
+ drv = &qcrypto_nettle_des_rfb_driver_ctr;
+ break;
+ default:
+ goto bad_cipher_mode;
+ }
+
+ ctx = g_new0(QCryptoNettleDESRFB, 1);
+ ctx->base.driver = drv;
+
+ rfbkey = qcrypto_cipher_munge_des_rfb_key(key, nkey);
+ des_set_key(&ctx->key, rfbkey);
+ g_free(rfbkey);
+
+ return &ctx->base;
+ }
case QCRYPTO_CIPHER_ALG_3DES:
- ctx->ctx = g_new0(struct des3_ctx, 1);
- des3_set_key(ctx->ctx, key);
-
- ctx->alg_encrypt_native = des3_encrypt_native;
- ctx->alg_decrypt_native = des3_decrypt_native;
- ctx->alg_encrypt_wrapper = des3_encrypt_wrapper;
- ctx->alg_decrypt_wrapper = des3_decrypt_wrapper;
-
- ctx->blocksize = DES3_BLOCK_SIZE;
- break;
+ {
+ QCryptoNettleDES3 *ctx;
+ const QCryptoCipherDriver *drv;
+
+ switch (mode) {
+ case QCRYPTO_CIPHER_MODE_ECB:
+ drv = &qcrypto_nettle_des3_driver_ecb;
+ break;
+ case QCRYPTO_CIPHER_MODE_CBC:
+ drv = &qcrypto_nettle_des3_driver_cbc;
+ break;
+ case QCRYPTO_CIPHER_MODE_CTR:
+ drv = &qcrypto_nettle_des3_driver_ctr;
+ break;
+ default:
+ goto bad_cipher_mode;
+ }
+
+ ctx = g_new0(QCryptoNettleDES3, 1);
+ ctx->base.driver = drv;
+ des3_set_key(&ctx->key, key);
+ return &ctx->base;
+ }
case QCRYPTO_CIPHER_ALG_AES_128:
- ctx->ctx = g_new0(QCryptoNettleAES128, 1);
-
- if (mode == QCRYPTO_CIPHER_MODE_XTS) {
- ctx->ctx_tweak = g_new0(QCryptoNettleAES128, 1);
-
- nkey /= 2;
- aes128_set_encrypt_key(&((QCryptoNettleAES128 *)ctx->ctx)->enc,
- key);
- aes128_set_decrypt_key(&((QCryptoNettleAES128 *)ctx->ctx)->dec,
- key);
-
- aes128_set_encrypt_key(&((QCryptoNettleAES128 *)ctx->ctx_tweak)->
- enc, key + nkey);
- aes128_set_decrypt_key(&((QCryptoNettleAES128 *)ctx->ctx_tweak)->
- dec, key + nkey);
- } else {
- aes128_set_encrypt_key(&((QCryptoNettleAES128 *)ctx->ctx)->enc,
- key);
- aes128_set_decrypt_key(&((QCryptoNettleAES128 *)ctx->ctx)->dec,
- key);
+ {
+ QCryptoNettleAES128 *ctx = g_new0(QCryptoNettleAES128, 1);
+
+ switch (mode) {
+ case QCRYPTO_CIPHER_MODE_ECB:
+ ctx->base.driver = &qcrypto_nettle_aes128_driver_ecb;
+ break;
+ case QCRYPTO_CIPHER_MODE_CBC:
+ ctx->base.driver = &qcrypto_nettle_aes128_driver_cbc;
+ break;
+ case QCRYPTO_CIPHER_MODE_CTR:
+ ctx->base.driver = &qcrypto_nettle_aes128_driver_ctr;
+ break;
+ case QCRYPTO_CIPHER_MODE_XTS:
+ ctx->base.driver = &qcrypto_nettle_aes128_driver_xts;
+ nkey /= 2;
+ aes128_set_encrypt_key(&ctx->key_xts[0], key + nkey);
+ aes128_set_decrypt_key(&ctx->key_xts[1], key + nkey);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ aes128_set_encrypt_key(&ctx->key[0], key);
+ aes128_set_decrypt_key(&ctx->key[1], key);
+
+ return &ctx->base;
}
- ctx->alg_encrypt_native = aes128_encrypt_native;
- ctx->alg_decrypt_native = aes128_decrypt_native;
- ctx->alg_encrypt_wrapper = aes128_encrypt_wrapper;
- ctx->alg_decrypt_wrapper = aes128_decrypt_wrapper;
-
- ctx->blocksize = AES_BLOCK_SIZE;
- break;
-
case QCRYPTO_CIPHER_ALG_AES_192:
- ctx->ctx = g_new0(QCryptoNettleAES192, 1);
-
- if (mode == QCRYPTO_CIPHER_MODE_XTS) {
- ctx->ctx_tweak = g_new0(QCryptoNettleAES192, 1);
-
- nkey /= 2;
- aes192_set_encrypt_key(&((QCryptoNettleAES192 *)ctx->ctx)->enc,
- key);
- aes192_set_decrypt_key(&((QCryptoNettleAES192 *)ctx->ctx)->dec,
- key);
-
- aes192_set_encrypt_key(&((QCryptoNettleAES192 *)ctx->ctx_tweak)->
- enc, key + nkey);
- aes192_set_decrypt_key(&((QCryptoNettleAES192 *)ctx->ctx_tweak)->
- dec, key + nkey);
- } else {
- aes192_set_encrypt_key(&((QCryptoNettleAES192 *)ctx->ctx)->enc,
- key);
- aes192_set_decrypt_key(&((QCryptoNettleAES192 *)ctx->ctx)->dec,
- key);
+ {
+ QCryptoNettleAES192 *ctx = g_new0(QCryptoNettleAES192, 1);
+
+ switch (mode) {
+ case QCRYPTO_CIPHER_MODE_ECB:
+ ctx->base.driver = &qcrypto_nettle_aes192_driver_ecb;
+ break;
+ case QCRYPTO_CIPHER_MODE_CBC:
+ ctx->base.driver = &qcrypto_nettle_aes192_driver_cbc;
+ break;
+ case QCRYPTO_CIPHER_MODE_CTR:
+ ctx->base.driver = &qcrypto_nettle_aes192_driver_ctr;
+ break;
+ case QCRYPTO_CIPHER_MODE_XTS:
+ ctx->base.driver = &qcrypto_nettle_aes192_driver_xts;
+ nkey /= 2;
+ aes192_set_encrypt_key(&ctx->key_xts[0], key + nkey);
+ aes192_set_decrypt_key(&ctx->key_xts[1], key + nkey);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ aes192_set_encrypt_key(&ctx->key[0], key);
+ aes192_set_decrypt_key(&ctx->key[1], key);
+
+ return &ctx->base;
}
- ctx->alg_encrypt_native = aes192_encrypt_native;
- ctx->alg_decrypt_native = aes192_decrypt_native;
- ctx->alg_encrypt_wrapper = aes192_encrypt_wrapper;
- ctx->alg_decrypt_wrapper = aes192_decrypt_wrapper;
-
- ctx->blocksize = AES_BLOCK_SIZE;
- break;
-
case QCRYPTO_CIPHER_ALG_AES_256:
- ctx->ctx = g_new0(QCryptoNettleAES256, 1);
-
- if (mode == QCRYPTO_CIPHER_MODE_XTS) {
- ctx->ctx_tweak = g_new0(QCryptoNettleAES256, 1);
-
- nkey /= 2;
- aes256_set_encrypt_key(&((QCryptoNettleAES256 *)ctx->ctx)->enc,
- key);
- aes256_set_decrypt_key(&((QCryptoNettleAES256 *)ctx->ctx)->dec,
- key);
-
- aes256_set_encrypt_key(&((QCryptoNettleAES256 *)ctx->ctx_tweak)->
- enc, key + nkey);
- aes256_set_decrypt_key(&((QCryptoNettleAES256 *)ctx->ctx_tweak)->
- dec, key + nkey);
- } else {
- aes256_set_encrypt_key(&((QCryptoNettleAES256 *)ctx->ctx)->enc,
- key);
- aes256_set_decrypt_key(&((QCryptoNettleAES256 *)ctx->ctx)->dec,
- key);
+ {
+ QCryptoNettleAES256 *ctx = g_new0(QCryptoNettleAES256, 1);
+
+ switch (mode) {
+ case QCRYPTO_CIPHER_MODE_ECB:
+ ctx->base.driver = &qcrypto_nettle_aes256_driver_ecb;
+ break;
+ case QCRYPTO_CIPHER_MODE_CBC:
+ ctx->base.driver = &qcrypto_nettle_aes256_driver_cbc;
+ break;
+ case QCRYPTO_CIPHER_MODE_CTR:
+ ctx->base.driver = &qcrypto_nettle_aes256_driver_ctr;
+ break;
+ case QCRYPTO_CIPHER_MODE_XTS:
+ ctx->base.driver = &qcrypto_nettle_aes256_driver_xts;
+ nkey /= 2;
+ aes256_set_encrypt_key(&ctx->key_xts[0], key + nkey);
+ aes256_set_decrypt_key(&ctx->key_xts[1], key + nkey);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ aes256_set_encrypt_key(&ctx->key[0], key);
+ aes256_set_decrypt_key(&ctx->key[1], key);
+
+ return &ctx->base;
}
- ctx->alg_encrypt_native = aes256_encrypt_native;
- ctx->alg_decrypt_native = aes256_decrypt_native;
- ctx->alg_encrypt_wrapper = aes256_encrypt_wrapper;
- ctx->alg_decrypt_wrapper = aes256_decrypt_wrapper;
-
- ctx->blocksize = AES_BLOCK_SIZE;
- break;
-
case QCRYPTO_CIPHER_ALG_CAST5_128:
- ctx->ctx = g_new0(struct cast128_ctx, 1);
-
- if (mode == QCRYPTO_CIPHER_MODE_XTS) {
- ctx->ctx_tweak = g_new0(struct cast128_ctx, 1);
-
- nkey /= 2;
- cast5_set_key(ctx->ctx, nkey, key);
- cast5_set_key(ctx->ctx_tweak, nkey, key + nkey);
- } else {
- cast5_set_key(ctx->ctx, nkey, key);
+ {
+ QCryptoNettleCAST128 *ctx;
+ const QCryptoCipherDriver *drv;
+
+ switch (mode) {
+ case QCRYPTO_CIPHER_MODE_ECB:
+ drv = &qcrypto_nettle_cast128_driver_ecb;
+ break;
+ case QCRYPTO_CIPHER_MODE_CBC:
+ drv = &qcrypto_nettle_cast128_driver_cbc;
+ break;
+ case QCRYPTO_CIPHER_MODE_CTR:
+ drv = &qcrypto_nettle_cast128_driver_ctr;
+ break;
+ default:
+ goto bad_cipher_mode;
+ }
+
+ ctx = g_new0(QCryptoNettleCAST128, 1);
+ ctx->base.driver = drv;
+ cast5_set_key(&ctx->key, nkey, key);
+
+ return &ctx->base;
}
- ctx->alg_encrypt_native = cast128_encrypt_native;
- ctx->alg_decrypt_native = cast128_decrypt_native;
- ctx->alg_encrypt_wrapper = cast128_encrypt_wrapper;
- ctx->alg_decrypt_wrapper = cast128_decrypt_wrapper;
-
- ctx->blocksize = CAST128_BLOCK_SIZE;
- break;
-
case QCRYPTO_CIPHER_ALG_SERPENT_128:
case QCRYPTO_CIPHER_ALG_SERPENT_192:
case QCRYPTO_CIPHER_ALG_SERPENT_256:
- ctx->ctx = g_new0(struct serpent_ctx, 1);
-
- if (mode == QCRYPTO_CIPHER_MODE_XTS) {
- ctx->ctx_tweak = g_new0(struct serpent_ctx, 1);
-
- nkey /= 2;
- serpent_set_key(ctx->ctx, nkey, key);
- serpent_set_key(ctx->ctx_tweak, nkey, key + nkey);
- } else {
- serpent_set_key(ctx->ctx, nkey, key);
+ {
+ QCryptoNettleSerpent *ctx = g_new0(QCryptoNettleSerpent, 1);
+
+ switch (mode) {
+ case QCRYPTO_CIPHER_MODE_ECB:
+ ctx->base.driver = &qcrypto_nettle_serpent_driver_ecb;
+ break;
+ case QCRYPTO_CIPHER_MODE_CBC:
+ ctx->base.driver = &qcrypto_nettle_serpent_driver_cbc;
+ break;
+ case QCRYPTO_CIPHER_MODE_CTR:
+ ctx->base.driver = &qcrypto_nettle_serpent_driver_ctr;
+ break;
+ case QCRYPTO_CIPHER_MODE_XTS:
+ ctx->base.driver = &qcrypto_nettle_serpent_driver_xts;
+ nkey /= 2;
+ serpent_set_key(&ctx->key_xts, nkey, key + nkey);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ serpent_set_key(&ctx->key, nkey, key);
+
+ return &ctx->base;
}
- ctx->alg_encrypt_native = serpent_encrypt_native;
- ctx->alg_decrypt_native = serpent_decrypt_native;
- ctx->alg_encrypt_wrapper = serpent_encrypt_wrapper;
- ctx->alg_decrypt_wrapper = serpent_decrypt_wrapper;
-
- ctx->blocksize = SERPENT_BLOCK_SIZE;
- break;
-
case QCRYPTO_CIPHER_ALG_TWOFISH_128:
case QCRYPTO_CIPHER_ALG_TWOFISH_192:
case QCRYPTO_CIPHER_ALG_TWOFISH_256:
- ctx->ctx = g_new0(struct twofish_ctx, 1);
-
- if (mode == QCRYPTO_CIPHER_MODE_XTS) {
- ctx->ctx_tweak = g_new0(struct twofish_ctx, 1);
-
- nkey /= 2;
- twofish_set_key(ctx->ctx, nkey, key);
- twofish_set_key(ctx->ctx_tweak, nkey, key + nkey);
- } else {
- twofish_set_key(ctx->ctx, nkey, key);
+ {
+ QCryptoNettleTwofish *ctx = g_new0(QCryptoNettleTwofish, 1);
+
+ switch (mode) {
+ case QCRYPTO_CIPHER_MODE_ECB:
+ ctx->base.driver = &qcrypto_nettle_twofish_driver_ecb;
+ break;
+ case QCRYPTO_CIPHER_MODE_CBC:
+ ctx->base.driver = &qcrypto_nettle_twofish_driver_cbc;
+ break;
+ case QCRYPTO_CIPHER_MODE_CTR:
+ ctx->base.driver = &qcrypto_nettle_twofish_driver_ctr;
+ break;
+ case QCRYPTO_CIPHER_MODE_XTS:
+ ctx->base.driver = &qcrypto_nettle_twofish_driver_xts;
+ nkey /= 2;
+ twofish_set_key(&ctx->key_xts, nkey, key + nkey);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ twofish_set_key(&ctx->key, nkey, key);
+
+ return &ctx->base;
}
- ctx->alg_encrypt_native = twofish_encrypt_native;
- ctx->alg_decrypt_native = twofish_decrypt_native;
- ctx->alg_encrypt_wrapper = twofish_encrypt_wrapper;
- ctx->alg_decrypt_wrapper = twofish_decrypt_wrapper;
-
- ctx->blocksize = TWOFISH_BLOCK_SIZE;
- break;
-
default:
error_setg(errp, "Unsupported cipher algorithm %s",
QCryptoCipherAlgorithm_str(alg));
- goto error;
- }
- g_assert(is_power_of_2(ctx->blocksize));
-
- 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;
+ return NULL;
}
- ctx->iv = g_new0(uint8_t, ctx->blocksize);
-
- ctx->base.driver = &qcrypto_cipher_lib_driver;
- return &ctx->base;
-
- error:
- qcrypto_nettle_cipher_free_ctx(ctx);
+ bad_cipher_mode:
+ error_setg(errp, "Unsupported cipher mode %s",
+ QCryptoCipherMode_str(mode));
return NULL;
}
-
-
-static void
-qcrypto_nettle_cipher_ctx_free(QCryptoCipher *cipher)
-{
- QCryptoCipherNettle *ctx = container_of(cipher, QCryptoCipherNettle, base);
-
- qcrypto_nettle_cipher_free_ctx(ctx);
-}
-
-
-static int
-qcrypto_nettle_cipher_encrypt(QCryptoCipher *cipher,
- const void *in,
- void *out,
- size_t len,
- Error **errp)
-{
- QCryptoCipherNettle *ctx = container_of(cipher, QCryptoCipherNettle, base);
-
- if (len & (ctx->blocksize - 1)) {
- error_setg(errp, "Length %zu must be a multiple of block size %zu",
- len, ctx->blocksize);
- return -1;
- }
-
- switch (cipher->mode) {
- case QCRYPTO_CIPHER_MODE_ECB:
- ctx->alg_encrypt_wrapper(ctx->ctx, len, out, in);
- break;
-
- case QCRYPTO_CIPHER_MODE_CBC:
- cbc_encrypt(ctx->ctx, ctx->alg_encrypt_native,
- ctx->blocksize, ctx->iv,
- len, out, in);
- break;
-
- case QCRYPTO_CIPHER_MODE_XTS:
-#ifdef CONFIG_QEMU_PRIVATE_XTS
- xts_encrypt(ctx->ctx, ctx->ctx_tweak,
- ctx->alg_encrypt_wrapper, ctx->alg_decrypt_wrapper,
- ctx->iv, len, out, in);
-#else
- xts_encrypt_message(ctx->ctx, ctx->ctx_tweak,
- ctx->alg_encrypt_native,
- ctx->iv, len, out, in);
-#endif
- break;
-
- case QCRYPTO_CIPHER_MODE_CTR:
- ctr_crypt(ctx->ctx, ctx->alg_encrypt_native,
- ctx->blocksize, ctx->iv,
- len, out, in);
- break;
-
- default:
- error_setg(errp, "Unsupported cipher mode %s",
- QCryptoCipherMode_str(cipher->mode));
- return -1;
- }
- return 0;
-}
-
-
-static int
-qcrypto_nettle_cipher_decrypt(QCryptoCipher *cipher,
- const void *in,
- void *out,
- size_t len,
- Error **errp)
-{
- QCryptoCipherNettle *ctx = container_of(cipher, QCryptoCipherNettle, base);
-
- if (len & (ctx->blocksize - 1)) {
- error_setg(errp, "Length %zu must be a multiple of block size %zu",
- len, ctx->blocksize);
- return -1;
- }
-
- switch (cipher->mode) {
- case QCRYPTO_CIPHER_MODE_ECB:
- ctx->alg_decrypt_wrapper(ctx->ctx, len, out, in);
- break;
-
- case QCRYPTO_CIPHER_MODE_CBC:
- cbc_decrypt(ctx->ctx, ctx->alg_decrypt_native,
- ctx->blocksize, ctx->iv,
- len, out, in);
- break;
-
- case QCRYPTO_CIPHER_MODE_XTS:
-#ifdef CONFIG_QEMU_PRIVATE_XTS
- xts_decrypt(ctx->ctx, ctx->ctx_tweak,
- ctx->alg_encrypt_wrapper, ctx->alg_decrypt_wrapper,
- ctx->iv, len, out, in);
-#else
- xts_decrypt_message(ctx->ctx, ctx->ctx_tweak,
- ctx->alg_decrypt_native,
- ctx->alg_encrypt_native,
- ctx->iv, len, out, in);
-#endif
- break;
- case QCRYPTO_CIPHER_MODE_CTR:
- ctr_crypt(ctx->ctx, ctx->alg_encrypt_native,
- ctx->blocksize, ctx->iv,
- len, out, in);
- break;
-
- default:
- error_setg(errp, "Unsupported cipher mode %s",
- QCryptoCipherMode_str(cipher->mode));
- return -1;
- }
- return 0;
-}
-
-static int
-qcrypto_nettle_cipher_setiv(QCryptoCipher *cipher,
- const uint8_t *iv, size_t niv,
- Error **errp)
-{
- QCryptoCipherNettle *ctx = container_of(cipher, QCryptoCipherNettle, 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_cipher_lib_driver = {
- .cipher_encrypt = qcrypto_nettle_cipher_encrypt,
- .cipher_decrypt = qcrypto_nettle_cipher_decrypt,
- .cipher_setiv = qcrypto_nettle_cipher_setiv,
- .cipher_free = qcrypto_nettle_cipher_ctx_free,
-};
--
2.26.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PULL 17/17] crypto/gcrypt: Split QCryptoCipherGcrypt into subclasses
2020-09-10 10:06 [PULL 00/17] Crypto next patches Daniel P. Berrangé
` (15 preceding siblings ...)
2020-09-10 10:06 ` [PULL 16/17] crypto/nettle: Split QCryptoCipherNettle " Daniel P. Berrangé
@ 2020-09-10 10:06 ` Daniel P. Berrangé
2020-09-12 21:53 ` [PULL 00/17] Crypto next patches Peter Maydell
17 siblings, 0 replies; 19+ messages in thread
From: Daniel P. Berrangé @ 2020-09-10 10:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Richard Henderson, Daniel P. Berrangé
From: Richard Henderson <richard.henderson@linaro.org>
With gcrypt, most of the dispatch happens in the library,
so there aren't many classes to create. However, we can
still create separate dispatch for CTR mode, and for
CONFIG_QEMU_PRIVATE_XTS, which avoids needing to check
for these modes at runtime.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
crypto/cipher-gcrypt.c.inc | 493 ++++++++++++++++++-------------------
1 file changed, 238 insertions(+), 255 deletions(-)
diff --git a/crypto/cipher-gcrypt.c.inc b/crypto/cipher-gcrypt.c.inc
index 7a1fbc9745..42d4137534 100644
--- a/crypto/cipher-gcrypt.c.inc
+++ b/crypto/cipher-gcrypt.c.inc
@@ -24,8 +24,6 @@
#include <gcrypt.h>
-static const struct QCryptoCipherDriver qcrypto_cipher_lib_driver;
-
bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode)
{
@@ -57,36 +55,212 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
}
}
-typedef struct QCryptoCipherGcrypt QCryptoCipherGcrypt;
-struct QCryptoCipherGcrypt {
+typedef struct QCryptoCipherGcrypt {
QCryptoCipher base;
gcry_cipher_hd_t handle;
size_t blocksize;
#ifdef CONFIG_QEMU_PRIVATE_XTS
gcry_cipher_hd_t tweakhandle;
- /* Initialization vector or Counter */
- uint8_t *iv;
+ uint8_t iv[XTS_BLOCK_SIZE];
#endif
-};
+} QCryptoCipherGcrypt;
+
-static void
-qcrypto_gcrypt_cipher_free_ctx(QCryptoCipherGcrypt *ctx,
- QCryptoCipherMode mode)
+static void qcrypto_gcrypt_ctx_free(QCryptoCipher *cipher)
{
- if (!ctx) {
- return;
- }
+ QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
gcry_cipher_close(ctx->handle);
+ g_free(ctx);
+}
+
+static int qcrypto_gcrypt_encrypt(QCryptoCipher *cipher, const void *in,
+ void *out, size_t len, Error **errp)
+{
+ QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
+ gcry_error_t err;
+
+ if (len & (ctx->blocksize - 1)) {
+ error_setg(errp, "Length %zu must be a multiple of block size %zu",
+ len, ctx->blocksize);
+ return -1;
+ }
+
+ 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;
+}
+
+
+static int qcrypto_gcrypt_decrypt(QCryptoCipher *cipher, const void *in,
+ void *out, size_t len, Error **errp)
+{
+ QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
+ gcry_error_t err;
+
+ if (len & (ctx->blocksize - 1)) {
+ error_setg(errp, "Length %zu must be a multiple of block size %zu",
+ len, ctx->blocksize);
+ return -1;
+ }
+
+ 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;
+}
+
+static int qcrypto_gcrypt_setiv(QCryptoCipher *cipher,
+ const uint8_t *iv, size_t niv,
+ Error **errp)
+{
+ QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
+ gcry_error_t err;
+
+ if (niv != ctx->blocksize) {
+ error_setg(errp, "Expected IV size %zu not %zu",
+ ctx->blocksize, niv);
+ return -1;
+ }
+
+ 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 0;
+}
+
+static int qcrypto_gcrypt_ctr_setiv(QCryptoCipher *cipher,
+ const uint8_t *iv, size_t niv,
+ Error **errp)
+{
+ QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
+ gcry_error_t err;
+
+ if (niv != ctx->blocksize) {
+ error_setg(errp, "Expected IV size %zu not %zu",
+ ctx->blocksize, niv);
+ return -1;
+ }
+
+ err = gcry_cipher_setctr(ctx->handle, iv, niv);
+ if (err != 0) {
+ error_setg(errp, "Cannot set Counter: %s", gcry_strerror(err));
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static const struct QCryptoCipherDriver qcrypto_gcrypt_driver = {
+ .cipher_encrypt = qcrypto_gcrypt_encrypt,
+ .cipher_decrypt = qcrypto_gcrypt_decrypt,
+ .cipher_setiv = qcrypto_gcrypt_setiv,
+ .cipher_free = qcrypto_gcrypt_ctx_free,
+};
+
+static const struct QCryptoCipherDriver qcrypto_gcrypt_ctr_driver = {
+ .cipher_encrypt = qcrypto_gcrypt_encrypt,
+ .cipher_decrypt = qcrypto_gcrypt_decrypt,
+ .cipher_setiv = qcrypto_gcrypt_ctr_setiv,
+ .cipher_free = qcrypto_gcrypt_ctx_free,
+};
+
#ifdef CONFIG_QEMU_PRIVATE_XTS
- if (mode == QCRYPTO_CIPHER_MODE_XTS) {
- gcry_cipher_close(ctx->tweakhandle);
+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;
}
- g_free(ctx->iv);
-#endif
- g_free(ctx);
+
+ 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,
@@ -95,32 +269,10 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
Error **errp)
{
QCryptoCipherGcrypt *ctx;
+ const QCryptoCipherDriver *drv;
gcry_error_t err;
int gcryalg, gcrymode;
- 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;
- break;
- case QCRYPTO_CIPHER_MODE_CTR:
- gcrymode = GCRY_CIPHER_MODE_CTR;
- break;
- default:
- error_setg(errp, "Unsupported cipher mode %s",
- QCryptoCipherMode_str(mode));
- return NULL;
- }
-
if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) {
return NULL;
}
@@ -129,54 +281,70 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
case QCRYPTO_CIPHER_ALG_DES_RFB:
gcryalg = GCRY_CIPHER_DES;
break;
-
case QCRYPTO_CIPHER_ALG_3DES:
gcryalg = GCRY_CIPHER_3DES;
break;
-
case QCRYPTO_CIPHER_ALG_AES_128:
gcryalg = GCRY_CIPHER_AES128;
break;
-
case QCRYPTO_CIPHER_ALG_AES_192:
gcryalg = GCRY_CIPHER_AES192;
break;
-
case QCRYPTO_CIPHER_ALG_AES_256:
gcryalg = GCRY_CIPHER_AES256;
break;
-
case QCRYPTO_CIPHER_ALG_CAST5_128:
gcryalg = GCRY_CIPHER_CAST5;
break;
-
case QCRYPTO_CIPHER_ALG_SERPENT_128:
gcryalg = GCRY_CIPHER_SERPENT128;
break;
-
case QCRYPTO_CIPHER_ALG_SERPENT_192:
gcryalg = GCRY_CIPHER_SERPENT192;
break;
-
case QCRYPTO_CIPHER_ALG_SERPENT_256:
gcryalg = GCRY_CIPHER_SERPENT256;
break;
-
case QCRYPTO_CIPHER_ALG_TWOFISH_128:
gcryalg = GCRY_CIPHER_TWOFISH128;
break;
-
case QCRYPTO_CIPHER_ALG_TWOFISH_256:
gcryalg = GCRY_CIPHER_TWOFISH;
break;
-
default:
error_setg(errp, "Unsupported cipher algorithm %s",
QCryptoCipherAlgorithm_str(alg));
return NULL;
}
+ drv = &qcrypto_gcrypt_driver;
+ switch (mode) {
+ case QCRYPTO_CIPHER_MODE_ECB:
+ 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;
+ break;
+ case QCRYPTO_CIPHER_MODE_CTR:
+ drv = &qcrypto_gcrypt_ctr_driver;
+ gcrymode = GCRY_CIPHER_MODE_CTR;
+ break;
+ default:
+ error_setg(errp, "Unsupported cipher mode %s",
+ QCryptoCipherMode_str(mode));
+ return NULL;
+ }
+
ctx = g_new0(QCryptoCipherGcrypt, 1);
+ ctx->base.driver = drv;
err = gcry_cipher_open(&ctx->handle, gcryalg, gcrymode, 0);
if (err != 0) {
@@ -184,8 +352,16 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
gcry_strerror(err));
goto error;
}
+ 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",
@@ -203,224 +379,31 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
uint8_t *rfbkey = qcrypto_cipher_munge_des_rfb_key(key, nkey);
err = gcry_cipher_setkey(ctx->handle, rfbkey, nkey);
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);
+ err = gcry_cipher_setkey(ctx->tweakhandle, key + nkey, nkey);
if (err != 0) {
- error_setg(errp, "Cannot set key: %s",
- gcry_strerror(err));
+ error_setg(errp, "Cannot set key: %s", gcry_strerror(err));
goto error;
}
- 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));
- goto error;
- }
- switch (alg) {
- case QCRYPTO_CIPHER_ALG_AES_128:
- case QCRYPTO_CIPHER_ALG_AES_192:
- case QCRYPTO_CIPHER_ALG_AES_256:
- case QCRYPTO_CIPHER_ALG_SERPENT_128:
- case QCRYPTO_CIPHER_ALG_SERPENT_192:
- case QCRYPTO_CIPHER_ALG_SERPENT_256:
- case QCRYPTO_CIPHER_ALG_TWOFISH_128:
- case QCRYPTO_CIPHER_ALG_TWOFISH_256:
- ctx->blocksize = 16;
- break;
- case QCRYPTO_CIPHER_ALG_3DES:
- case QCRYPTO_CIPHER_ALG_CAST5_128:
- ctx->blocksize = 8;
- break;
- default:
- g_assert_not_reached();
- }
+ err = gcry_cipher_setkey(ctx->handle, key, nkey);
}
- g_assert(is_power_of_2(ctx->blocksize));
-
-#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;
- }
- ctx->iv = g_new0(uint8_t, ctx->blocksize);
+ if (err != 0) {
+ error_setg(errp, "Cannot set key: %s", gcry_strerror(err));
+ goto error;
}
-#endif
- ctx->base.driver = &qcrypto_cipher_lib_driver;
return &ctx->base;
error:
- qcrypto_gcrypt_cipher_free_ctx(ctx, mode);
- return NULL;
-}
-
-
-static void
-qcrypto_gcrypt_cipher_ctx_free(QCryptoCipher *cipher)
-{
- QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
-
- qcrypto_gcrypt_cipher_free_ctx(ctx, cipher->mode);
-}
-
-
-#ifdef CONFIG_QEMU_PRIVATE_XTS
-static void qcrypto_gcrypt_xts_encrypt(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_decrypt(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);
-}
-#endif
-
-static int
-qcrypto_gcrypt_cipher_encrypt(QCryptoCipher *cipher,
- const void *in,
- void *out,
- size_t len,
- Error **errp)
-{
- QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
- gcry_error_t err;
-
- if (len & (ctx->blocksize - 1)) {
- error_setg(errp, "Length %zu must be a multiple of block size %zu",
- len, ctx->blocksize);
- 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);
- 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;
-}
-
-
-static int
-qcrypto_gcrypt_cipher_decrypt(QCryptoCipher *cipher,
- const void *in,
- void *out,
- size_t len,
- Error **errp)
-{
- QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
- gcry_error_t err;
-
- if (len & (ctx->blocksize - 1)) {
- error_setg(errp, "Length %zu must be a multiple of block size %zu",
- len, ctx->blocksize);
- 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);
- 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;
-}
-
-static int
-qcrypto_gcrypt_cipher_setiv(QCryptoCipher *cipher,
- const uint8_t *iv, size_t niv,
- Error **errp)
-{
- QCryptoCipherGcrypt *ctx = container_of(cipher, QCryptoCipherGcrypt, base);
- gcry_error_t err;
-
- if (niv != ctx->blocksize) {
- error_setg(errp, "Expected IV size %zu not %zu",
- ctx->blocksize, niv);
- return -1;
- }
-
#ifdef CONFIG_QEMU_PRIVATE_XTS
- if (ctx->iv) {
- memcpy(ctx->iv, iv, niv);
- return 0;
- }
+ gcry_cipher_close(ctx->tweakhandle);
#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",
- gcry_strerror(err));
- return -1;
- }
- }
-
- return 0;
+ gcry_cipher_close(ctx->handle);
+ g_free(ctx);
+ return NULL;
}
-
-
-static const struct QCryptoCipherDriver qcrypto_cipher_lib_driver = {
- .cipher_encrypt = qcrypto_gcrypt_cipher_encrypt,
- .cipher_decrypt = qcrypto_gcrypt_cipher_decrypt,
- .cipher_setiv = qcrypto_gcrypt_cipher_setiv,
- .cipher_free = qcrypto_gcrypt_cipher_ctx_free,
-};
--
2.26.2
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PULL 00/17] Crypto next patches
2020-09-10 10:06 [PULL 00/17] Crypto next patches Daniel P. Berrangé
` (16 preceding siblings ...)
2020-09-10 10:06 ` [PULL 17/17] crypto/gcrypt: Split QCryptoCipherGcrypt " Daniel P. Berrangé
@ 2020-09-12 21:53 ` Peter Maydell
17 siblings, 0 replies; 19+ messages in thread
From: Peter Maydell @ 2020-09-12 21:53 UTC (permalink / raw)
To: Daniel P. Berrangé; +Cc: QEMU Developers
On Thu, 10 Sep 2020 at 11:07, Daniel P. Berrangé <berrange@redhat.com> wrote:
>
> The following changes since commit 9435a8b3dd35f1f926f1b9127e8a906217a5518a:
>
> Merge remote-tracking branch 'remotes/kraxel/tags/sirius/ipxe-20200908-pull=
> -request' into staging (2020-09-08 21:21:13 +0100)
>
> are available in the Git repository at:
>
> https://gitlab.com/berrange/qemu tags/crypt-perf-pull-request
>
> for you to fetch changes up to 1b010d9339497b081c3b8ab4f98b2a21f2cae08d:
>
> crypto/gcrypt: Split QCryptoCipherGcrypt into subclasses (2020-09-10 11:02:=
> 23 +0100)
>
> ----------------------------------------------------------------
> Improve performance of crypto cipher subsystem
>
> ----------------------------------------------------------------
>
Applied, thanks.
Please update the changelog at https://wiki.qemu.org/ChangeLog/5.2
for any user-visible changes.
-- PMM
^ permalink raw reply [flat|nested] 19+ messages in thread