aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block/crypto.c6
-rw-r--r--crypto/block-luks.c24
-rw-r--r--qapi/crypto.json6
3 files changed, 35 insertions, 1 deletions
diff --git a/block/crypto.c b/block/crypto.c
index 7f61e12686..7aa7eb553e 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -33,6 +33,7 @@
#define BLOCK_CRYPTO_OPT_LUKS_IVGEN_ALG "ivgen-alg"
#define BLOCK_CRYPTO_OPT_LUKS_IVGEN_HASH_ALG "ivgen-hash-alg"
#define BLOCK_CRYPTO_OPT_LUKS_HASH_ALG "hash-alg"
+#define BLOCK_CRYPTO_OPT_LUKS_ITER_TIME "iter-time"
typedef struct BlockCrypto BlockCrypto;
@@ -183,6 +184,11 @@ static QemuOptsList block_crypto_create_opts_luks = {
.type = QEMU_OPT_STRING,
.help = "Name of encryption hash algorithm",
},
+ {
+ .name = BLOCK_CRYPTO_OPT_LUKS_ITER_TIME,
+ .type = QEMU_OPT_NUMBER,
+ .help = "Time to spend in PBKDF in milliseconds",
+ },
{ /* end of list */ }
},
};
diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index bc086acdab..91a4172287 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -920,6 +920,9 @@ qcrypto_block_luks_create(QCryptoBlock *block,
uint64_t iters;
memcpy(&luks_opts, &options->u.luks, sizeof(luks_opts));
+ if (!luks_opts.has_iter_time) {
+ luks_opts.iter_time = 1000;
+ }
if (!luks_opts.has_cipher_alg) {
luks_opts.cipher_alg = QCRYPTO_CIPHER_ALG_AES_256;
}
@@ -1075,6 +1078,16 @@ qcrypto_block_luks_create(QCryptoBlock *block,
goto error;
}
+ if (iters > (ULLONG_MAX / luks_opts.iter_time)) {
+ error_setg_errno(errp, ERANGE,
+ "PBKDF iterations %llu too large to scale",
+ (unsigned long long)iters);
+ goto error;
+ }
+
+ /* iter_time was in millis, but count_iters reported for secs */
+ iters = iters * luks_opts.iter_time / 1000;
+
/* Why /= 8 ? That matches cryptsetup, but there's no
* explanation why they chose /= 8... Probably so that
* if all 8 keyslots are active we only spend 1 second
@@ -1144,6 +1157,17 @@ qcrypto_block_luks_create(QCryptoBlock *block,
error_propagate(errp, local_err);
goto error;
}
+
+ if (iters > (ULLONG_MAX / luks_opts.iter_time)) {
+ error_setg_errno(errp, ERANGE,
+ "PBKDF iterations %llu too large to scale",
+ (unsigned long long)iters);
+ goto error;
+ }
+
+ /* iter_time was in millis, but count_iters reported for secs */
+ iters = iters * luks_opts.iter_time / 1000;
+
/* Why /= 2 ? That matches cryptsetup, but there's no
* explanation why they chose /= 2... */
iters /= 2;
diff --git a/qapi/crypto.json b/qapi/crypto.json
index 34d2583154..2b6118f660 100644
--- a/qapi/crypto.json
+++ b/qapi/crypto.json
@@ -185,6 +185,9 @@
# Currently defaults to 'sha256'
# @hash-alg: #optional the master key hash algorithm
# Currently defaults to 'sha256'
+# @iter-time: #optional number of milliseconds to spend in
+# PBKDF passphrase processing. Currently defaults
+# to 1000. (since 2.8)
# Since: 2.6
##
{ 'struct': 'QCryptoBlockCreateOptionsLUKS',
@@ -193,7 +196,8 @@
'*cipher-mode': 'QCryptoCipherMode',
'*ivgen-alg': 'QCryptoIVGenAlgorithm',
'*ivgen-hash-alg': 'QCryptoHashAlgorithm',
- '*hash-alg': 'QCryptoHashAlgorithm'}}
+ '*hash-alg': 'QCryptoHashAlgorithm',
+ '*iter-time': 'int'}}
##