Résumé

  • Dans le RFC 9846, KeyUpdate fait avancer le secret de trafic applicatif de l’émetteur. Le message est protégé par l’ancienne clé ; les records suivants utilisent la nouvelle génération et le destinataire avance la chaîne de réception correspondante.
  • update_requested oblige normalement à renouveler l’autre sens avant la prochaine donnée applicative, mais ne cède pas la connexion au pair. Les sens restent indépendants, les requêtes croisées peuvent produire deux avancées, les requêtes silencieuses se regroupent et les plafonds demeurent locaux.
  • Un compte rendu sérieux distingue la programmation de l’API, l’émission de la transition, son acceptation et le succès des nouvelles données. Même réunis, ces faits ne prouvent ni l’effacement de l’ancien secret, ni une nouvelle authentification, ni l’autorisation métier.

Deux horloges derrière une seule connexion

Prenons un flux TLS 1.3 qui reste ouvert pendant des heures. Le client décide de renouveler sa clé d’émission et demande au serveur de faire de même. Il construit un KeyUpdate avec la valeur 1. Cette valeur tient dans le corps minimal du message ; l’état qu’elle déclenche se déploie pourtant en plusieurs temps.

Le client chiffre la transition avec sa clé d’émission actuelle. Après l’avoir envoyée, tous ses records futurs passent à la génération suivante. Le serveur vérifie la transition avec son ancienne clé de réception, puis dérive la nouvelle. Sa réponse, si elle est due, part sous son ancienne clé d’émission ; elle ne change qu’ensuite la direction serveur vers client.

L’expression courante « la connexion a changé de clé » masque donc deux chaînes. Une métrique globale peut afficher une égalité rassurante tout en cachant une réponse en attente, deux requêtes croisées ou un décalage entre bibliothèque TLS et chiffrement déporté.

RFC 9846, et non plus RFC 8446

Le RFC 9846 a remplacé le RFC 8446 en 2026 sans changer le numéro de version TLS 1.3 ni casser la compatibilité. Il conserve le type de handshake 24 et deux valeurs valides : update_not_requested(0) et update_requested(1). Un KeyUpdate reçu avant Finished impose l’alerte unexpected_message ; toute autre valeur impose illegal_parameter.

Le message doit s’aligner sur une frontière de record avant le changement de clé. Le destinataire ne peut accepter du trafic de la génération suivante qu’après avoir authentifié la transition sous l’ancienne clé. Cette règle relie la continuité cryptographique à une décision du pair et ferme une voie d’attaque par troncature.

Le prochain application traffic secret est dérivé du secret directionnel courant avec HKDF-Expand-Label et l’étiquette traffic upd. De ce secret viennent une nouvelle clé et un nouvel IV. Le texte actuel ajoute une limite d’époque côté émission de 2^48-1. Le récepteur ne doit pas faire respecter cette limite à la place de l’émetteur. Si une réponse demandée dépasserait le plafond local, l’émetteur ne doit pas l’effectuer et devrait ignorer le drapeau.

Une obligation bornée

update_requested n’est pas une suggestion sans effet. En règle générale, son destinataire envoie un KeyUpdate update_not_requested avant son prochain record Application Data. Mais le protocole refuse d’en faire un droit illimité sur le travail distant.

Tant qu’une requête réciproque reste en attente, l’initiateur ne peut pas en émettre une autre. Plusieurs KeyUpdate reçus pendant le silence du destinataire peuvent être satisfaits par une seule réponse. Si les deux pairs lancent simultanément une requête et que les messages se croisent, chacun répond encore : les deux sens peuvent avancer de deux générations.

Cette concurrence licite explique pourquoi l’écart d’un compteur n’est pas nécessairement une panne. Elle rappelle aussi que la vérification cryptographique d’une requête n’autorise pas une consommation arbitraire de CPU. Fréquence, backoff, terminaison et traitement des limites relèvent du code local.

La chaîne dérivée ne visite pas la mémoire du pair

Après dérivation, le RFC 9846 demande à l’implémentation de supprimer l’ancien secret de trafic et les clés associées. La réussite d’un record sous la nouvelle génération prouve que les deux côtés ont atteint un état compatible dans ce sens. Elle ne prouve pas où l’ancienne valeur subsiste.

Heap, HSM, table kTLS, core dump ou copie de diagnostic restent hors du champ du message. L’effacement est une obligation de mise en œuvre et de gouvernance de la mémoire. Transformer la réponse du pair en certificat d’effacement crée une preuve que le protocole n’a jamais fournie.

KeyUpdate ne renouvelle pas davantage l’identité. Le certificat, la vérification du service, l’authentification éventuelle du client et la politique applicative restent ceux de la connexion existante. Une clé fraîche peut protéger une opération interdite ; elle n’en change pas l’autorité.

Les API révèlent les étapes cachées

Dans OpenSSL, SSL_key_update() ne s’utilise qu’après le handshake initial. L’appel prépare le travail, mais une lecture, une écriture ou un pilotage explicite du handshake le fait réellement progresser. L’application doit aussi ordonner les écritures encore pendantes. Le retour de fonction ne date donc pas l’émission réseau.

GnuTLS expose séparément le renouvellement local et la demande au pair avec GNUTLS_KU_PEER. L’opération ressemble à un envoi de record et peut demander une reprise non bloquante. Sa documentation distingue explicitement rekey et re-authentication.

rustls fournit refresh_traffic_keys() et suit normalement les limites de confidentialité de la suite cryptographique. Quand son interface kernel externalise la protection des records, l’application reprend la responsabilité du comptage, du renouvellement et de l’arrêt. La disponibilité d’une fonction ne prouve donc ni son exécution, ni son calendrier, ni sa politique.

Trois transports, trois preuves

QUIC emploie TLS 1.3 pour établir ses secrets, mais interdit les messages TLS KeyUpdate. QUIC v1 utilise le bit Key Phase, les accusés de réception de paquets et l’étiquette quic ku. Une sonde limitée au handshake type 24 conclurait à tort qu’une connexion QUIC ne renouvelle jamais ses clés.

DTLS 1.3 conserve KeyUpdate et y ajoute des époques, des ACK et la conservation temporaire des anciennes clés pour les datagrammes retardés. Une réponse peut croiser la demande et ne vaut donc pas automatiquement accusé de réception. À proximité de sa limite d’époque, DTLS peut aussi ignorer une demande réciproque qui ferait dépasser le plafond.

Le nom générique « rekey » ne suffit pas. Toute preuve doit préciser transport et version avant d’interpréter un numéro de génération, une réponse ou la conservation d’une ancienne clé.

Le registre sans secrets

Un événement exploitable conserve la référence de connexion, le rôle, le transport, le sens, les générations avant/après, la cause locale ou distante, le drapeau de requête, l’authentification de la transition sous l’ancienne clé, l’alignement de record, les écritures pendantes, le premier succès sous la nouvelle génération, les croisements ou regroupements, la décision de limitation et l’alerte finale.

Il sépare quatre jalons : planifié, émis, accepté, donnée réussie. Une capture réseau ne nomme généralement pas KeyUpdate, car TLS 1.3 le chiffre. Dans un laboratoire borné, callbacks, compteurs et journal de clés peuvent relier le ciphertext à l’événement. En production, copier les secrets dans l’observabilité détruirait la sécurité que la mesure prétend surveiller.

La preuve d’effacement reste un dossier local distinct. On peut la corréler avec la transition sans prétendre que le wire l’a transportée.

Sources