提交 3bd18890 编写于 作者: D Daniel P. Berrange

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: NEric Blake <eblake@redhat.com>
Signed-off-by: NDaniel P. Berrange <berrange@redhat.com>
上级 59b060be
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#define BLOCK_CRYPTO_OPT_LUKS_IVGEN_ALG "ivgen-alg" #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_IVGEN_HASH_ALG "ivgen-hash-alg"
#define BLOCK_CRYPTO_OPT_LUKS_HASH_ALG "hash-alg" #define BLOCK_CRYPTO_OPT_LUKS_HASH_ALG "hash-alg"
#define BLOCK_CRYPTO_OPT_LUKS_ITER_TIME "iter-time"
typedef struct BlockCrypto BlockCrypto; typedef struct BlockCrypto BlockCrypto;
...@@ -183,6 +184,11 @@ static QemuOptsList block_crypto_create_opts_luks = { ...@@ -183,6 +184,11 @@ static QemuOptsList block_crypto_create_opts_luks = {
.type = QEMU_OPT_STRING, .type = QEMU_OPT_STRING,
.help = "Name of encryption hash algorithm", .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 */ } { /* end of list */ }
}, },
}; };
......
...@@ -920,6 +920,9 @@ qcrypto_block_luks_create(QCryptoBlock *block, ...@@ -920,6 +920,9 @@ qcrypto_block_luks_create(QCryptoBlock *block,
uint64_t iters; uint64_t iters;
memcpy(&luks_opts, &options->u.luks, sizeof(luks_opts)); 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) { if (!luks_opts.has_cipher_alg) {
luks_opts.cipher_alg = QCRYPTO_CIPHER_ALG_AES_256; luks_opts.cipher_alg = QCRYPTO_CIPHER_ALG_AES_256;
} }
...@@ -1075,6 +1078,16 @@ qcrypto_block_luks_create(QCryptoBlock *block, ...@@ -1075,6 +1078,16 @@ qcrypto_block_luks_create(QCryptoBlock *block,
goto error; 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 /* Why /= 8 ? That matches cryptsetup, but there's no
* explanation why they chose /= 8... Probably so that * explanation why they chose /= 8... Probably so that
* if all 8 keyslots are active we only spend 1 second * if all 8 keyslots are active we only spend 1 second
...@@ -1144,6 +1157,17 @@ qcrypto_block_luks_create(QCryptoBlock *block, ...@@ -1144,6 +1157,17 @@ qcrypto_block_luks_create(QCryptoBlock *block,
error_propagate(errp, local_err); error_propagate(errp, local_err);
goto error; 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 /* Why /= 2 ? That matches cryptsetup, but there's no
* explanation why they chose /= 2... */ * explanation why they chose /= 2... */
iters /= 2; iters /= 2;
......
...@@ -185,6 +185,9 @@ ...@@ -185,6 +185,9 @@
# Currently defaults to 'sha256' # Currently defaults to 'sha256'
# @hash-alg: #optional the master key hash algorithm # @hash-alg: #optional the master key hash algorithm
# Currently defaults to 'sha256' # 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 # Since: 2.6
## ##
{ 'struct': 'QCryptoBlockCreateOptionsLUKS', { 'struct': 'QCryptoBlockCreateOptionsLUKS',
...@@ -193,7 +196,8 @@ ...@@ -193,7 +196,8 @@
'*cipher-mode': 'QCryptoCipherMode', '*cipher-mode': 'QCryptoCipherMode',
'*ivgen-alg': 'QCryptoIVGenAlgorithm', '*ivgen-alg': 'QCryptoIVGenAlgorithm',
'*ivgen-hash-alg': 'QCryptoHashAlgorithm', '*ivgen-hash-alg': 'QCryptoHashAlgorithm',
'*hash-alg': 'QCryptoHashAlgorithm'}} '*hash-alg': 'QCryptoHashAlgorithm',
'*iter-time': 'int'}}
## ##
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册