ADR-082 — Additifs crypto : AEAD à nonce explicite (record/packet), BLAKE2s (WireGuard), PBKDF2 (SASL/SCRAM) — descellement additif couche-1-v1.x
Statut : Proposé — ratification BDFL requise (surface crypto, hors délégation
additive automatique ADR-065). RFC de
structure (ADR-015). Complète ADR-078/ADR-081
sous la même discipline (ADR-034, KAT-gate).
Consommateurs : air-tls, air-quic, air-wireguard, air-ssh, air-mail.
Catégorie : Descellement additif de la couche 1 scellée (air-crypto). Aucune
rupture ; complète les additifs crypto.
Contexte
La plomberie (air-wireguard, air-mail) et une relecture des piles TLS/QUIC/SSH
révèlent trois besoins non couverts par le cœur v1 ni par ADR-078/081 :
- AEAD à nonce EXPLICITE (le point important). La façade
AirAeadv1 est anti-mésusage : elle génère un nonce aléatoire interne et rendnonce‖ct‖tag(specair-crypto§5). Or toutes les piles de session protègent leurs enregistrements/paquets avec un nonce déterministe =IV ⊕ compteur: TLS 1.3 record (RFC 8446 §5.3), QUIC packet (RFC 9001 §5.3), WireGuard transport (compteur), SSH aes-gcm. Le nonce n’est pas aléatoire et n’est pas préfixé au message. ⇒ il manque un AEAD où l’appelant fournit le nonce. - BLAKE2s —
air-wireguard: hash + MAC keyed (MAC1/MAC2, cookie) + KDF (HMAC-BLAKE2s) du handshake Noise.air-cryptov1 ablake3(différé, tirecc), pasblake2. - PBKDF2-HMAC-SHA256 —
air-mail: mécanisme SASLSCRAM-SHA-256.air-cryptoa HKDF/Argon2, pas PBKDF2.
Décision
(1) air_crypto::lowlevel::AirAeadExplicitNonce — AEAD à nonce fourni
#![allow(unused)]
fn main() {
pub mod lowlevel { // opt-in expert-only (déjà introduit par ADR-081)
/// AEAD (AES-128/256-GCM | ChaCha20-Poly1305) où **l'appelant fournit le nonce**.
/// Pour les protocoles à nonce DÉTERMINISTE (TLS record, QUIC packet, WireGuard, SSH-GCM).
pub struct AirAeadExplicitNonce { /* aes-gcm | chacha20poly1305 */ }
impl AirAeadExplicitNonce {
pub fn seal(&self, nonce: &[u8; 12], plaintext: &[u8], aad: &[u8]) -> AirResult<Vec<u8>>; // ct‖tag
pub fn open(&self, nonce: &[u8; 12], sealed: &[u8], aad: &[u8]) -> AirResult<Vec<u8>>;
}
}
}
- Backends :
aes-gcm/chacha20poly1305(déjà présents) — seule l’API à nonce explicite s’ajoute. KAT : NIST GCM, RFC 8439. - Décision anti-mésusage : dans
lowlevel(opt-in) précisément parce que le nonce explicite est dangereux (réutilisation = catastrophe). La façadeAirAead(nonce aléatoire géré) reste le défaut applicatif. Contrat documenté : l’appelant DOIT garantir l’unicité du nonce par clé — ce que les key schedules TLS/QUIC/WireGuard garantissent par construction (compteur/séquence jamais réutilisé).
(2) BLAKE2s — hash + MAC keyed + HMAC (WireGuard)
#![allow(unused)]
fn main() {
pub enum AirHashAlgorithm { /* … */ Blake2s /* additif */ }
/// MAC keyed BLAKE2s (MAC1/MAC2 WireGuard) + HMAC-BLAKE2s (KDF Noise).
pub struct AirBlake2sMac { /* blake2 (RustCrypto) */ }
}
- Backend :
blake2(RustCrypto) — pur Rust, ZÉRO-C (≠blake3qui tirecc; c’est la raison du report de blake3, sans objet pour blake2). KAT : RFC 7693.
(3) PBKDF2-HMAC-SHA256 (SASL SCRAM)
#![allow(unused)]
fn main() {
pub struct AirPbkdf2;
impl AirPbkdf2 {
pub fn derive_sha256(password: &[u8], salt: &[u8], iterations: u32, out: &mut [u8]) -> AirResult<()>;
}
}
- Backend :
pbkdf2(RustCrypto), pur Rust. KAT : RFC 6070. Optionnel : requis pourSCRAM-SHA-256;OAUTHBEARER/XOAUTH2(token) l’évitent.
Sécurité (cœur de la remontée BDFL)
- AEAD à nonce explicite = le sujet sensible. Isolé dans
lowlevel(opt-in, expert-only), contrat d’unicité de nonce documenté ; la façade à nonce géré reste le défaut. Sans cet additif, TLS/QUIC/WireGuard/SSH ne peuvent pas protéger leurs enregistrements correctement (ils ne doivent PAS préfixer un nonce aléatoire). - BLAKE2s / PBKDF2 : primitives standard auditées (RustCrypto), pur Rust, zéro-C.
no_std-strict (features aléa exclues,AirRandomcouche 0) ; KAT-gated.
Gouvernance
- Surface crypto ⇒ ratification BDFL (comme ADR-078/081).
- Exceptions 80 % :
blake2,pbkdf2ajoutées (EXCEPTIONS.md+DEPENDENCIES.md) ;aes-gcm/chacha20poly1305déjà présents. - Tags : rejoint le lot d’additifs crypto (
couche-1-v1.7, ADR-078) ou uncouche-1-v1.xsubséquent, après implémentation KAT-gated + barrière 2 arches.
Conséquences
- Correction rétroactive :
air-tls(record),air-quic(packet),air-ssh(aes-gcm),air-wireguard(transport) utilisentlowlevel::AirAeadExplicitNoncepour la protection d’enregistrement/paquet — pas la façadeAirAeadà nonce aléatoire. Les specs concernées le notent. air-wireguard: BLAKE2s disponible ;air-mail: SCRAM-SHA-256 disponible.
Alternatives rejetées
- Détourner la façade
AirAead(nonce aléatoire) pour les protocoles — faux : ces protocoles imposent un nonce déterministe (IV⊕compteur), non préfixé ; un nonce aléatoire casserait l’interop et gonflerait chaque record. Rejeté. - Exposer le nonce explicite dans la façade par défaut — affaiblirait la posture
anti-mésusage pour tout le code applicatif. Rejeté : réservé à
lowlevel. blake3au lieu deblake2— WireGuard spécifie BLAKE2s ; et blake3 tirecc(surface C). Rejeté.
Suite
- Section « Additifs planifiés » d’
air-cryptoétendue. Notes correctives dansair-tls/air-quic/air-ssh/air-wireguard(record/packet AEAD) etair-mail(SCRAM). Ratification BDFL puis implémentation KAT-gated. Câblage registre/SUMMARY/ INDEX/EXCEPTIONS.