From patchwork Tue Jun 11 22:34:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 13694268 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5AE4C15531E; Tue, 11 Jun 2024 22:35:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718145340; cv=none; b=lFNzOQJpNui9G9xhemMW1gXyqrdpFQ0yxXaiwb7ITL1ICYkNhFfR8hQEWBzz5wEy9SuApuoZEvgmqSZN0EMwSZFpwNuOGQ+/M9OAJ0W54yROJzNtJq3+4xx3lw6RxGF5ec+q3jRaQahcJqquPhsOf4U748Lbp/Gne7llkT+eqYI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718145340; c=relaxed/simple; bh=7VrPUFJQpUoDtO+PXZdRTKQEsnnIGEdH+lnN9iF3+LI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qoA25aH0VxJqfPCmYfXKH24Prw2czg1yur7Gz+04hcChYzyFrgXKAK5pWwQ1by1H7vcCFQKm2n7AKw0/WR+PWiyFOb3VxkIfs4uy4R10xM1GDX8sW6gk13xBS4A4YK8l/YhQjrcRdpvylV8JFX/k3WGWzweNJ4FXGG5rU7reTXg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JTfeTQiV; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JTfeTQiV" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EC723C4AF1C; Tue, 11 Jun 2024 22:35:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1718145340; bh=7VrPUFJQpUoDtO+PXZdRTKQEsnnIGEdH+lnN9iF3+LI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JTfeTQiVZloNpNJzODcy4AuAc+J0mqfA8rHK7KnlcNNlX1sbgmFjPSZoo20gJdqsH CjnwHeTDcNxTe13vJ4ir8u2MKIRE3sNEH8QeROpDxMyu927Gd+B5DuJP5B14JCGeve bB9HFaT4azs8LNye7oPkRW3CXP/r5o0Z9wbFP8nLfH1jWNqMC79yM8+21R46FWzugX EnBiulhhwtot6n4E8Y9WGtfK0ftLNkzWlnlaiitnSCoX/lwLscPb5twKgi6ARMzz/D w4QItzziqQ65numWJX0k7+t+DDGHchJZMXHVR8noaXdA4CKTHip2nm1rhKux0dGE64 1nbbPATzBKC/A== From: Eric Biggers To: linux-scsi@vger.kernel.org Cc: linux-samsung-soc@vger.kernel.org, linux-fscrypt@vger.kernel.org, Alim Akhtar , Avri Altman , Bart Van Assche , "Martin K . Petersen" , Peter Griffin , =?utf-8?q?Andr=C3=A9_Draszik?= , William McVicker Subject: [PATCH 1/6] scsi: ufs: core: Add UFSHCD_QUIRK_CUSTOM_CRYPTO_PROFILE Date: Tue, 11 Jun 2024 15:34:14 -0700 Message-ID: <20240611223419.239466-2-ebiggers@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240611223419.239466-1-ebiggers@kernel.org> References: <20240611223419.239466-1-ebiggers@kernel.org> Precedence: bulk X-Mailing-List: linux-scsi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Eric Biggers Add UFSHCD_QUIRK_CUSTOM_CRYPTO_PROFILE which lets UFS host drivers initialize the blk_crypto_profile themselves rather than have it be initialized by ufshcd-core according to the UFSHCI standard. This is needed to support inline encryption on the "Exynos" UFS controller which has a nonstandard interface. Signed-off-by: Eric Biggers --- drivers/ufs/core/ufshcd-crypto.c | 10 +++++++--- include/ufs/ufshcd.h | 9 +++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) base-commit: 83a7eefedc9b56fe7bfeff13b6c7356688ffa670 diff --git a/drivers/ufs/core/ufshcd-crypto.c b/drivers/ufs/core/ufshcd-crypto.c index f2c4422cab86..debc925ae439 100644 --- a/drivers/ufs/core/ufshcd-crypto.c +++ b/drivers/ufs/core/ufshcd-crypto.c @@ -157,10 +157,13 @@ int ufshcd_hba_init_crypto_capabilities(struct ufs_hba *hba) { int cap_idx; int err = 0; enum blk_crypto_mode_num blk_mode_num; + if (hba->quirks & UFSHCD_QUIRK_CUSTOM_CRYPTO_PROFILE) + return 0; + /* * Don't use crypto if either the hardware doesn't advertise the * standard crypto capability bit *or* if the vendor specific driver * hasn't advertised that crypto is supported. */ @@ -226,13 +229,14 @@ void ufshcd_init_crypto(struct ufs_hba *hba) int slot; if (!(hba->caps & UFSHCD_CAP_CRYPTO)) return; - /* Clear all keyslots - the number of keyslots is (CFGC + 1) */ - for (slot = 0; slot < hba->crypto_capabilities.config_count + 1; slot++) - ufshcd_clear_keyslot(hba, slot); + /* Clear all keyslots. */ + for (slot = 0; slot < hba->crypto_profile.num_slots; slot++) + hba->crypto_profile.ll_ops.keyslot_evict(&hba->crypto_profile, + NULL, slot); } void ufshcd_crypto_register(struct ufs_hba *hba, struct request_queue *q) { if (hba->caps & UFSHCD_CAP_CRYPTO) diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index bad88bd91995..b354a7eee478 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -641,10 +641,19 @@ enum ufshcd_quirks { /* * Some host does not implement SQ Run Time Command (SQRTC) register * thus need this quirk to skip related flow. */ UFSHCD_QUIRK_MCQ_BROKEN_RTC = 1 << 21, + + /* + * This quirk needs to be enabled if the host controller supports inline + * encryption but it needs to initialize the crypto capabilities in a + * nonstandard way and/or needs to override blk_crypto_ll_ops. If + * enabled, the standard code won't initialize the blk_crypto_profile; + * ufs_hba_variant_ops::init() must do it instead. + */ + UFSHCD_QUIRK_CUSTOM_CRYPTO_PROFILE = 1 << 22, }; enum ufshcd_caps { /* Allow dynamic clk gating */ UFSHCD_CAP_CLK_GATING = 1 << 0, From patchwork Tue Jun 11 22:34:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 13694269 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D4CEE1553B5; Tue, 11 Jun 2024 22:35:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718145340; cv=none; b=ZGf4bJEpxHJzvxdTprGPSOhdnFcXgVH4WVEXLQNmvXsVGltRYWwQKyKjYGqAQ8vv/tWRDopmYXxDw8iQCDmUAZH1fcDVtgF7pMH9jMKiU+ZDrD4CvSSasvqzLnVuQ5nO81a/LS2Gca1y4/Rwje+UzisfYeHEoyR506RN8ukEVWo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718145340; c=relaxed/simple; bh=YA5Wzxud6EXdeHJeBEt5IKmz1fvFGpRCpVtCdnLGIDc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=N6or1QjMPBKEXhd+nYaZHWGVvWmbW/o3K0jK/DUoSpRO/A0iqdGhvdnNBkqCJy3EjpvpWKC0xbYIT1CrahfxLQ7TF1bb95hBJv7W6YgGxao0BIwuICgv/EJeywn8ERk4pMQU3wKQK3JTpsr+/i7avypxWSY8w7lkiBXWFJ/0eHY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gv3UYMHx; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="gv3UYMHx" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5FE86C3277B; Tue, 11 Jun 2024 22:35:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1718145340; bh=YA5Wzxud6EXdeHJeBEt5IKmz1fvFGpRCpVtCdnLGIDc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gv3UYMHxqi5NnLVeHsp+bmjtr+Ts95v0+HU/iv9gafgpYk8+AlJWBRZlV/mc/Xqok +Al/b0hfatf+VoKkBz6CAYhIS6Am+1TTvC/0DJJ2pBkkanNDAfv93pWe/2R32Aahho 5Rw52y4ZNFGth6BLL/DpFaUeXLc7KMjmezLjOcoGgwa/IxlVV8n2E2TmblWkaV+TyH sV/A6Fms8xalSN3ne0IBzMQG425t4ATjLmg++dL6STAGCO/2Jy27UMgtECeHtpTGYw GDeLhV8RuzZRtJeD05ctsuG5ln8b5vlB0sN32P5JL2lV6E59TJqIgoVnYxht+vdwss YrD4cTbJhIL0A== From: Eric Biggers To: linux-scsi@vger.kernel.org Cc: linux-samsung-soc@vger.kernel.org, linux-fscrypt@vger.kernel.org, Alim Akhtar , Avri Altman , Bart Van Assche , "Martin K . Petersen" , Peter Griffin , =?utf-8?q?Andr=C3=A9_Draszik?= , William McVicker Subject: [PATCH 2/6] scsi: ufs: core: fold ufshcd_clear_keyslot() into its caller Date: Tue, 11 Jun 2024 15:34:15 -0700 Message-ID: <20240611223419.239466-3-ebiggers@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240611223419.239466-1-ebiggers@kernel.org> References: <20240611223419.239466-1-ebiggers@kernel.org> Precedence: bulk X-Mailing-List: linux-scsi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Eric Biggers Fold ufshcd_clear_keyslot() into its only remaining caller. Signed-off-by: Eric Biggers --- drivers/ufs/core/ufshcd-crypto.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/ufs/core/ufshcd-crypto.c b/drivers/ufs/core/ufshcd-crypto.c index debc925ae439..b4980fd91cee 100644 --- a/drivers/ufs/core/ufshcd-crypto.c +++ b/drivers/ufs/core/ufshcd-crypto.c @@ -93,31 +93,25 @@ static int ufshcd_crypto_keyslot_program(struct blk_crypto_profile *profile, memzero_explicit(&cfg, sizeof(cfg)); return err; } -static int ufshcd_clear_keyslot(struct ufs_hba *hba, int slot) +static int ufshcd_crypto_keyslot_evict(struct blk_crypto_profile *profile, + const struct blk_crypto_key *key, + unsigned int slot) { + struct ufs_hba *hba = + container_of(profile, struct ufs_hba, crypto_profile); /* * Clear the crypto cfg on the device. Clearing CFGE * might not be sufficient, so just clear the entire cfg. */ union ufs_crypto_cfg_entry cfg = {}; return ufshcd_program_key(hba, &cfg, slot); } -static int ufshcd_crypto_keyslot_evict(struct blk_crypto_profile *profile, - const struct blk_crypto_key *key, - unsigned int slot) -{ - struct ufs_hba *hba = - container_of(profile, struct ufs_hba, crypto_profile); - - return ufshcd_clear_keyslot(hba, slot); -} - bool ufshcd_crypto_enable(struct ufs_hba *hba) { if (!(hba->caps & UFSHCD_CAP_CRYPTO)) return false; From patchwork Tue Jun 11 22:34:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 13694270 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 48BD215531E; Tue, 11 Jun 2024 22:35:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718145341; cv=none; b=Gf4jcoamAKEc3TBcuJgi7PeXpL7t51qSTr5LwgCANvyhLED0h+Ctw4KEwsCsE8RrIAEB9MP4zBOnLF5ODFDdBlZeNnbUiq0OLQOZYFsvO8PakFDE/2pAQ1AzPSKL84+GqsoHVuNNtI4cfvLj4h2Cs7lrvz1buR6Tyrvdnzkh75Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718145341; c=relaxed/simple; bh=fgtjDmvA7l/lm4vzhuNJpYhxPFnEHAPhYNU28MhUq8o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=O1VIPAWtR1NZzwiSmCTSM/jiofzV2muK4uc7WsFOh+n/IXrOJoZee7hZNYdW2ROF6JkXnwgFFx/PHZSJIMM3GtMCikEdk5xSbn+gjzuGSdvbrIA8DZkl5gIgAycfQ+5Q2uz+TO0yInb1kfcuxXXcN7h0+13NYVv+Q6oaNj7n6fE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=g+j3qSjy; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="g+j3qSjy" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C8664C4AF48; Tue, 11 Jun 2024 22:35:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1718145341; bh=fgtjDmvA7l/lm4vzhuNJpYhxPFnEHAPhYNU28MhUq8o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=g+j3qSjyXjXYggClXPG+1G+YJ4/M4terDqPLIESu4Dj61oUA3ven4Odubt1d7hbE8 gXY06MbrmJs41jVqOYKsijvEdaAC2049TdH4nsmHPhPExFMssK1ILtN9LTV8ihLvBV G1EQDiS7wHPxd9x2CFgcrPI7P8kkG4pg5v8xkrWNNRSO5PrZMS5pghu1NL1DX3Hjz8 6BMj/b3j56+KOSu0ratSincUqPrDcR15VimC6fqMYCNOGXLpTeVxQPV8zBcfrYBwrV 2l9SP8n5iul/c4rAshu9L6fQ5rdp9HHkOysAPZdwThEmOg+Ii66wzTr0A+ZUTRuyrv iZB1Eug5LmjXw== From: Eric Biggers To: linux-scsi@vger.kernel.org Cc: linux-samsung-soc@vger.kernel.org, linux-fscrypt@vger.kernel.org, Alim Akhtar , Avri Altman , Bart Van Assche , "Martin K . Petersen" , Peter Griffin , =?utf-8?q?Andr=C3=A9_Draszik?= , William McVicker Subject: [PATCH 3/6] scsi: ufs: core: Add UFSHCD_QUIRK_BROKEN_CRYPTO_ENABLE Date: Tue, 11 Jun 2024 15:34:16 -0700 Message-ID: <20240611223419.239466-4-ebiggers@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240611223419.239466-1-ebiggers@kernel.org> References: <20240611223419.239466-1-ebiggers@kernel.org> Precedence: bulk X-Mailing-List: linux-scsi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Eric Biggers Add UFSHCD_QUIRK_BROKEN_CRYPTO_ENABLE which tells the UFS core to not use the crypto enable bit defined by the UFS specification. This is needed to support inline encryption on the "Exynos" UFS controller. Signed-off-by: Eric Biggers --- drivers/ufs/core/ufshcd-crypto.c | 8 ++++++++ include/ufs/ufshcd.h | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/drivers/ufs/core/ufshcd-crypto.c b/drivers/ufs/core/ufshcd-crypto.c index b4980fd91cee..a714dad82cd1 100644 --- a/drivers/ufs/core/ufshcd-crypto.c +++ b/drivers/ufs/core/ufshcd-crypto.c @@ -108,17 +108,25 @@ static int ufshcd_crypto_keyslot_evict(struct blk_crypto_profile *profile, union ufs_crypto_cfg_entry cfg = {}; return ufshcd_program_key(hba, &cfg, slot); } +/* + * Reprogram the keyslots if needed, and return true if CRYPTO_GENERAL_ENABLE + * should be used in the host controller initialization sequence. + */ bool ufshcd_crypto_enable(struct ufs_hba *hba) { if (!(hba->caps & UFSHCD_CAP_CRYPTO)) return false; /* Reset might clear all keys, so reprogram all the keys. */ blk_crypto_reprogram_all_keys(&hba->crypto_profile); + + if (hba->quirks & UFSHCD_QUIRK_BROKEN_CRYPTO_ENABLE) + return false; + return true; } static const struct blk_crypto_ll_ops ufshcd_crypto_ops = { .keyslot_program = ufshcd_crypto_keyslot_program, diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index b354a7eee478..4b7ad23a4420 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -650,10 +650,17 @@ enum ufshcd_quirks { * nonstandard way and/or needs to override blk_crypto_ll_ops. If * enabled, the standard code won't initialize the blk_crypto_profile; * ufs_hba_variant_ops::init() must do it instead. */ UFSHCD_QUIRK_CUSTOM_CRYPTO_PROFILE = 1 << 22, + + /* + * This quirk needs to be enabled if the host controller supports inline + * encryption but does not support the CRYPTO_GENERAL_ENABLE bit, i.e. + * host controller initialization fails if that bit is set. + */ + UFSHCD_QUIRK_BROKEN_CRYPTO_ENABLE = 1 << 23, }; enum ufshcd_caps { /* Allow dynamic clk gating */ UFSHCD_CAP_CLK_GATING = 1 << 0, From patchwork Tue Jun 11 22:34:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 13694271 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EB863155A46; Tue, 11 Jun 2024 22:35:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718145342; cv=none; b=f7+u0NsOMvpU90JfVNxxZQ7vx5lLyqYvtSpX3Xv/LKkMdHnVBs+Icti93haR9fVIvDQvxsmlPDovqHGzKBeuDE4PKc1Onic5rcpMicS2dEKw1bjzGxWkWgo95dvvfJrKq/gdBWSjnMSVrdn0VHuWYnIM0AP/H0uBVRHKdnbbqgw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718145342; c=relaxed/simple; bh=u0jYwdKW3UnVrdgG/w93hhY2HIs0pseo3u1lMTfTwls=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=W5iXUzfVv7HqLpowWIVJ928tMEjhvaq5VgkhtzehSOYGW8+YDzyI28YBBc1ED3oKY/HioC1Aw+nDkU9QpQlIwI0jvNrpkJ1MKlEwhfSo67rA3KZEW5txvydkkUJJXt1hzh9Mpl5u7Wi9im0F2oSy4FLc4WRkGXd0AzrLsoVDOuo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qgMRtB6S; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="qgMRtB6S" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3C887C2BD10; Tue, 11 Jun 2024 22:35:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1718145341; bh=u0jYwdKW3UnVrdgG/w93hhY2HIs0pseo3u1lMTfTwls=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qgMRtB6SsZOOAlt2/G4BArfiJF+0XyYqrSc4S6J3U1mQpfdPdldpsaKL75l4mj8IA b+G1SQwFb9LiTJzeheS2c0BJT0BEE5i49hQxAhtt414QOT40NgRTGOHBu5jePPadmW ggREBbtTLGFKBKjG8RQYkfpwSmaePJQ5N4VXMW96fKDFqNpccIKNDz/fbMvl7bUy8I gnWrcUxxM3sVdhLgK6jh4mjS+VJTEFiQNq5PE/SlTWh9voj4PqFq7XsRceLLB59xv+ jSs/3hTfifB3CDvOPGK8TWvM/e5W4leCFvqykT6+D83SXWlQfGpCMYWoGCNKk5gkI+ wGQNsQem4MpWA== From: Eric Biggers To: linux-scsi@vger.kernel.org Cc: linux-samsung-soc@vger.kernel.org, linux-fscrypt@vger.kernel.org, Alim Akhtar , Avri Altman , Bart Van Assche , "Martin K . Petersen" , Peter Griffin , =?utf-8?q?Andr=C3=A9_Draszik?= , William McVicker Subject: [PATCH 4/6] scsi: ufs: core: Add fill_crypto_prdt variant op Date: Tue, 11 Jun 2024 15:34:17 -0700 Message-ID: <20240611223419.239466-5-ebiggers@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240611223419.239466-1-ebiggers@kernel.org> References: <20240611223419.239466-1-ebiggers@kernel.org> Precedence: bulk X-Mailing-List: linux-scsi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Eric Biggers Add a variant op to allow host drivers to initialize nonstandard crypto-related fields in the PRDT. This is needed to support inline encryption on the "Exynos" UFS controller. Note that this will be used together with the support for overriding the PRDT entry size that was already added by commit ada1e653a5ea ("scsi: ufs: core: Allow UFS host drivers to override the sg entry size"). Signed-off-by: Eric Biggers --- drivers/ufs/core/ufshcd-crypto.h | 19 +++++++++++++++++++ drivers/ufs/core/ufshcd.c | 2 +- include/ufs/ufshcd.h | 4 ++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/ufs/core/ufshcd-crypto.h b/drivers/ufs/core/ufshcd-crypto.h index be8596f20ba2..3eb8df42e194 100644 --- a/drivers/ufs/core/ufshcd-crypto.h +++ b/drivers/ufs/core/ufshcd-crypto.h @@ -35,10 +35,23 @@ ufshcd_prepare_req_desc_hdr_crypto(struct ufshcd_lrb *lrbp, h->cci = lrbp->crypto_key_slot; h->dunl = cpu_to_le32(lower_32_bits(lrbp->data_unit_num)); h->dunu = cpu_to_le32(upper_32_bits(lrbp->data_unit_num)); } +static inline int ufshcd_crypto_fill_prdt(struct ufs_hba *hba, + struct ufshcd_lrb *lrbp) +{ + struct scsi_cmnd *cmd = lrbp->cmd; + const struct bio_crypt_ctx *crypt_ctx = scsi_cmd_to_rq(cmd)->crypt_ctx; + + if (crypt_ctx && hba->vops && hba->vops->fill_crypto_prdt) + return hba->vops->fill_crypto_prdt(hba, crypt_ctx, + lrbp->ucd_prdt_ptr, + scsi_sg_count(cmd)); + return 0; +} + bool ufshcd_crypto_enable(struct ufs_hba *hba); int ufshcd_hba_init_crypto_capabilities(struct ufs_hba *hba); void ufshcd_init_crypto(struct ufs_hba *hba); @@ -52,10 +65,16 @@ static inline void ufshcd_prepare_lrbp_crypto(struct request *rq, static inline void ufshcd_prepare_req_desc_hdr_crypto(struct ufshcd_lrb *lrbp, struct request_desc_header *h) { } +static inline int ufshcd_crypto_fill_prdt(struct ufs_hba *hba, + struct ufshcd_lrb *lrbp) +{ + return 0; +} + static inline bool ufshcd_crypto_enable(struct ufs_hba *hba) { return false; } diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 0cf07194bbe8..e8a044149562 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -2634,11 +2634,11 @@ static int ufshcd_map_sg(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) if (sg_segments < 0) return sg_segments; ufshcd_sgl_to_prdt(hba, lrbp, sg_segments, scsi_sglist(cmd)); - return 0; + return ufshcd_crypto_fill_prdt(hba, lrbp); } /** * ufshcd_enable_intr - enable interrupts * @hba: per adapter instance diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index 4b7ad23a4420..59aa6c831a41 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -319,10 +319,11 @@ struct ufs_pwr_mode_info { * @dbg_register_dump: used to dump controller debug information * @phy_initialization: used to initialize phys * @device_reset: called to issue a reset pulse on the UFS device * @config_scaling_param: called to configure clock scaling parameters * @program_key: program or evict an inline encryption key + * @fill_crypto_prdt: initialize crypto-related fields in the PRDT * @event_notify: called to notify important events * @reinit_notify: called to notify reinit of UFSHCD during max gear switch * @mcq_config_resource: called to configure MCQ platform resources * @get_hba_mac: called to get vendor specific mac value, mandatory for mcq mode * @op_runtime_config: called to config Operation and runtime regs Pointers @@ -363,10 +364,13 @@ struct ufs_hba_variant_ops { void (*config_scaling_param)(struct ufs_hba *hba, struct devfreq_dev_profile *profile, struct devfreq_simple_ondemand_data *data); int (*program_key)(struct ufs_hba *hba, const union ufs_crypto_cfg_entry *cfg, int slot); + int (*fill_crypto_prdt)(struct ufs_hba *hba, + const struct bio_crypt_ctx *crypt_ctx, + void *prdt, unsigned int num_segments); void (*event_notify)(struct ufs_hba *hba, enum ufs_event_type evt, void *data); void (*reinit_notify)(struct ufs_hba *); int (*mcq_config_resource)(struct ufs_hba *hba); int (*get_hba_mac)(struct ufs_hba *hba); From patchwork Tue Jun 11 22:34:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 13694272 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 81DF5155C80; Tue, 11 Jun 2024 22:35:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718145342; cv=none; b=Db3U1TM5b5M9xHozcs5oZITV5I77GrNiAsUIq3FcN7dj7sIejC/XacD22xxyca+Quo5Jw/qbqH5l2BfSeQj+ahuNVB4h0IKCBsnk+smV3COhRppu893/MzThbmAW0vRU5LKR7ZyK+f2swQzBDGaXj5U50fn8r3UglVMjkAl3WD8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718145342; c=relaxed/simple; bh=uLgd/ay0FcbtDF6bgTmIf7jaAQbU5UzGDgBMZx7c9fs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=urj/fHujzXLFXR68crWeL9UtvVhM0b37qWARYs4SWUm/m6CAq9aSbyOMApI8vC4uigC2PEeG/Btam/RLfaKxH8h4l3EMKs9IuEgPxuTEM/wbTdkH7EPBkfcPXV8xCKPoekdB/k1HxH8DKdmN8XKOK2pO3fTwRrOAUqYXNgQ9h74= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ChUN+Hl1; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ChUN+Hl1" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A4E10C4AF1C; Tue, 11 Jun 2024 22:35:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1718145341; bh=uLgd/ay0FcbtDF6bgTmIf7jaAQbU5UzGDgBMZx7c9fs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ChUN+Hl1lGVFVM2zroVMq8JmvgZE/tkv0jYMA6kaTf9oG5FY8tcNDN075fwc0Y7qC ZIeJ2/LxZk7SsLhGQfPX8G/7IIH2TrHqwSupoprqYjUXmDqpSnB+A0E25PpxmUqg66 Ry0OOnhKBMsv6kqppb6eM1/YNs980azI68ufX4EQObibaWQdkEBVPFmuHwNhj/Njau c4ARDJAzncpOHSQbIhp0Z9HeX4HK1bRCvxeYZQ2SihcG45QNepWOKXVW7SNh7RzksM AqX15lcxPFq4XB6gw7CWO6VjLVU2WuNEHmf/9A2g09jgmG9kIJUG1NyN2A5h8juG8P z1Y6z+hMau9pg== From: Eric Biggers To: linux-scsi@vger.kernel.org Cc: linux-samsung-soc@vger.kernel.org, linux-fscrypt@vger.kernel.org, Alim Akhtar , Avri Altman , Bart Van Assche , "Martin K . Petersen" , Peter Griffin , =?utf-8?q?Andr=C3=A9_Draszik?= , William McVicker Subject: [PATCH 5/6] scsi: ufs: core: Add UFSHCD_QUIRK_KEYS_IN_PRDT Date: Tue, 11 Jun 2024 15:34:18 -0700 Message-ID: <20240611223419.239466-6-ebiggers@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240611223419.239466-1-ebiggers@kernel.org> References: <20240611223419.239466-1-ebiggers@kernel.org> Precedence: bulk X-Mailing-List: linux-scsi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Eric Biggers Since the nonstandard inline encryption support on Exynos SoCs requires that raw cryptographic keys be copied into the PRDT, it is desirable to zeroize those keys after each request to keep them from being left in memory. Therefore, add a quirk bit that enables the zeroization. We could instead do the zeroization unconditionally. However, using a quirk bit avoids adding the zeroization overhead to standard devices. Signed-off-by: Eric Biggers --- drivers/ufs/core/ufshcd-crypto.h | 17 +++++++++++++++++ drivers/ufs/core/ufshcd.c | 1 + include/ufs/ufshcd.h | 8 ++++++++ 3 files changed, 26 insertions(+) diff --git a/drivers/ufs/core/ufshcd-crypto.h b/drivers/ufs/core/ufshcd-crypto.h index 3eb8df42e194..89bb97c14c15 100644 --- a/drivers/ufs/core/ufshcd-crypto.h +++ b/drivers/ufs/core/ufshcd-crypto.h @@ -48,10 +48,24 @@ static inline int ufshcd_crypto_fill_prdt(struct ufs_hba *hba, lrbp->ucd_prdt_ptr, scsi_sg_count(cmd)); return 0; } +static inline void ufshcd_crypto_clear_prdt(struct ufs_hba *hba, + struct ufshcd_lrb *lrbp) +{ + if (!(hba->quirks & UFSHCD_QUIRK_KEYS_IN_PRDT)) + return; + + if (!(scsi_cmd_to_rq(lrbp->cmd)->crypt_ctx)) + return; + + /* Zeroize the PRDT because it can contain cryptographic keys. */ + memzero_explicit(lrbp->ucd_prdt_ptr, + ufshcd_sg_entry_size(hba) * scsi_sg_count(lrbp->cmd)); +} + bool ufshcd_crypto_enable(struct ufs_hba *hba); int ufshcd_hba_init_crypto_capabilities(struct ufs_hba *hba); void ufshcd_init_crypto(struct ufs_hba *hba); @@ -71,10 +85,13 @@ static inline int ufshcd_crypto_fill_prdt(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) { return 0; } +static inline void ufshcd_crypto_clear_prdt(struct ufs_hba *hba, + struct ufshcd_lrb *lrbp) { } + static inline bool ufshcd_crypto_enable(struct ufs_hba *hba) { return false; } diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index e8a044149562..8ac4fb141b01 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -5472,10 +5472,11 @@ void ufshcd_release_scsi_cmd(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) { struct scsi_cmnd *cmd = lrbp->cmd; scsi_dma_unmap(cmd); + ufshcd_crypto_clear_prdt(hba, lrbp); ufshcd_release(hba); ufshcd_clk_scaling_update_busy(hba); } /** diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index 59aa6c831a41..fe0073b37224 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -661,10 +661,18 @@ enum ufshcd_quirks { * This quirk needs to be enabled if the host controller supports inline * encryption but does not support the CRYPTO_GENERAL_ENABLE bit, i.e. * host controller initialization fails if that bit is set. */ UFSHCD_QUIRK_BROKEN_CRYPTO_ENABLE = 1 << 23, + + /* + * This quirk needs to be enabled if the host controller driver copies + * cryptographic keys into the PRDT in order to send them to hardware, + * and therefore the PRDT should be zeroized after each request (as per + * the standard best practice for managing keys). + */ + UFSHCD_QUIRK_KEYS_IN_PRDT = 1 << 24, }; enum ufshcd_caps { /* Allow dynamic clk gating */ UFSHCD_CAP_CLK_GATING = 1 << 0, From patchwork Tue Jun 11 22:34:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 13694273 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7F6B3155A5D; Tue, 11 Jun 2024 22:35:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718145342; cv=none; b=b0hWVfVmzATSibmcrL0Kbu1KWoOhs53Y00/zDketENyiOegK9nXSuOSjpsb5iWTnOcGbdaWcjf1RtBf4l5YjPUd+A8Y4aR6yA2iOup2DHoWds2xEskJeLwRKhUT5mAXZc1c05vrc+aFdTwBs12UK3+5R5Y5zRjG6ZWmTdkiNbzI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718145342; c=relaxed/simple; bh=4tEuqrAcgZtsBsOs4iafGri1iafX3gtInXu87ZPA0rA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CCQ9wsKUOtle9vfp8vyNo8pah4FcKMODNAdTA26XcUCcn5TG9KZOjfvwXi0C9OIDgpe/KAMvxupeJ1XyTPgwEML0plH8xisRPydBYwYXkoPJFDGQuoqDaa7KDSv0/hWM+OE5UQrGBmOpu0S1ISaN5juGBHHiVLx58WZYsIO8u64= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=inm5qZPs; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="inm5qZPs" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 199AAC4AF48; Tue, 11 Jun 2024 22:35:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1718145342; bh=4tEuqrAcgZtsBsOs4iafGri1iafX3gtInXu87ZPA0rA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=inm5qZPsymf3Ss/IffBaKSwvlrD7s8xrQxZ2jle/1XKc+PMPjIRHS80cnplK3P+YW 1SZRmJTJU/xv0WYMnYMA9cNBP5O4awNfDdML8a4PTM6HkiHJQxVlkgnT5Gn/tMcfqk XponH0F96DImIUZB3v+sPq2iAsG/sxmp4s97W0upPKyDx4CSso0PNHR+XFu3RsVSNR w1dmc8m8rZGLOxivugmM0By8j4FFSyJry+rHFcSlDW0bteLQ1izlxqtXVW/kkeBfbT lqI4XOQ7kp+q8V5IMA69rAZDvEMdDepwRDBXpyE3rDJF/7DPFPA4N198akuWoKx9hu CgjSj9oSqTb3Q== From: Eric Biggers To: linux-scsi@vger.kernel.org Cc: linux-samsung-soc@vger.kernel.org, linux-fscrypt@vger.kernel.org, Alim Akhtar , Avri Altman , Bart Van Assche , "Martin K . Petersen" , Peter Griffin , =?utf-8?q?Andr=C3=A9_Draszik?= , William McVicker Subject: [PATCH 6/6] scsi: ufs: exynos: Add support for Flash Memory Protector (FMP) Date: Tue, 11 Jun 2024 15:34:19 -0700 Message-ID: <20240611223419.239466-7-ebiggers@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240611223419.239466-1-ebiggers@kernel.org> References: <20240611223419.239466-1-ebiggers@kernel.org> Precedence: bulk X-Mailing-List: linux-scsi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Eric Biggers Add support for Flash Memory Protector (FMP), which is the inline encryption hardware on Exynos and Exynos-based SoCs. Specifically, add support for the "traditional FMP mode" that works on many Exynos-based SoCs including gs101. This is the mode that uses "software keys" and is compatible with the upstream kernel's existing inline encryption framework in the block and filesystem layers. I plan to add support for the wrapped key support on gs101 at a later time. Tested on gs101 (specifically Pixel 6) by running the 'encrypt' group of xfstests on a filesystem mounted with the 'inlinecrypt' mount option. Signed-off-by: Eric Biggers --- drivers/ufs/host/ufs-exynos.c | 219 +++++++++++++++++++++++++++++++++- 1 file changed, 218 insertions(+), 1 deletion(-) diff --git a/drivers/ufs/host/ufs-exynos.c b/drivers/ufs/host/ufs-exynos.c index 88d125d1ee3c..969c4eedbe2d 100644 --- a/drivers/ufs/host/ufs-exynos.c +++ b/drivers/ufs/host/ufs-exynos.c @@ -6,10 +6,13 @@ * Author: Seungwon Jeon * Author: Alim Akhtar * */ +#include +#include +#include #include #include #include #include #include @@ -1149,10 +1152,221 @@ static inline void exynos_ufs_priv_init(struct ufs_hba *hba, ufs->rx_sel_idx = 0; hba->priv = (void *)ufs; hba->quirks = ufs->drv_data->quirks; } +#ifdef CONFIG_SCSI_UFS_CRYPTO + +/* + * Support for Flash Memory Protector (FMP), which is the inline encryption + * hardware on Exynos and Exynos-based SoCs. The interface to this hardware is + * not compatible with the standard UFS crypto. It requires that encryption be + * configured in the PRDT using a nonstandard extension. + */ + +enum fmp_crypto_algo_mode { + FMP_BYPASS_MODE = 0, + FMP_ALGO_MODE_AES_CBC = 1, + FMP_ALGO_MODE_AES_XTS = 2, +}; +enum fmp_crypto_key_length { + FMP_KEYLEN_256BIT = 1, +}; +#define FMP_DATA_UNIT_SIZE SZ_4K + +/* This is the nonstandard format of PRDT entries when FMP is enabled. */ +struct fmp_sg_entry { + + /* + * This is the standard PRDT entry, but with nonstandard bitfields in + * the high bits of the 'size' field, i.e. the last 32-bit word. When + * these nonstandard bitfields are zero, the data segment won't be + * encrypted or decrypted. Otherwise they specify the algorithm and key + * length with which the data segment will be encrypted or decrypted. + */ + struct ufshcd_sg_entry base; + + /* The initialization vector (IV) with all bytes reversed */ + __be64 file_iv[2]; + + /* + * The key with all bytes reversed. For XTS, the two halves of the key + * are given separately and are byte-reversed separately. + */ + __be64 file_enckey[4]; + __be64 file_twkey[4]; + + /* Unused */ + __be64 disk_iv[2]; + __be64 reserved[2]; +}; + +#define SMC_CMD_FMP_SECURITY 0xC2001810 +#define SMC_CMD_SMU 0xC2001850 +#define SMC_CMD_FMP_SMU_RESUME 0xC2001860 +#define SMU_EMBEDDED 0 +#define SMU_INIT 0 +#define CFG_DESCTYPE_3 3 + +static inline long exynos_smc(unsigned long cmd, unsigned long arg0, + unsigned long arg1, unsigned long arg2) +{ + struct arm_smccc_res res; + + arm_smccc_smc(cmd, arg0, arg1, arg2, 0, 0, 0, 0, &res); + return res.a0; +} + +static void exynos_ufs_fmp_init(struct ufs_hba *hba) +{ + struct blk_crypto_profile *profile = &hba->crypto_profile; + long ret; + + /* + * Check for the standard crypto support bit, since it's available even + * though the rest of the interface to FMP is nonstandard. + * + * This check should have the effect of preventing the driver from + * trying to use FMP on old Exynos SoCs that don't have FMP. + */ + if (!(ufshcd_readl(hba, REG_CONTROLLER_CAPABILITIES) & + MASK_CRYPTO_SUPPORT)) + return; + + /* + * This call (which sets DESCTYPE to 0x3 in the FMPSECURITY0 register) + * is needed to make the hardware use the larger PRDT entry size. + */ + BUILD_BUG_ON(sizeof(struct fmp_sg_entry) != 128); + ret = exynos_smc(SMC_CMD_FMP_SECURITY, 0, SMU_EMBEDDED, CFG_DESCTYPE_3); + if (ret) { + dev_warn(hba->dev, + "SMC_CMD_FMP_SECURITY failed on init: %ld. Disabling FMP support.\n", + ret); + return; + } + ufshcd_set_sg_entry_size(hba, sizeof(struct fmp_sg_entry)); + + /* + * This is needed to initialize FMP. Without it, errors occur when + * inline encryption is used. + */ + ret = exynos_smc(SMC_CMD_SMU, SMU_INIT, SMU_EMBEDDED, 0); + if (ret) { + dev_err(hba->dev, + "SMC_CMD_SMU(SMU_INIT) failed: %ld. Disabling FMP support.\n", + ret); + return; + } + + /* Advertise crypto capabilities to the block layer. */ + ret = devm_blk_crypto_profile_init(hba->dev, profile, 0); + if (ret) { + /* Only ENOMEM should be possible here. */ + dev_err(hba->dev, "Failed to initialize crypto profile: %ld\n", + ret); + return; + } + profile->max_dun_bytes_supported = AES_BLOCK_SIZE; + profile->dev = hba->dev; + profile->modes_supported[BLK_ENCRYPTION_MODE_AES_256_XTS] = + FMP_DATA_UNIT_SIZE; + + /* Advertise crypto support to ufshcd-core. */ + hba->caps |= UFSHCD_CAP_CRYPTO; + + /* Advertise crypto quirks to ufshcd-core. */ + hba->quirks |= UFSHCD_QUIRK_CUSTOM_CRYPTO_PROFILE | + UFSHCD_QUIRK_BROKEN_CRYPTO_ENABLE | + UFSHCD_QUIRK_KEYS_IN_PRDT; + +} + +static void exynos_ufs_fmp_resume(struct ufs_hba *hba) +{ + long ret; + + ret = exynos_smc(SMC_CMD_FMP_SECURITY, 0, SMU_EMBEDDED, CFG_DESCTYPE_3); + if (ret) + dev_err(hba->dev, + "SMC_CMD_FMP_SECURITY failed on resume: %ld\n", ret); + + ret = exynos_smc(SMC_CMD_FMP_SMU_RESUME, 0, SMU_EMBEDDED, 0); + if (ret) + dev_err(hba->dev, "SMC_CMD_FMP_SMU_RESUME failed: %ld\n", ret); +} + +static inline __be64 fmp_key_word(const u8 *key, int j) +{ + return cpu_to_be64(get_unaligned_le64( + key + AES_KEYSIZE_256 - (j + 1) * sizeof(u64))); +} + +/* Fill the PRDT for a request according to the given encryption context. */ +static int exynos_ufs_fmp_fill_prdt(struct ufs_hba *hba, + const struct bio_crypt_ctx *crypt_ctx, + void *prdt, unsigned int num_segments) +{ + struct fmp_sg_entry *fmp_prdt = prdt; + const u8 *enckey = crypt_ctx->bc_key->raw; + const u8 *twkey = enckey + AES_KEYSIZE_256; + u64 dun_lo = crypt_ctx->bc_dun[0]; + u64 dun_hi = crypt_ctx->bc_dun[1]; + unsigned int i; + + /* If FMP wasn't enabled, we shouldn't get any encrypted requests. */ + if (WARN_ON_ONCE(!(hba->caps & UFSHCD_CAP_CRYPTO))) + return -EIO; + + /* Configure FMP on each segment of the request. */ + for (i = 0; i < num_segments; i++) { + struct fmp_sg_entry *prd = &fmp_prdt[i]; + int j; + + /* Each segment must be exactly one data unit. */ + if (prd->base.size != cpu_to_le32(FMP_DATA_UNIT_SIZE - 1)) { + dev_err(hba->dev, + "data segment is misaligned for FMP\n"); + return -EIO; + } + + /* Set the algorithm and key length. */ + prd->base.size |= cpu_to_le32((FMP_ALGO_MODE_AES_XTS << 28) | + (FMP_KEYLEN_256BIT << 26)); + + /* Set the IV. */ + prd->file_iv[0] = cpu_to_be64(dun_hi); + prd->file_iv[1] = cpu_to_be64(dun_lo); + + /* Set the key. */ + for (j = 0; j < AES_KEYSIZE_256 / sizeof(u64); j++) { + prd->file_enckey[j] = fmp_key_word(enckey, j); + prd->file_twkey[j] = fmp_key_word(twkey, j); + } + + /* Increment the data unit number. */ + dun_lo++; + if (dun_lo == 0) + dun_hi++; + } + return 0; +} + +#else /* CONFIG_SCSI_UFS_CRYPTO */ + +static void exynos_ufs_fmp_init(struct ufs_hba *hba) +{ +} + +static void exynos_ufs_fmp_resume(struct ufs_hba *hba) +{ +} + +#define exynos_ufs_fmp_fill_prdt NULL + +#endif /* !CONFIG_SCSI_UFS_CRYPTO */ + static int exynos_ufs_init(struct ufs_hba *hba) { struct device *dev = hba->dev; struct platform_device *pdev = to_platform_device(dev); struct exynos_ufs *ufs; @@ -1196,10 +1410,12 @@ static int exynos_ufs_init(struct ufs_hba *hba) goto out; } exynos_ufs_priv_init(hba, ufs); + exynos_ufs_fmp_init(hba); + if (ufs->drv_data->drv_init) { ret = ufs->drv_data->drv_init(dev, ufs); if (ret) { dev_err(dev, "failed to init drv-data\n"); goto out; @@ -1430,11 +1646,11 @@ static int exynos_ufs_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) if (!ufshcd_is_link_active(hba)) phy_power_on(ufs->phy); exynos_ufs_config_smu(ufs); - + exynos_ufs_fmp_resume(hba); return 0; } static int exynosauto_ufs_vh_link_startup_notify(struct ufs_hba *hba, enum ufs_notify_change_status status) @@ -1696,10 +1912,11 @@ static const struct ufs_hba_variant_ops ufs_hba_exynos_ops = { .setup_xfer_req = exynos_ufs_specify_nexus_t_xfer_req, .setup_task_mgmt = exynos_ufs_specify_nexus_t_tm_req, .hibern8_notify = exynos_ufs_hibern8_notify, .suspend = exynos_ufs_suspend, .resume = exynos_ufs_resume, + .fill_crypto_prdt = exynos_ufs_fmp_fill_prdt, }; static struct ufs_hba_variant_ops ufs_hba_exynosauto_vh_ops = { .name = "exynosauto_ufs_vh", .init = exynosauto_ufs_vh_init,