]> git.proxmox.com Git - mirror_qemu.git/blob - tests/unit/test-crypto-cipher.c
qapi: allow unions to contain further unions
[mirror_qemu.git] / tests / unit / test-crypto-cipher.c
1 /*
2 * QEMU Crypto cipher algorithms
3 *
4 * Copyright (c) 2015 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
23 #include "crypto/init.h"
24 #include "crypto/cipher.h"
25 #include "qapi/error.h"
26
27 typedef struct QCryptoCipherTestData QCryptoCipherTestData;
28 struct QCryptoCipherTestData {
29 const char *path;
30 QCryptoCipherAlgorithm alg;
31 QCryptoCipherMode mode;
32 const char *key;
33 const char *plaintext;
34 const char *ciphertext;
35 const char *iv;
36 };
37
38 /* AES test data comes from appendix F of:
39 *
40 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
41 */
42 static QCryptoCipherTestData test_data[] = {
43 {
44 /* NIST F.1.1 ECB-AES128.Encrypt */
45 .path = "/crypto/cipher/aes-ecb-128",
46 .alg = QCRYPTO_CIPHER_ALG_AES_128,
47 .mode = QCRYPTO_CIPHER_MODE_ECB,
48 .key = "2b7e151628aed2a6abf7158809cf4f3c",
49 .plaintext =
50 "6bc1bee22e409f96e93d7e117393172a"
51 "ae2d8a571e03ac9c9eb76fac45af8e51"
52 "30c81c46a35ce411e5fbc1191a0a52ef"
53 "f69f2445df4f9b17ad2b417be66c3710",
54 .ciphertext =
55 "3ad77bb40d7a3660a89ecaf32466ef97"
56 "f5d3d58503b9699de785895a96fdbaaf"
57 "43b1cd7f598ece23881b00e3ed030688"
58 "7b0c785e27e8ad3f8223207104725dd4"
59 },
60 {
61 /* NIST F.1.3 ECB-AES192.Encrypt */
62 .path = "/crypto/cipher/aes-ecb-192",
63 .alg = QCRYPTO_CIPHER_ALG_AES_192,
64 .mode = QCRYPTO_CIPHER_MODE_ECB,
65 .key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b",
66 .plaintext =
67 "6bc1bee22e409f96e93d7e117393172a"
68 "ae2d8a571e03ac9c9eb76fac45af8e51"
69 "30c81c46a35ce411e5fbc1191a0a52ef"
70 "f69f2445df4f9b17ad2b417be66c3710",
71 .ciphertext =
72 "bd334f1d6e45f25ff712a214571fa5cc"
73 "974104846d0ad3ad7734ecb3ecee4eef"
74 "ef7afd2270e2e60adce0ba2face6444e"
75 "9a4b41ba738d6c72fb16691603c18e0e"
76 },
77 {
78 /* NIST F.1.5 ECB-AES256.Encrypt */
79 .path = "/crypto/cipher/aes-ecb-256",
80 .alg = QCRYPTO_CIPHER_ALG_AES_256,
81 .mode = QCRYPTO_CIPHER_MODE_ECB,
82 .key =
83 "603deb1015ca71be2b73aef0857d7781"
84 "1f352c073b6108d72d9810a30914dff4",
85 .plaintext =
86 "6bc1bee22e409f96e93d7e117393172a"
87 "ae2d8a571e03ac9c9eb76fac45af8e51"
88 "30c81c46a35ce411e5fbc1191a0a52ef"
89 "f69f2445df4f9b17ad2b417be66c3710",
90 .ciphertext =
91 "f3eed1bdb5d2a03c064b5a7e3db181f8"
92 "591ccb10d410ed26dc5ba74a31362870"
93 "b6ed21b99ca6f4f9f153e7b1beafed1d"
94 "23304b7a39f9f3ff067d8d8f9e24ecc7",
95 },
96 {
97 /* NIST F.2.1 CBC-AES128.Encrypt */
98 .path = "/crypto/cipher/aes-cbc-128",
99 .alg = QCRYPTO_CIPHER_ALG_AES_128,
100 .mode = QCRYPTO_CIPHER_MODE_CBC,
101 .key = "2b7e151628aed2a6abf7158809cf4f3c",
102 .iv = "000102030405060708090a0b0c0d0e0f",
103 .plaintext =
104 "6bc1bee22e409f96e93d7e117393172a"
105 "ae2d8a571e03ac9c9eb76fac45af8e51"
106 "30c81c46a35ce411e5fbc1191a0a52ef"
107 "f69f2445df4f9b17ad2b417be66c3710",
108 .ciphertext =
109 "7649abac8119b246cee98e9b12e9197d"
110 "5086cb9b507219ee95db113a917678b2"
111 "73bed6b8e3c1743b7116e69e22229516"
112 "3ff1caa1681fac09120eca307586e1a7",
113 },
114 {
115 /* NIST F.2.3 CBC-AES128.Encrypt */
116 .path = "/crypto/cipher/aes-cbc-192",
117 .alg = QCRYPTO_CIPHER_ALG_AES_192,
118 .mode = QCRYPTO_CIPHER_MODE_CBC,
119 .key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b",
120 .iv = "000102030405060708090a0b0c0d0e0f",
121 .plaintext =
122 "6bc1bee22e409f96e93d7e117393172a"
123 "ae2d8a571e03ac9c9eb76fac45af8e51"
124 "30c81c46a35ce411e5fbc1191a0a52ef"
125 "f69f2445df4f9b17ad2b417be66c3710",
126 .ciphertext =
127 "4f021db243bc633d7178183a9fa071e8"
128 "b4d9ada9ad7dedf4e5e738763f69145a"
129 "571b242012fb7ae07fa9baac3df102e0"
130 "08b0e27988598881d920a9e64f5615cd",
131 },
132 {
133 /* NIST F.2.5 CBC-AES128.Encrypt */
134 .path = "/crypto/cipher/aes-cbc-256",
135 .alg = QCRYPTO_CIPHER_ALG_AES_256,
136 .mode = QCRYPTO_CIPHER_MODE_CBC,
137 .key =
138 "603deb1015ca71be2b73aef0857d7781"
139 "1f352c073b6108d72d9810a30914dff4",
140 .iv = "000102030405060708090a0b0c0d0e0f",
141 .plaintext =
142 "6bc1bee22e409f96e93d7e117393172a"
143 "ae2d8a571e03ac9c9eb76fac45af8e51"
144 "30c81c46a35ce411e5fbc1191a0a52ef"
145 "f69f2445df4f9b17ad2b417be66c3710",
146 .ciphertext =
147 "f58c4c04d6e5f1ba779eabfb5f7bfbd6"
148 "9cfc4e967edb808d679f777bc6702c7d"
149 "39f23369a9d9bacfa530e26304231461"
150 "b2eb05e2c39be9fcda6c19078c6a9d1b",
151 },
152 {
153 /*
154 * Testing 'password' as plaintext fits
155 * in single AES block, and gives identical
156 * ciphertext in ECB and CBC modes
157 */
158 .path = "/crypto/cipher/des-ecb-56-one-block",
159 .alg = QCRYPTO_CIPHER_ALG_DES,
160 .mode = QCRYPTO_CIPHER_MODE_ECB,
161 .key = "80c4a2e691d5b3f7",
162 .plaintext = "70617373776f7264",
163 .ciphertext = "73fa80b66134e403",
164 },
165 {
166 /* See previous comment */
167 .path = "/crypto/cipher/des-cbc-56-one-block",
168 .alg = QCRYPTO_CIPHER_ALG_DES,
169 .mode = QCRYPTO_CIPHER_MODE_CBC,
170 .key = "80c4a2e691d5b3f7",
171 .iv = "0000000000000000",
172 .plaintext = "70617373776f7264",
173 .ciphertext = "73fa80b66134e403",
174 },
175 {
176 .path = "/crypto/cipher/des-ecb-56",
177 .alg = QCRYPTO_CIPHER_ALG_DES,
178 .mode = QCRYPTO_CIPHER_MODE_ECB,
179 .key = "80c4a2e691d5b3f7",
180 .plaintext =
181 "6bc1bee22e409f96e93d7e117393172a"
182 "ae2d8a571e03ac9c9eb76fac45af8e51"
183 "30c81c46a35ce411e5fbc1191a0a52ef"
184 "f69f2445df4f9b17ad2b417be66c3710",
185 .ciphertext =
186 "8f346aaf64eaf24040720d80648c52e7"
187 "aefc616be53ab1a3d301e69d91e01838"
188 "ffd29f1bb5596ad94ea2d8e6196b7f09"
189 "30d8ed0bf2773af36dd82a6280c20926",
190 },
191 {
192 /* Borrowed from linux-kernel crypto/testmgr.h */
193 .path = "/crypto/cipher/3des-cbc",
194 .alg = QCRYPTO_CIPHER_ALG_3DES,
195 .mode = QCRYPTO_CIPHER_MODE_CBC,
196 .key =
197 "e9c0ff2e760b6424444d995a12d640c0"
198 "eac284e81495dbe8",
199 .iv =
200 "7d3388930f93b242",
201 .plaintext =
202 "6f54206f614d796e5320636565727374"
203 "54206f6f4d206e612079655372637465"
204 "20736f54206f614d796e532063656572"
205 "737454206f6f4d206e61207965537263"
206 "746520736f54206f614d796e53206365"
207 "6572737454206f6f4d206e6120796553"
208 "7263746520736f54206f614d796e5320"
209 "63656572737454206f6f4d206e610a79",
210 .ciphertext =
211 "0e2db6973c5633f4671721c76e8ad549"
212 "74b34905c51cd0ed12565c5396b6007d"
213 "9048fcf58d2939cc8ad5351836234ed7"
214 "76d1da0c9467bb048bf2036ca8cfb6ea"
215 "226447aa8f7513bf9fc2c3f0c956c57a"
216 "71632e897b1e12cae25fafd8a4f8c97a"
217 "d6f92131624445a6d6bc5ad32d5443cc"
218 "9ddea570e942458a6bfab19113b0d919",
219 },
220 {
221 /* Borrowed from linux-kernel crypto/testmgr.h */
222 .path = "/crypto/cipher/3des-ecb",
223 .alg = QCRYPTO_CIPHER_ALG_3DES,
224 .mode = QCRYPTO_CIPHER_MODE_ECB,
225 .key =
226 "0123456789abcdef5555555555555555"
227 "fedcba9876543210",
228 .plaintext =
229 "736f6d6564617461",
230 .ciphertext =
231 "18d748e563620572",
232 },
233 {
234 /* Borrowed from linux-kernel crypto/testmgr.h */
235 .path = "/crypto/cipher/3des-ctr",
236 .alg = QCRYPTO_CIPHER_ALG_3DES,
237 .mode = QCRYPTO_CIPHER_MODE_CTR,
238 .key =
239 "9cd6f39cb95a67005a67002dceeb2dce"
240 "ebb45172b451721f",
241 .iv =
242 "ffffffffffffffff",
243 .plaintext =
244 "05ec77fb42d559208b128669f05bcf56"
245 "39ad349f66ea7dc448d3ba0db118e34a"
246 "fe41285c278e11856cf75ec2553ca00b"
247 "9265e970db4fd6b900b41fe649fd442f"
248 "533a8d149863ca5dc1a833a70e9178ec"
249 "77de42d5bc078b12e54cf05b22563980"
250 "6b9f66c950c4af36ba0d947fe34add41"
251 "28b31a8e11f843f75e21553c876e9265"
252 "cc57dba235b900eb72e649d0442fb619"
253 "8d14ff46ca5d24a8339a6d9178c377de"
254 "a108bc07ee71e54cd75b22b51c806bf2"
255 "45c9503baf369960947fc64adda40fb3"
256 "1aed74f8432a5e218813876ef158cc57"
257 "3ea2359c67eb72c549d0bb02b619e04b"
258 "ff46295d248f169a6df45fc3aa3da108"
259 "937aee71d84cd7be01b51ce74ef2452c"
260 "503b82159960cb52c6a930a40f9679ed"
261 "74df432abd048813fa4df15823573e81"
262 "689c67ce51c5ac37bb02957ce04bd246"
263 "29b01b8f16f940f45f26aa3d846f937a"
264 "cd54d8a30abe01e873e74ed1452cb71e"
265 "8215fc47cb5225a9309b629679c074df"
266 "a609bd04ef76fa4dd458238a1d8168f3"
267 "5ace5138ac379e61957cc74bd2a50cb0"
268 "1be275f9402b5f268910846ff659cd54"
269 "3fa30a9d64e873da4ed1b803b71ee148"
270 "fc472e52258c179b62f55cc0ab32a609"
271 "907bef76d94dd4bf068a1de44ff35a2d"
272 "5138836a9e61c853c7ae31a50c977ee2"
273 "75dc402bb2058910fb42f65920543f86"
274 "699d64cf56daad34b803ea7de148d347",
275 .ciphertext =
276 "07c20820721f49ef19cd6f3253052215"
277 "a2852bdb85d2d8b9dd0d1b45cb6911d4"
278 "eabeb2455d0caebea0c127ac659f537e"
279 "afc21bb5b86d360c25c0f86d0b2901da"
280 "1378dc89121243faf612ef8d87627883"
281 "e2be41204c6d351bd10c30cfe2de2b03"
282 "bf4573d4e55995d1b39b276297bdde7f"
283 "a4d23980aa5023f074883da86a18793b"
284 "c4966c8d2240926ed6ad2a1fde63c0e7"
285 "07f72df7b5f3f0cc017c2a9bc210caaa"
286 "fd2b3fc5f3f6fc9b45db53e45bf3c97b"
287 "8e52ffc802b8ac9da10039da3d2d0e01"
288 "097d8d5ebe53b9b08ee7e2966ab278ea"
289 "de238ba5fa5ce3dabf8e316a55d16ab2"
290 "b5466fa5f0eeba1f9f98b0664fd03fa9"
291 "df5f58c4f4ff755c403a097e6e1c97d4"
292 "cce7e771cf0b150871fa0797cde6ca1d"
293 "14280ccf99137af1ebfafa9207de1da1"
294 "d33669fe514d9f2e83374f1f4830ed04"
295 "4da4ef3aca76f41c418f6337782f86a6"
296 "ef417ed2af88ab675271c38ef8269372"
297 "aad60ee70b46b13ab408a9a8a0cf200c"
298 "52bc8b0556b2bc319b74b92929969a50"
299 "dc45dc1aeb0c64d4d3057e5955c3f490"
300 "c2abf89b8adacea1c3f4ad77dd44c8ac"
301 "a3f1c9d2195cb0caa234c1f76cfdac65"
302 "32dc48c4f2006b77f17d76acc031632a"
303 "a53a62c891b10365cb43d106dfc367bc"
304 "dce0cd35ce4965a0527ba70d07a91bb0"
305 "407772c2ea0e3a7846b991b6e73d5142"
306 "fd51b0c62c6313785ceefccfc4700034",
307 },
308 {
309 /* RFC 2144, Appendix B.1 */
310 .path = "/crypto/cipher/cast5-128",
311 .alg = QCRYPTO_CIPHER_ALG_CAST5_128,
312 .mode = QCRYPTO_CIPHER_MODE_ECB,
313 .key = "0123456712345678234567893456789A",
314 .plaintext = "0123456789abcdef",
315 .ciphertext = "238b4fe5847e44b2",
316 },
317 {
318 /* libgcrypt serpent.c */
319 .path = "/crypto/cipher/serpent-128",
320 .alg = QCRYPTO_CIPHER_ALG_SERPENT_128,
321 .mode = QCRYPTO_CIPHER_MODE_ECB,
322 .key = "00000000000000000000000000000000",
323 .plaintext = "d29d576fcea3a3a7ed9099f29273d78e",
324 .ciphertext = "b2288b968ae8b08648d1ce9606fd992d",
325 },
326 {
327 /* libgcrypt serpent.c */
328 .path = "/crypto/cipher/serpent-192",
329 .alg = QCRYPTO_CIPHER_ALG_SERPENT_192,
330 .mode = QCRYPTO_CIPHER_MODE_ECB,
331 .key = "00000000000000000000000000000000"
332 "0000000000000000",
333 .plaintext = "d29d576fceaba3a7ed9899f2927bd78e",
334 .ciphertext = "130e353e1037c22405e8faefb2c3c3e9",
335 },
336 {
337 /* libgcrypt serpent.c */
338 .path = "/crypto/cipher/serpent-256a",
339 .alg = QCRYPTO_CIPHER_ALG_SERPENT_256,
340 .mode = QCRYPTO_CIPHER_MODE_ECB,
341 .key = "00000000000000000000000000000000"
342 "00000000000000000000000000000000",
343 .plaintext = "d095576fcea3e3a7ed98d9f29073d78e",
344 .ciphertext = "b90ee5862de69168f2bdd5125b45472b",
345 },
346 {
347 /* libgcrypt serpent.c */
348 .path = "/crypto/cipher/serpent-256b",
349 .alg = QCRYPTO_CIPHER_ALG_SERPENT_256,
350 .mode = QCRYPTO_CIPHER_MODE_ECB,
351 .key = "00000000000000000000000000000000"
352 "00000000000000000000000000000000",
353 .plaintext = "00000000010000000200000003000000",
354 .ciphertext = "2061a42782bd52ec691ec383b03ba77c",
355 },
356 {
357 /* Twofish paper "Known Answer Test" */
358 .path = "/crypto/cipher/twofish-128",
359 .alg = QCRYPTO_CIPHER_ALG_TWOFISH_128,
360 .mode = QCRYPTO_CIPHER_MODE_ECB,
361 .key = "d491db16e7b1c39e86cb086b789f5419",
362 .plaintext = "019f9809de1711858faac3a3ba20fbc3",
363 .ciphertext = "6363977de839486297e661c6c9d668eb",
364 },
365 {
366 /* Twofish paper "Known Answer Test", I=3 */
367 .path = "/crypto/cipher/twofish-192",
368 .alg = QCRYPTO_CIPHER_ALG_TWOFISH_192,
369 .mode = QCRYPTO_CIPHER_MODE_ECB,
370 .key = "88b2b2706b105e36b446bb6d731a1e88"
371 "efa71f788965bd44",
372 .plaintext = "39da69d6ba4997d585b6dc073ca341b2",
373 .ciphertext = "182b02d81497ea45f9daacdc29193a65",
374 },
375 {
376 /* Twofish paper "Known Answer Test", I=4 */
377 .path = "/crypto/cipher/twofish-256",
378 .alg = QCRYPTO_CIPHER_ALG_TWOFISH_256,
379 .mode = QCRYPTO_CIPHER_MODE_ECB,
380 .key = "d43bb7556ea32e46f2a282b7d45b4e0d"
381 "57ff739d4dc92c1bd7fc01700cc8216f",
382 .plaintext = "90afe91bb288544f2c32dc239b2635e6",
383 .ciphertext = "6cb4561c40bf0a9705931cb6d408e7fa",
384 },
385 {
386 /* #1 32 byte key, 32 byte PTX */
387 .path = "/crypto/cipher/aes-xts-128-1",
388 .alg = QCRYPTO_CIPHER_ALG_AES_128,
389 .mode = QCRYPTO_CIPHER_MODE_XTS,
390 .key =
391 "00000000000000000000000000000000"
392 "00000000000000000000000000000000",
393 .iv =
394 "00000000000000000000000000000000",
395 .plaintext =
396 "00000000000000000000000000000000"
397 "00000000000000000000000000000000",
398 .ciphertext =
399 "917cf69ebd68b2ec9b9fe9a3eadda692"
400 "cd43d2f59598ed858c02c2652fbf922e",
401 },
402 {
403 /* #2, 32 byte key, 32 byte PTX */
404 .path = "/crypto/cipher/aes-xts-128-2",
405 .alg = QCRYPTO_CIPHER_ALG_AES_128,
406 .mode = QCRYPTO_CIPHER_MODE_XTS,
407 .key =
408 "11111111111111111111111111111111"
409 "22222222222222222222222222222222",
410 .iv =
411 "33333333330000000000000000000000",
412 .plaintext =
413 "44444444444444444444444444444444"
414 "44444444444444444444444444444444",
415 .ciphertext =
416 "c454185e6a16936e39334038acef838b"
417 "fb186fff7480adc4289382ecd6d394f0",
418 },
419 {
420 /* #5 from xts.7, 32 byte key, 32 byte PTX */
421 .path = "/crypto/cipher/aes-xts-128-3",
422 .alg = QCRYPTO_CIPHER_ALG_AES_128,
423 .mode = QCRYPTO_CIPHER_MODE_XTS,
424 .key =
425 "fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0"
426 "bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0",
427 .iv =
428 "9a785634120000000000000000000000",
429 .plaintext =
430 "44444444444444444444444444444444"
431 "44444444444444444444444444444444",
432 .ciphertext =
433 "b01f86f8edc1863706fa8a4253e34f28"
434 "af319de38334870f4dd1f94cbe9832f1",
435 },
436 {
437 /* #4, 32 byte key, 512 byte PTX */
438 .path = "/crypto/cipher/aes-xts-128-4",
439 .alg = QCRYPTO_CIPHER_ALG_AES_128,
440 .mode = QCRYPTO_CIPHER_MODE_XTS,
441 .key =
442 "27182818284590452353602874713526"
443 "31415926535897932384626433832795",
444 .iv =
445 "00000000000000000000000000000000",
446 .plaintext =
447 "000102030405060708090a0b0c0d0e0f"
448 "101112131415161718191a1b1c1d1e1f"
449 "202122232425262728292a2b2c2d2e2f"
450 "303132333435363738393a3b3c3d3e3f"
451 "404142434445464748494a4b4c4d4e4f"
452 "505152535455565758595a5b5c5d5e5f"
453 "606162636465666768696a6b6c6d6e6f"
454 "707172737475767778797a7b7c7d7e7f"
455 "808182838485868788898a8b8c8d8e8f"
456 "909192939495969798999a9b9c9d9e9f"
457 "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
458 "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
459 "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
460 "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
461 "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
462 "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"
463 "000102030405060708090a0b0c0d0e0f"
464 "101112131415161718191a1b1c1d1e1f"
465 "202122232425262728292a2b2c2d2e2f"
466 "303132333435363738393a3b3c3d3e3f"
467 "404142434445464748494a4b4c4d4e4f"
468 "505152535455565758595a5b5c5d5e5f"
469 "606162636465666768696a6b6c6d6e6f"
470 "707172737475767778797a7b7c7d7e7f"
471 "808182838485868788898a8b8c8d8e8f"
472 "909192939495969798999a9b9c9d9e9f"
473 "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
474 "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
475 "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
476 "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
477 "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
478 "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
479 .ciphertext =
480 "27a7479befa1d476489f308cd4cfa6e2"
481 "a96e4bbe3208ff25287dd3819616e89c"
482 "c78cf7f5e543445f8333d8fa7f560000"
483 "05279fa5d8b5e4ad40e736ddb4d35412"
484 "328063fd2aab53e5ea1e0a9f332500a5"
485 "df9487d07a5c92cc512c8866c7e860ce"
486 "93fdf166a24912b422976146ae20ce84"
487 "6bb7dc9ba94a767aaef20c0d61ad0265"
488 "5ea92dc4c4e41a8952c651d33174be51"
489 "a10c421110e6d81588ede82103a252d8"
490 "a750e8768defffed9122810aaeb99f91"
491 "72af82b604dc4b8e51bcb08235a6f434"
492 "1332e4ca60482a4ba1a03b3e65008fc5"
493 "da76b70bf1690db4eae29c5f1badd03c"
494 "5ccf2a55d705ddcd86d449511ceb7ec3"
495 "0bf12b1fa35b913f9f747a8afd1b130e"
496 "94bff94effd01a91735ca1726acd0b19"
497 "7c4e5b03393697e126826fb6bbde8ecc"
498 "1e08298516e2c9ed03ff3c1b7860f6de"
499 "76d4cecd94c8119855ef5297ca67e9f3"
500 "e7ff72b1e99785ca0a7e7720c5b36dc6"
501 "d72cac9574c8cbbc2f801e23e56fd344"
502 "b07f22154beba0f08ce8891e643ed995"
503 "c94d9a69c9f1b5f499027a78572aeebd"
504 "74d20cc39881c213ee770b1010e4bea7"
505 "18846977ae119f7a023ab58cca0ad752"
506 "afe656bb3c17256a9f6e9bf19fdd5a38"
507 "fc82bbe872c5539edb609ef4f79c203e"
508 "bb140f2e583cb2ad15b4aa5b655016a8"
509 "449277dbd477ef2c8d6c017db738b18d"
510 "eb4a427d1923ce3ff262735779a418f2"
511 "0a282df920147beabe421ee5319d0568",
512 },
513 {
514 /* Bad config - cast5-128 has 8 byte block size
515 * which is incompatible with XTS
516 */
517 .path = "/crypto/cipher/cast5-xts-128",
518 .alg = QCRYPTO_CIPHER_ALG_CAST5_128,
519 .mode = QCRYPTO_CIPHER_MODE_XTS,
520 .key =
521 "27182818284590452353602874713526"
522 "31415926535897932384626433832795",
523 },
524 {
525 /* NIST F.5.1 CTR-AES128.Encrypt */
526 .path = "/crypto/cipher/aes-ctr-128",
527 .alg = QCRYPTO_CIPHER_ALG_AES_128,
528 .mode = QCRYPTO_CIPHER_MODE_CTR,
529 .key = "2b7e151628aed2a6abf7158809cf4f3c",
530 .iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
531 .plaintext =
532 "6bc1bee22e409f96e93d7e117393172a"
533 "ae2d8a571e03ac9c9eb76fac45af8e51"
534 "30c81c46a35ce411e5fbc1191a0a52ef"
535 "f69f2445df4f9b17ad2b417be66c3710",
536 .ciphertext =
537 "874d6191b620e3261bef6864990db6ce"
538 "9806f66b7970fdff8617187bb9fffdff"
539 "5ae4df3edbd5d35e5b4f09020db03eab"
540 "1e031dda2fbe03d1792170a0f3009cee",
541 },
542 {
543 /* NIST F.5.3 CTR-AES192.Encrypt */
544 .path = "/crypto/cipher/aes-ctr-192",
545 .alg = QCRYPTO_CIPHER_ALG_AES_192,
546 .mode = QCRYPTO_CIPHER_MODE_CTR,
547 .key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b",
548 .iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
549 .plaintext =
550 "6bc1bee22e409f96e93d7e117393172a"
551 "ae2d8a571e03ac9c9eb76fac45af8e51"
552 "30c81c46a35ce411e5fbc1191a0a52ef"
553 "f69f2445df4f9b17ad2b417be66c3710",
554 .ciphertext =
555 "1abc932417521ca24f2b0459fe7e6e0b"
556 "090339ec0aa6faefd5ccc2c6f4ce8e94"
557 "1e36b26bd1ebc670d1bd1d665620abf7"
558 "4f78a7f6d29809585a97daec58c6b050",
559 },
560 {
561 /* NIST F.5.5 CTR-AES256.Encrypt */
562 .path = "/crypto/cipher/aes-ctr-256",
563 .alg = QCRYPTO_CIPHER_ALG_AES_256,
564 .mode = QCRYPTO_CIPHER_MODE_CTR,
565 .key = "603deb1015ca71be2b73aef0857d7781"
566 "1f352c073b6108d72d9810a30914dff4",
567 .iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
568 .plaintext =
569 "6bc1bee22e409f96e93d7e117393172a"
570 "ae2d8a571e03ac9c9eb76fac45af8e51"
571 "30c81c46a35ce411e5fbc1191a0a52ef"
572 "f69f2445df4f9b17ad2b417be66c3710",
573 .ciphertext =
574 "601ec313775789a5b7a7f504bbf3d228"
575 "f443e3ca4d62b59aca84e990cacaf5c5"
576 "2b0930daa23de94ce87017ba2d84988d"
577 "dfc9c58db67aada613c2dd08457941a6",
578 }
579 };
580
581
582 static inline int unhex(char c)
583 {
584 if (c >= 'a' && c <= 'f') {
585 return 10 + (c - 'a');
586 }
587 if (c >= 'A' && c <= 'F') {
588 return 10 + (c - 'A');
589 }
590 return c - '0';
591 }
592
593 static inline char hex(int i)
594 {
595 if (i < 10) {
596 return '0' + i;
597 }
598 return 'a' + (i - 10);
599 }
600
601 static size_t unhex_string(const char *hexstr,
602 uint8_t **data)
603 {
604 size_t len;
605 size_t i;
606
607 if (!hexstr) {
608 *data = NULL;
609 return 0;
610 }
611
612 len = strlen(hexstr);
613 *data = g_new0(uint8_t, len / 2);
614
615 for (i = 0; i < len; i += 2) {
616 (*data)[i/2] = (unhex(hexstr[i]) << 4) | unhex(hexstr[i+1]);
617 }
618 return len / 2;
619 }
620
621 static char *hex_string(const uint8_t *bytes,
622 size_t len)
623 {
624 char *hexstr = g_new0(char, len * 2 + 1);
625 size_t i;
626
627 for (i = 0; i < len; i++) {
628 hexstr[i*2] = hex((bytes[i] >> 4) & 0xf);
629 hexstr[i*2+1] = hex(bytes[i] & 0xf);
630 }
631 hexstr[len*2] = '\0';
632
633 return hexstr;
634 }
635
636 static void test_cipher(const void *opaque)
637 {
638 const QCryptoCipherTestData *data = opaque;
639
640 QCryptoCipher *cipher;
641 uint8_t *key, *iv = NULL, *ciphertext = NULL,
642 *plaintext = NULL, *outtext = NULL;
643 size_t nkey, niv = 0, nciphertext = 0, nplaintext = 0;
644 char *outtexthex = NULL;
645 size_t ivsize, keysize, blocksize;
646 Error *err = NULL;
647
648 nkey = unhex_string(data->key, &key);
649 if (data->iv) {
650 niv = unhex_string(data->iv, &iv);
651 }
652 if (data->ciphertext) {
653 nciphertext = unhex_string(data->ciphertext, &ciphertext);
654 }
655 if (data->plaintext) {
656 nplaintext = unhex_string(data->plaintext, &plaintext);
657 }
658
659 g_assert(nciphertext == nplaintext);
660
661 outtext = g_new0(uint8_t, nciphertext);
662
663 cipher = qcrypto_cipher_new(
664 data->alg, data->mode,
665 key, nkey,
666 &err);
667 if (data->plaintext) {
668 g_assert(err == NULL);
669 g_assert(cipher != NULL);
670 } else {
671 error_free_or_abort(&err);
672 g_assert(cipher == NULL);
673 goto cleanup;
674 }
675
676 keysize = qcrypto_cipher_get_key_len(data->alg);
677 blocksize = qcrypto_cipher_get_block_len(data->alg);
678 ivsize = qcrypto_cipher_get_iv_len(data->alg, data->mode);
679
680 if (data->mode == QCRYPTO_CIPHER_MODE_XTS) {
681 g_assert_cmpint(keysize * 2, ==, nkey);
682 } else {
683 g_assert_cmpint(keysize, ==, nkey);
684 }
685 g_assert_cmpint(ivsize, ==, niv);
686 if (niv) {
687 g_assert_cmpint(blocksize, ==, niv);
688 }
689
690 if (iv) {
691 g_assert(qcrypto_cipher_setiv(cipher,
692 iv, niv,
693 &error_abort) == 0);
694 }
695 g_assert(qcrypto_cipher_encrypt(cipher,
696 plaintext,
697 outtext,
698 nplaintext,
699 &error_abort) == 0);
700
701 outtexthex = hex_string(outtext, nciphertext);
702
703 g_assert_cmpstr(outtexthex, ==, data->ciphertext);
704
705 g_free(outtexthex);
706
707 if (iv) {
708 g_assert(qcrypto_cipher_setiv(cipher,
709 iv, niv,
710 &error_abort) == 0);
711 }
712 g_assert(qcrypto_cipher_decrypt(cipher,
713 ciphertext,
714 outtext,
715 nplaintext,
716 &error_abort) == 0);
717
718 outtexthex = hex_string(outtext, nplaintext);
719
720 g_assert_cmpstr(outtexthex, ==, data->plaintext);
721
722 cleanup:
723 g_free(outtext);
724 g_free(outtexthex);
725 g_free(key);
726 g_free(iv);
727 g_free(ciphertext);
728 g_free(plaintext);
729 qcrypto_cipher_free(cipher);
730 }
731
732
733 static void test_cipher_null_iv(void)
734 {
735 QCryptoCipher *cipher;
736 uint8_t key[32] = { 0 };
737 uint8_t plaintext[32] = { 0 };
738 uint8_t ciphertext[32] = { 0 };
739
740 cipher = qcrypto_cipher_new(
741 QCRYPTO_CIPHER_ALG_AES_256,
742 QCRYPTO_CIPHER_MODE_CBC,
743 key, sizeof(key),
744 &error_abort);
745 g_assert(cipher != NULL);
746
747 /* Don't call qcrypto_cipher_setiv */
748
749 qcrypto_cipher_encrypt(cipher,
750 plaintext,
751 ciphertext,
752 sizeof(plaintext),
753 &error_abort);
754
755 qcrypto_cipher_free(cipher);
756 }
757
758 static void test_cipher_short_plaintext(void)
759 {
760 Error *err = NULL;
761 QCryptoCipher *cipher;
762 uint8_t key[32] = { 0 };
763 uint8_t plaintext1[20] = { 0 };
764 uint8_t ciphertext1[20] = { 0 };
765 uint8_t plaintext2[40] = { 0 };
766 uint8_t ciphertext2[40] = { 0 };
767 int ret;
768
769 cipher = qcrypto_cipher_new(
770 QCRYPTO_CIPHER_ALG_AES_256,
771 QCRYPTO_CIPHER_MODE_CBC,
772 key, sizeof(key),
773 &error_abort);
774 g_assert(cipher != NULL);
775
776 /* Should report an error as plaintext is shorter
777 * than block size
778 */
779 ret = qcrypto_cipher_encrypt(cipher,
780 plaintext1,
781 ciphertext1,
782 sizeof(plaintext1),
783 &err);
784 g_assert(ret == -1);
785 error_free_or_abort(&err);
786
787 /* Should report an error as plaintext is larger than
788 * block size, but not a multiple of block size
789 */
790 ret = qcrypto_cipher_encrypt(cipher,
791 plaintext2,
792 ciphertext2,
793 sizeof(plaintext2),
794 &err);
795 g_assert(ret == -1);
796 error_free_or_abort(&err);
797
798 qcrypto_cipher_free(cipher);
799 }
800
801 int main(int argc, char **argv)
802 {
803 size_t i;
804
805 g_test_init(&argc, &argv, NULL);
806
807 g_assert(qcrypto_init(NULL) == 0);
808
809 for (i = 0; i < G_N_ELEMENTS(test_data); i++) {
810 if (qcrypto_cipher_supports(test_data[i].alg, test_data[i].mode)) {
811 g_test_add_data_func(test_data[i].path, &test_data[i], test_cipher);
812 }
813 }
814
815 g_test_add_func("/crypto/cipher/null-iv",
816 test_cipher_null_iv);
817
818 g_test_add_func("/crypto/cipher/short-plaintext",
819 test_cipher_short_plaintext);
820
821 return g_test_run();
822 }