OSDN Git Service

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