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",
376 static inline int unhex(char c
)
378 if (c
>= 'a' && c
<= 'f') {
379 return 10 + (c
- 'a');
381 if (c
>= 'A' && c
<= 'F') {
382 return 10 + (c
- 'A');
387 static inline char hex(int i
)
392 return 'a' + (i
- 10);
395 static size_t unhex_string(const char *hexstr
,
406 len
= strlen(hexstr
);
407 *data
= g_new0(uint8_t, len
/ 2);
409 for (i
= 0; i
< len
; i
+= 2) {
410 (*data
)[i
/2] = (unhex(hexstr
[i
]) << 4) | unhex(hexstr
[i
+1]);
415 static char *hex_string(const uint8_t *bytes
,
418 char *hexstr
= g_new0(char, len
* 2 + 1);
421 for (i
= 0; i
< len
; i
++) {
422 hexstr
[i
*2] = hex((bytes
[i
] >> 4) & 0xf);
423 hexstr
[i
*2+1] = hex(bytes
[i
] & 0xf);
425 hexstr
[len
*2] = '\0';
430 static void test_cipher(const void *opaque
)
432 const QCryptoCipherTestData
*data
= opaque
;
434 QCryptoCipher
*cipher
;
435 uint8_t *key
, *iv
, *ciphertext
, *plaintext
, *outtext
;
436 size_t nkey
, niv
, nciphertext
, nplaintext
;
438 size_t ivsize
, keysize
, blocksize
;
440 nkey
= unhex_string(data
->key
, &key
);
441 niv
= unhex_string(data
->iv
, &iv
);
442 nciphertext
= unhex_string(data
->ciphertext
, &ciphertext
);
443 nplaintext
= unhex_string(data
->plaintext
, &plaintext
);
445 g_assert(nciphertext
== nplaintext
);
447 outtext
= g_new0(uint8_t, nciphertext
);
449 cipher
= qcrypto_cipher_new(
450 data
->alg
, data
->mode
,
453 g_assert(cipher
!= NULL
);
455 keysize
= qcrypto_cipher_get_key_len(data
->alg
);
456 blocksize
= qcrypto_cipher_get_block_len(data
->alg
);
457 ivsize
= qcrypto_cipher_get_iv_len(data
->alg
, data
->mode
);
459 if (data
->mode
== QCRYPTO_CIPHER_MODE_XTS
) {
460 g_assert_cmpint(keysize
* 2, ==, nkey
);
462 g_assert_cmpint(keysize
, ==, nkey
);
464 g_assert_cmpint(ivsize
, ==, niv
);
466 g_assert_cmpint(blocksize
, ==, niv
);
470 g_assert(qcrypto_cipher_setiv(cipher
,
474 g_assert(qcrypto_cipher_encrypt(cipher
,
480 outtexthex
= hex_string(outtext
, nciphertext
);
482 g_assert_cmpstr(outtexthex
, ==, data
->ciphertext
);
487 g_assert(qcrypto_cipher_setiv(cipher
,
491 g_assert(qcrypto_cipher_decrypt(cipher
,
497 outtexthex
= hex_string(outtext
, nplaintext
);
499 g_assert_cmpstr(outtexthex
, ==, data
->plaintext
);
507 qcrypto_cipher_free(cipher
);
511 static void test_cipher_null_iv(void)
513 QCryptoCipher
*cipher
;
514 uint8_t key
[32] = { 0 };
515 uint8_t plaintext
[32] = { 0 };
516 uint8_t ciphertext
[32] = { 0 };
518 cipher
= qcrypto_cipher_new(
519 QCRYPTO_CIPHER_ALG_AES_256
,
520 QCRYPTO_CIPHER_MODE_CBC
,
523 g_assert(cipher
!= NULL
);
525 /* Don't call qcrypto_cipher_setiv */
527 qcrypto_cipher_encrypt(cipher
,
533 qcrypto_cipher_free(cipher
);
536 static void test_cipher_short_plaintext(void)
539 QCryptoCipher
*cipher
;
540 uint8_t key
[32] = { 0 };
541 uint8_t plaintext1
[20] = { 0 };
542 uint8_t ciphertext1
[20] = { 0 };
543 uint8_t plaintext2
[40] = { 0 };
544 uint8_t ciphertext2
[40] = { 0 };
547 cipher
= qcrypto_cipher_new(
548 QCRYPTO_CIPHER_ALG_AES_256
,
549 QCRYPTO_CIPHER_MODE_CBC
,
552 g_assert(cipher
!= NULL
);
554 /* Should report an error as plaintext is shorter
557 ret
= qcrypto_cipher_encrypt(cipher
,
563 g_assert(err
!= NULL
);
568 /* Should report an error as plaintext is larger than
569 * block size, but not a multiple of block size
571 ret
= qcrypto_cipher_encrypt(cipher
,
577 g_assert(err
!= NULL
);
580 qcrypto_cipher_free(cipher
);
583 int main(int argc
, char **argv
)
587 g_test_init(&argc
, &argv
, NULL
);
589 g_assert(qcrypto_init(NULL
) == 0);
591 for (i
= 0; i
< G_N_ELEMENTS(test_data
); i
++) {
592 if (qcrypto_cipher_supports(test_data
[i
].alg
)) {
593 g_test_add_data_func(test_data
[i
].path
, &test_data
[i
], test_cipher
);
597 g_test_add_func("/crypto/cipher/null-iv",
598 test_cipher_null_iv
);
600 g_test_add_func("/crypto/cipher/short-plaintext",
601 test_cipher_short_plaintext
);