The popularity of the Java programming language has led to its wide adoption in cloud computing infrastructures. However, Java applications running in untrusted clouds are vulnerable to various forms of privileged attacks. The emergence of trusted execution environments (TEEs) such as Intel SGX mitigates this problem. TEEs protect code and data in secure enclaves inaccessible to untrusted software, including the kernel and hypervisors. To efficiently use TEEs, developers must manually partition their applications into trusted and untrusted parts, in order to reduce the size of the trusted computing base (TCB) and minimise the risks of security vulnerabilities. However, partitioning applications poses two important challenges: (i) ensuring efficient object communication between the partitioned components, and (ii) ensuring the consistency of garbage collection between the parts, especially with memory-managed languages such as Java. We present Montsalvat, a tool which provides a practical and intuitive annotation-based partitioning approach for Java applications destined for secure enclaves. Montsalvat provides an RMI-like mechanism to ensure inter-object communication, as well as consistent garbage collection across the partitioned components. We implement Montsalvat with GraalVM native-image, a tool for compiling Java applications ahead-of-time into standalone native executables that do not require a JVM at runtime. Our extensive evaluation with micro- and macro-benchmarks shows our partitioning approach to boost performance in real-world applications
academic
Montsalvat: Particionamiento de Aplicaciones Java para Minimizar la TCB en Intel SGX
La popularidad del lenguaje de programación Java ha resultado en su adopción generalizada en infraestructuras de computación en la nube. Sin embargo, las aplicaciones Java que se ejecutan en entornos de nube no confiables son susceptibles a diversos ataques privilegiados. La aparición de Entornos de Ejecución Confiable (TEE) como Intel SGX mitiga este problema. Los TEE protegen el código y los datos dentro de enclaves seguros, impidiéndoles ser accedidos por software no confiable, incluyendo el núcleo e hipervisores. Para utilizar eficientemente los TEE, los desarrolladores deben particionar manualmente las aplicaciones en componentes confiables y no confiables para reducir el tamaño de la Base de Computación Confiable (TCB) y minimizar el riesgo de vulnerabilidades de seguridad. Este artículo propone la herramienta Montsalvat, que proporciona un método de particionamiento basado en anotaciones práctico e intuitivo para aplicaciones Java orientadas a enclaves seguros. Montsalvat proporciona un mecanismo similar a RMI para garantizar la comunicación entre objetos, así como recolección de basura consistente entre componentes particionados.
Amenazas de Seguridad: Las aplicaciones Java en entornos de nube no confiables enfrentan amenazas de ataques privilegiados, incluyendo ataques a nivel de núcleo e hipervisor
Requisito de Minimización de TCB: Al utilizar TEE como Intel SGX, es necesario minimizar la base de computación confiable para reducir la superficie de ataque
Complejidad del Particionamiento: El particionamiento manual de aplicaciones Java requiere manejar problemas complejos como la comunicación entre objetos y la consistencia de la recolección de basura
Soluciones de Aplicación Completa: SCONE, Graphene-SGX, etc., colocan la aplicación completa (incluyendo la JVM) dentro del enclave, resultando en una TCB excesivamente grande (millones de líneas de código)
Soluciones Específicas de Marco: VC3, SecureKeeper, etc., solo se aplican a marcos específicos, careciendo de generalidad
Soluciones Existentes de Particionamiento Java:
Civet requiere LibOS completo, la TCB sigue siendo muy grande
Uranus requiere herramientas de terceros para inferir particiones confiables, requiriendo mayor intervención del desarrollador
Método de Particionamiento Basado en Anotaciones: Se propone un método práctico e intuitivo de anotación a nivel de clase (@Trusted, @Untrusted, @Neutral) para particionar aplicaciones Java
Mecanismo RMI: Se diseña un mecanismo de comunicación de objetos entre enclaves similar a RMI, implementando invocaciones de métodos remotos transparentes a través de objetos proxy
Recolección de Basura Distribuida: Se implementa una extensión de GC basada en referencias débiles, garantizando la consistencia de destrucción de objetos entre montones confiables y no confiables
Integración con GraalVM: Integración profunda con GraalVM native-image, aprovechando la compilación AOT para optimizar el rendimiento
Mejora de Rendimiento: Se logra una mejora de rendimiento significativa en aplicaciones reales (PalDB 6.6×, GraphChi 2.2×)
Entrada: Código fuente de aplicación Java con anotaciones de seguridad
Salida: Native images particionados confiables y no confiables, desplegables en el entorno Intel SGX
Restricciones: Mantener la semántica original de la aplicación, garantizar la comunicación de objetos y la consistencia de GC
Utiliza el marco Javassist para la transformación de bytecode:
Generación de Clases Proxy:
Se genera una clase proxy para cada clase confiable en el tiempo de ejecución no confiable
Se genera una clase proxy para cada clase no confiable en el tiempo de ejecución confiable
Las clases proxy conservan las firmas de método originales, pero el cuerpo del método se reemplaza con llamadas entre enclaves
Inyección de Métodos de Retransmisión:
// El método original se transforma en un método de retransmisión
@CEntryPoint
public static void relayAccount(Isolate ctx, int hash,
CCharPointer buf, int b) {
String s = deserialize(buf);
Account mirror = new Account(s, b);
mirrorProxyRegistry.add(hash, mirror);
}
Mecanismo de Mapeo de Objetos:
A cada objeto proxy se le asigna un valor hash único
Se mantienen registros de mapeo proxy-objeto espejo
Se implementan referencias de objetos entre enclaves mediante valores hash
// Sincronización de GC basada en referencias débiles
WeakReference<ProxyObject> weakRef = new WeakReference<>(proxy);
proxyWeakRefs.add(new ProxyWeakRefEntry(weakRef, proxy.getHash()));
// Helper de GC verifica periódicamente
if (weakRef.get() == null) {
// El objeto proxy ha sido recolectado, notifica al otro lado
// para destruir el objeto espejo
notifyMirrorDestruction(hash);
}
@Trusted class DBReader // Operaciones de lectura sensibles protegidas
@Untrusted class DBWriter // Operaciones de escritura I/O movidas fuera del enclave
El esquema RTWU tiene mejor rendimiento porque evita costosas transiciones de escritura del enclave.
El artículo cita 60 referencias relacionadas, cubriendo múltiples campos incluyendo tecnología SGX, aplicaciones TEE, seguridad Java, optimización de compilación, etc., proporcionando una base teórica sólida para esta investigación.
Evaluación General: Este es un artículo de investigación de sistemas de alta calidad que resuelve el problema práctico del despliegue de aplicaciones Java en entornos TEE. El diseño del método es razonable, la implementación es completa, los experimentos son suficientes, y posee excelente valor académico y práctico. Aunque aún hay espacio para mejora en la sobrecarga de RMI y la aplicabilidad, proporciona referencias importantes para investigaciones en campos relacionados.