From patchwork Mon Aug 12 17:56:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11090339 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 96FC0184E for ; Mon, 12 Aug 2019 17:57:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 89D0728541 for ; Mon, 12 Aug 2019 17:57:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7E9142855C; Mon, 12 Aug 2019 17:57:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 297FC28541 for ; Mon, 12 Aug 2019 17:57:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726835AbfHLR5P (ORCPT ); Mon, 12 Aug 2019 13:57:15 -0400 Received: from mail.kernel.org ([198.145.29.99]:53486 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726424AbfHLR5P (ORCPT ); Mon, 12 Aug 2019 13:57:15 -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 CE78C206C2; Mon, 12 Aug 2019 17:57:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1565632633; bh=VnVK7IcJS4ndc+hgxpNrZS63vpaG3tfeZ5Om1UeZ63o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=0moHkGY1gIf0j4X0xerJmasJNtvIYTpirICNTBIzbIyEAxVwICJAd4Ps6M8S6iS/y hF4iOmDtcP4KH48bqLcYHtqTyLILbnuKXrha8JsrmpFdeZFiGcLo3L7zzm+24d2Igc fHROgfL8pk4vNboDJnXclWTJ7huWR+EiHSzJuI1w= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [RFC PATCH 1/8] xfs_io/encrypt: remove unimplemented encryption modes Date: Mon, 12 Aug 2019 10:56:27 -0700 Message-Id: <20190812175635.34186-2-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.rc1.153.gdeed80330f-goog In-Reply-To: <20190812175635.34186-1-ebiggers@kernel.org> References: <20190812175635.34186-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: fstests-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: fstests@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 8db35259..e8766dc1 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 Mon Aug 12 17:56:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11090367 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7288C1864 for ; Mon, 12 Aug 2019 17:57:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 62F352856F for ; Mon, 12 Aug 2019 17:57:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 50F7B2855C; Mon, 12 Aug 2019 17:57:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BD9442856F for ; Mon, 12 Aug 2019 17:57:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726859AbfHLR5Q (ORCPT ); Mon, 12 Aug 2019 13:57:16 -0400 Received: from mail.kernel.org ([198.145.29.99]:53488 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726497AbfHLR5Q (ORCPT ); Mon, 12 Aug 2019 13:57:16 -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 180DD2075B; Mon, 12 Aug 2019 17:57:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1565632634; bh=Q4ldZqJhDcqMdzBcCtfF3VNQ9TSIT/jJ5pshtq8rjFk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DnZi6tyZyNB0yt3vHwq0kYEN1kKhZxotmT3LgldlCz4w6XcmkevwtnzR9GqvhyJrZ Um30GyK67ERFfjzduIoW2bZvz0XP3lITdym9JeepUNv2ONLjvIFGu2PBjzAzsE/43a pQ/znkLU+ia5FiOAa2Z9Xoz5mvnA9WMHo5MiuV3Q= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [RFC PATCH 2/8] xfs_io/encrypt: update to UAPI definitions from Linux v5.4 Date: Mon, 12 Aug 2019 10:56:28 -0700 Message-Id: <20190812175635.34186-3-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.rc1.153.gdeed80330f-goog In-Reply-To: <20190812175635.34186-1-ebiggers@kernel.org> References: <20190812175635.34186-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: fstests-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: fstests@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 e8766dc1..ac473ed7 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 Mon Aug 12 17:56:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11090343 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D47311395 for ; Mon, 12 Aug 2019 17:57:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C52C42855C for ; Mon, 12 Aug 2019 17:57:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B980F28564; Mon, 12 Aug 2019 17:57:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7346E28567 for ; Mon, 12 Aug 2019 17:57:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726842AbfHLR5Q (ORCPT ); Mon, 12 Aug 2019 13:57:16 -0400 Received: from mail.kernel.org ([198.145.29.99]:53490 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726551AbfHLR5P (ORCPT ); Mon, 12 Aug 2019 13:57:15 -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 5578320842; Mon, 12 Aug 2019 17:57:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1565632634; bh=vsCEhR6Yea5ciaelGsZTFgcWllOw6bWfgsk3zHX6fEk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RCe6WFyL7H+wMnNtECERo8PidBkduw5N9bZo1q9zDobsL08k7Rs9rB5bWyaaxRhuC AjrzFbYaNauQN4Dqi+dhHYknJQ9NJAEMX0WZoOhDFTHvPD1ylVHLRlZ2NGc9IOg3Zf Hv7+qxo1Rtvn2UAQqdHj5Jfn0y1p8KXEhXv5C7t8= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [RFC PATCH 3/8] xfs_io/encrypt: add new encryption modes Date: Mon, 12 Aug 2019 10:56:29 -0700 Message-Id: <20190812175635.34186-4-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.rc1.153.gdeed80330f-goog In-Reply-To: <20190812175635.34186-1-ebiggers@kernel.org> References: <20190812175635.34186-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: fstests-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: fstests@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/io/encrypt.c b/io/encrypt.c index ac473ed7..11eb4a3e 100644 --- a/io/encrypt.c +++ b/io/encrypt.c @@ -156,7 +156,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\n" +" AES-256-XTS, AES-256-CTS, AES-128-CBC, AES-128-CTS, Adiantum\n" " FLAGS and VERSION must be numeric.\n" "\n" " Note that it's only possible to set an encryption policy on an empty\n" @@ -170,6 +170,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 bool From patchwork Mon Aug 12 17:56:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11090383 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6077B1395 for ; Mon, 12 Aug 2019 17:57:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 553D328541 for ; Mon, 12 Aug 2019 17:57:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 49DE22855C; Mon, 12 Aug 2019 17:57:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AF78228563 for ; Mon, 12 Aug 2019 17:57:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726424AbfHLR5T (ORCPT ); Mon, 12 Aug 2019 13:57:19 -0400 Received: from mail.kernel.org ([198.145.29.99]:53492 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726811AbfHLR5P (ORCPT ); Mon, 12 Aug 2019 13:57:15 -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 934972085A; Mon, 12 Aug 2019 17:57:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1565632634; bh=aNKMGKHvMimoTL5bdrwJTA4vdFi4Qd4yC7CtgJ7JiSM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fkk33+z6Scco3s5kjVj06vlYY35LW/2KS9PMjLj0+ZBICJ+LYUJ4tRPNCljBmqTjm k+R1RWSApV56z/ieAGx2dRWySPgDpIwJsOACEK5fx/jyfVpPTAvJAlIbFWVWwzCmaY LTqLLXZTbeOhh8gwEY+ySG6UQu9tkpqoAn1XBk4s= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [RFC PATCH 4/8] xfs_io/encrypt: extend 'get_encpolicy' to support v2 policies Date: Mon, 12 Aug 2019 10:56:30 -0700 Message-Id: <20190812175635.34186-5-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.rc1.153.gdeed80330f-goog In-Reply-To: <20190812175635.34186-1-ebiggers@kernel.org> References: <20190812175635.34186-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: fstests-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: fstests@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 | 150 +++++++++++++++++++++++++++++++++++++++++----- man/man8/xfs_io.8 | 15 ++++- 2 files changed, 147 insertions(+), 18 deletions(-) diff --git a/io/encrypt.c b/io/encrypt.c index 11eb4a3e..5b92cfae 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 */ @@ -139,6 +139,20 @@ struct fscrypt_get_key_status_arg { 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) { @@ -218,7 +232,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; @@ -229,29 +243,131 @@ 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; - if (ioctl(file->fd, FS_IOC_GET_ENCRYPTION_POLICY, &policy) < 0) { + 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 (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; } @@ -351,11 +467,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 Mon Aug 12 17:56:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11090353 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 95EBB184E for ; Mon, 12 Aug 2019 17:57:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8729E2855C for ; Mon, 12 Aug 2019 17:57:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 77ABF2856F; Mon, 12 Aug 2019 17:57:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8DD242856B for ; Mon, 12 Aug 2019 17:57:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726877AbfHLR5R (ORCPT ); Mon, 12 Aug 2019 13:57:17 -0400 Received: from mail.kernel.org ([198.145.29.99]:53494 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726219AbfHLR5Q (ORCPT ); Mon, 12 Aug 2019 13:57:16 -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 D7A0C208C2; Mon, 12 Aug 2019 17:57:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1565632635; bh=oH9KlgKFDqc8kCsonilIgiq7lHkfAjMLijL+1MmNtWo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oy6biDKs+QvnwqjpLZzta8SnfvTCIFtLYsF5IROjbaFltrGcOzxqXtqNHSRncnayw coKdGSMCTQMlyPKKzeMFOqy/wKytyO3zmt2aPg8+L414lPxAKUeuHVRPg4ZqCPqa1f iM8NWGvUMxX/l8rh0FpV2+oTYi3fiWErEH98Ppcg= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [RFC PATCH 5/8] xfs_io/encrypt: extend 'set_encpolicy' to support v2 policies Date: Mon, 12 Aug 2019 10:56:31 -0700 Message-Id: <20190812175635.34186-6-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.rc1.153.gdeed80330f-goog In-Reply-To: <20190812175635.34186-1-ebiggers@kernel.org> References: <20190812175635.34186-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: fstests-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: fstests@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 | 228 ++++++++++++++++++++++++++++++++++++---------- man/man8/xfs_io.8 | 19 +++- 2 files changed, 194 insertions(+), 53 deletions(-) diff --git a/io/encrypt.c b/io/encrypt.c index 5b92cfae..f982cd17 100644 --- a/io/encrypt.c +++ b/io/encrypt.c @@ -161,13 +161,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" " AES-256-XTS, AES-256-CTS, AES-128-CBC, AES-128-CTS, Adiantum\n" @@ -231,6 +236,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]) { @@ -255,6 +289,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) { @@ -375,46 +495,54 @@ 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)) { + 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)) { + 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); } @@ -425,40 +553,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); + version = str2keyspec(argv[0], version, &key_spec); + if (version < 0) return 0; - } - - x = strtoull(keydesc, &tmp, 16); - if (tmp == keydesc || *tmp != '\0') { - fprintf(stderr, "invalid key descriptor: %s\n", - keydesc); - 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) { + 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; } @@ -478,7 +610,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 Mon Aug 12 17:56:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11090369 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8751E1395 for ; Mon, 12 Aug 2019 17:57:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7C5772855C for ; Mon, 12 Aug 2019 17:57:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 70D5828563; Mon, 12 Aug 2019 17:57:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 06F3128564 for ; Mon, 12 Aug 2019 17:57:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726843AbfHLR5Q (ORCPT ); Mon, 12 Aug 2019 13:57:16 -0400 Received: from mail.kernel.org ([198.145.29.99]:53500 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726838AbfHLR5P (ORCPT ); Mon, 12 Aug 2019 13:57:15 -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 20DA820663; Mon, 12 Aug 2019 17:57:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1565632635; bh=E/mEA6VYjpNAcWlUtsN+wmRnoN7g8zucA+Eeqh+Mf9g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dUWJusQlxMr8M24FxYuxDoX+Q4UVYsbGR2ALLHsDhXfCtmfm+v6pMgvy9qhT77oNp vcLeUlGTjJP//p9qCLRw72VPEO/d6HNQjOoZbf3ZLtBsp86HYf1MSCaZ0WzI/bHNMN bSXvY27PpWcyIeIH8X//CyHvrA7WTNaPaG0PCExg= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [RFC PATCH 6/8] xfs_io/encrypt: add 'add_enckey' command Date: Mon, 12 Aug 2019 10:56:32 -0700 Message-Id: <20190812175635.34186-7-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.rc1.153.gdeed80330f-goog In-Reply-To: <20190812175635.34186-1-ebiggers@kernel.org> References: <20190812175635.34186-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: fstests-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: fstests@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 f982cd17..038c4cce 100644 --- a/io/encrypt.c +++ b/io/encrypt.c @@ -138,6 +138,7 @@ struct fscrypt_get_key_status_arg { static cmdinfo_t get_encpolicy_cmd; static cmdinfo_t set_encpolicy_cmd; +static cmdinfo_t add_enckey_cmd; static void get_encpolicy_help(void) @@ -183,6 +184,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 const struct { __u8 mode; const char *name; @@ -594,6 +611,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) { + fprintf(stderr, "calloc failed\n"); + 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) { @@ -618,6 +717,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 Mon Aug 12 17:56:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11090357 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 123FB13AC for ; Mon, 12 Aug 2019 17:57:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0553028574 for ; Mon, 12 Aug 2019 17:57:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EE1562856B; Mon, 12 Aug 2019 17:57:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4D24C28567 for ; Mon, 12 Aug 2019 17:57:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726872AbfHLR5Q (ORCPT ); Mon, 12 Aug 2019 13:57:16 -0400 Received: from mail.kernel.org ([198.145.29.99]:53510 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726839AbfHLR5Q (ORCPT ); Mon, 12 Aug 2019 13:57:16 -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 5E85A214C6; Mon, 12 Aug 2019 17:57:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1565632635; bh=0fFeTCkHHz7+HM4rgMp50Skdeei22QOwH1bnrl1K+9A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=X6nwjjWYIiX28uEhnUwcSXQGmPd5nyo0RhV+xn9Sd/8L9WLwCsXqSqJmysPOM2oyA sGUCH7FhAngsXHJStjLz8zAqlXNLLTUGQtep1Zi6+AW5NnVX8ZSPdv6unWMIUj5vkg JoKzQmTsMRF1u0Ey01WJBZDcra1uRXhDwqlvRC1c= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [RFC PATCH 7/8] xfs_io/encrypt: add 'rm_enckey' command Date: Mon, 12 Aug 2019 10:56:33 -0700 Message-Id: <20190812175635.34186-8-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.rc1.153.gdeed80330f-goog In-Reply-To: <20190812175635.34186-1-ebiggers@kernel.org> References: <20190812175635.34186-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: fstests-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: fstests@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 038c4cce..213c9c53 100644 --- a/io/encrypt.c +++ b/io/encrypt.c @@ -139,6 +139,7 @@ struct fscrypt_get_key_status_arg { 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) @@ -200,6 +201,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 const struct { __u8 mode; const char *name; @@ -693,6 +709,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) { @@ -726,7 +790,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 = _("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..a6894778 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 " 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 Mon Aug 12 17:56:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11090351 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 75AA31395 for ; Mon, 12 Aug 2019 17:57:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6724B2855C for ; Mon, 12 Aug 2019 17:57:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5B45628581; Mon, 12 Aug 2019 17:57:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B8E212855C for ; Mon, 12 Aug 2019 17:57:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726881AbfHLR5R (ORCPT ); Mon, 12 Aug 2019 13:57:17 -0400 Received: from mail.kernel.org ([198.145.29.99]:53518 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726424AbfHLR5Q (ORCPT ); Mon, 12 Aug 2019 13:57:16 -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 9BDEC2173B; Mon, 12 Aug 2019 17:57:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1565632635; bh=XDR5nEPqIxvlwTE29rWAMyZx2mM15AvRPof1zupibW4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CXvJske7w6ZGCxdAFUqW0Ga/+HEW85ti2wHxjSvfHNzeItCcTTbj/YcxX5621KHpO t9oma6R1Gicqcfe8h6OrenNX3Lj5XJfsGHYYZ+dXFY6b+pnfMV2bETID07z+6A1aN1 9IPwSEF0qg7IwkB5Z12gE703EFb0kS1i8ePvyn88= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [RFC PATCH 8/8] xfs_io/encrypt: add 'enckey_status' command Date: Mon, 12 Aug 2019 10:56:34 -0700 Message-Id: <20190812175635.34186-9-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.rc1.153.gdeed80330f-goog In-Reply-To: <20190812175635.34186-1-ebiggers@kernel.org> References: <20190812175635.34186-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: fstests-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: fstests@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 213c9c53..19c74983 100644 --- a/io/encrypt.c +++ b/io/encrypt.c @@ -140,6 +140,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) @@ -216,6 +217,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 const struct { __u8 mode; const char *name; @@ -757,6 +771,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) { @@ -800,8 +860,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 a6894778..9af6e542 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