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