From patchwork Mon Dec 2 12:02:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 13890357 X-Patchwork-Delegate: snitzer@redhat.com Received: from mail-wm1-f49.google.com (mail-wm1-f49.google.com [209.85.128.49]) (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 3AE0C1FECA8 for ; Mon, 2 Dec 2024 12:02:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140963; cv=none; b=ifEAkoR44j5LYNC8ekzRn/BA6KHKh3PlVPS/zUwkOF1qChI8PWKgpi6T1QQLg+Nx1Z1BFmzU6bgo30shJrme2vFnJC3Mot0NE/T89yo4DuzIyznqZActHwMvmPICszi7tsJ7u4n93ShiJqK2lPzd5eHvNvX+AN62MM8XkP9H5ig= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140963; c=relaxed/simple; bh=qcO4vlgouTZUoxbMg4A1kS/H5m+qPaoD2b/JuxjyuLM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nEJZTAtSbKhOiLK1RciDSe0ZKI8e3lt2Jk8N5A/zADzHVhCewzZO1L+XNL+yewMsxNSmxw6P1/ibgDu41KnHXOba+t6OECBIYl88H2yLNmEwSlQkHSfpLPILvDzKxRD6tz1lLFgyfooZLOJ8/l0QZdhK7KtsUp43XSvDqiAgqOQ= 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=iFyc9fAj; arc=none smtp.client-ip=209.85.128.49 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="iFyc9fAj" Received: by mail-wm1-f49.google.com with SMTP id 5b1f17b1804b1-4349e4e252dso39067895e9.0 for ; Mon, 02 Dec 2024 04:02:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1733140957; x=1733745757; darn=lists.linux.dev; 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=2ApP1gyaL805sTy865Ej0ZPwQXHrSgz8imZAh/8mluI=; b=iFyc9fAjUzpe62sZU+7XrgiFUUZsYI1AB8O7jCkZamuDYvVEI8ncoKbA9heXIn63SD e1QC+mWZNVDUnKKAm4PU+PpIYLt81rDkPNPiTTD1GYbPeW6MvENOpRMPIxbf1gPD17Vj ONGaWY9yefEUHZu/Mg+UT7Uasln3wTN0GGoehDCfCJhDV0l4yPwogxe3orfK78ln2u1f 9ACnn38aO+Z5hxHiEHXUnfwa55uXRBkMcuifRz2HdBkZpOJ07u6i3HGKHOENb69ALYgR ggh5ZFi8lIKLsS2XJ+2pJOvtjrgzhwoAz4ZVAxp7acJgvH+Qxwe3kC/M60furoTj9l+J OnCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733140957; x=1733745757; 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=2ApP1gyaL805sTy865Ej0ZPwQXHrSgz8imZAh/8mluI=; b=sdLfujv/f5sCODsNnDRi38mfypDU5ruiGCSANFAMpbbTH/yob5AdA0pBWgjenxdcJV CuL67h5YTVorT2RBkWOrNhoj8YBazYJL3THltNrkndLtj690AgJUYg3HRkugRQcU1vIy GreBPEJrqCoRjBWY6cKYZidGFYcizPidO4q58UWssNuvOUtGB2NSnbZrqz0P7ov/pSdQ MU13ZD7mH/SFKJ1ZiTcpNZexLqB+xYcNd7hPbrz+UmbhzeYQYKTJS0nA1+/Yjy3Mb45n fxy90jP9H5M2hc9KBnJg3hLX5ALZVNPQmJX1UaA715EQOEAEMR79QYvFk/4ctJQQU8NG MGRA== X-Forwarded-Encrypted: i=1; AJvYcCXAq/M934dsGJ8Lg+z/czoj0CpD1ptYVM7fbuqwnQ5HKMagqU2AQ75SSqhUJn/enqnmf1bn8/ZlXA==@lists.linux.dev X-Gm-Message-State: AOJu0Yy2ZwEq5Q0NFzb3eKdEc7laaZEXylbpsuk251tfe1gRLKnzGG1d CRJyxJb2nk46SvqEzx4DWTXkeiBEFqR8A/yKWnWmBbLvccGTOEJgZS4+LDGBg4A= X-Gm-Gg: ASbGncvoCMkeMXf83OJsKn5BHNfJp9odHuTlG9SBj3pCGjw5Sw5TZ/tfXDypoa+/YYN eCIwKOQR8n7HrqaWYmw7ftd+Rq259zN2pzYrqNlW6/T7z68nytRnPa27eN6hBayptCILuhrYw/+ 7WNYSDtbo838FrpYnwxN63a5emgXOLAXw3PR/QdFve3Whq+c/0clBlbjJKKWYzDTdIvfRlkp0Dq VSvGCcKy0lH1rK3MWVSvcxt7pW6DLgq7LazNBbp X-Google-Smtp-Source: AGHT+IFEkrD1lmfnq4TQrvCFkegezRL739wPRbb/05Fcm3hI1hn+5uUqprKcY8HdnKBGzxS589QCYw== X-Received: by 2002:a05:600c:2308:b0:434:a781:f5d5 with SMTP id 5b1f17b1804b1-434a9df0a16mr227832365e9.30.1733140955659; Mon, 02 Dec 2024 04:02:35 -0800 (PST) Received: from [127.0.1.1] ([193.57.185.11]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-434b0d9bed7sm152396095e9.8.2024.12.02.04.02.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Dec 2024 04:02:35 -0800 (PST) From: Bartosz Golaszewski Date: Mon, 02 Dec 2024 13:02:17 +0100 Subject: [PATCH RESEND v7 01/17] blk-crypto: add basic hardware-wrapped key support Precedence: bulk X-Mailing-List: dm-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241202-wrapped-keys-v7-1-67c3ca3f3282@linaro.org> References: <20241202-wrapped-keys-v7-0-67c3ca3f3282@linaro.org> In-Reply-To: <20241202-wrapped-keys-v7-0-67c3ca3f3282@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" , Gaurav Kashyap , Neil Armstrong , Dmitry Baryshkov , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam 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.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=34607; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=on5yaYO38DQRHenqzynC5FEA4N3g8TxMBe4aWaR9Rxw=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnTaHRnGHEcJxcs1EkF98kyGrOk/OMJhyvEobbU qAWjHwFdlCJAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZ02h0QAKCRARpy6gFHHX cseLD/4lsWOg2kG9oDp8QJXabBldvvOetav9HeANHB9E8oSJ0ojayAJsVpY8G4UwVHPxYiFVzLH 5eG/PP0xC7mrSgeof98AB4RNro/H9/mAr0eHWkNl0nP9fLK/CYChPFeUWciIaL4FLCdpKD3wnr4 Psomk6GGY2dl0RVTQZkMZlcWpgAsBETEZiIyPWgg/WeXtuyzXOzOF54LXYijImkmiYbCZILB3mL NsXUpjQiYO+WwVm7iRKKIuENoA64E7LB1xC5nwwmFrGdd9hJYnJcN754eKMmIt/PH3Uv2gRQuTC 0AVzgNASdUoETgHHo/JQC2vHCb4Ndd1wmQSq1v+iCgua57nq+qFJpiqaaam54GP4gV+/xi5ehFJ Axa3syeJ4CDOQU/vntg7UElvOKCxtoc0FN9fG65PKgSiXAuZSyZiRexx+ojpzEcmhqcoMX+X8/g uE/6Ck3uEAUUIZdKcAmeD4i2vK9xkeV4cvKNtkOraatmjdDsKWJGG2IRivoRhVKnCjB1z1m/hdv Lqv/NPJ7/ms3CTn2EzmmU6rwJVbpNM3Kt1O/vOEohCOXBwYylwjO+LUb2v+hbMdUS3NfJZK4l3x ExOXZf56ZZ0d7cHqnEeFO1c440klZeGluhe4QGpBjCpo2BPPEhsLZofftYR5n8/V3zh1tAfiufY 9tZIqpcwHfIHjnw== 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 Reviewed-by: Konrad Dybcio 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 90b733422ed46..07218455a2bc3 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 29a205482617c..89da79ba6934c 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 93a141979694b..1893df9a8f06c 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 7fabc883e39f1..1b92276ed2fcc 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 4d760b092deb9..5a09d0ef1a011 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 bd8b796ae683b..3e2ab66a46aef 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -1250,6 +1250,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 d5f4b6972f63e..6652982410ec5 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 a714dad82cd1f..7d3a3e228db0d 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 40de69860dcf9..ee92c78e798bd 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 90ab33cb5d0ef..229287a7f451f 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 5e5822c18ee41..19066d86ecbf7 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 Mon Dec 2 12:02:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 13890356 X-Patchwork-Delegate: snitzer@redhat.com Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.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 7F35D1FE468 for ; Mon, 2 Dec 2024 12:02:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140962; cv=none; b=Vt/j4nBJ3Q20t8GIVd6fwerVzjoFZqC+/7kXjnKF7nibNS8AH0o2aoN2Q30f9vCkUAYjQG/DnS3/A/ix131cCBjcrPqnYrVcTvalS08aVLZU79ld7Vl9YU1gY9CPOxUPQDgfuoxthDQTprJGhTwMjHDMx8nTuVu8ZibnjJkWuG8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140962; c=relaxed/simple; bh=LzGMfdzUV+Y46qXBl6OSCXMbe5Hki1n9TnlpYa25zFs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=l03vhV/3NEo2T6iKs3Z4OHk83ySmp9E1jBPzUrJQ2oQGlEQyPuMghFS8UwPYpnRpBCp47uDidg1Ucx/KchXRA1GgTZ0Q4T5OJNfcuOufMErP7+S3FjW/41qHoErpO4XigTCO/CA1HaWHO0Atx+um5HkaZcrKwaLuGFbly0shKt0= 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=mZkA83SK; arc=none smtp.client-ip=209.85.128.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="mZkA83SK" Received: by mail-wm1-f50.google.com with SMTP id 5b1f17b1804b1-434a10588f3so25926955e9.1 for ; Mon, 02 Dec 2024 04:02:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1733140959; x=1733745759; darn=lists.linux.dev; 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=isf4tmI1TFlpMNrHBrQw/VRoOgZ13JbCedLYTAnuHuc=; b=mZkA83SKdacqEJYJ5+Xyc23cTuwF/k4TEf3sZ6GwqhdqbAkepX9wc0U8sus5rw/R3N tqsFTZayq3SmCqzHVRrs7VtRFUY7tCMlL4twfqWMCIBzKI0LKsZizg/CFaIZn23EFYJU 3iQgLL7gaLwqNzFaDJsBhkb5qC69sUn4615xIHiH8in1sh7Mxs+o9q3SKkXcR5gyGABP LkeHNjIdDtjglx+dv0ztfldTNJLbo9vL/KT19hM8siuOEnDwxK7QGz4FA7wTjqhCbH5p NpXjCIIg8qOuw76FUYMNHKuSUKaimPpxwm0gAo4gBeLqxWFBCovH1xMysLIceJkItwfK xpSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733140959; x=1733745759; 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=isf4tmI1TFlpMNrHBrQw/VRoOgZ13JbCedLYTAnuHuc=; b=N4tUflptNbzsIlpuI5NNyhuRlqJafmOh58/GMTEgZv7jQ8DbbNFP4gyYfS+5etY9U7 bTGQkt3ZnLRwpuOAGLqffuvLYejfzEyyWLDnAkB2loHnGqPyaApw7kmLWLhTGIKCIWYT sEGjf9LtdkWuwsiFDjil/BRmXxFsxLRCIWn2MUqjo2LJk2QMh5/bFtVPhbvytzkC8gj8 wJG7wLBEs7vZXLSWzsnUdViVgMlh6QsPgNurMtqEggDuaYRWcJGC4Kohu8Vts4uE8l71 kxsYD31gyAZR1GUe/nbl5m3notoIy4NFEod97yJFSQZVI0pjlVpru86An8+ur1X9iEli e5XQ== X-Forwarded-Encrypted: i=1; AJvYcCV+mAStEIN2wGQ7crEYjqD8jhI/Vts4o9/a8g2h5lLrh8dT5H3MAuDYhWEfPPdqKMywZnu77oBpLw==@lists.linux.dev X-Gm-Message-State: AOJu0YxrlWoSBTiU8QoM+K23BcTlKUheN9YvM6f0TDwTe/AQQdjhL5D3 PnjiVAKmsZv8b0N1ZH9tiqcSrBQ60D2B1YuYLP97e1zIx/prsWaEKbg1Amg+gmA= X-Gm-Gg: ASbGnct7OLjhUxDMEd0rQuYvXf3BH0Gpn8xt8tAftEfBV8KEwiC0YopaICGYuxUCo1F CwqJEmF0kswXmOmgRzLtU1wyLqc/TJqir/pb0vgtwkB2NRL2DLG3d2CxwjT22m6CS9gg/0/JxuC 0eIrULzBlwn0QsVO6BcJaFOeJ6b7XSDXraR2jhDWk9LMALpcCSwMAL9W7D+4v6Hr6+f5dx5wnRf 3Cxk6hS0LiAL6HiRoGmURrf4kEvXH4/Vyt+OuwA X-Google-Smtp-Source: AGHT+IFyBiFCBHi0GjpQ9+378VjxeMr4mk7bXx5Q6Ff8EGSFk4eXjenWxQuJ2EnHaFTd+wgJcPjbew== X-Received: by 2002:a05:600c:3151:b0:431:55af:a230 with SMTP id 5b1f17b1804b1-434a9e0a13bmr182587605e9.33.1733140958526; Mon, 02 Dec 2024 04:02:38 -0800 (PST) Received: from [127.0.1.1] ([193.57.185.11]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-434b0d9bed7sm152396095e9.8.2024.12.02.04.02.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Dec 2024 04:02:37 -0800 (PST) From: Bartosz Golaszewski Date: Mon, 02 Dec 2024 13:02:18 +0100 Subject: [PATCH RESEND v7 02/17] blk-crypto: show supported key types in sysfs Precedence: bulk X-Mailing-List: dm-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241202-wrapped-keys-v7-2-67c3ca3f3282@linaro.org> References: <20241202-wrapped-keys-v7-0-67c3ca3f3282@linaro.org> In-Reply-To: <20241202-wrapped-keys-v7-0-67c3ca3f3282@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" , Gaurav Kashyap , Neil Armstrong , Dmitry Baryshkov , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam 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.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=4358; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=ouSW/AlBhcEQvzE0ZK6zQ4sIBZ/J3LTs3gGhGDeZ9Qc=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnTaHRPDZZ8ak9Vx84mOBLXW+PqnaGDBHBzx25E 5JBsjl2KNKJAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZ02h0QAKCRARpy6gFHHX clh8D/wONYkdQU4zXTyIM6UpM9KdOjBgXHgeuZVDZ7SAshMMizdm5gX9f7H2zVMdIuSt76K6d6u cMg1ZkazEPMCyGbGkMYTZgX1KLeOSX729FQkI/XGhdtucfMNRUPMkbXKB122qZE8LlhQvc6phKC p2UhVZeW64+Ra1c8GZeWM9Z3CDg4B58MlNsN/qGy/qiCtZHQ44502g4gF+xriuz50n1CdmIsmYD h+6gWYhQmIXJU8XtM5DNR7e2TTAGj38IeBH8695rLvG//xOrU6UqZ6PHfQff0LoYRkIQMfOFLK7 woyqpgiSFr2jdfAREny4u1mhD/d3AvCn0Sy1STxH8iEJCMbzhE9gb7InwOge5q8D+tevPWGKhL5 vSR/+ncRoSnWUDgzMY4NZimO0WaiQph4cS5SPzR7xr8sc1dD/GgPs9ZV3mSmnwUvOZZHsa5ws9x 72dyysTG7nG+DL7gHfHA1qjiornBkIJDCDg1H3RNDgDrcO9B/6PtE9JI99WBm89ry4TiWDq45+s puBce4kKAEsPDwoB9/ySQ8b8PKGuly8pSzPw7GwFPtKD/9nU38/axyjeWHTJXZOep5oIF0jFLmY kXwzHyku949IdO50MvA9k+o7xIcBCLbPGABRHVrq9SAoUiNwCJ5aheX8QQPirCs9DeHh4bMKVC5 Ehjgh9sDY2NqawA== X-Developer-Key: i=bartosz.golaszewski@linaro.org; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 From: Eric Biggers Add sysfs files that indicate which type(s) of keys are supported by the inline encryption hardware associated with a particular request queue: /sys/block/$disk/queue/crypto/hw_wrapped_keys /sys/block/$disk/queue/crypto/standard_keys Userspace can use the presence or absence of these files to decide what encyption settings to use. Don't use a single key_type file, as devices might support both key types at the same time. Signed-off-by: Eric Biggers Reviewed-by: Konrad Dybcio Signed-off-by: Bartosz Golaszewski --- Documentation/ABI/stable/sysfs-block | 18 ++++++++++++++++++ block/blk-crypto-sysfs.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/Documentation/ABI/stable/sysfs-block b/Documentation/ABI/stable/sysfs-block index 0cceb2badc836..998681e7043d5 100644 --- a/Documentation/ABI/stable/sysfs-block +++ b/Documentation/ABI/stable/sysfs-block @@ -229,6 +229,16 @@ Description: encryption, refer to Documentation/block/inline-encryption.rst. +What: /sys/block//queue/crypto/hw_wrapped_keys +Contact: linux-block@vger.kernel.org +Description: + [RO] The presence of this file indicates that the device + supports hardware-wrapped inline encryption keys, i.e. key blobs + that can only be unwrapped and used by dedicated hardware. For + more information about hardware-wrapped inline encryption keys, + see Documentation/block/inline-encryption.rst. + + What: /sys/block//queue/crypto/max_dun_bits Date: February 2022 Contact: linux-block@vger.kernel.org @@ -267,6 +277,14 @@ Description: use with inline encryption. +What: /sys/block//queue/crypto/standard_keys +Contact: linux-block@vger.kernel.org +Description: + [RO] The presence of this file indicates that the device + supports standard inline encryption keys, i.e. keys that are + managed in raw, plaintext form in software. + + What: /sys/block//queue/dax Date: June 2016 Contact: linux-block@vger.kernel.org diff --git a/block/blk-crypto-sysfs.c b/block/blk-crypto-sysfs.c index a304434489bac..acab50493f2cd 100644 --- a/block/blk-crypto-sysfs.c +++ b/block/blk-crypto-sysfs.c @@ -31,6 +31,13 @@ static struct blk_crypto_attr *attr_to_crypto_attr(struct attribute *attr) return container_of(attr, struct blk_crypto_attr, attr); } +static ssize_t hw_wrapped_keys_show(struct blk_crypto_profile *profile, + struct blk_crypto_attr *attr, char *page) +{ + /* Always show supported, since the file doesn't exist otherwise. */ + return sysfs_emit(page, "supported\n"); +} + static ssize_t max_dun_bits_show(struct blk_crypto_profile *profile, struct blk_crypto_attr *attr, char *page) { @@ -43,20 +50,48 @@ static ssize_t num_keyslots_show(struct blk_crypto_profile *profile, return sysfs_emit(page, "%u\n", profile->num_slots); } +static ssize_t standard_keys_show(struct blk_crypto_profile *profile, + struct blk_crypto_attr *attr, char *page) +{ + /* Always show supported, since the file doesn't exist otherwise. */ + return sysfs_emit(page, "supported\n"); +} + #define BLK_CRYPTO_RO_ATTR(_name) \ static struct blk_crypto_attr _name##_attr = __ATTR_RO(_name) +BLK_CRYPTO_RO_ATTR(hw_wrapped_keys); BLK_CRYPTO_RO_ATTR(max_dun_bits); BLK_CRYPTO_RO_ATTR(num_keyslots); +BLK_CRYPTO_RO_ATTR(standard_keys); + +static umode_t blk_crypto_is_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct blk_crypto_profile *profile = kobj_to_crypto_profile(kobj); + struct blk_crypto_attr *a = attr_to_crypto_attr(attr); + + if (a == &hw_wrapped_keys_attr && + !(profile->key_types_supported & BLK_CRYPTO_KEY_TYPE_HW_WRAPPED)) + return 0; + if (a == &standard_keys_attr && + !(profile->key_types_supported & BLK_CRYPTO_KEY_TYPE_STANDARD)) + return 0; + + return 0444; +} static struct attribute *blk_crypto_attrs[] = { + &hw_wrapped_keys_attr.attr, &max_dun_bits_attr.attr, &num_keyslots_attr.attr, + &standard_keys_attr.attr, NULL, }; static const struct attribute_group blk_crypto_attr_group = { .attrs = blk_crypto_attrs, + .is_visible = blk_crypto_is_visible, }; /* From patchwork Mon Dec 2 12:02:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 13890358 X-Patchwork-Delegate: snitzer@redhat.com Received: from mail-wm1-f48.google.com (mail-wm1-f48.google.com [209.85.128.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 681831FF5EC for ; Mon, 2 Dec 2024 12:02:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140967; cv=none; b=YKhM0ybN7clvTMWLqX1yBpJJzOQo80DCtfNH8U2N4pFM5d3icD/Gz412KtIR6jkSb2HwgY/SHbp4Rx/07JJhfqFKZOySsY8Mn37WYnFoiOPdghQkLP5fCDQ3m/BN+M7GcYY9TjmPVDkvyHuXDKzRXyZBiZ8UUn6rNkXdzStrNXw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140967; c=relaxed/simple; bh=Hgr5gnEcipo3iroC2Z35QugNVIgPPBWK9LcPRSXICLA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BY0KTokKGUVFdoLyc/ap+WMNBqn2eQ7Ct2z+b0pn2NwHxV6W9GdH+4mU6FRV1cMN0y6hlzOxo1SPM5FFpPjRoSfXinOnkfJbFB7vXog7KQdn4sSvD99ikcMJeACEAOj22YdE5ly4Xjp2BQGDPt1OxIm0et98mMceWdKdMtXU+EE= 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=ydBsYd74; arc=none smtp.client-ip=209.85.128.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="ydBsYd74" Received: by mail-wm1-f48.google.com with SMTP id 5b1f17b1804b1-434a099ba95so37570005e9.0 for ; Mon, 02 Dec 2024 04:02:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1733140963; x=1733745763; darn=lists.linux.dev; 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=JbmHDTbdMbFLibDhFaSSw7kfgSGxZjF1PeLKMBpjXLU=; b=ydBsYd7421ueX3IBC2+V9zy6y87dKaTmXvNp6FxeTdX2qegM+8k5/8CQMvnR5FUJ3O G2xPlqKiCejPYOA+U+8L20icM1o+q3pVsgmnbinOicYhy3A7dPTRz86/QaOaVvcetEXY dYs89acV6hfNUd4+fdZ4ZRFyLz7lN9wbXYcsbtqfG1inT7+0MW1Ekh0OyKHkWoun2pjk m/LCalFK+FiNWFm7knEoRE2TlOKsHlmzRrrzWLDErBnAOc5KwDOiArENVxKBiiCkkPSG GRaAxAQZzPF7vBIaJK0RmEGBVaU5ZLZOvzxGLIusFYUCFgLsIorqUVV+16tPWH9zME3k aTqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733140963; x=1733745763; 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=JbmHDTbdMbFLibDhFaSSw7kfgSGxZjF1PeLKMBpjXLU=; b=T9hWFkA9WvqEfEx1KLiTM4SfHWRKEgbpol15wYp5ksms8QVHWn9qG/GZM/yydPQ21o VV9ZW7VGWpEmv6WDu3xo6f6zkrqfdMVEdU01c46NaW/d0q6epPzan5Oxcsef/DMQHTuA 0KQQ1XMtXB92QgMLu92X+HgXYwZKpkJoF/sJn2IAilRoMAvZNiOUFQnB4kFl58VVj1U/ bUGkJfS25tdQnV3I/EsaareuSiBEl+8OdgpI8rwwx19enHJnCp+W+AKkvJVSsGkw9kZC SAxg7hUNFr4OYatXNyc4IuruEYuBcAiVShZnRLdODOq5LEGBM+dw0TpV3jiHw4xSsIUu 15Kw== X-Forwarded-Encrypted: i=1; AJvYcCXUHmx2RWdb7wQM3aqxdv6sIVYM0YXK0D0lddLpb2GI8emJPv+9VnxAZMWB6g26sdCijTkNfjuzrw==@lists.linux.dev X-Gm-Message-State: AOJu0YyXiqlMIGD1Im3DgJJzoAIsKHoHQbd5/QhMdQbo0Zi3cNR0AFvP tONJxiR81Lcv+04R+aOuHPp280sf4LFzUxfI5m64a/OWLGlDhwMLRnKvjd68moM= X-Gm-Gg: ASbGncsH79fgxsajSwKIWrKftE8pF922maeHRMexT05um8K2GRdXrPnhKajGiDFM2z8 2YosGJmRTMO8HTYWovS7wALH7xo+PMXwsDmpyO5om/uTYNhtqZ7UiV5TuCpPZBu1i4c8XpITWXt 6zKHgSymIdu+AiLNpyTLXGltBtApay87BjdMY+2T4pqFsNOZN79tn/BmFXi/DJCsfbYW/or4DeT 6PWDyji+C64j133sPp3Z5eqFA+n1pWlg61ewlX9 X-Google-Smtp-Source: AGHT+IHaPui7+q4ZFmgBdHckntm6x5uHCL4yx9ak/3SvbuzD88H1/SeN3aoXoB92x7+chgCt+jsCSQ== X-Received: by 2002:a05:6000:18a3:b0:385:e8b0:df11 with SMTP id ffacd0b85a97d-385e8b0e037mr4813389f8f.37.1733140960834; Mon, 02 Dec 2024 04:02:40 -0800 (PST) Received: from [127.0.1.1] ([193.57.185.11]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-434b0d9bed7sm152396095e9.8.2024.12.02.04.02.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Dec 2024 04:02:40 -0800 (PST) From: Bartosz Golaszewski Date: Mon, 02 Dec 2024 13:02:19 +0100 Subject: [PATCH RESEND v7 03/17] blk-crypto: add ioctls to create and prepare hardware-wrapped keys Precedence: bulk X-Mailing-List: dm-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241202-wrapped-keys-v7-3-67c3ca3f3282@linaro.org> References: <20241202-wrapped-keys-v7-0-67c3ca3f3282@linaro.org> In-Reply-To: <20241202-wrapped-keys-v7-0-67c3ca3f3282@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" , Gaurav Kashyap , Neil Armstrong , Dmitry Baryshkov , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam 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.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=18924; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=XVd9BEBUqKhLheLfRrJQYUbVZgWWUoQ/WAiYDGJYj6w=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnTaHSa2hKCjXqvabjMLfRi1dsmvc7YNcl8wsX1 I0DkwyKkouJAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZ02h0gAKCRARpy6gFHHX coGzEACUO+jaQcPhr8E6oxRlGwkw9b+JvHcQpbWY9j8wPCJfuKdXYvHSLP5vV4JxI721pS5rYcq G96xHSiIQao+tNxOSAx06J8WOamGv78zpJXg2pGiml0sEOn+YIA9u7Zf4V9M162TFaLs23AFDnv R3AiORGGDUi+001ct+K8PPro4TqhOlI0uSC49/OZEoas98Eb/j++2Rq7EN6xudHQyvZXAc87gCp pxfa4V39LwVgqsJc7DYyWyxUOqEffJymZK/eRF1DwRY+hOtVrADwEKRZHMagMNvf0abNVVpHKpz SehAoND/x7ge1Aj4St70C5ZNndzvNvQwLh1rJNTVll5LKVlN6BRdcLPKos0Q0rjj6wyobnz8JNe SGfnOxG0KqDtDInBr5HjE9/fqgzRCKijrAtCS7FhA3z/72IXpkv41lrbH+MAqff7pcIsXFPMJ1v o+Dpxbs0jvbj+BXwYT04v7JbTowmvM5G+ug4rbzOLcIBy+29ZH1QMprdgtHlEVVNRdNIJCMQ+wA mbC7+u6hhNUmrc5aINayi4I1QZeEoDaHdDPhePZAW1GACY52E9qj9OXh4DGB5EbbI6SosxfbMTU wIwOMfWEuY2MYl56hoqmLUMcyTL6gHk+Do4g68QFU3D2PRRmDI8/x/Qj7p8sNdIIha9NPaE+odx c7MK67qEoL9y8oQ== X-Developer-Key: i=bartosz.golaszewski@linaro.org; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 From: Eric Biggers Until this point, the kernel can use hardware-wrapped keys to do encryption if userspace provides one -- specifically a key in ephemerally-wrapped form. However, no generic way has been provided for userspace to get such a key in the first place. Getting such a key is a two-step process. First, the key needs to be imported from a raw key or generated by the hardware, producing a key in long-term wrapped form. This happens once in the whole lifetime of the key. Second, the long-term wrapped key needs to be converted into ephemerally-wrapped form. This happens each time the key is "unlocked". In Android, these operations are supported in a generic way through KeyMint, a userspace abstraction layer. However, that method is Android-specific and can't be used on other Linux systems, may rely on proprietary libraries, and also misleads people into supporting KeyMint features like rollback resistance that make sense for other KeyMint keys but don't make sense for hardware-wrapped inline encryption keys. Therefore, this patch provides a generic kernel interface for these operations by introducing new block device ioctls: - BLKCRYPTOIMPORTKEY: convert a raw key to long-term wrapped form. - BLKCRYPTOGENERATEKEY: have the hardware generate a new key, then return it in long-term wrapped form. - BLKCRYPTOPREPAREKEY: convert a key from long-term wrapped form to ephemerally-wrapped form. These ioctls are implemented using new operations in blk_crypto_ll_ops. Signed-off-by: Eric Biggers Signed-off-by: Bartosz Golaszewski --- Documentation/block/inline-encryption.rst | 32 +++++ Documentation/userspace-api/ioctl/ioctl-number.rst | 2 + block/blk-crypto-internal.h | 9 ++ block/blk-crypto-profile.c | 57 ++++++++ block/blk-crypto.c | 143 +++++++++++++++++++++ block/ioctl.c | 5 + include/linux/blk-crypto-profile.h | 53 ++++++++ include/linux/blk-crypto.h | 1 + include/uapi/linux/blk-crypto.h | 44 +++++++ include/uapi/linux/fs.h | 6 +- 10 files changed, 348 insertions(+), 4 deletions(-) diff --git a/Documentation/block/inline-encryption.rst b/Documentation/block/inline-encryption.rst index 07218455a2bc3..e31b32495f66f 100644 --- a/Documentation/block/inline-encryption.rst +++ b/Documentation/block/inline-encryption.rst @@ -486,6 +486,38 @@ keys, when hardware support is available. This works in the following way: blk-crypto-fallback doesn't support hardware-wrapped keys. Therefore, hardware-wrapped keys can only be used with actual inline encryption hardware. +All the above deals with hardware-wrapped keys in ephemerally-wrapped form only. +To get such keys in the first place, new block device ioctls have been added to +provide a generic interface to creating and preparing such keys: + +- ``BLKCRYPTOIMPORTKEY`` converts a raw key to long-term wrapped form. It takes + in a pointer to a ``struct blk_crypto_import_key_arg``. The caller must set + ``raw_key_ptr`` and ``raw_key_size`` to the pointer and size (in bytes) of the + raw key to import. On success, ``BLKCRYPTOIMPORTKEY`` returns 0 and writes + the resulting long-term wrapped key blob to the buffer pointed to by + ``lt_key_ptr``, which is of maximum size ``lt_key_size``. It also updates + ``lt_key_size`` to be the actual size of the key. On failure, it returns -1 + and sets errno. + +- ``BLKCRYPTOGENERATEKEY`` is like ``BLKCRYPTOIMPORTKEY``, but it has the + hardware generate the key instead of importing one. It takes in a pointer to + a ``struct blk_crypto_generate_key_arg``. + +- ``BLKCRYPTOPREPAREKEY`` converts a key from long-term wrapped form to + ephemerally-wrapped form. It takes in a pointer to a ``struct + blk_crypto_prepare_key_arg``. The caller must set ``lt_key_ptr`` and + ``lt_key_size`` to the pointer and size (in bytes) of the long-term wrapped + key blob to convert. On success, ``BLKCRYPTOPREPAREKEY`` returns 0 and writes + the resulting ephemerally-wrapped key blob to the buffer pointed to by + ``eph_key_ptr``, which is of maximum size ``eph_key_size``. It also updates + ``eph_key_size`` to be the actual size of the key. On failure, it returns -1 + and sets errno. + +Userspace needs to use either ``BLKCRYPTOIMPORTKEY`` or ``BLKCRYPTOGENERATEKEY`` +once to create a key, and then ``BLKCRYPTOPREPAREKEY`` each time the key is +unlocked and added to the kernel. Note that these ioctls have no relevance for +standard keys; they are only for hardware-wrapped keys. + Testability ----------- diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst index 243f1f1b554a2..b9d385e3c7bc5 100644 --- a/Documentation/userspace-api/ioctl/ioctl-number.rst +++ b/Documentation/userspace-api/ioctl/ioctl-number.rst @@ -85,6 +85,8 @@ Code Seq# Include File Comments 0x10 20-2F arch/s390/include/uapi/asm/hypfs.h 0x12 all linux/fs.h BLK* ioctls linux/blkpg.h + linux/blkzoned.h + linux/blk-crypto.h 0x15 all linux/fs.h FS_IOC_* ioctls 0x1b all InfiniBand Subsystem diff --git a/block/blk-crypto-internal.h b/block/blk-crypto-internal.h index 1893df9a8f06c..ccf6dff6ff6be 100644 --- a/block/blk-crypto-internal.h +++ b/block/blk-crypto-internal.h @@ -83,6 +83,9 @@ int __blk_crypto_evict_key(struct blk_crypto_profile *profile, bool __blk_crypto_cfg_supported(struct blk_crypto_profile *profile, const struct blk_crypto_config *cfg); +int blk_crypto_ioctl(struct block_device *bdev, unsigned int cmd, + void __user *argp); + #else /* CONFIG_BLK_INLINE_ENCRYPTION */ static inline int blk_crypto_sysfs_register(struct gendisk *disk) @@ -130,6 +133,12 @@ static inline bool blk_crypto_rq_has_keyslot(struct request *rq) return false; } +static inline int blk_crypto_ioctl(struct block_device *bdev, unsigned int cmd, + void __user *argp) +{ + return -ENOTTY; +} + #endif /* CONFIG_BLK_INLINE_ENCRYPTION */ void __bio_crypt_advance(struct bio *bio, unsigned int bytes); diff --git a/block/blk-crypto-profile.c b/block/blk-crypto-profile.c index 1b92276ed2fcc..f6419502fcbee 100644 --- a/block/blk-crypto-profile.c +++ b/block/blk-crypto-profile.c @@ -502,6 +502,63 @@ int blk_crypto_derive_sw_secret(struct block_device *bdev, return err; } +int blk_crypto_import_key(struct blk_crypto_profile *profile, + const u8 *raw_key, size_t raw_key_size, + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]) +{ + int ret; + + if (!profile) + return -EOPNOTSUPP; + if (!(profile->key_types_supported & BLK_CRYPTO_KEY_TYPE_HW_WRAPPED)) + return -EOPNOTSUPP; + if (!profile->ll_ops.import_key) + return -EOPNOTSUPP; + blk_crypto_hw_enter(profile); + ret = profile->ll_ops.import_key(profile, raw_key, raw_key_size, + lt_key); + blk_crypto_hw_exit(profile); + return ret; +} + +int blk_crypto_generate_key(struct blk_crypto_profile *profile, + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]) +{ + int ret; + + if (!profile) + return -EOPNOTSUPP; + if (!(profile->key_types_supported & BLK_CRYPTO_KEY_TYPE_HW_WRAPPED)) + return -EOPNOTSUPP; + if (!profile->ll_ops.generate_key) + return -EOPNOTSUPP; + + blk_crypto_hw_enter(profile); + ret = profile->ll_ops.generate_key(profile, lt_key); + blk_crypto_hw_exit(profile); + return ret; +} + +int blk_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]) +{ + int ret; + + if (!profile) + return -EOPNOTSUPP; + if (!(profile->key_types_supported & BLK_CRYPTO_KEY_TYPE_HW_WRAPPED)) + return -EOPNOTSUPP; + if (!profile->ll_ops.prepare_key) + return -EOPNOTSUPP; + + blk_crypto_hw_enter(profile); + ret = profile->ll_ops.prepare_key(profile, lt_key, lt_key_size, + eph_key); + blk_crypto_hw_exit(profile); + return ret; +} + /** * blk_crypto_intersect_capabilities() - restrict supported crypto capabilities * by child device diff --git a/block/blk-crypto.c b/block/blk-crypto.c index 5a09d0ef1a011..2270a88e2e4d8 100644 --- a/block/blk-crypto.c +++ b/block/blk-crypto.c @@ -467,3 +467,146 @@ void blk_crypto_evict_key(struct block_device *bdev, pr_warn_ratelimited("%pg: error %d evicting key\n", bdev, err); } EXPORT_SYMBOL_GPL(blk_crypto_evict_key); + +static int blk_crypto_ioctl_import_key(struct blk_crypto_profile *profile, + void __user *argp) +{ + struct blk_crypto_import_key_arg arg; + u8 raw_key[BLK_CRYPTO_MAX_STANDARD_KEY_SIZE]; + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]; + int ret; + + if (copy_from_user(&arg, argp, sizeof(arg))) + return -EFAULT; + + if (memchr_inv(arg.reserved, 0, sizeof(arg.reserved))) + return -EINVAL; + + if (arg.raw_key_size < 16 || arg.raw_key_size > sizeof(raw_key)) + return -EINVAL; + + if (copy_from_user(raw_key, u64_to_user_ptr(arg.raw_key_ptr), + arg.raw_key_size)) { + ret = -EFAULT; + goto out; + } + ret = blk_crypto_import_key(profile, raw_key, arg.raw_key_size, lt_key); + if (ret < 0) + goto out; + if (ret > arg.lt_key_size) { + ret = -EOVERFLOW; + goto out; + } + arg.lt_key_size = ret; + if (copy_to_user(u64_to_user_ptr(arg.lt_key_ptr), lt_key, + arg.lt_key_size) || + copy_to_user(argp, &arg, sizeof(arg))) { + ret = -EFAULT; + goto out; + } + ret = 0; + +out: + memzero_explicit(raw_key, sizeof(raw_key)); + memzero_explicit(lt_key, sizeof(lt_key)); + return ret; +} + +static int blk_crypto_ioctl_generate_key(struct blk_crypto_profile *profile, + void __user *argp) +{ + struct blk_crypto_generate_key_arg arg; + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]; + int ret; + + if (copy_from_user(&arg, argp, sizeof(arg))) + return -EFAULT; + + if (memchr_inv(arg.reserved, 0, sizeof(arg.reserved))) + return -EINVAL; + + ret = blk_crypto_generate_key(profile, lt_key); + if (ret < 0) + goto out; + if (ret > arg.lt_key_size) { + ret = -EOVERFLOW; + goto out; + } + arg.lt_key_size = ret; + if (copy_to_user(u64_to_user_ptr(arg.lt_key_ptr), lt_key, + arg.lt_key_size) || + copy_to_user(argp, &arg, sizeof(arg))) { + ret = -EFAULT; + goto out; + } + ret = 0; + +out: + memzero_explicit(lt_key, sizeof(lt_key)); + return ret; +} + +static int blk_crypto_ioctl_prepare_key(struct blk_crypto_profile *profile, + void __user *argp) +{ + struct blk_crypto_prepare_key_arg arg; + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]; + u8 eph_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]; + int ret; + + if (copy_from_user(&arg, argp, sizeof(arg))) + return -EFAULT; + + if (memchr_inv(arg.reserved, 0, sizeof(arg.reserved))) + return -EINVAL; + + if (arg.lt_key_size > sizeof(lt_key)) + return -EINVAL; + + if (copy_from_user(lt_key, u64_to_user_ptr(arg.lt_key_ptr), + arg.lt_key_size)) { + ret = -EFAULT; + goto out; + } + ret = blk_crypto_prepare_key(profile, lt_key, arg.lt_key_size, eph_key); + if (ret < 0) + goto out; + if (ret > arg.eph_key_size) { + ret = -EOVERFLOW; + goto out; + } + arg.eph_key_size = ret; + if (copy_to_user(u64_to_user_ptr(arg.eph_key_ptr), eph_key, + arg.eph_key_size) || + copy_to_user(argp, &arg, sizeof(arg))) { + ret = -EFAULT; + goto out; + } + ret = 0; + +out: + memzero_explicit(lt_key, sizeof(lt_key)); + memzero_explicit(eph_key, sizeof(eph_key)); + return ret; +} + +int blk_crypto_ioctl(struct block_device *bdev, unsigned int cmd, + void __user *argp) +{ + struct blk_crypto_profile *profile = + bdev_get_queue(bdev)->crypto_profile; + + if (!profile) + return -EOPNOTSUPP; + + switch (cmd) { + case BLKCRYPTOIMPORTKEY: + return blk_crypto_ioctl_import_key(profile, argp); + case BLKCRYPTOGENERATEKEY: + return blk_crypto_ioctl_generate_key(profile, argp); + case BLKCRYPTOPREPAREKEY: + return blk_crypto_ioctl_prepare_key(profile, argp); + default: + return -ENOTTY; + } +} diff --git a/block/ioctl.c b/block/ioctl.c index 6554b728bae6a..faa40f383e273 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -15,6 +15,7 @@ #include #include #include "blk.h" +#include "blk-crypto-internal.h" static int blkpg_do_ioctl(struct block_device *bdev, struct blkpg_partition __user *upart, int op) @@ -620,6 +621,10 @@ static int blkdev_common_ioctl(struct block_device *bdev, blk_mode_t mode, case BLKTRACESTOP: case BLKTRACETEARDOWN: return blk_trace_ioctl(bdev, cmd, argp); + case BLKCRYPTOIMPORTKEY: + case BLKCRYPTOGENERATEKEY: + case BLKCRYPTOPREPAREKEY: + return blk_crypto_ioctl(bdev, cmd, argp); case IOC_PR_REGISTER: return blkdev_pr_register(bdev, mode, argp); case IOC_PR_RESERVE: diff --git a/include/linux/blk-crypto-profile.h b/include/linux/blk-crypto-profile.h index 229287a7f451f..a3eef098f3c3d 100644 --- a/include/linux/blk-crypto-profile.h +++ b/include/linux/blk-crypto-profile.h @@ -71,6 +71,48 @@ struct blk_crypto_ll_ops { 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]); + + /** + * @import_key: Create a hardware-wrapped key by importing a raw key. + * + * This only needs to be implemented if BLK_CRYPTO_KEY_TYPE_HW_WRAPPED + * is supported. + * + * On success, must write the new key in long-term wrapped form to + * @lt_key and return its size in bytes. On failure, must return a + * -errno value. + */ + int (*import_key)(struct blk_crypto_profile *profile, + const u8 *raw_key, size_t raw_key_size, + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]); + + /** + * @generate_key: Generate a hardware-wrapped key. + * + * This only needs to be implemented if BLK_CRYPTO_KEY_TYPE_HW_WRAPPED + * is supported. + * + * On success, must write the new key in long-term wrapped form to + * @lt_key and return its size in bytes. On failure, must return a + * -errno value. + */ + int (*generate_key)(struct blk_crypto_profile *profile, + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]); + + /** + * @prepare_key: Prepare a hardware-wrapped key to be used. + * + * Prepare a hardware-wrapped key to be used by converting it from + * long-term wrapped form to ephemerally-wrapped form. This only needs + * to be implemented if BLK_CRYPTO_KEY_TYPE_HW_WRAPPED is supported. + * + * On success, must write the key in ephemerally-wrapped form to + * @eph_key and return its size in bytes. On failure, must return a + * -errno value. + */ + int (*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]); }; /** @@ -163,6 +205,17 @@ void blk_crypto_reprogram_all_keys(struct blk_crypto_profile *profile); void blk_crypto_profile_destroy(struct blk_crypto_profile *profile); +int blk_crypto_import_key(struct blk_crypto_profile *profile, + const u8 *raw_key, size_t raw_key_size, + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]); + +int blk_crypto_generate_key(struct blk_crypto_profile *profile, + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]); + +int blk_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]); + void blk_crypto_intersect_capabilities(struct blk_crypto_profile *parent, const struct blk_crypto_profile *child); diff --git a/include/linux/blk-crypto.h b/include/linux/blk-crypto.h index 19066d86ecbf7..e61008c236688 100644 --- a/include/linux/blk-crypto.h +++ b/include/linux/blk-crypto.h @@ -7,6 +7,7 @@ #define __LINUX_BLK_CRYPTO_H #include +#include enum blk_crypto_mode_num { BLK_ENCRYPTION_MODE_INVALID, diff --git a/include/uapi/linux/blk-crypto.h b/include/uapi/linux/blk-crypto.h new file mode 100644 index 0000000000000..97302c6eb6afe --- /dev/null +++ b/include/uapi/linux/blk-crypto.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _UAPI_LINUX_BLK_CRYPTO_H +#define _UAPI_LINUX_BLK_CRYPTO_H + +#include +#include + +struct blk_crypto_import_key_arg { + /* Raw key (input) */ + __u64 raw_key_ptr; + __u64 raw_key_size; + /* Long-term wrapped key blob (output) */ + __u64 lt_key_ptr; + __u64 lt_key_size; + __u64 reserved[4]; +}; + +struct blk_crypto_generate_key_arg { + /* Long-term wrapped key blob (output) */ + __u64 lt_key_ptr; + __u64 lt_key_size; + __u64 reserved[4]; +}; + +struct blk_crypto_prepare_key_arg { + /* Long-term wrapped key blob (input) */ + __u64 lt_key_ptr; + __u64 lt_key_size; + /* Ephemerally-wrapped key blob (output) */ + __u64 eph_key_ptr; + __u64 eph_key_size; + __u64 reserved[4]; +}; + +/* + * These ioctls share the block device ioctl space; see uapi/linux/fs.h. + * 140-141 are reserved for future blk-crypto ioctls; any more than that would + * require an additional allocation from the block device ioctl space. + */ +#define BLKCRYPTOIMPORTKEY _IOWR(0x12, 137, struct blk_crypto_import_key_arg) +#define BLKCRYPTOGENERATEKEY _IOWR(0x12, 138, struct blk_crypto_generate_key_arg) +#define BLKCRYPTOPREPAREKEY _IOWR(0x12, 139, struct blk_crypto_prepare_key_arg) + +#endif /* _UAPI_LINUX_BLK_CRYPTO_H */ diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h index 7539717707337..07180da44e13d 100644 --- a/include/uapi/linux/fs.h +++ b/include/uapi/linux/fs.h @@ -203,10 +203,8 @@ struct fsxattr { #define BLKROTATIONAL _IO(0x12,126) #define BLKZEROOUT _IO(0x12,127) #define BLKGETDISKSEQ _IOR(0x12,128,__u64) -/* - * A jump here: 130-136 are reserved for zoned block devices - * (see uapi/linux/blkzoned.h) - */ +/* 130-136 are used by zoned block device ioctls (uapi/linux/blkzoned.h) */ +/* 137-141 are used by blk-crypto ioctls (uapi/linux/blk-crypto.h) */ #define BMAP_IOCTL 1 /* obsolete - kept for compatibility */ #define FIBMAP _IO(0x00,1) /* bmap access */ From patchwork Mon Dec 2 12:02:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 13890359 X-Patchwork-Delegate: snitzer@redhat.com 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 D10E61FECAF for ; Mon, 2 Dec 2024 12:02:45 +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=1733140972; cv=none; b=szUtE5DXVQPI90fBACkfrU+Pa/dnmiQ/JGw3kQFKxTsZ2POyZXEEk/OYD6qqVsPe6URCLKvdwKCVZUAxUVwVJD4L+iAn5lX9vHyvCZKh2tUZXu+GWTuH3dUtRBSI9lkj0pJCKIsGQJH68wgWX4HXkozAreGrpCpDaryj69TTDbc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140972; c=relaxed/simple; bh=fQ5UQE+przlZ0BeiqrSFVoMcpjW+DwXdZQn/uPLysoo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CvCuYN1Y4otQF5u+YZh/UyK5ZGJBDKNUtGNtwpIHn3LJComp+azo3ABUJVMmx22rG5No0Bx3VQp7vte7yPZ0D7/Kz59Io5Vv2DiChUZavX6jnwX4DMqn+XmKfv1h6eifwa/1YkMG4KrpB6n+/oi8fxdOrnyXh8EVDcVYvoTVP8k= 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=LHgeGX65; 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="LHgeGX65" Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-434a736518eso52520095e9.1 for ; Mon, 02 Dec 2024 04:02:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1733140964; x=1733745764; darn=lists.linux.dev; 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=fzYsR4fPMAUSlweUAnZ3z9CwJlVMGTkodPbQGaiasNY=; b=LHgeGX650UBCmAe4/WcHUG9VK6rav48pLAnUCjROMATbQvWvtcXUV/IWMLRCMGBWfg 4tiVCeh6+TDq7bZTrM18/SqzPGFIXjZwfW9/4untdK3t66iv6E8QUO+2s6p5mBmKACbd FF+avoNL2k5puOzIIesKKmzRBWwTxYFg5vtFszcGsifBMGAyPJn7Mr1Gl3jkm1FGLQP7 KSiTtaIhgWMNSkKK9ZhPCHPnEb832X9BDVYvvPdc5D3anKfbJEZZH772SOKOgjKZb03w cULD4ntc9qb7bSThcZ2lpqf6KSSvcRQc1sgA95bSkBk/B4xvy8l0JRJXN2XIit9bmgNe yy4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733140964; x=1733745764; 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=fzYsR4fPMAUSlweUAnZ3z9CwJlVMGTkodPbQGaiasNY=; b=T4079UU31wEhR2HxDXX+wLxa6NDNiSW9SCHTuZeGNvt2vl3JIR/aYVKh8SORYAKTYW tDk//c13vj6DcCR+2bRNUA+g0OioB8S/K8Zf1dUygJqjs3UFMZ1NiKmE/9VcstpungeB aMcwjGmER9X6QJ1rTCZfFg6lXr3C6Niy1XBXiqb9ZsX/3hUaJeWLQBtC+noxphy9bv8J cO1cJfbUG0zC/OKBMx6/au4bxgdR2Ow0Ju4jRgQ2J7mNayDjQsa+lNRO6krtrJ2aOftB Gjq9/+09Akyg6cNeNbvWlgFA7p644FuZs9PvlnGlyaElPRtxlss2OY4wvYxGBAdKMcyy pwaw== X-Forwarded-Encrypted: i=1; AJvYcCWuaQM4wF4bq0nBntpFdIiHeSxW9N8MiUIzt3MDqM9q5D3vPZT9Z7e5jXRqSEa6QonZv34Xe8D8Ew==@lists.linux.dev X-Gm-Message-State: AOJu0YwfbNMUU0RO4SnMHo21jJ1gm/ySeko4CPU9+oczpglS6rojmUGo fJKScxCaajpgDylr0fKNVwRJvPvrNgsx6GJkyMNOFzN6RBexTK72mTzoW3RiOsU= X-Gm-Gg: ASbGncuL7+LFHb8TGw7HNVa40ewD6dvKEgWrjPg7I14lo6tRJ63Drs3Bl/pASFN89U4 F7h2wS4ffIP0AT3m5SduNWJDQOoZJsBLeD7RfBTb3izXB+c0v8S8cXKjSXUEr93WZlv4aST8IFt Fjh4aSpdMosD0OLmSWkFLDcM1U0WTWaR/6uqm3qUkiQ7LnDHo5zz15GCCqh3OB32wrnk131uo2Q s0l1NrfP0Jf9ra+N5szTr9S7wo4NmOVk2Zo8w59 X-Google-Smtp-Source: AGHT+IE+10EBP2XKoBiZXQmEhzLLRfyuxNX9inrS2NiqBNIcNWRu8PFg9CIjxYZcAnLsObazRExuVA== X-Received: by 2002:a05:600c:4f85:b0:431:4f29:9539 with SMTP id 5b1f17b1804b1-434a9dfbb05mr220160665e9.32.1733140963342; Mon, 02 Dec 2024 04:02:43 -0800 (PST) Received: from [127.0.1.1] ([193.57.185.11]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-434b0d9bed7sm152396095e9.8.2024.12.02.04.02.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Dec 2024 04:02:42 -0800 (PST) From: Bartosz Golaszewski Date: Mon, 02 Dec 2024 13:02:20 +0100 Subject: [PATCH RESEND v7 04/17] fscrypt: add support for hardware-wrapped keys Precedence: bulk X-Mailing-List: dm-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241202-wrapped-keys-v7-4-67c3ca3f3282@linaro.org> References: <20241202-wrapped-keys-v7-0-67c3ca3f3282@linaro.org> In-Reply-To: <20241202-wrapped-keys-v7-0-67c3ca3f3282@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" , Gaurav Kashyap , Neil Armstrong , Dmitry Baryshkov , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam 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.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=40243; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=wqhiZ88ieICtwNPbt7E4MyENol1dZqLnOFjNt8pcbww=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnTaHS256+NH5RYrGYqGi6oqF+h7Gr9B+/Z0LcU uA+V+ZBdoyJAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZ02h0gAKCRARpy6gFHHX cmXCD/401A0qhPfGNqLIfutoAp6YTTDV480/CWY09AJzfFPinybQt/Umg15231IUNCOf65KqIBm SFAgssIi+zo9Tw01jv3OVgX5M1qGtjOykowndiU8F6GGilT6PiYU49dCD+o+YY9ezT+AuQdcAxE dy5hNJEiR31KpHtAn9DZHcaidvF9zrSWU6hPhdIWt7itd+A55ABhi7UAbyN7RF0KonrGWDEGroe fftV4zWIfJ4KU6GE+fxYHelxHOex3joVfkdQLNI4vLxm8680XAfogYYaqaWHLKWoq9knmGS28gS DUHIRFfbwiM540Emw0JgrUfJLpu07r/x10HUzrejK5kNT93lGEGbVHz6LylvhDYQRahiJJHnFoi Inx0xhP99u+TtCeR0Im1cIM0kNZBz4/4ZvuMuHS4piqxbyimhWPzYAxnKTHf1aEojYsrnR1o8eU xNqxbuNPJhy3mIacDlDOitFwb3Iodtdbx8pkvCQrGW8RUkhKUx4bS7ICqNMRrTA92467QnRyjKF tz2Uc9v0FwFzoQ9gnbdT4AEbejYuNdkJgWj3mgU5W8GwgNGpdzropZo9btONIciniOw4BKI1eS8 ueuVojkjZYp78siSQGeTPCyQ6tichKn2MPUB3juV2VagbwgsuPaCpr17yaKZhQqzHQZvpzhZsoD ul+0D/vYeDjcb1A== X-Developer-Key: i=bartosz.golaszewski@linaro.org; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 From: Eric Biggers Add support for hardware-wrapped keys to fscrypt. Such keys are protected from certain attacks, such as cold boot attacks. For more information, see the "Hardware-wrapped keys" section of Documentation/block/inline-encryption.rst. To support hardware-wrapped keys in fscrypt, we allow the fscrypt master keys to be hardware-wrapped, and we allow encryption policies to be flagged as needing a hardware-wrapped key. File contents encryption is done by passing the wrapped key to the inline encryption hardware via blk-crypto. Other fscrypt operations such as filenames encryption continue to be done by the kernel, using the "software secret" which the hardware derives. For more information, see the documentation which this patch adds to Documentation/filesystems/fscrypt.rst. Note that this feature doesn't require any filesystem-specific changes. However it does depend on inline encryption support, and thus currently it is only applicable to ext4 and f2fs. This feature is intentionally not UAPI or on-disk format compatible with the version of this feature in the Android Common Kernels, as that version was meant as a temporary solution and it took some shortcuts. Once upstreamed, this new version should be used going forwards. This patch has been heavily rewritten from the original version by Gaurav Kashyap and Barani Muthukumaran . Signed-off-by: Eric Biggers Reviewed-by: Konrad Dybcio Signed-off-by: Bartosz Golaszewski --- Documentation/filesystems/fscrypt.rst | 154 ++++++++++++++++++++++++++++++---- fs/crypto/fscrypt_private.h | 71 ++++++++++++++-- fs/crypto/hkdf.c | 4 +- fs/crypto/inline_crypt.c | 46 ++++++++-- fs/crypto/keyring.c | 124 +++++++++++++++++++-------- fs/crypto/keysetup.c | 54 +++++++++++- fs/crypto/keysetup_v1.c | 5 +- fs/crypto/policy.c | 11 ++- include/uapi/linux/fscrypt.h | 7 +- 9 files changed, 402 insertions(+), 74 deletions(-) diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst index 04eaab01314bc..a359a92d6c47a 100644 --- a/Documentation/filesystems/fscrypt.rst +++ b/Documentation/filesystems/fscrypt.rst @@ -70,7 +70,7 @@ Online attacks -------------- fscrypt (and storage encryption in general) can only provide limited -protection, if any at all, against online attacks. In detail: +protection against online attacks. In detail: Side-channel attacks ~~~~~~~~~~~~~~~~~~~~ @@ -99,16 +99,23 @@ Therefore, any encryption-specific access control checks would merely be enforced by kernel *code* and therefore would be largely redundant with the wide variety of access control mechanisms already available.) -Kernel memory compromise -~~~~~~~~~~~~~~~~~~~~~~~~ +Read-only kernel memory compromise +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -An attacker who compromises the system enough to read from arbitrary -memory, e.g. by mounting a physical attack or by exploiting a kernel -security vulnerability, can compromise all encryption keys that are -currently in use. +Unless `hardware-wrapped keys`_ are used, an attacker who gains the +ability to read from arbitrary kernel memory, e.g. by mounting a +physical attack or by exploiting a kernel security vulnerability, can +compromise all fscrypt keys that are currently in-use. This also +extends to cold boot attacks; if the system is suddenly powered off, +keys the system was using may remain in memory for a short time. -However, fscrypt allows encryption keys to be removed from the kernel, -which may protect them from later compromise. +However, if hardware-wrapped keys are used, then the fscrypt master +keys and file contents encryption keys (but not other types of fscrypt +subkeys such as filenames encryption keys) are protected from +compromises of arbitrary kernel memory. + +In addition, fscrypt allows encryption keys to be removed from the +kernel, which may protect them from later compromise. In more detail, the FS_IOC_REMOVE_ENCRYPTION_KEY ioctl (or the FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS ioctl) can wipe a master @@ -145,6 +152,24 @@ However, these ioctls have some limitations: accelerator hardware (if used by the crypto API to implement any of the algorithms), or in other places not explicitly considered here. +Full system compromise +~~~~~~~~~~~~~~~~~~~~~~ + +An attacker who gains "root" access and/or the ability to execute +arbitrary kernel code can freely exfiltrate data that is protected by +any in-use fscrypt keys. Thus, usually fscrypt provides no meaningful +protection in this scenario. (Data that is protected by a key that is +absent throughout the entire attack remains protected, modulo the +limitations of key removal mentioned above in the case where the key +was removed prior to the attack.) + +However, if `hardware-wrapped keys`_ are used, such attackers will be +unable to exfiltrate the master keys or file contents keys in a form +that will be usable after the system is powered off. This may be +useful if the attacker is significantly time-limited and/or +bandwidth-limited, so they can only exfiltrate some data and need to +rely on a later offline attack to exfiltrate the rest of it. + Limitations of v1 policies ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -171,6 +196,11 @@ policies on all new encrypted directories. Key hierarchy ============= +Note: this section assumes the use of standard keys (i.e. "software +keys") rather than hardware-wrapped keys. The use of hardware-wrapped +keys modifies the key hierarchy slightly. For details, see the +`Hardware-wrapped keys`_ section. + Master Keys ----------- @@ -614,6 +644,8 @@ This structure must be initialized as follows: policies`_. - FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32: See `IV_INO_LBLK_32 policies`_. + - FSCRYPT_POLICY_FLAG_HW_WRAPPED_KEY: This flag denotes that this + policy uses a hardware-wrapped key. See `Hardware-wrapped keys`_. v1 encryption policies only support the PAD_* and DIRECT_KEY flags. The other flags are only supported by v2 encryption policies. @@ -836,7 +868,8 @@ a pointer to struct fscrypt_add_key_arg, defined as follows:: struct fscrypt_key_specifier key_spec; __u32 raw_size; __u32 key_id; - __u32 __reserved[8]; + __u32 flags; + __u32 __reserved[7]; __u8 raw[]; }; @@ -855,7 +888,7 @@ a pointer to struct fscrypt_add_key_arg, defined as follows:: struct fscrypt_provisioning_key_payload { __u32 type; - __u32 __reserved; + __u32 flags; __u8 raw[]; }; @@ -883,6 +916,12 @@ as follows: Alternatively, if ``key_id`` is nonzero, this field must be 0, since in that case the size is implied by the specified Linux keyring key. +- ``flags`` contains optional flags from ````: + + - FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED: This denotes that the key is a + hardware-wrapped key. See `Hardware-wrapped keys`_. This flag + can't be used if FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR is used. + - ``key_id`` is 0 if the raw key is given directly in the ``raw`` field. Otherwise ``key_id`` is the ID of a Linux keyring key of type "fscrypt-provisioning" whose payload is @@ -924,6 +963,8 @@ FS_IOC_ADD_ENCRYPTION_KEY can fail with the following errors: caller does not have the CAP_SYS_ADMIN capability in the initial user namespace; or the raw key was specified by Linux key ID but the process lacks Search permission on the key. +- ``EBADMSG``: FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED was specified, but the + key isn't a valid hardware-wrapped key - ``EDQUOT``: the key quota for this user would be exceeded by adding the key - ``EINVAL``: invalid key size or key specifier type, or reserved bits @@ -935,7 +976,9 @@ FS_IOC_ADD_ENCRYPTION_KEY can fail with the following errors: - ``ENOTTY``: this type of filesystem does not implement encryption - ``EOPNOTSUPP``: the kernel was not configured with encryption support for this filesystem, or the filesystem superblock has not - had encryption enabled on it + had encryption enabled on it, or FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED was + specified but the filesystem and/or the hardware doesn't support + hardware-wrapped keys Legacy method ~~~~~~~~~~~~~ @@ -998,9 +1041,8 @@ or removed by non-root users. These ioctls don't work on keys that were added via the legacy process-subscribed keyrings mechanism. -Before using these ioctls, read the `Kernel memory compromise`_ -section for a discussion of the security goals and limitations of -these ioctls. +Before using these ioctls, read the `Online attacks`_ section for a +discussion of the security goals and limitations of these ioctls. FS_IOC_REMOVE_ENCRYPTION_KEY ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1320,7 +1362,8 @@ inline encryption hardware doesn't have the needed crypto capabilities (e.g. support for the needed encryption algorithm and data unit size) and where blk-crypto-fallback is unusable. (For blk-crypto-fallback to be usable, it must be enabled in the kernel configuration with -CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y.) +CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y, and the file must be +protected by a standard key rather than a hardware-wrapped key.) Currently fscrypt always uses the filesystem block size (which is usually 4096 bytes) as the data unit size. Therefore, it can only use @@ -1328,7 +1371,84 @@ inline encryption hardware that supports that data unit size. Inline encryption doesn't affect the ciphertext or other aspects of the on-disk format, so users may freely switch back and forth between -using "inlinecrypt" and not using "inlinecrypt". +using "inlinecrypt" and not using "inlinecrypt". An exception is that +files that are protected by a hardware-wrapped key can only be +encrypted/decrypted by the inline encryption hardware and therefore +can only be accessed when the "inlinecrypt" mount option is used. For +more information about hardware-wrapped keys, see below. + +Hardware-wrapped keys +--------------------- + +fscrypt supports using *hardware-wrapped keys* when the inline +encryption hardware supports it. Such keys are only present in kernel +memory in wrapped (encrypted) form; they can only be unwrapped +(decrypted) by the inline encryption hardware and are temporally bound +to the current boot. This prevents the keys from being compromised if +kernel memory is leaked. This is done without limiting the number of +keys that can be used and while still allowing the execution of +cryptographic tasks that are tied to the same key but can't use inline +encryption hardware, e.g. filenames encryption. + +Note that hardware-wrapped keys aren't specific to fscrypt; they are a +block layer feature (part of *blk-crypto*). For more details about +hardware-wrapped keys, see the block layer documentation at +:ref:`Documentation/block/inline-encryption.rst +`. Below, we just focus on the details of how +fscrypt can use hardware-wrapped keys. + +fscrypt supports hardware-wrapped keys by allowing the fscrypt master +keys to be hardware-wrapped keys as an alternative to standard keys. +To add a hardware-wrapped key with `FS_IOC_ADD_ENCRYPTION_KEY`_, +userspace must specify FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED in the +``flags`` field of struct fscrypt_add_key_arg and also in the +``flags`` field of struct fscrypt_provisioning_key_payload when +applicable. The key must be in ephemerally-wrapped form, not +long-term wrapped form. + +To specify that files will be protected by a hardware-wrapped key, +userspace must specify FSCRYPT_POLICY_FLAG_HW_WRAPPED_KEY in the +encryption policy. (Note that this flag is somewhat redundant, as the +encryption policy also contains the key identifier, and +hardware-wrapped keys and standard keys will have different key +identifiers. However, it is sometimes helpful to make it explicit +that an encryption policy is supposed to use a hardware-wrapped key.) + +Some limitations apply. First, files protected by a hardware-wrapped +key are tied to the system's inline encryption hardware. Therefore +they can only be accessed when the "inlinecrypt" mount option is used, +and they can't be included in portable filesystem images. Second, +currently the hardware-wrapped key support is only compatible with +`IV_INO_LBLK_64 policies`_ and `IV_INO_LBLK_32 policies`_, as it +assumes that there is just one file contents encryption key per +fscrypt master key rather than one per file. Future work may address +this limitation by passing per-file nonces down the storage stack to +allow the hardware to derive per-file keys. + +Implementation-wise, to encrypt/decrypt the contents of files that are +protected by a hardware-wrapped key, fscrypt uses blk-crypto, +attaching the hardware-wrapped key to the bio crypt contexts. As is +the case with standard keys, the block layer will program the key into +a keyslot when it isn't already in one. However, when programming a +hardware-wrapped key, the hardware doesn't program the given key +directly into a keyslot but rather unwraps it (using the hardware's +ephemeral wrapping key) and derives the inline encryption key from it. +The inline encryption key is the key that actually gets programmed +into a keyslot, and it is never exposed to software. + +However, fscrypt doesn't just do file contents encryption; it also +uses its master keys to derive filenames encryption keys, key +identifiers, and sometimes some more obscure types of subkeys such as +dirhash keys. So even with file contents encryption out of the +picture, fscrypt still needs a raw key to work with. To get such a +key from a hardware-wrapped key, fscrypt asks the inline encryption +hardware to derive a cryptographically isolated "software secret" from +the hardware-wrapped key. fscrypt uses this "software secret" to key +its KDF to derive all subkeys other than file contents keys. + +Note that this implies that the hardware-wrapped key feature only +protects the file contents encryption keys. It doesn't protect other +fscrypt subkeys such as filenames encryption keys. Direct I/O support ================== diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h index 8371e4e1f596a..bd01759e16539 100644 --- a/fs/crypto/fscrypt_private.h +++ b/fs/crypto/fscrypt_private.h @@ -27,6 +27,27 @@ */ #define FSCRYPT_MIN_KEY_SIZE 16 +/* Maximum size of a standard fscrypt master key */ +#define FSCRYPT_MAX_STANDARD_KEY_SIZE 64 + +/* Maximum size of a hardware-wrapped fscrypt master key */ +#define FSCRYPT_MAX_HW_WRAPPED_KEY_SIZE BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE + +/* + * Maximum size of an fscrypt master key across both key types. + * This should just use max(), but max() doesn't work in a struct definition. + */ +#define FSCRYPT_MAX_ANY_KEY_SIZE \ + (FSCRYPT_MAX_HW_WRAPPED_KEY_SIZE > FSCRYPT_MAX_STANDARD_KEY_SIZE ? \ + FSCRYPT_MAX_HW_WRAPPED_KEY_SIZE : FSCRYPT_MAX_STANDARD_KEY_SIZE) + +/* + * FSCRYPT_MAX_KEY_SIZE is defined in the UAPI header, but the addition of + * hardware-wrapped keys has made it misleading as it's only for standard keys. + * Don't use it in kernel code; use one of the above constants instead. + */ +#undef FSCRYPT_MAX_KEY_SIZE + #define FSCRYPT_CONTEXT_V1 1 #define FSCRYPT_CONTEXT_V2 2 @@ -360,13 +381,16 @@ int fscrypt_init_hkdf(struct fscrypt_hkdf *hkdf, const u8 *master_key, * outputs are unique and cryptographically isolated, i.e. knowledge of one * output doesn't reveal another. */ -#define HKDF_CONTEXT_KEY_IDENTIFIER 1 /* info= */ +#define HKDF_CONTEXT_KEY_IDENTIFIER_FOR_STANDARD_KEY \ + 1 /* info= */ #define HKDF_CONTEXT_PER_FILE_ENC_KEY 2 /* info=file_nonce */ #define HKDF_CONTEXT_DIRECT_KEY 3 /* info=mode_num */ #define HKDF_CONTEXT_IV_INO_LBLK_64_KEY 4 /* info=mode_num||fs_uuid */ #define HKDF_CONTEXT_DIRHASH_KEY 5 /* info=file_nonce */ #define HKDF_CONTEXT_IV_INO_LBLK_32_KEY 6 /* info=mode_num||fs_uuid */ #define HKDF_CONTEXT_INODE_HASH_KEY 7 /* info= */ +#define HKDF_CONTEXT_KEY_IDENTIFIER_FOR_HW_WRAPPED_KEY \ + 8 /* info= */ int fscrypt_hkdf_expand(const struct fscrypt_hkdf *hkdf, u8 context, const u8 *info, unsigned int infolen, @@ -385,12 +409,17 @@ fscrypt_using_inline_encryption(const struct fscrypt_inode_info *ci) } int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key, - const u8 *raw_key, + const u8 *raw_key, size_t raw_key_size, + bool is_hw_wrapped, const struct fscrypt_inode_info *ci); void fscrypt_destroy_inline_crypt_key(struct super_block *sb, struct fscrypt_prepared_key *prep_key); +int fscrypt_derive_sw_secret(struct super_block *sb, + const u8 *wrapped_key, size_t wrapped_key_size, + u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]); + /* * Check whether the crypto transform or blk-crypto key has been allocated in * @prep_key, depending on which encryption implementation the file will use. @@ -427,7 +456,8 @@ fscrypt_using_inline_encryption(const struct fscrypt_inode_info *ci) static inline int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key, - const u8 *raw_key, + const u8 *raw_key, size_t raw_key_size, + bool is_hw_wrapped, const struct fscrypt_inode_info *ci) { WARN_ON_ONCE(1); @@ -440,6 +470,15 @@ fscrypt_destroy_inline_crypt_key(struct super_block *sb, { } +static inline int +fscrypt_derive_sw_secret(struct super_block *sb, + const u8 *wrapped_key, size_t wrapped_key_size, + u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]) +{ + fscrypt_warn(NULL, "kernel doesn't support hardware-wrapped keys"); + return -EOPNOTSUPP; +} + static inline bool fscrypt_is_key_prepared(struct fscrypt_prepared_key *prep_key, const struct fscrypt_inode_info *ci) @@ -456,11 +495,23 @@ fscrypt_is_key_prepared(struct fscrypt_prepared_key *prep_key, struct fscrypt_master_key_secret { /* - * For v2 policy keys: HKDF context keyed by this master key. - * For v1 policy keys: not set (hkdf.hmac_tfm == NULL). + * The KDF with which subkeys of this key can be derived. + * + * For v1 policy keys, this isn't applicable and won't be set. + * Otherwise, this KDF will be keyed by this master key if + * ->is_hw_wrapped=false, or by the "software secret" that hardware + * derived from this master key if ->is_hw_wrapped=true. */ struct fscrypt_hkdf hkdf; + /* + * True if this key is a hardware-wrapped key; false if this key is a + * standard key (i.e. a "software key"). For v1 policy keys this will + * always be false, as v1 policy support is a legacy feature which + * doesn't support newer functionality such as hardware-wrapped keys. + */ + bool is_hw_wrapped; + /* * Size of the raw key in bytes. This remains set even if ->raw was * zeroized due to no longer being needed. I.e. we still remember the @@ -468,8 +519,14 @@ struct fscrypt_master_key_secret { */ u32 size; - /* For v1 policy keys: the raw key. Wiped for v2 policy keys. */ - u8 raw[FSCRYPT_MAX_KEY_SIZE]; + /* + * The raw key which userspace provided, when still needed. This can be + * either a standard key or a hardware-wrapped key, as indicated by + * ->is_hw_wrapped. In the case of a standard, v2 policy key, there is + * no need to remember the raw key separately from ->hkdf so this field + * will be zeroized as soon as ->hkdf is initialized. + */ + u8 raw[FSCRYPT_MAX_ANY_KEY_SIZE]; } __randomize_layout; diff --git a/fs/crypto/hkdf.c b/fs/crypto/hkdf.c index 5a384dad2c72f..7e007810e4346 100644 --- a/fs/crypto/hkdf.c +++ b/fs/crypto/hkdf.c @@ -4,7 +4,9 @@ * Function"), aka RFC 5869. See also the original paper (Krawczyk 2010): * "Cryptographic Extraction and Key Derivation: The HKDF Scheme". * - * This is used to derive keys from the fscrypt master keys. + * This is used to derive keys from the fscrypt master keys (or from the + * "software secrets" which hardware derives from the fscrypt master keys, in + * the case that the fscrypt master keys are hardware-wrapped keys). * * Copyright 2019 Google LLC */ diff --git a/fs/crypto/inline_crypt.c b/fs/crypto/inline_crypt.c index ee92c78e798bd..eedbf42dd78ed 100644 --- a/fs/crypto/inline_crypt.c +++ b/fs/crypto/inline_crypt.c @@ -93,6 +93,7 @@ int fscrypt_select_encryption_impl(struct fscrypt_inode_info *ci) { const struct inode *inode = ci->ci_inode; struct super_block *sb = inode->i_sb; + unsigned int policy_flags = fscrypt_policy_flags(&ci->ci_policy); struct blk_crypto_config crypto_cfg; struct block_device **devs; unsigned int num_devs; @@ -118,8 +119,7 @@ int fscrypt_select_encryption_impl(struct fscrypt_inode_info *ci) * doesn't work with IV_INO_LBLK_32. For now, simply exclude * IV_INO_LBLK_32 with blocksize != PAGE_SIZE from inline encryption. */ - if ((fscrypt_policy_flags(&ci->ci_policy) & - FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) && + if ((policy_flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) && sb->s_blocksize != PAGE_SIZE) return 0; @@ -130,7 +130,9 @@ 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; + crypto_cfg.key_type = + (policy_flags & FSCRYPT_POLICY_FLAG_HW_WRAPPED_KEY) ? + BLK_CRYPTO_KEY_TYPE_HW_WRAPPED : BLK_CRYPTO_KEY_TYPE_STANDARD; devs = fscrypt_get_devices(sb, &num_devs); if (IS_ERR(devs)) @@ -151,12 +153,15 @@ int fscrypt_select_encryption_impl(struct fscrypt_inode_info *ci) } int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key, - const u8 *raw_key, + const u8 *raw_key, size_t raw_key_size, + bool is_hw_wrapped, const struct fscrypt_inode_info *ci) { const struct inode *inode = ci->ci_inode; struct super_block *sb = inode->i_sb; enum blk_crypto_mode_num crypto_mode = ci->ci_mode->blk_crypto_mode; + enum blk_crypto_key_type key_type = is_hw_wrapped ? + BLK_CRYPTO_KEY_TYPE_HW_WRAPPED : BLK_CRYPTO_KEY_TYPE_STANDARD; struct blk_crypto_key *blk_key; struct block_device **devs; unsigned int num_devs; @@ -167,9 +172,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, ci->ci_mode->keysize, - BLK_CRYPTO_KEY_TYPE_STANDARD, crypto_mode, - fscrypt_get_dun_bytes(ci), + err = blk_crypto_init_key(blk_key, raw_key, raw_key_size, key_type, + crypto_mode, fscrypt_get_dun_bytes(ci), 1U << ci->ci_data_unit_bits); if (err) { fscrypt_err(inode, "error %d initializing blk-crypto key", err); @@ -228,6 +232,34 @@ void fscrypt_destroy_inline_crypt_key(struct super_block *sb, kfree_sensitive(blk_key); } +/* + * Ask the inline encryption hardware to derive the software secret from a + * hardware-wrapped key. Returns -EOPNOTSUPP if hardware-wrapped keys aren't + * supported on this filesystem or hardware. + */ +int fscrypt_derive_sw_secret(struct super_block *sb, + const u8 *wrapped_key, size_t wrapped_key_size, + u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]) +{ + int err; + + /* The filesystem must be mounted with -o inlinecrypt. */ + if (!(sb->s_flags & SB_INLINECRYPT)) { + fscrypt_warn(NULL, + "%s: filesystem not mounted with inlinecrypt\n", + sb->s_id); + return -EOPNOTSUPP; + } + + err = blk_crypto_derive_sw_secret(sb->s_bdev, wrapped_key, + wrapped_key_size, sw_secret); + if (err == -EOPNOTSUPP) + fscrypt_warn(NULL, + "%s: block device doesn't support hardware-wrapped keys\n", + sb->s_id); + return err; +} + bool __fscrypt_inode_uses_inline_crypto(const struct inode *inode) { return inode->i_crypt_info->ci_inlinecrypt; diff --git a/fs/crypto/keyring.c b/fs/crypto/keyring.c index 787e9c8938ba3..a6293dc6fdd9f 100644 --- a/fs/crypto/keyring.c +++ b/fs/crypto/keyring.c @@ -149,11 +149,11 @@ static int fscrypt_user_key_instantiate(struct key *key, struct key_preparsed_payload *prep) { /* - * We just charge FSCRYPT_MAX_KEY_SIZE bytes to the user's key quota for - * each key, regardless of the exact key size. The amount of memory - * actually used is greater than the size of the raw key anyway. + * We just charge FSCRYPT_MAX_STANDARD_KEY_SIZE bytes to the user's key + * quota for each key, regardless of the exact key size. The amount of + * memory actually used is greater than the size of the raw key anyway. */ - return key_payload_reserve(key, FSCRYPT_MAX_KEY_SIZE); + return key_payload_reserve(key, FSCRYPT_MAX_STANDARD_KEY_SIZE); } static void fscrypt_user_key_describe(const struct key *key, struct seq_file *m) @@ -558,20 +558,45 @@ static int add_master_key(struct super_block *sb, int err; if (key_spec->type == FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER) { - err = fscrypt_init_hkdf(&secret->hkdf, secret->raw, - secret->size); + u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]; + u8 *kdf_key = secret->raw; + unsigned int kdf_key_size = secret->size; + u8 keyid_kdf_ctx = HKDF_CONTEXT_KEY_IDENTIFIER_FOR_STANDARD_KEY; + + /* + * For standard keys, the fscrypt master key is used directly as + * the fscrypt KDF key. For hardware-wrapped keys, we have to + * pass the master key to the hardware to derive the KDF key, + * which is then only used to derive non-file-contents subkeys. + */ + if (secret->is_hw_wrapped) { + err = fscrypt_derive_sw_secret(sb, secret->raw, + secret->size, sw_secret); + if (err) + return err; + kdf_key = sw_secret; + kdf_key_size = sizeof(sw_secret); + /* + * To avoid weird behavior if someone manages to + * determine sw_secret and add it as a standard key, + * ensure that hardware-wrapped keys and standard keys + * will have different key identifiers by deriving their + * key identifiers using different KDF contexts. + */ + keyid_kdf_ctx = + HKDF_CONTEXT_KEY_IDENTIFIER_FOR_HW_WRAPPED_KEY; + } + err = fscrypt_init_hkdf(&secret->hkdf, kdf_key, kdf_key_size); + /* + * Now that the KDF context is initialized, the raw KDF key is + * no longer needed. + */ + memzero_explicit(kdf_key, kdf_key_size); if (err) return err; - /* - * Now that the HKDF context is initialized, the raw key is no - * longer needed. - */ - memzero_explicit(secret->raw, secret->size); - /* Calculate the key identifier */ - err = fscrypt_hkdf_expand(&secret->hkdf, - HKDF_CONTEXT_KEY_IDENTIFIER, NULL, 0, + err = fscrypt_hkdf_expand(&secret->hkdf, keyid_kdf_ctx, NULL, 0, key_spec->u.identifier, FSCRYPT_KEY_IDENTIFIER_SIZE); if (err) @@ -580,19 +605,36 @@ static int add_master_key(struct super_block *sb, return do_add_master_key(sb, secret, key_spec); } +/* + * Validate the size of an fscrypt master key being added. Note that this is + * just an initial check, as we don't know which ciphers will be used yet. + * There is a stricter size check later when the key is actually used by a file. + */ +static inline bool fscrypt_valid_key_size(size_t size, u32 add_key_flags) +{ + u32 max_size = (add_key_flags & FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED) ? + FSCRYPT_MAX_HW_WRAPPED_KEY_SIZE : + FSCRYPT_MAX_STANDARD_KEY_SIZE; + + return size >= FSCRYPT_MIN_KEY_SIZE && size <= max_size; +} + static int fscrypt_provisioning_key_preparse(struct key_preparsed_payload *prep) { const struct fscrypt_provisioning_key_payload *payload = prep->data; - if (prep->datalen < sizeof(*payload) + FSCRYPT_MIN_KEY_SIZE || - prep->datalen > sizeof(*payload) + FSCRYPT_MAX_KEY_SIZE) + if (prep->datalen < sizeof(*payload)) + return -EINVAL; + + if (!fscrypt_valid_key_size(prep->datalen - sizeof(*payload), + payload->flags)) return -EINVAL; if (payload->type != FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR && payload->type != FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER) return -EINVAL; - if (payload->__reserved) + if (payload->flags & ~FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED) return -EINVAL; prep->payload.data[0] = kmemdup(payload, prep->datalen, GFP_KERNEL); @@ -639,18 +681,18 @@ static struct key_type key_type_fscrypt_provisioning = { * Retrieve the raw key from the Linux keyring key specified by 'key_id', and * store it into 'secret'. * - * The key must be of type "fscrypt-provisioning" and must have the field - * fscrypt_provisioning_key_payload::type set to 'type', indicating that it's - * only usable with fscrypt with the particular KDF version identified by - * 'type'. We don't use the "logon" key type because there's no way to - * completely restrict the use of such keys; they can be used by any kernel API - * that accepts "logon" keys and doesn't require a specific service prefix. + * The key must be of type "fscrypt-provisioning" and must have the 'type' and + * 'flags' field of the payload set to the given values, indicating that the key + * is intended for use for the specified purpose. We don't use the "logon" key + * type because there's no way to completely restrict the use of such keys; they + * can be used by any kernel API that accepts "logon" keys and doesn't require a + * specific service prefix. * * The ability to specify the key via Linux keyring key is intended for cases * where userspace needs to re-add keys after the filesystem is unmounted and * re-mounted. Most users should just provide the raw key directly instead. */ -static int get_keyring_key(u32 key_id, u32 type, +static int get_keyring_key(u32 key_id, u32 type, u32 flags, struct fscrypt_master_key_secret *secret) { key_ref_t ref; @@ -667,8 +709,12 @@ static int get_keyring_key(u32 key_id, u32 type, goto bad_key; payload = key->payload.data[0]; - /* Don't allow fscrypt v1 keys to be used as v2 keys and vice versa. */ - if (payload->type != type) + /* + * Don't allow fscrypt v1 keys to be used as v2 keys and vice versa. + * Similarly, don't allow hardware-wrapped keys to be used as + * non-hardware-wrapped keys and vice versa. + */ + if (payload->type != type || payload->flags != flags) goto bad_key; secret->size = key->datalen - sizeof(*payload); @@ -734,15 +780,24 @@ int fscrypt_ioctl_add_key(struct file *filp, void __user *_uarg) return -EACCES; memset(&secret, 0, sizeof(secret)); + + if (arg.flags) { + if (arg.flags & ~FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED) + return -EINVAL; + if (arg.key_spec.type != FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER) + return -EINVAL; + secret.is_hw_wrapped = true; + } + if (arg.key_id) { if (arg.raw_size != 0) return -EINVAL; - err = get_keyring_key(arg.key_id, arg.key_spec.type, &secret); + err = get_keyring_key(arg.key_id, arg.key_spec.type, arg.flags, + &secret); if (err) goto out_wipe_secret; } else { - if (arg.raw_size < FSCRYPT_MIN_KEY_SIZE || - arg.raw_size > FSCRYPT_MAX_KEY_SIZE) + if (!fscrypt_valid_key_size(arg.raw_size, arg.flags)) return -EINVAL; secret.size = arg.raw_size; err = -EFAULT; @@ -770,13 +825,13 @@ EXPORT_SYMBOL_GPL(fscrypt_ioctl_add_key); static void fscrypt_get_test_dummy_secret(struct fscrypt_master_key_secret *secret) { - static u8 test_key[FSCRYPT_MAX_KEY_SIZE]; + static u8 test_key[FSCRYPT_MAX_STANDARD_KEY_SIZE]; - get_random_once(test_key, FSCRYPT_MAX_KEY_SIZE); + get_random_once(test_key, sizeof(test_key)); memset(secret, 0, sizeof(*secret)); - secret->size = FSCRYPT_MAX_KEY_SIZE; - memcpy(secret->raw, test_key, FSCRYPT_MAX_KEY_SIZE); + secret->size = sizeof(test_key); + memcpy(secret->raw, test_key, sizeof(test_key)); } int fscrypt_get_test_dummy_key_identifier( @@ -790,7 +845,8 @@ int fscrypt_get_test_dummy_key_identifier( err = fscrypt_init_hkdf(&secret.hkdf, secret.raw, secret.size); if (err) goto out; - err = fscrypt_hkdf_expand(&secret.hkdf, HKDF_CONTEXT_KEY_IDENTIFIER, + err = fscrypt_hkdf_expand(&secret.hkdf, + HKDF_CONTEXT_KEY_IDENTIFIER_FOR_STANDARD_KEY, NULL, 0, key_identifier, FSCRYPT_KEY_IDENTIFIER_SIZE); out: diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c index b4fe01ea4bd4c..b139c63bd39b0 100644 --- a/fs/crypto/keysetup.c +++ b/fs/crypto/keysetup.c @@ -153,7 +153,9 @@ int fscrypt_prepare_key(struct fscrypt_prepared_key *prep_key, struct crypto_skcipher *tfm; if (fscrypt_using_inline_encryption(ci)) - return fscrypt_prepare_inline_crypt_key(prep_key, raw_key, ci); + return fscrypt_prepare_inline_crypt_key(prep_key, raw_key, + ci->ci_mode->keysize, + false, ci); tfm = fscrypt_allocate_skcipher(ci->ci_mode, raw_key, ci->ci_inode); if (IS_ERR(tfm)) @@ -195,14 +197,29 @@ static int setup_per_mode_enc_key(struct fscrypt_inode_info *ci, struct fscrypt_mode *mode = ci->ci_mode; const u8 mode_num = mode - fscrypt_modes; struct fscrypt_prepared_key *prep_key; - u8 mode_key[FSCRYPT_MAX_KEY_SIZE]; + u8 mode_key[FSCRYPT_MAX_STANDARD_KEY_SIZE]; u8 hkdf_info[sizeof(mode_num) + sizeof(sb->s_uuid)]; unsigned int hkdf_infolen = 0; + bool use_hw_wrapped_key = false; int err; if (WARN_ON_ONCE(mode_num > FSCRYPT_MODE_MAX)) return -EINVAL; + if (mk->mk_secret.is_hw_wrapped && S_ISREG(inode->i_mode)) { + /* Using a hardware-wrapped key for file contents encryption */ + if (!fscrypt_using_inline_encryption(ci)) { + if (sb->s_flags & SB_INLINECRYPT) + fscrypt_warn(ci->ci_inode, + "Hardware-wrapped key required, but no suitable inline encryption capabilities are available"); + else + fscrypt_warn(ci->ci_inode, + "Hardware-wrapped keys require inline encryption (-o inlinecrypt)"); + return -EINVAL; + } + use_hw_wrapped_key = true; + } + prep_key = &keys[mode_num]; if (fscrypt_is_key_prepared(prep_key, ci)) { ci->ci_enc_key = *prep_key; @@ -214,6 +231,16 @@ static int setup_per_mode_enc_key(struct fscrypt_inode_info *ci, if (fscrypt_is_key_prepared(prep_key, ci)) goto done_unlock; + if (use_hw_wrapped_key) { + err = fscrypt_prepare_inline_crypt_key(prep_key, + mk->mk_secret.raw, + mk->mk_secret.size, true, + ci); + if (err) + goto out_unlock; + goto done_unlock; + } + BUILD_BUG_ON(sizeof(mode_num) != 1); BUILD_BUG_ON(sizeof(sb->s_uuid) != 16); BUILD_BUG_ON(sizeof(hkdf_info) != 17); @@ -336,6 +363,19 @@ static int fscrypt_setup_v2_file_key(struct fscrypt_inode_info *ci, { int err; + if (mk->mk_secret.is_hw_wrapped && + !(ci->ci_policy.v2.flags & FSCRYPT_POLICY_FLAG_HW_WRAPPED_KEY)) { + fscrypt_warn(ci->ci_inode, + "Given key is hardware-wrapped, but file isn't protected by a hardware-wrapped key"); + return -EINVAL; + } + if ((ci->ci_policy.v2.flags & FSCRYPT_POLICY_FLAG_HW_WRAPPED_KEY) && + !mk->mk_secret.is_hw_wrapped) { + fscrypt_warn(ci->ci_inode, + "File is protected by a hardware-wrapped key, but given key isn't hardware-wrapped"); + return -EINVAL; + } + if (ci->ci_policy.v2.flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) { /* * DIRECT_KEY: instead of deriving per-file encryption keys, the @@ -362,7 +402,7 @@ static int fscrypt_setup_v2_file_key(struct fscrypt_inode_info *ci, FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) { err = fscrypt_setup_iv_ino_lblk_32_key(ci, mk); } else { - u8 derived_key[FSCRYPT_MAX_KEY_SIZE]; + u8 derived_key[FSCRYPT_MAX_STANDARD_KEY_SIZE]; err = fscrypt_hkdf_expand(&mk->mk_secret.hkdf, HKDF_CONTEXT_PER_FILE_ENC_KEY, @@ -499,6 +539,14 @@ static int setup_file_encryption_key(struct fscrypt_inode_info *ci, switch (ci->ci_policy.version) { case FSCRYPT_POLICY_V1: + if (WARN_ON(mk->mk_secret.is_hw_wrapped)) { + /* + * This should never happen, as adding a v1 policy key + * that is hardware-wrapped isn't allowed. + */ + err = -EINVAL; + goto out_release_key; + } err = fscrypt_setup_v1_file_key(ci, mk->mk_secret.raw); break; case FSCRYPT_POLICY_V2: diff --git a/fs/crypto/keysetup_v1.c b/fs/crypto/keysetup_v1.c index cf3b58ec32cce..8f2d44e6726a9 100644 --- a/fs/crypto/keysetup_v1.c +++ b/fs/crypto/keysetup_v1.c @@ -118,7 +118,8 @@ find_and_lock_process_key(const char *prefix, payload = (const struct fscrypt_key *)ukp->data; if (ukp->datalen != sizeof(struct fscrypt_key) || - payload->size < 1 || payload->size > FSCRYPT_MAX_KEY_SIZE) { + payload->size < 1 || + payload->size > FSCRYPT_MAX_STANDARD_KEY_SIZE) { fscrypt_warn(NULL, "key with description '%s' has invalid payload", key->description); @@ -149,7 +150,7 @@ struct fscrypt_direct_key { const struct fscrypt_mode *dk_mode; struct fscrypt_prepared_key dk_key; u8 dk_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE]; - u8 dk_raw[FSCRYPT_MAX_KEY_SIZE]; + u8 dk_raw[FSCRYPT_MAX_STANDARD_KEY_SIZE]; }; static void free_direct_key(struct fscrypt_direct_key *dk) diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c index 701259991277e..91102635e98aa 100644 --- a/fs/crypto/policy.c +++ b/fs/crypto/policy.c @@ -229,7 +229,8 @@ static bool fscrypt_supported_v2_policy(const struct fscrypt_policy_v2 *policy, if (policy->flags & ~(FSCRYPT_POLICY_FLAGS_PAD_MASK | FSCRYPT_POLICY_FLAG_DIRECT_KEY | FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 | - FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32)) { + FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32 | + FSCRYPT_POLICY_FLAG_HW_WRAPPED_KEY)) { fscrypt_warn(inode, "Unsupported encryption flags (0x%02x)", policy->flags); return false; @@ -269,6 +270,14 @@ static bool fscrypt_supported_v2_policy(const struct fscrypt_policy_v2 *policy, } } + if ((policy->flags & FSCRYPT_POLICY_FLAG_HW_WRAPPED_KEY) && + !(policy->flags & (FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 | + FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32))) { + fscrypt_warn(inode, + "HW_WRAPPED_KEY flag can only be used with IV_INO_LBLK_64 or IV_INO_LBLK_32"); + return false; + } + if ((policy->flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) && !supported_direct_key_modes(inode, policy->contents_encryption_mode, policy->filenames_encryption_mode)) diff --git a/include/uapi/linux/fscrypt.h b/include/uapi/linux/fscrypt.h index 7a8f4c2901873..2724febca08fe 100644 --- a/include/uapi/linux/fscrypt.h +++ b/include/uapi/linux/fscrypt.h @@ -20,6 +20,7 @@ #define FSCRYPT_POLICY_FLAG_DIRECT_KEY 0x04 #define FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 0x08 #define FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32 0x10 +#define FSCRYPT_POLICY_FLAG_HW_WRAPPED_KEY 0x20 /* Encryption algorithms */ #define FSCRYPT_MODE_AES_256_XTS 1 @@ -119,7 +120,7 @@ struct fscrypt_key_specifier { */ struct fscrypt_provisioning_key_payload { __u32 type; - __u32 __reserved; + __u32 flags; __u8 raw[]; }; @@ -128,7 +129,9 @@ struct fscrypt_add_key_arg { struct fscrypt_key_specifier key_spec; __u32 raw_size; __u32 key_id; - __u32 __reserved[8]; +#define FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED 0x00000001 + __u32 flags; + __u32 __reserved[7]; __u8 raw[]; }; From patchwork Mon Dec 2 12:02:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 13890360 X-Patchwork-Delegate: snitzer@redhat.com Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.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 7AAC1203704 for ; Mon, 2 Dec 2024 12:02:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140973; cv=none; b=s9NUy93z5+xjYG2+CVUHqMcyacTGlnHTmKau8vV5pUZSZeirm7XHOrV2NN/DQCJPAkQp5HVmrkF0YCDed3oRe1mOxhTcNpOLLNFL3yetYQ/MmMUiTt0CPUBFDLe9M5WrElPMH3W0eKVz+OeGrKbvFcginKCQGH+BhqloSiEx5K4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140973; c=relaxed/simple; bh=6YzjV0NPQ5Asz3NMWwdStqqiu2ZFZDJL+XQN18G4jho=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nkj6vvFI4QEOm40Znab+y3kSD5KQO+cQip/KPTzTqJwzekcpVMOm9+faJbbCWFKYgo1oaqJLhp0OnIYqjtMAJ8Epy5l8QIo58npvCWRnxqsZ+ZF2Euubh9O0aagLLJwuQyOrr2tzo1dQevNExrPPFeUcND0Ucl0tS20FcMF3Dlk= 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=loDUasdg; arc=none smtp.client-ip=209.85.128.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="loDUasdg" Received: by mail-wm1-f50.google.com with SMTP id 5b1f17b1804b1-434acf1f9abso38161385e9.2 for ; Mon, 02 Dec 2024 04:02:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1733140967; x=1733745767; darn=lists.linux.dev; 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=ZwrqUgzomeZAg551+85HwI0DROl0jONzf+FyxNyg5dI=; b=loDUasdgcv4bpWE9J3WOV/CGoR6sZ1lvUUQCb3wC5Aogfzakoo15soBs+vkUpn7+eA fKBNSOYsX2S72TUpTx9e7SiF+r/uTXuPkpWGkorH9XxgAhuE7WArIcd8MQANIDqjti9P zh/Zkph6IJYJ5Cxj7UOvtqOHns933rLCPxIRiLQV8WRIhl6oqW4VV0R7GskscbvGadC4 B6mcFxsVIjAdVj9yPFneHfhVA3BTZfbQPcAbf3gYs+Fd+BHJoLqymKIoy2wTxUAR/v5i NGC1OCAH3xWpeqqsJ2g9xCBHkC9Zr5jwcTlPoolrarPLrmy7diUYEnmmsU5vB6qBDyNr vTlQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733140967; x=1733745767; 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=ZwrqUgzomeZAg551+85HwI0DROl0jONzf+FyxNyg5dI=; b=udiYdyeZLX3vQoRbUN5Oa0KKqkEun8hIqgBSFLLEQtatJGdc03JJ5iY+aEyhsL8Q/4 HI69AIOd9g9qxvkR8NeQKRMuVnt56scOj6puE+IOpXsZ5sOOXgedBTL+jtJVYtO672E7 NcpMRZwX4x2dWMHeUrmjamXjWJdoYhRoYju1R/07TQPBiRoPHrlD9PC5bX6oftCEd0vI 6eVz89ltGwlxBjSpeQfA0YzQx2l3rfHjAXp3/rb9apTJJNMcUuU2oqqHc1ppdYc2u+el ieqPVmjd5rV4Lw1JOuhjYKQorlRUMrcISsd+MiKhBDSluacJuJ7xMRDjUCeOHzlyClkd hp7w== X-Forwarded-Encrypted: i=1; AJvYcCWY9prHmkjLAlfxFUlYpfHG7W0Ox8SmdLWTKs7Ke7S6H8dtNiveqajX9SXDe5HSpN4PO9SXU5kurA==@lists.linux.dev X-Gm-Message-State: AOJu0YwEkE42cqQTflYj8NVPD1rIsNYjBGBGZ+qxX6giHXAsX14GAMXn ymMYU54p76JrANTk9cABV6HrrYaCRVATdXXQFHiyioyocVzZ3MuRJVRZdNodXCI= X-Gm-Gg: ASbGncvaDlz0De3iTKEDvIG88YJKdYhHxaRxWh1W6Ue+PqE/CZlmiogKuE3pwWaG6hD P7VYBDhGVvhTGA2SepOedIocEjxntyIOvPBDEMWqELr83z7HoypMapXJbKIrROcyXF/w62jwKUD T0mip5P3l9X64Gblg51TtFLKdWMs4snaYr4J6a1ONEvaSxwJdHKeRkaHlhyRBRCpTcPEZO/iFqy +imBQTH7+pG9f4mcp3ED/ipZXLPeMOZ8pGXthuN X-Google-Smtp-Source: AGHT+IG/w7cCjN0oKPl08ooPpL18eC2QfHH3rm9TU2c2V07Nmil57JLBdJ4jBndbMqB2SsBSN/dg+w== X-Received: by 2002:a05:600c:198c:b0:434:a30b:5455 with SMTP id 5b1f17b1804b1-434a9e0ac32mr189639205e9.27.1733140965235; Mon, 02 Dec 2024 04:02:45 -0800 (PST) Received: from [127.0.1.1] ([193.57.185.11]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-434b0d9bed7sm152396095e9.8.2024.12.02.04.02.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Dec 2024 04:02:44 -0800 (PST) From: Bartosz Golaszewski Date: Mon, 02 Dec 2024 13:02:21 +0100 Subject: [PATCH RESEND v7 05/17] ice, ufs, mmc: use the blk_crypto_key struct when programming the key Precedence: bulk X-Mailing-List: dm-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241202-wrapped-keys-v7-5-67c3ca3f3282@linaro.org> References: <20241202-wrapped-keys-v7-0-67c3ca3f3282@linaro.org> In-Reply-To: <20241202-wrapped-keys-v7-0-67c3ca3f3282@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" , Gaurav Kashyap , Neil Armstrong , Dmitry Baryshkov , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam 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.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=9620; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=Xxy7T1ivWX9tbiX/lU4uTl3nRxq9bf8iN/DI5qFBRo4=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnTaHSarEJ/NUdEhODEKyrsFZmobZ9td42n/5Va leOaiEpWfKJAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZ02h0gAKCRARpy6gFHHX ciLJD/9WdWPTFWXr4k9CfLh5BwJ2ksXCgxTPX/hCV8uJPp36IJkZgXBK2kMQ/m4RKPB0AxPQtnC /3W1vMNHhU+aQblrj1haiomFSfr34M0Y6KDYpdlLWvDuVPs+QZ4DwSxiZtivQY4y9ccvuu1JXgM 6BeWxRD8SdPHA+r7bPBEgfdKG0Ymf/yqhxU9/w27tu/7gV7+mP9hsxGeXB9k9jbklKwJ1tXy1Vq 2zx6dGg3Gh16sjt27Dz6a+Cm9ake/TAhJHJlm5geNBOoCOW+IWHicXsH2ue77VO03xl9uJKsLsF pB4iKkF1IdIG8c4wkYijgXDcy/ywjNRSPnjQG10Vgg1SWNU/t5ThyR54F65TA/Imf/S0G/ycKYI ss5UgeyX/KgIyNeGsuB2PFqd75ILftltKR4g8m2uBqtfgCVayu/zn3y+wBbT3e0Y2H+r7GniuO2 gwhoKbvhNy/IiqghWMS3lhgSjqIDtrw6cExBYPCbS3cC07eGiQF+kuyalt7AN59+E+jVSeiS1TD gofrBL/OD8yyn+0fqFVmrbr00Ec4uhOTIocMOq7fx+728BpJexy5SIq+R3l3ofRjzhEyCLyhGZw Lmrs03J1HFzdWl8mguECrWfdf54OJdSY7aGvPX8xEJsEap9v8qqVsbn/grRlmlec8tF3E2iKO/Q c6bcieyRsfI3ZqA== 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 Reviewed-by: Konrad Dybcio 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 6652982410ec5..91da6de1d6501 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 fab9d74445ba7..06099fd32f23e 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 e00208535bd1c..b8770524c0087 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 393d2d1d275f1..e89baaf574bc1 100644 --- a/drivers/soc/qcom/ice.c +++ b/drivers/soc/qcom/ice.c @@ -163,8 +163,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 { @@ -183,7 +183,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 7d3a3e228db0d..33083e0cad6e1 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 68040b2ab5f82..44fb4a4c0f2d7 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 5870a94599a25..9dd835dba2a78 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 d7aca9e61684f..bc6f08397769c 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -373,6 +373,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 Mon Dec 2 12:02:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 13890361 X-Patchwork-Delegate: snitzer@redhat.com Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com [209.85.128.42]) (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 9CC7C204094 for ; Mon, 2 Dec 2024 12:02:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140974; cv=none; b=ubxr9OAzSN0ONmhZHS2GlTE83L+asAqyzdruUARR6e8ztpGajvncbP6G9xuhbDXWqKtceWj7CcevfzE4X2AvZDF4DVKeh6GEY9mrBWXDZuHaFqtTMXo5l+lxn0ZUef+qRLqKtwuxJZOz7mULyJsMsVJ2nJ+HXlnurUdkZsPeit4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140974; c=relaxed/simple; bh=2ORU5vyUJ27lap9sqAiI3qTrLNQQhoC73WWhD6bjviY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CAcC5pEi+ltHS2WXjXNpzVzLaGaWk3CHflNknL81N5POmofdOb8wGRDi83LksIVb2WX7bPw06CraXBv7pjrRJRFZdgWFAt/48fhC6w5wxIw/2dqUwzKxPxWJ9MIXRGKv4BL7rF3Jd5uAdSo95nZEbucMgzv09P0Q2ohWmuMY/SQ= 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=y/y/4G5m; arc=none smtp.client-ip=209.85.128.42 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="y/y/4G5m" Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-434a736518eso52520935e9.1 for ; Mon, 02 Dec 2024 04:02:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1733140967; x=1733745767; darn=lists.linux.dev; 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=v5lbIjJ4pCG8r8J9xIS9Rd3wgRBn4855nSdT5ZJ6kC4=; b=y/y/4G5m4T13jumbRBfXIWBI+uF9Azi+0kGyWhm75LvSRCLGcTtw/m10AsxPnZj+kx XB3lyU5jB3P5BCTYm/hdjIhE59xNVPusZVJVns/N9Z/5IeVOh3GJ/6zuZ8nebicCblQZ GKX1l59sYYVI7FbQgaXCmzbgFFNNxmaNhn+ElYGGMcZs3Ul1lgEANSs1A5IFHPCcO5Un uIMCdA6MO4o7mQi135g3SbnrMt9SahIcUAyEz15OkDHMclqe+Ug1DBx6b4Lj/+uPfTLW yDbDckeUJrlLFxoaYqXav01ALN6qIyIAe40ku52Gh5nuiDkmvEqMzNvVEFVMPVDmrOYD Sbdw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733140967; x=1733745767; 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=v5lbIjJ4pCG8r8J9xIS9Rd3wgRBn4855nSdT5ZJ6kC4=; b=MFuiho1Rhr6uti4H86fUEEpL5Av2d4ZRISWZCJ+kch77HEVvYKuxmnTIiGUBf1RNXP AJ/9hZpKN1mOmFIArpHWd5LuQtHxDgSWBvOhIQlZnKuPSrIYX94SsG1jhPKCc/IuVHDP 5EpuOeGkVTOYnNQpEuakOcttZNuGY+NavAN/GrPOTzoiH1yM6c/x/qRnlugu0zljxBKH 1nEt7cYcZaNVaT19tDg1OpcgvYe17bUezLffBNY9hHu52mgdy6QM49oMWf7hrCzIko5l zjLOilaUST98mmXcPtiGKx7yhcBIoAd1y/ID+G6mbfExMpJZiOPVXht6yhznzNglXqYo O97w== X-Forwarded-Encrypted: i=1; AJvYcCW1QpIg1sG4tO7DbS2PjWvip1tbvwgG/5OptmprCWKPWwZHpGoDk7y3p1yc3PBUNb8eb2F0h+eyHQ==@lists.linux.dev X-Gm-Message-State: AOJu0Yz58L8PWCfykHL4pQxpGq1rQETOmHVPyODDfOtSyj2QzxzbGlxQ rxllqnY9zu2nQl6f/5sOxOymGwsoAjWWSGicFBLdrlHsZZVc5VFP9ZoqVXnpgQI= X-Gm-Gg: ASbGncvo3DwrjPwdG3Y62OL9giwKdID4D7A1gZylj41jahvH0vXrRP5x4EXtInr4cmp zRQVbsM9jVpFVj3JuvERu/mnOWAj6mMC66l5yQVhNRCoNnxXqMFcI9uYC9vr4W4cXtnu99krqzk wU2IdHsIMotO/LDesOBZP9gRUsYUR0/xtfMsmoAfL5qyw5evbRCWa0eBaJMO50i3ZInGCqe8NVq 4kvs/wXmhfaiEPkjLpbbd9ASO7WbXOCUFaetPg1 X-Google-Smtp-Source: AGHT+IHQAyekXbdAXZ7eydZRNVx2vlbKBM8IKXEW49sElJ/U7e3rXwUNnq8MwjxBEeFibtagQDeTrA== X-Received: by 2002:a05:600c:3585:b0:434:a04d:1670 with SMTP id 5b1f17b1804b1-434a9d4f86dmr259111775e9.0.1733140966888; Mon, 02 Dec 2024 04:02:46 -0800 (PST) Received: from [127.0.1.1] ([193.57.185.11]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-434b0d9bed7sm152396095e9.8.2024.12.02.04.02.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Dec 2024 04:02:46 -0800 (PST) From: Bartosz Golaszewski Date: Mon, 02 Dec 2024 13:02:22 +0100 Subject: [PATCH RESEND v7 06/17] firmware: qcom: scm: add a call for deriving the software secret Precedence: bulk X-Mailing-List: dm-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241202-wrapped-keys-v7-6-67c3ca3f3282@linaro.org> References: <20241202-wrapped-keys-v7-0-67c3ca3f3282@linaro.org> In-Reply-To: <20241202-wrapped-keys-v7-0-67c3ca3f3282@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" , Gaurav Kashyap , Neil Armstrong , Dmitry Baryshkov , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam 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.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=4754; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=wotGjX4ZTp3jBAnHlA+0tTqo+DEvuJKXXEnuWdkW8m0=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnTaHTdc124fFeQJuf7Q4Szt+eF8iUREMbzDgTo ZfwiG+IpcCJAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZ02h0wAKCRARpy6gFHHX ctmGEADNdGvvGUYSlzGzUnBCi7/j35SwFxgaa6QN+8TI9JXd8mR3ZZ73L+Gmt7gpQym2/zRyEAl yF9/T9SK51RnNQvukU0EOstfpk9NWNgC2d/UtA8jk7/QqKPnhyny1XqDVqVpQlrPJAGY29KYjO/ ME4Nc4nzYQhFHaGF8+iadJD2oKXkgQLq1Z7ykIzTVLkqeaq79bHA3uhFwLCbhLq6HHvZD2K4GiY 96E2ByHsy5IA0qauyMOac6NmaXLo7WA8qqgThdJLsmjSCiOyWnLRpsdGlvvZXA4+58mhW/+JRU5 P1MadkpeijDlZ/Khp8aJdiTi7eu1yghd90ZgFMXCum14b/G2lzXSXxz8xhpETWtdpqSc7YLqF2+ pwPIiFY8lbELeKrUJY6oOeMXlbzlwY42/TI0rnYaymh+C0XgQGTrgJd1vWe6b70up1xJiwOeC4k NWBgKKYYfvMJXcqWW4CFRZIWlxsKt4h9PmKZ7VEC9BLe8aCwVnjcrvdC8RijQqXtPKtRGGOdFTN JkIuz5tVVVhwN+Sn5iYXMAT1Lhuu5iQRc4F4jawLqNLXO6gmzkQl9z1UsKQJzM7mdWLxIbZtlEe u9A095ThTUabhV8PLKo9qX8UaIhlpPnqgzlTmptY9kqpqdQNGy0pCpRSRCPGVGgIwhsngV3Uw/Z zE2EoBf2tLqlt9w== 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 Reviewed-by: Konrad Dybcio 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 72bf87ddcd969..d523ce671997e 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -1279,6 +1279,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 e36b2f67607fc..55547ed27edd9 100644 --- a/drivers/firmware/qcom/qcom_scm.h +++ b/drivers/firmware/qcom/qcom_scm.h @@ -128,6 +128,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 4621aec0328c2..b843678bc3ee4 100644 --- a/include/linux/firmware/qcom/qcom_scm.h +++ b/include/linux/firmware/qcom/qcom_scm.h @@ -105,6 +105,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 Mon Dec 2 12:02:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 13890362 X-Patchwork-Delegate: snitzer@redhat.com Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.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 727F52040AA for ; Mon, 2 Dec 2024 12:02:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140976; cv=none; b=fUIOoNDIkeBgUWS8MPq40k6CH1S96Qo/1VSyiHnyB0HL9xSqQpUTbAndD55vSMD6hzVibUuL6ATO3N4dt+R4DkJ0fW+oblBHFqV2tcK75b+6EeOMiA6sRcpdPAhH+T8Vr3KE9mjWcFHpfCDw6aUAr8hgIT/7QzMSXKYcKYKqPk8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140976; c=relaxed/simple; bh=ROTvJ0Yd+ruiUat4sX5vxOMtnWR7c6X2Q7M75jA57vw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mzVirRAQ/s8Imh6j5ALjfFu9SHbMUMnSbVv/chuOAC6NUNnzXnkmvr9M8QzUHLAcvpXPFDAUckskIF5TCNJhlYO663GFAQfc97q+LsLtkBx+z1+hMr5d0YePBq/Tao2vG7FijrVa5i187171JH1z2zQQgy2prAzf1lHHU0xVh+A= 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=uEWsZIr6; arc=none smtp.client-ip=209.85.128.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="uEWsZIr6" Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-434a2033562so33445355e9.1 for ; Mon, 02 Dec 2024 04:02:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1733140971; x=1733745771; darn=lists.linux.dev; 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=SEsGyUMJRC5EIXHWCuaafkTJXMkTib5fTjMr637WgyE=; b=uEWsZIr6b30UkUwS16ApToghoUafd7AIW4s7lz7YdPDbDvpCTFc3FM0uM8HKru/Hvp cajSZWGlqLXYh6vdYh2RYCGMDDK8T2HTe4EbQ+cSxbrETp1BZVPq9qTys+6QQjdfMyQv bonLa4qPZSBTiOJXeRIAPRdBR1tqqhABc8F0eUdq3FxYKuN93bUcjqKfBoIHetzt4V9O iHs4yM34HPifgE+sUgw8HWWVetJH1Ct4knMdLrx+KEriV31Tr1MIm3RaX4ltFv5X3dJm u5qByinwu5stMeg09BmE7rUN/ZOzh5bAS74U6n0xZmeLs2AqtuT3qkZbTAJ+QIkJOzL0 tbFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733140971; x=1733745771; 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=SEsGyUMJRC5EIXHWCuaafkTJXMkTib5fTjMr637WgyE=; b=TUKlEjtcCvu2rXzNJBtPYdRl14dziA5qS/t0VdX5x6hoFGw/z9FN1GzkfJUWbCXf6B S2gj8jNOM0zHHA3AUJ0eMuyyJWqnoWq3CIXrVjoP6wwvoE8Zf4y+y4UwMNXnj4qDyKf8 Vh9m1n3nvreDLGRTfhdWG9qv7oFcKBLvqd7B8giOqG4FTgNHP29mBDxb+8wg0SGNYWi+ VWjQ14CwU+oQ3Np09idA6msUcvugvcrkUKtIzlpDsUgaA9Sp1B2CJNl+rWxLVfbmcTM4 9JXlr4y+tMWeD7q1APv2RzqZHTTJgDp8WTefgP5UWABGmaVYr+GlhJoaoVzqGhV7EngB QvFQ== X-Forwarded-Encrypted: i=1; AJvYcCWRKJMS/QEkUV/vh/PC96CVTW4W2wFEbbvnbegtYaGIGzKN86GGhWSjb5KahzN66hnOCcUXxIhI8Q==@lists.linux.dev X-Gm-Message-State: AOJu0YxaY1SB1pUK/S6OnxSfY7dbz6NBVHsYNcvYghIC026JwGNsCjCa cZo0rpzH0UiuifC3rpmmVHUF8AdAdfhKQCoJbHyF+W0Yms9VbrEh+DFD81LQrKA= X-Gm-Gg: ASbGncuaQMp5ia4oHH1ja+A49vM0rfry1viKmIgt5P5QWLRps6q9NK6O0GPSTEdyV2N UyE4FNb4RDWAaToEJ98wtdKTcT/q+0jcpwNDzNoRy91Oi6qLrzo2gT8FLGvC47+9HNQ8gwU6zHE JN5CgW0GNQCSL3QNlbAM6Y7ey64ewT8HX9mg7hQzqOoMBZ3SZF8XHtmb32uZiUrllL66lLAlm4A cgTRqnLgRSYuYnJaZRiGGSvzNgAi63pH6rKGvrT X-Google-Smtp-Source: AGHT+IGGvCQ+UQ3Gz+sFnJwX+0j17r5lPzFWBw9hCLQAKsSSM8aNBNxk7Vxt475KPIwUN1cEjvQLSw== X-Received: by 2002:a05:600c:3585:b0:42f:7e87:3438 with SMTP id 5b1f17b1804b1-434a9d4ff94mr219950105e9.0.1733140968936; Mon, 02 Dec 2024 04:02:48 -0800 (PST) Received: from [127.0.1.1] ([193.57.185.11]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-434b0d9bed7sm152396095e9.8.2024.12.02.04.02.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Dec 2024 04:02:48 -0800 (PST) From: Bartosz Golaszewski Date: Mon, 02 Dec 2024 13:02:23 +0100 Subject: [PATCH RESEND v7 07/17] firmware: qcom: scm: add calls for creating, preparing and importing keys Precedence: bulk X-Mailing-List: dm-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241202-wrapped-keys-v7-7-67c3ca3f3282@linaro.org> References: <20241202-wrapped-keys-v7-0-67c3ca3f3282@linaro.org> In-Reply-To: <20241202-wrapped-keys-v7-0-67c3ca3f3282@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" , Gaurav Kashyap , Neil Armstrong , Dmitry Baryshkov , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam 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.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=8105; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=iHvq6iDlNKonVx5gQ2c2tHZaOwqk7ZK6GmSQUyzlGxM=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnTaHTkbQUmO8rR7TlwBjsVv+pAdkGOHURn8Kyt gn2lFrWAHOJAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZ02h0wAKCRARpy6gFHHX cv2ED/0Y74IPZuyaqMDggcPamep1hRbZ1e70ccf4F82LpeyvNGtwjWIe9bOUOccNNXGFAazQNRO M0v9u036osn6tsRIuqpFSQ1jFnb/FUVLSxcp2lI4Q83qOsGzXH8SycN4U7aPKdIRVw9A36+vCm6 m/0+L7Xu91Shq77pEHIHuqjdBAEYyt/iMxQMCvHQfinj9Kw/yVNx+ZNkhVqjKojQiGUXvhldqI9 Wt8qZg5tdAC6Hfz71Xbq5dWHgZBwUCOBJN6czCD/f9rsfTvtz1EaO29i7FccOvp+X6z1o3wiD58 HodAlcrC+LfVtACsONNQUz30/wucJbEojQ6Rk8FnnXqXivERxYoKsk7VIj/+lNdmiqaLc0P4buR +/rKL60YvGEI9bCazu9q0BFOyjV4djbtFIFU+W0DXJ0DcMcOgurOMDtr63y+UpqN5eAr1MdzNMX gNsErL29RkWSQV/bcLe2XashBE6PXe6beD8qxmYJYvoW+v0+zpw2L8/O8y6mhid52NOL21ZH1hI aJj1Cvdy2qEdjA19/hVIeX03xQ1Fjh+NiEgLfUPh3pJ6gTVTlqiEzQQ/4TfuXws+jz5MFnF+i3y arj+MFPRnZi3wmb+Cz9TxMn6XEH0uTV2MeV2+hpU25jjZ0HrAsp4/+LvOQfah2FHQkIuWY+SA+Q Dm+y3KAcj6z029Q== 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. [Bartosz: improve kerneldocs, fix hex values coding style, rewrite commit message] Tested-by: Neil Armstrong Signed-off-by: Gaurav Kashyap Co-developed-by: Bartosz Golaszewski Reviewed-by: Konrad Dybcio 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 d523ce671997e..14ba2c798f4d7 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -1344,6 +1344,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 55547ed27edd9..097369d38b84e 100644 --- a/drivers/firmware/qcom/qcom_scm.h +++ b/drivers/firmware/qcom/qcom_scm.h @@ -129,6 +129,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 b843678bc3ee4..9a585c1af959d 100644 --- a/include/linux/firmware/qcom/qcom_scm.h +++ b/include/linux/firmware/qcom/qcom_scm.h @@ -107,6 +107,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 Mon Dec 2 12:02:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 13890363 X-Patchwork-Delegate: snitzer@redhat.com Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.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 9EC26202F72 for ; Mon, 2 Dec 2024 12:02:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140977; cv=none; b=lBHAO6aMfAT8IOHgjvg0VWWX9CAHFF/QAr/YE2IskVeeTKouary0kc7FnCMx2KCL3S8hn8W+2uMexnGOgx5kLEJFkox8zdNK4ueHREuUlF4E0anNzPVcic9iOPKf5bUJHxBTNBEcJGA6ZpGKBMvxXH/yW9nTVBk0Cw7YEKHFCww= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140977; c=relaxed/simple; bh=aRvxC21BhTxDXUKjx9ruTN4tMTQfge2gVFw2Pfe7Z+8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dOQ574zj5v3IoDZ1KJKvR3aXLJXSRjUb/vFnDqhC7RZJhVjWxI7pDPexHAwN1BL2a9RKrAsgAsb5tNF8pGC+s5pV2P8WnSb3k8tqaLmEHvsiti4VsQDFpoeYESh6elHVv8m6EH3xUVmnctIf33e/Ta34gdwDWnRuYdlM14BpqEA= 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=tLVJbSa3; arc=none smtp.client-ip=209.85.128.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="tLVJbSa3" Received: by mail-wm1-f45.google.com with SMTP id 5b1f17b1804b1-434a742481aso33374305e9.3 for ; Mon, 02 Dec 2024 04:02:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1733140972; x=1733745772; darn=lists.linux.dev; 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=touQmIBQiXzWh1JEM9Gfn3mWpH6OCuAp3TCnoOv4GIQ=; b=tLVJbSa3x9Qq9ypsnaq7+VNsJame1VtLHC/xhg8/7BbA3K8wwuDCpywjWBsXU6JWbY TMSHmog4uZJANin9+BJiV/hp6hMHxyudfh+wlIboDjCT3T5xu97jZnffak0tgqFkfjCB qXIHwKdeF9Tg2PkfRR4XHD7iETbIbqb0GL8SBJzqbOMb5NqU33uD6Z47y7xdjzHhpq2Y yRXcp1mpgO+ZCazqUn+awBVBcD6cutz1S8cWd3ANmFTEsPR1oc9iPu14+kP6gTqc58f7 1vqCPszQ1nAJfZdz4eB6mTyYX8ys9i9G0n8ieDNAvPc6atmWs9AdRnVJvgZl6qD87s4N 1PpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733140972; x=1733745772; 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=touQmIBQiXzWh1JEM9Gfn3mWpH6OCuAp3TCnoOv4GIQ=; b=eHz+XsX5/nVsAIrYVnpiy/Qk71UaNY7Kr3+UDGrDihYwQ93VpyGczUZYhEwHEjAN3p igGCY5s5Mc4nHO35yuZRcqR2UUXqW7Geu0UPIGdroRR5Q2i6ss4jUVIatc33wAKrLt0X 0X5r2ypv1Th2oVYKHcghmRohiyk5EdqFwMSIeHsfeXBhxbbm9jjnJqN18Cavo8bL13CN C/vBwPdqTXB0dDJvcW1DwLFGXDvBvdCLkt3Ze5nToGdWZ8B6PBrHz9x4LGAn9LfZ8BNY 8cR5+LS4ISrnW0Jg1JcdO8S2XvzmF8Qpr90M4hO9pIrHWlNqgaprJLuCfglaqsU7prii AZwQ== X-Forwarded-Encrypted: i=1; AJvYcCUUnJpxXsaALt+UE/UhlCt58FSm+dZ2bh7Ro2Na5fFxyeyk1d9wDuUieKsrS5dSk1zYn0xO+DXSqA==@lists.linux.dev X-Gm-Message-State: AOJu0YyfBQh/pTXPf1nlAIF5rvtYGRQWTL08gXRcQVeWbD0mifwSTImv /UZs98y28PLZ4mvNBoD05wVYfA3JjmlRPR+YM2lXWob5LB+7SoD5Ky6TdZhViUc= X-Gm-Gg: ASbGncskoI6rXL963SUmhDJTB6MtzOK9zgxWeaKz/MXrak9yw4sZliqPrwODuP0jpiU VBnsLWRYmi0ESUJcWsY/epohmAc/2pqvR1uy2WsU4V8I6aDrArX4RZyXrGo++7J59iIalWlighW nDErboPpJN3ILmAQUzZ55AfMl+nS5zHa2bDuMkkps4a5c4hDWw6mR6OaeqZJNmUqZdQx/7p2j0I 7j2TBPZuFwN415NWj8jFhUbholD14J8tj17s4bO X-Google-Smtp-Source: AGHT+IFVcG0WNXyZYjt32w+M6ShxZPiZDTgzJ1i2L8r2rKvxPJYT9RhXpy10UK6vs45kZUSgKb1ygg== X-Received: by 2002:a05:600c:4686:b0:434:a962:2a8c with SMTP id 5b1f17b1804b1-434a9df6af9mr185930165e9.22.1733140972279; Mon, 02 Dec 2024 04:02:52 -0800 (PST) Received: from [127.0.1.1] ([193.57.185.11]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-434b0d9bed7sm152396095e9.8.2024.12.02.04.02.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Dec 2024 04:02:51 -0800 (PST) From: Bartosz Golaszewski Date: Mon, 02 Dec 2024 13:02:24 +0100 Subject: [PATCH RESEND v7 08/17] firmware: qcom: scm: add a call for checking wrapped key support Precedence: bulk X-Mailing-List: dm-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241202-wrapped-keys-v7-8-67c3ca3f3282@linaro.org> References: <20241202-wrapped-keys-v7-0-67c3ca3f3282@linaro.org> In-Reply-To: <20241202-wrapped-keys-v7-0-67c3ca3f3282@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" , Gaurav Kashyap , Neil Armstrong , Dmitry Baryshkov , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam 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.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=1817; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=+R6JPSKxZAYNPKLIpsJZoN7OEYE2IK3CNpaiaGjz6AY=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnTaHUvjd2zifuwXGVatR1JdebHWc/LZaLwgmus WGS0vMLua+JAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZ02h1AAKCRARpy6gFHHX ctfPEACUk/7ZHHbhr8W2JfWwwmaiESzyTdR99Tou0BMLTIZyn9sJx0cMYsTClkr7tiSefKwqE4g A820hXjV7BEcEXwPxeJx5la8tQwsM7TuIP7TQakNzw+7HVZgviuxbez66ieom/ien9ksULr6dbC oGbUgUvT76nFiqf9lbMvgPgIjZkWqbu2FRmHZ4oodKwmYDerflRYUYY7IiqZUuEqVpyPNLRU4hG lH0PELE8mXUy6uqTukt1hUfiIrWPl8K6wY2RnWmeTT1I6wmAYXnQtk1YmxiBx2iTP0/eb2cf5HH RLJiBAd5aw2IlKRoCQpnSi0kWp2ltZbKyNWS0oP0eCc7/mFTJvPDjQviA09N1xcDW1lH3LjbCje 6aatX/buSYuHDD2UId9EtMN7yfPC9n3YL9GvQsuVAN2rFyKaFt9xUTXgu0d2DJVjsiKeb1vd/In 9rZ7c6bmHqNWRQjr22FT7YFz0xn1vxbKBObpWgkMdRxGC8qYnWuTO0UztFmHv5G3LUegTbFKLWT rXSJVszMxetXS5xKZTRRC/JW/+GHLVgl3QahGu9MPz6IuhuenA6ppDctI+TrMtmHD3NtzxM7vpa OHpol0GySgnRNelpG3cVBYIbrp1N2qHzbUnLkMz2VEhh/vlfzV1Xzy5d+bzPG6H9q8e6nhTBWVx cSYraZo571HQOpw== X-Developer-Key: i=bartosz.golaszewski@linaro.org; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 From: Bartosz Golaszewski Add a helper that allows users to check if wrapped key support is available on the platform by checking if the SCM call allowing to derive the software secret from a wrapped key is enabled. Reviewed-by: Konrad Dybcio Signed-off-by: Bartosz Golaszewski --- drivers/firmware/qcom/qcom_scm.c | 7 +++++++ include/linux/firmware/qcom/qcom_scm.h | 1 + 2 files changed, 8 insertions(+) diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index 14ba2c798f4d7..915b3fc388baa 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -1279,6 +1279,13 @@ int qcom_scm_ice_set_key(u32 index, const u8 *key, u32 key_size, } EXPORT_SYMBOL_GPL(qcom_scm_ice_set_key); +bool qcom_scm_has_wrapped_key_support(void) +{ + return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_ES, + QCOM_SCM_ES_DERIVE_SW_SECRET); +} +EXPORT_SYMBOL_GPL(qcom_scm_has_wrapped_key_support); + /** * qcom_scm_derive_sw_secret() - Derive software secret from wrapped key * @wkey: the hardware wrapped key inaccessible to software diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h index 9a585c1af959d..f4aed380ace5d 100644 --- a/include/linux/firmware/qcom/qcom_scm.h +++ b/include/linux/firmware/qcom/qcom_scm.h @@ -112,6 +112,7 @@ 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_has_wrapped_key_support(void); bool qcom_scm_hdcp_available(void); int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp); From patchwork Mon Dec 2 12:02:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 13890364 X-Patchwork-Delegate: snitzer@redhat.com Received: from mail-wm1-f52.google.com (mail-wm1-f52.google.com [209.85.128.52]) (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 938B0205E00 for ; Mon, 2 Dec 2024 12:02:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140980; cv=none; b=KaG1AQrb8+IjagNHF2+Dxok7r1UffjlprVtNGucTNb/OPKYqc4vGiq3sOqugUknSGOGpPRlGISCIj8sY/0iK1nB2u2wzJ5SnSD8wJVFI3GN453tdRwSvnaqTqy3S723/4cWb/d72GZ1fUNKO0KIHAy777ickENY4BSsMTClO7x0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140980; c=relaxed/simple; bh=f59y2sAoxUD19VFlzXOZIuQVVcrSA8fWNTuWTCMkgVg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CkrChazQzxENVNCzdHNmzMrK2et0lIblbPC3IRtpzh1bK4aSJ4XfhwDjjxFw0GF3ozZV+nHxfUFOb4+V2XuzeP0UyuPbepn+6IJXcCxfiWo1iihTJTc7BiyWWMafFrJ81ZHMLRwqa2KKX+vRQkxKa47yzPowsRUmm5FK+/8p7mg= 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=2gYNfH+h; arc=none smtp.client-ip=209.85.128.52 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="2gYNfH+h" Received: by mail-wm1-f52.google.com with SMTP id 5b1f17b1804b1-4349e4e252dso39071065e9.0 for ; Mon, 02 Dec 2024 04:02:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1733140975; x=1733745775; darn=lists.linux.dev; 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=ftcUOFK9BkThfl3JBnS7+/vU5+8BtkX9fgCwRavyYYk=; b=2gYNfH+h/A+zAZXrMFQ95h2O+rFoGQFsnPvXH7Zkc1IDq0hzLIxkWJdvY5SeP4t/0n mLFGMpfs5BgG5cpKjt/jo79P4Mn7HPbVFdNPuqpE1rR6RxBrTxvX7BXeQLZToCZNqV4l I2w59vskCu5tdyK6rTuVR/Wxr+GGk/yoXlRuhv8h2wax9rjoWB24Ys3DjyVfRcOvWhAy lu3EGJwqWjxV7st99Sd8Hb0kau6TLD8Zya6puhx0xzwu0/6nFJrxEG6olRhn0QuRPGih xgItKtZREDYsoAja6dKpYF6BMaPPNjH6ndOolbmYloqZ92mlTODh5m0t1clhqM2qZwct CAXA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733140975; x=1733745775; 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=ftcUOFK9BkThfl3JBnS7+/vU5+8BtkX9fgCwRavyYYk=; b=QZbvy+RTeW4lIhuLQibsLTjVlD5dtVBLSdo7NKHWoPnfhvcE3t1OprMLby85Cmy6YD Gnk8/3+l95bcDr9geJ3YrnmO900kFMa3AuXgNI6oS+CCbEuIIsFjqGw79geYci8ckRD6 E+mPO6teYGFnJHpEM0FzUv0zA7uGAF2MyYURqS5sVhNDbtsqYcerCkX93Fo8VOmfcNPg KHtYfQYMks9uGszgQq3+N2+eW39u1exyX6B9P5AT2Bg+U4wjfb7081EMOA0rpZ35IMue 6OeNrWZEp63XpxLw4m5+8RxlqsBp2qZwe/mwjXxa69quL8rCnq87yqEbeGmzlYkRK/vn mXaw== X-Forwarded-Encrypted: i=1; AJvYcCVO734bI6sPJCEw+uh4spRwolcGG4+OmeiKhhooqe9D/uzep53aYF4/CFoGhHUnJud9n9igPVNmaw==@lists.linux.dev X-Gm-Message-State: AOJu0YyccBTxqE3UcjOfzeJ45dQAwWm/G364D0S+S6yfx8/PA6MvuytE 5lsi6WssFAITGZFvwXkni8xFWPRY9OYuaap9MZMIMXknQUG7T94hIpRURy2S5pI= X-Gm-Gg: ASbGncsg2mpRQqqY2dW5J/A52vAPgInvbwS8bqncVtCB/8n6DjYtt1oB3SInitZx+bx MUNbz1AjC4M4eO0jhoyHZDFTnHUZEis3ff4aDkQwVBDk48s+njvtoe9pB5Pj+QNAmopm0aOKA0+ 9ODfkPn36KesWomTHPDf65Hm0QXCUYU7auRggd9fX2LyvHuoM90RsT5LxLSQNCSk6anJTfB/oCS 0ulFxIYqWQ2gVxg+r2ZQ2TtJWYilT7h6fsjNfyM X-Google-Smtp-Source: AGHT+IF7osq7PiK5X8TwQQbGuOfXP+0HTGbUIuO4TGAFWYSSBQCIgi6CIixopBv4gVFfOdC24T67nA== X-Received: by 2002:a05:600c:1ca7:b0:434:a202:7a0d with SMTP id 5b1f17b1804b1-434a9de44b7mr184701065e9.22.1733140974400; Mon, 02 Dec 2024 04:02:54 -0800 (PST) Received: from [127.0.1.1] ([193.57.185.11]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-434b0d9bed7sm152396095e9.8.2024.12.02.04.02.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Dec 2024 04:02:54 -0800 (PST) From: Bartosz Golaszewski Date: Mon, 02 Dec 2024 13:02:25 +0100 Subject: [PATCH RESEND v7 09/17] soc: qcom: ice: add HWKM support to the ICE driver Precedence: bulk X-Mailing-List: dm-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241202-wrapped-keys-v7-9-67c3ca3f3282@linaro.org> References: <20241202-wrapped-keys-v7-0-67c3ca3f3282@linaro.org> In-Reply-To: <20241202-wrapped-keys-v7-0-67c3ca3f3282@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" , Gaurav Kashyap , Neil Armstrong , Dmitry Baryshkov , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam 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.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=9623; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=QdDciS7N9Q18RVCBLlPev9WG0N3W7Imry7+pIFcB1Sw=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnTaHUB2ZcB3CguIfWYlMi++x/fKzCPTWqIebCH RkX/AjSVOuJAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZ02h1AAKCRARpy6gFHHX cv6yD/0RH5EUpQh90ceBbnf0GNGSpg9btdpxa0Ju7xN490n5XAgED9KEOEyzaG7+//+cEWa7jIB o6B5U7JGkXFPAo01bdT5XnP0pY2NREtymnbDhutCUQE4RSp00ewNTgezFcxjRcDMpMcvpT3b2WB lhis+N6NYtSrXDGsVOKgAlE7DHDjH3lT0MT2rbrpl5QJsLkildh7mXlJ2qVjzNQjLu/kfxEA3zv JzUhSO/tP3rjmCrxE7othTFUUU19FhuOP6Ombctt9F3MCucbrmdH51gmdHPYtou7q4dbGAoYrQp zz2LSm0S0qlFQMJTt6y5iX4ygJIh/2DM3IYRHeKaxy1kEwJWnfUXggs4UxkbUyAHIN+H1JMfHKZ 3XqnvliEiGTfb2RdlJjEZS+8ExcoeHonULnjVJfp9Uafl/XWZDVXeP7W2TDG2CoueuvufhQdRpR 2gzRKS0O69M20mi/UUR7SwwfC0zpF8C9G0nCG/yzjAozCJ4JPEwXAfhLjHVsadnMsoQBQIaaP+3 8n/3u0KgB9RcUT+Aw5MXhBlgq+Syoz5p8o2f/hzA2mPmk9/AlUt/v3Fi/rc8dKOeY1XVq8bt6uN b3c9joyMPMWWiGelDBN/Eh3J6MwAWhyHclSf2W6aUvqu1b0mRKsvs/P/+d6BrKWrPeKy+8WYysz Znr6RHJrsEpEwUA== 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 Reviewed-by: Konrad Dybcio 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 e89baaf574bc1..5f138e278554c 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)) @@ -46,6 +83,9 @@ struct qcom_ice { void __iomem *base; struct clk *core_clk; + u8 hwkm_version; + bool use_hwkm; + bool hwkm_init_complete; }; static bool qcom_ice_check_supported(struct qcom_ice *ice) @@ -63,8 +103,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); @@ -113,27 +166,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); @@ -149,6 +281,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); @@ -156,6 +292,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; } @@ -205,6 +342,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) { @@ -239,6 +382,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 9dd835dba2a78..1f52e82e3e1ca 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 Mon Dec 2 12:02:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 13890365 X-Patchwork-Delegate: snitzer@redhat.com 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 5BB5A207A16 for ; Mon, 2 Dec 2024 12:02:59 +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=1733140982; cv=none; b=S+r+tEx48QRxLEThtzXsNmioMfpcAsLx0mvoM+37JLB5NhcumwrhHi5uQTytxGMVq+guMr0U7zQ5GKm4L7ljlfnVhmuG1RWD9F1If0NVyv9cGxJb0Pb1cb8ffW3ScnLuMvnv2D+ALEMHqCKugro7cedvW+dFgWppK+ZMyWJnkUI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140982; c=relaxed/simple; bh=TA4B3fyGt2CM5SHreS4634i2jVgA0QAzzGXgqVryOAg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZD4y20Xeu2RSXOehx5b+qDtEwiyisc1PofoSvFWM+jQHlMlRV0ghkUKr7Pma92Kgam7XUfDIGDBYyNlEAVE/7thmWkpIu4cqnylfQqvCwALI0gzi0EzJmOVooy5Dp/AlqKI3gO8/GK03b9j8FEliI7P7LPDe+BVdJ9HpopiClMA= 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=CMbIJP2M; 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="CMbIJP2M" Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-434a10588f3so25931155e9.1 for ; Mon, 02 Dec 2024 04:02:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1733140978; x=1733745778; darn=lists.linux.dev; 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=ENVRndH/0R8z7KIBdB13dMhkwu6GEyC+j8MIg5fgRYY=; b=CMbIJP2M0BQUGYgC5KiTiTpDsPKWwgCpLs2WH7rMY9qACPJSNRPnB/C9f2K/HqXpcZ MjcCP+vdbb4s34CKMJDod0rp78Rbv+5tfZ5B/+9Pjq7JWL+pM2uqS3nLk3mutwrIVQfo 374iLgOAZyABSB8TxIAhMsxIEre7YUkH69v8+aDhkN+ieJXxoe4oUFRupAfV/nRDjKrX fb6uNjPTC05UivIq7OvsKSO0S7Wsnt5h3mQgmIcpe572fS32SSYpghGnCfWaQyVnxtyd v21hHxiWBcrY1eUfdSxcEycbdsnVeD9Hp1H69YSPXRTAzhO0pjkcFeRIMJN4PBrEFcEp fQ8A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733140978; x=1733745778; 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=ENVRndH/0R8z7KIBdB13dMhkwu6GEyC+j8MIg5fgRYY=; b=tgB6UCcwkAMHWr5hO/jO9QfFegtQmxWeKbppRu8/xWioEWccBdYTxQq18C1qF2A4Fw Yz2vo51HP6PYcLx88VEi8BLg1TadmoSvxbjRZ823hQbjZvtV/eF97XKN/ClFx+SRPOja 4ht3xG0MQzrHNcmACXCW75L5Y4JCC2n0ZznUvfJqzPyvrNP46PxZFizz86fP9YlVsGkE Ynw6Ho0RtG9Hbv6eVw75HH8EuEtmuRgSNEG5c4HyXgBalqlY+Q9nvuPUzHHoU14XENqK 13sHufUbUcoQFXEFgSOOsIysMFD/FkOokaBVgzNKwtU4wznCPC3lTleg1V9p1VyKenQo yFdQ== X-Forwarded-Encrypted: i=1; AJvYcCX0Q/YCKS1sOS1Ko8gR6td9AoA8QjdFZ3ZyOv0H08PglId4bgUoj6DhxxfIVxKdUezXtg+ees1wEQ==@lists.linux.dev X-Gm-Message-State: AOJu0YzCyDwd6cDZbkyPaJrLBxC2JisOP6aywJD1u+sTERlGLstz81D8 DIaSJYEwR3dHTRj/NPfZx6bGtHuM4OGH9rmv6CceLTqzqXcj2RHmg+pdZi4AGfs= X-Gm-Gg: ASbGncuQl8fAVC4lzRvKQZLUNdmBOE4ih6HKN2JjXXLleKqmCpw5nzqCnTDqFeOyPcv H0G7AGkRxDvmqq6xuLFYLtF21vg4K/UZMmtV0ai/MgXywMat8odqE241fWyACrHU/B7ESCszTuV 1qEcxbZCHWjWXKlvPEH/O+k26cCrpqTEDeiDJhgZqkipDZbfbnucqk1kdOAp+je4sLTPTir5UVT 8vkNmUlsdbxeVblydhfYuVQo+K40Wz9uC7tquJJ X-Google-Smtp-Source: AGHT+IFWyXRf8rkt+k0mrxH33J9pbMghYb3Zg0nOw117JklEJ2A8HlPMp2Xl9MunztcUpcgDviuWdQ== X-Received: by 2002:a05:600c:b8b:b0:434:9e17:18e5 with SMTP id 5b1f17b1804b1-434a9d4f7famr223589455e9.0.1733140976376; Mon, 02 Dec 2024 04:02:56 -0800 (PST) Received: from [127.0.1.1] ([193.57.185.11]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-434b0d9bed7sm152396095e9.8.2024.12.02.04.02.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Dec 2024 04:02:56 -0800 (PST) From: Bartosz Golaszewski Date: Mon, 02 Dec 2024 13:02:26 +0100 Subject: [PATCH RESEND v7 10/17] soc: qcom: ice: add support for hardware wrapped keys Precedence: bulk X-Mailing-List: dm-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241202-wrapped-keys-v7-10-67c3ca3f3282@linaro.org> References: <20241202-wrapped-keys-v7-0-67c3ca3f3282@linaro.org> In-Reply-To: <20241202-wrapped-keys-v7-0-67c3ca3f3282@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" , Gaurav Kashyap , Neil Armstrong , Dmitry Baryshkov , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam 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.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=8351; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=4eGznOyJ6jIlOR4N8SwTDY1Bm/ka7XPc9moCeYXUmlA=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnTaHURoKmLgKNErYt+kREnqsfebciFZDqEHUSY qn//W00zk6JAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZ02h1AAKCRARpy6gFHHX cillD/4lmG39c3yJzIIeRBg7RYJFW0rISfZaAyg8EJKILzOI/aV4YRrX4o9eBpHEJObvDkYEPPG 2etWkhiGsEbKEsbZUMVN1vPVDIr1ZuQIwfOuk9RiAjMJ8CdtG91JP/yG+aGETnrxgAUlP99L14c giN37nqe5tnbCcRI+EZ5wMeb6VuYG8HtZFlBe2uKXt2Sj0nnQotufnKQPwWVBrIhThp+j7/Ytqm frQUShV0GH4EMCj7fU1fE3jLC1sOSO/h82S6tlJLv2ZJqT0TlytLUbe9iRe6m769Pne2hBVVnZf bpgppRtPoNaF/YECNEEUmpK4PxOfQs4ricaShn1gOrrShLRQI/TynLKnRZbLLhgQrFU3OmVXPsI RAlkcsH2eNl1aIFR5QUKbA730cZYQ6viekH4k+VE4lYdJIApmW760UUwhSVEAUb84ImlOaNxxCY GQxSoH7Zee0/Ay5KinfiwK814nwa08vjoc0AHkMZJvEyxj05/vqoCqwPi8d2NV0+0RtSVaOGZ85 DzwjnRk0lpxdgKYNzfkYXMhV8YccMnkRoMTdADJo+AyvdEohaLrxggTiVfD6ucj3YehKRCWEtb+ x3tbADP1cOteUL6cfOIPixok/S4LvHiHWcPqWBTWkCADwJGq3fsv/RmdAx3Y2bDCzVsOugqhA3T SFEuPkYxzkE2NdQ== X-Developer-Key: i=bartosz.golaszewski@linaro.org; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 From: Gaurav Kashyap Now that HWKM support has been added to ICE, extend the ICE driver to support hardware wrapped keys programming coming in from the storage controllers (UFS and eMMC). This is similar to raw keys where the call is forwarded to Trustzone, however we also need to clear and re-enable CFGE before and after programming the key. Derive software secret support is also added by forwarding the call to the corresponding SCM API. Wrapped keys are only used if the new module parameter is set AND the architecture supports HWKM. Tested-by: Neil Armstrong Reviewed-by: Om Prakash Singh Signed-off-by: Gaurav Kashyap Signed-off-by: Bartosz Golaszewski --- drivers/soc/qcom/ice.c | 128 ++++++++++++++++++++++++++++++++++++++++++++----- include/soc/qcom/ice.h | 4 ++ 2 files changed, 121 insertions(+), 11 deletions(-) diff --git a/drivers/soc/qcom/ice.c b/drivers/soc/qcom/ice.c index 5f138e278554c..e83e74e39e44f 100644 --- a/drivers/soc/qcom/ice.c +++ b/drivers/soc/qcom/ice.c @@ -28,6 +28,8 @@ #define QCOM_ICE_REG_BIST_STATUS 0x0070 #define QCOM_ICE_REG_ADVANCED_CONTROL 0x1000 #define QCOM_ICE_REG_CONTROL 0x0 +#define QCOM_ICE_LUT_KEYS_CRYPTOCFG_R16 0x4040 + /* QCOM ICE HWKM registers */ #define QCOM_ICE_REG_HWKM_TZ_KM_CTL 0x1000 #define QCOM_ICE_REG_HWKM_TZ_KM_STATUS 0x1004 @@ -62,6 +64,8 @@ #define QCOM_ICE_HWKM_DISABLE_CRC_CHECKS_VAL (BIT(1) | BIT(2)) #define QCOM_ICE_HWKM_RSP_FIFO_CLEAR_VAL BIT(3) +#define QCOM_ICE_HWKM_CFG_ENABLE_VAL BIT(7) + /* BIST ("built-in self-test") status flags */ #define QCOM_ICE_BIST_STATUS_MASK GENMASK(31, 28) @@ -69,6 +73,8 @@ #define QCOM_ICE_FORCE_HW_KEY0_SETTING_MASK 0x2 #define QCOM_ICE_FORCE_HW_KEY1_SETTING_MASK 0x4 +#define QCOM_ICE_LUT_KEYS_CRYPTOCFG_OFFSET 0x80 + #define QCOM_ICE_HWKM_REG_OFFSET 0x8000 #define HWKM_OFFSET(reg) ((reg) + QCOM_ICE_HWKM_REG_OFFSET) @@ -78,6 +84,15 @@ #define qcom_ice_readl(engine, reg) \ readl((engine)->base + (reg)) +#define QCOM_ICE_LUT_CRYPTOCFG_SLOT_OFFSET(slot) \ + (QCOM_ICE_LUT_KEYS_CRYPTOCFG_R16 + \ + QCOM_ICE_LUT_KEYS_CRYPTOCFG_OFFSET * slot) + +static bool ufs_qcom_use_wrapped_keys; +module_param_named(use_wrapped_keys, ufs_qcom_use_wrapped_keys, bool, 0660); +MODULE_PARM_DESC(use_wrapped_keys, +"Use HWKM for wrapped keys support if available on the platform"); + struct qcom_ice { struct device *dev; void __iomem *base; @@ -88,6 +103,16 @@ struct qcom_ice { bool hwkm_init_complete; }; +union crypto_cfg { + __le32 regval; + struct { + u8 dusize; + u8 capidx; + u8 reserved; + u8 cfge; + }; +}; + static bool qcom_ice_check_supported(struct qcom_ice *ice) { u32 regval = qcom_ice_readl(ice, QCOM_ICE_REG_VERSION); @@ -298,6 +323,46 @@ int qcom_ice_suspend(struct qcom_ice *ice) } EXPORT_SYMBOL_GPL(qcom_ice_suspend); +/* + * For v1 the ICE slot will be calculated in the trustzone. + */ +static int translate_hwkm_slot(struct qcom_ice *ice, int slot) +{ + return (ice->hwkm_version == 1) ? slot : (slot * 2); +} + +static int qcom_ice_program_wrapped_key(struct qcom_ice *ice, + const struct blk_crypto_key *key, + u8 data_unit_size, int slot) +{ + union crypto_cfg cfg = { + .dusize = data_unit_size, + .capidx = QCOM_SCM_ICE_CIPHER_AES_256_XTS, + .cfge = QCOM_ICE_HWKM_CFG_ENABLE_VAL, + }; + int hwkm_slot; + int err; + + hwkm_slot = translate_hwkm_slot(ice, slot); + + /* Clear CFGE */ + qcom_ice_writel(ice, 0x0, QCOM_ICE_LUT_CRYPTOCFG_SLOT_OFFSET(slot)); + + /* Call trustzone to program the wrapped key using hwkm */ + err = qcom_scm_ice_set_key(hwkm_slot, key->raw, key->size, + QCOM_SCM_ICE_CIPHER_AES_256_XTS, data_unit_size); + if (err) { + pr_err("%s:SCM call Error: 0x%x slot %d\n", __func__, err, + slot); + return err; + } + + /* Enable CFGE after programming key */ + qcom_ice_writel(ice, cfg.regval, QCOM_ICE_LUT_CRYPTOCFG_SLOT_OFFSET(slot)); + + return err; +} + int qcom_ice_program_key(struct qcom_ice *ice, u8 algorithm_id, u8 key_size, const struct blk_crypto_key *bkey, @@ -313,24 +378,40 @@ int qcom_ice_program_key(struct qcom_ice *ice, /* Only AES-256-XTS has been tested so far. */ if (algorithm_id != QCOM_ICE_CRYPTO_ALG_AES_XTS || - key_size != QCOM_ICE_CRYPTO_KEY_SIZE_256) { + (key_size != QCOM_ICE_CRYPTO_KEY_SIZE_256 && + key_size != QCOM_ICE_CRYPTO_KEY_SIZE_WRAPPED)) { dev_err_ratelimited(dev, "Unhandled crypto capability; algorithm_id=%d, key_size=%d\n", algorithm_id, key_size); return -EINVAL; } - memcpy(key.bytes, bkey->raw, AES_256_XTS_KEY_SIZE); + if (ufs_qcom_use_wrapped_keys && + (bkey->crypto_cfg.key_type == BLK_CRYPTO_KEY_TYPE_HW_WRAPPED)) { + /* It is expected that HWKM init has completed before programming wrapped keys */ + if (!ice->use_hwkm || !ice->hwkm_init_complete) { + dev_err_ratelimited(dev, "HWKM not currently used or initialized\n"); + return -EINVAL; + } + err = qcom_ice_program_wrapped_key(ice, bkey, data_unit_size, + slot); + } else { + if (bkey->size != QCOM_ICE_CRYPTO_KEY_SIZE_256) + dev_err_ratelimited(dev, + "Incorrect key size; bkey->size=%d\n", + algorithm_id); + return -EINVAL; + 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++) - __cpu_to_be32s(&key.words[i]); + /* The SCM call requires that the key words are encoded in big endian */ + for (i = 0; i < ARRAY_SIZE(key.words); i++) + __cpu_to_be32s(&key.words[i]); - err = qcom_scm_ice_set_key(slot, key.bytes, AES_256_XTS_KEY_SIZE, - QCOM_SCM_ICE_CIPHER_AES_256_XTS, - data_unit_size); - - memzero_explicit(&key, sizeof(key)); + err = qcom_scm_ice_set_key(slot, key.bytes, AES_256_XTS_KEY_SIZE, + QCOM_SCM_ICE_CIPHER_AES_256_XTS, + data_unit_size); + memzero_explicit(&key, sizeof(key)); + } return err; } @@ -338,7 +419,23 @@ EXPORT_SYMBOL_GPL(qcom_ice_program_key); int qcom_ice_evict_key(struct qcom_ice *ice, int slot) { - return qcom_scm_ice_invalidate_key(slot); + int hwkm_slot = slot; + + if (ice->use_hwkm) { + hwkm_slot = translate_hwkm_slot(ice, slot); + + /* + * Ignore calls to evict key when HWKM is supported and hwkm + * init is not yet done. This is to avoid the clearing all + * slots call during a storage reset when ICE is still in + * legacy mode. HWKM slave in ICE takes care of zeroing out + * the keytable on reset. + */ + if (!ice->hwkm_init_complete) + return 0; + } + + return qcom_scm_ice_invalidate_key(hwkm_slot); } EXPORT_SYMBOL_GPL(qcom_ice_evict_key); @@ -348,6 +445,15 @@ bool qcom_ice_hwkm_supported(struct qcom_ice *ice) } EXPORT_SYMBOL_GPL(qcom_ice_hwkm_supported); +int qcom_ice_derive_sw_secret(struct qcom_ice *ice, const u8 wkey[], + unsigned int wkey_size, + u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]) +{ + return qcom_scm_derive_sw_secret(wkey, wkey_size, + sw_secret, BLK_CRYPTO_SW_SECRET_SIZE); +} +EXPORT_SYMBOL_GPL(qcom_ice_derive_sw_secret); + static struct qcom_ice *qcom_ice_create(struct device *dev, void __iomem *base) { diff --git a/include/soc/qcom/ice.h b/include/soc/qcom/ice.h index 1f52e82e3e1ca..dabe0d3a1fd05 100644 --- a/include/soc/qcom/ice.h +++ b/include/soc/qcom/ice.h @@ -17,6 +17,7 @@ enum qcom_ice_crypto_key_size { QCOM_ICE_CRYPTO_KEY_SIZE_192 = 0x2, QCOM_ICE_CRYPTO_KEY_SIZE_256 = 0x3, QCOM_ICE_CRYPTO_KEY_SIZE_512 = 0x4, + QCOM_ICE_CRYPTO_KEY_SIZE_WRAPPED = 0x5, }; enum qcom_ice_crypto_alg { @@ -35,5 +36,8 @@ int qcom_ice_program_key(struct qcom_ice *ice, 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); +int qcom_ice_derive_sw_secret(struct qcom_ice *ice, const u8 wkey[], + unsigned int wkey_size, + u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]); struct qcom_ice *of_qcom_ice_get(struct device *dev); #endif /* __QCOM_ICE_H__ */ From patchwork Mon Dec 2 12:02:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 13890366 X-Patchwork-Delegate: snitzer@redhat.com 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 51528208970 for ; Mon, 2 Dec 2024 12:03:01 +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=1733140984; cv=none; b=RUHQx9WqH33C2eyTlIBYtvs4fpLBuq+NZai+4lc2CvlSqLBYZn36Bc/rHxklCGxiGUh0HZSzFGKSEmNJtkp9/aqVsuOb0Qo+oXR5sn1P73OmgLkgfPb6/uxsTeYOVZI3D/FGxR7X58JInYP95H7JBr7Nr2d3LblFGiL6f27kknU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140984; c=relaxed/simple; bh=QjUMBAWkjky6GHRxx2Gd0Kb/brgb9vo6Utawe6cSi0w=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mWXftxaGFVx7ZycJZTazxZmY7Rs2GmM7xn0MS6gSwSjBje2pDvJkxVKO7EnKhK90GjkGc8VIgpYhZ2XSnWGti2nLKGUvjFizZhfmI2q7SgSkg7B8u1yjV3vwPAviXD4fR4I42jfmtZ1RGAL2X9zAnUAP1u3zRs5b1NUnNL4edOA= 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=AAbuPnOx; 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="AAbuPnOx" Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-434a766b475so38216035e9.1 for ; Mon, 02 Dec 2024 04:03:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1733140980; x=1733745780; darn=lists.linux.dev; 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=PYd9QLS1DFmWBH98/OcoHCVn4HW80u7O0xy+afAXA98=; b=AAbuPnOxIBXrcSFJb2GzSWXrkK7pJXYxNfdvJRv5nAqTasQ50tDoP0HfFmh3CxXRsm PqjOACbszCjuijhSyZxj5mQgq0k4M9uUPv5Z5dcvIhYgTxvz1oFo3UwE4lnMlHSwZaGm IgHcaagu2nyZYNFru2xczws7TjB1IFS7KtpP9+26qt5h5BqdbgW3EivCsIa0AnC1pETv 0jtOT2WGvLvIE1LJRgpKfjFNCnK+kHJu7DA4p7cdBCDfDYoJ4F/+vp5VFfyBwog0I+ae A4qOSC8zNM5TDCaRKonQvC9vs9hMal6kiBv8xW1D+MIwr5gKAm15Yb4P5B8mAHBStuuo VAwg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733140980; x=1733745780; 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=PYd9QLS1DFmWBH98/OcoHCVn4HW80u7O0xy+afAXA98=; b=a9GQL8XOtpn3MlrHowG69nzSxJ0k2YNscv0b+UPL+8+ZG6sQsgETwMc6MGURxikBef ZpTUE8N+m4hb3BHlKdWZNmUgk0/PrV26H4Nu8Atq9b2DXDIaVzRhIRoU6kbIPSfYJYGE RIcDR5wTjN4RNaGDZkBZvjuWkfm0YOwEldLY1faSKDoepdaAA/W+mJghbavRBvpI+AsW ez8xdTFUjIbQofixW/UoAAXs1hYkDrBroQZgxJyCm9XcwsVVc/xtW9F+Ieyj3/8hTane XVzmjjeMFpZnUzQaWxI3TB6Ak+PtDGJJsRpL+MfvZ34vzn7zzs7b+kLpLVqBYiP6ifQ8 ipHg== X-Forwarded-Encrypted: i=1; AJvYcCXMvXp8an0edRBihY0NCfpvMiVrFefJPA7mayiLmgjjx2wJiepZQhLdnhSl2npQMXLcdvAuZ6Ul4A==@lists.linux.dev X-Gm-Message-State: AOJu0YzuaniIyP4t1jNw7QdOBwqIS2fl1RV8Ua3FCUJeEUPAJ3G1MWe+ AF4pgJNuhPJNnqsA4GR51r691X3LedkQECmF4TA/7OrgJqt9TQchXGhGcTb/z1o= X-Gm-Gg: ASbGncvmVzuwMjaVRZbx0GtEJHV/vt45Ch3Td/RVQ35EMixncyYgQHowfbrWOURV6Nb XjZjTaB9u4Tdc3oEnYi6ZdmbwrSxS25OET79AeuwQ188IW1TiUpdi/V/iQLZtXkEK9FFjyIDXvM xALdrXfQsDPTPYhD3lY//dbqdICqaHY+BkT1vfaD6S8xUxs2L1cunSdSyT0/W2fFcdt6FO/7ScN gI2ppGMRbzvv1I1crj2bYVWi+ulrVwA1n0KS/C9 X-Google-Smtp-Source: AGHT+IH0sFHTrv69HUdG+L8j6VdCnN8rBYNeyeTlRD+CzCFrwH/SAYb29NCJbhplyj0igslu9w0Q2A== X-Received: by 2002:a05:600c:588c:b0:434:a7e3:db50 with SMTP id 5b1f17b1804b1-434a9df26cbmr164746035e9.21.1733140979519; Mon, 02 Dec 2024 04:02:59 -0800 (PST) Received: from [127.0.1.1] ([193.57.185.11]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-434b0d9bed7sm152396095e9.8.2024.12.02.04.02.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Dec 2024 04:02:59 -0800 (PST) From: Bartosz Golaszewski Date: Mon, 02 Dec 2024 13:02:27 +0100 Subject: [PATCH RESEND v7 11/17] soc: qcom: ice: add support for generating, importing and preparing keys Precedence: bulk X-Mailing-List: dm-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241202-wrapped-keys-v7-11-67c3ca3f3282@linaro.org> References: <20241202-wrapped-keys-v7-0-67c3ca3f3282@linaro.org> In-Reply-To: <20241202-wrapped-keys-v7-0-67c3ca3f3282@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" , Gaurav Kashyap , Neil Armstrong , Dmitry Baryshkov , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam 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.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=4969; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=wBmla9vpsk6IBou1zRMUSL0Tc/0bcTxXP/Te/sINSVg=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnTaHVlurYu6yUto1xPH8+t0uD32/BAubsZIDSD KpG+fHxPN6JAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZ02h1QAKCRARpy6gFHHX cnYzD/4iS5EmKewFMxerNwnCDZ06zB2aegC187jsiQelALVuMOCjEtjnIdq+IBsg+5Bd95kxxut AjMNK+unKpUaISzjphujFll8jvVmldtEYZQ3A1kC0uiKhSymgaLeBKIDx9oipPlzVjK5f84J6ay Ey72wMbnEhKM0OAT153STQnYD4aIqHCRnlvdsISbnaPCe9PmsJV8L0XowD+04nJ1W0JTQu+HBll X6OSinVUm52afgcSR6cuCKK1Sg1tLxgGXxXYmj9TrdXgXx0rZPBH2sa9TCxUl2fadX+hazHxa7q PUCRMczS1ZdaEIrdjC8RV6rPxvly9GxSCjYCmNI5yDgtIkox3eOmB+jKTLOERWTcAKYCT/dZfKm Y0mIz+EEWaZRQhOtsNFQgZoZxLUB8e7vIhlZFh1NmOnuy3dNhCQmosgpYSn3nHwO5xccu6KkWUO jgr6md2l7GCiQZl70zPFFRImvlbO+xTEc9VZyc59fkpf9KoHVhcyCysgB90TeL0IF/hSnki6LH8 9oiv/s0/cf65N2m16fRQ1q2S4gGmhnnekolXyTiRbOisI7FgG0vYyZRO0ni8D2La+EkXhEMVKIj o8GThV5BypWpTOq0KnJA8XwlULQiwYBmOWpdO2lKvMaRMAZDkyk0vS8z9rwA5LsgOUSiuWYRpvr VIB7GYqgN9RV3gA== X-Developer-Key: i=bartosz.golaszewski@linaro.org; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 From: Gaurav Kashyap With the new SCM calls that interface with TrustZone and allow us to use the Hardware Key Manager functionality, we can now add support for hardware wrapped keys to the Qualcomm ICE SoC driver. Upcoming patches will connect that layer with the block layer ioctls. Tested-by: Neil Armstrong Signed-off-by: Gaurav Kashyap Co-developed-by: Bartosz Golaszewski Signed-off-by: Bartosz Golaszewski --- drivers/soc/qcom/ice.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/soc/qcom/ice.h | 8 +++++ 2 files changed, 89 insertions(+) diff --git a/drivers/soc/qcom/ice.c b/drivers/soc/qcom/ice.c index e83e74e39e44f..6f0c6fcaf0f3d 100644 --- a/drivers/soc/qcom/ice.c +++ b/drivers/soc/qcom/ice.c @@ -22,6 +22,13 @@ #define AES_256_XTS_KEY_SIZE 64 +/* + * Wrapped key sizes that HWKM expects and manages is different for different + * versions of the hardware. + */ +#define QCOM_ICE_HWKM_WRAPPED_KEY_SIZE(v) \ + ((v) == 1 ? 68 : 100) + /* QCOM ICE registers */ #define QCOM_ICE_REG_VERSION 0x0008 #define QCOM_ICE_REG_FUSE_SETTING 0x0010 @@ -454,6 +461,80 @@ int qcom_ice_derive_sw_secret(struct qcom_ice *ice, const u8 wkey[], } EXPORT_SYMBOL_GPL(qcom_ice_derive_sw_secret); +/** + * qcom_ice_generate_key() - Generate a wrapped key for inline encryption + * @ice: ICE driver data + * @lt_key: long-term wrapped key to be generated, which is + * BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE in size. + * + * Make a scm call into trustzone to generate a wrapped key for storage + * encryption using hwkm. + * + * Returns: 0 on success, -errno on failure. + */ +int qcom_ice_generate_key(struct qcom_ice *ice, + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]) +{ + size_t wk_size = QCOM_ICE_HWKM_WRAPPED_KEY_SIZE(ice->hwkm_version); + + if (!qcom_scm_generate_ice_key(lt_key, wk_size)) + return wk_size; + + return 0; +} +EXPORT_SYMBOL_GPL(qcom_ice_generate_key); + +/** + * qcom_ice_prepare_key() - Prepare a long-term wrapped key for inline encryption + * @ice: ICE driver data + * @lt_key: longterm wrapped key that was generated or imported. + * @lt_key_size: size of the longterm wrapped_key + * @eph_key: wrapped key returned which has been wrapped with a per-boot ephemeral key, + * size of which is BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE in size. + * + * Make a scm call into trustzone to prepare a wrapped key for storage + * encryption by rewrapping the longterm wrapped key with a per boot ephemeral + * key using hwkm. + * + * Return: 0 on success; -errno on failure. + */ +int qcom_ice_prepare_key(struct qcom_ice *ice, const u8 *lt_key, size_t lt_key_size, + u8 eph_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]) +{ + size_t wk_size = QCOM_ICE_HWKM_WRAPPED_KEY_SIZE(ice->hwkm_version); + + if (!qcom_scm_prepare_ice_key(lt_key, lt_key_size, eph_key, wk_size)) + return wk_size; + + return 0; +} +EXPORT_SYMBOL_GPL(qcom_ice_prepare_key); + +/** + * qcom_ice_import_key() - Import a raw key for inline encryption + * ice: ICE driver data + * @imp_key: raw key that has to be imported + * @imp_key_size: size of the imported key + * @lt_key: longterm wrapped key that is imported, which is + * BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE in size. + * + * Make a scm call into trustzone to import a raw key for storage encryption + * and generate a longterm wrapped key using hwkm. + * + * Return: 0 on success; -errno on failure. + */ +int qcom_ice_import_key(struct qcom_ice *ice, const u8 *imp_key, size_t imp_key_size, + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]) +{ + size_t wk_size = QCOM_ICE_HWKM_WRAPPED_KEY_SIZE(ice->hwkm_version); + + if (!qcom_scm_import_ice_key(imp_key, imp_key_size, lt_key, wk_size)) + return wk_size; + + return 0; +} +EXPORT_SYMBOL_GPL(qcom_ice_import_key); + static struct qcom_ice *qcom_ice_create(struct device *dev, void __iomem *base) { diff --git a/include/soc/qcom/ice.h b/include/soc/qcom/ice.h index dabe0d3a1fd05..dcf277d196ff6 100644 --- a/include/soc/qcom/ice.h +++ b/include/soc/qcom/ice.h @@ -39,5 +39,13 @@ bool qcom_ice_hwkm_supported(struct qcom_ice *ice); int qcom_ice_derive_sw_secret(struct qcom_ice *ice, const u8 wkey[], unsigned int wkey_size, u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]); +int qcom_ice_generate_key(struct qcom_ice *ice, + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]); +int qcom_ice_prepare_key(struct qcom_ice *ice, + const u8 *lt_key, size_t lt_key_size, + u8 eph_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]); +int qcom_ice_import_key(struct qcom_ice *ice, + const u8 *imp_key, size_t imp_key_size, + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]); struct qcom_ice *of_qcom_ice_get(struct device *dev); #endif /* __QCOM_ICE_H__ */ From patchwork Mon Dec 2 12:02:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 13890367 X-Patchwork-Delegate: snitzer@redhat.com Received: from mail-wm1-f53.google.com (mail-wm1-f53.google.com [209.85.128.53]) (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 7874720966B for ; Mon, 2 Dec 2024 12:03:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140986; cv=none; b=IeNIlktDWk5xf5Tv929CPR3o+QI1PQyJZLoDwhjYl4uzBctosicQv3GIabBYu5mym6mXvdlqim5Tn11u8GUZrYuyniWV3cgTC7xsxqD/GVXEA+9XyKZO7YrEY9QR4WWDUbUuLwdSEbfHeW4qHp77MZ6VpzKTduiSnL5hTHfIbW4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140986; c=relaxed/simple; bh=AqF63O/Ib0+mAPITy6g8+BVgv9brQasaHdYYrdxQTrk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=annOs/+PFf1QxI3esnewG+ZYW03jUkaVTzgY62zOSJWFI7MAJd7hXI/QD8kyV4MVIwX+IDDvx6BRkH2fkcageHHKZLXbl60Pu3R3r/dVivsjHU1yZ2rnMayhosVmTwM/7fNUkgqtxG7Zp4uAa67m8aXxhMKlVihul2ftZhMFPZI= 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=r0ndFjja; arc=none smtp.client-ip=209.85.128.53 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="r0ndFjja" Received: by mail-wm1-f53.google.com with SMTP id 5b1f17b1804b1-434acf1f9abso38164235e9.2 for ; Mon, 02 Dec 2024 04:03:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1733140981; x=1733745781; darn=lists.linux.dev; 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=gYruTmcB1Bftzc/voPlNnlx7ouCt6Ma+mW6cK8AFUIA=; b=r0ndFjjazWFIJ16Np5dcXc8In/9D+tn/zH5ZuROG+be49K+A4t3vqkj60JzyGLa561 KYgoz+k03DZHidHtJi59m5cn+QHUrefQuiakK+2NXMS9NXVpjFFbIUrazR4f6uwKD8ZL RWdKbit8MQ4VqgohaWrxJzHN96Zr2k06Rz9lRWjhAUzYxBIMPIiFSdVH7kFgiQC9abrc 1QOAr79o2Iw9g+5ybow5rHHhZ6zQpZl+pF1zN88g+GDFLzMvrANOK4wDVSZJpnNlxSa8 hEMftWgU4RFtd7+cmeyB7Us7cNEf2lVlBZ5mlhsf45RG22LXDcjXSXFQwvaG97zh25KP Tiaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733140981; x=1733745781; 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=gYruTmcB1Bftzc/voPlNnlx7ouCt6Ma+mW6cK8AFUIA=; b=jXxdwCCT+rUgti0GNtxRqIVJXylJzrR2qeQ9sjwZtIk9v8995wDdyda5T5kenpQefi w+FXXgIhINOfPzUU17YD6QbR9oqyvdsWkguy+P8FfJqHgN86fe1B14iyi3vHFt6T7b1Z NXpL0P3Au2VtAdAmI9qFfVvlBMIiN4DM8ujkJQKrviviLC3dvYkFyWhfc8vzUHO3xbZJ MmRiDYnS7obMC59WT4nLx44FPapdf5hfiiSvkg663APcwklWGis/4SwjPQNxUFztIHKX D/EVEVQu2cmKf2t/MjbSX9bV2ZSbiUDWANgzsIWJosizGct0pQmXZiT6qSB01q5fLVKe B5mQ== X-Forwarded-Encrypted: i=1; AJvYcCUo0FJuMGjNSoNhqO/+XWTDF3mIfafcwERcu0aLNdvtFwP9zqr1BgkaONXYt6QHV57r1IZALFFv9w==@lists.linux.dev X-Gm-Message-State: AOJu0Yyq6L37yFoPIa3TW/O3+wOWc6wyM0Td/LIqXc1aY8A8NtTcmNKz SIuXkcgIKIqTTWioarkMciiQ76+1u1Z3cyef0wKZNVwIbG6rHlHMuwlbkoffEY8= X-Gm-Gg: ASbGncskeMLaJxGKaurdWOMhQCKCiSmw7NUPR8/Etw+0PHTtIZm4LS92TEYVmdlVLN1 VWEotln3H5L5CDlsIh+xv2GSfjexxhi4oiKSBpPW3bBer0HSPAMRu2XCx85lxFfnsZOGstfWoFs F4xZjVx4sL/nkfW/13A1xtNjDn8P9XAbFp5l3Fpa+9ZoeH2loT3Aljw+JLReTKlAIUl2NSmndAF hePXT6zqIsHAqCmPLVZP5xkmeD6wsGjXCVPExMz X-Google-Smtp-Source: AGHT+IH2nzvAB3orz8c5uRDN7301DF9ak1WkbxvD6Xg2UwkFlwWmF7C9APA4wxhU1G0XcB5G0CCeWg== X-Received: by 2002:a05:600c:1e06:b0:42c:b187:bde9 with SMTP id 5b1f17b1804b1-434a9e0bc3fmr222546695e9.30.1733140981243; Mon, 02 Dec 2024 04:03:01 -0800 (PST) Received: from [127.0.1.1] ([193.57.185.11]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-434b0d9bed7sm152396095e9.8.2024.12.02.04.02.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Dec 2024 04:03:00 -0800 (PST) From: Bartosz Golaszewski Date: Mon, 02 Dec 2024 13:02:28 +0100 Subject: [PATCH RESEND v7 12/17] ufs: core: add support for wrapped keys to UFS core Precedence: bulk X-Mailing-List: dm-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241202-wrapped-keys-v7-12-67c3ca3f3282@linaro.org> References: <20241202-wrapped-keys-v7-0-67c3ca3f3282@linaro.org> In-Reply-To: <20241202-wrapped-keys-v7-0-67c3ca3f3282@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" , Gaurav Kashyap , Neil Armstrong , Dmitry Baryshkov , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam 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.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=2886; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=KDRiDKGiOR40fLHLM58rwn0K0j6tx7t9Y60UZCPt2/Y=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnTaHVRwop+WnyjY5L41879Dt/Woqbv2vxlbW7D sSLqwx1OkKJAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZ02h1QAKCRARpy6gFHHX ctOvEACAFUZHNYcJjh/LSB8KSkFcf+ZYvmftdMT8boQLn7AnmN4Ei4Hw0XHry5lTmJ0qMJAtqVb cd8ABKa59peuhCt4FgaE5Vkoa0o0dvA6+gUlGoh/77zfb1/o3ysp2LZiYSP5NzRKfasuAGM6pWS lENKbBd/ZfT0QV6T8NsmHxgFiwH0GUqw7cgpVOS0f/udj7J416/Km+3rMmmz+2XFP0VwAx1WZJO wGyvNhCUCHVJfWyvkrsQoe2fuE+qy1F9Iw9KmSU2LH0jmfFHfVMxrABQZgllsVHEKgkzC8VbLkf HJFMqgkGOJRzWwpaSdJV9YjgrfRCBCxbCRTjRUDgvF5hLUl6qe4pDLgVDW3j8ighcfCAjgRJljz /2gM+bUOISVp0/xZMaBQChDVxjjjY4IA0jCSGaPwoEXWagvenW2KZVHnzSlxFg9wnb57gp+hx8J BFkdZrUmHdSt1WN0cvyWGuw2qOfSlWI+0Uy9npKT5zOqOymbC44Y6wr7MWQ6sHovB4JDTY7EvgX cyVV+mi8sKc2+DMLouyOtdqY6Ty7HfKcLjcdn9o5b3r7mBnVc7v40npv16zlDP20Hl6D/IfJpGe ojN4SC46+97/DDpRkafl6PZtbHlYMJbr0ojcZQLsJAlJYrEQNxysJgZ7kkXIJ0m3SVjlysufQj0 ob47mYBh8sQ4FVQ== 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 Reviewed-by: Konrad Dybcio 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 33083e0cad6e1..64389e8769108 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 bc6f08397769c..db2b71f760717 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -761,6 +761,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 Mon Dec 2 12:02:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 13890368 X-Patchwork-Delegate: snitzer@redhat.com Received: from mail-wr1-f53.google.com (mail-wr1-f53.google.com [209.85.221.53]) (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 60F2A209F24 for ; Mon, 2 Dec 2024 12:03:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140989; cv=none; b=QCtNPHMeeC7pdTvcgs7ivpDr3aLTocFVCv3ju2xlkmWsTeWDgrtVrKJEuzbe9XRHTNSX89GnO1DfYwYW5K3cM4QpNlA8M81sTUk01xgTSE5ddNZyGOgmeTMXJV7xTtYj1nANPjkESlA7BtNhEI/ktB4GSKYp8kxZBW4VGiBYmfY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140989; c=relaxed/simple; bh=rDgzjyrCxow20O57yxOKv5Dt7aQaZyB78v7qF4RvpKA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iFIfrCk0GWyCll0MCi+UWHE9aV/f2qGt4/AJSq90LjG5ebXvYxpwCV1hzhKIO2x49OOJP6VIoNXZylUbTFNo+odD06K84a/mAvHeU6Ta/T75mVIvWYCIS+6c6j9TPoJUCFJeE2LQXg3sOKM38TMpAe7MZkDhcxo/jf/v/R0w5qE= 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=ZXOesDt8; arc=none smtp.client-ip=209.85.221.53 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="ZXOesDt8" Received: by mail-wr1-f53.google.com with SMTP id ffacd0b85a97d-385e3621518so1526623f8f.1 for ; Mon, 02 Dec 2024 04:03:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1733140984; x=1733745784; darn=lists.linux.dev; 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=KbT2yjWECByZX4YoBFRCDGctDmzwqVa2hRpV/DsyHrc=; b=ZXOesDt8Uho7Fe8yVCSQKc6z4aRXhTOdIxKt1H4aAnDJUn4fQ/Cmx8/HqHRiAShTDN YM9XDKHm8Fu05TZwITgO503ohYOamfYbwzxMbVnUf29vauoEjEBiyBPq+Pa0HUzGYWPV GWW0rEYPTRdN4XQE6mewEho3iNGlOG6Tmc1z5lkseRc1w90naLSgC5BGsVZtPG6T0zkv MhSxY4KPImqYKXH91ZNUEyXhmHS9Oto4ofqQWSyEgy6Pd7zV1rjWfIGZiVqatZ6j5ncG sOMUwRDhtXym/aKXRTuomtWlUoAg3WpHfS9yATwP16uC+zohMFBvNJO8s0WbIxfZRSQn ZJIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733140984; x=1733745784; 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=KbT2yjWECByZX4YoBFRCDGctDmzwqVa2hRpV/DsyHrc=; b=ptUbWiP+cWEmyE3oSGUEC5e0zaSR5H/WVfEm8mbtOQOJGEjYicp2u/U14Ue6v6+Ljv Gfq+w3abd4cl2ijIJ28kWPReZGw5bGeXw4n23bN0iGEnDhrmquEt3u+BxzxZf5uknRVI 9ZBPrY7r/aSugaYum3VklyW6RAWCzXzD3AkwzOO0R3vo5QeuxwNDWYtvRN4pVa4l6lEC OAl3OwmtXf/nJbOt4DYsDi9VpKzHyVDS0jWliS7Gc5RumoKDj0btRMEoWG7mLm0pd/KE CtuuTnt5k1FP+YohLu3anPCULSuBxtYGjPr/0snUfhtOu9gJNNcdksM51s7OYj89/fRe LBVw== X-Forwarded-Encrypted: i=1; AJvYcCVDuwHapLKXuTgs/5doAp6Qiy8UTYC6AJSm8DV7Aormh1kXWfaNtAdWoA/1cG6ERIiw4uRtZ9FxwA==@lists.linux.dev X-Gm-Message-State: AOJu0Ywy1DHSShPYvPZ5qEYzaPhVA8UqixUfOfFokNIUMrKWuY4hihOW 5Nem4j0w3Qm7NCABvm81CJ0pf4uJIyAiFYK+bGNgadCUHZTcgjfIS5lmlz47dPk= X-Gm-Gg: ASbGncs2hoNehXqvy+MQlAqMi3Hqj2WB/9LcLQBHbMMTYNRTdkuN82TpQpTvLyDiUl6 n7a0Fw2ahhlHnsRO6HEaxC+1cRUvJRy88eRyavR35ipfq1LCbsbIEbohEuw9bCxmjvLnQ08QHaF KZTaXbcPjhRUMlymc3lPgyBv9oulDbXbv5+BECPrSzz4S4fGjE9dkbBE9bH1SPa1LHShAQLupNI Ds2KE4p2JXJMT8xA+k49gMVgSNHQj6JEIdSwAJB X-Google-Smtp-Source: AGHT+IE8InKM+5p5YhbHKlZqW5eKtWZzURRtuhs650gYc2AEjKaWvw/sZZSN1CqSTaFlPcWax4Q/Mw== X-Received: by 2002:a5d:64ee:0:b0:385:f677:859b with SMTP id ffacd0b85a97d-385f67789a8mr1422366f8f.10.1733140983205; Mon, 02 Dec 2024 04:03:03 -0800 (PST) Received: from [127.0.1.1] ([193.57.185.11]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-434b0d9bed7sm152396095e9.8.2024.12.02.04.03.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Dec 2024 04:03:02 -0800 (PST) From: Bartosz Golaszewski Date: Mon, 02 Dec 2024 13:02:29 +0100 Subject: [PATCH RESEND v7 13/17] ufs: core: add support for deriving the software secret Precedence: bulk X-Mailing-List: dm-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241202-wrapped-keys-v7-13-67c3ca3f3282@linaro.org> References: <20241202-wrapped-keys-v7-0-67c3ca3f3282@linaro.org> In-Reply-To: <20241202-wrapped-keys-v7-0-67c3ca3f3282@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" , Gaurav Kashyap , Neil Armstrong , Dmitry Baryshkov , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam 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.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=2650; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=MQigyGWoS7egCiFabEGvOIGlVmzO1zHpQlE1Kmp4zmE=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnTaHVIFBM1y8uWTaoURGUfuIgsk9gDANWKQCsa 8zWklwoa4iJAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZ02h1QAKCRARpy6gFHHX cgLDEADBrjGlnEDnOX6YzXmxa3INqU5S9zTFOsYDq/wb2dUpJF462gP2OnwVdwfJVV0cyWufaVS 0/l0ZqTS3zvGBArVt6A1c8blcMiztmUuVjRcwhKHNRnzbf2JIZlGbgd1I7b6YYS1twaziT+9c25 iG3kbnS9u10fc7U4HqOOd+9DpVXJ4uxY3DPvP8W3gh0lJGfxeNmnlXwItZIB0EJ3Zi/0K4lJcg5 cKDNcTr2MQlnc2WZ1G/nsWB2Ar2LoP61yARuh5xaLaD0dAK+iQ4CqDdzazIw+hiko+8Tx9zoxSY cHdvYsWKYYgEnzt8DkEmZH8/QYKXAYxgwL1HP49sIGLwq2NRREAXQCmXXJZ7NihiNinLMQsl5Et pKNVMm/VP27H3ysZv1Es74K+PkL9uC5yzLEHbnElaGefcEfoZW9elsd6PHdxKkZ7HHVPg0CH6Gz EwYJUrlucD2BHHbfFT5OFScj583jzecNIRSnYLsbhT2npxqsG5fhEamL9RaDwexQ/32+qZeaogO Gz7hx9WMoOAy8hfUXGhlKuY8R6kammvqYgztudMdbTxwkPFfipCHbXUr9lXjNVBV6fAoB1KuIAT jLGh8Hk2Aigj6gUSpjqyX5uG+LzT9c1GHeN0XsOW/MxPLokfo/7Eat/kVPMFFdjUuL13y5zqNwx wlUgeZoRfVCAaMw== X-Developer-Key: i=bartosz.golaszewski@linaro.org; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 From: Gaurav Kashyap Extend the UFS core to allow calling the block layer's callback for deriving the software secret from a wrapped key. This is needed as in most cases the wrapped key support will be vendor-specific and the implementation will live in the specific UFS driver. Tested-by: Neil Armstrong Reviewed-by: Om Prakash Singh Signed-off-by: Gaurav Kashyap Reviewed-by: Konrad Dybcio Signed-off-by: Bartosz Golaszewski --- drivers/ufs/core/ufshcd-crypto.c | 15 +++++++++++++++ include/ufs/ufshcd.h | 3 +++ 2 files changed, 18 insertions(+) diff --git a/drivers/ufs/core/ufshcd-crypto.c b/drivers/ufs/core/ufshcd-crypto.c index 64389e8769108..2530239d42afa 100644 --- a/drivers/ufs/core/ufshcd-crypto.c +++ b/drivers/ufs/core/ufshcd-crypto.c @@ -113,6 +113,20 @@ static int ufshcd_crypto_keyslot_evict(struct blk_crypto_profile *profile, return ufshcd_program_key(hba, NULL, &cfg, slot); } +static int ufshcd_crypto_derive_sw_secret(struct blk_crypto_profile *profile, + const u8 wkey[], size_t wkey_size, + u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]) +{ + struct ufs_hba *hba = + container_of(profile, struct ufs_hba, crypto_profile); + + if (hba->vops && hba->vops->derive_sw_secret) + return hba->vops->derive_sw_secret(hba, wkey, wkey_size, + sw_secret); + + return -EOPNOTSUPP; +} + /* * Reprogram the keyslots if needed, and return true if CRYPTO_GENERAL_ENABLE * should be used in the host controller initialization sequence. @@ -134,6 +148,7 @@ bool ufshcd_crypto_enable(struct ufs_hba *hba) 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, }; static enum blk_crypto_mode_num diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index db2b71f760717..1b7c36e5347b2 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -375,6 +375,9 @@ struct ufs_hba_variant_ops { int (*program_key)(struct ufs_hba *hba, const struct blk_crypto_key *bkey, const union ufs_crypto_cfg_entry *cfg, int slot); + int (*derive_sw_secret)(struct ufs_hba *hba, const u8 wkey[], + unsigned int wkey_size, + u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]); int (*fill_crypto_prdt)(struct ufs_hba *hba, const struct bio_crypt_ctx *crypt_ctx, void *prdt, unsigned int num_segments); From patchwork Mon Dec 2 12:02:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 13890369 X-Patchwork-Delegate: snitzer@redhat.com Received: from mail-wm1-f46.google.com (mail-wm1-f46.google.com [209.85.128.46]) (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 6DF1920A5CA for ; Mon, 2 Dec 2024 12:03:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140990; cv=none; b=fMrDEZL0MH91zIJYTuUDZsKsSfUEEG1pdgxViAnu3XcGzKguXATG7S7+rDh05oPOW46pOre/luEyVZbqbFK6UXvvC5z94/xbAdkffOANH9k0ZdbuKrwEDptN7C8MQh/KOBL2Eh7RfZZ8aRF5z4kAqPUgh2bILi0ILQGu1AZZAZo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140990; c=relaxed/simple; bh=IN6etAo6wtAFxbXGT9XJbAOrzWvZ9os6hEZ0IsjibBE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=knj9sWxOWTNQwJ4pYSydM7HPcZcYQhb5OSSSwoo2J+0jGl7y67CC7GQ/e2jHDh/Y2W0q8l9Hifkj3D6/rcGslsoTpQc4diougifyT0mYrFShFIrZU5XOPPeYJPVChPwr/vQMBUPwdrjgmbT2oBRX1dL7sPsrQBGWeNyfi3SiNFI= 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=ZrFC+H/i; arc=none smtp.client-ip=209.85.128.46 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="ZrFC+H/i" Received: by mail-wm1-f46.google.com with SMTP id 5b1f17b1804b1-434a10588f3so25932805e9.1 for ; Mon, 02 Dec 2024 04:03:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1733140986; x=1733745786; darn=lists.linux.dev; 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=R7TOWAjI6mgo3typHSgU/6g6JMqxt2KgeMAkh5f6OGU=; b=ZrFC+H/ivBf9Ig5xC8mX3ezZYUJy7IF9XIZB5q+VdbQK4c+5E0QvAOSPf4ro3KZt4R JKZ12BfP0ju5mRgVlbqPL+9VjNw6EG2+dmGgJLgZla7IagbDvzggDXelttKB8xAukbQG p4YpBIOYp5sxwKdBcft1vaE0RMBWHvHR4uGb36omIhG9FTZRN5q5Ogu67d7IgreO7JWO QSAxcaBmUJ9eZ3mGk+A6ghSNXoqUZRWybs9JsxFexM4+BpCOy9+Ev+6hfPG/QG6voFGR 6izUNnBN1Y+nulMvQmP08avRgUbsi677gt/iMmS+hTj8RE67RLcDo2F4V0vWKwHRRTse bF3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733140986; x=1733745786; 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=R7TOWAjI6mgo3typHSgU/6g6JMqxt2KgeMAkh5f6OGU=; b=HhT89mOZeIYwZQFY6Bz3jInVjF3SfYmXWy1/nrgGF+C+oQmISTWhGRwOb4W6a+wddu eSRbfJsmeOif6mmN1ZzQEDBVds8jbWj934gNGbcuLbyqRL83b6tJaIsYLXiHmL5JklcF HhPPKxvH9a/cdX3spkeAzWhRiCs0fCPjtHt8yswyQ/wKlDNJEc++5VdSAZdjswD4mKZR 0LXCNt2e37iHCNXHC/m2SZt464v1hX/Sj5nTxDfgtKQlVX3XEa9E004HPjrDyGbSN7dT la3b709+D3eztVLumVYcAO1IwLTjbrM6fYiselh1mpMhIsZoQbhamK+XBnmRe6Q6vhwr nsjA== X-Forwarded-Encrypted: i=1; AJvYcCXsr5DY4sR0IngD4Nt/KWYQtZNl/oM/qt3OSWqu2Q5Wn3GktcEfUNhvK76lKcqdlZMi1Leu/295pQ==@lists.linux.dev X-Gm-Message-State: AOJu0YwuAVjqCiXr1WHtdsalV+Emp3wBVlnDPnFj8iNcyx/LgrS2DFYT 0UfCSlkTBJZD9iGJau53MGYzKgHiKWQKh0LF0Vo7Fbd4x5O/MAovEbCXCmXSBYQ= X-Gm-Gg: ASbGncsp891evyb+pS5dM12FU9TJzkatWLdCA83Kk55QMyqWsOpbTLvoGRAyOTJFqyJ JufFfh9jXjPU+SkhdJL7DXHidfVYJokbjvhUnRxdj1qESjDdEugrkEg881eWLaRT7JMlzjT8agG M2pALvi931Ux0bYr0H936KVEMhtGt1qQoQvmZCJ6rftm45nwdcq5T36Buvrhd3FQj1rg7cLe6B+ W7HqG7aKOOqc34VbxdjoMYwtJPxgVWjr3L5iA/a X-Google-Smtp-Source: AGHT+IEblIdLaPCkPWIaBiUzUXooM1nm9pS8RLKm1Rnw6SlcAmQnVQ8kz2BvOTzozxeqidhfvRPTjw== X-Received: by 2002:a05:600c:1f06:b0:431:2b66:44f7 with SMTP id 5b1f17b1804b1-434a9df7a8dmr222885245e9.31.1733140985417; Mon, 02 Dec 2024 04:03:05 -0800 (PST) Received: from [127.0.1.1] ([193.57.185.11]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-434b0d9bed7sm152396095e9.8.2024.12.02.04.03.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Dec 2024 04:03:05 -0800 (PST) From: Bartosz Golaszewski Date: Mon, 02 Dec 2024 13:02:30 +0100 Subject: [PATCH RESEND v7 14/17] ufs: core: add support for generating, importing and preparing keys Precedence: bulk X-Mailing-List: dm-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241202-wrapped-keys-v7-14-67c3ca3f3282@linaro.org> References: <20241202-wrapped-keys-v7-0-67c3ca3f3282@linaro.org> In-Reply-To: <20241202-wrapped-keys-v7-0-67c3ca3f3282@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" , Gaurav Kashyap , Neil Armstrong , Dmitry Baryshkov , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam 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.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=2597; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=vY4XQO43wfRW3xI/7uuZkDLPJhyrBjrY4cfeoG+PMz8=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnTaHWIEnk3YZilaM3RjOTRCNfoccxXCgiWgs21 PjJLQo3KemJAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZ02h1gAKCRARpy6gFHHX cqWwD/9s/QIp9RedYoUmJr1mV39dwfCeiVoo/zmuH5/kRvjp3XhFzfg2DqWPpeeuZzf4R7gl4pa TGNNYvSnl0SfdPXR12dGxbYjuFmeOT87jjfu45B3lEI1Np4kftp7cteHHlfW+FxPN5KhvcblES7 QxdHm2LrduuzMq0/FxM+hC9DpQt/+OXlvWsKWAlKSGMlQcipS1S3CMf5yD7Z1vDCL8NipDuYgCZ ttVGBqJFaSM5AWdLgyem1tjCDr3RPe6Vc1Un8Q9DaIoQU8S3oe6/c8asuBo/mUhCMeykG/D0Edi uVZActTVn61PZqT12d9/TmzqFi5l/MfPLYfm77QxR7kz/uN7OalyD4IoESTVgIXDmBOFpaE6eHq rCGy3veOw29fuN/M3FQnZJ7I7j/HR2ZNlLHIDdRuNXJjO7EUv3bHh3y+9ivDCUgP/5VadNva9Xn Z5msG0AiQLYeJP79rSFnBcyGtkZtoy/GIZje927jyU/40K+nCgN5O8VMIIgu4QNc3rr88zolZ6j T4NapWeYPWTFd/Adi4kGJWvbB+HTASJdsR6vQgA/iCQctW/qjmhY41Di1IdWa5RGS3QQPfl19cV jSN9v+ZDOJXkQpuBbWU4ZDxTX7sgO2MqUqTO7YMBZm1deTKc8QnTBCqzgkTdfjjsEQMm6JnQwlY OYJxCc9PqOLjdOw== 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 Reviewed-by: Konrad Dybcio 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 2530239d42afa..49c0784f2432d 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 Mon Dec 2 12:02:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 13890370 X-Patchwork-Delegate: snitzer@redhat.com Received: from mail-wm1-f49.google.com (mail-wm1-f49.google.com [209.85.128.49]) (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 774FC20A5FC for ; Mon, 2 Dec 2024 12:03:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140992; cv=none; b=l6OxtXBVOnUtUXMg2g4Pb5YDtZ0kE3eXVEW85JlwN21ETUqoDWqPG3Co5n4q3hkoA3Vd3gSdhJL0u+DOSASk0TkUN1xQtC441xC12nJiKt2Bhjz9piPK6cOL9F47qAdleJWGb0BYqGn7F6iRCocGPrXYXG/mzBwKjWj4PpAeygE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140992; c=relaxed/simple; bh=tLil8meoc4gv8jDi+YbsmsnrrlmnezAGx9Zmm7GaWVo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NGRAZdnzt9i/mjNW7Uh/JASE18wMJ6HeTYWiSiJANzL4PpIC9dG5w4a5BYEMDlJ2/D49LV7wM/Cxd0P3pdikxo5g7WXrr8Bn8YKaFRWTJ7paN7K36rDy+dQEUXqI6+XC4vw76lr4jmmcAc9ssQwNFJae/H7nRYS2s1jb35QJLMM= 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=c1ZVdEyZ; arc=none smtp.client-ip=209.85.128.49 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="c1ZVdEyZ" Received: by mail-wm1-f49.google.com with SMTP id 5b1f17b1804b1-434a044dce2so52460475e9.2 for ; Mon, 02 Dec 2024 04:03:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1733140988; x=1733745788; darn=lists.linux.dev; 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=sappCm7n6rv8bu1mrPLrVjny9xNCVnDXbUHbfHv3TVM=; b=c1ZVdEyZWplswEPsmTJgy3/VKX6xKWla/u5Nr2gegCAnVzkYnmjS3D/hgzLJ3MCCgk EXrtNXICahy/Wtvq3Yh8tpVgqHPWbUPoQRmF83HEUKHTu1wuprIxy56+wmbKQ3kt7Cad wrHk6dOqbSi8eZ/XPWeCAHZVqxTtL8svs0aZGyfEW5Z6tf3FRU0V71P85IBhI4kLx7Tz K+8+VR7mSS2PkwlBJtAFj+MwFggk568rdw/g7xDFf3YjEmhdh0xZioqujVvOUy3Qn3d1 Ul6AByTQ1AHVJ31PydBMY77hKPa5oUJHf1gefFPs25i8xQuK1mOKfQDU7TlCOtZaMAGS A4aw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733140988; x=1733745788; 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=sappCm7n6rv8bu1mrPLrVjny9xNCVnDXbUHbfHv3TVM=; b=QbfNywaK79GTwc6EEmpnT/dJrA3YbtTrvPKn/9PvKPxEa0Xu6Mfy8teMAsikRSjLPk UkJL7jUaiYRSp+RAnVMHX0vrcTO7wUaj3uzHFN3Y8FrjGK5+XHT5pAnVMv3lOuz2xmmF JvuB0lJTZAttseGdjKwc7MLwb/WZQ+SI53NuOlutKi3zxfXo7Ht+WDx/T+DKr0/1vzNq jMI0xMD+hAjg+ZxmS3eLfkgqKB5xHlHjTFvqt7Lwwqg7GDJ85egEF5S6IIr3SVJm10Ii 0lPTYbY4TGp5LS9kZ90kQTt6Mld6isQsGtK/qTzLA8v0zQu8qeU9SWg3AQex9lb9KB6o R9Pw== X-Forwarded-Encrypted: i=1; AJvYcCVPIZKehCGQSAYB+8JlE87aEwHdVVaLrrZGWa8CWmQp+4r8sEIW5BkwAG2SSJ5GYCuEQDs8W/Om1g==@lists.linux.dev X-Gm-Message-State: AOJu0YzUyp8UbPIhrZprhgqhq4pKGey8dkuzffLs7IQYs3A1kOo9B09S jz0lCPjiVUOB+7d8BxX3/n3wrfnHRScrGmKnndjw8bJfKxgb2q+XSAqaUP3y3I0= X-Gm-Gg: ASbGncvCEmR4iRpQEuCR9fAxoUnwbgxqJPGzByu9YT46JROfrhqqATM/cWcF8n5lS4Q C+dQQqC7HQM6XI5Hi1yeebbJ9PijhlME+RZKbV4RmymfHB5WsB2HZbPB1GWu5CL1EnxlbGzTSxo vnmSPJyqORKAS0gS5BtpHHBsMh2XKF9xMW8gxoeb/2wCGNsVMXZF1d0i4bOCdgho5e2cJTHjZOR jw+NPSvoQZgtwG7GHsnhlC7RUMCntfpNVKYwgvz X-Google-Smtp-Source: AGHT+IEnvVRRAOJVEjWRQWTGwHp22oveK1WwEh+juBK0mIY5I5V6RUTWWmdVE0kkT1ZZUSSqgRYdrg== X-Received: by 2002:a05:600c:5254:b0:434:a30b:5445 with SMTP id 5b1f17b1804b1-434a9dcf2b6mr228982825e9.19.1733140987582; Mon, 02 Dec 2024 04:03:07 -0800 (PST) Received: from [127.0.1.1] ([193.57.185.11]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-434b0d9bed7sm152396095e9.8.2024.12.02.04.03.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Dec 2024 04:03:07 -0800 (PST) From: Bartosz Golaszewski Date: Mon, 02 Dec 2024 13:02:31 +0100 Subject: [PATCH RESEND v7 15/17] ufs: host: add support for wrapped keys in QCom UFS Precedence: bulk X-Mailing-List: dm-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241202-wrapped-keys-v7-15-67c3ca3f3282@linaro.org> References: <20241202-wrapped-keys-v7-0-67c3ca3f3282@linaro.org> In-Reply-To: <20241202-wrapped-keys-v7-0-67c3ca3f3282@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" , Gaurav Kashyap , Neil Armstrong , Dmitry Baryshkov , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam 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.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=1568; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=gi1rUYia1K9GFiqOdv+A9A7WV4lUw8MkRuPETlXFN6A=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnTaHWPhF96W8ta0sCsu5xIcmZfLZdnO+UJtTSV wzlGPTq5gmJAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZ02h1gAKCRARpy6gFHHX co/FEACxG2K3W52mA5oFbkrWPJHbaBrdjs6ZZ6SOuehliuBdNm+Wz2Oy8crOCOYPqWebYcc26eb yPbA8sjRYDkffqLtV/s9YOqk6gpEXdWN9ajsb40qdBMhQrYutHku2TP5/VKW9jaqfNfdcjZ8AaO 8nwx/ItU7yfm4ZayW+ipCJVMqBrRnq5uYZK2GVWbYZ+ze16foZqM+e2rvspmK4PCdg5v9daW11n sDy39z3Wop5EmNv8pHEcZl75vgIdi491tNZez659SdK4PL9HTxtnUYcUQp6P+5/TvBQjxb1KnZm uoykfHHiVTy/NMiSOXhcdScRPj8oX5w5nKsvm8Pa1mtyCkOaAgq44uKYg7tLLGLY2nZO3eXftca cYRJ03ax17LjdQK3JKgLXm0O6wZG1OyFsTfNYyLMm/sKTXXNTymFevZcLU5npYV8hole5/g6Rmu qkriHdAQWNi0ijA3MuvyGJWherx1iRu9nD4MBoyy9HUiUe5yc99cTb6f3r1v5lyZMvm2u5Hcv5o E4lng/VeJ3F/jFbopzAX0kcv39GpsNs9bKVW3t6lQG/aBBj8Hz9XnSftigxj8EVXt+Lp64M61TA Uvp78T+A5eqi5vt1WMGgtCdKqRiamJ7EdRat88mL8ZGVEHOkgsDKOobNebSsLDJP2Pp81sSm242 HSMB1FMpcMha/CQ== X-Developer-Key: i=bartosz.golaszewski@linaro.org; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 From: Gaurav Kashyap Use the wrapped keys capability when HWKM is supported. Whether to use HWKM or not would be decided during an ICE probe, and based on this information, UFS can decide to use wrapped or raw keys. Also, propagate the appropriate key size to the ICE driver when wrapped keys are used. Tested-by: Neil Armstrong Reviewed-by: Om Prakash Singh Signed-off-by: Gaurav Kashyap Signed-off-by: Bartosz Golaszewski --- drivers/ufs/host/ufs-qcom.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c index 44fb4a4c0f2d7..fd774531cbbf3 100644 --- a/drivers/ufs/host/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c @@ -129,6 +129,8 @@ static int ufs_qcom_ice_init(struct ufs_qcom_host *host) host->ice = ice; hba->caps |= UFSHCD_CAP_CRYPTO; + if (qcom_ice_hwkm_supported(host->ice)) + hba->caps |= UFSHCD_CAP_WRAPPED_CRYPTO_KEYS; return 0; } @@ -166,7 +168,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 (bkey->crypto_cfg.key_type == BLK_CRYPTO_KEY_TYPE_HW_WRAPPED) + ice_key_size = QCOM_ICE_CRYPTO_KEY_SIZE_WRAPPED; + else + 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, From patchwork Mon Dec 2 12:02:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 13890371 X-Patchwork-Delegate: snitzer@redhat.com Received: from mail-wm1-f44.google.com (mail-wm1-f44.google.com [209.85.128.44]) (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 47D7B20ADFD for ; Mon, 2 Dec 2024 12:03:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140994; cv=none; b=B8V6c51XY0njWNIiWWnoCApr0lfWzlePKO9Bp5Gu0KYi4NeC7v6F05c143IWtIhGCGejTzhGh34ltMjfUUpk64uex3uP+XvSeGYmcdeb1AWhyKDT3YoGFDTG0qiX/Kw1M4H3iVNUHnP14assueI9HBMxl5AXCaENq1h/jLGfdqA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140994; c=relaxed/simple; bh=gdr3l+RFSHrWyEruQBFmEvtHoeWmaRMEJf4HRZMyXWA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=IFeDF5Wewf0XzSCLWupkZkL5bEC91cARF0E+emnuBfL1R5kVAOjoLGAOeUy3QW1DnW/Qbdz5qq/M3uf8aosJMd3PiaJNY12gtBs0lEXuIIgM25p9QXu1DICpAvmcp4kfiNDtXspfcOkUXM2u6ZElDT7dPFASDpUShwh9h13h42Y= 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=axka+lLT; arc=none smtp.client-ip=209.85.128.44 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="axka+lLT" Received: by mail-wm1-f44.google.com with SMTP id 5b1f17b1804b1-434a45f05feso52446175e9.3 for ; Mon, 02 Dec 2024 04:03:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1733140989; x=1733745789; darn=lists.linux.dev; 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=b+PmcWdMJm7CbMMHOaGOj0ZiJf4zVkJvWt/4CpfiDHk=; b=axka+lLTyPA3LT/ZFo2l9Bqvu7I3T2youZ99DS7IIEb1jdrUhwATEcf2KR01VESp8M TuW8U0NkDi1mO851gQDp+LH2cIH0a0xQ3V8f9tXNyPXpJ3YEEhAQPmmlj6sI3w8hK5a6 cqj7/52c9qKITalypDgg7ks/Gzq+yNefJzlUFKQYlUnFyuvOLlCyihIZVVUPVznvXE6g TecojPziBAJEpWMzhC/MNcnIbq6pvFaa9TnOb6WO3MlHms8XnhHVRqWZ+nkF81fN4cRT QJYVRhVVG8bCalbHp2njpi57y96CRnycC9/nuSMLQNjNKZhqchSYO/uXF8k6YzFBlYL5 ORSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733140989; x=1733745789; 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=b+PmcWdMJm7CbMMHOaGOj0ZiJf4zVkJvWt/4CpfiDHk=; b=CI0VKpgj6dnTnm66wIjXXNX/eh36ea1et6YNtb/3aQUKku1ycLXS0z1U/HYHTXIXsX y8TvZf7vj9MFGPRFIZXQXBBPXOD74X3TEwOOCF+uAFe+n1E11I38FH7h89+kTCVmYZHC PDEHlBhlVa6ePNSN+BCeqG5AiburUv/rsW9LGBJRnFprDbtzDVwXdHoFaHIZPH9FPb0U eRGQ5Lo7Br82vzj7Bp19yp/6kgXLt0uYePntDQzrEfze7pQkyIV26++qVOB+9ss8PdWQ B53/7MMvmwRlQWzsMgMMhKw13xCFC19vkn40T6JR0dt27PUOtC1geI2+VQYWZlDmg5wm rcIg== X-Forwarded-Encrypted: i=1; AJvYcCVvio4STFU2XBCJEM2zbUdrTXZ/DbKiz3BGYfPgAF9e/mXBnaVtsTQoYxNw9fSLHkolT3DTSpySDA==@lists.linux.dev X-Gm-Message-State: AOJu0YwjG95A1TtAXusULs3dmbXARIDS6D0qYnmCHkKzx24/jZ/6EqyJ tajB9V3vgWsWtt6GJLtC0EiZZ15i4by4w9Px8cxBwy2qhDrfvKp7I7j+gMZpJ9s= X-Gm-Gg: ASbGncvhkUFPvFRXsGosUAwP6J41W/bfkoxQnmJMct18G0KfWCcArTa2qUEQxOpVv07 DEgyg5xiRtqj3x83T5GpC2Et+ucs7HJL2i50lziiuKiOwatNRv5ohmMm2oIkzS5QmMgBNF/XAxZ wOcEgi1ZUdenbIBh1NRPO31FnzzMMCPjmHojEnrPx7Q7/IQ9kzuENHZ5WK+0egaQA0n+sQf7J12 5IvWVLxPQ9/3br5O6OmsueNzT4KrlKcxcrel8UV X-Google-Smtp-Source: AGHT+IEe2U0hKMLkW/kvwI9IdOuJTARvAn++dsfGezCEbCgsSOocEJZ25SQAJNm8raH54gf64cUe+w== X-Received: by 2002:a05:600c:45cd:b0:431:6083:cd30 with SMTP id 5b1f17b1804b1-434a9dbb631mr238682775e9.6.1733140989459; Mon, 02 Dec 2024 04:03:09 -0800 (PST) Received: from [127.0.1.1] ([193.57.185.11]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-434b0d9bed7sm152396095e9.8.2024.12.02.04.03.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Dec 2024 04:03:09 -0800 (PST) From: Bartosz Golaszewski Date: Mon, 02 Dec 2024 13:02:32 +0100 Subject: [PATCH RESEND v7 16/17] ufs: host: add a callback for deriving software secrets and use it Precedence: bulk X-Mailing-List: dm-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241202-wrapped-keys-v7-16-67c3ca3f3282@linaro.org> References: <20241202-wrapped-keys-v7-0-67c3ca3f3282@linaro.org> In-Reply-To: <20241202-wrapped-keys-v7-0-67c3ca3f3282@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" , Gaurav Kashyap , Neil Armstrong , Dmitry Baryshkov , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam 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.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=2570; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=MdNk2H0tGYbBpgVzTRjqUx6qkSuTV/Qf3E5ZrGPzFBA=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnTaHWQd1yXC+tq8uQ59eAQtfHl/6mdb5ozK09+ cHD49JahjaJAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZ02h1gAKCRARpy6gFHHX cscOD/4uo18/YSJusBFEPhCAOQrXkTC5my/rO09DdLTqE1XGp8d5iJ4c6VBgl5c4j875tDft90Z LDoSqYOoSOkIXdQq2w+e+CPuuVWHB0sljyAE4Hd5qhEPsan4OX2pG8PxGOQJQvO1RtZLbbW8RMt DjKvBxiA+g1hSmn0OvDw3NE9s/QFHLejldEX7SZ9kj8PhPlX+TensgJVR54kv24sOuq6eLhJN3R KxYmUnBAp7YNxsO3e1FaWBqE48qiRGhH8EXRXPgDjMUx0SPMefYjyw0rLA2rOp7BztoBqnT9Njc DsB/bpdeQFAH+GyMeBQ712WeIP4uTR6sler/piAQ+hqKa4h8HH4QK45eL8IUdz4U9PwMZzKfNzC p+C8F+zSJsQJQ/h0Z6YW6cNhaqBbsKJBZ5KmFiSgDUTt5h0CKDv8geQrxc4xleoqgrEulbqyLs9 uH/1uBh+s86e5O4zxOiTp8EJUi/w7QHGy1Jx12c7Ua/cpw3HcuxV1J1vPndRA/+e4ew07AzVkBi mFeYHiSVYHHGT7YWuJK4PZCc9K9RJd/6QL37q+pT21CKuNGaqgaakybuaRo1IRReUDShiyqx9Sv td2iQmTzE5dNeT/nt5pMvJ6iX5JubFvUwokCEdED5zxLe9X2C/g79WCXNWZrh7/u6aYfu6OfQLJ ukpOFb4JFzQ/yPw== 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 Reviewed-by: Konrad Dybcio 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 fd774531cbbf3..0da2674777d2c 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) { @@ -1833,6 +1847,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 1b7c36e5347b2..dc8c055eae79a 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -325,6 +325,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 From patchwork Mon Dec 2 12:02:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 13890372 X-Patchwork-Delegate: snitzer@redhat.com Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.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 1B3D220B80A for ; Mon, 2 Dec 2024 12:03:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140996; cv=none; b=t/M9Bw4QlWRa2+LPISm74TayQhbIDxbKwtf9SteyQ/kOknZkY5hMEErJx2KWoNUaxTdakF0Izy8I4/6wF3OILXGUUqSUQz2xs3YqMIJ77RKrb1SlN1HLMba3OZGQXYx4qh/XPxkiEc8GfRfy6BvnoFEn/3DshtxJb6YpXu8h3U0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733140996; c=relaxed/simple; bh=SXqWmFdKruhDvAdboiSEhg1Z6NA3pG4WBm4XMylxPB0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Q2QEm3C5VBfRBTP03X2xYGT/meqY+ulbBUrPBT5DhyaOc208oTyy3dUMX6COB1/Kb6oqHnDMrWKjZeZnSaUDyE/UxhWlG72Qn0A5LlTisA4hKl4CkJI5A8++mNpwm8GZhQUYQDW1Px6cudi6AHDB4xN1SwfNxVr/n6n19Hu5dow= 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=I4fRSzRz; arc=none smtp.client-ip=209.85.128.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="I4fRSzRz" Received: by mail-wm1-f50.google.com with SMTP id 5b1f17b1804b1-434a9f2da82so35792075e9.2 for ; Mon, 02 Dec 2024 04:03:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1733140992; x=1733745792; darn=lists.linux.dev; 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=/OaNa1GU6C5pLmKUM+e3Rmrgncx6u+ty/51M3vyn6vY=; b=I4fRSzRzVPUoIPieMTc4gbkpP9NXLOBJM7S9myrfovIgbXBDSiwJFKRVdyKKh0xNQm zXivZMg+Qu4l3sB0VLNCGlXn4KHf8ipW1HwqBz+1gmUjFPr+UNntsBtZ67g+egLboRNT dw3441uBzcny+C4F5UQpJyqpI4UXHwJW7c0h2+zQeodrkb/CDY8lUAoGdBWBb0WQpzgP O/yKFXYhwzdxmbJLDJ/1FgQSDTZSy01baw01i4i0SOBK37voLZwkZyRA6B6+xGHOkR/h zVctth24otOCmGt6Aqw9g2r0hjT/CToh3/RRi0BHPMH02dtyecmH6eA6nH/Q4XOXo/WP XDsQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733140992; x=1733745792; 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=/OaNa1GU6C5pLmKUM+e3Rmrgncx6u+ty/51M3vyn6vY=; b=LPoQ4/TvIloKkRmsuMp1pYypsL51Oaw+dXdsbBrsHGPmVDDD/jVK6GqsS97EsTD9sx 7CUv3bL0xwV4HjL3aIbLXP3aMoTIOMNIaRoT3yr3oWir2JALKn470YerZjX/5w4fhni1 qKzYlSjezF2nkwQS+mQnckt2fJw5+pKRJA7tD+z3StZTtpiIiS5S+kLGLwmoQ+LLw2bz Xqdu+fs/mVZSeWNwi0s79eie5rLcLsjhkdjLdxAztlIixR0eOjXJpSS+RtNZA445bvEq CX1hGYdp+dRB5+T8B/Eq7wMe6kX7IPGScIK64SC8bRvOxj9WlxOHd2axuEfPdrhPF/Fq 9Hjw== X-Forwarded-Encrypted: i=1; AJvYcCV8TfGVkt/KPCyADGz8JKBGI1eV/lvZFoKE27/6zOcU5gwwCZLX/dYYYTpmAnjtiX3jd8pSs6ukIA==@lists.linux.dev X-Gm-Message-State: AOJu0YwVh5PMrTuoO5/s36BKKQSWHfa7KTPyLekl3DVEaIYv0ouinaE4 jYg1qNYj3kqDlqGlTpEHj1x1rraAjB3yYlFzoDxhT5mek9sz/w6aHmN+qQTKIsg= X-Gm-Gg: ASbGncs55VLkpTeXDSoAboHh/PmwxhIyYMNPjGIpKcs4TNGDnTFcJ5HosqUgIeCseCr FqUXWvYaFrH8lpYZPoFyRDgCS3m85RWFm0nuDMwqk79x7rPRaA1mtkEiYhFjy44VObZSlGME0FI WDNrI3fJZrc2ajxZlC7TYKI4nyr8Aw4XP4Hc/mwAOeGywpB7+0Se8Qdrpryups0QzV5aMPmdQmS /j1cGkiM7yoErIT5KxfcuaC1TtcHBPrUcmlt2DR X-Google-Smtp-Source: AGHT+IGWc47EwqH71rhHjv/KfoAe6eeXRpWu/7Snf36bMmrQREw14b0jX49/ol9dK3YY1FcYfUD0BA== X-Received: by 2002:a05:600c:3aca:b0:434:a7f1:6545 with SMTP id 5b1f17b1804b1-434a9dfbe52mr188320625e9.27.1733140992113; Mon, 02 Dec 2024 04:03:12 -0800 (PST) Received: from [127.0.1.1] ([193.57.185.11]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-434b0d9bed7sm152396095e9.8.2024.12.02.04.03.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Dec 2024 04:03:11 -0800 (PST) From: Bartosz Golaszewski Date: Mon, 02 Dec 2024 13:02:33 +0100 Subject: [PATCH RESEND v7 17/17] ufs: host: add support for generating, importing and preparing wrapped keys Precedence: bulk X-Mailing-List: dm-devel@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241202-wrapped-keys-v7-17-67c3ca3f3282@linaro.org> References: <20241202-wrapped-keys-v7-0-67c3ca3f3282@linaro.org> In-Reply-To: <20241202-wrapped-keys-v7-0-67c3ca3f3282@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" , Gaurav Kashyap , Neil Armstrong , Dmitry Baryshkov , "Martin K. Petersen" , Eric Biggers , "Theodore Y. Ts'o" , Jaegeuk Kim , Alexander Viro , Christian Brauner , Jan Kara , Bjorn Andersson , Konrad Dybcio , Manivannan Sadhasivam 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.14.1 X-Developer-Signature: v=1; a=openpgp-sha256; l=4284; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=3S2Zj/hLbrM4DjwdvlxVSy1kmPJ99K5Qvwb4G0BsQ0U=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBnTaHXzRXDCRoQFXnAuSVzn467NjNF+9zLmE0aj 0uunEU1gB2JAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCZ02h1wAKCRARpy6gFHHX cuOpD/47sYsAvMcTPt3gWFt5Ys+R87FxssehI6pHubn+78bsn3A96WfHX3VZdjGFkUwzq7viptr RlKwm+AjcRkZCIAp+ugg5N9+8vPcTORKyP9xbzi7EASkZpDo+IU4OlmiCU4v2zTgcGAcyyrfoZZ 5Mqwy0vmUjKyZIpos5R7Vo7shS5vI07xLGO+HJdM1HDJKzWrKAvLgFlfxMI3mifhdVSnObs7sIz PZ0CGeMWoJohiueJpkAyQXRZfbSFlm74sgWDPkoi6v9jF9xQfmm0fDXDP3mtTwiZ9rmwRUDILhm 80/0JruiNWEcI6DgtbnR9LCRn9NVRiEcj/CFI6fUpD/g0u1FlzFrOIsV+3vyMqwTigQfduAHnaf sKpjFNq+0F+G6zwx+qfv6+m6l0/FqibL/QD368m/6UWEOuA5QdztggCXz/CeAUKS8LnrO1qFpRm 3NMlOEksrfrnKJDsL5h7Brl5U9AHsY2VotvmZOOv7oBITkFrqej9++l0E1DEoLLnSev9qv0SQ53 JG5CKq3vK049drq4KYMkWXs/rp3EA3Sa2NOQHBpKztdYLU7AvN67AK6kkGthMVGHTmiamfx7I5V SZKIg7FYbj/sALZWC0cI58VEgRQI/d2RllME12D+mExb4lYIMiN+FEzToGsTZKmVFXGfyQzL+jF 9XB34b80/dF528w== X-Developer-Key: i=bartosz.golaszewski@linaro.org; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 From: Gaurav Kashyap Extend the UFS core ops to include callbacks for generating, importing and prepating HW wrapped keys using the lower-level block crypto operations and implement them for QCom UFS. Reviewed-by: Om Prakash Singh Tested-by: Neil Armstrong Signed-off-by: Gaurav Kashyap Reviewed-by: Konrad Dybcio Signed-off-by: Bartosz Golaszewski --- drivers/ufs/host/ufs-qcom.c | 34 ++++++++++++++++++++++++++++++++++ include/ufs/ufshcd.h | 11 +++++++++++ 2 files changed, 45 insertions(+) diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c index 0da2674777d2c..58a310e2571b2 100644 --- a/drivers/ufs/host/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c @@ -195,10 +195,41 @@ static int ufs_qcom_ice_derive_sw_secret(struct ufs_hba *hba, const u8 wkey[], return qcom_ice_derive_sw_secret(host->ice, wkey, wkey_size, sw_secret); } +static int ufs_qcom_ice_generate_key(struct ufs_hba *hba, + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]) +{ + struct ufs_qcom_host *host = ufshcd_get_variant(hba); + + return qcom_ice_generate_key(host->ice, lt_key); +} + +static int ufs_qcom_ice_prepare_key(struct ufs_hba *hba, + const u8 *lt_key, size_t lt_key_size, + u8 eph_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]) +{ + struct ufs_qcom_host *host = ufshcd_get_variant(hba); + + return qcom_ice_prepare_key(host->ice, lt_key, lt_key_size, + eph_key); +} + +static int ufs_qcom_ice_import_key(struct ufs_hba *hba, + const u8 *imp_key, size_t imp_key_size, + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]) +{ + struct ufs_qcom_host *host = ufshcd_get_variant(hba); + + return qcom_ice_import_key(host->ice, imp_key, imp_key_size, + lt_key); +} + #else #define ufs_qcom_ice_program_key NULL #define ufs_qcom_ice_derive_sw_secret NULL +#define ufs_qcom_ice_generate_key NULL +#define ufs_qcom_ice_prepare_key NULL +#define ufs_qcom_ice_import_key NULL static inline void ufs_qcom_ice_enable(struct ufs_qcom_host *host) { @@ -1848,6 +1879,9 @@ static const struct ufs_hba_variant_ops ufs_hba_qcom_vops = { .config_scaling_param = ufs_qcom_config_scaling_param, .program_key = ufs_qcom_ice_program_key, .derive_sw_secret = ufs_qcom_ice_derive_sw_secret, + .generate_key = ufs_qcom_ice_generate_key, + .prepare_key = ufs_qcom_ice_prepare_key, + .import_key = ufs_qcom_ice_import_key, .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 dc8c055eae79a..df51c0a96c675 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -326,6 +326,9 @@ struct ufs_pwr_mode_info { * @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 + * @generate_key: generate a storage key and return longterm wrapped key + * @prepare_key: unwrap longterm key and return ephemeral wrapped key + * @import_key: import sw storage key and return longterm 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 @@ -379,6 +382,14 @@ struct ufs_hba_variant_ops { int (*derive_sw_secret)(struct ufs_hba *hba, const u8 wkey[], unsigned int wkey_size, u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]); + int (*generate_key)(struct ufs_hba *hba, + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]); + int (*prepare_key)(struct ufs_hba *hba, + const u8 *lt_key, size_t lt_key_size, + u8 eph_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]); + int (*import_key)(struct ufs_hba *hba, + const u8 *imp_key, size_t imp_key_size, + u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]); int (*fill_crypto_prdt)(struct ufs_hba *hba, const struct bio_crypt_ctx *crypt_ctx, void *prdt, unsigned int num_segments);