From patchwork Fri Sep 20 00:18:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11153597 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 4135B197C for ; Fri, 20 Sep 2019 00:20:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 16038217D6 for ; Fri, 20 Sep 2019 00:20:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1568938815; bh=07GkLK5+IzP0sCKfynkWiJ1o48r/r4rDz3uaqTzV+vs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=VD0jbPUIF7UDBijtji37LiQLHwtl7j4YA4z1CVsDIrWUEkUfcbP1822BFYk70iHV0 eUYaMPXhQgm2GQdGNeVCrmBo2FHUKsE55fkKQNJg18AWPr1BlBUH6/hVeKAufm/P+Z j3NggAVz8hRDX8Oqml6xEZANLZ1Rzu9TuJnttJ6c= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392424AbfITAUH (ORCPT ); Thu, 19 Sep 2019 20:20:07 -0400 Received: from mail.kernel.org ([198.145.29.99]:35302 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390558AbfITAUH (ORCPT ); Thu, 19 Sep 2019 20:20:07 -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 9800921907; Fri, 20 Sep 2019 00:20:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1568938802; bh=07GkLK5+IzP0sCKfynkWiJ1o48r/r4rDz3uaqTzV+vs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WubDGV1GjF8/5WBKw2vHcHq/VK5+VME5QLiIA9yOuXgVCk1bHaAFI3Hz/dIOkMMsY WX0suGJwMWYtSU1zOg/yDLjYcv+axFaft/q1yWY0MEsJZdub43gk2weipPuKU72gUW vGK16aU6UK+8lmU/F8B8rop3cxQRL7OT82GmRz1I= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [PATCH v2 1/8] xfs_io/encrypt: remove unimplemented encryption modes Date: Thu, 19 Sep 2019 17:18:15 -0700 Message-Id: <20190920001822.257411-2-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.351.gc4317032e6-goog In-Reply-To: <20190920001822.257411-1-ebiggers@kernel.org> References: <20190920001822.257411-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 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 Fri Sep 20 00:18:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11153609 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 830D676 for ; Fri, 20 Sep 2019 00:20:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6204F21929 for ; Fri, 20 Sep 2019 00:20:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1568938816; bh=R68sT6tk1TVFXsGkPVy06H8fXd6AE99jtDW31Nx5pLg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=EPlCviXfnd2mES0RiNx3Ja+LXqCXKom3DRjSRJht5y5k4K3NF4wHWDt8vd0J/zzJW yvzg+AdUHc8H/Y9aYSVGhE/tt+kAoO2yoOKmbdt60SIUoJQMigouQGQWeJVjIVUyLF 5lQ9eKy7Y1Pn7v4klKqMrQOxrEbzdq9JHGJMcKfA= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2393803AbfITAUI (ORCPT ); Thu, 19 Sep 2019 20:20:08 -0400 Received: from mail.kernel.org ([198.145.29.99]:35304 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391390AbfITAUI (ORCPT ); Thu, 19 Sep 2019 20:20:08 -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 D4F7121920; Fri, 20 Sep 2019 00:20:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1568938803; bh=R68sT6tk1TVFXsGkPVy06H8fXd6AE99jtDW31Nx5pLg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=M0A/DXPLfXdqYEcW4/ctvwfVxhkDgTTtlHGR1v5Sv8hOoIkB2xD++KoqaGuXa0g4r BRCfZ+olrda+UgUruoa1h/wLsvnEPVfHcBnj5jp6Svvqn/AafgmY+/rGcPtV6Ppm3/ h1f6gbGsTUO/Y71EanM+JCCCyhN0rMFdf7ULmQzI= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [PATCH v2 2/8] xfs_io/encrypt: update to UAPI definitions from Linux v5.4 Date: Thu, 19 Sep 2019 17:18:16 -0700 Message-Id: <20190920001822.257411-3-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.351.gc4317032e6-goog In-Reply-To: <20190920001822.257411-1-ebiggers@kernel.org> References: <20190920001822.257411-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 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 Fri Sep 20 00:18:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11153603 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 DE49A3AC5 for ; Fri, 20 Sep 2019 00:20:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B405821920 for ; Fri, 20 Sep 2019 00:20:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1568938815; bh=/iBbWJUHXXeizMoV7RFiy8dyUlcRnueuVF6qOxMeDNg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=PLUsSJ5FgAHKXSz0a2pMNSxdSzg6lmhLCyhxHIo73mWYa7Hu9h39eG0OaroQFzROV vqyVoeNQwYKc5nrM0ZISztscXzHNsiRVvxzNR88rjKxxjkIkwz9INUC4Emag0Kf6Q1 TEUNUmbvMy8ayN0czSnRgpRynZC8+tc/s6VSUPZ4= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2393192AbfITAUI (ORCPT ); Thu, 19 Sep 2019 20:20:08 -0400 Received: from mail.kernel.org ([198.145.29.99]:35306 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391401AbfITAUH (ORCPT ); Thu, 19 Sep 2019 20:20:07 -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 217CE21924; Fri, 20 Sep 2019 00:20:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1568938803; bh=/iBbWJUHXXeizMoV7RFiy8dyUlcRnueuVF6qOxMeDNg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QkThbXT2O3BgCUSff5nGiS8tOEyB2rkMb/PREifE3naegUKA2pybrCBZ5cZXV9VfI iny1r9JKnrlhUOPsVkHLJx4fOngPpGtEuFcC/hkW5yhI7kvKxN2BP6BnchaLR2NyKp qWtWUXtmdFhMwP7j4uoDnI2G9xpOaRR90qEHj89E= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [PATCH v2 3/8] xfs_io/encrypt: add new encryption modes Date: Thu, 19 Sep 2019 17:18:17 -0700 Message-Id: <20190920001822.257411-4-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.351.gc4317032e6-goog In-Reply-To: <20190920001822.257411-1-ebiggers@kernel.org> References: <20190920001822.257411-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 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 011a6410..f5046e5b 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 Fri Sep 20 00:18:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11153613 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 D9ACD197C for ; Fri, 20 Sep 2019 00:20:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B84DC21920 for ; Fri, 20 Sep 2019 00:20:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1568938816; bh=CK7mg5Js52t3O0qxmlvDRO/FTd4SxmqfrYdmh70yRyU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=sMLEKTxwDwh6XV0AaYpZABBa0/xImlfqL+LEHlwKHKJuU1L+tJT256B0hI2bTidsi jdrg1R9B1r5TAGHr7EhI1AnVKoj+52WfL3j76NyynKnbS+h4zwW+Df+TDrFcgtTBlY vFw0kIytAirImT7L16tAIk0BCOTz93UKFWT3vrCw= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2393855AbfITAUJ (ORCPT ); Thu, 19 Sep 2019 20:20:09 -0400 Received: from mail.kernel.org ([198.145.29.99]:35308 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391427AbfITAUI (ORCPT ); Thu, 19 Sep 2019 20:20:08 -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 5EEFA21928; Fri, 20 Sep 2019 00:20:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1568938803; bh=CK7mg5Js52t3O0qxmlvDRO/FTd4SxmqfrYdmh70yRyU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MzNTsy+A4tKdbFSyvfSgxQEUj5PGiTmLPxMhw1l/Ks1kXwNtjtwIv9oxIMYd4LNZV Seo4N/fQFLU2+YkSaUutIBU0dtbQxGDA+FSuzvoEw7Ax35PYqPSbz21xJWPDMRDnO/ FeE6X6cIvuvCFCEi28tBKzg1dzBhkUFHjzyCHgZE= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [PATCH v2 4/8] xfs_io/encrypt: extend 'get_encpolicy' to support v2 policies Date: Thu, 19 Sep 2019 17:18:18 -0700 Message-Id: <20190920001822.257411-5-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.351.gc4317032e6-goog In-Reply-To: <20190920001822.257411-1-ebiggers@kernel.org> References: <20190920001822.257411-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 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 f5046e5b..b8141d96 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 Fri Sep 20 00:18:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11153619 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 659D376 for ; Fri, 20 Sep 2019 00:20:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 447F321907 for ; Fri, 20 Sep 2019 00:20:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1568938817; bh=EDoX5X0VnxlCU2C2iKFyV03s2mnsId+jxd+0JaLoSd0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=krQhjraH87SSjn0waA8wYJrFkOqxY9lx6tmzFCenVDc6LFlmy6auMHZNjOWJAp6jl 1HEHJz9OkPr4ky4ijtYc3dQaGrrcV3KFj8/i8nSisYHjKuCDlUhdcYyXNrZoJP5u4P 6OJmMvd35fd0/zl50qggxoL1zG0QpfWaUNwzbVgs= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2394375AbfITAUL (ORCPT ); Thu, 19 Sep 2019 20:20:11 -0400 Received: from mail.kernel.org ([198.145.29.99]:35314 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2393915AbfITAUK (ORCPT ); Thu, 19 Sep 2019 20:20:10 -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 A274321929; Fri, 20 Sep 2019 00:20:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1568938803; bh=EDoX5X0VnxlCU2C2iKFyV03s2mnsId+jxd+0JaLoSd0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=1mPleOeCqYY6UOqzfQG3vXQEsaMWCy1Bo0w36/77K3bLSeBFzmSNQL5QcuEpwnoUd a/KzGyMChvpVNs/GI4t68hD/7bXqS6/Ji2vhffyPF+OZmjOlgJ1wHBOYrtFLXOsPp8 fMgKa/aJIGNvsngI+dKTRgEeBeJU0YVhTxmzKYEI= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [PATCH v2 5/8] xfs_io/encrypt: extend 'set_encpolicy' to support v2 policies Date: Thu, 19 Sep 2019 17:18:19 -0700 Message-Id: <20190920001822.257411-6-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.351.gc4317032e6-goog In-Reply-To: <20190920001822.257411-1-ebiggers@kernel.org> References: <20190920001822.257411-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 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 b8141d96..7d061c51 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 Fri Sep 20 00:18:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11153629 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 522E5195A for ; Fri, 20 Sep 2019 00:20:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 31304217D6 for ; Fri, 20 Sep 2019 00:20:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1568938818; bh=f+B/RSp3cHGDYSRj0llx5Zvc9oiIdBeOdX+KbI0CfEU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=N6gNpyNDWIXFv6yMZwQ+mhUyGhli5Bh8h3Qr27tPXcFLSG9A7f4IIZOgLmrZjp0Pz eECMjw++3IBi2SSwx1XHgq5LnCzXGMksyLloas67oMYC4m8g625NRpcibyYcKOpyac dcOZn5zs4BYOJgchwTt3uXUmIo6sF8rPUa0anJQE= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2394378AbfITAUL (ORCPT ); Thu, 19 Sep 2019 20:20:11 -0400 Received: from mail.kernel.org ([198.145.29.99]:35316 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391427AbfITAUL (ORCPT ); Thu, 19 Sep 2019 20:20:11 -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 DF0F62196E; Fri, 20 Sep 2019 00:20:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1568938804; bh=f+B/RSp3cHGDYSRj0llx5Zvc9oiIdBeOdX+KbI0CfEU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AyH8FhtoEjbXd0xfKORt45SGfnNTlsyfcMhgmh5jHBWuH0H+GK2rG/pciVy8tJMov cyIGWV8si3SgbDRiI8He3NRMmR5bXTqYpg7+/uTv1uFBqO/awyMu4JBA2CPi+AH8yu SIhHZKMWnM+H/EVKqJ7IlFXXClQrIgAUFgduSCdo= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [PATCH v2 6/8] xfs_io/encrypt: add 'add_enckey' command Date: Thu, 19 Sep 2019 17:18:20 -0700 Message-Id: <20190920001822.257411-7-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.351.gc4317032e6-goog In-Reply-To: <20190920001822.257411-1-ebiggers@kernel.org> References: <20190920001822.257411-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 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 7d061c51..d38ac595 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 Fri Sep 20 00:18:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11153637 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 0F29F4324 for ; Fri, 20 Sep 2019 00:20:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E214B217D6 for ; Fri, 20 Sep 2019 00:20:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1568938819; bh=uuc5Lpa0q72dvtswU5pNjoe7wiK15UNZgLSeWPXs2HM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=w/Xv7wL1PIMzKPK07E0IkmDfCIjYO0533QTLlcHECU5UVJCZid5dl5qmY4zNrroxI uT6sUhtBlM938A6X34NZ9kU4RfcgcrGiyJ3/6Nb4XhGR2NGOl1jxewvGF/h6ijDEVY LoUTOoQE3u6blo7ZLLfQe/k8Nzl854iOtOHhVui8= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2394383AbfITAUN (ORCPT ); Thu, 19 Sep 2019 20:20:13 -0400 Received: from mail.kernel.org ([198.145.29.99]:35314 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391427AbfITAUM (ORCPT ); Thu, 19 Sep 2019 20:20:12 -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 27DA12196F; Fri, 20 Sep 2019 00:20:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1568938804; bh=uuc5Lpa0q72dvtswU5pNjoe7wiK15UNZgLSeWPXs2HM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=D1ZQPB8SktK2kepzT/MxWF6BI7jz5bTGdBoyf8qk4BpnkAOCf2im3qBBCPVqgi7+t Yu+Al/A4SPhbShIzCpmcJALqQagcPXHa8o4PzsNUpwqROyE+PVhVJ1uKzWTaYF2uoR DVhl4g2cXiGOWjlZ2FCetjNPKvM1Ab6xSb+9lLC4= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [PATCH v2 7/8] xfs_io/encrypt: add 'rm_enckey' command Date: Thu, 19 Sep 2019 17:18:21 -0700 Message-Id: <20190920001822.257411-8-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.351.gc4317032e6-goog In-Reply-To: <20190920001822.257411-1-ebiggers@kernel.org> References: <20190920001822.257411-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 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 d38ac595..7531c4ad 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 Fri Sep 20 00:18:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 11153633 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 AD46C76 for ; Fri, 20 Sep 2019 00:20:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8920B217D6 for ; Fri, 20 Sep 2019 00:20:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1568938818; bh=15s3hwrzkVFeRRfqhw+wOdxUkp/3LCHzjvI+wPq9t9s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=tOAqCRVuzi4iOEBd1mf4xOd7XmeIvo6nFmRPWSDHoQJLoPoixMOYBGokblImr0vY0 wjuQPqcaKOFvOS+eOFQBpMkuT7/Rtjh6keitx5skbeJmirDdoeX1Lwz2Eur+5nE3WX ad8fUlxKEc3M7gPEcisqAzAOwtmG0LDR2CCl9kRo= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2394381AbfITAUM (ORCPT ); Thu, 19 Sep 2019 20:20:12 -0400 Received: from mail.kernel.org ([198.145.29.99]:35316 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2394379AbfITAUM (ORCPT ); Thu, 19 Sep 2019 20:20:12 -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 659CC21A49; Fri, 20 Sep 2019 00:20:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1568938804; bh=15s3hwrzkVFeRRfqhw+wOdxUkp/3LCHzjvI+wPq9t9s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=f9Nl/Eq1fOFtro0/3Flp487IHI1XPL38+AWEwOcGlLpUYiB0sKu2vOi6wdlAstlY3 edPjRG5/vjqY4lf1edQAwWOtwOIrbDf8M4IeYvntK3MjPoFds5GbQPhQMYZrQ6gayg A2kj4hHQ97TDsuB4BjVDY5yaGSsLWenMwgIMgMmg= From: Eric Biggers To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [PATCH v2 8/8] xfs_io/encrypt: add 'enckey_status' command Date: Thu, 19 Sep 2019 17:18:22 -0700 Message-Id: <20190920001822.257411-9-ebiggers@kernel.org> X-Mailer: git-send-email 2.23.0.351.gc4317032e6-goog In-Reply-To: <20190920001822.257411-1-ebiggers@kernel.org> References: <20190920001822.257411-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 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 7531c4ad..426040e9 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