Received: by 2002:ac0:da4c:0:0:0:0:0 with SMTP id a12csp1792377imi; Sat, 23 Jul 2022 18:25:54 -0700 (PDT) X-Google-Smtp-Source: AGRyM1uYMjA2dNpnXWV/l6ESL0xS0JEgck6OrlxwQUOffXuXPDr+wirXzYojelGxC4I+wPi7L7QS X-Received: by 2002:a17:907:7fa9:b0:72f:36fd:ef89 with SMTP id qk41-20020a1709077fa900b0072f36fdef89mr5030140ejc.433.1658625954182; Sat, 23 Jul 2022 18:25:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1658625954; cv=none; d=google.com; s=arc-20160816; b=fBUNUfR11+pIAMBHyhy4txcIEW5s8jCK7TBqtDmGfhVfqwsQPE6XU2/GSNEylULyB7 O3z5PZwP3AcmDOxJaSxw57PC3pWJIWTBL//FTm3CFBL2IPVxALuG9nAqKKJahmURNQlT ynz3SPWw1M3jQKILe1Ch/y5uDFcAp8ykZUsxqQv1/v8dylRSgjlfgrBqxzh7JZ+2M2IH nYhE64h3jbF92BKJ/QG25p+4huB2F/v2mgYuGODsFGSdWRZ3rmlj2e5Jql/jYgQz+9lN 6vlejRpZpVu4vJMPSvGuK7Ri/UqbHOmvkZ8qx0vfPxZdBMbTjMJSz0cdxCX8AXMp+B4a FaoQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=OfnmA3xpObXpkQlrKAM8orW1w9mk4EwR/fHb7XpN8xo=; b=d7DdeIies2B2tfOzQq+4jkCuNtng9Tme59i9sas0CAIOz+l4s5ft5HZ25fwY6tWwcW Iy6t2waDICtvKamDQPSRUNmEgjVF2oePQ7HVxPWV7k4xWzYwLDSdPQMMOeLOQsh6S0q/ W8/v0R3oDdBexHms8PdTpBtvArWzafIHdQ091Ri37p+R6lb16GoTGPALObFBlHlWlpnK pacOgpuwdJIfvQ8Vbrk+Fgdl0BsSuEBvHG5esDx78vcXCSd6rTWTIDTIb+2vbGpMQsBq O26nVmEPbXwcWRpz7L3tQi8WCfA/9WWG/KZyU6U6QBuJCRmhqOjgmfgaiiSj2vWCEEem 4VXw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (bad format) header.i=@dorminy.me header.s=mail header.b=a0j67J4y; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=dorminy.me Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id m14-20020a056402510e00b0043bbc9402b5si10756849edd.604.2022.07.23.18.25.29; Sat, 23 Jul 2022 18:25:54 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=neutral (bad format) header.i=@dorminy.me header.s=mail header.b=a0j67J4y; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=dorminy.me Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238971AbiGXAwq (ORCPT + 99 others); Sat, 23 Jul 2022 20:52:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36666 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238762AbiGXAwm (ORCPT ); Sat, 23 Jul 2022 20:52:42 -0400 Received: from box.fidei.email (box.fidei.email [71.19.144.250]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 978E715808 for ; Sat, 23 Jul 2022 17:52:41 -0700 (PDT) Received: from authenticated-user (box.fidei.email [71.19.144.250]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by box.fidei.email (Postfix) with ESMTPSA id 41581807A4; Sat, 23 Jul 2022 20:52:39 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=dorminy.me; s=mail; t=1658623959; bh=/Auu+zShTeWj9DHWTD51820t+/RDBXtbtl/1inaJ2Ww=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=a0j67J4yxKtoJgpKntURGLLLsWbClFmeYbISVmZfeNFBg69QmCXwpqkyyESntaWt6 fVU0/JqSZTB/PsJ7NIOJOkUQgoNAD/jj3l7W/ccXdNufA60HpH9x1Adit+qGm5IWBZ ZIn/6oZnfqLHXfOUzgs+qez4a2yBmS/CroCaf29zn+6DMoPh3TPf/wlyMYce+f2l1X plJCGRLSfrZtIx+q4sCpoGkksOYKAsLMGgNrgKjJyd2aGhGc46h44aFufKxV/Plfld kYnLZu0ebxjyUm54dEB2iogRp7NQrQGL2c201DTMyB56j9dUmRy6dICk/JdoxrJykP Zsq1f4WlKeT7A== From: Sweet Tea Dorminy To: "Theodore Y . Ts'o " , Jaegeuk Kim , Eric Biggers , linux-fscrypt@vger.kernel.org, linux-kernel@vger.kernel.org, linux-btrfs@vger.kernel.org, osandov@osandov.com, kernel-team@fb.com Cc: Sweet Tea Dorminy Subject: [PATCH RFC 1/4] fscrypt: expose fscrypt_nokey_name Date: Sat, 23 Jul 2022 20:52:25 -0400 Message-Id: <1b3a23e209144d95794f77ecfa1362a5683cc4b6.1658623235.git.sweettea-kernel@dorminy.me> In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,SPF_HELO_PASS,SPF_PASS autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Omar Sandoval Btrfs stores its data structures, including filenames in directories, in its own buffer implementation, struct extent_buffer, composed of several non-contiguous pages. We could copy filenames into a temporary buffer and use fscrypt_match_name() against that buffer, such extensive memcpying would be expensive. Instead, exposing fscrypt_nokey_name as in this change allows btrfs to recapitulate fscrypt_match_name() using methods on struct extent_buffer instead of dealing with a raw byte array. Signed-off-by: Omar Sandoval Signed-off-by: Sweet Tea Dorminy --- fs/crypto/fname.c | 39 +-------------------------------------- include/linux/fscrypt.h | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c index 14e0ef5e9a20..5d5c26d827fd 100644 --- a/fs/crypto/fname.c +++ b/fs/crypto/fname.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include "fscrypt_private.h" @@ -26,43 +25,7 @@ #define FSCRYPT_FNAME_MIN_MSG_LEN 16 /* - * struct fscrypt_nokey_name - identifier for directory entry when key is absent - * - * When userspace lists an encrypted directory without access to the key, the - * filesystem must present a unique "no-key name" for each filename that allows - * it to find the directory entry again if requested. Naively, that would just - * mean using the ciphertext filenames. However, since the ciphertext filenames - * can contain illegal characters ('\0' and '/'), they must be encoded in some - * way. We use base64url. But that can cause names to exceed NAME_MAX (255 - * bytes), so we also need to use a strong hash to abbreviate long names. - * - * The filesystem may also need another kind of hash, the "dirhash", to quickly - * find the directory entry. Since filesystems normally compute the dirhash - * over the on-disk filename (i.e. the ciphertext), it's not computable from - * no-key names that abbreviate the ciphertext using the strong hash to fit in - * NAME_MAX. It's also not computable if it's a keyed hash taken over the - * plaintext (but it may still be available in the on-disk directory entry); - * casefolded directories use this type of dirhash. At least in these cases, - * each no-key name must include the name's dirhash too. - * - * To meet all these requirements, we base64url-encode the following - * variable-length structure. It contains the dirhash, or 0's if the filesystem - * didn't provide one; up to 149 bytes of the ciphertext name; and for - * ciphertexts longer than 149 bytes, also the SHA-256 of the remaining bytes. - * - * This ensures that each no-key name contains everything needed to find the - * directory entry again, contains only legal characters, doesn't exceed - * NAME_MAX, is unambiguous unless there's a SHA-256 collision, and that we only - * take the performance hit of SHA-256 on very long filenames (which are rare). - */ -struct fscrypt_nokey_name { - u32 dirhash[2]; - u8 bytes[149]; - u8 sha256[SHA256_DIGEST_SIZE]; -}; /* 189 bytes => 252 bytes base64url-encoded, which is <= NAME_MAX (255) */ - -/* - * Decoded size of max-size no-key name, i.e. a name that was abbreviated using + * Decoded size of max-size nokey name, i.e. a name that was abbreviated using * the strong hash and thus includes the 'sha256' field. This isn't simply * sizeof(struct fscrypt_nokey_name), as the padding at the end isn't included. */ diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index e60d57c99cb6..6020b738c3b2 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -16,6 +16,7 @@ #include #include #include +#include #include /* @@ -54,6 +55,42 @@ struct fscrypt_name { #define fname_name(p) ((p)->disk_name.name) #define fname_len(p) ((p)->disk_name.len) +/* + * struct fscrypt_nokey_name - identifier for directory entry when key is absent + * + * When userspace lists an encrypted directory without access to the key, the + * filesystem must present a unique "no-key name" for each filename that allows + * it to find the directory entry again if requested. Naively, that would just + * mean using the ciphertext filenames. However, since the ciphertext filenames + * can contain illegal characters ('\0' and '/'), they must be encoded in some + * way. We use base64url. But that can cause names to exceed NAME_MAX (255 + * bytes), so we also need to use a strong hash to abbreviate long names. + * + * The filesystem may also need another kind of hash, the "dirhash", to quickly + * find the directory entry. Since filesystems normally compute the dirhash + * over the on-disk filename (i.e. the ciphertext), it's not computable from + * no-key names that abbreviate the ciphertext using the strong hash to fit in + * NAME_MAX. It's also not computable if it's a keyed hash taken over the + * plaintext (but it may still be available in the on-disk directory entry); + * casefolded directories use this type of dirhash. At least in these cases, + * each no-key name must include the name's dirhash too. + * + * To meet all these requirements, we base64url-encode the following + * variable-length structure. It contains the dirhash, or 0's if the filesystem + * didn't provide one; up to 149 bytes of the ciphertext name; and for + * ciphertexts longer than 149 bytes, also the SHA-256 of the remaining bytes. + * + * This ensures that each no-key name contains everything needed to find the + * directory entry again, contains only legal characters, doesn't exceed + * NAME_MAX, is unambiguous unless there's a SHA-256 collision, and that we only + * take the performance hit of SHA-256 on very long filenames (which are rare). + */ +struct fscrypt_nokey_name { + u32 dirhash[2]; + u8 bytes[149]; + u8 sha256[SHA256_DIGEST_SIZE]; +}; /* 189 bytes => 252 bytes base64url-encoded, which is <= NAME_MAX (255) */ + /* Maximum value for the third parameter of fscrypt_operations.set_context(). */ #define FSCRYPT_SET_CONTEXT_MAX_SIZE 40 -- 2.35.1