xref: /qemu/tests/unit/test-crypto-cipher.c (revision b21e2380)
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 }
823