Skip to content

feat(tls): add an aws-lc backend behind CAN_HUB_TLS_BACKEND - #176

Merged
jamofer merged 10 commits into
mainfrom
feat/awslc-tls-backend
Aug 4, 2026
Merged

feat(tls): add an aws-lc backend behind CAN_HUB_TLS_BACKEND#176
jamofer merged 10 commits into
mainfrom
feat/awslc-tls-backend

Conversation

@jamofer

@jamofer jamofer commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

What

Add AWS-LC as a selectable TLS backend: -DCAN_HUB_TLS_BACKEND=awslc. OpenSSL stays the default and is untouched.

Why

Roadmap §4. OpenSSL is 90% of a release binary — 4.62 MB of the 5.11 MB of symbols in can-hub-agent, measured by intersecting the binary's symbols with the archives'. That matters for the device-side agent.

The roadmap picked wolfSSL. That recommendation was wrong and this PR does not implement it: it judged the licence against the AGPL arm only, and can-hub is dual-licensed (README.md, LICENSE.commercial). wolfSSL is GPLv3, so a commercial licensee would need their own wolfSSL licence. GnuTLS falls the same way — LGPLv2.1+, and its mandatory GMP is LGPLv3/GPL-2+, which does not survive static linking into a proprietary product.

AWS-LC is Apache-2.0 OR ISC, so it works in both arms.

Results

OpenSSL AWS-LC
can-hub-agent, stripped 6.66 MB 1.90 MB (−71%)
Dependency build, cold 58s 48s
Changes to our TLS code 3 lines behind an #if
Cross-compile manual arch mapping + a CMAKE_SIZEOF_VOID_P workaround plain CMake

Most of the size win is configuration, not the library: -ffunction-sections+--gc-sections (which the tree only applied to its own sources, and only in the static profile) takes it to 3.61 MB, and AWS-LC's OPENSSL_SMALL to 2.13 MB. That is wolfSSL territory (1.88 MB) without the licence.

How

quic_tls_backend.h absorbs the shape difference between ngtcp2's two backends — the ossl one wraps each session in a context object and needs a global init, the boringssl one configures the SSL_CTX once and uses the SSL as the native handle. Identity minting moves to tls_identity_openssl.c behind tls_identity_backend.h; AWS-LC reuses it unchanged.

The one real incompatibility: BoringSSL forks leave ED25519 out of their default signature preferences, so two ED25519 identities fail with NO_COMMON_SIGNATURE_ALGORITHMS before certificate verification ever runs. It is asked for explicitly on both sides. This cost a while to find because the symptom was a silent HANDSHAKE_FAILURE_ON_CLIENT_HELLO and openssl s_client handshakes fine against the same server.

Testing

  • make test green (412) on both backends
  • e2e suite 56/56 against AWS-LC (CAN_HUB_BIN_DIR=build/awslc-final)
  • Interop matrix, all four combinations with TOFU pinning: AWS-LC↔AWS-LC, AWS-LC↔OpenSSL, OpenSSL↔AWS-LC, OpenSSL↔OpenSSL — a mixed fleet works, so this can roll out gradually
  • TLS-over-TCP and QUIC both verified

One e2e test, Socketcand Write Burst, failed on the first AWS-LC run at 393/400. It is pre-existing flakiness, not a regression: OpenSSL fails it too (395/400 on one of two runs) while AWS-LC passed 400/400 twice. The final full run is 56/56.

Notes

Not done here, and needed before AWS-LC could become the default: cross-compile arm64/armhf, the CAN_HUB_STATIC profile, and the Windows build. Rather than leave those as silent surprises, CAN_HUB_TLS_BACKEND now rejects an unknown value and refuses the two combinations that are not wired up, instead of quietly building OpenSSL because CAN_HUB_STATIC is evaluated first.

Under AWS-LC the verify preferences list ED25519 alone, so that build will not accept a peer certificate signed with anything else. Every identity this project mints is ED25519, so it is a tightening rather than a restriction — but it is an asymmetry with the OpenSSL build, which accepts the stack defaults.

Review of the first CI run caught a real regression this PR introduced: TlsIdentity_FingerprintOfPeer, extracted to deduplicate the peer-fingerprint code, existed only in the linux tree while tls_channel.c is shared with windows. The windows cross-build failed to link; it now has the same helper and builds.

wolfSSL was built, ported and measured before the licence ruled it out; that work is not in this diff, only in the branch history.

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