From patchwork Fri Oct 11 18:54:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 834638 Received: from mail-wr1-f51.google.com (mail-wr1-f51.google.com [209.85.221.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 75CF81D040F for ; Fri, 11 Oct 2024 18:54:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728672877; cv=none; b=KDv6dYPQY7gtWvA6kk0xtmrjABK1ClXi4dOux8lVqDTXqc62Vwev1EOW1qkJSIZErqvuqOaK2KQNmO93I61ZqNiQ1+0eyLmw6SfnYnuYmu5j72Xx2C0+r8r9CoDQzD9uS2VqufKxkaLEmumFoE1vuCBGQPt5d1+9ZFqoq4Y9MwI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728672877; c=relaxed/simple; bh=jKmpd4lqWYjC/bI56bxkX7EXYN8HCf2Hkw0YVqivTbw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=u8VqXOYFfEB3CSRyT+EbjaXmKj2rdtbG6iOC9TTkvRN0eX5ONb93Kx4WSEbUiCaW9NmV5E3AOUxYm+tPhFCXN6LdDjBKfrk8lMFSpnsXmYZUGMzz6ZTRCJHB8I3pVhMHTajESYLGYdD8fYz0x2bln/KXGTHHE06tIRvZvjsmoRE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl; spf=none smtp.mailfrom=bgdev.pl; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b=a/iLtV/L; arc=none smtp.client-ip=209.85.221.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b="a/iLtV/L" Received: by mail-wr1-f51.google.com with SMTP id ffacd0b85a97d-37d51055097so1081342f8f.3 for ; Fri, 11 Oct 2024 11:54:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1728672870; x=1729277670; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=v9VxJ4jmLuD56SmEUpoUOEdV2HsuGTvp1hd0r9VZvLY=; b=a/iLtV/LoYcdBPDDUpmeHaZ/G9Lx0AVINbJchCrlFxcwgSwYkVD2fkAjXdaUO/D1uH tCphn1bebk298C+UNtmU2c145uxy8OTDdVD1H2/WZCrx9vG1sviYjCyI6FwqL+i/0e5J YUzyyfRAeW3FDf/zQLnwz6uprsVaqvNxDJBZLaKkwA3WouDJpeoGiDOomw8CDo0NebM2 D1on1ErqZUwubv7AwkT0QQkZzqxJilXw8odJO9+DVsYW4husHlP6MMn86Pw17DtLPeV6 7ZSL6Yfwl8VQHeWqRDW1KJfNRgi2yCZ5YpkkMGTeb3pf0/ViAK977biDBDNolBzvxuu3 z4iA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1728672870; x=1729277670; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=v9VxJ4jmLuD56SmEUpoUOEdV2HsuGTvp1hd0r9VZvLY=; b=g1ERjZOTiwA4F0Z6WJoeuTR0N2nIA1PAM83Sq88MzjenHMDT0ydS4kvce2b0XBMqaV ddCGWwSgcNTh5D7kHMP7CRmdOlUf6Ee8v9PDrD2CoWuHvlEusDaHHgpl/kdQZxgtgnAs 2LMnJC7xXRVJBhx/XXp8mGr2/14lbUbMtnp6tFYl7zheXsckUcHwNvhIyfnzFD7JxFGU 7PV8qlnKoCz9wpndq2IpR9vqgDFkxjB+lB1gC85orbaH5BOVwoulwy4y6PXIftZOcmLo mZjBjbJPVbIajW82gEqlVTeiWzBSGpo05Ie7iYUXo5AAYbzx68dyiukcS0u1LtCoGcBB NppQ== X-Forwarded-Encrypted: i=1; AJvYcCUzX3Vsx2yxo/9aTxCztiwb3FBC2/5kYDtmyZcJ/a9/mYN5CdMYteGw4PoQlR3S+S9TeFJV9dtfZNX8Swgo@vger.kernel.org X-Gm-Message-State: AOJu0Yxkm7mRd5qfGag0fxKqZgA7nMeORrTBmC85307afqGnrBe+i9LL 8ujk7lepKK/xc5oIstjCTApCGz9QV5i3Kxgt+3r7/hxG5R6fZ4rwsTHwb4eh8TA= X-Google-Smtp-Source: AGHT+IG9XeK1ZJbQFlnDi+MQX22opDpqQ9TV9krLRzQ61dIv9JL7pNlicWbCfnHSREoPg83EQJOd3Q== X-Received: by 2002:adf:e852:0:b0:37d:4fe9:b6a4 with SMTP id ffacd0b85a97d-37d600c8cc7mr367322f8f.50.1728672869346; Fri, 11 Oct 2024 11:54:29 -0700 (PDT) Received: from [127.0.1.1] ([2a01:cb1d:dc:7e00:68b8:bef:b7eb:538f]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-37d4b79fe7csm4559161f8f.70.2024.10.11.11.54.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Oct 2024 11:54:28 -0700 (PDT) From: Bartosz Golaszewski Date: Fri, 11 Oct 2024 20:54:00 +0200 Subject: [PATCH v7 01/17] blk-crypto: add basic hardware-wrapped key support Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241011-wrapped-keys-v7-1-e3f7a752059b@linaro.org> References: <20241011-wrapped-keys-v7-0-e3f7a752059b@linaro.org> In-Reply-To: <20241011-wrapped-keys-v7-0-e3f7a752059b@linaro.org> To: Jens Axboe , Jonathan Corbet , Alasdair Kergon , Mike Snitzer , Mikulas Patocka , Adrian Hunter , Asutosh Das , Ritesh Harjani , Ulf Hansson , Alim Akhtar , Avri Altman , Bart Van Assche , "James E.J. Bottomley" , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam , Dmitry Baryshkov , Gaurav Kashyap , Neil Armstrong Cc: linux-block@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, dm-devel@lists.linux.dev, linux-mmc@vger.kernel.org, linux-scsi@vger.kernel.org, linux-fscrypt@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-arm-msm@vger.kernel.org, Bartosz Golaszewski , Eric Biggers X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=34532; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=SYxIafHRjfmwA6JlhloJqr10zFsTaHOg0dvLgW2y5O8=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnCXRctEKhSzkZF4k9HAcBuhdoEMA2jK2w3TDnT 2usuP+XFIqJAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZwl0XAAKCRARpy6gFHHX co8RD/9fvlpQu5v7QpXzPKZOQ6cYohkCkHq+ffOWMFBJh4ZdwmwVp//uqr6Y400qAs7MO1rr4c4 WyZeRUZDuFsOQwGZmsTqeHs1sXQCrab+K1WTqEuV4SxmZTKZEGecq61qdj8rR/DRLIwNsy+AKVP awopqkiJCml+4a7RimTDRK+W1EVy5K2qsXywbp+kX8QH8/T9CnwqXcAgoUFcugekd6Svh6iE8rZ EYkJXOxGFO3b4imX3wVBbO7kyUUlKKG/5g5da0EdNkUNgU+ExXNf+iybBW8uAL0U124mo9P3Uxn E/mooEmqFS37zlB6TKRuI4fB9jf3r4aWSZ/Wnrwyq/b+RVmQBkZTNk6syueoY55u99k1jQiYAjI EiiFAOtp3P2atYlcLxiAZIWTkiSFA2nrVukDBvFiG3CJiFz/J9jKDGpFBz8iP2CXcYdIkKWsusm m2OjmjyA6IkZ3peZ7uPLfHjqgsNJXA5oZWhm1v+6/9P4zLICoEJrgMJ1MWxEhaIWaM5Y1WPxk5Z 0/uH8lJw6yIzl9M+fqZsPZbFcYknd5DpqkkV+0Du3yvc912VmO8fCaEzd8e+4nGvAQ4gb4Zq60u n9dIcpJ1C5lTkpY08Ou4egU1/lr2vyDRKmFbdY8uBzr+tQBH6c5DP+VI3lB8FIuI9ksJX8B817X Gc2XaH5UvQTuMvQ== X-Developer-Key: i=bartosz.golaszewski@linaro.org; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 From: Eric Biggers To prevent keys from being compromised if an attacker acquires read access to kernel memory, some inline encryption hardware can accept keys which are wrapped by a per-boot hardware-internal key. This avoids needing to keep the raw keys in kernel memory, without limiting the number of keys that can be used. Such hardware also supports deriving a "software secret" for cryptographic tasks that can't be handled by inline encryption; this is needed for fscrypt to work properly. To support this hardware, allow struct blk_crypto_key to represent a hardware-wrapped key as an alternative to a standard key, and make drivers set flags in struct blk_crypto_profile to indicate which types of keys they support. Also add the ->derive_sw_secret() low-level operation, which drivers supporting wrapped keys must implement. For more information, see the detailed documentation which this patch adds to Documentation/block/inline-encryption.rst. Signed-off-by: Eric Biggers Signed-off-by: Bartosz Golaszewski --- Documentation/block/inline-encryption.rst | 213 +++++++++++++++++++++++++++++- block/blk-crypto-fallback.c | 5 +- block/blk-crypto-internal.h | 1 + block/blk-crypto-profile.c | 46 +++++++ block/blk-crypto.c | 51 +++++-- drivers/md/dm-table.c | 1 + drivers/mmc/host/cqhci-crypto.c | 2 + drivers/ufs/core/ufshcd-crypto.c | 1 + fs/crypto/inline_crypt.c | 4 +- include/linux/blk-crypto-profile.h | 20 +++ include/linux/blk-crypto.h | 74 ++++++++++- 11 files changed, 394 insertions(+), 24 deletions(-) diff --git a/Documentation/block/inline-encryption.rst b/Documentation/block/inline-encryption.rst index 90b733422ed4..07218455a2bc 100644 --- a/Documentation/block/inline-encryption.rst +++ b/Documentation/block/inline-encryption.rst @@ -77,10 +77,10 @@ Basic design ============ We introduce ``struct blk_crypto_key`` to represent an inline encryption key and -how it will be used. This includes the actual bytes of the key; the size of the -key; the algorithm and data unit size the key will be used with; and the number -of bytes needed to represent the maximum data unit number the key will be used -with. +how it will be used. This includes the type of the key (standard or +hardware-wrapped); the actual bytes of the key; the size of the key; the +algorithm and data unit size the key will be used with; and the number of bytes +needed to represent the maximum data unit number the key will be used with. We introduce ``struct bio_crypt_ctx`` to represent an encryption context. It contains a data unit number and a pointer to a blk_crypto_key. We add pointers @@ -301,3 +301,208 @@ kernel will pretend that the device does not support hardware inline encryption When the crypto API fallback is enabled, this means that all bios with and encryption context will use the fallback, and IO will complete as usual. When the fallback is disabled, a bio with an encryption context will be failed. + +.. _hardware_wrapped_keys: + +Hardware-wrapped keys +===================== + +Motivation and threat model +--------------------------- + +Linux storage encryption (dm-crypt, fscrypt, eCryptfs, etc.) traditionally +relies on the raw encryption key(s) being present in kernel memory so that the +encryption can be performed. This traditionally isn't seen as a problem because +the key(s) won't be present during an offline attack, which is the main type of +attack that storage encryption is intended to protect from. + +However, there is an increasing desire to also protect users' data from other +types of attacks (to the extent possible), including: + +- Cold boot attacks, where an attacker with physical access to a system suddenly + powers it off, then immediately dumps the system memory to extract recently + in-use encryption keys, then uses these keys to decrypt user data on-disk. + +- Online attacks where the attacker is able to read kernel memory without fully + compromising the system, followed by an offline attack where any extracted + keys can be used to decrypt user data on-disk. An example of such an online + attack would be if the attacker is able to run some code on the system that + exploits a Meltdown-like vulnerability but is unable to escalate privileges. + +- Online attacks where the attacker fully compromises the system, but their data + exfiltration is significantly time-limited and/or bandwidth-limited, so in + order to completely exfiltrate the data they need to extract the encryption + keys to use in a later offline attack. + +Hardware-wrapped keys are a feature of inline encryption hardware that is +designed to protect users' data from the above attacks (to the extent possible), +without introducing limitations such as a maximum number of keys. + +Note that it is impossible to **fully** protect users' data from these attacks. +Even in the attacks where the attacker "just" gets read access to kernel memory, +they can still extract any user data that is present in memory, including +plaintext pagecache pages of encrypted files. The focus here is just on +protecting the encryption keys, as those instantly give access to **all** user +data in any following offline attack, rather than just some of it (where which +data is included in that "some" might not be controlled by the attacker). + +Solution overview +----------------- + +Inline encryption hardware typically has "keyslots" into which software can +program keys for the hardware to use; the contents of keyslots typically can't +be read back by software. As such, the above security goals could be achieved +if the kernel simply erased its copy of the key(s) after programming them into +keyslot(s) and thereafter only referred to them via keyslot number. + +However, that naive approach runs into the problem that it limits the number of +unlocked keys to the number of keyslots, which typically is a small number. In +cases where there is only one encryption key system-wide (e.g., a full-disk +encryption key), that can be tolerable. However, in general there can be many +logged-in users with many different keys, and/or many running applications with +application-specific encrypted storage areas. This is especially true if +file-based encryption (e.g. fscrypt) is being used. + +Thus, it is important for the kernel to still have a way to "remind" the +hardware about a key, without actually having the raw key itself. This would +ensure that the number of hardware keyslots only limits the number of active I/O +requests, not other things such as the number of logged-in users, the number of +running apps, or the number of encrypted storage areas that apps can create. + +Somewhat less importantly, it is also desirable that the raw keys are never +visible to software at all, even while being initially unlocked. This would +ensure that a read-only compromise of system memory will never allow a key to be +extracted to be used off-system, even if it occurs when a key is being unlocked. + +To solve all these problems, some vendors of inline encryption hardware have +made their hardware support *hardware-wrapped keys*. Hardware-wrapped keys +are encrypted keys that can only be unwrapped (decrypted) and used by hardware +-- either by the inline encryption hardware itself, or by a dedicated hardware +block that can directly provision keys to the inline encryption hardware. + +(We refer to them as "hardware-wrapped keys" rather than simply "wrapped keys" +to add some clarity in cases where there could be other types of wrapped keys, +such as in file-based encryption. Key wrapping is a commonly used technique.) + +The key which wraps (encrypts) hardware-wrapped keys is a hardware-internal key +that is never exposed to software; it is either a persistent key (a "long-term +wrapping key") or a per-boot key (an "ephemeral wrapping key"). The long-term +wrapped form of the key is what is initially unlocked, but it is erased from +memory as soon as it is converted into an ephemerally-wrapped key. In-use +hardware-wrapped keys are always ephemerally-wrapped, not long-term wrapped. + +As inline encryption hardware can only be used to encrypt/decrypt data on-disk, +the hardware also includes a level of indirection; it doesn't use the unwrapped +key directly for inline encryption, but rather derives both an inline encryption +key and a "software secret" from it. Software can use the "software secret" for +tasks that can't use the inline encryption hardware, such as filenames +encryption. The software secret is not protected from memory compromise. + +Key hierarchy +------------- + +Here is the key hierarchy for a hardware-wrapped key:: + + Hardware-wrapped key + | + | + + | + ----------------------------- + | | + Inline encryption key Software secret + +The components are: + +- *Hardware-wrapped key*: a key for the hardware's KDF (Key Derivation + Function), in ephemerally-wrapped form. The key wrapping algorithm is a + hardware implementation detail that doesn't impact kernel operation, but a + strong authenticated encryption algorithm such as AES-256-GCM is recommended. + +- *Hardware KDF*: a KDF (Key Derivation Function) which the hardware uses to + derive subkeys after unwrapping the wrapped key. The hardware's choice of KDF + doesn't impact kernel operation, but it does need to be known for testing + purposes, and it's also assumed to have at least a 256-bit security strength. + All known hardware uses the SP800-108 KDF in Counter Mode with AES-256-CMAC, + with a particular choice of labels and contexts; new hardware should use this + already-vetted KDF. + +- *Inline encryption key*: a derived key which the hardware directly provisions + to a keyslot of the inline encryption hardware, without exposing it to + software. In all known hardware, this will always be an AES-256-XTS key. + However, in principle other encryption algorithms could be supported too. + Hardware must derive distinct subkeys for each supported encryption algorithm. + +- *Software secret*: a derived key which the hardware returns to software so + that software can use it for cryptographic tasks that can't use inline + encryption. This value is cryptographically isolated from the inline + encryption key, i.e. knowing one doesn't reveal the other. (The KDF ensures + this.) Currently, the software secret is always 32 bytes and thus is suitable + for cryptographic applications that require up to a 256-bit security strength. + Some use cases (e.g. full-disk encryption) won't require the software secret. + +Example: in the case of fscrypt, the fscrypt master key (the key that protects a +particular set of encrypted directories) is made hardware-wrapped. The inline +encryption key is used as the file contents encryption key, while the software +secret (rather than the master key directly) is used to key fscrypt's KDF +(HKDF-SHA512) to derive other subkeys such as filenames encryption keys. + +Note that currently this design assumes a single inline encryption key per +hardware-wrapped key, without any further key derivation. Thus, in the case of +fscrypt, currently hardware-wrapped keys are only compatible with the "inline +encryption optimized" settings, which use one file contents encryption key per +encryption policy rather than one per file. This design could be extended to +make the hardware derive per-file keys using per-file nonces passed down the +storage stack, and in fact some hardware already supports this; future work is +planned to remove this limitation by adding the corresponding kernel support. + +Kernel support +-------------- + +The inline encryption support of the kernel's block layer ("blk-crypto") has +been extended to support hardware-wrapped keys as an alternative to standard +keys, when hardware support is available. This works in the following way: + +- A ``key_types_supported`` field is added to the crypto capabilities in + ``struct blk_crypto_profile``. This allows device drivers to declare that + they support standard keys, hardware-wrapped keys, or both. + +- ``struct blk_crypto_key`` can now contain a hardware-wrapped key as an + alternative to a standard key; a ``key_type`` field is added to + ``struct blk_crypto_config`` to distinguish between the different key types. + This allows users of blk-crypto to en/decrypt data using a hardware-wrapped + key in a way very similar to using a standard key. + +- A new method ``blk_crypto_ll_ops::derive_sw_secret`` is added. Device drivers + that support hardware-wrapped keys must implement this method. Users of + blk-crypto can call ``blk_crypto_derive_sw_secret()`` to access this method. + +- The programming and eviction of hardware-wrapped keys happens via + ``blk_crypto_ll_ops::keyslot_program`` and + ``blk_crypto_ll_ops::keyslot_evict``, just like it does for standard keys. If + a driver supports hardware-wrapped keys, then it must handle hardware-wrapped + keys being passed to these methods. + +blk-crypto-fallback doesn't support hardware-wrapped keys. Therefore, +hardware-wrapped keys can only be used with actual inline encryption hardware. + +Testability +----------- + +Both the hardware KDF and the inline encryption itself are well-defined +algorithms that don't depend on any secrets other than the unwrapped key. +Therefore, if the unwrapped key is known to software, these algorithms can be +reproduced in software in order to verify the ciphertext that is written to disk +by the inline encryption hardware. + +However, the unwrapped key will only be known to software for testing if the +"import" functionality is used. Proper testing is not possible in the +"generate" case where the hardware generates the key itself. The correct +operation of the "generate" mode thus relies on the security and correctness of +the hardware RNG and its use to generate the key, as well as the testing of the +"import" mode as that should cover all parts other than the key generation. + +For an example of a test that verifies the ciphertext written to disk in the +"import" mode, see the fscrypt hardware-wrapped key tests in xfstests, or +`Android's vts_kernel_encryption_test +`_. diff --git a/block/blk-crypto-fallback.c b/block/blk-crypto-fallback.c index b1e7415f8439..00f638955657 100644 --- a/block/blk-crypto-fallback.c +++ b/block/blk-crypto-fallback.c @@ -87,7 +87,7 @@ static struct bio_set crypto_bio_split; * This is the key we set when evicting a keyslot. This *should* be the all 0's * key, but AES-XTS rejects that key, so we use some random bytes instead. */ -static u8 blank_key[BLK_CRYPTO_MAX_KEY_SIZE]; +static u8 blank_key[BLK_CRYPTO_MAX_STANDARD_KEY_SIZE]; static void blk_crypto_fallback_evict_keyslot(unsigned int slot) { @@ -539,7 +539,7 @@ static int blk_crypto_fallback_init(void) if (blk_crypto_fallback_inited) return 0; - get_random_bytes(blank_key, BLK_CRYPTO_MAX_KEY_SIZE); + get_random_bytes(blank_key, sizeof(blank_key)); err = bioset_init(&crypto_bio_split, 64, 0, 0); if (err) @@ -561,6 +561,7 @@ static int blk_crypto_fallback_init(void) blk_crypto_fallback_profile->ll_ops = blk_crypto_fallback_ll_ops; blk_crypto_fallback_profile->max_dun_bytes_supported = BLK_CRYPTO_MAX_IV_SIZE; + blk_crypto_fallback_profile->key_types_supported = BLK_CRYPTO_KEY_TYPE_STANDARD; /* All blk-crypto modes have a crypto API fallback. */ for (i = 0; i < BLK_ENCRYPTION_MODE_MAX; i++) diff --git a/block/blk-crypto-internal.h b/block/blk-crypto-internal.h index 93a141979694..1893df9a8f06 100644 --- a/block/blk-crypto-internal.h +++ b/block/blk-crypto-internal.h @@ -14,6 +14,7 @@ struct blk_crypto_mode { const char *name; /* name of this mode, shown in sysfs */ const char *cipher_str; /* crypto API name (for fallback case) */ unsigned int keysize; /* key size in bytes */ + unsigned int security_strength; /* security strength in bytes */ unsigned int ivsize; /* iv size in bytes */ }; diff --git a/block/blk-crypto-profile.c b/block/blk-crypto-profile.c index 7fabc883e39f..1b92276ed2fc 100644 --- a/block/blk-crypto-profile.c +++ b/block/blk-crypto-profile.c @@ -352,6 +352,8 @@ bool __blk_crypto_cfg_supported(struct blk_crypto_profile *profile, return false; if (profile->max_dun_bytes_supported < cfg->dun_bytes) return false; + if (!(profile->key_types_supported & cfg->key_type)) + return false; return true; } @@ -462,6 +464,44 @@ bool blk_crypto_register(struct blk_crypto_profile *profile, } EXPORT_SYMBOL_GPL(blk_crypto_register); +/** + * blk_crypto_derive_sw_secret() - Derive software secret from wrapped key + * @bdev: a block device that supports hardware-wrapped keys + * @eph_key: the hardware-wrapped key in ephemerally-wrapped form + * @eph_key_size: size of @eph_key in bytes + * @sw_secret: (output) the software secret + * + * Given a hardware-wrapped key in ephemerally-wrapped form (the same form that + * it is used for I/O), ask the hardware to derive the secret which software can + * use for cryptographic tasks other than inline encryption. This secret is + * guaranteed to be cryptographically isolated from the inline encryption key, + * i.e. derived with a different KDF context. + * + * Return: 0 on success, -EOPNOTSUPP if the block device doesn't support + * hardware-wrapped keys, -EBADMSG if the key isn't a valid + * hardware-wrapped key, or another -errno code. + */ +int blk_crypto_derive_sw_secret(struct block_device *bdev, + const u8 *eph_key, size_t eph_key_size, + u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]) +{ + struct blk_crypto_profile *profile = + bdev_get_queue(bdev)->crypto_profile; + int err; + + if (!profile) + return -EOPNOTSUPP; + if (!(profile->key_types_supported & BLK_CRYPTO_KEY_TYPE_HW_WRAPPED)) + return -EOPNOTSUPP; + if (!profile->ll_ops.derive_sw_secret) + return -EOPNOTSUPP; + blk_crypto_hw_enter(profile); + err = profile->ll_ops.derive_sw_secret(profile, eph_key, eph_key_size, + sw_secret); + blk_crypto_hw_exit(profile); + return err; +} + /** * blk_crypto_intersect_capabilities() - restrict supported crypto capabilities * by child device @@ -485,10 +525,12 @@ void blk_crypto_intersect_capabilities(struct blk_crypto_profile *parent, child->max_dun_bytes_supported); for (i = 0; i < ARRAY_SIZE(child->modes_supported); i++) parent->modes_supported[i] &= child->modes_supported[i]; + parent->key_types_supported &= child->key_types_supported; } else { parent->max_dun_bytes_supported = 0; memset(parent->modes_supported, 0, sizeof(parent->modes_supported)); + parent->key_types_supported = 0; } } EXPORT_SYMBOL_GPL(blk_crypto_intersect_capabilities); @@ -521,6 +563,9 @@ bool blk_crypto_has_capabilities(const struct blk_crypto_profile *target, target->max_dun_bytes_supported) return false; + if (reference->key_types_supported & ~target->key_types_supported) + return false; + return true; } EXPORT_SYMBOL_GPL(blk_crypto_has_capabilities); @@ -555,5 +600,6 @@ void blk_crypto_update_capabilities(struct blk_crypto_profile *dst, sizeof(dst->modes_supported)); dst->max_dun_bytes_supported = src->max_dun_bytes_supported; + dst->key_types_supported = src->key_types_supported; } EXPORT_SYMBOL_GPL(blk_crypto_update_capabilities); diff --git a/block/blk-crypto.c b/block/blk-crypto.c index 4d760b092deb..5a09d0ef1a01 100644 --- a/block/blk-crypto.c +++ b/block/blk-crypto.c @@ -23,24 +23,28 @@ const struct blk_crypto_mode blk_crypto_modes[] = { .name = "AES-256-XTS", .cipher_str = "xts(aes)", .keysize = 64, + .security_strength = 32, .ivsize = 16, }, [BLK_ENCRYPTION_MODE_AES_128_CBC_ESSIV] = { .name = "AES-128-CBC-ESSIV", .cipher_str = "essiv(cbc(aes),sha256)", .keysize = 16, + .security_strength = 16, .ivsize = 16, }, [BLK_ENCRYPTION_MODE_ADIANTUM] = { .name = "Adiantum", .cipher_str = "adiantum(xchacha12,aes)", .keysize = 32, + .security_strength = 32, .ivsize = 32, }, [BLK_ENCRYPTION_MODE_SM4_XTS] = { .name = "SM4-XTS", .cipher_str = "xts(sm4)", .keysize = 32, + .security_strength = 16, .ivsize = 16, }, }; @@ -76,9 +80,15 @@ static int __init bio_crypt_ctx_init(void) /* This is assumed in various places. */ BUILD_BUG_ON(BLK_ENCRYPTION_MODE_INVALID != 0); - /* Sanity check that no algorithm exceeds the defined limits. */ + /* + * Validate the crypto mode properties. This ideally would be done with + * static assertions, but boot-time checks are the next best thing. + */ for (i = 0; i < BLK_ENCRYPTION_MODE_MAX; i++) { - BUG_ON(blk_crypto_modes[i].keysize > BLK_CRYPTO_MAX_KEY_SIZE); + BUG_ON(blk_crypto_modes[i].keysize > + BLK_CRYPTO_MAX_STANDARD_KEY_SIZE); + BUG_ON(blk_crypto_modes[i].security_strength > + blk_crypto_modes[i].keysize); BUG_ON(blk_crypto_modes[i].ivsize > BLK_CRYPTO_MAX_IV_SIZE); } @@ -315,8 +325,9 @@ int __blk_crypto_rq_bio_prep(struct request *rq, struct bio *bio, /** * blk_crypto_init_key() - Prepare a key for use with blk-crypto * @blk_key: Pointer to the blk_crypto_key to initialize. - * @raw_key: Pointer to the raw key. Must be the correct length for the chosen - * @crypto_mode; see blk_crypto_modes[]. + * @raw_key: the raw bytes of the key + * @raw_key_size: size of the raw key in bytes + * @key_type: type of the key -- either standard or hardware-wrapped * @crypto_mode: identifier for the encryption algorithm to use * @dun_bytes: number of bytes that will be used to specify the DUN when this * key is used @@ -325,7 +336,9 @@ int __blk_crypto_rq_bio_prep(struct request *rq, struct bio *bio, * Return: 0 on success, -errno on failure. The caller is responsible for * zeroizing both blk_key and raw_key when done with them. */ -int blk_crypto_init_key(struct blk_crypto_key *blk_key, const u8 *raw_key, +int blk_crypto_init_key(struct blk_crypto_key *blk_key, + const u8 *raw_key, size_t raw_key_size, + enum blk_crypto_key_type key_type, enum blk_crypto_mode_num crypto_mode, unsigned int dun_bytes, unsigned int data_unit_size) @@ -338,8 +351,19 @@ int blk_crypto_init_key(struct blk_crypto_key *blk_key, const u8 *raw_key, return -EINVAL; mode = &blk_crypto_modes[crypto_mode]; - if (mode->keysize == 0) + switch (key_type) { + case BLK_CRYPTO_KEY_TYPE_STANDARD: + if (raw_key_size != mode->keysize) + return -EINVAL; + break; + case BLK_CRYPTO_KEY_TYPE_HW_WRAPPED: + if (raw_key_size < mode->security_strength || + raw_key_size > BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE) + return -EINVAL; + break; + default: return -EINVAL; + } if (dun_bytes == 0 || dun_bytes > mode->ivsize) return -EINVAL; @@ -350,9 +374,10 @@ int blk_crypto_init_key(struct blk_crypto_key *blk_key, const u8 *raw_key, blk_key->crypto_cfg.crypto_mode = crypto_mode; blk_key->crypto_cfg.dun_bytes = dun_bytes; blk_key->crypto_cfg.data_unit_size = data_unit_size; + blk_key->crypto_cfg.key_type = key_type; blk_key->data_unit_size_bits = ilog2(data_unit_size); - blk_key->size = mode->keysize; - memcpy(blk_key->raw, raw_key, mode->keysize); + blk_key->size = raw_key_size; + memcpy(blk_key->raw, raw_key, raw_key_size); return 0; } @@ -372,8 +397,10 @@ bool blk_crypto_config_supported_natively(struct block_device *bdev, bool blk_crypto_config_supported(struct block_device *bdev, const struct blk_crypto_config *cfg) { - return IS_ENABLED(CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK) || - blk_crypto_config_supported_natively(bdev, cfg); + if (IS_ENABLED(CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK) && + cfg->key_type == BLK_CRYPTO_KEY_TYPE_STANDARD) + return true; + return blk_crypto_config_supported_natively(bdev, cfg); } /** @@ -396,6 +423,10 @@ int blk_crypto_start_using_key(struct block_device *bdev, { if (blk_crypto_config_supported_natively(bdev, &key->crypto_cfg)) return 0; + if (key->crypto_cfg.key_type != BLK_CRYPTO_KEY_TYPE_STANDARD) { + pr_warn_once("tried to use wrapped key, but hardware doesn't support it\n"); + return -EOPNOTSUPP; + } return blk_crypto_fallback_start_using_mode(key->crypto_cfg.crypto_mode); } diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index dbd39b9722b9..f6af54551881 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -1255,6 +1255,7 @@ static int dm_table_construct_crypto_profile(struct dm_table *t) profile->max_dun_bytes_supported = UINT_MAX; memset(profile->modes_supported, 0xFF, sizeof(profile->modes_supported)); + profile->key_types_supported = ~0; for (i = 0; i < t->num_targets; i++) { struct dm_target *ti = dm_table_get_target(t, i); diff --git a/drivers/mmc/host/cqhci-crypto.c b/drivers/mmc/host/cqhci-crypto.c index d5f4b6972f63..6652982410ec 100644 --- a/drivers/mmc/host/cqhci-crypto.c +++ b/drivers/mmc/host/cqhci-crypto.c @@ -210,6 +210,8 @@ int cqhci_crypto_init(struct cqhci_host *cq_host) /* Unfortunately, CQHCI crypto only supports 32 DUN bits. */ profile->max_dun_bytes_supported = 4; + profile->key_types_supported = BLK_CRYPTO_KEY_TYPE_STANDARD; + /* * Cache all the crypto capabilities and advertise the supported crypto * modes and data unit sizes to the block layer. diff --git a/drivers/ufs/core/ufshcd-crypto.c b/drivers/ufs/core/ufshcd-crypto.c index a714dad82cd1..7d3a3e228db0 100644 --- a/drivers/ufs/core/ufshcd-crypto.c +++ b/drivers/ufs/core/ufshcd-crypto.c @@ -195,6 +195,7 @@ int ufshcd_hba_init_crypto_capabilities(struct ufs_hba *hba) hba->crypto_profile.ll_ops = ufshcd_crypto_ops; /* UFS only supports 8 bytes for any DUN */ hba->crypto_profile.max_dun_bytes_supported = 8; + hba->crypto_profile.key_types_supported = BLK_CRYPTO_KEY_TYPE_STANDARD; hba->crypto_profile.dev = hba->dev; /* diff --git a/fs/crypto/inline_crypt.c b/fs/crypto/inline_crypt.c index 40de69860dcf..ee92c78e798b 100644 --- a/fs/crypto/inline_crypt.c +++ b/fs/crypto/inline_crypt.c @@ -130,6 +130,7 @@ int fscrypt_select_encryption_impl(struct fscrypt_inode_info *ci) crypto_cfg.crypto_mode = ci->ci_mode->blk_crypto_mode; crypto_cfg.data_unit_size = 1U << ci->ci_data_unit_bits; crypto_cfg.dun_bytes = fscrypt_get_dun_bytes(ci); + crypto_cfg.key_type = BLK_CRYPTO_KEY_TYPE_STANDARD; devs = fscrypt_get_devices(sb, &num_devs); if (IS_ERR(devs)) @@ -166,7 +167,8 @@ int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key, if (!blk_key) return -ENOMEM; - err = blk_crypto_init_key(blk_key, raw_key, crypto_mode, + err = blk_crypto_init_key(blk_key, raw_key, ci->ci_mode->keysize, + BLK_CRYPTO_KEY_TYPE_STANDARD, crypto_mode, fscrypt_get_dun_bytes(ci), 1U << ci->ci_data_unit_bits); if (err) { diff --git a/include/linux/blk-crypto-profile.h b/include/linux/blk-crypto-profile.h index 90ab33cb5d0e..229287a7f451 100644 --- a/include/linux/blk-crypto-profile.h +++ b/include/linux/blk-crypto-profile.h @@ -57,6 +57,20 @@ struct blk_crypto_ll_ops { int (*keyslot_evict)(struct blk_crypto_profile *profile, const struct blk_crypto_key *key, unsigned int slot); + + /** + * @derive_sw_secret: Derive the software secret from a hardware-wrapped + * key in ephemerally-wrapped form. + * + * This only needs to be implemented if BLK_CRYPTO_KEY_TYPE_HW_WRAPPED + * is supported. + * + * Must return 0 on success, -EBADMSG if the key is invalid, or another + * -errno code on other errors. + */ + int (*derive_sw_secret)(struct blk_crypto_profile *profile, + const u8 *eph_key, size_t eph_key_size, + u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]); }; /** @@ -84,6 +98,12 @@ struct blk_crypto_profile { */ unsigned int max_dun_bytes_supported; + /** + * @key_types_supported: A bitmask of the supported key types: + * BLK_CRYPTO_KEY_TYPE_STANDARD and/or BLK_CRYPTO_KEY_TYPE_HW_WRAPPED. + */ + unsigned int key_types_supported; + /** * @modes_supported: Array of bitmasks that specifies whether each * combination of crypto mode and data unit size is supported. diff --git a/include/linux/blk-crypto.h b/include/linux/blk-crypto.h index 5e5822c18ee4..19066d86ecbf 100644 --- a/include/linux/blk-crypto.h +++ b/include/linux/blk-crypto.h @@ -17,7 +17,58 @@ enum blk_crypto_mode_num { BLK_ENCRYPTION_MODE_MAX, }; -#define BLK_CRYPTO_MAX_KEY_SIZE 64 +/* + * Supported types of keys. Must be bitflags due to their use in + * blk_crypto_profile::key_types_supported. + */ +enum blk_crypto_key_type { + /* + * Standard keys (i.e. "software keys"). These keys are simply kept in + * raw, plaintext form in kernel memory. + */ + BLK_CRYPTO_KEY_TYPE_STANDARD = 1 << 0, + + /* + * Hardware-wrapped keys. These keys are only present in kernel memory + * in ephemerally-wrapped form, and they can only be unwrapped by + * dedicated hardware. For details, see the "Hardware-wrapped keys" + * section of Documentation/block/inline-encryption.rst. + */ + BLK_CRYPTO_KEY_TYPE_HW_WRAPPED = 1 << 1, +}; + +/* + * Currently the maximum standard key size is 64 bytes, as that is the key size + * of BLK_ENCRYPTION_MODE_AES_256_XTS which takes the longest key. + * + * The maximum hardware-wrapped key size depends on the hardware's key wrapping + * algorithm, which is a hardware implementation detail, so it isn't precisely + * specified. But currently 128 bytes is plenty in practice. Implementations + * are recommended to wrap a 32-byte key for the hardware KDF with AES-256-GCM, + * which should result in a size closer to 64 bytes than 128. + * + * Both of these values can trivially be increased if ever needed. + */ +#define BLK_CRYPTO_MAX_STANDARD_KEY_SIZE 64 +#define BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE 128 + +/* This should use max(), but max() doesn't work in a struct definition. */ +#define BLK_CRYPTO_MAX_ANY_KEY_SIZE \ + (BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE > \ + BLK_CRYPTO_MAX_STANDARD_KEY_SIZE ? \ + BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE : BLK_CRYPTO_MAX_STANDARD_KEY_SIZE) + +/* + * Size of the "software secret" which can be derived from a hardware-wrapped + * key. This is currently always 32 bytes. Note, the choice of 32 bytes + * assumes that the software secret is only used directly for algorithms that + * don't require more than a 256-bit key to get the desired security strength. + * If it were to be used e.g. directly as an AES-256-XTS key, then this would + * need to be increased (which is possible if hardware supports it, but care + * would need to be taken to avoid breaking users who need exactly 32 bytes). + */ +#define BLK_CRYPTO_SW_SECRET_SIZE 32 + /** * struct blk_crypto_config - an inline encryption key's crypto configuration * @crypto_mode: encryption algorithm this key is for @@ -26,20 +77,23 @@ enum blk_crypto_mode_num { * ciphertext. This is always a power of 2. It might be e.g. the * filesystem block size or the disk sector size. * @dun_bytes: the maximum number of bytes of DUN used when using this key + * @key_type: the type of this key -- either standard or hardware-wrapped */ struct blk_crypto_config { enum blk_crypto_mode_num crypto_mode; unsigned int data_unit_size; unsigned int dun_bytes; + enum blk_crypto_key_type key_type; }; /** * struct blk_crypto_key - an inline encryption key - * @crypto_cfg: the crypto configuration (like crypto_mode, key size) for this - * key + * @crypto_cfg: the crypto mode, data unit size, key type, and other + * characteristics of this key and how it will be used * @data_unit_size_bits: log2 of data_unit_size - * @size: size of this key in bytes (determined by @crypto_cfg.crypto_mode) - * @raw: the raw bytes of this key. Only the first @size bytes are used. + * @size: size of this key in bytes. The size of a standard key is fixed for a + * given crypto mode, but the size of a hardware-wrapped key can vary. + * @raw: the bytes of this key. Only the first @size bytes are significant. * * A blk_crypto_key is immutable once created, and many bios can reference it at * the same time. It must not be freed until all bios using it have completed @@ -49,7 +103,7 @@ struct blk_crypto_key { struct blk_crypto_config crypto_cfg; unsigned int data_unit_size_bits; unsigned int size; - u8 raw[BLK_CRYPTO_MAX_KEY_SIZE]; + u8 raw[BLK_CRYPTO_MAX_ANY_KEY_SIZE]; }; #define BLK_CRYPTO_MAX_IV_SIZE 32 @@ -87,7 +141,9 @@ bool bio_crypt_dun_is_contiguous(const struct bio_crypt_ctx *bc, unsigned int bytes, const u64 next_dun[BLK_CRYPTO_DUN_ARRAY_SIZE]); -int blk_crypto_init_key(struct blk_crypto_key *blk_key, const u8 *raw_key, +int blk_crypto_init_key(struct blk_crypto_key *blk_key, + const u8 *raw_key, size_t raw_key_size, + enum blk_crypto_key_type key_type, enum blk_crypto_mode_num crypto_mode, unsigned int dun_bytes, unsigned int data_unit_size); @@ -103,6 +159,10 @@ bool blk_crypto_config_supported_natively(struct block_device *bdev, bool blk_crypto_config_supported(struct block_device *bdev, const struct blk_crypto_config *cfg); +int blk_crypto_derive_sw_secret(struct block_device *bdev, + const u8 *eph_key, size_t eph_key_size, + u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]); + #else /* CONFIG_BLK_INLINE_ENCRYPTION */ static inline bool bio_has_crypt_ctx(struct bio *bio) From patchwork Fri Oct 11 18:54:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 834637 Received: from mail-wr1-f45.google.com (mail-wr1-f45.google.com [209.85.221.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E2EDF1D094A for ; Fri, 11 Oct 2024 18:54:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728672884; cv=none; b=FkOD0LPeg/H+foZPV68NG2sOb6WlG1qR/B50S5UFU11jhD2btpcYt8YhJ9Rs8WQpNFIyYxDm16MWYYJWECICJLLkJxgCsXOG8pQeklomPvK/8+LRJVi5Ibm3af0Zl6PkIV0do46P6qmCBd9o4Yo3capDW7932+4YWR1BfzF9avA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728672884; c=relaxed/simple; bh=TVcoi08YdOSb8oDH8EN+lfvTR+VBW0n8+wvckAnUAa4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ITSN2wJWSUmC8mgtqzxazfoeNUO64bbVr8Vd+wzfiuLW/D+7ds8WuxqjNlZ3GUI+bfyX93mOhp75CSIeJ77gegQZ16YDK08CueeFwljXWSGvKrpBlkesx+gjdhAOmCcHpd4OsEuZj4GWBroFbLlmvqqExI961SK9is5QER+ptoE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl; spf=none smtp.mailfrom=bgdev.pl; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b=s4n74iM3; arc=none smtp.client-ip=209.85.221.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b="s4n74iM3" Received: by mail-wr1-f45.google.com with SMTP id ffacd0b85a97d-37d3ecad390so2073049f8f.1 for ; Fri, 11 Oct 2024 11:54:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1728672876; x=1729277676; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=nZnC+NzMxbBNE8bYS/olhN0qtTPuhjTkO3+y4T7Jrac=; b=s4n74iM3kF2n0V+Jrcjc+f89xyxk6aoiJJqLONaAsFy1sxtAFGpnqlidtOp5Ma1DMm 9Bpr6ZGnqR3n9hc1lcZGqYYTC1gJaCSJHNuoZpQPzXQZti1frSWJLV3UNQhjLT4jnfyu CjnrjffrEqUUdrAcbKtoeDd93FymRH+dMXYIbRTaEaWpkzpfr5HumlFDxms+NPXIg24w IvZcVc1WN2F3khJamFgrnl2lqA3TOYGug+Utr/L0cf68GlEiTcByFFosAlsFdh4z3qGn 37VBLFONaLUNiPOiQ5dSw53CaVtfbF3MPq7Zsoti51lJQYm9duWFlMPgb+xDEqmaTG5O 0stA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1728672876; x=1729277676; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nZnC+NzMxbBNE8bYS/olhN0qtTPuhjTkO3+y4T7Jrac=; b=lwR9bODNsmqQizZ59CZXybTXqTcWzKP7l+U+cd1RHax3bFGVyqe6XqBXZURaaXv0+U KtzSruboavd6K21i/cwU9P0aC+31+o2KM/6teBJKZvQqAOzHatlYTMRu8SREQFd8bl/e OrwZsYtzlomGRyrFxY6Di6QeKJok5GZHMW5kgFFb0PENjkZybq2TEjGaUKPh2W/0ocdw DVILkliS/cwE34XAKdV3OWdIHPZ3QFOOgQCzJGE8DZp7e5UthMmSO+M1zP6Ei9z4c0kb iN373CJNxqzevbOxxx5Frm0gx2dibLNmAbcv1Y9cQWjs9asNVPPS4CRYWc1CbzqdJhOb WihQ== X-Forwarded-Encrypted: i=1; AJvYcCU2p7amkqlizyf64yWuOZNI+CHFrvYFDvf5siM7aqYuGpwPMTgZ075NmbD+juei0rR7aW3dMY6nFrVmXHq0@vger.kernel.org X-Gm-Message-State: AOJu0Yz2jhFCVSq08DpWPxz9J/yHU3QqdBqGdgsIUxsBMHjM34ravedl wyqUvXcSygRGu2f00OlsG1gwt4kUjYK9/JVaGQ+Qi3HV49/9HwixAXNCvPHmt+U= X-Google-Smtp-Source: AGHT+IHF5ftxwy6C2IV6BhdzepwOwmc8pV/1K2VFvT4bOGIqEF+YlIwsiJG8XtWohgCM+DxnW6PhCw== X-Received: by 2002:a5d:4b4f:0:b0:37c:ccba:8c93 with SMTP id ffacd0b85a97d-37d551d5520mr2941090f8f.11.1728672875839; Fri, 11 Oct 2024 11:54:35 -0700 (PDT) Received: from [127.0.1.1] ([2a01:cb1d:dc:7e00:68b8:bef:b7eb:538f]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-37d4b79fe7csm4559161f8f.70.2024.10.11.11.54.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Oct 2024 11:54:34 -0700 (PDT) From: Bartosz Golaszewski Date: Fri, 11 Oct 2024 20:54:04 +0200 Subject: [PATCH v7 05/17] ice, ufs, mmc: use the blk_crypto_key struct when programming the key Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241011-wrapped-keys-v7-5-e3f7a752059b@linaro.org> References: <20241011-wrapped-keys-v7-0-e3f7a752059b@linaro.org> In-Reply-To: <20241011-wrapped-keys-v7-0-e3f7a752059b@linaro.org> To: Jens Axboe , Jonathan Corbet , Alasdair Kergon , Mike Snitzer , Mikulas Patocka , Adrian Hunter , Asutosh Das , Ritesh Harjani , Ulf Hansson , Alim Akhtar , Avri Altman , Bart Van Assche , "James E.J. Bottomley" , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam , Dmitry Baryshkov , Gaurav Kashyap , Neil Armstrong Cc: linux-block@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, dm-devel@lists.linux.dev, linux-mmc@vger.kernel.org, linux-scsi@vger.kernel.org, linux-fscrypt@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-arm-msm@vger.kernel.org, Bartosz Golaszewski , Om Prakash Singh X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=9551; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=I7Y+KQKzlXr1sMzaRDIfaMwDopJDttwwaTz2q/TpDsE=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnCXRdiOyTz9952m6q9xkxcxzv5R+NuuY425uuP OZyG30oqOCJAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZwl0XQAKCRARpy6gFHHX cl3OD/4kJqfrmCHLUkuFbrjWMCbspjq53py6mnP6O8OqR0vXrvBsCuNYRAnLYHzQVo7s1ZcK31j A60GPeW7V9FlAw5gxHCWUkFYnPngMZCuLmrzicpBzg1Bfizq7BGdNLkXPj0VOIUP+J7WOSzCPSG p2uEisbzWamNpSd/h4Rpt3whOeMYFSBYp/4JIfB89EPCeqhz+5YSOGETtXqVwpCtFfqM1neM69g Z6DKCh6ew4BVBEEm/xQCIhBUI5AVW6HfDvOU5GOFyRY1u2SjhwRQnuMVJScU8PzLGOqPv3wGejN jTeDbzUrJJQI5nDjUK6n/gaxQ9YDkLeOR8oslD2UTSW4NDYIumd5bDFhnS2Kx9RXt87BQV9HbxP nwSNWHsksBQbFfZvdjO/jBqJ6MUNtWDY8VmC+whvmrpSCi2/0ot2hOGgnQUSgEsHewtFxkaqA5M SYQUYNFbZ7XNSG9IHYRj3Pn0wfL/VIQkYyHmq9NzopneTWIaUT/1qxEe0hK+THN5cfEffVIWc9h CKQ0xWvVqEukh40O4QkAw/9i6M9Ek0Zua34mxPoavEyjm+pNrSVAPpJNIPldLBFh4Ct/CmbJT0E p10ilYlAyg/TucqzYILf+qwjU35xjpaErDrmV55TRJjHPgUrp0AXsy+TcU7gw+1yOK5RdtY+WHz jlHMDFxePBkxvRA== X-Developer-Key: i=bartosz.golaszewski@linaro.org; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 From: Gaurav Kashyap The program key ops in the storage controller does not pass on the blk_crypto_key structure to ICE, this is okay with raw keys of standard AES XTS sizes. However, wrapped keyblobs can be of any size and in preparation for that, modify the ICE and storage controller APIs to accept blk_crypto_key which can carry larger keys and indicate their size. Reviewed-by: Om Prakash Singh Tested-by: Neil Armstrong Acked-by: Ulf Hansson # For MMC Reviewed-by: Bartosz Golaszewski Signed-off-by: Gaurav Kashyap Signed-off-by: Bartosz Golaszewski --- drivers/mmc/host/cqhci-crypto.c | 7 ++++--- drivers/mmc/host/cqhci.h | 2 ++ drivers/mmc/host/sdhci-msm.c | 6 ++++-- drivers/soc/qcom/ice.c | 6 +++--- drivers/ufs/core/ufshcd-crypto.c | 7 ++++--- drivers/ufs/host/ufs-qcom.c | 6 ++++-- include/soc/qcom/ice.h | 5 +++-- include/ufs/ufshcd.h | 1 + 8 files changed, 25 insertions(+), 15 deletions(-) diff --git a/drivers/mmc/host/cqhci-crypto.c b/drivers/mmc/host/cqhci-crypto.c index 6652982410ec..91da6de1d650 100644 --- a/drivers/mmc/host/cqhci-crypto.c +++ b/drivers/mmc/host/cqhci-crypto.c @@ -32,6 +32,7 @@ cqhci_host_from_crypto_profile(struct blk_crypto_profile *profile) } static int cqhci_crypto_program_key(struct cqhci_host *cq_host, + const struct blk_crypto_key *bkey, const union cqhci_crypto_cfg_entry *cfg, int slot) { @@ -39,7 +40,7 @@ static int cqhci_crypto_program_key(struct cqhci_host *cq_host, int i; if (cq_host->ops->program_key) - return cq_host->ops->program_key(cq_host, cfg, slot); + return cq_host->ops->program_key(cq_host, bkey, cfg, slot); /* Clear CFGE */ cqhci_writel(cq_host, 0, slot_offset + 16 * sizeof(cfg->reg_val[0])); @@ -99,7 +100,7 @@ static int cqhci_crypto_keyslot_program(struct blk_crypto_profile *profile, memcpy(cfg.crypto_key, key->raw, key->size); } - err = cqhci_crypto_program_key(cq_host, &cfg, slot); + err = cqhci_crypto_program_key(cq_host, key, &cfg, slot); memzero_explicit(&cfg, sizeof(cfg)); return err; @@ -113,7 +114,7 @@ static int cqhci_crypto_clear_keyslot(struct cqhci_host *cq_host, int slot) */ union cqhci_crypto_cfg_entry cfg = {}; - return cqhci_crypto_program_key(cq_host, &cfg, slot); + return cqhci_crypto_program_key(cq_host, NULL, &cfg, slot); } static int cqhci_crypto_keyslot_evict(struct blk_crypto_profile *profile, diff --git a/drivers/mmc/host/cqhci.h b/drivers/mmc/host/cqhci.h index fab9d74445ba..06099fd32f23 100644 --- a/drivers/mmc/host/cqhci.h +++ b/drivers/mmc/host/cqhci.h @@ -12,6 +12,7 @@ #include #include #include +#include #include /* registers */ @@ -291,6 +292,7 @@ struct cqhci_host_ops { void (*post_disable)(struct mmc_host *mmc); #ifdef CONFIG_MMC_CRYPTO int (*program_key)(struct cqhci_host *cq_host, + const struct blk_crypto_key *bkey, const union cqhci_crypto_cfg_entry *cfg, int slot); #endif void (*set_tran_desc)(struct cqhci_host *cq_host, u8 **desc, diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index e00208535bd1..b8770524c008 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -1859,6 +1859,7 @@ static __maybe_unused int sdhci_msm_ice_suspend(struct sdhci_msm_host *msm_host) * vendor-specific SCM calls for this; it doesn't support the standard way. */ static int sdhci_msm_program_key(struct cqhci_host *cq_host, + const struct blk_crypto_key *bkey, const union cqhci_crypto_cfg_entry *cfg, int slot) { @@ -1866,6 +1867,7 @@ static int sdhci_msm_program_key(struct cqhci_host *cq_host, struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); union cqhci_crypto_cap_entry cap; + u8 ice_key_size; /* Only AES-256-XTS has been tested so far. */ cap = cq_host->crypto_cap_array[cfg->crypto_cap_idx]; @@ -1873,11 +1875,11 @@ static int sdhci_msm_program_key(struct cqhci_host *cq_host, cap.key_size != CQHCI_CRYPTO_KEY_SIZE_256) return -EINVAL; + ice_key_size = QCOM_ICE_CRYPTO_KEY_SIZE_256; if (cfg->config_enable & CQHCI_CRYPTO_CONFIGURATION_ENABLE) return qcom_ice_program_key(msm_host->ice, QCOM_ICE_CRYPTO_ALG_AES_XTS, - QCOM_ICE_CRYPTO_KEY_SIZE_256, - cfg->crypto_key, + ice_key_size, bkey, cfg->data_unit_size, slot); else return qcom_ice_evict_key(msm_host->ice, slot); diff --git a/drivers/soc/qcom/ice.c b/drivers/soc/qcom/ice.c index 50be7a9274a1..4393262a1bf2 100644 --- a/drivers/soc/qcom/ice.c +++ b/drivers/soc/qcom/ice.c @@ -164,8 +164,8 @@ EXPORT_SYMBOL_GPL(qcom_ice_suspend); int qcom_ice_program_key(struct qcom_ice *ice, u8 algorithm_id, u8 key_size, - const u8 crypto_key[], u8 data_unit_size, - int slot) + const struct blk_crypto_key *bkey, + u8 data_unit_size, int slot) { struct device *dev = ice->dev; union { @@ -184,7 +184,7 @@ int qcom_ice_program_key(struct qcom_ice *ice, return -EINVAL; } - memcpy(key.bytes, crypto_key, AES_256_XTS_KEY_SIZE); + memcpy(key.bytes, bkey->raw, AES_256_XTS_KEY_SIZE); /* The SCM call requires that the key words are encoded in big endian */ for (i = 0; i < ARRAY_SIZE(key.words); i++) diff --git a/drivers/ufs/core/ufshcd-crypto.c b/drivers/ufs/core/ufshcd-crypto.c index 7d3a3e228db0..33083e0cad6e 100644 --- a/drivers/ufs/core/ufshcd-crypto.c +++ b/drivers/ufs/core/ufshcd-crypto.c @@ -18,6 +18,7 @@ static const struct ufs_crypto_alg_entry { }; static int ufshcd_program_key(struct ufs_hba *hba, + const struct blk_crypto_key *bkey, const union ufs_crypto_cfg_entry *cfg, int slot) { int i; @@ -27,7 +28,7 @@ static int ufshcd_program_key(struct ufs_hba *hba, ufshcd_hold(hba); if (hba->vops && hba->vops->program_key) { - err = hba->vops->program_key(hba, cfg, slot); + err = hba->vops->program_key(hba, bkey, cfg, slot); goto out; } @@ -89,7 +90,7 @@ static int ufshcd_crypto_keyslot_program(struct blk_crypto_profile *profile, memcpy(cfg.crypto_key, key->raw, key->size); } - err = ufshcd_program_key(hba, &cfg, slot); + err = ufshcd_program_key(hba, key, &cfg, slot); memzero_explicit(&cfg, sizeof(cfg)); return err; @@ -107,7 +108,7 @@ static int ufshcd_crypto_keyslot_evict(struct blk_crypto_profile *profile, */ union ufs_crypto_cfg_entry cfg = {}; - return ufshcd_program_key(hba, &cfg, slot); + return ufshcd_program_key(hba, NULL, &cfg, slot); } /* diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c index a5a0646bb80a..2f317a4c3edf 100644 --- a/drivers/ufs/host/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c @@ -150,6 +150,7 @@ static inline int ufs_qcom_ice_suspend(struct ufs_qcom_host *host) } static int ufs_qcom_ice_program_key(struct ufs_hba *hba, + const struct blk_crypto_key *bkey, const union ufs_crypto_cfg_entry *cfg, int slot) { @@ -157,6 +158,7 @@ static int ufs_qcom_ice_program_key(struct ufs_hba *hba, union ufs_crypto_cap_entry cap; bool config_enable = cfg->config_enable & UFS_CRYPTO_CONFIGURATION_ENABLE; + u8 ice_key_size; /* Only AES-256-XTS has been tested so far. */ cap = hba->crypto_cap_array[cfg->crypto_cap_idx]; @@ -164,11 +166,11 @@ static int ufs_qcom_ice_program_key(struct ufs_hba *hba, cap.key_size != UFS_CRYPTO_KEY_SIZE_256) return -EOPNOTSUPP; + ice_key_size = QCOM_ICE_CRYPTO_KEY_SIZE_256; if (config_enable) return qcom_ice_program_key(host->ice, QCOM_ICE_CRYPTO_ALG_AES_XTS, - QCOM_ICE_CRYPTO_KEY_SIZE_256, - cfg->crypto_key, + ice_key_size, bkey, cfg->data_unit_size, slot); else return qcom_ice_evict_key(host->ice, slot); diff --git a/include/soc/qcom/ice.h b/include/soc/qcom/ice.h index 5870a94599a2..9dd835dba2a7 100644 --- a/include/soc/qcom/ice.h +++ b/include/soc/qcom/ice.h @@ -7,6 +7,7 @@ #define __QCOM_ICE_H__ #include +#include struct qcom_ice; @@ -30,8 +31,8 @@ int qcom_ice_resume(struct qcom_ice *ice); int qcom_ice_suspend(struct qcom_ice *ice); int qcom_ice_program_key(struct qcom_ice *ice, u8 algorithm_id, u8 key_size, - const u8 crypto_key[], u8 data_unit_size, - int slot); + const struct blk_crypto_key *bkey, + u8 data_unit_size, int slot); int qcom_ice_evict_key(struct qcom_ice *ice, int slot); struct qcom_ice *of_qcom_ice_get(struct device *dev); #endif /* __QCOM_ICE_H__ */ diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index a95282b9f743..331b1ed171da 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -370,6 +370,7 @@ struct ufs_hba_variant_ops { struct devfreq_dev_profile *profile, struct devfreq_simple_ondemand_data *data); int (*program_key)(struct ufs_hba *hba, + const struct blk_crypto_key *bkey, const union ufs_crypto_cfg_entry *cfg, int slot); int (*fill_crypto_prdt)(struct ufs_hba *hba, const struct bio_crypt_ctx *crypt_ctx, From patchwork Fri Oct 11 18:54:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 834635 Received: from mail-wr1-f50.google.com (mail-wr1-f50.google.com [209.85.221.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7D9B81D0B93 for ; Fri, 11 Oct 2024 18:54:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728672888; cv=none; b=NnVZjcuA3k4GVXyffkk1PM1xsZ7vOk7cBavxwszKxEojmfcP4WDYydKyjAbPJh+g28y7hlYZZA/tAMz30IJk28UdW+eGiyDcQchxkcxkNKlcMz3EX8qm7aZ0bSi5DCsye6AGSMimW8BblBKq99OVhaQ8whhEVVuMnwb5kxj7coo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728672888; c=relaxed/simple; bh=mo5nSpTL1mpJJWn0T0y9bjvmiNBacX4BLWzH1Oz6MfM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=H+lXRiPnjr9c5DXVb5PFU/7VaLx84Dqfu8E3UvmVMA1BGpUXyQbswdvsXcSnRzo42sn4gC3Dit1ElAeqpkTVV4nilsfdPxu0j/YNEI3h6DAceDvVvjBkCA3dd4vPuargiKng2dIjmaIVnuEd4RPeb7KcUZBTJhzPsm3zUhxq8qY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl; spf=none smtp.mailfrom=bgdev.pl; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b=GmDB+U0v; arc=none smtp.client-ip=209.85.221.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b="GmDB+U0v" Received: by mail-wr1-f50.google.com with SMTP id ffacd0b85a97d-37cea34cb57so1422915f8f.0 for ; Fri, 11 Oct 2024 11:54:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1728672877; x=1729277677; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=4Wcsu/BoMjTUXPdQVFWnBAqjwXxZAUnjwMCSCOoMsVU=; b=GmDB+U0v3pGEOuMXnP75axNhqK3Mk2RDsFZe6/nnFuVRRB91lejFhJAXbxh+0DPXEB ZQX+cgIwNNIHTxeSfS6Yd/Wp1ygOYTUnCAcHK5skGhUPcemv4zIGVAroMn6kSEf3VXQA ZO6AGLSdObmYhDK3w85a/tRNQnbo1gFrtgsZDpwIfCwrsor/8pE0oMmsMF/ZXplaDXhZ r3YpHblCZ62590niXPGnSwCoTFSQwLWInc2+2Kk66iv9GCLpTe/1+QoDQf7G6JSbETgB UiTyHNSvZJ52csBjv6Vu6Ly047AR+SpABHgtX+lS2sgRNy1bfwnB7wdqKq9O75YBzRnh Wmjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1728672877; x=1729277677; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=4Wcsu/BoMjTUXPdQVFWnBAqjwXxZAUnjwMCSCOoMsVU=; b=jw5fOf600xVp+aKur4/4sjs8SUe3KcMtdAinp+hx+6SNjgr5CkjSjA2VZKxAOk5Xqz p8hWeHl0fbj76CXvnf3WrLgZKKbosd16A7apr0xCy+ErCh8kDO8A5UaybOEpoKi1Uzk2 pmpsw8VlE9DMqQgvyrneZ6LhvHXDaCKwSgZH5J/94kJCyeHzwiSbK+RTt91o/c7pmMwG RPHl00Uo4Nf+iICItudZ6Owhqu44CZKpQBu+N9SH8eiUVzjjBsNH0kCCb+M1+UKl4jBK ikrB5iZSyFcUwLt/bueuvVCKqRQai08n3Hx19wWyJYKYqd2BX0fd+AOFfr5NYhp+Z4QA vs8g== X-Forwarded-Encrypted: i=1; AJvYcCWVEmGOrpiwt8PTmZF89dzDkY98r6uoD3yiYQqQV/v8bYsgajy+9XLZfj+Qo0zGpCvls5lZcRFTJNFISHGd@vger.kernel.org X-Gm-Message-State: AOJu0Yxu72Py2pJGty06+zS+sAwg+G7K7dcpFZX+fZ81h3gcDg6BOnjk cnivgH/azGQxi0b2AX5xnM6YaYlcNw/N3dJdBhjj4Un3rRtxHLEaFhej4iWxnPk= X-Google-Smtp-Source: AGHT+IGJRtphPqQxoohXNT7jWzpAxRyc8QWyHB5IpQBS4Uxzri1qnnK+OyqNQYC9Dlk/8fepYxnZqg== X-Received: by 2002:a5d:4d4a:0:b0:37d:4527:ba1c with SMTP id ffacd0b85a97d-37d5531a0a2mr2265033f8f.49.1728672877197; Fri, 11 Oct 2024 11:54:37 -0700 (PDT) Received: from [127.0.1.1] ([2a01:cb1d:dc:7e00:68b8:bef:b7eb:538f]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-37d4b79fe7csm4559161f8f.70.2024.10.11.11.54.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Oct 2024 11:54:36 -0700 (PDT) From: Bartosz Golaszewski Date: Fri, 11 Oct 2024 20:54:05 +0200 Subject: [PATCH v7 06/17] firmware: qcom: scm: add a call for deriving the software secret Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241011-wrapped-keys-v7-6-e3f7a752059b@linaro.org> References: <20241011-wrapped-keys-v7-0-e3f7a752059b@linaro.org> In-Reply-To: <20241011-wrapped-keys-v7-0-e3f7a752059b@linaro.org> To: Jens Axboe , Jonathan Corbet , Alasdair Kergon , Mike Snitzer , Mikulas Patocka , Adrian Hunter , Asutosh Das , Ritesh Harjani , Ulf Hansson , Alim Akhtar , Avri Altman , Bart Van Assche , "James E.J. Bottomley" , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam , Dmitry Baryshkov , Gaurav Kashyap , Neil Armstrong Cc: linux-block@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, dm-devel@lists.linux.dev, linux-mmc@vger.kernel.org, linux-scsi@vger.kernel.org, linux-fscrypt@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-arm-msm@vger.kernel.org, Bartosz Golaszewski X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4695; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=ENWj0XXoRMUHozAURbUmYvdkrtvsQDUyvPd8uYMRh8g=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnCXRd+XGr6al4uOgJo7BV6uBYWZBSMD7qzVQ0E V8+Hic+dlyJAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZwl0XQAKCRARpy6gFHHX ckIxEADQN44/Z+EkIi7nPzdOyuBr39lwQhprzHZAE44Ha2zq+j8DRjjBRWzCQFT49F9N2v/18zn M6+0kg08r8t1FeTBnSX+qxU2Mj47YRkUeAWJnTb1FocoJDf+o42TRORhFb3DCdJsCP/m1zqaIFD xdY+pbui5IXjGk0+Bf4LIUyIPdJj6J+kLvBEleoOZtjl+3q35YLawYYWPIowUjP0xvZIf+fYGQ2 HeO6MfS2/ztGuVDcAfDQ4ezMHMnh1i4nQqNeNomY6zIqgvvmdn3Iy7HQ2HZvocg1Zbnr+59aM1M DF6/dwYg021Vm5FtIHFpnj2TNVpQqObSg0RaK20ht8Ak607vNjFncCORRYzNY2jkVbdQZ1PLXa7 mBX2iaWk65PAOUG/PDiidPEwmhbnGSC7CKNxNeVwygINv0//M4NHOu6LatO7uX5DMcmUtIHFtdi SQApLuH3oyOo8Op8zmhNLl/UXewgMJeyUxxSLMJ9c7JIuKBpCdij9IFTGLBPqvVTj3gdCuC6agl KszKrPtk9TNyQ0zvwjQ+Wx2tlN9/mBEDnYQ8ZDqwOGS9QmW3EPW6edbRtq79ZzfgvaiGNBUM6yB 591vPuaYzAwSGiWgSPdWADhem9W9DwxYcmbv6w8BhoRERNajoJClgft8rVtmuNrZdOW3TYTljTt omvxX48juAN4xtQ== X-Developer-Key: i=bartosz.golaszewski@linaro.org; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 From: Gaurav Kashyap Inline storage encryption may require deriving a software secret from storage keys added to the kernel. For raw keys, this can be directly done in the kernel as keys are not encrypted in memory. However, hardware wrapped keys can only be unwrapped by the HW wrapping entity. In case of Qualcomm's wrapped key solution, this is done by the Hardware Key Manager (HWKM) from Trustzone. Add a new SCM call which provides a hook to the software secret crypto profile API provided by the block layer. Tested-by: Neil Armstrong Signed-off-by: Gaurav Kashyap Reviewed-by: Dmitry Baryshkov Signed-off-by: Bartosz Golaszewski --- drivers/firmware/qcom/qcom_scm.c | 65 ++++++++++++++++++++++++++++++++++ drivers/firmware/qcom/qcom_scm.h | 1 + include/linux/firmware/qcom/qcom_scm.h | 2 ++ 3 files changed, 68 insertions(+) diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index ebb58bd63eda..de90d21c2dfa 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -1252,6 +1252,71 @@ int qcom_scm_ice_set_key(u32 index, const u8 *key, u32 key_size, } EXPORT_SYMBOL_GPL(qcom_scm_ice_set_key); +/** + * qcom_scm_derive_sw_secret() - Derive software secret from wrapped key + * @wkey: the hardware wrapped key inaccessible to software + * @wkey_size: size of the wrapped key + * @sw_secret: the secret to be derived which is exactly the secret size + * @sw_secret_size: size of the sw_secret + * + * Derive a software secret from a hardware wrapped key for software crypto + * operations. + * For wrapped keys, the key needs to be unwrapped, in order to derive a + * software secret, which can be done in the hardware from a secure execution + * environment. + * + * For more information on sw secret, please refer to "Hardware-wrapped keys" + * section of Documentation/block/inline-encryption.rst. + * + * Return: 0 on success; -errno on failure. + */ +int qcom_scm_derive_sw_secret(const u8 *wkey, size_t wkey_size, + u8 *sw_secret, size_t sw_secret_size) +{ + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_ES, + .cmd = QCOM_SCM_ES_DERIVE_SW_SECRET, + .arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_RW, + QCOM_SCM_VAL, QCOM_SCM_RW, + QCOM_SCM_VAL), + .args[1] = wkey_size, + .args[3] = sw_secret_size, + .owner = ARM_SMCCC_OWNER_SIP, + }; + + int ret; + + void *wkey_buf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool, + wkey_size, + GFP_KERNEL); + if (!wkey_buf) + return -ENOMEM; + + void *secret_buf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool, + sw_secret_size, + GFP_KERNEL); + if (!secret_buf) { + ret = -ENOMEM; + goto out_free_wrapped; + } + + memcpy(wkey_buf, wkey, wkey_size); + desc.args[0] = qcom_tzmem_to_phys(wkey_buf); + desc.args[2] = qcom_tzmem_to_phys(secret_buf); + + ret = qcom_scm_call(__scm->dev, &desc, NULL); + if (!ret) + memcpy(sw_secret, secret_buf, sw_secret_size); + + memzero_explicit(secret_buf, sw_secret_size); + +out_free_wrapped: + memzero_explicit(wkey_buf, wkey_size); + + return ret; +} +EXPORT_SYMBOL_GPL(qcom_scm_derive_sw_secret); + /** * qcom_scm_hdcp_available() - Check if secure environment supports HDCP. * diff --git a/drivers/firmware/qcom/qcom_scm.h b/drivers/firmware/qcom/qcom_scm.h index 685b8f59e7a6..5a98b90ece32 100644 --- a/drivers/firmware/qcom/qcom_scm.h +++ b/drivers/firmware/qcom/qcom_scm.h @@ -127,6 +127,7 @@ struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void); #define QCOM_SCM_SVC_ES 0x10 /* Enterprise Security */ #define QCOM_SCM_ES_INVALIDATE_ICE_KEY 0x03 #define QCOM_SCM_ES_CONFIG_SET_ICE_KEY 0x04 +#define QCOM_SCM_ES_DERIVE_SW_SECRET 0x07 #define QCOM_SCM_SVC_HDCP 0x11 #define QCOM_SCM_HDCP_INVOKE 0x01 diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h index 9f14976399ab..0ef4415e2023 100644 --- a/include/linux/firmware/qcom/qcom_scm.h +++ b/include/linux/firmware/qcom/qcom_scm.h @@ -103,6 +103,8 @@ bool qcom_scm_ice_available(void); int qcom_scm_ice_invalidate_key(u32 index); int qcom_scm_ice_set_key(u32 index, const u8 *key, u32 key_size, enum qcom_scm_ice_cipher cipher, u32 data_unit_size); +int qcom_scm_derive_sw_secret(const u8 *wkey, size_t wkey_size, + u8 *sw_secret, size_t sw_secret_size); bool qcom_scm_hdcp_available(void); int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp); From patchwork Fri Oct 11 18:54:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 834636 Received: from mail-wr1-f48.google.com (mail-wr1-f48.google.com [209.85.221.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 969521D048B for ; Fri, 11 Oct 2024 18:54:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728672889; cv=none; b=hLR0lPb1jrrMdgIGNbfFPNL5gTYuxdLZqR1BRPX9cMqnSg2Stv+qzc3Yz8VkTxc0FiWjWhpR8grvcFSEe0Oot3ubHxS6osCejIqICzO6F2Lw0J18gHAemhpvNzVADAyDh51iSZGY7KELNFo0ernTzekzxDZFCQAEYVrZ/vogFCs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728672889; c=relaxed/simple; bh=4tSMqXGX/3ETUOMKuUjYph4+Zl/mK4LSfM1HiT+8vN0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MtK/n9BEBo26YU3F3zg3E+HmftIfcXpHFjxYjApWPFe2uCZ8bsq06DvG3B6CCObo4vVZYuUbTrSe3fi8dGChXnKJRDIaqd4cpTGRmSeKWN6cCrZ33iF1u2nlJynB+an6wZeWpuRbFaqbua5QQe7SKjTLCAinLXHUb1ZTpgHFzpA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl; spf=none smtp.mailfrom=bgdev.pl; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b=umaHx467; arc=none smtp.client-ip=209.85.221.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b="umaHx467" Received: by mail-wr1-f48.google.com with SMTP id ffacd0b85a97d-37d538fe5f2so856610f8f.2 for ; Fri, 11 Oct 2024 11:54:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1728672878; x=1729277678; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=1fBQGAiKArd769nsi4mYfjlrkxDV83MQGk5ueRBcZsk=; b=umaHx467lXWMi46aZlOfBezqLWZ1q5xyEAA+tq3PLahUt90KQ9iQzPmkAm8BMu10DY GC0KP3yKtXSoW7AOMeq7QIK0ply7chYBktWJpcl71myXx+y/QiT+2tadri2/lmZMj4Iv JT8KeMb1ACojKswVSj9Ln61J/sMZjSqdqIoHLJeXxCkNiZtn188oT8QLg2t1KaKIxjnl kykTnDCy1n0NP92pMsxTK8asnOKP8UoZOlTBNNLox4o4jO8jbfX9sjchXO2NamBdlR+v TyLlkaLs/LTi1voUids4DSe89P+xu9XR1fg467JLaYjsnTljO3yzAh5MdS4uhDaPKV2k s38Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1728672878; x=1729277678; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1fBQGAiKArd769nsi4mYfjlrkxDV83MQGk5ueRBcZsk=; b=gmL9qe93eehgXstLd6mwxJVf9uPgv2zcyimOTNFIQeCABbX8Bt8YO7kw7vMy8ZMttO hBS7c7A9QihxsFlQ+bWv8Ddl3Dh9UE9qNo7a5OnJz71yE0RIRJ0vDc34RowkLVzGqW1d 52MQc1vkrDGFn+q8YSPyNJ6ydfAVhK0B0lnpsVuQQI7deOXK0OyfSFWZQ7sSO9ND2p2j 6LU3OcstKk3U05hoKyBmPP2ALD7HddJnzpVSxOqqlw8PV4t1xetsXjOwUf0b0bexBraF g977SkDS4P6L4eetAIjOEzTaU1CsgfJXvgig913iRfN4gp04V6IMH0w+K6VgWoWxPPoJ 8CGw== X-Forwarded-Encrypted: i=1; AJvYcCWA/0VBXTqHdM+WRrJcGz5INXISt6ZasIcosREGRj1wH0czk+iZJjbJzFWmPU8zhOnkYSapmc+KHAvNzDXn@vger.kernel.org X-Gm-Message-State: AOJu0YxVABIneBvBz11bbQpa+sg6ql/GkTK90bsxVJY1XNz2ouMX3zx0 iGMaWajf84zI+9I+tMbdpOhK+gXcwGPM9AvXGRVpJobcK1QKFeZUkHhD9tNCHWw= X-Google-Smtp-Source: AGHT+IGGQ6RiFp9mxtQK4IZAf9S/fcCDsP1OdM98Kb3iWa5znBD4baXzZoXLBsdvuBRnC9GKLmTIGA== X-Received: by 2002:a05:6000:18c:b0:37d:5173:7a54 with SMTP id ffacd0b85a97d-37d552d8858mr2567965f8f.52.1728672878481; Fri, 11 Oct 2024 11:54:38 -0700 (PDT) Received: from [127.0.1.1] ([2a01:cb1d:dc:7e00:68b8:bef:b7eb:538f]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-37d4b79fe7csm4559161f8f.70.2024.10.11.11.54.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Oct 2024 11:54:38 -0700 (PDT) From: Bartosz Golaszewski Date: Fri, 11 Oct 2024 20:54:06 +0200 Subject: [PATCH v7 07/17] firmware: qcom: scm: add calls for creating, preparing and importing keys Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241011-wrapped-keys-v7-7-e3f7a752059b@linaro.org> References: <20241011-wrapped-keys-v7-0-e3f7a752059b@linaro.org> In-Reply-To: <20241011-wrapped-keys-v7-0-e3f7a752059b@linaro.org> To: Jens Axboe , Jonathan Corbet , Alasdair Kergon , Mike Snitzer , Mikulas Patocka , Adrian Hunter , Asutosh Das , Ritesh Harjani , Ulf Hansson , Alim Akhtar , Avri Altman , Bart Van Assche , "James E.J. Bottomley" , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam , Dmitry Baryshkov , Gaurav Kashyap , Neil Armstrong Cc: linux-block@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, dm-devel@lists.linux.dev, linux-mmc@vger.kernel.org, linux-scsi@vger.kernel.org, linux-fscrypt@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-arm-msm@vger.kernel.org, Bartosz Golaszewski X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=8044; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=n2w7tDh91QSO/VCvctNHCH3FCBZSppE4FqQ9BuGYdig=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnCXRedmNOyQclM3efsfE1xIzmfzcXdAdvsiCds Cw67I+4UIiJAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZwl0XgAKCRARpy6gFHHX cjVMEAC8WumT6S/Z4BadeUEP7I8IKC7ktgYxERz/FB8eBThq9vc1sNwu+iR5IW/En7JNlHMCbj5 870up/MuITOauIGZE/0pmFqXz7NXBdNiUVjtorypetGopjwyHcu73WVV8LVKnAG/dGrM/cryiEJ b1/FPitB6ChC5fPBAL+xClNbrAIIDSUtEufarldvQqg87+Lj6haKsFewFASHBvK2B0zGynXMm6j Qi+VpJglGqh0LhNGzCjfx4fysYcVa00IxDlha2JzITaVW7nlDFSJr47JmL/EkKJ87+MtqkU+9Ln wBre94tWjPhDKZWMUUayv4bCWFoSsYLdCFLz50+fAdPbWtQnMXMAjZ/6ZF1/P0reT6w3r9oBzZ0 F1gw72q2uyGKaXOQQpEetJzMAQs8S5j8qFtB/qD8kGOLdOulIPhhWk5CGMydQjRv9uZuWC4ESgY PYbKiemrdDHj6rtuGagZOveE0T5rSPHUofNLc6gj6CcvtXfCgU5CUBo643htwa0An6rSGKpez5i Akh+O8ypOmGlkp/YNSu8QbMFAcweqtiGWxT7cUcs9gvIJ9Ybnb079sWTB8rcZozIWk9YVVEDoh1 RA5g0Yh4Eta7Q0KPovdRj+qAL4DqI0TnlC/EI4C/U0ztvzJQWk+E30xH/vHXLdApGMbXw9hF3Vr mt4tQmrehnlyCbA== X-Developer-Key: i=bartosz.golaszewski@linaro.org; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 From: Gaurav Kashyap Storage encryption has two IOCTLs for creating, importing and preparing keys for encryption. For wrapped keys, these IOCTLs need to interface with Qualcomm's Trustzone. Add the following keys: generate_key: This is used to generate and return a longterm wrapped key. Trustzone achieves this by generating a key and then wrapping it using the Hawrdware Key Manager (HWKM), returning a wrapped keyblob. import_key: The functionality is similar to generate, but here: a raw key is imported into the HWKM and a longterm wrapped keyblob is returned. prepare_key: The longterm wrapped key from the import or generate calls is made further secure by rewrapping it with a per-boot, ephemeral wrapped key before installing it in the kernel for programming into ICE. Tested-by: Neil Armstrong Signed-off-by: Gaurav Kashyap [Bartosz: improve kerneldocs, fix hex values coding style, rewrite commit message] Co-developed-by: Bartosz Golaszewski Signed-off-by: Bartosz Golaszewski --- drivers/firmware/qcom/qcom_scm.c | 161 +++++++++++++++++++++++++++++++++ drivers/firmware/qcom/qcom_scm.h | 3 + include/linux/firmware/qcom/qcom_scm.h | 5 + 3 files changed, 169 insertions(+) diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index de90d21c2dfa..3a59fd2a45b5 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -1317,6 +1317,167 @@ int qcom_scm_derive_sw_secret(const u8 *wkey, size_t wkey_size, } EXPORT_SYMBOL_GPL(qcom_scm_derive_sw_secret); +/** + * qcom_scm_generate_ice_key() - Generate a wrapped key for encryption. + * @lt_key: the wrapped key returned after key generation + * @lt_key_size: size of the wrapped key to be returned. + * + * Generate a key using the built-in HW module in the SoC. Wrap the key using + * the platform-specific Key Encryption Key and return to the caller. + * + * Return: 0 on success; -errno on failure. + */ +int qcom_scm_generate_ice_key(u8 *lt_key, size_t lt_key_size) +{ + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_ES, + .cmd = QCOM_SCM_ES_GENERATE_ICE_KEY, + .arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_RW, QCOM_SCM_VAL), + .args[1] = lt_key_size, + .owner = ARM_SMCCC_OWNER_SIP, + }; + + int ret; + + void *lt_key_buf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool, + lt_key_size, + GFP_KERNEL); + if (!lt_key_buf) + return -ENOMEM; + + desc.args[0] = qcom_tzmem_to_phys(lt_key_buf); + + ret = qcom_scm_call(__scm->dev, &desc, NULL); + if (!ret) + memcpy(lt_key, lt_key_buf, lt_key_size); + + memzero_explicit(lt_key_buf, lt_key_size); + + return ret; +} +EXPORT_SYMBOL_GPL(qcom_scm_generate_ice_key); + +/** + * qcom_scm_prepare_ice_key() - Get the per-boot ephemeral wrapped key + * @lt_key: the longterm wrapped key + * @lt_key_size: size of the wrapped key + * @eph_key: ephemeral wrapped key to be returned + * @eph_key_size: size of the ephemeral wrapped key + * + * Qualcomm wrapped keys (longterm keys) are rewrapped with a per-boot + * ephemeral key for added protection. These are ephemeral in nature as + * they are valid only for that boot. + * + * Retrieve the key wrapped with the per-boot ephemeral key and return it to + * the caller. + * + * Return: 0 on success; -errno on failure. + */ +int qcom_scm_prepare_ice_key(const u8 *lt_key, size_t lt_key_size, + u8 *eph_key, size_t eph_key_size) +{ + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_ES, + .cmd = QCOM_SCM_ES_PREPARE_ICE_KEY, + .arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_RO, + QCOM_SCM_VAL, QCOM_SCM_RW, + QCOM_SCM_VAL), + .args[1] = lt_key_size, + .args[3] = eph_key_size, + .owner = ARM_SMCCC_OWNER_SIP, + }; + + int ret; + + void *lt_key_buf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool, + lt_key_size, + GFP_KERNEL); + if (!lt_key_buf) + return -ENOMEM; + + void *eph_key_buf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool, + eph_key_size, + GFP_KERNEL); + if (!eph_key_buf) { + ret = -ENOMEM; + goto out_free_longterm; + } + + memcpy(lt_key_buf, lt_key, lt_key_size); + desc.args[0] = qcom_tzmem_to_phys(lt_key_buf); + desc.args[2] = qcom_tzmem_to_phys(eph_key_buf); + + ret = qcom_scm_call(__scm->dev, &desc, NULL); + if (!ret) + memcpy(eph_key, eph_key_buf, eph_key_size); + + memzero_explicit(eph_key_buf, eph_key_size); + +out_free_longterm: + memzero_explicit(lt_key_buf, lt_key_size); + + return ret; +} +EXPORT_SYMBOL_GPL(qcom_scm_prepare_ice_key); + +/** + * qcom_scm_import_ice_key() - Import a wrapped key for encryption + * @imp_key: the raw key that is imported + * @imp_key_size: size of the key to be imported + * @lt_key: the wrapped key to be returned + * @lt_key_size: size of the wrapped key + * + * Import a raw key and return a long-term wrapped key to the caller. + * + * Return: 0 on success; -errno on failure. + */ +int qcom_scm_import_ice_key(const u8 *imp_key, size_t imp_key_size, + u8 *lt_key, size_t lt_key_size) +{ + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_ES, + .cmd = QCOM_SCM_ES_IMPORT_ICE_KEY, + .arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_RO, + QCOM_SCM_VAL, QCOM_SCM_RW, + QCOM_SCM_VAL), + .args[1] = imp_key_size, + .args[3] = lt_key_size, + .owner = ARM_SMCCC_OWNER_SIP, + }; + + int ret; + + void *imp_key_buf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool, + imp_key_size, + GFP_KERNEL); + if (!imp_key_buf) + return -ENOMEM; + + void *lt_key_buf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool, + lt_key_size, + GFP_KERNEL); + if (!lt_key_buf) { + ret = -ENOMEM; + goto out_free_longterm; + } + + memcpy(imp_key_buf, imp_key, imp_key_size); + desc.args[0] = qcom_tzmem_to_phys(imp_key_buf); + desc.args[2] = qcom_tzmem_to_phys(lt_key_buf); + + ret = qcom_scm_call(__scm->dev, &desc, NULL); + if (!ret) + memcpy(lt_key, lt_key_buf, lt_key_size); + + memzero_explicit(lt_key_buf, lt_key_size); + +out_free_longterm: + memzero_explicit(imp_key_buf, imp_key_size); + + return ret; +} +EXPORT_SYMBOL_GPL(qcom_scm_import_ice_key); + /** * qcom_scm_hdcp_available() - Check if secure environment supports HDCP. * diff --git a/drivers/firmware/qcom/qcom_scm.h b/drivers/firmware/qcom/qcom_scm.h index 5a98b90ece32..85f46ae7bd37 100644 --- a/drivers/firmware/qcom/qcom_scm.h +++ b/drivers/firmware/qcom/qcom_scm.h @@ -128,6 +128,9 @@ struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void); #define QCOM_SCM_ES_INVALIDATE_ICE_KEY 0x03 #define QCOM_SCM_ES_CONFIG_SET_ICE_KEY 0x04 #define QCOM_SCM_ES_DERIVE_SW_SECRET 0x07 +#define QCOM_SCM_ES_GENERATE_ICE_KEY 0x08 +#define QCOM_SCM_ES_PREPARE_ICE_KEY 0x09 +#define QCOM_SCM_ES_IMPORT_ICE_KEY 0x0a #define QCOM_SCM_SVC_HDCP 0x11 #define QCOM_SCM_HDCP_INVOKE 0x01 diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h index 0ef4415e2023..b5ab39b35490 100644 --- a/include/linux/firmware/qcom/qcom_scm.h +++ b/include/linux/firmware/qcom/qcom_scm.h @@ -105,6 +105,11 @@ int qcom_scm_ice_set_key(u32 index, const u8 *key, u32 key_size, enum qcom_scm_ice_cipher cipher, u32 data_unit_size); int qcom_scm_derive_sw_secret(const u8 *wkey, size_t wkey_size, u8 *sw_secret, size_t sw_secret_size); +int qcom_scm_generate_ice_key(u8 *lt_key, size_t lt_key_size); +int qcom_scm_prepare_ice_key(const u8 *lt_key, size_t lt_key_size, + u8 *eph_key, size_t eph_size); +int qcom_scm_import_ice_key(const u8 *imp_key, size_t imp_size, + u8 *lt_key, size_t lt_key_size); bool qcom_scm_hdcp_available(void); int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp); From patchwork Fri Oct 11 18:54:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 834634 Received: from mail-wr1-f41.google.com (mail-wr1-f41.google.com [209.85.221.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BD22A1D0404 for ; Fri, 11 Oct 2024 18:54:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728672892; cv=none; b=E5erWE3ETtv1HpiJGYJndS6+i8eHX2WW8HB/W5UHik90mb1p2KUQYFbJ7nPsloyo0IOBXkf9yNv7wxwQdfb9Y+F6EVSY2rp9rN9OeAg11e1+yw4Bjluq+CgtQtIqCtMcp/DZkGwuO4nGe7zTYiKXtbsNdteCM7pMk8yBn72TiMA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728672892; c=relaxed/simple; bh=NTpnGYJWRKUfD2+EdtJmRcavDBWB/vbpL4lKlrJIiuI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZJMqHBjEbz5zkFxcKVT6aoRujtCzbI/aIxiK7duHAZ5UzOdeIT3QNBdDxQdBV5N5htfcMiIjGiQdxPqhlGdBW54GNxljqgD18cM1q68P1nolkhPjpXk0tDkEWDZsUhqgshKtTyXf021syCKg2UHE6DFAo11opf6t4MZs8uBzh5A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl; spf=none smtp.mailfrom=bgdev.pl; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b=FuVVJ4gn; arc=none smtp.client-ip=209.85.221.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b="FuVVJ4gn" Received: by mail-wr1-f41.google.com with SMTP id ffacd0b85a97d-37d5aedd177so518417f8f.1 for ; Fri, 11 Oct 2024 11:54:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1728672881; x=1729277681; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=QvGNvxvKM8eiH1ZuQL0JBic8eLP1K1xp7NCDrQaUBYs=; b=FuVVJ4gnPKq5xTqYItIXn8PImt5plWOvk+oynyYHUz/A4qhI9U8oAKL8gmyotcZhuY 6Qovssg3HWwLbO0JzCiz/JkV/SdntkAo2AntUa0yZhY1WHCyU99Gi7D/60DyswtzWCpv nP8glFOxzCn81vXgU4ysSZMl0ktvIB68UpN10+0NSZ1mKVGHK+Aq4JvwyhEzfX3UUSf3 4bk8iyw41aGWZJgRdJSEv6DL+QsGz05y6TXU9XOLYFXbiAmfTLPfHxCN5dEH6nBcTmOn iPOoH4RXL5tGy4moEUIEPPed2fEnqP666l8E89ZDtAF95GsPX52y8lHGvX/x+FwA5pEz ASrA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1728672881; x=1729277681; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=QvGNvxvKM8eiH1ZuQL0JBic8eLP1K1xp7NCDrQaUBYs=; b=S4ya/RR+IC/YaQxp+hejOqa4mD7E3mBZBcJZp3limjvl8cfewT6P7o28KsP/Nxe0W2 TmKSpQjkMxwiGu8+Lx8Py7zZPyyvK2U4gsRsnKaUYcQ6Sm4MO9sJkQzQhG2I2xEQUltt 4XqnvDiHUkehnGNJBLNP8OU5XbDpQqoK1b/dXskXZiPxSotcEcVOn0cToZEf/NnNnAh/ V4QLSBIkd7JdlRCelObOYJTGCX40b1KwRlMcp/Ot5LM5LwWT9OfZ6OHxlM44Qtip61lS Pyj0eRpUJfEEK2Tbj03SqUb8uCxygamSbkjBNlhWDLaxmsbS4w5/hL3HHfSN2FhNOHN8 /3cg== X-Forwarded-Encrypted: i=1; AJvYcCUDd+Iln3LkRu7spHnC1AzOeCLdNMD/DgrG4y1Mm9KrGpvzZuimxOPAg+hH6RaouAKFTjUntX7Hh3uHxmUR@vger.kernel.org X-Gm-Message-State: AOJu0YzPriVK2UTCX0xjmle+531/+uFir/2dWoYvwF5djx2YVS1Ur/PY EXkpZ0brM1oGAeNAlqBpBa/ojI4WCw/Rvax2cPu8o7Yac/doIXEzPxYuV/NPbIE= X-Google-Smtp-Source: AGHT+IFBiRHpA/2anQVcoQGSuXpNm6xFEP3FrWrt3y5o67BcMn10hdldcHKEx3xYiIax2LY/pbI/Mw== X-Received: by 2002:a5d:6e43:0:b0:37c:cee0:96e6 with SMTP id ffacd0b85a97d-37d551fc08dmr3069018f8f.27.1728672881110; Fri, 11 Oct 2024 11:54:41 -0700 (PDT) Received: from [127.0.1.1] ([2a01:cb1d:dc:7e00:68b8:bef:b7eb:538f]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-37d4b79fe7csm4559161f8f.70.2024.10.11.11.54.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Oct 2024 11:54:40 -0700 (PDT) From: Bartosz Golaszewski Date: Fri, 11 Oct 2024 20:54:08 +0200 Subject: [PATCH v7 09/17] soc: qcom: ice: add HWKM support to the ICE driver Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241011-wrapped-keys-v7-9-e3f7a752059b@linaro.org> References: <20241011-wrapped-keys-v7-0-e3f7a752059b@linaro.org> In-Reply-To: <20241011-wrapped-keys-v7-0-e3f7a752059b@linaro.org> To: Jens Axboe , Jonathan Corbet , Alasdair Kergon , Mike Snitzer , Mikulas Patocka , Adrian Hunter , Asutosh Das , Ritesh Harjani , Ulf Hansson , Alim Akhtar , Avri Altman , Bart Van Assche , "James E.J. Bottomley" , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam , Dmitry Baryshkov , Gaurav Kashyap , Neil Armstrong Cc: linux-block@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, dm-devel@lists.linux.dev, linux-mmc@vger.kernel.org, linux-scsi@vger.kernel.org, linux-fscrypt@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-arm-msm@vger.kernel.org, Bartosz Golaszewski X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=9572; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=JLFG06y2/CVmmFjvX7qoJO0lgzWocHfOpOak0flGkYo=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnCXRfZrb1iPof5VSEAFaweN9V67nZlKlXvIT5l mb4JDKqcEGJAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZwl0XwAKCRARpy6gFHHX ckF+D/4/aOLiX8hPp2gLDvruhIs8jUH+HhEzOeWHciDZ6eSVZMCq0pQYnVJTFWSkPTBHtqj92tb E2pXCORkPeaSWPxllo4Culhn4ZnQ7sqCBSj4H/KMh4nncMpqzhJYa9PyW+N12WKn+MKQt2tJr7A 82psPAxjevYV+zwxyrXCQcZhTXjpA8V3IsfAi3SHqaPgL4NDf/zwoH1nUUXJgUi8FHPGjeNnPVE RMOMw6NmN2NTQ7wrvt8BVfEe1M0uleVziiOgoukqij5YIQUg4iXhBGp7B/D/jbhb4PFjBOrgQwf bn2o83MhS8JlEUBpGanjcZ7VXWWXj4aMbpIwYZDMmE3JsE6LqiSdMnECzW6eZX9rGfKZm6OO+Cg AKh+WuKeSFQh8S9AEzLwiksVTXWF813eCEoGwc7jeBKWb9n/5jXRx4o7A1SDyn8/k2kSufs9CAz TzpseGhUktFPXr9q97H6/w82YFabqXwCMUYmNJlU2CaoXQ7CzsuZGv3yMD3N4dPYkZJSmGfQvTv JqY9C+vIKmPrOrecRDaXOpVHHA6nAmcu4Qovy8jZHoNVSH4mcY2RTjcU+V6zVY7fmySoSkjeI+B AXisxiWsMgirLiDHzowjtzSIMBZeZ+Ei9kWQ7AUR8vHzxF8T3imurZ90C1oZmb/uhV9BhK1sr40 z23KO6zQN05LMLg== X-Developer-Key: i=bartosz.golaszewski@linaro.org; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 From: Gaurav Kashyap Qualcomm's ICE (Inline Crypto Engine) contains a proprietary key management hardware called Hardware Key Manager (HWKM). Add HWKM support to the ICE driver if it is available on the platform. HWKM primarily provides hardware wrapped key support where the ICE (storage) keys are not available in software and instead protected in hardware. When HWKM software support is not fully available (from Trustzone), there can be a scenario where the ICE hardware supports HWKM, but it cannot be used for wrapped keys. In this case, raw keys have to be used without using the HWKM. We query the TZ at run-time to find out whether wrapped keys support is available. Tested-by: Neil Armstrong Signed-off-by: Gaurav Kashyap Signed-off-by: Bartosz Golaszewski --- drivers/soc/qcom/ice.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++-- include/soc/qcom/ice.h | 1 + 2 files changed, 149 insertions(+), 4 deletions(-) diff --git a/drivers/soc/qcom/ice.c b/drivers/soc/qcom/ice.c index 4393262a1bf2..667d993694ac 100644 --- a/drivers/soc/qcom/ice.c +++ b/drivers/soc/qcom/ice.c @@ -27,6 +27,40 @@ #define QCOM_ICE_REG_FUSE_SETTING 0x0010 #define QCOM_ICE_REG_BIST_STATUS 0x0070 #define QCOM_ICE_REG_ADVANCED_CONTROL 0x1000 +#define QCOM_ICE_REG_CONTROL 0x0 +/* QCOM ICE HWKM registers */ +#define QCOM_ICE_REG_HWKM_TZ_KM_CTL 0x1000 +#define QCOM_ICE_REG_HWKM_TZ_KM_STATUS 0x1004 +#define QCOM_ICE_REG_HWKM_BANK0_BANKN_IRQ_STATUS 0x2008 +#define QCOM_ICE_REG_HWKM_BANK0_BBAC_0 0x5000 +#define QCOM_ICE_REG_HWKM_BANK0_BBAC_1 0x5004 +#define QCOM_ICE_REG_HWKM_BANK0_BBAC_2 0x5008 +#define QCOM_ICE_REG_HWKM_BANK0_BBAC_3 0x500C +#define QCOM_ICE_REG_HWKM_BANK0_BBAC_4 0x5010 + +/* QCOM ICE HWKM reg vals */ +#define QCOM_ICE_HWKM_BIST_DONE_V1 BIT(16) +#define QCOM_ICE_HWKM_BIST_DONE_V2 BIT(9) +#define QCOM_ICE_HWKM_BIST_DONE(ver) QCOM_ICE_HWKM_BIST_DONE_V##ver + +#define QCOM_ICE_HWKM_CRYPTO_BIST_DONE_V1 BIT(14) +#define QCOM_ICE_HWKM_CRYPTO_BIST_DONE_V2 BIT(7) +#define QCOM_ICE_HWKM_CRYPTO_BIST_DONE(v) QCOM_ICE_HWKM_CRYPTO_BIST_DONE_V##v + +#define QCOM_ICE_HWKM_BOOT_CMD_LIST1_DONE BIT(2) +#define QCOM_ICE_HWKM_BOOT_CMD_LIST0_DONE BIT(1) +#define QCOM_ICE_HWKM_KT_CLEAR_DONE BIT(0) + +#define QCOM_ICE_HWKM_BIST_VAL(v) (QCOM_ICE_HWKM_BIST_DONE(v) | \ + QCOM_ICE_HWKM_CRYPTO_BIST_DONE(v) | \ + QCOM_ICE_HWKM_BOOT_CMD_LIST1_DONE | \ + QCOM_ICE_HWKM_BOOT_CMD_LIST0_DONE | \ + QCOM_ICE_HWKM_KT_CLEAR_DONE) + +#define QCOM_ICE_HWKM_V1_STANDARD_MODE_VAL (BIT(0) | BIT(1) | BIT(2)) +#define QCOM_ICE_HWKM_V2_STANDARD_MODE_MASK GENMASK(31, 1) +#define QCOM_ICE_HWKM_DISABLE_CRC_CHECKS_VAL (BIT(1) | BIT(2)) +#define QCOM_ICE_HWKM_RSP_FIFO_CLEAR_VAL BIT(3) /* BIST ("built-in self-test") status flags */ #define QCOM_ICE_BIST_STATUS_MASK GENMASK(31, 28) @@ -35,6 +69,9 @@ #define QCOM_ICE_FORCE_HW_KEY0_SETTING_MASK 0x2 #define QCOM_ICE_FORCE_HW_KEY1_SETTING_MASK 0x4 +#define QCOM_ICE_HWKM_REG_OFFSET 0x8000 +#define HWKM_OFFSET(reg) ((reg) + QCOM_ICE_HWKM_REG_OFFSET) + #define qcom_ice_writel(engine, val, reg) \ writel((val), (engine)->base + (reg)) @@ -47,6 +84,9 @@ struct qcom_ice { struct device_link *link; struct clk *core_clk; + u8 hwkm_version; + bool use_hwkm; + bool hwkm_init_complete; }; static bool qcom_ice_check_supported(struct qcom_ice *ice) @@ -64,8 +104,21 @@ static bool qcom_ice_check_supported(struct qcom_ice *ice) return false; } - dev_info(dev, "Found QC Inline Crypto Engine (ICE) v%d.%d.%d\n", - major, minor, step); + if (major >= 4 || (major == 3 && minor == 2 && step >= 1)) + ice->hwkm_version = 2; + else if (major == 3 && minor == 2) + ice->hwkm_version = 1; + else + ice->hwkm_version = 0; + + if (ice->hwkm_version == 0) + ice->use_hwkm = false; + + dev_info(dev, "Found QC Inline Crypto Engine (ICE) v%d.%d.%d, HWKM v%d\n", + major, minor, step, ice->hwkm_version); + + if (!ice->use_hwkm) + dev_info(dev, "QC ICE HWKM (Hardware Key Manager) not used/supported"); /* If fuses are blown, ICE might not work in the standard way. */ regval = qcom_ice_readl(ice, QCOM_ICE_REG_FUSE_SETTING); @@ -114,27 +167,106 @@ static void qcom_ice_optimization_enable(struct qcom_ice *ice) * fails, so we needn't do it in software too, and (c) properly testing * storage encryption requires testing the full storage stack anyway, * and not relying on hardware-level self-tests. + * + * However, we still care about if HWKM BIST failed (when supported) as + * important functionality would fail later, so disable hwkm on failure. */ static int qcom_ice_wait_bist_status(struct qcom_ice *ice) { u32 regval; + u32 bist_done_val; int err; err = readl_poll_timeout(ice->base + QCOM_ICE_REG_BIST_STATUS, regval, !(regval & QCOM_ICE_BIST_STATUS_MASK), 50, 5000); - if (err) + if (err) { dev_err(ice->dev, "Timed out waiting for ICE self-test to complete\n"); + return err; + } + if (ice->use_hwkm) { + bist_done_val = ice->hwkm_version == 1 ? + QCOM_ICE_HWKM_BIST_VAL(1) : + QCOM_ICE_HWKM_BIST_VAL(2); + if (qcom_ice_readl(ice, + HWKM_OFFSET(QCOM_ICE_REG_HWKM_TZ_KM_STATUS)) != + bist_done_val) { + dev_err(ice->dev, "HWKM BIST error\n"); + ice->use_hwkm = false; + err = -ENODEV; + } + } return err; } +static void qcom_ice_enable_standard_mode(struct qcom_ice *ice) +{ + u32 val = 0; + + /* + * When ICE is in standard (hwkm) mode, it supports HW wrapped + * keys, and when it is in legacy mode, it only supports standard + * (non HW wrapped) keys. + * + * Put ICE in standard mode, ICE defaults to legacy mode. + * Legacy mode - ICE HWKM slave not supported. + * Standard mode - ICE HWKM slave supported. + * + * Depending on the version of HWKM, it is controlled by different + * registers in ICE. + */ + if (ice->hwkm_version >= 2) { + val = qcom_ice_readl(ice, QCOM_ICE_REG_CONTROL); + val = val & QCOM_ICE_HWKM_V2_STANDARD_MODE_MASK; + qcom_ice_writel(ice, val, QCOM_ICE_REG_CONTROL); + } else { + qcom_ice_writel(ice, QCOM_ICE_HWKM_V1_STANDARD_MODE_VAL, + HWKM_OFFSET(QCOM_ICE_REG_HWKM_TZ_KM_CTL)); + } +} + +static void qcom_ice_hwkm_init(struct qcom_ice *ice) +{ + /* Disable CRC checks. This HWKM feature is not used. */ + qcom_ice_writel(ice, QCOM_ICE_HWKM_DISABLE_CRC_CHECKS_VAL, + HWKM_OFFSET(QCOM_ICE_REG_HWKM_TZ_KM_CTL)); + + /* + * Give register bank of the HWKM slave access to read and modify + * the keyslots in ICE HWKM slave. Without this, trustzone will not + * be able to program keys into ICE. + */ + qcom_ice_writel(ice, GENMASK(31, 0), HWKM_OFFSET(QCOM_ICE_REG_HWKM_BANK0_BBAC_0)); + qcom_ice_writel(ice, GENMASK(31, 0), HWKM_OFFSET(QCOM_ICE_REG_HWKM_BANK0_BBAC_1)); + qcom_ice_writel(ice, GENMASK(31, 0), HWKM_OFFSET(QCOM_ICE_REG_HWKM_BANK0_BBAC_2)); + qcom_ice_writel(ice, GENMASK(31, 0), HWKM_OFFSET(QCOM_ICE_REG_HWKM_BANK0_BBAC_3)); + qcom_ice_writel(ice, GENMASK(31, 0), HWKM_OFFSET(QCOM_ICE_REG_HWKM_BANK0_BBAC_4)); + + /* Clear HWKM response FIFO before doing anything */ + qcom_ice_writel(ice, QCOM_ICE_HWKM_RSP_FIFO_CLEAR_VAL, + HWKM_OFFSET(QCOM_ICE_REG_HWKM_BANK0_BANKN_IRQ_STATUS)); + ice->hwkm_init_complete = true; +} + int qcom_ice_enable(struct qcom_ice *ice) { + int err; + qcom_ice_low_power_mode_enable(ice); qcom_ice_optimization_enable(ice); - return qcom_ice_wait_bist_status(ice); + if (ice->use_hwkm) + qcom_ice_enable_standard_mode(ice); + + err = qcom_ice_wait_bist_status(ice); + if (err) + return err; + + if (ice->use_hwkm) + qcom_ice_hwkm_init(ice); + + return err; } EXPORT_SYMBOL_GPL(qcom_ice_enable); @@ -150,6 +282,10 @@ int qcom_ice_resume(struct qcom_ice *ice) return err; } + if (ice->use_hwkm) { + qcom_ice_enable_standard_mode(ice); + qcom_ice_hwkm_init(ice); + } return qcom_ice_wait_bist_status(ice); } EXPORT_SYMBOL_GPL(qcom_ice_resume); @@ -157,6 +293,7 @@ EXPORT_SYMBOL_GPL(qcom_ice_resume); int qcom_ice_suspend(struct qcom_ice *ice) { clk_disable_unprepare(ice->core_clk); + ice->hwkm_init_complete = false; return 0; } @@ -206,6 +343,12 @@ int qcom_ice_evict_key(struct qcom_ice *ice, int slot) } EXPORT_SYMBOL_GPL(qcom_ice_evict_key); +bool qcom_ice_hwkm_supported(struct qcom_ice *ice) +{ + return ice->use_hwkm; +} +EXPORT_SYMBOL_GPL(qcom_ice_hwkm_supported); + static struct qcom_ice *qcom_ice_create(struct device *dev, void __iomem *base) { @@ -240,6 +383,7 @@ static struct qcom_ice *qcom_ice_create(struct device *dev, engine->core_clk = devm_clk_get_enabled(dev, NULL); if (IS_ERR(engine->core_clk)) return ERR_CAST(engine->core_clk); + engine->use_hwkm = qcom_scm_has_wrapped_key_support(); if (!qcom_ice_check_supported(engine)) return ERR_PTR(-EOPNOTSUPP); diff --git a/include/soc/qcom/ice.h b/include/soc/qcom/ice.h index 9dd835dba2a7..1f52e82e3e1c 100644 --- a/include/soc/qcom/ice.h +++ b/include/soc/qcom/ice.h @@ -34,5 +34,6 @@ int qcom_ice_program_key(struct qcom_ice *ice, const struct blk_crypto_key *bkey, u8 data_unit_size, int slot); int qcom_ice_evict_key(struct qcom_ice *ice, int slot); +bool qcom_ice_hwkm_supported(struct qcom_ice *ice); struct qcom_ice *of_qcom_ice_get(struct device *dev); #endif /* __QCOM_ICE_H__ */ From patchwork Fri Oct 11 18:54:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 834633 Received: from mail-lj1-f181.google.com (mail-lj1-f181.google.com [209.85.208.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4CB0D1D1314 for ; Fri, 11 Oct 2024 18:54:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728672896; cv=none; b=GpmbotFcoxadGYkyWViFcKmhHiNXopXMDUt1uy4QByqDrkyWGtUPPYwykcpvtlBk7O/LS0o2cZ8Ztbv39SJ4UyXw7jrudEzn+5TaQaddmmzJB3gSPMwR/7jaOvZ4EuDVBPs1SvnO6xtx6YYSowuuA6O4Rh8tcY7lg4PTT6SMlUY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728672896; c=relaxed/simple; bh=ldj2GPboWWV6klKA5zzXhrbBgDv7yjuDukUxSR5XLac=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BVVFTRTj7KGd4UI0GAB7t1LZZuRA3L3Yf4wnV696YrfgGpCeu1v9avhErTm7gxma1ifQwE9oj8M63VWUOFsH+lYfyFj4DKKqbr0dIbG9PZ9UYLFnx44GJooV4ADyyC5GcSgDWnZvI6WDk1G8WoFpzbnrYwIDLIVjaV+8xrDmoTk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl; spf=none smtp.mailfrom=bgdev.pl; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b=M2VzqzTd; arc=none smtp.client-ip=209.85.208.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b="M2VzqzTd" Received: by mail-lj1-f181.google.com with SMTP id 38308e7fff4ca-2facaa16826so21351981fa.0 for ; Fri, 11 Oct 2024 11:54:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1728672886; x=1729277686; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=IQv7sxIwl848pSZRL5IFcSxv5uf9mZ9Yp6m9/sxxkj0=; b=M2VzqzTdsdVMo1arefVpg9IgUvodk6S7hvolPuXVQXZ61deDZOO8KGhVph2A6PNqrU WAkYvqWoM0fV1cHHZ4EMnsXheDXjFDFg0d14NMO6MnYjX+Xx2WthV+GxVoABvKbkoaaj RAdc080tr7TFMKQCdZJ8ht8RpMQAtNJwney+TTflBu+Y5RInyW7JWncpVf9nt+3vNDqT N22HtoQyVUbD3YxJj/B729fWBI6jx6v0l2s2WeXm3cPGwoy5m5/nTg1HtyWH0h5+tWuf XCO1/KBHiT1EUqsLOhOMmUmSew9Yng2YVXgFDnResl1VLwdLgkaSSinRfXuqI7fjKlPf a+Dw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1728672886; x=1729277686; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=IQv7sxIwl848pSZRL5IFcSxv5uf9mZ9Yp6m9/sxxkj0=; b=IcOTKVi87SHtQTbJtwxdtw+/ncnYFoEou43/LH8tldqycumQKE/+bDskUOqKDxJmWU LXUPHz7MqgeAx9pjUBgRVTWwqJoGk3TtKe0qmeO+i8JDsrarsJW6ZjLQg4hDI8EUy3zo vAxkVq1C0jZxG5BB+PcmQFi1iqUxrpJAD8agAYJPyqtzjX5dNaCiLk8RH+hwzeynNhLB My2yB1WwMeYWUGjx8WaCamTocCDWCrCdC5Cxc0AQbSSYx1/BmxQnXo/W5EuGIOXF8QvQ Sx0vlD48mw0MkDhaF4wVXyU1nZ3xUaLFhGBsM2AYq1rvIGBry09aWNafofxCMyZnYYbt nnew== X-Forwarded-Encrypted: i=1; AJvYcCVPuuystdABxU8egiR0t34DsJKwFr8350J1c7lX/QKx3R/GxYtXqZX1Q8ycSOzeHDPO7kpLQtPXcOADMarO@vger.kernel.org X-Gm-Message-State: AOJu0YzH9aap9DWDF+qP/gMrnBQf//w9GVyOkjDrzuYRUoPWjWZZaAdj faBu01kPL0Eo6MoK/NvL+RbkrHMzZfMvVDoAbDzo/ijWfPe8oq+1c9acgrhlQb0= X-Google-Smtp-Source: AGHT+IFcy03ZRQPqSeC9cuSBxo4PkWZJsOoMLCkEkzXlqxzk+nbj3iXHAOOO2iMhPWzZrAvTqRNEkQ== X-Received: by 2002:a2e:5152:0:b0:2fb:3475:42e2 with SMTP id 38308e7fff4ca-2fb347543e3mr16437861fa.24.1728672885435; Fri, 11 Oct 2024 11:54:45 -0700 (PDT) Received: from [127.0.1.1] ([2a01:cb1d:dc:7e00:68b8:bef:b7eb:538f]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-37d4b79fe7csm4559161f8f.70.2024.10.11.11.54.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Oct 2024 11:54:45 -0700 (PDT) From: Bartosz Golaszewski Date: Fri, 11 Oct 2024 20:54:11 +0200 Subject: [PATCH v7 12/17] ufs: core: add support for wrapped keys to UFS core Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241011-wrapped-keys-v7-12-e3f7a752059b@linaro.org> References: <20241011-wrapped-keys-v7-0-e3f7a752059b@linaro.org> In-Reply-To: <20241011-wrapped-keys-v7-0-e3f7a752059b@linaro.org> To: Jens Axboe , Jonathan Corbet , Alasdair Kergon , Mike Snitzer , Mikulas Patocka , Adrian Hunter , Asutosh Das , Ritesh Harjani , Ulf Hansson , Alim Akhtar , Avri Altman , Bart Van Assche , "James E.J. Bottomley" , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam , Dmitry Baryshkov , Gaurav Kashyap , Neil Armstrong Cc: linux-block@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, dm-devel@lists.linux.dev, linux-mmc@vger.kernel.org, linux-scsi@vger.kernel.org, linux-fscrypt@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-arm-msm@vger.kernel.org, Bartosz Golaszewski X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2829; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=kSNAg4Cg7lt9kA8Y9QFGrqnE75GttRm2ZeCOs5zZLVY=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnCXRgz3wpu0+BmPDjfUCGlQZykfD0g8J2gBSHw e4ovQlJ612JAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZwl0YAAKCRARpy6gFHHX chbaEADYsgCUHfhaeIXNmnetIBjLR65WJIKNlWjqtGy1b23P35IBpeYFt5NbCJUqQwn8mvEuenD yFDO2Ihso7iqDPh9LwXeBj/tShzSpZYi5IZOo33vKuLiYflO3gdutzjawn7QjzTQuPQYeHlODzJ H5ejRZCjuzJsmLfDuPl2eldtgzORJe9ppVqw2gkqP5XApQxnWzFsNBVg67wg7L2fiuxBDlt/2OJ EZvsA9DGxgfKQ+Xhatcpfy3pZM0hUBXv7KIMcdC1SBjqC9T4cW8sou5ZYBEb+BJJxyUvpCwhttr DHD+T4sPMbqUHG9cEexHSm1VmpojWGFVouvfMlrmlgj5OdFYQEU+k/d2S+wYfgwQrsM9uRGx12n sG3IsyJpgSFNcConqxl/sb8WfPM6KJ/MfUxz+nn+mFxQrzN3m2yoxHjmkrtgSFlSNAJsciiIB19 1/X6yevLw6GW+6nkyUQmqgkEDFuTPQdDdHbJc4l0HvYR81ABEzS6ynmzikb/O8DqwdfrFO1hrO/ jLvTYI+DiaPqlswdRt3+GzO6cDw+NQjY+0nfUkJ4NQLaltWoQepSDL1xbeYzuAS6/9Pok1/mHsQ zH10aVHSDaxTwYoYint8S3Lv501kGiuEiKZPDoqPEoAg6KsPLH+dG7CCAurIhpf9AbkN4cA4k/7 pRutaMpiIigVkyA== X-Developer-Key: i=bartosz.golaszewski@linaro.org; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 From: Gaurav Kashyap Add a new UFS capability flag indicating that the controller supports HW wrapped keys and use it to determine which mechanism to use in UFS core. Tested-by: Neil Armstrong Signed-off-by: Gaurav Kashyap Signed-off-by: Bartosz Golaszewski --- drivers/ufs/core/ufshcd-crypto.c | 24 ++++++++++++++++-------- include/ufs/ufshcd.h | 5 +++++ 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/ufs/core/ufshcd-crypto.c b/drivers/ufs/core/ufshcd-crypto.c index 33083e0cad6e..64389e876910 100644 --- a/drivers/ufs/core/ufshcd-crypto.c +++ b/drivers/ufs/core/ufshcd-crypto.c @@ -81,13 +81,15 @@ static int ufshcd_crypto_keyslot_program(struct blk_crypto_profile *profile, cfg.crypto_cap_idx = cap_idx; cfg.config_enable = UFS_CRYPTO_CONFIGURATION_ENABLE; - if (ccap_array[cap_idx].algorithm_id == UFS_CRYPTO_ALG_AES_XTS) { - /* In XTS mode, the blk_crypto_key's size is already doubled */ - memcpy(cfg.crypto_key, key->raw, key->size/2); - memcpy(cfg.crypto_key + UFS_CRYPTO_KEY_MAX_SIZE/2, - key->raw + key->size/2, key->size/2); - } else { - memcpy(cfg.crypto_key, key->raw, key->size); + if (key->crypto_cfg.key_type != BLK_CRYPTO_KEY_TYPE_HW_WRAPPED) { + if (ccap_array[cap_idx].algorithm_id == UFS_CRYPTO_ALG_AES_XTS) { + /* In XTS mode, the blk_crypto_key's size is already doubled */ + memcpy(cfg.crypto_key, key->raw, key->size / 2); + memcpy(cfg.crypto_key + UFS_CRYPTO_KEY_MAX_SIZE / 2, + key->raw + key->size / 2, key->size / 2); + } else { + memcpy(cfg.crypto_key, key->raw, key->size); + } } err = ufshcd_program_key(hba, key, &cfg, slot); @@ -196,7 +198,13 @@ int ufshcd_hba_init_crypto_capabilities(struct ufs_hba *hba) hba->crypto_profile.ll_ops = ufshcd_crypto_ops; /* UFS only supports 8 bytes for any DUN */ hba->crypto_profile.max_dun_bytes_supported = 8; - hba->crypto_profile.key_types_supported = BLK_CRYPTO_KEY_TYPE_STANDARD; + if (hba->caps & UFSHCD_CAP_WRAPPED_CRYPTO_KEYS) + hba->crypto_profile.key_types_supported = + BLK_CRYPTO_KEY_TYPE_HW_WRAPPED; + else + hba->crypto_profile.key_types_supported = + BLK_CRYPTO_KEY_TYPE_STANDARD; + hba->crypto_profile.dev = hba->dev; /* diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index 331b1ed171da..19c36f4ca381 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -763,6 +763,11 @@ enum ufshcd_caps { * WriteBooster when scaling the clock down. */ UFSHCD_CAP_WB_WITH_CLK_SCALING = 1 << 12, + + /* + * UFS controller supports HW wrapped keys when using inline encryption. + */ + UFSHCD_CAP_WRAPPED_CRYPTO_KEYS = 1 << 13, }; struct ufs_hba_variant_params { From patchwork Fri Oct 11 18:54:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 834632 Received: from mail-wm1-f47.google.com (mail-wm1-f47.google.com [209.85.128.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7BBE81D27B8 for ; Fri, 11 Oct 2024 18:54:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728672900; cv=none; b=JMzWPWJ2xILYArNXTbfSJlBPWCqSgQiP0OojLuIF6Qw7E2ESDBHKSJC5scitsGU41uxtGcWiCfYnpbytUw4SGs3D1nXT0PQ5CcJJdxYlOlCUUpyLaiihC6sabmOldMWHXJJneVf8xMiJlBfUDTonbBNeNCPLLMz/6G/6n4nfj0Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728672900; c=relaxed/simple; bh=rCoqdQ9B7Hn8xdsgALiUMx6hOr/x0MpVdqxz3Ze2hQA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=sCDCecZ0ZZGim1X06caQphjtRr1uDaigSMBvzu/20rU2fFlKXHVDsRXVjmncVoDKWGtxpGR+RDZmAdBkn9hEQy/Attu/a8AKwI8NgBV9HNaoLEb+8/QYfk85Q3fxaJ7erqM1STIoxfk8fOM4iviVcq9jL4UsB/NcF6aYwpen+KA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl; spf=none smtp.mailfrom=bgdev.pl; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b=nRkMEkO3; arc=none smtp.client-ip=209.85.128.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b="nRkMEkO3" Received: by mail-wm1-f47.google.com with SMTP id 5b1f17b1804b1-4311ae6426aso12855285e9.2 for ; Fri, 11 Oct 2024 11:54:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1728672888; x=1729277688; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=bhatKWKJuxfltx1oNZ6oUaNqgboH9F2TpuTRwRw3JfI=; b=nRkMEkO3WAn4V05TmXnB8gjaBNhfQPZIJTzt6Q9SV7V9A9wJG9louYgBc2SltMkUap vbrFbizKTeMn3tVVPXoR+aXaDEK4mvx/79VTmud68FnTyjKPbeSP3kv3SmN+Ldy+pciT d1Gm4NGWZYTacVA7upmqdi+8j0jpmjLYW8am9eglDhMVjp4nMhw4oECCp0broom8aUkQ pdFkw6jEl68o696hM9TqwtVbQsu0UCms/Jy06Y6Yg4ceN1uTW8c62GxgWklzNckDVQMN nMENVlUK7ev0l7OQRcROTSK5WFio43Fn9Nac2ZFE0I4kIpReIOqaBBeUzFPIFg31eotx TnJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1728672888; x=1729277688; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=bhatKWKJuxfltx1oNZ6oUaNqgboH9F2TpuTRwRw3JfI=; b=aO0FCXbzaJOsgBPzA83iJzsBeNCo/pbN/HLltP8ElTJDEUQrZRp3jObi/uORQBSq2n GXS1sMBp/E43NfhbRvTuKG1GKDCBoGcJN6EKeR94rk7vFcQyNIlXHcLDeUW0qyVrFLDl 4/LXo557wPC5HzvV9g4CiYBblN1QHL57WwOJLBC/w71uWmhdiEkTSP7sCMGMKRy/tKbZ 5toH+z8wut1+bWH5AOFdxu00YyU1xPvGUlJC+HOqoAIhDHu/AZ+pA4qatpHG1LSvE4VQ niWtwvtPZhzw+1Lx78TKUt0pjGowPFGL5iGyBbT5zT3cX5/SwPet6YAAXeRWLebWO5J4 +Wlg== X-Forwarded-Encrypted: i=1; AJvYcCVlKk+L0wX6lg4jAEbtvrJchAzSeRSycCic9gpkGLXIX63tCcO+1f13yB51QXn1CwI0Oz5/wqt1EawtGqGQ@vger.kernel.org X-Gm-Message-State: AOJu0Yw3lE7SPF3nfdPUCe43Fz1NMUnF21raGhYNkGnnFxSOfO0suhdK yx+c7ZfaCSz6tpgm38SjF3aFClgmKzvBxAnn+v5wkkJ3+J04pdaTjzxD8TCRZEo= X-Google-Smtp-Source: AGHT+IGmsTYdyN8AnM0SFDW0KnEWUsE2KWdNV7xLu0WWRUc2MVy9WTK7gb9S/nVCr2balMC3xW7jWQ== X-Received: by 2002:a05:600c:1e03:b0:42f:520b:1591 with SMTP id 5b1f17b1804b1-4311df474abmr30031205e9.24.1728672888171; Fri, 11 Oct 2024 11:54:48 -0700 (PDT) Received: from [127.0.1.1] ([2a01:cb1d:dc:7e00:68b8:bef:b7eb:538f]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-37d4b79fe7csm4559161f8f.70.2024.10.11.11.54.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Oct 2024 11:54:47 -0700 (PDT) From: Bartosz Golaszewski Date: Fri, 11 Oct 2024 20:54:13 +0200 Subject: [PATCH v7 14/17] ufs: core: add support for generating, importing and preparing keys Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241011-wrapped-keys-v7-14-e3f7a752059b@linaro.org> References: <20241011-wrapped-keys-v7-0-e3f7a752059b@linaro.org> In-Reply-To: <20241011-wrapped-keys-v7-0-e3f7a752059b@linaro.org> To: Jens Axboe , Jonathan Corbet , Alasdair Kergon , Mike Snitzer , Mikulas Patocka , Adrian Hunter , Asutosh Das , Ritesh Harjani , Ulf Hansson , Alim Akhtar , Avri Altman , Bart Van Assche , "James E.J. Bottomley" , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam , Dmitry Baryshkov , Gaurav Kashyap , Neil Armstrong Cc: linux-block@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, dm-devel@lists.linux.dev, linux-mmc@vger.kernel.org, linux-scsi@vger.kernel.org, linux-fscrypt@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-arm-msm@vger.kernel.org, Bartosz Golaszewski , Om Prakash Singh X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2542; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=+ALSGPhqSpFCx8VMqBEOHa6jvoZdtMRVH6U+tA0zR4E=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnCXRgIa9JxS13dmB3BNLm5fvTras3dIpSag6X7 iOgkq4b7OWJAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZwl0YAAKCRARpy6gFHHX cv+EEADf3pf7OpbgUzzA0lbKqWbwldOeq01TQaRjRNSnIIGR9Pir/kkxjWn0wIojkhZLtqaRXdZ i6cbuaIfFzAbqGeGUNmocV4ivByw808djzRGDXZj5C/l9O0Ztf7Oulz+QvskdWsEmmLhgffrwNt MP/Z47wGvTnVQVsXGbIEyPZSX82eglF9A2u71/d0+Ozb2OjKpwMxAj0UEasybrj7K4+i9MGVTa2 6JlU2kEB/3H1vhhysqZK5T78mKy2Prl97HwuTUgqm+yQ6QLeyyjKXbwWIWe/tG/ZJYUuhnf+cfR E7pphMtjVKPduJeEvBJU3ocdLgtCsiLBxS53CktanacXKOWGWDCkVVn2M2dK2nY6l3YKh7KnQHM VJxRQoQffBcRXUNbhgfUtiaF1Hq3ZE6OVtGBmFUH/1OlE10cn2eEeWmhJ/rS5oBkcajHBvHCwAG 2e1hR41YzEjaKMs1GXbm3nJTI5ogUwQ9gAtur2KYXkd6NSOVy0VeZKfk6mG2/ZzFz9zP7g2EZce lpaXSpe24sTH4DE8/e0OXNRxb/LM0B3U6Klpsf2zUKXvfc1tUo7SXpVKPuGAxs8fjXDxBm6ezhH ab1ZdLu+2XbyoeTs8wAf4xThVS+VVcFDIwYRCMOiG8FEOiBFAn1Rn8/S/tA/XcvAwQirGxP58ML bS1eVfDWvezVEww== X-Developer-Key: i=bartosz.golaszewski@linaro.org; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 From: Gaurav Kashyap The block layer now allows storage controllers to implement the operations for handling wrapped keys. We can now extend the UFS core to also support them by reaching into the block layer. Add hooks corresponding with the existing crypto operations lower on the stack. Tested-by: Neil Armstrong Reviewed-by: Om Prakash Singh Signed-off-by: Gaurav Kashyap Signed-off-by: Bartosz Golaszewski --- drivers/ufs/core/ufshcd-crypto.c | 41 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/ufs/core/ufshcd-crypto.c b/drivers/ufs/core/ufshcd-crypto.c index 2530239d42af..49c0784f2432 100644 --- a/drivers/ufs/core/ufshcd-crypto.c +++ b/drivers/ufs/core/ufshcd-crypto.c @@ -145,10 +145,51 @@ bool ufshcd_crypto_enable(struct ufs_hba *hba) return true; } +static int ufshcd_crypto_generate_key(struct blk_crypto_profile *profile, + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]) +{ + struct ufs_hba *hba = + container_of(profile, struct ufs_hba, crypto_profile); + + if (hba->vops && hba->vops->generate_key) + return hba->vops->generate_key(hba, lt_key); + + return -EOPNOTSUPP; +} + +static int ufshcd_crypto_prepare_key(struct blk_crypto_profile *profile, + const u8 *lt_key, size_t lt_key_size, + u8 eph_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]) +{ + struct ufs_hba *hba = + container_of(profile, struct ufs_hba, crypto_profile); + + if (hba->vops && hba->vops->prepare_key) + return hba->vops->prepare_key(hba, lt_key, lt_key_size, eph_key); + + return -EOPNOTSUPP; +} + +static int ufshcd_crypto_import_key(struct blk_crypto_profile *profile, + const u8 *imp_key, size_t imp_key_size, + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]) +{ + struct ufs_hba *hba = + container_of(profile, struct ufs_hba, crypto_profile); + + if (hba->vops && hba->vops->import_key) + return hba->vops->import_key(hba, imp_key, imp_key_size, lt_key); + + return -EOPNOTSUPP; +} + static const struct blk_crypto_ll_ops ufshcd_crypto_ops = { .keyslot_program = ufshcd_crypto_keyslot_program, .keyslot_evict = ufshcd_crypto_keyslot_evict, .derive_sw_secret = ufshcd_crypto_derive_sw_secret, + .generate_key = ufshcd_crypto_generate_key, + .prepare_key = ufshcd_crypto_prepare_key, + .import_key = ufshcd_crypto_import_key, }; static enum blk_crypto_mode_num From patchwork Fri Oct 11 18:54:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 834631 Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4D4F31D0DEB for ; Fri, 11 Oct 2024 18:54:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728672904; cv=none; b=lA0uZhBVLlXUp3C5HOrz/HFmMbS9tNJLTG7oQxar/Ca9wiu4nZ75KM64L7akyDpdO1kObJhAEwfy1mxUySqkdXeVfxlmYq/JQ1bTHnM1hVhokE4Y0m4gEkBqHQ8lIE0hWUFifYPJsTWOL38YW2/MW82v5w7EzT3Ofe/u1HpOMcw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728672904; c=relaxed/simple; bh=e1gtd88RzjTEdKgz5vKtdQEHaWC6suwW5itfB3BJQME=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qTiaaytdDs0wN9yqI2f3EgS7ZNkznTcm2J1qNuk8Mcj2QA9Ft8v19TnpO7lyhFs11z3ko+cIlYVN8yrHakUaQDT9FEjxB9ltOVq1USxzxvfKi1I/fHrkuryRSZTPHOCfgpPB6xyf3EUrk75+qsXzMy1Oa8wcKW/kk1lSUcuGaR0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl; spf=none smtp.mailfrom=bgdev.pl; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b=p0A8yWx3; arc=none smtp.client-ip=209.85.128.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b="p0A8yWx3" Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-430f6bc9ca6so18066605e9.2 for ; Fri, 11 Oct 2024 11:54:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1728672892; x=1729277692; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=H45D+zQ4RlZo87PnQlpnl9k3Po/Ceaj5Q2WfHuVjsjY=; b=p0A8yWx3OoCljbbWdvX+WqHz0Dsg4ejsm68SeCsnGKpsZFz2+z3AKNhmuuSuLzw6ug rxIGcld16NVdxN8Iesbd8WECOerZq7tppUBoA63LMzXXUJMNz2RINMu29sBhXUlpjTE4 7GP70BrfbWKynZb4G/AYt0W+mKoOUvRl0xw9YGmasyNdTv0q3HDI3mfFgXUZTwNiYp2f txunhWxzSiieJ+XxFLzo+jM225ZQwUz19bTeOVpJwGRR7GiCISJUhxhnfltGpOtfeean +bio2aDx0J+o3orHOxRZWeQkD6iYhlYnDhgm1WXWX28kpmw6gdZQbzGPemT42yQiFlNB 3DJw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1728672892; x=1729277692; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=H45D+zQ4RlZo87PnQlpnl9k3Po/Ceaj5Q2WfHuVjsjY=; b=UJBFAZbDDX0jkk5od5/MvK6MSlgM1Wyw3a4akLfqWzo/ZMy4qQmk8FNqsyVrmUS3GU bFgBN8gLNH1kUZvTgnxNE+Hw9L6o/9bOHdGo4ALDGoCKEvENluEV6wd8yq0fSjTE2XjX v9ixH2C6k7g48aBGmYLEUR2L0BJ/2JpPUOiqLem+WQD3OXiTPHfL2EZQwiDYfeaP30xO EkEoEeqxLNFil4XxCZVJ1i5c3QXeVpeVpMeNoyX7KduCDGgzbKDMmEZ3Kxlxal87WbEz pTeSZQ/2B4q40rpF39Yuan+RRtJysbc/Vl6E22V4y29/IAGQlr5Cv34Z0JCHdnkUorZU RT7g== X-Forwarded-Encrypted: i=1; AJvYcCWqvyck0Dnh44sv9+rj9XU2BtkIKroE5qjgy3MuscrQKdKzfPqXdQIzSpN/dDFs3Acv5aR3MZmBm9g1PykC@vger.kernel.org X-Gm-Message-State: AOJu0Yw0ONtuH14QSggHQeV5LsbDTfktr8rMtPomTlLtHGAoBiGG6UvH ywg7Rvzd2zY9ZaAfuf84y2isouSA45sV6N8bTWTL5vWVjBpgMK67i3yJ+qN+syU= X-Google-Smtp-Source: AGHT+IGoTXSLCWNbiKvBBCB8iuDTBloAvzoGmWYaf2ibRIfcx4PwXi3/91OEiktNbtQQzvwdztwuZg== X-Received: by 2002:a05:600c:190f:b0:431:251a:9dc9 with SMTP id 5b1f17b1804b1-431256099fdmr3480875e9.25.1728672892069; Fri, 11 Oct 2024 11:54:52 -0700 (PDT) Received: from [127.0.1.1] ([2a01:cb1d:dc:7e00:68b8:bef:b7eb:538f]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-37d4b79fe7csm4559161f8f.70.2024.10.11.11.54.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Oct 2024 11:54:51 -0700 (PDT) From: Bartosz Golaszewski Date: Fri, 11 Oct 2024 20:54:15 +0200 Subject: [PATCH v7 16/17] ufs: host: add a callback for deriving software secrets and use it Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241011-wrapped-keys-v7-16-e3f7a752059b@linaro.org> References: <20241011-wrapped-keys-v7-0-e3f7a752059b@linaro.org> In-Reply-To: <20241011-wrapped-keys-v7-0-e3f7a752059b@linaro.org> To: Jens Axboe , Jonathan Corbet , Alasdair Kergon , Mike Snitzer , Mikulas Patocka , Adrian Hunter , Asutosh Das , Ritesh Harjani , Ulf Hansson , Alim Akhtar , Avri Altman , Bart Van Assche , "James E.J. Bottomley" , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam , Dmitry Baryshkov , Gaurav Kashyap , Neil Armstrong Cc: linux-block@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, dm-devel@lists.linux.dev, linux-mmc@vger.kernel.org, linux-scsi@vger.kernel.org, linux-fscrypt@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-arm-msm@vger.kernel.org, Bartosz Golaszewski X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2513; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=8izsipyIaDBdSDiSjvy9mf21cushU27meDYZO8QM7MY=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnCXRhwyf+sbRZiDFPfQnZmkfF4U7jfh05yXQav c1LkPJCdPeJAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZwl0YQAKCRARpy6gFHHX cqB7D/95mHJd7lZyDeS8zmIiYEZFW6SUNcNDYRflN999g4QScsSRTKlq3MTcag3Ca8ltNUoJIug 39wPTbq1I/X4YXzUshJpgGyNrzQuSZLcNlz/0CdD8URU1pLkFmPyY4MiXpu3oh+NQ/o67QYtiMJ v43/AALUcHRtWLYflg1ZxUAqMPXsG4WK8RtjPxdauvJY1FKhOPEs3hhMpnrAsj5IIbHbot1IxOR 0eyjVtaIbciJa2EnmaMwjUIBNeIBG2O0p4NTSbIwyX3i+wqvemAx4yBWK+RyzKfrCaVhz6a8KcB ov8vJP4nCLNxST6gtuasJ1jiOpE+uqWjm5ec3TBerQiy8tVH/PvTI3EXKSCgacHeeyiF0vhe+ji wR4YvxwSm0y8XK+4lYYv2vOW/viQ4eF3IjxGR64O8g5P1z1OSIeSp2jJ0aTipkSh72yTCm2hMoy eoiYN+G9pZimXdoq1h3ouQz2PExiECAIYS/NE6bsZ3vihyhgExQ24oFpoAhGVPgeK8ma3ReFC2F g+9Iv64HG9yUE1X/w86/vby7nlQ32V464qHqdz7PdMJ3IzZLQCvDhAJCtyHC2iTc/Y5ZeJwfoL1 8lDEtDIK1LNhbGnL0ICafGD5S6YgALrTCClSAxesU0bMYwYiALDVzXhzi4R2slJHNHXjiN0WHRd 2IlGSJY+nTTII6w== X-Developer-Key: i=bartosz.golaszewski@linaro.org; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 From: Gaurav Kashyap Add a new UFS core callback for deriving software secrets from hardware wrapped keys and implement it in QCom UFS. Tested-by: Neil Armstrong Signed-off-by: Gaurav Kashyap Signed-off-by: Bartosz Golaszewski --- drivers/ufs/host/ufs-qcom.c | 15 +++++++++++++++ include/ufs/ufshcd.h | 1 + 2 files changed, 16 insertions(+) diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c index 880df3a8955a..862e02bf8f64 100644 --- a/drivers/ufs/host/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c @@ -182,9 +182,23 @@ static int ufs_qcom_ice_program_key(struct ufs_hba *hba, return qcom_ice_evict_key(host->ice, slot); } +/* + * Derive a software secret from a hardware wrapped key. The key is unwrapped in + * hardware from trustzone and a software key/secret is then derived from it. + */ +static int ufs_qcom_ice_derive_sw_secret(struct ufs_hba *hba, const u8 wkey[], + unsigned int wkey_size, + u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]) +{ + struct ufs_qcom_host *host = ufshcd_get_variant(hba); + + return qcom_ice_derive_sw_secret(host->ice, wkey, wkey_size, sw_secret); +} + #else #define ufs_qcom_ice_program_key NULL +#define ufs_qcom_ice_derive_sw_secret NULL static inline void ufs_qcom_ice_enable(struct ufs_qcom_host *host) { @@ -1832,6 +1846,7 @@ static const struct ufs_hba_variant_ops ufs_hba_qcom_vops = { .device_reset = ufs_qcom_device_reset, .config_scaling_param = ufs_qcom_config_scaling_param, .program_key = ufs_qcom_ice_program_key, + .derive_sw_secret = ufs_qcom_ice_derive_sw_secret, .reinit_notify = ufs_qcom_reinit_notify, .mcq_config_resource = ufs_qcom_mcq_config_resource, .get_hba_mac = ufs_qcom_get_hba_mac, diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index d74a26a36f5b..c172c1dd9209 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -323,6 +323,7 @@ struct ufs_pwr_mode_info { * @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 + * @derive_sw_secret: derive sw secret from a wrapped 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