Linux Documentation
 help / color / mirror / Atom feed
From: hang.suan.wang@altera.com
To: Dinh Nguyen <dinguyen@kernel.org>,
	linux-kernel@vger.kernel.org, Jonathan Corbet <corbet@lwn.net>,
	Shuah Khan <skhan@linuxfoundation.org>,
	Randy Dunlap <rdunlap@infradead.org>,
	Jonathan Cameron <jic23@kernel.org>,
	Svyatoslav Ryhel <clamor95@gmail.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Ethan Nelson-Moore <enelsonmoore@gmail.com>,
	Pasha Tatashin <pasha.tatashin@soleen.com>,
	Jakub Kicinski <kuba@kernel.org>,
	Giovanni Cabiddu <giovanni.cabiddu@intel.com>,
	Jiri Slaby <jirislaby@kernel.org>,
	Suren Baghdasaryan <surenb@google.com>,
	Gabriel Whigham <gabewhigham@gmail.com>,
	Will Deacon <will@kernel.org>, Kiryl Shutsemau <kas@kernel.org>,
	Douglas Anderson <dianders@chromium.org>,
	Chen-Yu Tsai <wenst@chromium.org>,
	"Michael S . Tsirkin" <mst@redhat.com>,
	Thomas Zimmermann <tzimmermann@suse.de>,
	Huacai Chen <chenhuacai@kernel.org>,
	linux-doc@vger.kernel.org
Cc: muhammad.nazim.amirul.nazle.asmade@altera.com,
	tze.yee.ng@altera.com, chee.nouk.phoon@altera.com,
	genevieve.chan@altera.com, adrian.ho.yin.ng@altera.com
Subject: [PATCH v9 0/3] Add Altera SoCFPGA Crypto Service (FCS) driver
Date: Thu,  5 Nov 2026 09:17:09 -0800	[thread overview]
Message-ID: <cover.1793895849.git.hang.suan.wang@altera.com> (raw)

From: Hang Suan Wang <hang.suan.wang@altera.com>

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 and SMMU IOVAs are passed to the SDM.

The caller opens one SDM crypto session with FCS_IOC_OPEN_SESSION and
closes it with FCS_IOC_CLOSE_SESSION. SDOS commands use that session and
do not open or close it. The session belongs to the file that opened it:
another file cannot use it or close it. Closing that file, including when
the process exits, closes the session in the driver's release path. The
SDM allows one session at a time. Each command takes the device lock, so
only one request is in flight, and the kernel gives each command a new
context ID. That ID is not part of the user ABI.

This is the session model later FCS commands will use, so a key imported
in a future series stays alive until the caller closes the session. Those
commands are not in this series. The ioctls are usable on their own. This
series does not add a daemon in the kernel or require one in userspace.

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 payloads are 32 to 32,672 bytes. Trusted keys wrap key
   material, which is far smaller, 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. It is a misc device (/dev/socfpga-fcs).
   FCS_IOC_OPEN_SESSION and FCS_IOC_CLOSE_SESSION manage the SDM crypto
   session. FCS_IOC_SDOS encrypts or decrypts on that session.

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 64-byte plaintext:

   root@agilex5e:~# hexdump random_payload_bin2.bin
   0007cc0 a5e3 b39e cd9a 86de b3e7 d035 ad6f 6b4a
   0007cd0 1327 9672 25ec 1947 d98e e61e 9b2d 594d
   0007ce0 0474 29a2 fd28 e5a2 4a4b b608 6271 7e3d
   0007cf0 5c61 c2d1 4c7e 7aa6 e347 10b7 9aae 5439

   root@agilex5e:~# ./fcs_client -e
   root@agilex5e:~# ./fcs_client -E -i random_payload_bin2.bin -o
                    random_payload_encrypted_bin2.bin -v
   root@agilex5e:~# ./fcs_client -D -i random_payload_encrypted_bin2.bin -o
                    random_payload_decrypted_bin2.bin -v
   root@agilex5e:~# ./fcs_client -l

   root@agilex5e:~# hexdump -C random_payload_decrypted_bin2.bin
   e3 a5 9e b3 9a cd de 86  e7 b3 35 d0 6f ad 4a 6b  |..........5.o.Jk|
   27 13 72 96 ec 25 47 19  8e d9 1e e6 2d 9b 4d 59  |'.r..%G.....-.MY|
   74 04 a2 29 28 fd a2 e5  4b 4a 08 b6 71 62 3d 7e  |t..)(...KJ..qb=~|
   61 5c d1 c2 7e 4c a6 7a  47 e3 b7 10 ae 9a 39 54  |a\..~L.zG.....9T|

---
Changes since v8:
 - Rework the FCS core into a command engine,
   socfpga_fcs_core_engine(), that takes per-command parameters.
   The caller supplies a fresh context ID for each command.
 - Poll for async completion instead of registering a service-layer
   callback, fixing a race on the shared completion.
 - Fix a NULL dereference in the ATF version callback when the
   response carries no payload.
 - Return -ETIMEDOUT when a request times out; only busy and
   no-response statuses are retried until the deadline.
 - Reject an SDOS op_mode other than 0 or 1 with -EINVAL instead of
   passing it to the firmware.
 - Report the SDM status in error_code even when a request fails.
 - Update the ioctl and ABI documentation, including the errno table.

Changes since v7:
 - Give the caller the session lifecycle. FCS_IOC_OPEN_SESSION opens one
   SDM crypto session. FCS_IOC_CLOSE_SESSION closes it. SDOS no longer
   opens or closes the session, including when a request fails.
 - Bind the session to the file that opened it. Another open returns
   -EBUSY. Use or close from another file returns -EPERM.
 - Close the session from the file release path, so process exit still
   tears it down.
 - Generate a new context ID for each command. It remains internal to
   the kernel.
 - Document the session lifecycle, and split EBUSY and EPERM in the
   ioctl and ABI docs.

Changes since v6:
 - Add proper support for the two SDOS address forms required by the SDM:
   pass the physical address backing each buffer separately from its
   SMMU-remapped IOVA.
 - Resolve DMA IOVAs through the device IOMMU domain with
   iommu_iova_to_phys(), and reject physical addresses outside the SDM's
   32-bit addressable range.
 - Allocate FCS service buffers with DMA_ATTR_FORCE_CONTIGUOUS on the SMMU
   path so their backing memory is reachable by the SDM; track allocation
   attributes and use matching dma_free_attrs().
 - Mark only the FCS service channel as requiring physically reachable
   contiguous allocations.
 - Rebase onto the current upstream stratix10-svc implementation and update
   FCS child-device registration and cleanup.
 - Convert FCS core logging to device-scoped dev_*() messages.
 - Update the MAINTAINERS mailing list and Makefile placement.

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 feature

 .../sysfs-devices-platform-stratix10-fcs      |  21 +
 Documentation/misc-devices/index.rst          |   1 +
 Documentation/misc-devices/socfpga-fcs.rst    | 231 +++++
 .../userspace-api/ioctl/ioctl-number.rst      |   2 +
 MAINTAINERS                                   |  11 +
 drivers/firmware/Kconfig                      |  17 +
 drivers/firmware/Makefile                     |   2 +
 drivers/firmware/socfpga-fcs-core.c           | 856 ++++++++++++++++++
 drivers/firmware/socfpga-fcs.c                | 297 ++++++
 drivers/firmware/stratix10-svc.c              | 184 +++-
 include/linux/firmware/intel/socfpga-fcs.h    | 168 ++++
 include/linux/firmware/intel/stratix10-smc.h  |  64 ++
 .../firmware/intel/stratix10-svc-client.h     |  16 +-
 include/uapi/misc/socfpga-fcs-crypto.h        | 136 +++
 14 files changed, 1994 insertions(+), 12 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-devices-platform-stratix10-fcs
 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

-- 
2.43.7


             reply	other threads:[~2026-11-05 17:17 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-05 17:17 hang.suan.wang [this message]
2026-11-05 17:17 ` [PATCH v9 1/3] firmware: stratix10-svc: increase args array hang.suan.wang
2026-11-05 17:17 ` [PATCH v9 2/3] firmware: stratix10-svc: add FCS crypto-service commands for Agilex 5 hang.suan.wang
2026-11-05 17:17 ` [PATCH v9 3/3] firmware: socfpga-fcs: add Altera SoCFPGA FCS driver with SDOS feature hang.suan.wang

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=cover.1793895849.git.hang.suan.wang@altera.com \
    --to=hang.suan.wang@altera.com \
    --cc=adrian.ho.yin.ng@altera.com \
    --cc=akpm@linux-foundation.org \
    --cc=chee.nouk.phoon@altera.com \
    --cc=chenhuacai@kernel.org \
    --cc=clamor95@gmail.com \
    --cc=corbet@lwn.net \
    --cc=dianders@chromium.org \
    --cc=dinguyen@kernel.org \
    --cc=enelsonmoore@gmail.com \
    --cc=gabewhigham@gmail.com \
    --cc=genevieve.chan@altera.com \
    --cc=giovanni.cabiddu@intel.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jic23@kernel.org \
    --cc=jirislaby@kernel.org \
    --cc=kas@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mst@redhat.com \
    --cc=muhammad.nazim.amirul.nazle.asmade@altera.com \
    --cc=pasha.tatashin@soleen.com \
    --cc=rdunlap@infradead.org \
    --cc=skhan@linuxfoundation.org \
    --cc=surenb@google.com \
    --cc=tze.yee.ng@altera.com \
    --cc=tzimmermann@suse.de \
    --cc=wenst@chromium.org \
    --cc=will@kernel.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