Repository navigation
crypto: add C906 ChaCha20 primitive to OpenSSL - #506
Conversation
Build outputsCompared with the build of main at 6c78048. 4 changed, 1 added, 0 removed of 595 outputs.
|
dormancygrace
left a comment
There was a problem hiding this comment.
I read the generated assembly against the generator, and it is consistent:
- the a0–a4 ABI and the callee-saved registers;
- the stack layout;
- the counter handling (
addiw,sw 48(a0)); - byte-wise
th.vle/th.vse, so alignment and in-place calls are fine.
The provider's split at the 32-bit counter wrap matches the tail call. verify.c passes its 1680 cases on x86.
The hardware qualification is pending as stated. My comments are about making that qualification conclusive.
dormancygrace
left a comment
There was a problem hiding this comment.
Follow-up at the current head.
- The generated assembly still checks out: s0–s11 are saved in a 416-byte frame, and the keystream is wiped.
- Patches 0001–0004 apply to 3.5.9 with zero fuzz, and the host tests pass.
- The length check before the helper is a good change.
The earlier comments on verify.c and on the /proc/cpuinfo parse still apply. I added a concrete option to each thread.
Poly1305 is now the larger half of this AEAD; OpenSSL has no RISC-V assembly for itWith the C906 ChaCha20 in place, the remaining ChaCha20-Poly1305 time in OpenSSL is mostly Poly1305. OpenSSL 3.5.9 has no Rough comparison on the C906 at 1 GHz. The three numbers come from different harnesses, so treat them as an order-of-magnitude comparison:
The kernel file is Andy Polyakov's CRYPTOGAMS perlasm. Its header says it was "initially for use with OpenSSL", and the license is
|
# Conflicts: # tests/README.md
|
The CRYPTOGAMS suggestion is distinct from the earlier Go-assembly experiment, so the earlier result does not reject it. I have built both the kernel perlasm's 64-bit path and its 32-bit arithmetic path for RV64 against the same OpenSSL profile. The existing There is a hardware-specific detail to include in the comparison: the C906 multiplier RTL chooses the short or iterative path from the operands' upper 32 bits. Thus wide For the ChaCha review, f5c23c6 uses the existing startup hwprobe, defines the 640-byte threshold once, adds a test-only counter at the actual assembly entry, and supplies component/overhead and seccomp tests. The production library still has 5808 dynamic definitions. Host dispatch sanitizer tests and negative controls pass; expanded native tests remain pending. The stack now includes current main, so the duplicate network fixture change is gone from #506. |
dormancygrace
left a comment
There was a problem hiding this comment.
Re-reviewed at c2d5592. No blocking issues.
- Detection: hwprobe key 11 (
RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0), bit 0 (XTheadVector), matches the v7.3 uapi. Withcpus=NULLit is the all-online-CPU intersection, and an unknown key comes back as -1, which leaves the path off. The flag is tested before the once/env check, so other CPUs pay one load. - Opt-in:
secure_getenv("NANOKVM_OPENSSL_CHACHA20") == "auto", generic otherwise.imageCurlEnv()keeps explicit operator values, andcurl_env_test.gocovers unset/generic/unknown/empty/auto. The downloader already pins ChaCha on its first attempt (curlImageArgs(..., true)), so the path really runs: about 15–17% less curl CPU innative-https-results.jsonl. - The entry counter in the assembly exists only under
NKOS_CHACHA_TEST. - 640-byte thread: accepted, see the reply there.
One stack-wide observation is in the #509 review: the patched libraries are slower than the base at small sizes even with every new path off. The 64-byte ChaCha row here (6.39 vs 6.84) fits the same pattern.
dormancygrace
left a comment
There was a problem hiding this comment.
Reviewed the final head f5f992db168f0995fce20af11f2ab1da18025709. No new blocking findings.
Rechecked the generated assembly, 32-bit counter-wrap handling, 416-byte aligned frame, saved registers and keystream wipe. Startup hwprobe uses the all-online-CPU intersection; unknown capability, missing opt-in and disabled vector threads retain the upstream path. The downloader preserves explicit operator overrides. The earlier native qualification and timing remain attributed to their recorded builds.
Generator/encoding checks, real dispatch sanitizer tests and all three gate-removal negative controls pass, as do the downloader race tests. Integration with current main preserves both log-vector and Keccak CI checks without changing the ChaCha patch. Existing resolved findings remain addressed.
All 19 final-head CI checks pass, including the firmware build.
Add the shared C906 five-block ChaCha20 kernel to OpenSSL 3.5.9's existing primitive dispatch. The default provider retains AEAD, Poly1305, TLS and counter-limit handling. Other algorithms remain separate patches/PRs.
Calls of at least 640 bytes can use the kernel only with explicit
NANOKVM_OPENSSL_CHACHA20=auto, startup hwprobe confirmation of XTheadVector across online CPUs, and vector permission for the calling thread. The download service sets this opt-in for its curl child and preserves explicit operator overrides. Default/unknown/generic settings stay on upstream software without a per-cipher prctl. Direct libcsecure_getenvavoids musl's lazy UID/GID syscalls inside OpenSSH preauth seccomp. No cipher call reads cpuinfo or invokes hwprobe; denied/unknown hardware or thread gates fall back.Final physical C906 results (six rotated trials, current policy build):
Validation: 1680 native differential cases and 408 AEAD known-answer/rejected-tag cases; actual assembly entry counters (instrumented build only) across threshold, generic and vector-off/on threads; first-cipher seccomp tests killing file/probe/UID/GID calls and default-path prctl; six actual OpenSSH preauth cipher/request-size combinations; host ASan/UBSan dispatcher tests with three negative controls; Go download race tests and vet. Production retains 5808 dynamic definitions. Assembly regeneration and encoding checks pass.
Raw component, fixed-layout, syscall-overhead, HTTPS and memory data plus source/binary identities are in
firmware/crypto/experimental/openssl-chacha20/. The per-call prctl costs about 0.61 us in the isolated native measurement. Kernel Poly1305 alternatives were evaluated but are not included. Current main is integrated; the already-merged network fixture fix is absent from this diff.