Dans les protocoles de transmission chiffrée, l'établissement d'une session repose sur l'authentification réciproque des extrémités et la dérivation de clés éphémères. Comme les paquets d'amorce circulent sur des liaisons publiques non sécurisées, ils constituent une cible privilégiée. Un tiers incapable de déchiffrer le tunnel peut néanmoins intercepter des paquets de poignée de main valides et les renvoyer en boucle vers la passerelle.

Avec les protocoles traditionnels comme IPsec IKEv2 ou OpenVPN classique, la réception d'un paquet de négociation oblige le serveur à réserver des zones de mémoire tampon, valider des chaînes de certificats complexes et exécuter des calculs modulaires lourds. Une vague de paquets réémis (attaque par rejeu) sature rapidement le processeur et la mémoire, aboutissant à un déni de service pour les utilisateurs légitimes.

WireGuard écarte ce risque grâce à une architecture épurée. Au cœur de la charge utile authentifiée de chaque paquet d'initiation figure un horodatage strictement croissant de 12 octets basé sur la norme TAI64N. En contrôlant cette valeur en temps constant avant même de créer un état de session, WireGuard rejette les paquets rejoués avec un coût de calcul pratiquement nul.

Le modèle de menace lié au rejeu des paquets d'amorce

Pour mesurer l'intérêt d'un horodatage chiffré, analysons la phase d'échange initiale régie par le motif Noise_IK :

Échange d'initiation dans WireGuard (Noise_IKpsk2) :
Client (Initiateur)                                   Serveur (Répondeur)
  |                                                           |
  |--- Type 1 : Initiation de poignée de main --------------->|
  |    - Clé publique éphémère en clair (32 octets)           |
  |    - Clé statique chiffrée (48 octets AEAD)               |
  |    - Horodatage TAI64N chiffré (28 octets AEAD)           |
  |    - Balises mac1 (16 octets), mac2 (16 octets)           |
  |                                                           |
  |<-- Type 2 : Réponse de poignée de main -------------------|

Dans le paquet de type 1, l'identité statique du client et l'horodatage sont protégés par l'algorithme ChaCha20-Poly1305 via une clé dérivée d'opérations Diffie-Hellman.

Si un tiers intercepte ce paquet sur le réseau, il ne peut en modifier le contenu car la balise d'authentification Poly1305 signale immédiatement toute altération. Cependant, en l'absence de vérification de temporalité, ce tiers pourrait renvoyer le paquet des millions de fois :

  • Le serveur déchiffrerait avec succès l'identité du client.
  • Le serveur calculerait une multiplication scalaire sur Curve25519 pour formuler sa réponse.
  • Le serveur mobiliserait de la mémoire pour gérer une demi-session en attente.

Cette asymétrie d'effort (nul pour l'émetteur hostile, lourd pour la passerelle) fragiliserait la disponibilité du service.

Structure binaire de l'horodatage TAI64N

Au lieu d'utiliser l'horloge UNIX ordinaire, WireGuard a sélectionné le standard TAI64N imaginé par Dan Bernstein. L'heure UNIX classique subit des corrections de secondes intercalaires (leap seconds) qui peuvent faire reculer l'horloge système ou étaler la durée, créant des anomalies exploitables lors des décalages.

Le Temps Atomique International (TAI) fournit une échelle de secondes continue qui ne recule jamais. Le format TAI64N enregistre ce temps avec une finesse nanoseconde au sein d'une structure compacte de 12 octets :

Format binaire TAI64N dans WireGuard (12 octets) :
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      Secondes TAI64 (Partie haute)            |
|                   (Entier 64 bits Big-Endian)                 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      Secondes TAI64 (Partie basse)            |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                     Fraction en nanosecondes                  |
|                   (Entier 32 bits Big-Endian)                 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  1. Secondes TAI64 (8 octets) : Comptabilise les secondes écoulées depuis l'origine ($2^{62}$ correspondant au 01/01/1970 à 00:00:10 TAI), écartant le bogue de l'an 2038.
  2. Nanosecondes (4 octets) : Exprime la fraction de seconde de $0$ à $999,999,999$. Cette précision nanoseconde garantit que des reconnexions très rapprochées produisent des valeurs toujours strictement croissantes.

Dans le paquet de type 1, ces 12 octets sont chiffrés pour former un bloc de 28 octets (12 octets de données et 16 octets d'intégrité Poly1305). Chiffré de bout en bout, l'horodatage ne peut pas être observé pour mesurer la dérive d'horloge de l'équipement client.

Validation dans le noyau et rejet en temps constant

Dès l'arrivée d'une trame d'initiation, le module noyau de WireGuard suit une séquence de contrôles ordonnée :

Arrivée du paquet d'initiation (Type 1)
         |
         v
[Vérification MAC1 : hachage SipHash avec la clé publique du serveur]
         |
         +--> Échec ? Abandon immédiat (Aucune mémoire réservée)
         v
[Calcul de clé DH : clé éphémère * clé statique]
         |
         v
[Déchiffrement de la clé statique et de l'horodatage TAI64N via AEAD]
         |
         +--> Échec de la balise ? Abandon immédiat
         v
[Comparaison en temps constant avec last_sent_handshake du pair]
         |
         +--> Horodatage reçu <= last_sent_handshake ?
         |         |
         |         v
         |    Abandon immédiat (Rejeu détecté ! Aucune session créée)
         v
[Mise à jour : last_sent_handshake = Horodatage reçu]
         |
         v
[Génération du paquet réponse de Type 2]

Le serveur confronte l'horodatage déchiffré à la valeur last_sent_handshake mémorisée pour ce pair. Si la valeur reçue est inférieure ou égale au repère antérieur, le paquet est immédiatement écarté sans émission d'erreur ni mobilisation de mémoire.

Le test est conduit en temps constant (constant-time), neutralisant les attaques par canal auxiliaire basées sur le chronométrage.

Critère d'évaluation Horodatage UNIX classique Horodatage TAI64N WireGuard Défi aléatoire (Nonce)
Encombrement réseau 4 à 8 octets 12 octets 16 à 32 octets
Aller-retours (RTT) nécessaires 1 RTT 0 RTT (validation au 1er paquet) 1 RTT complet (échange de jeton)
Résistance aux sauts de temps Sensible aux ajustements de seconde Immunité totale (échelle TAI) Insensible (valeur aléatoire)
Protection de l'empreinte d'horloge Transmise en clair dans l'en-tête Dissimulée dans le bloc AEAD Absente
Mémoire consommée sur le serveur Élevée (historique des nonces) Nulle (un repère par pair) Modérée (cache de cookies)

Situations particulières : écart horaire, veille et décalage d'horloge

La règle d'acceptation de WireGuard reposant sur la condition reçu > précédent, les variations d'horloge réelles s'articulent ainsi :

Écart d'heure entre client et passerelle

WireGuard ne réclame pas une synchronisation à la microseconde entre les deux systèmes. Le serveur ne compare pas l'heure du client avec la sienne ; il vérifie uniquement que l'horodatage est supérieur à celui de la dernière poignée de main acceptée pour ce même client. Un équipement décalé de plusieurs heures fonctionnera normalement dès lors que son horloge locale avance.

Mise en veille prolongée d'un terminal mobile

Lorsqu'un appareil mobile se met en veille, son horloge matérielle peut connaître un léger glissement. Au réveil, le système d'exploitation rétablit l'heure via NTP. Dès que l'horloge avance, la tentative suivante génère naturellement un horodatage plus élevé et aboutit sans délai.

Réinitialisation accidentelle de l'horloge

Si la batterie d'un équipement se décharge totalement et remet l'horloge système en 1970, le serveur rejettera les paquets tant que l'heure locale n'aura pas été recalée par le réseau sur une valeur postérieure au dernier enregistrement.

Gestion robuste de la monotonie dans RiceGuard

Afin de préserver la disponibilité des accès réseau face aux aléas d'horloge des terminaux mobiles, VPNRice introduit des mécanismes d'adaptation au sein du moteur RiceGuard :

  • Compteur monotone sous enclave sécurisée : Sur les systèmes mobiles sujets aux réajustements horaires des opérateurs, RiceGuard maintient un compteur matériel autonome. En cas de recul de l'horloge système, le moteur applique une compensation pour que les horodatages TAI64N émis demeurent strictement croissants.
  • Continuité lors des basculements de passerelles : Lors des opérations de maintenance sur les nœuds réseau, le gestionnaire de clés transfère les repères temporels des pairs validés, prévenant toute coupure d'accès.
  • Synergie avec la protection Cookie MAC2 : Face à des attaques volumétriques massives, le filtrage TAI64N s'associe au mécanisme de cookies sans état, neutralisant des millions de paquets invalides à la vitesse du réseau physique sans saturer les cœurs du serveur.

Grâce à la rigueur du standard TAI64N, WireGuard et RiceGuard garantissent une barrière efficace contre les attaques par rejeu tout en maintenant un raccordement immédiat des liaisons de communication.

Télécharger VPNRice.\n