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