mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Add callback for PBKDF benchmark.
Also change API so the kdf structure is continuously updated with the benchmarked data (callback can see progress or debug).
This commit is contained in:
@@ -67,7 +67,8 @@ int crypt_pbkdf_perf(const char *kdf, const char *hash,
|
|||||||
const char *salt, size_t salt_size,
|
const char *salt, size_t salt_size,
|
||||||
size_t volume_key_size, uint32_t time_ms,
|
size_t volume_key_size, uint32_t time_ms,
|
||||||
uint32_t max_memory_kb, uint32_t parallel_threads,
|
uint32_t max_memory_kb, uint32_t parallel_threads,
|
||||||
uint32_t *iterations_out, uint32_t *memory_out);
|
uint32_t *iterations_out, uint32_t *memory_out,
|
||||||
|
int (*progress)(long time_ms, void *usrptr), void *usrptr);
|
||||||
|
|
||||||
#if USE_INTERNAL_PBKDF2
|
#if USE_INTERNAL_PBKDF2
|
||||||
/* internal PBKDF2 implementation */
|
/* internal PBKDF2 implementation */
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
* PBKDF performance check
|
* PBKDF performance check
|
||||||
* Copyright (C) 2012-2017, Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2012-2017, Red Hat, Inc. All rights reserved.
|
||||||
* Copyright (C) 2012-2017, Milan Broz
|
* Copyright (C) 2012-2017, Milan Broz
|
||||||
|
* Copyright (C) 2016-2017, Ondrej Mosnacek
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or
|
* This file is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@@ -26,15 +27,6 @@
|
|||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include "crypto_backend.h"
|
#include "crypto_backend.h"
|
||||||
|
|
||||||
//#define BENCH_DEBUG
|
|
||||||
|
|
||||||
#ifdef BENCH_DEBUG
|
|
||||||
#include <stdio.h> /* FIXME: debug */
|
|
||||||
#define bench_log(args...) fprintf(stderr, args)
|
|
||||||
#else
|
|
||||||
#define bench_log(args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define BENCH_MIN_MS 250
|
#define BENCH_MIN_MS 250
|
||||||
#define BENCH_MIN_MS_FAST 10
|
#define BENCH_MIN_MS_FAST 10
|
||||||
#define BENCH_PERCENT_ATLEAST 95
|
#define BENCH_PERCENT_ATLEAST 95
|
||||||
@@ -123,7 +115,8 @@ static int measure_argon2(const char *kdf, const char *password, size_t password
|
|||||||
static int crypt_argon2_check(const char *kdf, const char *password, size_t password_length,
|
static int crypt_argon2_check(const char *kdf, const char *password, size_t password_length,
|
||||||
const char *salt, size_t salt_length, size_t key_length,
|
const char *salt, size_t salt_length, size_t key_length,
|
||||||
uint32_t min_t_cost, uint32_t max_m_cost, uint32_t parallel,
|
uint32_t min_t_cost, uint32_t max_m_cost, uint32_t parallel,
|
||||||
int target_ms, uint32_t *out_t_cost, uint32_t *out_m_cost)
|
int target_ms, uint32_t *out_t_cost, uint32_t *out_m_cost,
|
||||||
|
int (*progress)(long time_ms, void *usrptr), void *usrptr)
|
||||||
{
|
{
|
||||||
int r = 0;
|
int r = 0;
|
||||||
char *key = NULL;
|
char *key = NULL;
|
||||||
@@ -132,7 +125,6 @@ static int crypt_argon2_check(const char *kdf, const char *password, size_t pass
|
|||||||
long ms;
|
long ms;
|
||||||
long ms_atleast = (long)target_ms * BENCH_PERCENT_ATLEAST / 100;
|
long ms_atleast = (long)target_ms * BENCH_PERCENT_ATLEAST / 100;
|
||||||
long ms_atmost = (long)target_ms * BENCH_PERCENT_ATMOST / 100;
|
long ms_atmost = (long)target_ms * BENCH_PERCENT_ATMOST / 100;
|
||||||
struct timespec tstart, tend;
|
|
||||||
|
|
||||||
if (key_length <= 0 || target_ms <= 0)
|
if (key_length <= 0 || target_ms <= 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -140,8 +132,6 @@ static int crypt_argon2_check(const char *kdf, const char *password, size_t pass
|
|||||||
if (max_m_cost < min_m_cost)
|
if (max_m_cost < min_m_cost)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &tstart);
|
|
||||||
|
|
||||||
key = malloc(key_length);
|
key = malloc(key_length);
|
||||||
if (!key)
|
if (!key)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@@ -154,12 +144,17 @@ static int crypt_argon2_check(const char *kdf, const char *password, size_t pass
|
|||||||
r = measure_argon2(kdf, password, password_length, salt, salt_length,
|
r = measure_argon2(kdf, password, password_length, salt, salt_length,
|
||||||
key, key_length, t_cost, m_cost, parallel,
|
key, key_length, t_cost, m_cost, parallel,
|
||||||
BENCH_SAMPLES_FAST, BENCH_MIN_MS, &ms);
|
BENCH_SAMPLES_FAST, BENCH_MIN_MS, &ms);
|
||||||
|
if (!r) {
|
||||||
|
/* Update parameters to actual measurement */
|
||||||
|
*out_t_cost = t_cost;
|
||||||
|
*out_m_cost = m_cost;
|
||||||
|
if (progress && progress(ms, usrptr))
|
||||||
|
r = -EINTR;
|
||||||
|
}
|
||||||
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
bench_log("Pre-initial parameters: t_cost = %lu; m_cost = %lu; ms = %lu\n",
|
|
||||||
(long unsigned)t_cost, (long unsigned)m_cost, ms);
|
|
||||||
|
|
||||||
if (ms >= BENCH_MIN_MS)
|
if (ms >= BENCH_MIN_MS)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -188,8 +183,6 @@ static int crypt_argon2_check(const char *kdf, const char *password, size_t pass
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bench_log("Initial parameters: t_cost = %lu; m_cost = %lu; ms = %lu\n",
|
|
||||||
(long unsigned)t_cost, (long unsigned)m_cost, ms);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 2. Use the params obtained in (1.) to estimate the target params.
|
* 2. Use the params obtained in (1.) to estimate the target params.
|
||||||
@@ -221,22 +214,19 @@ static int crypt_argon2_check(const char *kdf, const char *password, size_t pass
|
|||||||
r = measure_argon2(kdf, password, password_length, salt, salt_length,
|
r = measure_argon2(kdf, password, password_length, salt, salt_length,
|
||||||
key, key_length, t_cost, m_cost, parallel,
|
key, key_length, t_cost, m_cost, parallel,
|
||||||
BENCH_SAMPLES_SLOW, ms_atleast, &ms);
|
BENCH_SAMPLES_SLOW, ms_atleast, &ms);
|
||||||
|
|
||||||
|
if (!r) {
|
||||||
|
/* Update parameters to actual measurement */
|
||||||
|
*out_t_cost = t_cost;
|
||||||
|
*out_m_cost = m_cost;
|
||||||
|
if (progress && progress(ms, usrptr))
|
||||||
|
r = -EINTR;
|
||||||
|
}
|
||||||
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
bench_log("Candidate parameters: t_cost = %lu; m_cost = %lu; ms = %lu\n",
|
} while (ms < ms_atleast || ms > ms_atmost);
|
||||||
(long unsigned)t_cost, (long unsigned)m_cost, ms);
|
|
||||||
} while(ms < ms_atleast || ms > ms_atmost);
|
|
||||||
|
|
||||||
bench_log("Accepted parameters: t_cost = %lu; m_cost = %lu\n",
|
|
||||||
(long unsigned)t_cost, (long unsigned)m_cost);
|
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &tend);
|
|
||||||
|
|
||||||
bench_log("Benchmark took: %ld ms\n", timespec_ms(&tstart, &tend));
|
|
||||||
|
|
||||||
*out_t_cost = t_cost;
|
|
||||||
*out_m_cost = m_cost;
|
|
||||||
out:
|
out:
|
||||||
if (key) {
|
if (key) {
|
||||||
crypt_backend_memzero(key, key_length);
|
crypt_backend_memzero(key, key_length);
|
||||||
@@ -249,7 +239,9 @@ out:
|
|||||||
static int crypt_pbkdf_check(const char *kdf, const char *hash,
|
static int crypt_pbkdf_check(const char *kdf, const char *hash,
|
||||||
const char *password, size_t password_length,
|
const char *password, size_t password_length,
|
||||||
const char *salt, size_t salt_length,
|
const char *salt, size_t salt_length,
|
||||||
size_t key_length, uint32_t *iter_secs)
|
size_t key_length, uint32_t *iter_secs, int target_ms,
|
||||||
|
int (*progress)(long time_ms, void *usrptr), void *usrptr)
|
||||||
|
|
||||||
{
|
{
|
||||||
struct rusage rstart, rend;
|
struct rusage rstart, rend;
|
||||||
int r = 0, step = 0;
|
int r = 0, step = 0;
|
||||||
@@ -273,6 +265,7 @@ static int crypt_pbkdf_check(const char *kdf, const char *hash,
|
|||||||
|
|
||||||
r = crypt_pbkdf(kdf, hash, password, password_length, salt,
|
r = crypt_pbkdf(kdf, hash, password, password_length, salt,
|
||||||
salt_length, key, key_length, iterations, 0, 0);
|
salt_length, key, key_length, iterations, 0, 0);
|
||||||
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@@ -282,6 +275,14 @@ static int crypt_pbkdf_check(const char *kdf, const char *hash,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ms = time_ms(&rstart, &rend);
|
ms = time_ms(&rstart, &rend);
|
||||||
|
|
||||||
|
*iter_secs = (uint32_t)((uint64_t)iterations * (uint64_t)target_ms / (uint64_t)ms);
|
||||||
|
|
||||||
|
if (progress && progress(ms, usrptr)) {
|
||||||
|
r = -EINTR;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (ms > 500)
|
if (ms > 500)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -299,9 +300,6 @@ static int crypt_pbkdf_check(const char *kdf, const char *hash,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iter_secs)
|
|
||||||
*iter_secs = (iterations * 1000) / ms;
|
|
||||||
out:
|
out:
|
||||||
if (key) {
|
if (key) {
|
||||||
crypt_backend_memzero(key, key_length);
|
crypt_backend_memzero(key, key_length);
|
||||||
@@ -317,31 +315,27 @@ int crypt_pbkdf_perf(const char *kdf, const char *hash,
|
|||||||
const char *salt, size_t salt_size,
|
const char *salt, size_t salt_size,
|
||||||
size_t volume_key_size, uint32_t time_ms,
|
size_t volume_key_size, uint32_t time_ms,
|
||||||
uint32_t max_memory_kb, uint32_t parallel_threads,
|
uint32_t max_memory_kb, uint32_t parallel_threads,
|
||||||
uint32_t *iterations_out, uint32_t *memory_out)
|
uint32_t *iterations_out, uint32_t *memory_out,
|
||||||
|
int (*progress)(long time_ms, void *usrptr), void *usrptr)
|
||||||
{
|
{
|
||||||
uint32_t iterations_sec;
|
int r = -EINVAL;
|
||||||
int r;
|
|
||||||
|
|
||||||
if (!kdf)
|
if (!kdf || !iterations_out || !memory_out)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!strcmp(kdf, "pbkdf2")) {
|
*memory_out = 0;
|
||||||
if (!iterations_out || memory_out)
|
*iterations_out = 0;
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
|
if (!strcmp(kdf, "pbkdf2"))
|
||||||
r = crypt_pbkdf_check(kdf, hash, password, password_size,
|
r = crypt_pbkdf_check(kdf, hash, password, password_size,
|
||||||
salt, salt_size, volume_key_size, &iterations_sec);
|
salt, salt_size, volume_key_size,
|
||||||
|
iterations_out, time_ms, progress, usrptr);
|
||||||
*iterations_out = (uint32_t)((uint64_t)iterations_sec * (uint64_t)time_ms / 1000);
|
|
||||||
} else if (!strncmp(kdf, "argon2", 6)) {
|
|
||||||
if (!iterations_out || !memory_out)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
r = crypt_argon2_check(kdf, password, password_size, salt, salt_size,
|
|
||||||
volume_key_size, ARGON2_MIN_T_COST, max_memory_kb,
|
|
||||||
parallel_threads, time_ms, iterations_out, memory_out);
|
|
||||||
} else
|
|
||||||
r = -EINVAL;
|
|
||||||
|
|
||||||
|
else if (!strncmp(kdf, "argon2", 6))
|
||||||
|
r = crypt_argon2_check(kdf, password, password_size,
|
||||||
|
salt, salt_size, volume_key_size,
|
||||||
|
ARGON2_MIN_T_COST, max_memory_kb,
|
||||||
|
parallel_threads, time_ms, iterations_out,
|
||||||
|
memory_out, progress, usrptr);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1110,14 +1110,14 @@ int crypt_benchmark(struct crypt_device *cd,
|
|||||||
* @return @e 0 on success or negative errno value otherwise.
|
* @return @e 0 on success or negative errno value otherwise.
|
||||||
*/
|
*/
|
||||||
int crypt_benchmark_pbkdf(struct crypt_device *cd,
|
int crypt_benchmark_pbkdf(struct crypt_device *cd,
|
||||||
const struct crypt_pbkdf_type *pbkdf,
|
struct crypt_pbkdf_type *pbkdf,
|
||||||
const char *password,
|
const char *password,
|
||||||
size_t password_size,
|
size_t password_size,
|
||||||
const char *salt,
|
const char *salt,
|
||||||
size_t salt_size,
|
size_t salt_size,
|
||||||
size_t volume_key_size,
|
size_t volume_key_size,
|
||||||
uint32_t *iterations,
|
int (*progress)(long time_ms, void *usrptr),
|
||||||
uint32_t *memory);
|
void *usrptr);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|||||||
@@ -727,7 +727,7 @@ int LUKS_generate_phdr(struct luks_phdr *header,
|
|||||||
size_t blocksPerStripeSet, currentSector;
|
size_t blocksPerStripeSet, currentSector;
|
||||||
int r;
|
int r;
|
||||||
uuid_t partitionUuid;
|
uuid_t partitionUuid;
|
||||||
const struct crypt_pbkdf_type pbkdf = {
|
struct crypt_pbkdf_type pbkdf = {
|
||||||
.type = CRYPT_KDF_PBKDF2,
|
.type = CRYPT_KDF_PBKDF2,
|
||||||
.hash = hashSpec,
|
.hash = hashSpec,
|
||||||
.time_ms = 1000,
|
.time_ms = 1000,
|
||||||
@@ -785,7 +785,7 @@ int LUKS_generate_phdr(struct luks_phdr *header,
|
|||||||
}
|
}
|
||||||
|
|
||||||
r = crypt_benchmark_pbkdf(ctx, &pbkdf, "foo", 3, "bar", 3, vk->keylength,
|
r = crypt_benchmark_pbkdf(ctx, &pbkdf, "foo", 3, "bar", 3, vk->keylength,
|
||||||
PBKDF2_per_sec, NULL);
|
NULL, NULL);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_err(ctx, _("Not compatible PBKDF2 options (using hash algorithm %s).\n"),
|
log_err(ctx, _("Not compatible PBKDF2 options (using hash algorithm %s).\n"),
|
||||||
header->hashSpec);
|
header->hashSpec);
|
||||||
@@ -793,6 +793,7 @@ int LUKS_generate_phdr(struct luks_phdr *header,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Compute master key digest */
|
/* Compute master key digest */
|
||||||
|
*PBKDF2_per_sec = pbkdf.time_ms;
|
||||||
iteration_time_ms /= 8;
|
iteration_time_ms /= 8;
|
||||||
header->mkDigestIterations = at_least((uint32_t)(*PBKDF2_per_sec/1024) * iteration_time_ms,
|
header->mkDigestIterations = at_least((uint32_t)(*PBKDF2_per_sec/1024) * iteration_time_ms,
|
||||||
LUKS_MKD_ITERATIONS_MIN);
|
LUKS_MKD_ITERATIONS_MIN);
|
||||||
@@ -864,7 +865,7 @@ int LUKS_set_key(unsigned int keyIndex,
|
|||||||
char *AfKey = NULL;
|
char *AfKey = NULL;
|
||||||
size_t AFEKSize;
|
size_t AFEKSize;
|
||||||
double PBKDF2_temp;
|
double PBKDF2_temp;
|
||||||
const struct crypt_pbkdf_type pbkdf = {
|
struct crypt_pbkdf_type pbkdf = {
|
||||||
.type = CRYPT_KDF_PBKDF2,
|
.type = CRYPT_KDF_PBKDF2,
|
||||||
.hash = hdr->hashSpec,
|
.hash = hdr->hashSpec,
|
||||||
.time_ms = 1000,
|
.time_ms = 1000,
|
||||||
@@ -887,7 +888,7 @@ int LUKS_set_key(unsigned int keyIndex,
|
|||||||
log_dbg("Calculating data for key slot %d", keyIndex);
|
log_dbg("Calculating data for key slot %d", keyIndex);
|
||||||
|
|
||||||
r = crypt_benchmark_pbkdf(ctx, &pbkdf, "foo", 3, "bar", 3, vk->keylength,
|
r = crypt_benchmark_pbkdf(ctx, &pbkdf, "foo", 3, "bar", 3, vk->keylength,
|
||||||
PBKDF2_per_sec, NULL);
|
NULL, NULL);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_err(ctx, _("Not compatible PBKDF2 options (using hash algorithm %s).\n"),
|
log_err(ctx, _("Not compatible PBKDF2 options (using hash algorithm %s).\n"),
|
||||||
hdr->hashSpec);
|
hdr->hashSpec);
|
||||||
@@ -897,6 +898,7 @@ int LUKS_set_key(unsigned int keyIndex,
|
|||||||
/*
|
/*
|
||||||
* Final iteration count is at least LUKS_SLOT_ITERATIONS_MIN
|
* Final iteration count is at least LUKS_SLOT_ITERATIONS_MIN
|
||||||
*/
|
*/
|
||||||
|
*PBKDF2_per_sec = pbkdf.time_ms;
|
||||||
PBKDF2_temp = ((double)*PBKDF2_per_sec * iteration_time_ms / 1000.);
|
PBKDF2_temp = ((double)*PBKDF2_per_sec * iteration_time_ms / 1000.);
|
||||||
assert(PBKDF2_temp < UINT32_MAX);
|
assert(PBKDF2_temp < UINT32_MAX);
|
||||||
hdr->keyblock[keyIndex].passwordIterations = at_least((uint32_t)PBKDF2_temp,
|
hdr->keyblock[keyIndex].passwordIterations = at_least((uint32_t)PBKDF2_temp,
|
||||||
|
|||||||
@@ -232,14 +232,14 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int crypt_benchmark_pbkdf(struct crypt_device *cd,
|
int crypt_benchmark_pbkdf(struct crypt_device *cd,
|
||||||
const struct crypt_pbkdf_type *pbkdf,
|
struct crypt_pbkdf_type *pbkdf,
|
||||||
const char *password,
|
const char *password,
|
||||||
size_t password_size,
|
size_t password_size,
|
||||||
const char *salt,
|
const char *salt,
|
||||||
size_t salt_size,
|
size_t salt_size,
|
||||||
size_t volume_key_size,
|
size_t volume_key_size,
|
||||||
uint32_t *iterations,
|
int (*progress)(long time_ms, void *usrptr),
|
||||||
uint32_t *memory)
|
void *usrptr)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@@ -248,7 +248,7 @@ int crypt_benchmark_pbkdf(struct crypt_device *cd,
|
|||||||
return r;
|
return r;
|
||||||
|
|
||||||
/* Hack to not print hash for argon, it is used also for AF later.*/
|
/* Hack to not print hash for argon, it is used also for AF later.*/
|
||||||
if (pbkdf->hash && !memory)
|
if (!strcmp(pbkdf->type, CRYPT_KDF_PBKDF2))
|
||||||
log_dbg("Running %s-%s benchmark.", pbkdf->type, pbkdf->hash);
|
log_dbg("Running %s-%s benchmark.", pbkdf->type, pbkdf->hash);
|
||||||
else
|
else
|
||||||
log_dbg("Running %s benchmark.", pbkdf->type);
|
log_dbg("Running %s benchmark.", pbkdf->type);
|
||||||
@@ -256,11 +256,11 @@ int crypt_benchmark_pbkdf(struct crypt_device *cd,
|
|||||||
r = crypt_pbkdf_perf(pbkdf->type, pbkdf->hash, password, password_size,
|
r = crypt_pbkdf_perf(pbkdf->type, pbkdf->hash, password, password_size,
|
||||||
salt, salt_size, volume_key_size, pbkdf->time_ms,
|
salt, salt_size, volume_key_size, pbkdf->time_ms,
|
||||||
pbkdf->max_memory_kb, pbkdf->parallel_threads,
|
pbkdf->max_memory_kb, pbkdf->parallel_threads,
|
||||||
iterations, memory);
|
&pbkdf->time_ms, &pbkdf->max_memory_kb, progress, usrptr);
|
||||||
|
|
||||||
if (!r)
|
if (!r)
|
||||||
log_dbg(" %u iterations, %u memory (for %zu-bits key).",
|
log_dbg(" %u iterations, %u memory (for %zu-bits key).",
|
||||||
iterations ? *iterations : 0, memory ? *memory : 0,
|
pbkdf->time_ms, pbkdf->max_memory_kb,
|
||||||
volume_key_size * 8);
|
volume_key_size * 8);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -532,43 +532,57 @@ out:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int benchmark_callback(long time_ms, void *usrptr)
|
||||||
|
{
|
||||||
|
struct crypt_pbkdf_type *pbkdf = usrptr;
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
check_signal(&r);
|
||||||
|
if (r)
|
||||||
|
log_err("Benchmark interrupted.\n");
|
||||||
|
else
|
||||||
|
log_dbg("PBKDF benchmark: memory cost = %u, iterations = %u, "
|
||||||
|
"threads = %u (took %ld ms)", pbkdf->max_memory_kb,
|
||||||
|
pbkdf->time_ms, pbkdf->parallel_threads, time_ms);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
static int action_benchmark_kdf(const char *kdf, const char *hash, size_t key_size)
|
static int action_benchmark_kdf(const char *kdf, const char *hash, size_t key_size)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
if (!strcmp(kdf, CRYPT_KDF_PBKDF2)) {
|
if (!strcmp(kdf, CRYPT_KDF_PBKDF2)) {
|
||||||
const struct crypt_pbkdf_type pbkdf = {
|
struct crypt_pbkdf_type pbkdf = {
|
||||||
.type = CRYPT_KDF_PBKDF2,
|
.type = CRYPT_KDF_PBKDF2,
|
||||||
.hash = hash,
|
.hash = hash,
|
||||||
.time_ms = 1000,
|
.time_ms = 1000,
|
||||||
};
|
};
|
||||||
uint32_t kdf_iters;
|
|
||||||
|
|
||||||
r = crypt_benchmark_pbkdf(NULL, &pbkdf, "foo", 3, "bar", 3, key_size,
|
r = crypt_benchmark_pbkdf(NULL, &pbkdf, "foo", 3, "bar", 3, key_size,
|
||||||
&kdf_iters, NULL);
|
&benchmark_callback, &pbkdf);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_std("PBKDF2-%-9s N/A\n", hash);
|
log_std("PBKDF2-%-9s N/A\n", hash);
|
||||||
else
|
else
|
||||||
log_std("PBKDF2-%-9s %7u iterations per second for %zu-bit key\n",
|
log_std("PBKDF2-%-9s %7u iterations per second for %zu-bit key\n",
|
||||||
hash, kdf_iters, key_size * 8);
|
hash, pbkdf.time_ms, key_size * 8);
|
||||||
} else {
|
} else {
|
||||||
const struct crypt_pbkdf_type pbkdf = {
|
struct crypt_pbkdf_type pbkdf = {
|
||||||
.type = kdf,
|
.type = kdf,
|
||||||
.time_ms = opt_iteration_time ?: 800,
|
.time_ms = opt_iteration_time ?: 800,
|
||||||
.max_memory_kb = opt_pbkdf_memory,
|
.max_memory_kb = opt_pbkdf_memory,
|
||||||
.parallel_threads = opt_pbkdf_parallel,
|
.parallel_threads = opt_pbkdf_parallel,
|
||||||
};
|
};
|
||||||
uint32_t iters, memory;
|
|
||||||
|
|
||||||
r = crypt_benchmark_pbkdf(NULL, &pbkdf, "foo", 3,
|
r = crypt_benchmark_pbkdf(NULL, &pbkdf, "foo", 3,
|
||||||
"barbarbarbarbarbar", 18, key_size, &iters, &memory);
|
"barbarbarbarbarbar", 18, key_size,
|
||||||
|
&benchmark_callback, &pbkdf);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_std("%-10s N/A\n", kdf);
|
log_std("%-10s N/A\n", kdf);
|
||||||
else
|
else
|
||||||
log_std("%-10s %4u iterations, %5u memory, "
|
log_std("%-10s %4u iterations, %5u memory, "
|
||||||
"%1u parallel threads (CPUs) for "
|
"%1u parallel threads (CPUs) for "
|
||||||
"%zu-bit key (%u ms time)\n", kdf,
|
"%zu-bit key (requested %u ms time)\n", kdf,
|
||||||
iters, memory, pbkdf.parallel_threads,
|
pbkdf.time_ms, pbkdf.max_memory_kb, pbkdf.parallel_threads,
|
||||||
key_size * 8, (unsigned)pbkdf.time_ms);
|
key_size * 8, opt_iteration_time ?: 800);
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
|||||||
Reference in New Issue
Block a user