Contexte technique
Les instructions RDRAND et RDSEED d’AMD et d’Intel fournissent du hasard matériel directement depuis le processeur. Elles sont souvent exploitées dans les bibliothèques cryptographiques pour alimenter les générateurs de nombres pseudo‑aléatoires (CSPRNG). Le forum Flat Assembler recense un problème observé uniquement sur des processeurs AMD Zen 2 : lorsqu’on demande un résultat de 16 bits, la valeur 0 n’apparaît jamais, alors qu’elle est présente sans aucune restriction sur les mêmes programmes exécutés sur un processeur Intel.
Analyse du dysfonctionnement
Le test décrit consiste à appeler RDRAND ou RDSEED en mode 16 bits et à compter les occurrences de chaque valeur dans l’intervalle 0‑65535. Sur AMD, le compteur de zéro reste à zéro, alors que les 65 535 autres valeurs sont observées. Le même code, exécuté en 32 bits ou 64 bits, produit bien des zéros dans les 16 bits de poids faible, ce qui indique que le problème ne provient pas du pipeline de génération mais de la façon dont le processeur traite les requêtes de petite taille.
Selon la spécification d’Intel et d’AMD, RDRAND doit générer une distribution uniforme sur l’ensemble du domaine demandé, incluant la valeur nulle. L’absence de zéro suggère une forme de bias introduite par le micro‑code AMD lorsqu’il effectue un « masking » ou un « re‑roll » des résultats qui seraient égaux à zéro. Une hypothèse plausible est que le circuit interne de l’entropie élimine les états de sortie nuls pour éviter une éventuelle confusion avec un code d’erreur, bien que la documentation officielle ne mentionne aucun tel comportement.
Correction pratique
Le contournement proposé consiste à demander un nombre de 32 bits ou 64 bits, puis à tronquer les 16 bits de poids faible pour l’affichage. Cette méthode réintroduit les zéros parce que la partie basse d’un nombre aléatoire de plus grande taille possède la même probabilité d’être nulle que n’importe quel autre sous‑ensemble de bits. Le code de démonstration fourni dans l’archive gtk4-bargraph.tar.gz montre comment remplacer les lignes :
rdrand ax ; 16‑bitpar :
rdrand eax ; 32‑bit
and eax, 0xFFFF ; garder les 16 bits de poids faibleCette modification élimine l’anomalie visuelle du graphique et confirme que le générateur produit bien des zéros lorsqu’on ne contraint pas explicitement la largeur de sortie.
Implications pour la sécurité
Dans les scénarios cryptographiques, l’utilisation directe de RDRAND ou RDSEED comme source d’entropie brute est déjà déconseillée sans post‑traitement, car les sorties peuvent contenir des biais ou être sujettes à des attaques de récupération d’état. Le biais observé sur AMD Zen 2 accentue ce risque : un algorithme qui suppose une distribution parfaitement uniforme pourrait sous‑estimer la probabilité d’occurrence de certaines valeurs, affectant notamment les protocoles qui utilisent le zéro comme point de départ (ex. génération de clés à base de zéro, nonces). Même si le contournement logiciel résout le problème pour les applications non critiques, les développeurs de bibliothèques cryptographiques doivent intégrer une étape de « whitening » ou de mélange supplémentaire afin de neutraliser tout biais matériel.