From: Milan Broz Date: Wed, 5 Dec 2012 19:35:42 +0000 (+0100) Subject: Add PBKDF2 benchmark. X-Git-Tag: upstream/1.6~124 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bd494d23c5516f5b60ca031862373634d0aba64e;p=platform%2Fupstream%2Fcryptsetup.git Add PBKDF2 benchmark. --- diff --git a/lib/crypto_backend/crypto_backend.h b/lib/crypto_backend/crypto_backend.h index be5c6f0..0c71d9d 100644 --- a/lib/crypto_backend/crypto_backend.h +++ b/lib/crypto_backend/crypto_backend.h @@ -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, diff --git a/lib/crypto_backend/pbkdf_check.c b/lib/crypto_backend/pbkdf_check.c index 086aa38..69f6bfb 100644 --- a/lib/crypto_backend/pbkdf_check.c +++ b/lib/crypto_backend/pbkdf_check.c @@ -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; diff --git a/lib/libcryptsetup.h b/lib/libcryptsetup.h index 0f19f03..04c53fb 100644 --- a/lib/libcryptsetup.h +++ b/lib/libcryptsetup.h @@ -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 * diff --git a/lib/libcryptsetup.sym b/lib/libcryptsetup.sym index 78bc281..801add6 100644 --- a/lib/libcryptsetup.sym +++ b/lib/libcryptsetup.sym @@ -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; diff --git a/lib/luks1/keymanage.c b/lib/luks1/keymanage.c index 3bd57ee..204484a 100644 --- a/lib/luks1/keymanage.c +++ b/lib/luks1/keymanage.c @@ -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 diff --git a/lib/utils_benchmark.c b/lib/utils_benchmark.c index 850ac7c..4ee0c03 100644 --- a/lib/utils_benchmark.c +++ b/lib/utils_benchmark.c @@ -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; +} diff --git a/src/cryptsetup.c b/src/cryptsetup.c index e969373..6fb3f8e 100644 --- a/src/cryptsetup.c +++ b/src/cryptsetup.c @@ -4,6 +4,7 @@ * Copyright (C) 2004, Christophe Saout * Copyright (C) 2004-2007, Clemens Fruhwirth * 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);