Skip to content

crypto: add direct SG2002 transport for OpenSSL - #507

Draft
dormancygrace wants to merge 9 commits into
codex/openssl-chacha20from
codex/openssl-sg2002
Draft

dormancygrace wants to merge 9 commits into
codex/openssl-chacha20from
codex/openssl-sg2002

Conversation

@dormancygrace

Copy link
Copy Markdown
Owner

Add a shared direct SG2002 ioctl client for the separate OpenSSL algorithm patches. It uses the existing /dev/sg2002-aes-probe version-1 ABI, without cryptodev or ENGINE. This transport-only patch enables no hardware algorithm by itself.

Each bulk operation owns its descriptor and capability check. Requests use private state/output until successful completion, so late copy failures cannot corrupt in-place input before software fallback. There is no cached descriptor or userspace mutex to inherit across fork/provider unload. Controller errors disable further hardware use in the process; interruptions and temporary failures permit later attempts. Hashes avoid the cipher/Base64 output-scratch frame.

Validation: clean OpenSSL 3.5.9 RISC-V cross-build without warnings; host ASan/UBSan fault tests exercise 56 submissions across all seven hardware algorithms, capability/ABI/poison checks, fd lifecycle and retry/disable behavior. A negative control proves the tests reject direct writes to caller output. CI runs these tests and the ChaCha assembly reproducibility check.

Stacked on #506 for the patch application infrastructure. Draft pending physical device integration tests in the per-algorithm PRs. Each algorithm gets its own OpenSSL patch, correctness/threshold/RAM evidence and PR.

@github-actions

github-actions Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Build outputs

Compared with the build of main at 2571baa; codex/openssl-chacha20 is at 6ce28df, so outputs changed since then are listed too.

4 changed, 159 added, 145 removed of 584 outputs.

directory files
changed opensbi opensbi/build-manifest.json (records the hash of platform/build.sh)
changed server server/NanoKVM-Server
server/nkos-update
changed web web/index.html
added tools 14 files
added web 145 files
removed web 145 files
Hashes: outputs-sha256 artifact of this run.

@dormancygrace dormancygrace left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found no memory-safety or crypto-correctness issue in the transport.

  • The ABI header is a byte-exact copy of the kernel one.
  • The struct sizes match.
  • The host transport test and its negative control pass.
  • Mutating transaction() shows the test catches real failure-path bugs.

One more point, beyond the inline comments: once the module is loaded, every root process using this libcrypto offloads by default. The only switch is NANOKVM_OPENSSL_DMA=off in each process's environment. CryptoDMA running next to the H.265 encoder used to hang the SoC. Write burst 4 in the kernel module fixed that, but this new userspace path has no measurement with concurrent video yet. Until it does, please consider a system-wide switch (for example honouring /etc/kvm/disable_hardware_aes) or default-off.

A question: sg2002_aes_probe.c still describes itself as an "Experimental" diagnostic backend and says it is not a production driver. Now that libcrypto depends on /dev/sg2002-aes-probe, is its ioctl ABI a stable userspace contract? If so, the module description should say so.

Comment thread firmware/crypto/openssl-c906/0002-sg2002-transport.patch Outdated
+ || !CRYPTO_THREAD_run_once(&once, init_options) || disabled
+ || atomic_load_explicit(&failed, memory_order_relaxed))
+ return -1;
+ fd = open("/dev/sg2002-aes-probe", O_RDWR | O_CLOEXEC);

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every operation does open + fstat + SG2002_CRYPTO_INFO + close before RUN. In the driver, INFO takes the same global mutex as an in-flight DMA request, which SRTP and the kernel GCM path also hold. So even an attempt that ends in software fallback queues behind video-call traffic.

Negative results are not remembered either. The device is mode 0600, so every non-root operation repeats a failing open, as does every operation in a system without the module.

Capabilities and ABI never change while the module is loaded, and RUN already reports poison as EIO. Could the INFO result and permanent failures (ENOENT, EACCES, ABI mismatch) be cached process-wide, keeping only the fd per operation? Otherwise, please include this cost when the per-algorithm thresholds are measured.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented positive capability/ABI caching and permanent negative caching in f5c9efe. Steady-state operations no longer issue INFO or acquire the driver mutex for that query. ENOENT/EACCES/protocol failures are remembered; EMFILE/EINTR remain retryable. Each operation still owns its close-on-exec descriptor, so no shared descriptor or new userspace lock crosses fork/provider unload. Concurrent first probes may repeat INFO; subsequent calls use the atomic capability mask. The sanitizer/fault suite verifies these cache transitions and descriptor closure.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With INFO cached, the remaining per-operation work is open + fstat + RUN + close. The later PRs measured a large fixed cost per call, at heads that predate f5c9efe. Converting their MiB/CPU-s figures into time per call:

The driver comment puts one spinning 1216-byte RUN at about 19 µs. f5c9efe removed one ioctl and its mutex wait, which cannot account for tens of microseconds. So most of the fixed cost should remain: open/close plus EVP and provider setup. Please measure begin/end alone (10k iterations, plus strace -T on a 4 KiB hash) to split the two.

If open/close dominates, the structural fix is one O_CLOEXEC fd per library image. That is a real decision for you: it pins the module against rmmod, and it brings back the fork/unload handling you avoided on purpose. If the fixed part falls substantially, the SHA-1 crossover and the 2–2.5 KiB AES cutoffs should drop accordingly (my estimate).

Comment thread firmware/crypto/openssl-c906/0002-sg2002-transport.patch Outdated

@dormancygrace dormancygrace left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for f5c9efe. It addresses most of my earlier points: secure_getenv is now in 0002, INFO is cached after the first successful probe, and permanent failures (ENOENT/EACCES/ENOTTY/EINVAL/EMSGSIZE, among others) are latched. I resolved those threads.

What remains per operation is open + fstat + RUN + close; details in the reply on the open/INFO thread.

Two smaller questions:

  • Latched ENOENT and EACCES last for the library image. A long-lived process that starts before the sg2002 module is loaded never uses DMA. Is the module guaranteed to be loaded before such daemons start, or should an ENOENT latch expire after some time?
  • System-wide switch. One is still missing. INFO already carries the algorithm mask that this transport honours, so a module parameter that masks bits of that field would give an admin-controlled off switch for new processes, with no file read in userspace.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant