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
,
289 if (data
->expect_header
) {
290 g_assert_cmpint(header
.capacity
, >, 0);
292 g_assert_cmpint(header
.capacity
, ==, 0);
295 test_block_assert_setup(data
, blk
);
297 qcrypto_block_free(blk
);
298 object_unparent(sec
);
300 /* Ensure we can't open without the secret */
301 blk
= qcrypto_block_open(data
->open_opts
, NULL
,
302 test_block_read_func
,
307 g_assert(blk
== NULL
);
309 /* Ensure we can't open without the secret, unless NO_IO */
310 blk
= qcrypto_block_open(data
->open_opts
, NULL
,
311 test_block_read_func
,
313 QCRYPTO_BLOCK_OPEN_NO_IO
,
317 g_assert(qcrypto_block_get_cipher(blk
) == NULL
);
318 g_assert(qcrypto_block_get_ivgen(blk
) == NULL
);
320 qcrypto_block_free(blk
);
323 /* Now open for real with secret */
324 sec
= test_block_secret();
325 blk
= qcrypto_block_open(data
->open_opts
, NULL
,
326 test_block_read_func
,
333 test_block_assert_setup(data
, blk
);
335 qcrypto_block_free(blk
);
337 object_unparent(sec
);
339 buffer_free(&header
);
344 typedef const char *(*LuksHeaderDoBadStuff
)(QCryptoBlockLUKSHeader
*hdr
);
347 test_luks_bad_header(gconstpointer data
)
349 LuksHeaderDoBadStuff badstuff
= data
;
352 Object
*sec
= test_block_secret();
353 QCryptoBlockLUKSHeader hdr
;
357 memset(&buf
, 0, sizeof(buf
));
358 buffer_init(&buf
, "header");
360 /* Correctly create the volume initially */
361 blk
= qcrypto_block_create(&luks_create_opts_default
, NULL
,
362 test_block_init_func
,
363 test_block_write_func
,
368 qcrypto_block_free(blk
);
370 /* Mangle it in some unpleasant way */
371 g_assert(buf
.offset
>= sizeof(hdr
));
372 memcpy(&hdr
, buf
.buffer
, sizeof(hdr
));
373 qcrypto_block_luks_to_disk_endian(&hdr
);
375 msg
= badstuff(&hdr
);
377 qcrypto_block_luks_from_disk_endian(&hdr
);
378 memcpy(buf
.buffer
, &hdr
, sizeof(hdr
));
380 /* Check that we fail to open it again */
381 blk
= qcrypto_block_open(&luks_open_opts
, NULL
,
382 test_block_read_func
,
390 g_assert_cmpstr(error_get_pretty(err
), ==, msg
);
393 object_unparent(sec
);
398 static const char *luks_bad_null_term_cipher_name(QCryptoBlockLUKSHeader
*hdr
)
400 /* Replace NUL termination with spaces */
401 char *offset
= hdr
->cipher_name
+ strlen(hdr
->cipher_name
);
402 memset(offset
, ' ', sizeof(hdr
->cipher_name
) - (offset
- hdr
->cipher_name
));
404 return "LUKS header cipher name is not NUL terminated";
407 static const char *luks_bad_null_term_cipher_mode(QCryptoBlockLUKSHeader
*hdr
)
409 /* Replace NUL termination with spaces */
410 char *offset
= hdr
->cipher_mode
+ strlen(hdr
->cipher_mode
);
411 memset(offset
, ' ', sizeof(hdr
->cipher_mode
) - (offset
- hdr
->cipher_mode
));
413 return "LUKS header cipher mode is not NUL terminated";
416 static const char *luks_bad_null_term_hash_spec(QCryptoBlockLUKSHeader
*hdr
)
418 /* Replace NUL termination with spaces */
419 char *offset
= hdr
->hash_spec
+ strlen(hdr
->hash_spec
);
420 memset(offset
, ' ', sizeof(hdr
->hash_spec
) - (offset
- hdr
->hash_spec
));
422 return "LUKS header hash spec is not NUL terminated";
425 static const char *luks_bad_cipher_name_empty(QCryptoBlockLUKSHeader
*hdr
)
427 memcpy(hdr
->cipher_name
, "", 1);
429 return "Algorithm '' with key size 32 bytes not supported";
432 static const char *luks_bad_cipher_name_unknown(QCryptoBlockLUKSHeader
*hdr
)
434 memcpy(hdr
->cipher_name
, "aess", 5);
436 return "Algorithm 'aess' with key size 32 bytes not supported";
439 static const char *luks_bad_cipher_xts_size(QCryptoBlockLUKSHeader
*hdr
)
441 hdr
->master_key_len
= 33;
443 return "XTS cipher key length should be a multiple of 2";
446 static const char *luks_bad_cipher_cbc_size(QCryptoBlockLUKSHeader
*hdr
)
448 hdr
->master_key_len
= 33;
449 memcpy(hdr
->cipher_mode
, "cbc-essiv", 10);
451 return "Algorithm 'aes' with key size 33 bytes not supported";
454 static const char *luks_bad_cipher_mode_empty(QCryptoBlockLUKSHeader
*hdr
)
456 memcpy(hdr
->cipher_mode
, "", 1);
458 return "Unexpected cipher mode string format ''";
461 static const char *luks_bad_cipher_mode_unknown(QCryptoBlockLUKSHeader
*hdr
)
463 memcpy(hdr
->cipher_mode
, "xfs", 4);
465 return "Unexpected cipher mode string format 'xfs'";
468 static const char *luks_bad_ivgen_separator(QCryptoBlockLUKSHeader
*hdr
)
470 memcpy(hdr
->cipher_mode
, "xts:plain64", 12);
472 return "Unexpected cipher mode string format 'xts:plain64'";
475 static const char *luks_bad_ivgen_name_empty(QCryptoBlockLUKSHeader
*hdr
)
477 memcpy(hdr
->cipher_mode
, "xts-", 5);
479 return "IV generator '' not supported";
482 static const char *luks_bad_ivgen_name_unknown(QCryptoBlockLUKSHeader
*hdr
)
484 memcpy(hdr
->cipher_mode
, "xts-plain65", 12);
486 return "IV generator 'plain65' not supported";
489 static const char *luks_bad_ivgen_hash_empty(QCryptoBlockLUKSHeader
*hdr
)
491 memcpy(hdr
->cipher_mode
, "xts-plain65:", 13);
493 return "Hash algorithm '' not supported";
496 static const char *luks_bad_ivgen_hash_unknown(QCryptoBlockLUKSHeader
*hdr
)
498 memcpy(hdr
->cipher_mode
, "xts-plain65:sha257", 19);
500 return "Hash algorithm 'sha257' not supported";
503 static const char *luks_bad_hash_spec_empty(QCryptoBlockLUKSHeader
*hdr
)
505 memcpy(hdr
->hash_spec
, "", 1);
507 return "Hash algorithm '' not supported";
510 static const char *luks_bad_hash_spec_unknown(QCryptoBlockLUKSHeader
*hdr
)
512 memcpy(hdr
->hash_spec
, "sha2566", 8);
514 return "Hash algorithm 'sha2566' not supported";
517 static const char *luks_bad_stripes(QCryptoBlockLUKSHeader
*hdr
)
519 hdr
->key_slots
[0].stripes
= 3999;
521 return "Keyslot 0 is corrupted (stripes 3999 != 4000)";
524 static const char *luks_bad_key_overlap_header(QCryptoBlockLUKSHeader
*hdr
)
526 hdr
->key_slots
[0].key_offset_sector
= 2;
528 return "Keyslot 0 is overlapping with the LUKS header";
531 static const char *luks_bad_key_overlap_key(QCryptoBlockLUKSHeader
*hdr
)
533 hdr
->key_slots
[0].key_offset_sector
= hdr
->key_slots
[1].key_offset_sector
;
535 return "Keyslots 0 and 1 are overlapping in the header";
538 static const char *luks_bad_key_overlap_payload(QCryptoBlockLUKSHeader
*hdr
)
540 hdr
->key_slots
[0].key_offset_sector
= hdr
->payload_offset_sector
+ 42;
542 return "Keyslot 0 is overlapping with the encrypted payload";
545 static const char *luks_bad_payload_overlap_header(QCryptoBlockLUKSHeader
*hdr
)
547 hdr
->payload_offset_sector
= 2;
549 return "LUKS payload is overlapping with the header";
552 static const char *luks_bad_key_iterations(QCryptoBlockLUKSHeader
*hdr
)
554 hdr
->key_slots
[0].iterations
= 0;
556 return "Keyslot 0 iteration count is zero";
559 static const char *luks_bad_iterations(QCryptoBlockLUKSHeader
*hdr
)
561 hdr
->master_key_iterations
= 0;
563 return "LUKS key iteration count is zero";
567 int main(int argc
, char **argv
)
571 module_call_init(MODULE_INIT_QOM
);
572 g_test_init(&argc
, &argv
, NULL
);
574 g_assert(qcrypto_init(NULL
) == 0);
576 for (i
= 0; i
< G_N_ELEMENTS(test_data
); i
++) {
577 if (test_data
[i
].open_opts
->format
== Q_CRYPTO_BLOCK_FORMAT_LUKS
&&
578 !qcrypto_hash_supports(test_data
[i
].hash_alg
)) {
581 if (!test_data
[i
].slow
||
583 g_test_add_data_func(test_data
[i
].path
, &test_data
[i
], test_block
);
589 g_test_add_data_func("/crypto/block/luks/bad/cipher-name-nul-term",
590 luks_bad_null_term_cipher_name
,
591 test_luks_bad_header
);
592 g_test_add_data_func("/crypto/block/luks/bad/cipher-mode-nul-term",
593 luks_bad_null_term_cipher_mode
,
594 test_luks_bad_header
);
595 g_test_add_data_func("/crypto/block/luks/bad/hash-spec-nul-term",
596 luks_bad_null_term_hash_spec
,
597 test_luks_bad_header
);
598 g_test_add_data_func("/crypto/block/luks/bad/cipher-name-empty",
599 luks_bad_cipher_name_empty
,
600 test_luks_bad_header
);
601 g_test_add_data_func("/crypto/block/luks/bad/cipher-name-unknown",
602 luks_bad_cipher_name_unknown
,
603 test_luks_bad_header
);
604 g_test_add_data_func("/crypto/block/luks/bad/cipher-xts-size",
605 luks_bad_cipher_xts_size
,
606 test_luks_bad_header
);
607 g_test_add_data_func("/crypto/block/luks/bad/cipher-cbc-size",
608 luks_bad_cipher_cbc_size
,
609 test_luks_bad_header
);
610 g_test_add_data_func("/crypto/block/luks/bad/cipher-mode-empty",
611 luks_bad_cipher_mode_empty
,
612 test_luks_bad_header
);
613 g_test_add_data_func("/crypto/block/luks/bad/cipher-mode-unknown",
614 luks_bad_cipher_mode_unknown
,
615 test_luks_bad_header
);
616 g_test_add_data_func("/crypto/block/luks/bad/ivgen-separator",
617 luks_bad_ivgen_separator
,
618 test_luks_bad_header
);
619 g_test_add_data_func("/crypto/block/luks/bad/ivgen-name-empty",
620 luks_bad_ivgen_name_empty
,
621 test_luks_bad_header
);
622 g_test_add_data_func("/crypto/block/luks/bad/ivgen-name-unknown",
623 luks_bad_ivgen_name_unknown
,
624 test_luks_bad_header
);
625 g_test_add_data_func("/crypto/block/luks/bad/ivgen-hash-empty",
626 luks_bad_ivgen_hash_empty
,
627 test_luks_bad_header
);
628 g_test_add_data_func("/crypto/block/luks/bad/ivgen-hash-unknown",
629 luks_bad_ivgen_hash_unknown
,
630 test_luks_bad_header
);
631 g_test_add_data_func("/crypto/block/luks/bad/hash-spec-empty",
632 luks_bad_hash_spec_empty
,
633 test_luks_bad_header
);
634 g_test_add_data_func("/crypto/block/luks/bad/hash-spec-unknown",
635 luks_bad_hash_spec_unknown
,
636 test_luks_bad_header
);
637 g_test_add_data_func("/crypto/block/luks/bad/stripes",
639 test_luks_bad_header
);
640 g_test_add_data_func("/crypto/block/luks/bad/key-overlap-header",
641 luks_bad_key_overlap_header
,
642 test_luks_bad_header
);
643 g_test_add_data_func("/crypto/block/luks/bad/key-overlap-key",
644 luks_bad_key_overlap_key
,
645 test_luks_bad_header
);
646 g_test_add_data_func("/crypto/block/luks/bad/key-overlap-payload",
647 luks_bad_key_overlap_payload
,
648 test_luks_bad_header
);
649 g_test_add_data_func("/crypto/block/luks/bad/payload-overlap-header",
650 luks_bad_payload_overlap_header
,
651 test_luks_bad_header
);
652 g_test_add_data_func("/crypto/block/luks/bad/iterations",
654 test_luks_bad_header
);
655 g_test_add_data_func("/crypto/block/luks/bad/key-iterations",
656 luks_bad_key_iterations
,
657 test_luks_bad_header
);