1 /* 2 * QEMU Crypto anti forensic information splitter 3 * 4 * Copyright (c) 2015-2016 Red Hat, Inc. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 2 9 * of the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #ifndef QCRYPTO_AFSPLIT_H 21 #define QCRYPTO_AFSPLIT_H 22 23 #include "crypto/hash.h" 24 25 /** 26 * This module implements the anti-forensic splitter that is specified 27 * as part of the LUKS format: 28 * 29 * http://clemens.endorphin.org/cryptography 30 * http://clemens.endorphin.org/TKS1-draft.pdf 31 * 32 * The core idea is to take a short piece of data (key material) 33 * and process it to expand it to a much larger piece of data. 34 * The expansion process is reversible, to obtain the original 35 * short data. The key property of the expansion is that if any 36 * byte in the larger data set is changed / missing, it should be 37 * impossible to recreate the original short data. 38 * 39 * <example> 40 * <title>Creating a large split key for storage</title> 41 * <programlisting> 42 * size_t nkey = 32; 43 * uint32_t stripes = 32768; // To produce a 1 MB split key 44 * uint8_t *masterkey = ....a 32-byte AES key... 45 * uint8_t *splitkey; 46 * 47 * splitkey = g_new0(uint8_t, nkey * stripes); 48 * 49 * if (qcrypto_afsplit_encode(QCRYPTO_HASH_ALGO_SHA256, 50 * nkey, stripes, 51 * masterkey, splitkey, errp) < 0) { 52 * g_free(splitkey); 53 * g_free(masterkey); 54 * return -1; 55 * } 56 * 57 * ...store splitkey somewhere... 58 * 59 * g_free(splitkey); 60 * g_free(masterkey); 61 * </programlisting> 62 * </example> 63 * 64 * <example> 65 * <title>Retrieving a master key from storage</title> 66 * <programlisting> 67 * size_t nkey = 32; 68 * uint32_t stripes = 32768; // To produce a 1 MB split key 69 * uint8_t *masterkey; 70 * uint8_t *splitkey = .... read in 1 MB of data... 71 * 72 * masterkey = g_new0(uint8_t, nkey); 73 * 74 * if (qcrypto_afsplit_decode(QCRYPTO_HASH_ALGO_SHA256, 75 * nkey, stripes, 76 * splitkey, masterkey, errp) < 0) { 77 * g_free(splitkey); 78 * g_free(masterkey); 79 * return -1; 80 * } 81 * 82 * ..decrypt data with masterkey... 83 * 84 * g_free(splitkey); 85 * g_free(masterkey); 86 * </programlisting> 87 * </example> 88 */ 89 90 /** 91 * qcrypto_afsplit_encode: 92 * @hash: the hash algorithm to use for data expansion 93 * @blocklen: the size of @in in bytes 94 * @stripes: the number of times to expand @in in size 95 * @in: the master key to be expanded in size 96 * @out: preallocated buffer to hold the split key 97 * @errp: pointer to a NULL-initialized error object 98 * 99 * Split the data in @in, which is @blocklen bytes in 100 * size, to form a larger piece of data @out, which is 101 * @blocklen * @stripes bytes in size. 102 * 103 * Returns: 0 on success, -1 on error; 104 */ 105 int qcrypto_afsplit_encode(QCryptoHashAlgo hash, 106 size_t blocklen, 107 uint32_t stripes, 108 const uint8_t *in, 109 uint8_t *out, 110 Error **errp); 111 112 /** 113 * qcrypto_afsplit_decode: 114 * @hash: the hash algorithm to use for data compression 115 * @blocklen: the size of @out in bytes 116 * @stripes: the number of times to decrease @in in size 117 * @in: the split key to be recombined 118 * @out: preallocated buffer to hold the master key 119 * @errp: pointer to a NULL-initialized error object 120 * 121 * Join the data in @in, which is @blocklen * @stripes 122 * bytes in size, to form the original small piece of 123 * data @out, which is @blocklen bytes in size. 124 * 125 * Returns: 0 on success, -1 on error; 126 */ 127 int qcrypto_afsplit_decode(QCryptoHashAlgo hash, 128 size_t blocklen, 129 uint32_t stripes, 130 const uint8_t *in, 131 uint8_t *out, 132 Error **errp); 133 134 #endif /* QCRYPTO_AFSPLIT_H */ 135