GNU/Linux >> Tutoriales Linux >  >> Linux

¿Es apropiado utilizar haveged como fuente de entropía en las máquinas virtuales?

(Advertencia: Ciertamente no afirmo que HAVEGE esté a la altura de sus afirmaciones. No he comprobado su teoría o implementación.)

Para obtener aleatoriedad, HAVEGE y sistemas similares se alimentan de "eventos físicos" y, en particular, del tiempo de eventos físicos. Dichos eventos incluyen ocurrencias de interrupciones de hardware (que, a su vez, recopilan datos sobre pulsaciones de teclas, movimientos del mouse, paquetes de Ethernet entrantes, tiempo para que un disco duro complete una solicitud de escritura...). HAVEGE también afirma alimentarse de todos los tipos de errores de caché que ocurren en una CPU (caché L1, caché L2, TLB, predicción de rama...); el comportamiento de estos elementos depende de lo que la CPU haya estado haciendo en los miles de ciclos de reloj anteriores, por lo que existe la posibilidad de cierta "aleatoriedad". Esto depende de la posibilidad de medir la hora actual con gran precisión (no necesariamente exactitud), que es donde el rdtsc entra en juego la instrucción. Devuelve el contenido actual de un contador interno que se incrementa en cada ciclo de reloj, por lo que ofrece una precisión de subnanosegundos.

Para un sistema de máquina virtual, hay tres opciones con respecto a esta instrucción:

  1. Deje que la instrucción vaya directamente al hardware.
  2. Atrapa la instrucción y emulala.
  3. Deshabilitar la instrucción por completo.

Si el administrador de VM elige la primera solución, entonces rdtsc tiene toda la precisión necesaria y debería funcionar tan bien como si estuviera en una máquina física, con el fin de recopilar entropía de los eventos de hardware. Sin embargo, dado que se trata de una máquina virtual, es una aplicación en el sistema host; no obtiene la CPU todo el tiempo. Desde el punto de vista del sistema operativo invitado usando rdtsc , esto parece como si su CPU fuera "robada" ocasionalmente:dos rdtsc sucesivos las instrucciones, nominalmente separadas por un solo ciclo de reloj, pueden reportar un aumento del contador en varios millones . En pocas palabras, cuando rdtsc simplemente se aplica en el hardware, luego el sistema operativo invitado puede usarlo para detectar la presencia de un hipervisor.

La segunda solución está destinada a hacer que la emulación sea más "perfecta" al mantener un contador de ciclos virtual por VM, que realiza un seguimiento de los ciclos realmente asignados a esa VM. La ventaja es que rdtsc , desde el punto de vista del huésped, ya no exhibirá el efecto de "ciclos robados". La desventaja es que esta emulación se realiza mediante la activación y captura de una excepción de CPU, lo que aumenta el costo de rdtsc código de operación de unas pocas docenas de ciclos de reloj (depende de la marca de la CPU; algunos ejecutan rdtsc en menos de 10 ciclos, otro uso 60 o 70 ciclos) a más de mil de ciclos Si el invitado intenta hacer mucho rdtsc (como HAVEGE será propenso a hacer), luego se ralentizará a paso de tortuga. Además, el código de manejo de excepciones interrumpirá la medida; en lugar de medir el tiempo de los eventos de hardware, el código medirá el tiempo de ejecución del controlador de excepciones, lo que posiblemente puede reducir la calidad de la aleatoriedad extraída.

La tercera solución (deshabilitar rdtsc ) simplemente evitará que HAVEGE devuelva una buena aleatoriedad. Dado que utiliza internamente un PRNG, la salida aún puede engañar a las herramientas de análisis estadístico, porque hay una gran diferencia entre "aparentar aleatorio" y "ser impredecible" (las herramientas de análisis estadístico siguen el camino de "aparentar aleatorio", pero la seguridad criptográfica se basa en la imprevisibilidad ).

El manual de VirtualBox afirma que VirtualBox, por defecto, sigue el primer método (rdtsc se permite incondicionalmente y se aplica directamente en el hardware), pero se puede configurar para aplicar la segunda solución (que no desea, en este caso).

Para probar lo que hace su VM, puede probar este pequeño programa (compilar con gcc -W -Wall -O en Linux; el -O es importante):

#include <stdio.h>

#if defined(__i386__)

static __inline__ unsigned long long rdtsc(void)
{
        unsigned long long int x;

        __asm__ __volatile__ (".byte 0x0f, 0x31" : "=A" (x));
        return x;
}

#elif defined(__x86_64__)

static __inline__ unsigned long long rdtsc(void)
{
        unsigned hi, lo;

        __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
        return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}

#endif

int
main(void)
{
        long i;
        unsigned long long d;

        d = 0;
        for (i = 0; i < 1000000; i ++) {
                unsigned long long b, e;

                b = rdtsc();
                e = rdtsc();
                d += e - b;
        }
        printf("average : %.3f\n", (double)d / 1000000.0);
        return 0;
}

En una máquina no virtual, con el "verdadero" rdtsc , este deberá reportar un valor entre 10 y 100, dependiendo de la marca de la CPU. Si el valor informado es 0, o si el programa falla, entonces rdtsc está desactivado. Si el valor está en miles, entonces rdtsc se emula, lo que significa que la recopilación de entropía puede no funcionar tan bien como se esperaba.

Tenga en cuenta que incluso obtener un valor entre 10 y 100 no garantiza que rdtsc no se emula, porque el administrador de VM, mientras mantiene su contador virtual, puede restarle el tiempo esperado necesario para la ejecución del controlador de excepciones. En última instancia, realmente necesita echar un buen vistazo al manual y la configuración de su administrador de VM.

Por supuesto, toda la premisa de HAVEGE es cuestionable. Para cualquier seguridad práctica, necesita algunos bits "aleatorios reales", no más de 200, que usa como semilla en un PRNG criptográficamente seguro. El PRNG producirá gigabytes de pseudo-alea indistinguibles de la verdadera aleatoriedad, y eso es lo suficientemente bueno para todos los propósitos prácticos.

Insistir en volver al hardware por cada bit parece otro brote de esa idea defectuosa que ve la entropía como una especie de gasolina, que se quema cuando se mira.


Sobre el aviso de polarssl:se puede encontrar una respuesta técnica detallada en la fuente de Debian más reciente:

http://bazaar.launchpad.net/~ubuntu-branches/debian/experimental/haveged/experimental/revision/12?start_revid=12#debian/README.Debian

El resumen ejecutivo es:polarssl !=haveged !=HAVEGE

Sobre los experimentos del emulador embloms.se:

El haveged conjunto de pruebas, NIST y ent , verifique que una compilación fuente haya producido un RNG funcional. Se requieren pruebas en tiempo de ejecución para verificar el funcionamiento protegido en un entorno virtual. Esa es una adición bastante reciente a haveged.

Sobre las pruebas estadísticas:

Supongamos que tiene un hardware RNG , un TRNG , ¿cómo sabes que no está roto? Roturas de hardware. El organismo de normalización alemán tiene una especificación que se ocupa de ese mismo problema, AIS31 . Ese enfoque es adoptado por haveged. En:

http://www.issihosts.com/haveged/ais31.html

La no previsibilidad de HAVEGE es exactamente el mismo mecanismo visto en el software de evaluación comparativa. No se debe a la deriva del temporizador, sino a la agregación de los comportamientos asíncronos en un procesador moderno. Realmente no importa si las variaciones de rendimiento provienen de una falta de memoria caché o de un intervalo de tiempo entregado a otro procesador. La precisión del temporizador tampoco importa siempre que sea "adecuada". ¿Cómo se determina eso? Por la salida. Por diseño (o quizás por diseño) /dev/random es inmune a los datos de entrada deficientes. La única manera de subvertir el diseño es mentir sobre la entropía añadida al fondo de entropía. Las versiones más recientes de haveged realizan una estimación de entropía en tiempo de ejecución en la salida generada para garantizar que la salida sea consistente con un TRNG ideal.

Resumen ejecutivo:haveged la salida es indistinguible de un TRNG según las pruebas utilizadas por el organismo de normalización alemán para certificar TRNG . Si ese no es el caso, haveged se apagará.


(Actualizado , con agradecimiento a gwuertz el autor/mantenedor actual de haveged , me perdí la separación entre HAVEGE y haveged .)

haveged es una implementación distinta del método HAVEGE para generar números aleatorios, está actualizado, mantenido y documentado aquí:http://www.issihosts.com/haveged/ (y ya no usa libhavege directamente).

HAVEGE no es muy actual (2006), aunque alguien lo ha parcheado más recientemente (2009) por velocidad y corrección. Sería cauteloso porque no documenta su método, no menciona las máquinas virtuales y, como se señaló, se basa (en gran medida) en RDTSC (o plataforma equivalente). (También el código fuente me hace estremecer, pero eso es bastante subjetivo).

Argumentaré que la VM del host no debería filtrar involuntariamente ningún estado a los invitados, por lo que no debe considerarse una buena fuente de entropía cuando se usa este método.

Un mejor enfoque en Linux es rng-tools con el controlador rng paravirtualizado virtio-rng (es decir, permitir que un invitado acceda a la entropía recopilada por el host, eliminando muchos problemas potenciales sobre la vista de invitados de eventos "aleatorios"), o puede encontrar Entropy Corredor más útil. En chips Intel recientes, también puede exponer la instrucción RDRAND a los invitados, evitando el problema.

Este artículo (de la charla de hpa en LinuxCon Europe 2012 ) es una lectura útil:http://lwn.net/Articles/525459/ , también analiza HAVEGE /haveged (aunque la distinción tampoco está clara aquí).

Consulte las respuestas a esta pregunta para obtener algunas ideas sobre cómo determinar la falta de aleatoriedad:¿Qué estadísticas se pueden usar para identificar datos pseudoaleatorios?


Linux
  1. ¿Qué solución de copia de seguridad de código abierto utiliza?

  2. Cómo eliminar máquinas virtuales basadas en KVM en Redhat Linux

  3. Quickemu:ejecute máquinas virtuales Windows, macOS y Linux

  4. Máquinas virtuales semanales, con scripts de compilación

  5. Cómo usar el comando fuente dentro del script de canalización de Jenkins

Administre máquinas virtuales KVM con el programa Virsh

Cómo crear máquinas virtuales Proxmox desde el panel de interfaz de usuario web de Proxmox VE

Cómo exportar e importar máquinas virtuales VirtualBox

10 paneles de control comerciales/de código abierto para la gestión de máquinas virtuales (VM)

Cómo crear y administrar máquinas virtuales en KVM

¿Qué es BusyBox en Linux? ¿Cómo usarlo?