From 3e308f20edfd65a21c98eb2d8079dacd47957444 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Sat, 24 Oct 2015 11:55:48 +0100 Subject: crypto: implement the LUKS block encryption format Provide a block encryption implementation that follows the LUKS/dm-crypt specification. This supports all combinations of hash, cipher algorithm, cipher mode and iv generator that are implemented by the current crypto layer. There is support for opening existing volumes formatted by dm-crypt, and for formatting new volumes. In the latter case it will only use key slot 0. Reviewed-by: Eric Blake Signed-off-by: Daniel P. Berrange --- tests/test-crypto-block.c | 127 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 2 deletions(-) (limited to 'tests/test-crypto-block.c') diff --git a/tests/test-crypto-block.c b/tests/test-crypto-block.c index 3f65383..cdbe09d 100644 --- a/tests/test-crypto-block.c +++ b/tests/test-crypto-block.c @@ -23,6 +23,15 @@ #include "crypto/block.h" #include "qemu/buffer.h" #include "crypto/secret.h" +#ifndef _WIN32 +#include +#endif + +#if defined(CONFIG_UUID) && (defined(_WIN32) || defined RUSAGE_THREAD) +#define TEST_LUKS +#else +#undef TEST_LUKS +#endif static QCryptoBlockCreateOptions qcow_create_opts = { .format = Q_CRYPTO_BLOCK_FORMAT_QCOW, @@ -40,6 +49,63 @@ static QCryptoBlockOpenOptions qcow_open_opts = { }, }; + +#ifdef TEST_LUKS +static QCryptoBlockOpenOptions luks_open_opts = { + .format = Q_CRYPTO_BLOCK_FORMAT_LUKS, + .u.luks = { + .has_key_secret = true, + .key_secret = (char *)"sec0", + }, +}; + + +/* Creation with all default values */ +static QCryptoBlockCreateOptions luks_create_opts_default = { + .format = Q_CRYPTO_BLOCK_FORMAT_LUKS, + .u.luks = { + .has_key_secret = true, + .key_secret = (char *)"sec0", + }, +}; + + +/* ...and with explicit values */ +static QCryptoBlockCreateOptions luks_create_opts_aes256_cbc_plain64 = { + .format = Q_CRYPTO_BLOCK_FORMAT_LUKS, + .u.luks = { + .has_key_secret = true, + .key_secret = (char *)"sec0", + .has_cipher_alg = true, + .cipher_alg = QCRYPTO_CIPHER_ALG_AES_256, + .has_cipher_mode = true, + .cipher_mode = QCRYPTO_CIPHER_MODE_CBC, + .has_ivgen_alg = true, + .ivgen_alg = QCRYPTO_IVGEN_ALG_PLAIN64, + }, +}; + + +static QCryptoBlockCreateOptions luks_create_opts_aes256_cbc_essiv = { + .format = Q_CRYPTO_BLOCK_FORMAT_LUKS, + .u.luks = { + .has_key_secret = true, + .key_secret = (char *)"sec0", + .has_cipher_alg = true, + .cipher_alg = QCRYPTO_CIPHER_ALG_AES_256, + .has_cipher_mode = true, + .cipher_mode = QCRYPTO_CIPHER_MODE_CBC, + .has_ivgen_alg = true, + .ivgen_alg = QCRYPTO_IVGEN_ALG_ESSIV, + .has_ivgen_hash_alg = true, + .ivgen_hash_alg = QCRYPTO_HASH_ALG_SHA256, + .has_hash_alg = true, + .hash_alg = QCRYPTO_HASH_ALG_SHA1, + }, +}; +#endif /* TEST_LUKS */ + + static struct QCryptoBlockTestData { const char *path; QCryptoBlockCreateOptions *create_opts; @@ -52,7 +118,9 @@ static struct QCryptoBlockTestData { QCryptoHashAlgorithm hash_alg; QCryptoIVGenAlgorithm ivgen_alg; - QCryptoCipherAlgorithm ivgen_hash; + QCryptoHashAlgorithm ivgen_hash; + + bool slow; } test_data[] = { { .path = "/crypto/block/qcow", @@ -66,6 +134,54 @@ static struct QCryptoBlockTestData { .ivgen_alg = QCRYPTO_IVGEN_ALG_PLAIN64, }, +#ifdef TEST_LUKS + { + .path = "/crypto/block/luks/default", + .create_opts = &luks_create_opts_default, + .open_opts = &luks_open_opts, + + .expect_header = true, + + .cipher_alg = QCRYPTO_CIPHER_ALG_AES_256, + .cipher_mode = QCRYPTO_CIPHER_MODE_XTS, + .hash_alg = QCRYPTO_HASH_ALG_SHA256, + + .ivgen_alg = QCRYPTO_IVGEN_ALG_PLAIN64, + + .slow = true, + }, + { + .path = "/crypto/block/luks/aes-256-cbc-plain64", + .create_opts = &luks_create_opts_aes256_cbc_plain64, + .open_opts = &luks_open_opts, + + .expect_header = true, + + .cipher_alg = QCRYPTO_CIPHER_ALG_AES_256, + .cipher_mode = QCRYPTO_CIPHER_MODE_CBC, + .hash_alg = QCRYPTO_HASH_ALG_SHA256, + + .ivgen_alg = QCRYPTO_IVGEN_ALG_PLAIN64, + + .slow = true, + }, + { + .path = "/crypto/block/luks/aes-256-cbc-essiv", + .create_opts = &luks_create_opts_aes256_cbc_essiv, + .open_opts = &luks_open_opts, + + .expect_header = true, + + .cipher_alg = QCRYPTO_CIPHER_ALG_AES_256, + .cipher_mode = QCRYPTO_CIPHER_MODE_CBC, + .hash_alg = QCRYPTO_HASH_ALG_SHA1, + + .ivgen_alg = QCRYPTO_IVGEN_ALG_ESSIV, + .ivgen_hash = QCRYPTO_HASH_ALG_SHA256, + + .slow = true, + }, +#endif }; @@ -232,7 +348,14 @@ int main(int argc, char **argv) g_assert(qcrypto_init(NULL) == 0); for (i = 0; i < G_N_ELEMENTS(test_data); i++) { - g_test_add_data_func(test_data[i].path, &test_data[i], test_block); + if (test_data[i].open_opts->format == Q_CRYPTO_BLOCK_FORMAT_LUKS && + !qcrypto_hash_supports(test_data[i].hash_alg)) { + continue; + } + if (!test_data[i].slow || + g_test_slow()) { + g_test_add_data_func(test_data[i].path, &test_data[i], test_block); + } } return g_test_run(); -- cgit v1.1