CryptoAPI pour GNU/Linux, du point de vue de l'utilisateur/ice par David Bryson [mutex@kerneli.org] traduction : intrigeri [intrigeri@squat.net] version 1.2 du 27 décembre 2002 Nous allons parler de l'utilisation de la cryptographie forte sous GNU/Linux. A l'aide des patches pour le noyau dont cet article parle, vous pouvez crypter l'intégralité de votre disque dur, de vos connections réseau, et même votre swap. Nous allons présenter deux de ces solutions, et nous concentrer principalement sur l'une d'entre elles : CryptoAPI pour GNU/Linux. La cryptographie est la science qui conçoit et analyse des chiffres. Un chiffre est un algorithme qui transforme du texte en clair en une soupe incompréhensible nommée texte crypté, via une séquence de code prédéterminée. Le but est que seul-e-s l'expéditeur/ice et le/la destinataire aient accès à la clé, et donc qu'ils/elles soient les seul-e-s à avoir accès au texte en clair. L'application du chiffre sur le texte se nomme l'encryptage, et le processus inverse, le décryptage. Une clé est nécessaire pour encrypter des données avec un chiffre donné. Cette clé est ce qui sécurise le chiffre, et permet son/sa seul-e propriétaire de décrypter ce qui a été encrypté. La clé est fournie au chiffre, en plus du texte en clair, pour produire le texte crypté. Pour ce qui est du décryptage, la clé et le texte crypté sont fournis au chiffre, qui renvoie le texte en clair. Donner au noyau Linux le support de la cryptographie vous donne moult moyens de sécuriser vos données. Cet article explique comment le faire, en utilisant CryptoAPI. Quelques utilisations possibles de CryptoAPI sont : - L'encryptage de tout support physique (partitions de disque dur, swap, cdroms) Sans ça, toute personne qui prendrait votre disque dur et l'installerait sur une autre machine pourrait lire les données qui y sont stockées... grâce au support de la cryptographie au niveau du noyau, vous pouvez encrypter la partition qui contient vos répertoire home ; ainsi, vos données seront illisibles... sauf par vous. - L'encryptage du trafic réseau, ie. IPsec ou toute autre forme de cryptage réseau d'un bout à l'autre Les VPNs (Virtual Private Networks / réseaux privés virtuels) permettent d'encrypter les communications avant qu'elles ne sortent de votre ordinateur ; l'utilisation des VPNs étant en pleine expansion, il est important, pour conserver un niveau correct de performances et de sécurité, d'avoir un noyau gérant la cryptographie. Les différentes implémentations de la cryptographie --------------------------------------------------- Il existe actuellement deux principaux moyen d'ajouter le support de la cryptographie au noyau Linux. Nous citerons brièvement loop-AES, puis nous nous concentrerons sur CryptoAPI. Ces deux solutions ont l'avantage de se "brancher" sur le noyau sans modifier ses sources (ni redémarrer !). La seule modification devant être faite au code source du noyau est un patch à appliquer sur le pilote de loopback, qui peut aisément être chargé/déchargé s'il est compilé sous forme de module. Nous espérons voir ce patch intégré dans le noyau prochainement. Ce patch permet au module de loopback d'intercepter les requêtes de lecture/écriture sur le système de fichiers crypté, et d'encrypter/décrypter les données à la volée. Nous préciserons ceci dans les prochains paragraphes. Loop-AES est conçu uniquement pour le cryptage de systèmes de fichiers ; il utilise comme chiffre le fameux AES (Advanced Encryption Standard / Standard avancé de cryptage), et donc l'algorithme de Rijndael. Il est plutôt rapide, et fournit une implémentation en assembleur pour les processeurs Intel x86 (les autre architectures se contenteront de l'implémentation en C). Pour plus d'informartion sur loop-AES, visitez la page qui lui est consacrée sur SourceForge page, http://loopaes.sourceforge.net. Le package CryptoAPI fournit une solution plus polyvalente de cryptographie au niveau du noyau. Il utilise une interface générique permettant à tout module du noyau d'encrypter/décrypter des données. Le cryptage de systèmes de fichiers n'est qu'une de ses nombreuses applications possibles. CryptoAPI fournit 12 chiffres différents, et supporte le montage/démontage et l'utilisation des systèmes de fichiers encryptés avec loop-AES. Installation de CryptoAPI ------------------------- Voyons maitenant comment faire fonctionner CryptoAPI sur votre machine. Il nous faut tout d'abord obtenir les sources de votre noyau et les dernières sources de CryptoAPI correspondant au noyau que vous utilisez. La dernière version de CryptoAPI est toujours disponible ici : http://www.kernel.org/pub/linux/kernel/crypto/. A partir de cryptoapi-0.1.0, le module cryptoloop n'est plus inclus dans les sources de CryptoAPI, il vous faut donc le télécharger séparément, au même endroit. Une fois que vous avez téléchargé ces archives, décompressez les dans /usr/src/cryptoapi : $ cd /usr/src/cryptoapi $ tar xvzf cryptoapi-0.1.0.tar.gz $ tar xvzf cryptoloop-0.0.1.tar.gz NB : Lisez toujours le README pour tout logiciel que vous téléchargez ! Avant de compiler un chiffre, nous devons patcher le driver de loop pour les raisons évoquées plus haut. Il existe actuellement deux patches, tout deux distribués avec CryptoAPI. Le patch loop-iv offre le support minimal nécessaire à CryptoAPI, tandis que le patch loop-jari, distribué avec loop-AES, corrige quelques bugs. Nous aurons une approche minimaliste, et nous ne nous occuperons que du patch loop-iv (Initialization Vector), suffisant pour ce qui nous occupe. Pour cela, allez dans le répertoire contenant les sources de CryptoAPI, et lancez cette commande : $ cd cryptoapi-0.1.0 $ make patchkernel KDIR= LOOP=iv $ cd ../cryptoloop-0.0.1 $ make patch-kernel KDIR= LOOP=iv NB : Même si vous n'utilisez pas une version du noyau correspondant exactement à celle du patch loop-iv, vous avez des chances de parvenir à vos fins, car le driver de loop n'a presque pas changé depuis le passage du noyau 2.2 au 2.4. Il existe un script permettant de déterminer la version du patch la plus proche de celle de votre noyau, et d'appliquer le patch automatiquement. Si vous souhaitez utiliser le le patch loop-jari, donnez au paramètre LOOP la valeur 'jari' au lieu de 'iv'. Ceci étant fait, vous devez recompiler le driver de loop. Si vous avez déjà une configuration de noyau prête, vous pouvez vous contenter de recompiler et installer le module loop. Sinon, il vous faut compiler le module à la main, en précisant quelques flags au compilateur C. Vous pouvez maintenant compiler les modules des chiffres et le plugin de loopback pour la cryptographie, puis les installer sans recompiler l'intégralité de notre noyau, grâce à la magie des modules. Pour compiler ces modules, tapez simplement : $ make modules KDIR= Et les modules de CrytoAPI seront compilés, après quoi nous pouvons les installer dans le répertoire approprié, afin de pouvoir les charger. Un script le fera pour vous si vous exécutez cette commande : $ make install_modules Avant que de pouvoir utiliser le cryptage via loopback, il nous faut compiler un logiciel ne faisant pas partie du noyau : le programme lo-setup, qui fait partie du package util-linux, a besoin d'être patché pour être capable de dire au noyau quel chiffre et quelle clé utiliser. Selon la distribution GNU/Linux utilisée, la méthode est différente : si vous utilisez Debian Woody (ou supérieure), la version patchée de losetup est d'ores et déjà installée, dans le package util-linux. Les utilisateur/ice/s de Debian Potato peuvent télécharger le patch et recompiler util-linux. Il existe des RPMs patchés pour RedHat, ainsi que des patches pour les sources, sur http://www.kerneli.org. Si votre distribution ne fournit pas ce patch, proposez à ses fournisseur/se/s une version patchée de losetup. Une fois que la bonne version de losetup est installée, CryptoAPI est installée sur votre ordinateur, et vous êtes prêt-e à mettre en place des systèmes de fichiers cryptés ! Utiliser CryptoAPI ------------------ Nous parlerons dans ce paragraphe d'une des applications de CryptoAPI : encrypter un système de fichiers entier. Sur la plupart des systèmes, le disque dur est partagé en plusieurs partitions. Chaque partition peut être montée dans un répertoire vide. Une configuration pourrait être, par exemple : Partition Mount point /dev/hda1 / /dev/hda2 swap space /dev/hda5 /usr /dev/hda6 /var /dev/hda7 /home Supposons que vous vouliez encrypter la partition qui contient vos répertoires home, c'est-à-dire /dev/hda7. Cela signifie que toute donnée écrite sur cette partition sera encryptée : texte brut, fichiers binaires, et même les données propres au système de fichiers (des choses comme les informations sur les inodes, les noms de fichiers et de répertoires, etc.). Dans l'introduction, nous avons dit que CryptoAPI supportait l'encryptage de systèmes de fichiers via le périphérique de loopback ; nous allons maintenant expliquer ce mécanisme. La méthode traditionnelle pour monter un système de fichiers, que ce soit au démarrage ou plus tard, est l'utilisation de la commande mount. Nous pouvons, dans notre exemple, monter les répertoires home par la commande suivante : $ mount -t ext2 /dev/hda7 /home ... qui dit au noyau que le périphérique /dev/hda7 contient un système de fichiers ext2 (le système de fichiers traditionnel sous GNU/Linux), et que toute requête vers un fichier de /home doit aller vers cette partition. Le périphérique de loopback ajoute un niveau de redirection pour monter un système de fichiers. Au lieu de monter le système de fichiers directement sur /home, on monte le système de fichiers sur le périphérique de loopback, puis on monte ce dernier sur /home. Ceci a l'effet de faire passer par le périphérique de loopback toutes les commandes du noyau vers le système de fichiers. C'est à cette étape que toute commande peut être interceptée et modifiée pour encrypter (pour une commande d'écriture) et décrypter (pour une commande de lecture). Ici intervient le pilote cryptoloop. Une fois que tout a été monté, chaque commande dirigée vers le système de fichiers est interceptée par le périphérique de loopback, redirigée vers le driver cryptoloop, qui la traite, puis la passe au système de fichiers. Nous pouvons maintenant encrypter toutes les données sur la partition ! Vous pouvez aussi réléchir à la façon dont tout ceci s'insère dans le schéma d'encryptage/décryptage du début. Le périphérique de loopback a le rôle du chiffre, cryptoloop fournit la clé, et le système de fichiers représente le texte en clair et le texte encrypté. Il y a deux façons d'encrypter des fichiers sur votre système. L'une utilise un vrai périphérique, tel qu'une partition de disque dur. L'autre consiste en l'utilisation d'un très gros fichier contenant un système de fichiers, qui sera monté via le périphérique de loopback. Nous étudierons ici la seconde méthode. La première étape est de créer un gros fichier ; plus il sera gros, plus il pourra contenir de données, exactement comme une partition de disque dur. De même, une fois que le fichier est créé, et qu'un système de fichiers y est mis en place, nous ne pouvons plus le redimensionner sans perdre les données qui y sont stockées. Afin de créer ce gros fichier, nous devons le remplir de données pour qu'il prenne de l'espace sur le disque dur. Nous le remplirons de données pseudo-aléatoires, générées par le périphérique /dev/urandom. Il serait aussi possible (et plus rapide) de le remplir de zéros, à l'aide de /dev/zero. Toutefois, ceci permettrait à un-e éventuel-le attaqueur/se de voir où sont stockées les données. Comme vous pouvez le constater, cela facilite grandement la tache d'un-e attaqueur/se, par rapport à un périphérique de stockage semblant ne contenir que des données aléatoires. Maintenant que nous avons expliqué comment tout ceci fonctionne, configurons-le. Commençons par charger les quatre principaux modules CryptoAPI dans le noyau : - cryptoapi, qui fournit l'interface générique pour les différents chiffres - cryptoloop, l'interface entre les chiffres et le pilote loop - loop, le pilote patché avec lequel cryptoloop communique - cipher-x, où x est le chiffre que vous souhaitez utiliser Pour charger les trois premiers modules, utilisons la commande modprobe : $ modprobe cryptoloop Ceci devrait charger les modules cryptoapi, loop et cryptoloop dans le noyau. Vous pouvez le vérifier avec la commande lsmod, qui devrait donner quelque chose dans ce genre : Module Size Used by Not tainted cryptoloop 1884 0 (unused) loop 7664 0 [cryptoloop] cryptoapi 3204 0 [cryptoloop] Il nous faut maintenant créer le fichier contenant des données pseudo-aléatoires, avec la commande dd, AVANT de créer un système de fichiers dessus. Le périphérique /dev/urandom génère des données pseudo-aléatoires, à partir des données fournies par le périphérique /dev/random. A la différence de /dev/random, il fournit un flux constant d'octets, mais plus l'entropie fournie par /dev/random sera faible, moins /dev/urandom sera aléatoire. Ceci fonctionne mieux quand des événements aléatoires se produisent, comme des mouvements de souris. Par conséquent, quand vous exécuterez la commande suivante, essayez de déplacer votre souris, ou de taper énormément sur votre clavier. Ces deux manipulations contribuent à la source d'entropie. $ dd if=/dev/urandom of=/home/intrigeri/cryptofichier bs=1M count=50 Ceci créera un fichier de 50 Mo dans mon répertoire home. Cette étape peut malheureusement prendre beaucoup de temps, selon la rapidité de votre système. Puis nous devons charger un module fournissant un chiffre. Dans ces exemples, j'utiliserai le chiffre nommé twofish. Tous ces modules ont des noms préfixés par ``cipher-'' ; pour charger twofish avec modprobe, nous exécuterons donc : $ modprobe cipher-twofish Nous pouvons maintenant monter ce fichier comme un périphérique de stockage normal ; avant tout, utilisons la commande losetup : $ losetup -e twofish /dev/loop0 /home/intrigeri/cryptofichier L'option -e précise le chiffre devant être utilisé, qui est, dans notre cas, twofish ; /dev/loop0 est le périphérique de loop que nous utilisons, et /home/intrigeri/cryptofichier est le nom du fichier. Le programme losetup vous demandera la taille de la clé (keysize) à utiliser et un mot de passe, dans lequel j'ai entré '128' puis mon mot de passe. En général, pour un chiffre donné, plus la clé est longue, et plus vos données seront difficiles à décrypter par une attaque de type ``force brute''. Toutefois, une clé de 128 bits pour un chiffre donné peut être plus forte qu'une clé de 1024 bits pour un autre chiffre. Votre mot de passe est utilisé pour générer la clé, mais point n'est besoin qu'il ait la même longueur que la clé ; il serait en effet pour le moins pénible de taper un mot de passe de 128 caractères pour générer une clé de 1024 bits. Le mot de passe sera plutôt utilisé pour générer une clé avec une fonction de hash. Available keysizes (bits): 128 192 256 Keysize: 128 Password : Initialisons ensuite un système de fichiers, via le périphérique de loopback, sur le fichier que nous avons créé, grâce à la commande mkfs : $ mkfs -t ext2 /dev/loop0 Vous pouvez évidemment choisir le type du système de fichiers à créer, mais cet exemple utilise ext2. Nous pouvons maintenant monter notre système de fichiers exactement comme un périphérique de stockage normal, avec la commande mount : $ mount -t ext2 /dev/loop0 /mnt/crypto Vous devriez maintenant pouvoir y copier des fichiers comme s'il s'agissait d'un périphérique de stockage monté classique. Vous avez un système de fichiers crypté, profitez-en ! Une question redondante sur la liste de discussion linux-crypto est ``Comment fait-on pour une partition root cryptée ?''. Ceci, bien qu'étant possible avec le périphérique cryptoloop, n'est pas recommandé. L'impact sur les performances de la machine serait en effet très mauvais, et cela nécessiterait quelques modifications de la procédure d'initialisation du système. Il est plus logique de n'encrypter que les informations "sensibles", comme un répertoire home. N'oubliez pas ensuite de démonter votre système de fichiers crypté et de libérer le périphérique de loop, afin que quiconque souhaitant le monter doive entrer le mot de passe. $ umount /mnt/crypto $ losetup -d /dev/loop0 Il est facile d'automatiser ces étapes avec des scripts shell, afin de n'avoir pas à exécuter ces deux commandes pour le montage/démontage. CryptoAPI, au passé, au présent, et au futur -------------------------------------------- Au moment où ceci a été écrit, la première version de CryptoAPI est sur le point de sortir, sous forme d'une branche du patch international pour le noyau (kernel-int). Le patch kernelint était au départ conçu pour ne faire que de l'encryptage de systèmes de fichiers, avec les noyaux de la série 2.2. Il a ensuite évolué vers une API générique fournissant la cryptographie au noyau. Cette évolution a laissé le projet en hibernation pendant environ 6 mois avant qu'une nouvelle base de code soit publiée. Mais, avec une nouvelle équipe de développeur/se/s, la progression a repris. Quelques lignes directrices de l'évolution future de CryptoAPI : - Lisibilité du code : les chiffres fournis viennent de sources diverses, et certains n'ont pas été implémentés par l'équipe de CryptoAPI. Leur style de programmation est par conséquent peu cohérent, ce qui les rend difficiles à étudier pour un-e programmeur/se. Une standardisation de ce code est en cours. - Implémentation en assembleur des chiffres pour différentes architectures : ceci améliorera la vitesse d'exécution et diminuera les besoins en mémoire vive. Ceci est particulièrement utile dans des situations de grosse charge d'une machine, quand chaque cycle processeur compte. - Support du matériel cryptographique : plusieurs fabricants fournissent du matériel implémentant des chiffres. Ce matériel a généralement des performances 1000 fois supérieures aux meilleures implémentations logicielles. Quand ces lignes ont été écrites, la nouveau code de base de CryptoAPI devait encore mûrir. Il a encore besoin de travail ; c'est pourquoi le projet recherche toujours des programmeur/se/s plein-e-s d'entrain, et expérimenté-e-s en cryptographie ou en programmation du noyau. Et celles/ceux qui ne peuvent programmer peuvent toujours aider en testant les nouveaux patches et en envoyant des rapports de bugs. En espérant que cet article vous ait expliqué comment sécuriser vos données avec la cryptographie, grâce à CryptoAPI. Suivez l'évolution du projet CryptoAPI sur notre site http://www.kerneli.org.