xref: /qemu/tests/unit/test-crypto-cipher.c (revision a0e93dd8)
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 #ifdef CONFIG_CRYPTO_SM4
386     {
387         /* SM4, GB/T 32907-2016, Appendix A.1 */
388         .path = "/crypto/cipher/sm4",
389         .alg = QCRYPTO_CIPHER_ALG_SM4,
390         .mode = QCRYPTO_CIPHER_MODE_ECB,
391         .key = "0123456789abcdeffedcba9876543210",
392         .plaintext  =
393             "0123456789abcdeffedcba9876543210",
394         .ciphertext =
395             "681edf34d206965e86b3e94f536e4246",
396     },
397 #endif
398     {
399         /* #1 32 byte key, 32 byte PTX */
400         .path = "/crypto/cipher/aes-xts-128-1",
401         .alg = QCRYPTO_CIPHER_ALG_AES_128,
402         .mode = QCRYPTO_CIPHER_MODE_XTS,
403         .key =
404             "00000000000000000000000000000000"
405             "00000000000000000000000000000000",
406         .iv =
407             "00000000000000000000000000000000",
408         .plaintext =
409             "00000000000000000000000000000000"
410             "00000000000000000000000000000000",
411         .ciphertext =
412             "917cf69ebd68b2ec9b9fe9a3eadda692"
413             "cd43d2f59598ed858c02c2652fbf922e",
414     },
415     {
416         /* #2, 32 byte key, 32 byte PTX */
417         .path = "/crypto/cipher/aes-xts-128-2",
418         .alg = QCRYPTO_CIPHER_ALG_AES_128,
419         .mode = QCRYPTO_CIPHER_MODE_XTS,
420         .key =
421             "11111111111111111111111111111111"
422             "22222222222222222222222222222222",
423         .iv =
424             "33333333330000000000000000000000",
425         .plaintext =
426             "44444444444444444444444444444444"
427             "44444444444444444444444444444444",
428         .ciphertext =
429             "c454185e6a16936e39334038acef838b"
430             "fb186fff7480adc4289382ecd6d394f0",
431     },
432     {
433         /* #5 from xts.7, 32 byte key, 32 byte PTX */
434         .path = "/crypto/cipher/aes-xts-128-3",
435         .alg = QCRYPTO_CIPHER_ALG_AES_128,
436         .mode = QCRYPTO_CIPHER_MODE_XTS,
437         .key =
438             "fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0"
439             "bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0",
440         .iv =
441             "9a785634120000000000000000000000",
442         .plaintext =
443             "44444444444444444444444444444444"
444             "44444444444444444444444444444444",
445         .ciphertext =
446             "b01f86f8edc1863706fa8a4253e34f28"
447             "af319de38334870f4dd1f94cbe9832f1",
448     },
449     {
450         /* #4, 32 byte key, 512 byte PTX  */
451         .path = "/crypto/cipher/aes-xts-128-4",
452         .alg = QCRYPTO_CIPHER_ALG_AES_128,
453         .mode = QCRYPTO_CIPHER_MODE_XTS,
454         .key =
455             "27182818284590452353602874713526"
456             "31415926535897932384626433832795",
457         .iv =
458             "00000000000000000000000000000000",
459         .plaintext =
460             "000102030405060708090a0b0c0d0e0f"
461             "101112131415161718191a1b1c1d1e1f"
462             "202122232425262728292a2b2c2d2e2f"
463             "303132333435363738393a3b3c3d3e3f"
464             "404142434445464748494a4b4c4d4e4f"
465             "505152535455565758595a5b5c5d5e5f"
466             "606162636465666768696a6b6c6d6e6f"
467             "707172737475767778797a7b7c7d7e7f"
468             "808182838485868788898a8b8c8d8e8f"
469             "909192939495969798999a9b9c9d9e9f"
470             "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
471             "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
472             "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
473             "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
474             "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
475             "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"
476             "000102030405060708090a0b0c0d0e0f"
477             "101112131415161718191a1b1c1d1e1f"
478             "202122232425262728292a2b2c2d2e2f"
479             "303132333435363738393a3b3c3d3e3f"
480             "404142434445464748494a4b4c4d4e4f"
481             "505152535455565758595a5b5c5d5e5f"
482             "606162636465666768696a6b6c6d6e6f"
483             "707172737475767778797a7b7c7d7e7f"
484             "808182838485868788898a8b8c8d8e8f"
485             "909192939495969798999a9b9c9d9e9f"
486             "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
487             "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
488             "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
489             "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
490             "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
491             "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
492         .ciphertext =
493             "27a7479befa1d476489f308cd4cfa6e2"
494             "a96e4bbe3208ff25287dd3819616e89c"
495             "c78cf7f5e543445f8333d8fa7f560000"
496             "05279fa5d8b5e4ad40e736ddb4d35412"
497             "328063fd2aab53e5ea1e0a9f332500a5"
498             "df9487d07a5c92cc512c8866c7e860ce"
499             "93fdf166a24912b422976146ae20ce84"
500             "6bb7dc9ba94a767aaef20c0d61ad0265"
501             "5ea92dc4c4e41a8952c651d33174be51"
502             "a10c421110e6d81588ede82103a252d8"
503             "a750e8768defffed9122810aaeb99f91"
504             "72af82b604dc4b8e51bcb08235a6f434"
505             "1332e4ca60482a4ba1a03b3e65008fc5"
506             "da76b70bf1690db4eae29c5f1badd03c"
507             "5ccf2a55d705ddcd86d449511ceb7ec3"
508             "0bf12b1fa35b913f9f747a8afd1b130e"
509             "94bff94effd01a91735ca1726acd0b19"
510             "7c4e5b03393697e126826fb6bbde8ecc"
511             "1e08298516e2c9ed03ff3c1b7860f6de"
512             "76d4cecd94c8119855ef5297ca67e9f3"
513             "e7ff72b1e99785ca0a7e7720c5b36dc6"
514             "d72cac9574c8cbbc2f801e23e56fd344"
515             "b07f22154beba0f08ce8891e643ed995"
516             "c94d9a69c9f1b5f499027a78572aeebd"
517             "74d20cc39881c213ee770b1010e4bea7"
518             "18846977ae119f7a023ab58cca0ad752"
519             "afe656bb3c17256a9f6e9bf19fdd5a38"
520             "fc82bbe872c5539edb609ef4f79c203e"
521             "bb140f2e583cb2ad15b4aa5b655016a8"
522             "449277dbd477ef2c8d6c017db738b18d"
523             "eb4a427d1923ce3ff262735779a418f2"
524             "0a282df920147beabe421ee5319d0568",
525     },
526     {
527         /* Bad config - cast5-128 has 8 byte block size
528          * which is incompatible with XTS
529          */
530         .path = "/crypto/cipher/cast5-xts-128",
531         .alg = QCRYPTO_CIPHER_ALG_CAST5_128,
532         .mode = QCRYPTO_CIPHER_MODE_XTS,
533         .key =
534             "27182818284590452353602874713526"
535             "31415926535897932384626433832795",
536     },
537     {
538         /* NIST F.5.1 CTR-AES128.Encrypt */
539         .path = "/crypto/cipher/aes-ctr-128",
540         .alg = QCRYPTO_CIPHER_ALG_AES_128,
541         .mode = QCRYPTO_CIPHER_MODE_CTR,
542         .key = "2b7e151628aed2a6abf7158809cf4f3c",
543         .iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
544         .plaintext  =
545             "6bc1bee22e409f96e93d7e117393172a"
546             "ae2d8a571e03ac9c9eb76fac45af8e51"
547             "30c81c46a35ce411e5fbc1191a0a52ef"
548             "f69f2445df4f9b17ad2b417be66c3710",
549         .ciphertext =
550             "874d6191b620e3261bef6864990db6ce"
551             "9806f66b7970fdff8617187bb9fffdff"
552             "5ae4df3edbd5d35e5b4f09020db03eab"
553             "1e031dda2fbe03d1792170a0f3009cee",
554     },
555     {
556         /* NIST F.5.3 CTR-AES192.Encrypt */
557         .path = "/crypto/cipher/aes-ctr-192",
558         .alg = QCRYPTO_CIPHER_ALG_AES_192,
559         .mode = QCRYPTO_CIPHER_MODE_CTR,
560         .key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b",
561         .iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
562         .plaintext  =
563             "6bc1bee22e409f96e93d7e117393172a"
564             "ae2d8a571e03ac9c9eb76fac45af8e51"
565             "30c81c46a35ce411e5fbc1191a0a52ef"
566             "f69f2445df4f9b17ad2b417be66c3710",
567         .ciphertext =
568             "1abc932417521ca24f2b0459fe7e6e0b"
569             "090339ec0aa6faefd5ccc2c6f4ce8e94"
570             "1e36b26bd1ebc670d1bd1d665620abf7"
571             "4f78a7f6d29809585a97daec58c6b050",
572     },
573     {
574         /* NIST F.5.5 CTR-AES256.Encrypt */
575         .path = "/crypto/cipher/aes-ctr-256",
576         .alg = QCRYPTO_CIPHER_ALG_AES_256,
577         .mode = QCRYPTO_CIPHER_MODE_CTR,
578         .key = "603deb1015ca71be2b73aef0857d7781"
579                "1f352c073b6108d72d9810a30914dff4",
580         .iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
581         .plaintext  =
582             "6bc1bee22e409f96e93d7e117393172a"
583             "ae2d8a571e03ac9c9eb76fac45af8e51"
584             "30c81c46a35ce411e5fbc1191a0a52ef"
585             "f69f2445df4f9b17ad2b417be66c3710",
586         .ciphertext =
587             "601ec313775789a5b7a7f504bbf3d228"
588             "f443e3ca4d62b59aca84e990cacaf5c5"
589             "2b0930daa23de94ce87017ba2d84988d"
590             "dfc9c58db67aada613c2dd08457941a6",
591     }
592 };
593 
594 
595 static inline int unhex(char c)
596 {
597     if (c >= 'a' && c <= 'f') {
598         return 10 + (c - 'a');
599     }
600     if (c >= 'A' && c <= 'F') {
601         return 10 + (c - 'A');
602     }
603     return c - '0';
604 }
605 
606 static inline char hex(int i)
607 {
608     if (i < 10) {
609         return '0' + i;
610     }
611     return 'a' + (i - 10);
612 }
613 
614 static size_t unhex_string(const char *hexstr,
615                            uint8_t **data)
616 {
617     size_t len;
618     size_t i;
619 
620     if (!hexstr) {
621         *data = NULL;
622         return 0;
623     }
624 
625     len = strlen(hexstr);
626     *data = g_new0(uint8_t, len / 2);
627 
628     for (i = 0; i < len; i += 2) {
629         (*data)[i/2] = (unhex(hexstr[i]) << 4) | unhex(hexstr[i+1]);
630     }
631     return len / 2;
632 }
633 
634 static char *hex_string(const uint8_t *bytes,
635                         size_t len)
636 {
637     char *hexstr = g_new0(char, len * 2 + 1);
638     size_t i;
639 
640     for (i = 0; i < len; i++) {
641         hexstr[i*2] = hex((bytes[i] >> 4) & 0xf);
642         hexstr[i*2+1] = hex(bytes[i] & 0xf);
643     }
644     hexstr[len*2] = '\0';
645 
646     return hexstr;
647 }
648 
649 static void test_cipher(const void *opaque)
650 {
651     const QCryptoCipherTestData *data = opaque;
652 
653     QCryptoCipher *cipher;
654     uint8_t *key, *iv = NULL, *ciphertext = NULL,
655         *plaintext = NULL, *outtext = NULL;
656     size_t nkey, niv = 0, nciphertext = 0, nplaintext = 0;
657     char *outtexthex = NULL;
658     size_t ivsize, keysize, blocksize;
659     Error *err = NULL;
660 
661     nkey = unhex_string(data->key, &key);
662     if (data->iv) {
663         niv = unhex_string(data->iv, &iv);
664     }
665     if (data->ciphertext) {
666         nciphertext = unhex_string(data->ciphertext, &ciphertext);
667     }
668     if (data->plaintext) {
669         nplaintext = unhex_string(data->plaintext, &plaintext);
670     }
671 
672     g_assert(nciphertext == nplaintext);
673 
674     outtext = g_new0(uint8_t, nciphertext);
675 
676     cipher = qcrypto_cipher_new(
677         data->alg, data->mode,
678         key, nkey,
679         &err);
680     if (data->plaintext) {
681         g_assert(err == NULL);
682         g_assert(cipher != NULL);
683     } else {
684         error_free_or_abort(&err);
685         g_assert(cipher == NULL);
686         goto cleanup;
687     }
688 
689     keysize = qcrypto_cipher_get_key_len(data->alg);
690     blocksize = qcrypto_cipher_get_block_len(data->alg);
691     ivsize = qcrypto_cipher_get_iv_len(data->alg, data->mode);
692 
693     if (data->mode == QCRYPTO_CIPHER_MODE_XTS) {
694         g_assert_cmpint(keysize * 2, ==, nkey);
695     } else {
696         g_assert_cmpint(keysize, ==, nkey);
697     }
698     g_assert_cmpint(ivsize, ==, niv);
699     if (niv) {
700         g_assert_cmpint(blocksize, ==, niv);
701     }
702 
703     if (iv) {
704         g_assert(qcrypto_cipher_setiv(cipher,
705                                       iv, niv,
706                                       &error_abort) == 0);
707     }
708     g_assert(qcrypto_cipher_encrypt(cipher,
709                                     plaintext,
710                                     outtext,
711                                     nplaintext,
712                                     &error_abort) == 0);
713 
714     outtexthex = hex_string(outtext, nciphertext);
715 
716     g_assert_cmpstr(outtexthex, ==, data->ciphertext);
717 
718     g_free(outtexthex);
719 
720     if (iv) {
721         g_assert(qcrypto_cipher_setiv(cipher,
722                                       iv, niv,
723                                       &error_abort) == 0);
724     }
725     g_assert(qcrypto_cipher_decrypt(cipher,
726                                     ciphertext,
727                                     outtext,
728                                     nplaintext,
729                                     &error_abort) == 0);
730 
731     outtexthex = hex_string(outtext, nplaintext);
732 
733     g_assert_cmpstr(outtexthex, ==, data->plaintext);
734 
735  cleanup:
736     g_free(outtext);
737     g_free(outtexthex);
738     g_free(key);
739     g_free(iv);
740     g_free(ciphertext);
741     g_free(plaintext);
742     qcrypto_cipher_free(cipher);
743 }
744 
745 
746 static void test_cipher_null_iv(void)
747 {
748     QCryptoCipher *cipher;
749     uint8_t key[32] = { 0 };
750     uint8_t plaintext[32] = { 0 };
751     uint8_t ciphertext[32] = { 0 };
752 
753     cipher = qcrypto_cipher_new(
754         QCRYPTO_CIPHER_ALG_AES_256,
755         QCRYPTO_CIPHER_MODE_CBC,
756         key, sizeof(key),
757         &error_abort);
758     g_assert(cipher != NULL);
759 
760     /* Don't call qcrypto_cipher_setiv */
761 
762     qcrypto_cipher_encrypt(cipher,
763                            plaintext,
764                            ciphertext,
765                            sizeof(plaintext),
766                            &error_abort);
767 
768     qcrypto_cipher_free(cipher);
769 }
770 
771 static void test_cipher_short_plaintext(void)
772 {
773     Error *err = NULL;
774     QCryptoCipher *cipher;
775     uint8_t key[32] = { 0 };
776     uint8_t plaintext1[20] = { 0 };
777     uint8_t ciphertext1[20] = { 0 };
778     uint8_t plaintext2[40] = { 0 };
779     uint8_t ciphertext2[40] = { 0 };
780     int ret;
781 
782     cipher = qcrypto_cipher_new(
783         QCRYPTO_CIPHER_ALG_AES_256,
784         QCRYPTO_CIPHER_MODE_CBC,
785         key, sizeof(key),
786         &error_abort);
787     g_assert(cipher != NULL);
788 
789     /* Should report an error as plaintext is shorter
790      * than block size
791      */
792     ret = qcrypto_cipher_encrypt(cipher,
793                                  plaintext1,
794                                  ciphertext1,
795                                  sizeof(plaintext1),
796                                  &err);
797     g_assert(ret == -1);
798     error_free_or_abort(&err);
799 
800     /* Should report an error as plaintext is larger than
801      * block size, but not a multiple of block size
802      */
803     ret = qcrypto_cipher_encrypt(cipher,
804                                  plaintext2,
805                                  ciphertext2,
806                                  sizeof(plaintext2),
807                                  &err);
808     g_assert(ret == -1);
809     error_free_or_abort(&err);
810 
811     qcrypto_cipher_free(cipher);
812 }
813 
814 int main(int argc, char **argv)
815 {
816     size_t i;
817 
818     g_test_init(&argc, &argv, NULL);
819 
820     g_assert(qcrypto_init(NULL) == 0);
821 
822     for (i = 0; i < G_N_ELEMENTS(test_data); i++) {
823         if (qcrypto_cipher_supports(test_data[i].alg, test_data[i].mode)) {
824             g_test_add_data_func(test_data[i].path, &test_data[i], test_cipher);
825         }
826     }
827 
828     g_test_add_func("/crypto/cipher/null-iv",
829                     test_cipher_null_iv);
830 
831     g_test_add_func("/crypto/cipher/short-plaintext",
832                     test_cipher_short_plaintext);
833 
834     return g_test_run();
835 }
836