2 * QEMU Crypto block encryption
4 * Copyright (c) 2016 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.1 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"
22 #include "qapi/error.h"
23 #include "crypto/init.h"
24 #include "crypto/block.h"
25 #include "crypto/block-luks-priv.h"
26 #include "qemu/buffer.h"
27 #include "qemu/module.h"
28 #include "crypto/secret.h"
30 #include <sys/resource.h>
33 #if (defined(_WIN32) || defined RUSAGE_THREAD) && \
34 (defined(CONFIG_NETTLE) || defined(CONFIG_GCRYPT) || \
35 defined(CONFIG_GNUTLS_CRYPTO))
41 static QCryptoBlockCreateOptions qcow_create_opts
= {
42 .format
= Q_CRYPTO_BLOCK_FORMAT_QCOW
,
44 .key_secret
= (char *)"sec0",
48 static QCryptoBlockOpenOptions qcow_open_opts
= {
49 .format
= Q_CRYPTO_BLOCK_FORMAT_QCOW
,
51 .key_secret
= (char *)"sec0",
57 static QCryptoBlockOpenOptions luks_open_opts
= {
58 .format
= Q_CRYPTO_BLOCK_FORMAT_LUKS
,
60 .key_secret
= (char *)"sec0",
65 /* Creation with all default values */
66 static QCryptoBlockCreateOptions luks_create_opts_default
= {
67 .format
= Q_CRYPTO_BLOCK_FORMAT_LUKS
,
69 .key_secret
= (char *)"sec0",
74 /* ...and with explicit values */
75 static QCryptoBlockCreateOptions luks_create_opts_aes256_cbc_plain64
= {
76 .format
= Q_CRYPTO_BLOCK_FORMAT_LUKS
,
78 .key_secret
= (char *)"sec0",
79 .has_cipher_alg
= true,
80 .cipher_alg
= QCRYPTO_CIPHER_ALG_AES_256
,
81 .has_cipher_mode
= true,
82 .cipher_mode
= QCRYPTO_CIPHER_MODE_CBC
,
83 .has_ivgen_alg
= true,
84 .ivgen_alg
= QCRYPTO_IVGEN_ALG_PLAIN64
,
89 static QCryptoBlockCreateOptions luks_create_opts_aes256_cbc_essiv
= {
90 .format
= Q_CRYPTO_BLOCK_FORMAT_LUKS
,
92 .key_secret
= (char *)"sec0",
93 .has_cipher_alg
= true,
94 .cipher_alg
= QCRYPTO_CIPHER_ALG_AES_256
,
95 .has_cipher_mode
= true,
96 .cipher_mode
= QCRYPTO_CIPHER_MODE_CBC
,
97 .has_ivgen_alg
= true,
98 .ivgen_alg
= QCRYPTO_IVGEN_ALG_ESSIV
,
99 .has_ivgen_hash_alg
= true,
100 .ivgen_hash_alg
= QCRYPTO_HASH_ALG_SHA256
,
101 .has_hash_alg
= true,
102 .hash_alg
= QCRYPTO_HASH_ALG_SHA1
,
105 #endif /* TEST_LUKS */
108 static struct QCryptoBlockTestData
{
110 QCryptoBlockCreateOptions
*create_opts
;
111 QCryptoBlockOpenOptions
*open_opts
;
115 QCryptoCipherAlgorithm cipher_alg
;
116 QCryptoCipherMode cipher_mode
;
117 QCryptoHashAlgorithm hash_alg
;
119 QCryptoIVGenAlgorithm ivgen_alg
;
120 QCryptoHashAlgorithm ivgen_hash
;
125 .path
= "/crypto/block/qcow",
126 .create_opts
= &qcow_create_opts
,
127 .open_opts
= &qcow_open_opts
,
129 .expect_header
= false,
131 .cipher_alg
= QCRYPTO_CIPHER_ALG_AES_128
,
132 .cipher_mode
= QCRYPTO_CIPHER_MODE_CBC
,
134 .ivgen_alg
= QCRYPTO_IVGEN_ALG_PLAIN64
,
138 .path
= "/crypto/block/luks/default",
139 .create_opts
= &luks_create_opts_default
,
140 .open_opts
= &luks_open_opts
,
142 .expect_header
= true,
144 .cipher_alg
= QCRYPTO_CIPHER_ALG_AES_256
,
145 .cipher_mode
= QCRYPTO_CIPHER_MODE_XTS
,
146 .hash_alg
= QCRYPTO_HASH_ALG_SHA256
,
148 .ivgen_alg
= QCRYPTO_IVGEN_ALG_PLAIN64
,
153 .path
= "/crypto/block/luks/aes-256-cbc-plain64",
154 .create_opts
= &luks_create_opts_aes256_cbc_plain64
,
155 .open_opts
= &luks_open_opts
,
157 .expect_header
= true,
159 .cipher_alg
= QCRYPTO_CIPHER_ALG_AES_256
,
160 .cipher_mode
= QCRYPTO_CIPHER_MODE_CBC
,
161 .hash_alg
= QCRYPTO_HASH_ALG_SHA256
,
163 .ivgen_alg
= QCRYPTO_IVGEN_ALG_PLAIN64
,
168 .path
= "/crypto/block/luks/aes-256-cbc-essiv",
169 .create_opts
= &luks_create_opts_aes256_cbc_essiv
,
170 .open_opts
= &luks_open_opts
,
172 .expect_header
= true,
174 .cipher_alg
= QCRYPTO_CIPHER_ALG_AES_256
,
175 .cipher_mode
= QCRYPTO_CIPHER_MODE_CBC
,
176 .hash_alg
= QCRYPTO_HASH_ALG_SHA1
,
178 .ivgen_alg
= QCRYPTO_IVGEN_ALG_ESSIV
,
179 .ivgen_hash
= QCRYPTO_HASH_ALG_SHA256
,
187 static int test_block_read_func(QCryptoBlock
*block
,
194 Buffer
*header
= opaque
;
196 g_assert_cmpint(offset
+ buflen
, <=, header
->capacity
);
198 memcpy(buf
, header
->buffer
+ offset
, buflen
);
204 static int test_block_init_func(QCryptoBlock
*block
,
209 Buffer
*header
= opaque
;
211 g_assert_cmpint(header
->capacity
, ==, 0);
213 buffer_reserve(header
, headerlen
);
219 static int test_block_write_func(QCryptoBlock
*block
,
226 Buffer
*header
= opaque
;
228 g_assert_cmpint(buflen
+ offset
, <=, header
->capacity
);
230 memcpy(header
->buffer
+ offset
, buf
, buflen
);
231 header
->offset
= offset
+ buflen
;
237 static Object
*test_block_secret(void)
239 return object_new_with_props(
241 object_get_objects_root(),
248 static void test_block_assert_setup(const struct QCryptoBlockTestData
*data
,
252 QCryptoCipher
*cipher
;
254 ivgen
= qcrypto_block_get_ivgen(blk
);
255 cipher
= qcrypto_block_get_cipher(blk
);
260 g_assert_cmpint(data
->cipher_alg
, ==, cipher
->alg
);
261 g_assert_cmpint(data
->cipher_mode
, ==, cipher
->mode
);
262 g_assert_cmpint(data
->hash_alg
, ==,
263 qcrypto_block_get_kdf_hash(blk
));
265 g_assert_cmpint(data
->ivgen_alg
, ==,
266 qcrypto_ivgen_get_algorithm(ivgen
));
267 g_assert_cmpint(data
->ivgen_hash
, ==,
268 qcrypto_ivgen_get_hash(ivgen
));
272 static void test_block(gconstpointer opaque
)
274 const struct QCryptoBlockTestData
*data
= opaque
;
277 Object
*sec
= test_block_secret();
279 memset(&header
, 0, sizeof(header
));
280 buffer_init(&header
, "header");
282 blk
= qcrypto_block_create(data
->create_opts
, NULL
,
283 test_block_init_func
,
284 test_block_write_func
,
290 if (data
->expect_header
) {
291 g_assert_cmpint(header
.capacity
, >, 0);
293 g_assert_cmpint(header
.capacity
, ==, 0);
296 test_block_assert_setup(data
, blk
);
298 qcrypto_block_free(blk
);
299 object_unparent(sec
);
301 /* Ensure we can't open without the secret */
302 blk
= qcrypto_block_open(data
->open_opts
, NULL
,
303 test_block_read_func
,
308 g_assert(blk
== NULL
);
310 /* Ensure we can't open without the secret, unless NO_IO */
311 blk
= qcrypto_block_open(data
->open_opts
, NULL
,
312 test_block_read_func
,
314 QCRYPTO_BLOCK_OPEN_NO_IO
,
318 g_assert(qcrypto_block_get_cipher(blk
) == NULL
);
319 g_assert(qcrypto_block_get_ivgen(blk
) == NULL
);
321 qcrypto_block_free(blk
);
324 /* Now open for real with secret */
325 sec
= test_block_secret();
326 blk
= qcrypto_block_open(data
->open_opts
, NULL
,
327 test_block_read_func
,
334 test_block_assert_setup(data
, blk
);
336 qcrypto_block_free(blk
);
338 object_unparent(sec
);
340 buffer_free(&header
);
345 typedef const char *(*LuksHeaderDoBadStuff
)(QCryptoBlockLUKSHeader
*hdr
);
348 test_luks_bad_header(gconstpointer data
)
350 LuksHeaderDoBadStuff badstuff
= data
;
353 Object
*sec
= test_block_secret();
354 QCryptoBlockLUKSHeader hdr
;
358 memset(&buf
, 0, sizeof(buf
));
359 buffer_init(&buf
, "header");
361 /* Correctly create the volume initially */
362 blk
= qcrypto_block_create(&luks_create_opts_default
, NULL
,
363 test_block_init_func
,
364 test_block_write_func
,
370 qcrypto_block_free(blk
);
372 /* Mangle it in some unpleasant way */
373 g_assert(buf
.offset
>= sizeof(hdr
));
374 memcpy(&hdr
, buf
.buffer
, sizeof(hdr
));
375 qcrypto_block_luks_to_disk_endian(&hdr
);
377 msg
= badstuff(&hdr
);
379 qcrypto_block_luks_from_disk_endian(&hdr
);
380 memcpy(buf
.buffer
, &hdr
, sizeof(hdr
));
382 /* Check that we fail to open it again */
383 blk
= qcrypto_block_open(&luks_open_opts
, NULL
,
384 test_block_read_func
,
392 g_assert_cmpstr(error_get_pretty(err
), ==, msg
);
395 object_unparent(sec
);
400 static const char *luks_bad_null_term_cipher_name(QCryptoBlockLUKSHeader
*hdr
)
402 /* Replace NUL termination with spaces */
403 char *offset
= hdr
->cipher_name
+ strlen(hdr
->cipher_name
);
404 memset(offset
, ' ', sizeof(hdr
->cipher_name
) - (offset
- hdr
->cipher_name
));
406 return "LUKS header cipher name is not NUL terminated";
409 static const char *luks_bad_null_term_cipher_mode(QCryptoBlockLUKSHeader
*hdr
)
411 /* Replace NUL termination with spaces */
412 char *offset
= hdr
->cipher_mode
+ strlen(hdr
->cipher_mode
);
413 memset(offset
, ' ', sizeof(hdr
->cipher_mode
) - (offset
- hdr
->cipher_mode
));
415 return "LUKS header cipher mode is not NUL terminated";
418 static const char *luks_bad_null_term_hash_spec(QCryptoBlockLUKSHeader
*hdr
)
420 /* Replace NUL termination with spaces */
421 char *offset
= hdr
->hash_spec
+ strlen(hdr
->hash_spec
);
422 memset(offset
, ' ', sizeof(hdr
->hash_spec
) - (offset
- hdr
->hash_spec
));
424 return "LUKS header hash spec is not NUL terminated";
427 static const char *luks_bad_cipher_name_empty(QCryptoBlockLUKSHeader
*hdr
)
429 memcpy(hdr
->cipher_name
, "", 1);
431 return "Algorithm '' with key size 32 bytes not supported";
434 static const char *luks_bad_cipher_name_unknown(QCryptoBlockLUKSHeader
*hdr
)
436 memcpy(hdr
->cipher_name
, "aess", 5);
438 return "Algorithm 'aess' with key size 32 bytes not supported";
441 static const char *luks_bad_cipher_xts_size(QCryptoBlockLUKSHeader
*hdr
)
443 hdr
->master_key_len
= 33;
445 return "XTS cipher key length should be a multiple of 2";
448 static const char *luks_bad_cipher_cbc_size(QCryptoBlockLUKSHeader
*hdr
)
450 hdr
->master_key_len
= 33;
451 memcpy(hdr
->cipher_mode
, "cbc-essiv", 10);
453 return "Algorithm 'aes' with key size 33 bytes not supported";
456 static const char *luks_bad_cipher_mode_empty(QCryptoBlockLUKSHeader
*hdr
)
458 memcpy(hdr
->cipher_mode
, "", 1);
460 return "Unexpected cipher mode string format ''";
463 static const char *luks_bad_cipher_mode_unknown(QCryptoBlockLUKSHeader
*hdr
)
465 memcpy(hdr
->cipher_mode
, "xfs", 4);
467 return "Unexpected cipher mode string format 'xfs'";
470 static const char *luks_bad_ivgen_separator(QCryptoBlockLUKSHeader
*hdr
)
472 memcpy(hdr
->cipher_mode
, "xts:plain64", 12);
474 return "Unexpected cipher mode string format 'xts:plain64'";
477 static const char *luks_bad_ivgen_name_empty(QCryptoBlockLUKSHeader
*hdr
)
479 memcpy(hdr
->cipher_mode
, "xts-", 5);
481 return "IV generator '' not supported";
484 static const char *luks_bad_ivgen_name_unknown(QCryptoBlockLUKSHeader
*hdr
)
486 memcpy(hdr
->cipher_mode
, "xts-plain65", 12);
488 return "IV generator 'plain65' not supported";
491 static const char *luks_bad_ivgen_hash_empty(QCryptoBlockLUKSHeader
*hdr
)
493 memcpy(hdr
->cipher_mode
, "xts-plain65:", 13);
495 return "Hash algorithm '' not supported";
498 static const char *luks_bad_ivgen_hash_unknown(QCryptoBlockLUKSHeader
*hdr
)
500 memcpy(hdr
->cipher_mode
, "xts-plain65:sha257", 19);
502 return "Hash algorithm 'sha257' not supported";
505 static const char *luks_bad_hash_spec_empty(QCryptoBlockLUKSHeader
*hdr
)
507 memcpy(hdr
->hash_spec
, "", 1);
509 return "Hash algorithm '' not supported";
512 static const char *luks_bad_hash_spec_unknown(QCryptoBlockLUKSHeader
*hdr
)
514 memcpy(hdr
->hash_spec
, "sha2566", 8);
516 return "Hash algorithm 'sha2566' not supported";
519 static const char *luks_bad_stripes(QCryptoBlockLUKSHeader
*hdr
)
521 hdr
->key_slots
[0].stripes
= 3999;
523 return "Keyslot 0 is corrupted (stripes 3999 != 4000)";
526 static const char *luks_bad_key_overlap_header(QCryptoBlockLUKSHeader
*hdr
)
528 hdr
->key_slots
[0].key_offset_sector
= 2;
530 return "Keyslot 0 is overlapping with the LUKS header";
533 static const char *luks_bad_key_overlap_key(QCryptoBlockLUKSHeader
*hdr
)
535 hdr
->key_slots
[0].key_offset_sector
= hdr
->key_slots
[1].key_offset_sector
;
537 return "Keyslots 0 and 1 are overlapping in the header";
540 static const char *luks_bad_key_overlap_payload(QCryptoBlockLUKSHeader
*hdr
)
542 hdr
->key_slots
[0].key_offset_sector
= hdr
->payload_offset_sector
+ 42;
544 return "Keyslot 0 is overlapping with the encrypted payload";
547 static const char *luks_bad_payload_overlap_header(QCryptoBlockLUKSHeader
*hdr
)
549 hdr
->payload_offset_sector
= 2;
551 return "LUKS payload is overlapping with the header";
554 static const char *luks_bad_key_iterations(QCryptoBlockLUKSHeader
*hdr
)
556 hdr
->key_slots
[0].iterations
= 0;
558 return "Keyslot 0 iteration count is zero";
561 static const char *luks_bad_iterations(QCryptoBlockLUKSHeader
*hdr
)
563 hdr
->master_key_iterations
= 0;
565 return "LUKS key iteration count is zero";
569 int main(int argc
, char **argv
)
573 module_call_init(MODULE_INIT_QOM
);
574 g_test_init(&argc
, &argv
, NULL
);
576 g_assert(qcrypto_init(NULL
) == 0);
578 for (i
= 0; i
< G_N_ELEMENTS(test_data
); i
++) {
579 if (test_data
[i
].open_opts
->format
== Q_CRYPTO_BLOCK_FORMAT_LUKS
&&
580 !qcrypto_hash_supports(test_data
[i
].hash_alg
)) {
583 if (!test_data
[i
].slow
||
585 g_test_add_data_func(test_data
[i
].path
, &test_data
[i
], test_block
);
591 g_test_add_data_func("/crypto/block/luks/bad/cipher-name-nul-term",
592 luks_bad_null_term_cipher_name
,
593 test_luks_bad_header
);
594 g_test_add_data_func("/crypto/block/luks/bad/cipher-mode-nul-term",
595 luks_bad_null_term_cipher_mode
,
596 test_luks_bad_header
);
597 g_test_add_data_func("/crypto/block/luks/bad/hash-spec-nul-term",
598 luks_bad_null_term_hash_spec
,
599 test_luks_bad_header
);
600 g_test_add_data_func("/crypto/block/luks/bad/cipher-name-empty",
601 luks_bad_cipher_name_empty
,
602 test_luks_bad_header
);
603 g_test_add_data_func("/crypto/block/luks/bad/cipher-name-unknown",
604 luks_bad_cipher_name_unknown
,
605 test_luks_bad_header
);
606 g_test_add_data_func("/crypto/block/luks/bad/cipher-xts-size",
607 luks_bad_cipher_xts_size
,
608 test_luks_bad_header
);
609 g_test_add_data_func("/crypto/block/luks/bad/cipher-cbc-size",
610 luks_bad_cipher_cbc_size
,
611 test_luks_bad_header
);
612 g_test_add_data_func("/crypto/block/luks/bad/cipher-mode-empty",
613 luks_bad_cipher_mode_empty
,
614 test_luks_bad_header
);
615 g_test_add_data_func("/crypto/block/luks/bad/cipher-mode-unknown",
616 luks_bad_cipher_mode_unknown
,
617 test_luks_bad_header
);
618 g_test_add_data_func("/crypto/block/luks/bad/ivgen-separator",
619 luks_bad_ivgen_separator
,
620 test_luks_bad_header
);
621 g_test_add_data_func("/crypto/block/luks/bad/ivgen-name-empty",
622 luks_bad_ivgen_name_empty
,
623 test_luks_bad_header
);
624 g_test_add_data_func("/crypto/block/luks/bad/ivgen-name-unknown",
625 luks_bad_ivgen_name_unknown
,
626 test_luks_bad_header
);
627 g_test_add_data_func("/crypto/block/luks/bad/ivgen-hash-empty",
628 luks_bad_ivgen_hash_empty
,
629 test_luks_bad_header
);
630 g_test_add_data_func("/crypto/block/luks/bad/ivgen-hash-unknown",
631 luks_bad_ivgen_hash_unknown
,
632 test_luks_bad_header
);
633 g_test_add_data_func("/crypto/block/luks/bad/hash-spec-empty",
634 luks_bad_hash_spec_empty
,
635 test_luks_bad_header
);
636 g_test_add_data_func("/crypto/block/luks/bad/hash-spec-unknown",
637 luks_bad_hash_spec_unknown
,
638 test_luks_bad_header
);
639 g_test_add_data_func("/crypto/block/luks/bad/stripes",
641 test_luks_bad_header
);
642 g_test_add_data_func("/crypto/block/luks/bad/key-overlap-header",
643 luks_bad_key_overlap_header
,
644 test_luks_bad_header
);
645 g_test_add_data_func("/crypto/block/luks/bad/key-overlap-key",
646 luks_bad_key_overlap_key
,
647 test_luks_bad_header
);
648 g_test_add_data_func("/crypto/block/luks/bad/key-overlap-payload",
649 luks_bad_key_overlap_payload
,
650 test_luks_bad_header
);
651 g_test_add_data_func("/crypto/block/luks/bad/payload-overlap-header",
652 luks_bad_payload_overlap_header
,
653 test_luks_bad_header
);
654 g_test_add_data_func("/crypto/block/luks/bad/iterations",
656 test_luks_bad_header
);
657 g_test_add_data_func("/crypto/block/luks/bad/key-iterations",
658 luks_bad_key_iterations
,
659 test_luks_bad_header
);