Skip to contentSkip to conversation

Add Altera SoCFPGA Crypto Service (FCS) driver

PATCH Superseded [email protected] 2 participants 5 messages Sep 15 – Sep 23

Subsystems (2)

v5 of 9 Superseded Latest is v9 →

lore
Share & tools
lore
#0 lore raw

v5 cover Add Altera SoCFPGA Crypto Service (FCS) driver

From: Hang Suan Wang <[email protected]>

This series adds Linux support for one of the Altera SoCFPGA Crypto Service (FCS): Secure Data Object Service (SDOS). FCS is a runtime cryptographic interface provided by the Secure Device Manager (SDM).

The SDM is the hardware security controller in Altera SoCFPGA devices. Host software reaches it through the existing stratix10-svc mailbox, which uses Arm Trusted Firmware SIP SMC calls. In this series does not expose the rest of FCS (RNG, AES, SHA, key management, and so on).

SDOS protects data at rest. The SDM encrypts and decrypts using a key derived from a device-unique SDOS root key that never leaves the secure boundary. The host supplies plaintext (or an authenticated object) and never handles raw key material. A primary use case is black-key provisioning.

SDOS requests use the stratix10-svc asynchronous SIP SMC path. Source and destination buffers are allocated from the service-layer memory pool, and their physical addresses are passed to the SDM. Each request opens an SDM crypto session, runs under a lock (one in-flight transaction), and closes the session afterwards.

The series is organized as follows:
- Patch 1 (prerequisite) enlarges the stratix10-svc SMC argument array so the asynchronous FCS SDOS command can pass its full set of parameters.

- Patch 2 (prerequisite) extends the stratix10-svc service layer with the FCS command codes and matching SIP SMC function IDs, adds the Agilex 5 (intel,agilex5-svc) match, and registers a "stratix10-fcs" platform device that an FCS client driver binds to.

- Patch 3 adds the FCS driver implementing SDOS encrypt/decrypt. It is exposed as a misc device (/dev/socfpga-fcs) via ioctl FCS_IOC_SDOS. The crypto session is opened and closed in the kernel and is not part of the user ABI.

Testing:
- Built for arm64 (defconfig + CONFIG_ALTERA_SOCFPGA_FCS=m).
- Tested on an Agilex 5 SoC FPGA board (SDOS root key provisioned). SDOS encrypt/decrypt round-trip; the decrypted output matches the original 32-byte plaintext:

   root@agilex5e:~# hexdump -v -e '/1 "%02x "' secret.bin
   61 37 36 61 64 62 66 63 32 31 32 65 63 64 30 35
   35 35 33 66 38 34 62 33 34 63 65 39 36 65 63 35
   65 62 64 31 31 31 32 37 30 38 39 37 64 35 32 64
   64 66 39 35 65 63 34 66 61 38 30 38 64 63 32 35
   root@agilex5e:~# ./fcs_client -E -i secret.bin -o enc.bin -d 0x1234 -r
                    0xabcd
   root@agilex5e:~# ./fcs_client -D -i enc.bin -o sdos_decrypt.bin
   root@agilex5e:~# hexdump -v -e '/1 "%02x "' sdos_decrypt.bin
   61 37 36 61 64 62 66 63 32 31 32 65 63 64 30 35
   35 35 33 66 38 34 62 33 34 63 65 39 36 65 63 35
   65 62 64 31 31 31 32 37 30 38 39 37 64 35 32 64
   64 66 39 35 65 63 34 66 61 38 30 38 64 63 32 35

---
Changes since v4:
- Read ATF version words with lower_32_bits() so a 32-bit value in an arm_smccc unsigned long is correct on 64-bit big-endian.
- Keep the SDOS payload size when SDM returns 0x102/0x103 (decrypt OK, outdated key). Those are success-with-warning; still return the plaintext.
- Release the svc channel in driver remove, not on last close, so unbind cannot free parent channel memory while an fd is still open.
- Guard fcs_alloc_buf()/fcs_free_buf() with the lock and a NULL channel check so they do not use the channel after unbind.
- Always call stratix10_svc_done() after the ATF version query, including send failure, so the sync svc kthread is stopped safely.

Changes since v3:
- Rebase onto current linux-upstream; register stratix10-fcs beside the existing socfpga-hwmon child device.
- Drop context_id from the ioctl UAPI; the kernel owns session and context
- Make FCS state per-device and kref-counted so an open fd can outlive driver remove (-ENODEV after unbind).
- Copy user buffers in the front-end; the core uses kernel pointers only.
- Use kzalloc_obj() and shorten comments.

Changes since v2:
socfpga-fcs (front-end):
- Replace the sysfs store interface with an ioctl character device (/dev/socfpga_fcs) using a fixed-width UAPI struct and compat_ptr_ioctl(), fixing the KASAN out-of-bounds read and the 32-bit incompatibility of casting the sysfs buffer as a pointer.
- Add include/uapi/misc/socfpga-fcs-crypto.h and register the ioctl magic in Documentation/userspace-api/ioctl/ioctl-number.rst.
- Add a .release handler so a session is torn down if the owning fd is closed (including on crash).
socfpga-fcs (core):
- Manage the crypto session internally: SDOS opens and closes its own session; reject a concurrent open with -EBUSY. Removes the user-visible open/close-session interface and session UUID, fixing the session-exhaustion/DoS concern.
- Harden the async poll loop: keep polling until the deadline and always call stratix10_svc_async_done(), fixing the teardown use-after-free from the previous -EINPROGRESS early-return and the needless full-timeout block.
- Clear receive_cb only on the synchronous send-error path so a late firmware response cannot deref a NULL callback.
- Set priv = NULL on all fcs_init() error paths so a later probe is not permanently rejected with -EBUSY.
- Read the SDOS owner ID with get_unaligned_le64() for correct little-endian handling on big-endian hosts.
stratix10-svc:
- Enlarge the SMC arguments array so the async SDOS command can pass its full parameter set (through a11).
- In remove(), unregister the child devices before stratix10_svc_async_exit() so async_poll() cannot race a freed handle.

Changes since v1:
stratix10-svc:
- Forward result registers (kaddr1) for OPEN_SESSION and SDOS_DATA_EXT so session ID / output length reach the client.
socfpga-fcs (front-end):
- Publish sysfs via driver.dev_groups on the platform device instead of a raw kobject under /sys/kernel; callbacks now get a struct device.
socfpga-fcs (core):
- Convert completion timeouts with msecs_to_jiffies(); drop TIMEOUT.
- On SDM-busy timeout (-EAGAIN), abort without async_done() (no id reuse) and return -EINPROGRESS.
- SDOS: on in-flight abort, leak s_buf/d_buf instead of freeing to avoid corruption from late firmware DMA.
- Validate the caller UUID early in fcs_sdos_crypt().
- Enforce single instance: -EBUSY in fcs_init() and priv NULL-guard in fcs_acquire_cmd_ctx().
- Drop the always-zero platform attribute and fcs_get_platform().
- Set/clear receive_cb only around the synchronous send.
- Use device-lifetime priv->completion for the async path (was on-stack).
- Use the local ctx snapshot consistently in fcs_sdos_crypt() and fcs_session_close().
- Point sdos.dst_size at priv->sdos_output_size, not a stack variable.
socfpga-fcs.h:
- Drop platform/AGILEX5_PLAT; add sdos_output_size.
---

Hang Suan Wang (3):
firmware: stratix10-svc: increase args array
firmware: stratix10-svc: add FCS crypto-service commands for Agilex 5
firmware: socfpga-fcs: add Altera SoCFPGA FCS driver with SDOS

 .../userspace-api/ioctl/ioctl-number.rst      |   1 +
 MAINTAINERS                                   |   9 +
 drivers/firmware/Kconfig                      |  17 +
 drivers/firmware/Makefile                     |   2 +
 drivers/firmware/socfpga-fcs-core.c           | 715 ++++++++++++++++++
 drivers/firmware/socfpga-fcs.c                | 294 +++++++
 drivers/firmware/stratix10-svc.c              |  65 +-
 include/linux/firmware/intel/socfpga-fcs.h    | 130 ++++
 include/linux/firmware/intel/stratix10-smc.h  |  64 ++
 .../firmware/intel/stratix10-svc-client.h     |  18 +-
 include/uapi/misc/socfpga-fcs-crypto.h        |  28 +
 11 files changed, 1335 insertions(+), 8 deletions(-)
 create mode 100644 drivers/firmware/socfpga-fcs-core.c
 create mode 100644 drivers/firmware/socfpga-fcs.c
 create mode 100644 include/linux/firmware/intel/socfpga-fcs.h
 create mode 100644 include/uapi/misc/socfpga-fcs-crypto.h
Signature · 1 line
2.43.7
#1 lore raw

PATCH v5 1/3 firmware: stratix10-svc: increase args array

From: Hang Suan Wang <[email protected]>

Increase args array from 3 to 6, for the SDOS encryption to call smc call which is used for args to be passed via registers and not physically mapped buffer.

---
 drivers/firmware/stratix10-svc.c                    | 6 ++++--
 include/linux/firmware/intel/stratix10-svc-client.h | 2 +-
 2 files changed, 5 insertions(+), 3 deletions(-)
drivers/firmware/stratix10-svc.c +4 -2
index f8c2da207cb4..07345efeef0c 100644
@@ -173,7 +173,7 @@ struct stratix10_svc_data {
 	size_t size_output;
 	u32 command;
 	u32 flag;
-	u64 arg[3];
+	u64 arg[6];
 };
 
 /**
@@ -1888,7 +1888,9 @@ int stratix10_svc_send(struct stratix10_svc_chan *chan, void *msg)
 	p_data->arg[0] = p_msg->arg[0];
 	p_data->arg[1] = p_msg->arg[1];
 	p_data->arg[2] = p_msg->arg[2];
-	p_data->size = p_msg->payload_length;
+	p_data->arg[3] = p_msg->arg[3];
+	p_data->arg[4] = p_msg->arg[4];
+	p_data->arg[5] = p_msg->arg[5];
 	p_data->chan = chan;
 	pr_debug("%s: %s: put to FIFO pa=0x%016x, cmd=%x, size=%u\n",
 		 __func__,
include/linux/firmware/intel/stratix10-svc-client.h +1 -1
index af13dacdf5ac..9bb46c3cb0f8 100644
@@ -215,7 +215,7 @@ struct stratix10_svc_client_msg {
 	void *payload_output;
 	size_t payload_length_output;
 	enum stratix10_svc_command_code command;
-	u64 arg[3];
+	u64 arg[6];
 };
 
 /**
Signature · 1 line
2.43.7
#2 lore raw

PATCH v5 2/3 firmware: stratix10-svc: add FCS crypto-service commands for Agilex 5

In reply to [email protected]

From: Hang Suan Wang <[email protected]>

The Agilex 5 Secure Device Manager (SDM 1.5) exposes an FPGA Crypto Service (FCS) over the existing SIP SMC mailbox: a session-based interface for crypto primitives such as SDOS (Secure Data Object Service) encrypt/decrypt. The service layer has no command to drive it yet.

Configure stratix10-svc about this interface so an in-kernel FCS client can use it:

- add the client command codes COMMAND_FCS_CRYPTO_OPEN_SESSION, COMMAND_FCS_CRYPTO_CLOSE_SESSION and COMMAND_FCS_SDOS_DATA_EXT (all asynchronous)

- add the matching asynchronous SIP SMC function IDs (INTEL_SIP_SMC_ASYNC_FCS_OPEN_CS_SESSION, INTEL_SIP_SMC_ASYNC_FCS_CLOSE_CS_SESSION and INTEL_SIP_SMC_ASYNC_FCS_CRYPTION_EXT) with their register-usage documentation;

- match "intel,agilex5-svc" and register a "stratix10-fcs" child platform device, mirroring the existing RSU child, so an FCS client driver can bind without a dedicated device-tree node;

- dispatch the new commands in the asynchronous send and response paths; for the SDOS data command, translate the source and destination buffers (allocated from the service-layer gen_pool) to physical addresses and pass them, together with the session/context IDs and owner ID, to the SDM.

The transport is unchanged: Agilex 5 reuses the SIP SMC calling convention and async mailbox ABI the driver already implements, so no new transport mechanism is required.

The SDOS SMMU-remapped address slots currently carry the buffer physical addresses; SMMU remapping support is added in a follow-up series.

This is a prerequisite for the SoCFPGA FCS driver, the first in-tree consumer of these commands.

---
 drivers/firmware/stratix10-svc.c              | 59 +++++++++++++++--
 include/linux/firmware/intel/stratix10-smc.h  | 64 +++++++++++++++++++
 .../firmware/intel/stratix10-svc-client.h     | 16 +++++
 3 files changed, 134 insertions(+), 5 deletions(-)
drivers/firmware/stratix10-svc.c +54 -5
index 07345efeef0c..8ead4a3c4a1b 100644
@@ -46,6 +46,7 @@
 
 /* stratix10 service layer clients */
 #define STRATIX10_RSU				"stratix10-rsu"
+#define STRATIX10_FCS				"stratix10-fcs"
 #define SOCFPGA_HWMON				"socfpga-hwmon"
 
 /* Maximum number of SDM client IDs. */
@@ -106,10 +107,12 @@ struct stratix10_svc_chan;
 /**
  * struct stratix10_svc - svc private data
  * @stratix10_svc_rsu: pointer to stratix10 RSU device
+ * @stratix10_svc_fcs: pointer to stratix10 FCS device
  * @stratix10_svc_hwmon: pointer to stratix10 HWMON device
  */
 struct stratix10_svc {
 	struct platform_device *stratix10_svc_rsu;
+	struct platform_device *stratix10_svc_fcs;
 	struct platform_device *stratix10_svc_hwmon;
 };
 
@@ -1398,6 +1401,30 @@ int stratix10_svc_async_send(struct stratix10_svc_chan *chan, void *msg,
 		STRATIX10_SIP_SMC_SET_TRANSACTIONID_X1(handle->transaction_id);
 
 	switch (p_msg->command) {
+	case COMMAND_FCS_CRYPTO_OPEN_SESSION:
+		args.a0 = INTEL_SIP_SMC_ASYNC_FCS_OPEN_CS_SESSION;
+		break;
+	case COMMAND_FCS_CRYPTO_CLOSE_SESSION:
+		args.a0 = INTEL_SIP_SMC_ASYNC_FCS_CLOSE_CS_SESSION;
+		args.a2 = p_msg->arg[0];
+		break;
+	case COMMAND_FCS_SDOS_DATA_EXT:
+		args.a0 = INTEL_SIP_SMC_ASYNC_FCS_CRYPTION_EXT;
+		args.a2 = p_msg->arg[0];
+		args.a3 = p_msg->arg[1];
+		args.a4 = p_msg->arg[2];
+		/* payloads are allocated from the svc gen_pool; pass phys addr */
+		args.a5 = gen_pool_virt_to_phys(ctrl->genpool,
+						(unsigned long)p_msg->payload);
+		args.a6 = p_msg->payload_length;
+		args.a7 = gen_pool_virt_to_phys(ctrl->genpool,
+						(unsigned long)p_msg->payload_output);
+		args.a8 = p_msg->payload_length_output;
+		args.a9 = p_msg->arg[3];
+		/* SMMU remapping is added later; pass phys addr for now */
+		args.a10 = args.a5;
+		args.a11 = args.a7;
+		break;
 	case COMMAND_RSU_GET_SPT_TABLE:
 		args.a0 = INTEL_SIP_SMC_ASYNC_RSU_GET_SPT;
 		break;
@@ -1495,8 +1522,13 @@ static int stratix10_svc_async_prepare_response(struct stratix10_svc_chan *chan,
 	data->status = STRATIX10_GET_SDM_STATUS_CODE(handle->res.a1);
 
 	switch (p_msg->command) {
+	case COMMAND_FCS_CRYPTO_CLOSE_SESSION:
 	case COMMAND_RSU_NOTIFY:
 		break;
+	case COMMAND_FCS_CRYPTO_OPEN_SESSION:
+	case COMMAND_FCS_SDOS_DATA_EXT:
+		data->kaddr1 = (void *)&handle->res.a2;
+		break;
 	case COMMAND_RSU_GET_SPT_TABLE:
 		data->kaddr1 = (void *)&handle->res.a2;
 		data->kaddr2 = (void *)&handle->res.a3;
@@ -2004,6 +2036,7 @@ EXPORT_SYMBOL_GPL(stratix10_svc_free_memory);
 static const struct of_device_id stratix10_svc_drv_match[] = {
 	{.compatible = "intel,stratix10-svc"},
 	{.compatible = "intel,agilex-svc"},
+	{.compatible = "intel,agilex5-svc"},
 	{},
 };
 
@@ -2107,7 +2140,18 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev)
 
 	ret = platform_device_add(svc->stratix10_svc_rsu);
 	if (ret)
-		goto err_put_device;
+		goto err_put_rsu;
+
+	svc->stratix10_svc_fcs = platform_device_alloc(STRATIX10_FCS, 0);
+	if (!svc->stratix10_svc_fcs) {
+		dev_err(dev, "failed to allocate %s device\n", STRATIX10_FCS);
+		ret = -ENOMEM;
+		goto err_unregister_rsu;
+	}
+
+	ret = platform_device_add(svc->stratix10_svc_fcs);
+	if (ret)
+		goto err_put_fcs;
 
 	if (IS_ENABLED(CONFIG_SENSORS_ALTERA_SOCFPGA_HWMON)) {
 		svc->stratix10_svc_hwmon =
@@ -2139,10 +2183,14 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev)
 err_unregister_clients:
 	if (svc->stratix10_svc_hwmon)
 		platform_device_unregister(svc->stratix10_svc_hwmon);
-	if (svc->stratix10_svc_rsu)
-		platform_device_unregister(svc->stratix10_svc_rsu);
+	platform_device_unregister(svc->stratix10_svc_fcs);
+	goto err_unregister_rsu;
+err_put_fcs:
+	platform_device_put(svc->stratix10_svc_fcs);
+err_unregister_rsu:
+	platform_device_unregister(svc->stratix10_svc_rsu);
 	goto err_free_fifos;
-err_put_device:
+err_put_rsu:
 	platform_device_put(svc->stratix10_svc_rsu);
 err_free_fifos:
 	/* only remove from list if list_add_tail() was reached */
@@ -2164,9 +2212,10 @@ static void stratix10_svc_drv_remove(struct platform_device *pdev)
 	struct stratix10_svc_controller *ctrl = platform_get_drvdata(pdev);
 	struct stratix10_svc *svc = ctrl->svc;
 
-	platform_device_unregister(svc->stratix10_svc_rsu);
 	if (svc->stratix10_svc_hwmon)
 		platform_device_unregister(svc->stratix10_svc_hwmon);
+	platform_device_unregister(svc->stratix10_svc_fcs);
+	platform_device_unregister(svc->stratix10_svc_rsu);
 
 	stratix10_svc_async_exit(ctrl);
 
include/linux/firmware/intel/stratix10-smc.h +64 -0

70 lines not on this page · raw message

include/linux/firmware/intel/stratix10-svc-client.h +16 -0
index 9bb46c3cb0f8..ffc1ac7c9785 100644
@@ -7,6 +7,8 @@
 #ifndef __STRATIX10_SVC_CLIENT_H
 #define __STRATIX10_SVC_CLIENT_H
 
+#include <linux/types.h>
+
 /*
  * Service layer driver supports client names
  *
@@ -122,6 +124,15 @@ struct stratix10_svc_chan;
  * @COMMAND_SMC_SVC_VERSION: Non-mailbox SMC SVC API Version,
  * return status is SVC_STATUS_OK
  *
+ * @COMMAND_FCS_CRYPTO_OPEN_SESSION: open the crypto service session(s),
+ * return status is SVC_STATUS_OK or SVC_STATUS_ERROR
+ *
+ * @COMMAND_FCS_CRYPTO_CLOSE_SESSION: close the crypto service session(s),
+ * return status is SVC_STATUS_OK or SVC_STATUS_ERROR
+ *
+ * @COMMAND_FCS_SDOS_DATA_EXT: extend SDOS data encryption & decryption,
+ * return status is SVC_STATUS_OK or SVC_STATUS_ERROR
+ *
  * @COMMAND_MBOX_SEND_CMD: send generic mailbox command, return status is
  * SVC_STATUS_OK or SVC_STATUS_ERROR
  *
@@ -190,6 +201,11 @@ enum stratix10_svc_command_code {
 	COMMAND_FCS_RANDOM_NUMBER_GEN,
 	/* for general status poll */
 	COMMAND_POLL_SERVICE_STATUS = 40,
+	/* for crypto service */
+	COMMAND_FCS_CRYPTO_OPEN_SESSION = 50,
+	COMMAND_FCS_CRYPTO_CLOSE_SESSION,
+	/* for extended SDOS encrypt/decrypt */
+	COMMAND_FCS_SDOS_DATA_EXT = 82,
 	/* for generic mailbox send command */
 	COMMAND_MBOX_SEND_CMD = 100,
 	/* Non-mailbox SMC Call */
Signature · 1 line
2.43.7
maintainer
#3 lore raw

Re: [PATCH v5 2/3] firmware: stratix10-svc: add FCS crypto-service commands for Agilex 5

Hi Hang Suan,

Quoted 87 lines · On 9/15/26 03:25, [email protected] wrote:

From: Hang Suan Wang <[email protected]>

The Agilex 5 Secure Device Manager (SDM 1.5) exposes an FPGA Crypto Service (FCS) over the existing SIP SMC mailbox: a session-based interface for crypto primitives such as SDOS (Secure Data Object Service) encrypt/decrypt. The service layer has no command to drive it yet.

Configure stratix10-svc about this interface so an in-kernel FCS client can use it:

- add the client command codes COMMAND_FCS_CRYPTO_OPEN_SESSION, COMMAND_FCS_CRYPTO_CLOSE_SESSION and COMMAND_FCS_SDOS_DATA_EXT (all asynchronous)

- add the matching asynchronous SIP SMC function IDs (INTEL_SIP_SMC_ASYNC_FCS_OPEN_CS_SESSION, INTEL_SIP_SMC_ASYNC_FCS_CLOSE_CS_SESSION and INTEL_SIP_SMC_ASYNC_FCS_CRYPTION_EXT) with their register-usage documentation;

- match "intel,agilex5-svc" and register a "stratix10-fcs" child platform device, mirroring the existing RSU child, so an FCS client driver can bind without a dedicated device-tree node;

- dispatch the new commands in the asynchronous send and response paths; for the SDOS data command, translate the source and destination buffers (allocated from the service-layer gen_pool) to physical addresses and pass them, together with the session/context IDs and owner ID, to the SDM.

The transport is unchanged: Agilex 5 reuses the SIP SMC calling convention and async mailbox ABI the driver already implements, so no new transport mechanism is required.

The SDOS SMMU-remapped address slots currently carry the buffer physical addresses; SMMU remapping support is added in a follow-up series.

This is a prerequisite for the SoCFPGA FCS driver, the first in-tree consumer of these commands.

---
  drivers/firmware/stratix10-svc.c              | 59 +++++++++++++++--
  include/linux/firmware/intel/stratix10-smc.h  | 64 +++++++++++++++++++
  .../firmware/intel/stratix10-svc-client.h     | 16 +++++
  3 files changed, 134 insertions(+), 5 deletions(-)
drivers/firmware/stratix10-svc.c +11 -0
index 07345efeef0c..8ead4a3c4a1b 100644
@@ -46,6 +46,7 @@
 
  /* stratix10 service layer clients */
  #define STRATIX10_RSU				"stratix10-rsu"
+#define STRATIX10_FCS				"stratix10-fcs"
  #define SOCFPGA_HWMON				"socfpga-hwmon"
 
  /* Maximum number of SDM client IDs. */
@@ -106,10 +107,12 @@ struct stratix10_svc_chan;
  /**
   * struct stratix10_svc - svc private data
   * @stratix10_svc_rsu: pointer to stratix10 RSU device
+ * @stratix10_svc_fcs: pointer to stratix10 FCS device
   * @stratix10_svc_hwmon: pointer to stratix10 HWMON device
   */
  struct stratix10_svc {
  	struct platform_device *stratix10_svc_rsu;
+	struct platform_device *stratix10_svc_fcs;
  	struct platform_device *stratix10_svc_hwmon;
  };
 
@@ -1398,6 +1401,30 @@ int stratix10_svc_async_send(struct stratix10_svc_chan *chan, void *msg,
  		STRATIX10_SIP_SMC_SET_TRANSACTIONID_X1(handle->transaction_id);
 
  	switch (p_msg->command) {
+	case COMMAND_FCS_CRYPTO_OPEN_SESSION:
+		args.a0 = INTEL_SIP_SMC_ASYNC_FCS_OPEN_CS_SESSION;
+		break;
+	case COMMAND_FCS_CRYPTO_CLOSE_SESSION:
+		args.a0 = INTEL_SIP_SMC_ASYNC_FCS_CLOSE_CS_SESSION;
+		args.a2 = p_msg->arg[0];
+		break;
+	case COMMAND_FCS_SDOS_DATA_EXT:

drivers/firmware/stratix10-svc.c int stratix10_svc_async_send(struct stratix10_svc_chan *chan, void *msg, · line 1421

Quoted 10 lines
drivers/firmware/stratix10-svc.c +10 -0
+		args.a0 = INTEL_SIP_SMC_ASYNC_FCS_CRYPTION_EXT;
+		args.a2 = p_msg->arg[0];
+		args.a3 = p_msg->arg[1];
+		args.a4 = p_msg->arg[2];
+		/* payloads are allocated from the svc gen_pool; pass phys addr */
+		args.a5 = gen_pool_virt_to_phys(ctrl->genpool,
+						(unsigned long)p_msg->payload);
+		args.a6 = p_msg->payload_length;
+		args.a7 = gen_pool_virt_to_phys(ctrl->genpool,
+						(unsigned long)p_msg->payload_output);

These calls to gen_pool_virt_to_phys() can fail.

<snip>

include/linux/firmware/intel/stratix10-svc-client.h line 10

Quoted 10 lines
drivers/firmware/stratix10-svc.c +0 -0
   * Sync call to request temperature
include/linux/firmware/intel/stratix10-svc-client.h +1 -0
index 9bb46c3cb0f8..ffc1ac7c9785 100644
@@ -7,6 +7,8 @@
  #ifndef __STRATIX10_SVC_CLIENT_H
  #define __STRATIX10_SVC_CLIENT_H
 
+#include <linux/types.h>

I don't think you need the above include.

Dinh

#4 lore raw

PATCH v5 3/3 firmware: socfpga-fcs: add Altera SoCFPGA FCS driver with SDOS

In reply to [email protected]

From: Hang Suan Wang <[email protected]>

Add the Altera SoCFPGA Crypto Service (FCS) driver, which exposes the Secure Data Object Service (SDOS) encrypt/decrypt operation to non-secure host software.

The SDOS protects data at rest: the SDM encrypts and decrypts using a key derived from a device-unique SDOS root key plus an SDM-generated IV, so the host never handles raw key material or IVs. It only submits plaintext it already owns and receives authenticated ciphertext objects managed by the SDM. A primary use case is black key, where operational keys are installed without ever appearing in cleartext.

The driver is a standalone module and describes no hardware of its own. It binds by name to the "stratix10-fcs" platform device registered by stratix10-svc, so no device-tree node is required. SDOS requests go to the SDM through the stratix10-svc asynchronous SIP SMC path using service-layer memory pool buffers that the SDM can reach via physical or SMMU-remapped addresses. Userspace talks to /dev/socfpga-fcs via ioctl and sysfs exposes atf_version.

For encryption the SDM returns a structured object (header, ciphertext, HMAC). For decryption the SDM validates the HMAC and enforces the 64-bit owner ID from the object header so only the creator can decrypt it.

Each SDOS request opens an SDM crypto session, runs under priv->lock (one in-flight transaction), and closes the session afterwards.

---
 .../userspace-api/ioctl/ioctl-number.rst      |   1 +
 MAINTAINERS                                   |   9 +
 drivers/firmware/Kconfig                      |  17 +
 drivers/firmware/Makefile                     |   2 +
 drivers/firmware/socfpga-fcs-core.c           | 715 ++++++++++++++++++
 drivers/firmware/socfpga-fcs.c                | 294 +++++++
 include/linux/firmware/intel/socfpga-fcs.h    | 130 ++++
 include/uapi/misc/socfpga-fcs-crypto.h        |  28 +
 8 files changed, 1196 insertions(+)
 create mode 100644 drivers/firmware/socfpga-fcs-core.c
 create mode 100644 drivers/firmware/socfpga-fcs.c
 create mode 100644 include/linux/firmware/intel/socfpga-fcs.h
 create mode 100644 include/uapi/misc/socfpga-fcs-crypto.h
Documentation/userspace-api/ioctl/ioctl-number.rst +1 -0
index 2fc53093752d..a1e07f7f6870 100644
@@ -348,6 +348,7 @@ Code  Seq#    Include File                                             Comments
                                                                        <mailto:[email protected]>
 0xA6  00-0F  uapi/linux/alloc_tag.h                                    Memory allocation profiling
                                                                        <mailto:[email protected]>
+0xA6  00-1F  uapi/misc/socfpga-fcs-crypto.h                            Altera SoCFPGA FCS (Crypto Service)
 0xAA  00-3F  linux/uapi/linux/userfaultfd.h
 0xAB  00-1F  linux/nbd.h
 0xAC  00-1F  linux/raw.h
MAINTAINERS +9 -0
index 3b2eb2a7a89a..b6e60dc4d868 100644
@@ -945,6 +945,15 @@ ALPS PS/2 TOUCHPAD DRIVER
 R:	Pali Rohár <[email protected]>
 F:	drivers/input/mouse/alps.*
 
+ALTERA FCS DRIVER
+M:	Hang Suan Wang <[email protected]>
+M:	Genevieve Chan <[email protected]>
+L:	[email protected]
+S:	Maintained
+F:	drivers/firmware/socfpga-fcs*
+F:	include/linux/firmware/intel/socfpga-fcs*
+F:	include/uapi/misc/socfpga-fcs*
+
 ALTERA MAILBOX DRIVER
 M:	Tien Sung Ang <[email protected]>
 S:	Maintained
drivers/firmware/Kconfig +17 -0
index b7cc11e4fbfa..15727855fd5f 100644
@@ -193,6 +193,23 @@ config INTEL_STRATIX10_RSU
 
 	  Say Y here if you want Intel RSU support.
 
+config ALTERA_SOCFPGA_FCS
+	tristate "Altera SoCFPGA Crypto Services (FCS)"
+	depends on INTEL_STRATIX10_SERVICE
+	help
+	  Altera SoCFPGA Crypto Services (FCS) driver gives user space
+	  access to the crypto services of the Secure Device Manager (SDM)
+	  through the Intel Service Layer, with requests forwarded to Arm
+	  Trusted Firmware.
+
+	  The SDM executes or authorizes the requests using device-rooted
+	  security resources. Protected key material stays within the
+	  secure firmware boundary and is never exposed to non-secure host
+	  software.
+
+	  Say Y here to add support for Altera SoCFPGA Crypto Services
+	  (FCS).
+
 config MTK_ADSP_IPC
 	tristate "MTK ADSP IPC Protocol driver"
 	depends on MTK_ADSP_MBOX
drivers/firmware/Makefile +2 -0
index be46f1e1dc77..10431273e401 100644
@@ -11,6 +11,8 @@ obj-$(CONFIG_EDD)		+= edd.o
 obj-$(CONFIG_DMIID)		+= dmi-id.o
 obj-$(CONFIG_INTEL_STRATIX10_SERVICE) += stratix10-svc.o
 obj-$(CONFIG_INTEL_STRATIX10_RSU)     += stratix10-rsu.o
+obj-$(CONFIG_ALTERA_SOCFPGA_FCS) += altera-fcs.o
+altera-fcs-y := socfpga-fcs.o socfpga-fcs-core.o
 obj-$(CONFIG_ISCSI_IBFT_FIND)	+= iscsi_ibft_find.o
 obj-$(CONFIG_ISCSI_IBFT)	+= iscsi_ibft.o
 obj-$(CONFIG_FIRMWARE_MEMMAP)	+= memmap.o
drivers/firmware/socfpga-fcs-core.c new file +715 -0

715 lines not on this page · raw message

drivers/firmware/socfpga-fcs.c new file +294 -0

294 lines not on this page · raw message

include/linux/firmware/intel/socfpga-fcs.h new file +130 -0

130 lines not on this page · raw message

include/uapi/misc/socfpga-fcs-crypto.h new file +28 -0
new file mode 100644
index 000000000000..a96aa21b0baf
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
+/*
+ * Description:
+ * This driver is developed for the SDM SoCFPGA Crypto Service (FCS). It
+ * provides an ioctl interface for the SDOS (Secure Data Object Service)
+ * encrypt/decrypt operation. The crypto session and the per-request context
+ * ID are managed by the kernel internally, so neither is part of the user
+ * ABI.
+ */
+#ifndef __SOCFPGA_FCS_CRYPTO_H
+#define __SOCFPGA_FCS_CRYPTO_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+struct fcs_ioc_sdos {
+	__u64 error_code;	/* __user ptr to __s32 (out)              */
+	__u64 src;		/* __user ptr to input buffer (in)        */
+	__u64 dst;		/* __user ptr to output buffer (out)      */
+	__u64 dst_size;		/* __user ptr to __u32 capacity/len (in/out) */
+	__u32 op_mode;		/* (in)  */
+	__u32 src_size;		/* (in)  */
+};
+
+#define FCS_IOC_MAGIC		0xA6
+#define FCS_IOC_SDOS		_IOWR(FCS_IOC_MAGIC, 1, struct fcs_ioc_sdos)
+
+#endif /* __SOCFPGA_FCS_CRYPTO_H */
Signature · 1 line
2.43.7