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 9*422c16e7SChetan 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; 295a95e0fcSDaniel P. Berrange QCryptoHashAlgorithm 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", 395a95e0fcSDaniel P. Berrange .hash = QCRYPTO_HASH_ALG_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", 715a95e0fcSDaniel P. Berrange .hash = QCRYPTO_HASH_ALG_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", 805a95e0fcSDaniel P. Berrange .hash = QCRYPTO_HASH_ALG_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", 915a95e0fcSDaniel P. Berrange .hash = QCRYPTO_HASH_ALG_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 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 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 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 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