1 /* 2 * e4crypt.c - ext4 encryption management utility 3 * 4 * Copyright (c) 2014 Google, Inc. 5 * SHA512 implementation from libtomcrypt. 6 * 7 * Authors: Michael Halcrow <mhalcrow (at) google.com>, 8 * Ildar Muslukhov <ildarm (at) google.com> 9 */ 10 11 #ifndef _LARGEFILE_SOURCE 12 #define _LARGEFILE_SOURCE 13 #endif 14 15 #ifndef _LARGEFILE64_SOURCE 16 #define _LARGEFILE64_SOURCE 17 #endif 18 19 #ifndef _GNU_SOURCE 20 #define _GNU_SOURCE 21 #endif 22 23 #include "config.h" 24 #include <assert.h> 25 #include <errno.h> 26 #include <getopt.h> 27 #include <dirent.h> 28 #include <errno.h> 29 #include <stdarg.h> 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <string.h> 33 #include <mntent.h> 34 #include <sys/ioctl.h> 35 #include <sys/stat.h> 36 #include <sys/types.h> 37 #include <fcntl.h> 38 #include <termios.h> 39 #include <unistd.h> 40 #include <signal.h> 41 #if !defined(HAVE_ADD_KEY) || !defined(HAVE_KEYCTL) 42 #include <sys/syscall.h> 43 #endif 44 #ifdef HAVE_SYS_KEY_H 45 #include <sys/key.h> 46 #endif 47 48 #include "ext2fs/ext2_fs.h" 49 #include "ext2fs/ext2fs.h" 50 #include "uuid/uuid.h" 51 52 /* special process keyring shortcut IDs */ 53 #define KEY_SPEC_THREAD_KEYRING -1 54 #define KEY_SPEC_PROCESS_KEYRING -2 55 #define KEY_SPEC_SESSION_KEYRING -3 56 #define KEY_SPEC_USER_KEYRING -4 57 #define KEY_SPEC_USER_SESSION_KEYRING -5 58 #define KEY_SPEC_GROUP_KEYRING -6 59 60 #define KEYCTL_GET_KEYRING_ID 0 61 #define KEYCTL_JOIN_SESSION_KEYRING 1 62 #define KEYCTL_DESCRIBE 6 63 #define KEYCTL_SEARCH 10 64 #define KEYCTL_SESSION_TO_PARENT 18 65 66 typedef __s32 key_serial_t; 67 68 #define EXT4_KEY_REF_STR_BUF_SIZE ((EXT4_KEY_DESCRIPTOR_SIZE * 2) + 1) 69 70 #ifndef EXT4_IOC_GET_ENCRYPTION_PWSALT 71 #define EXT4_IOC_GET_ENCRYPTION_PWSALT _IOW('f', 20, __u8[16]) 72 #endif 73 74 #define OPT_VERBOSE 0x0001 75 #define OPT_QUIET 0x0002 76 77 int options; 78 79 #ifndef HAVE_KEYCTL 80 static long keyctl(int cmd, ...) 81 { 82 va_list va; 83 unsigned long arg2, arg3, arg4, arg5; 84 85 va_start(va, cmd); 86 arg2 = va_arg(va, unsigned long); 87 arg3 = va_arg(va, unsigned long); 88 arg4 = va_arg(va, unsigned long); 89 arg5 = va_arg(va, unsigned long); 90 va_end(va); 91 return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5); 92 } 93 #endif 94 95 #ifndef HAVE_ADD_KEY 96 static key_serial_t add_key(const char *type, const char *description, 97 const void *payload, size_t plen, 98 key_serial_t keyring) 99 { 100 return syscall(__NR_add_key, type, description, payload, 101 plen, keyring); 102 } 103 #endif 104 105 static const unsigned char *hexchars = (const unsigned char *) "0123456789abcdef"; 106 static const size_t hexchars_size = 16; 107 108 #define SHA512_LENGTH 64 109 #define EXT2FS_KEY_TYPE_LOGON "logon" 110 #define EXT2FS_KEY_DESC_PREFIX "ext4:" 111 #define EXT2FS_KEY_DESC_PREFIX_SIZE 5 112 113 #define EXT4_IOC_SET_ENCRYPTION_POLICY _IOR('f', 19, struct ext4_encryption_policy) 114 #define EXT4_IOC_GET_ENCRYPTION_POLICY _IOW('f', 21, struct ext4_encryption_policy) 115 116 static int int_log2(int arg) 117 { 118 int l = 0; 119 120 arg >>= 1; 121 while (arg) { 122 l++; 123 arg >>= 1; 124 } 125 return l; 126 } 127 128 static void validate_paths(int argc, char *argv[], int path_start_index) 129 { 130 int x; 131 int valid = 1; 132 struct stat st; 133 134 for (x = path_start_index; x < argc; x++) { 135 int ret = access(argv[x], W_OK); 136 if (ret) { 137 invalid: 138 perror(argv[x]); 139 valid = 0; 140 continue; 141 } 142 ret = stat(argv[x], &st); 143 if (ret < 0) 144 goto invalid; 145 if (!S_ISDIR(st.st_mode)) { 146 fprintf(stderr, "%s is not a directory\n", argv[x]); 147 goto invalid; 148 } 149 } 150 if (!valid) 151 exit(1); 152 } 153 154 static int hex2byte(const char *hex, size_t hex_size, unsigned char *bytes, 155 size_t bytes_size) 156 { 157 size_t x; 158 unsigned char *h, *l; 159 160 if (hex_size % 2) 161 return -EINVAL; 162 for (x = 0; x < hex_size; x += 2) { 163 h = memchr(hexchars, hex[x], hexchars_size); 164 if (!h) 165 return -EINVAL; 166 l = memchr(hexchars, hex[x + 1], hexchars_size); 167 if (!l) 168 return -EINVAL; 169 if ((x >> 1) >= bytes_size) 170 return -EINVAL; 171 bytes[x >> 1] = (((unsigned char)(h - hexchars) << 4) + 172 (unsigned char)(l - hexchars)); 173 } 174 return 0; 175 } 176 177 /* 178 * Salt handling 179 */ 180 struct salt { 181 unsigned char *salt; 182 char key_ref_str[EXT4_KEY_REF_STR_BUF_SIZE]; 183 unsigned char key_desc[EXT4_KEY_DESCRIPTOR_SIZE]; 184 unsigned char key[EXT4_MAX_KEY_SIZE]; 185 size_t salt_len; 186 }; 187 struct salt *salt_list; 188 unsigned num_salt; 189 unsigned max_salt; 190 char in_passphrase[EXT4_MAX_PASSPHRASE_SIZE]; 191 192 static struct salt *find_by_salt(unsigned char *salt, size_t salt_len) 193 { 194 unsigned int i; 195 struct salt *p; 196 197 for (i = 0, p = salt_list; i < num_salt; i++, p++) 198 if ((p->salt_len == salt_len) && 199 !memcmp(p->salt, salt, salt_len)) 200 return p; 201 return NULL; 202 } 203 204 static void add_salt(unsigned char *salt, size_t salt_len) 205 { 206 if (find_by_salt(salt, salt_len)) 207 return; 208 if (num_salt >= max_salt) { 209 max_salt = num_salt + 10; 210 salt_list = realloc(salt_list, max_salt * sizeof(struct salt)); 211 if (!salt_list) { 212 fprintf(stderr, "Couldn't allocate salt list\n"); 213 exit(1); 214 } 215 } 216 salt_list[num_salt].salt = salt; 217 salt_list[num_salt].salt_len = salt_len; 218 num_salt++; 219 } 220 221 static void clear_secrets(void) 222 { 223 if (salt_list) { 224 memset(salt_list, 0, sizeof(struct salt) * max_salt); 225 free(salt_list); 226 salt_list = NULL; 227 } 228 memset(in_passphrase, 0, sizeof(in_passphrase)); 229 } 230 231 static void die_signal_handler(int signum EXT2FS_ATTR((unused)), 232 siginfo_t *siginfo EXT2FS_ATTR((unused)), 233 void *context EXT2FS_ATTR((unused))) 234 { 235 clear_secrets(); 236 exit(-1); 237 } 238 239 static void sigcatcher_setup(void) 240 { 241 struct sigaction sa; 242 243 memset(&sa, 0, sizeof(struct sigaction)); 244 sa.sa_sigaction = die_signal_handler; 245 sa.sa_flags = SA_SIGINFO; 246 247 sigaction(SIGHUP, &sa, 0); 248 sigaction(SIGINT, &sa, 0); 249 sigaction(SIGQUIT, &sa, 0); 250 sigaction(SIGFPE, &sa, 0); 251 sigaction(SIGILL, &sa, 0); 252 sigaction(SIGBUS, &sa, 0); 253 sigaction(SIGSEGV, &sa, 0); 254 sigaction(SIGABRT, &sa, 0); 255 sigaction(SIGPIPE, &sa, 0); 256 sigaction(SIGALRM, &sa, 0); 257 sigaction(SIGTERM, &sa, 0); 258 sigaction(SIGUSR1, &sa, 0); 259 sigaction(SIGUSR2, &sa, 0); 260 sigaction(SIGPOLL, &sa, 0); 261 sigaction(SIGPROF, &sa, 0); 262 sigaction(SIGSYS, &sa, 0); 263 sigaction(SIGTRAP, &sa, 0); 264 sigaction(SIGVTALRM, &sa, 0); 265 sigaction(SIGXCPU, &sa, 0); 266 sigaction(SIGXFSZ, &sa, 0); 267 } 268 269 270 #define PARSE_FLAGS_NOTSUPP_OK 0x0001 271 #define PARSE_FLAGS_FORCE_FN 0x0002 272 273 static void parse_salt(char *salt_str, int flags) 274 { 275 unsigned char buf[EXT4_MAX_SALT_SIZE]; 276 char *cp = salt_str; 277 unsigned char *salt_buf; 278 int fd, ret, salt_len = 0; 279 280 if (flags & PARSE_FLAGS_FORCE_FN) 281 goto salt_from_filename; 282 if (strncmp(cp, "s:", 2) == 0) { 283 cp += 2; 284 salt_len = strlen(cp); 285 if (salt_len >= EXT4_MAX_SALT_SIZE) 286 goto invalid_salt; 287 strncpy((char *) buf, cp, sizeof(buf)); 288 } else if (cp[0] == '/') { 289 salt_from_filename: 290 fd = open(cp, O_RDONLY | O_DIRECTORY); 291 if (fd == -1 && errno == ENOTDIR) 292 fd = open(cp, O_RDONLY); 293 if (fd == -1) { 294 perror(cp); 295 exit(1); 296 } 297 ret = ioctl(fd, EXT4_IOC_GET_ENCRYPTION_PWSALT, &buf); 298 close(fd); 299 if (ret < 0) { 300 if (flags & PARSE_FLAGS_NOTSUPP_OK) 301 return; 302 perror("EXT4_IOC_GET_ENCRYPTION_PWSALT"); 303 exit(1); 304 } 305 if (options & OPT_VERBOSE) { 306 char tmp[80]; 307 uuid_unparse(buf, tmp); 308 printf("%s has pw salt %s\n", cp, tmp); 309 } 310 salt_len = 16; 311 } else if (strncmp(cp, "f:", 2) == 0) { 312 cp += 2; 313 goto salt_from_filename; 314 } else if (strncmp(cp, "0x", 2) == 0) { 315 unsigned char *h, *l; 316 317 cp += 2; 318 if (strlen(cp) & 1) 319 goto invalid_salt; 320 while (*cp) { 321 if (salt_len >= EXT4_MAX_SALT_SIZE) 322 goto invalid_salt; 323 h = memchr(hexchars, *cp++, hexchars_size); 324 l = memchr(hexchars, *cp++, hexchars_size); 325 if (!h || !l) 326 goto invalid_salt; 327 buf[salt_len++] = 328 (((unsigned char)(h - hexchars) << 4) + 329 (unsigned char)(l - hexchars)); 330 } 331 } else if (uuid_parse(cp, buf) == 0) { 332 salt_len = 16; 333 } else { 334 invalid_salt: 335 fprintf(stderr, "Invalid salt: %s\n", salt_str); 336 exit(1); 337 } 338 salt_buf = malloc(salt_len); 339 if (!salt_buf) { 340 fprintf(stderr, "Couldn't allocate salt\n"); 341 exit(1); 342 } 343 memcpy(salt_buf, buf, salt_len); 344 add_salt(salt_buf, salt_len); 345 } 346 347 static void set_policy(struct salt *set_salt, int pad, 348 int argc, char *argv[], int path_start_index) 349 { 350 struct salt *salt; 351 struct ext4_encryption_policy policy; 352 uuid_t uu; 353 int fd; 354 int x; 355 int rc; 356 357 if ((pad != 4) && (pad != 8) && 358 (pad != 16) && (pad != 32)) { 359 fprintf(stderr, "Invalid padding %d\n", pad); 360 exit(1); 361 } 362 363 for (x = path_start_index; x < argc; x++) { 364 fd = open(argv[x], O_DIRECTORY); 365 if (fd == -1) { 366 perror(argv[x]); 367 exit(1); 368 } 369 if (set_salt) 370 salt = set_salt; 371 else { 372 if (ioctl(fd, EXT4_IOC_GET_ENCRYPTION_PWSALT, 373 &uu) < 0) { 374 perror("EXT4_IOC_GET_ENCRYPTION_PWSALT"); 375 exit(1); 376 } 377 salt = find_by_salt(uu, sizeof(uu)); 378 if (!salt) { 379 fprintf(stderr, "Couldn't find salt!?!\n"); 380 exit(1); 381 } 382 } 383 policy.version = 0; 384 policy.contents_encryption_mode = 385 EXT4_ENCRYPTION_MODE_AES_256_XTS; 386 policy.filenames_encryption_mode = 387 EXT4_ENCRYPTION_MODE_AES_256_CTS; 388 policy.flags = int_log2(pad >> 2); 389 memcpy(policy.master_key_descriptor, salt->key_desc, 390 EXT4_KEY_DESCRIPTOR_SIZE); 391 rc = ioctl(fd, EXT4_IOC_SET_ENCRYPTION_POLICY, &policy); 392 close(fd); 393 if (rc) { 394 printf("Error [%s] setting policy.\nThe key descriptor " 395 "[%s] may not match the existing encryption " 396 "context for directory [%s].\n", 397 strerror(errno), salt->key_ref_str, argv[x]); 398 continue; 399 } 400 printf("Key with descriptor [%s] applied to %s.\n", 401 salt->key_ref_str, argv[x]); 402 } 403 } 404 405 static void pbkdf2_sha512(const char *passphrase, struct salt *salt, 406 unsigned int count, 407 unsigned char derived_key[EXT4_MAX_KEY_SIZE]) 408 { 409 size_t passphrase_size = strlen(passphrase); 410 unsigned char buf[SHA512_LENGTH + EXT4_MAX_PASSPHRASE_SIZE] = {0}; 411 unsigned char tempbuf[SHA512_LENGTH] = {0}; 412 char final[SHA512_LENGTH] = {0}; 413 unsigned char saltbuf[EXT4_MAX_SALT_SIZE + EXT4_MAX_PASSPHRASE_SIZE] = {0}; 414 int actual_buf_len = SHA512_LENGTH + passphrase_size; 415 int actual_saltbuf_len = EXT4_MAX_SALT_SIZE + passphrase_size; 416 unsigned int x, y; 417 __u32 *final_u32 = (__u32 *)final; 418 __u32 *temp_u32 = (__u32 *)tempbuf; 419 420 if (passphrase_size > EXT4_MAX_PASSPHRASE_SIZE) { 421 printf("Passphrase size is %zd; max is %d.\n", passphrase_size, 422 EXT4_MAX_PASSPHRASE_SIZE); 423 exit(1); 424 } 425 if (salt->salt_len > EXT4_MAX_SALT_SIZE) { 426 printf("Salt size is %zd; max is %d.\n", salt->salt_len, 427 EXT4_MAX_SALT_SIZE); 428 exit(1); 429 } 430 assert(EXT4_MAX_KEY_SIZE <= SHA512_LENGTH); 431 432 memcpy(saltbuf, salt->salt, salt->salt_len); 433 memcpy(&saltbuf[EXT4_MAX_SALT_SIZE], passphrase, passphrase_size); 434 435 memcpy(&buf[SHA512_LENGTH], passphrase, passphrase_size); 436 437 for (x = 0; x < count; ++x) { 438 if (x == 0) { 439 ext2fs_sha512(saltbuf, actual_saltbuf_len, tempbuf); 440 } else { 441 /* 442 * buf: [previous hash || passphrase] 443 */ 444 memcpy(buf, tempbuf, SHA512_LENGTH); 445 ext2fs_sha512(buf, actual_buf_len, tempbuf); 446 } 447 for (y = 0; y < (sizeof(final) / sizeof(*final_u32)); ++y) 448 final_u32[y] = final_u32[y] ^ temp_u32[y]; 449 } 450 memcpy(derived_key, final, EXT4_MAX_KEY_SIZE); 451 } 452 453 static int disable_echo(struct termios *saved_settings) 454 { 455 struct termios current_settings; 456 int rc = 0; 457 458 rc = tcgetattr(0, ¤t_settings); 459 if (rc) 460 return rc; 461 *saved_settings = current_settings; 462 current_settings.c_lflag &= ~ECHO; 463 rc = tcsetattr(0, TCSANOW, ¤t_settings); 464 465 return rc; 466 } 467 468 static void get_passphrase(char *passphrase, int len) 469 { 470 char *p; 471 struct termios current_settings; 472 473 assert(len > 0); 474 disable_echo(¤t_settings); 475 p = fgets(passphrase, len, stdin); 476 tcsetattr(0, TCSANOW, ¤t_settings); 477 printf("\n"); 478 if (!p) { 479 printf("Aborting.\n"); 480 exit(1); 481 } 482 p = strrchr(passphrase, '\n'); 483 if (!p) 484 p = passphrase + len - 1; 485 *p = '\0'; 486 } 487 488 struct keyring_map { 489 char name[4]; 490 size_t name_len; 491 int code; 492 }; 493 494 static const struct keyring_map keyrings[] = { 495 {"@us", 3, KEY_SPEC_USER_SESSION_KEYRING}, 496 {"@u", 2, KEY_SPEC_USER_KEYRING}, 497 {"@s", 2, KEY_SPEC_SESSION_KEYRING}, 498 {"@g", 2, KEY_SPEC_GROUP_KEYRING}, 499 {"@p", 2, KEY_SPEC_PROCESS_KEYRING}, 500 {"@t", 2, KEY_SPEC_THREAD_KEYRING}, 501 }; 502 503 static int get_keyring_id(const char *keyring) 504 { 505 unsigned int x; 506 char *end; 507 508 /* 509 * If no keyring is specified, by default use either the user 510 * session key ring or the session keyring. Fetching the 511 * session keyring will return the user session keyring if no 512 * session keyring has been set. 513 * 514 * We need to do this instead of simply adding the key to 515 * KEY_SPEC_SESSION_KEYRING since trying to add a key to a 516 * session keyring that does not yet exist will cause the 517 * kernel to create a session keyring --- which wil then get 518 * garbage collected as soon as e4crypt exits. 519 * 520 * The fact that the keyctl system call and the add_key system 521 * call treats KEY_SPEC_SESSION_KEYRING differently when a 522 * session keyring does not exist is very unfortunate and 523 * confusing, but so it goes... 524 */ 525 if (keyring == NULL) 526 return keyctl(KEYCTL_GET_KEYRING_ID, 527 KEY_SPEC_SESSION_KEYRING, 0); 528 for (x = 0; x < (sizeof(keyrings) / sizeof(keyrings[0])); ++x) { 529 if (strcmp(keyring, keyrings[x].name) == 0) { 530 return keyrings[x].code; 531 } 532 } 533 x = strtoul(keyring, &end, 10); 534 if (*end == '\0') { 535 if (keyctl(KEYCTL_DESCRIBE, x, NULL, 0) < 0) 536 return 0; 537 return x; 538 } 539 return 0; 540 } 541 542 static void generate_key_ref_str(struct salt *salt) 543 { 544 unsigned char key_ref1[SHA512_LENGTH]; 545 unsigned char key_ref2[SHA512_LENGTH]; 546 int x; 547 548 ext2fs_sha512(salt->key, EXT4_MAX_KEY_SIZE, key_ref1); 549 ext2fs_sha512(key_ref1, SHA512_LENGTH, key_ref2); 550 memcpy(salt->key_desc, key_ref2, EXT4_KEY_DESCRIPTOR_SIZE); 551 for (x = 0; x < EXT4_KEY_DESCRIPTOR_SIZE; ++x) { 552 sprintf(&salt->key_ref_str[x * 2], "%02x", 553 salt->key_desc[x]); 554 } 555 salt->key_ref_str[EXT4_KEY_REF_STR_BUF_SIZE - 1] = '\0'; 556 } 557 558 static void insert_key_into_keyring(const char *keyring, struct salt *salt) 559 { 560 int keyring_id = get_keyring_id(keyring); 561 struct ext4_encryption_key key; 562 char key_ref_full[EXT2FS_KEY_DESC_PREFIX_SIZE + 563 EXT4_KEY_REF_STR_BUF_SIZE]; 564 int rc; 565 566 if (keyring_id == 0) { 567 printf("Invalid keyring [%s].\n", keyring); 568 exit(1); 569 } 570 sprintf(key_ref_full, "%s%s", EXT2FS_KEY_DESC_PREFIX, 571 salt->key_ref_str); 572 rc = keyctl(KEYCTL_SEARCH, keyring_id, EXT2FS_KEY_TYPE_LOGON, 573 key_ref_full, 0); 574 if (rc != -1) { 575 if ((options & OPT_QUIET) == 0) 576 printf("Key with descriptor [%s] already exists\n", 577 salt->key_ref_str); 578 return; 579 } else if ((rc == -1) && (errno != ENOKEY)) { 580 printf("keyctl_search failed: %s\n", strerror(errno)); 581 if (errno == -EINVAL) 582 printf("Keyring [%s] is not available.\n", keyring); 583 exit(1); 584 } 585 key.mode = EXT4_ENCRYPTION_MODE_AES_256_XTS; 586 memcpy(key.raw, salt->key, EXT4_MAX_KEY_SIZE); 587 key.size = EXT4_MAX_KEY_SIZE; 588 rc = add_key(EXT2FS_KEY_TYPE_LOGON, key_ref_full, (void *)&key, 589 sizeof(key), keyring_id); 590 if (rc == -1) { 591 if (errno == EDQUOT) { 592 printf("Error adding key to keyring; quota exceeded\n"); 593 } else { 594 printf("Error adding key with key descriptor [%s]: " 595 "%s\n", salt->key_ref_str, strerror(errno)); 596 } 597 exit(1); 598 } else { 599 if ((options & OPT_QUIET) == 0) 600 printf("Added key with descriptor [%s]\n", 601 salt->key_ref_str); 602 } 603 } 604 605 static void get_default_salts(void) 606 { 607 FILE *f = setmntent("/etc/mtab", "r"); 608 struct mntent *mnt; 609 610 while (f && ((mnt = getmntent(f)) != NULL)) { 611 if (strcmp(mnt->mnt_type, "ext4") || 612 access(mnt->mnt_dir, R_OK)) 613 continue; 614 parse_salt(mnt->mnt_dir, PARSE_FLAGS_NOTSUPP_OK); 615 } 616 endmntent(f); 617 } 618 619 /* Functions which implement user commands */ 620 621 struct cmd_desc { 622 const char *cmd_name; 623 void (*cmd_func)(int, char **, const struct cmd_desc *); 624 const char *cmd_desc; 625 const char *cmd_help; 626 int cmd_flags; 627 }; 628 629 #define CMD_HIDDEN 0x0001 630 631 static void do_help(int argc, char **argv, const struct cmd_desc *cmd); 632 633 #define add_key_desc "adds a key to the user's keyring" 634 #define add_key_help \ 635 "e4crypt add_key -S salt [ -k keyring ] [-v] [-q] [ path ... ]\n\n" \ 636 "Prompts the user for a passphrase and inserts it into the specified\n" \ 637 "keyring. If no keyring is specified, e4crypt will use the session\n" \ 638 "keyring if it exists or the user session keyring if it does not.\n\n" \ 639 "If one or more directory paths are specified, e4crypt will try to\n" \ 640 "set the policy of those directories to use the key just entered by\n" \ 641 "the user.\n" 642 643 static void do_add_key(int argc, char **argv, const struct cmd_desc *cmd) 644 { 645 struct salt *salt; 646 char *keyring = NULL; 647 int i, opt, pad = 4; 648 unsigned j; 649 650 while ((opt = getopt(argc, argv, "k:S:p:vq")) != -1) { 651 switch (opt) { 652 case 'k': 653 /* Specify a keyring. */ 654 keyring = optarg; 655 break; 656 case 'p': 657 pad = atoi(optarg); 658 break; 659 case 'S': 660 /* Salt value for passphrase. */ 661 parse_salt(optarg, 0); 662 break; 663 case 'v': 664 options |= OPT_VERBOSE; 665 break; 666 case 'q': 667 options |= OPT_QUIET; 668 break; 669 default: 670 fprintf(stderr, "Unrecognized option: %c\n", opt); 671 case '?': 672 fputs("USAGE:\n ", stderr); 673 fputs(cmd->cmd_help, stderr); 674 exit(1); 675 } 676 } 677 if (num_salt == 0) 678 get_default_salts(); 679 if (num_salt == 0) { 680 fprintf(stderr, "No salt values available\n"); 681 exit(1); 682 } 683 validate_paths(argc, argv, optind); 684 for (i = optind; i < argc; i++) 685 parse_salt(argv[i], PARSE_FLAGS_FORCE_FN); 686 printf("Enter passphrase (echo disabled): "); 687 get_passphrase(in_passphrase, sizeof(in_passphrase)); 688 for (j = 0, salt = salt_list; j < num_salt; j++, salt++) { 689 pbkdf2_sha512(in_passphrase, salt, 690 EXT4_PBKDF2_ITERATIONS, salt->key); 691 generate_key_ref_str(salt); 692 insert_key_into_keyring(keyring, salt); 693 } 694 if (optind != argc) 695 set_policy(NULL, pad, argc, argv, optind); 696 clear_secrets(); 697 exit(0); 698 } 699 700 #define set_policy_desc "sets a policy for directories" 701 #define set_policy_help \ 702 "e4crypt set_policy policy path ... \n\n" \ 703 "Sets the policy for the directories specified on the command line.\n" \ 704 "All directories must be empty to set the policy; if the directory\n" \ 705 "already has a policy established, e4crypt will validate that it the\n" \ 706 "policy matches what was specified. A policy is an encryption key\n" \ 707 "identifier consisting of 16 hexadecimal characters.\n" 708 709 static void do_set_policy(int argc, char **argv, const struct cmd_desc *cmd) 710 { 711 struct salt saltbuf; 712 int c, pad = 4; 713 714 while ((c = getopt (argc, argv, "p:")) != EOF) { 715 switch (c) { 716 case 'p': 717 pad = atoi(optarg); 718 break; 719 } 720 } 721 722 if (argc < optind + 2) { 723 fprintf(stderr, "Missing required argument(s).\n\n"); 724 fputs("USAGE:\n ", stderr); 725 fputs(cmd->cmd_help, stderr); 726 exit(1); 727 } 728 729 if ((strlen(argv[optind]) != (EXT4_KEY_DESCRIPTOR_SIZE * 2)) || 730 hex2byte(argv[optind], (EXT4_KEY_DESCRIPTOR_SIZE * 2), 731 saltbuf.key_desc, EXT4_KEY_DESCRIPTOR_SIZE)) { 732 printf("Invalid key descriptor [%s]. Valid characters " 733 "are 0-9 and a-f, lower case. " 734 "Length must be %d.\n", 735 argv[optind], (EXT4_KEY_DESCRIPTOR_SIZE * 2)); 736 exit(1); 737 } 738 validate_paths(argc, argv, optind+1); 739 strcpy(saltbuf.key_ref_str, argv[optind]); 740 set_policy(&saltbuf, pad, argc, argv, optind+1); 741 exit(0); 742 } 743 744 #define get_policy_desc "get the encryption for directories" 745 #define get_policy_help \ 746 "e4crypt get_policy path ... \n\n" \ 747 "Gets the policy for the directories specified on the command line.\n" 748 749 static void do_get_policy(int argc, char **argv, const struct cmd_desc *cmd) 750 { 751 struct ext4_encryption_policy policy; 752 struct stat st; 753 int i, j, fd, rc; 754 755 if (argc < 2) { 756 fprintf(stderr, "Missing required argument(s).\n\n"); 757 fputs("USAGE:\n ", stderr); 758 fputs(cmd->cmd_help, stderr); 759 exit(1); 760 } 761 762 for (i = 1; i < argc; i++) { 763 if (stat(argv[i], &st) < 0) { 764 perror(argv[i]); 765 continue; 766 } 767 fd = open(argv[i], 768 S_ISDIR(st.st_mode) ? O_DIRECTORY : O_RDONLY); 769 if (fd == -1) { 770 perror(argv[i]); 771 exit(1); 772 } 773 rc = ioctl(fd, EXT4_IOC_GET_ENCRYPTION_POLICY, &policy); 774 close(fd); 775 if (rc) { 776 printf("Error getting policy for %s: %s\n", 777 argv[i], strerror(errno)); 778 continue; 779 } 780 printf("%s: ", argv[i]); 781 for (j = 0; j < EXT4_KEY_DESCRIPTOR_SIZE; j++) { 782 printf("%02x", (unsigned char) policy.master_key_descriptor[j]); 783 } 784 fputc('\n', stdout); 785 } 786 exit(0); 787 } 788 789 #define new_session_desc "give the invoking process a new session keyring" 790 #define new_session_help \ 791 "e4crypt new_session\n\n" \ 792 "Give the invoking process (typically a shell) a new session keyring,\n" \ 793 "discarding its old session keyring.\n" 794 795 static void do_new_session(int argc, char **argv EXT2FS_ATTR((unused)), 796 const struct cmd_desc *cmd) 797 { 798 long keyid, ret; 799 800 if (argc > 1) { 801 fputs("Excess arguments\n\n", stderr); 802 fputs(cmd->cmd_help, stderr); 803 exit(1); 804 } 805 keyid = keyctl(KEYCTL_JOIN_SESSION_KEYRING, NULL); 806 if (keyid < 0) { 807 perror("KEYCTL_JOIN_SESSION_KEYRING"); 808 exit(1); 809 } 810 ret = keyctl(KEYCTL_SESSION_TO_PARENT, NULL); 811 if (ret < 0) { 812 perror("KEYCTL_SESSION_TO_PARENT"); 813 exit(1); 814 } 815 printf("Switched invoking process to new session keyring %ld\n", keyid); 816 exit(0); 817 } 818 819 #define CMD(name) { #name, do_##name, name##_desc, name##_help, 0 } 820 #define _CMD(name) { #name, do_##name, NULL, NULL, CMD_HIDDEN } 821 822 const struct cmd_desc cmd_list[] = { 823 _CMD(help), 824 CMD(add_key), 825 CMD(get_policy), 826 CMD(new_session), 827 CMD(set_policy), 828 { NULL, NULL, NULL, NULL, 0 } 829 }; 830 831 static void do_help(int argc, char **argv, 832 const struct cmd_desc *cmd EXT2FS_ATTR((unused))) 833 { 834 const struct cmd_desc *p; 835 836 if (argc > 1) { 837 for (p = cmd_list; p->cmd_name; p++) { 838 if (p->cmd_flags & CMD_HIDDEN) 839 continue; 840 if (strcmp(p->cmd_name, argv[1]) == 0) { 841 putc('\n', stdout); 842 fputs("USAGE:\n ", stdout); 843 fputs(p->cmd_help, stdout); 844 exit(0); 845 } 846 } 847 printf("Unknown command: %s\n\n", argv[1]); 848 } 849 850 fputs("Available commands:\n", stdout); 851 for (p = cmd_list; p->cmd_name; p++) { 852 if (p->cmd_flags & CMD_HIDDEN) 853 continue; 854 printf(" %-20s %s\n", p->cmd_name, p->cmd_desc); 855 } 856 printf("\nTo get more information on a command, " 857 "type 'e4crypt help cmd'\n"); 858 exit(0); 859 } 860 861 int main(int argc, char *argv[]) 862 { 863 const struct cmd_desc *cmd; 864 865 if (argc < 2) 866 do_help(argc, argv, cmd_list); 867 868 sigcatcher_setup(); 869 for (cmd = cmd_list; cmd->cmd_name; cmd++) { 870 if (strcmp(cmd->cmd_name, argv[1]) == 0) { 871 cmd->cmd_func(argc-1, argv+1, cmd); 872 exit(0); 873 } 874 } 875 printf("Unknown command: %s\n\n", argv[1]); 876 do_help(1, argv, cmd_list); 877 return 0; 878 } 879