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
{
30 QCryptoCipherAlgorithm alg
;
31 QCryptoCipherMode mode
;
33 const char *plaintext
;
34 const char *ciphertext
;
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",
50 "6bc1bee22e409f96e93d7e117393172a"
51 "ae2d8a571e03ac9c9eb76fac45af8e51"
52 "30c81c46a35ce411e5fbc1191a0a52ef"
53 "f69f2445df4f9b17ad2b417be66c3710",
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",
67 "6bc1bee22e409f96e93d7e117393172a"
68 "ae2d8a571e03ac9c9eb76fac45af8e51"
69 "30c81c46a35ce411e5fbc1191a0a52ef"
70 "f69f2445df4f9b17ad2b417be66c3710",
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
,
83 "603deb1015ca71be2b73aef0857d7781"
84 "1f352c073b6108d72d9810a30914dff4",
86 "6bc1bee22e409f96e93d7e117393172a"
87 "ae2d8a571e03ac9c9eb76fac45af8e51"
88 "30c81c46a35ce411e5fbc1191a0a52ef"
89 "f69f2445df4f9b17ad2b417be66c3710",
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",
104 "6bc1bee22e409f96e93d7e117393172a"
105 "ae2d8a571e03ac9c9eb76fac45af8e51"
106 "30c81c46a35ce411e5fbc1191a0a52ef"
107 "f69f2445df4f9b17ad2b417be66c3710",
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",
122 "6bc1bee22e409f96e93d7e117393172a"
123 "ae2d8a571e03ac9c9eb76fac45af8e51"
124 "30c81c46a35ce411e5fbc1191a0a52ef"
125 "f69f2445df4f9b17ad2b417be66c3710",
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
,
138 "603deb1015ca71be2b73aef0857d7781"
139 "1f352c073b6108d72d9810a30914dff4",
140 .iv
= "000102030405060708090a0b0c0d0e0f",
142 "6bc1bee22e409f96e93d7e117393172a"
143 "ae2d8a571e03ac9c9eb76fac45af8e51"
144 "30c81c46a35ce411e5fbc1191a0a52ef"
145 "f69f2445df4f9b17ad2b417be66c3710",
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",
158 "6bc1bee22e409f96e93d7e117393172a"
159 "ae2d8a571e03ac9c9eb76fac45af8e51"
160 "30c81c46a35ce411e5fbc1191a0a52ef"
161 "f69f2445df4f9b17ad2b417be66c3710",
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"
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"
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
,
251 "00000000000000000000000000000000"
252 "00000000000000000000000000000000",
254 "00000000000000000000000000000000",
256 "00000000000000000000000000000000"
257 "00000000000000000000000000000000",
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
,
268 "11111111111111111111111111111111"
269 "22222222222222222222222222222222",
271 "33333333330000000000000000000000",
273 "44444444444444444444444444444444"
274 "44444444444444444444444444444444",
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
,
285 "fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0"
286 "bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0",
288 "9a785634120000000000000000000000",
290 "44444444444444444444444444444444"
291 "44444444444444444444444444444444",
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
,
302 "27182818284590452353602874713526"
303 "31415926535897932384626433832795",
305 "00000000000000000000000000000000",
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",
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
,
381 "27182818284590452353602874713526"
382 "31415926535897932384626433832795",
387 static inline int unhex(char c
)
389 if (c
>= 'a' && c
<= 'f') {
390 return 10 + (c
- 'a');
392 if (c
>= 'A' && c
<= 'F') {
393 return 10 + (c
- 'A');
398 static inline char hex(int i
)
403 return 'a' + (i
- 10);
406 static size_t unhex_string(const char *hexstr
,
417 len
= strlen(hexstr
);
418 *data
= g_new0(uint8_t, len
/ 2);
420 for (i
= 0; i
< len
; i
+= 2) {
421 (*data
)[i
/2] = (unhex(hexstr
[i
]) << 4) | unhex(hexstr
[i
+1]);
426 static char *hex_string(const uint8_t *bytes
,
429 char *hexstr
= g_new0(char, len
* 2 + 1);
432 for (i
= 0; i
< len
; i
++) {
433 hexstr
[i
*2] = hex((bytes
[i
] >> 4) & 0xf);
434 hexstr
[i
*2+1] = hex(bytes
[i
] & 0xf);
436 hexstr
[len
*2] = '\0';
441 static void test_cipher(const void *opaque
)
443 const QCryptoCipherTestData
*data
= opaque
;
445 QCryptoCipher
*cipher
;
446 uint8_t *key
, *iv
= NULL
, *ciphertext
= NULL
,
447 *plaintext
= NULL
, *outtext
= NULL
;
448 size_t nkey
, niv
= 0, nciphertext
= 0, nplaintext
= 0;
449 char *outtexthex
= NULL
;
450 size_t ivsize
, keysize
, blocksize
;
453 nkey
= unhex_string(data
->key
, &key
);
455 niv
= unhex_string(data
->iv
, &iv
);
457 if (data
->ciphertext
) {
458 nciphertext
= unhex_string(data
->ciphertext
, &ciphertext
);
460 if (data
->plaintext
) {
461 nplaintext
= unhex_string(data
->plaintext
, &plaintext
);
464 g_assert(nciphertext
== nplaintext
);
466 outtext
= g_new0(uint8_t, nciphertext
);
468 cipher
= qcrypto_cipher_new(
469 data
->alg
, data
->mode
,
472 if (data
->plaintext
) {
473 g_assert(err
== NULL
);
474 g_assert(cipher
!= NULL
);
476 error_free_or_abort(&err
);
477 g_assert(cipher
== NULL
);
481 keysize
= qcrypto_cipher_get_key_len(data
->alg
);
482 blocksize
= qcrypto_cipher_get_block_len(data
->alg
);
483 ivsize
= qcrypto_cipher_get_iv_len(data
->alg
, data
->mode
);
485 if (data
->mode
== QCRYPTO_CIPHER_MODE_XTS
) {
486 g_assert_cmpint(keysize
* 2, ==, nkey
);
488 g_assert_cmpint(keysize
, ==, nkey
);
490 g_assert_cmpint(ivsize
, ==, niv
);
492 g_assert_cmpint(blocksize
, ==, niv
);
496 g_assert(qcrypto_cipher_setiv(cipher
,
500 g_assert(qcrypto_cipher_encrypt(cipher
,
506 outtexthex
= hex_string(outtext
, nciphertext
);
508 g_assert_cmpstr(outtexthex
, ==, data
->ciphertext
);
513 g_assert(qcrypto_cipher_setiv(cipher
,
517 g_assert(qcrypto_cipher_decrypt(cipher
,
523 outtexthex
= hex_string(outtext
, nplaintext
);
525 g_assert_cmpstr(outtexthex
, ==, data
->plaintext
);
534 qcrypto_cipher_free(cipher
);
538 static void test_cipher_null_iv(void)
540 QCryptoCipher
*cipher
;
541 uint8_t key
[32] = { 0 };
542 uint8_t plaintext
[32] = { 0 };
543 uint8_t ciphertext
[32] = { 0 };
545 cipher
= qcrypto_cipher_new(
546 QCRYPTO_CIPHER_ALG_AES_256
,
547 QCRYPTO_CIPHER_MODE_CBC
,
550 g_assert(cipher
!= NULL
);
552 /* Don't call qcrypto_cipher_setiv */
554 qcrypto_cipher_encrypt(cipher
,
560 qcrypto_cipher_free(cipher
);
563 static void test_cipher_short_plaintext(void)
566 QCryptoCipher
*cipher
;
567 uint8_t key
[32] = { 0 };
568 uint8_t plaintext1
[20] = { 0 };
569 uint8_t ciphertext1
[20] = { 0 };
570 uint8_t plaintext2
[40] = { 0 };
571 uint8_t ciphertext2
[40] = { 0 };
574 cipher
= qcrypto_cipher_new(
575 QCRYPTO_CIPHER_ALG_AES_256
,
576 QCRYPTO_CIPHER_MODE_CBC
,
579 g_assert(cipher
!= NULL
);
581 /* Should report an error as plaintext is shorter
584 ret
= qcrypto_cipher_encrypt(cipher
,
590 g_assert(err
!= NULL
);
595 /* Should report an error as plaintext is larger than
596 * block size, but not a multiple of block size
598 ret
= qcrypto_cipher_encrypt(cipher
,
604 g_assert(err
!= NULL
);
607 qcrypto_cipher_free(cipher
);
610 int main(int argc
, char **argv
)
614 g_test_init(&argc
, &argv
, NULL
);
616 g_assert(qcrypto_init(NULL
) == 0);
618 for (i
= 0; i
< G_N_ELEMENTS(test_data
); i
++) {
619 if (qcrypto_cipher_supports(test_data
[i
].alg
)) {
620 g_test_add_data_func(test_data
[i
].path
, &test_data
[i
], test_cipher
);
624 g_test_add_func("/crypto/cipher/null-iv",
625 test_cipher_null_iv
);
627 g_test_add_func("/crypto/cipher/short-plaintext",
628 test_cipher_short_plaintext
);