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