Received: by 2002:a05:6a10:f3d0:0:0:0:0 with SMTP id a16csp2832242pxv; Mon, 12 Jul 2021 03:03:32 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwwuiJ35EriR3Y2lCBPUlYkbPIUlDWiMkSKJpr5m31Tcm9/9Au8iqVw02bPdgMUreZhp2LB X-Received: by 2002:a92:c56d:: with SMTP id b13mr36871134ilj.169.1626084212116; Mon, 12 Jul 2021 03:03:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626084212; cv=none; d=google.com; s=arc-20160816; b=0FvaPSiz7hT1w4hRPdN9NiM0UxD1M/ym0EWZ6qjW56d4lKCs0KGnXoCUYhzf7wEKqF JRtUYqaagi9B40/oKN0Ey8Mnoyg8ec8iHwkTIEmALl72oNB6FTke6uwbuMHOUjIDa9// V6PcyaNf/WIa5C9b1ZxAwkH2eVZ+WPCRqv2QvR3xrgpqfg0409BRf79NxcSnn8advMq6 9IBxk4Jjoem9T62/mCs/gxT8GOyY+4RAwYTfOT10nW4oIQ5wqt8upl5PyivmWUsmout9 4d8SdHLLpxDFv2T7Tp2gonan1Q3V1gp8kJiOhYTDV1PzHVamwnqYe+fhUaCrs8S0Cpic iqIg== 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 :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=1+U2VI8kL9VcCZkT0cZ9QVYqKj0j/U5szqn71A0A6ew=; b=i1505qCEoYslOmOdGocr4RLtJ4ciExePu8eBoB6zjUzA4QzQ7lDLMHIbEyaHTJV/B8 53pZGHuozjw01hq6JBx4FNZu6h/uxu/5k8SpHzVSmptHTiV3BcX97buNQAsPC9+PZ7rH 8tLolOkTrPyiWJNFVG8C991kyPdqVRFkY9lx/kWWZHTDQvCA769ta+BKEZz6mK7w+gxk vD/6sYNpnP/wGqaBKR2mOPRqf0GLIlG3y+YX0r4CKo6eUwo1SwpBuxqY+Uhtq1gYkUIV 05DBgIWOpU1epqIc2ztP+YxyLB51bPZhMsJEwMDM7bqqxPUH7uSROXeVNYFg9RoVtoFv dJaw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=wRtZSMaF; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id w16si17287019jal.57.2021.07.12.03.03.20; Mon, 12 Jul 2021 03:03:32 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=wRtZSMaF; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244813AbhGLHSt (ORCPT + 99 others); Mon, 12 Jul 2021 03:18:49 -0400 Received: from mail.kernel.org ([198.145.29.99]:53956 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241025AbhGLGya (ORCPT ); Mon, 12 Jul 2021 02:54:30 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 8876C61004; Mon, 12 Jul 2021 06:51:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1626072700; bh=JiV23D7s319bQuMgVN3/RSbx9xSUP3/IuO9DjcHrKo4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=wRtZSMaFmOYVkn2KmqEjS20RfN5XMFNTq3u/662Hfj7/7v5j8yCHpkMOv5ovWb8Sa C4jEGuScB/37LmcPsO5c+hindQZ9r8WgDz37AKURjdxU/OLrkc5aS73hPUpp+730XY /uU3DG4vAtY0Zvzl14PENpAc6VmNByswySXGTtlo= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Eric Biggers Subject: [PATCH 5.10 585/593] fscrypt: fix derivation of SipHash keys on big endian CPUs Date: Mon, 12 Jul 2021 08:12:25 +0200 Message-Id: <20210712060959.756747733@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210712060843.180606720@linuxfoundation.org> References: <20210712060843.180606720@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Eric Biggers commit 2fc2b430f559fdf32d5d1dd5ceaa40e12fb77bdf upstream. Typically, the cryptographic APIs that fscrypt uses take keys as byte arrays, which avoids endianness issues. However, siphash_key_t is an exception. It is defined as 'u64 key[2];', i.e. the 128-bit key is expected to be given directly as two 64-bit words in CPU endianness. fscrypt_derive_dirhash_key() and fscrypt_setup_iv_ino_lblk_32_key() forgot to take this into account. Therefore, the SipHash keys used to index encrypted+casefolded directories differ on big endian vs. little endian platforms, as do the SipHash keys used to hash inode numbers for IV_INO_LBLK_32-encrypted directories. This makes such directories non-portable between these platforms. Fix this by always using the little endian order. This is a breaking change for big endian platforms, but this should be fine in practice since these features (encrypt+casefold support, and the IV_INO_LBLK_32 flag) aren't known to actually be used on any big endian platforms yet. Fixes: aa408f835d02 ("fscrypt: derive dirhash key for casefolded directories") Fixes: e3b1078bedd3 ("fscrypt: add support for IV_INO_LBLK_32 policies") Cc: # v5.6+ Link: https://lore.kernel.org/r/20210605075033.54424-1-ebiggers@kernel.org Signed-off-by: Eric Biggers Signed-off-by: Greg Kroah-Hartman --- fs/crypto/keysetup.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) --- a/fs/crypto/keysetup.c +++ b/fs/crypto/keysetup.c @@ -210,15 +210,40 @@ out_unlock: return err; } +/* + * Derive a SipHash key from the given fscrypt master key and the given + * application-specific information string. + * + * Note that the KDF produces a byte array, but the SipHash APIs expect the key + * as a pair of 64-bit words. Therefore, on big endian CPUs we have to do an + * endianness swap in order to get the same results as on little endian CPUs. + */ +static int fscrypt_derive_siphash_key(const struct fscrypt_master_key *mk, + u8 context, const u8 *info, + unsigned int infolen, siphash_key_t *key) +{ + int err; + + err = fscrypt_hkdf_expand(&mk->mk_secret.hkdf, context, info, infolen, + (u8 *)key, sizeof(*key)); + if (err) + return err; + + BUILD_BUG_ON(sizeof(*key) != 16); + BUILD_BUG_ON(ARRAY_SIZE(key->key) != 2); + le64_to_cpus(&key->key[0]); + le64_to_cpus(&key->key[1]); + return 0; +} + int fscrypt_derive_dirhash_key(struct fscrypt_info *ci, const struct fscrypt_master_key *mk) { int err; - err = fscrypt_hkdf_expand(&mk->mk_secret.hkdf, HKDF_CONTEXT_DIRHASH_KEY, - ci->ci_nonce, FSCRYPT_FILE_NONCE_SIZE, - (u8 *)&ci->ci_dirhash_key, - sizeof(ci->ci_dirhash_key)); + err = fscrypt_derive_siphash_key(mk, HKDF_CONTEXT_DIRHASH_KEY, + ci->ci_nonce, FSCRYPT_FILE_NONCE_SIZE, + &ci->ci_dirhash_key); if (err) return err; ci->ci_dirhash_key_initialized = true; @@ -253,10 +278,9 @@ static int fscrypt_setup_iv_ino_lblk_32_ if (mk->mk_ino_hash_key_initialized) goto unlock; - err = fscrypt_hkdf_expand(&mk->mk_secret.hkdf, - HKDF_CONTEXT_INODE_HASH_KEY, NULL, 0, - (u8 *)&mk->mk_ino_hash_key, - sizeof(mk->mk_ino_hash_key)); + err = fscrypt_derive_siphash_key(mk, + HKDF_CONTEXT_INODE_HASH_KEY, + NULL, 0, &mk->mk_ino_hash_key); if (err) goto unlock; /* pairs with smp_load_acquire() above */