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