Skip to content

crypto: offload OpenSSL DES ECB and CBC to SG2002 - #512

Closed
dormancygrace wants to merge 15 commits into
codex/openssl-aesfrom
codex/openssl-des
Closed

dormancygrace wants to merge 15 commits into
codex/openssl-aesfrom
codex/openssl-des

Conversation

@dormancygrace

@dormancygrace dormancygrace commented Oct 26, 2026 •

Copy link
Copy Markdown
Owner

Use direct SG2002 DMA for DES ECB/CBC whole-block prefixes from 1536 B; keep the existing C906/O3 software below that size and after hardware absence/failure. OpenSSL retains padding, buffering and IV continuation. No cryptodev, ENGINE or new software assembly is added.

The shared helper's initial and continuation thresholds are explicit; DES retains 1536 B for both. Context size grows from 328 to 336 B for the retained hardware key, with operation-local output scratch. Historical three-rotation threshold-selection data and exact identities are committed and labelled separately from the final restricted-ISA integration checks.

The final stack after the AES parent update passes native DMA-on/off block, SHA, CTR, GCM and upstream vectors, including 1944 block cases and 20,736 independent AES tail/IV cases. Legacy provider loading is verified; its transport uses public libc secure_getenv rather than a private libcrypto symbol. Host sanitizer tests cover committed prefixes, in-place CBC, IVs, first/later failures and descriptor lifetime. native-final-validation.json pins the tested libcrypto, legacy provider and all patches.

Stacked on #511. Triple DES remains separate in #513.

@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 provider-policy change: single DES stays in the legacy provider, and 3DES and SHA-1 stay where they were. The CBC chaining and the software tail are correct.

Comment thread .github/workflows/ci.yml
run: python3 firmware/crypto/experimental/openssl-aes/test-blocks.py
- name: OpenSSL block-mode EVP reference
run: |
cc -O1 -g -Wall -Wextra -Werror -fsanitize=address,undefined firmware/crypto/experimental/openssl-des/verify.c -lcrypto -o /tmp/openssl-block-verify

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.

This links the host libssl-dev, which contains none of these patches, and the patched code is __riscv-only anyway. So the step passes regardless of the DMA code. It is useful as a pin of the test vectors, but please name it that way, and do not count its 1944 cases as coverage of the offload.

The real check is running verify.c on the device against the patched libcrypto, once with DMA enabled and once with NANOKVM_OPENSSL_DMA=off, and comparing the fingerprints.

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.

Still open: this step still links the host libcrypto. If a real check is wanted, cross-build the patched tree and run verify.c under qemu-riscv64 with no device node, which also covers the software fallback path.

Comment thread firmware/crypto/openssl-c906/0006-des-dma.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.

The code is fine, and the 1536 B minimum is conservative. A two-point fit of the README numbers gives about 96 µs per call plus about 13 ns/B, so DMA breaks even near 1 KiB (my estimate). The transport fix moved to 0002, so I resolved that thread. The CI step is still open.

DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks);
+
+#if defined(__riscv) && __riscv_xlen == 64 && !defined(FIPS_MODULE)
+ if (len >= 1536) {

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.

Who calls single DES with at least 1.5 KiB on this device? It is reachable only through the legacy provider. The usual legacy users (MS-CHAPv2 or NTLM challenge/response, PBES1 in PKCS#12) work on 8–64 bytes and never reach the cutoff. build-openssl.py applies every *.patch, so merging this ships the offload, an extra raw key copy per context, and another requalification at every OpenSSL bump. Unless there is a named consumer, please keep 0006 out of the production patch directory (for example under experimental/) or drop it.

If it stays, please define the minimum once: 1536 appears twice per function, and ossl_sg2002_cipher already rejects len < minimum, so the outer if can go.

passes. Native provider loading, EVP vectors, DMA counters, throughput and RAM
measurements are pending; no speedup is claimed.

Native C906: the integrated 1944-case block-mode test and upstream DES vectors pass. Three rotated trials found only a small gain at 1 KiB, but DES-CBC decryption at 1536 bytes reached 12.54 versus 8.86 MiB/CPU-s upstream; at 16 KiB, 49.95 versus 9.48. The measured DMA minimum is 1536 bytes. The O3 software core already unrolls all rounds and uses C906 extraction, rotate and indexed-load instructions; no replacement software implementation has been selected.

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.

This paragraph contradicts lines 6 and 20 ("1024-byte minimum is pending", "no speedup is claimed"). openssl-c906/README.md still calls 1 KiB unqualified. Please keep one statement. The 1536 B value rests on CBC decryption only; please add ECB and CBC encryption, and commit the raw trials.

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.

The experimental README is fixed, but firmware/crypto/openssl-c906/README.md (DES section) still says "The initial 1 KiB threshold remains unqualified", while the patch uses a measured 1536. Please update that line; then this can be resolved.

@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-aes is at 84de85e, 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.

Re-reviewed at 6ac974a.

  • Continuation floor: both calls pass 1536, 1536, so every later chunk must again exceed the session minimum. From #507, a RUN with the fd already held costs about 22.5 µs (measured for 4 KiB SHA-256). DES software runs at about 9.5 MiB/CPU-s, so 22.5 µs covers only about 220 bytes. A floor equal to the initial minimum throws away the session cost already paid. Please use a measured continuation value, or at least AES's 512.
  • Stale README line: see the reply in the README thread.
  • CI: the new "block-mode EVP reference" step also links host libcrypto, so the CI thread stays open. Like #508, it is not blocking.
  • The small-size regression with DMA off (DES-CBC encrypt at 64 B: 3.22 → 2.74) is covered in the #509 review.

@dormancygrace

Copy link
Copy Markdown
Owner Author

Owner decision (2026-10-27): single DES has no consumer on the device, so this offload is dropped. Closing. The shared block-mode verifier in experimental/openssl-des/verify.c is still cited by #511; see the note there.

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