1 /* 2 * cryptsetup library API check functions 3 * 4 * Copyright (C) 2009 Red Hat, Inc. All rights reserved. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * version 2 as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 */ 19 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include <string.h> 23 #include <unistd.h> 24 #include <fcntl.h> 25 //#include <linux/fs.h> 26 #include <errno.h> 27 #include <sys/param.h> 28 #include <sys/stat.h> 29 #include <sys/ioctl.h> 30 31 #include "libcryptsetup.h" 32 33 #define DMDIR "/dev/mapper/" 34 35 #define DEVICE_1 "/dev/vn1" 36 #define DEVICE_1_UUID "28632274-8c8a-493f-835b-da802e1c576b" 37 #define DEVICE_2 "/dev/vn2" 38 #define DEVICE_EMPTY_name "crypt_zero" 39 #define DEVICE_EMPTY DMDIR DEVICE_EMPTY_name 40 #define DEVICE_ERROR_name "crypt_error" 41 #define DEVICE_ERROR DMDIR DEVICE_ERROR_name 42 43 #define CDEVICE_1 "ctest1" 44 #define CDEVICE_2 "ctest2" 45 #define CDEVICE_WRONG "O_o" 46 47 #define IMAGE1 "compatimage.img" 48 #define IMAGE_EMPTY "empty.img" 49 50 #define KEYFILE1 "key1.file" 51 #define KEY1 "compatkey" 52 53 #define KEYFILE2 "key2.file" 54 #define KEY2 "0123456789abcdef" 55 56 static int _debug = 0; 57 static int _verbose = 1; 58 59 static char global_log[4096]; 60 static int global_lines = 0; 61 62 static int gcrypt_compatible = 0; 63 64 // Helpers 65 static int _prepare_keyfile(const char *name, const char *passphrase) 66 { 67 int fd, r; 68 69 fd = open(name, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR); 70 if (fd != -1) { 71 r = write(fd, passphrase, strlen(passphrase)); 72 close(fd); 73 } else 74 r = 0; 75 76 return r == strlen(passphrase) ? 0 : 1; 77 } 78 79 static void _remove_keyfiles(void) 80 { 81 remove(KEYFILE1); 82 remove(KEYFILE2); 83 } 84 85 // Decode key from its hex representation 86 static int crypt_decode_key(char *key, char *hex, unsigned int size) 87 { 88 char buffer[3]; 89 char *endp; 90 unsigned int i; 91 92 buffer[2] = '\0'; 93 94 for (i = 0; i < size; i++) { 95 buffer[0] = *hex++; 96 buffer[1] = *hex++; 97 98 key[i] = (unsigned char)strtoul(buffer, &endp, 16); 99 100 if (endp != &buffer[2]) 101 return -1; 102 } 103 104 if (*hex != '\0') 105 return -1; 106 107 return 0; 108 } 109 110 static int yesDialog(char *msg) 111 { 112 return 1; 113 } 114 115 static void cmdLineLog(int level, char *msg) 116 { 117 strncat(global_log, msg, sizeof(global_log) - strlen(global_log)); 118 global_lines++; 119 } 120 121 static void new_log(int level, const char *msg, void *usrptr) 122 { 123 cmdLineLog(level, (char*)msg); 124 } 125 126 127 static void reset_log() 128 { 129 memset(global_log, 0, sizeof(global_log)); 130 global_lines = 0; 131 } 132 133 static struct interface_callbacks cmd_icb = { 134 .yesDialog = yesDialog, 135 .log = cmdLineLog, 136 }; 137 138 static void _cleanup(void) 139 { 140 int r; 141 struct stat st; 142 143 //r = system("udevadm settle"); 144 145 if (!stat(DMDIR CDEVICE_1, &st)) 146 r = system("dmsetup remove " CDEVICE_1); 147 148 if (!stat(DMDIR CDEVICE_2, &st)) 149 r = system("dmsetup remove " CDEVICE_2); 150 151 if (!stat(DEVICE_EMPTY, &st)) 152 r = system("dmsetup remove " DEVICE_EMPTY_name); 153 154 if (!stat(DEVICE_ERROR, &st)) 155 r = system("dmsetup remove " DEVICE_ERROR_name); 156 157 if (!strncmp("/dev/vn", DEVICE_1, 7)) 158 r = system("vnconfig -u " DEVICE_1); 159 160 if (!strncmp("/dev/vn", DEVICE_2, 7)) 161 r = system("vnconfig -u " DEVICE_2); 162 163 r = system("rm -f " IMAGE_EMPTY); 164 _remove_keyfiles(); 165 } 166 167 static void _setup(void) 168 { 169 int r; 170 171 r = system("dmsetup create " DEVICE_EMPTY_name " --table \"0 10000 zero\""); 172 r = system("dmsetup create " DEVICE_ERROR_name " --table \"0 10000 error\""); 173 if (!strncmp("/dev/vn", DEVICE_1, 7)) { 174 r = system(" [ ! -e " IMAGE1 " ] && bzip2 -dk " IMAGE1 ".bz2"); 175 r = system("vnconfig -S labels -T " DEVICE_1 " " IMAGE1); 176 } 177 if (!strncmp("/dev/vn", DEVICE_2, 7)) { 178 r = system("dd if=/dev/zero of=" IMAGE_EMPTY " bs=1M count=4"); 179 r = system("vnconfig -S labels -T " DEVICE_2 " " IMAGE_EMPTY); 180 } 181 182 } 183 184 void check_ok(int status, int line, const char *func) 185 { 186 char buf[256]; 187 188 if (status) { 189 crypt_get_error(buf, sizeof(buf)); 190 printf("FAIL line %d [%s]: code %d, %s\n", line, func, status, buf); 191 _cleanup(); 192 exit(-1); 193 } 194 } 195 196 void check_ko(int status, int line, const char *func) 197 { 198 char buf[256]; 199 200 memset(buf, 0, sizeof(buf)); 201 crypt_get_error(buf, sizeof(buf)); 202 if (status >= 0) { 203 printf("FAIL line %d [%s]: code %d, %s\n", line, func, status, buf); 204 _cleanup(); 205 exit(-1); 206 } else if (_verbose) 207 printf(" => errno %d, errmsg: %s\n", status, buf); 208 } 209 210 void check_equal(int line, const char *func) 211 { 212 printf("FAIL line %d [%s]: expected equal values differs.\n", line, func); 213 _cleanup(); 214 exit(-1); 215 } 216 217 void xlog(const char *msg, const char *tst, const char *func, int line, const char *txt) 218 { 219 if (_verbose) { 220 if (txt) 221 printf(" [%s,%s:%d] %s [%s]\n", msg, func, line, tst, txt); 222 else 223 printf(" [%s,%s:%d] %s\n", msg, func, line, tst); 224 } 225 } 226 #define OK_(x) do { xlog("(success)", #x, __FUNCTION__, __LINE__, NULL); \ 227 check_ok((x), __LINE__, __FUNCTION__); \ 228 } while(0) 229 #define FAIL_(x, y) do { xlog("(fail) ", #x, __FUNCTION__, __LINE__, y); \ 230 check_ko((x), __LINE__, __FUNCTION__); \ 231 } while(0) 232 #define EQ_(x, y) do { xlog("(equal) ", #x " == " #y, __FUNCTION__, __LINE__, NULL); \ 233 if ((x) != (y)) check_equal(__LINE__, __FUNCTION__); \ 234 } while(0) 235 236 #define RUN_(x, y) do { printf("%s: %s\n", #x, (y)); x(); } while (0) 237 238 // OLD API TESTS 239 static void LuksUUID(void) 240 { 241 struct crypt_options co = { .icb = &cmd_icb }; 242 243 co.device = DEVICE_EMPTY; 244 EQ_(crypt_luksUUID(&co), -EINVAL); 245 246 co.device = DEVICE_ERROR; 247 EQ_(crypt_luksUUID(&co), -EINVAL); 248 249 reset_log(); 250 co.device = DEVICE_1; 251 OK_(crypt_luksUUID(&co)); 252 EQ_(strlen(global_log), 37); /* UUID + "\n" */ 253 EQ_(strncmp(global_log, DEVICE_1_UUID, strlen(DEVICE_1_UUID)), 0); 254 255 } 256 257 static void IsLuks(void) 258 { 259 struct crypt_options co = { .icb = &cmd_icb }; 260 261 co.device = DEVICE_EMPTY; 262 EQ_(crypt_isLuks(&co), -EINVAL); 263 264 co.device = DEVICE_ERROR; 265 EQ_(crypt_isLuks(&co), -EINVAL); 266 267 co.device = DEVICE_1; 268 OK_(crypt_isLuks(&co)); 269 } 270 271 static void LuksOpen(void) 272 { 273 struct crypt_options co = { 274 .name = CDEVICE_1, 275 //.passphrase = "blabla", 276 .icb = &cmd_icb, 277 }; 278 279 OK_(_prepare_keyfile(KEYFILE1, KEY1)); 280 co.key_file = KEYFILE1; 281 282 co.device = DEVICE_EMPTY; 283 EQ_(crypt_luksOpen(&co), -EINVAL); 284 285 co.device = DEVICE_ERROR; 286 EQ_(crypt_luksOpen(&co), -EINVAL); 287 288 co.device = DEVICE_1; 289 OK_(crypt_luksOpen(&co)); 290 FAIL_(crypt_luksOpen(&co), "already open"); 291 292 _remove_keyfiles(); 293 } 294 295 static void query_device(void) 296 { 297 struct crypt_options co = {. icb = &cmd_icb }; 298 299 co.name = CDEVICE_WRONG; 300 EQ_(crypt_query_device(&co), 0); 301 302 co.name = CDEVICE_1; 303 EQ_(crypt_query_device(&co), 1); 304 305 OK_(strncmp(crypt_get_dir(), DMDIR, 11)); 306 OK_(strcmp(co.cipher, "aes-cbc-essiv:sha256")); 307 EQ_(co.key_size, 16); 308 EQ_(co.offset, 1032); 309 EQ_(co.flags & CRYPT_FLAG_READONLY, 0); 310 EQ_(co.skip, 0); 311 crypt_put_options(&co); 312 } 313 314 static void remove_device(void) 315 { 316 int fd; 317 struct crypt_options co = {. icb = &cmd_icb }; 318 319 co.name = CDEVICE_WRONG; 320 EQ_(crypt_remove_device(&co), -ENODEV); 321 322 fd = open(DMDIR CDEVICE_1, O_RDONLY); 323 co.name = CDEVICE_1; 324 FAIL_(crypt_remove_device(&co), "device busy"); 325 close(fd); 326 327 OK_(crypt_remove_device(&co)); 328 } 329 330 static void LuksFormat(void) 331 { 332 struct crypt_options co = { 333 .device = DEVICE_2, 334 .key_size = 256 / 8, 335 .key_slot = -1, 336 .cipher = "aes-cbc-essiv:sha256", 337 .hash = "sha1", 338 .flags = 0, 339 .iteration_time = 10, 340 .align_payload = 0, 341 .icb = &cmd_icb, 342 }; 343 344 OK_(_prepare_keyfile(KEYFILE1, KEY1)); 345 346 co.new_key_file = KEYFILE1; 347 co.device = DEVICE_ERROR; 348 FAIL_(crypt_luksFormat(&co), "error device"); 349 350 co.device = DEVICE_2; 351 OK_(crypt_luksFormat(&co)); 352 353 co.new_key_file = NULL; 354 co.key_file = KEYFILE1; 355 co.name = CDEVICE_2; 356 OK_(crypt_luksOpen(&co)); 357 OK_(crypt_remove_device(&co)); 358 _remove_keyfiles(); 359 } 360 361 static void LuksKeyGame(void) 362 { 363 int i; 364 struct crypt_options co = { 365 .device = DEVICE_2, 366 .key_size = 256 / 8, 367 .key_slot = -1, 368 .cipher = "aes-cbc-essiv:sha256", 369 .hash = "sha1", 370 .flags = 0, 371 .iteration_time = 10, 372 .align_payload = 0, 373 .icb = &cmd_icb, 374 }; 375 376 OK_(_prepare_keyfile(KEYFILE1, KEY1)); 377 OK_(_prepare_keyfile(KEYFILE2, KEY2)); 378 379 co.new_key_file = KEYFILE1; 380 co.device = DEVICE_2; 381 co.key_slot = 8; 382 FAIL_(crypt_luksFormat(&co), "wrong slot #"); 383 384 co.key_slot = 7; // last slot 385 OK_(crypt_luksFormat(&co)); 386 387 co.new_key_file = KEYFILE1; 388 co.key_file = KEYFILE1; 389 co.key_slot = 8; 390 FAIL_(crypt_luksAddKey(&co), "wrong slot #"); 391 co.key_slot = 7; 392 FAIL_(crypt_luksAddKey(&co), "slot already used"); 393 394 co.key_slot = 6; 395 OK_(crypt_luksAddKey(&co)); 396 397 co.key_file = KEYFILE2 "blah"; 398 co.key_slot = 5; 399 FAIL_(crypt_luksAddKey(&co), "keyfile not found"); 400 401 co.new_key_file = KEYFILE2; // key to add 402 co.key_file = KEYFILE1; 403 co.key_slot = -1; 404 for (i = 0; i < 6; i++) 405 OK_(crypt_luksAddKey(&co)); //FIXME: EQ_(i)? 406 407 FAIL_(crypt_luksAddKey(&co), "all slots full"); 408 409 // REMOVE KEY 410 co.new_key_file = KEYFILE1; // key to remove 411 co.key_file = NULL; 412 co.key_slot = 8; // should be ignored 413 // only 2 slots should use KEYFILE1 414 OK_(crypt_luksRemoveKey(&co)); 415 OK_(crypt_luksRemoveKey(&co)); 416 FAIL_(crypt_luksRemoveKey(&co), "no slot with this passphrase"); 417 418 co.new_key_file = KEYFILE2 "blah"; 419 co.key_file = NULL; 420 FAIL_(crypt_luksRemoveKey(&co), "keyfile not found"); 421 422 // KILL SLOT 423 co.new_key_file = NULL; 424 co.key_file = NULL; 425 co.key_slot = 8; 426 FAIL_(crypt_luksKillSlot(&co), "wrong slot #"); 427 co.key_slot = 7; 428 FAIL_(crypt_luksKillSlot(&co), "slot already wiped"); 429 430 co.key_slot = 5; 431 OK_(crypt_luksKillSlot(&co)); 432 433 _remove_keyfiles(); 434 } 435 436 size_t _get_device_size(const char *device) 437 { 438 #if 0 /* XXX swildner */ 439 unsigned long size = 0; 440 int fd; 441 442 fd = open(device, O_RDONLY); 443 if (fd == -1) 444 return 0; 445 (void)ioctl(fd, BLKGETSIZE, &size); 446 close(fd); 447 448 return size; 449 #endif 450 return DEV_BSIZE; 451 } 452 453 void DeviceResizeGame(void) 454 { 455 size_t orig_size; 456 struct crypt_options co = { 457 .name = CDEVICE_2, 458 .device = DEVICE_2, 459 .key_size = 128 / 8, 460 .cipher = "aes-cbc-plain", 461 .hash = "sha1", 462 .offset = 333, 463 .skip = 0, 464 .icb = &cmd_icb, 465 }; 466 467 orig_size = _get_device_size(DEVICE_2); 468 469 OK_(_prepare_keyfile(KEYFILE2, KEY2)); 470 471 co.key_file = KEYFILE2; 472 co.size = 1000; 473 OK_(crypt_create_device(&co)); 474 EQ_(_get_device_size(DMDIR CDEVICE_2), 1000); 475 476 co.size = 2000; 477 OK_(crypt_resize_device(&co)); 478 EQ_(_get_device_size(DMDIR CDEVICE_2), 2000); 479 480 co.size = 0; 481 OK_(crypt_resize_device(&co)); 482 EQ_(_get_device_size(DMDIR CDEVICE_2), (orig_size - 333)); 483 co.size = 0; 484 co.offset = 444; 485 co.skip = 555; 486 co.cipher = "aes-cbc-essiv:sha256"; 487 OK_(crypt_update_device(&co)); 488 EQ_(_get_device_size(DMDIR CDEVICE_2), (orig_size - 444)); 489 490 memset(&co, 0, sizeof(co)); 491 co.icb = &cmd_icb, 492 co.name = CDEVICE_2; 493 EQ_(crypt_query_device(&co), 1); 494 EQ_(strcmp(co.cipher, "aes-cbc-essiv:sha256"), 0); 495 EQ_(co.key_size, 128 / 8); 496 EQ_(co.offset, 444); 497 EQ_(co.skip, 555); 498 crypt_put_options(&co); 499 500 // dangerous switch device still works 501 memset(&co, 0, sizeof(co)); 502 co.name = CDEVICE_2, 503 co.device = DEVICE_1; 504 co.key_file = KEYFILE2; 505 co.key_size = 128 / 8; 506 co.cipher = "aes-cbc-plain"; 507 co.hash = "sha1"; 508 co.icb = &cmd_icb; 509 OK_(crypt_update_device(&co)); 510 511 memset(&co, 0, sizeof(co)); 512 co.icb = &cmd_icb, 513 co.name = CDEVICE_2; 514 EQ_(crypt_query_device(&co), 1); 515 EQ_(strcmp(co.cipher, "aes-cbc-plain"), 0); 516 EQ_(co.key_size, 128 / 8); 517 EQ_(co.offset, 0); 518 EQ_(co.skip, 0); 519 // This expect lookup returns prefered /dev/loopX 520 EQ_(strcmp(co.device, DEVICE_1), 0); 521 crypt_put_options(&co); 522 523 memset(&co, 0, sizeof(co)); 524 co.icb = &cmd_icb, 525 co.name = CDEVICE_2; 526 OK_(crypt_remove_device(&co)); 527 528 _remove_keyfiles(); 529 } 530 531 // NEW API tests 532 533 static void AddDevicePlain(void) 534 { 535 struct crypt_device *cd; 536 struct crypt_params_plain params = { 537 .hash = "sha1", 538 .skip = 0, 539 .offset = 0, 540 }; 541 int fd; 542 char key[128], key2[128], path[128]; 543 544 char *passphrase = "blabla"; 545 char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; 546 size_t key_size = strlen(mk_hex) / 2; 547 char *cipher = "aes"; 548 char *cipher_mode = "cbc-essiv:sha256"; 549 550 crypt_decode_key(key, mk_hex, key_size); 551 552 FAIL_(crypt_init(&cd, ""), "empty device string"); 553 554 // default is "plain" hash - no password hash 555 OK_(crypt_init(&cd, DEVICE_1)); 556 OK_(crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, key_size, NULL)); 557 OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); 558 EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); 559 // FIXME: this should get key from active device? 560 //OK_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key2, &key_size, passphrase, strlen(passphrase))); 561 //OK_(memcmp(key, key2, key_size)); 562 OK_(crypt_deactivate(cd, CDEVICE_1)); 563 crypt_free(cd); 564 565 // Now use hashed password 566 OK_(crypt_init(&cd, DEVICE_1)); 567 OK_(crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, key_size, ¶ms)); 568 OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, passphrase, strlen(passphrase), 0)); 569 570 // device status check 571 EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); 572 snprintf(path, sizeof(path), "%s/%s", crypt_get_dir(), CDEVICE_1); 573 fd = open(path, O_RDONLY); 574 EQ_(crypt_status(cd, CDEVICE_1), CRYPT_BUSY); 575 FAIL_(crypt_deactivate(cd, CDEVICE_1), "Device is busy"); 576 close(fd); 577 OK_(crypt_deactivate(cd, CDEVICE_1)); 578 EQ_(crypt_status(cd, CDEVICE_1), CRYPT_INACTIVE); 579 580 OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); 581 EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); 582 583 // retrieve volume key check 584 memset(key2, 0, key_size); 585 key_size--; 586 // small buffer 587 FAIL_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key2, &key_size, passphrase, strlen(passphrase)), "small buffer"); 588 key_size++; 589 OK_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key2, &key_size, passphrase, strlen(passphrase))); 590 591 OK_(memcmp(key, key2, key_size)); 592 OK_(strcmp(cipher, crypt_get_cipher(cd))); 593 OK_(strcmp(cipher_mode, crypt_get_cipher_mode(cd))); 594 EQ_(key_size, crypt_get_volume_key_size(cd)); 595 EQ_(0, crypt_get_data_offset(cd)); 596 OK_(crypt_deactivate(cd, CDEVICE_1)); 597 crypt_free(cd); 598 } 599 600 static void UseLuksDevice(void) 601 { 602 struct crypt_device *cd; 603 char key[128]; 604 size_t key_size; 605 606 OK_(crypt_init(&cd, DEVICE_1)); 607 OK_(crypt_load(cd, CRYPT_LUKS1, NULL)); 608 EQ_(crypt_status(cd, CDEVICE_1), CRYPT_INACTIVE); 609 OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0)); 610 FAIL_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0), "already open"); 611 EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); 612 OK_(crypt_deactivate(cd, CDEVICE_1)); 613 FAIL_(crypt_deactivate(cd, CDEVICE_1), "no such device"); 614 615 key_size = 16; 616 OK_(strcmp("aes", crypt_get_cipher(cd))); 617 OK_(strcmp("cbc-essiv:sha256", crypt_get_cipher_mode(cd))); 618 OK_(strcmp(DEVICE_1_UUID, crypt_get_uuid(cd))); 619 EQ_(key_size, crypt_get_volume_key_size(cd)); 620 EQ_(1032, crypt_get_data_offset(cd)); 621 622 EQ_(0, crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key, &key_size, KEY1, strlen(KEY1))); 623 OK_(crypt_volume_key_verify(cd, key, key_size)); 624 OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); 625 EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); 626 OK_(crypt_deactivate(cd, CDEVICE_1)); 627 628 key[1] = ~key[1]; 629 FAIL_(crypt_volume_key_verify(cd, key, key_size), "key mismatch"); 630 FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0), "key mismatch"); 631 crypt_free(cd); 632 } 633 634 static void SuspendDevice(void) 635 { 636 int suspend_status; 637 struct crypt_device *cd; 638 639 OK_(crypt_init(&cd, DEVICE_1)); 640 OK_(crypt_load(cd, CRYPT_LUKS1, NULL)); 641 OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0)); 642 643 suspend_status = crypt_suspend(cd, CDEVICE_1); 644 if (suspend_status == -ENOTSUP) { 645 printf("WARNING: Suspend/Resume not supported, skipping test.\n"); 646 goto out; 647 } 648 OK_(suspend_status); 649 FAIL_(crypt_suspend(cd, CDEVICE_1), "already suspended"); 650 651 FAIL_(crypt_resume_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1)-1), "wrong key"); 652 OK_(crypt_resume_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1))); 653 FAIL_(crypt_resume_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1)), "not suspended"); 654 655 OK_(_prepare_keyfile(KEYFILE1, KEY1)); 656 OK_(crypt_suspend(cd, CDEVICE_1)); 657 FAIL_(crypt_resume_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1 "blah", 0), "wrong keyfile"); 658 OK_(crypt_resume_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0)); 659 FAIL_(crypt_resume_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0), "not suspended"); 660 _remove_keyfiles(); 661 out: 662 OK_(crypt_deactivate(cd, CDEVICE_1)); 663 crypt_free(cd); 664 } 665 666 static void AddDeviceLuks(void) 667 { 668 struct crypt_device *cd; 669 struct crypt_params_luks1 params = { 670 .hash = "sha512", 671 .data_alignment = 2048, // 4M, data offset will be 4096 672 }; 673 char key[128], key2[128]; 674 675 char *passphrase = "blabla"; 676 char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; 677 size_t key_size = strlen(mk_hex) / 2; 678 char *cipher = "aes"; 679 char *cipher_mode = "cbc-essiv:sha256"; 680 681 crypt_decode_key(key, mk_hex, key_size); 682 683 OK_(crypt_init(&cd, DEVICE_2)); 684 OK_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, ¶ms)); 685 686 // even with no keyslots defined it can be activated by volume key 687 OK_(crypt_volume_key_verify(cd, key, key_size)); 688 OK_(crypt_activate_by_volume_key(cd, CDEVICE_2, key, key_size, 0)); 689 EQ_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE); 690 OK_(crypt_deactivate(cd, CDEVICE_2)); 691 692 // now with keyslot 693 EQ_(7, crypt_keyslot_add_by_volume_key(cd, 7, key, key_size, passphrase, strlen(passphrase))); 694 EQ_(CRYPT_SLOT_ACTIVE_LAST, crypt_keyslot_status(cd, 7)); 695 EQ_(7, crypt_activate_by_passphrase(cd, CDEVICE_2, CRYPT_ANY_SLOT, passphrase, strlen(passphrase), 0)); 696 EQ_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE); 697 OK_(crypt_deactivate(cd, CDEVICE_2)); 698 699 FAIL_(crypt_keyslot_add_by_volume_key(cd, 7, key, key_size, passphrase, strlen(passphrase)), "slot used"); 700 key[1] = ~key[1]; 701 FAIL_(crypt_keyslot_add_by_volume_key(cd, 6, key, key_size, passphrase, strlen(passphrase)), "key mismatch"); 702 key[1] = ~key[1]; 703 EQ_(6, crypt_keyslot_add_by_volume_key(cd, 6, key, key_size, passphrase, strlen(passphrase))); 704 EQ_(CRYPT_SLOT_ACTIVE, crypt_keyslot_status(cd, 6)); 705 706 FAIL_(crypt_keyslot_destroy(cd, 8), "invalid keyslot"); 707 FAIL_(crypt_keyslot_destroy(cd, CRYPT_ANY_SLOT), "invalid keyslot"); 708 FAIL_(crypt_keyslot_destroy(cd, 0), "keyslot not used"); 709 OK_(crypt_keyslot_destroy(cd, 7)); 710 EQ_(CRYPT_SLOT_INACTIVE, crypt_keyslot_status(cd, 7)); 711 EQ_(CRYPT_SLOT_ACTIVE_LAST, crypt_keyslot_status(cd, 6)); 712 713 EQ_(6, crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key2, &key_size, passphrase, strlen(passphrase))); 714 OK_(crypt_volume_key_verify(cd, key2, key_size)); 715 716 OK_(memcmp(key, key2, key_size)); 717 OK_(strcmp(cipher, crypt_get_cipher(cd))); 718 OK_(strcmp(cipher_mode, crypt_get_cipher_mode(cd))); 719 EQ_(key_size, crypt_get_volume_key_size(cd)); 720 EQ_(4096, crypt_get_data_offset(cd)); 721 722 reset_log(); 723 crypt_set_log_callback(cd, &new_log, NULL); 724 OK_(crypt_dump(cd)); 725 OK_(!(global_lines != 0)); 726 crypt_set_log_callback(cd, NULL, NULL); 727 reset_log(); 728 729 FAIL_(crypt_deactivate(cd, CDEVICE_2), "not active"); 730 crypt_free(cd); 731 } 732 733 // Check that gcrypt is properly initialised in format 734 static void NonFIPSAlg(void) 735 { 736 struct crypt_device *cd; 737 struct crypt_params_luks1 params = { 738 .hash = "whirlpool", 739 }; 740 char key[128] = ""; 741 size_t key_size = 128; 742 char *cipher = "aes"; 743 char *cipher_mode = "cbc-essiv:sha256"; 744 745 if (!gcrypt_compatible) { 746 printf("WARNING: old libgcrypt, skipping test.\n"); 747 return; 748 } 749 OK_(crypt_init(&cd, DEVICE_2)); 750 OK_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, ¶ms)); 751 crypt_free(cd); 752 } 753 754 755 static void _gcrypt_compatible() 756 { 757 int maj, min, patch; 758 FILE *f; 759 760 if (!(f = popen("libgcrypt-config --version", "r"))) 761 return; 762 763 if (fscanf(f, "%d.%d.%d", &maj, &min, &patch) == 3 && 764 maj >= 1 && min >= 4) 765 gcrypt_compatible = 1; 766 if (_debug) 767 printf("libgcrypt version %d.%d.%d detected.\n", maj, min, patch); 768 769 (void)fclose(f); 770 return; 771 } 772 773 int main (int argc, char *argv[]) 774 { 775 int i; 776 777 if (getuid() != 0) { 778 printf("You must be root to run this test.\n"); 779 exit(0); 780 } 781 782 for (i = 1; i < argc; i++) { 783 if (!strcmp("-v", argv[i]) || !strcmp("--verbose", argv[i])) 784 _verbose = 1; 785 else if (!strcmp("--debug", argv[i])) 786 _debug = _verbose = 1; 787 } 788 789 _cleanup(); 790 _setup(); 791 _gcrypt_compatible(); 792 793 crypt_set_debug_level(_debug ? CRYPT_DEBUG_ALL : CRYPT_DEBUG_NONE); 794 795 RUN_(NonFIPSAlg, "Crypto is properly initialised in format"); //must be the first! 796 RUN_(LuksUUID, "luksUUID API call"); 797 RUN_(IsLuks, "isLuks API call"); 798 RUN_(LuksOpen, "luksOpen API call"); 799 RUN_(query_device, "crypt_query_device API call"); 800 RUN_(remove_device, "crypt_remove_device API call"); 801 RUN_(LuksFormat, "luksFormat API call"); 802 RUN_(LuksKeyGame, "luksAddKey, RemoveKey, KillSlot API calls"); 803 RUN_(DeviceResizeGame, "regular crypto, resize calls"); 804 805 RUN_(AddDevicePlain, "plain device API creation exercise"); 806 RUN_(AddDeviceLuks, "Format and use LUKS device"); 807 RUN_(UseLuksDevice, "Use pre-formated LUKS device"); 808 RUN_(SuspendDevice, "Suspend/Resume test"); 809 810 _cleanup(); 811 return 0; 812 } 813