1 /* 2 * QEMU Crypto IV generator algorithms 3 * 4 * Copyright (c) 2015-2016 Red Hat, Inc. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 * 19 */ 20 21 #include "qemu/osdep.h" 22 #include "qapi/error.h" 23 #include "crypto/ivgen.h" 24 25 26 struct QCryptoIVGenTestData { 27 const char *path; 28 uint64_t sector; 29 QCryptoIVGenAlgo ivalg; 30 QCryptoHashAlgo hashalg; 31 QCryptoCipherAlgo cipheralg; 32 const uint8_t *key; 33 size_t nkey; 34 const uint8_t *iv; 35 size_t niv; 36 } test_data[] = { 37 /* Small */ 38 { 39 "/crypto/ivgen/plain/1", 40 .sector = 0x1, 41 .ivalg = QCRYPTO_IV_GEN_ALGO_PLAIN, 42 .iv = (const uint8_t *)"\x01\x00\x00\x00\x00\x00\x00\x00" 43 "\x00\x00\x00\x00\x00\x00\x00\x00", 44 .niv = 16, 45 }, 46 /* Big ! */ 47 { 48 "/crypto/ivgen/plain/1f2e3d4c", 49 .sector = 0x1f2e3d4cULL, 50 .ivalg = QCRYPTO_IV_GEN_ALGO_PLAIN, 51 .iv = (const uint8_t *)"\x4c\x3d\x2e\x1f\x00\x00\x00\x00" 52 "\x00\x00\x00\x00\x00\x00\x00\x00", 53 .niv = 16, 54 }, 55 /* Truncation */ 56 { 57 "/crypto/ivgen/plain/1f2e3d4c5b6a7988", 58 .sector = 0x1f2e3d4c5b6a7988ULL, 59 .ivalg = QCRYPTO_IV_GEN_ALGO_PLAIN, 60 .iv = (const uint8_t *)"\x88\x79\x6a\x5b\x00\x00\x00\x00" 61 "\x00\x00\x00\x00\x00\x00\x00\x00", 62 .niv = 16, 63 }, 64 /* Small */ 65 { 66 "/crypto/ivgen/plain64/1", 67 .sector = 0x1, 68 .ivalg = QCRYPTO_IV_GEN_ALGO_PLAIN64, 69 .iv = (const uint8_t *)"\x01\x00\x00\x00\x00\x00\x00\x00" 70 "\x00\x00\x00\x00\x00\x00\x00\x00", 71 .niv = 16, 72 }, 73 /* Big ! */ 74 { 75 "/crypto/ivgen/plain64/1f2e3d4c", 76 .sector = 0x1f2e3d4cULL, 77 .ivalg = QCRYPTO_IV_GEN_ALGO_PLAIN64, 78 .iv = (const uint8_t *)"\x4c\x3d\x2e\x1f\x00\x00\x00\x00" 79 "\x00\x00\x00\x00\x00\x00\x00\x00", 80 .niv = 16, 81 }, 82 /* No Truncation */ 83 { 84 "/crypto/ivgen/plain64/1f2e3d4c5b6a7988", 85 .sector = 0x1f2e3d4c5b6a7988ULL, 86 .ivalg = QCRYPTO_IV_GEN_ALGO_PLAIN64, 87 .iv = (const uint8_t *)"\x88\x79\x6a\x5b\x4c\x3d\x2e\x1f" 88 "\x00\x00\x00\x00\x00\x00\x00\x00", 89 .niv = 16, 90 }, 91 /* Small */ 92 { 93 "/crypto/ivgen/essiv/1", 94 .sector = 0x1, 95 .ivalg = QCRYPTO_IV_GEN_ALGO_ESSIV, 96 .cipheralg = QCRYPTO_CIPHER_ALGO_AES_128, 97 .hashalg = QCRYPTO_HASH_ALGO_SHA256, 98 .key = (const uint8_t *)"\x00\x01\x02\x03\x04\x05\x06\x07" 99 "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 100 .nkey = 16, 101 .iv = (const uint8_t *)"\xd4\x83\x71\xb2\xa1\x94\x53\x88" 102 "\x1c\x7a\x2d\06\x2d\x0b\x65\x46", 103 .niv = 16, 104 }, 105 /* Big ! */ 106 { 107 "/crypto/ivgen/essiv/1f2e3d4c", 108 .sector = 0x1f2e3d4cULL, 109 .ivalg = QCRYPTO_IV_GEN_ALGO_ESSIV, 110 .cipheralg = QCRYPTO_CIPHER_ALGO_AES_128, 111 .hashalg = QCRYPTO_HASH_ALGO_SHA256, 112 .key = (const uint8_t *)"\x00\x01\x02\x03\x04\x05\x06\x07" 113 "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 114 .nkey = 16, 115 .iv = (const uint8_t *)"\x5d\x36\x09\x5d\xc6\x9e\x5e\xe9" 116 "\xe3\x02\x8d\xd8\x7a\x3d\xe7\x8f", 117 .niv = 16, 118 }, 119 /* No Truncation */ 120 { 121 "/crypto/ivgen/essiv/1f2e3d4c5b6a7988", 122 .sector = 0x1f2e3d4c5b6a7988ULL, 123 .ivalg = QCRYPTO_IV_GEN_ALGO_ESSIV, 124 .cipheralg = QCRYPTO_CIPHER_ALGO_AES_128, 125 .hashalg = QCRYPTO_HASH_ALGO_SHA256, 126 .key = (const uint8_t *)"\x00\x01\x02\x03\x04\x05\x06\x07" 127 "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 128 .nkey = 16, 129 .iv = (const uint8_t *)"\x58\xbb\x81\x94\x51\x83\x23\x23" 130 "\x7a\x08\x93\xa9\xdc\xd2\xd9\xab", 131 .niv = 16, 132 }, 133 }; 134 135 136 static void test_ivgen(const void *opaque) 137 { 138 const struct QCryptoIVGenTestData *data = opaque; 139 g_autofree uint8_t *iv = g_new0(uint8_t, data->niv); 140 g_autoptr(QCryptoIVGen) ivgen = NULL; 141 142 if (!qcrypto_cipher_supports(data->cipheralg, 143 QCRYPTO_CIPHER_MODE_ECB)) { 144 return; 145 } 146 147 ivgen = qcrypto_ivgen_new( 148 data->ivalg, 149 data->cipheralg, 150 data->hashalg, 151 data->key, 152 data->nkey, 153 &error_abort); 154 155 qcrypto_ivgen_calculate(ivgen, 156 data->sector, 157 iv, 158 data->niv, 159 &error_abort); 160 161 g_assert(memcmp(iv, data->iv, data->niv) == 0); 162 } 163 164 int main(int argc, char **argv) 165 { 166 size_t i; 167 g_test_init(&argc, &argv, NULL); 168 for (i = 0; i < G_N_ELEMENTS(test_data); i++) { 169 if (test_data[i].ivalg == QCRYPTO_IV_GEN_ALGO_ESSIV && 170 !qcrypto_hash_supports(test_data[i].hashalg)) { 171 continue; 172 } 173 g_test_add_data_func(test_data[i].path, 174 &(test_data[i]), 175 test_ivgen); 176 } 177 return g_test_run(); 178 } 179