]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - io/encrypt.c
xfs: convert to new timestamp accessors
[thirdparty/xfsprogs-dev.git] / io / encrypt.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright 2016, 2019 Google LLC
4 * Author: Eric Biggers <ebiggers@google.com>
5 */
6
7 #ifdef OVERRIDE_SYSTEM_FSCRYPT_ADD_KEY_ARG
8 # define fscrypt_add_key_arg sys_fscrypt_add_key_arg
9 #endif
10 #ifdef OVERRIDE_SYSTEM_FSCRYPT_POLICY_V2
11 # define fscrypt_policy_v2 sys_fscrypt_policy_v2
12 # define fscrypt_get_policy_ex_arg sys_fscrypt_get_policy_ex_arg
13 #endif
14 #include "platform_defs.h"
15 #include "command.h"
16 #include "init.h"
17 #include "libfrog/paths.h"
18 #include "io.h"
19
20 #ifndef ARRAY_SIZE
21 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
22 #endif
23
24 /*
25 * Declare the fscrypt ioctls if needed, since someone may be compiling xfsprogs
26 * with old kernel headers. But <linux/fs.h> has already been included, so be
27 * careful not to declare things twice.
28 */
29
30 /* first batch of ioctls (Linux headers v4.6+) */
31 #ifndef FS_IOC_SET_ENCRYPTION_POLICY
32 #define fscrypt_policy fscrypt_policy_v1
33 #define FS_IOC_SET_ENCRYPTION_POLICY _IOR('f', 19, struct fscrypt_policy)
34 #define FS_IOC_GET_ENCRYPTION_PWSALT _IOW('f', 20, __u8[16])
35 #define FS_IOC_GET_ENCRYPTION_POLICY _IOW('f', 21, struct fscrypt_policy)
36 #endif
37
38 /*
39 * Since the log2_data_unit_size field was added later than fscrypt_policy_v2
40 * itself, we may need to override the system definition to get that field.
41 * And also fscrypt_get_policy_ex_arg since it contains fscrypt_policy_v2.
42 */
43 #if !defined(FS_IOC_GET_ENCRYPTION_POLICY_EX) || \
44 defined(OVERRIDE_SYSTEM_FSCRYPT_POLICY_V2)
45 #undef fscrypt_policy_v2
46 struct fscrypt_policy_v2 {
47 __u8 version;
48 __u8 contents_encryption_mode;
49 __u8 filenames_encryption_mode;
50 __u8 flags;
51 __u8 log2_data_unit_size;
52 __u8 __reserved[3];
53 __u8 master_key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE];
54 };
55
56 #undef fscrypt_get_policy_ex_arg
57 struct fscrypt_get_policy_ex_arg {
58 __u64 policy_size; /* input/output */
59 union {
60 __u8 version;
61 struct fscrypt_policy_v1 v1;
62 struct fscrypt_policy_v2 v2;
63 } policy; /* output */
64 };
65 #endif
66
67 /*
68 * Second batch of ioctls (Linux headers v5.4+), plus some renamings from FS_ to
69 * FSCRYPT_. We don't bother defining the old names here.
70 */
71 #ifndef FS_IOC_GET_ENCRYPTION_POLICY_EX
72
73 #define FSCRYPT_POLICY_FLAGS_PAD_4 0x00
74 #define FSCRYPT_POLICY_FLAGS_PAD_8 0x01
75 #define FSCRYPT_POLICY_FLAGS_PAD_16 0x02
76 #define FSCRYPT_POLICY_FLAGS_PAD_32 0x03
77 #define FSCRYPT_POLICY_FLAGS_PAD_MASK 0x03
78 #define FSCRYPT_POLICY_FLAG_DIRECT_KEY 0x04
79
80 #define FSCRYPT_MODE_AES_256_XTS 1
81 #define FSCRYPT_MODE_AES_256_CTS 4
82 #define FSCRYPT_MODE_AES_128_CBC 5
83 #define FSCRYPT_MODE_AES_128_CTS 6
84 #define FSCRYPT_MODE_ADIANTUM 9
85
86 /*
87 * In the headers for Linux v4.6 through v5.3, 'struct fscrypt_policy_v1' is
88 * already defined under its old name, 'struct fscrypt_policy'. But it's fine
89 * to define it under its new name too.
90 *
91 * Note: "v1" policies really are version "0" in the API.
92 */
93 #define FSCRYPT_POLICY_V1 0
94 #define FSCRYPT_KEY_DESCRIPTOR_SIZE 8
95 struct fscrypt_policy_v1 {
96 __u8 version;
97 __u8 contents_encryption_mode;
98 __u8 filenames_encryption_mode;
99 __u8 flags;
100 __u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE];
101 };
102
103 #define FSCRYPT_POLICY_V2 2
104 #define FSCRYPT_KEY_IDENTIFIER_SIZE 16
105 /* struct fscrypt_policy_v2 was defined earlier */
106
107 #define FSCRYPT_MAX_KEY_SIZE 64
108
109 #define FS_IOC_GET_ENCRYPTION_POLICY_EX _IOWR('f', 22, __u8[9]) /* size + version */
110 /* struct fscrypt_get_policy_ex_arg was defined earlier */
111
112 #define FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR 1
113 #define FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER 2
114 struct fscrypt_key_specifier {
115 __u32 type; /* one of FSCRYPT_KEY_SPEC_TYPE_* */
116 __u32 __reserved;
117 union {
118 __u8 __reserved[32]; /* reserve some extra space */
119 __u8 descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE];
120 __u8 identifier[FSCRYPT_KEY_IDENTIFIER_SIZE];
121 } u;
122 };
123
124 /* FS_IOC_ADD_ENCRYPTION_KEY is defined later */
125
126 #define FS_IOC_REMOVE_ENCRYPTION_KEY _IOWR('f', 24, struct fscrypt_remove_key_arg)
127 #define FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS _IOWR('f', 25, struct fscrypt_remove_key_arg)
128 struct fscrypt_remove_key_arg {
129 struct fscrypt_key_specifier key_spec;
130 #define FSCRYPT_KEY_REMOVAL_STATUS_FLAG_FILES_BUSY 0x00000001
131 #define FSCRYPT_KEY_REMOVAL_STATUS_FLAG_OTHER_USERS 0x00000002
132 __u32 removal_status_flags; /* output */
133 __u32 __reserved[5];
134 };
135
136 #define FS_IOC_GET_ENCRYPTION_KEY_STATUS _IOWR('f', 26, struct fscrypt_get_key_status_arg)
137 struct fscrypt_get_key_status_arg {
138 /* input */
139 struct fscrypt_key_specifier key_spec;
140 __u32 __reserved[6];
141
142 /* output */
143 #define FSCRYPT_KEY_STATUS_ABSENT 1
144 #define FSCRYPT_KEY_STATUS_PRESENT 2
145 #define FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED 3
146 __u32 status;
147 #define FSCRYPT_KEY_STATUS_FLAG_ADDED_BY_SELF 0x00000001
148 __u32 status_flags;
149 __u32 user_count;
150 __u32 __out_reserved[13];
151 };
152
153 #endif /* !FS_IOC_GET_ENCRYPTION_POLICY_EX */
154
155 /*
156 * Since the key_id field was added later than struct fscrypt_add_key_arg
157 * itself, we may need to override the system definition to get that field.
158 */
159 #if !defined(FS_IOC_ADD_ENCRYPTION_KEY) || \
160 defined(OVERRIDE_SYSTEM_FSCRYPT_ADD_KEY_ARG)
161 #undef fscrypt_add_key_arg
162 struct fscrypt_add_key_arg {
163 struct fscrypt_key_specifier key_spec;
164 __u32 raw_size;
165 __u32 key_id;
166 __u32 __reserved[8];
167 __u8 raw[];
168 };
169 #endif
170
171 #ifndef FS_IOC_ADD_ENCRYPTION_KEY
172 # define FS_IOC_ADD_ENCRYPTION_KEY _IOWR('f', 23, struct fscrypt_add_key_arg)
173 #endif
174
175 static const struct {
176 __u8 mode;
177 const char *name;
178 } available_modes[] = {
179 {FSCRYPT_MODE_AES_256_XTS, "AES-256-XTS"},
180 {FSCRYPT_MODE_AES_256_CTS, "AES-256-CTS"},
181 {FSCRYPT_MODE_AES_128_CBC, "AES-128-CBC"},
182 {FSCRYPT_MODE_AES_128_CTS, "AES-128-CTS"},
183 {FSCRYPT_MODE_ADIANTUM, "Adiantum"},
184 };
185
186 static cmdinfo_t get_encpolicy_cmd;
187 static cmdinfo_t set_encpolicy_cmd;
188 static cmdinfo_t add_enckey_cmd;
189 static cmdinfo_t rm_enckey_cmd;
190 static cmdinfo_t enckey_status_cmd;
191
192 static void
193 get_encpolicy_help(void)
194 {
195 printf(_(
196 "\n"
197 " display the encryption policy of the current file\n"
198 "\n"
199 " -1 -- Use only the old ioctl to get the encryption policy.\n"
200 " This only works if the file has a v1 encryption policy.\n"
201 " -t -- Test whether v2 encryption policies are supported.\n"
202 " Prints \"supported\", \"unsupported\", or an error message.\n"
203 "\n"));
204 }
205
206 static void
207 set_encpolicy_help(void)
208 {
209 int i;
210
211 printf(_(
212 "\n"
213 " assign an encryption policy to the currently open file\n"
214 "\n"
215 " Examples:\n"
216 " 'set_encpolicy' - assign v1 policy with default key descriptor\n"
217 " (0000000000000000)\n"
218 " 'set_encpolicy -v 2' - assign v2 policy with default key identifier\n"
219 " (00000000000000000000000000000000)\n"
220 " 'set_encpolicy 0000111122223333' - assign v1 policy with given key descriptor\n"
221 " 'set_encpolicy 00001111222233334444555566667777' - assign v2 policy with given\n"
222 " key identifier\n"
223 "\n"
224 " -c MODE -- contents encryption mode\n"
225 " -n MODE -- filenames encryption mode\n"
226 " -f FLAGS -- policy flags\n"
227 " -s LOG2_DUSIZE -- log2 of data unit size\n"
228 " -v VERSION -- policy version\n"
229 "\n"
230 " MODE can be numeric or one of the following predefined values:\n"));
231 printf(" ");
232 for (i = 0; i < ARRAY_SIZE(available_modes); i++) {
233 printf("%s", available_modes[i].name);
234 if (i != ARRAY_SIZE(available_modes) - 1)
235 printf(", ");
236 }
237 printf("\n");
238 printf(_(
239 " FLAGS and VERSION must be numeric.\n"
240 "\n"
241 " Note that it's only possible to set an encryption policy on an empty\n"
242 " directory. It's then inherited by new files and subdirectories.\n"
243 "\n"));
244 }
245
246 static void
247 add_enckey_help(void)
248 {
249 printf(_(
250 "\n"
251 " add an encryption key to the filesystem\n"
252 "\n"
253 " Examples:\n"
254 " 'add_enckey' - add key for v2 policies\n"
255 " 'add_enckey -d 0000111122223333' - add key for v1 policies w/ given descriptor\n"
256 "\n"
257 "Unless -k is given, the key in binary is read from standard input.\n"
258 " -d DESCRIPTOR -- master_key_descriptor\n"
259 " -k KEY_ID -- ID of fscrypt-provisioning key containing the raw key\n"
260 "\n"));
261 }
262
263 static void
264 rm_enckey_help(void)
265 {
266 printf(_(
267 "\n"
268 " remove an encryption key from the filesystem\n"
269 "\n"
270 " Examples:\n"
271 " 'rm_enckey 0000111122223333' - remove key for v1 policies w/ given descriptor\n"
272 " 'rm_enckey 00001111222233334444555566667777' - remove key for v2 policies w/ given identifier\n"
273 "\n"
274 " -a -- remove key for all users who have added it (privileged operation)\n"
275 "\n"));
276 }
277
278 static void
279 enckey_status_help(void)
280 {
281 printf(_(
282 "\n"
283 " get the status of a filesystem encryption key\n"
284 "\n"
285 " Examples:\n"
286 " 'enckey_status 0000111122223333' - get status of v1 policy key\n"
287 " 'enckey_status 00001111222233334444555566667777' - get status of v2 policy key\n"
288 "\n"));
289 }
290
291 static bool
292 parse_byte_value(const char *arg, __u8 *value_ret)
293 {
294 long value;
295 char *tmp;
296
297 value = strtol(arg, &tmp, 0);
298 if (value < 0 || value > 255 || tmp == arg || *tmp != '\0')
299 return false;
300 *value_ret = value;
301 return true;
302 }
303
304 static bool
305 parse_mode(const char *arg, __u8 *mode_ret)
306 {
307 int i;
308
309 for (i = 0; i < ARRAY_SIZE(available_modes); i++) {
310 if (strcmp(arg, available_modes[i].name) == 0) {
311 *mode_ret = available_modes[i].mode;
312 return true;
313 }
314 }
315
316 return parse_byte_value(arg, mode_ret);
317 }
318
319 static const char *
320 mode2str(__u8 mode)
321 {
322 static char buf[32];
323 int i;
324
325 for (i = 0; i < ARRAY_SIZE(available_modes); i++)
326 if (mode == available_modes[i].mode)
327 return available_modes[i].name;
328
329 sprintf(buf, "0x%02x", mode);
330 return buf;
331 }
332
333 static int
334 hexchar2bin(char c)
335 {
336 if (c >= '0' && c <= '9')
337 return c - '0';
338 if (c >= 'a' && c <= 'f')
339 return 10 + (c - 'a');
340 if (c >= 'A' && c <= 'F')
341 return 10 + (c - 'A');
342 return -1;
343 }
344
345 static bool
346 hex2bin(const char *hex, __u8 *bin, size_t bin_len)
347 {
348 if (strlen(hex) != 2 * bin_len)
349 return false;
350
351 while (bin_len--) {
352 int hi = hexchar2bin(*hex++);
353 int lo = hexchar2bin(*hex++);
354
355 if (hi < 0 || lo < 0)
356 return false;
357 *bin++ = (hi << 4) | lo;
358 }
359 return true;
360 }
361
362 static const char *
363 keydesc2str(const __u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE])
364 {
365 static char buf[2 * FSCRYPT_KEY_DESCRIPTOR_SIZE + 1];
366 int i;
367
368 for (i = 0; i < FSCRYPT_KEY_DESCRIPTOR_SIZE; i++)
369 sprintf(&buf[2 * i], "%02x", master_key_descriptor[i]);
370
371 return buf;
372 }
373
374 static const char *
375 keyid2str(const __u8 master_key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE])
376 {
377 static char buf[2 * FSCRYPT_KEY_IDENTIFIER_SIZE + 1];
378 int i;
379
380 for (i = 0; i < FSCRYPT_KEY_IDENTIFIER_SIZE; i++)
381 sprintf(&buf[2 * i], "%02x", master_key_identifier[i]);
382
383 return buf;
384 }
385
386 static const char *
387 keyspectype(const struct fscrypt_key_specifier *key_spec)
388 {
389 switch (key_spec->type) {
390 case FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR:
391 return _("descriptor");
392 case FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER:
393 return _("identifier");
394 }
395 return _("[unknown]");
396 }
397
398 static const char *
399 keyspec2str(const struct fscrypt_key_specifier *key_spec)
400 {
401 switch (key_spec->type) {
402 case FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR:
403 return keydesc2str(key_spec->u.descriptor);
404 case FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER:
405 return keyid2str(key_spec->u.identifier);
406 }
407 return _("[unknown]");
408 }
409
410 static bool
411 str2keydesc(const char *str,
412 __u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE])
413 {
414 if (!hex2bin(str, master_key_descriptor, FSCRYPT_KEY_DESCRIPTOR_SIZE)) {
415 fprintf(stderr, _("invalid key descriptor: %s\n"), str);
416 return false;
417 }
418 return true;
419 }
420
421 static bool
422 str2keyid(const char *str,
423 __u8 master_key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE])
424 {
425 if (!hex2bin(str, master_key_identifier, FSCRYPT_KEY_IDENTIFIER_SIZE)) {
426 fprintf(stderr, _("invalid key identifier: %s\n"), str);
427 return false;
428 }
429 return true;
430 }
431
432 /*
433 * Parse a key specifier (descriptor or identifier) given as a hex string.
434 *
435 * 8 bytes (16 hex chars) == key descriptor == v1 encryption policy.
436 * 16 bytes (32 hex chars) == key identifier == v2 encryption policy.
437 *
438 * If a policy_version is given (>= 0), then the corresponding type of key
439 * specifier is required. Otherwise the specifier type and policy_version are
440 * determined based on the length of the given hex string.
441 *
442 * Returns the policy version, or -1 on error.
443 */
444 static int
445 str2keyspec(const char *str, int policy_version,
446 struct fscrypt_key_specifier *key_spec)
447 {
448 if (policy_version < 0) { /* version unspecified? */
449 size_t len = strlen(str);
450
451 if (len == 2 * FSCRYPT_KEY_DESCRIPTOR_SIZE) {
452 policy_version = FSCRYPT_POLICY_V1;
453 } else if (len == 2 * FSCRYPT_KEY_IDENTIFIER_SIZE) {
454 policy_version = FSCRYPT_POLICY_V2;
455 } else {
456 fprintf(stderr, _("invalid key specifier: %s\n"), str);
457 return -1;
458 }
459 }
460 if (policy_version == FSCRYPT_POLICY_V2) {
461 if (!str2keyid(str, key_spec->u.identifier))
462 return -1;
463 key_spec->type = FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER;
464 } else {
465 if (!str2keydesc(str, key_spec->u.descriptor))
466 return -1;
467 key_spec->type = FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR;
468 }
469 return policy_version;
470 }
471
472 static int
473 parse_key_id(const char *arg)
474 {
475 long value;
476 char *tmp;
477
478 value = strtol(arg, &tmp, 0);
479 if (value <= 0 || value > INT_MAX || tmp == arg || *tmp != '\0') {
480 fprintf(stderr, _("invalid key ID: %s\n"), arg);
481 /* 0 is never a valid Linux key ID. */
482 return 0;
483 }
484 return value;
485 }
486
487 static void
488 test_for_v2_policy_support(void)
489 {
490 struct fscrypt_get_policy_ex_arg arg;
491
492 arg.policy_size = sizeof(arg.policy);
493
494 if (ioctl(file->fd, FS_IOC_GET_ENCRYPTION_POLICY_EX, &arg) == 0 ||
495 errno == ENODATA /* file unencrypted */) {
496 printf(_("supported\n"));
497 return;
498 }
499 if (errno == ENOTTY) {
500 printf(_("unsupported\n"));
501 return;
502 }
503 fprintf(stderr,
504 _("%s: unexpected error checking for FS_IOC_GET_ENCRYPTION_POLICY_EX support: %s\n"),
505 file->name, strerror(errno));
506 exitcode = 1;
507 }
508
509 static void
510 show_v1_encryption_policy(const struct fscrypt_policy_v1 *policy)
511 {
512 printf(_("Encryption policy for %s:\n"), file->name);
513 printf(_("\tPolicy version: %u\n"), policy->version);
514 printf(_("\tMaster key descriptor: %s\n"),
515 keydesc2str(policy->master_key_descriptor));
516 printf(_("\tContents encryption mode: %u (%s)\n"),
517 policy->contents_encryption_mode,
518 mode2str(policy->contents_encryption_mode));
519 printf(_("\tFilenames encryption mode: %u (%s)\n"),
520 policy->filenames_encryption_mode,
521 mode2str(policy->filenames_encryption_mode));
522 printf(_("\tFlags: 0x%02x\n"), policy->flags);
523 }
524
525 static void
526 show_v2_encryption_policy(const struct fscrypt_policy_v2 *policy)
527 {
528 printf(_("Encryption policy for %s:\n"), file->name);
529 printf(_("\tPolicy version: %u\n"), policy->version);
530 printf(_("\tMaster key identifier: %s\n"),
531 keyid2str(policy->master_key_identifier));
532 printf(_("\tContents encryption mode: %u (%s)\n"),
533 policy->contents_encryption_mode,
534 mode2str(policy->contents_encryption_mode));
535 printf(_("\tFilenames encryption mode: %u (%s)\n"),
536 policy->filenames_encryption_mode,
537 mode2str(policy->filenames_encryption_mode));
538 printf(_("\tFlags: 0x%02x\n"), policy->flags);
539 }
540
541 static int
542 get_encpolicy_f(int argc, char **argv)
543 {
544 int c;
545 struct fscrypt_get_policy_ex_arg arg;
546 bool only_use_v1_ioctl = false;
547 int res;
548
549 while ((c = getopt(argc, argv, "1t")) != EOF) {
550 switch (c) {
551 case '1':
552 only_use_v1_ioctl = true;
553 break;
554 case 't':
555 test_for_v2_policy_support();
556 return 0;
557 default:
558 return command_usage(&get_encpolicy_cmd);
559 }
560 }
561 argc -= optind;
562 argv += optind;
563
564 if (argc != 0)
565 return command_usage(&get_encpolicy_cmd);
566
567 /* first try the new ioctl */
568 if (only_use_v1_ioctl) {
569 res = -1;
570 errno = ENOTTY;
571 } else {
572 arg.policy_size = sizeof(arg.policy);
573 res = ioctl(file->fd, FS_IOC_GET_ENCRYPTION_POLICY_EX, &arg);
574 }
575
576 /* fall back to the old ioctl */
577 if (res != 0 && errno == ENOTTY)
578 res = ioctl(file->fd, FS_IOC_GET_ENCRYPTION_POLICY,
579 &arg.policy.v1);
580
581 if (res != 0) {
582 fprintf(stderr, _("%s: failed to get encryption policy: %s\n"),
583 file->name, strerror(errno));
584 exitcode = 1;
585 return 0;
586 }
587
588 switch (arg.policy.version) {
589 case FSCRYPT_POLICY_V1:
590 show_v1_encryption_policy(&arg.policy.v1);
591 break;
592 case FSCRYPT_POLICY_V2:
593 show_v2_encryption_policy(&arg.policy.v2);
594 break;
595 default:
596 printf(_("Encryption policy for %s:\n"), file->name);
597 printf(_("\tPolicy version: %u (unknown)\n"),
598 arg.policy.version);
599 break;
600 }
601 return 0;
602 }
603
604 static int
605 set_encpolicy_f(int argc, char **argv)
606 {
607 int c;
608 __u8 contents_encryption_mode = FSCRYPT_MODE_AES_256_XTS;
609 __u8 filenames_encryption_mode = FSCRYPT_MODE_AES_256_CTS;
610 __u8 flags = FSCRYPT_POLICY_FLAGS_PAD_16;
611 __u8 log2_data_unit_size = 0;
612 int version = -1; /* unspecified */
613 struct fscrypt_key_specifier key_spec;
614 union {
615 __u8 version;
616 struct fscrypt_policy_v1 v1;
617 struct fscrypt_policy_v2 v2;
618 } policy;
619
620 while ((c = getopt(argc, argv, "c:n:f:s:v:")) != EOF) {
621 switch (c) {
622 case 'c':
623 if (!parse_mode(optarg, &contents_encryption_mode)) {
624 fprintf(stderr,
625 _("invalid contents encryption mode: %s\n"),
626 optarg);
627 exitcode = 1;
628 return 0;
629 }
630 break;
631 case 'n':
632 if (!parse_mode(optarg, &filenames_encryption_mode)) {
633 fprintf(stderr,
634 _("invalid filenames encryption mode: %s\n"),
635 optarg);
636 exitcode = 1;
637 return 0;
638 }
639 break;
640 case 'f':
641 if (!parse_byte_value(optarg, &flags)) {
642 fprintf(stderr, _("invalid flags: %s\n"),
643 optarg);
644 exitcode = 1;
645 return 0;
646 }
647 break;
648 case 's':
649 if (!parse_byte_value(optarg, &log2_data_unit_size)) {
650 fprintf(stderr, _("invalid log2_dusize: %s\n"),
651 optarg);
652 exitcode = 1;
653 return 0;
654 }
655 break;
656 case 'v': {
657 __u8 val;
658
659 if (!parse_byte_value(optarg, &val)) {
660 fprintf(stderr,
661 _("invalid policy version: %s\n"),
662 optarg);
663 exitcode = 1;
664 return 0;
665 }
666 if (val == 1) /* Just to avoid annoying people... */
667 val = FSCRYPT_POLICY_V1;
668 version = val;
669 break;
670 }
671 default:
672 exitcode = 1;
673 return command_usage(&set_encpolicy_cmd);
674 }
675 }
676 argc -= optind;
677 argv += optind;
678
679 if (argc > 1) {
680 exitcode = 1;
681 return command_usage(&set_encpolicy_cmd);
682 }
683
684 /*
685 * If unspecified, the key descriptor or identifier defaults to all 0's.
686 * If the policy version is additionally unspecified, it defaults to v1.
687 */
688 memset(&key_spec, 0, sizeof(key_spec));
689 if (argc > 0) {
690 version = str2keyspec(argv[0], version, &key_spec);
691 if (version < 0) {
692 exitcode = 1;
693 return 0;
694 }
695 }
696 if (version < 0) /* version unspecified? */
697 version = FSCRYPT_POLICY_V1;
698
699 memset(&policy, 0, sizeof(policy));
700 policy.version = version;
701 if (version == FSCRYPT_POLICY_V2) {
702 policy.v2.contents_encryption_mode = contents_encryption_mode;
703 policy.v2.filenames_encryption_mode = filenames_encryption_mode;
704 policy.v2.flags = flags;
705 policy.v2.log2_data_unit_size = log2_data_unit_size;
706 memcpy(policy.v2.master_key_identifier, key_spec.u.identifier,
707 FSCRYPT_KEY_IDENTIFIER_SIZE);
708 } else {
709 if (log2_data_unit_size != 0) {
710 fprintf(stderr,
711 "v1 policy does not support selecting the data unit size\n");
712 exitcode = 1;
713 return 0;
714 }
715 /*
716 * xfstests passes .version = 255 for testing. Just use
717 * 'struct fscrypt_policy_v1' for both v1 and unknown versions.
718 */
719 policy.v1.contents_encryption_mode = contents_encryption_mode;
720 policy.v1.filenames_encryption_mode = filenames_encryption_mode;
721 policy.v1.flags = flags;
722 memcpy(policy.v1.master_key_descriptor, key_spec.u.descriptor,
723 FSCRYPT_KEY_DESCRIPTOR_SIZE);
724 }
725
726 if (ioctl(file->fd, FS_IOC_SET_ENCRYPTION_POLICY, &policy) != 0) {
727 fprintf(stderr, _("%s: failed to set encryption policy: %s\n"),
728 file->name, strerror(errno));
729 exitcode = 1;
730 }
731 return 0;
732 }
733
734 static ssize_t
735 read_until_limit_or_eof(int fd, void *buf, size_t limit)
736 {
737 size_t bytes_read = 0;
738 ssize_t res;
739
740 while (limit) {
741 res = read(fd, buf, limit);
742 if (res < 0)
743 return res;
744 if (res == 0)
745 break;
746 buf += res;
747 bytes_read += res;
748 limit -= res;
749 }
750 return bytes_read;
751 }
752
753 static int
754 add_enckey_f(int argc, char **argv)
755 {
756 int c;
757 struct fscrypt_add_key_arg *arg;
758 ssize_t raw_size;
759 int retval = 0;
760
761 arg = calloc(1, sizeof(*arg) + FSCRYPT_MAX_KEY_SIZE + 1);
762 if (!arg) {
763 perror("calloc");
764 exitcode = 1;
765 return 0;
766 }
767
768 arg->key_spec.type = FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER;
769
770 while ((c = getopt(argc, argv, "d:k:")) != EOF) {
771 switch (c) {
772 case 'd':
773 arg->key_spec.type = FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR;
774 if (!str2keydesc(optarg, arg->key_spec.u.descriptor))
775 goto out;
776 break;
777 case 'k':
778 arg->key_id = parse_key_id(optarg);
779 if (arg->key_id == 0)
780 goto out;
781 break;
782 default:
783 exitcode = 1;
784 retval = command_usage(&add_enckey_cmd);
785 goto out;
786 }
787 }
788 argc -= optind;
789 argv += optind;
790
791 if (argc != 0) {
792 exitcode = 1;
793 retval = command_usage(&add_enckey_cmd);
794 goto out;
795 }
796
797 if (arg->key_id == 0) {
798 raw_size = read_until_limit_or_eof(STDIN_FILENO, arg->raw,
799 FSCRYPT_MAX_KEY_SIZE + 1);
800 if (raw_size < 0) {
801 fprintf(stderr, _("Error reading key from stdin: %s\n"),
802 strerror(errno));
803 exitcode = 1;
804 goto out;
805 }
806 if (raw_size > FSCRYPT_MAX_KEY_SIZE) {
807 fprintf(stderr,
808 _("Invalid key; got > FSCRYPT_MAX_KEY_SIZE (%d) bytes on stdin!\n"),
809 FSCRYPT_MAX_KEY_SIZE);
810 exitcode = 1;
811 goto out;
812 }
813 arg->raw_size = raw_size;
814 } /* else, raw key is given via key with ID 'key_id' */
815
816 if (ioctl(file->fd, FS_IOC_ADD_ENCRYPTION_KEY, arg) != 0) {
817 fprintf(stderr, _("Error adding encryption key: %s\n"),
818 strerror(errno));
819 exitcode = 1;
820 goto out;
821 }
822 printf(_("Added encryption key with %s %s\n"),
823 keyspectype(&arg->key_spec), keyspec2str(&arg->key_spec));
824 out:
825 memset(arg->raw, 0, FSCRYPT_MAX_KEY_SIZE + 1);
826 free(arg);
827 return retval;
828 }
829
830 static int
831 rm_enckey_f(int argc, char **argv)
832 {
833 int c;
834 struct fscrypt_remove_key_arg arg;
835 int ioc = FS_IOC_REMOVE_ENCRYPTION_KEY;
836
837 memset(&arg, 0, sizeof(arg));
838
839 while ((c = getopt(argc, argv, "a")) != EOF) {
840 switch (c) {
841 case 'a':
842 ioc = FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS;
843 break;
844 default:
845 exitcode = 1;
846 return command_usage(&rm_enckey_cmd);
847 }
848 }
849 argc -= optind;
850 argv += optind;
851
852 if (argc != 1) {
853 exitcode = 1;
854 return command_usage(&rm_enckey_cmd);
855 }
856
857 if (str2keyspec(argv[0], -1, &arg.key_spec) < 0) {
858 exitcode = 1;
859 return 0;
860 }
861
862 if (ioctl(file->fd, ioc, &arg) != 0) {
863 fprintf(stderr, _("Error removing encryption key: %s\n"),
864 strerror(errno));
865 exitcode = 1;
866 return 0;
867 }
868 if (arg.removal_status_flags &
869 FSCRYPT_KEY_REMOVAL_STATUS_FLAG_OTHER_USERS) {
870 printf(_("Removed user's claim to encryption key with %s %s\n"),
871 keyspectype(&arg.key_spec), keyspec2str(&arg.key_spec));
872 } else if (arg.removal_status_flags &
873 FSCRYPT_KEY_REMOVAL_STATUS_FLAG_FILES_BUSY) {
874 printf(_("Removed encryption key with %s %s, but files still busy\n"),
875 keyspectype(&arg.key_spec), keyspec2str(&arg.key_spec));
876 } else {
877 printf(_("Removed encryption key with %s %s\n"),
878 keyspectype(&arg.key_spec), keyspec2str(&arg.key_spec));
879 }
880 return 0;
881 }
882
883 static int
884 enckey_status_f(int argc, char **argv)
885 {
886 struct fscrypt_get_key_status_arg arg;
887
888 memset(&arg, 0, sizeof(arg));
889
890 if (str2keyspec(argv[1], -1, &arg.key_spec) < 0) {
891 exitcode = 1;
892 return 0;
893 }
894
895 if (ioctl(file->fd, FS_IOC_GET_ENCRYPTION_KEY_STATUS, &arg) != 0) {
896 fprintf(stderr, _("Error getting encryption key status: %s\n"),
897 strerror(errno));
898 exitcode = 1;
899 return 0;
900 }
901
902 switch (arg.status) {
903 case FSCRYPT_KEY_STATUS_PRESENT:
904 printf(_("Present"));
905 if (arg.user_count || arg.status_flags) {
906 printf(" (user_count=%u", arg.user_count);
907 if (arg.status_flags &
908 FSCRYPT_KEY_STATUS_FLAG_ADDED_BY_SELF)
909 printf(", added_by_self");
910 arg.status_flags &=
911 ~FSCRYPT_KEY_STATUS_FLAG_ADDED_BY_SELF;
912 if (arg.status_flags)
913 printf(", unknown_flags=0x%08x",
914 arg.status_flags);
915 printf(")");
916 }
917 printf("\n");
918 return 0;
919 case FSCRYPT_KEY_STATUS_ABSENT:
920 printf(_("Absent\n"));
921 return 0;
922 case FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED:
923 printf(_("Incompletely removed\n"));
924 return 0;
925 default:
926 printf(_("Unknown status (%u)\n"), arg.status);
927 return 0;
928 }
929 }
930
931 void
932 encrypt_init(void)
933 {
934 get_encpolicy_cmd.name = "get_encpolicy";
935 get_encpolicy_cmd.cfunc = get_encpolicy_f;
936 get_encpolicy_cmd.args = _("[-1] [-t]");
937 get_encpolicy_cmd.argmin = 0;
938 get_encpolicy_cmd.argmax = -1;
939 get_encpolicy_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
940 get_encpolicy_cmd.oneline =
941 _("display the encryption policy of the current file");
942 get_encpolicy_cmd.help = get_encpolicy_help;
943
944 set_encpolicy_cmd.name = "set_encpolicy";
945 set_encpolicy_cmd.cfunc = set_encpolicy_f;
946 set_encpolicy_cmd.args =
947 _("[-c mode] [-n mode] [-f flags] [-s log2_dusize] [-v version] [keyspec]");
948 set_encpolicy_cmd.argmin = 0;
949 set_encpolicy_cmd.argmax = -1;
950 set_encpolicy_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
951 set_encpolicy_cmd.oneline =
952 _("assign an encryption policy to the current file");
953 set_encpolicy_cmd.help = set_encpolicy_help;
954
955 add_enckey_cmd.name = "add_enckey";
956 add_enckey_cmd.cfunc = add_enckey_f;
957 add_enckey_cmd.args = _("[-d descriptor] [-k key_id]");
958 add_enckey_cmd.argmin = 0;
959 add_enckey_cmd.argmax = -1;
960 add_enckey_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
961 add_enckey_cmd.oneline = _("add an encryption key to the filesystem");
962 add_enckey_cmd.help = add_enckey_help;
963
964 rm_enckey_cmd.name = "rm_enckey";
965 rm_enckey_cmd.cfunc = rm_enckey_f;
966 rm_enckey_cmd.args = _("[-a] keyspec");
967 rm_enckey_cmd.argmin = 0;
968 rm_enckey_cmd.argmax = -1;
969 rm_enckey_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
970 rm_enckey_cmd.oneline =
971 _("remove an encryption key from the filesystem");
972 rm_enckey_cmd.help = rm_enckey_help;
973
974 enckey_status_cmd.name = "enckey_status";
975 enckey_status_cmd.cfunc = enckey_status_f;
976 enckey_status_cmd.args = _("keyspec");
977 enckey_status_cmd.argmin = 1;
978 enckey_status_cmd.argmax = 1;
979 enckey_status_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
980 enckey_status_cmd.oneline =
981 _("get the status of a filesystem encryption key");
982 enckey_status_cmd.help = enckey_status_help;
983
984 add_command(&get_encpolicy_cmd);
985 add_command(&set_encpolicy_cmd);
986 add_command(&add_enckey_cmd);
987 add_command(&rm_enckey_cmd);
988 add_command(&enckey_status_cmd);
989 }