hw/intc/armv7m_nvic: Provide default "reset the system" behaviour for SYSRESETREQ
[qemu.git] / include / crypto / afsplit.h
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_ALG_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_ALG_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(QCryptoHashAlgorithm 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(QCryptoHashAlgorithm 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 */