diff options
-rw-r--r-- | block/crypto.c | 6 | ||||
-rw-r--r-- | crypto/block-luks.c | 24 | ||||
-rw-r--r-- | qapi/crypto.json | 6 |
3 files changed, 35 insertions, 1 deletions
diff --git a/block/crypto.c b/block/crypto.c index 7f61e12..7aa7eb5 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 bc086ac..91a4172 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 34d2583..2b6118f 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'}} ## |