mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Add PBKDF2 benchmark.
This commit is contained in:
@@ -56,7 +56,10 @@ enum { CRYPT_RND_NORMAL = 0, CRYPT_RND_KEY = 1, CRYPT_RND_SALT = 2 };
|
||||
int crypt_backend_rng(char *buffer, size_t length, int quality, int fips);
|
||||
|
||||
/* PBKDF*/
|
||||
int crypt_pbkdf_check(const char *kdf, const char *hash, uint64_t *iter_secs);
|
||||
int crypt_pbkdf_check(const char *kdf, const char *hash,
|
||||
const char *password, size_t password_size,
|
||||
const char *salt, size_t salt_size,
|
||||
uint64_t *iter_secs);
|
||||
int crypt_pbkdf(const char *kdf, const char *hash,
|
||||
const char *password, size_t password_length,
|
||||
const char *salt, size_t salt_length,
|
||||
|
||||
@@ -38,7 +38,10 @@ static long time_ms(struct rusage *start, struct rusage *end)
|
||||
}
|
||||
|
||||
/* This code benchmarks PBKDF and returns iterations/second using specified hash */
|
||||
int crypt_pbkdf_check(const char *kdf, const char *hash, uint64_t *iter_secs)
|
||||
int crypt_pbkdf_check(const char *kdf, const char *hash,
|
||||
const char *password, size_t password_size,
|
||||
const char *salt, size_t salt_size,
|
||||
uint64_t *iter_secs)
|
||||
{
|
||||
struct rusage rstart, rend;
|
||||
int r = 0, step = 0;
|
||||
@@ -54,7 +57,8 @@ int crypt_pbkdf_check(const char *kdf, const char *hash, uint64_t *iter_secs)
|
||||
if (getrusage(RUSAGE_SELF, &rstart) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
r = crypt_pbkdf(kdf, hash, "foo", 3, "bar", 3, &buf, 1, iterations);
|
||||
r = crypt_pbkdf(kdf, hash, password, password_size, salt,
|
||||
salt_size, &buf, 1, iterations);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -905,6 +905,15 @@ int crypt_benchmark(struct crypt_device *cd,
|
||||
double *encryption_mbs,
|
||||
double *decryption_mbs);
|
||||
|
||||
int crypt_benchmark_kdf(struct crypt_device *cd,
|
||||
const char *kdf,
|
||||
const char *hash,
|
||||
const char *password,
|
||||
size_t password_size,
|
||||
const char *salt,
|
||||
size_t salt_size,
|
||||
uint64_t *iterations_sec);
|
||||
|
||||
/**
|
||||
* Get cipher used in device
|
||||
*
|
||||
|
||||
@@ -40,6 +40,7 @@ CRYPTSETUP_1.0 {
|
||||
crypt_status;
|
||||
crypt_dump;
|
||||
crypt_benchmark;
|
||||
crypt_benchmark_kdf;
|
||||
crypt_get_cipher;
|
||||
crypt_get_cipher_mode;
|
||||
crypt_get_uuid;
|
||||
|
||||
@@ -598,21 +598,6 @@ int LUKS_write_phdr(struct luks_phdr *hdr,
|
||||
return r;
|
||||
}
|
||||
|
||||
static int LUKS_PBKDF2_performance_check(const char *hashSpec,
|
||||
uint64_t *PBKDF2_per_sec,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
if (!*PBKDF2_per_sec) {
|
||||
if (crypt_pbkdf_check("pbkdf2", hashSpec, PBKDF2_per_sec) < 0) {
|
||||
log_err(ctx, _("Not compatible PBKDF2 options (using hash algorithm %s).\n"), hashSpec);
|
||||
return -EINVAL;
|
||||
}
|
||||
log_dbg("PBKDF2: %" PRIu64 " iterations per second using hash %s.", *PBKDF2_per_sec, hashSpec);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LUKS_generate_phdr(struct luks_phdr *header,
|
||||
const struct volume_key *vk,
|
||||
const char *cipherName, const char *cipherMode, const char *hashSpec,
|
||||
@@ -669,8 +654,13 @@ int LUKS_generate_phdr(struct luks_phdr *header,
|
||||
return r;
|
||||
}
|
||||
|
||||
if ((r = LUKS_PBKDF2_performance_check(header->hashSpec, PBKDF2_per_sec, ctx)))
|
||||
r = crypt_benchmark_kdf(ctx, "pbkdf2", header->hashSpec,
|
||||
"foo", 3, "bar", 3, PBKDF2_per_sec);
|
||||
if (r < 0) {
|
||||
log_err(ctx, _("Not compatible PBKDF2 options (using hash algorithm %s).\n"),
|
||||
header->hashSpec);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Compute master key digest */
|
||||
iteration_time_ms /= 8;
|
||||
@@ -760,8 +750,13 @@ int LUKS_set_key(unsigned int keyIndex,
|
||||
|
||||
log_dbg("Calculating data for key slot %d", keyIndex);
|
||||
|
||||
if ((r = LUKS_PBKDF2_performance_check(hdr->hashSpec, PBKDF2_per_sec, ctx)))
|
||||
r = crypt_benchmark_kdf(ctx, "pbkdf2", hdr->hashSpec,
|
||||
"foo", 3, "bar", 3, PBKDF2_per_sec);
|
||||
if (r < 0) {
|
||||
log_err(ctx, _("Not compatible PBKDF2 options (using hash algorithm %s).\n"),
|
||||
hdr->hashSpec);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Avoid floating point operation
|
||||
|
||||
@@ -215,3 +215,33 @@ out:
|
||||
free(cp.iv);
|
||||
return r;
|
||||
}
|
||||
|
||||
int crypt_benchmark_kdf(struct crypt_device *cd,
|
||||
const char *kdf,
|
||||
const char *hash,
|
||||
const char *password,
|
||||
size_t password_size,
|
||||
const char *salt,
|
||||
size_t salt_size,
|
||||
uint64_t *iterations_sec)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!iterations_sec)
|
||||
return -EINVAL;
|
||||
|
||||
r = init_crypto(cd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!strncmp(kdf, "pbkdf2", 6))
|
||||
r = crypt_pbkdf_check(kdf, hash, password, password_size,
|
||||
salt, salt_size, iterations_sec);
|
||||
else
|
||||
r = -EINVAL;
|
||||
|
||||
if (!r)
|
||||
log_dbg("KDF %s, hash %s: %" PRIu64 " iterations per second.",
|
||||
kdf, hash, *iterations_sec);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* Copyright (C) 2004, Christophe Saout <christophe@saout.de>
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2012, Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -422,6 +423,21 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int action_benchmark_kdf(const char *hash)
|
||||
{
|
||||
uint64_t kdf_iters;
|
||||
int r;
|
||||
|
||||
r = crypt_benchmark_kdf(NULL, "pbkdf2", hash, "foo", 3, "bar", 3,
|
||||
&kdf_iters);
|
||||
if (r < 0)
|
||||
log_std("PBKDF2-%-9s N/A\n", hash);
|
||||
else
|
||||
log_std("PBKDF2-%-9s %7" PRIu64 " iterations per second\n",
|
||||
hash, kdf_iters);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int action_benchmark(void)
|
||||
{
|
||||
static struct {
|
||||
@@ -444,8 +460,6 @@ static int action_benchmark(void)
|
||||
{ "twofish", "xts", 64, 16 },
|
||||
{ NULL, NULL, 0, 0 }
|
||||
};
|
||||
const char *header = "# Tests are approximate using memory only (no storage IO).\n"
|
||||
"# Algorithm | Key | Encryption | Decryption\n";
|
||||
char cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
|
||||
double enc_mbr = 0, dec_mbr = 0;
|
||||
int key_size = (opt_key_size ?: DEFAULT_PLAIN_KEYBITS);
|
||||
@@ -454,7 +468,10 @@ static int action_benchmark(void)
|
||||
char *c;
|
||||
int i, r;
|
||||
|
||||
if (opt_cipher) {
|
||||
log_std("# Tests are approximate using memory only (no storage IO).\n");
|
||||
if (opt_hash) {
|
||||
r = action_benchmark_kdf(opt_hash);
|
||||
} else if (opt_cipher) {
|
||||
r = crypt_parse_name_and_mode(opt_cipher, cipher, NULL, cipher_mode);
|
||||
if (r < 0) {
|
||||
log_err(_("No known cipher specification pattern detected.\n"));
|
||||
@@ -473,7 +490,7 @@ static int action_benchmark(void)
|
||||
key_size / 8, iv_size, buffer_size,
|
||||
&enc_mbr, &dec_mbr);
|
||||
if (!r) {
|
||||
log_std("%s", header);
|
||||
log_std("# Algorithm | Key | Encryption | Decryption\n");
|
||||
strncat(cipher, "-", MAX_CIPHER_LEN);
|
||||
strncat(cipher, cipher_mode, MAX_CIPHER_LEN);
|
||||
log_std("%12s %4db %5.1f MiB/s %5.1f MiB/s\n",
|
||||
@@ -481,6 +498,11 @@ static int action_benchmark(void)
|
||||
} else if (r == -ENOENT)
|
||||
log_err(_("Cipher %s is not available.\n"), opt_cipher);
|
||||
} else {
|
||||
action_benchmark_kdf("sha1");
|
||||
action_benchmark_kdf("sha256");
|
||||
action_benchmark_kdf("sha512");
|
||||
action_benchmark_kdf("ripemd160");
|
||||
action_benchmark_kdf("whirlpool");
|
||||
for (i = 0; bciphers[i].cipher; i++) {
|
||||
r = crypt_benchmark(NULL, bciphers[i].cipher, bciphers[i].mode,
|
||||
bciphers[i].key_size, bciphers[i].iv_size,
|
||||
@@ -490,7 +512,7 @@ static int action_benchmark(void)
|
||||
if (r == -ENOENT)
|
||||
skipped++;
|
||||
if (i == 0)
|
||||
log_std("%s", header);
|
||||
log_std("# Algorithm | Key | Encryption | Decryption\n");
|
||||
|
||||
snprintf(cipher, MAX_CIPHER_LEN, "%s-%s",
|
||||
bciphers[i].cipher, bciphers[i].mode);
|
||||
|
||||
Reference in New Issue
Block a user