From patchwork Sat Sep 28 00:02:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11165293 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 879D01747 for ; Sat, 28 Sep 2019 00:03:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6588F20869 for ; Sat, 28 Sep 2019 00:03:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1569629025; bh=FVW8c7dxtnnfeeRELqBdj69UriRU9Me3FZsaq5q0jjg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=0pVSDi1N5vKW4p6LNWZKGcxZJ4NTX3FNAIwWOos2db84BS20sqY0qfJxvwDGtPfR5 rDFaGv0f86XRDOwcy8OTlsrKP0FuQ6BC615J3V7wnRwVEXTEuf0sUKU5wvA9MhG7DS zymM01gmYq2rFWBEHAE3slgY4piFTamPnCAeEbKU= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728077AbfI1ADp (ORCPT ); Fri, 27 Sep 2019 20:03:45 -0400 Received: from mail.kernel.org ([198.145.29.99]:49212 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726408AbfI1ADo (ORCPT ); Fri, 27 Sep 2019 20:03:44 -0400 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 2690720869; Sat, 28 Sep 2019 00:03:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1569629024; bh=FVW8c7dxtnnfeeRELqBdj69UriRU9Me3FZsaq5q0jjg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TgqF54/gBEz6y4Ojtwz9uIR2dAvDyQ3BhOQtPx6WrRCETl2yd4Iu3Kzneyw9mSWAc 8tfQWfL1VuPV5GsxmhyPDTWEzs8VATi9YR8XydV3hG4FtJeamwxSB8L1BVc3dBphrG dHR0rApxxa3pFgmKUBQyCcd/18DhkxqmY7W8IHBI= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [PATCH v3 1/9] xfs_io/encrypt: remove unimplemented encryption modes Date: Fri, 27 Sep 2019 17:02:35 -0700 Message-Id: <20190928000243.77634-2-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.444.g18eeb5a265-goog In-Reply-To: <20190928000243.77634-1-ebiggers@kernel.org> References: <20190928000243.77634-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Eric Biggers Although mode numbers were originally reserved for AES-256-GCM and AES-256-CBC, these were never implemented in the kernel, and there are no plans to do so anymore. These mode numbers may be used for something else in the future. Also, xfstests (the only known user of the xfs_io encryption commands) doesn't try to use them. Finally, most of the fscrypt constants have been given new names in the UAPI header, but the unused constants have not been given new names since userspace should just stop referencing them instead. So remove them from xfs_io. Signed-off-by: Eric Biggers --- io/encrypt.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/io/encrypt.c b/io/encrypt.c index 7a0b2465..70c9e5eb 100644 --- a/io/encrypt.c +++ b/io/encrypt.c @@ -49,8 +49,6 @@ struct fscrypt_policy { #define FS_ENCRYPTION_MODE_INVALID 0 #define FS_ENCRYPTION_MODE_AES_256_XTS 1 -#define FS_ENCRYPTION_MODE_AES_256_GCM 2 -#define FS_ENCRYPTION_MODE_AES_256_CBC 3 #define FS_ENCRYPTION_MODE_AES_256_CTS 4 #endif /* FS_ENCRYPTION_MODE_AES_256_XTS */ @@ -74,7 +72,7 @@ set_encpolicy_help(void) " -v VERSION -- version of policy structure\n" "\n" " MODE can be numeric or one of the following predefined values:\n" -" AES-256-XTS, AES-256-CTS, AES-256-GCM, AES-256-CBC\n" +" AES-256-XTS, AES-256-CTS\n" " FLAGS and VERSION must be numeric.\n" "\n" " Note that it's only possible to set an encryption policy on an empty\n" @@ -88,8 +86,6 @@ static const struct { } available_modes[] = { {FS_ENCRYPTION_MODE_AES_256_XTS, "AES-256-XTS"}, {FS_ENCRYPTION_MODE_AES_256_CTS, "AES-256-CTS"}, - {FS_ENCRYPTION_MODE_AES_256_GCM, "AES-256-GCM"}, - {FS_ENCRYPTION_MODE_AES_256_CBC, "AES-256-CBC"}, }; static bool From patchwork Sat Sep 28 00:02:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11165313 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 977BA18B6 for ; Sat, 28 Sep 2019 00:03:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 745FF21906 for ; Sat, 28 Sep 2019 00:03:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1569629027; bh=hDl16fGWjW2sqfA04onzI6BqmQSNE2vrVY7tjMM6qoo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=iiEpnQoIV6THQfK/td+ASKPTfp/hHjSEje4y2zXpxA9sb6k05XC/TfVBN80iLyW5D fGW92RX2WvQTDrJA/TtOKVZYz3zQjjLE2I0Ehz69JhhW/hu0+E+7CTadhxteloprJ9 KkyiIeXFZYJeUwp7BR5Y8C99SqriziefujJ4dlx4= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728355AbfI1ADq (ORCPT ); Fri, 27 Sep 2019 20:03:46 -0400 Received: from mail.kernel.org ([198.145.29.99]:49218 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726762AbfI1ADp (ORCPT ); Fri, 27 Sep 2019 20:03:45 -0400 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 643D721655; Sat, 28 Sep 2019 00:03:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1569629024; bh=hDl16fGWjW2sqfA04onzI6BqmQSNE2vrVY7tjMM6qoo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=g2cxMDv7RgqMybCp6OsO156Wt20ICi5bNgxjQ8zID9Cfm5BcFeTb0Z3Bs+Usr1l2m lvYL40u5DAsUMyiccTIR15jSOSXXmbp/0BwF8fKLJaCGyMKBvqCtu7np9C1z1qpfgb ETvfn5/LETrBOm6UP5V5GL5x25brORd6FeUd0ORg= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [PATCH v3 2/9] xfs_io/encrypt: update to UAPI definitions from Linux v5.4 Date: Fri, 27 Sep 2019 17:02:36 -0700 Message-Id: <20190928000243.77634-3-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.444.g18eeb5a265-goog In-Reply-To: <20190928000243.77634-1-ebiggers@kernel.org> References: <20190928000243.77634-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Eric Biggers Update to the latest fscrypt UAPI definitions, including: - New names for some existing definitions (FSCRYPT_ instead of FS_). - New ioctls. - New encryption mode numbers and flags. This patch doesn't make any change to the program logic itself. Signed-off-by: Eric Biggers --- io/encrypt.c | 160 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 122 insertions(+), 38 deletions(-) diff --git a/io/encrypt.c b/io/encrypt.c index 70c9e5eb..011a6410 100644 --- a/io/encrypt.c +++ b/io/encrypt.c @@ -15,42 +15,126 @@ #endif /* - * We may have to declare the fscrypt ioctls ourselves because someone may be - * compiling xfsprogs with old kernel headers. And since some old versions of - * declared the policy struct and ioctl numbers but not the flags - * and modes, our declarations must be split into two conditional blocks. + * Declare the fscrypt ioctls if needed, since someone may be compiling xfsprogs + * with old kernel headers. But has already been included, so be + * careful not to declare things twice. */ -/* Policy struct and ioctl numbers */ +/* first batch of ioctls (Linux headers v4.6+) */ #ifndef FS_IOC_SET_ENCRYPTION_POLICY -#define FS_KEY_DESCRIPTOR_SIZE 8 +#define fscrypt_policy fscrypt_policy_v1 +#define FS_IOC_SET_ENCRYPTION_POLICY _IOR('f', 19, struct fscrypt_policy) +#define FS_IOC_GET_ENCRYPTION_PWSALT _IOW('f', 20, __u8[16]) +#define FS_IOC_GET_ENCRYPTION_POLICY _IOW('f', 21, struct fscrypt_policy) +#endif + +/* + * Second batch of ioctls (Linux headers v5.4+), plus some renamings from FS_ to + * FSCRYPT_. We don't bother defining the old names here. + */ +#ifndef FS_IOC_GET_ENCRYPTION_POLICY_EX + +#define FSCRYPT_POLICY_FLAGS_PAD_4 0x00 +#define FSCRYPT_POLICY_FLAGS_PAD_8 0x01 +#define FSCRYPT_POLICY_FLAGS_PAD_16 0x02 +#define FSCRYPT_POLICY_FLAGS_PAD_32 0x03 +#define FSCRYPT_POLICY_FLAGS_PAD_MASK 0x03 +#define FSCRYPT_POLICY_FLAG_DIRECT_KEY 0x04 + +#define FSCRYPT_MODE_AES_256_XTS 1 +#define FSCRYPT_MODE_AES_256_CTS 4 +#define FSCRYPT_MODE_AES_128_CBC 5 +#define FSCRYPT_MODE_AES_128_CTS 6 +#define FSCRYPT_MODE_ADIANTUM 9 + +/* + * In the headers for Linux v4.6 through v5.3, 'struct fscrypt_policy_v1' is + * already defined under its old name, 'struct fscrypt_policy'. But it's fine + * to define it under its new name too. + * + * Note: "v1" policies really are version "0" in the API. + */ +#define FSCRYPT_POLICY_V1 0 +#define FSCRYPT_KEY_DESCRIPTOR_SIZE 8 +struct fscrypt_policy_v1 { + __u8 version; + __u8 contents_encryption_mode; + __u8 filenames_encryption_mode; + __u8 flags; + __u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE]; +}; -struct fscrypt_policy { +#define FSCRYPT_POLICY_V2 2 +#define FSCRYPT_KEY_IDENTIFIER_SIZE 16 +struct fscrypt_policy_v2 { __u8 version; __u8 contents_encryption_mode; __u8 filenames_encryption_mode; __u8 flags; - __u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE]; -} __attribute__((packed)); - -#define FS_IOC_SET_ENCRYPTION_POLICY _IOR('f', 19, struct fscrypt_policy) -#define FS_IOC_GET_ENCRYPTION_PWSALT _IOW('f', 20, __u8[16]) -#define FS_IOC_GET_ENCRYPTION_POLICY _IOW('f', 21, struct fscrypt_policy) -#endif /* FS_IOC_SET_ENCRYPTION_POLICY */ - -/* Policy flags and encryption modes */ -#ifndef FS_ENCRYPTION_MODE_AES_256_XTS -#define FS_POLICY_FLAGS_PAD_4 0x00 -#define FS_POLICY_FLAGS_PAD_8 0x01 -#define FS_POLICY_FLAGS_PAD_16 0x02 -#define FS_POLICY_FLAGS_PAD_32 0x03 -#define FS_POLICY_FLAGS_PAD_MASK 0x03 -#define FS_POLICY_FLAGS_VALID 0x03 - -#define FS_ENCRYPTION_MODE_INVALID 0 -#define FS_ENCRYPTION_MODE_AES_256_XTS 1 -#define FS_ENCRYPTION_MODE_AES_256_CTS 4 -#endif /* FS_ENCRYPTION_MODE_AES_256_XTS */ + __u8 __reserved[4]; + __u8 master_key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]; +}; + +#define FSCRYPT_MAX_KEY_SIZE 64 + +#define FS_IOC_GET_ENCRYPTION_POLICY_EX _IOWR('f', 22, __u8[9]) /* size + version */ +struct fscrypt_get_policy_ex_arg { + __u64 policy_size; /* input/output */ + union { + __u8 version; + struct fscrypt_policy_v1 v1; + struct fscrypt_policy_v2 v2; + } policy; /* output */ +}; + +#define FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR 1 +#define FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER 2 +struct fscrypt_key_specifier { + __u32 type; /* one of FSCRYPT_KEY_SPEC_TYPE_* */ + __u32 __reserved; + union { + __u8 __reserved[32]; /* reserve some extra space */ + __u8 descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE]; + __u8 identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]; + } u; +}; + +#define FS_IOC_ADD_ENCRYPTION_KEY _IOWR('f', 23, struct fscrypt_add_key_arg) +struct fscrypt_add_key_arg { + struct fscrypt_key_specifier key_spec; + __u32 raw_size; + __u32 __reserved[9]; + __u8 raw[]; +}; + +#define FS_IOC_REMOVE_ENCRYPTION_KEY _IOWR('f', 24, struct fscrypt_remove_key_arg) +#define FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS _IOWR('f', 25, struct fscrypt_remove_key_arg) +struct fscrypt_remove_key_arg { + struct fscrypt_key_specifier key_spec; +#define FSCRYPT_KEY_REMOVAL_STATUS_FLAG_FILES_BUSY 0x00000001 +#define FSCRYPT_KEY_REMOVAL_STATUS_FLAG_OTHER_USERS 0x00000002 + __u32 removal_status_flags; /* output */ + __u32 __reserved[5]; +}; + +#define FS_IOC_GET_ENCRYPTION_KEY_STATUS _IOWR('f', 26, struct fscrypt_get_key_status_arg) +struct fscrypt_get_key_status_arg { + /* input */ + struct fscrypt_key_specifier key_spec; + __u32 __reserved[6]; + + /* output */ +#define FSCRYPT_KEY_STATUS_ABSENT 1 +#define FSCRYPT_KEY_STATUS_PRESENT 2 +#define FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED 3 + __u32 status; +#define FSCRYPT_KEY_STATUS_FLAG_ADDED_BY_SELF 0x00000001 + __u32 status_flags; + __u32 user_count; + __u32 __out_reserved[13]; +}; + +#endif /* !FS_IOC_GET_ENCRYPTION_POLICY_EX */ static cmdinfo_t get_encpolicy_cmd; static cmdinfo_t set_encpolicy_cmd; @@ -84,8 +168,8 @@ static const struct { __u8 mode; const char *name; } available_modes[] = { - {FS_ENCRYPTION_MODE_AES_256_XTS, "AES-256-XTS"}, - {FS_ENCRYPTION_MODE_AES_256_CTS, "AES-256-CTS"}, + {FSCRYPT_MODE_AES_256_XTS, "AES-256-XTS"}, + {FSCRYPT_MODE_AES_256_CTS, "AES-256-CTS"}, }; static bool @@ -131,12 +215,12 @@ mode2str(__u8 mode) } static const char * -keydesc2str(__u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE]) +keydesc2str(__u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE]) { - static char buf[2 * FS_KEY_DESCRIPTOR_SIZE + 1]; + static char buf[2 * FSCRYPT_KEY_DESCRIPTOR_SIZE + 1]; int i; - for (i = 0; i < FS_KEY_DESCRIPTOR_SIZE; i++) + for (i = 0; i < FSCRYPT_KEY_DESCRIPTOR_SIZE; i++) sprintf(&buf[2 * i], "%02x", master_key_descriptor[i]); return buf; @@ -176,9 +260,9 @@ set_encpolicy_f(int argc, char **argv) /* Initialize the policy structure with default values */ memset(&policy, 0, sizeof(policy)); - policy.contents_encryption_mode = FS_ENCRYPTION_MODE_AES_256_XTS; - policy.filenames_encryption_mode = FS_ENCRYPTION_MODE_AES_256_CTS; - policy.flags = FS_POLICY_FLAGS_PAD_16; + policy.contents_encryption_mode = FSCRYPT_MODE_AES_256_XTS; + policy.filenames_encryption_mode = FSCRYPT_MODE_AES_256_CTS; + policy.flags = FSCRYPT_POLICY_FLAGS_PAD_16; /* Parse options */ while ((c = getopt(argc, argv, "c:n:f:v:")) != EOF) { @@ -229,7 +313,7 @@ set_encpolicy_f(int argc, char **argv) unsigned long long x; int i; - if (strlen(keydesc) != FS_KEY_DESCRIPTOR_SIZE * 2) { + if (strlen(keydesc) != FSCRYPT_KEY_DESCRIPTOR_SIZE * 2) { fprintf(stderr, "invalid key descriptor: %s\n", keydesc); return 0; @@ -242,7 +326,7 @@ set_encpolicy_f(int argc, char **argv) return 0; } - for (i = 0; i < FS_KEY_DESCRIPTOR_SIZE; i++) { + for (i = 0; i < FSCRYPT_KEY_DESCRIPTOR_SIZE; i++) { policy.master_key_descriptor[i] = x >> 56; x <<= 8; } From patchwork Sat Sep 28 00:02:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11165349 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CD9B71800 for ; Sat, 28 Sep 2019 00:03:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id AC1C220863 for ; Sat, 28 Sep 2019 00:03:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1569629030; bh=3U5C9V4mtkfRFfuGPXOxRamHWW9N5CsHL6wyIeN+iHY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=Bdsnm+xgzVWv1eEblldwcV7z0KNu3zouPGT0qiawmVY/TcaMZho2oGhXERIwpoYta PPwuxhoiSWHkMyzZ2BIV8isKafWkExV/Ym5YokJ3p3BMyvcXh5DMY379lX2rfpgozQ c3pv0QyUQF5HEybZVrZuInargUv+Y+/GWrGq0SY4= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728321AbfI1ADp (ORCPT ); Fri, 27 Sep 2019 20:03:45 -0400 Received: from mail.kernel.org ([198.145.29.99]:49220 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727899AbfI1ADp (ORCPT ); Fri, 27 Sep 2019 20:03:45 -0400 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id A1883217D9; Sat, 28 Sep 2019 00:03:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1569629024; bh=3U5C9V4mtkfRFfuGPXOxRamHWW9N5CsHL6wyIeN+iHY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ExWdGS14nyGYod4uFoOLCCFVSavxkjQOYcBZl/u+NXgkB/DubphYgbjEmnL24Wuu4 ckaTRBtvy8/u+5Xyx2/pcRAq8X8UNxb1fudLqzFSb3kV6KfLopbrGjrj/m+X+v6RLc yRI4Zee0ph6Oqgvnjq1KDEsKCNdDhJGQndYU5Pgw= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [PATCH v3 3/9] xfs_io/encrypt: generate encryption modes for 'help set_encpolicy' Date: Fri, 27 Sep 2019 17:02:37 -0700 Message-Id: <20190928000243.77634-4-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.444.g18eeb5a265-goog In-Reply-To: <20190928000243.77634-1-ebiggers@kernel.org> References: <20190928000243.77634-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Eric Biggers Print all encryption modes that are defined in the code, rather than hardcoding the modes in the help text. Signed-off-by: Eric Biggers --- io/encrypt.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/io/encrypt.c b/io/encrypt.c index 011a6410..7d3e3b73 100644 --- a/io/encrypt.c +++ b/io/encrypt.c @@ -136,12 +136,22 @@ struct fscrypt_get_key_status_arg { #endif /* !FS_IOC_GET_ENCRYPTION_POLICY_EX */ +static const struct { + __u8 mode; + const char *name; +} available_modes[] = { + {FSCRYPT_MODE_AES_256_XTS, "AES-256-XTS"}, + {FSCRYPT_MODE_AES_256_CTS, "AES-256-CTS"}, +}; + static cmdinfo_t get_encpolicy_cmd; static cmdinfo_t set_encpolicy_cmd; static void set_encpolicy_help(void) { + int i; + printf(_( "\n" " assign an encryption policy to the currently open file\n" @@ -155,8 +165,15 @@ set_encpolicy_help(void) " -f FLAGS -- policy flags\n" " -v VERSION -- version of policy structure\n" "\n" -" MODE can be numeric or one of the following predefined values:\n" -" AES-256-XTS, AES-256-CTS\n" +" MODE can be numeric or one of the following predefined values:\n")); + printf(" "); + for (i = 0; i < ARRAY_SIZE(available_modes); i++) { + printf("%s", available_modes[i].name); + if (i != ARRAY_SIZE(available_modes) - 1) + printf(", "); + } + printf("\n"); + printf(_( " FLAGS and VERSION must be numeric.\n" "\n" " Note that it's only possible to set an encryption policy on an empty\n" @@ -164,14 +181,6 @@ set_encpolicy_help(void) "\n")); } -static const struct { - __u8 mode; - const char *name; -} available_modes[] = { - {FSCRYPT_MODE_AES_256_XTS, "AES-256-XTS"}, - {FSCRYPT_MODE_AES_256_CTS, "AES-256-CTS"}, -}; - static bool parse_byte_value(const char *arg, __u8 *value_ret) { From patchwork Sat Sep 28 00:02:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11165347 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A36B61850 for ; Sat, 28 Sep 2019 00:03:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8172420863 for ; Sat, 28 Sep 2019 00:03:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1569629030; bh=UsogPjngA9eL0uet4QxTG+iA9tjVFy/4skK34PyKJko=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=ySYs7PPAGj46WOZLy8uYRa308roqW/D8rqV/ln/nMJJKdp3z1+fjV437VYf3Kki7O fm0GMSbv5KIxnsD+j/pR/VTwX5fANgM9vKiJHThcE5SClJ5HRmhwpS7qn97SsiBEff OcFAqt6m/jJccHNKh2x8/rJB27Vtx8StHvcwOehM= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727899AbfI1ADq (ORCPT ); Fri, 27 Sep 2019 20:03:46 -0400 Received: from mail.kernel.org ([198.145.29.99]:49222 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728300AbfI1ADp (ORCPT ); Fri, 27 Sep 2019 20:03:45 -0400 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id DE93921841; Sat, 28 Sep 2019 00:03:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1569629025; bh=UsogPjngA9eL0uet4QxTG+iA9tjVFy/4skK34PyKJko=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EO6Mu4DtylVKt8fP91tFYNUrhDJztpbk9RAAswACVF0Ojg0dkStH68+ECwiv7bgCY KuqqNgWxo8Hev5Q0WYcUQ36QLnHh/FPS4sLwJnIZcmj8Fxzkyi60iDmVZw8VUZ9m1h Ev+ZTjbFP5zhZSTI0E6brPkc9Y8R0pbRiN4XYbc8= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [PATCH v3 4/9] xfs_io/encrypt: add new encryption modes Date: Fri, 27 Sep 2019 17:02:38 -0700 Message-Id: <20190928000243.77634-5-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.444.g18eeb5a265-goog In-Reply-To: <20190928000243.77634-1-ebiggers@kernel.org> References: <20190928000243.77634-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Eric Biggers Add new encryption modes: AES-128-CBC and AES-128-CTS (supported since Linux v4.11), and Adiantum (supported since Linux v5.0). Signed-off-by: Eric Biggers --- io/encrypt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/io/encrypt.c b/io/encrypt.c index 7d3e3b73..8a511379 100644 --- a/io/encrypt.c +++ b/io/encrypt.c @@ -142,6 +142,9 @@ static const struct { } available_modes[] = { {FSCRYPT_MODE_AES_256_XTS, "AES-256-XTS"}, {FSCRYPT_MODE_AES_256_CTS, "AES-256-CTS"}, + {FSCRYPT_MODE_AES_128_CBC, "AES-128-CBC"}, + {FSCRYPT_MODE_AES_128_CTS, "AES-128-CTS"}, + {FSCRYPT_MODE_ADIANTUM, "Adiantum"}, }; static cmdinfo_t get_encpolicy_cmd; From patchwork Sat Sep 28 00:02:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11165325 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B4ED01747 for ; Sat, 28 Sep 2019 00:03:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 932BB20869 for ; Sat, 28 Sep 2019 00:03:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1569629028; bh=8iNxlPsbf4UuhwmKyi9pdYljEvO3mRbrRJdEe/YZNmE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=E77EcYGVgUt2ouAMcdSkY2hrkMQOZZbEH0P7Mf25r1TEYVHxcxCImGaNxlGuSMZBW 06jlgxemjXgxtrBEFfW6Cmzb0DGRFDWtGmdP2LrVmKQUN2+Ufp1pAGsrTq15mnxyIG 5o/+2jbkO6FWYnjXR6U26Nkz2cmyia55zzKgHxCQ= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728395AbfI1ADr (ORCPT ); Fri, 27 Sep 2019 20:03:47 -0400 Received: from mail.kernel.org ([198.145.29.99]:49236 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726033AbfI1ADq (ORCPT ); Fri, 27 Sep 2019 20:03:46 -0400 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 282DC20863; Sat, 28 Sep 2019 00:03:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1569629025; bh=8iNxlPsbf4UuhwmKyi9pdYljEvO3mRbrRJdEe/YZNmE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fWGesjI2spOgJiAfdc/YLyq6KaXxSS1oH3a7XmhkovsGCSKRFZ5FhAA2TKMSH2GL1 diblX2c8uKapx5MgI41ROuJa8FfJa8n8eIVLmG/Q58WOzrpZPBQwK3nUIOCdK25nVk wWq6Otat5PbuO09fheB1NO4U8HTAeSG4DDNfiztw= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [PATCH v3 5/9] xfs_io/encrypt: extend 'get_encpolicy' to support v2 policies Date: Fri, 27 Sep 2019 17:02:39 -0700 Message-Id: <20190928000243.77634-6-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.444.g18eeb5a265-goog In-Reply-To: <20190928000243.77634-1-ebiggers@kernel.org> References: <20190928000243.77634-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Eric Biggers get_encpolicy uses the FS_IOC_GET_ENCRYPTION_POLICY ioctl to retrieve the file's encryption policy, then displays it. But that only works for v1 encryption policies. A new ioctl, FS_IOC_GET_ENCRYPTION_POLICY_EX, has been introduced which is more flexible and can retrieve both v1 and v2 encryption policies. Make get_encpolicy use the new ioctl if the kernel supports it and display the resulting the v1 or v2 encryption policy. Otherwise, fall back to the old ioctl and display the v1 policy. Also add new options: -1: Use the old ioctl only. This will be used to test the old ioctl even when the kernel supports the new one. -t: Test whether the new ioctl is supported. This will be useful to determine whether v2 policies should be tested or not. Signed-off-by: Eric Biggers --- io/encrypt.c | 153 ++++++++++++++++++++++++++++++++++++++++------ man/man8/xfs_io.8 | 15 ++++- 2 files changed, 149 insertions(+), 19 deletions(-) diff --git a/io/encrypt.c b/io/encrypt.c index 8a511379..0b45e93f 100644 --- a/io/encrypt.c +++ b/io/encrypt.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2016 Google, Inc. All Rights Reserved. + * Copyright 2016, 2019 Google LLC * Author: Eric Biggers */ @@ -150,6 +150,20 @@ static const struct { static cmdinfo_t get_encpolicy_cmd; static cmdinfo_t set_encpolicy_cmd; +static void +get_encpolicy_help(void) +{ + printf(_( +"\n" +" display the encryption policy of the current file\n" +"\n" +" -1 -- Use only the old ioctl to get the encryption policy.\n" +" This only works if the file has a v1 encryption policy.\n" +" -t -- Test whether v2 encryption policies are supported.\n" +" Prints \"supported\", \"unsupported\", or an error message.\n" +"\n")); +} + static void set_encpolicy_help(void) { @@ -227,7 +241,7 @@ mode2str(__u8 mode) } static const char * -keydesc2str(__u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE]) +keydesc2str(const __u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE]) { static char buf[2 * FSCRYPT_KEY_DESCRIPTOR_SIZE + 1]; int i; @@ -238,29 +252,132 @@ keydesc2str(__u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE]) return buf; } +static const char * +keyid2str(const __u8 master_key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]) +{ + static char buf[2 * FSCRYPT_KEY_IDENTIFIER_SIZE + 1]; + int i; + + for (i = 0; i < FSCRYPT_KEY_IDENTIFIER_SIZE; i++) + sprintf(&buf[2 * i], "%02x", master_key_identifier[i]); + + return buf; +} + +static void +test_for_v2_policy_support(void) +{ + struct fscrypt_get_policy_ex_arg arg; + + arg.policy_size = sizeof(arg.policy); + + if (ioctl(file->fd, FS_IOC_GET_ENCRYPTION_POLICY_EX, &arg) == 0 || + errno == ENODATA /* file unencrypted */) { + printf(_("supported\n")); + return; + } + if (errno == ENOTTY) { + printf(_("unsupported\n")); + return; + } + fprintf(stderr, + _("%s: unexpected error checking for FS_IOC_GET_ENCRYPTION_POLICY_EX support: %s\n"), + file->name, strerror(errno)); + exitcode = 1; +} + +static void +show_v1_encryption_policy(const struct fscrypt_policy_v1 *policy) +{ + printf(_("Encryption policy for %s:\n"), file->name); + printf(_("\tPolicy version: %u\n"), policy->version); + printf(_("\tMaster key descriptor: %s\n"), + keydesc2str(policy->master_key_descriptor)); + printf(_("\tContents encryption mode: %u (%s)\n"), + policy->contents_encryption_mode, + mode2str(policy->contents_encryption_mode)); + printf(_("\tFilenames encryption mode: %u (%s)\n"), + policy->filenames_encryption_mode, + mode2str(policy->filenames_encryption_mode)); + printf(_("\tFlags: 0x%02x\n"), policy->flags); +} + +static void +show_v2_encryption_policy(const struct fscrypt_policy_v2 *policy) +{ + printf(_("Encryption policy for %s:\n"), file->name); + printf(_("\tPolicy version: %u\n"), policy->version); + printf(_("\tMaster key identifier: %s\n"), + keyid2str(policy->master_key_identifier)); + printf(_("\tContents encryption mode: %u (%s)\n"), + policy->contents_encryption_mode, + mode2str(policy->contents_encryption_mode)); + printf(_("\tFilenames encryption mode: %u (%s)\n"), + policy->filenames_encryption_mode, + mode2str(policy->filenames_encryption_mode)); + printf(_("\tFlags: 0x%02x\n"), policy->flags); +} + static int get_encpolicy_f(int argc, char **argv) { - struct fscrypt_policy policy; + int c; + struct fscrypt_get_policy_ex_arg arg; + bool only_use_v1_ioctl = false; + int res; + + while ((c = getopt(argc, argv, "1t")) != EOF) { + switch (c) { + case '1': + only_use_v1_ioctl = true; + break; + case 't': + test_for_v2_policy_support(); + return 0; + default: + return command_usage(&get_encpolicy_cmd); + } + } + argc -= optind; + argv += optind; + + if (argc != 0) + return command_usage(&get_encpolicy_cmd); + + /* first try the new ioctl */ + if (only_use_v1_ioctl) { + res = -1; + errno = ENOTTY; + } else { + arg.policy_size = sizeof(arg.policy); + res = ioctl(file->fd, FS_IOC_GET_ENCRYPTION_POLICY_EX, &arg); + } + + /* fall back to the old ioctl */ + if (res != 0 && errno == ENOTTY) + res = ioctl(file->fd, FS_IOC_GET_ENCRYPTION_POLICY, + &arg.policy.v1); - if (ioctl(file->fd, FS_IOC_GET_ENCRYPTION_POLICY, &policy) < 0) { - fprintf(stderr, "%s: failed to get encryption policy: %s\n", + if (res != 0) { + fprintf(stderr, _("%s: failed to get encryption policy: %s\n"), file->name, strerror(errno)); exitcode = 1; return 0; } - printf("Encryption policy for %s:\n", file->name); - printf("\tPolicy version: %u\n", policy.version); - printf("\tMaster key descriptor: %s\n", - keydesc2str(policy.master_key_descriptor)); - printf("\tContents encryption mode: %u (%s)\n", - policy.contents_encryption_mode, - mode2str(policy.contents_encryption_mode)); - printf("\tFilenames encryption mode: %u (%s)\n", - policy.filenames_encryption_mode, - mode2str(policy.filenames_encryption_mode)); - printf("\tFlags: 0x%02x\n", policy.flags); + switch (arg.policy.version) { + case FSCRYPT_POLICY_V1: + show_v1_encryption_policy(&arg.policy.v1); + break; + case FSCRYPT_POLICY_V2: + show_v2_encryption_policy(&arg.policy.v2); + break; + default: + printf(_("Encryption policy for %s:\n"), file->name); + printf(_("\tPolicy version: %u (unknown)\n"), + arg.policy.version); + break; + } return 0; } @@ -360,11 +477,13 @@ encrypt_init(void) { get_encpolicy_cmd.name = "get_encpolicy"; get_encpolicy_cmd.cfunc = get_encpolicy_f; + get_encpolicy_cmd.args = _("[-1] [-t]"); get_encpolicy_cmd.argmin = 0; - get_encpolicy_cmd.argmax = 0; + get_encpolicy_cmd.argmax = -1; get_encpolicy_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; get_encpolicy_cmd.oneline = _("display the encryption policy of the current file"); + get_encpolicy_cmd.help = get_encpolicy_help; set_encpolicy_cmd.name = "set_encpolicy"; set_encpolicy_cmd.cfunc = set_encpolicy_f; diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8 index 6e064bdd..3dd34a0c 100644 --- a/man/man8/xfs_io.8 +++ b/man/man8/xfs_io.8 @@ -724,10 +724,21 @@ version of policy structure (numeric) .RE .PD .TP -.BR get_encpolicy +.BI "get_encpolicy [ \-1 ] [ \-t ]" On filesystems that support encryption, display the encryption policy of the current file. - +.RS 1.0i +.PD 0 +.TP 0.4i +.BI \-1 +Use only the old ioctl to get the encryption policy. This only works if the +file has a v1 encryption policy. +.TP +.BI \-t +Test whether v2 encryption policies are supported. Prints "supported", +"unsupported", or an error message. +.RE +.PD .TP .BR lsattr " [ " \-R " | " \-D " | " \-a " | " \-v " ]" List extended inode flags on the currently open file. If the From patchwork Sat Sep 28 00:02:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11165339 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E89051800 for ; Sat, 28 Sep 2019 00:03:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C689A20863 for ; Sat, 28 Sep 2019 00:03:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1569629029; bh=G8XX6ARY5KwlfHMwmZ4GkP30VKzaYTEBqzwW5+qLfQs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=Rs/C/OyZdU4IbecyjZVDYkL2GMK3Vin1hlA9DZ+Pnx/LF0XgAGzmT3Wuspi8Mx97N f1u95fmrsdlNoZIjaxVsXHVt836fOJNOlMSCkB1Pmf33bTcMQdb38NRm3W6tTU2vw8 N5lrzNgT8YM1io/FNe1ydQMaiAn/zJnEUx6Iuphg= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728365AbfI1ADq (ORCPT ); Fri, 27 Sep 2019 20:03:46 -0400 Received: from mail.kernel.org ([198.145.29.99]:49222 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728312AbfI1ADq (ORCPT ); Fri, 27 Sep 2019 20:03:46 -0400 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 6CE8521850; Sat, 28 Sep 2019 00:03:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1569629025; bh=G8XX6ARY5KwlfHMwmZ4GkP30VKzaYTEBqzwW5+qLfQs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ltHabBdWP/slBaeOxkMWGjB5dFoIfKMr2gIiVMcWL+QZbZTqNpe+gzreyS/YpTVP8 /dAMhxBkbNc4hYc6mmC6V8yroDCXVe99jPcWc0+VbF3mqr7YrKZr4x3uZzT63F+UaY fAvmvD5vE6D11Fn0mCwUu9KbB/tQTUp1Cy69hF1A= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [PATCH v3 6/9] xfs_io/encrypt: extend 'set_encpolicy' to support v2 policies Date: Fri, 27 Sep 2019 17:02:40 -0700 Message-Id: <20190928000243.77634-7-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.444.g18eeb5a265-goog In-Reply-To: <20190928000243.77634-1-ebiggers@kernel.org> References: <20190928000243.77634-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Eric Biggers Extend the 'set_encpolicy' xfs_io command to support setting v2 encryption policies, in addition to v1 encryption policies which it currently supports. This uses the same ioctl, where the 'version' field at the beginning of the struct is used to determine whether the struct is fscrypt_policy_v1 or fscrypt_policy_v2. The command sets a v2 policy when the user either gave the longer key specification used in such policies (a 16-byte master_key_identifier rather than an 8-byte master_key_descriptor), or passed '-v 2'. Signed-off-by: Eric Biggers --- io/encrypt.c | 236 ++++++++++++++++++++++++++++++++++++---------- man/man8/xfs_io.8 | 19 +++- 2 files changed, 199 insertions(+), 56 deletions(-) diff --git a/io/encrypt.c b/io/encrypt.c index 0b45e93f..603d569b 100644 --- a/io/encrypt.c +++ b/io/encrypt.c @@ -174,13 +174,18 @@ set_encpolicy_help(void) " assign an encryption policy to the currently open file\n" "\n" " Examples:\n" -" 'set_encpolicy' - assign policy with default key [0000000000000000]\n" -" 'set_encpolicy 0000111122223333' - assign policy with specified key\n" +" 'set_encpolicy' - assign v1 policy with default key descriptor\n" +" (0000000000000000)\n" +" 'set_encpolicy -v 2' - assign v2 policy with default key identifier\n" +" (00000000000000000000000000000000)\n" +" 'set_encpolicy 0000111122223333' - assign v1 policy with given key descriptor\n" +" 'set_encpolicy 00001111222233334444555566667777' - assign v2 policy with given\n" +" key identifier\n" "\n" " -c MODE -- contents encryption mode\n" " -n MODE -- filenames encryption mode\n" " -f FLAGS -- policy flags\n" -" -v VERSION -- version of policy structure\n" +" -v VERSION -- policy version\n" "\n" " MODE can be numeric or one of the following predefined values:\n")); printf(" "); @@ -240,6 +245,35 @@ mode2str(__u8 mode) return buf; } +static int +hexchar2bin(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return 10 + (c - 'a'); + if (c >= 'A' && c <= 'F') + return 10 + (c - 'A'); + return -1; +} + +static bool +hex2bin(const char *hex, __u8 *bin, size_t bin_len) +{ + if (strlen(hex) != 2 * bin_len) + return false; + + while (bin_len--) { + int hi = hexchar2bin(*hex++); + int lo = hexchar2bin(*hex++); + + if (hi < 0 || lo < 0) + return false; + *bin++ = (hi << 4) | lo; + } + return true; +} + static const char * keydesc2str(const __u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE]) { @@ -264,6 +298,92 @@ keyid2str(const __u8 master_key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]) return buf; } +static const char * +keyspectype(const struct fscrypt_key_specifier *key_spec) +{ + switch (key_spec->type) { + case FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR: + return _("descriptor"); + case FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER: + return _("identifier"); + } + return _("[unknown]"); +} + +static const char * +keyspec2str(const struct fscrypt_key_specifier *key_spec) +{ + switch (key_spec->type) { + case FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR: + return keydesc2str(key_spec->u.descriptor); + case FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER: + return keyid2str(key_spec->u.identifier); + } + return _("[unknown]"); +} + +static bool +str2keydesc(const char *str, + __u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE]) +{ + if (!hex2bin(str, master_key_descriptor, FSCRYPT_KEY_DESCRIPTOR_SIZE)) { + fprintf(stderr, _("invalid key descriptor: %s\n"), str); + return false; + } + return true; +} + +static bool +str2keyid(const char *str, + __u8 master_key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]) +{ + if (!hex2bin(str, master_key_identifier, FSCRYPT_KEY_IDENTIFIER_SIZE)) { + fprintf(stderr, _("invalid key identifier: %s\n"), str); + return false; + } + return true; +} + +/* + * Parse a key specifier (descriptor or identifier) given as a hex string. + * + * 8 bytes (16 hex chars) == key descriptor == v1 encryption policy. + * 16 bytes (32 hex chars) == key identifier == v2 encryption policy. + * + * If a policy_version is given (>= 0), then the corresponding type of key + * specifier is required. Otherwise the specifier type and policy_version are + * determined based on the length of the given hex string. + * + * Returns the policy version, or -1 on error. + */ +static int +str2keyspec(const char *str, int policy_version, + struct fscrypt_key_specifier *key_spec) +{ + if (policy_version < 0) { /* version unspecified? */ + size_t len = strlen(str); + + if (len == 2 * FSCRYPT_KEY_DESCRIPTOR_SIZE) { + policy_version = FSCRYPT_POLICY_V1; + } else if (len == 2 * FSCRYPT_KEY_IDENTIFIER_SIZE) { + policy_version = FSCRYPT_POLICY_V2; + } else { + fprintf(stderr, _("invalid key specifier: %s\n"), str); + return -1; + } + } + if (policy_version == FSCRYPT_POLICY_V2) { + if (!str2keyid(str, key_spec->u.identifier)) + return -1; + key_spec->type = FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER; + } else { + if (!str2keydesc(str, key_spec->u.descriptor)) + return -1; + key_spec->type = FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR; + } + return policy_version; +} + static void test_for_v2_policy_support(void) { @@ -385,46 +505,56 @@ static int set_encpolicy_f(int argc, char **argv) { int c; - struct fscrypt_policy policy; - - /* Initialize the policy structure with default values */ - memset(&policy, 0, sizeof(policy)); - policy.contents_encryption_mode = FSCRYPT_MODE_AES_256_XTS; - policy.filenames_encryption_mode = FSCRYPT_MODE_AES_256_CTS; - policy.flags = FSCRYPT_POLICY_FLAGS_PAD_16; + __u8 contents_encryption_mode = FSCRYPT_MODE_AES_256_XTS; + __u8 filenames_encryption_mode = FSCRYPT_MODE_AES_256_CTS; + __u8 flags = FSCRYPT_POLICY_FLAGS_PAD_16; + int version = -1; /* unspecified */ + struct fscrypt_key_specifier key_spec; + union { + __u8 version; + struct fscrypt_policy_v1 v1; + struct fscrypt_policy_v2 v2; + } policy; - /* Parse options */ while ((c = getopt(argc, argv, "c:n:f:v:")) != EOF) { switch (c) { case 'c': - if (!parse_mode(optarg, - &policy.contents_encryption_mode)) { - fprintf(stderr, "invalid contents encryption " - "mode: %s\n", optarg); + if (!parse_mode(optarg, &contents_encryption_mode)) { + fprintf(stderr, + _("invalid contents encryption mode: %s\n"), + optarg); return 0; } break; case 'n': - if (!parse_mode(optarg, - &policy.filenames_encryption_mode)) { - fprintf(stderr, "invalid filenames encryption " - "mode: %s\n", optarg); + if (!parse_mode(optarg, &filenames_encryption_mode)) { + fprintf(stderr, + _("invalid filenames encryption mode: %s\n"), + optarg); return 0; } break; case 'f': - if (!parse_byte_value(optarg, &policy.flags)) { - fprintf(stderr, "invalid flags: %s\n", optarg); + if (!parse_byte_value(optarg, &flags)) { + fprintf(stderr, _("invalid flags: %s\n"), + optarg); return 0; } break; - case 'v': - if (!parse_byte_value(optarg, &policy.version)) { - fprintf(stderr, "invalid policy version: %s\n", + case 'v': { + __u8 val; + + if (!parse_byte_value(optarg, &val)) { + fprintf(stderr, + _("invalid policy version: %s\n"), optarg); return 0; } + if (val == 1) /* Just to avoid annoying people... */ + val = FSCRYPT_POLICY_V1; + version = val; break; + } default: return command_usage(&set_encpolicy_cmd); } @@ -435,40 +565,44 @@ set_encpolicy_f(int argc, char **argv) if (argc > 1) return command_usage(&set_encpolicy_cmd); - /* Parse key descriptor if specified */ + /* + * If unspecified, the key descriptor or identifier defaults to all 0's. + * If the policy version is additionally unspecified, it defaults to v1. + */ + memset(&key_spec, 0, sizeof(key_spec)); if (argc > 0) { - const char *keydesc = argv[0]; - char *tmp; - unsigned long long x; - int i; - - if (strlen(keydesc) != FSCRYPT_KEY_DESCRIPTOR_SIZE * 2) { - fprintf(stderr, "invalid key descriptor: %s\n", - keydesc); - return 0; - } - - x = strtoull(keydesc, &tmp, 16); - if (tmp == keydesc || *tmp != '\0') { - fprintf(stderr, "invalid key descriptor: %s\n", - keydesc); + version = str2keyspec(argv[0], version, &key_spec); + if (version < 0) return 0; - } + } + if (version < 0) /* version unspecified? */ + version = FSCRYPT_POLICY_V1; - for (i = 0; i < FSCRYPT_KEY_DESCRIPTOR_SIZE; i++) { - policy.master_key_descriptor[i] = x >> 56; - x <<= 8; - } + memset(&policy, 0, sizeof(policy)); + policy.version = version; + if (version == FSCRYPT_POLICY_V2) { + policy.v2.contents_encryption_mode = contents_encryption_mode; + policy.v2.filenames_encryption_mode = filenames_encryption_mode; + policy.v2.flags = flags; + memcpy(policy.v2.master_key_identifier, key_spec.u.identifier, + FSCRYPT_KEY_IDENTIFIER_SIZE); + } else { + /* + * xfstests passes .version = 255 for testing. Just use + * 'struct fscrypt_policy_v1' for both v1 and unknown versions. + */ + policy.v1.contents_encryption_mode = contents_encryption_mode; + policy.v1.filenames_encryption_mode = filenames_encryption_mode; + policy.v1.flags = flags; + memcpy(policy.v1.master_key_descriptor, key_spec.u.descriptor, + FSCRYPT_KEY_DESCRIPTOR_SIZE); } - /* Set the encryption policy */ - if (ioctl(file->fd, FS_IOC_SET_ENCRYPTION_POLICY, &policy) < 0) { - fprintf(stderr, "%s: failed to set encryption policy: %s\n", + if (ioctl(file->fd, FS_IOC_SET_ENCRYPTION_POLICY, &policy) != 0) { + fprintf(stderr, _("%s: failed to set encryption policy: %s\n"), file->name, strerror(errno)); exitcode = 1; - return 0; } - return 0; } @@ -488,7 +622,7 @@ encrypt_init(void) set_encpolicy_cmd.name = "set_encpolicy"; set_encpolicy_cmd.cfunc = set_encpolicy_f; set_encpolicy_cmd.args = - _("[-c mode] [-n mode] [-f flags] [-v version] [keydesc]"); + _("[-c mode] [-n mode] [-f flags] [-v version] [keyspec]"); set_encpolicy_cmd.argmin = 0; set_encpolicy_cmd.argmax = -1; set_encpolicy_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8 index 3dd34a0c..18fcde0f 100644 --- a/man/man8/xfs_io.8 +++ b/man/man8/xfs_io.8 @@ -701,12 +701,17 @@ Swaps extent forks between files. The current open file is the target. The donor file is specified by path. Note that file data is not copied (file content moves with the fork(s)). .TP -.BI "set_encpolicy [ \-c " mode " ] [ \-n " mode " ] [ \-f " flags " ] [ \-v " version " ] [ " keydesc " ]" +.BI "set_encpolicy [ \-c " mode " ] [ \-n " mode " ] [ \-f " flags " ] [ \-v " version " ] [ " keyspec " ]" On filesystems that support encryption, assign an encryption policy to the current file. -.I keydesc -is a 16-byte hex string which identifies the encryption key to use. -If not specified, a "default" key descriptor of all 0's will be used. +.I keyspec +is a hex string which specifies the encryption key to use. For v1 encryption +policies, +.I keyspec +must be a 16-character hex string (8 bytes). For v2 policies, +.I keyspec +must be a 32-character hex string (16 bytes). If unspecified, an all-zeroes +value is used. .RS 1.0i .PD 0 .TP 0.4i @@ -720,7 +725,11 @@ filenames encryption mode (e.g. AES-256-CTS) policy flags (numeric) .TP .BI \-v " version" -version of policy structure (numeric) +policy version. Defaults to 1 or 2 depending on the length of +.IR keyspec ; +or to 1 if +.I keyspec +is unspecified. .RE .PD .TP From patchwork Sat Sep 28 00:02:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11165337 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BDFF81850 for ; Sat, 28 Sep 2019 00:03:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9CC1920863 for ; Sat, 28 Sep 2019 00:03:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1569629029; bh=31Ae/oI0gSi0gW1iJlsrC6JwW8faLTmhoVq1OHp8LY8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=0vBgCZbkhpofBwKYF/roLdJ7ZSL0YVax2vDx94fUKWpYsnDLhRSPUg8TZM4zEtd06 tf3RIIhAhsGPBvgZS9yBjbdo86WrjcQtTgkOA1EqK/EHHyLN+X7KEwu6bX3K7WnTU4 q8P/ZsBES/m6+1AHV94az3QcviQar6O+kdTFCTOc= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728312AbfI1ADr (ORCPT ); Fri, 27 Sep 2019 20:03:47 -0400 Received: from mail.kernel.org ([198.145.29.99]:49276 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728336AbfI1ADq (ORCPT ); Fri, 27 Sep 2019 20:03:46 -0400 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id AC90721841; Sat, 28 Sep 2019 00:03:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1569629025; bh=31Ae/oI0gSi0gW1iJlsrC6JwW8faLTmhoVq1OHp8LY8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=zO1MImGov5CVpck/+6nOn13TxERNPSyNbV6deQQ7JcxJJ+y8gmCVkN8Oai75BS9AB qA68SZ7m+sEl2dGTTrwnYlMyUocKpGnOjvo4iYEdL4NoQPcHeTmrWSZjuE2VM+ofL6 sT7iDIIiHTlLRXK1fdn23EMwqBwfogk5PpfHhb/4= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [PATCH v3 7/9] xfs_io/encrypt: add 'add_enckey' command Date: Fri, 27 Sep 2019 17:02:41 -0700 Message-Id: <20190928000243.77634-8-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.444.g18eeb5a265-goog In-Reply-To: <20190928000243.77634-1-ebiggers@kernel.org> References: <20190928000243.77634-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Eric Biggers Add an 'add_enckey' command to xfs_io, to provide a command-line interface to the FS_IOC_ADD_ENCRYPTION_KEY ioctl. Signed-off-by: Eric Biggers --- io/encrypt.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++ man/man8/xfs_io.8 | 15 +++++++ 2 files changed, 124 insertions(+) diff --git a/io/encrypt.c b/io/encrypt.c index 603d569b..056f15bc 100644 --- a/io/encrypt.c +++ b/io/encrypt.c @@ -149,6 +149,7 @@ static const struct { static cmdinfo_t get_encpolicy_cmd; static cmdinfo_t set_encpolicy_cmd; +static cmdinfo_t add_enckey_cmd; static void get_encpolicy_help(void) @@ -203,6 +204,22 @@ set_encpolicy_help(void) "\n")); } +static void +add_enckey_help(void) +{ + printf(_( +"\n" +" add an encryption key to the filesystem\n" +"\n" +" Examples:\n" +" 'add_enckey' - add key for v2 policies\n" +" 'add_enckey -d 0000111122223333' - add key for v1 policies w/ given descriptor\n" +"\n" +"The key in binary is read from standard input.\n" +" -d DESCRIPTOR -- master_key_descriptor\n" +"\n")); +} + static bool parse_byte_value(const char *arg, __u8 *value_ret) { @@ -606,6 +623,88 @@ set_encpolicy_f(int argc, char **argv) return 0; } +static ssize_t +read_until_limit_or_eof(int fd, void *buf, size_t limit) +{ + size_t bytes_read = 0; + ssize_t res; + + while (limit) { + res = read(fd, buf, limit); + if (res < 0) + return res; + if (res == 0) + break; + buf += res; + bytes_read += res; + limit -= res; + } + return bytes_read; +} + +static int +add_enckey_f(int argc, char **argv) +{ + int c; + struct fscrypt_add_key_arg *arg; + ssize_t raw_size; + + arg = calloc(1, sizeof(*arg) + FSCRYPT_MAX_KEY_SIZE + 1); + if (!arg) { + perror("calloc"); + exitcode = 1; + return 0; + } + + arg->key_spec.type = FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER; + + while ((c = getopt(argc, argv, "d:")) != EOF) { + switch (c) { + case 'd': + arg->key_spec.type = FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR; + if (!str2keydesc(optarg, arg->key_spec.u.descriptor)) + goto out; + break; + default: + return command_usage(&add_enckey_cmd); + } + } + argc -= optind; + argv += optind; + + if (argc != 0) + return command_usage(&add_enckey_cmd); + + raw_size = read_until_limit_or_eof(STDIN_FILENO, arg->raw, + FSCRYPT_MAX_KEY_SIZE + 1); + if (raw_size < 0) { + fprintf(stderr, _("Error reading key from stdin: %s\n"), + strerror(errno)); + exitcode = 1; + goto out; + } + if (raw_size > FSCRYPT_MAX_KEY_SIZE) { + fprintf(stderr, + _("Invalid key; got > FSCRYPT_MAX_KEY_SIZE (%d) bytes on stdin!\n"), + FSCRYPT_MAX_KEY_SIZE); + goto out; + } + arg->raw_size = raw_size; + + if (ioctl(file->fd, FS_IOC_ADD_ENCRYPTION_KEY, arg) != 0) { + fprintf(stderr, _("Error adding encryption key: %s\n"), + strerror(errno)); + exitcode = 1; + goto out; + } + printf(_("Added encryption key with %s %s\n"), + keyspectype(&arg->key_spec), keyspec2str(&arg->key_spec)); +out: + memset(arg->raw, 0, FSCRYPT_MAX_KEY_SIZE + 1); + free(arg); + return 0; +} + void encrypt_init(void) { @@ -630,6 +729,16 @@ encrypt_init(void) _("assign an encryption policy to the current file"); set_encpolicy_cmd.help = set_encpolicy_help; + add_enckey_cmd.name = "add_enckey"; + add_enckey_cmd.cfunc = add_enckey_f; + add_enckey_cmd.args = _("[-d descriptor]"); + add_enckey_cmd.argmin = 0; + add_enckey_cmd.argmax = -1; + add_enckey_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; + add_enckey_cmd.oneline = _("add an encryption key to the filesystem"); + add_enckey_cmd.help = add_enckey_help; + add_command(&get_encpolicy_cmd); add_command(&set_encpolicy_cmd); + add_command(&add_enckey_cmd); } diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8 index 18fcde0f..7d6a23fe 100644 --- a/man/man8/xfs_io.8 +++ b/man/man8/xfs_io.8 @@ -749,6 +749,21 @@ Test whether v2 encryption policies are supported. Prints "supported", .RE .PD .TP +.BI "add_enckey [ \-d " descriptor " ]" +On filesystems that support encryption, add an encryption key to the filesystem +containing the currently open file. The key in binary (typically 64 bytes long) +is read from standard input. +.RS 1.0i +.PD 0 +.TP 0.4i +.BI \-d " descriptor" +key descriptor, as a 16-character hex string (8 bytes). If given, the key will +be available for use by v1 encryption policies that use this descriptor. +Otherwise, the key is added as a v2 policy key, and on success the resulting +"key identifier" will be printed. +.RE +.PD +.TP .BR lsattr " [ " \-R " | " \-D " | " \-a " | " \-v " ]" List extended inode flags on the currently open file. If the .B \-R From patchwork Sat Sep 28 00:02:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11165341 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 22EE917EE for ; Sat, 28 Sep 2019 00:03:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id F110B20863 for ; Sat, 28 Sep 2019 00:03:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1569629030; bh=4yFgMLLRzDQhAwfYsQJ8UPEpfn2f0UZeBSDxuI1YCg0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=QS4HzCwkjWZZIfDDY5t/uxwkl1y7VvAu0ks4Y8p+ISkE9rs569KUaWmXrFs20EL4E VBvL7dny8wrrI/sThEbX7NA/31c/Rp0H0bdxdUz0j5iMEW6dYLB9JC/dQBXcUU1FIi DFWH6nH6KTQvZESeEs+gYs1Ydhg+3gQ5xpO96dLo= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726762AbfI1ADt (ORCPT ); Fri, 27 Sep 2019 20:03:49 -0400 Received: from mail.kernel.org ([198.145.29.99]:49290 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728346AbfI1ADr (ORCPT ); Fri, 27 Sep 2019 20:03:47 -0400 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id EA387217D9; Sat, 28 Sep 2019 00:03:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1569629026; bh=4yFgMLLRzDQhAwfYsQJ8UPEpfn2f0UZeBSDxuI1YCg0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=j4fT24M9xMfaEPM2yflav6ShwoNyt6r7y7J25uYfdE4YaPvgu7GgWeaBixTHmoUvd ISwrv4tQPhGvCx8/fAWDjS6UEdwAYt+dnWFh0mPFzKbcs3oopc78PM6wPuA7sXrMRz bfHj9z7z3z8jOjlyXxD5Kb0x5xIB9UqAIWi+nLy4= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [PATCH v3 8/9] xfs_io/encrypt: add 'rm_enckey' command Date: Fri, 27 Sep 2019 17:02:42 -0700 Message-Id: <20190928000243.77634-9-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.444.g18eeb5a265-goog In-Reply-To: <20190928000243.77634-1-ebiggers@kernel.org> References: <20190928000243.77634-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Eric Biggers Add a 'rm_enckey' command to xfs_io, to provide a command-line interface to the FS_IOC_REMOVE_ENCRYPTION_KEY and FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS ioctls. Signed-off-by: Eric Biggers --- io/encrypt.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++ man/man8/xfs_io.8 | 15 ++++++++++ 2 files changed, 90 insertions(+) diff --git a/io/encrypt.c b/io/encrypt.c index 056f15bc..e87ac393 100644 --- a/io/encrypt.c +++ b/io/encrypt.c @@ -150,6 +150,7 @@ static const struct { static cmdinfo_t get_encpolicy_cmd; static cmdinfo_t set_encpolicy_cmd; static cmdinfo_t add_enckey_cmd; +static cmdinfo_t rm_enckey_cmd; static void get_encpolicy_help(void) @@ -220,6 +221,21 @@ add_enckey_help(void) "\n")); } +static void +rm_enckey_help(void) +{ + printf(_( +"\n" +" remove an encryption key from the filesystem\n" +"\n" +" Examples:\n" +" 'rm_enckey 0000111122223333' - remove key for v1 policies w/ given descriptor\n" +" 'rm_enckey 00001111222233334444555566667777' - remove key for v2 policies w/ given identifier\n" +"\n" +" -a -- remove key for all users who have added it (privileged operation)\n" +"\n")); +} + static bool parse_byte_value(const char *arg, __u8 *value_ret) { @@ -705,6 +721,54 @@ out: return 0; } +static int +rm_enckey_f(int argc, char **argv) +{ + int c; + struct fscrypt_remove_key_arg arg; + int ioc = FS_IOC_REMOVE_ENCRYPTION_KEY; + + memset(&arg, 0, sizeof(arg)); + + while ((c = getopt(argc, argv, "a")) != EOF) { + switch (c) { + case 'a': + ioc = FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS; + break; + default: + return command_usage(&rm_enckey_cmd); + } + } + argc -= optind; + argv += optind; + + if (argc != 1) + return command_usage(&rm_enckey_cmd); + + if (str2keyspec(argv[0], -1, &arg.key_spec) < 0) + return 0; + + if (ioctl(file->fd, ioc, &arg) != 0) { + fprintf(stderr, _("Error removing encryption key: %s\n"), + strerror(errno)); + exitcode = 1; + return 0; + } + if (arg.removal_status_flags & + FSCRYPT_KEY_REMOVAL_STATUS_FLAG_OTHER_USERS) { + printf(_("Removed user's claim to encryption key with %s %s\n"), + keyspectype(&arg.key_spec), keyspec2str(&arg.key_spec)); + } else if (arg.removal_status_flags & + FSCRYPT_KEY_REMOVAL_STATUS_FLAG_FILES_BUSY) { + printf(_("Removed encryption key with %s %s, but files still busy\n"), + keyspectype(&arg.key_spec), keyspec2str(&arg.key_spec)); + } else { + printf(_("Removed encryption key with %s %s\n"), + keyspectype(&arg.key_spec), keyspec2str(&arg.key_spec)); + } + return 0; +} + void encrypt_init(void) { @@ -738,7 +802,18 @@ encrypt_init(void) add_enckey_cmd.oneline = _("add an encryption key to the filesystem"); add_enckey_cmd.help = add_enckey_help; + rm_enckey_cmd.name = "rm_enckey"; + rm_enckey_cmd.cfunc = rm_enckey_f; + rm_enckey_cmd.args = _("[-a] keyspec"); + rm_enckey_cmd.argmin = 0; + rm_enckey_cmd.argmax = -1; + rm_enckey_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; + rm_enckey_cmd.oneline = + _("remove an encryption key from the filesystem"); + rm_enckey_cmd.help = rm_enckey_help; + add_command(&get_encpolicy_cmd); add_command(&set_encpolicy_cmd); add_command(&add_enckey_cmd); + add_command(&rm_enckey_cmd); } diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8 index 7d6a23fe..be90905a 100644 --- a/man/man8/xfs_io.8 +++ b/man/man8/xfs_io.8 @@ -764,6 +764,21 @@ Otherwise, the key is added as a v2 policy key, and on success the resulting .RE .PD .TP +.BI "rm_enckey [ -a ] " keyspec +On filesystems that support encryption, remove an encryption key from the +filesystem containing the currently open file. +.I keyspec +is a hex string specifying the key to remove, as a 16-character "key descriptor" +or a 32-character "key identifier". +.RS 1.0i +.PD 0 +.TP 0.4i +.BI \-a +Remove the key for all users who have added it, not just the current user. This +is a privileged operation. +.RE +.PD +.TP .BR lsattr " [ " \-R " | " \-D " | " \-a " | " \-v " ]" List extended inode flags on the currently open file. If the .B \-R From patchwork Sat Sep 28 00:02:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11165331 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3F81718B7 for ; Sat, 28 Sep 2019 00:03:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1E42620863 for ; Sat, 28 Sep 2019 00:03:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1569629029; bh=iQiiSRk5um6idrEBv8xJVv/EmadTk5icRiI2l/5qtO0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=fOJjjhYwVBP3c0HABUB5dNLpDbkuHvB15NrM+Zav67+3W/F56F7wm8fU/qfgTiT1P Ph/sx6z+4MhNswRRvsSuvdST5LKIbbjwjxXhJ7bDki6Mf5r7WDXXwciX5H6bI7BXI0 GBzLQPc/4dqeomZVnjDennxN+sgTlf9hOno6Xduo= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726033AbfI1ADs (ORCPT ); Fri, 27 Sep 2019 20:03:48 -0400 Received: from mail.kernel.org ([198.145.29.99]:49304 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726762AbfI1ADr (ORCPT ); Fri, 27 Sep 2019 20:03:47 -0400 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 33EC420869; Sat, 28 Sep 2019 00:03:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1569629026; bh=iQiiSRk5um6idrEBv8xJVv/EmadTk5icRiI2l/5qtO0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OCbvBn1pT7bEst5rgfJDLiqH1ONMeETM9Y5518d74JNKTYue6T8vJ5xLXxzCkn4zA t27+hUh/h0tM3JfNLi4+EKmeeT9sEJUcZmJWSAdUQfEmUtUTAtXx7JSvjKeHibc8pF okVFP1dh2k26Q5bugysotaap3W4eQTVQhUn18vcI= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [PATCH v3 9/9] xfs_io/encrypt: add 'enckey_status' command Date: Fri, 27 Sep 2019 17:02:43 -0700 Message-Id: <20190928000243.77634-10-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.444.g18eeb5a265-goog In-Reply-To: <20190928000243.77634-1-ebiggers@kernel.org> References: <20190928000243.77634-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org From: Eric Biggers Add an 'enckey_status' command to xfs_io, to provide a command-line interface to the FS_IOC_GET_ENCRYPTION_KEY_STATUS ioctl. Signed-off-by: Eric Biggers --- io/encrypt.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++ man/man8/xfs_io.8 | 6 ++++ 2 files changed, 77 insertions(+) diff --git a/io/encrypt.c b/io/encrypt.c index e87ac393..17d61cfb 100644 --- a/io/encrypt.c +++ b/io/encrypt.c @@ -151,6 +151,7 @@ static cmdinfo_t get_encpolicy_cmd; static cmdinfo_t set_encpolicy_cmd; static cmdinfo_t add_enckey_cmd; static cmdinfo_t rm_enckey_cmd; +static cmdinfo_t enckey_status_cmd; static void get_encpolicy_help(void) @@ -236,6 +237,19 @@ rm_enckey_help(void) "\n")); } +static void +enckey_status_help(void) +{ + printf(_( +"\n" +" get the status of a filesystem encryption key\n" +"\n" +" Examples:\n" +" 'enckey_status 0000111122223333' - get status of v1 policy key\n" +" 'enckey_status 00001111222233334444555566667777' - get status of v2 policy key\n" +"\n")); +} + static bool parse_byte_value(const char *arg, __u8 *value_ret) { @@ -769,6 +783,52 @@ rm_enckey_f(int argc, char **argv) return 0; } +static int +enckey_status_f(int argc, char **argv) +{ + struct fscrypt_get_key_status_arg arg; + + memset(&arg, 0, sizeof(arg)); + + if (str2keyspec(argv[1], -1, &arg.key_spec) < 0) + return 0; + + if (ioctl(file->fd, FS_IOC_GET_ENCRYPTION_KEY_STATUS, &arg) != 0) { + fprintf(stderr, _("Error getting encryption key status: %s\n"), + strerror(errno)); + exitcode = 1; + return 0; + } + + switch (arg.status) { + case FSCRYPT_KEY_STATUS_PRESENT: + printf(_("Present")); + if (arg.user_count || arg.status_flags) { + printf(" (user_count=%u", arg.user_count); + if (arg.status_flags & + FSCRYPT_KEY_STATUS_FLAG_ADDED_BY_SELF) + printf(", added_by_self"); + arg.status_flags &= + ~FSCRYPT_KEY_STATUS_FLAG_ADDED_BY_SELF; + if (arg.status_flags) + printf(", unknown_flags=0x%08x", + arg.status_flags); + printf(")"); + } + printf("\n"); + return 0; + case FSCRYPT_KEY_STATUS_ABSENT: + printf(_("Absent\n")); + return 0; + case FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED: + printf(_("Incompletely removed\n")); + return 0; + default: + printf(_("Unknown status (%u)\n"), arg.status); + return 0; + } +} + void encrypt_init(void) { @@ -812,8 +872,19 @@ encrypt_init(void) _("remove an encryption key from the filesystem"); rm_enckey_cmd.help = rm_enckey_help; + enckey_status_cmd.name = "enckey_status"; + enckey_status_cmd.cfunc = enckey_status_f; + enckey_status_cmd.args = _("keyspec"); + enckey_status_cmd.argmin = 1; + enckey_status_cmd.argmax = 1; + enckey_status_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; + enckey_status_cmd.oneline = + _("get the status of a filesystem encryption key"); + enckey_status_cmd.help = enckey_status_help; + add_command(&get_encpolicy_cmd); add_command(&set_encpolicy_cmd); add_command(&add_enckey_cmd); add_command(&rm_enckey_cmd); + add_command(&enckey_status_cmd); } diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8 index be90905a..2db071e9 100644 --- a/man/man8/xfs_io.8 +++ b/man/man8/xfs_io.8 @@ -779,6 +779,12 @@ is a privileged operation. .RE .PD .TP +.BI "enckey_status " keyspec +On filesystems that support encryption, display the status of an encryption key. +.I keyspec +is a hex string specifying the key for which to display the status, as a +16-character "key descriptor" or a 32-character "key identifier". +.TP .BR lsattr " [ " \-R " | " \-D " | " \-a " | " \-v " ]" List extended inode flags on the currently open file. If the .B \-R