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"
24 #include "crypto/init.h"
25 #include "crypto/cipher.h"
26 #include "qapi/error.h"
28 typedef struct QCryptoCipherTestData QCryptoCipherTestData
;
29 struct QCryptoCipherTestData
{
31 QCryptoCipherAlgorithm alg
;
32 QCryptoCipherMode mode
;
34 const char *plaintext
;
35 const char *ciphertext
;
39 /* AES test data comes from appendix F of:
41 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
43 static QCryptoCipherTestData test_data
[] = {
45 /* NIST F.1.1 ECB-AES128.Encrypt */
46 .path
= "/crypto/cipher/aes-ecb-128",
47 .alg
= QCRYPTO_CIPHER_ALG_AES_128
,
48 .mode
= QCRYPTO_CIPHER_MODE_ECB
,
49 .key
= "2b7e151628aed2a6abf7158809cf4f3c",
51 "6bc1bee22e409f96e93d7e117393172a"
52 "ae2d8a571e03ac9c9eb76fac45af8e51"
53 "30c81c46a35ce411e5fbc1191a0a52ef"
54 "f69f2445df4f9b17ad2b417be66c3710",
56 "3ad77bb40d7a3660a89ecaf32466ef97"
57 "f5d3d58503b9699de785895a96fdbaaf"
58 "43b1cd7f598ece23881b00e3ed030688"
59 "7b0c785e27e8ad3f8223207104725dd4"
62 /* NIST F.1.3 ECB-AES192.Encrypt */
63 .path
= "/crypto/cipher/aes-ecb-192",
64 .alg
= QCRYPTO_CIPHER_ALG_AES_192
,
65 .mode
= QCRYPTO_CIPHER_MODE_ECB
,
66 .key
= "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b",
68 "6bc1bee22e409f96e93d7e117393172a"
69 "ae2d8a571e03ac9c9eb76fac45af8e51"
70 "30c81c46a35ce411e5fbc1191a0a52ef"
71 "f69f2445df4f9b17ad2b417be66c3710",
73 "bd334f1d6e45f25ff712a214571fa5cc"
74 "974104846d0ad3ad7734ecb3ecee4eef"
75 "ef7afd2270e2e60adce0ba2face6444e"
76 "9a4b41ba738d6c72fb16691603c18e0e"
79 /* NIST F.1.5 ECB-AES256.Encrypt */
80 .path
= "/crypto/cipher/aes-ecb-256",
81 .alg
= QCRYPTO_CIPHER_ALG_AES_256
,
82 .mode
= QCRYPTO_CIPHER_MODE_ECB
,
84 "603deb1015ca71be2b73aef0857d7781"
85 "1f352c073b6108d72d9810a30914dff4",
87 "6bc1bee22e409f96e93d7e117393172a"
88 "ae2d8a571e03ac9c9eb76fac45af8e51"
89 "30c81c46a35ce411e5fbc1191a0a52ef"
90 "f69f2445df4f9b17ad2b417be66c3710",
92 "f3eed1bdb5d2a03c064b5a7e3db181f8"
93 "591ccb10d410ed26dc5ba74a31362870"
94 "b6ed21b99ca6f4f9f153e7b1beafed1d"
95 "23304b7a39f9f3ff067d8d8f9e24ecc7",
98 /* NIST F.2.1 CBC-AES128.Encrypt */
99 .path
= "/crypto/cipher/aes-cbc-128",
100 .alg
= QCRYPTO_CIPHER_ALG_AES_128
,
101 .mode
= QCRYPTO_CIPHER_MODE_CBC
,
102 .key
= "2b7e151628aed2a6abf7158809cf4f3c",
103 .iv
= "000102030405060708090a0b0c0d0e0f",
105 "6bc1bee22e409f96e93d7e117393172a"
106 "ae2d8a571e03ac9c9eb76fac45af8e51"
107 "30c81c46a35ce411e5fbc1191a0a52ef"
108 "f69f2445df4f9b17ad2b417be66c3710",
110 "7649abac8119b246cee98e9b12e9197d"
111 "5086cb9b507219ee95db113a917678b2"
112 "73bed6b8e3c1743b7116e69e22229516"
113 "3ff1caa1681fac09120eca307586e1a7",
116 /* NIST F.2.3 CBC-AES128.Encrypt */
117 .path
= "/crypto/cipher/aes-cbc-192",
118 .alg
= QCRYPTO_CIPHER_ALG_AES_192
,
119 .mode
= QCRYPTO_CIPHER_MODE_CBC
,
120 .key
= "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b",
121 .iv
= "000102030405060708090a0b0c0d0e0f",
123 "6bc1bee22e409f96e93d7e117393172a"
124 "ae2d8a571e03ac9c9eb76fac45af8e51"
125 "30c81c46a35ce411e5fbc1191a0a52ef"
126 "f69f2445df4f9b17ad2b417be66c3710",
128 "4f021db243bc633d7178183a9fa071e8"
129 "b4d9ada9ad7dedf4e5e738763f69145a"
130 "571b242012fb7ae07fa9baac3df102e0"
131 "08b0e27988598881d920a9e64f5615cd",
134 /* NIST F.2.5 CBC-AES128.Encrypt */
135 .path
= "/crypto/cipher/aes-cbc-256",
136 .alg
= QCRYPTO_CIPHER_ALG_AES_256
,
137 .mode
= QCRYPTO_CIPHER_MODE_CBC
,
139 "603deb1015ca71be2b73aef0857d7781"
140 "1f352c073b6108d72d9810a30914dff4",
141 .iv
= "000102030405060708090a0b0c0d0e0f",
143 "6bc1bee22e409f96e93d7e117393172a"
144 "ae2d8a571e03ac9c9eb76fac45af8e51"
145 "30c81c46a35ce411e5fbc1191a0a52ef"
146 "f69f2445df4f9b17ad2b417be66c3710",
148 "f58c4c04d6e5f1ba779eabfb5f7bfbd6"
149 "9cfc4e967edb808d679f777bc6702c7d"
150 "39f23369a9d9bacfa530e26304231461"
151 "b2eb05e2c39be9fcda6c19078c6a9d1b",
154 .path
= "/crypto/cipher/des-rfb-ecb-56",
155 .alg
= QCRYPTO_CIPHER_ALG_DES_RFB
,
156 .mode
= QCRYPTO_CIPHER_MODE_ECB
,
157 .key
= "0123456789abcdef",
159 "6bc1bee22e409f96e93d7e117393172a"
160 "ae2d8a571e03ac9c9eb76fac45af8e51"
161 "30c81c46a35ce411e5fbc1191a0a52ef"
162 "f69f2445df4f9b17ad2b417be66c3710",
164 "8f346aaf64eaf24040720d80648c52e7"
165 "aefc616be53ab1a3d301e69d91e01838"
166 "ffd29f1bb5596ad94ea2d8e6196b7f09"
167 "30d8ed0bf2773af36dd82a6280c20926",
170 /* RFC 2144, Appendix B.1 */
171 .path
= "/crypto/cipher/cast5-128",
172 .alg
= QCRYPTO_CIPHER_ALG_CAST5_128
,
173 .mode
= QCRYPTO_CIPHER_MODE_ECB
,
174 .key
= "0123456712345678234567893456789A",
175 .plaintext
= "0123456789abcdef",
176 .ciphertext
= "238b4fe5847e44b2",
179 /* libgcrypt serpent.c */
180 .path
= "/crypto/cipher/serpent-128",
181 .alg
= QCRYPTO_CIPHER_ALG_SERPENT_128
,
182 .mode
= QCRYPTO_CIPHER_MODE_ECB
,
183 .key
= "00000000000000000000000000000000",
184 .plaintext
= "d29d576fcea3a3a7ed9099f29273d78e",
185 .ciphertext
= "b2288b968ae8b08648d1ce9606fd992d",
188 /* libgcrypt serpent.c */
189 .path
= "/crypto/cipher/serpent-192",
190 .alg
= QCRYPTO_CIPHER_ALG_SERPENT_192
,
191 .mode
= QCRYPTO_CIPHER_MODE_ECB
,
192 .key
= "00000000000000000000000000000000"
194 .plaintext
= "d29d576fceaba3a7ed9899f2927bd78e",
195 .ciphertext
= "130e353e1037c22405e8faefb2c3c3e9",
198 /* libgcrypt serpent.c */
199 .path
= "/crypto/cipher/serpent-256a",
200 .alg
= QCRYPTO_CIPHER_ALG_SERPENT_256
,
201 .mode
= QCRYPTO_CIPHER_MODE_ECB
,
202 .key
= "00000000000000000000000000000000"
203 "00000000000000000000000000000000",
204 .plaintext
= "d095576fcea3e3a7ed98d9f29073d78e",
205 .ciphertext
= "b90ee5862de69168f2bdd5125b45472b",
208 /* libgcrypt serpent.c */
209 .path
= "/crypto/cipher/serpent-256b",
210 .alg
= QCRYPTO_CIPHER_ALG_SERPENT_256
,
211 .mode
= QCRYPTO_CIPHER_MODE_ECB
,
212 .key
= "00000000000000000000000000000000"
213 "00000000000000000000000000000000",
214 .plaintext
= "00000000010000000200000003000000",
215 .ciphertext
= "2061a42782bd52ec691ec383b03ba77c",
218 /* Twofish paper "Known Answer Test" */
219 .path
= "/crypto/cipher/twofish-128",
220 .alg
= QCRYPTO_CIPHER_ALG_TWOFISH_128
,
221 .mode
= QCRYPTO_CIPHER_MODE_ECB
,
222 .key
= "d491db16e7b1c39e86cb086b789f5419",
223 .plaintext
= "019f9809de1711858faac3a3ba20fbc3",
224 .ciphertext
= "6363977de839486297e661c6c9d668eb",
227 /* Twofish paper "Known Answer Test", I=3 */
228 .path
= "/crypto/cipher/twofish-192",
229 .alg
= QCRYPTO_CIPHER_ALG_TWOFISH_192
,
230 .mode
= QCRYPTO_CIPHER_MODE_ECB
,
231 .key
= "88b2b2706b105e36b446bb6d731a1e88"
233 .plaintext
= "39da69d6ba4997d585b6dc073ca341b2",
234 .ciphertext
= "182b02d81497ea45f9daacdc29193a65",
237 /* Twofish paper "Known Answer Test", I=4 */
238 .path
= "/crypto/cipher/twofish-256",
239 .alg
= QCRYPTO_CIPHER_ALG_TWOFISH_256
,
240 .mode
= QCRYPTO_CIPHER_MODE_ECB
,
241 .key
= "d43bb7556ea32e46f2a282b7d45b4e0d"
242 "57ff739d4dc92c1bd7fc01700cc8216f",
243 .plaintext
= "90afe91bb288544f2c32dc239b2635e6",
244 .ciphertext
= "6cb4561c40bf0a9705931cb6d408e7fa",
247 /* #1 32 byte key, 32 byte PTX */
248 .path
= "/crypto/cipher/aes-xts-128-1",
249 .alg
= QCRYPTO_CIPHER_ALG_AES_128
,
250 .mode
= QCRYPTO_CIPHER_MODE_XTS
,
252 "00000000000000000000000000000000"
253 "00000000000000000000000000000000",
255 "00000000000000000000000000000000",
257 "00000000000000000000000000000000"
258 "00000000000000000000000000000000",
260 "917cf69ebd68b2ec9b9fe9a3eadda692"
261 "cd43d2f59598ed858c02c2652fbf922e",
264 /* #2, 32 byte key, 32 byte PTX */
265 .path
= "/crypto/cipher/aes-xts-128-2",
266 .alg
= QCRYPTO_CIPHER_ALG_AES_128
,
267 .mode
= QCRYPTO_CIPHER_MODE_XTS
,
269 "11111111111111111111111111111111"
270 "22222222222222222222222222222222",
272 "33333333330000000000000000000000",
274 "44444444444444444444444444444444"
275 "44444444444444444444444444444444",
277 "c454185e6a16936e39334038acef838b"
278 "fb186fff7480adc4289382ecd6d394f0",
281 /* #5 from xts.7, 32 byte key, 32 byte PTX */
282 .path
= "/crypto/cipher/aes-xts-128-3",
283 .alg
= QCRYPTO_CIPHER_ALG_AES_128
,
284 .mode
= QCRYPTO_CIPHER_MODE_XTS
,
286 "fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0"
287 "bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0",
289 "9a785634120000000000000000000000",
291 "44444444444444444444444444444444"
292 "44444444444444444444444444444444",
294 "b01f86f8edc1863706fa8a4253e34f28"
295 "af319de38334870f4dd1f94cbe9832f1",
298 /* #4, 32 byte key, 512 byte PTX */
299 .path
= "/crypto/cipher/aes-xts-128-4",
300 .alg
= QCRYPTO_CIPHER_ALG_AES_128
,
301 .mode
= QCRYPTO_CIPHER_MODE_XTS
,
303 "27182818284590452353602874713526"
304 "31415926535897932384626433832795",
306 "00000000000000000000000000000000",
308 "000102030405060708090a0b0c0d0e0f"
309 "101112131415161718191a1b1c1d1e1f"
310 "202122232425262728292a2b2c2d2e2f"
311 "303132333435363738393a3b3c3d3e3f"
312 "404142434445464748494a4b4c4d4e4f"
313 "505152535455565758595a5b5c5d5e5f"
314 "606162636465666768696a6b6c6d6e6f"
315 "707172737475767778797a7b7c7d7e7f"
316 "808182838485868788898a8b8c8d8e8f"
317 "909192939495969798999a9b9c9d9e9f"
318 "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
319 "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
320 "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
321 "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
322 "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
323 "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"
324 "000102030405060708090a0b0c0d0e0f"
325 "101112131415161718191a1b1c1d1e1f"
326 "202122232425262728292a2b2c2d2e2f"
327 "303132333435363738393a3b3c3d3e3f"
328 "404142434445464748494a4b4c4d4e4f"
329 "505152535455565758595a5b5c5d5e5f"
330 "606162636465666768696a6b6c6d6e6f"
331 "707172737475767778797a7b7c7d7e7f"
332 "808182838485868788898a8b8c8d8e8f"
333 "909192939495969798999a9b9c9d9e9f"
334 "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
335 "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
336 "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
337 "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
338 "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
339 "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
341 "27a7479befa1d476489f308cd4cfa6e2"
342 "a96e4bbe3208ff25287dd3819616e89c"
343 "c78cf7f5e543445f8333d8fa7f560000"
344 "05279fa5d8b5e4ad40e736ddb4d35412"
345 "328063fd2aab53e5ea1e0a9f332500a5"
346 "df9487d07a5c92cc512c8866c7e860ce"
347 "93fdf166a24912b422976146ae20ce84"
348 "6bb7dc9ba94a767aaef20c0d61ad0265"
349 "5ea92dc4c4e41a8952c651d33174be51"
350 "a10c421110e6d81588ede82103a252d8"
351 "a750e8768defffed9122810aaeb99f91"
352 "72af82b604dc4b8e51bcb08235a6f434"
353 "1332e4ca60482a4ba1a03b3e65008fc5"
354 "da76b70bf1690db4eae29c5f1badd03c"
355 "5ccf2a55d705ddcd86d449511ceb7ec3"
356 "0bf12b1fa35b913f9f747a8afd1b130e"
357 "94bff94effd01a91735ca1726acd0b19"
358 "7c4e5b03393697e126826fb6bbde8ecc"
359 "1e08298516e2c9ed03ff3c1b7860f6de"
360 "76d4cecd94c8119855ef5297ca67e9f3"
361 "e7ff72b1e99785ca0a7e7720c5b36dc6"
362 "d72cac9574c8cbbc2f801e23e56fd344"
363 "b07f22154beba0f08ce8891e643ed995"
364 "c94d9a69c9f1b5f499027a78572aeebd"
365 "74d20cc39881c213ee770b1010e4bea7"
366 "18846977ae119f7a023ab58cca0ad752"
367 "afe656bb3c17256a9f6e9bf19fdd5a38"
368 "fc82bbe872c5539edb609ef4f79c203e"
369 "bb140f2e583cb2ad15b4aa5b655016a8"
370 "449277dbd477ef2c8d6c017db738b18d"
371 "eb4a427d1923ce3ff262735779a418f2"
372 "0a282df920147beabe421ee5319d0568",
377 static inline int unhex(char c
)
379 if (c
>= 'a' && c
<= 'f') {
380 return 10 + (c
- 'a');
382 if (c
>= 'A' && c
<= 'F') {
383 return 10 + (c
- 'A');
388 static inline char hex(int i
)
393 return 'a' + (i
- 10);
396 static size_t unhex_string(const char *hexstr
,
407 len
= strlen(hexstr
);
408 *data
= g_new0(uint8_t, len
/ 2);
410 for (i
= 0; i
< len
; i
+= 2) {
411 (*data
)[i
/2] = (unhex(hexstr
[i
]) << 4) | unhex(hexstr
[i
+1]);
416 static char *hex_string(const uint8_t *bytes
,
419 char *hexstr
= g_new0(char, len
* 2 + 1);
422 for (i
= 0; i
< len
; i
++) {
423 hexstr
[i
*2] = hex((bytes
[i
] >> 4) & 0xf);
424 hexstr
[i
*2+1] = hex(bytes
[i
] & 0xf);
426 hexstr
[len
*2] = '\0';
431 static void test_cipher(const void *opaque
)
433 const QCryptoCipherTestData
*data
= opaque
;
435 QCryptoCipher
*cipher
;
436 uint8_t *key
, *iv
, *ciphertext
, *plaintext
, *outtext
;
437 size_t nkey
, niv
, nciphertext
, nplaintext
;
439 size_t ivsize
, keysize
, blocksize
;
441 nkey
= unhex_string(data
->key
, &key
);
442 niv
= unhex_string(data
->iv
, &iv
);
443 nciphertext
= unhex_string(data
->ciphertext
, &ciphertext
);
444 nplaintext
= unhex_string(data
->plaintext
, &plaintext
);
446 g_assert(nciphertext
== nplaintext
);
448 outtext
= g_new0(uint8_t, nciphertext
);
450 cipher
= qcrypto_cipher_new(
451 data
->alg
, data
->mode
,
454 g_assert(cipher
!= NULL
);
456 keysize
= qcrypto_cipher_get_key_len(data
->alg
);
457 blocksize
= qcrypto_cipher_get_block_len(data
->alg
);
458 ivsize
= qcrypto_cipher_get_iv_len(data
->alg
, data
->mode
);
460 if (data
->mode
== QCRYPTO_CIPHER_MODE_XTS
) {
461 g_assert_cmpint(keysize
* 2, ==, nkey
);
463 g_assert_cmpint(keysize
, ==, nkey
);
465 g_assert_cmpint(ivsize
, ==, niv
);
467 g_assert_cmpint(blocksize
, ==, niv
);
471 g_assert(qcrypto_cipher_setiv(cipher
,
475 g_assert(qcrypto_cipher_encrypt(cipher
,
481 outtexthex
= hex_string(outtext
, nciphertext
);
483 g_assert_cmpstr(outtexthex
, ==, data
->ciphertext
);
488 g_assert(qcrypto_cipher_setiv(cipher
,
492 g_assert(qcrypto_cipher_decrypt(cipher
,
498 outtexthex
= hex_string(outtext
, nplaintext
);
500 g_assert_cmpstr(outtexthex
, ==, data
->plaintext
);
508 qcrypto_cipher_free(cipher
);
512 static void test_cipher_null_iv(void)
514 QCryptoCipher
*cipher
;
515 uint8_t key
[32] = { 0 };
516 uint8_t plaintext
[32] = { 0 };
517 uint8_t ciphertext
[32] = { 0 };
519 cipher
= qcrypto_cipher_new(
520 QCRYPTO_CIPHER_ALG_AES_256
,
521 QCRYPTO_CIPHER_MODE_CBC
,
524 g_assert(cipher
!= NULL
);
526 /* Don't call qcrypto_cipher_setiv */
528 qcrypto_cipher_encrypt(cipher
,
534 qcrypto_cipher_free(cipher
);
537 static void test_cipher_short_plaintext(void)
540 QCryptoCipher
*cipher
;
541 uint8_t key
[32] = { 0 };
542 uint8_t plaintext1
[20] = { 0 };
543 uint8_t ciphertext1
[20] = { 0 };
544 uint8_t plaintext2
[40] = { 0 };
545 uint8_t ciphertext2
[40] = { 0 };
548 cipher
= qcrypto_cipher_new(
549 QCRYPTO_CIPHER_ALG_AES_256
,
550 QCRYPTO_CIPHER_MODE_CBC
,
553 g_assert(cipher
!= NULL
);
555 /* Should report an error as plaintext is shorter
558 ret
= qcrypto_cipher_encrypt(cipher
,
564 g_assert(err
!= NULL
);
569 /* Should report an error as plaintext is larger than
570 * block size, but not a multiple of block size
572 ret
= qcrypto_cipher_encrypt(cipher
,
578 g_assert(err
!= NULL
);
581 qcrypto_cipher_free(cipher
);
584 int main(int argc
, char **argv
)
588 g_test_init(&argc
, &argv
, NULL
);
590 g_assert(qcrypto_init(NULL
) == 0);
592 for (i
= 0; i
< G_N_ELEMENTS(test_data
); i
++) {
593 if (qcrypto_cipher_supports(test_data
[i
].alg
)) {
594 g_test_add_data_func(test_data
[i
].path
, &test_data
[i
], test_cipher
);
598 g_test_add_func("/crypto/cipher/null-iv",
599 test_cipher_null_iv
);
601 g_test_add_func("/crypto/cipher/short-plaintext",
602 test_cipher_short_plaintext
);