xref: /openbmc/qemu/include/crypto/afsplit.h (revision b8eada54b2ad8a7d98d93d5ab4d3e888c5880097)
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