]> git.proxmox.com Git - mirror_qemu.git/blob - tests/test-crypto-cipher.c
test-qga: Avoid qobject_from_jsonv("%"PRId64)
[mirror_qemu.git] / tests / 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 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 /* 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",
176 },
177 {
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",
185 },
186 {
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",
195 },
196 {
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",
205 },
206 {
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",
215 },
216 {
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",
224 },
225 {
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",
234 },
235 {
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",
244 },
245 {
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",
261 },
262 {
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",
278 },
279 {
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",
295 },
296 {
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",
372 },
373 {
374 /* Bad config - cast5-128 has 8 byte block size
375 * which is incompatible with XTS
376 */
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",
383 },
384 {
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",
401 },
402 {
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",
419 },
420 {
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",
438 }
439 };
440
441
442 static inline int unhex(char c)
443 {
444 if (c >= 'a' && c <= 'f') {
445 return 10 + (c - 'a');
446 }
447 if (c >= 'A' && c <= 'F') {
448 return 10 + (c - 'A');
449 }
450 return c - '0';
451 }
452
453 static inline char hex(int i)
454 {
455 if (i < 10) {
456 return '0' + i;
457 }
458 return 'a' + (i - 10);
459 }
460
461 static size_t unhex_string(const char *hexstr,
462 uint8_t **data)
463 {
464 size_t len;
465 size_t i;
466
467 if (!hexstr) {
468 *data = NULL;
469 return 0;
470 }
471
472 len = strlen(hexstr);
473 *data = g_new0(uint8_t, len / 2);
474
475 for (i = 0; i < len; i += 2) {
476 (*data)[i/2] = (unhex(hexstr[i]) << 4) | unhex(hexstr[i+1]);
477 }
478 return len / 2;
479 }
480
481 static char *hex_string(const uint8_t *bytes,
482 size_t len)
483 {
484 char *hexstr = g_new0(char, len * 2 + 1);
485 size_t i;
486
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);
490 }
491 hexstr[len*2] = '\0';
492
493 return hexstr;
494 }
495
496 static void test_cipher(const void *opaque)
497 {
498 const QCryptoCipherTestData *data = opaque;
499
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;
507
508 nkey = unhex_string(data->key, &key);
509 if (data->iv) {
510 niv = unhex_string(data->iv, &iv);
511 }
512 if (data->ciphertext) {
513 nciphertext = unhex_string(data->ciphertext, &ciphertext);
514 }
515 if (data->plaintext) {
516 nplaintext = unhex_string(data->plaintext, &plaintext);
517 }
518
519 g_assert(nciphertext == nplaintext);
520
521 outtext = g_new0(uint8_t, nciphertext);
522
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;
534 }
535
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);
539
540 if (data->mode == QCRYPTO_CIPHER_MODE_XTS) {
541 g_assert_cmpint(keysize * 2, ==, nkey);
542 } else {
543 g_assert_cmpint(keysize, ==, nkey);
544 }
545 g_assert_cmpint(ivsize, ==, niv);
546 if (niv) {
547 g_assert_cmpint(blocksize, ==, niv);
548 }
549
550 if (iv) {
551 g_assert(qcrypto_cipher_setiv(cipher,
552 iv, niv,
553 &error_abort) == 0);
554 }
555 g_assert(qcrypto_cipher_encrypt(cipher,
556 plaintext,
557 outtext,
558 nplaintext,
559 &error_abort) == 0);
560
561 outtexthex = hex_string(outtext, nciphertext);
562
563 g_assert_cmpstr(outtexthex, ==, data->ciphertext);
564
565 g_free(outtexthex);
566
567 if (iv) {
568 g_assert(qcrypto_cipher_setiv(cipher,
569 iv, niv,
570 &error_abort) == 0);
571 }
572 g_assert(qcrypto_cipher_decrypt(cipher,
573 ciphertext,
574 outtext,
575 nplaintext,
576 &error_abort) == 0);
577
578 outtexthex = hex_string(outtext, nplaintext);
579
580 g_assert_cmpstr(outtexthex, ==, data->plaintext);
581
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);
590 }
591
592
593 static void test_cipher_null_iv(void)
594 {
595 QCryptoCipher *cipher;
596 uint8_t key[32] = { 0 };
597 uint8_t plaintext[32] = { 0 };
598 uint8_t ciphertext[32] = { 0 };
599
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);
606
607 /* Don't call qcrypto_cipher_setiv */
608
609 qcrypto_cipher_encrypt(cipher,
610 plaintext,
611 ciphertext,
612 sizeof(plaintext),
613 &error_abort);
614
615 qcrypto_cipher_free(cipher);
616 }
617
618 static void test_cipher_short_plaintext(void)
619 {
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;
628
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);
635
636 /* Should report an error as plaintext is shorter
637 * than block size
638 */
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);
646
647 error_free(err);
648 err = NULL;
649
650 /* Should report an error as plaintext is larger than
651 * block size, but not a multiple of block size
652 */
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);
660
661 error_free(err);
662 qcrypto_cipher_free(cipher);
663 }
664
665 int main(int argc, char **argv)
666 {
667 size_t i;
668
669 g_test_init(&argc, &argv, NULL);
670
671 g_assert(qcrypto_init(NULL) == 0);
672
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);
676 }
677 }
678
679 g_test_add_func("/crypto/cipher/null-iv",
680 test_cipher_null_iv);
681
682 g_test_add_func("/crypto/cipher/short-plaintext",
683 test_cipher_short_plaintext);
684
685 return g_test_run();
686 }