From patchwork Mon Oct 23 21:40:48 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 10023229 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id DC41F603D7 for ; Mon, 23 Oct 2017 21:43:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CE13F28921 for ; Mon, 23 Oct 2017 21:43:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C320228938; Mon, 23 Oct 2017 21:43:58 +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=-6.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM 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 5AC4C28921 for ; Mon, 23 Oct 2017 21:43:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932343AbdJWVnz (ORCPT ); Mon, 23 Oct 2017 17:43:55 -0400 Received: from mail-io0-f193.google.com ([209.85.223.193]:48684 "EHLO mail-io0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932184AbdJWVma (ORCPT ); Mon, 23 Oct 2017 17:42:30 -0400 Received: by mail-io0-f193.google.com with SMTP id j17so21704486iod.5; Mon, 23 Oct 2017 14:42:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=OMXcS9y24ubcseOc+pBdDRqhoky0kt8ih38nCA8A/Gs=; b=arrW1K/ldyXztDfm70pKJJSgrCA71CdpqQaaWlmoCHb5qCqNmKGz/YYmoa/YWuP8qh laxUBenf2OnBG0+pOVVzGSP+Mr8QMu/OARUO10Jp+dZJLDIfJgop63Adbud7Es5tPg1s y87hPn35jsQG7wA4paKhqIPiVHOB7txpYZMlRHKmbsW9E2WAvmlq/wpvI3UdUVaJuqBe 0w8WGCH2Qc+QDyzRX8f6plS/vMC3C2dCsbL7VdB5RRR8srN+kPQnArZrEfgoMCKqfvsv 2sEqRqk3EJBfkqfI4Xj0loNbmoZ4xMowiX8Q3YXMaSyZ5etkxeoFD4B5xKpgZGGcwxX4 /7gg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=OMXcS9y24ubcseOc+pBdDRqhoky0kt8ih38nCA8A/Gs=; b=ONmWhqcH/YQeilcfsDwtxDplC3qYdUDgZSvlsRhVWupVPTeWlyEvaw789ohOOj5Zqi xPH6le+XH3prg8UtMKtrWFjoOxuacVKbW+s6G/gei7D9G04zr71U9Wz5p/XCy7guwQHd 3h0FXnGWCnG79Zi8YUoUsp46X4XvOnNHqjy0AvJm5NUa1sFIT11aPHgfWzWq+X7VOC59 oX5lIjcfYaCQtprG+GCRhypC8TfP8/1cZds3gcWt0QAYrzyALGRLjgUW/+lHo/U42EEh A/4ytytL/Y0waeWDYXQEvjkdI7JfL6b1tU3FMt5LPK2Is3eDpG4t7rWq25amP3JCwJLE XQ/w== X-Gm-Message-State: AMCzsaWY1zhNM+P/wil0VViefNBwAnrjeNOzAUU1tN0U5EK59ZG8KkO8 5KF882eqdQW5zoReBEEZYK8OYZTS X-Google-Smtp-Source: ABhQp+R/Ok11T+Ua/PLXztktVTW9ixZgtGZE67fAfGplStsc7eZQXQ2dBQck6whUs7AvUc6IamYpNQ== X-Received: by 10.107.169.34 with SMTP id s34mr10247939ioe.103.1508794949256; Mon, 23 Oct 2017 14:42:29 -0700 (PDT) Received: from ebiggers-linuxstation.kir.corp.google.com ([100.66.175.88]) by smtp.gmail.com with ESMTPSA id i63sm3558482ioi.68.2017.10.23.14.42.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 23 Oct 2017 14:42:28 -0700 (PDT) From: Eric Biggers To: linux-fscrypt@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-mtd@lists.infradead.org, linux-api@vger.kernel.org, keyrings@vger.kernel.org, "Theodore Y . Ts'o" , Jaegeuk Kim , Gwendal Grignou , Ryo Hashimoto , Sarthak Kukreti , Nick Desaulniers , Michael Halcrow , Eric Biggers Subject: [RFC PATCH 15/25] fscrypt: add UAPI definitions to get/set v2 encryption policies Date: Mon, 23 Oct 2017 14:40:48 -0700 Message-Id: <20171023214058.128121-16-ebiggers3@gmail.com> X-Mailer: git-send-email 2.15.0.rc0.271.g36b669edcc-goog In-Reply-To: <20171023214058.128121-1-ebiggers3@gmail.com> References: <20171023214058.128121-1-ebiggers3@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Eric Biggers Currently, fscrypt policies and xattrs identify the master key by master_key_descriptor, which is an arbitrary 8-byte value used to form the description of the keyring key. However, there is no verification that the key descriptor in any way corresponds with the key payload. Since ->i_crypt_info by necessity gets set up on a "first come, first serve" basis, this flaw allows a process with only read-only access to an encrypted file or directory to provide the wrong key, causing the file contents or directory listing to be corrupted. This is a bug with security implications which must be fixed. To fix this bug without simply locking down adding keys to root, we must replace master_key_descriptor with a cryptographic hash of the key. We name the replacement master_key_identifier and make it 16 bytes long, which should provide enough collision resistance, and more importantly preimage resistance, without bloating the size of the encryption xattr too much. This will be both an on-disk format and API change, since we'll need to define new versions of both the fscrypt_context and fscrypt_policy. This patch begins this process by defining the UAPI changes to manage v2 policies. (Note: we jump to version 2 even though the previous policy version number was 0 because the fscrypt_context was actually already using version 1, not version 0. It would be really confusing to have them always be 1 off from each other.) The existing FS_IOC_SET_ENCRYPTION_POLICY will be used to set a v2 policy, as the kernel will be able to examine the 'version' field. However, a new ioctl FS_IOC_GET_ENCRYPTION_POLICY_EX is needed to get a v2 policy, since the returned struct needs to be larger. This ioctl includes a size field as input, so that it can be used for both v1 and v2 policies as well as any new policy versions that may get added in the future. Signed-off-by: Eric Biggers --- include/uapi/linux/fscrypt.h | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/fscrypt.h b/include/uapi/linux/fscrypt.h index 9da153df238a..065060b20a34 100644 --- a/include/uapi/linux/fscrypt.h +++ b/include/uapi/linux/fscrypt.h @@ -7,7 +7,6 @@ * File system encryption support */ /* Policy provided via an ioctl on the topmost directory */ -#define FSCRYPT_KEY_DESCRIPTOR_SIZE 8 /* Encryption policy flags */ #define FSCRYPT_POLICY_FLAGS_PAD_4 0x00 @@ -26,13 +25,22 @@ #define FSCRYPT_MODE_AES_128_CBC 5 #define FSCRYPT_MODE_AES_128_CTS 6 -struct fscrypt_policy { +/* + * Legacy policy version; no key verification (potentially insecure). + * For new encrypted directories, use fscrypt_policy_v2 instead. + * + * Careful: the .version field for this is actually 0, not 1. + */ +#define FSCRYPT_POLICY_VERSION_LEGACY 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]; }; +#define fscrypt_policy fscrypt_policy_v1 /* * Process-subscribed "logon" key description prefix and payload format. @@ -47,6 +55,30 @@ struct fscrypt_key { __u32 size; }; +/* + * New policy version with HKDF and key verification (recommended). + */ +#define FSCRYPT_POLICY_VERSION_2 2 +#define FSCRYPT_KEY_IDENTIFIER_SIZE 16 +struct fscrypt_policy_v2 { + __u8 version; + __u8 contents_encryption_mode; + __u8 filenames_encryption_mode; + __u8 flags; + __u8 reserved[4]; + __u8 master_key_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]; +}; + +/* Struct passed to FS_IOC_GET_ENCRYPTION_POLICY_EX */ +struct fscrypt_get_policy_ex_args { + __u64 size; /* input/output */ + union { + __u8 version; + struct fscrypt_policy_v1 v1; + struct fscrypt_policy_v2 v2; + } policy; /* output */ +}; + struct fscrypt_key_specifier { __u32 type; #define FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR 1 @@ -91,6 +123,7 @@ struct fscrypt_get_key_status_args { #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) +#define FS_IOC_GET_ENCRYPTION_POLICY_EX _IOWR('f', 21, __u8[9]) /* size + version */ #define FS_IOC_ADD_ENCRYPTION_KEY _IOWR('f', 22, struct fscrypt_add_key_args) #define FS_IOC_REMOVE_ENCRYPTION_KEY _IOR( 'f', 23, struct fscrypt_remove_key_args) #define FS_IOC_GET_ENCRYPTION_KEY_STATUS _IOWR('f',24, struct fscrypt_get_key_status_args)