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