O gerador de números aleatórios da AMD não consegue gerar um 0?
CPUs da AMD parecem ter um bug em que a instrução de número aleatório de hardware de certas gerações (notavelmente `rdrand16` do Zen 2) quase nunca produz um 0 verdadeiro, ou sinaliza saídas zero como falhas, levantando dúvidas sobre o viés em valores que deveriam ser uniformemente aleatórios. Comentadores observam que a maioria dos sistemas não usa esses números de hardware diretamente, mas como sementes para RNGs de software mais fortes, e que kernels modernos misturam múltiplas fontes de entropia, de modo que uma única fonte defeituosa não deveria ser catastrófica — embora a história mostre que até pequenos vieses em RNGs podem virar vulnerabilidades reais. O debate se amplia para a questão de confiar ou não em RNGs opacos implementados pelo fornecedor, como kernels se protegem contra fontes de entropia ruins ou maliciosas, e os riscos de criar RNGs criptográficos personalizados no espaço do usuário.
Natureza do bug do RNG da AMD
- Relatos se concentram em CPUs da era Zen 1/2, nas quais
RDRAND16aparentemente nunca retorna 0, enquantoRDRAND32/64retornam. - Testes mais cuidadosos mostram que
RDRAND16pode gerar internamente 0, mas, quando isso acontece, o bit de carry (CF) é definido como 0, sinalizando “falha / tente novamente”.- Wrappers típicos então descartam esses resultados e repetem o loop, de modo que o código do usuário, na prática, nunca vê um zero de 16 bits.
- A taxa de “falhas” com CF=0 se alinha com 1/65536, e todas essas falhas retornam 0, sugerindo um comportamento sistemático em vez de pura ausência de 0.
- Gerações mais novas (Zen 3/4) não mostram o problema nos testes; o Zen 5 tem um erratum relacionado ao RDSEED em que um resultado todo em zero com CF=1 pode levar a workarounds semelhantes que reintroduzem um comportamento de “nunca zero”.
Relação com problemas passados de RNG em hardware
- Bugs anteriores de microcódigo no Zen 2 faziam com que
RDRANDsempre retornasse tudo 1 até ser atualizado. - Há preocupação de que “correções” de microcódigo possam ter trocado um padrão de erro (tudo 1) por outro (sem 0s).
- Alguns operadores de sistemas desativaram a confiança no RNG da CPU no kernel Linux por causa desse tipo de falha da AMD.
Impacto em segurança e qualidade da aleatoriedade
- Um lado: o impacto prático é mínimo porque:
- O RNG de hardware normalmente só é usado para semear um CSPRNG, como o pool do kernel.
- Perder 1 valor em 2^16 (ou 2^32/2^64) mal reduz o espaço de chaves.
- Outro lado: qualquer viés sistemático é um sinal de alerta:
- A história da criptografia mostra que pequenos vieses podem se tornar exploráveis em alguns protocolos.
- Mesmo que este viés específico seja provavelmente inofensivo, descartá-lo é visto como arriscado.
- A discussão revisita conceitos básicos:
- A saída desejada é uma distribuição uniforme discreta; “nunca 0” é viés.
- Previsibilidade não é apenas “não ser sempre o mesmo valor”, mas “nenhum valor ou predicado é favorecido”.
Mistura de entropia e confiança em hardware
- Há amplo consenso: não confie em um único RNG de hardware opaco; misture múltiplas fontes por meio de uma construção forte (CSPRNG, sponge ou XOF).
- Debate sobre:
- Se adicionar uma fonte “ruim”, mas não maliciosa, pode piorar um pool bom (a maioria diz que não; outros citam ataques em que uma fonte maliciosa que vê as outras entradas pode enviesar a saída).
- Se é melhor usar sempre interfaces do kernel (
/dev/urandom,getentropy/getrandom) em vez de criar RNGs no espaço do usuário.
- Alguns argumentam fortemente contra RNGs personalizados (histórico de falhas reais); outros defendem designs personalizados maduros, testados por muito tempo, baseados em XOF, especialmente para uso multiplataforma ou embarcado.
Validação, testes e como isso passou despercebido
- Vários comentaristas se surpreendem que um bug de distribuição tão simples tenha passado pela validação de hardware; hipóteses incluem:
- Planos de verificação incompletos (sem um bin específico de cobertura para 0).
- Erros de off-by-one.
- Observação prática: gerar um histograma de todas as 65.536 saídas de 16 bits é um teste de caixa-preta simples que deveria detectar essa classe de erro.