Add Altera SoCFPGA Crypto Service (FCS) driver
Subsystems (2)
v6 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). SDOS is an Altera-proprietary service that seals and unseals arbitrary application data. 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. 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.
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 obvious question is why this is not a trusted-keys backend or a crypto API transform. There are four reasons this feature cannot fit:
- No key handle. The key is derived inside the SDM from a device-unique root key and is never set, imported or named by the host, so there is nothing for setkey() to bind to.
- Object format. The SDM emits a firmware-defined container: a 40-byte header, the payload, and a 48-byte HMAC, with the owner ID carried inside the header. That is not a generic AEAD output.
- Size. SDOS seals arbitrary application data, from 72 up to 32,760 bytes. Trusted keys exist to wrap key material and their payloads are bounded far below that, so the keyring model does not fit a data-at-rest service.
- Status reporting. SDM statuses 0x102 and 0x103 mean "decryption succeeded, but the key is outdated or should be reprovisioned". They are successes carrying a warning, and the warning has to reach the caller together with valid plaintext. Neither keyctl nor AF_ALG carries a firmware status alongside a successful result.
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.binroot@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 v5:
- Drop the exported fcs_alloc_buf()/fcs_free_buf() helpers. fcs_sdos_crypt() now allocates and releases the service-layer pool buffers itself, both under priv->lock, so a pool buffer can no longer be leaked when the device is unbound while a request is in flight.
- Stage user data through kvmalloc() buffers in fcs_sdos() so copy_from_user()/copy_to_user() run outside priv->lock. A faulting user page can no longer pin the lock and block device removal.
- Read the remaining 32-bit mailbox results with lower_32_bits(): the SDOS payload size and the ATF version error status. Both still cast an arm_smccc unsigned long through a 32-bit pointer.
- Document struct fcs_ioc_sdos and FCS_IOC_SDOS with kernel-doc in include/uapi/misc/socfpga-fcs-crypto.h. The structure layout and the ioctl number are unchanged.
- Add Documentation/misc-devices/socfpga-fcs.rst: the device node, the ioctl, the size ranges per direction, the errno table, and the 0x102/0x103 success-with-warning statuses.
- Explain in this cover letter why SDOS is a dedicated ioctl rather than a trusted-keys backend or a crypto API transform.
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
Documentation/misc-devices/index.rst | 1 + Documentation/misc-devices/socfpga-fcs.rst | 140 ++++ .../userspace-api/ioctl/ioctl-number.rst | 1 + MAINTAINERS | 10 + drivers/firmware/Kconfig | 17 + drivers/firmware/Makefile | 2 + drivers/firmware/socfpga-fcs-core.c | 700 ++++++++++++++++++ drivers/firmware/socfpga-fcs.c | 296 ++++++++ drivers/firmware/stratix10-svc.c | 65 +- include/linux/firmware/intel/socfpga-fcs.h | 122 +++ include/linux/firmware/intel/stratix10-smc.h | 64 ++ .../firmware/intel/stratix10-svc-client.h | 18 +- include/uapi/misc/socfpga-fcs-crypto.h | 68 ++ 13 files changed, 1496 insertions(+), 8 deletions(-) create mode 100644 Documentation/misc-devices/socfpga-fcs.rst 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
PATCH v6 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
@@ -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
@@ -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
PATCH v6 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
@@ -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
@@ -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
Dinh Nguyen
maintainerRe: [PATCH v6 2/3] firmware: stratix10-svc: add FCS crypto-service commands for Agilex 5
Quoted 87 lines · On 9/23/26 12:23, [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_SESSIONandCOMMAND_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_SESSIONandINTEL_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.
Signed-off-by Hang Suan Wang <[email protected]>Reviewed-by Dinh Nguyen <[email protected]>--- 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@@ -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.
Quoted 161 lines
drivers/firmware/stratix10-svc.c +33
-5+ 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@@ -669,6 +669,70 @@ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE)#define INTEL_SIP_SMC_FCS_GET_PROVISION_DATA \ INTEL_SIP_SMC_STD_CALL_VAL(INTEL_SIP_SMC_FUNCID_FCS_GET_PROVISION_DATA) +/** +* Request INTEL_SIP_SMC_ASYNC_FCS_CRYPTION_EXT +* Async call to perform encryption/decryption +* +* Call register usage: +* a0 INTEL_SIP_SMC_ASYNC_FCS_CRYPTION_EXT +* a1 transaction job id +* a2 session ID +* a3 context ID +* a4 cryption operating mode (1 for encryption and 0 for decryption) +* a5 physical address of source +* a6 size of source +* a7 physical address of destination +* a8 size of destination +* a9 sdos ownership +* a10 smmu remapped address of source +* a11 smmu remapped address of destination +* a12-a17 not used +* +* Return status: +* a0 INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_STATUS_ERROR +* a1-a17 not used +*/ +#define INTEL_SIP_SMC_ASYNC_FUNC_ID_FCS_CRYPTION_EXT (0x12F) +#define INTEL_SIP_SMC_ASYNC_FCS_CRYPTION_EXT \ + INTEL_SIP_SMC_ASYNC_VAL(INTEL_SIP_SMC_ASYNC_FUNC_ID_FCS_CRYPTION_EXT) + +/** +* Request INTEL_SIP_SMC_ASYNC_FCS_OPEN_CS_SESSION +* Async call to open and establish a crypto service session with firmware +* +* Call register usage: +* a0 INTEL_SIP_SMC_FCS_OPEN_CRYPTO_SERVICE_SESSION +* a1 transaction job id +* a2-a17 not used +* +* Return status: +* a0 INTEL_SIP_SMC_STATUS_OK ,INTEL_SIP_SMC_STATUS_REJECTED +* or INTEL_SIP_SMC_STATUS_BUSY +* a1-a17 not used +*/ +#define INTEL_SIP_SMC_ASYNC_FUNC_ID_FCS_OPEN_CS_SESSION (0x13A) +#define INTEL_SIP_SMC_ASYNC_FCS_OPEN_CS_SESSION \ + INTEL_SIP_SMC_ASYNC_VAL(INTEL_SIP_SMC_ASYNC_FUNC_ID_FCS_OPEN_CS_SESSION) + +/** +* Request INTEL_SIP_SMC_ASYNC_FCS_CLOSE_CS_SESSION +* Async call to close a service session +* +* Call register usage: +* a0 INTEL_SIP_SMC_ASYNC_FCS_CLOSE_CS_SESSION +* a1 transaction job id +* a2 session ID +* a3-a17 not used +* +* Return status: +* a0 INTEL_SIP_SMC_STATUS_OK ,INTEL_SIP_SMC_STATUS_REJECTED +* or INTEL_SIP_SMC_STATUS_BUSY +* a1-a17 not used +*/ +#define INTEL_SIP_SMC_ASYNC_FUNC_ID_FCS_CLOSE_CS_SESSION (0x13B) +#define INTEL_SIP_SMC_ASYNC_FCS_CLOSE_CS_SESSION \ + INTEL_SIP_SMC_ASYNC_VAL(INTEL_SIP_SMC_ASYNC_FUNC_ID_FCS_CLOSE_CS_SESSION) +/** * Request INTEL_SIP_SMC_HWMON_READTEMP * Sync call to request temperature include/linux/firmware/intel/stratix10-svc-client.h +0
-0
include/linux/firmware/intel/stratix10-svc-client.h line 10
Quoted 4 lines
include/linux/firmware/intel/stratix10-svc-client.h +1
-0@@ -7,6 +7,8 @@#ifndef __STRATIX10_SVC_CLIENT_H#define __STRATIX10_SVC_CLIENT_H +#include <linux/types.h>
Shouldn't need this.
Dinh
PATCH v6 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 the 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.
--- Documentation/misc-devices/index.rst | 1 + Documentation/misc-devices/socfpga-fcs.rst | 140 ++++ .../userspace-api/ioctl/ioctl-number.rst | 1 + MAINTAINERS | 10 + drivers/firmware/Kconfig | 17 + drivers/firmware/Makefile | 2 + drivers/firmware/socfpga-fcs-core.c | 700 ++++++++++++++++++ drivers/firmware/socfpga-fcs.c | 296 ++++++++ include/linux/firmware/intel/socfpga-fcs.h | 122 +++ include/uapi/misc/socfpga-fcs-crypto.h | 68 ++ 10 files changed, 1357 insertions(+) create mode 100644 Documentation/misc-devices/socfpga-fcs.rst 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/misc-devices/index.rst +1 -0
@@ -24,6 +24,7 @@ fit into other categories. mrvl_cn10k_dpi oxsemi-tornado pci-endpoint-test + socfpga-fcs spear-pcie-gadget tps6594-pfsm uacce
Documentation/misc-devices/socfpga-fcs.rst new file +140 -0
140 lines not on this page · raw message
Documentation/userspace-api/ioctl/ioctl-number.rst +1 -0
@@ -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 +10 -0
@@ -945,6 +945,16 @@ 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: Documentation/misc-devices/socfpga-fcs.rst +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
@@ -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
@@ -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 +700 -0
700 lines not on this page · raw message
drivers/firmware/socfpga-fcs.c new file +296 -0
296 lines not on this page · raw message
include/linux/firmware/intel/socfpga-fcs.h new file +122 -0
122 lines not on this page · raw message
include/uapi/misc/socfpga-fcs-crypto.h new file +68 -0
68 lines not on this page · raw message
Signature · 1 line
2.43.7
Dinh Nguyen
maintainerRe: [PATCH v6 3/3] firmware: socfpga-fcs: add Altera SoCFPGA FCS driver with SDOS
Quoted 25 lines · On 9/23/26 12:23, [email protected] wrote:
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 the 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-fcsvia ioctl and sysfs exposesatf_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.
Quoted 8 lines
Each SDOS request opens an SDM crypto session, runs under
priv->lock(one in-flight transaction), and closes the session afterwards.Signed-off-by Hang Suan Wang <[email protected]>--- Documentation/misc-devices/index.rst | 1 + Documentation/misc-devices/socfpga-fcs.rst | 140 ++++ .../userspace-api/ioctl/ioctl-number.rst | 1 +
You forgot to include the maintainers for these files:
Jonathan Corbet <[email protected]> (maintainer:DOCUMENTATION) Shuah Khan <[email protected]> (reviewer:DOCUMENTATION) Randy Dunlap <[email protected]> (reviewer:DOCUMENTATION)
Quoted 189 lines
MAINTAINERS | 10 + drivers/firmware/Kconfig | 17 + drivers/firmware/Makefile | 2 + drivers/firmware/socfpga-fcs-core.c | 700 ++++++++++++++++++ drivers/firmware/socfpga-fcs.c | 296 ++++++++ include/linux/firmware/intel/socfpga-fcs.h | 122 +++ include/uapi/misc/socfpga-fcs-crypto.h | 68 ++q 10 files changed, 1357 insertions(+)create mode 100644
Documentation/misc-devices/socfpga-fcs.rstcreate mode 100644drivers/firmware/socfpga-fcs-core.ccreate mode 100644drivers/firmware/socfpga-fcs.ccreate mode 100644include/linux/firmware/intel/socfpga-fcs.hcreate mode 100644include/uapi/misc/socfpga-fcs-crypto.hDocumentation/misc-devices/index.rst +1
-0@@ -24,6 +24,7 @@ fit into other categories. mrvl_cn10k_dpi oxsemi-tornado pci-endpoint-test + socfpga-fcs spear-pcie-gadget tps6594-pfsm uacceDocumentation/misc-devices/socfpga-fcs.rst new file +140
-0@@ -0,0 +1,140 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=================================== +Altera SoCFPGA Crypto Service (FCS) +=================================== + +Overview +======== + +The Secure Device Manager (SDM) is the hardware security controller in Altera +SoCFPGA devices. It offers a runtime cryptographic interface, the FPGA Crypto +Service (FCS), which the host reaches through the stratix10-svc mailbox using +Arm Trusted Firmware SIP SMC calls. + +This driver exposes one FCS operation: the Secure Data Object Service (SDOS), +which encrypts and decrypts data at rest. The SDM derives the working key from +a device-unique SDOS root key that never leaves the secure boundary, so the +host never handles raw key material. A primary use case is black-key +provisioning. + +The crypto session and the per-request context ID are opened and closed by the +kernel around each request. Neither is part of the user ABI. + +Why a dedicated ioctl +===================== + +SDOS seals and unseals arbitrary application data of up to 32 KiB, not keys of +a bounded size, so the keyring payload limits of the trusted-keys subsystem do +not apply to it. The object it produces is a firmware-defined container rather +than a generic AEAD output, no key is ever set from the host so the crypto API +has nothing to bind a transform to, and the SDM returns per-operation status +values that must reach the caller alongside a valid result. + +Device node +=========== + +The driver registers a misc device:: + + /dev/socfpga-fcs + +Opening it takes a reference on the driver state. If the driver is unbound +while the file is open, subsequent operations fail with ``ENODEV`` rather than +tearing the file descriptor out from under the caller. + +Buffer sizes +============ + +An SDOS object consists of a 40-byte firmware-defined header, the payload, and +for an encrypted object a trailing 48-byte HMAC. The payload is between 32 and +32672 bytes. + +================== ================== ============== +``op_mode`` ``src_size`` range Maximum output +================== ================== ============== +non-zero (encrypt) 72 .. 32712 bytes 32760 bytes +zero (decrypt) 120 .. 32760 bytes 32712 bytes +================== ================== ============== + +Size the output buffer for the maximum shown above. The SDM reports the exact +produced length once the operation completes. + +Data structures +=============== + +.. kernel-doc:: include/uapi/misc/socfpga-fcs-crypto.h + :identifiers: fcs_ioc_sdos + +Driver IOCTLs +============= + +.. c:macro:: FCS_IOC_SDOS +.. kernel-doc:: include/uapi/misc/socfpga-fcs-crypto.h + :doc: FCS_IOC_SDOS + +Return value +============ + +On success 0 is returned and the ``__u32`` addressed by ``dst_size`` holds +the number of bytes the SDM produced. On error -1 is returned and ``errno`` +is set. + +=========== ================================================================ +Error Description +=========== ================================================================ +EINVAL ``dst`` or ``dst_size`` was NULL, or ``src_size`` was out of + range for ``op_mode``. +EMSGSIZE The output did not fit in ``dst``. The operation itself + succeeded and ``error_code`` holds the SDM status, but the + result is discarded, so ``dst`` must be sized for the maximum + output. +EFAULT One of the supplied addresses was not accessible. +EIO The SDM reported a fatal error. ``error_code`` holds the status. +ENODEV The device was unbound while the file descriptor was open. +ENOMEM Staging buffers could not be allocated. +ERESTARTSYS A signal arrived while waiting for another request to finish. + Only one SDM transaction is in flight at a time. +=========== ================================================================ + +SDM status values +================= + +The ``__s32`` addressed by ``error_code`` carries the firmware status. Two +decrypt results are successes that carry a warning: the ioctl returns 0 for +both and the plaintext is in ``dst``. + +======= ================================================================ +Status Description +======= ================================================================ +0x000 The operation completed successfully. +0x102 Decryption succeeded; reprovisioning the key is recommended. +0x103 Decryption succeeded, but not with the latest key. +======= ================================================================ + +Any other non-zero status is fatal and the ioctl fails with ``EIO``. + +User-space usage +================ +A sample userspace application demonstrating these ioctls can be found at +`Git Repository - altera-fpga/libfcs <https://github.com/altera-fpga/libfcs>`_ + +Decrypting an object:: + + __u8 out[32712]; /* maximum decrypt output */ + __u32 out_len = sizeof(out); + __s32 status = 0; + + struct fcs_ioc_sdos arg = { + .error_code = (__u64)(uintptr_t)&status, + .src = (__u64)(uintptr_t)in, + .src_size = in_len, + .dst = (__u64)(uintptr_t)out, + .dst_size = (__u64)(uintptr_t)&out_len, + .op_mode = 0, /* decrypt */ + }; + + if (ioctl(fd, FCS_IOC_SDOS, &arg) == 0) + /* out_len bytes of plaintext in out */ + write(STDOUT_FILENO, out, out_len); + else + fprintf(stderr, "SDOS failed: %m, SDM status 0x%x\n", status);Documentation/userspace-api/ioctl/ioctl-number.rst +1
-0@@ -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.hMAINTAINERS +0
-0
MAINTAINERS ALPS PS/2 TOUCHPAD DRIVER · line 951
Quoted 7 lines
MAINTAINERS +4
-0@@ -945,6 +945,16 @@ 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]
Why linux-arm? Should be just linux-kernel.
Quoted 42 lines
MAINTAINERS +6
-0+S: Maintained +F: Documentation/misc-devices/socfpga-fcs.rst +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: Maintaineddrivers/firmware/Kconfig +17
-0@@ -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_MBOXdrivers/firmware/Makefile +0
-0
drivers/firmware/Makefile obj-$(CONFIG_EDD) += edd.o · line 15
Quoted 5 lines
drivers/firmware/Makefile +2
-0@@ -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
Follow the alphabetical order of these entries.
Quoted 87 lines
drivers/firmware/Makefile +0
-0obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.odrivers/firmware/socfpga-fcs-core.c new file +78
-0@@ -0,0 +1,700 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* +* Copyright (C) 2026 Altera Corporation +*/ + +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/random.h> +#include <linux/slab.h> +#include <linux/unaligned.h> +#include <linux/firmware/intel/socfpga-fcs.h> +#include <linux/firmware/intel/stratix10-svc-client.h> + +#define OWNER_ID_OFFSET 12 + +#define SDOS_DECRYPTION_REPROVISION_KEY_WARN 0x102 +#define SDOS_DECRYPTION_NOT_LATEST_KEY_WARN 0x103 + +#define MSG_RETRY 3 +#define FCS_RETRY_SLEEP_MS 1 + +struct fcs_cmd_params { +const void *src; +void *dst; +u32 src_len; +u32 dst_len; +u32 op_mode; +u64 own; +}; + +/** +* fcs_atf_version_callback() - service-layer callback for the ATF version query +* @client: pointer to the stratix10-svc client +* @data: pointer to the service-layer callback data +*/ +static void fcs_atf_version_callback (struct stratix10_svc_client *client, +struct stratix10_svc_cb_data *data) +{ +struct socfpga_fcs_priv *p = client->priv; + + p->status = data->status; +if (data->status ==BIT (SVC_STATUS_OK )) { + p->status =0 ; + p->atf_version[0 ] =lower_32_bits (*(unsigned long *)data->kaddr1); + p->atf_version[1 ] =lower_32_bits (*(unsigned long *)data->kaddr2); + p->atf_version[2 ] =lower_32_bits (*(unsigned long *)data->kaddr3); + p->atf_version_valid = true; + }else if (data->status ==BIT (SVC_STATUS_ERROR )) { + p->status =lower_32_bits (*(unsigned long *)data->kaddr1); +dev_err (client->dev,"mbox_error=0x%x\n" , p->status); + } + +complete (&p->completion); +} + +/** +* fcs_async_callback() - completion callback for an async service request +* @ptr: pointer to the completion to signal +*/ +static void fcs_async_callback (void *ptr) +{ +if (ptr) +complete (ptr); +} + +/** +* fcs_svc_send_sync() - run a command on the synchronous service path +* @msg: service-layer message to send +* @timeout: time to wait for the response +* Return: 0 on success, negative errno on failure. +*/ +static int fcs_svc_send_sync (struct socfpga_fcs_priv *priv, +struct stratix10_svc_client_msg *msg, +unsigned long timeout) +{ +int ret; + +reinit_completion (&priv->completion);
drivers/firmware/socfpga-fcs-core.c line 88
Quoted 10 lines
drivers/firmware/socfpga-fcs-core.c new file +10
-0+ +/* +* receive_cb is only used by the sync send path; leave it set so a +* late response cannot find a NULL callback. +*/ + priv->client.receive_cb = fcs_atf_version_callback; + + ret =stratix10_svc_send (priv->chan, msg); +if (ret) { +pr_err ("failed to send message to service channel\n" );
Try not to mix dev_err and pr_err. You should be using dev_err here. Same comment for all the pr_err() and pr_debug(). <snip>
Quoted 18 lines
include/linux/firmware/intel/socfpga-fcs.h new file +12
-0@@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +* Copyright (C) 2026 Altera Corporation +* +* SDOS-only subset of the SoCFPGA FCS (FPGA Crypto Service) interface, +* shared between the driver front-end (socfpga-fcs.c) and the command +* engine (socfpga-fcs-core.c). +* +* The command engine deals in kernel pointers only: front-ends own every +* transfer to and from user space. In-kernel consumers can therefore drive +* the same engine directly. +*/
include/linux/firmware/intel/socfpga-fcs.h line 22
Quoted 10 lines
include/linux/firmware/intel/socfpga-fcs.h new file +10
-0+#ifndef __SOCFPGA_FCS_H +#define __SOCFPGA_FCS_H + +#include <linux/completion.h> +#include <linux/device.h> +#include <linux/kref.h> +#include <linux/miscdevice.h> +#include <linux/mutex.h> +#include <linux/types.h> +#include <linux/firmware/intel/stratix10-svc-client.h>
You shouldn't need all of these includes.
Quoted 110 lines
include/linux/firmware/intel/socfpga-fcs.h new file +100
-0+ +#define SDOS_HEADER_SZ 40 +#define SDOS_HMAC_SZ 48 +#define SDOS_PLAINDATA_MIN_SZ 32 +#define SDOS_PLAINDATA_MAX_SZ 32672 +#define SDOS_DECRYPTED_MIN_SZ (SDOS_PLAINDATA_MIN_SZ + SDOS_HEADER_SZ) +#define SDOS_DECRYPTED_MAX_SZ (SDOS_PLAINDATA_MAX_SZ + SDOS_HEADER_SZ) +#define SDOS_ENCRYPTED_MIN_SZ (SDOS_PLAINDATA_MIN_SZ + SDOS_HEADER_SZ + SDOS_HMAC_SZ) +#define SDOS_ENCRYPTED_MAX_SZ (SDOS_PLAINDATA_MAX_SZ + SDOS_HEADER_SZ + SDOS_HMAC_SZ) + +/** +* struct fcs_sdos_req - parameters for one SDOS encrypt/decrypt operation +* @op_mode: non-zero to encrypt, zero to decrypt +* @src: input buffer, any kernel address +* @src_len: number of valid bytes in @src +* @dst: output buffer, any kernel address +* @dst_len: on entry the capacity of @dst, on return the number of bytes the +* SDM produced +* @status: SDM mailbox status, valid only when @status_valid is set +* @status_valid: set by the engine once the mailbox transaction completed, +* whether it succeeded or reported a firmware error. Clear +* after a transport failure, where no firmware status exists. +* +* Every pointer is a kernel address, so the engine never touches user memory. +*/ +struct fcs_sdos_req { +u32 op_mode; +const void *src; +u32 src_len; +void *dst; +u32 dst_len; +s32 status; +bool status_valid; +}; + +/** +* Private driver state for the SoCFPGA FCS that holds the SDM/ATF service +* channel, the lock serialising command submission, and the latest mailbox +* status/response. +*/ +struct socfpga_fcs_priv { +/* Communication channel */ +struct stratix10_svc_chan *chan; +struct stratix10_svc_client client; +struct miscdevice miscdev; +/* +* Held by the driver and by every open file. An fd may outlive driver +* detach, so this state is not devm-managed: the firmware channel and +* the allocation are released only when the last reference goes. +*/ +struct kref refcount; +/* Set on remove(); further operations fail with -ENODEV. */ +bool removed; +struct completion completion; +/* +* Serializes FCS command submission: guards the session state and the +* single in-flight mailbox transaction (completion/status/resp) so only +* one SDM request is outstanding at a time. It also covers the whole +* lifetime of the service-layer pool buffers, so they cannot outlive +* @chan; user-space copying happens outside it. +*/ +struct mutex lock; +int status; +u32 resp; +u32 session_id; +/* non-zero while a crypto context is active */ +u32 context_id; +u32 atf_version[3 ]; +bool atf_version_valid; +}; + +enum fcs_command_code { +FCS_DEV_CRYPTO_OPEN_SESSION , +FCS_DEV_CRYPTO_CLOSE_SESSION , +FCS_DEV_SDOS_DATA_EXT , +FCS_DEV_ATF_VERSION , +}; + +int fcs_sdos_output_size (u32 op_mode,u32 src_len,u32 *out_len); + +/* +* Allocate the per-device FCS state and set up the service channel; reads the +* ATF version. The state is reference counted; release the driver's reference +* with fcs_put(). Returns an ERR_PTR on failure. +*/ +struct socfpga_fcs_priv *fcs_init (struct device *dev); + +/* Take/drop a reference; the last put closes the session and frees the state. */ +void fcs_get (struct socfpga_fcs_priv *priv); +void fcs_put (struct socfpga_fcs_priv *priv); + +/* Refuse further operations with -ENODEV; call from the remove path. */ +void fcs_mark_removed (struct socfpga_fcs_priv *priv); + +int fcs_get_atf_version (struct socfpga_fcs_priv *priv,u32 *version); + +/* Perform an SDOS (Secure Data Object Service) encrypt/decrypt operation. */ +int fcs_sdos_crypt (struct socfpga_fcs_priv *priv,struct fcs_sdos_req *req); + +#endif /* SOCFPGA_FCS_H */ include/uapi/misc/socfpga-fcs-crypto.h new file +4
-0@@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ +/* +* Description: +* This driver is developed for the SDM SoCFPGA Crypto Service (FCS). It
include/uapi/misc/socfpga-fcs-crypto.h line 14
Quoted 10 lines
include/uapi/misc/socfpga-fcs-crypto.h new file +10
-0+* 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>
Also don't need these.
Dinh