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 QCryptoIVGenAlgorithm ivalg;
30 QCryptoHashAlgorithm hashalg;
31 QCryptoCipherAlgorithm 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_IVGEN_ALG_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_IVGEN_ALG_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_IVGEN_ALG_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_IVGEN_ALG_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_IVGEN_ALG_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_IVGEN_ALG_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_IVGEN_ALG_ESSIV,
96 .cipheralg = QCRYPTO_CIPHER_ALG_AES_128,
97 .hashalg = QCRYPTO_HASH_ALG_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_IVGEN_ALG_ESSIV,
110 .cipheralg = QCRYPTO_CIPHER_ALG_AES_128,
111 .hashalg = QCRYPTO_HASH_ALG_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_IVGEN_ALG_ESSIV,
124 .cipheralg = QCRYPTO_CIPHER_ALG_AES_128,
125 .hashalg = QCRYPTO_HASH_ALG_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
test_ivgen(const void * opaque)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
main(int argc,char ** argv)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_IVGEN_ALG_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