1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright 2016, 2019 Google LLC
4 * Author: Eric Biggers <ebiggers@google.com>
7 #ifdef OVERRIDE_SYSTEM_FSCRYPT_ADD_KEY_ARG
8 # define fscrypt_add_key_arg sys_fscrypt_add_key_arg
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
14 #include "platform_defs.h"
17 #include "libfrog/paths.h"
21 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
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.
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)
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.
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
{
48 __u8 contents_encryption_mode
;
49 __u8 filenames_encryption_mode
;
51 __u8 log2_data_unit_size
;
53 __u8 master_key_identifier
[FSCRYPT_KEY_IDENTIFIER_SIZE
];
56 #undef fscrypt_get_policy_ex_arg
57 struct fscrypt_get_policy_ex_arg
{
58 __u64 policy_size
; /* input/output */
61 struct fscrypt_policy_v1 v1
;
62 struct fscrypt_policy_v2 v2
;
63 } policy
; /* output */
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.
71 #ifndef FS_IOC_GET_ENCRYPTION_POLICY_EX
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
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
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.
91 * Note: "v1" policies really are version "0" in the API.
93 #define FSCRYPT_POLICY_V1 0
94 #define FSCRYPT_KEY_DESCRIPTOR_SIZE 8
95 struct fscrypt_policy_v1
{
97 __u8 contents_encryption_mode
;
98 __u8 filenames_encryption_mode
;
100 __u8 master_key_descriptor
[FSCRYPT_KEY_DESCRIPTOR_SIZE
];
103 #define FSCRYPT_POLICY_V2 2
104 #define FSCRYPT_KEY_IDENTIFIER_SIZE 16
105 /* struct fscrypt_policy_v2 was defined earlier */
107 #define FSCRYPT_MAX_KEY_SIZE 64
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 */
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_* */
118 __u8 __reserved
[32]; /* reserve some extra space */
119 __u8 descriptor
[FSCRYPT_KEY_DESCRIPTOR_SIZE
];
120 __u8 identifier
[FSCRYPT_KEY_IDENTIFIER_SIZE
];
124 /* FS_IOC_ADD_ENCRYPTION_KEY is defined later */
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 */
136 #define FS_IOC_GET_ENCRYPTION_KEY_STATUS _IOWR('f', 26, struct fscrypt_get_key_status_arg)
137 struct fscrypt_get_key_status_arg
{
139 struct fscrypt_key_specifier key_spec
;
143 #define FSCRYPT_KEY_STATUS_ABSENT 1
144 #define FSCRYPT_KEY_STATUS_PRESENT 2
145 #define FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED 3
147 #define FSCRYPT_KEY_STATUS_FLAG_ADDED_BY_SELF 0x00000001
150 __u32 __out_reserved
[13];
153 #endif /* !FS_IOC_GET_ENCRYPTION_POLICY_EX */
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.
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
;
171 #ifndef FS_IOC_ADD_ENCRYPTION_KEY
172 # define FS_IOC_ADD_ENCRYPTION_KEY _IOWR('f', 23, struct fscrypt_add_key_arg)
175 static const struct {
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"},
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
;
193 get_encpolicy_help(void)
197 " display the encryption policy of the current file\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"
207 set_encpolicy_help(void)
213 " assign an encryption policy to the currently open file\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"
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"
230 " MODE can be numeric or one of the following predefined values:\n"));
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)
239 " FLAGS and VERSION must be numeric.\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"
247 add_enckey_help(void)
251 " add an encryption key to the filesystem\n"
254 " 'add_enckey' - add key for v2 policies\n"
255 " 'add_enckey -d 0000111122223333' - add key for v1 policies w/ given descriptor\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"
268 " remove an encryption key from the filesystem\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"
274 " -a -- remove key for all users who have added it (privileged operation)\n"
279 enckey_status_help(void)
283 " get the status of a filesystem encryption key\n"
286 " 'enckey_status 0000111122223333' - get status of v1 policy key\n"
287 " 'enckey_status 00001111222233334444555566667777' - get status of v2 policy key\n"
292 parse_byte_value(const char *arg
, __u8
*value_ret
)
297 value
= strtol(arg
, &tmp
, 0);
298 if (value
< 0 || value
> 255 || tmp
== arg
|| *tmp
!= '\0')
305 parse_mode(const char *arg
, __u8
*mode_ret
)
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
;
316 return parse_byte_value(arg
, mode_ret
);
325 for (i
= 0; i
< ARRAY_SIZE(available_modes
); i
++)
326 if (mode
== available_modes
[i
].mode
)
327 return available_modes
[i
].name
;
329 sprintf(buf
, "0x%02x", mode
);
336 if (c
>= '0' && c
<= '9')
338 if (c
>= 'a' && c
<= 'f')
339 return 10 + (c
- 'a');
340 if (c
>= 'A' && c
<= 'F')
341 return 10 + (c
- 'A');
346 hex2bin(const char *hex
, __u8
*bin
, size_t bin_len
)
348 if (strlen(hex
) != 2 * bin_len
)
352 int hi
= hexchar2bin(*hex
++);
353 int lo
= hexchar2bin(*hex
++);
355 if (hi
< 0 || lo
< 0)
357 *bin
++ = (hi
<< 4) | lo
;
363 keydesc2str(const __u8 master_key_descriptor
[FSCRYPT_KEY_DESCRIPTOR_SIZE
])
365 static char buf
[2 * FSCRYPT_KEY_DESCRIPTOR_SIZE
+ 1];
368 for (i
= 0; i
< FSCRYPT_KEY_DESCRIPTOR_SIZE
; i
++)
369 sprintf(&buf
[2 * i
], "%02x", master_key_descriptor
[i
]);
375 keyid2str(const __u8 master_key_identifier
[FSCRYPT_KEY_IDENTIFIER_SIZE
])
377 static char buf
[2 * FSCRYPT_KEY_IDENTIFIER_SIZE
+ 1];
380 for (i
= 0; i
< FSCRYPT_KEY_IDENTIFIER_SIZE
; i
++)
381 sprintf(&buf
[2 * i
], "%02x", master_key_identifier
[i
]);
387 keyspectype(const struct fscrypt_key_specifier
*key_spec
)
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");
395 return _("[unknown]");
399 keyspec2str(const struct fscrypt_key_specifier
*key_spec
)
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
);
407 return _("[unknown]");
411 str2keydesc(const char *str
,
412 __u8 master_key_descriptor
[FSCRYPT_KEY_DESCRIPTOR_SIZE
])
414 if (!hex2bin(str
, master_key_descriptor
, FSCRYPT_KEY_DESCRIPTOR_SIZE
)) {
415 fprintf(stderr
, _("invalid key descriptor: %s\n"), str
);
422 str2keyid(const char *str
,
423 __u8 master_key_identifier
[FSCRYPT_KEY_IDENTIFIER_SIZE
])
425 if (!hex2bin(str
, master_key_identifier
, FSCRYPT_KEY_IDENTIFIER_SIZE
)) {
426 fprintf(stderr
, _("invalid key identifier: %s\n"), str
);
433 * Parse a key specifier (descriptor or identifier) given as a hex string.
435 * 8 bytes (16 hex chars) == key descriptor == v1 encryption policy.
436 * 16 bytes (32 hex chars) == key identifier == v2 encryption policy.
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.
442 * Returns the policy version, or -1 on error.
445 str2keyspec(const char *str
, int policy_version
,
446 struct fscrypt_key_specifier
*key_spec
)
448 if (policy_version
< 0) { /* version unspecified? */
449 size_t len
= strlen(str
);
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
;
456 fprintf(stderr
, _("invalid key specifier: %s\n"), str
);
460 if (policy_version
== FSCRYPT_POLICY_V2
) {
461 if (!str2keyid(str
, key_spec
->u
.identifier
))
463 key_spec
->type
= FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER
;
465 if (!str2keydesc(str
, key_spec
->u
.descriptor
))
467 key_spec
->type
= FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR
;
469 return policy_version
;
473 parse_key_id(const char *arg
)
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. */
488 test_for_v2_policy_support(void)
490 struct fscrypt_get_policy_ex_arg arg
;
492 arg
.policy_size
= sizeof(arg
.policy
);
494 if (ioctl(file
->fd
, FS_IOC_GET_ENCRYPTION_POLICY_EX
, &arg
) == 0 ||
495 errno
== ENODATA
/* file unencrypted */) {
496 printf(_("supported\n"));
499 if (errno
== ENOTTY
) {
500 printf(_("unsupported\n"));
504 _("%s: unexpected error checking for FS_IOC_GET_ENCRYPTION_POLICY_EX support: %s\n"),
505 file
->name
, strerror(errno
));
510 show_v1_encryption_policy(const struct fscrypt_policy_v1
*policy
)
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
);
526 show_v2_encryption_policy(const struct fscrypt_policy_v2
*policy
)
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
);
542 get_encpolicy_f(int argc
, char **argv
)
545 struct fscrypt_get_policy_ex_arg arg
;
546 bool only_use_v1_ioctl
= false;
549 while ((c
= getopt(argc
, argv
, "1t")) != EOF
) {
552 only_use_v1_ioctl
= true;
555 test_for_v2_policy_support();
558 return command_usage(&get_encpolicy_cmd
);
565 return command_usage(&get_encpolicy_cmd
);
567 /* first try the new ioctl */
568 if (only_use_v1_ioctl
) {
572 arg
.policy_size
= sizeof(arg
.policy
);
573 res
= ioctl(file
->fd
, FS_IOC_GET_ENCRYPTION_POLICY_EX
, &arg
);
576 /* fall back to the old ioctl */
577 if (res
!= 0 && errno
== ENOTTY
)
578 res
= ioctl(file
->fd
, FS_IOC_GET_ENCRYPTION_POLICY
,
582 fprintf(stderr
, _("%s: failed to get encryption policy: %s\n"),
583 file
->name
, strerror(errno
));
588 switch (arg
.policy
.version
) {
589 case FSCRYPT_POLICY_V1
:
590 show_v1_encryption_policy(&arg
.policy
.v1
);
592 case FSCRYPT_POLICY_V2
:
593 show_v2_encryption_policy(&arg
.policy
.v2
);
596 printf(_("Encryption policy for %s:\n"), file
->name
);
597 printf(_("\tPolicy version: %u (unknown)\n"),
605 set_encpolicy_f(int argc
, char **argv
)
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
;
616 struct fscrypt_policy_v1 v1
;
617 struct fscrypt_policy_v2 v2
;
620 while ((c
= getopt(argc
, argv
, "c:n:f:s:v:")) != EOF
) {
623 if (!parse_mode(optarg
, &contents_encryption_mode
)) {
625 _("invalid contents encryption mode: %s\n"),
632 if (!parse_mode(optarg
, &filenames_encryption_mode
)) {
634 _("invalid filenames encryption mode: %s\n"),
641 if (!parse_byte_value(optarg
, &flags
)) {
642 fprintf(stderr
, _("invalid flags: %s\n"),
649 if (!parse_byte_value(optarg
, &log2_data_unit_size
)) {
650 fprintf(stderr
, _("invalid log2_dusize: %s\n"),
659 if (!parse_byte_value(optarg
, &val
)) {
661 _("invalid policy version: %s\n"),
666 if (val
== 1) /* Just to avoid annoying people... */
667 val
= FSCRYPT_POLICY_V1
;
673 return command_usage(&set_encpolicy_cmd
);
681 return command_usage(&set_encpolicy_cmd
);
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.
688 memset(&key_spec
, 0, sizeof(key_spec
));
690 version
= str2keyspec(argv
[0], version
, &key_spec
);
696 if (version
< 0) /* version unspecified? */
697 version
= FSCRYPT_POLICY_V1
;
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
);
709 if (log2_data_unit_size
!= 0) {
711 "v1 policy does not support selecting the data unit size\n");
716 * xfstests passes .version = 255 for testing. Just use
717 * 'struct fscrypt_policy_v1' for both v1 and unknown versions.
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
);
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
));
735 read_until_limit_or_eof(int fd
, void *buf
, size_t limit
)
737 size_t bytes_read
= 0;
741 res
= read(fd
, buf
, limit
);
754 add_enckey_f(int argc
, char **argv
)
757 struct fscrypt_add_key_arg
*arg
;
761 arg
= calloc(1, sizeof(*arg
) + FSCRYPT_MAX_KEY_SIZE
+ 1);
768 arg
->key_spec
.type
= FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER
;
770 while ((c
= getopt(argc
, argv
, "d:k:")) != EOF
) {
773 arg
->key_spec
.type
= FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR
;
774 if (!str2keydesc(optarg
, arg
->key_spec
.u
.descriptor
))
778 arg
->key_id
= parse_key_id(optarg
);
779 if (arg
->key_id
== 0)
784 retval
= command_usage(&add_enckey_cmd
);
793 retval
= command_usage(&add_enckey_cmd
);
797 if (arg
->key_id
== 0) {
798 raw_size
= read_until_limit_or_eof(STDIN_FILENO
, arg
->raw
,
799 FSCRYPT_MAX_KEY_SIZE
+ 1);
801 fprintf(stderr
, _("Error reading key from stdin: %s\n"),
806 if (raw_size
> FSCRYPT_MAX_KEY_SIZE
) {
808 _("Invalid key; got > FSCRYPT_MAX_KEY_SIZE (%d) bytes on stdin!\n"),
809 FSCRYPT_MAX_KEY_SIZE
);
813 arg
->raw_size
= raw_size
;
814 } /* else, raw key is given via key with ID 'key_id' */
816 if (ioctl(file
->fd
, FS_IOC_ADD_ENCRYPTION_KEY
, arg
) != 0) {
817 fprintf(stderr
, _("Error adding encryption key: %s\n"),
822 printf(_("Added encryption key with %s %s\n"),
823 keyspectype(&arg
->key_spec
), keyspec2str(&arg
->key_spec
));
825 memset(arg
->raw
, 0, FSCRYPT_MAX_KEY_SIZE
+ 1);
831 rm_enckey_f(int argc
, char **argv
)
834 struct fscrypt_remove_key_arg arg
;
835 int ioc
= FS_IOC_REMOVE_ENCRYPTION_KEY
;
837 memset(&arg
, 0, sizeof(arg
));
839 while ((c
= getopt(argc
, argv
, "a")) != EOF
) {
842 ioc
= FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS
;
846 return command_usage(&rm_enckey_cmd
);
854 return command_usage(&rm_enckey_cmd
);
857 if (str2keyspec(argv
[0], -1, &arg
.key_spec
) < 0) {
862 if (ioctl(file
->fd
, ioc
, &arg
) != 0) {
863 fprintf(stderr
, _("Error removing encryption key: %s\n"),
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
));
877 printf(_("Removed encryption key with %s %s\n"),
878 keyspectype(&arg
.key_spec
), keyspec2str(&arg
.key_spec
));
884 enckey_status_f(int argc
, char **argv
)
886 struct fscrypt_get_key_status_arg arg
;
888 memset(&arg
, 0, sizeof(arg
));
890 if (str2keyspec(argv
[1], -1, &arg
.key_spec
) < 0) {
895 if (ioctl(file
->fd
, FS_IOC_GET_ENCRYPTION_KEY_STATUS
, &arg
) != 0) {
896 fprintf(stderr
, _("Error getting encryption key status: %s\n"),
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");
911 ~FSCRYPT_KEY_STATUS_FLAG_ADDED_BY_SELF
;
912 if (arg
.status_flags
)
913 printf(", unknown_flags=0x%08x",
919 case FSCRYPT_KEY_STATUS_ABSENT
:
920 printf(_("Absent\n"));
922 case FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED
:
923 printf(_("Incompletely removed\n"));
926 printf(_("Unknown status (%u)\n"), arg
.status
);
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
;
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
;
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
;
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
;
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
;
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
);