Skip to content

crypto: add direct SG2002 transport for OpenSSL - #507

Merged
dormancygrace merged 11 commits into
mainfrom
codex/openssl-sg2002
Oct 27, 2026
Merged

dormancygrace merged 11 commits into
mainfrom
codex/openssl-sg2002

Conversation

@dormancygrace

@dormancygrace dormancygrace commented Oct 26, 2026 •

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.

Cache successful capability/ABI probes and permanent absence, permission and protocol failures. Each operation owns its close-on-exec descriptor; there is no descriptor cache or userspace mutex crossing fork/provider unload. Requests use private state/output until successful completion, so late copy failures cannot corrupt in-place input before software fallback. Interruptions and temporary resource failures permit later attempts. Hashes avoid the cipher/Base64 output-scratch frame. Public libc secure_getenv also works when the transport is linked into the legacy provider; caches are per library image.

Validation: clean OpenSSL 3.5.9 C906/O3 build; host ASan/UBSan fault tests cover 77 submissions across all seven transport algorithms, capability/ABI/poison checks, descriptor lifecycle and retry/disable behavior. A negative control catches writes directly to caller output. Final native algorithm integration with DMA on/off passes 1944 block, 864 SHA, 288 CTR, 408 AEAD and 2160 extended GCM cases per mode, plus upstream vectors. Private OpenSSH preauth checks pass with denied hardware access.

Three native 10,000-iteration measurements of the final transport put open/close at 17.1 us, cached begin/end at 25.8 us and a 4 KiB SHA-256 RUN on a held descriptor at 22.5 us of CPU. Full fetched-EVP SHA-256 costs 96.6 us, versus 118.7 us with legacy method lookup on each init. Raw JSONL, an own-child syscall trace, reproducible helpers and binary identities are in firmware/crypto/experimental/openssl-sg2002/. The trace confirms one device open/fstat/INFO/RUN/close for a cold hash; its ptrace wall times are not native syscall latencies. A permanent descriptor is not introduced because its module lifetime, fork and sandbox behavior need separate qualification.

Stacked on #506. Each algorithm retains its own OpenSSL patch, native profitability threshold and correctness/RAM evidence.

@github-actions

github-actions Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Build outputs

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

4 changed, 1 added, 0 removed of 595 outputs.

directory files
changed server server/NanoKVM-Server
changed tools tools/openssl/usr/lib/libcrypto.so.3
tools/openssl/usr/lib/ossl-modules/legacy.so
tools/openssl/usr/share/nanokvm/openssl/source.json
added tools tools/openssl/usr/share/licenses/nanokvm-openssl/C906-BSD-3-Clause.txt
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
Comment thread firmware/crypto/openssl-c906/0002-sg2002-transport.patch Outdated
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.

@dormancygrace
dormancygrace marked this pull request as ready for review October 27, 2026 09:30

@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.

Re-reviewed at 5a1f8b3. The session-cost data answers my per-call question:

CPU per call
open + close 17.1 µs
cached begin + end 25.8 µs
4 KiB SHA-256 RUN, fd held 22.5 µs
full 4 KiB EVP SHA-256 96.6 µs

Keeping descriptors operation-owned is your call, and the thresholds now include that cost. No further requests on the transport.

One consequence for the algorithm patches: once an operation holds the fd, each further RUN costs only the RUN. #511 already uses this through continuation_minimum. SHA-256 (#508) and DES/TDES (#512/#513) do not yet; details are in those reviews.

@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.

Reviewed the final head a6c9d4c7ef0314416437d128a84e775f15dc2f6f. No new blocking findings.

Rechecked operation-owned CLOEXEC descriptors, cached ABI/capabilities, permanent versus retryable errors, and transactional output/state handling after late copy failure. The transport sanitizer suite passes 77 submissions across seven algorithms; the negative control detects writes to caller output before successful completion.

The previously documented native descriptor cost remains included in the algorithm thresholds. Current main and the parent ChaCha branch are integrated; the transport patch is unchanged. Existing resolved findings remain addressed.

All 18 fast checks pass on this head; the full firmware build is still running with no reported failure.

Base automatically changed from codex/openssl-chacha20 to main October 27, 2026 14:08
@dormancygrace
dormancygrace merged commit 7d15b0c into main Oct 27, 2026
19 checks passed
@dormancygrace
dormancygrace deleted the codex/openssl-sg2002 branch October 27, 2026 14:09
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