io: Introduce a qio_channel_set_feature() helper
[qemu/ar7.git] / tests / test-crypto-cipher.c
blob5d9e535e2efb04cddfc5aa8252513d5b7bfd38d2
1 /*
2 * QEMU Crypto cipher algorithms
4 * Copyright (c) 2015 Red Hat, Inc.
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 of the License, or (at your option) any later version.
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.
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/>.
21 #include "qemu/osdep.h"
23 #include "crypto/init.h"
24 #include "crypto/cipher.h"
25 #include "qapi/error.h"
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;
38 /* AES test data comes from appendix F of:
40 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
42 static QCryptoCipherTestData test_data[] = {
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"
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"
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",
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",
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",
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",
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",
169 /* RFC 2144, Appendix B.1 */
170 .path = "/crypto/cipher/cast5-128",
171 .alg = QCRYPTO_CIPHER_ALG_CAST5_128,
172 .mode = QCRYPTO_CIPHER_MODE_ECB,
173 .key = "0123456712345678234567893456789A",
174 .plaintext = "0123456789abcdef",
175 .ciphertext = "238b4fe5847e44b2",
178 /* libgcrypt serpent.c */
179 .path = "/crypto/cipher/serpent-128",
180 .alg = QCRYPTO_CIPHER_ALG_SERPENT_128,
181 .mode = QCRYPTO_CIPHER_MODE_ECB,
182 .key = "00000000000000000000000000000000",
183 .plaintext = "d29d576fcea3a3a7ed9099f29273d78e",
184 .ciphertext = "b2288b968ae8b08648d1ce9606fd992d",
187 /* libgcrypt serpent.c */
188 .path = "/crypto/cipher/serpent-192",
189 .alg = QCRYPTO_CIPHER_ALG_SERPENT_192,
190 .mode = QCRYPTO_CIPHER_MODE_ECB,
191 .key = "00000000000000000000000000000000"
192 "0000000000000000",
193 .plaintext = "d29d576fceaba3a7ed9899f2927bd78e",
194 .ciphertext = "130e353e1037c22405e8faefb2c3c3e9",
197 /* libgcrypt serpent.c */
198 .path = "/crypto/cipher/serpent-256a",
199 .alg = QCRYPTO_CIPHER_ALG_SERPENT_256,
200 .mode = QCRYPTO_CIPHER_MODE_ECB,
201 .key = "00000000000000000000000000000000"
202 "00000000000000000000000000000000",
203 .plaintext = "d095576fcea3e3a7ed98d9f29073d78e",
204 .ciphertext = "b90ee5862de69168f2bdd5125b45472b",
207 /* libgcrypt serpent.c */
208 .path = "/crypto/cipher/serpent-256b",
209 .alg = QCRYPTO_CIPHER_ALG_SERPENT_256,
210 .mode = QCRYPTO_CIPHER_MODE_ECB,
211 .key = "00000000000000000000000000000000"
212 "00000000000000000000000000000000",
213 .plaintext = "00000000010000000200000003000000",
214 .ciphertext = "2061a42782bd52ec691ec383b03ba77c",
217 /* Twofish paper "Known Answer Test" */
218 .path = "/crypto/cipher/twofish-128",
219 .alg = QCRYPTO_CIPHER_ALG_TWOFISH_128,
220 .mode = QCRYPTO_CIPHER_MODE_ECB,
221 .key = "d491db16e7b1c39e86cb086b789f5419",
222 .plaintext = "019f9809de1711858faac3a3ba20fbc3",
223 .ciphertext = "6363977de839486297e661c6c9d668eb",
226 /* Twofish paper "Known Answer Test", I=3 */
227 .path = "/crypto/cipher/twofish-192",
228 .alg = QCRYPTO_CIPHER_ALG_TWOFISH_192,
229 .mode = QCRYPTO_CIPHER_MODE_ECB,
230 .key = "88b2b2706b105e36b446bb6d731a1e88"
231 "efa71f788965bd44",
232 .plaintext = "39da69d6ba4997d585b6dc073ca341b2",
233 .ciphertext = "182b02d81497ea45f9daacdc29193a65",
236 /* Twofish paper "Known Answer Test", I=4 */
237 .path = "/crypto/cipher/twofish-256",
238 .alg = QCRYPTO_CIPHER_ALG_TWOFISH_256,
239 .mode = QCRYPTO_CIPHER_MODE_ECB,
240 .key = "d43bb7556ea32e46f2a282b7d45b4e0d"
241 "57ff739d4dc92c1bd7fc01700cc8216f",
242 .plaintext = "90afe91bb288544f2c32dc239b2635e6",
243 .ciphertext = "6cb4561c40bf0a9705931cb6d408e7fa",
246 /* #1 32 byte key, 32 byte PTX */
247 .path = "/crypto/cipher/aes-xts-128-1",
248 .alg = QCRYPTO_CIPHER_ALG_AES_128,
249 .mode = QCRYPTO_CIPHER_MODE_XTS,
250 .key =
251 "00000000000000000000000000000000"
252 "00000000000000000000000000000000",
253 .iv =
254 "00000000000000000000000000000000",
255 .plaintext =
256 "00000000000000000000000000000000"
257 "00000000000000000000000000000000",
258 .ciphertext =
259 "917cf69ebd68b2ec9b9fe9a3eadda692"
260 "cd43d2f59598ed858c02c2652fbf922e",
263 /* #2, 32 byte key, 32 byte PTX */
264 .path = "/crypto/cipher/aes-xts-128-2",
265 .alg = QCRYPTO_CIPHER_ALG_AES_128,
266 .mode = QCRYPTO_CIPHER_MODE_XTS,
267 .key =
268 "11111111111111111111111111111111"
269 "22222222222222222222222222222222",
270 .iv =
271 "33333333330000000000000000000000",
272 .plaintext =
273 "44444444444444444444444444444444"
274 "44444444444444444444444444444444",
275 .ciphertext =
276 "c454185e6a16936e39334038acef838b"
277 "fb186fff7480adc4289382ecd6d394f0",
280 /* #5 from xts.7, 32 byte key, 32 byte PTX */
281 .path = "/crypto/cipher/aes-xts-128-3",
282 .alg = QCRYPTO_CIPHER_ALG_AES_128,
283 .mode = QCRYPTO_CIPHER_MODE_XTS,
284 .key =
285 "fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0"
286 "bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0",
287 .iv =
288 "9a785634120000000000000000000000",
289 .plaintext =
290 "44444444444444444444444444444444"
291 "44444444444444444444444444444444",
292 .ciphertext =
293 "b01f86f8edc1863706fa8a4253e34f28"
294 "af319de38334870f4dd1f94cbe9832f1",
297 /* #4, 32 byte key, 512 byte PTX */
298 .path = "/crypto/cipher/aes-xts-128-4",
299 .alg = QCRYPTO_CIPHER_ALG_AES_128,
300 .mode = QCRYPTO_CIPHER_MODE_XTS,
301 .key =
302 "27182818284590452353602874713526"
303 "31415926535897932384626433832795",
304 .iv =
305 "00000000000000000000000000000000",
306 .plaintext =
307 "000102030405060708090a0b0c0d0e0f"
308 "101112131415161718191a1b1c1d1e1f"
309 "202122232425262728292a2b2c2d2e2f"
310 "303132333435363738393a3b3c3d3e3f"
311 "404142434445464748494a4b4c4d4e4f"
312 "505152535455565758595a5b5c5d5e5f"
313 "606162636465666768696a6b6c6d6e6f"
314 "707172737475767778797a7b7c7d7e7f"
315 "808182838485868788898a8b8c8d8e8f"
316 "909192939495969798999a9b9c9d9e9f"
317 "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
318 "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
319 "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
320 "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
321 "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
322 "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"
323 "000102030405060708090a0b0c0d0e0f"
324 "101112131415161718191a1b1c1d1e1f"
325 "202122232425262728292a2b2c2d2e2f"
326 "303132333435363738393a3b3c3d3e3f"
327 "404142434445464748494a4b4c4d4e4f"
328 "505152535455565758595a5b5c5d5e5f"
329 "606162636465666768696a6b6c6d6e6f"
330 "707172737475767778797a7b7c7d7e7f"
331 "808182838485868788898a8b8c8d8e8f"
332 "909192939495969798999a9b9c9d9e9f"
333 "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
334 "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
335 "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
336 "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
337 "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
338 "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
339 .ciphertext =
340 "27a7479befa1d476489f308cd4cfa6e2"
341 "a96e4bbe3208ff25287dd3819616e89c"
342 "c78cf7f5e543445f8333d8fa7f560000"
343 "05279fa5d8b5e4ad40e736ddb4d35412"
344 "328063fd2aab53e5ea1e0a9f332500a5"
345 "df9487d07a5c92cc512c8866c7e860ce"
346 "93fdf166a24912b422976146ae20ce84"
347 "6bb7dc9ba94a767aaef20c0d61ad0265"
348 "5ea92dc4c4e41a8952c651d33174be51"
349 "a10c421110e6d81588ede82103a252d8"
350 "a750e8768defffed9122810aaeb99f91"
351 "72af82b604dc4b8e51bcb08235a6f434"
352 "1332e4ca60482a4ba1a03b3e65008fc5"
353 "da76b70bf1690db4eae29c5f1badd03c"
354 "5ccf2a55d705ddcd86d449511ceb7ec3"
355 "0bf12b1fa35b913f9f747a8afd1b130e"
356 "94bff94effd01a91735ca1726acd0b19"
357 "7c4e5b03393697e126826fb6bbde8ecc"
358 "1e08298516e2c9ed03ff3c1b7860f6de"
359 "76d4cecd94c8119855ef5297ca67e9f3"
360 "e7ff72b1e99785ca0a7e7720c5b36dc6"
361 "d72cac9574c8cbbc2f801e23e56fd344"
362 "b07f22154beba0f08ce8891e643ed995"
363 "c94d9a69c9f1b5f499027a78572aeebd"
364 "74d20cc39881c213ee770b1010e4bea7"
365 "18846977ae119f7a023ab58cca0ad752"
366 "afe656bb3c17256a9f6e9bf19fdd5a38"
367 "fc82bbe872c5539edb609ef4f79c203e"
368 "bb140f2e583cb2ad15b4aa5b655016a8"
369 "449277dbd477ef2c8d6c017db738b18d"
370 "eb4a427d1923ce3ff262735779a418f2"
371 "0a282df920147beabe421ee5319d0568",
374 /* Bad config - cast5-128 has 8 byte block size
375 * which is incompatible with XTS
377 .path = "/crypto/cipher/cast5-xts-128",
378 .alg = QCRYPTO_CIPHER_ALG_CAST5_128,
379 .mode = QCRYPTO_CIPHER_MODE_XTS,
380 .key =
381 "27182818284590452353602874713526"
382 "31415926535897932384626433832795",
385 /* NIST F.5.1 CTR-AES128.Encrypt */
386 .path = "/crypto/cipher/aes-ctr-128",
387 .alg = QCRYPTO_CIPHER_ALG_AES_128,
388 .mode = QCRYPTO_CIPHER_MODE_CTR,
389 .key = "2b7e151628aed2a6abf7158809cf4f3c",
390 .iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
391 .plaintext =
392 "6bc1bee22e409f96e93d7e117393172a"
393 "ae2d8a571e03ac9c9eb76fac45af8e51"
394 "30c81c46a35ce411e5fbc1191a0a52ef"
395 "f69f2445df4f9b17ad2b417be66c3710",
396 .ciphertext =
397 "874d6191b620e3261bef6864990db6ce"
398 "9806f66b7970fdff8617187bb9fffdff"
399 "5ae4df3edbd5d35e5b4f09020db03eab"
400 "1e031dda2fbe03d1792170a0f3009cee",
403 /* NIST F.5.3 CTR-AES192.Encrypt */
404 .path = "/crypto/cipher/aes-ctr-192",
405 .alg = QCRYPTO_CIPHER_ALG_AES_192,
406 .mode = QCRYPTO_CIPHER_MODE_CTR,
407 .key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b",
408 .iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
409 .plaintext =
410 "6bc1bee22e409f96e93d7e117393172a"
411 "ae2d8a571e03ac9c9eb76fac45af8e51"
412 "30c81c46a35ce411e5fbc1191a0a52ef"
413 "f69f2445df4f9b17ad2b417be66c3710",
414 .ciphertext =
415 "1abc932417521ca24f2b0459fe7e6e0b"
416 "090339ec0aa6faefd5ccc2c6f4ce8e94"
417 "1e36b26bd1ebc670d1bd1d665620abf7"
418 "4f78a7f6d29809585a97daec58c6b050",
421 /* NIST F.5.5 CTR-AES256.Encrypt */
422 .path = "/crypto/cipher/aes-ctr-256",
423 .alg = QCRYPTO_CIPHER_ALG_AES_256,
424 .mode = QCRYPTO_CIPHER_MODE_CTR,
425 .key = "603deb1015ca71be2b73aef0857d7781"
426 "1f352c073b6108d72d9810a30914dff4",
427 .iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
428 .plaintext =
429 "6bc1bee22e409f96e93d7e117393172a"
430 "ae2d8a571e03ac9c9eb76fac45af8e51"
431 "30c81c46a35ce411e5fbc1191a0a52ef"
432 "f69f2445df4f9b17ad2b417be66c3710",
433 .ciphertext =
434 "601ec313775789a5b7a7f504bbf3d228"
435 "f443e3ca4d62b59aca84e990cacaf5c5"
436 "2b0930daa23de94ce87017ba2d84988d"
437 "dfc9c58db67aada613c2dd08457941a6",
442 static inline int unhex(char c)
444 if (c >= 'a' && c <= 'f') {
445 return 10 + (c - 'a');
447 if (c >= 'A' && c <= 'F') {
448 return 10 + (c - 'A');
450 return c - '0';
453 static inline char hex(int i)
455 if (i < 10) {
456 return '0' + i;
458 return 'a' + (i - 10);
461 static size_t unhex_string(const char *hexstr,
462 uint8_t **data)
464 size_t len;
465 size_t i;
467 if (!hexstr) {
468 *data = NULL;
469 return 0;
472 len = strlen(hexstr);
473 *data = g_new0(uint8_t, len / 2);
475 for (i = 0; i < len; i += 2) {
476 (*data)[i/2] = (unhex(hexstr[i]) << 4) | unhex(hexstr[i+1]);
478 return len / 2;
481 static char *hex_string(const uint8_t *bytes,
482 size_t len)
484 char *hexstr = g_new0(char, len * 2 + 1);
485 size_t i;
487 for (i = 0; i < len; i++) {
488 hexstr[i*2] = hex((bytes[i] >> 4) & 0xf);
489 hexstr[i*2+1] = hex(bytes[i] & 0xf);
491 hexstr[len*2] = '\0';
493 return hexstr;
496 static void test_cipher(const void *opaque)
498 const QCryptoCipherTestData *data = opaque;
500 QCryptoCipher *cipher;
501 uint8_t *key, *iv = NULL, *ciphertext = NULL,
502 *plaintext = NULL, *outtext = NULL;
503 size_t nkey, niv = 0, nciphertext = 0, nplaintext = 0;
504 char *outtexthex = NULL;
505 size_t ivsize, keysize, blocksize;
506 Error *err = NULL;
508 nkey = unhex_string(data->key, &key);
509 if (data->iv) {
510 niv = unhex_string(data->iv, &iv);
512 if (data->ciphertext) {
513 nciphertext = unhex_string(data->ciphertext, &ciphertext);
515 if (data->plaintext) {
516 nplaintext = unhex_string(data->plaintext, &plaintext);
519 g_assert(nciphertext == nplaintext);
521 outtext = g_new0(uint8_t, nciphertext);
523 cipher = qcrypto_cipher_new(
524 data->alg, data->mode,
525 key, nkey,
526 &err);
527 if (data->plaintext) {
528 g_assert(err == NULL);
529 g_assert(cipher != NULL);
530 } else {
531 error_free_or_abort(&err);
532 g_assert(cipher == NULL);
533 goto cleanup;
536 keysize = qcrypto_cipher_get_key_len(data->alg);
537 blocksize = qcrypto_cipher_get_block_len(data->alg);
538 ivsize = qcrypto_cipher_get_iv_len(data->alg, data->mode);
540 if (data->mode == QCRYPTO_CIPHER_MODE_XTS) {
541 g_assert_cmpint(keysize * 2, ==, nkey);
542 } else {
543 g_assert_cmpint(keysize, ==, nkey);
545 g_assert_cmpint(ivsize, ==, niv);
546 if (niv) {
547 g_assert_cmpint(blocksize, ==, niv);
550 if (iv) {
551 g_assert(qcrypto_cipher_setiv(cipher,
552 iv, niv,
553 &error_abort) == 0);
555 g_assert(qcrypto_cipher_encrypt(cipher,
556 plaintext,
557 outtext,
558 nplaintext,
559 &error_abort) == 0);
561 outtexthex = hex_string(outtext, nciphertext);
563 g_assert_cmpstr(outtexthex, ==, data->ciphertext);
565 g_free(outtexthex);
567 if (iv) {
568 g_assert(qcrypto_cipher_setiv(cipher,
569 iv, niv,
570 &error_abort) == 0);
572 g_assert(qcrypto_cipher_decrypt(cipher,
573 ciphertext,
574 outtext,
575 nplaintext,
576 &error_abort) == 0);
578 outtexthex = hex_string(outtext, nplaintext);
580 g_assert_cmpstr(outtexthex, ==, data->plaintext);
582 cleanup:
583 g_free(outtext);
584 g_free(outtexthex);
585 g_free(key);
586 g_free(iv);
587 g_free(ciphertext);
588 g_free(plaintext);
589 qcrypto_cipher_free(cipher);
593 static void test_cipher_null_iv(void)
595 QCryptoCipher *cipher;
596 uint8_t key[32] = { 0 };
597 uint8_t plaintext[32] = { 0 };
598 uint8_t ciphertext[32] = { 0 };
600 cipher = qcrypto_cipher_new(
601 QCRYPTO_CIPHER_ALG_AES_256,
602 QCRYPTO_CIPHER_MODE_CBC,
603 key, sizeof(key),
604 &error_abort);
605 g_assert(cipher != NULL);
607 /* Don't call qcrypto_cipher_setiv */
609 qcrypto_cipher_encrypt(cipher,
610 plaintext,
611 ciphertext,
612 sizeof(plaintext),
613 &error_abort);
615 qcrypto_cipher_free(cipher);
618 static void test_cipher_short_plaintext(void)
620 Error *err = NULL;
621 QCryptoCipher *cipher;
622 uint8_t key[32] = { 0 };
623 uint8_t plaintext1[20] = { 0 };
624 uint8_t ciphertext1[20] = { 0 };
625 uint8_t plaintext2[40] = { 0 };
626 uint8_t ciphertext2[40] = { 0 };
627 int ret;
629 cipher = qcrypto_cipher_new(
630 QCRYPTO_CIPHER_ALG_AES_256,
631 QCRYPTO_CIPHER_MODE_CBC,
632 key, sizeof(key),
633 &error_abort);
634 g_assert(cipher != NULL);
636 /* Should report an error as plaintext is shorter
637 * than block size
639 ret = qcrypto_cipher_encrypt(cipher,
640 plaintext1,
641 ciphertext1,
642 sizeof(plaintext1),
643 &err);
644 g_assert(ret == -1);
645 g_assert(err != NULL);
647 error_free(err);
648 err = NULL;
650 /* Should report an error as plaintext is larger than
651 * block size, but not a multiple of block size
653 ret = qcrypto_cipher_encrypt(cipher,
654 plaintext2,
655 ciphertext2,
656 sizeof(plaintext2),
657 &err);
658 g_assert(ret == -1);
659 g_assert(err != NULL);
661 error_free(err);
662 qcrypto_cipher_free(cipher);
665 int main(int argc, char **argv)
667 size_t i;
669 g_test_init(&argc, &argv, NULL);
671 g_assert(qcrypto_init(NULL) == 0);
673 for (i = 0; i < G_N_ELEMENTS(test_data); i++) {
674 if (qcrypto_cipher_supports(test_data[i].alg, test_data[i].mode)) {
675 g_test_add_data_func(test_data[i].path, &test_data[i], test_cipher);
679 g_test_add_func("/crypto/cipher/null-iv",
680 test_cipher_null_iv);
682 g_test_add_func("/crypto/cipher/short-plaintext",
683 test_cipher_short_plaintext);
685 return g_test_run();