También me gustaría saber si sería teóricamente posible (aunque obviamente difícil) traducir un compilador JIT existente (por ejemplo, .NET CLR) que produce código que encripta automáticamente su memoria de modo de usuario.
Esto podría ser bastante difícil de hacer para el sistema operativo en nombre de un programa. La razón de esto es que las páginas virtuales asignadas por el sistema operativo son controladas por la CPU: el sistema operativo le indica a la CPU qué quiere en términos de áreas de almacenamiento y la CPU calcula las compensaciones sobre esa base para cada programa. y aplica el resultado directamente. Lea el MMU y sobre la página x86 .
En resumen, cuando su programa realiza el cálculo mov eax, [edi+something]
, la MMU / paginación maneja la traducción de la dirección y emite un error de página cuando no se encuentra la página. Eso le permite cargar la página fuera de almacenamiento, si es necesario.
Por lo tanto, el acceso a la memoria no pasa por el kernel per se y, como tal, no se puede conectar y procesar como un archivo puede leer o escribir (sus lecturas y escrituras se traducen a través de las llamadas apropiadas del sistema al sistema de archivos apropiado estructura. Como tal, el sistema operativo ve los datos a medida que pasan. No necesita una llamada del sistema para escribir en la RAM. Podría crear uno, pero solo funcionaría para los programas que lo llaman y, por lo tanto, no para la mayoría de los programas).
Sin embargo, eso no significa que un proceso JIT no pueda hacer esto en nombre de una aplicación, o la aplicación en sí misma no podría mantener los datos cifrados hasta que necesite cargarlos en registros, descifrarlos a medida que pasan. sobre los datos.
En ese caso, te interesa el tema SteveS Cubre bien - tienes un problema clave de almacenamiento. La clave en sí también debe estar en la memoria RAM en algún lugar. Este es un problema de las tortugas en su totalidad: básicamente, es imposible mantener esa llave "segura".
Finalmente, dado que poder leer la RAM de otra aplicación requiere acceso de modo supervisor a la CPU (es decir, espacio del kernel), es probable que tenga problemas mayores si su preocupación es la interceptación del software. Si su preocupación es el hardware, creo que la seguridad física podría ser una mejor manera de mitigar el riesgo.
Editar Busqué documentos. Aquí hay uno llamado CryptKeeper . Su técnica es tener un gran "disco RAM encriptado" como archivo de intercambio y cambiar todas sus páginas cuando no se utiliza:
Mitigamos esta vulnerabilidad con Cryptkeeper (CK), un
Administrador de memoria virtual encriptado por software. Productos tradicionales
Los procesadores no pueden operar con datos encriptados, por lo que los segmentos CK
RAM en un conjunto de trabajo más pequeño llamado Clear, y un
Dispositivo de memoria RAM encriptado más grande llamado Crypt. Como el trabajo
espacio se llena, las páginas se intercambian automáticamente en el cifrado
parte de la memoria, y se descifran bajo demanda.
Aparentemente, el rendimiento no es tan malo, pero no creo que haya implementaciones todavía.
Edit 2 Así que resulta que CryptKeeper y el mecanismos de cifrado de intercambio de OpenBSD funcionan en un nivel muy similar; en realidad no encripta la memoria física, pero usa la memoria física como una estructura de intercambio, forzando fallas de página y encriptando / desencriptando datos en resolución.
EDIT del autor de la pregunta, diciembre de 2018: AMD ahora admite la extensión del conjunto de instrucciones de SME que permite el cifrado de hardware de las páginas RAM, más TSME para el cifrado de memoria completa, y SEV para su uso con memoria cifrada en virtualización. Esto parece habilitar el cifrado de la memoria del sistema completo en las plataformas AMD64 modernas.