15a95e0fcSDaniel P. Berrange /* 25a95e0fcSDaniel P. Berrange * QEMU Crypto anti forensic information splitter 35a95e0fcSDaniel P. Berrange * 45a95e0fcSDaniel P. Berrange * Copyright (c) 2015-2016 Red Hat, Inc. 55a95e0fcSDaniel P. Berrange * 6e361a772SThomas Huth * This program is free software; you can redistribute it and/or 75a95e0fcSDaniel P. Berrange * modify it under the terms of the GNU General Public License 85a95e0fcSDaniel P. Berrange * as published by the Free Software Foundation; either version 2 95a95e0fcSDaniel P. Berrange * of the License, or (at your option) any later version. 105a95e0fcSDaniel P. Berrange * 11e361a772SThomas Huth * This program is distributed in the hope that it will be useful, 125a95e0fcSDaniel P. Berrange * but WITHOUT ANY WARRANTY; without even the implied warranty of 135a95e0fcSDaniel P. Berrange * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14e361a772SThomas Huth * General Public License for more details. 155a95e0fcSDaniel P. Berrange * 16e361a772SThomas Huth * You should have received a copy of the GNU General Public License 17e361a772SThomas Huth * along with this program; if not, see <http://www.gnu.org/licenses/>. 185a95e0fcSDaniel P. Berrange */ 195a95e0fcSDaniel P. Berrange 202a6a4076SMarkus Armbruster #ifndef QCRYPTO_AFSPLIT_H 212a6a4076SMarkus Armbruster #define QCRYPTO_AFSPLIT_H 225a95e0fcSDaniel P. Berrange 235a95e0fcSDaniel P. Berrange #include "crypto/hash.h" 245a95e0fcSDaniel P. Berrange 255a95e0fcSDaniel P. Berrange /** 265a95e0fcSDaniel P. Berrange * This module implements the anti-forensic splitter that is specified 275a95e0fcSDaniel P. Berrange * as part of the LUKS format: 285a95e0fcSDaniel P. Berrange * 295a95e0fcSDaniel P. Berrange * http://clemens.endorphin.org/cryptography 305a95e0fcSDaniel P. Berrange * http://clemens.endorphin.org/TKS1-draft.pdf 315a95e0fcSDaniel P. Berrange * 325a95e0fcSDaniel P. Berrange * The core idea is to take a short piece of data (key material) 335a95e0fcSDaniel P. Berrange * and process it to expand it to a much larger piece of data. 345a95e0fcSDaniel P. Berrange * The expansion process is reversible, to obtain the original 355a95e0fcSDaniel P. Berrange * short data. The key property of the expansion is that if any 365a95e0fcSDaniel P. Berrange * byte in the larger data set is changed / missing, it should be 375a95e0fcSDaniel P. Berrange * impossible to recreate the original short data. 385a95e0fcSDaniel P. Berrange * 395a95e0fcSDaniel P. Berrange * <example> 405a95e0fcSDaniel P. Berrange * <title>Creating a large split key for storage</title> 415a95e0fcSDaniel P. Berrange * <programlisting> 425a95e0fcSDaniel P. Berrange * size_t nkey = 32; 435a95e0fcSDaniel P. Berrange * uint32_t stripes = 32768; // To produce a 1 MB split key 445a95e0fcSDaniel P. Berrange * uint8_t *masterkey = ....a 32-byte AES key... 455a95e0fcSDaniel P. Berrange * uint8_t *splitkey; 465a95e0fcSDaniel P. Berrange * 475a95e0fcSDaniel P. Berrange * splitkey = g_new0(uint8_t, nkey * stripes); 485a95e0fcSDaniel P. Berrange * 49*ef834aa2SMarkus Armbruster * if (qcrypto_afsplit_encode(QCRYPTO_HASH_ALGO_SHA256, 505a95e0fcSDaniel P. Berrange * nkey, stripes, 515a95e0fcSDaniel P. Berrange * masterkey, splitkey, errp) < 0) { 525a95e0fcSDaniel P. Berrange * g_free(splitkey); 535a95e0fcSDaniel P. Berrange * g_free(masterkey); 545a95e0fcSDaniel P. Berrange * return -1; 555a95e0fcSDaniel P. Berrange * } 565a95e0fcSDaniel P. Berrange * 575a95e0fcSDaniel P. Berrange * ...store splitkey somewhere... 585a95e0fcSDaniel P. Berrange * 595a95e0fcSDaniel P. Berrange * g_free(splitkey); 605a95e0fcSDaniel P. Berrange * g_free(masterkey); 615a95e0fcSDaniel P. Berrange * </programlisting> 625a95e0fcSDaniel P. Berrange * </example> 635a95e0fcSDaniel P. Berrange * 645a95e0fcSDaniel P. Berrange * <example> 655a95e0fcSDaniel P. Berrange * <title>Retrieving a master key from storage</title> 665a95e0fcSDaniel P. Berrange * <programlisting> 675a95e0fcSDaniel P. Berrange * size_t nkey = 32; 685a95e0fcSDaniel P. Berrange * uint32_t stripes = 32768; // To produce a 1 MB split key 695a95e0fcSDaniel P. Berrange * uint8_t *masterkey; 705a95e0fcSDaniel P. Berrange * uint8_t *splitkey = .... read in 1 MB of data... 715a95e0fcSDaniel P. Berrange * 725a95e0fcSDaniel P. Berrange * masterkey = g_new0(uint8_t, nkey); 735a95e0fcSDaniel P. Berrange * 74*ef834aa2SMarkus Armbruster * if (qcrypto_afsplit_decode(QCRYPTO_HASH_ALGO_SHA256, 755a95e0fcSDaniel P. Berrange * nkey, stripes, 765a95e0fcSDaniel P. Berrange * splitkey, masterkey, errp) < 0) { 775a95e0fcSDaniel P. Berrange * g_free(splitkey); 785a95e0fcSDaniel P. Berrange * g_free(masterkey); 795a95e0fcSDaniel P. Berrange * return -1; 805a95e0fcSDaniel P. Berrange * } 815a95e0fcSDaniel P. Berrange * 825a95e0fcSDaniel P. Berrange * ..decrypt data with masterkey... 835a95e0fcSDaniel P. Berrange * 845a95e0fcSDaniel P. Berrange * g_free(splitkey); 855a95e0fcSDaniel P. Berrange * g_free(masterkey); 865a95e0fcSDaniel P. Berrange * </programlisting> 875a95e0fcSDaniel P. Berrange * </example> 885a95e0fcSDaniel P. Berrange */ 895a95e0fcSDaniel P. Berrange 905a95e0fcSDaniel P. Berrange /** 915a95e0fcSDaniel P. Berrange * qcrypto_afsplit_encode: 925a95e0fcSDaniel P. Berrange * @hash: the hash algorithm to use for data expansion 935a95e0fcSDaniel P. Berrange * @blocklen: the size of @in in bytes 945a95e0fcSDaniel P. Berrange * @stripes: the number of times to expand @in in size 955a95e0fcSDaniel P. Berrange * @in: the master key to be expanded in size 965a95e0fcSDaniel P. Berrange * @out: preallocated buffer to hold the split key 975a95e0fcSDaniel P. Berrange * @errp: pointer to a NULL-initialized error object 985a95e0fcSDaniel P. Berrange * 995a95e0fcSDaniel P. Berrange * Split the data in @in, which is @blocklen bytes in 1005a95e0fcSDaniel P. Berrange * size, to form a larger piece of data @out, which is 1015a95e0fcSDaniel P. Berrange * @blocklen * @stripes bytes in size. 1025a95e0fcSDaniel P. Berrange * 1035a95e0fcSDaniel P. Berrange * Returns: 0 on success, -1 on error; 1045a95e0fcSDaniel P. Berrange */ 105*ef834aa2SMarkus Armbruster int qcrypto_afsplit_encode(QCryptoHashAlgo hash, 1065a95e0fcSDaniel P. Berrange size_t blocklen, 1075a95e0fcSDaniel P. Berrange uint32_t stripes, 1085a95e0fcSDaniel P. Berrange const uint8_t *in, 1095a95e0fcSDaniel P. Berrange uint8_t *out, 1105a95e0fcSDaniel P. Berrange Error **errp); 1115a95e0fcSDaniel P. Berrange 1125a95e0fcSDaniel P. Berrange /** 1135a95e0fcSDaniel P. Berrange * qcrypto_afsplit_decode: 1145a95e0fcSDaniel P. Berrange * @hash: the hash algorithm to use for data compression 1155a95e0fcSDaniel P. Berrange * @blocklen: the size of @out in bytes 1165a95e0fcSDaniel P. Berrange * @stripes: the number of times to decrease @in in size 1175a95e0fcSDaniel P. Berrange * @in: the split key to be recombined 1185a95e0fcSDaniel P. Berrange * @out: preallocated buffer to hold the master key 1195a95e0fcSDaniel P. Berrange * @errp: pointer to a NULL-initialized error object 1205a95e0fcSDaniel P. Berrange * 1215a95e0fcSDaniel P. Berrange * Join the data in @in, which is @blocklen * @stripes 1225a95e0fcSDaniel P. Berrange * bytes in size, to form the original small piece of 1235a95e0fcSDaniel P. Berrange * data @out, which is @blocklen bytes in size. 1245a95e0fcSDaniel P. Berrange * 1255a95e0fcSDaniel P. Berrange * Returns: 0 on success, -1 on error; 1265a95e0fcSDaniel P. Berrange */ 127*ef834aa2SMarkus Armbruster int qcrypto_afsplit_decode(QCryptoHashAlgo hash, 1285a95e0fcSDaniel P. Berrange size_t blocklen, 1295a95e0fcSDaniel P. Berrange uint32_t stripes, 1305a95e0fcSDaniel P. Berrange const uint8_t *in, 1315a95e0fcSDaniel P. Berrange uint8_t *out, 1325a95e0fcSDaniel P. Berrange Error **errp); 1335a95e0fcSDaniel P. Berrange 1342a6a4076SMarkus Armbruster #endif /* QCRYPTO_AFSPLIT_H */ 135