mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Oleksij Rempel <o.rempel@pengutronix.de>
To: barebox@lists.infradead.org
Cc: Oleksij Rempel <o.rempel@pengutronix.de>
Subject: [PATCH v1 6/7] nvmem: bsec: Implement NVMEM protect via regmap_seal for OTP locking
Date: Fri, 30 May 2025 13:41:05 +0200	[thread overview]
Message-ID: <20250530114106.1009454-7-o.rempel@pengutronix.de> (raw)
In-Reply-To: <20250530114106.1009454-1-o.rempel@pengutronix.de>

Enable the NVMEM 'protect' cdev operation for the STM32 BSEC driver.
This allows One-Time Programmable (OTP) memory words managed by the
BSEC driver to be permanently write-locked using the standard NVMEM
protection mechanism.

This change implements the recently added `regmap_bus->reg_seal`
interface for the BSEC driver. A new function,
`stm32_bsec_do_reg_seal_otp`, calls the `BSEC_SMC_WRLOCK_OTP` Secure
Monitor Call to perform the hardware OTP word lock. This function is
triggered when `regmap_seal` is called with the
`REGMAP_SEAL_WRITE_PROTECT | REGMAP_SEAL_PERMANENT` flags, which the
NVMEM-regmap bridge uses for `prot=1` (protect) requests. The
`BSEC_SMC_WRLOCK_OTP` enum value is also added.

This explicit sealing via `regmap_seal` is currently implemented for
the SMC path.

Testing from Barebox CLI:

This functionality allows explicit locking of already programmed OTP
words.  The following example demonstrates programming an OTP word,
locking it, and then verifying the write protection.

Assume the BSEC NVMEM device is `/dev/bsec0` and its parameters are
accessed via `bsec0`.

1. Enable permanent OTP writes:
   bsec0.permanent_write_enable=1

2. Program an OTP word (e.g., byte offset 0x170 with value 0x12345678):
   mw -d /dev/bsec0 -l 0x170 0x12345678
   md -s /dev/bsec0 -l 0x170+4  # Expected: Shows 0x12345678

3. Lock this specific OTP word using the 'protect' command:
   # Protects 4 bytes (one 32-bit word) starting at byte offset 0x170
   protect /dev/bsec0 0x170+4
   # Check dmesg for BSEC driver logs confirming the lock via SMC.

4. Verify the write protection:
   mw -d /dev/bsec0 -l 0x170 0xAABBCCDD
   # This write should fail or have no effect on the hardware's fuses
   # value. The mw command itself might not report an error for OTPs if
   # the underlying hardware silently ignores writes to locked bits/words.

   md -s /dev/bsec0 -l 0x170+4
   # Expected: Should still show the original locked value (0x12345678),
   # confirming the write attempt was blocked or ineffective.

5. Verify unprotection is not possible:
   unprotect /dev/bsec0 0x170 4
   # This command should fail, returning an error (e.g., -EOPNOTSUPP or
   # -EPERM) from the driver, as BSEC OTP locks are permanent.

6. (Optional) Disable permanent OTP writes when done:
   bsec0.permanent_write_enable=0

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 drivers/nvmem/bsec.c        | 27 +++++++++++++++++++++++++++
 include/mach/stm32mp/bsec.h |  1 +
 2 files changed, 28 insertions(+)

diff --git a/drivers/nvmem/bsec.c b/drivers/nvmem/bsec.c
index 9ca98e6180f8..b67b55addfe0 100644
--- a/drivers/nvmem/bsec.c
+++ b/drivers/nvmem/bsec.c
@@ -74,9 +74,36 @@ static int stm32_bsec_reg_write(void *ctx, unsigned reg, unsigned val)
 		return bsec_smc(BSEC_SMC_WRITE_SHADOW, reg, val, NULL);
 }
 
+static int stm32_bsec_do_reg_seal_otp(void *ctx, unsigned int reg,
+				      unsigned int flags)
+{
+	struct bsec_priv *priv = ctx;
+	struct device *dev = &priv->dev;
+
+	if (!priv->permanent_write_enable) {
+		dev_warn(dev, "BSEC seal: permanent_write_enable is OFF.\n");
+		return -EACCES;
+	}
+
+	/* Only REGMAP_SEAL_WRITE_PROTECT and REGMAP_SEAL_PERMANENT
+	 * flags are supported for BSEC OTP sealing.
+	 */
+	if ((flags & (REGMAP_SEAL_WRITE_PROTECT | REGMAP_SEAL_PERMANENT)) !=
+	    (REGMAP_SEAL_WRITE_PROTECT | REGMAP_SEAL_PERMANENT)) {
+		dev_warn(dev, "BSEC seal: unsupported flags 0x%x.\n", flags);
+		return -EINVAL;
+	}
+
+	dev_dbg(dev, "BSEC seal: Locking OTP word at byte offset 0x%x via SMC.\n",
+		reg);
+
+	return bsec_smc(BSEC_SMC_WRLOCK_OTP, reg, 0, NULL);
+}
+
 static struct regmap_bus stm32_bsec_regmap_bus = {
 	.reg_write = stm32_bsec_reg_write,
 	.reg_read = stm32_bsec_read_shadow,
+	.reg_seal = stm32_bsec_do_reg_seal_otp,
 };
 
 static void stm32_bsec_set_unique_machine_id(struct regmap *map)
diff --git a/include/mach/stm32mp/bsec.h b/include/mach/stm32mp/bsec.h
index 45eb0a3f4523..be8cec536a40 100644
--- a/include/mach/stm32mp/bsec.h
+++ b/include/mach/stm32mp/bsec.h
@@ -26,6 +26,7 @@ enum bsec_op {
 	BSEC_SMC_READ_OTP	= 4,
 	BSEC_SMC_READ_ALL	= 5,
 	BSEC_SMC_WRITE_ALL	= 6,
+	BSEC_SMC_WRLOCK_OTP	= 7,
 };
 
 static inline enum bsec_smc bsec_read_field(unsigned field, unsigned *val)
-- 
2.39.5




  parent reply	other threads:[~2025-05-30 11:44 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-30 11:40 [PATCH v1 0/7] NVMEM: Introduce write protection support Oleksij Rempel
2025-05-30 11:41 ` [PATCH v1 1/7] nvmem: Add 'protect' operation to core framework Oleksij Rempel
2025-06-02  9:04   ` Sascha Hauer
2025-05-30 11:41 ` [PATCH v1 2/7] nvmem: rmem: add write and protect support Oleksij Rempel
2025-06-02  9:33   ` Sascha Hauer
2025-05-30 11:41 ` [PATCH v1 3/7] commands: nvmem: Add support for creating dynamic rmem devices Oleksij Rempel
2025-06-02  9:41   ` Sascha Hauer
2025-05-30 11:41 ` [PATCH v1 4/7] regmap: Add reg_seal operation for hardware protection Oleksij Rempel
2025-06-02  9:47   ` Sascha Hauer
2025-05-30 11:41 ` [PATCH v1 5/7] nvmem: regmap: Implement protect operation using regmap_seal Oleksij Rempel
2025-06-02  9:57   ` Sascha Hauer
2025-05-30 11:41 ` Oleksij Rempel [this message]
2025-05-30 11:41 ` [PATCH v1 7/7] nvmem: rmem: Use unique device name for NVMEM registration Oleksij Rempel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250530114106.1009454-7-o.rempel@pengutronix.de \
    --to=o.rempel@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox