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 /* 413*bd56a55aSMaxim Levitsky * Returns number of sectors needed to store the key material 414*bd56a55aSMaxim Levitsky * given number of anti forensic stripes 415*bd56a55aSMaxim Levitsky */ 416*bd56a55aSMaxim Levitsky static int 417*bd56a55aSMaxim Levitsky qcrypto_block_luks_splitkeylen_sectors(const QCryptoBlockLUKS *luks, 418*bd56a55aSMaxim Levitsky unsigned int header_sectors, 419*bd56a55aSMaxim Levitsky unsigned int stripes) 420*bd56a55aSMaxim Levitsky { 421*bd56a55aSMaxim Levitsky /* 422*bd56a55aSMaxim Levitsky * This calculation doesn't match that shown in the spec, 423*bd56a55aSMaxim Levitsky * but instead follows the cryptsetup implementation. 424*bd56a55aSMaxim Levitsky */ 425*bd56a55aSMaxim Levitsky 426*bd56a55aSMaxim Levitsky size_t splitkeylen = luks->header.master_key_len * stripes; 427*bd56a55aSMaxim Levitsky 428*bd56a55aSMaxim Levitsky /* First align the key material size to block size*/ 429*bd56a55aSMaxim Levitsky size_t splitkeylen_sectors = 430*bd56a55aSMaxim Levitsky DIV_ROUND_UP(splitkeylen, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE); 431*bd56a55aSMaxim Levitsky 432*bd56a55aSMaxim Levitsky /* Then also align the key material size to the size of the header */ 433*bd56a55aSMaxim Levitsky return ROUND_UP(splitkeylen_sectors, header_sectors); 434*bd56a55aSMaxim Levitsky } 435*bd56a55aSMaxim Levitsky 436*bd56a55aSMaxim 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 { 5339fa9c1c2SMaxim Levitsky if (memcmp(luks->header.magic, qcrypto_block_luks_magic, 5349fa9c1c2SMaxim Levitsky QCRYPTO_BLOCK_LUKS_MAGIC_LEN) != 0) { 5359fa9c1c2SMaxim Levitsky error_setg(errp, "Volume is not in LUKS format"); 5369fa9c1c2SMaxim Levitsky return -1; 5379fa9c1c2SMaxim Levitsky } 5389fa9c1c2SMaxim Levitsky 5399fa9c1c2SMaxim Levitsky if (luks->header.version != QCRYPTO_BLOCK_LUKS_VERSION) { 5409fa9c1c2SMaxim Levitsky error_setg(errp, "LUKS version %" PRIu32 " is not supported", 5419fa9c1c2SMaxim Levitsky luks->header.version); 5429fa9c1c2SMaxim Levitsky return -1; 5439fa9c1c2SMaxim Levitsky } 5449fa9c1c2SMaxim Levitsky return 0; 5459fa9c1c2SMaxim Levitsky } 5469fa9c1c2SMaxim Levitsky 5479fa9c1c2SMaxim Levitsky /* 5489fa9c1c2SMaxim Levitsky * Parses the crypto parameters that are stored in the LUKS header 5499fa9c1c2SMaxim Levitsky */ 5509fa9c1c2SMaxim Levitsky 5519fa9c1c2SMaxim Levitsky static int 5529fa9c1c2SMaxim Levitsky qcrypto_block_luks_parse_header(QCryptoBlockLUKS *luks, Error **errp) 5539fa9c1c2SMaxim Levitsky { 5549fa9c1c2SMaxim Levitsky g_autofree char *cipher_mode = g_strdup(luks->header.cipher_mode); 5559fa9c1c2SMaxim Levitsky char *ivgen_name, *ivhash_name; 5569fa9c1c2SMaxim Levitsky Error *local_err = NULL; 5579fa9c1c2SMaxim Levitsky 5589fa9c1c2SMaxim Levitsky /* 5599fa9c1c2SMaxim Levitsky * The cipher_mode header contains a string that we have 5609fa9c1c2SMaxim Levitsky * to further parse, of the format 5619fa9c1c2SMaxim Levitsky * 5629fa9c1c2SMaxim Levitsky * <cipher-mode>-<iv-generator>[:<iv-hash>] 5639fa9c1c2SMaxim Levitsky * 5649fa9c1c2SMaxim Levitsky * eg cbc-essiv:sha256, cbc-plain64 5659fa9c1c2SMaxim Levitsky */ 5669fa9c1c2SMaxim Levitsky ivgen_name = strchr(cipher_mode, '-'); 5679fa9c1c2SMaxim Levitsky if (!ivgen_name) { 5689fa9c1c2SMaxim Levitsky error_setg(errp, "Unexpected cipher mode string format %s", 5699fa9c1c2SMaxim Levitsky luks->header.cipher_mode); 5709fa9c1c2SMaxim Levitsky return -1; 5719fa9c1c2SMaxim Levitsky } 5729fa9c1c2SMaxim Levitsky *ivgen_name = '\0'; 5739fa9c1c2SMaxim Levitsky ivgen_name++; 5749fa9c1c2SMaxim Levitsky 5759fa9c1c2SMaxim Levitsky ivhash_name = strchr(ivgen_name, ':'); 5769fa9c1c2SMaxim Levitsky if (!ivhash_name) { 5779fa9c1c2SMaxim Levitsky luks->ivgen_hash_alg = 0; 5789fa9c1c2SMaxim Levitsky } else { 5799fa9c1c2SMaxim Levitsky *ivhash_name = '\0'; 5809fa9c1c2SMaxim Levitsky ivhash_name++; 5819fa9c1c2SMaxim Levitsky 5829fa9c1c2SMaxim Levitsky luks->ivgen_hash_alg = qcrypto_block_luks_hash_name_lookup(ivhash_name, 5839fa9c1c2SMaxim Levitsky &local_err); 5849fa9c1c2SMaxim Levitsky if (local_err) { 5859fa9c1c2SMaxim Levitsky error_propagate(errp, local_err); 5869fa9c1c2SMaxim Levitsky return -1; 5879fa9c1c2SMaxim Levitsky } 5889fa9c1c2SMaxim Levitsky } 5899fa9c1c2SMaxim Levitsky 5909fa9c1c2SMaxim Levitsky luks->cipher_mode = qcrypto_block_luks_cipher_mode_lookup(cipher_mode, 5919fa9c1c2SMaxim Levitsky &local_err); 5929fa9c1c2SMaxim Levitsky if (local_err) { 5939fa9c1c2SMaxim Levitsky error_propagate(errp, local_err); 5949fa9c1c2SMaxim Levitsky return -1; 5959fa9c1c2SMaxim Levitsky } 5969fa9c1c2SMaxim Levitsky 5979fa9c1c2SMaxim Levitsky luks->cipher_alg = 5989fa9c1c2SMaxim Levitsky qcrypto_block_luks_cipher_name_lookup(luks->header.cipher_name, 5999fa9c1c2SMaxim Levitsky luks->cipher_mode, 6009fa9c1c2SMaxim Levitsky luks->header.master_key_len, 6019fa9c1c2SMaxim Levitsky &local_err); 6029fa9c1c2SMaxim Levitsky if (local_err) { 6039fa9c1c2SMaxim Levitsky error_propagate(errp, local_err); 6049fa9c1c2SMaxim Levitsky return -1; 6059fa9c1c2SMaxim Levitsky } 6069fa9c1c2SMaxim Levitsky 6079fa9c1c2SMaxim Levitsky luks->hash_alg = 6089fa9c1c2SMaxim Levitsky qcrypto_block_luks_hash_name_lookup(luks->header.hash_spec, 6099fa9c1c2SMaxim Levitsky &local_err); 6109fa9c1c2SMaxim Levitsky if (local_err) { 6119fa9c1c2SMaxim Levitsky error_propagate(errp, local_err); 6129fa9c1c2SMaxim Levitsky return -1; 6139fa9c1c2SMaxim Levitsky } 6149fa9c1c2SMaxim Levitsky 6159fa9c1c2SMaxim Levitsky luks->ivgen_alg = qcrypto_block_luks_ivgen_name_lookup(ivgen_name, 6169fa9c1c2SMaxim Levitsky &local_err); 6179fa9c1c2SMaxim Levitsky if (local_err) { 6189fa9c1c2SMaxim Levitsky error_propagate(errp, local_err); 6199fa9c1c2SMaxim Levitsky return -1; 6209fa9c1c2SMaxim Levitsky } 6219fa9c1c2SMaxim Levitsky 6229fa9c1c2SMaxim Levitsky if (luks->ivgen_alg == QCRYPTO_IVGEN_ALG_ESSIV) { 6239fa9c1c2SMaxim Levitsky if (!ivhash_name) { 6249fa9c1c2SMaxim Levitsky error_setg(errp, "Missing IV generator hash specification"); 6259fa9c1c2SMaxim Levitsky return -1; 6269fa9c1c2SMaxim Levitsky } 6279fa9c1c2SMaxim Levitsky luks->ivgen_cipher_alg = 6289fa9c1c2SMaxim Levitsky qcrypto_block_luks_essiv_cipher(luks->cipher_alg, 6299fa9c1c2SMaxim Levitsky luks->ivgen_hash_alg, 6309fa9c1c2SMaxim Levitsky &local_err); 6319fa9c1c2SMaxim Levitsky if (local_err) { 6329fa9c1c2SMaxim Levitsky error_propagate(errp, local_err); 6339fa9c1c2SMaxim Levitsky return -1; 6349fa9c1c2SMaxim Levitsky } 6359fa9c1c2SMaxim Levitsky } else { 6369fa9c1c2SMaxim Levitsky 6379fa9c1c2SMaxim Levitsky /* 6389fa9c1c2SMaxim Levitsky * Note we parsed the ivhash_name earlier in the cipher_mode 6399fa9c1c2SMaxim Levitsky * spec string even with plain/plain64 ivgens, but we 6409fa9c1c2SMaxim Levitsky * will ignore it, since it is irrelevant for these ivgens. 6419fa9c1c2SMaxim Levitsky * This is for compat with dm-crypt which will silently 6429fa9c1c2SMaxim Levitsky * ignore hash names with these ivgens rather than report 6439fa9c1c2SMaxim Levitsky * an error about the invalid usage 6449fa9c1c2SMaxim Levitsky */ 6459fa9c1c2SMaxim Levitsky luks->ivgen_cipher_alg = luks->cipher_alg; 6469fa9c1c2SMaxim Levitsky } 6479fa9c1c2SMaxim Levitsky return 0; 6489fa9c1c2SMaxim Levitsky } 6499fa9c1c2SMaxim Levitsky 6509fa9c1c2SMaxim Levitsky /* 6513994a7c9SMaxim Levitsky * Given a key slot, user password, and the master key, 6523994a7c9SMaxim Levitsky * will store the encrypted master key there, and update the 6533994a7c9SMaxim Levitsky * in-memory header. User must then write the in-memory header 6543994a7c9SMaxim Levitsky * 6553994a7c9SMaxim Levitsky * Returns: 6563994a7c9SMaxim Levitsky * 0 if the keyslot was written successfully 6573994a7c9SMaxim Levitsky * with the provided password 6583994a7c9SMaxim Levitsky * -1 if a fatal error occurred while storing the key 6593994a7c9SMaxim Levitsky */ 6603994a7c9SMaxim Levitsky static int 6613994a7c9SMaxim Levitsky qcrypto_block_luks_store_key(QCryptoBlock *block, 6623994a7c9SMaxim Levitsky unsigned int slot_idx, 6633994a7c9SMaxim Levitsky const char *password, 6643994a7c9SMaxim Levitsky uint8_t *masterkey, 6653994a7c9SMaxim Levitsky uint64_t iter_time, 6663994a7c9SMaxim Levitsky QCryptoBlockWriteFunc writefunc, 6673994a7c9SMaxim Levitsky void *opaque, 6683994a7c9SMaxim Levitsky Error **errp) 6693994a7c9SMaxim Levitsky { 6703994a7c9SMaxim Levitsky QCryptoBlockLUKS *luks = block->opaque; 6713994a7c9SMaxim Levitsky QCryptoBlockLUKSKeySlot *slot = &luks->header.key_slots[slot_idx]; 6723994a7c9SMaxim Levitsky g_autofree uint8_t *splitkey = NULL; 6733994a7c9SMaxim Levitsky size_t splitkeylen; 6743994a7c9SMaxim Levitsky g_autofree uint8_t *slotkey = NULL; 6753994a7c9SMaxim Levitsky g_autoptr(QCryptoCipher) cipher = NULL; 6763994a7c9SMaxim Levitsky g_autoptr(QCryptoIVGen) ivgen = NULL; 6773994a7c9SMaxim Levitsky Error *local_err = NULL; 6783994a7c9SMaxim Levitsky uint64_t iters; 6793994a7c9SMaxim Levitsky int ret = -1; 6803994a7c9SMaxim Levitsky 6813994a7c9SMaxim Levitsky if (qcrypto_random_bytes(slot->salt, 6823994a7c9SMaxim Levitsky QCRYPTO_BLOCK_LUKS_SALT_LEN, 6833994a7c9SMaxim Levitsky errp) < 0) { 6843994a7c9SMaxim Levitsky goto cleanup; 6853994a7c9SMaxim Levitsky } 6863994a7c9SMaxim Levitsky 6873994a7c9SMaxim Levitsky splitkeylen = luks->header.master_key_len * slot->stripes; 6883994a7c9SMaxim Levitsky 6893994a7c9SMaxim Levitsky /* 6903994a7c9SMaxim Levitsky * Determine how many iterations are required to 6913994a7c9SMaxim Levitsky * hash the user password while consuming 1 second of compute 6923994a7c9SMaxim Levitsky * time 6933994a7c9SMaxim Levitsky */ 6943994a7c9SMaxim Levitsky iters = qcrypto_pbkdf2_count_iters(luks->hash_alg, 6953994a7c9SMaxim Levitsky (uint8_t *)password, strlen(password), 6963994a7c9SMaxim Levitsky slot->salt, 6973994a7c9SMaxim Levitsky QCRYPTO_BLOCK_LUKS_SALT_LEN, 6983994a7c9SMaxim Levitsky luks->header.master_key_len, 6993994a7c9SMaxim Levitsky &local_err); 7003994a7c9SMaxim Levitsky if (local_err) { 7013994a7c9SMaxim Levitsky error_propagate(errp, local_err); 7023994a7c9SMaxim Levitsky goto cleanup; 7033994a7c9SMaxim Levitsky } 7043994a7c9SMaxim Levitsky 7053994a7c9SMaxim Levitsky if (iters > (ULLONG_MAX / iter_time)) { 7063994a7c9SMaxim Levitsky error_setg_errno(errp, ERANGE, 7073994a7c9SMaxim Levitsky "PBKDF iterations %llu too large to scale", 7083994a7c9SMaxim Levitsky (unsigned long long)iters); 7093994a7c9SMaxim Levitsky goto cleanup; 7103994a7c9SMaxim Levitsky } 7113994a7c9SMaxim Levitsky 7123994a7c9SMaxim Levitsky /* iter_time was in millis, but count_iters reported for secs */ 7133994a7c9SMaxim Levitsky iters = iters * iter_time / 1000; 7143994a7c9SMaxim Levitsky 7153994a7c9SMaxim Levitsky if (iters > UINT32_MAX) { 7163994a7c9SMaxim Levitsky error_setg_errno(errp, ERANGE, 7173994a7c9SMaxim Levitsky "PBKDF iterations %llu larger than %u", 7183994a7c9SMaxim Levitsky (unsigned long long)iters, UINT32_MAX); 7193994a7c9SMaxim Levitsky goto cleanup; 7203994a7c9SMaxim Levitsky } 7213994a7c9SMaxim Levitsky 7223994a7c9SMaxim Levitsky slot->iterations = 7233994a7c9SMaxim Levitsky MAX(iters, QCRYPTO_BLOCK_LUKS_MIN_SLOT_KEY_ITERS); 7243994a7c9SMaxim Levitsky 7253994a7c9SMaxim Levitsky 7263994a7c9SMaxim Levitsky /* 7273994a7c9SMaxim Levitsky * Generate a key that we'll use to encrypt the master 7283994a7c9SMaxim Levitsky * key, from the user's password 7293994a7c9SMaxim Levitsky */ 7303994a7c9SMaxim Levitsky slotkey = g_new0(uint8_t, luks->header.master_key_len); 7313994a7c9SMaxim Levitsky if (qcrypto_pbkdf2(luks->hash_alg, 7323994a7c9SMaxim Levitsky (uint8_t *)password, strlen(password), 7333994a7c9SMaxim Levitsky slot->salt, 7343994a7c9SMaxim Levitsky QCRYPTO_BLOCK_LUKS_SALT_LEN, 7353994a7c9SMaxim Levitsky slot->iterations, 7363994a7c9SMaxim Levitsky slotkey, luks->header.master_key_len, 7373994a7c9SMaxim Levitsky errp) < 0) { 7383994a7c9SMaxim Levitsky goto cleanup; 7393994a7c9SMaxim Levitsky } 7403994a7c9SMaxim Levitsky 7413994a7c9SMaxim Levitsky 7423994a7c9SMaxim Levitsky /* 7433994a7c9SMaxim Levitsky * Setup the encryption objects needed to encrypt the 7443994a7c9SMaxim Levitsky * master key material 7453994a7c9SMaxim Levitsky */ 7463994a7c9SMaxim Levitsky cipher = qcrypto_cipher_new(luks->cipher_alg, 7473994a7c9SMaxim Levitsky luks->cipher_mode, 7483994a7c9SMaxim Levitsky slotkey, luks->header.master_key_len, 7493994a7c9SMaxim Levitsky errp); 7503994a7c9SMaxim Levitsky if (!cipher) { 7513994a7c9SMaxim Levitsky goto cleanup; 7523994a7c9SMaxim Levitsky } 7533994a7c9SMaxim Levitsky 7543994a7c9SMaxim Levitsky ivgen = qcrypto_ivgen_new(luks->ivgen_alg, 7553994a7c9SMaxim Levitsky luks->ivgen_cipher_alg, 7563994a7c9SMaxim Levitsky luks->ivgen_hash_alg, 7573994a7c9SMaxim Levitsky slotkey, luks->header.master_key_len, 7583994a7c9SMaxim Levitsky errp); 7593994a7c9SMaxim Levitsky if (!ivgen) { 7603994a7c9SMaxim Levitsky goto cleanup; 7613994a7c9SMaxim Levitsky } 7623994a7c9SMaxim Levitsky 7633994a7c9SMaxim Levitsky /* 7643994a7c9SMaxim Levitsky * Before storing the master key, we need to vastly 7653994a7c9SMaxim Levitsky * increase its size, as protection against forensic 7663994a7c9SMaxim Levitsky * disk data recovery 7673994a7c9SMaxim Levitsky */ 7683994a7c9SMaxim Levitsky splitkey = g_new0(uint8_t, splitkeylen); 7693994a7c9SMaxim Levitsky 7703994a7c9SMaxim Levitsky if (qcrypto_afsplit_encode(luks->hash_alg, 7713994a7c9SMaxim Levitsky luks->header.master_key_len, 7723994a7c9SMaxim Levitsky slot->stripes, 7733994a7c9SMaxim Levitsky masterkey, 7743994a7c9SMaxim Levitsky splitkey, 7753994a7c9SMaxim Levitsky errp) < 0) { 7763994a7c9SMaxim Levitsky goto cleanup; 7773994a7c9SMaxim Levitsky } 7783994a7c9SMaxim Levitsky 7793994a7c9SMaxim Levitsky /* 7803994a7c9SMaxim Levitsky * Now we encrypt the split master key with the key generated 7813994a7c9SMaxim Levitsky * from the user's password, before storing it 7823994a7c9SMaxim Levitsky */ 7833994a7c9SMaxim Levitsky if (qcrypto_block_cipher_encrypt_helper(cipher, block->niv, ivgen, 7843994a7c9SMaxim Levitsky QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, 7853994a7c9SMaxim Levitsky 0, 7863994a7c9SMaxim Levitsky splitkey, 7873994a7c9SMaxim Levitsky splitkeylen, 7883994a7c9SMaxim Levitsky errp) < 0) { 7893994a7c9SMaxim Levitsky goto cleanup; 7903994a7c9SMaxim Levitsky } 7913994a7c9SMaxim Levitsky 7923994a7c9SMaxim Levitsky /* Write out the slot's master key material. */ 7933994a7c9SMaxim Levitsky if (writefunc(block, 7943994a7c9SMaxim Levitsky slot->key_offset_sector * 7953994a7c9SMaxim Levitsky QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, 7963994a7c9SMaxim Levitsky splitkey, splitkeylen, 7973994a7c9SMaxim Levitsky opaque, 7983994a7c9SMaxim Levitsky errp) != splitkeylen) { 7993994a7c9SMaxim Levitsky goto cleanup; 8003994a7c9SMaxim Levitsky } 8013994a7c9SMaxim Levitsky 8023994a7c9SMaxim Levitsky slot->active = QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED; 8033994a7c9SMaxim Levitsky 8043994a7c9SMaxim Levitsky if (qcrypto_block_luks_store_header(block, writefunc, opaque, errp) < 0) { 8053994a7c9SMaxim Levitsky goto cleanup; 8063994a7c9SMaxim Levitsky } 8073994a7c9SMaxim Levitsky 8083994a7c9SMaxim Levitsky ret = 0; 8093994a7c9SMaxim Levitsky 8103994a7c9SMaxim Levitsky cleanup: 8113994a7c9SMaxim Levitsky if (slotkey) { 8123994a7c9SMaxim Levitsky memset(slotkey, 0, luks->header.master_key_len); 8133994a7c9SMaxim Levitsky } 8143994a7c9SMaxim Levitsky if (splitkey) { 8153994a7c9SMaxim Levitsky memset(splitkey, 0, splitkeylen); 8163994a7c9SMaxim Levitsky } 8173994a7c9SMaxim Levitsky return ret; 8183994a7c9SMaxim Levitsky } 8193994a7c9SMaxim Levitsky 8203994a7c9SMaxim Levitsky /* 8213e308f20SDaniel P. Berrange * Given a key slot, and user password, this will attempt to unlock 8223e308f20SDaniel P. Berrange * the master encryption key from the key slot. 8233e308f20SDaniel P. Berrange * 8243e308f20SDaniel P. Berrange * Returns: 8253e308f20SDaniel P. Berrange * 0 if the key slot is disabled, or key could not be decrypted 8263e308f20SDaniel P. Berrange * with the provided password 8273e308f20SDaniel P. Berrange * 1 if the key slot is enabled, and key decrypted successfully 8283e308f20SDaniel P. Berrange * with the provided password 8293e308f20SDaniel P. Berrange * -1 if a fatal error occurred loading the key 8303e308f20SDaniel P. Berrange */ 8313e308f20SDaniel P. Berrange static int 8323e308f20SDaniel P. Berrange qcrypto_block_luks_load_key(QCryptoBlock *block, 8337e60a6f5SMaxim Levitsky size_t slot_idx, 8343e308f20SDaniel P. Berrange const char *password, 8353e308f20SDaniel P. Berrange uint8_t *masterkey, 8363e308f20SDaniel P. Berrange QCryptoBlockReadFunc readfunc, 8373e308f20SDaniel P. Berrange void *opaque, 8383e308f20SDaniel P. Berrange Error **errp) 8393e308f20SDaniel P. Berrange { 8403e308f20SDaniel P. Berrange QCryptoBlockLUKS *luks = block->opaque; 8417e60a6f5SMaxim Levitsky const QCryptoBlockLUKSKeySlot *slot = &luks->header.key_slots[slot_idx]; 84257b9f113SDaniel P. Berrangé g_autofree uint8_t *splitkey = NULL; 8433e308f20SDaniel P. Berrange size_t splitkeylen; 84457b9f113SDaniel P. Berrangé g_autofree uint8_t *possiblekey = NULL; 8453e308f20SDaniel P. Berrange ssize_t rv; 84657b9f113SDaniel P. Berrangé g_autoptr(QCryptoCipher) cipher = NULL; 8473e308f20SDaniel P. Berrange uint8_t keydigest[QCRYPTO_BLOCK_LUKS_DIGEST_LEN]; 84857b9f113SDaniel P. Berrangé g_autoptr(QCryptoIVGen) ivgen = NULL; 8493e308f20SDaniel P. Berrange size_t niv; 8503e308f20SDaniel P. Berrange 8513e308f20SDaniel P. Berrange if (slot->active != QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED) { 8523e308f20SDaniel P. Berrange return 0; 8533e308f20SDaniel P. Berrange } 8543e308f20SDaniel P. Berrange 8551ddd52e4SMaxim Levitsky splitkeylen = luks->header.master_key_len * slot->stripes; 8563e308f20SDaniel P. Berrange splitkey = g_new0(uint8_t, splitkeylen); 8571ddd52e4SMaxim Levitsky possiblekey = g_new0(uint8_t, luks->header.master_key_len); 8583e308f20SDaniel P. Berrange 8593e308f20SDaniel P. Berrange /* 8603e308f20SDaniel P. Berrange * The user password is used to generate a (possible) 8613e308f20SDaniel P. Berrange * decryption key. This may or may not successfully 8623e308f20SDaniel P. Berrange * decrypt the master key - we just blindly assume 8633e308f20SDaniel P. Berrange * the key is correct and validate the results of 8643e308f20SDaniel P. Berrange * decryption later. 8653e308f20SDaniel P. Berrange */ 8669d80e59dSMaxim Levitsky if (qcrypto_pbkdf2(luks->hash_alg, 8673e308f20SDaniel P. Berrange (const uint8_t *)password, strlen(password), 8683e308f20SDaniel P. Berrange slot->salt, QCRYPTO_BLOCK_LUKS_SALT_LEN, 8693e308f20SDaniel P. Berrange slot->iterations, 8701ddd52e4SMaxim Levitsky possiblekey, luks->header.master_key_len, 8713e308f20SDaniel P. Berrange errp) < 0) { 87257b9f113SDaniel P. Berrangé return -1; 8733e308f20SDaniel P. Berrange } 8743e308f20SDaniel P. Berrange 8753e308f20SDaniel P. Berrange /* 8763e308f20SDaniel P. Berrange * We need to read the master key material from the 8773e308f20SDaniel P. Berrange * LUKS key material header. What we're reading is 8783e308f20SDaniel P. Berrange * not the raw master key, but rather the data after 8793e308f20SDaniel P. Berrange * it has been passed through AFSplit and the result 8803e308f20SDaniel P. Berrange * then encrypted. 8813e308f20SDaniel P. Berrange */ 8823e308f20SDaniel P. Berrange rv = readfunc(block, 883f0d3c362SMaxim Levitsky slot->key_offset_sector * QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, 8843e308f20SDaniel P. Berrange splitkey, splitkeylen, 885e4a3507eSDaniel P. Berrange opaque, 88637509233SFam Zheng errp); 8873e308f20SDaniel P. Berrange if (rv < 0) { 88857b9f113SDaniel P. Berrangé return -1; 8893e308f20SDaniel P. Berrange } 8903e308f20SDaniel P. Berrange 8913e308f20SDaniel P. Berrange 8923e308f20SDaniel P. Berrange /* Setup the cipher/ivgen that we'll use to try to decrypt 8933e308f20SDaniel P. Berrange * the split master key material */ 8949d80e59dSMaxim Levitsky cipher = qcrypto_cipher_new(luks->cipher_alg, 8959d80e59dSMaxim Levitsky luks->cipher_mode, 8969d80e59dSMaxim Levitsky possiblekey, 8979d80e59dSMaxim Levitsky luks->header.master_key_len, 8983e308f20SDaniel P. Berrange errp); 8993e308f20SDaniel P. Berrange if (!cipher) { 90057b9f113SDaniel P. Berrangé return -1; 9013e308f20SDaniel P. Berrange } 9023e308f20SDaniel P. Berrange 9039d80e59dSMaxim Levitsky niv = qcrypto_cipher_get_iv_len(luks->cipher_alg, 9049d80e59dSMaxim Levitsky luks->cipher_mode); 9059d80e59dSMaxim Levitsky 9069d80e59dSMaxim Levitsky ivgen = qcrypto_ivgen_new(luks->ivgen_alg, 9079d80e59dSMaxim Levitsky luks->ivgen_cipher_alg, 9089d80e59dSMaxim Levitsky luks->ivgen_hash_alg, 9099d80e59dSMaxim Levitsky possiblekey, 9109d80e59dSMaxim Levitsky luks->header.master_key_len, 9113e308f20SDaniel P. Berrange errp); 9123e308f20SDaniel P. Berrange if (!ivgen) { 91357b9f113SDaniel P. Berrangé return -1; 9143e308f20SDaniel P. Berrange } 9153e308f20SDaniel P. Berrange 9163e308f20SDaniel P. Berrange 9173e308f20SDaniel P. Berrange /* 9183e308f20SDaniel P. Berrange * The master key needs to be decrypted in the same 9193e308f20SDaniel P. Berrange * way that the block device payload will be decrypted 9203e308f20SDaniel P. Berrange * later. In particular we'll be using the IV generator 9213e308f20SDaniel P. Berrange * to reset the encryption cipher every time the master 9223e308f20SDaniel P. Berrange * key crosses a sector boundary. 9233e308f20SDaniel P. Berrange */ 9240270417cSVladimir Sementsov-Ogievskiy if (qcrypto_block_cipher_decrypt_helper(cipher, 9253e308f20SDaniel P. Berrange niv, 9263e308f20SDaniel P. Berrange ivgen, 9273e308f20SDaniel P. Berrange QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, 9283e308f20SDaniel P. Berrange 0, 9293e308f20SDaniel P. Berrange splitkey, 9303e308f20SDaniel P. Berrange splitkeylen, 9313e308f20SDaniel P. Berrange errp) < 0) { 93257b9f113SDaniel P. Berrangé return -1; 9333e308f20SDaniel P. Berrange } 9343e308f20SDaniel P. Berrange 9353e308f20SDaniel P. Berrange /* 9363e308f20SDaniel P. Berrange * Now we've decrypted the split master key, join 9373e308f20SDaniel P. Berrange * it back together to get the actual master key. 9383e308f20SDaniel P. Berrange */ 9399d80e59dSMaxim Levitsky if (qcrypto_afsplit_decode(luks->hash_alg, 9401ddd52e4SMaxim Levitsky luks->header.master_key_len, 9413e308f20SDaniel P. Berrange slot->stripes, 9423e308f20SDaniel P. Berrange splitkey, 9433e308f20SDaniel P. Berrange masterkey, 9443e308f20SDaniel P. Berrange errp) < 0) { 94557b9f113SDaniel P. Berrangé return -1; 9463e308f20SDaniel P. Berrange } 9473e308f20SDaniel P. Berrange 9483e308f20SDaniel P. Berrange 9493e308f20SDaniel P. Berrange /* 9503e308f20SDaniel P. Berrange * We still don't know that the masterkey we got is valid, 9513e308f20SDaniel P. Berrange * because we just blindly assumed the user's password 9523e308f20SDaniel P. Berrange * was correct. This is where we now verify it. We are 9533e308f20SDaniel P. Berrange * creating a hash of the master key using PBKDF and 9543e308f20SDaniel P. Berrange * then comparing that to the hash stored in the key slot 9553e308f20SDaniel P. Berrange * header 9563e308f20SDaniel P. Berrange */ 9579d80e59dSMaxim Levitsky if (qcrypto_pbkdf2(luks->hash_alg, 9581ddd52e4SMaxim Levitsky masterkey, 9591ddd52e4SMaxim Levitsky luks->header.master_key_len, 9603e308f20SDaniel P. Berrange luks->header.master_key_salt, 9613e308f20SDaniel P. Berrange QCRYPTO_BLOCK_LUKS_SALT_LEN, 9623e308f20SDaniel P. Berrange luks->header.master_key_iterations, 9631ddd52e4SMaxim Levitsky keydigest, 9641ddd52e4SMaxim Levitsky G_N_ELEMENTS(keydigest), 9653e308f20SDaniel P. Berrange errp) < 0) { 96657b9f113SDaniel P. Berrangé return -1; 9673e308f20SDaniel P. Berrange } 9683e308f20SDaniel P. Berrange 9693e308f20SDaniel P. Berrange if (memcmp(keydigest, luks->header.master_key_digest, 9703e308f20SDaniel P. Berrange QCRYPTO_BLOCK_LUKS_DIGEST_LEN) == 0) { 9713e308f20SDaniel P. Berrange /* Success, we got the right master key */ 97257b9f113SDaniel P. Berrangé return 1; 9733e308f20SDaniel P. Berrange } 9743e308f20SDaniel P. Berrange 9753e308f20SDaniel P. Berrange /* Fail, user's password was not valid for this key slot, 9763e308f20SDaniel P. Berrange * tell caller to try another slot */ 97757b9f113SDaniel P. Berrangé return 0; 9783e308f20SDaniel P. Berrange } 9793e308f20SDaniel P. Berrange 9803e308f20SDaniel P. Berrange 9813e308f20SDaniel P. Berrange /* 9823e308f20SDaniel P. Berrange * Given a user password, this will iterate over all key 9833e308f20SDaniel P. Berrange * slots and try to unlock each active key slot using the 9843e308f20SDaniel P. Berrange * password until it successfully obtains a master key. 9853e308f20SDaniel P. Berrange * 9863e308f20SDaniel P. Berrange * Returns 0 if a key was loaded, -1 if no keys could be loaded 9873e308f20SDaniel P. Berrange */ 9883e308f20SDaniel P. Berrange static int 9893e308f20SDaniel P. Berrange qcrypto_block_luks_find_key(QCryptoBlock *block, 9903e308f20SDaniel P. Berrange const char *password, 9911ddd52e4SMaxim Levitsky uint8_t *masterkey, 9923e308f20SDaniel P. Berrange QCryptoBlockReadFunc readfunc, 9933e308f20SDaniel P. Berrange void *opaque, 9943e308f20SDaniel P. Berrange Error **errp) 9953e308f20SDaniel P. Berrange { 9963e308f20SDaniel P. Berrange size_t i; 9973e308f20SDaniel P. Berrange int rv; 9983e308f20SDaniel P. Berrange 9993e308f20SDaniel P. Berrange for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) { 10003e308f20SDaniel P. Berrange rv = qcrypto_block_luks_load_key(block, 10017e60a6f5SMaxim Levitsky i, 10023e308f20SDaniel P. Berrange password, 10031ddd52e4SMaxim Levitsky masterkey, 10043e308f20SDaniel P. Berrange readfunc, 10053e308f20SDaniel P. Berrange opaque, 10063e308f20SDaniel P. Berrange errp); 10073e308f20SDaniel P. Berrange if (rv < 0) { 10083e308f20SDaniel P. Berrange goto error; 10093e308f20SDaniel P. Berrange } 10103e308f20SDaniel P. Berrange if (rv == 1) { 10113e308f20SDaniel P. Berrange return 0; 10123e308f20SDaniel P. Berrange } 10133e308f20SDaniel P. Berrange } 10143e308f20SDaniel P. Berrange 10153e308f20SDaniel P. Berrange error_setg(errp, "Invalid password, cannot unlock any keyslot"); 10163e308f20SDaniel P. Berrange error: 10173e308f20SDaniel P. Berrange return -1; 10183e308f20SDaniel P. Berrange } 10193e308f20SDaniel P. Berrange 10203e308f20SDaniel P. Berrange 10213e308f20SDaniel P. Berrange static int 10223e308f20SDaniel P. Berrange qcrypto_block_luks_open(QCryptoBlock *block, 10233e308f20SDaniel P. Berrange QCryptoBlockOpenOptions *options, 10241cd9a787SDaniel P. Berrange const char *optprefix, 10253e308f20SDaniel P. Berrange QCryptoBlockReadFunc readfunc, 10263e308f20SDaniel P. Berrange void *opaque, 10273e308f20SDaniel P. Berrange unsigned int flags, 1028c972fa12SVladimir Sementsov-Ogievskiy size_t n_threads, 10293e308f20SDaniel P. Berrange Error **errp) 10303e308f20SDaniel P. Berrange { 10319d80e59dSMaxim Levitsky QCryptoBlockLUKS *luks = NULL; 103257b9f113SDaniel P. Berrangé g_autofree uint8_t *masterkey = NULL; 103357b9f113SDaniel P. Berrangé g_autofree char *password = NULL; 10343e308f20SDaniel P. Berrange 10353e308f20SDaniel P. Berrange if (!(flags & QCRYPTO_BLOCK_OPEN_NO_IO)) { 10363e308f20SDaniel P. Berrange if (!options->u.luks.key_secret) { 10371cd9a787SDaniel P. Berrange error_setg(errp, "Parameter '%skey-secret' is required for cipher", 10381cd9a787SDaniel P. Berrange optprefix ? optprefix : ""); 10393e308f20SDaniel P. Berrange return -1; 10403e308f20SDaniel P. Berrange } 10413e308f20SDaniel P. Berrange password = qcrypto_secret_lookup_as_utf8( 10423e308f20SDaniel P. Berrange options->u.luks.key_secret, errp); 10433e308f20SDaniel P. Berrange if (!password) { 10443e308f20SDaniel P. Berrange return -1; 10453e308f20SDaniel P. Berrange } 10463e308f20SDaniel P. Berrange } 10473e308f20SDaniel P. Berrange 10483e308f20SDaniel P. Berrange luks = g_new0(QCryptoBlockLUKS, 1); 10493e308f20SDaniel P. Berrange block->opaque = luks; 10503e308f20SDaniel P. Berrange 1051dde2c5afSMaxim Levitsky if (qcrypto_block_luks_load_header(block, readfunc, opaque, errp) < 0) { 10523e308f20SDaniel P. Berrange goto fail; 10533e308f20SDaniel P. Berrange } 10543e308f20SDaniel P. Berrange 10559fa9c1c2SMaxim Levitsky if (qcrypto_block_luks_check_header(luks, errp) < 0) { 10563e308f20SDaniel P. Berrange goto fail; 10573e308f20SDaniel P. Berrange } 10583e308f20SDaniel P. Berrange 10599fa9c1c2SMaxim Levitsky if (qcrypto_block_luks_parse_header(luks, errp) < 0) { 10603e308f20SDaniel P. Berrange goto fail; 10613e308f20SDaniel P. Berrange } 10623e308f20SDaniel P. Berrange 10633e308f20SDaniel P. Berrange if (!(flags & QCRYPTO_BLOCK_OPEN_NO_IO)) { 10643e308f20SDaniel P. Berrange /* Try to find which key slot our password is valid for 10653e308f20SDaniel P. Berrange * and unlock the master key from that slot. 10663e308f20SDaniel P. Berrange */ 10671ddd52e4SMaxim Levitsky 10681ddd52e4SMaxim Levitsky masterkey = g_new0(uint8_t, luks->header.master_key_len); 10691ddd52e4SMaxim Levitsky 10703e308f20SDaniel P. Berrange if (qcrypto_block_luks_find_key(block, 10713e308f20SDaniel P. Berrange password, 10721ddd52e4SMaxim Levitsky masterkey, 10733e308f20SDaniel P. Berrange readfunc, opaque, 10743e308f20SDaniel P. Berrange errp) < 0) { 10753e308f20SDaniel P. Berrange goto fail; 10763e308f20SDaniel P. Berrange } 10773e308f20SDaniel P. Berrange 10783e308f20SDaniel P. Berrange /* We have a valid master key now, so can setup the 10793e308f20SDaniel P. Berrange * block device payload decryption objects 10803e308f20SDaniel P. Berrange */ 10819d80e59dSMaxim Levitsky block->kdfhash = luks->hash_alg; 10829d80e59dSMaxim Levitsky block->niv = qcrypto_cipher_get_iv_len(luks->cipher_alg, 10839d80e59dSMaxim Levitsky luks->cipher_mode); 10849d80e59dSMaxim Levitsky 10859d80e59dSMaxim Levitsky block->ivgen = qcrypto_ivgen_new(luks->ivgen_alg, 10869d80e59dSMaxim Levitsky luks->ivgen_cipher_alg, 10879d80e59dSMaxim Levitsky luks->ivgen_hash_alg, 10881ddd52e4SMaxim Levitsky masterkey, 10891ddd52e4SMaxim Levitsky luks->header.master_key_len, 10903e308f20SDaniel P. Berrange errp); 10913e308f20SDaniel P. Berrange if (!block->ivgen) { 10923e308f20SDaniel P. Berrange goto fail; 10933e308f20SDaniel P. Berrange } 10943e308f20SDaniel P. Berrange 109561dd8a9aSMaxim Levitsky if (qcrypto_block_init_cipher(block, 10969d80e59dSMaxim Levitsky luks->cipher_alg, 10979d80e59dSMaxim Levitsky luks->cipher_mode, 10981ddd52e4SMaxim Levitsky masterkey, 10991ddd52e4SMaxim Levitsky luks->header.master_key_len, 11001ddd52e4SMaxim Levitsky n_threads, 110161dd8a9aSMaxim Levitsky errp) < 0) { 11023e308f20SDaniel P. Berrange goto fail; 11033e308f20SDaniel P. Berrange } 11043e308f20SDaniel P. Berrange } 11053e308f20SDaniel P. Berrange 1106850f49deSDaniel P. Berrange block->sector_size = QCRYPTO_BLOCK_LUKS_SECTOR_SIZE; 1107f0d3c362SMaxim Levitsky block->payload_offset = luks->header.payload_offset_sector * 1108850f49deSDaniel P. Berrange block->sector_size; 11093e308f20SDaniel P. Berrange 11103e308f20SDaniel P. Berrange return 0; 11113e308f20SDaniel P. Berrange 11123e308f20SDaniel P. Berrange fail: 1113c972fa12SVladimir Sementsov-Ogievskiy qcrypto_block_free_cipher(block); 11143e308f20SDaniel P. Berrange qcrypto_ivgen_free(block->ivgen); 11153e308f20SDaniel P. Berrange g_free(luks); 111661dd8a9aSMaxim Levitsky return -1; 11173e308f20SDaniel P. Berrange } 11183e308f20SDaniel P. Berrange 11193e308f20SDaniel P. Berrange 11202ef950f9SFam Zheng static void 11212ef950f9SFam Zheng qcrypto_block_luks_uuid_gen(uint8_t *uuidstr) 11223e308f20SDaniel P. Berrange { 11232ef950f9SFam Zheng QemuUUID uuid; 11242ef950f9SFam Zheng qemu_uuid_generate(&uuid); 11252ef950f9SFam Zheng qemu_uuid_unparse(&uuid, (char *)uuidstr); 11263e308f20SDaniel P. Berrange } 11273e308f20SDaniel P. Berrange 11283e308f20SDaniel P. Berrange static int 11293e308f20SDaniel P. Berrange qcrypto_block_luks_create(QCryptoBlock *block, 11303e308f20SDaniel P. Berrange QCryptoBlockCreateOptions *options, 11311cd9a787SDaniel P. Berrange const char *optprefix, 11323e308f20SDaniel P. Berrange QCryptoBlockInitFunc initfunc, 11333e308f20SDaniel P. Berrange QCryptoBlockWriteFunc writefunc, 11343e308f20SDaniel P. Berrange void *opaque, 11353e308f20SDaniel P. Berrange Error **errp) 11363e308f20SDaniel P. Berrange { 11373e308f20SDaniel P. Berrange QCryptoBlockLUKS *luks; 11383e308f20SDaniel P. Berrange QCryptoBlockCreateOptionsLUKS luks_opts; 11393e308f20SDaniel P. Berrange Error *local_err = NULL; 114057b9f113SDaniel P. Berrangé g_autofree uint8_t *masterkey = NULL; 1141*bd56a55aSMaxim Levitsky size_t header_sectors; 1142*bd56a55aSMaxim Levitsky size_t split_key_sectors; 11433e308f20SDaniel P. Berrange size_t i; 114457b9f113SDaniel P. Berrangé g_autofree char *password = NULL; 11453e308f20SDaniel P. Berrange const char *cipher_alg; 11463e308f20SDaniel P. Berrange const char *cipher_mode; 11473e308f20SDaniel P. Berrange const char *ivgen_alg; 11483e308f20SDaniel P. Berrange const char *ivgen_hash_alg = NULL; 11493e308f20SDaniel P. Berrange const char *hash_alg; 115057b9f113SDaniel P. Berrangé g_autofree char *cipher_mode_spec = NULL; 115159b060beSDaniel P. Berrange uint64_t iters; 11523e308f20SDaniel P. Berrange 11533e308f20SDaniel P. Berrange memcpy(&luks_opts, &options->u.luks, sizeof(luks_opts)); 11543bd18890SDaniel P. Berrange if (!luks_opts.has_iter_time) { 11552ab66cd5SDaniel P. Berrange luks_opts.iter_time = 2000; 11563bd18890SDaniel P. Berrange } 11573e308f20SDaniel P. Berrange if (!luks_opts.has_cipher_alg) { 11583e308f20SDaniel P. Berrange luks_opts.cipher_alg = QCRYPTO_CIPHER_ALG_AES_256; 11593e308f20SDaniel P. Berrange } 11603e308f20SDaniel P. Berrange if (!luks_opts.has_cipher_mode) { 11613e308f20SDaniel P. Berrange luks_opts.cipher_mode = QCRYPTO_CIPHER_MODE_XTS; 11623e308f20SDaniel P. Berrange } 11633e308f20SDaniel P. Berrange if (!luks_opts.has_ivgen_alg) { 11643e308f20SDaniel P. Berrange luks_opts.ivgen_alg = QCRYPTO_IVGEN_ALG_PLAIN64; 11653e308f20SDaniel P. Berrange } 11663e308f20SDaniel P. Berrange if (!luks_opts.has_hash_alg) { 11673e308f20SDaniel P. Berrange luks_opts.hash_alg = QCRYPTO_HASH_ALG_SHA256; 11683e308f20SDaniel P. Berrange } 11698b7cdba3SDaniel P. Berrange if (luks_opts.ivgen_alg == QCRYPTO_IVGEN_ALG_ESSIV) { 11708b7cdba3SDaniel P. Berrange if (!luks_opts.has_ivgen_hash_alg) { 11718b7cdba3SDaniel P. Berrange luks_opts.ivgen_hash_alg = QCRYPTO_HASH_ALG_SHA256; 11728b7cdba3SDaniel P. Berrange luks_opts.has_ivgen_hash_alg = true; 11738b7cdba3SDaniel P. Berrange } 11748b7cdba3SDaniel P. Berrange } 11759d80e59dSMaxim Levitsky 11769d80e59dSMaxim Levitsky luks = g_new0(QCryptoBlockLUKS, 1); 11779d80e59dSMaxim Levitsky block->opaque = luks; 11789d80e59dSMaxim Levitsky 11799d80e59dSMaxim Levitsky luks->cipher_alg = luks_opts.cipher_alg; 11809d80e59dSMaxim Levitsky luks->cipher_mode = luks_opts.cipher_mode; 11819d80e59dSMaxim Levitsky luks->ivgen_alg = luks_opts.ivgen_alg; 11829d80e59dSMaxim Levitsky luks->ivgen_hash_alg = luks_opts.ivgen_hash_alg; 11839d80e59dSMaxim Levitsky luks->hash_alg = luks_opts.hash_alg; 11849d80e59dSMaxim Levitsky 11859d80e59dSMaxim Levitsky 11868b7cdba3SDaniel P. Berrange /* Note we're allowing ivgen_hash_alg to be set even for 11878b7cdba3SDaniel P. Berrange * non-essiv iv generators that don't need a hash. It will 11888b7cdba3SDaniel P. Berrange * be silently ignored, for compatibility with dm-crypt */ 11893e308f20SDaniel P. Berrange 11903e308f20SDaniel P. Berrange if (!options->u.luks.key_secret) { 11911cd9a787SDaniel P. Berrange error_setg(errp, "Parameter '%skey-secret' is required for cipher", 11921cd9a787SDaniel P. Berrange optprefix ? optprefix : ""); 11939d80e59dSMaxim Levitsky goto error; 11943e308f20SDaniel P. Berrange } 11953e308f20SDaniel P. Berrange password = qcrypto_secret_lookup_as_utf8(luks_opts.key_secret, errp); 11963e308f20SDaniel P. Berrange if (!password) { 11979d80e59dSMaxim Levitsky goto error; 11983e308f20SDaniel P. Berrange } 11993e308f20SDaniel P. Berrange 12003e308f20SDaniel P. Berrange 12013e308f20SDaniel P. Berrange memcpy(luks->header.magic, qcrypto_block_luks_magic, 12023e308f20SDaniel P. Berrange QCRYPTO_BLOCK_LUKS_MAGIC_LEN); 12033e308f20SDaniel P. Berrange 12043e308f20SDaniel P. Berrange /* We populate the header in native endianness initially and 12053e308f20SDaniel P. Berrange * then convert everything to big endian just before writing 12063e308f20SDaniel P. Berrange * it out to disk 12073e308f20SDaniel P. Berrange */ 12083e308f20SDaniel P. Berrange luks->header.version = QCRYPTO_BLOCK_LUKS_VERSION; 12092ef950f9SFam Zheng qcrypto_block_luks_uuid_gen(luks->header.uuid); 12103e308f20SDaniel P. Berrange 12113e308f20SDaniel P. Berrange cipher_alg = qcrypto_block_luks_cipher_alg_lookup(luks_opts.cipher_alg, 12123e308f20SDaniel P. Berrange errp); 12133e308f20SDaniel P. Berrange if (!cipher_alg) { 12143e308f20SDaniel P. Berrange goto error; 12153e308f20SDaniel P. Berrange } 12163e308f20SDaniel P. Berrange 1217977c736fSMarkus Armbruster cipher_mode = QCryptoCipherMode_str(luks_opts.cipher_mode); 1218977c736fSMarkus Armbruster ivgen_alg = QCryptoIVGenAlgorithm_str(luks_opts.ivgen_alg); 12193e308f20SDaniel P. Berrange if (luks_opts.has_ivgen_hash_alg) { 1220977c736fSMarkus Armbruster ivgen_hash_alg = QCryptoHashAlgorithm_str(luks_opts.ivgen_hash_alg); 12213e308f20SDaniel P. Berrange cipher_mode_spec = g_strdup_printf("%s-%s:%s", cipher_mode, ivgen_alg, 12223e308f20SDaniel P. Berrange ivgen_hash_alg); 12233e308f20SDaniel P. Berrange } else { 12243e308f20SDaniel P. Berrange cipher_mode_spec = g_strdup_printf("%s-%s", cipher_mode, ivgen_alg); 12253e308f20SDaniel P. Berrange } 1226977c736fSMarkus Armbruster hash_alg = QCryptoHashAlgorithm_str(luks_opts.hash_alg); 12273e308f20SDaniel P. Berrange 12283e308f20SDaniel P. Berrange 12293e308f20SDaniel P. Berrange if (strlen(cipher_alg) >= QCRYPTO_BLOCK_LUKS_CIPHER_NAME_LEN) { 12303e308f20SDaniel P. Berrange error_setg(errp, "Cipher name '%s' is too long for LUKS header", 12313e308f20SDaniel P. Berrange cipher_alg); 12323e308f20SDaniel P. Berrange goto error; 12333e308f20SDaniel P. Berrange } 12343e308f20SDaniel P. Berrange if (strlen(cipher_mode_spec) >= QCRYPTO_BLOCK_LUKS_CIPHER_MODE_LEN) { 12353e308f20SDaniel P. Berrange error_setg(errp, "Cipher mode '%s' is too long for LUKS header", 12363e308f20SDaniel P. Berrange cipher_mode_spec); 12373e308f20SDaniel P. Berrange goto error; 12383e308f20SDaniel P. Berrange } 12393e308f20SDaniel P. Berrange if (strlen(hash_alg) >= QCRYPTO_BLOCK_LUKS_HASH_SPEC_LEN) { 12403e308f20SDaniel P. Berrange error_setg(errp, "Hash name '%s' is too long for LUKS header", 12413e308f20SDaniel P. Berrange hash_alg); 12423e308f20SDaniel P. Berrange goto error; 12433e308f20SDaniel P. Berrange } 12443e308f20SDaniel P. Berrange 12453e308f20SDaniel P. Berrange if (luks_opts.ivgen_alg == QCRYPTO_IVGEN_ALG_ESSIV) { 12469d80e59dSMaxim Levitsky luks->ivgen_cipher_alg = 12479d80e59dSMaxim Levitsky qcrypto_block_luks_essiv_cipher(luks_opts.cipher_alg, 12483e308f20SDaniel P. Berrange luks_opts.ivgen_hash_alg, 12493e308f20SDaniel P. Berrange &local_err); 12503e308f20SDaniel P. Berrange if (local_err) { 12513e308f20SDaniel P. Berrange error_propagate(errp, local_err); 12523e308f20SDaniel P. Berrange goto error; 12533e308f20SDaniel P. Berrange } 12543e308f20SDaniel P. Berrange } else { 12559d80e59dSMaxim Levitsky luks->ivgen_cipher_alg = luks_opts.cipher_alg; 12563e308f20SDaniel P. Berrange } 12573e308f20SDaniel P. Berrange 12583e308f20SDaniel P. Berrange strcpy(luks->header.cipher_name, cipher_alg); 12593e308f20SDaniel P. Berrange strcpy(luks->header.cipher_mode, cipher_mode_spec); 12603e308f20SDaniel P. Berrange strcpy(luks->header.hash_spec, hash_alg); 12613e308f20SDaniel P. Berrange 1262f0d3c362SMaxim Levitsky luks->header.master_key_len = 1263f0d3c362SMaxim Levitsky qcrypto_cipher_get_key_len(luks_opts.cipher_alg); 1264f0d3c362SMaxim Levitsky 12653e308f20SDaniel P. Berrange if (luks_opts.cipher_mode == QCRYPTO_CIPHER_MODE_XTS) { 1266f0d3c362SMaxim Levitsky luks->header.master_key_len *= 2; 12673e308f20SDaniel P. Berrange } 12683e308f20SDaniel P. Berrange 12693e308f20SDaniel P. Berrange /* Generate the salt used for hashing the master key 12703e308f20SDaniel P. Berrange * with PBKDF later 12713e308f20SDaniel P. Berrange */ 12723e308f20SDaniel P. Berrange if (qcrypto_random_bytes(luks->header.master_key_salt, 12733e308f20SDaniel P. Berrange QCRYPTO_BLOCK_LUKS_SALT_LEN, 12743e308f20SDaniel P. Berrange errp) < 0) { 12753e308f20SDaniel P. Berrange goto error; 12763e308f20SDaniel P. Berrange } 12773e308f20SDaniel P. Berrange 12783e308f20SDaniel P. Berrange /* Generate random master key */ 1279f0d3c362SMaxim Levitsky masterkey = g_new0(uint8_t, luks->header.master_key_len); 12803e308f20SDaniel P. Berrange if (qcrypto_random_bytes(masterkey, 1281f0d3c362SMaxim Levitsky luks->header.master_key_len, errp) < 0) { 12823e308f20SDaniel P. Berrange goto error; 12833e308f20SDaniel P. Berrange } 12843e308f20SDaniel P. Berrange 12853e308f20SDaniel P. Berrange 12863e308f20SDaniel P. Berrange /* Setup the block device payload encryption objects */ 1287c972fa12SVladimir Sementsov-Ogievskiy if (qcrypto_block_init_cipher(block, luks_opts.cipher_alg, 1288c972fa12SVladimir Sementsov-Ogievskiy luks_opts.cipher_mode, masterkey, 1289f0d3c362SMaxim Levitsky luks->header.master_key_len, 1, errp) < 0) { 12903e308f20SDaniel P. Berrange goto error; 12913e308f20SDaniel P. Berrange } 12923e308f20SDaniel P. Berrange 12933e308f20SDaniel P. Berrange block->kdfhash = luks_opts.hash_alg; 12943e308f20SDaniel P. Berrange block->niv = qcrypto_cipher_get_iv_len(luks_opts.cipher_alg, 12953e308f20SDaniel P. Berrange luks_opts.cipher_mode); 12963e308f20SDaniel P. Berrange block->ivgen = qcrypto_ivgen_new(luks_opts.ivgen_alg, 12979d80e59dSMaxim Levitsky luks->ivgen_cipher_alg, 12983e308f20SDaniel P. Berrange luks_opts.ivgen_hash_alg, 1299f0d3c362SMaxim Levitsky masterkey, luks->header.master_key_len, 13003e308f20SDaniel P. Berrange errp); 13013e308f20SDaniel P. Berrange 13023e308f20SDaniel P. Berrange if (!block->ivgen) { 13033e308f20SDaniel P. Berrange goto error; 13043e308f20SDaniel P. Berrange } 13053e308f20SDaniel P. Berrange 13063e308f20SDaniel P. Berrange 13073e308f20SDaniel P. Berrange /* Determine how many iterations we need to hash the master 13083e308f20SDaniel P. Berrange * key, in order to have 1 second of compute time used 13093e308f20SDaniel P. Berrange */ 131059b060beSDaniel P. Berrange iters = qcrypto_pbkdf2_count_iters(luks_opts.hash_alg, 1311f0d3c362SMaxim Levitsky masterkey, luks->header.master_key_len, 13123e308f20SDaniel P. Berrange luks->header.master_key_salt, 13133e308f20SDaniel P. Berrange QCRYPTO_BLOCK_LUKS_SALT_LEN, 1314e74aabcfSDaniel P. Berrange QCRYPTO_BLOCK_LUKS_DIGEST_LEN, 13153e308f20SDaniel P. Berrange &local_err); 13163e308f20SDaniel P. Berrange if (local_err) { 13173e308f20SDaniel P. Berrange error_propagate(errp, local_err); 13183e308f20SDaniel P. Berrange goto error; 13193e308f20SDaniel P. Berrange } 13203e308f20SDaniel P. Berrange 13213bd18890SDaniel P. Berrange if (iters > (ULLONG_MAX / luks_opts.iter_time)) { 13223bd18890SDaniel P. Berrange error_setg_errno(errp, ERANGE, 13233bd18890SDaniel P. Berrange "PBKDF iterations %llu too large to scale", 13243bd18890SDaniel P. Berrange (unsigned long long)iters); 13253bd18890SDaniel P. Berrange goto error; 13263bd18890SDaniel P. Berrange } 13273bd18890SDaniel P. Berrange 13283bd18890SDaniel P. Berrange /* iter_time was in millis, but count_iters reported for secs */ 13293bd18890SDaniel P. Berrange iters = iters * luks_opts.iter_time / 1000; 13303bd18890SDaniel P. Berrange 13313e308f20SDaniel P. Berrange /* Why /= 8 ? That matches cryptsetup, but there's no 13323e308f20SDaniel P. Berrange * explanation why they chose /= 8... Probably so that 13333e308f20SDaniel P. Berrange * if all 8 keyslots are active we only spend 1 second 13343e308f20SDaniel P. Berrange * in total time to check all keys */ 133559b060beSDaniel P. Berrange iters /= 8; 133659b060beSDaniel P. Berrange if (iters > UINT32_MAX) { 133759b060beSDaniel P. Berrange error_setg_errno(errp, ERANGE, 133859b060beSDaniel P. Berrange "PBKDF iterations %llu larger than %u", 133959b060beSDaniel P. Berrange (unsigned long long)iters, UINT32_MAX); 134059b060beSDaniel P. Berrange goto error; 134159b060beSDaniel P. Berrange } 134259b060beSDaniel P. Berrange iters = MAX(iters, QCRYPTO_BLOCK_LUKS_MIN_MASTER_KEY_ITERS); 134359b060beSDaniel P. Berrange luks->header.master_key_iterations = iters; 13443e308f20SDaniel P. Berrange 13453e308f20SDaniel P. Berrange /* Hash the master key, saving the result in the LUKS 13463e308f20SDaniel P. Berrange * header. This hash is used when opening the encrypted 13473e308f20SDaniel P. Berrange * device to verify that the user password unlocked a 13483e308f20SDaniel P. Berrange * valid master key 13493e308f20SDaniel P. Berrange */ 13503e308f20SDaniel P. Berrange if (qcrypto_pbkdf2(luks_opts.hash_alg, 1351f0d3c362SMaxim Levitsky masterkey, luks->header.master_key_len, 13523e308f20SDaniel P. Berrange luks->header.master_key_salt, 13533e308f20SDaniel P. Berrange QCRYPTO_BLOCK_LUKS_SALT_LEN, 13543e308f20SDaniel P. Berrange luks->header.master_key_iterations, 13553e308f20SDaniel P. Berrange luks->header.master_key_digest, 13563e308f20SDaniel P. Berrange QCRYPTO_BLOCK_LUKS_DIGEST_LEN, 13573e308f20SDaniel P. Berrange errp) < 0) { 13583e308f20SDaniel P. Berrange goto error; 13593e308f20SDaniel P. Berrange } 13603e308f20SDaniel P. Berrange 1361*bd56a55aSMaxim Levitsky /* start with the sector that follows the header*/ 1362*bd56a55aSMaxim Levitsky header_sectors = QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET / 1363*bd56a55aSMaxim Levitsky QCRYPTO_BLOCK_LUKS_SECTOR_SIZE; 13643e308f20SDaniel P. Berrange 1365*bd56a55aSMaxim Levitsky split_key_sectors = 1366*bd56a55aSMaxim Levitsky qcrypto_block_luks_splitkeylen_sectors(luks, 1367*bd56a55aSMaxim Levitsky header_sectors, 1368*bd56a55aSMaxim Levitsky QCRYPTO_BLOCK_LUKS_STRIPES); 1369*bd56a55aSMaxim Levitsky 13703e308f20SDaniel P. Berrange for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) { 1371*bd56a55aSMaxim Levitsky QCryptoBlockLUKSKeySlot *slot = &luks->header.key_slots[i]; 1372*bd56a55aSMaxim Levitsky slot->active = QCRYPTO_BLOCK_LUKS_KEY_SLOT_DISABLED; 13733e308f20SDaniel P. Berrange 1374*bd56a55aSMaxim Levitsky slot->key_offset_sector = header_sectors + i * split_key_sectors; 1375*bd56a55aSMaxim Levitsky slot->stripes = QCRYPTO_BLOCK_LUKS_STRIPES; 13763e308f20SDaniel P. Berrange } 13773e308f20SDaniel P. Berrange 13783e308f20SDaniel P. Berrange /* The total size of the LUKS headers is the partition header + key 13793e308f20SDaniel P. Berrange * slot headers, rounded up to the nearest sector, combined with 13803e308f20SDaniel P. Berrange * the size of each master key material region, also rounded up 13813e308f20SDaniel P. Berrange * to the nearest sector */ 1382*bd56a55aSMaxim Levitsky luks->header.payload_offset_sector = header_sectors + 1383*bd56a55aSMaxim Levitsky QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS * split_key_sectors; 13843e308f20SDaniel P. Berrange 1385850f49deSDaniel P. Berrange block->sector_size = QCRYPTO_BLOCK_LUKS_SECTOR_SIZE; 1386f0d3c362SMaxim Levitsky block->payload_offset = luks->header.payload_offset_sector * 1387850f49deSDaniel P. Berrange block->sector_size; 13883e308f20SDaniel P. Berrange 13893e308f20SDaniel P. Berrange /* Reserve header space to match payload offset */ 1390e4a3507eSDaniel P. Berrange initfunc(block, block->payload_offset, opaque, &local_err); 13913e308f20SDaniel P. Berrange if (local_err) { 13923e308f20SDaniel P. Berrange error_propagate(errp, local_err); 13933e308f20SDaniel P. Berrange goto error; 13943e308f20SDaniel P. Berrange } 13953e308f20SDaniel P. Berrange 13963e308f20SDaniel P. Berrange 13973994a7c9SMaxim Levitsky /* populate the slot 0 with the password encrypted master key*/ 13983994a7c9SMaxim Levitsky /* This will also store the header */ 13993994a7c9SMaxim Levitsky if (qcrypto_block_luks_store_key(block, 14003994a7c9SMaxim Levitsky 0, 14013994a7c9SMaxim Levitsky password, 14023994a7c9SMaxim Levitsky masterkey, 14033994a7c9SMaxim Levitsky luks_opts.iter_time, 14043994a7c9SMaxim Levitsky writefunc, 1405e4a3507eSDaniel P. Berrange opaque, 14063994a7c9SMaxim Levitsky errp) < 0) { 14073e308f20SDaniel P. Berrange goto error; 14083e308f20SDaniel P. Berrange } 14093e308f20SDaniel P. Berrange 1410f0d3c362SMaxim Levitsky memset(masterkey, 0, luks->header.master_key_len); 14113e308f20SDaniel P. Berrange 14123e308f20SDaniel P. Berrange return 0; 14133e308f20SDaniel P. Berrange 14143e308f20SDaniel P. Berrange error: 14153e308f20SDaniel P. Berrange if (masterkey) { 1416f0d3c362SMaxim Levitsky memset(masterkey, 0, luks->header.master_key_len); 14173e308f20SDaniel P. Berrange } 14183e308f20SDaniel P. Berrange 1419c972fa12SVladimir Sementsov-Ogievskiy qcrypto_block_free_cipher(block); 1420b640adcaSVladimir Sementsov-Ogievskiy qcrypto_ivgen_free(block->ivgen); 1421b640adcaSVladimir Sementsov-Ogievskiy 14223e308f20SDaniel P. Berrange g_free(luks); 14233e308f20SDaniel P. Berrange return -1; 14243e308f20SDaniel P. Berrange } 14253e308f20SDaniel P. Berrange 14263e308f20SDaniel P. Berrange 142740c85028SDaniel P. Berrange static int qcrypto_block_luks_get_info(QCryptoBlock *block, 142840c85028SDaniel P. Berrange QCryptoBlockInfo *info, 142940c85028SDaniel P. Berrange Error **errp) 143040c85028SDaniel P. Berrange { 143140c85028SDaniel P. Berrange QCryptoBlockLUKS *luks = block->opaque; 143240c85028SDaniel P. Berrange QCryptoBlockInfoLUKSSlot *slot; 143340c85028SDaniel P. Berrange QCryptoBlockInfoLUKSSlotList *slots = NULL, **prev = &info->u.luks.slots; 143440c85028SDaniel P. Berrange size_t i; 143540c85028SDaniel P. Berrange 143640c85028SDaniel P. Berrange info->u.luks.cipher_alg = luks->cipher_alg; 143740c85028SDaniel P. Berrange info->u.luks.cipher_mode = luks->cipher_mode; 143840c85028SDaniel P. Berrange info->u.luks.ivgen_alg = luks->ivgen_alg; 143940c85028SDaniel P. Berrange if (info->u.luks.ivgen_alg == QCRYPTO_IVGEN_ALG_ESSIV) { 144040c85028SDaniel P. Berrange info->u.luks.has_ivgen_hash_alg = true; 144140c85028SDaniel P. Berrange info->u.luks.ivgen_hash_alg = luks->ivgen_hash_alg; 144240c85028SDaniel P. Berrange } 144340c85028SDaniel P. Berrange info->u.luks.hash_alg = luks->hash_alg; 144440c85028SDaniel P. Berrange info->u.luks.payload_offset = block->payload_offset; 144540c85028SDaniel P. Berrange info->u.luks.master_key_iters = luks->header.master_key_iterations; 144640c85028SDaniel P. Berrange info->u.luks.uuid = g_strndup((const char *)luks->header.uuid, 144740c85028SDaniel P. Berrange sizeof(luks->header.uuid)); 144840c85028SDaniel P. Berrange 144940c85028SDaniel P. Berrange for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) { 145040c85028SDaniel P. Berrange slots = g_new0(QCryptoBlockInfoLUKSSlotList, 1); 145140c85028SDaniel P. Berrange *prev = slots; 145240c85028SDaniel P. Berrange 145340c85028SDaniel P. Berrange slots->value = slot = g_new0(QCryptoBlockInfoLUKSSlot, 1); 145440c85028SDaniel P. Berrange slot->active = luks->header.key_slots[i].active == 145540c85028SDaniel P. Berrange QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED; 1456f0d3c362SMaxim Levitsky slot->key_offset = luks->header.key_slots[i].key_offset_sector 145740c85028SDaniel P. Berrange * QCRYPTO_BLOCK_LUKS_SECTOR_SIZE; 145840c85028SDaniel P. Berrange if (slot->active) { 145940c85028SDaniel P. Berrange slot->has_iters = true; 146040c85028SDaniel P. Berrange slot->iters = luks->header.key_slots[i].iterations; 146140c85028SDaniel P. Berrange slot->has_stripes = true; 146240c85028SDaniel P. Berrange slot->stripes = luks->header.key_slots[i].stripes; 146340c85028SDaniel P. Berrange } 146440c85028SDaniel P. Berrange 146540c85028SDaniel P. Berrange prev = &slots->next; 146640c85028SDaniel P. Berrange } 146740c85028SDaniel P. Berrange 146840c85028SDaniel P. Berrange return 0; 146940c85028SDaniel P. Berrange } 147040c85028SDaniel P. Berrange 147140c85028SDaniel P. Berrange 14723e308f20SDaniel P. Berrange static void qcrypto_block_luks_cleanup(QCryptoBlock *block) 14733e308f20SDaniel P. Berrange { 14743e308f20SDaniel P. Berrange g_free(block->opaque); 14753e308f20SDaniel P. Berrange } 14763e308f20SDaniel P. Berrange 14773e308f20SDaniel P. Berrange 14783e308f20SDaniel P. Berrange static int 14793e308f20SDaniel P. Berrange qcrypto_block_luks_decrypt(QCryptoBlock *block, 14804609742aSDaniel P. Berrange uint64_t offset, 14813e308f20SDaniel P. Berrange uint8_t *buf, 14823e308f20SDaniel P. Berrange size_t len, 14833e308f20SDaniel P. Berrange Error **errp) 14843e308f20SDaniel P. Berrange { 14854609742aSDaniel P. Berrange assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); 14864609742aSDaniel P. Berrange assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); 14870f0d596cSVladimir Sementsov-Ogievskiy return qcrypto_block_decrypt_helper(block, 14883e308f20SDaniel P. Berrange QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, 14894609742aSDaniel P. Berrange offset, buf, len, errp); 14903e308f20SDaniel P. Berrange } 14913e308f20SDaniel P. Berrange 14923e308f20SDaniel P. Berrange 14933e308f20SDaniel P. Berrange static int 14943e308f20SDaniel P. Berrange qcrypto_block_luks_encrypt(QCryptoBlock *block, 14954609742aSDaniel P. Berrange uint64_t offset, 14963e308f20SDaniel P. Berrange uint8_t *buf, 14973e308f20SDaniel P. Berrange size_t len, 14983e308f20SDaniel P. Berrange Error **errp) 14993e308f20SDaniel P. Berrange { 15004609742aSDaniel P. Berrange assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); 15014609742aSDaniel P. Berrange assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); 15020f0d596cSVladimir Sementsov-Ogievskiy return qcrypto_block_encrypt_helper(block, 15033e308f20SDaniel P. Berrange QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, 15044609742aSDaniel P. Berrange offset, buf, len, errp); 15053e308f20SDaniel P. Berrange } 15063e308f20SDaniel P. Berrange 15073e308f20SDaniel P. Berrange 15083e308f20SDaniel P. Berrange const QCryptoBlockDriver qcrypto_block_driver_luks = { 15093e308f20SDaniel P. Berrange .open = qcrypto_block_luks_open, 15103e308f20SDaniel P. Berrange .create = qcrypto_block_luks_create, 151140c85028SDaniel P. Berrange .get_info = qcrypto_block_luks_get_info, 15123e308f20SDaniel P. Berrange .cleanup = qcrypto_block_luks_cleanup, 15133e308f20SDaniel P. Berrange .decrypt = qcrypto_block_luks_decrypt, 15143e308f20SDaniel P. Berrange .encrypt = qcrypto_block_luks_encrypt, 15153e308f20SDaniel P. Berrange .has_format = qcrypto_block_luks_has_format, 15163e308f20SDaniel P. Berrange }; 1517