* [PATCH v4 0/2] ufs: rpmb: make RPMB usable with OP-TEE key derivation
@ 2026-08-27 7:03 Jorge Ramirez-Ortiz
2026-08-27 7:03 ` [PATCH v4 1/2] ufs: rpmb: retry power-on UNIT ATTENTION on the RPMB WLUN Jorge Ramirez-Ortiz
2026-08-27 7:03 ` [PATCH v4 2/2] ufs: rpmb: use a fixed-length RPMB dev_id Jorge Ramirez-Ortiz
0 siblings, 2 replies; 4+ messages in thread
From: Jorge Ramirez-Ortiz @ 2026-08-27 7:03 UTC (permalink / raw)
To: jorge.ramirez, beanhuo, James.Bottomley, martin.petersen,
alim.akhtar, avri.altman, bvanassche, beanhuo, can.guo,
sumit.garg, jenswi
Cc: linux-scsi, linux-kernel, op-tee
This series makes UFS RPMB work out of the box with an OP-TEE that
implements the standard eMMC RPMB key-derivation flow, without requiring
any fundamental changes on the OP-TEE side.
RPMB provides an authenticated, replay-protected storage area whose
security relies on a secret authentication key. In our setup that key is
never exposed to the kernel: OP-TEE derives it in the secure world from
its hardware-unique key and a device identifier (dev_id) that the RPMB
core hands down. OP-TEE's implementation targets eMMC, where dev_id is
the 16-byte eMMC CID, and both the fixed length and the raw-CID layout
are baked into its key derivation.
Two things stand in the way of reusing that same, unmodified OP-TEE flow
for UFS RPMB:
1. On a cold boot the very first frame sent to the RPMB well-known LU
comes back with a power-on UNIT ATTENTION (ASC 0x29), which the SCSI
core reports rather than retries. RPMB has no earlier guaranteed
access that could clear the condition first, so RPMB fails on every
power cycle. Patch 1 asks the SCSI core to retry the power-on UNIT
ATTENTION on the RPMB WLUN.
2. The UFS RPMB id is "<device_id>-R<region>", which is variable length
and longer than 16 bytes. Passing it verbatim would tie the derived
key to a length OP-TEE does not expect and diverge from the fixed
eMMC CID ABI. Patch 2 hashes it into a fixed 16-byte dev_id with
blake2b, keeping the key stable and unique per region while matching
the eMMC CID layout OP-TEE relies on. The hash algorithm and input
string are thus part of the key-derivation ABI and must stay stable.
With both patches, UFS RPMB is functional from the first access after a
cold boot and derives keys through the existing eMMC-style OP-TEE flow,
(requires minimal OP-TEE changes pending on the CID proposal done here).
Tested on IQ-9075 with Open Firmware [1], pending OP-TEE changes
[1]https://ldts.github.io/qcom-buildroot
Dependencies:
U-boot:
https://lore.kernel.org/u-boot/20260720085202.537019-1-jorge.ramirez@oss.qualcomm.com/T/#mc423eb4dcf8a15849077029e4f7c1913bb7d8873
OP-TEE:
https://github.com/OP-TEE/optee_os/pull/7881
v4:
* ufs: rpmb: retry power-on UNIT ATTENTION on the RPMB WLUN: open-code
the power-on ASC 0x29 (with a naming comment) as the rest of the SCSI
tree does, instead of a UFS_RPMB_ASC_POWER_ON define; add a
UFS_RPMB_UA_RETRIES define for the retry count; reworded the commit
message.
* ufs: rpmb: use a fixed-length RPMB dev_id: reworded the commit
message; no functional change.
v3:
* ufs: rpmb: use a fixed-length RPMB dev_id: hash into a stack buffer
instead of a kzalloc'd one; rpmb_dev_register() copies dev_id, so the
heap allocation and its cleanup were unnecessary.
v2:
* ufs: rpmb: replace blake2s with blake2b so that the same support
can be added to u-boot (CRYPTO_LIB_BLAKE2B)
* added links to U-boot and OP-TEE changes.
v1:
* ufs: rpmb: retry power-on UNIT ATTENTION on the RPMB WLUN:
- fix using uses SCMD_FAILURE_ASC_ANY to retry any Unit Attention
- fix unused variable
* ufs: rpmb: use a fixed-length RPMB dev_id
- fix selecting a non-existent Kconfig symbol
Jorge Ramirez-Ortiz (2):
ufs: rpmb: retry power-on UNIT ATTENTION on the RPMB WLUN
ufs: rpmb: use a fixed-length RPMB dev_id
drivers/ufs/Kconfig | 1 +
drivers/ufs/core/ufs-rpmb.c | 29 ++++++++++++++++++++++++++---
2 files changed, 27 insertions(+), 3 deletions(-)
--
2.54.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v4 1/2] ufs: rpmb: retry power-on UNIT ATTENTION on the RPMB WLUN
2026-08-27 7:03 [PATCH v4 0/2] ufs: rpmb: make RPMB usable with OP-TEE key derivation Jorge Ramirez-Ortiz
@ 2026-08-27 7:03 ` Jorge Ramirez-Ortiz
2026-08-27 7:03 ` [PATCH v4 2/2] ufs: rpmb: use a fixed-length RPMB dev_id Jorge Ramirez-Ortiz
1 sibling, 0 replies; 4+ messages in thread
From: Jorge Ramirez-Ortiz @ 2026-08-27 7:03 UTC (permalink / raw)
To: jorge.ramirez, beanhuo, James.Bottomley, martin.petersen,
alim.akhtar, avri.altman, bvanassche, beanhuo, can.guo,
sumit.garg, jenswi
Cc: linux-scsi, linux-kernel, op-tee
After a power cycle, the first command sent to any UFS logical unit
completes with CHECK CONDITION reporting a power-on UNIT ATTENTION.
The SCSI core surfaces this condition to the caller rather than
retrying it.
For the RPMB well-known LU the first command after boot is the first
RPMB frame, and RPMB has no earlier, guaranteed access that could clear
the condition beforehand. The power-on UNIT ATTENTION therefore reaches
RPMB and fails that first frame, breaking RPMB on every cold boot.
The RPMB WLUN needs the power-on UNIT ATTENTION to be retried so that
RPMB works from the very first access after a power cycle.
Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez@oss.qualcomm.com>
---
drivers/ufs/core/ufs-rpmb.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/ufs/core/ufs-rpmb.c b/drivers/ufs/core/ufs-rpmb.c
index ffad049872b9..79e6cd2b20a0 100644
--- a/drivers/ufs/core/ufs-rpmb.c
+++ b/drivers/ufs/core/ufs-rpmb.c
@@ -21,6 +21,7 @@
#include <linux/unaligned.h>
#include "ufshcd-priv.h"
+#define UFS_RPMB_UA_RETRIES 3 /* Retries for the power-on UNIT ATTENTION */
#define UFS_RPMB_SEC_PROTOCOL 0xEC /* JEDEC UFS application */
#define UFS_RPMB_SEC_PROTOCOL_ID 0x01 /* JEDEC UFS RPMB protocol ID, CDB byte3 */
@@ -40,6 +41,22 @@ struct ufs_rpmb_dev {
static int ufs_sec_submit(struct ufs_hba *hba, u16 spsp, void *buffer, size_t len, bool send)
{
struct scsi_device *sdev = hba->ufs_rpmb_wlun;
+ struct scsi_failure failure_defs[] = {
+ {
+ .sense = UNIT_ATTENTION,
+ .asc = 0x29, /* power on, reset, or bus device reset occurred */
+ .ascq = SCMD_FAILURE_ASCQ_ANY,
+ .allowed = UFS_RPMB_UA_RETRIES,
+ .result = SAM_STAT_CHECK_CONDITION,
+ },
+ {}
+ };
+ struct scsi_failures failures = {
+ .failure_definitions = failure_defs,
+ };
+ const struct scsi_exec_args exec_args = {
+ .failures = &failures,
+ };
u8 cdb[12] = { };
cdb[0] = send ? SECURITY_PROTOCOL_OUT : SECURITY_PROTOCOL_IN;
@@ -48,7 +65,8 @@ static int ufs_sec_submit(struct ufs_hba *hba, u16 spsp, void *buffer, size_t le
put_unaligned_be32(len, &cdb[6]);
return scsi_execute_cmd(sdev, cdb, send ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN,
- buffer, len, /*timeout=*/30 * HZ, 0, NULL);
+ buffer, len, /*timeout=*/30 * HZ, /*retries=*/0,
+ &exec_args);
}
/* UFS RPMB route frames implementation */
--
2.54.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v4 2/2] ufs: rpmb: use a fixed-length RPMB dev_id
2026-08-27 7:03 [PATCH v4 0/2] ufs: rpmb: make RPMB usable with OP-TEE key derivation Jorge Ramirez-Ortiz
2026-08-27 7:03 ` [PATCH v4 1/2] ufs: rpmb: retry power-on UNIT ATTENTION on the RPMB WLUN Jorge Ramirez-Ortiz
@ 2026-08-27 7:03 ` Jorge Ramirez-Ortiz
2026-08-27 7:17 ` sashiko-bot
1 sibling, 1 reply; 4+ messages in thread
From: Jorge Ramirez-Ortiz @ 2026-08-27 7:03 UTC (permalink / raw)
To: jorge.ramirez, beanhuo, James.Bottomley, martin.petersen,
alim.akhtar, avri.altman, bvanassche, beanhuo, can.guo,
sumit.garg, jenswi
Cc: linux-scsi, linux-kernel, op-tee
The RPMB authentication key is derived from the dev_id handed to the
RPMB subsystem. OP-TEE implements the eMMC RPMB flow, where the dev_id
is the eMMC CID: a fixed 16-byte value the key derivation depends on.
The UFS RPMB id is "<device_id>-R<region>", which is variable length
and longer than 16 bytes. Handing it to the RPMB subsystem as-is would
tie the derived key to a length OP-TEE does not expect and diverge from
the fixed-CID eMMC ABI, forcing OP-TEE to be taught about
variable-length UFS ids.
A fixed 16-byte dev_id is needed so the derived key stays stable and
unique per region while matching the eMMC CID layout OP-TEE relies on,
keeping the key-derivation ABI identical with no OP-TEE change. The
reduction to a fixed 16 bytes must also be reproducible by the
bootloaders (such as U-Boot) that derive the same dev_id.
Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez@oss.qualcomm.com>
---
drivers/ufs/Kconfig | 1 +
drivers/ufs/core/ufs-rpmb.c | 9 +++++++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/ufs/Kconfig b/drivers/ufs/Kconfig
index f662e7ce71f1..b62c00e7ff06 100644
--- a/drivers/ufs/Kconfig
+++ b/drivers/ufs/Kconfig
@@ -7,6 +7,7 @@ menuconfig SCSI_UFSHCD
tristate "Universal Flash Storage Controller"
depends on SCSI && SCSI_DMA
depends on RPMB || !RPMB
+ select CRYPTO_LIB_BLAKE2B if RPMB
select PM_DEVFREQ
select DEVFREQ_GOV_SIMPLE_ONDEMAND
select NLS
diff --git a/drivers/ufs/core/ufs-rpmb.c b/drivers/ufs/core/ufs-rpmb.c
index 79e6cd2b20a0..cb3ac23fa01a 100644
--- a/drivers/ufs/core/ufs-rpmb.c
+++ b/drivers/ufs/core/ufs-rpmb.c
@@ -10,6 +10,7 @@
* Can Guo <can.guo@oss.qualcomm.com>
*/
+#include <crypto/blake2b.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/kernel.h>
@@ -21,6 +22,7 @@
#include <linux/unaligned.h>
#include "ufshcd-priv.h"
+#define UFS_RPMB_ID_LEN 16 /* Match eMMC CID Length */
#define UFS_RPMB_UA_RETRIES 3 /* Retries for the power-on UNIT ATTENTION */
#define UFS_RPMB_SEC_PROTOCOL 0xEC /* JEDEC UFS application */
#define UFS_RPMB_SEC_PROTOCOL_ID 0x01 /* JEDEC UFS RPMB protocol ID, CDB byte3 */
@@ -153,6 +155,7 @@ static void ufs_rpmb_device_release(struct device *dev)
int ufs_rpmb_probe(struct ufs_hba *hba)
{
struct ufs_rpmb_dev *ufs_rpmb, *it, *tmp;
+ u8 dev_id[UFS_RPMB_ID_LEN];
struct rpmb_dev *rdev;
char *cid = NULL;
int region;
@@ -213,8 +216,10 @@ int ufs_rpmb_probe(struct ufs_hba *hba)
goto err_out;
}
- descr.dev_id = cid;
- descr.dev_id_len = strlen(cid);
+ blake2b(NULL, 0, cid, strlen(cid), dev_id, UFS_RPMB_ID_LEN);
+
+ descr.dev_id = dev_id;
+ descr.dev_id_len = UFS_RPMB_ID_LEN;
descr.capacity = cap;
/* Register RPMB device */
--
2.54.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v4 2/2] ufs: rpmb: use a fixed-length RPMB dev_id
2026-08-27 7:03 ` [PATCH v4 2/2] ufs: rpmb: use a fixed-length RPMB dev_id Jorge Ramirez-Ortiz
@ 2026-08-27 7:17 ` sashiko-bot
0 siblings, 0 replies; 4+ messages in thread
From: sashiko-bot @ 2026-08-27 7:17 UTC (permalink / raw)
To: Jorge Ramirez-Ortiz; +Cc: linux-scsi
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
Pre-existing issues:
- [High] The bus type `ufs_rpmb_bus_type` is never registered, causing device_register() to unconditionally fail.
- [High] Using devm_kzalloc for a structure embedding a struct device violates driver model lifetime rules, leading to a Use-After-Free on unbind and memory leaks on error paths.
- [High] Parent-child reference counting deadlock in device removal paths prevents unregistration and causes a permanent memory and device leak.
--
commit ecc19262c86a06d5ad583f54476cad317a179650
Author: Jorge Ramirez-Ortiz <jorge.ramirez@oss.qualcomm.com>
ufs: rpmb: use a fixed-length RPMB dev_id
The RPMB authentication key is derived from the dev_id handed to the RPMB
subsystem. A fixed 16-byte dev_id is needed so the derived key stays stable
and unique per region while matching the eMMC CID layout.
> diff --git a/drivers/ufs/core/ufs-rpmb.c b/drivers/ufs/core/ufs-rpmb.c
> index 00ba4f3b842bf..783ecfc7581d7 100644
> --- a/drivers/ufs/core/ufs-rpmb.c
> +++ b/drivers/ufs/core/ufs-rpmb.c
[ ... ]
> @@ -215,8 +218,10 @@ int ufs_rpmb_probe(struct ufs_hba *hba)
> goto err_out;
> }
>
> - descr.dev_id = cid;
> - descr.dev_id_len = strlen(cid);
> + blake2b(NULL, 0, cid, strlen(cid), dev_id, UFS_RPMB_ID_LEN);
> +
> + descr.dev_id = dev_id;
> + descr.dev_id_len = UFS_RPMB_ID_LEN;
> descr.capacity = cap;
>
> /* Register RPMB device */
[Severity: High]
This isn't a bug introduced by this patch, but looking at how the bus is
assigned slightly earlier in ufs_rpmb_probe():
ufs_rpmb->dev.bus = &ufs_rpmb_bus_type;
Is ufs_rpmb_bus_type ever registered with bus_register()? If it is never
registered, won't device_register() unconditionally fail with -EINVAL because
it cannot find the subsystem for the unregistered bus, breaking the UFS RPMB
registration on every boot?
[Severity: High]
This is a pre-existing issue, but I noticed that ufs_rpmb_probe() allocates
the ufs_rpmb structure using devm_kzalloc() slightly earlier in the same
function:
ufs_rpmb = devm_kzalloc(hba->dev, sizeof(*ufs_rpmb), GFP_KERNEL);
Since this structure embeds a struct device (ufs_rpmb->dev) which gets
registered with device_register(), could this lead to a use-after-free on
unbind?
If a user unbinds the hba->dev driver while holding a sysfs reference to
ufs_rpmb->dev, devres will immediately free the memory. When the user later
drops the final reference, wouldn't the kernel access the freed memory when
calling ufs_rpmb_device_release()?
[Severity: High]
This is a pre-existing issue, but is there an unresolvable cyclic dependency
during device removal? Looking at how the child device is unregistered inside
the parent's release callback:
drivers/ufs/core/ufs-rpmb.c:ufs_rpmb_device_release() {
struct ufs_rpmb_dev *ufs_rpmb = dev_get_drvdata(dev);
rpmb_dev_unregister(ufs_rpmb->rdev);
}
When device_unregister(&ufs_rpmb->dev) is called during a probe error path or
removal, the child device (rdev) is not unregistered first. Since the child
still holds a reference to the parent, the parent's refcount never reaches 0.
Wouldn't this prevent ufs_rpmb_device_release() from ever executing, causing
both devices to be permanently leaked?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260827070345.2853821-1-jorge.ramirez@oss.qualcomm.com?part=2
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-08-27 7:17 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-27 7:03 [PATCH v4 0/2] ufs: rpmb: make RPMB usable with OP-TEE key derivation Jorge Ramirez-Ortiz
2026-08-27 7:03 ` [PATCH v4 1/2] ufs: rpmb: retry power-on UNIT ATTENTION on the RPMB WLUN Jorge Ramirez-Ortiz
2026-08-27 7:03 ` [PATCH v4 2/2] ufs: rpmb: use a fixed-length RPMB dev_id Jorge Ramirez-Ortiz
2026-08-27 7:17 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox