1 /* 2 * QEMU Crypto block encryption 3 * 4 * Copyright (c) 2016 Red Hat, Inc. 5 * 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. 10 * 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. 15 * 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/>. 18 * 19 */ 20 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" 29 #ifndef _WIN32 30 #include <sys/resource.h> 31 #endif 32 33 #if (defined(_WIN32) || defined RUSAGE_THREAD) && \ 34 (defined(CONFIG_NETTLE) || defined(CONFIG_GCRYPT) || \ 35 defined(CONFIG_GNUTLS_CRYPTO)) 36 #define TEST_LUKS 37 #else 38 #undef TEST_LUKS 39 #endif 40 41 static QCryptoBlockCreateOptions qcow_create_opts = { 42 .format = Q_CRYPTO_BLOCK_FORMAT_QCOW, 43 .u.qcow = { 44 .has_key_secret = true, 45 .key_secret = (char *)"sec0", 46 }, 47 }; 48 49 static QCryptoBlockOpenOptions qcow_open_opts = { 50 .format = Q_CRYPTO_BLOCK_FORMAT_QCOW, 51 .u.qcow = { 52 .has_key_secret = true, 53 .key_secret = (char *)"sec0", 54 }, 55 }; 56 57 58 #ifdef TEST_LUKS 59 static QCryptoBlockOpenOptions luks_open_opts = { 60 .format = Q_CRYPTO_BLOCK_FORMAT_LUKS, 61 .u.luks = { 62 .has_key_secret = true, 63 .key_secret = (char *)"sec0", 64 }, 65 }; 66 67 68 /* Creation with all default values */ 69 static QCryptoBlockCreateOptions luks_create_opts_default = { 70 .format = Q_CRYPTO_BLOCK_FORMAT_LUKS, 71 .u.luks = { 72 .has_key_secret = true, 73 .key_secret = (char *)"sec0", 74 }, 75 }; 76 77 78 /* ...and with explicit values */ 79 static QCryptoBlockCreateOptions luks_create_opts_aes256_cbc_plain64 = { 80 .format = Q_CRYPTO_BLOCK_FORMAT_LUKS, 81 .u.luks = { 82 .has_key_secret = true, 83 .key_secret = (char *)"sec0", 84 .has_cipher_alg = true, 85 .cipher_alg = QCRYPTO_CIPHER_ALG_AES_256, 86 .has_cipher_mode = true, 87 .cipher_mode = QCRYPTO_CIPHER_MODE_CBC, 88 .has_ivgen_alg = true, 89 .ivgen_alg = QCRYPTO_IVGEN_ALG_PLAIN64, 90 }, 91 }; 92 93 94 static QCryptoBlockCreateOptions luks_create_opts_aes256_cbc_essiv = { 95 .format = Q_CRYPTO_BLOCK_FORMAT_LUKS, 96 .u.luks = { 97 .has_key_secret = true, 98 .key_secret = (char *)"sec0", 99 .has_cipher_alg = true, 100 .cipher_alg = QCRYPTO_CIPHER_ALG_AES_256, 101 .has_cipher_mode = true, 102 .cipher_mode = QCRYPTO_CIPHER_MODE_CBC, 103 .has_ivgen_alg = true, 104 .ivgen_alg = QCRYPTO_IVGEN_ALG_ESSIV, 105 .has_ivgen_hash_alg = true, 106 .ivgen_hash_alg = QCRYPTO_HASH_ALG_SHA256, 107 .has_hash_alg = true, 108 .hash_alg = QCRYPTO_HASH_ALG_SHA1, 109 }, 110 }; 111 #endif /* TEST_LUKS */ 112 113 114 static struct QCryptoBlockTestData { 115 const char *path; 116 QCryptoBlockCreateOptions *create_opts; 117 QCryptoBlockOpenOptions *open_opts; 118 119 bool expect_header; 120 121 QCryptoCipherAlgorithm cipher_alg; 122 QCryptoCipherMode cipher_mode; 123 QCryptoHashAlgorithm hash_alg; 124 125 QCryptoIVGenAlgorithm ivgen_alg; 126 QCryptoHashAlgorithm ivgen_hash; 127 128 bool slow; 129 } test_data[] = { 130 { 131 .path = "/crypto/block/qcow", 132 .create_opts = &qcow_create_opts, 133 .open_opts = &qcow_open_opts, 134 135 .expect_header = false, 136 137 .cipher_alg = QCRYPTO_CIPHER_ALG_AES_128, 138 .cipher_mode = QCRYPTO_CIPHER_MODE_CBC, 139 140 .ivgen_alg = QCRYPTO_IVGEN_ALG_PLAIN64, 141 }, 142 #ifdef TEST_LUKS 143 { 144 .path = "/crypto/block/luks/default", 145 .create_opts = &luks_create_opts_default, 146 .open_opts = &luks_open_opts, 147 148 .expect_header = true, 149 150 .cipher_alg = QCRYPTO_CIPHER_ALG_AES_256, 151 .cipher_mode = QCRYPTO_CIPHER_MODE_XTS, 152 .hash_alg = QCRYPTO_HASH_ALG_SHA256, 153 154 .ivgen_alg = QCRYPTO_IVGEN_ALG_PLAIN64, 155 156 .slow = true, 157 }, 158 { 159 .path = "/crypto/block/luks/aes-256-cbc-plain64", 160 .create_opts = &luks_create_opts_aes256_cbc_plain64, 161 .open_opts = &luks_open_opts, 162 163 .expect_header = true, 164 165 .cipher_alg = QCRYPTO_CIPHER_ALG_AES_256, 166 .cipher_mode = QCRYPTO_CIPHER_MODE_CBC, 167 .hash_alg = QCRYPTO_HASH_ALG_SHA256, 168 169 .ivgen_alg = QCRYPTO_IVGEN_ALG_PLAIN64, 170 171 .slow = true, 172 }, 173 { 174 .path = "/crypto/block/luks/aes-256-cbc-essiv", 175 .create_opts = &luks_create_opts_aes256_cbc_essiv, 176 .open_opts = &luks_open_opts, 177 178 .expect_header = true, 179 180 .cipher_alg = QCRYPTO_CIPHER_ALG_AES_256, 181 .cipher_mode = QCRYPTO_CIPHER_MODE_CBC, 182 .hash_alg = QCRYPTO_HASH_ALG_SHA1, 183 184 .ivgen_alg = QCRYPTO_IVGEN_ALG_ESSIV, 185 .ivgen_hash = QCRYPTO_HASH_ALG_SHA256, 186 187 .slow = true, 188 }, 189 #endif 190 }; 191 192 193 static int test_block_read_func(QCryptoBlock *block, 194 size_t offset, 195 uint8_t *buf, 196 size_t buflen, 197 void *opaque, 198 Error **errp) 199 { 200 Buffer *header = opaque; 201 202 g_assert_cmpint(offset + buflen, <=, header->capacity); 203 204 memcpy(buf, header->buffer + offset, buflen); 205 206 return 0; 207 } 208 209 210 static int test_block_init_func(QCryptoBlock *block, 211 size_t headerlen, 212 void *opaque, 213 Error **errp) 214 { 215 Buffer *header = opaque; 216 217 g_assert_cmpint(header->capacity, ==, 0); 218 219 buffer_reserve(header, headerlen); 220 221 return 0; 222 } 223 224 225 static int test_block_write_func(QCryptoBlock *block, 226 size_t offset, 227 const uint8_t *buf, 228 size_t buflen, 229 void *opaque, 230 Error **errp) 231 { 232 Buffer *header = opaque; 233 234 g_assert_cmpint(buflen + offset, <=, header->capacity); 235 236 memcpy(header->buffer + offset, buf, buflen); 237 header->offset = offset + buflen; 238 239 return 0; 240 } 241 242 243 static Object *test_block_secret(void) 244 { 245 return object_new_with_props( 246 TYPE_QCRYPTO_SECRET, 247 object_get_objects_root(), 248 "sec0", 249 &error_abort, 250 "data", "123456", 251 NULL); 252 } 253 254 static void test_block_assert_setup(const struct QCryptoBlockTestData *data, 255 QCryptoBlock *blk) 256 { 257 QCryptoIVGen *ivgen; 258 QCryptoCipher *cipher; 259 260 ivgen = qcrypto_block_get_ivgen(blk); 261 cipher = qcrypto_block_get_cipher(blk); 262 263 g_assert(ivgen); 264 g_assert(cipher); 265 266 g_assert_cmpint(data->cipher_alg, ==, cipher->alg); 267 g_assert_cmpint(data->cipher_mode, ==, cipher->mode); 268 g_assert_cmpint(data->hash_alg, ==, 269 qcrypto_block_get_kdf_hash(blk)); 270 271 g_assert_cmpint(data->ivgen_alg, ==, 272 qcrypto_ivgen_get_algorithm(ivgen)); 273 g_assert_cmpint(data->ivgen_hash, ==, 274 qcrypto_ivgen_get_hash(ivgen)); 275 } 276 277 278 static void test_block(gconstpointer opaque) 279 { 280 const struct QCryptoBlockTestData *data = opaque; 281 QCryptoBlock *blk; 282 Buffer header; 283 Object *sec = test_block_secret(); 284 285 memset(&header, 0, sizeof(header)); 286 buffer_init(&header, "header"); 287 288 blk = qcrypto_block_create(data->create_opts, NULL, 289 test_block_init_func, 290 test_block_write_func, 291 &header, 292 &error_abort); 293 g_assert(blk); 294 295 if (data->expect_header) { 296 g_assert_cmpint(header.capacity, >, 0); 297 } else { 298 g_assert_cmpint(header.capacity, ==, 0); 299 } 300 301 test_block_assert_setup(data, blk); 302 303 qcrypto_block_free(blk); 304 object_unparent(sec); 305 306 /* Ensure we can't open without the secret */ 307 blk = qcrypto_block_open(data->open_opts, NULL, 308 test_block_read_func, 309 &header, 310 0, 311 1, 312 NULL); 313 g_assert(blk == NULL); 314 315 /* Ensure we can't open without the secret, unless NO_IO */ 316 blk = qcrypto_block_open(data->open_opts, NULL, 317 test_block_read_func, 318 &header, 319 QCRYPTO_BLOCK_OPEN_NO_IO, 320 1, 321 &error_abort); 322 323 g_assert(qcrypto_block_get_cipher(blk) == NULL); 324 g_assert(qcrypto_block_get_ivgen(blk) == NULL); 325 326 qcrypto_block_free(blk); 327 328 329 /* Now open for real with secret */ 330 sec = test_block_secret(); 331 blk = qcrypto_block_open(data->open_opts, NULL, 332 test_block_read_func, 333 &header, 334 0, 335 1, 336 &error_abort); 337 g_assert(blk); 338 339 test_block_assert_setup(data, blk); 340 341 qcrypto_block_free(blk); 342 343 object_unparent(sec); 344 345 buffer_free(&header); 346 } 347 348 349 #ifdef TEST_LUKS 350 typedef const char *(*LuksHeaderDoBadStuff)(QCryptoBlockLUKSHeader *hdr); 351 352 static void 353 test_luks_bad_header(gconstpointer data) 354 { 355 LuksHeaderDoBadStuff badstuff = data; 356 QCryptoBlock *blk; 357 Buffer buf; 358 Object *sec = test_block_secret(); 359 QCryptoBlockLUKSHeader hdr; 360 Error *err = NULL; 361 const char *msg; 362 363 memset(&buf, 0, sizeof(buf)); 364 buffer_init(&buf, "header"); 365 366 /* Correctly create the volume initially */ 367 blk = qcrypto_block_create(&luks_create_opts_default, NULL, 368 test_block_init_func, 369 test_block_write_func, 370 &buf, 371 &error_abort); 372 g_assert(blk); 373 374 qcrypto_block_free(blk); 375 376 /* Mangle it in some unpleasant way */ 377 g_assert(buf.offset >= sizeof(hdr)); 378 memcpy(&hdr, buf.buffer, sizeof(hdr)); 379 qcrypto_block_luks_to_disk_endian(&hdr); 380 381 msg = badstuff(&hdr); 382 383 qcrypto_block_luks_from_disk_endian(&hdr); 384 memcpy(buf.buffer, &hdr, sizeof(hdr)); 385 386 /* Check that we fail to open it again */ 387 blk = qcrypto_block_open(&luks_open_opts, NULL, 388 test_block_read_func, 389 &buf, 390 0, 391 1, 392 &err); 393 g_assert(!blk); 394 g_assert(err); 395 396 g_assert_cmpstr(error_get_pretty(err), ==, msg); 397 error_free(err); 398 399 object_unparent(sec); 400 401 buffer_free(&buf); 402 } 403 404 static const char *luks_bad_null_term_cipher_name(QCryptoBlockLUKSHeader *hdr) 405 { 406 /* Replace NUL termination with spaces */ 407 char *offset = hdr->cipher_name + strlen(hdr->cipher_name); 408 memset(offset, ' ', sizeof(hdr->cipher_name) - (offset - hdr->cipher_name)); 409 410 return "LUKS header cipher name is not NUL terminated"; 411 } 412 413 static const char *luks_bad_null_term_cipher_mode(QCryptoBlockLUKSHeader *hdr) 414 { 415 /* Replace NUL termination with spaces */ 416 char *offset = hdr->cipher_mode + strlen(hdr->cipher_mode); 417 memset(offset, ' ', sizeof(hdr->cipher_mode) - (offset - hdr->cipher_mode)); 418 419 return "LUKS header cipher mode is not NUL terminated"; 420 } 421 422 static const char *luks_bad_null_term_hash_spec(QCryptoBlockLUKSHeader *hdr) 423 { 424 /* Replace NUL termination with spaces */ 425 char *offset = hdr->hash_spec + strlen(hdr->hash_spec); 426 memset(offset, ' ', sizeof(hdr->hash_spec) - (offset - hdr->hash_spec)); 427 428 return "LUKS header hash spec is not NUL terminated"; 429 } 430 431 static const char *luks_bad_cipher_name_empty(QCryptoBlockLUKSHeader *hdr) 432 { 433 memcpy(hdr->cipher_name, "", 1); 434 435 return "Algorithm '' with key size 32 bytes not supported"; 436 } 437 438 static const char *luks_bad_cipher_name_unknown(QCryptoBlockLUKSHeader *hdr) 439 { 440 memcpy(hdr->cipher_name, "aess", 5); 441 442 return "Algorithm 'aess' with key size 32 bytes not supported"; 443 } 444 445 static const char *luks_bad_cipher_xts_size(QCryptoBlockLUKSHeader *hdr) 446 { 447 hdr->master_key_len = 33; 448 449 return "XTS cipher key length should be a multiple of 2"; 450 } 451 452 static const char *luks_bad_cipher_cbc_size(QCryptoBlockLUKSHeader *hdr) 453 { 454 hdr->master_key_len = 33; 455 memcpy(hdr->cipher_mode, "cbc-essiv", 10); 456 457 return "Algorithm 'aes' with key size 33 bytes not supported"; 458 } 459 460 static const char *luks_bad_cipher_mode_empty(QCryptoBlockLUKSHeader *hdr) 461 { 462 memcpy(hdr->cipher_mode, "", 1); 463 464 return "Unexpected cipher mode string format ''"; 465 } 466 467 static const char *luks_bad_cipher_mode_unknown(QCryptoBlockLUKSHeader *hdr) 468 { 469 memcpy(hdr->cipher_mode, "xfs", 4); 470 471 return "Unexpected cipher mode string format 'xfs'"; 472 } 473 474 static const char *luks_bad_ivgen_separator(QCryptoBlockLUKSHeader *hdr) 475 { 476 memcpy(hdr->cipher_mode, "xts:plain64", 12); 477 478 return "Unexpected cipher mode string format 'xts:plain64'"; 479 } 480 481 static const char *luks_bad_ivgen_name_empty(QCryptoBlockLUKSHeader *hdr) 482 { 483 memcpy(hdr->cipher_mode, "xts-", 5); 484 485 return "IV generator '' not supported"; 486 } 487 488 static const char *luks_bad_ivgen_name_unknown(QCryptoBlockLUKSHeader *hdr) 489 { 490 memcpy(hdr->cipher_mode, "xts-plain65", 12); 491 492 return "IV generator 'plain65' not supported"; 493 } 494 495 static const char *luks_bad_ivgen_hash_empty(QCryptoBlockLUKSHeader *hdr) 496 { 497 memcpy(hdr->cipher_mode, "xts-plain65:", 13); 498 499 return "Hash algorithm '' not supported"; 500 } 501 502 static const char *luks_bad_ivgen_hash_unknown(QCryptoBlockLUKSHeader *hdr) 503 { 504 memcpy(hdr->cipher_mode, "xts-plain65:sha257", 19); 505 506 return "Hash algorithm 'sha257' not supported"; 507 } 508 509 static const char *luks_bad_hash_spec_empty(QCryptoBlockLUKSHeader *hdr) 510 { 511 memcpy(hdr->hash_spec, "", 1); 512 513 return "Hash algorithm '' not supported"; 514 } 515 516 static const char *luks_bad_hash_spec_unknown(QCryptoBlockLUKSHeader *hdr) 517 { 518 memcpy(hdr->hash_spec, "sha2566", 8); 519 520 return "Hash algorithm 'sha2566' not supported"; 521 } 522 523 static const char *luks_bad_stripes(QCryptoBlockLUKSHeader *hdr) 524 { 525 hdr->key_slots[0].stripes = 3999; 526 527 return "Keyslot 0 is corrupted (stripes 3999 != 4000)"; 528 } 529 530 static const char *luks_bad_key_overlap_header(QCryptoBlockLUKSHeader *hdr) 531 { 532 hdr->key_slots[0].key_offset_sector = 2; 533 534 return "Keyslot 0 is overlapping with the LUKS header"; 535 } 536 537 static const char *luks_bad_key_overlap_key(QCryptoBlockLUKSHeader *hdr) 538 { 539 hdr->key_slots[0].key_offset_sector = hdr->key_slots[1].key_offset_sector; 540 541 return "Keyslots 0 and 1 are overlapping in the header"; 542 } 543 544 static const char *luks_bad_key_overlap_payload(QCryptoBlockLUKSHeader *hdr) 545 { 546 hdr->key_slots[0].key_offset_sector = hdr->payload_offset_sector + 42; 547 548 return "Keyslot 0 is overlapping with the encrypted payload"; 549 } 550 551 static const char *luks_bad_payload_overlap_header(QCryptoBlockLUKSHeader *hdr) 552 { 553 hdr->payload_offset_sector = 2; 554 555 return "LUKS payload is overlapping with the header"; 556 } 557 558 static const char *luks_bad_key_iterations(QCryptoBlockLUKSHeader *hdr) 559 { 560 hdr->key_slots[0].iterations = 0; 561 562 return "Keyslot 0 iteration count is zero"; 563 } 564 565 static const char *luks_bad_iterations(QCryptoBlockLUKSHeader *hdr) 566 { 567 hdr->master_key_iterations = 0; 568 569 return "LUKS key iteration count is zero"; 570 } 571 #endif 572 573 int main(int argc, char **argv) 574 { 575 gsize i; 576 577 module_call_init(MODULE_INIT_QOM); 578 g_test_init(&argc, &argv, NULL); 579 580 g_assert(qcrypto_init(NULL) == 0); 581 582 for (i = 0; i < G_N_ELEMENTS(test_data); i++) { 583 if (test_data[i].open_opts->format == Q_CRYPTO_BLOCK_FORMAT_LUKS && 584 !qcrypto_hash_supports(test_data[i].hash_alg)) { 585 continue; 586 } 587 if (!test_data[i].slow || 588 g_test_slow()) { 589 g_test_add_data_func(test_data[i].path, &test_data[i], test_block); 590 } 591 } 592 593 #ifdef TEST_LUKS 594 if (g_test_slow()) { 595 g_test_add_data_func("/crypto/block/luks/bad/cipher-name-nul-term", 596 luks_bad_null_term_cipher_name, 597 test_luks_bad_header); 598 g_test_add_data_func("/crypto/block/luks/bad/cipher-mode-nul-term", 599 luks_bad_null_term_cipher_mode, 600 test_luks_bad_header); 601 g_test_add_data_func("/crypto/block/luks/bad/hash-spec-nul-term", 602 luks_bad_null_term_hash_spec, 603 test_luks_bad_header); 604 g_test_add_data_func("/crypto/block/luks/bad/cipher-name-empty", 605 luks_bad_cipher_name_empty, 606 test_luks_bad_header); 607 g_test_add_data_func("/crypto/block/luks/bad/cipher-name-unknown", 608 luks_bad_cipher_name_unknown, 609 test_luks_bad_header); 610 g_test_add_data_func("/crypto/block/luks/bad/cipher-xts-size", 611 luks_bad_cipher_xts_size, 612 test_luks_bad_header); 613 g_test_add_data_func("/crypto/block/luks/bad/cipher-cbc-size", 614 luks_bad_cipher_cbc_size, 615 test_luks_bad_header); 616 g_test_add_data_func("/crypto/block/luks/bad/cipher-mode-empty", 617 luks_bad_cipher_mode_empty, 618 test_luks_bad_header); 619 g_test_add_data_func("/crypto/block/luks/bad/cipher-mode-unknown", 620 luks_bad_cipher_mode_unknown, 621 test_luks_bad_header); 622 g_test_add_data_func("/crypto/block/luks/bad/ivgen-separator", 623 luks_bad_ivgen_separator, 624 test_luks_bad_header); 625 g_test_add_data_func("/crypto/block/luks/bad/ivgen-name-empty", 626 luks_bad_ivgen_name_empty, 627 test_luks_bad_header); 628 g_test_add_data_func("/crypto/block/luks/bad/ivgen-name-unknown", 629 luks_bad_ivgen_name_unknown, 630 test_luks_bad_header); 631 g_test_add_data_func("/crypto/block/luks/bad/ivgen-hash-empty", 632 luks_bad_ivgen_hash_empty, 633 test_luks_bad_header); 634 g_test_add_data_func("/crypto/block/luks/bad/ivgen-hash-unknown", 635 luks_bad_ivgen_hash_unknown, 636 test_luks_bad_header); 637 g_test_add_data_func("/crypto/block/luks/bad/hash-spec-empty", 638 luks_bad_hash_spec_empty, 639 test_luks_bad_header); 640 g_test_add_data_func("/crypto/block/luks/bad/hash-spec-unknown", 641 luks_bad_hash_spec_unknown, 642 test_luks_bad_header); 643 g_test_add_data_func("/crypto/block/luks/bad/stripes", 644 luks_bad_stripes, 645 test_luks_bad_header); 646 g_test_add_data_func("/crypto/block/luks/bad/key-overlap-header", 647 luks_bad_key_overlap_header, 648 test_luks_bad_header); 649 g_test_add_data_func("/crypto/block/luks/bad/key-overlap-key", 650 luks_bad_key_overlap_key, 651 test_luks_bad_header); 652 g_test_add_data_func("/crypto/block/luks/bad/key-overlap-payload", 653 luks_bad_key_overlap_payload, 654 test_luks_bad_header); 655 g_test_add_data_func("/crypto/block/luks/bad/payload-overlap-header", 656 luks_bad_payload_overlap_header, 657 test_luks_bad_header); 658 g_test_add_data_func("/crypto/block/luks/bad/iterations", 659 luks_bad_iterations, 660 test_luks_bad_header); 661 g_test_add_data_func("/crypto/block/luks/bad/key-iterations", 662 luks_bad_key_iterations, 663 test_luks_bad_header); 664 } 665 #endif 666 667 return g_test_run(); 668 } 669