Repository navigation
crypto: optimize C906 AES and add measured SG2002 offload - #511
Conversation
dormancygrace
left a comment
There was a problem hiding this comment.
The CBC and CTR IV logic and the GCM 32-bit wrap split are correct against both the kernel driver and OpenSSL.
There is one correctness assumption that nothing verifies yet, and the provider glue is not covered by any test. I'd treat both as gates for leaving draft.
Build outputsCompared with the build of main at 6c78048; codex/openssl-sha256 is at 06f3d60, so outputs changed since then are listed too. 4 changed, 1 added, 0 removed of 595 outputs.
|
A more efficient AES-GCM design for this offloadSplitting GCM into its parts shows where the time goes on the SG2002, and why offloading only the CTR stream through
So GHASH is the bottleneck, not AES. The current patch has three structural costs on top of that:
The kernel already contains the efficient version of this: Proposal, in order of value1. Use the C906 GHASH in OpenSSL first, independent of the device. Generate an OpenSSL-ABI variant of the 0041 GHASH ( 2. Offload a whole record with a single ioctl that reuses the kernel's overlapped path. Add a A split 3. Keep the device handle per process. Open once ( 4. Choose the threshold from measurements of the final design. Compare it against step 1 alone at 1.4, 4 and 16 KiB, with and without concurrent H.265 video, and against the SRTP latency the engine mutex adds. With an overlapped record call, the crossover against software GCM should sit well below 1 KiB of data, but that needs measuring. Expected result. Software AES-GCM in OpenSSL becomes bounded by the faster GHASH (about 3× on that part). The device path approaches the in-kernel |
|
The serialized CTR/GHASH path and the 3 KiB stream-call boundary are real limitations. The current transport now caches INFO/ABI and permanent errors (f5c9efe); descriptors remain operation-owned. The combined AES/GHASH path needs to address both TLS versions before its crossover can replace the current thresholds. Two source/measurement details change the proposed implementation:
The correctness questions now have native evidence as well. The physical engine carries the full 128-bit CTR counter for AES-128/192/256, including carries into byte 11, byte 7 and the all-ones-minus-two vector. The new boundary split still removes that hardware-width dependency. The current integrated build (7b8c071; libcrypto SHA-256 |
dormancygrace
left a comment
There was a problem hiding this comment.
Thanks for b4efcf2.
- CTR carry: every CTR request is now split before the low 32-bit wrap, so correctness no longer depends on the engine's carry.
verify-ctr.c --raw-onlywill also show what the engine actually does. - GCM tests:
verify-gcm.cadds context copy, in-place operation and rejected tag/ciphertext across the 1/2/3/4 KiB cuts.
I resolved those two threads. The native run of the new suites is still pending, as the README says.
The indexed-load change is correct. th.lrwu rd,tbl,idx,0 is the same zero-extended load as add + lwu, from the same table addresses, so the leakage profile is unchanged; it is still T-table AES. The measured +17–21% matches one instruction fewer per lookup.
The DMA cutoffs are mostly set by the transport's per-call cost (see #507). Concrete suggestions follow inline.
dormancygrace
left a comment
There was a problem hiding this comment.
Re-reviewed at 84de85e. No blocking issues.
- Separate patch:
0005-aes-c906.patchnow holds the table-load change. I checked the fast path against upstreamdo_lookup:th.extu Ts,Qs,shamt+7,shamt+th.lrwu ...,2isTable[(Q >> shamt) & 0xFF].do_lookup_bytekeeps the ×4 stride withth.lrbu. Td4 uses bytes[8i+7:8i]with stride 1. Register-ordering constraints are unchanged from upstream. - cpp in the
.Srename: the only two# ifcomments inaes-riscv64.pl(lines 816/824 of 3.5.9) are converted. No other comment line looks like a directive. continuation_minimumapplies the session minimum only to the first chunk, as suggested. The GCM ctr32 path passes 2048/512, andverify-tails.ccovers 4096+16…3072 tails, offsets and in-place for all three modes.- Tail thread: accepted, see the reply there.
|
Restack needed: the owner dropped the SHA-1 (#509), DES (#512) and TDES (#513) offloads, since nothing on the device uses them. #512 and #513 are closed.
The environment fix that #512's 0006 carried is already in #507's 0002 ( |
84de85e to
9e3de10
Compare
dormancygrace
left a comment
There was a problem hiding this comment.
Addressed the scope cleanup request in head 9e3de10228a9e15cb4276e6e39585a62872cd211.
- The branch targets SHA-256 #508 directly. The SHA-1 commits, patch, qualification directory and CI step are absent. GHASH #527 follows this cleaned AES parent.
experimental/openssl-aes/verify.cpreserves the 972 AES cases from the shared verifier, with independently pinned OpenSSL 3.5.5 fingerprint019ff5988780130c. CI runs it under ASan/UBSan; it no longer requires the legacy provider.ossl_sg2002_cipheruses a fixed 16-byte block and accepts AES only. Non-AES IDs return before device access with output/IV unchanged. The legacy provider no longer links the DMA transport/helper.- All 15 final-head checks pass. Local validation includes 92,880 AES continuation cases, 960 dense CBC tail/failure cases, 25 GCM wrap cases, seven non-AES rejection cases, three helper negative controls, and EVP block/CTR/GCM/tail checks. A clean C906/O3 build applies all patches with zero fuzz and retains the same 5808 public exports.
scope-cleanup-validation.json records the new build and host checks. The earlier native performance, HTTPS and SSH results retain their original source/binary identities; native runs were not repeated for this cleanup. AES assembly, provider algorithms and thresholds are unchanged.
dormancygrace
left a comment
There was a problem hiding this comment.
Reviewed 432a9b47, including the incorporated SHA-256 fixes. The AES patches remain unchanged: AES-only acceptance, CBC in-place chaining, 128-bit CTR versus GCM low-32-bit carry, partial failures and continuation limits remain correct. The CI conflict resolution retains both the new SHA tests and every AES test.
Local validation passes: all five patches apply to the pinned OpenSSL source with zero fuzz; real C906 SHA arithmetic/wrapper tests, 92,880 sanitizer continuation cases, 960 dense-tail cases, 25 GCM wrap cases, seven rejected non-AES IDs and three negative controls. Independent host verifiers pass 972 AES, 2160 GCM, 288 CTR and 20,736 tail/output/IV cases. All fast final-head CI checks pass. No new AES correctness finding.
dormancygrace
left a comment
There was a problem hiding this comment.
Reviewed the final head 1db3b623bd0c9a35660d37f59d27b000c239e115. The corrected SHA-256 parent and current main are integrated; the AES implementation is unchanged.
Rechecked CBC decrypt IV preservation, low-32-bit CTR splitting, GCM counter rollover, continuation thresholds, provider context copies and scalar indexed-load equivalence. Local tests pass 92880 continuation cases, 960 dense CBC-tail cases, 25 GCM wrap/fault cases and seven non-AES rejections, with three negative controls.
Physical-device verification of the identical AES patches in the final GHASH candidate passes 972 AES, 408 AEAD, 2160 GCM split/copy/in-place/rejected-tag, 288 CTR-carry and 20736 tail/IV cases in each of generic, vector-only and vector-plus-DMA modes. No legacy SHA-1/DES/TDES offload was reintroduced. Existing resolved findings remain addressed; no new correctness issue found.
All 19 final-head CI checks pass, including the firmware build.
Speed up AES on C906 with a separately reviewable scalar patch and a bounded direct SG2002 DMA patch. OpenSSL keeps streaming, padding, GHASH, authentication and TLS; FIPS uses the unchanged fallback assembly. No cryptodev/ENGINE interface is added.
0005-aes-c906.patchuses byte extraction plus scaled indexed loads. Five native rotations show about 32–33% less CPU per AES block than upstream, with unchanged key setup and tables. Repeated EVP updates with an existing key improve even at 16 B: ECB 33–38%, CBC 17–27%, CTR 21–30% across key sizes/directions. Complete EVP calls that reinitialize a key for every 16–128 B operation can still regress; these results are published too.0005-aes-dma.patchselects initial minima against that faster software: 3072 B for ECB/CBC, 2048 B for CTR/GCM, and 512 B for a continuation on an already open descriptor. A 6000 B request now submits 4096+1904 B; a 16 B tail stays in software because another RUN loses there. The CTR/GCM minimum has one shared definition. Calls below the initial minimum skip the DMA helper, and request initialization happens only after validation and successful open.Recorded pre-cleanup three-rotation EVP results (MiB/CPU-s, baseline / patched software / patched DMA):
These use upstream software GHASH, without #527. The complete GCM numbers include five 3072 B DMA callbacks and a 1024 B software tail. A combined-record kernel API/persistent descriptor is a separate unselected experiment, not part of this implementation.
The common DMA cipher helper accepts AES only and rejects other algorithms before device access. SHA-1, DES, TDES and SM4 offloads are absent; the legacy provider no longer links the SG2002 transport. AES block verification is self-contained in
experimental/openssl-aes/verify.c: 972 cases, independent OpenSSL 3.5.5 fingerprint019ff5988780130c, exercised by CI.Current cleanup validation: 92,880 ASan/UBSan AES continuation cases, 960 dense tail/failure cases, 25 GCM counter-wrap cases and seven rejected non-AES IDs; three helper negative controls and an incorrect-fingerprint negative control. Host EVP checks pass 972 block, 288 CTR, 408 AEAD, 2160 GCM and 20,736 independent-output/IV tail cases. A clean C906/O3 build applies every patch with zero fuzz, removes the SHA-1 offload object and retains all 5808 public exports. Exact identities and results are in
scope-cleanup-validation.json.The earlier pinned native build passed DMA-on/off checks, upstream AES vectors, four real AES-128/256-GCM HTTPS downloads under TLS 1.2/1.3, and generic/FIPS fallback machine-code comparisons. Its original 1944-case verifier included the 972 AES cases now extracted. Native checks and timing were not repeated for this cleanup; raw historical reports retain their original source/library hashes. AES assembly, algorithms and thresholds are unchanged. Context sizes in those measurements are 472/984 B (AES/GCM), 24 B above pre-DMA contexts; no per-context output buffer.
Raw key-size × mode × direction trials from 16 B through 16 KiB, the experimental low-threshold sweep including 1024 B regressions, all source/binary identities and standalone harnesses are in
firmware/crypto/experimental/openssl-aes/. Stacked directly on SHA-256 #508; scalar and DMA changes are separate OpenSSL patches within this AES PR.The current head incorporates the SHA-256 continuation/CI fixes from #508. AES code and its thresholds are unchanged. Rechecked all five patches against the pinned source with zero fuzz, the real SHA assembly/wrapper, AES helper sanitizers and negative controls, and the independent AES/GCM/CTR/tail host verifiers. All fast final-head CI checks pass; the full firmware build is still running.