]> git.proxmox.com Git - mirror_qemu.git/blame - tests/test-crypto-cipher.c
cipher: fix leak on initialization error
[mirror_qemu.git] / tests / test-crypto-cipher.c
CommitLineData
ca38a4cc
DB
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
681c28a3 21#include "qemu/osdep.h"
ca38a4cc
DB
22
23#include "crypto/init.h"
24#include "crypto/cipher.h"
da34e65c 25#include "qapi/error.h"
ca38a4cc
DB
26
27typedef struct QCryptoCipherTestData QCryptoCipherTestData;
28struct 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 */
42static 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 },
084a85ee
DB
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 },
94318522
DB
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 },
50f6753e
DB
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 },
eaec903c
DB
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 },
a5d2f44d
DB
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",
3c28292f
GA
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",
a5d2f44d 438 }
ca38a4cc
DB
439};
440
441
442static 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
453static inline char hex(int i)
454{
455 if (i < 10) {
456 return '0' + i;
457 }
458 return 'a' + (i - 10);
459}
460
461static 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
481static 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
496static void test_cipher(const void *opaque)
497{
498 const QCryptoCipherTestData *data = opaque;
499
500 QCryptoCipher *cipher;
a5d2f44d
DB
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;
dd2bf9eb 505 size_t ivsize, keysize, blocksize;
a5d2f44d 506 Error *err = NULL;
ca38a4cc 507
ca38a4cc 508 nkey = unhex_string(data->key, &key);
a5d2f44d
DB
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 }
ca38a4cc
DB
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,
a5d2f44d
DB
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 }
ca38a4cc 535
dd2bf9eb
DB
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
eaec903c
DB
540 if (data->mode == QCRYPTO_CIPHER_MODE_XTS) {
541 g_assert_cmpint(keysize * 2, ==, nkey);
542 } else {
543 g_assert_cmpint(keysize, ==, nkey);
544 }
dd2bf9eb
DB
545 g_assert_cmpint(ivsize, ==, niv);
546 if (niv) {
547 g_assert_cmpint(blocksize, ==, niv);
548 }
ca38a4cc
DB
549
550 if (iv) {
551 g_assert(qcrypto_cipher_setiv(cipher,
552 iv, niv,
019c2ab8 553 &error_abort) == 0);
ca38a4cc
DB
554 }
555 g_assert(qcrypto_cipher_encrypt(cipher,
556 plaintext,
557 outtext,
558 nplaintext,
019c2ab8 559 &error_abort) == 0);
ca38a4cc
DB
560
561 outtexthex = hex_string(outtext, nciphertext);
562
563 g_assert_cmpstr(outtexthex, ==, data->ciphertext);
564
019c2ab8
DB
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
a5d2f44d 582 cleanup:
ca38a4cc
DB
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
eb2a770b
DB
592
593static 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
3a661f1e
DB
618static 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
ca38a4cc
DB
665int 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++) {
f844836d 674 if (qcrypto_cipher_supports(test_data[i].alg, test_data[i].mode)) {
aa413635
DB
675 g_test_add_data_func(test_data[i].path, &test_data[i], test_cipher);
676 }
ca38a4cc 677 }
eb2a770b
DB
678
679 g_test_add_func("/crypto/cipher/null-iv",
680 test_cipher_null_iv);
681
3a661f1e
DB
682 g_test_add_func("/crypto/cipher/short-plaintext",
683 test_cipher_short_plaintext);
684
ca38a4cc
DB
685 return g_test_run();
686}