crypto: make PBKDF iterations configurable for LUKS format
As protection against bruteforcing passphrases, the PBKDF algorithm is tuned by counting the number of iterations needed to produce 1 second of running time. If the machine that the image will be used on is much faster than the machine where the image is created, it can be desirable to raise the number of iterations. This change adds a new 'iter-time' property that allows the user to choose the iteration wallclock time. Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
59b060be18
commit
3bd18890ca
@ -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 */ }
|
||||
},
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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'}}
|
||||
|
||||
|
||||
##
|
||||
|
Loading…
Reference in New Issue
Block a user