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