xref: /qemu/tests/unit/test-crypto-afsplit.c (revision ef834aa2)
1da668aa1SThomas Huth /*
2da668aa1SThomas Huth  * QEMU Crypto anti-forensic splitter
3da668aa1SThomas Huth  *
4da668aa1SThomas Huth  * Copyright (c) 2015-2016 Red Hat, Inc.
5da668aa1SThomas Huth  *
6da668aa1SThomas Huth  * This library is free software; you can redistribute it and/or
7da668aa1SThomas Huth  * modify it under the terms of the GNU Lesser General Public
8da668aa1SThomas Huth  * License as published by the Free Software Foundation; either
9da668aa1SThomas Huth  * version 2.1 of the License, or (at your option) any later version.
10da668aa1SThomas Huth  *
11da668aa1SThomas Huth  * This library is distributed in the hope that it will be useful,
12da668aa1SThomas Huth  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13da668aa1SThomas Huth  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14da668aa1SThomas Huth  * Lesser General Public License for more details.
15da668aa1SThomas Huth  *
16da668aa1SThomas Huth  * You should have received a copy of the GNU Lesser General Public
17da668aa1SThomas Huth  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18da668aa1SThomas Huth  *
19da668aa1SThomas Huth  */
20da668aa1SThomas Huth 
21da668aa1SThomas Huth #include "qemu/osdep.h"
22da668aa1SThomas Huth #include "qapi/error.h"
23da668aa1SThomas Huth #include "crypto/init.h"
24da668aa1SThomas Huth #include "crypto/afsplit.h"
25da668aa1SThomas Huth 
26da668aa1SThomas Huth typedef struct QCryptoAFSplitTestData QCryptoAFSplitTestData;
27da668aa1SThomas Huth struct QCryptoAFSplitTestData {
28da668aa1SThomas Huth     const char *path;
29*ef834aa2SMarkus Armbruster     QCryptoHashAlgo hash;
30da668aa1SThomas Huth     uint32_t stripes;
31da668aa1SThomas Huth     size_t blocklen;
32da668aa1SThomas Huth     const uint8_t *key;
33da668aa1SThomas Huth     const uint8_t *splitkey;
34da668aa1SThomas Huth };
35da668aa1SThomas Huth 
36da668aa1SThomas Huth static QCryptoAFSplitTestData test_data[] = {
37da668aa1SThomas Huth     {
38da668aa1SThomas Huth         .path = "/crypto/afsplit/sha256/5",
39*ef834aa2SMarkus Armbruster         .hash = QCRYPTO_HASH_ALGO_SHA256,
40da668aa1SThomas Huth         .stripes = 5,
41da668aa1SThomas Huth         .blocklen = 32,
42da668aa1SThomas Huth         .key = (const uint8_t *)
43da668aa1SThomas Huth             "\x00\x01\x02\x03\x04\x05\x06\x07"
44da668aa1SThomas Huth             "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
45da668aa1SThomas Huth             "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
46da668aa1SThomas Huth             "\xa8\xa9\xaa\xab\xac\xad\xae\xaf",
47da668aa1SThomas Huth         .splitkey = (const uint8_t *)
48da668aa1SThomas Huth             "\xfd\xd2\x73\xb1\x7d\x99\x93\x34"
49da668aa1SThomas Huth             "\x70\xde\xfa\x07\xc5\xac\x58\xd2"
50da668aa1SThomas Huth             "\x30\x67\x2f\x1a\x35\x43\x60\x7d"
51da668aa1SThomas Huth             "\x77\x02\xdb\x62\x3c\xcb\x2c\x33"
52da668aa1SThomas Huth             "\x48\x08\xb6\xf1\x7c\xa3\x20\xa0"
53da668aa1SThomas Huth             "\xad\x2d\x4c\xf3\xcd\x18\x6f\x53"
54da668aa1SThomas Huth             "\xf9\xe8\xe7\x59\x27\x3c\xa9\x54"
55da668aa1SThomas Huth             "\x61\x87\xb3\xaf\xf6\xf7\x7e\x64"
56da668aa1SThomas Huth             "\x86\xaa\x89\x7f\x1f\x9f\xdb\x86"
57da668aa1SThomas Huth             "\xf4\xa2\x16\xff\xa3\x4f\x8c\xa1"
58da668aa1SThomas Huth             "\x59\xc4\x23\x34\x28\xc4\x77\x71"
59da668aa1SThomas Huth             "\x83\xd4\xcd\x8e\x89\x1b\xc7\xc5"
60da668aa1SThomas Huth             "\xae\x4d\xa9\xcd\xc9\x72\x85\x70"
61da668aa1SThomas Huth             "\x13\x68\x52\x83\xfc\xb8\x11\x72"
62da668aa1SThomas Huth             "\xba\x3d\xc6\x4a\x28\xfa\xe2\x86"
63da668aa1SThomas Huth             "\x7b\x27\xab\x58\xe1\xa4\xca\xf6"
64da668aa1SThomas Huth             "\x9e\xbc\xfe\x0c\x92\x79\xb3\xec"
65da668aa1SThomas Huth             "\x1c\x5f\x79\x3b\x0d\x1e\xaa\x1a"
66da668aa1SThomas Huth             "\x77\x0f\x70\x19\x4b\xc8\x80\xee"
67da668aa1SThomas Huth             "\x27\x7c\x6e\x4a\x91\x96\x5c\xf4"
68da668aa1SThomas Huth     },
69da668aa1SThomas Huth     {
70da668aa1SThomas Huth         .path = "/crypto/afsplit/sha256/5000",
71*ef834aa2SMarkus Armbruster         .hash = QCRYPTO_HASH_ALGO_SHA256,
72da668aa1SThomas Huth         .stripes = 5000,
73da668aa1SThomas Huth         .blocklen = 16,
74da668aa1SThomas Huth         .key = (const uint8_t *)
75da668aa1SThomas Huth             "\x00\x01\x02\x03\x04\x05\x06\x07"
76da668aa1SThomas Huth             "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
77da668aa1SThomas Huth     },
78da668aa1SThomas Huth     {
79da668aa1SThomas Huth         .path = "/crypto/afsplit/sha1/1000",
80*ef834aa2SMarkus Armbruster         .hash = QCRYPTO_HASH_ALGO_SHA1,
81da668aa1SThomas Huth         .stripes = 1000,
82da668aa1SThomas Huth         .blocklen = 32,
83da668aa1SThomas Huth         .key = (const uint8_t *)
84da668aa1SThomas Huth             "\x00\x01\x02\x03\x04\x05\x06\x07"
85da668aa1SThomas Huth             "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
86da668aa1SThomas Huth             "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
87da668aa1SThomas Huth             "\xa8\xa9\xaa\xab\xac\xad\xae\xaf",
88da668aa1SThomas Huth     },
89da668aa1SThomas Huth     {
90da668aa1SThomas Huth         .path = "/crypto/afsplit/sha256/big",
91*ef834aa2SMarkus Armbruster         .hash = QCRYPTO_HASH_ALGO_SHA256,
92da668aa1SThomas Huth         .stripes = 1000,
93da668aa1SThomas Huth         .blocklen = 64,
94da668aa1SThomas Huth         .key = (const uint8_t *)
95da668aa1SThomas Huth             "\x00\x01\x02\x03\x04\x05\x06\x07"
96da668aa1SThomas Huth             "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
97da668aa1SThomas Huth             "\x00\x01\x02\x03\x04\x05\x06\x07"
98da668aa1SThomas Huth             "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
99da668aa1SThomas Huth             "\x00\x01\x02\x03\x04\x05\x06\x07"
100da668aa1SThomas Huth             "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
101da668aa1SThomas Huth             "\x00\x01\x02\x03\x04\x05\x06\x07"
102da668aa1SThomas Huth             "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
103da668aa1SThomas Huth     },
104da668aa1SThomas Huth };
105da668aa1SThomas Huth 
106da668aa1SThomas Huth 
hex(int i)107da668aa1SThomas Huth static inline char hex(int i)
108da668aa1SThomas Huth {
109da668aa1SThomas Huth     if (i < 10) {
110da668aa1SThomas Huth         return '0' + i;
111da668aa1SThomas Huth     }
112da668aa1SThomas Huth     return 'a' + (i - 10);
113da668aa1SThomas Huth }
114da668aa1SThomas Huth 
hex_string(const uint8_t * bytes,size_t len)115da668aa1SThomas Huth static char *hex_string(const uint8_t *bytes,
116da668aa1SThomas Huth                         size_t len)
117da668aa1SThomas Huth {
118da668aa1SThomas Huth     char *hexstr = g_new0(char, len * 2 + 1);
119da668aa1SThomas Huth     size_t i;
120da668aa1SThomas Huth 
121da668aa1SThomas Huth     for (i = 0; i < len; i++) {
122da668aa1SThomas Huth         hexstr[i * 2] = hex((bytes[i] >> 4) & 0xf);
123da668aa1SThomas Huth         hexstr[i * 2 + 1] = hex(bytes[i] & 0xf);
124da668aa1SThomas Huth     }
125da668aa1SThomas Huth     hexstr[len * 2] = '\0';
126da668aa1SThomas Huth 
127da668aa1SThomas Huth     return hexstr;
128da668aa1SThomas Huth }
129da668aa1SThomas Huth 
test_afsplit(const void * opaque)130da668aa1SThomas Huth static void test_afsplit(const void *opaque)
131da668aa1SThomas Huth {
132da668aa1SThomas Huth     const QCryptoAFSplitTestData *data = opaque;
133da668aa1SThomas Huth     size_t splitlen = data->blocklen * data->stripes;
134da668aa1SThomas Huth     uint8_t *splitkey = g_new0(uint8_t, splitlen);
135da668aa1SThomas Huth     uint8_t *key = g_new0(uint8_t, data->blocklen);
136da668aa1SThomas Huth     gchar *expect, *actual;
137da668aa1SThomas Huth 
138da668aa1SThomas Huth     /* First time we round-trip the key */
139da668aa1SThomas Huth     qcrypto_afsplit_encode(data->hash,
140da668aa1SThomas Huth                            data->blocklen, data->stripes,
141da668aa1SThomas Huth                            data->key, splitkey,
142da668aa1SThomas Huth                            &error_abort);
143da668aa1SThomas Huth 
144da668aa1SThomas Huth     qcrypto_afsplit_decode(data->hash,
145da668aa1SThomas Huth                            data->blocklen, data->stripes,
146da668aa1SThomas Huth                            splitkey, key,
147da668aa1SThomas Huth                            &error_abort);
148da668aa1SThomas Huth 
149da668aa1SThomas Huth     expect = hex_string(data->key, data->blocklen);
150da668aa1SThomas Huth     actual = hex_string(key, data->blocklen);
151da668aa1SThomas Huth 
152da668aa1SThomas Huth     g_assert_cmpstr(actual, ==, expect);
153da668aa1SThomas Huth 
154da668aa1SThomas Huth     g_free(actual);
155da668aa1SThomas Huth     g_free(expect);
156da668aa1SThomas Huth 
157da668aa1SThomas Huth     /* Second time we merely try decoding a previous split */
158da668aa1SThomas Huth     if (data->splitkey) {
159da668aa1SThomas Huth         memset(key, 0, data->blocklen);
160da668aa1SThomas Huth 
161da668aa1SThomas Huth         qcrypto_afsplit_decode(data->hash,
162da668aa1SThomas Huth                                data->blocklen, data->stripes,
163da668aa1SThomas Huth                                data->splitkey, key,
164da668aa1SThomas Huth                                &error_abort);
165da668aa1SThomas Huth 
166da668aa1SThomas Huth         expect = hex_string(data->key, data->blocklen);
167da668aa1SThomas Huth         actual = hex_string(key, data->blocklen);
168da668aa1SThomas Huth 
169da668aa1SThomas Huth         g_assert_cmpstr(actual, ==, expect);
170da668aa1SThomas Huth 
171da668aa1SThomas Huth         g_free(actual);
172da668aa1SThomas Huth         g_free(expect);
173da668aa1SThomas Huth     }
174da668aa1SThomas Huth 
175da668aa1SThomas Huth     g_free(key);
176da668aa1SThomas Huth     g_free(splitkey);
177da668aa1SThomas Huth }
178da668aa1SThomas Huth 
main(int argc,char ** argv)179da668aa1SThomas Huth int main(int argc, char **argv)
180da668aa1SThomas Huth {
181da668aa1SThomas Huth     size_t i;
182da668aa1SThomas Huth 
183da668aa1SThomas Huth     g_test_init(&argc, &argv, NULL);
184da668aa1SThomas Huth 
185da668aa1SThomas Huth     g_assert(qcrypto_init(NULL) == 0);
186da668aa1SThomas Huth 
187da668aa1SThomas Huth     for (i = 0; i < G_N_ELEMENTS(test_data); i++) {
188da668aa1SThomas Huth         if (!qcrypto_hash_supports(test_data[i].hash)) {
189da668aa1SThomas Huth             continue;
190da668aa1SThomas Huth         }
191da668aa1SThomas Huth         g_test_add_data_func(test_data[i].path, &test_data[i], test_afsplit);
192da668aa1SThomas Huth     }
193da668aa1SThomas Huth     return g_test_run();
194da668aa1SThomas Huth }
195