SEND

From Livre IPv6

Revision as of 11:57, 26 June 2006 by Laurent Clevy (Talk | contribs) (Adresses CGA)

SeND : SEcure Neighbor Discovery

Introduction

SeND (RFC 3971) est une version sécurisée de NDP (Neighbor Discovery Protocol, RFC 2461 et RFC 2462), le protocole de découverte de voisins d'IPv6.

Il est conseillé de connaitre un minimum ce protocole (voir Découverte de voisins) et posséder quelques notions de sécurité (voir Sécurité, Généralités) avant de lire ce chapitre.

Après un état des lieux des problèmes de sécurité lié à NDP (RFC 3756), les travaux ont commencés afin de répondre à chacune des menaces décrites dans ce document. IPSec avait été envisagé à l'époque de la conception de NDP pour sécuriser ce dernier, mais cela s'est révélé inapproprié en pratique.

La première innovation est l'utilisation de CGA (RFC 3972) pour Cryptographically Generated Addresses, qui permet de créer des identifiants d'interfaces à partir d'une clé publique.

Le deuxième mécanisme important de SEND est la possibilité de découvrir automatiquement un chemin de certification sur le réseau.

Une extension du protocole NDP

Le protocole SEND ajoute des fonctions de sécurité grâce à l'ajout d'options au messages NDP.

Voici la structure de tels paquets :

                    <------------NDP Message---------------->
*-------------------------------------------------------------*
| IPv6 Header      | ICMPv6   | ND Message- | ND Message      |
| Next Header = 58 | Header   | specific    | Options         |
| (ICMPv6)         |          | data        |                 |
*-------------------------------------------------------------*
                    <--NDP Message header-->

L'option CGA permet de vérifier l'identité d'une machine émettrice d'un paquet NDP. Cette option contient entre autre la clé publique de la machine émettrice, dont la cohérence avec l'adresse source utilisée est vérifiée par la machine réceptrice.

L'option RSA contient une signature du paquet, calculée avec la clé privée de la machine émettrice. Le noeud recevant le paquet peut vérifier l'intégrité et l'authenticité du paquet, grâce à la clé publique reçue conjointement ou précédemment.

La confiance dans la clé publique utilisée par les options CGA et RSA se base sur un mécanisme de certification décrit dans les chapitres suivants.

Une option d'horodatage (Timestamp) est utilisée pour protéger NDP des attaques de type 'rejeu'.

Une option unicité (NOnce) est utilisée pour protéger les associations Demande/Réponse (Solicit/Advertisement) : une réponse NDP devra contenir la même valeur NOnce que la demande correspondante pour être valide.

Enfin deux options (Certicate Path Solicitation et Certificate Path Advertisement) sont utilisées afin de permettre la découverte automatique par une machine terminal d'un chemin de certification. Ce mécanisme permet à des machines utilisant l'auto configuration sans état (RFC 2462) de vérifier la légitimité d'un routeur et celle des préfixes publiés sur le lien auprès d'un tiers de confiance sur le réseau.

Ces options sont utilisées par NDP uniquement lorsque cela est nécessaire, c'est à dire pour se protéger d'un risque d'attaque spécifique.

Adresses CGA

Une adresse CGA (Cryptographically Generated Address) est utilisée afin de prouver, en temps qu'émetteur d'un message NDP, que l'on bien le propriétaire de l'adresse source utilisée : afin prouver son identité réseau. Une paire de clé Publique/Privée est générée pour chaque noeud voulant prouver la possession d'une adresse.

Le mécanisme de génération CGA crée la partie identifiant d'interface d'une adresse IPv6, à partir d'une clé publique et d'autres paramètres, comme le mécanisme de configuration sans état. Cette adresse est ensuite utilisée comme adresse source du message NDP, auquel au ajoute également l'option CGA, qui contient les paramètres ayant servis à la génération de l'adresse. Ainsi le récepteur peut générer une adresse CGA à partir des données reçues via l'option du même nom, et comparer la CGA calculée avec la CGA utilisée comme adresse source. Elles doivent être identiques bien sûr.

La génération et la vérification d'une adresse CGA sont basés sur l'utilisation d'une fonction de hachage non réversible, SHA-1, sur la clé publique. Il est donc facile de calculer une adresse CGA à partir de la clé publique, alors que l'inverse est, grâce à SHA-1, très difficile. Ceci est conçu afin d'éviter le vol d'adresse (Spoofing): si un pirate veut s'approprier une adresse, il lui faut également fournir la clé publique qui a servi à sa génération : il lui faut donc trouver les données d'entrée de l'algorithme SHA-1 en connaissant l'adresse CGA résultante, ce qu'interdit SHA-1.

Voyons en détails les algorithmes de génération et de vérification.

Génération d'une adresse CGA

Le principe est de créer une association cryptographique (avec fonction de hachage) entre une clé publique et une adresse IPv6.

Par la suite, lorsque que l'on parlera d'adresse, il faudra comprendre les 64 bits les plus à droite : ceux de l'identifiant d'interface.

Format d'une adresse CGA

Une adresse CGA dépend d'abord d'un paramètre de sécurité, noté Sec, codé sur 3 bits. Cette valeur est encodé dans les 3 bits les plus à gauche de l'adresse. L'adresse CGA est également associée à un ensemble de paramètres dit 'Paramètres CGA', dont une clé publique. Deux valeurs sont calculés à partir de ces paramètres CGA : Hash1 (sur 64 bits) et Hash2 (sur 112 bits).

Une adresse générée cryptographiquement (CGA address) est donc définie comme une adresse IPv6 vérifiant les propriétés suivantes:

  • Hash1 est égal à l'identifiant d'interface. Les bits de la valeur Sec, et les bits u et g sont ignorés dans cette comparaison.
  • Les 16*Sec bits les plus à gauche de Hash2 sont nuls.

En d'autres termes, si l'on définit les valeurs Mask1 et Mask2 de la façon suivante:

* Mask1 (sur 64 bits) = 0x1cffffffffffffff
* Mask2 (sur 112 bits) = 0x0000000000000000000000000000  si Sec=0,
                         0xffff000000000000000000000000  si Sec=1,
                         0xffffffff00000000000000000000  si Sec=2,
                         0xffffffffffff0000000000000000  si Sec=3,
                         0xffffffffffffffff000000000000  si Sec=4,
                         0xffffffffffffffffffff00000000  si Sec=5,
                         0xffffffffffffffffffffffff0000  si Sec=6, et
                         0xffffffffffffffffffffffffffff  si Sec=7.

alors les propriétés définissant une adresse CGA peuvent se réécrire ainsi:

  • Hash1 & Mask1 == Identifiant d'interface & Mask1
  • Hash2 & Mask2 == 0x0000000000000000000000000000

Paramètres CGA et valeurs Hash1 et Hash2

Chaque adresse CGA est associée à des paramètres CGA, dont voici le format:

   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
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                                                               |
  +                                                               +
  |                                                               |
  +                      Modifieur (16 octets)                    +
  |                                                               |
  +                                                               +
  |                                                               |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                                                               |
  +                    Préfixe de sous-réseau (8 octets)          +
  |                                                               |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |Collision Count|                                               |
  +-+-+-+-+-+-+-+-+                                               |
  |                                                               |
  ~                  Clé Publique (longueur variable)             ~
  |                                                               |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                                                               |
  ~          Champs d'extension (optionel, longueur variable      ~
  |                                                               |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • Modifieur : il s'agit d'un entier sur 128 bits, non signé, qui peut contenir n'importe quelle valeur. Le modifieur est utilisé lors de la génération et permet d'introduire de l'aléa dans la valeur de l'adresse.
  • Préfixe de sous réseau : préfixe de sous réseau de l'adresse CGA (64 bits)
  • Compteur de collision : entier non signé sur 8 bits dont les valeurs DOIVENT être 0, 1 ou 2.
  • Clé publique : c'est un champ de longueur variable qui contient la clé publique du propriétaire de l'adresse. Le format DOIT etre la forme DER du champ ASN.1 SubjectPublicKeyInfo tel que présent dans les certificats X509 (RFC 3280). SEND devrait utiliser une paire de clé RSA, avec une longueur minimale de 384 bits.
  • Champs d'entension : ces champs ne sont pas encore utilisés dans la spécification, mais pourront l'être dans le futur.

Les valeurs Hash1 et Hash2 sont calculés ainsi : l'algorithme SHA-1 est appliqué sur la structure des paramètres CGA. Hash1 est obtenu en prenant les 64 bits les plus à gauche de la valeur SHA-1 de 160 bits. Hash2 est obtenu également grâce à l'application de SHA-1 sur les paramètres CGA, mais avec les champs préfixe et collision à 0, et en gardant cette fois les 112 bits de gauche de la valeur SHA-1.

Algorithme de génération

La génération d'une adresse CGA devrait s'effectuer ainsi:

  1. Affecter au Modifieur une valeur pseudo-aléatoire sur 128 bits
  2. Concaténer de gauche à droite le Modifieur, 9 octets de valeur 0, la clé publique encodée, et les éventuels champs d'extension. Appliquer l'algorithme SHA-1 sur cette concaténation. Prendre les 112 bits les plus à gauche de la valeur SHA-1. Le résultat est Hash2
  3. Comparer les 16*Sec bits les plus à gauche de Hash2 avec 0. S'ils sont tous nuls, alors continuer à l'étape 4. Sinon, incrémenter le Modifieur de 1 et revenir à l'étape 2.
  4. Affecter 0 au champ Collision.
  5. Concaténer de gauche à droite la valeur finale du Modifieur, le préfixe réseau, le compteur de collision, la clé publique encodée, et les éventuels champs d'extension. Appliquer l'algorithme SHA-1 sur cette concaténation. Prendre les 64 bits les plus à gauche de la valeur SHA-1. Le résultat est Hash1
  6. Fabriquer un identifiant d'interface à partir de Hash1 en insérant la valeur de Sec dans les 3 bits les plus à gauche, et en mettant à zero les bits u et g.
  7. Concaténer les 64 bits du préfixe réseau au 64 bits de l'identifiant d'interface de façon à former une adresse IPv6 standard : avec ma partie préfix à gauche et la partie interface sur la droite.
  8. Effectuer une détection de collision d'adresses (DAD). En cas de collision, incrementer le compteur de collision et aller à l'étape 5. Après 3 collisions, l'algorithme s'arrête et rapporte une erreur.
  9. Former la structure des paramètres CGA en concaténant de gauche à droite : le Modifieur final, le préfixe réseau, le compteur de collision final, la clé publique encodée, et d'éventuel champs optionnels.

En sortie, cet algorithme de génération produit une nouvelle adresse CGA et une nouvelle structure de paramètres CGA.

Plusieurs valeurs du modifieur permettent de générer plusieurs CGA sans lien direct.

Pour la valeur Sec=0, l'algorithme est déterministe et rapide. Pour des valeurs de Sec plus grandes que zero, il n'est pas garanti que l'algorithme termine après un certain nombre d'itérations. Ceci est dû au fait que l'algorithme à été concu pour résister à des attaques de type 'force brute' pour des grandes valeurs de Sec.

Des optimisations de cet algorithme de génération sont possible (surtout dans la recherche de la valeur du modifieur), pourvu que

  • le format de la structure des paramètres CGA soit respectée
  • l'algorithme de vérification tel que décrit plus loin réussisse, avec une version optimisée de la génération.

Algorithme de vérification

L'algorithme prend en entrée une adresse IPv6 et une structure de paramètres CGA, tel que définie plus haut. Cette adresse est l'adresse source d'une paquet NDP reçu, et la structure des paramètres CGA est reçue via l'option ND CGAde ce même paquet.

  1. Vérifier que le compteur de collision contienne la valeur 0, 1 ou 2. Dans le cas contraire, la vérification échoue
  2. Vérifier que le préfixe réseau des paramètres CGA est égal au préfixe réseau de l'adresse IPv6. Dans le cas contraire, la vérification échoue
  3. Appliquer l'algorithme SHA-1 sur la structure des paramètres CGA. Garder les 64 bits de gauche. Le résultat est Hash1.
  4. Comparer Hash1 avec l'identifiant d'interface, en ignorant les bits u et g, et les 3 bits Sec (les 3 bits les plus à gauche). Si la comparaison échoue, la vérification échoue.
  5. Extraire la valeur Sec (les 3 bits les plus à gauche) de l'identiant d'interface
  6. Concaténer, de droite à gauche, le modifieur, 9 octets vides, la clé publique et les éventuelles extensions contenues dans la structure des paramètres CGA. Appliquer SHA-1 sur cette concaténation et garder les 112 bits les plus à gauche. La valeur obtenue est Hash2.
  7. Comparer les 16*Sec bits les plus à gauche de Hash2 avec 0. Si un seul d'entre eux n'est pas nul, la vérification échoue, sinon elle réussit.

Si la vérification échoue à n'importe quelle étape, alors l'algorithme DOIT s'arrêter immédiatement. Par contre s'il réussi, la machine qui a exécuté avec succès cet algorithme sait que la clé publique contenue dans les paramètres CGA est la clé authentique du possesseur de l'adresse. Le vérifieur peut extraire cette clé publique en enlevant les premiers 25 octets de la structure des paramètres CGA, et en décodant la structure ASN.1 SubjectPublicKeyInfo.

Le vérifieur doit être capable de traiter les valeurs de Sec suivantes : 0, 1, 2, 3, 4, 5, 6 et 7. L'algorithme est rapide, il ne nécessite au plus que 2 calcul SHA-1. L'algorithme de vérification doit être capable de traiter les clés publiques RSA au moins entre 384 et 2048 bits.

Exemple

Signature RSA

Options horodatage et 'NOnce'

Découverte dynamique du chemin de certification

Implementations connues

  • Docomo (mai 2006, implémentation complète sous license GPL, [1] )
  • Alcatel (septembre 2005, implémentation des options CGA et RSA, [2])
Personal tools