xref: /openbmc/qemu/tests/unit/test-crypto-ivgen.c (revision b91a0fa7)
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 
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_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