13e308f20SDaniel P. Berrange /* 23e308f20SDaniel P. Berrange * QEMU Crypto block device encryption LUKS format 33e308f20SDaniel P. Berrange * 43e308f20SDaniel P. Berrange * Copyright (c) 2015-2016 Red Hat, Inc. 53e308f20SDaniel P. Berrange * 63e308f20SDaniel P. Berrange * This library is free software; you can redistribute it and/or 73e308f20SDaniel P. Berrange * modify it under the terms of the GNU Lesser General Public 83e308f20SDaniel P. Berrange * License as published by the Free Software Foundation; either 9b7cbb874SThomas Huth * version 2.1 of the License, or (at your option) any later version. 103e308f20SDaniel P. Berrange * 113e308f20SDaniel P. Berrange * This library is distributed in the hope that it will be useful, 123e308f20SDaniel P. Berrange * but WITHOUT ANY WARRANTY; without even the implied warranty of 133e308f20SDaniel P. Berrange * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 143e308f20SDaniel P. Berrange * Lesser General Public License for more details. 153e308f20SDaniel P. Berrange * 163e308f20SDaniel P. Berrange * You should have received a copy of the GNU Lesser General Public 173e308f20SDaniel P. Berrange * License along with this library; if not, see <http://www.gnu.org/licenses/>. 183e308f20SDaniel P. Berrange * 193e308f20SDaniel P. Berrange */ 203e308f20SDaniel P. Berrange 213e308f20SDaniel P. Berrange #include "qemu/osdep.h" 22da34e65cSMarkus Armbruster #include "qapi/error.h" 2358369e22SPaolo Bonzini #include "qemu/bswap.h" 243e308f20SDaniel P. Berrange 25986bc8deSMichael S. Tsirkin #include "block-luks.h" 263e308f20SDaniel P. Berrange 273e308f20SDaniel P. Berrange #include "crypto/hash.h" 283e308f20SDaniel P. Berrange #include "crypto/afsplit.h" 293e308f20SDaniel P. Berrange #include "crypto/pbkdf.h" 303e308f20SDaniel P. Berrange #include "crypto/secret.h" 313e308f20SDaniel P. Berrange #include "crypto/random.h" 322ef950f9SFam Zheng #include "qemu/uuid.h" 333e308f20SDaniel P. Berrange 343e308f20SDaniel P. Berrange #include "qemu/coroutine.h" 353e308f20SDaniel P. Berrange 363e308f20SDaniel P. Berrange /* 373e308f20SDaniel P. Berrange * Reference for the LUKS format implemented here is 383e308f20SDaniel P. Berrange * 393e308f20SDaniel P. Berrange * docs/on-disk-format.pdf 403e308f20SDaniel P. Berrange * 413e308f20SDaniel P. Berrange * in 'cryptsetup' package source code 423e308f20SDaniel P. Berrange * 433e308f20SDaniel P. Berrange * This file implements the 1.2.1 specification, dated 443e308f20SDaniel P. Berrange * Oct 16, 2011. 453e308f20SDaniel P. Berrange */ 463e308f20SDaniel P. Berrange 473e308f20SDaniel P. Berrange typedef struct QCryptoBlockLUKS QCryptoBlockLUKS; 483e308f20SDaniel P. Berrange typedef struct QCryptoBlockLUKSHeader QCryptoBlockLUKSHeader; 493e308f20SDaniel P. Berrange typedef struct QCryptoBlockLUKSKeySlot QCryptoBlockLUKSKeySlot; 503e308f20SDaniel P. Berrange 513e308f20SDaniel P. Berrange 523e308f20SDaniel P. Berrange /* The following constants are all defined by the LUKS spec */ 533e308f20SDaniel P. Berrange #define QCRYPTO_BLOCK_LUKS_VERSION 1 543e308f20SDaniel P. Berrange 553e308f20SDaniel P. Berrange #define QCRYPTO_BLOCK_LUKS_MAGIC_LEN 6 563e308f20SDaniel P. Berrange #define QCRYPTO_BLOCK_LUKS_CIPHER_NAME_LEN 32 573e308f20SDaniel P. Berrange #define QCRYPTO_BLOCK_LUKS_CIPHER_MODE_LEN 32 583e308f20SDaniel P. Berrange #define QCRYPTO_BLOCK_LUKS_HASH_SPEC_LEN 32 593e308f20SDaniel P. Berrange #define QCRYPTO_BLOCK_LUKS_DIGEST_LEN 20 603e308f20SDaniel P. Berrange #define QCRYPTO_BLOCK_LUKS_SALT_LEN 32 613e308f20SDaniel P. Berrange #define QCRYPTO_BLOCK_LUKS_UUID_LEN 40 623e308f20SDaniel P. Berrange #define QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS 8 633e308f20SDaniel P. Berrange #define QCRYPTO_BLOCK_LUKS_STRIPES 4000 643e308f20SDaniel P. Berrange #define QCRYPTO_BLOCK_LUKS_MIN_SLOT_KEY_ITERS 1000 653e308f20SDaniel P. Berrange #define QCRYPTO_BLOCK_LUKS_MIN_MASTER_KEY_ITERS 1000 663e308f20SDaniel P. Berrange #define QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET 4096 673e308f20SDaniel P. Berrange 683e308f20SDaniel P. Berrange #define QCRYPTO_BLOCK_LUKS_KEY_SLOT_DISABLED 0x0000DEAD 693e308f20SDaniel P. Berrange #define QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED 0x00AC71F3 703e308f20SDaniel P. Berrange 713e308f20SDaniel P. Berrange #define QCRYPTO_BLOCK_LUKS_SECTOR_SIZE 512LL 723e308f20SDaniel P. Berrange 733e308f20SDaniel P. Berrange static const char qcrypto_block_luks_magic[QCRYPTO_BLOCK_LUKS_MAGIC_LEN] = { 743e308f20SDaniel P. Berrange 'L', 'U', 'K', 'S', 0xBA, 0xBE 753e308f20SDaniel P. Berrange }; 763e308f20SDaniel P. Berrange 773e308f20SDaniel P. Berrange typedef struct QCryptoBlockLUKSNameMap QCryptoBlockLUKSNameMap; 783e308f20SDaniel P. Berrange struct QCryptoBlockLUKSNameMap { 793e308f20SDaniel P. Berrange const char *name; 803e308f20SDaniel P. Berrange int id; 813e308f20SDaniel P. Berrange }; 823e308f20SDaniel P. Berrange 833e308f20SDaniel P. Berrange typedef struct QCryptoBlockLUKSCipherSizeMap QCryptoBlockLUKSCipherSizeMap; 843e308f20SDaniel P. Berrange struct QCryptoBlockLUKSCipherSizeMap { 853e308f20SDaniel P. Berrange uint32_t key_bytes; 863e308f20SDaniel P. Berrange int id; 873e308f20SDaniel P. Berrange }; 883e308f20SDaniel P. Berrange typedef struct QCryptoBlockLUKSCipherNameMap QCryptoBlockLUKSCipherNameMap; 893e308f20SDaniel P. Berrange struct QCryptoBlockLUKSCipherNameMap { 903e308f20SDaniel P. Berrange const char *name; 913e308f20SDaniel P. Berrange const QCryptoBlockLUKSCipherSizeMap *sizes; 923e308f20SDaniel P. Berrange }; 933e308f20SDaniel P. Berrange 943e308f20SDaniel P. Berrange 953e308f20SDaniel P. Berrange static const QCryptoBlockLUKSCipherSizeMap 963e308f20SDaniel P. Berrange qcrypto_block_luks_cipher_size_map_aes[] = { 973e308f20SDaniel P. Berrange { 16, QCRYPTO_CIPHER_ALG_AES_128 }, 983e308f20SDaniel P. Berrange { 24, QCRYPTO_CIPHER_ALG_AES_192 }, 993e308f20SDaniel P. Berrange { 32, QCRYPTO_CIPHER_ALG_AES_256 }, 1003e308f20SDaniel P. Berrange { 0, 0 }, 1013e308f20SDaniel P. Berrange }; 1023e308f20SDaniel P. Berrange 1033e308f20SDaniel P. Berrange static const QCryptoBlockLUKSCipherSizeMap 1043e308f20SDaniel P. Berrange qcrypto_block_luks_cipher_size_map_cast5[] = { 1053e308f20SDaniel P. Berrange { 16, QCRYPTO_CIPHER_ALG_CAST5_128 }, 1063e308f20SDaniel P. Berrange { 0, 0 }, 1073e308f20SDaniel P. Berrange }; 1083e308f20SDaniel P. Berrange 1093e308f20SDaniel P. Berrange static const QCryptoBlockLUKSCipherSizeMap 1103e308f20SDaniel P. Berrange qcrypto_block_luks_cipher_size_map_serpent[] = { 1113e308f20SDaniel P. Berrange { 16, QCRYPTO_CIPHER_ALG_SERPENT_128 }, 1123e308f20SDaniel P. Berrange { 24, QCRYPTO_CIPHER_ALG_SERPENT_192 }, 1133e308f20SDaniel P. Berrange { 32, QCRYPTO_CIPHER_ALG_SERPENT_256 }, 1143e308f20SDaniel P. Berrange { 0, 0 }, 1153e308f20SDaniel P. Berrange }; 1163e308f20SDaniel P. Berrange 1173e308f20SDaniel P. Berrange static const QCryptoBlockLUKSCipherSizeMap 1183e308f20SDaniel P. Berrange qcrypto_block_luks_cipher_size_map_twofish[] = { 1193e308f20SDaniel P. Berrange { 16, QCRYPTO_CIPHER_ALG_TWOFISH_128 }, 1203e308f20SDaniel P. Berrange { 24, QCRYPTO_CIPHER_ALG_TWOFISH_192 }, 1213e308f20SDaniel P. Berrange { 32, QCRYPTO_CIPHER_ALG_TWOFISH_256 }, 1223e308f20SDaniel P. Berrange { 0, 0 }, 1233e308f20SDaniel P. Berrange }; 1243e308f20SDaniel P. Berrange 1253e308f20SDaniel P. Berrange static const QCryptoBlockLUKSCipherNameMap 1263e308f20SDaniel P. Berrange qcrypto_block_luks_cipher_name_map[] = { 1273e308f20SDaniel P. Berrange { "aes", qcrypto_block_luks_cipher_size_map_aes }, 1283e308f20SDaniel P. Berrange { "cast5", qcrypto_block_luks_cipher_size_map_cast5 }, 1293e308f20SDaniel P. Berrange { "serpent", qcrypto_block_luks_cipher_size_map_serpent }, 1303e308f20SDaniel P. Berrange { "twofish", qcrypto_block_luks_cipher_size_map_twofish }, 1313e308f20SDaniel P. Berrange }; 1323e308f20SDaniel P. Berrange 1333e308f20SDaniel P. Berrange 1343e308f20SDaniel P. Berrange /* 1353e308f20SDaniel P. Berrange * This struct is written to disk in big-endian format, 1363e308f20SDaniel P. Berrange * but operated upon in native-endian format. 1373e308f20SDaniel P. Berrange */ 1383e308f20SDaniel P. Berrange struct QCryptoBlockLUKSKeySlot { 1393e308f20SDaniel P. Berrange /* state of keyslot, enabled/disable */ 1403e308f20SDaniel P. Berrange uint32_t active; 1413e308f20SDaniel P. Berrange /* iterations for PBKDF2 */ 1423e308f20SDaniel P. Berrange uint32_t iterations; 1433e308f20SDaniel P. Berrange /* salt for PBKDF2 */ 1443e308f20SDaniel P. Berrange uint8_t salt[QCRYPTO_BLOCK_LUKS_SALT_LEN]; 1453e308f20SDaniel P. Berrange /* start sector of key material */ 146f0d3c362SMaxim Levitsky uint32_t key_offset_sector; 1473e308f20SDaniel P. Berrange /* number of anti-forensic stripes */ 1483e308f20SDaniel P. Berrange uint32_t stripes; 1495993e3beSGreg Kurz }; 1503e308f20SDaniel P. Berrange 1513e308f20SDaniel P. Berrange QEMU_BUILD_BUG_ON(sizeof(struct QCryptoBlockLUKSKeySlot) != 48); 1523e308f20SDaniel P. Berrange 1533e308f20SDaniel P. Berrange 1543e308f20SDaniel P. Berrange /* 1553e308f20SDaniel P. Berrange * This struct is written to disk in big-endian format, 1563e308f20SDaniel P. Berrange * but operated upon in native-endian format. 1573e308f20SDaniel P. Berrange */ 1583e308f20SDaniel P. Berrange struct QCryptoBlockLUKSHeader { 1593e308f20SDaniel P. Berrange /* 'L', 'U', 'K', 'S', '0xBA', '0xBE' */ 1603e308f20SDaniel P. Berrange char magic[QCRYPTO_BLOCK_LUKS_MAGIC_LEN]; 1613e308f20SDaniel P. Berrange 1623e308f20SDaniel P. Berrange /* LUKS version, currently 1 */ 1633e308f20SDaniel P. Berrange uint16_t version; 1643e308f20SDaniel P. Berrange 1653e308f20SDaniel P. Berrange /* cipher name specification (aes, etc) */ 1663e308f20SDaniel P. Berrange char cipher_name[QCRYPTO_BLOCK_LUKS_CIPHER_NAME_LEN]; 1673e308f20SDaniel P. Berrange 1683e308f20SDaniel P. Berrange /* cipher mode specification (cbc-plain, xts-essiv:sha256, etc) */ 1693e308f20SDaniel P. Berrange char cipher_mode[QCRYPTO_BLOCK_LUKS_CIPHER_MODE_LEN]; 1703e308f20SDaniel P. Berrange 1713e308f20SDaniel P. Berrange /* hash specification (sha256, etc) */ 1723e308f20SDaniel P. Berrange char hash_spec[QCRYPTO_BLOCK_LUKS_HASH_SPEC_LEN]; 1733e308f20SDaniel P. Berrange 1743e308f20SDaniel P. Berrange /* start offset of the volume data (in 512 byte sectors) */ 175f0d3c362SMaxim Levitsky uint32_t payload_offset_sector; 1763e308f20SDaniel P. Berrange 1773e308f20SDaniel P. Berrange /* Number of key bytes */ 178f0d3c362SMaxim Levitsky uint32_t master_key_len; 1793e308f20SDaniel P. Berrange 1803e308f20SDaniel P. Berrange /* master key checksum after PBKDF2 */ 1813e308f20SDaniel P. Berrange uint8_t master_key_digest[QCRYPTO_BLOCK_LUKS_DIGEST_LEN]; 1823e308f20SDaniel P. Berrange 1833e308f20SDaniel P. Berrange /* salt for master key PBKDF2 */ 1843e308f20SDaniel P. Berrange uint8_t master_key_salt[QCRYPTO_BLOCK_LUKS_SALT_LEN]; 1853e308f20SDaniel P. Berrange 1863e308f20SDaniel P. Berrange /* iterations for master key PBKDF2 */ 1873e308f20SDaniel P. Berrange uint32_t master_key_iterations; 1883e308f20SDaniel P. Berrange 1893e308f20SDaniel P. Berrange /* UUID of the partition in standard ASCII representation */ 1903e308f20SDaniel P. Berrange uint8_t uuid[QCRYPTO_BLOCK_LUKS_UUID_LEN]; 1913e308f20SDaniel P. Berrange 1923e308f20SDaniel P. Berrange /* key slots */ 1933e308f20SDaniel P. Berrange QCryptoBlockLUKSKeySlot key_slots[QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS]; 1945993e3beSGreg Kurz }; 1953e308f20SDaniel P. Berrange 1963e308f20SDaniel P. Berrange QEMU_BUILD_BUG_ON(sizeof(struct QCryptoBlockLUKSHeader) != 592); 1973e308f20SDaniel P. Berrange 1983e308f20SDaniel P. Berrange 1993e308f20SDaniel P. Berrange struct QCryptoBlockLUKS { 2003e308f20SDaniel P. Berrange QCryptoBlockLUKSHeader header; 20140c85028SDaniel P. Berrange 2029d80e59dSMaxim Levitsky /* Main encryption algorithm used for encryption*/ 20340c85028SDaniel P. Berrange QCryptoCipherAlgorithm cipher_alg; 2049d80e59dSMaxim Levitsky 2059d80e59dSMaxim Levitsky /* Mode of encryption for the selected encryption algorithm */ 20640c85028SDaniel P. Berrange QCryptoCipherMode cipher_mode; 2079d80e59dSMaxim Levitsky 2089d80e59dSMaxim Levitsky /* Initialization vector generation algorithm */ 20940c85028SDaniel P. Berrange QCryptoIVGenAlgorithm ivgen_alg; 2109d80e59dSMaxim Levitsky 2119d80e59dSMaxim Levitsky /* Hash algorithm used for IV generation*/ 21240c85028SDaniel P. Berrange QCryptoHashAlgorithm ivgen_hash_alg; 2139d80e59dSMaxim Levitsky 2149d80e59dSMaxim Levitsky /* 2159d80e59dSMaxim Levitsky * Encryption algorithm used for IV generation. 2169d80e59dSMaxim Levitsky * Usually the same as main encryption algorithm 2179d80e59dSMaxim Levitsky */ 2189d80e59dSMaxim Levitsky QCryptoCipherAlgorithm ivgen_cipher_alg; 2199d80e59dSMaxim Levitsky 2209d80e59dSMaxim Levitsky /* Hash algorithm used in pbkdf2 function */ 22140c85028SDaniel P. Berrange QCryptoHashAlgorithm hash_alg; 2223e308f20SDaniel P. Berrange }; 2233e308f20SDaniel P. Berrange 2243e308f20SDaniel P. Berrange 2253e308f20SDaniel P. Berrange static int qcrypto_block_luks_cipher_name_lookup(const char *name, 2263e308f20SDaniel P. Berrange QCryptoCipherMode mode, 2273e308f20SDaniel P. Berrange uint32_t key_bytes, 2283e308f20SDaniel P. Berrange Error **errp) 2293e308f20SDaniel P. Berrange { 2303e308f20SDaniel P. Berrange const QCryptoBlockLUKSCipherNameMap *map = 2313e308f20SDaniel P. Berrange qcrypto_block_luks_cipher_name_map; 2323e308f20SDaniel P. Berrange size_t maplen = G_N_ELEMENTS(qcrypto_block_luks_cipher_name_map); 2333e308f20SDaniel P. Berrange size_t i, j; 2343e308f20SDaniel P. Berrange 2353e308f20SDaniel P. Berrange if (mode == QCRYPTO_CIPHER_MODE_XTS) { 2363e308f20SDaniel P. Berrange key_bytes /= 2; 2373e308f20SDaniel P. Berrange } 2383e308f20SDaniel P. Berrange 2393e308f20SDaniel P. Berrange for (i = 0; i < maplen; i++) { 2403e308f20SDaniel P. Berrange if (!g_str_equal(map[i].name, name)) { 2413e308f20SDaniel P. Berrange continue; 2423e308f20SDaniel P. Berrange } 2433e308f20SDaniel P. Berrange for (j = 0; j < map[i].sizes[j].key_bytes; j++) { 2443e308f20SDaniel P. Berrange if (map[i].sizes[j].key_bytes == key_bytes) { 2453e308f20SDaniel P. Berrange return map[i].sizes[j].id; 2463e308f20SDaniel P. Berrange } 2473e308f20SDaniel P. Berrange } 2483e308f20SDaniel P. Berrange } 2493e308f20SDaniel P. Berrange 2503e308f20SDaniel P. Berrange error_setg(errp, "Algorithm %s with key size %d bytes not supported", 2513e308f20SDaniel P. Berrange name, key_bytes); 2523e308f20SDaniel P. Berrange return 0; 2533e308f20SDaniel P. Berrange } 2543e308f20SDaniel P. Berrange 2553e308f20SDaniel P. Berrange static const char * 2563e308f20SDaniel P. Berrange qcrypto_block_luks_cipher_alg_lookup(QCryptoCipherAlgorithm alg, 2573e308f20SDaniel P. Berrange Error **errp) 2583e308f20SDaniel P. Berrange { 2593e308f20SDaniel P. Berrange const QCryptoBlockLUKSCipherNameMap *map = 2603e308f20SDaniel P. Berrange qcrypto_block_luks_cipher_name_map; 2613e308f20SDaniel P. Berrange size_t maplen = G_N_ELEMENTS(qcrypto_block_luks_cipher_name_map); 2623e308f20SDaniel P. Berrange size_t i, j; 2633e308f20SDaniel P. Berrange for (i = 0; i < maplen; i++) { 2643e308f20SDaniel P. Berrange for (j = 0; j < map[i].sizes[j].key_bytes; j++) { 2653e308f20SDaniel P. Berrange if (map[i].sizes[j].id == alg) { 2663e308f20SDaniel P. Berrange return map[i].name; 2673e308f20SDaniel P. Berrange } 2683e308f20SDaniel P. Berrange } 2693e308f20SDaniel P. Berrange } 2703e308f20SDaniel P. Berrange 2713e308f20SDaniel P. Berrange error_setg(errp, "Algorithm '%s' not supported", 272977c736fSMarkus Armbruster QCryptoCipherAlgorithm_str(alg)); 2733e308f20SDaniel P. Berrange return NULL; 2743e308f20SDaniel P. Berrange } 2753e308f20SDaniel P. Berrange 2763e308f20SDaniel P. Berrange /* XXX replace with qapi_enum_parse() in future, when we can 2773e308f20SDaniel P. Berrange * make that function emit a more friendly error message */ 2783e308f20SDaniel P. Berrange static int qcrypto_block_luks_name_lookup(const char *name, 279f7abe0ecSMarc-André Lureau const QEnumLookup *map, 2803e308f20SDaniel P. Berrange const char *type, 2813e308f20SDaniel P. Berrange Error **errp) 2823e308f20SDaniel P. Berrange { 2839ae33079SMarkus Armbruster int ret = qapi_enum_parse(map, name, -1, NULL); 2843e308f20SDaniel P. Berrange 2859ae33079SMarkus Armbruster if (ret < 0) { 2863e308f20SDaniel P. Berrange error_setg(errp, "%s %s not supported", type, name); 2873e308f20SDaniel P. Berrange return 0; 2883e308f20SDaniel P. Berrange } 2899ae33079SMarkus Armbruster return ret; 2909ae33079SMarkus Armbruster } 2913e308f20SDaniel P. Berrange 2923e308f20SDaniel P. Berrange #define qcrypto_block_luks_cipher_mode_lookup(name, errp) \ 2933e308f20SDaniel P. Berrange qcrypto_block_luks_name_lookup(name, \ 294f7abe0ecSMarc-André Lureau &QCryptoCipherMode_lookup, \ 2953e308f20SDaniel P. Berrange "Cipher mode", \ 2963e308f20SDaniel P. Berrange errp) 2973e308f20SDaniel P. Berrange 2983e308f20SDaniel P. Berrange #define qcrypto_block_luks_hash_name_lookup(name, errp) \ 2993e308f20SDaniel P. Berrange qcrypto_block_luks_name_lookup(name, \ 300f7abe0ecSMarc-André Lureau &QCryptoHashAlgorithm_lookup, \ 3013e308f20SDaniel P. Berrange "Hash algorithm", \ 3023e308f20SDaniel P. Berrange errp) 3033e308f20SDaniel P. Berrange 3043e308f20SDaniel P. Berrange #define qcrypto_block_luks_ivgen_name_lookup(name, errp) \ 3053e308f20SDaniel P. Berrange qcrypto_block_luks_name_lookup(name, \ 306f7abe0ecSMarc-André Lureau &QCryptoIVGenAlgorithm_lookup, \ 3073e308f20SDaniel P. Berrange "IV generator", \ 3083e308f20SDaniel P. Berrange errp) 3093e308f20SDaniel P. Berrange 3103e308f20SDaniel P. Berrange 3113e308f20SDaniel P. Berrange static bool 3123e308f20SDaniel P. Berrange qcrypto_block_luks_has_format(const uint8_t *buf, 3133e308f20SDaniel P. Berrange size_t buf_size) 3143e308f20SDaniel P. Berrange { 3153e308f20SDaniel P. Berrange const QCryptoBlockLUKSHeader *luks_header = (const void *)buf; 3163e308f20SDaniel P. Berrange 3173e308f20SDaniel P. Berrange if (buf_size >= offsetof(QCryptoBlockLUKSHeader, cipher_name) && 3183e308f20SDaniel P. Berrange memcmp(luks_header->magic, qcrypto_block_luks_magic, 3193e308f20SDaniel P. Berrange QCRYPTO_BLOCK_LUKS_MAGIC_LEN) == 0 && 3203e308f20SDaniel P. Berrange be16_to_cpu(luks_header->version) == QCRYPTO_BLOCK_LUKS_VERSION) { 3213e308f20SDaniel P. Berrange return true; 3223e308f20SDaniel P. Berrange } else { 3233e308f20SDaniel P. Berrange return false; 3243e308f20SDaniel P. Berrange } 3253e308f20SDaniel P. Berrange } 3263e308f20SDaniel P. Berrange 3273e308f20SDaniel P. Berrange 3283e308f20SDaniel P. Berrange /** 3293e308f20SDaniel P. Berrange * Deal with a quirk of dm-crypt usage of ESSIV. 3303e308f20SDaniel P. Berrange * 3313e308f20SDaniel P. Berrange * When calculating ESSIV IVs, the cipher length used by ESSIV 3323e308f20SDaniel P. Berrange * may be different from the cipher length used for the block 3333e308f20SDaniel P. Berrange * encryption, becauses dm-crypt uses the hash digest length 3343e308f20SDaniel P. Berrange * as the key size. ie, if you have AES 128 as the block cipher 3353e308f20SDaniel P. Berrange * and SHA 256 as ESSIV hash, then ESSIV will use AES 256 as 3363e308f20SDaniel P. Berrange * the cipher since that gets a key length matching the digest 3373e308f20SDaniel P. Berrange * size, not AES 128 with truncated digest as might be imagined 3383e308f20SDaniel P. Berrange */ 3393e308f20SDaniel P. Berrange static QCryptoCipherAlgorithm 3403e308f20SDaniel P. Berrange qcrypto_block_luks_essiv_cipher(QCryptoCipherAlgorithm cipher, 3413e308f20SDaniel P. Berrange QCryptoHashAlgorithm hash, 3423e308f20SDaniel P. Berrange Error **errp) 3433e308f20SDaniel P. Berrange { 3443e308f20SDaniel P. Berrange size_t digestlen = qcrypto_hash_digest_len(hash); 3453e308f20SDaniel P. Berrange size_t keylen = qcrypto_cipher_get_key_len(cipher); 3463e308f20SDaniel P. Berrange if (digestlen == keylen) { 3473e308f20SDaniel P. Berrange return cipher; 3483e308f20SDaniel P. Berrange } 3493e308f20SDaniel P. Berrange 3503e308f20SDaniel P. Berrange switch (cipher) { 3513e308f20SDaniel P. Berrange case QCRYPTO_CIPHER_ALG_AES_128: 3523e308f20SDaniel P. Berrange case QCRYPTO_CIPHER_ALG_AES_192: 3533e308f20SDaniel P. Berrange case QCRYPTO_CIPHER_ALG_AES_256: 3543e308f20SDaniel P. Berrange if (digestlen == qcrypto_cipher_get_key_len( 3553e308f20SDaniel P. Berrange QCRYPTO_CIPHER_ALG_AES_128)) { 3563e308f20SDaniel P. Berrange return QCRYPTO_CIPHER_ALG_AES_128; 3573e308f20SDaniel P. Berrange } else if (digestlen == qcrypto_cipher_get_key_len( 3583e308f20SDaniel P. Berrange QCRYPTO_CIPHER_ALG_AES_192)) { 3593e308f20SDaniel P. Berrange return QCRYPTO_CIPHER_ALG_AES_192; 3603e308f20SDaniel P. Berrange } else if (digestlen == qcrypto_cipher_get_key_len( 3613e308f20SDaniel P. Berrange QCRYPTO_CIPHER_ALG_AES_256)) { 3623e308f20SDaniel P. Berrange return QCRYPTO_CIPHER_ALG_AES_256; 3633e308f20SDaniel P. Berrange } else { 3643e308f20SDaniel P. Berrange error_setg(errp, "No AES cipher with key size %zu available", 3653e308f20SDaniel P. Berrange digestlen); 3663e308f20SDaniel P. Berrange return 0; 3673e308f20SDaniel P. Berrange } 3683e308f20SDaniel P. Berrange break; 3693e308f20SDaniel P. Berrange case QCRYPTO_CIPHER_ALG_SERPENT_128: 3703e308f20SDaniel P. Berrange case QCRYPTO_CIPHER_ALG_SERPENT_192: 3713e308f20SDaniel P. Berrange case QCRYPTO_CIPHER_ALG_SERPENT_256: 3723e308f20SDaniel P. Berrange if (digestlen == qcrypto_cipher_get_key_len( 3733e308f20SDaniel P. Berrange QCRYPTO_CIPHER_ALG_SERPENT_128)) { 3743e308f20SDaniel P. Berrange return QCRYPTO_CIPHER_ALG_SERPENT_128; 3753e308f20SDaniel P. Berrange } else if (digestlen == qcrypto_cipher_get_key_len( 3763e308f20SDaniel P. Berrange QCRYPTO_CIPHER_ALG_SERPENT_192)) { 3773e308f20SDaniel P. Berrange return QCRYPTO_CIPHER_ALG_SERPENT_192; 3783e308f20SDaniel P. Berrange } else if (digestlen == qcrypto_cipher_get_key_len( 3793e308f20SDaniel P. Berrange QCRYPTO_CIPHER_ALG_SERPENT_256)) { 3803e308f20SDaniel P. Berrange return QCRYPTO_CIPHER_ALG_SERPENT_256; 3813e308f20SDaniel P. Berrange } else { 3823e308f20SDaniel P. Berrange error_setg(errp, "No Serpent cipher with key size %zu available", 3833e308f20SDaniel P. Berrange digestlen); 3843e308f20SDaniel P. Berrange return 0; 3853e308f20SDaniel P. Berrange } 3863e308f20SDaniel P. Berrange break; 3873e308f20SDaniel P. Berrange case QCRYPTO_CIPHER_ALG_TWOFISH_128: 3883e308f20SDaniel P. Berrange case QCRYPTO_CIPHER_ALG_TWOFISH_192: 3893e308f20SDaniel P. Berrange case QCRYPTO_CIPHER_ALG_TWOFISH_256: 3903e308f20SDaniel P. Berrange if (digestlen == qcrypto_cipher_get_key_len( 3913e308f20SDaniel P. Berrange QCRYPTO_CIPHER_ALG_TWOFISH_128)) { 3923e308f20SDaniel P. Berrange return QCRYPTO_CIPHER_ALG_TWOFISH_128; 3933e308f20SDaniel P. Berrange } else if (digestlen == qcrypto_cipher_get_key_len( 3943e308f20SDaniel P. Berrange QCRYPTO_CIPHER_ALG_TWOFISH_192)) { 3953e308f20SDaniel P. Berrange return QCRYPTO_CIPHER_ALG_TWOFISH_192; 3963e308f20SDaniel P. Berrange } else if (digestlen == qcrypto_cipher_get_key_len( 3973e308f20SDaniel P. Berrange QCRYPTO_CIPHER_ALG_TWOFISH_256)) { 3983e308f20SDaniel P. Berrange return QCRYPTO_CIPHER_ALG_TWOFISH_256; 3993e308f20SDaniel P. Berrange } else { 4003e308f20SDaniel P. Berrange error_setg(errp, "No Twofish cipher with key size %zu available", 4013e308f20SDaniel P. Berrange digestlen); 4023e308f20SDaniel P. Berrange return 0; 4033e308f20SDaniel P. Berrange } 4043e308f20SDaniel P. Berrange break; 4053e308f20SDaniel P. Berrange default: 4063e308f20SDaniel P. Berrange error_setg(errp, "Cipher %s not supported with essiv", 407977c736fSMarkus Armbruster QCryptoCipherAlgorithm_str(cipher)); 4083e308f20SDaniel P. Berrange return 0; 4093e308f20SDaniel P. Berrange } 4103e308f20SDaniel P. Berrange } 4113e308f20SDaniel P. Berrange 4123e308f20SDaniel P. Berrange /* 413bd56a55aSMaxim Levitsky * Returns number of sectors needed to store the key material 414bd56a55aSMaxim Levitsky * given number of anti forensic stripes 415bd56a55aSMaxim Levitsky */ 416bd56a55aSMaxim Levitsky static int 417bd56a55aSMaxim Levitsky qcrypto_block_luks_splitkeylen_sectors(const QCryptoBlockLUKS *luks, 418bd56a55aSMaxim Levitsky unsigned int header_sectors, 419bd56a55aSMaxim Levitsky unsigned int stripes) 420bd56a55aSMaxim Levitsky { 421bd56a55aSMaxim Levitsky /* 422bd56a55aSMaxim Levitsky * This calculation doesn't match that shown in the spec, 423bd56a55aSMaxim Levitsky * but instead follows the cryptsetup implementation. 424bd56a55aSMaxim Levitsky */ 425bd56a55aSMaxim Levitsky 426bd56a55aSMaxim Levitsky size_t splitkeylen = luks->header.master_key_len * stripes; 427bd56a55aSMaxim Levitsky 428bd56a55aSMaxim Levitsky /* First align the key material size to block size*/ 429bd56a55aSMaxim Levitsky size_t splitkeylen_sectors = 430bd56a55aSMaxim Levitsky DIV_ROUND_UP(splitkeylen, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE); 431bd56a55aSMaxim Levitsky 432bd56a55aSMaxim Levitsky /* Then also align the key material size to the size of the header */ 433bd56a55aSMaxim Levitsky return ROUND_UP(splitkeylen_sectors, header_sectors); 434bd56a55aSMaxim Levitsky } 435bd56a55aSMaxim Levitsky 436bd56a55aSMaxim Levitsky /* 437dde2c5afSMaxim Levitsky * Stores the main LUKS header, taking care of endianess 438dde2c5afSMaxim Levitsky */ 439dde2c5afSMaxim Levitsky static int 440dde2c5afSMaxim Levitsky qcrypto_block_luks_store_header(QCryptoBlock *block, 441dde2c5afSMaxim Levitsky QCryptoBlockWriteFunc writefunc, 442dde2c5afSMaxim Levitsky void *opaque, 443dde2c5afSMaxim Levitsky Error **errp) 444dde2c5afSMaxim Levitsky { 445dde2c5afSMaxim Levitsky const QCryptoBlockLUKS *luks = block->opaque; 446dde2c5afSMaxim Levitsky Error *local_err = NULL; 447dde2c5afSMaxim Levitsky size_t i; 448dde2c5afSMaxim Levitsky g_autofree QCryptoBlockLUKSHeader *hdr_copy = NULL; 449dde2c5afSMaxim Levitsky 450dde2c5afSMaxim Levitsky /* Create a copy of the header */ 451dde2c5afSMaxim Levitsky hdr_copy = g_new0(QCryptoBlockLUKSHeader, 1); 452dde2c5afSMaxim Levitsky memcpy(hdr_copy, &luks->header, sizeof(QCryptoBlockLUKSHeader)); 453dde2c5afSMaxim Levitsky 454dde2c5afSMaxim Levitsky /* 455dde2c5afSMaxim Levitsky * Everything on disk uses Big Endian (tm), so flip header fields 456dde2c5afSMaxim Levitsky * before writing them 457dde2c5afSMaxim Levitsky */ 458dde2c5afSMaxim Levitsky cpu_to_be16s(&hdr_copy->version); 459dde2c5afSMaxim Levitsky cpu_to_be32s(&hdr_copy->payload_offset_sector); 460dde2c5afSMaxim Levitsky cpu_to_be32s(&hdr_copy->master_key_len); 461dde2c5afSMaxim Levitsky cpu_to_be32s(&hdr_copy->master_key_iterations); 462dde2c5afSMaxim Levitsky 463dde2c5afSMaxim Levitsky for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) { 464dde2c5afSMaxim Levitsky cpu_to_be32s(&hdr_copy->key_slots[i].active); 465dde2c5afSMaxim Levitsky cpu_to_be32s(&hdr_copy->key_slots[i].iterations); 466dde2c5afSMaxim Levitsky cpu_to_be32s(&hdr_copy->key_slots[i].key_offset_sector); 467dde2c5afSMaxim Levitsky cpu_to_be32s(&hdr_copy->key_slots[i].stripes); 468dde2c5afSMaxim Levitsky } 469dde2c5afSMaxim Levitsky 470dde2c5afSMaxim Levitsky /* Write out the partition header and key slot headers */ 471dde2c5afSMaxim Levitsky writefunc(block, 0, (const uint8_t *)hdr_copy, sizeof(*hdr_copy), 472dde2c5afSMaxim Levitsky opaque, &local_err); 473dde2c5afSMaxim Levitsky 474dde2c5afSMaxim Levitsky if (local_err) { 475dde2c5afSMaxim Levitsky error_propagate(errp, local_err); 476dde2c5afSMaxim Levitsky return -1; 477dde2c5afSMaxim Levitsky } 478dde2c5afSMaxim Levitsky return 0; 479dde2c5afSMaxim Levitsky } 480dde2c5afSMaxim Levitsky 481dde2c5afSMaxim Levitsky /* 482dde2c5afSMaxim Levitsky * Loads the main LUKS header,and byteswaps it to native endianess 483dde2c5afSMaxim Levitsky * And run basic sanity checks on it 484dde2c5afSMaxim Levitsky */ 485dde2c5afSMaxim Levitsky static int 486dde2c5afSMaxim Levitsky qcrypto_block_luks_load_header(QCryptoBlock *block, 487dde2c5afSMaxim Levitsky QCryptoBlockReadFunc readfunc, 488dde2c5afSMaxim Levitsky void *opaque, 489dde2c5afSMaxim Levitsky Error **errp) 490dde2c5afSMaxim Levitsky { 491dde2c5afSMaxim Levitsky ssize_t rv; 492dde2c5afSMaxim Levitsky size_t i; 493dde2c5afSMaxim Levitsky QCryptoBlockLUKS *luks = block->opaque; 494dde2c5afSMaxim Levitsky 495dde2c5afSMaxim Levitsky /* 496dde2c5afSMaxim Levitsky * Read the entire LUKS header, minus the key material from 497dde2c5afSMaxim Levitsky * the underlying device 498dde2c5afSMaxim Levitsky */ 499dde2c5afSMaxim Levitsky rv = readfunc(block, 0, 500dde2c5afSMaxim Levitsky (uint8_t *)&luks->header, 501dde2c5afSMaxim Levitsky sizeof(luks->header), 502dde2c5afSMaxim Levitsky opaque, 503dde2c5afSMaxim Levitsky errp); 504dde2c5afSMaxim Levitsky if (rv < 0) { 505dde2c5afSMaxim Levitsky return rv; 506dde2c5afSMaxim Levitsky } 507dde2c5afSMaxim Levitsky 508dde2c5afSMaxim Levitsky /* 509dde2c5afSMaxim Levitsky * The header is always stored in big-endian format, so 510dde2c5afSMaxim Levitsky * convert everything to native 511dde2c5afSMaxim Levitsky */ 512dde2c5afSMaxim Levitsky be16_to_cpus(&luks->header.version); 513dde2c5afSMaxim Levitsky be32_to_cpus(&luks->header.payload_offset_sector); 514dde2c5afSMaxim Levitsky be32_to_cpus(&luks->header.master_key_len); 515dde2c5afSMaxim Levitsky be32_to_cpus(&luks->header.master_key_iterations); 516dde2c5afSMaxim Levitsky 517dde2c5afSMaxim Levitsky for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) { 518dde2c5afSMaxim Levitsky be32_to_cpus(&luks->header.key_slots[i].active); 519dde2c5afSMaxim Levitsky be32_to_cpus(&luks->header.key_slots[i].iterations); 520dde2c5afSMaxim Levitsky be32_to_cpus(&luks->header.key_slots[i].key_offset_sector); 521dde2c5afSMaxim Levitsky be32_to_cpus(&luks->header.key_slots[i].stripes); 522dde2c5afSMaxim Levitsky } 523dde2c5afSMaxim Levitsky 524dde2c5afSMaxim Levitsky return 0; 525dde2c5afSMaxim Levitsky } 526dde2c5afSMaxim Levitsky 527dde2c5afSMaxim Levitsky /* 5289fa9c1c2SMaxim Levitsky * Does basic sanity checks on the LUKS header 5299fa9c1c2SMaxim Levitsky */ 5309fa9c1c2SMaxim Levitsky static int 5319fa9c1c2SMaxim Levitsky qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp) 5329fa9c1c2SMaxim Levitsky { 533*befdba9eSMaxim Levitsky size_t i, j; 534*befdba9eSMaxim Levitsky 535*befdba9eSMaxim Levitsky unsigned int header_sectors = QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET / 536*befdba9eSMaxim Levitsky QCRYPTO_BLOCK_LUKS_SECTOR_SIZE; 537*befdba9eSMaxim Levitsky 5389fa9c1c2SMaxim Levitsky if (memcmp(luks->header.magic, qcrypto_block_luks_magic, 5399fa9c1c2SMaxim Levitsky QCRYPTO_BLOCK_LUKS_MAGIC_LEN) != 0) { 5409fa9c1c2SMaxim Levitsky error_setg(errp, "Volume is not in LUKS format"); 5419fa9c1c2SMaxim Levitsky return -1; 5429fa9c1c2SMaxim Levitsky } 5439fa9c1c2SMaxim Levitsky 5449fa9c1c2SMaxim Levitsky if (luks->header.version != QCRYPTO_BLOCK_LUKS_VERSION) { 5459fa9c1c2SMaxim Levitsky error_setg(errp, "LUKS version %" PRIu32 " is not supported", 5469fa9c1c2SMaxim Levitsky luks->header.version); 5479fa9c1c2SMaxim Levitsky return -1; 5489fa9c1c2SMaxim Levitsky } 549*befdba9eSMaxim Levitsky 550*befdba9eSMaxim Levitsky /* Check all keyslots for corruption */ 551*befdba9eSMaxim Levitsky for (i = 0 ; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS ; i++) { 552*befdba9eSMaxim Levitsky 553*befdba9eSMaxim Levitsky const QCryptoBlockLUKSKeySlot *slot1 = &luks->header.key_slots[i]; 554*befdba9eSMaxim Levitsky unsigned int start1 = slot1->key_offset_sector; 555*befdba9eSMaxim Levitsky unsigned int len1 = 556*befdba9eSMaxim Levitsky qcrypto_block_luks_splitkeylen_sectors(luks, 557*befdba9eSMaxim Levitsky header_sectors, 558*befdba9eSMaxim Levitsky slot1->stripes); 559*befdba9eSMaxim Levitsky 560*befdba9eSMaxim Levitsky if (slot1->stripes == 0) { 561*befdba9eSMaxim Levitsky error_setg(errp, "Keyslot %zu is corrupted (stripes == 0)", i); 562*befdba9eSMaxim Levitsky return -1; 563*befdba9eSMaxim Levitsky } 564*befdba9eSMaxim Levitsky 565*befdba9eSMaxim Levitsky if (slot1->active != QCRYPTO_BLOCK_LUKS_KEY_SLOT_DISABLED && 566*befdba9eSMaxim Levitsky slot1->active != QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED) { 567*befdba9eSMaxim Levitsky error_setg(errp, 568*befdba9eSMaxim Levitsky "Keyslot %zu state (active/disable) is corrupted", i); 569*befdba9eSMaxim Levitsky return -1; 570*befdba9eSMaxim Levitsky } 571*befdba9eSMaxim Levitsky 572*befdba9eSMaxim Levitsky if (start1 + len1 > luks->header.payload_offset_sector) { 573*befdba9eSMaxim Levitsky error_setg(errp, 574*befdba9eSMaxim Levitsky "Keyslot %zu is overlapping with the encrypted payload", 575*befdba9eSMaxim Levitsky i); 576*befdba9eSMaxim Levitsky return -1; 577*befdba9eSMaxim Levitsky } 578*befdba9eSMaxim Levitsky 579*befdba9eSMaxim Levitsky for (j = i + 1 ; j < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS ; j++) { 580*befdba9eSMaxim Levitsky const QCryptoBlockLUKSKeySlot *slot2 = &luks->header.key_slots[j]; 581*befdba9eSMaxim Levitsky unsigned int start2 = slot2->key_offset_sector; 582*befdba9eSMaxim Levitsky unsigned int len2 = 583*befdba9eSMaxim Levitsky qcrypto_block_luks_splitkeylen_sectors(luks, 584*befdba9eSMaxim Levitsky header_sectors, 585*befdba9eSMaxim Levitsky slot2->stripes); 586*befdba9eSMaxim Levitsky 587*befdba9eSMaxim Levitsky if (start1 + len1 > start2 && start2 + len2 > start1) { 588*befdba9eSMaxim Levitsky error_setg(errp, 589*befdba9eSMaxim Levitsky "Keyslots %zu and %zu are overlapping in the header", 590*befdba9eSMaxim Levitsky i, j); 591*befdba9eSMaxim Levitsky return -1; 592*befdba9eSMaxim Levitsky } 593*befdba9eSMaxim Levitsky } 594*befdba9eSMaxim Levitsky 595*befdba9eSMaxim Levitsky } 5969fa9c1c2SMaxim Levitsky return 0; 5979fa9c1c2SMaxim Levitsky } 5989fa9c1c2SMaxim Levitsky 5999fa9c1c2SMaxim Levitsky /* 6009fa9c1c2SMaxim Levitsky * Parses the crypto parameters that are stored in the LUKS header 6019fa9c1c2SMaxim Levitsky */ 6029fa9c1c2SMaxim Levitsky 6039fa9c1c2SMaxim Levitsky static int 6049fa9c1c2SMaxim Levitsky qcrypto_block_luks_parse_header(QCryptoBlockLUKS *luks, Error **errp) 6059fa9c1c2SMaxim Levitsky { 6069fa9c1c2SMaxim Levitsky g_autofree char *cipher_mode = g_strdup(luks->header.cipher_mode); 6079fa9c1c2SMaxim Levitsky char *ivgen_name, *ivhash_name; 6089fa9c1c2SMaxim Levitsky Error *local_err = NULL; 6099fa9c1c2SMaxim Levitsky 6109fa9c1c2SMaxim Levitsky /* 6119fa9c1c2SMaxim Levitsky * The cipher_mode header contains a string that we have 6129fa9c1c2SMaxim Levitsky * to further parse, of the format 6139fa9c1c2SMaxim Levitsky * 6149fa9c1c2SMaxim Levitsky * <cipher-mode>-<iv-generator>[:<iv-hash>] 6159fa9c1c2SMaxim Levitsky * 6169fa9c1c2SMaxim Levitsky * eg cbc-essiv:sha256, cbc-plain64 6179fa9c1c2SMaxim Levitsky */ 6189fa9c1c2SMaxim Levitsky ivgen_name = strchr(cipher_mode, '-'); 6199fa9c1c2SMaxim Levitsky if (!ivgen_name) { 6209fa9c1c2SMaxim Levitsky error_setg(errp, "Unexpected cipher mode string format %s", 6219fa9c1c2SMaxim Levitsky luks->header.cipher_mode); 6229fa9c1c2SMaxim Levitsky return -1; 6239fa9c1c2SMaxim Levitsky } 6249fa9c1c2SMaxim Levitsky *ivgen_name = '\0'; 6259fa9c1c2SMaxim Levitsky ivgen_name++; 6269fa9c1c2SMaxim Levitsky 6279fa9c1c2SMaxim Levitsky ivhash_name = strchr(ivgen_name, ':'); 6289fa9c1c2SMaxim Levitsky if (!ivhash_name) { 6299fa9c1c2SMaxim Levitsky luks->ivgen_hash_alg = 0; 6309fa9c1c2SMaxim Levitsky } else { 6319fa9c1c2SMaxim Levitsky *ivhash_name = '\0'; 6329fa9c1c2SMaxim Levitsky ivhash_name++; 6339fa9c1c2SMaxim Levitsky 6349fa9c1c2SMaxim Levitsky luks->ivgen_hash_alg = qcrypto_block_luks_hash_name_lookup(ivhash_name, 6359fa9c1c2SMaxim Levitsky &local_err); 6369fa9c1c2SMaxim Levitsky if (local_err) { 6379fa9c1c2SMaxim Levitsky error_propagate(errp, local_err); 6389fa9c1c2SMaxim Levitsky return -1; 6399fa9c1c2SMaxim Levitsky } 6409fa9c1c2SMaxim Levitsky } 6419fa9c1c2SMaxim Levitsky 6429fa9c1c2SMaxim Levitsky luks->cipher_mode = qcrypto_block_luks_cipher_mode_lookup(cipher_mode, 6439fa9c1c2SMaxim Levitsky &local_err); 6449fa9c1c2SMaxim Levitsky if (local_err) { 6459fa9c1c2SMaxim Levitsky error_propagate(errp, local_err); 6469fa9c1c2SMaxim Levitsky return -1; 6479fa9c1c2SMaxim Levitsky } 6489fa9c1c2SMaxim Levitsky 6499fa9c1c2SMaxim Levitsky luks->cipher_alg = 6509fa9c1c2SMaxim Levitsky qcrypto_block_luks_cipher_name_lookup(luks->header.cipher_name, 6519fa9c1c2SMaxim Levitsky luks->cipher_mode, 6529fa9c1c2SMaxim Levitsky luks->header.master_key_len, 6539fa9c1c2SMaxim Levitsky &local_err); 6549fa9c1c2SMaxim Levitsky if (local_err) { 6559fa9c1c2SMaxim Levitsky error_propagate(errp, local_err); 6569fa9c1c2SMaxim Levitsky return -1; 6579fa9c1c2SMaxim Levitsky } 6589fa9c1c2SMaxim Levitsky 6599fa9c1c2SMaxim Levitsky luks->hash_alg = 6609fa9c1c2SMaxim Levitsky qcrypto_block_luks_hash_name_lookup(luks->header.hash_spec, 6619fa9c1c2SMaxim Levitsky &local_err); 6629fa9c1c2SMaxim Levitsky if (local_err) { 6639fa9c1c2SMaxim Levitsky error_propagate(errp, local_err); 6649fa9c1c2SMaxim Levitsky return -1; 6659fa9c1c2SMaxim Levitsky } 6669fa9c1c2SMaxim Levitsky 6679fa9c1c2SMaxim Levitsky luks->ivgen_alg = qcrypto_block_luks_ivgen_name_lookup(ivgen_name, 6689fa9c1c2SMaxim Levitsky &local_err); 6699fa9c1c2SMaxim Levitsky if (local_err) { 6709fa9c1c2SMaxim Levitsky error_propagate(errp, local_err); 6719fa9c1c2SMaxim Levitsky return -1; 6729fa9c1c2SMaxim Levitsky } 6739fa9c1c2SMaxim Levitsky 6749fa9c1c2SMaxim Levitsky if (luks->ivgen_alg == QCRYPTO_IVGEN_ALG_ESSIV) { 6759fa9c1c2SMaxim Levitsky if (!ivhash_name) { 6769fa9c1c2SMaxim Levitsky error_setg(errp, "Missing IV generator hash specification"); 6779fa9c1c2SMaxim Levitsky return -1; 6789fa9c1c2SMaxim Levitsky } 6799fa9c1c2SMaxim Levitsky luks->ivgen_cipher_alg = 6809fa9c1c2SMaxim Levitsky qcrypto_block_luks_essiv_cipher(luks->cipher_alg, 6819fa9c1c2SMaxim Levitsky luks->ivgen_hash_alg, 6829fa9c1c2SMaxim Levitsky &local_err); 6839fa9c1c2SMaxim Levitsky if (local_err) { 6849fa9c1c2SMaxim Levitsky error_propagate(errp, local_err); 6859fa9c1c2SMaxim Levitsky return -1; 6869fa9c1c2SMaxim Levitsky } 6879fa9c1c2SMaxim Levitsky } else { 6889fa9c1c2SMaxim Levitsky 6899fa9c1c2SMaxim Levitsky /* 6909fa9c1c2SMaxim Levitsky * Note we parsed the ivhash_name earlier in the cipher_mode 6919fa9c1c2SMaxim Levitsky * spec string even with plain/plain64 ivgens, but we 6929fa9c1c2SMaxim Levitsky * will ignore it, since it is irrelevant for these ivgens. 6939fa9c1c2SMaxim Levitsky * This is for compat with dm-crypt which will silently 6949fa9c1c2SMaxim Levitsky * ignore hash names with these ivgens rather than report 6959fa9c1c2SMaxim Levitsky * an error about the invalid usage 6969fa9c1c2SMaxim Levitsky */ 6979fa9c1c2SMaxim Levitsky luks->ivgen_cipher_alg = luks->cipher_alg; 6989fa9c1c2SMaxim Levitsky } 6999fa9c1c2SMaxim Levitsky return 0; 7009fa9c1c2SMaxim Levitsky } 7019fa9c1c2SMaxim Levitsky 7029fa9c1c2SMaxim Levitsky /* 7033994a7c9SMaxim Levitsky * Given a key slot, user password, and the master key, 7043994a7c9SMaxim Levitsky * will store the encrypted master key there, and update the 7053994a7c9SMaxim Levitsky * in-memory header. User must then write the in-memory header 7063994a7c9SMaxim Levitsky * 7073994a7c9SMaxim Levitsky * Returns: 7083994a7c9SMaxim Levitsky * 0 if the keyslot was written successfully 7093994a7c9SMaxim Levitsky * with the provided password 7103994a7c9SMaxim Levitsky * -1 if a fatal error occurred while storing the key 7113994a7c9SMaxim Levitsky */ 7123994a7c9SMaxim Levitsky static int 7133994a7c9SMaxim Levitsky qcrypto_block_luks_store_key(QCryptoBlock *block, 7143994a7c9SMaxim Levitsky unsigned int slot_idx, 7153994a7c9SMaxim Levitsky const char *password, 7163994a7c9SMaxim Levitsky uint8_t *masterkey, 7173994a7c9SMaxim Levitsky uint64_t iter_time, 7183994a7c9SMaxim Levitsky QCryptoBlockWriteFunc writefunc, 7193994a7c9SMaxim Levitsky void *opaque, 7203994a7c9SMaxim Levitsky Error **errp) 7213994a7c9SMaxim Levitsky { 7223994a7c9SMaxim Levitsky QCryptoBlockLUKS *luks = block->opaque; 7233994a7c9SMaxim Levitsky QCryptoBlockLUKSKeySlot *slot = &luks->header.key_slots[slot_idx]; 7243994a7c9SMaxim Levitsky g_autofree uint8_t *splitkey = NULL; 7253994a7c9SMaxim Levitsky size_t splitkeylen; 7263994a7c9SMaxim Levitsky g_autofree uint8_t *slotkey = NULL; 7273994a7c9SMaxim Levitsky g_autoptr(QCryptoCipher) cipher = NULL; 7283994a7c9SMaxim Levitsky g_autoptr(QCryptoIVGen) ivgen = NULL; 7293994a7c9SMaxim Levitsky Error *local_err = NULL; 7303994a7c9SMaxim Levitsky uint64_t iters; 7313994a7c9SMaxim Levitsky int ret = -1; 7323994a7c9SMaxim Levitsky 7333994a7c9SMaxim Levitsky if (qcrypto_random_bytes(slot->salt, 7343994a7c9SMaxim Levitsky QCRYPTO_BLOCK_LUKS_SALT_LEN, 7353994a7c9SMaxim Levitsky errp) < 0) { 7363994a7c9SMaxim Levitsky goto cleanup; 7373994a7c9SMaxim Levitsky } 7383994a7c9SMaxim Levitsky 7393994a7c9SMaxim Levitsky splitkeylen = luks->header.master_key_len * slot->stripes; 7403994a7c9SMaxim Levitsky 7413994a7c9SMaxim Levitsky /* 7423994a7c9SMaxim Levitsky * Determine how many iterations are required to 7433994a7c9SMaxim Levitsky * hash the user password while consuming 1 second of compute 7443994a7c9SMaxim Levitsky * time 7453994a7c9SMaxim Levitsky */ 7463994a7c9SMaxim Levitsky iters = qcrypto_pbkdf2_count_iters(luks->hash_alg, 7473994a7c9SMaxim Levitsky (uint8_t *)password, strlen(password), 7483994a7c9SMaxim Levitsky slot->salt, 7493994a7c9SMaxim Levitsky QCRYPTO_BLOCK_LUKS_SALT_LEN, 7503994a7c9SMaxim Levitsky luks->header.master_key_len, 7513994a7c9SMaxim Levitsky &local_err); 7523994a7c9SMaxim Levitsky if (local_err) { 7533994a7c9SMaxim Levitsky error_propagate(errp, local_err); 7543994a7c9SMaxim Levitsky goto cleanup; 7553994a7c9SMaxim Levitsky } 7563994a7c9SMaxim Levitsky 7573994a7c9SMaxim Levitsky if (iters > (ULLONG_MAX / iter_time)) { 7583994a7c9SMaxim Levitsky error_setg_errno(errp, ERANGE, 7593994a7c9SMaxim Levitsky "PBKDF iterations %llu too large to scale", 7603994a7c9SMaxim Levitsky (unsigned long long)iters); 7613994a7c9SMaxim Levitsky goto cleanup; 7623994a7c9SMaxim Levitsky } 7633994a7c9SMaxim Levitsky 7643994a7c9SMaxim Levitsky /* iter_time was in millis, but count_iters reported for secs */ 7653994a7c9SMaxim Levitsky iters = iters * iter_time / 1000; 7663994a7c9SMaxim Levitsky 7673994a7c9SMaxim Levitsky if (iters > UINT32_MAX) { 7683994a7c9SMaxim Levitsky error_setg_errno(errp, ERANGE, 7693994a7c9SMaxim Levitsky "PBKDF iterations %llu larger than %u", 7703994a7c9SMaxim Levitsky (unsigned long long)iters, UINT32_MAX); 7713994a7c9SMaxim Levitsky goto cleanup; 7723994a7c9SMaxim Levitsky } 7733994a7c9SMaxim Levitsky 7743994a7c9SMaxim Levitsky slot->iterations = 7753994a7c9SMaxim Levitsky MAX(iters, QCRYPTO_BLOCK_LUKS_MIN_SLOT_KEY_ITERS); 7763994a7c9SMaxim Levitsky 7773994a7c9SMaxim Levitsky 7783994a7c9SMaxim Levitsky /* 7793994a7c9SMaxim Levitsky * Generate a key that we'll use to encrypt the master 7803994a7c9SMaxim Levitsky * key, from the user's password 7813994a7c9SMaxim Levitsky */ 7823994a7c9SMaxim Levitsky slotkey = g_new0(uint8_t, luks->header.master_key_len); 7833994a7c9SMaxim Levitsky if (qcrypto_pbkdf2(luks->hash_alg, 7843994a7c9SMaxim Levitsky (uint8_t *)password, strlen(password), 7853994a7c9SMaxim Levitsky slot->salt, 7863994a7c9SMaxim Levitsky QCRYPTO_BLOCK_LUKS_SALT_LEN, 7873994a7c9SMaxim Levitsky slot->iterations, 7883994a7c9SMaxim Levitsky slotkey, luks->header.master_key_len, 7893994a7c9SMaxim Levitsky errp) < 0) { 7903994a7c9SMaxim Levitsky goto cleanup; 7913994a7c9SMaxim Levitsky } 7923994a7c9SMaxim Levitsky 7933994a7c9SMaxim Levitsky 7943994a7c9SMaxim Levitsky /* 7953994a7c9SMaxim Levitsky * Setup the encryption objects needed to encrypt the 7963994a7c9SMaxim Levitsky * master key material 7973994a7c9SMaxim Levitsky */ 7983994a7c9SMaxim Levitsky cipher = qcrypto_cipher_new(luks->cipher_alg, 7993994a7c9SMaxim Levitsky luks->cipher_mode, 8003994a7c9SMaxim Levitsky slotkey, luks->header.master_key_len, 8013994a7c9SMaxim Levitsky errp); 8023994a7c9SMaxim Levitsky if (!cipher) { 8033994a7c9SMaxim Levitsky goto cleanup; 8043994a7c9SMaxim Levitsky } 8053994a7c9SMaxim Levitsky 8063994a7c9SMaxim Levitsky ivgen = qcrypto_ivgen_new(luks->ivgen_alg, 8073994a7c9SMaxim Levitsky luks->ivgen_cipher_alg, 8083994a7c9SMaxim Levitsky luks->ivgen_hash_alg, 8093994a7c9SMaxim Levitsky slotkey, luks->header.master_key_len, 8103994a7c9SMaxim Levitsky errp); 8113994a7c9SMaxim Levitsky if (!ivgen) { 8123994a7c9SMaxim Levitsky goto cleanup; 8133994a7c9SMaxim Levitsky } 8143994a7c9SMaxim Levitsky 8153994a7c9SMaxim Levitsky /* 8163994a7c9SMaxim Levitsky * Before storing the master key, we need to vastly 8173994a7c9SMaxim Levitsky * increase its size, as protection against forensic 8183994a7c9SMaxim Levitsky * disk data recovery 8193994a7c9SMaxim Levitsky */ 8203994a7c9SMaxim Levitsky splitkey = g_new0(uint8_t, splitkeylen); 8213994a7c9SMaxim Levitsky 8223994a7c9SMaxim Levitsky if (qcrypto_afsplit_encode(luks->hash_alg, 8233994a7c9SMaxim Levitsky luks->header.master_key_len, 8243994a7c9SMaxim Levitsky slot->stripes, 8253994a7c9SMaxim Levitsky masterkey, 8263994a7c9SMaxim Levitsky splitkey, 8273994a7c9SMaxim Levitsky errp) < 0) { 8283994a7c9SMaxim Levitsky goto cleanup; 8293994a7c9SMaxim Levitsky } 8303994a7c9SMaxim Levitsky 8313994a7c9SMaxim Levitsky /* 8323994a7c9SMaxim Levitsky * Now we encrypt the split master key with the key generated 8333994a7c9SMaxim Levitsky * from the user's password, before storing it 8343994a7c9SMaxim Levitsky */ 8353994a7c9SMaxim Levitsky if (qcrypto_block_cipher_encrypt_helper(cipher, block->niv, ivgen, 8363994a7c9SMaxim Levitsky QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, 8373994a7c9SMaxim Levitsky 0, 8383994a7c9SMaxim Levitsky splitkey, 8393994a7c9SMaxim Levitsky splitkeylen, 8403994a7c9SMaxim Levitsky errp) < 0) { 8413994a7c9SMaxim Levitsky goto cleanup; 8423994a7c9SMaxim Levitsky } 8433994a7c9SMaxim Levitsky 8443994a7c9SMaxim Levitsky /* Write out the slot's master key material. */ 8453994a7c9SMaxim Levitsky if (writefunc(block, 8463994a7c9SMaxim Levitsky slot->key_offset_sector * 8473994a7c9SMaxim Levitsky QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, 8483994a7c9SMaxim Levitsky splitkey, splitkeylen, 8493994a7c9SMaxim Levitsky opaque, 8503994a7c9SMaxim Levitsky errp) != splitkeylen) { 8513994a7c9SMaxim Levitsky goto cleanup; 8523994a7c9SMaxim Levitsky } 8533994a7c9SMaxim Levitsky 8543994a7c9SMaxim Levitsky slot->active = QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED; 8553994a7c9SMaxim Levitsky 8563994a7c9SMaxim Levitsky if (qcrypto_block_luks_store_header(block, writefunc, opaque, errp) < 0) { 8573994a7c9SMaxim Levitsky goto cleanup; 8583994a7c9SMaxim Levitsky } 8593994a7c9SMaxim Levitsky 8603994a7c9SMaxim Levitsky ret = 0; 8613994a7c9SMaxim Levitsky 8623994a7c9SMaxim Levitsky cleanup: 8633994a7c9SMaxim Levitsky if (slotkey) { 8643994a7c9SMaxim Levitsky memset(slotkey, 0, luks->header.master_key_len); 8653994a7c9SMaxim Levitsky } 8663994a7c9SMaxim Levitsky if (splitkey) { 8673994a7c9SMaxim Levitsky memset(splitkey, 0, splitkeylen); 8683994a7c9SMaxim Levitsky } 8693994a7c9SMaxim Levitsky return ret; 8703994a7c9SMaxim Levitsky } 8713994a7c9SMaxim Levitsky 8723994a7c9SMaxim Levitsky /* 8733e308f20SDaniel P. Berrange * Given a key slot, and user password, this will attempt to unlock 8743e308f20SDaniel P. Berrange * the master encryption key from the key slot. 8753e308f20SDaniel P. Berrange * 8763e308f20SDaniel P. Berrange * Returns: 8773e308f20SDaniel P. Berrange * 0 if the key slot is disabled, or key could not be decrypted 8783e308f20SDaniel P. Berrange * with the provided password 8793e308f20SDaniel P. Berrange * 1 if the key slot is enabled, and key decrypted successfully 8803e308f20SDaniel P. Berrange * with the provided password 8813e308f20SDaniel P. Berrange * -1 if a fatal error occurred loading the key 8823e308f20SDaniel P. Berrange */ 8833e308f20SDaniel P. Berrange static int 8843e308f20SDaniel P. Berrange qcrypto_block_luks_load_key(QCryptoBlock *block, 8857e60a6f5SMaxim Levitsky size_t slot_idx, 8863e308f20SDaniel P. Berrange const char *password, 8873e308f20SDaniel P. Berrange uint8_t *masterkey, 8883e308f20SDaniel P. Berrange QCryptoBlockReadFunc readfunc, 8893e308f20SDaniel P. Berrange void *opaque, 8903e308f20SDaniel P. Berrange Error **errp) 8913e308f20SDaniel P. Berrange { 8923e308f20SDaniel P. Berrange QCryptoBlockLUKS *luks = block->opaque; 8937e60a6f5SMaxim Levitsky const QCryptoBlockLUKSKeySlot *slot = &luks->header.key_slots[slot_idx]; 89457b9f113SDaniel P. Berrangé g_autofree uint8_t *splitkey = NULL; 8953e308f20SDaniel P. Berrange size_t splitkeylen; 89657b9f113SDaniel P. Berrangé g_autofree uint8_t *possiblekey = NULL; 8973e308f20SDaniel P. Berrange ssize_t rv; 89857b9f113SDaniel P. Berrangé g_autoptr(QCryptoCipher) cipher = NULL; 8993e308f20SDaniel P. Berrange uint8_t keydigest[QCRYPTO_BLOCK_LUKS_DIGEST_LEN]; 90057b9f113SDaniel P. Berrangé g_autoptr(QCryptoIVGen) ivgen = NULL; 9013e308f20SDaniel P. Berrange size_t niv; 9023e308f20SDaniel P. Berrange 9033e308f20SDaniel P. Berrange if (slot->active != QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED) { 9043e308f20SDaniel P. Berrange return 0; 9053e308f20SDaniel P. Berrange } 9063e308f20SDaniel P. Berrange 9071ddd52e4SMaxim Levitsky splitkeylen = luks->header.master_key_len * slot->stripes; 9083e308f20SDaniel P. Berrange splitkey = g_new0(uint8_t, splitkeylen); 9091ddd52e4SMaxim Levitsky possiblekey = g_new0(uint8_t, luks->header.master_key_len); 9103e308f20SDaniel P. Berrange 9113e308f20SDaniel P. Berrange /* 9123e308f20SDaniel P. Berrange * The user password is used to generate a (possible) 9133e308f20SDaniel P. Berrange * decryption key. This may or may not successfully 9143e308f20SDaniel P. Berrange * decrypt the master key - we just blindly assume 9153e308f20SDaniel P. Berrange * the key is correct and validate the results of 9163e308f20SDaniel P. Berrange * decryption later. 9173e308f20SDaniel P. Berrange */ 9189d80e59dSMaxim Levitsky if (qcrypto_pbkdf2(luks->hash_alg, 9193e308f20SDaniel P. Berrange (const uint8_t *)password, strlen(password), 9203e308f20SDaniel P. Berrange slot->salt, QCRYPTO_BLOCK_LUKS_SALT_LEN, 9213e308f20SDaniel P. Berrange slot->iterations, 9221ddd52e4SMaxim Levitsky possiblekey, luks->header.master_key_len, 9233e308f20SDaniel P. Berrange errp) < 0) { 92457b9f113SDaniel P. Berrangé return -1; 9253e308f20SDaniel P. Berrange } 9263e308f20SDaniel P. Berrange 9273e308f20SDaniel P. Berrange /* 9283e308f20SDaniel P. Berrange * We need to read the master key material from the 9293e308f20SDaniel P. Berrange * LUKS key material header. What we're reading is 9303e308f20SDaniel P. Berrange * not the raw master key, but rather the data after 9313e308f20SDaniel P. Berrange * it has been passed through AFSplit and the result 9323e308f20SDaniel P. Berrange * then encrypted. 9333e308f20SDaniel P. Berrange */ 9343e308f20SDaniel P. Berrange rv = readfunc(block, 935f0d3c362SMaxim Levitsky slot->key_offset_sector * QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, 9363e308f20SDaniel P. Berrange splitkey, splitkeylen, 937e4a3507eSDaniel P. Berrange opaque, 93837509233SFam Zheng errp); 9393e308f20SDaniel P. Berrange if (rv < 0) { 94057b9f113SDaniel P. Berrangé return -1; 9413e308f20SDaniel P. Berrange } 9423e308f20SDaniel P. Berrange 9433e308f20SDaniel P. Berrange 9443e308f20SDaniel P. Berrange /* Setup the cipher/ivgen that we'll use to try to decrypt 9453e308f20SDaniel P. Berrange * the split master key material */ 9469d80e59dSMaxim Levitsky cipher = qcrypto_cipher_new(luks->cipher_alg, 9479d80e59dSMaxim Levitsky luks->cipher_mode, 9489d80e59dSMaxim Levitsky possiblekey, 9499d80e59dSMaxim Levitsky luks->header.master_key_len, 9503e308f20SDaniel P. Berrange errp); 9513e308f20SDaniel P. Berrange if (!cipher) { 95257b9f113SDaniel P. Berrangé return -1; 9533e308f20SDaniel P. Berrange } 9543e308f20SDaniel P. Berrange 9559d80e59dSMaxim Levitsky niv = qcrypto_cipher_get_iv_len(luks->cipher_alg, 9569d80e59dSMaxim Levitsky luks->cipher_mode); 9579d80e59dSMaxim Levitsky 9589d80e59dSMaxim Levitsky ivgen = qcrypto_ivgen_new(luks->ivgen_alg, 9599d80e59dSMaxim Levitsky luks->ivgen_cipher_alg, 9609d80e59dSMaxim Levitsky luks->ivgen_hash_alg, 9619d80e59dSMaxim Levitsky possiblekey, 9629d80e59dSMaxim Levitsky luks->header.master_key_len, 9633e308f20SDaniel P. Berrange errp); 9643e308f20SDaniel P. Berrange if (!ivgen) { 96557b9f113SDaniel P. Berrangé return -1; 9663e308f20SDaniel P. Berrange } 9673e308f20SDaniel P. Berrange 9683e308f20SDaniel P. Berrange 9693e308f20SDaniel P. Berrange /* 9703e308f20SDaniel P. Berrange * The master key needs to be decrypted in the same 9713e308f20SDaniel P. Berrange * way that the block device payload will be decrypted 9723e308f20SDaniel P. Berrange * later. In particular we'll be using the IV generator 9733e308f20SDaniel P. Berrange * to reset the encryption cipher every time the master 9743e308f20SDaniel P. Berrange * key crosses a sector boundary. 9753e308f20SDaniel P. Berrange */ 9760270417cSVladimir Sementsov-Ogievskiy if (qcrypto_block_cipher_decrypt_helper(cipher, 9773e308f20SDaniel P. Berrange niv, 9783e308f20SDaniel P. Berrange ivgen, 9793e308f20SDaniel P. Berrange QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, 9803e308f20SDaniel P. Berrange 0, 9813e308f20SDaniel P. Berrange splitkey, 9823e308f20SDaniel P. Berrange splitkeylen, 9833e308f20SDaniel P. Berrange errp) < 0) { 98457b9f113SDaniel P. Berrangé return -1; 9853e308f20SDaniel P. Berrange } 9863e308f20SDaniel P. Berrange 9873e308f20SDaniel P. Berrange /* 9883e308f20SDaniel P. Berrange * Now we've decrypted the split master key, join 9893e308f20SDaniel P. Berrange * it back together to get the actual master key. 9903e308f20SDaniel P. Berrange */ 9919d80e59dSMaxim Levitsky if (qcrypto_afsplit_decode(luks->hash_alg, 9921ddd52e4SMaxim Levitsky luks->header.master_key_len, 9933e308f20SDaniel P. Berrange slot->stripes, 9943e308f20SDaniel P. Berrange splitkey, 9953e308f20SDaniel P. Berrange masterkey, 9963e308f20SDaniel P. Berrange errp) < 0) { 99757b9f113SDaniel P. Berrangé return -1; 9983e308f20SDaniel P. Berrange } 9993e308f20SDaniel P. Berrange 10003e308f20SDaniel P. Berrange 10013e308f20SDaniel P. Berrange /* 10023e308f20SDaniel P. Berrange * We still don't know that the masterkey we got is valid, 10033e308f20SDaniel P. Berrange * because we just blindly assumed the user's password 10043e308f20SDaniel P. Berrange * was correct. This is where we now verify it. We are 10053e308f20SDaniel P. Berrange * creating a hash of the master key using PBKDF and 10063e308f20SDaniel P. Berrange * then comparing that to the hash stored in the key slot 10073e308f20SDaniel P. Berrange * header 10083e308f20SDaniel P. Berrange */ 10099d80e59dSMaxim Levitsky if (qcrypto_pbkdf2(luks->hash_alg, 10101ddd52e4SMaxim Levitsky masterkey, 10111ddd52e4SMaxim Levitsky luks->header.master_key_len, 10123e308f20SDaniel P. Berrange luks->header.master_key_salt, 10133e308f20SDaniel P. Berrange QCRYPTO_BLOCK_LUKS_SALT_LEN, 10143e308f20SDaniel P. Berrange luks->header.master_key_iterations, 10151ddd52e4SMaxim Levitsky keydigest, 10161ddd52e4SMaxim Levitsky G_N_ELEMENTS(keydigest), 10173e308f20SDaniel P. Berrange errp) < 0) { 101857b9f113SDaniel P. Berrangé return -1; 10193e308f20SDaniel P. Berrange } 10203e308f20SDaniel P. Berrange 10213e308f20SDaniel P. Berrange if (memcmp(keydigest, luks->header.master_key_digest, 10223e308f20SDaniel P. Berrange QCRYPTO_BLOCK_LUKS_DIGEST_LEN) == 0) { 10233e308f20SDaniel P. Berrange /* Success, we got the right master key */ 102457b9f113SDaniel P. Berrangé return 1; 10253e308f20SDaniel P. Berrange } 10263e308f20SDaniel P. Berrange 10273e308f20SDaniel P. Berrange /* Fail, user's password was not valid for this key slot, 10283e308f20SDaniel P. Berrange * tell caller to try another slot */ 102957b9f113SDaniel P. Berrangé return 0; 10303e308f20SDaniel P. Berrange } 10313e308f20SDaniel P. Berrange 10323e308f20SDaniel P. Berrange 10333e308f20SDaniel P. Berrange /* 10343e308f20SDaniel P. Berrange * Given a user password, this will iterate over all key 10353e308f20SDaniel P. Berrange * slots and try to unlock each active key slot using the 10363e308f20SDaniel P. Berrange * password until it successfully obtains a master key. 10373e308f20SDaniel P. Berrange * 10383e308f20SDaniel P. Berrange * Returns 0 if a key was loaded, -1 if no keys could be loaded 10393e308f20SDaniel P. Berrange */ 10403e308f20SDaniel P. Berrange static int 10413e308f20SDaniel P. Berrange qcrypto_block_luks_find_key(QCryptoBlock *block, 10423e308f20SDaniel P. Berrange const char *password, 10431ddd52e4SMaxim Levitsky uint8_t *masterkey, 10443e308f20SDaniel P. Berrange QCryptoBlockReadFunc readfunc, 10453e308f20SDaniel P. Berrange void *opaque, 10463e308f20SDaniel P. Berrange Error **errp) 10473e308f20SDaniel P. Berrange { 10483e308f20SDaniel P. Berrange size_t i; 10493e308f20SDaniel P. Berrange int rv; 10503e308f20SDaniel P. Berrange 10513e308f20SDaniel P. Berrange for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) { 10523e308f20SDaniel P. Berrange rv = qcrypto_block_luks_load_key(block, 10537e60a6f5SMaxim Levitsky i, 10543e308f20SDaniel P. Berrange password, 10551ddd52e4SMaxim Levitsky masterkey, 10563e308f20SDaniel P. Berrange readfunc, 10573e308f20SDaniel P. Berrange opaque, 10583e308f20SDaniel P. Berrange errp); 10593e308f20SDaniel P. Berrange if (rv < 0) { 10603e308f20SDaniel P. Berrange goto error; 10613e308f20SDaniel P. Berrange } 10623e308f20SDaniel P. Berrange if (rv == 1) { 10633e308f20SDaniel P. Berrange return 0; 10643e308f20SDaniel P. Berrange } 10653e308f20SDaniel P. Berrange } 10663e308f20SDaniel P. Berrange 10673e308f20SDaniel P. Berrange error_setg(errp, "Invalid password, cannot unlock any keyslot"); 10683e308f20SDaniel P. Berrange error: 10693e308f20SDaniel P. Berrange return -1; 10703e308f20SDaniel P. Berrange } 10713e308f20SDaniel P. Berrange 10723e308f20SDaniel P. Berrange 10733e308f20SDaniel P. Berrange static int 10743e308f20SDaniel P. Berrange qcrypto_block_luks_open(QCryptoBlock *block, 10753e308f20SDaniel P. Berrange QCryptoBlockOpenOptions *options, 10761cd9a787SDaniel P. Berrange const char *optprefix, 10773e308f20SDaniel P. Berrange QCryptoBlockReadFunc readfunc, 10783e308f20SDaniel P. Berrange void *opaque, 10793e308f20SDaniel P. Berrange unsigned int flags, 1080c972fa12SVladimir Sementsov-Ogievskiy size_t n_threads, 10813e308f20SDaniel P. Berrange Error **errp) 10823e308f20SDaniel P. Berrange { 10839d80e59dSMaxim Levitsky QCryptoBlockLUKS *luks = NULL; 108457b9f113SDaniel P. Berrangé g_autofree uint8_t *masterkey = NULL; 108557b9f113SDaniel P. Berrangé g_autofree char *password = NULL; 10863e308f20SDaniel P. Berrange 10873e308f20SDaniel P. Berrange if (!(flags & QCRYPTO_BLOCK_OPEN_NO_IO)) { 10883e308f20SDaniel P. Berrange if (!options->u.luks.key_secret) { 10891cd9a787SDaniel P. Berrange error_setg(errp, "Parameter '%skey-secret' is required for cipher", 10901cd9a787SDaniel P. Berrange optprefix ? optprefix : ""); 10913e308f20SDaniel P. Berrange return -1; 10923e308f20SDaniel P. Berrange } 10933e308f20SDaniel P. Berrange password = qcrypto_secret_lookup_as_utf8( 10943e308f20SDaniel P. Berrange options->u.luks.key_secret, errp); 10953e308f20SDaniel P. Berrange if (!password) { 10963e308f20SDaniel P. Berrange return -1; 10973e308f20SDaniel P. Berrange } 10983e308f20SDaniel P. Berrange } 10993e308f20SDaniel P. Berrange 11003e308f20SDaniel P. Berrange luks = g_new0(QCryptoBlockLUKS, 1); 11013e308f20SDaniel P. Berrange block->opaque = luks; 11023e308f20SDaniel P. Berrange 1103dde2c5afSMaxim Levitsky if (qcrypto_block_luks_load_header(block, readfunc, opaque, errp) < 0) { 11043e308f20SDaniel P. Berrange goto fail; 11053e308f20SDaniel P. Berrange } 11063e308f20SDaniel P. Berrange 11079fa9c1c2SMaxim Levitsky if (qcrypto_block_luks_check_header(luks, errp) < 0) { 11083e308f20SDaniel P. Berrange goto fail; 11093e308f20SDaniel P. Berrange } 11103e308f20SDaniel P. Berrange 11119fa9c1c2SMaxim Levitsky if (qcrypto_block_luks_parse_header(luks, errp) < 0) { 11123e308f20SDaniel P. Berrange goto fail; 11133e308f20SDaniel P. Berrange } 11143e308f20SDaniel P. Berrange 11153e308f20SDaniel P. Berrange if (!(flags & QCRYPTO_BLOCK_OPEN_NO_IO)) { 11163e308f20SDaniel P. Berrange /* Try to find which key slot our password is valid for 11173e308f20SDaniel P. Berrange * and unlock the master key from that slot. 11183e308f20SDaniel P. Berrange */ 11191ddd52e4SMaxim Levitsky 11201ddd52e4SMaxim Levitsky masterkey = g_new0(uint8_t, luks->header.master_key_len); 11211ddd52e4SMaxim Levitsky 11223e308f20SDaniel P. Berrange if (qcrypto_block_luks_find_key(block, 11233e308f20SDaniel P. Berrange password, 11241ddd52e4SMaxim Levitsky masterkey, 11253e308f20SDaniel P. Berrange readfunc, opaque, 11263e308f20SDaniel P. Berrange errp) < 0) { 11273e308f20SDaniel P. Berrange goto fail; 11283e308f20SDaniel P. Berrange } 11293e308f20SDaniel P. Berrange 11303e308f20SDaniel P. Berrange /* We have a valid master key now, so can setup the 11313e308f20SDaniel P. Berrange * block device payload decryption objects 11323e308f20SDaniel P. Berrange */ 11339d80e59dSMaxim Levitsky block->kdfhash = luks->hash_alg; 11349d80e59dSMaxim Levitsky block->niv = qcrypto_cipher_get_iv_len(luks->cipher_alg, 11359d80e59dSMaxim Levitsky luks->cipher_mode); 11369d80e59dSMaxim Levitsky 11379d80e59dSMaxim Levitsky block->ivgen = qcrypto_ivgen_new(luks->ivgen_alg, 11389d80e59dSMaxim Levitsky luks->ivgen_cipher_alg, 11399d80e59dSMaxim Levitsky luks->ivgen_hash_alg, 11401ddd52e4SMaxim Levitsky masterkey, 11411ddd52e4SMaxim Levitsky luks->header.master_key_len, 11423e308f20SDaniel P. Berrange errp); 11433e308f20SDaniel P. Berrange if (!block->ivgen) { 11443e308f20SDaniel P. Berrange goto fail; 11453e308f20SDaniel P. Berrange } 11463e308f20SDaniel P. Berrange 114761dd8a9aSMaxim Levitsky if (qcrypto_block_init_cipher(block, 11489d80e59dSMaxim Levitsky luks->cipher_alg, 11499d80e59dSMaxim Levitsky luks->cipher_mode, 11501ddd52e4SMaxim Levitsky masterkey, 11511ddd52e4SMaxim Levitsky luks->header.master_key_len, 11521ddd52e4SMaxim Levitsky n_threads, 115361dd8a9aSMaxim Levitsky errp) < 0) { 11543e308f20SDaniel P. Berrange goto fail; 11553e308f20SDaniel P. Berrange } 11563e308f20SDaniel P. Berrange } 11573e308f20SDaniel P. Berrange 1158850f49deSDaniel P. Berrange block->sector_size = QCRYPTO_BLOCK_LUKS_SECTOR_SIZE; 1159f0d3c362SMaxim Levitsky block->payload_offset = luks->header.payload_offset_sector * 1160850f49deSDaniel P. Berrange block->sector_size; 11613e308f20SDaniel P. Berrange 11623e308f20SDaniel P. Berrange return 0; 11633e308f20SDaniel P. Berrange 11643e308f20SDaniel P. Berrange fail: 1165c972fa12SVladimir Sementsov-Ogievskiy qcrypto_block_free_cipher(block); 11663e308f20SDaniel P. Berrange qcrypto_ivgen_free(block->ivgen); 11673e308f20SDaniel P. Berrange g_free(luks); 116861dd8a9aSMaxim Levitsky return -1; 11693e308f20SDaniel P. Berrange } 11703e308f20SDaniel P. Berrange 11713e308f20SDaniel P. Berrange 11722ef950f9SFam Zheng static void 11732ef950f9SFam Zheng qcrypto_block_luks_uuid_gen(uint8_t *uuidstr) 11743e308f20SDaniel P. Berrange { 11752ef950f9SFam Zheng QemuUUID uuid; 11762ef950f9SFam Zheng qemu_uuid_generate(&uuid); 11772ef950f9SFam Zheng qemu_uuid_unparse(&uuid, (char *)uuidstr); 11783e308f20SDaniel P. Berrange } 11793e308f20SDaniel P. Berrange 11803e308f20SDaniel P. Berrange static int 11813e308f20SDaniel P. Berrange qcrypto_block_luks_create(QCryptoBlock *block, 11823e308f20SDaniel P. Berrange QCryptoBlockCreateOptions *options, 11831cd9a787SDaniel P. Berrange const char *optprefix, 11843e308f20SDaniel P. Berrange QCryptoBlockInitFunc initfunc, 11853e308f20SDaniel P. Berrange QCryptoBlockWriteFunc writefunc, 11863e308f20SDaniel P. Berrange void *opaque, 11873e308f20SDaniel P. Berrange Error **errp) 11883e308f20SDaniel P. Berrange { 11893e308f20SDaniel P. Berrange QCryptoBlockLUKS *luks; 11903e308f20SDaniel P. Berrange QCryptoBlockCreateOptionsLUKS luks_opts; 11913e308f20SDaniel P. Berrange Error *local_err = NULL; 119257b9f113SDaniel P. Berrangé g_autofree uint8_t *masterkey = NULL; 1193bd56a55aSMaxim Levitsky size_t header_sectors; 1194bd56a55aSMaxim Levitsky size_t split_key_sectors; 11953e308f20SDaniel P. Berrange size_t i; 119657b9f113SDaniel P. Berrangé g_autofree char *password = NULL; 11973e308f20SDaniel P. Berrange const char *cipher_alg; 11983e308f20SDaniel P. Berrange const char *cipher_mode; 11993e308f20SDaniel P. Berrange const char *ivgen_alg; 12003e308f20SDaniel P. Berrange const char *ivgen_hash_alg = NULL; 12013e308f20SDaniel P. Berrange const char *hash_alg; 120257b9f113SDaniel P. Berrangé g_autofree char *cipher_mode_spec = NULL; 120359b060beSDaniel P. Berrange uint64_t iters; 12043e308f20SDaniel P. Berrange 12053e308f20SDaniel P. Berrange memcpy(&luks_opts, &options->u.luks, sizeof(luks_opts)); 12063bd18890SDaniel P. Berrange if (!luks_opts.has_iter_time) { 12072ab66cd5SDaniel P. Berrange luks_opts.iter_time = 2000; 12083bd18890SDaniel P. Berrange } 12093e308f20SDaniel P. Berrange if (!luks_opts.has_cipher_alg) { 12103e308f20SDaniel P. Berrange luks_opts.cipher_alg = QCRYPTO_CIPHER_ALG_AES_256; 12113e308f20SDaniel P. Berrange } 12123e308f20SDaniel P. Berrange if (!luks_opts.has_cipher_mode) { 12133e308f20SDaniel P. Berrange luks_opts.cipher_mode = QCRYPTO_CIPHER_MODE_XTS; 12143e308f20SDaniel P. Berrange } 12153e308f20SDaniel P. Berrange if (!luks_opts.has_ivgen_alg) { 12163e308f20SDaniel P. Berrange luks_opts.ivgen_alg = QCRYPTO_IVGEN_ALG_PLAIN64; 12173e308f20SDaniel P. Berrange } 12183e308f20SDaniel P. Berrange if (!luks_opts.has_hash_alg) { 12193e308f20SDaniel P. Berrange luks_opts.hash_alg = QCRYPTO_HASH_ALG_SHA256; 12203e308f20SDaniel P. Berrange } 12218b7cdba3SDaniel P. Berrange if (luks_opts.ivgen_alg == QCRYPTO_IVGEN_ALG_ESSIV) { 12228b7cdba3SDaniel P. Berrange if (!luks_opts.has_ivgen_hash_alg) { 12238b7cdba3SDaniel P. Berrange luks_opts.ivgen_hash_alg = QCRYPTO_HASH_ALG_SHA256; 12248b7cdba3SDaniel P. Berrange luks_opts.has_ivgen_hash_alg = true; 12258b7cdba3SDaniel P. Berrange } 12268b7cdba3SDaniel P. Berrange } 12279d80e59dSMaxim Levitsky 12289d80e59dSMaxim Levitsky luks = g_new0(QCryptoBlockLUKS, 1); 12299d80e59dSMaxim Levitsky block->opaque = luks; 12309d80e59dSMaxim Levitsky 12319d80e59dSMaxim Levitsky luks->cipher_alg = luks_opts.cipher_alg; 12329d80e59dSMaxim Levitsky luks->cipher_mode = luks_opts.cipher_mode; 12339d80e59dSMaxim Levitsky luks->ivgen_alg = luks_opts.ivgen_alg; 12349d80e59dSMaxim Levitsky luks->ivgen_hash_alg = luks_opts.ivgen_hash_alg; 12359d80e59dSMaxim Levitsky luks->hash_alg = luks_opts.hash_alg; 12369d80e59dSMaxim Levitsky 12379d80e59dSMaxim Levitsky 12388b7cdba3SDaniel P. Berrange /* Note we're allowing ivgen_hash_alg to be set even for 12398b7cdba3SDaniel P. Berrange * non-essiv iv generators that don't need a hash. It will 12408b7cdba3SDaniel P. Berrange * be silently ignored, for compatibility with dm-crypt */ 12413e308f20SDaniel P. Berrange 12423e308f20SDaniel P. Berrange if (!options->u.luks.key_secret) { 12431cd9a787SDaniel P. Berrange error_setg(errp, "Parameter '%skey-secret' is required for cipher", 12441cd9a787SDaniel P. Berrange optprefix ? optprefix : ""); 12459d80e59dSMaxim Levitsky goto error; 12463e308f20SDaniel P. Berrange } 12473e308f20SDaniel P. Berrange password = qcrypto_secret_lookup_as_utf8(luks_opts.key_secret, errp); 12483e308f20SDaniel P. Berrange if (!password) { 12499d80e59dSMaxim Levitsky goto error; 12503e308f20SDaniel P. Berrange } 12513e308f20SDaniel P. Berrange 12523e308f20SDaniel P. Berrange 12533e308f20SDaniel P. Berrange memcpy(luks->header.magic, qcrypto_block_luks_magic, 12543e308f20SDaniel P. Berrange QCRYPTO_BLOCK_LUKS_MAGIC_LEN); 12553e308f20SDaniel P. Berrange 12563e308f20SDaniel P. Berrange /* We populate the header in native endianness initially and 12573e308f20SDaniel P. Berrange * then convert everything to big endian just before writing 12583e308f20SDaniel P. Berrange * it out to disk 12593e308f20SDaniel P. Berrange */ 12603e308f20SDaniel P. Berrange luks->header.version = QCRYPTO_BLOCK_LUKS_VERSION; 12612ef950f9SFam Zheng qcrypto_block_luks_uuid_gen(luks->header.uuid); 12623e308f20SDaniel P. Berrange 12633e308f20SDaniel P. Berrange cipher_alg = qcrypto_block_luks_cipher_alg_lookup(luks_opts.cipher_alg, 12643e308f20SDaniel P. Berrange errp); 12653e308f20SDaniel P. Berrange if (!cipher_alg) { 12663e308f20SDaniel P. Berrange goto error; 12673e308f20SDaniel P. Berrange } 12683e308f20SDaniel P. Berrange 1269977c736fSMarkus Armbruster cipher_mode = QCryptoCipherMode_str(luks_opts.cipher_mode); 1270977c736fSMarkus Armbruster ivgen_alg = QCryptoIVGenAlgorithm_str(luks_opts.ivgen_alg); 12713e308f20SDaniel P. Berrange if (luks_opts.has_ivgen_hash_alg) { 1272977c736fSMarkus Armbruster ivgen_hash_alg = QCryptoHashAlgorithm_str(luks_opts.ivgen_hash_alg); 12733e308f20SDaniel P. Berrange cipher_mode_spec = g_strdup_printf("%s-%s:%s", cipher_mode, ivgen_alg, 12743e308f20SDaniel P. Berrange ivgen_hash_alg); 12753e308f20SDaniel P. Berrange } else { 12763e308f20SDaniel P. Berrange cipher_mode_spec = g_strdup_printf("%s-%s", cipher_mode, ivgen_alg); 12773e308f20SDaniel P. Berrange } 1278977c736fSMarkus Armbruster hash_alg = QCryptoHashAlgorithm_str(luks_opts.hash_alg); 12793e308f20SDaniel P. Berrange 12803e308f20SDaniel P. Berrange 12813e308f20SDaniel P. Berrange if (strlen(cipher_alg) >= QCRYPTO_BLOCK_LUKS_CIPHER_NAME_LEN) { 12823e308f20SDaniel P. Berrange error_setg(errp, "Cipher name '%s' is too long for LUKS header", 12833e308f20SDaniel P. Berrange cipher_alg); 12843e308f20SDaniel P. Berrange goto error; 12853e308f20SDaniel P. Berrange } 12863e308f20SDaniel P. Berrange if (strlen(cipher_mode_spec) >= QCRYPTO_BLOCK_LUKS_CIPHER_MODE_LEN) { 12873e308f20SDaniel P. Berrange error_setg(errp, "Cipher mode '%s' is too long for LUKS header", 12883e308f20SDaniel P. Berrange cipher_mode_spec); 12893e308f20SDaniel P. Berrange goto error; 12903e308f20SDaniel P. Berrange } 12913e308f20SDaniel P. Berrange if (strlen(hash_alg) >= QCRYPTO_BLOCK_LUKS_HASH_SPEC_LEN) { 12923e308f20SDaniel P. Berrange error_setg(errp, "Hash name '%s' is too long for LUKS header", 12933e308f20SDaniel P. Berrange hash_alg); 12943e308f20SDaniel P. Berrange goto error; 12953e308f20SDaniel P. Berrange } 12963e308f20SDaniel P. Berrange 12973e308f20SDaniel P. Berrange if (luks_opts.ivgen_alg == QCRYPTO_IVGEN_ALG_ESSIV) { 12989d80e59dSMaxim Levitsky luks->ivgen_cipher_alg = 12999d80e59dSMaxim Levitsky qcrypto_block_luks_essiv_cipher(luks_opts.cipher_alg, 13003e308f20SDaniel P. Berrange luks_opts.ivgen_hash_alg, 13013e308f20SDaniel P. Berrange &local_err); 13023e308f20SDaniel P. Berrange if (local_err) { 13033e308f20SDaniel P. Berrange error_propagate(errp, local_err); 13043e308f20SDaniel P. Berrange goto error; 13053e308f20SDaniel P. Berrange } 13063e308f20SDaniel P. Berrange } else { 13079d80e59dSMaxim Levitsky luks->ivgen_cipher_alg = luks_opts.cipher_alg; 13083e308f20SDaniel P. Berrange } 13093e308f20SDaniel P. Berrange 13103e308f20SDaniel P. Berrange strcpy(luks->header.cipher_name, cipher_alg); 13113e308f20SDaniel P. Berrange strcpy(luks->header.cipher_mode, cipher_mode_spec); 13123e308f20SDaniel P. Berrange strcpy(luks->header.hash_spec, hash_alg); 13133e308f20SDaniel P. Berrange 1314f0d3c362SMaxim Levitsky luks->header.master_key_len = 1315f0d3c362SMaxim Levitsky qcrypto_cipher_get_key_len(luks_opts.cipher_alg); 1316f0d3c362SMaxim Levitsky 13173e308f20SDaniel P. Berrange if (luks_opts.cipher_mode == QCRYPTO_CIPHER_MODE_XTS) { 1318f0d3c362SMaxim Levitsky luks->header.master_key_len *= 2; 13193e308f20SDaniel P. Berrange } 13203e308f20SDaniel P. Berrange 13213e308f20SDaniel P. Berrange /* Generate the salt used for hashing the master key 13223e308f20SDaniel P. Berrange * with PBKDF later 13233e308f20SDaniel P. Berrange */ 13243e308f20SDaniel P. Berrange if (qcrypto_random_bytes(luks->header.master_key_salt, 13253e308f20SDaniel P. Berrange QCRYPTO_BLOCK_LUKS_SALT_LEN, 13263e308f20SDaniel P. Berrange errp) < 0) { 13273e308f20SDaniel P. Berrange goto error; 13283e308f20SDaniel P. Berrange } 13293e308f20SDaniel P. Berrange 13303e308f20SDaniel P. Berrange /* Generate random master key */ 1331f0d3c362SMaxim Levitsky masterkey = g_new0(uint8_t, luks->header.master_key_len); 13323e308f20SDaniel P. Berrange if (qcrypto_random_bytes(masterkey, 1333f0d3c362SMaxim Levitsky luks->header.master_key_len, errp) < 0) { 13343e308f20SDaniel P. Berrange goto error; 13353e308f20SDaniel P. Berrange } 13363e308f20SDaniel P. Berrange 13373e308f20SDaniel P. Berrange 13383e308f20SDaniel P. Berrange /* Setup the block device payload encryption objects */ 1339c972fa12SVladimir Sementsov-Ogievskiy if (qcrypto_block_init_cipher(block, luks_opts.cipher_alg, 1340c972fa12SVladimir Sementsov-Ogievskiy luks_opts.cipher_mode, masterkey, 1341f0d3c362SMaxim Levitsky luks->header.master_key_len, 1, errp) < 0) { 13423e308f20SDaniel P. Berrange goto error; 13433e308f20SDaniel P. Berrange } 13443e308f20SDaniel P. Berrange 13453e308f20SDaniel P. Berrange block->kdfhash = luks_opts.hash_alg; 13463e308f20SDaniel P. Berrange block->niv = qcrypto_cipher_get_iv_len(luks_opts.cipher_alg, 13473e308f20SDaniel P. Berrange luks_opts.cipher_mode); 13483e308f20SDaniel P. Berrange block->ivgen = qcrypto_ivgen_new(luks_opts.ivgen_alg, 13499d80e59dSMaxim Levitsky luks->ivgen_cipher_alg, 13503e308f20SDaniel P. Berrange luks_opts.ivgen_hash_alg, 1351f0d3c362SMaxim Levitsky masterkey, luks->header.master_key_len, 13523e308f20SDaniel P. Berrange errp); 13533e308f20SDaniel P. Berrange 13543e308f20SDaniel P. Berrange if (!block->ivgen) { 13553e308f20SDaniel P. Berrange goto error; 13563e308f20SDaniel P. Berrange } 13573e308f20SDaniel P. Berrange 13583e308f20SDaniel P. Berrange 13593e308f20SDaniel P. Berrange /* Determine how many iterations we need to hash the master 13603e308f20SDaniel P. Berrange * key, in order to have 1 second of compute time used 13613e308f20SDaniel P. Berrange */ 136259b060beSDaniel P. Berrange iters = qcrypto_pbkdf2_count_iters(luks_opts.hash_alg, 1363f0d3c362SMaxim Levitsky masterkey, luks->header.master_key_len, 13643e308f20SDaniel P. Berrange luks->header.master_key_salt, 13653e308f20SDaniel P. Berrange QCRYPTO_BLOCK_LUKS_SALT_LEN, 1366e74aabcfSDaniel P. Berrange QCRYPTO_BLOCK_LUKS_DIGEST_LEN, 13673e308f20SDaniel P. Berrange &local_err); 13683e308f20SDaniel P. Berrange if (local_err) { 13693e308f20SDaniel P. Berrange error_propagate(errp, local_err); 13703e308f20SDaniel P. Berrange goto error; 13713e308f20SDaniel P. Berrange } 13723e308f20SDaniel P. Berrange 13733bd18890SDaniel P. Berrange if (iters > (ULLONG_MAX / luks_opts.iter_time)) { 13743bd18890SDaniel P. Berrange error_setg_errno(errp, ERANGE, 13753bd18890SDaniel P. Berrange "PBKDF iterations %llu too large to scale", 13763bd18890SDaniel P. Berrange (unsigned long long)iters); 13773bd18890SDaniel P. Berrange goto error; 13783bd18890SDaniel P. Berrange } 13793bd18890SDaniel P. Berrange 13803bd18890SDaniel P. Berrange /* iter_time was in millis, but count_iters reported for secs */ 13813bd18890SDaniel P. Berrange iters = iters * luks_opts.iter_time / 1000; 13823bd18890SDaniel P. Berrange 13833e308f20SDaniel P. Berrange /* Why /= 8 ? That matches cryptsetup, but there's no 13843e308f20SDaniel P. Berrange * explanation why they chose /= 8... Probably so that 13853e308f20SDaniel P. Berrange * if all 8 keyslots are active we only spend 1 second 13863e308f20SDaniel P. Berrange * in total time to check all keys */ 138759b060beSDaniel P. Berrange iters /= 8; 138859b060beSDaniel P. Berrange if (iters > UINT32_MAX) { 138959b060beSDaniel P. Berrange error_setg_errno(errp, ERANGE, 139059b060beSDaniel P. Berrange "PBKDF iterations %llu larger than %u", 139159b060beSDaniel P. Berrange (unsigned long long)iters, UINT32_MAX); 139259b060beSDaniel P. Berrange goto error; 139359b060beSDaniel P. Berrange } 139459b060beSDaniel P. Berrange iters = MAX(iters, QCRYPTO_BLOCK_LUKS_MIN_MASTER_KEY_ITERS); 139559b060beSDaniel P. Berrange luks->header.master_key_iterations = iters; 13963e308f20SDaniel P. Berrange 13973e308f20SDaniel P. Berrange /* Hash the master key, saving the result in the LUKS 13983e308f20SDaniel P. Berrange * header. This hash is used when opening the encrypted 13993e308f20SDaniel P. Berrange * device to verify that the user password unlocked a 14003e308f20SDaniel P. Berrange * valid master key 14013e308f20SDaniel P. Berrange */ 14023e308f20SDaniel P. Berrange if (qcrypto_pbkdf2(luks_opts.hash_alg, 1403f0d3c362SMaxim Levitsky masterkey, luks->header.master_key_len, 14043e308f20SDaniel P. Berrange luks->header.master_key_salt, 14053e308f20SDaniel P. Berrange QCRYPTO_BLOCK_LUKS_SALT_LEN, 14063e308f20SDaniel P. Berrange luks->header.master_key_iterations, 14073e308f20SDaniel P. Berrange luks->header.master_key_digest, 14083e308f20SDaniel P. Berrange QCRYPTO_BLOCK_LUKS_DIGEST_LEN, 14093e308f20SDaniel P. Berrange errp) < 0) { 14103e308f20SDaniel P. Berrange goto error; 14113e308f20SDaniel P. Berrange } 14123e308f20SDaniel P. Berrange 1413bd56a55aSMaxim Levitsky /* start with the sector that follows the header*/ 1414bd56a55aSMaxim Levitsky header_sectors = QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET / 1415bd56a55aSMaxim Levitsky QCRYPTO_BLOCK_LUKS_SECTOR_SIZE; 14163e308f20SDaniel P. Berrange 1417bd56a55aSMaxim Levitsky split_key_sectors = 1418bd56a55aSMaxim Levitsky qcrypto_block_luks_splitkeylen_sectors(luks, 1419bd56a55aSMaxim Levitsky header_sectors, 1420bd56a55aSMaxim Levitsky QCRYPTO_BLOCK_LUKS_STRIPES); 1421bd56a55aSMaxim Levitsky 14223e308f20SDaniel P. Berrange for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) { 1423bd56a55aSMaxim Levitsky QCryptoBlockLUKSKeySlot *slot = &luks->header.key_slots[i]; 1424bd56a55aSMaxim Levitsky slot->active = QCRYPTO_BLOCK_LUKS_KEY_SLOT_DISABLED; 14253e308f20SDaniel P. Berrange 1426bd56a55aSMaxim Levitsky slot->key_offset_sector = header_sectors + i * split_key_sectors; 1427bd56a55aSMaxim Levitsky slot->stripes = QCRYPTO_BLOCK_LUKS_STRIPES; 14283e308f20SDaniel P. Berrange } 14293e308f20SDaniel P. Berrange 14303e308f20SDaniel P. Berrange /* The total size of the LUKS headers is the partition header + key 14313e308f20SDaniel P. Berrange * slot headers, rounded up to the nearest sector, combined with 14323e308f20SDaniel P. Berrange * the size of each master key material region, also rounded up 14333e308f20SDaniel P. Berrange * to the nearest sector */ 1434bd56a55aSMaxim Levitsky luks->header.payload_offset_sector = header_sectors + 1435bd56a55aSMaxim Levitsky QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS * split_key_sectors; 14363e308f20SDaniel P. Berrange 1437850f49deSDaniel P. Berrange block->sector_size = QCRYPTO_BLOCK_LUKS_SECTOR_SIZE; 1438f0d3c362SMaxim Levitsky block->payload_offset = luks->header.payload_offset_sector * 1439850f49deSDaniel P. Berrange block->sector_size; 14403e308f20SDaniel P. Berrange 14413e308f20SDaniel P. Berrange /* Reserve header space to match payload offset */ 1442e4a3507eSDaniel P. Berrange initfunc(block, block->payload_offset, opaque, &local_err); 14433e308f20SDaniel P. Berrange if (local_err) { 14443e308f20SDaniel P. Berrange error_propagate(errp, local_err); 14453e308f20SDaniel P. Berrange goto error; 14463e308f20SDaniel P. Berrange } 14473e308f20SDaniel P. Berrange 14483e308f20SDaniel P. Berrange 14493994a7c9SMaxim Levitsky /* populate the slot 0 with the password encrypted master key*/ 14503994a7c9SMaxim Levitsky /* This will also store the header */ 14513994a7c9SMaxim Levitsky if (qcrypto_block_luks_store_key(block, 14523994a7c9SMaxim Levitsky 0, 14533994a7c9SMaxim Levitsky password, 14543994a7c9SMaxim Levitsky masterkey, 14553994a7c9SMaxim Levitsky luks_opts.iter_time, 14563994a7c9SMaxim Levitsky writefunc, 1457e4a3507eSDaniel P. Berrange opaque, 14583994a7c9SMaxim Levitsky errp) < 0) { 14593e308f20SDaniel P. Berrange goto error; 14603e308f20SDaniel P. Berrange } 14613e308f20SDaniel P. Berrange 1462f0d3c362SMaxim Levitsky memset(masterkey, 0, luks->header.master_key_len); 14633e308f20SDaniel P. Berrange 14643e308f20SDaniel P. Berrange return 0; 14653e308f20SDaniel P. Berrange 14663e308f20SDaniel P. Berrange error: 14673e308f20SDaniel P. Berrange if (masterkey) { 1468f0d3c362SMaxim Levitsky memset(masterkey, 0, luks->header.master_key_len); 14693e308f20SDaniel P. Berrange } 14703e308f20SDaniel P. Berrange 1471c972fa12SVladimir Sementsov-Ogievskiy qcrypto_block_free_cipher(block); 1472b640adcaSVladimir Sementsov-Ogievskiy qcrypto_ivgen_free(block->ivgen); 1473b640adcaSVladimir Sementsov-Ogievskiy 14743e308f20SDaniel P. Berrange g_free(luks); 14753e308f20SDaniel P. Berrange return -1; 14763e308f20SDaniel P. Berrange } 14773e308f20SDaniel P. Berrange 14783e308f20SDaniel P. Berrange 147940c85028SDaniel P. Berrange static int qcrypto_block_luks_get_info(QCryptoBlock *block, 148040c85028SDaniel P. Berrange QCryptoBlockInfo *info, 148140c85028SDaniel P. Berrange Error **errp) 148240c85028SDaniel P. Berrange { 148340c85028SDaniel P. Berrange QCryptoBlockLUKS *luks = block->opaque; 148440c85028SDaniel P. Berrange QCryptoBlockInfoLUKSSlot *slot; 148540c85028SDaniel P. Berrange QCryptoBlockInfoLUKSSlotList *slots = NULL, **prev = &info->u.luks.slots; 148640c85028SDaniel P. Berrange size_t i; 148740c85028SDaniel P. Berrange 148840c85028SDaniel P. Berrange info->u.luks.cipher_alg = luks->cipher_alg; 148940c85028SDaniel P. Berrange info->u.luks.cipher_mode = luks->cipher_mode; 149040c85028SDaniel P. Berrange info->u.luks.ivgen_alg = luks->ivgen_alg; 149140c85028SDaniel P. Berrange if (info->u.luks.ivgen_alg == QCRYPTO_IVGEN_ALG_ESSIV) { 149240c85028SDaniel P. Berrange info->u.luks.has_ivgen_hash_alg = true; 149340c85028SDaniel P. Berrange info->u.luks.ivgen_hash_alg = luks->ivgen_hash_alg; 149440c85028SDaniel P. Berrange } 149540c85028SDaniel P. Berrange info->u.luks.hash_alg = luks->hash_alg; 149640c85028SDaniel P. Berrange info->u.luks.payload_offset = block->payload_offset; 149740c85028SDaniel P. Berrange info->u.luks.master_key_iters = luks->header.master_key_iterations; 149840c85028SDaniel P. Berrange info->u.luks.uuid = g_strndup((const char *)luks->header.uuid, 149940c85028SDaniel P. Berrange sizeof(luks->header.uuid)); 150040c85028SDaniel P. Berrange 150140c85028SDaniel P. Berrange for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) { 150240c85028SDaniel P. Berrange slots = g_new0(QCryptoBlockInfoLUKSSlotList, 1); 150340c85028SDaniel P. Berrange *prev = slots; 150440c85028SDaniel P. Berrange 150540c85028SDaniel P. Berrange slots->value = slot = g_new0(QCryptoBlockInfoLUKSSlot, 1); 150640c85028SDaniel P. Berrange slot->active = luks->header.key_slots[i].active == 150740c85028SDaniel P. Berrange QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED; 1508f0d3c362SMaxim Levitsky slot->key_offset = luks->header.key_slots[i].key_offset_sector 150940c85028SDaniel P. Berrange * QCRYPTO_BLOCK_LUKS_SECTOR_SIZE; 151040c85028SDaniel P. Berrange if (slot->active) { 151140c85028SDaniel P. Berrange slot->has_iters = true; 151240c85028SDaniel P. Berrange slot->iters = luks->header.key_slots[i].iterations; 151340c85028SDaniel P. Berrange slot->has_stripes = true; 151440c85028SDaniel P. Berrange slot->stripes = luks->header.key_slots[i].stripes; 151540c85028SDaniel P. Berrange } 151640c85028SDaniel P. Berrange 151740c85028SDaniel P. Berrange prev = &slots->next; 151840c85028SDaniel P. Berrange } 151940c85028SDaniel P. Berrange 152040c85028SDaniel P. Berrange return 0; 152140c85028SDaniel P. Berrange } 152240c85028SDaniel P. Berrange 152340c85028SDaniel P. Berrange 15243e308f20SDaniel P. Berrange static void qcrypto_block_luks_cleanup(QCryptoBlock *block) 15253e308f20SDaniel P. Berrange { 15263e308f20SDaniel P. Berrange g_free(block->opaque); 15273e308f20SDaniel P. Berrange } 15283e308f20SDaniel P. Berrange 15293e308f20SDaniel P. Berrange 15303e308f20SDaniel P. Berrange static int 15313e308f20SDaniel P. Berrange qcrypto_block_luks_decrypt(QCryptoBlock *block, 15324609742aSDaniel P. Berrange uint64_t offset, 15333e308f20SDaniel P. Berrange uint8_t *buf, 15343e308f20SDaniel P. Berrange size_t len, 15353e308f20SDaniel P. Berrange Error **errp) 15363e308f20SDaniel P. Berrange { 15374609742aSDaniel P. Berrange assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); 15384609742aSDaniel P. Berrange assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); 15390f0d596cSVladimir Sementsov-Ogievskiy return qcrypto_block_decrypt_helper(block, 15403e308f20SDaniel P. Berrange QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, 15414609742aSDaniel P. Berrange offset, buf, len, errp); 15423e308f20SDaniel P. Berrange } 15433e308f20SDaniel P. Berrange 15443e308f20SDaniel P. Berrange 15453e308f20SDaniel P. Berrange static int 15463e308f20SDaniel P. Berrange qcrypto_block_luks_encrypt(QCryptoBlock *block, 15474609742aSDaniel P. Berrange uint64_t offset, 15483e308f20SDaniel P. Berrange uint8_t *buf, 15493e308f20SDaniel P. Berrange size_t len, 15503e308f20SDaniel P. Berrange Error **errp) 15513e308f20SDaniel P. Berrange { 15524609742aSDaniel P. Berrange assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); 15534609742aSDaniel P. Berrange assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); 15540f0d596cSVladimir Sementsov-Ogievskiy return qcrypto_block_encrypt_helper(block, 15553e308f20SDaniel P. Berrange QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, 15564609742aSDaniel P. Berrange offset, buf, len, errp); 15573e308f20SDaniel P. Berrange } 15583e308f20SDaniel P. Berrange 15593e308f20SDaniel P. Berrange 15603e308f20SDaniel P. Berrange const QCryptoBlockDriver qcrypto_block_driver_luks = { 15613e308f20SDaniel P. Berrange .open = qcrypto_block_luks_open, 15623e308f20SDaniel P. Berrange .create = qcrypto_block_luks_create, 156340c85028SDaniel P. Berrange .get_info = qcrypto_block_luks_get_info, 15643e308f20SDaniel P. Berrange .cleanup = qcrypto_block_luks_cleanup, 15653e308f20SDaniel P. Berrange .decrypt = qcrypto_block_luks_decrypt, 15663e308f20SDaniel P. Berrange .encrypt = qcrypto_block_luks_encrypt, 15673e308f20SDaniel P. Berrange .has_format = qcrypto_block_luks_has_format, 15683e308f20SDaniel P. Berrange }; 1569