15a95e0fcSDaniel P. Berrange /*
25a95e0fcSDaniel P. Berrange * QEMU Crypto anti-forensic splitter
35a95e0fcSDaniel P. Berrange *
45a95e0fcSDaniel P. Berrange * Copyright (c) 2015-2016 Red Hat, Inc.
55a95e0fcSDaniel P. Berrange *
65a95e0fcSDaniel P. Berrange * This library is free software; you can redistribute it and/or
75a95e0fcSDaniel P. Berrange * modify it under the terms of the GNU Lesser General Public
85a95e0fcSDaniel P. Berrange * License as published by the Free Software Foundation; either
9422c16e7SChetan Pant * version 2.1 of the License, or (at your option) any later version.
105a95e0fcSDaniel P. Berrange *
115a95e0fcSDaniel P. Berrange * This library is distributed in the hope that it will be useful,
125a95e0fcSDaniel P. Berrange * but WITHOUT ANY WARRANTY; without even the implied warranty of
135a95e0fcSDaniel P. Berrange * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
145a95e0fcSDaniel P. Berrange * Lesser General Public License for more details.
155a95e0fcSDaniel P. Berrange *
165a95e0fcSDaniel P. Berrange * You should have received a copy of the GNU Lesser General Public
175a95e0fcSDaniel P. Berrange * License along with this library; if not, see <http://www.gnu.org/licenses/>.
185a95e0fcSDaniel P. Berrange *
195a95e0fcSDaniel P. Berrange */
205a95e0fcSDaniel P. Berrange
215a95e0fcSDaniel P. Berrange #include "qemu/osdep.h"
22da34e65cSMarkus Armbruster #include "qapi/error.h"
235a95e0fcSDaniel P. Berrange #include "crypto/init.h"
245a95e0fcSDaniel P. Berrange #include "crypto/afsplit.h"
255a95e0fcSDaniel P. Berrange
265a95e0fcSDaniel P. Berrange typedef struct QCryptoAFSplitTestData QCryptoAFSplitTestData;
275a95e0fcSDaniel P. Berrange struct QCryptoAFSplitTestData {
285a95e0fcSDaniel P. Berrange const char *path;
29*ef834aa2SMarkus Armbruster QCryptoHashAlgo hash;
305a95e0fcSDaniel P. Berrange uint32_t stripes;
315a95e0fcSDaniel P. Berrange size_t blocklen;
325a95e0fcSDaniel P. Berrange const uint8_t *key;
335a95e0fcSDaniel P. Berrange const uint8_t *splitkey;
345a95e0fcSDaniel P. Berrange };
355a95e0fcSDaniel P. Berrange
365a95e0fcSDaniel P. Berrange static QCryptoAFSplitTestData test_data[] = {
375a95e0fcSDaniel P. Berrange {
385a95e0fcSDaniel P. Berrange .path = "/crypto/afsplit/sha256/5",
39*ef834aa2SMarkus Armbruster .hash = QCRYPTO_HASH_ALGO_SHA256,
405a95e0fcSDaniel P. Berrange .stripes = 5,
415a95e0fcSDaniel P. Berrange .blocklen = 32,
425a95e0fcSDaniel P. Berrange .key = (const uint8_t *)
435a95e0fcSDaniel P. Berrange "\x00\x01\x02\x03\x04\x05\x06\x07"
445a95e0fcSDaniel P. Berrange "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
455a95e0fcSDaniel P. Berrange "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
465a95e0fcSDaniel P. Berrange "\xa8\xa9\xaa\xab\xac\xad\xae\xaf",
475a95e0fcSDaniel P. Berrange .splitkey = (const uint8_t *)
485a95e0fcSDaniel P. Berrange "\xfd\xd2\x73\xb1\x7d\x99\x93\x34"
495a95e0fcSDaniel P. Berrange "\x70\xde\xfa\x07\xc5\xac\x58\xd2"
505a95e0fcSDaniel P. Berrange "\x30\x67\x2f\x1a\x35\x43\x60\x7d"
515a95e0fcSDaniel P. Berrange "\x77\x02\xdb\x62\x3c\xcb\x2c\x33"
525a95e0fcSDaniel P. Berrange "\x48\x08\xb6\xf1\x7c\xa3\x20\xa0"
535a95e0fcSDaniel P. Berrange "\xad\x2d\x4c\xf3\xcd\x18\x6f\x53"
545a95e0fcSDaniel P. Berrange "\xf9\xe8\xe7\x59\x27\x3c\xa9\x54"
555a95e0fcSDaniel P. Berrange "\x61\x87\xb3\xaf\xf6\xf7\x7e\x64"
565a95e0fcSDaniel P. Berrange "\x86\xaa\x89\x7f\x1f\x9f\xdb\x86"
575a95e0fcSDaniel P. Berrange "\xf4\xa2\x16\xff\xa3\x4f\x8c\xa1"
585a95e0fcSDaniel P. Berrange "\x59\xc4\x23\x34\x28\xc4\x77\x71"
595a95e0fcSDaniel P. Berrange "\x83\xd4\xcd\x8e\x89\x1b\xc7\xc5"
605a95e0fcSDaniel P. Berrange "\xae\x4d\xa9\xcd\xc9\x72\x85\x70"
615a95e0fcSDaniel P. Berrange "\x13\x68\x52\x83\xfc\xb8\x11\x72"
625a95e0fcSDaniel P. Berrange "\xba\x3d\xc6\x4a\x28\xfa\xe2\x86"
635a95e0fcSDaniel P. Berrange "\x7b\x27\xab\x58\xe1\xa4\xca\xf6"
645a95e0fcSDaniel P. Berrange "\x9e\xbc\xfe\x0c\x92\x79\xb3\xec"
655a95e0fcSDaniel P. Berrange "\x1c\x5f\x79\x3b\x0d\x1e\xaa\x1a"
665a95e0fcSDaniel P. Berrange "\x77\x0f\x70\x19\x4b\xc8\x80\xee"
675a95e0fcSDaniel P. Berrange "\x27\x7c\x6e\x4a\x91\x96\x5c\xf4"
685a95e0fcSDaniel P. Berrange },
695a95e0fcSDaniel P. Berrange {
705a95e0fcSDaniel P. Berrange .path = "/crypto/afsplit/sha256/5000",
71*ef834aa2SMarkus Armbruster .hash = QCRYPTO_HASH_ALGO_SHA256,
725a95e0fcSDaniel P. Berrange .stripes = 5000,
735a95e0fcSDaniel P. Berrange .blocklen = 16,
745a95e0fcSDaniel P. Berrange .key = (const uint8_t *)
755a95e0fcSDaniel P. Berrange "\x00\x01\x02\x03\x04\x05\x06\x07"
765a95e0fcSDaniel P. Berrange "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
775a95e0fcSDaniel P. Berrange },
785a95e0fcSDaniel P. Berrange {
795a95e0fcSDaniel P. Berrange .path = "/crypto/afsplit/sha1/1000",
80*ef834aa2SMarkus Armbruster .hash = QCRYPTO_HASH_ALGO_SHA1,
815a95e0fcSDaniel P. Berrange .stripes = 1000,
825a95e0fcSDaniel P. Berrange .blocklen = 32,
835a95e0fcSDaniel P. Berrange .key = (const uint8_t *)
845a95e0fcSDaniel P. Berrange "\x00\x01\x02\x03\x04\x05\x06\x07"
855a95e0fcSDaniel P. Berrange "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
865a95e0fcSDaniel P. Berrange "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
875a95e0fcSDaniel P. Berrange "\xa8\xa9\xaa\xab\xac\xad\xae\xaf",
885a95e0fcSDaniel P. Berrange },
895a95e0fcSDaniel P. Berrange {
905a95e0fcSDaniel P. Berrange .path = "/crypto/afsplit/sha256/big",
91*ef834aa2SMarkus Armbruster .hash = QCRYPTO_HASH_ALGO_SHA256,
925a95e0fcSDaniel P. Berrange .stripes = 1000,
935a95e0fcSDaniel P. Berrange .blocklen = 64,
945a95e0fcSDaniel P. Berrange .key = (const uint8_t *)
955a95e0fcSDaniel P. Berrange "\x00\x01\x02\x03\x04\x05\x06\x07"
965a95e0fcSDaniel P. Berrange "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
975a95e0fcSDaniel P. Berrange "\x00\x01\x02\x03\x04\x05\x06\x07"
985a95e0fcSDaniel P. Berrange "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
995a95e0fcSDaniel P. Berrange "\x00\x01\x02\x03\x04\x05\x06\x07"
1005a95e0fcSDaniel P. Berrange "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
1015a95e0fcSDaniel P. Berrange "\x00\x01\x02\x03\x04\x05\x06\x07"
1025a95e0fcSDaniel P. Berrange "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
1035a95e0fcSDaniel P. Berrange },
1045a95e0fcSDaniel P. Berrange };
1055a95e0fcSDaniel P. Berrange
1065a95e0fcSDaniel P. Berrange
hex(int i)1075a95e0fcSDaniel P. Berrange static inline char hex(int i)
1085a95e0fcSDaniel P. Berrange {
1095a95e0fcSDaniel P. Berrange if (i < 10) {
1105a95e0fcSDaniel P. Berrange return '0' + i;
1115a95e0fcSDaniel P. Berrange }
1125a95e0fcSDaniel P. Berrange return 'a' + (i - 10);
1135a95e0fcSDaniel P. Berrange }
1145a95e0fcSDaniel P. Berrange
hex_string(const uint8_t * bytes,size_t len)1155a95e0fcSDaniel P. Berrange static char *hex_string(const uint8_t *bytes,
1165a95e0fcSDaniel P. Berrange size_t len)
1175a95e0fcSDaniel P. Berrange {
1185a95e0fcSDaniel P. Berrange char *hexstr = g_new0(char, len * 2 + 1);
1195a95e0fcSDaniel P. Berrange size_t i;
1205a95e0fcSDaniel P. Berrange
1215a95e0fcSDaniel P. Berrange for (i = 0; i < len; i++) {
1225a95e0fcSDaniel P. Berrange hexstr[i * 2] = hex((bytes[i] >> 4) & 0xf);
1235a95e0fcSDaniel P. Berrange hexstr[i * 2 + 1] = hex(bytes[i] & 0xf);
1245a95e0fcSDaniel P. Berrange }
1255a95e0fcSDaniel P. Berrange hexstr[len * 2] = '\0';
1265a95e0fcSDaniel P. Berrange
1275a95e0fcSDaniel P. Berrange return hexstr;
1285a95e0fcSDaniel P. Berrange }
1295a95e0fcSDaniel P. Berrange
test_afsplit(const void * opaque)1305a95e0fcSDaniel P. Berrange static void test_afsplit(const void *opaque)
1315a95e0fcSDaniel P. Berrange {
1325a95e0fcSDaniel P. Berrange const QCryptoAFSplitTestData *data = opaque;
1335a95e0fcSDaniel P. Berrange size_t splitlen = data->blocklen * data->stripes;
1345a95e0fcSDaniel P. Berrange uint8_t *splitkey = g_new0(uint8_t, splitlen);
1355a95e0fcSDaniel P. Berrange uint8_t *key = g_new0(uint8_t, data->blocklen);
1365a95e0fcSDaniel P. Berrange gchar *expect, *actual;
1375a95e0fcSDaniel P. Berrange
1385a95e0fcSDaniel P. Berrange /* First time we round-trip the key */
1395a95e0fcSDaniel P. Berrange qcrypto_afsplit_encode(data->hash,
1405a95e0fcSDaniel P. Berrange data->blocklen, data->stripes,
1415a95e0fcSDaniel P. Berrange data->key, splitkey,
1425a95e0fcSDaniel P. Berrange &error_abort);
1435a95e0fcSDaniel P. Berrange
1445a95e0fcSDaniel P. Berrange qcrypto_afsplit_decode(data->hash,
1455a95e0fcSDaniel P. Berrange data->blocklen, data->stripes,
1465a95e0fcSDaniel P. Berrange splitkey, key,
1475a95e0fcSDaniel P. Berrange &error_abort);
1485a95e0fcSDaniel P. Berrange
1495a95e0fcSDaniel P. Berrange expect = hex_string(data->key, data->blocklen);
1505a95e0fcSDaniel P. Berrange actual = hex_string(key, data->blocklen);
1515a95e0fcSDaniel P. Berrange
1525a95e0fcSDaniel P. Berrange g_assert_cmpstr(actual, ==, expect);
1535a95e0fcSDaniel P. Berrange
1545a95e0fcSDaniel P. Berrange g_free(actual);
1555a95e0fcSDaniel P. Berrange g_free(expect);
1565a95e0fcSDaniel P. Berrange
1575a95e0fcSDaniel P. Berrange /* Second time we merely try decoding a previous split */
1585a95e0fcSDaniel P. Berrange if (data->splitkey) {
1595a95e0fcSDaniel P. Berrange memset(key, 0, data->blocklen);
1605a95e0fcSDaniel P. Berrange
1615a95e0fcSDaniel P. Berrange qcrypto_afsplit_decode(data->hash,
1625a95e0fcSDaniel P. Berrange data->blocklen, data->stripes,
1635a95e0fcSDaniel P. Berrange data->splitkey, key,
1645a95e0fcSDaniel P. Berrange &error_abort);
1655a95e0fcSDaniel P. Berrange
1665a95e0fcSDaniel P. Berrange expect = hex_string(data->key, data->blocklen);
1675a95e0fcSDaniel P. Berrange actual = hex_string(key, data->blocklen);
1685a95e0fcSDaniel P. Berrange
1695a95e0fcSDaniel P. Berrange g_assert_cmpstr(actual, ==, expect);
1705a95e0fcSDaniel P. Berrange
1715a95e0fcSDaniel P. Berrange g_free(actual);
1725a95e0fcSDaniel P. Berrange g_free(expect);
1735a95e0fcSDaniel P. Berrange }
1745a95e0fcSDaniel P. Berrange
1755a95e0fcSDaniel P. Berrange g_free(key);
1765a95e0fcSDaniel P. Berrange g_free(splitkey);
1775a95e0fcSDaniel P. Berrange }
1785a95e0fcSDaniel P. Berrange
main(int argc,char ** argv)1795a95e0fcSDaniel P. Berrange int main(int argc, char **argv)
1805a95e0fcSDaniel P. Berrange {
1815a95e0fcSDaniel P. Berrange size_t i;
1825a95e0fcSDaniel P. Berrange
1835a95e0fcSDaniel P. Berrange g_test_init(&argc, &argv, NULL);
1845a95e0fcSDaniel P. Berrange
1855a95e0fcSDaniel P. Berrange g_assert(qcrypto_init(NULL) == 0);
1865a95e0fcSDaniel P. Berrange
1875a95e0fcSDaniel P. Berrange for (i = 0; i < G_N_ELEMENTS(test_data); i++) {
1885a95e0fcSDaniel P. Berrange if (!qcrypto_hash_supports(test_data[i].hash)) {
1895a95e0fcSDaniel P. Berrange continue;
1905a95e0fcSDaniel P. Berrange }
1915a95e0fcSDaniel P. Berrange g_test_add_data_func(test_data[i].path, &test_data[i], test_afsplit);
1925a95e0fcSDaniel P. Berrange }
1935a95e0fcSDaniel P. Berrange return g_test_run();
1945a95e0fcSDaniel P. Berrange }
195