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