Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Audit s2n-tls — relevé chiffré pour la contingence air-tls maison

Note de travail (2026-07-07). Objectif : mesurer s2n-tls (la meilleure pile TLS tout-C, AWS) pour outiller la décision sur la contingence air-tls maison (ADR-042 §Contingence) — ne pas vendorer, ne pas porter le C, mais connaître précisément ce qu’on reprendrait en couverture fonctionnelle si l’on activait l’option pur-Rust. Source analysée : aws/s2n-tls, tag effectif v1.7.5, commit 632eb7cef3eb72a3a5466c62896b9c2879f30295 (2026-07-02), clone shallow + approfondissement des tags. Analyse statique (compte de fonctions, LOC, assembleur, dépendances CMake) — aucun build lancé. Cette note ne tranche rien : elle alimente la spec docs/specs/layer-2/air-tls.md.

0. Pourquoi cet audit

ADR-042 a acté la pile de production (rustls + aws-lc-rs + rustls-webpki) et gardé ouverte une contingence maison (pur Rust, patron sans-IO). Pour instruire cette contingence de façon crédible, il faut savoir ce que couvre la référence tout-C la plus sûre : combien de surface, combien de code, combien d’assembleur, quelles dépendances, quelle maintenance. C’est l’objet de ce relevé, dont la spec air-tls tire son inventaire d’objets (~61) et son périmètre.

1. Volumétrie du code (cœur de bibliothèque, hors tests)

Dossier.c.hLignesRôle
tls/1259544 903 (75 %)protocole : handshake, record, extensions, state machine
crypto/29278 359wrappers vers libcrypto (PAS de crypto : ni primitive, ni asm)
utils/14214 054stuffer d’appoint, safety macros, mem
stuffer/711 784buffers de (dé)sérialisation bornés
error/11931codes + messages
Cœur17614560 031
api/ (headers publics)125 398s2n.h + 11 headers unstable/

~60 k lignes de C portable pour le cœur. Les tests (volumineux) ne sont pas embarqués.

2. Surface API publique — 303 fonctions (macro S2N_API)

Décompte robuste : les occurrences S2N_API (303) et les identifiants s2n_*(...) uniques (303) concordent exactement.

FamilleFnRôleObjet air-tls correspondant
s2n_connection_*91cycle de vie + état par connexionTlsClient/TlsServer
s2n_config_*75politique partagéeTlsClientConfig/TlsServerConfig
s2n_client_hello_*25introspection ClientHelloClientHello
I/O (send/recv/negotiate/shutdown/peek/sendv/sendfile…)16handshake + transfertTlsStream + cœur sans-IO
s2n_psk_* / s2n_offered_psk_*14pre-shared keys (1.3)Psk/OfferedPsk
init/mem/rand global (s2n_init, s2n_cleanup, s2n_mem_*, s2n_rand_*, s2n_errno…)14bootstrap process-widemajoritairement éliminé (RAII Rust : ni init/cleanup global, ni callbacks mem)
s2n_cert_chain_and_key_*12chaîne + clé privéeCertifiedKey
s2n_crl_*9listes de révocationCertificateRevocationList
s2n_fingerprint_*8JA3/JA4ClientHelloFingerprint
s2n_async_pkey_*8offload signature (HSM)AsyncSigner (trait)
s2n_cert_*7trust store / validationRootCertStore + ServerCertVerifier
s2n_certificate_*5accès aux champs X.509Certificate
s2n_offered_early_data_*40-RTTEarlyDataConfig
s2n_session_*3repriseSessionTicket/SessionStore
Total303~61 objets Rust (spec air-tls)

Fonctions internes : ~1 695 symboles s2n_* uniques définis dans le cœur .c (~1 751 blocs de définition). Ratio surface/interne ≈ 18 % exposé.

3. Assembleur pur — ZÉRO ligne (résultat structurant)

Recherche exhaustive sur tout le dépôt : 0 fichier .S/.s/.asm, 0 asm inline (__asm__/asm volatile/asm(). Tout l’assembleur crypto vit dans libcrypto (AWS-LC), jamais dans s2n-tls. s2n = C portable pur (-std=gnu99) qui orchestre le protocole et délègue 100 % des primitives.

Corrobore exactement ADR-042 : « protocole memory-safe + primitives formellement vérifiées ». En maison, on transpose : protocole pur Rust (air-tls) + primitives air-crypto (RustCrypto). Le « 0 asm » de s2n confirme qu’un port de protocole n’a pas à toucher d’assembleur — l’asm est un problème de primitives, réglé par air-crypto.

4. Architectures processeur

TierPlateformes CIArches
Tier 1 (build+tests garantis en CI)Ubuntu, Amazon Linux 2/2023, NixOS, OpenBSD, FreeBSD, macOSx86_64, aarch64, i686
Tier 2 (build garanti)Fedora, Ubuntu anciensx86_64, aarch64

Couvre les deux cibles jour-1 d’Air (x86_64 + ARM64, ADR-014). C portable → aucune dépendance d’architecture dans s2n lui-même (elle est dans libcrypto).

5. Cadence de mise à jour — très active

  • 169 tags de release. Rythme ~2 releases/mois : v1.7.5 (2026-06-24), v1.7.4 (2026-06-05), v1.7.3 (2026-05-04), v1.7.2 (2026-03-31)…
  • ~25 à 53 commits/mois sur 12 mois glissants (juin 2026 : 53). Équipe AWS financée, réponse sécurité rapide → fiabilité sur 10-20 ans (argument ADR-042 pour le provider aws-lc-rs).

6. Dépendances

  • libcrypto (obligatoire, enfichable) : AWS-LC (recommandé), OpenSSL 1.0.2/1.1.1/3.0.x, LibreSSL, BoringSSL. Aucun crypto vendoré dans s2n.
  • pthreads (find_package(Threads REQUIRED)).
  • Python3 : tests uniquement, pas à l’exécution.
  • Bindings Rust officiels : bindings/rust/ (crate s2n-tls) — pertinent si Air voulait wrapper s2n plutôt que le réécrire (option écartée par ADR-042 : le C du protocole reste exposé).

Fonctionnalités liées au provider : PQ key exchange + FIPS + sandboxing = AWS-LC uniquement.

7. Toolchain Linux

  • Build system : CMake (préféré ; Makefile en repli). Standard -std=gnu99.
  • Compilateur : gcc ET clang supportés et testés en CI (matrice ~5 clang / 3 gcc). clang privilégié pour sanitizers/fuzzing.
  • Provider recommandé : AWS-LC (perf + sécurité + FIPS 140-3 + PQ). Option S2N_INTERN_LIBCRYPTO pour figer/isoler une version (repro ADR-025, évite les collisions de symboles).

8. Ce que l’on retient pour air-tls maison

  1. Empreinte à reprendre : ~60 k lignes de protocole (dont tls/ = 45 k, la vraie masse). En maison, cette masse devient du Rust memory-safe ; les primitives (le reste) restent hors air-tls (dans air-crypto).
  2. Zéro asm à porter : le port maison ne touche aucun assembleur — confirmé par le 0 de s2n. L’asm est un sujet air-crypto/RustCrypto (AES-NI/ARMv8 détectés automatiquement), pas air-tls.
  3. Couverture fonctionnelle cible : les 303 fonctions publiques se replient sur ~61 objets Rust (spec air-tls §Inventaire) — le facteur ~5 vient des idiomes (builder au lieu de 75 setters config, une struct-connexion au lieu de 91 fonctions connection, RAII qui supprime les 14 fonctions init/mem/rand).
  4. Périmètre sécurité : on n’importe que le moderne. s2n supporte encore des provider OpenSSL 1.0.2/1.1.1 (fin de vie) ; air-tls ne spécifie que TLS 1.3 — le legacy est omis par conception (cf. spec §Périmètre de sécurité).
  5. Règle des 80 % (ADR-024) : un client TLS Air ne consommerait qu’une fraction des 303 fonctions → au sens strict, vendoring exigé, exclu pour du crypto (ADR-034). D’où soit l’exception nommée rustls (ADR-042, production), soit la maison (air-tls, zéro tierce) — les deux options que ce projet garde.

9. Provenance & reproductibilité de l’audit

Commandes clés (rejouables) : clone shallow aws/s2n-tlsgit fetch --tags --deepen=3000 (cadence) ; find/grep pour LOC, .S/.s/.asm et asm inline ; grep -c S2N_API api/ + extraction des identifiants s2n_*( (surface) ; parse de CMakeLists.txt (find_package, SEARCH_LIBCRYPTO, S2N_INTERN_LIBCRYPTO) et README.md/docs/BUILD.md (plateformes, providers, compilateurs). Aucun build crypto lancé, analyse statique seule.


Licence du document : MPL 2.0 — note de travail, exploratoire (non engageante). Alimente docs/specs/layer-2/air-tls.md (contingence maison, ADR-042 §Contingence).