Journal scdrand: alimenter le pool d’entropie du noyau à partir d’une carte à puce

Posté par  (site web personnel) . Licence CC By‑SA.
Étiquettes : aucune
25
13
août
2014

Possesseur d’une carte OpenPGP, je cherchais un moyen d’exploiter le générateur de nombres aléatoires dont elle est équipée.

Une rapide recherche m’a immédiatement emmené vers TokenTools, qui semble faire exactement ce que je voulais. Malheureusement, ce programme ne peut pas cohabiter harmonieusement avec scdaemon, le démon de GnuPG chargé d’interagir avec les cartes à puce : TokenTools ne peut pas accéder à la carte tant que scdaemon tourne — or j’ai besoin de scdaemon pour l’utilisation routinière de ma carte OpenPGP (signer, déchiffrer, m’authentifier).

Plutôt que d’envisager une alternance fastidieuse entre scdaemon et TokenTools, j’ai donc entrepris d’écrire un petit programme similaire à TokenTools, mais qui accède à la carte par l’intermédiaire de scdaemon plutôt qu’en concurrence de ce dernier.

Voici donc scdrand, un programme qui obtient quelques octets aléatoires (de 1 à 256) à partir d’une carte à puce compatible¹ et les utilise pour approvisionner le pool d’entropie du noyau (le pool qui alimente à son tour /dev/random et /dev/urandom).

L’utilisation est supposée être simple, dès l’instant où un agent GPG et scdaemon sont disponibles et en cours d’utilisation (ce qui devrait probablement être le cas si vous êtes déjà utilisateur d’une carte OpenPGP). Par exemple :

$ scdrand 64

demande 64 octets aléatoires à la carte, les fournit au noyau et se termine.

Une utilisation un peu plus poussée est la suivante :

$ scdrand -l -i 2 -t 512 256

Ici, scdrand va vérifier toutes les deux secondes s’il y a au moins 512 bits d’entropie disponible dans le pool du noyau, et dans le cas contraire, approvisionner celui-ci avec 256 octets aléatoires en provenance de la carte.

Pour visualiser l’effet de scdrand, j’ai suivi l’état du pool d’entropie du noyau (nombre de bits d’entropie disponibles, consultable dans /proc/sys/kernel/random/entropy_avail) pendant la génération d’une paire de clefs RSA par GnuPG, d’abord sans, puis avec scdrand.

Effets de scdrand sur le pool d’entropie

Comme on peut le voir sur le graphe ci-dessus, la génération d’une paire de clefs vide instantanément le pool d’entropie et le maintient à un niveau très bas tant que la paire n’est pas générée. Sans sources d’entropie supplémentaire (GnuPG conseille à ce moment-là de bouger la souris, de saisir n’importe quoi sur le clavier ou de solliciter les disques durs — ce que je n’ai pas fait pour cet exemple), cela a pris ici une quarantaine de secondes, après quoi le noyau a encore besoin d’une trentaine de secondes pour ramener le pool d’entropie au niveau basal.

La deuxième paire de clefs, générée avec scdrand tournant dans un autre terminal, vide tout aussi le pool d’entropie. Mais cette fois-ci, au bout de deux secondes le pool est réapprovisionné par scdrand. En conséquence, trois secondes suffisent à GnuPG pour générer la paire de clefs, et le pool d’entropie revient à son niveau de base en moins de vingt secondes.

Évidemment, si vous ne passez pas votre temps à créer de nouvelles clefs toutes les cinq minutes, l’intérêt de tout celà est sans doute assez limité… Mais si ça vous intéresse tout de même, le code est là :


¹ La commande GET CHALLENGE permettant la génération de données aléatoires est spécifiée dans le standard ISO 7816-6 et n’est pas spécifique à l’application OpenPGP, donc scdrand devrait pouvoir utiliser d’autres types de carte. Mais je n’ai pu tester qu’avec une carte OpenPGP 2.0.

  • # Qualité de l'aléa de la carte ?

    Posté par  . Évalué à 6. Dernière modification le 13 août 2014 à 22:58.

    Ça me semble intéressant, mais la première question que je me pose c'est sur la qualité de l'aléa généré par le RNG de la smartcard. Quand j'ai acheté ma smartcard, j'avais cherché des renseignement dessus, pour savoir si je faisais une génération de clefs sur ma machine puis un transfert et effacement ou une génération de clefs sur la smartcard. Je n'avais pas trouvé d'informations pertinentes (peut-être ai-je mal cherché), et j'avais donc opté pour la seconde solution.

    Ajouter de l'entropie au pool du noyau est en soi une bonne idée, mais avant de penser à faire ce genre de choses, j'aimerai être sûr de l'aléa que je rajoute.

    • [^] # Re: Qualité de l'aléa de la carte ?

      Posté par  . Évalué à 3.

      pour savoir si je faisais une génération de clefs sur ma machine […] ou […] la smartcard […] j'avais donc opté pour la seconde solution.

      Il fallait lire la première solution. J'ai généré les clefs sur ma machine n'ayant pas d'informations sur le RNG de la smartcard.

    • [^] # Re: Qualité de l'aléa de la carte ?

      Posté par  (site web personnel) . Évalué à 3.

      la première question que je me pose c'est sur la qualité de l'aléa généré par le RNG de la smartcard

      C’est évidemment une bonne question, mais à laquelle je ne suis pas du tout qualifié pour répondre. Je ne sais ni comment fonctionne le RNG, ni s’il a été conçu avec soin, ni s’il n’a pas été dûment « backdooré » par la NSA — mais sur ce dernier point, j’ai personnellement un tout peu plus confiance dans le RNG d’une smartcard conçue par une société allemande (g10code, qui est aussi derrière GnuPG) que dans celui intégré par un fondeur américain dans ses processeurs.

    • [^] # Re: Qualité de l'aléa de la carte ?

      Posté par  (site web personnel) . Évalué à 5.

      Quand j'ai acheté ma smartcard, j'avais cherché des renseignement dessus, pour savoir si je faisais une génération de clefs sur ma machine puis un transfert et effacement ou une génération de clefs sur la smartcard.

      De toute façon cette seconde possibilité est une mauvaise idée, parce que cela donne des clefs que tu ne peux pas sauvegarder, et que tu devras changer, avec tout le dérangement que cela implique, le jour où ta carte cessera de fonctionner.

      • [^] # Re: Qualité de l'aléa de la carte ?

        Posté par  . Évalué à 2.

        Le dérangement que cela implique est assez faible. Ma carte ne contient pas ma clef principale, qui elle est stocké sur un support déconnecté, mais que des sous-clefs. Si la carte cesse de fonctionner, je renouvelle les sous-clefs.

        • [^] # Re: Qualité de l'aléa de la carte ?

          Posté par  . Évalué à 2.

          Tu ne peux plus rien faire avec tout ce que tu as fait avec ta carte, non ?

          • [^] # Re: Qualité de l'aléa de la carte ?

            Posté par  . Évalué à 2.

            Il est vrai que je ne pourrais plus déchiffrer ce qui était destiné à la clef de chiffrement de la carte. Bon, dans la pratique, j'ai une sauvegarde des parties privées des sous-clefs sur le même support que la clef principale.

            Je veux juste dire que ça ne serait pas si catastrophique que cela de perdre les parties privées de ces sous-clefs, la clef de certification, qui n'est pas utile au jour le jour, étant stocké sur un support différent (et déconnecté).

            • [^] # Re: Qualité de l'aléa de la carte ?

              Posté par  . Évalué à 2.

              Bon, dans la pratique, j'ai une sauvegarde des parties privées des sous-clefs sur le même support que la clef principale.

              Oui, tu l'as dit, tu n'utilises pas la deuxième solution mais la première. Il n'en reste pas moins qu'en l'absence de la sauvegarde de la/les Kpriv, ce qui est le cas dans le deuxième solution, t'es grave dans la merde pour tout ce qui touche la confidentialité en cas de soucis avec la carte à puce, car tu as besoin de la Kpriv, et moins ou pas pour l'intégrité ou l'authentification (faut voir ce dont on a besoin précisément selon les use cases).

          • [^] # Re: Qualité de l'aléa de la carte ?

            Posté par  (site web personnel) . Évalué à 2.

            Pour la sous-clef de signature, ça ne pose aucun problème particulier.

            En revanche, il ne serait en effet plus possible de déchiffrer tout ce qui aurait été chiffré avec l’ancienne sous-clef de chiffrement — par exemple, d’anciens e-mails reçus que tu aurais gardé sous forme chiffrée, ou même des e-mails récents que l’on t’aurait envoyé entre le moment où tu perds l’usage de la carte et le moment où tu mets en circulation les nouvelles sous-clefs.

            Impossible aussi de s’authentifier sur un serveur où la seule clef acceptée serait celle présente sur la carte.

  • # Temps de récupérartion

    Posté par  . Évalué à 5.

    On voit qu'avec la carte, tu repasse au dessus de 512 octets (le trigger) en 3 secondes. Vu que tu fait un poll toutes les deux secondes, je me demande ce que tu aurais comme résultats avec un poll plus fréquent (genre une demi seconde).

    « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

    • [^] # Re: Temps de récupérartion

      Posté par  (site web personnel) . Évalué à 3.

      L’implémentation actuelle ne permet pas un intervalle inférieur à la seconde (le code utilise sleep(3), il faudrait le remplacer par usleep(3) ou nanosleep(2) pour descendre en-deçà de la seconde).

      Avec un poll toutes les secondes, un test fait à l’instant me donne :

      # temps     entropy_avail
      00:31:40    945
      00:31:41    964
      00:31:42    989
      00:31:43    1002
      00:31:44    955
      00:31:45    961
      00:31:46    985
      00:31:47    1013
      00:31:48    963
      00:31:49    4
      00:31:50    780
      00:31:51    781
      00:31:52    797
      00:31:53    802
      00:31:54    803
      00:31:55    804
      

      La génération de la clef est lancée à 00:31:49, l’entropie disponible chute immédiatement à 4. Une seconde plus tard, elle est déjà repassée au-dessus du seuil d’intervention.

  • # webcam

    Posté par  . Évalué à 2.

    Ne pourrait on pas utiliser ce programme pour générer de l'entropie par exemple depuis une simple webcam?
    La chaleur ambiante est connue pour générer du bruit dans les capteur optiques numériques.

    • [^] # Re: webcam

      Posté par  . Évalué à 2.

      Le problème, c'est que pour ajouter un truc vraiment aléatoire (et pas un simple truc qu'on peut prédire), il faut mesurer des choses différentes par webcam.

      « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

      • [^] # Re: webcam

        Posté par  . Évalué à 2.

        Je pensais plutôt au bruit numérique causé par la chaleur. On ne s'intéresse pas à l'image proprement dite mais au bit de poid faible des pixels qui a tendance à fluctuer aléatoirement en fonction du rayonnement infrarouge ambiant.
        Utiliser le bit de poid faible d'un seul pixel n'est probablement pas une bonne idée mais un XOR sur une dizaine ou une centaine de pixels devrait être acceptable pour générer 1 bit aléatoire.
        Avec une image entière on devrait pouvoir générer plusieurs milliers d'octets.

        • [^] # Re: webcam

          Posté par  . Évalué à 3.

          qui a tendance à fluctuer aléatoirement en fonction du rayonnement infrarouge ambiant

          Justement, tu dis que c'est aléatoire, et je dis que si on connaît le modèle, il y a peut-être moyen de définir un sous-ensemble qui réduirait l'espace de l'aléa.

          « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

          • [^] # Re: webcam

            Posté par  . Évalué à 3.

            Par exemple, si tous les sous-pixels, voire les pixels eux même, ne sont pas indépendants. Ou postprocessing du capteur.

    • [^] # Re: webcam

      Posté par  (site web personnel) . Évalué à 6.

      Ne pourrait on pas utiliser ce programme pour générer de l'entropie par exemple depuis une simple webcam?

      Ce programme, non, il n’utilise qu’une smartcard comme seule source d’aléa. Mais si tu veux réutiliser juste le bout de code qui s’occupe d’ajouter les données aléatoires au noyau (pour le combiner avec un code qui obtient des données en provenance d’une webcam), ne te prive pas, c’est libre. :) (Et le bout de code en question ne fait de toute façon que quelques lignes, en fait c’est essentiellement un appel à ioctl(2) sur un descripteur de fichier sur /dev/random.)

  • # haveged

    Posté par  . Évalué à 2.

    À savoir que le démon haveged permet de générer des nombres aléatoires en utilisant l'aléa du matériel. Étant donné qu'il est conseillé d'utiliser plusieurs sources afin de remplir le pool d'entropie du noyau, ce dernier peut être utilisé en complément.

    De mon côté, je suis à la recherche d'une clé USB que je pourrai toujours avoir sur moi et contenant ma/mes clés privées. Auriez vous connaissance d'un tel dispositif ?

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.