I also would like to know if it would be theoretically possible (whilst obviously difficult) to translate an existing JIT compiler (e.g. .NET CLR) that produces code that automatically encrypts its user-mode memory.
Potrebbe essere piuttosto difficile per il sistema operativo fare per conto di un programma. La ragione di ciò è che le pagine virtuali allocate dal sistema operativo sono infatti controllate dalla CPU: il sistema operativo istruisce la CPU su ciò che vuole in termini di aree di memoria e la CPU calcola quindi gli offset su quella base per ciascun programma e applica direttamente il risultato. Leggi la MMU e Paging on 86 .
In breve, quando il tuo programma esegue il calcolo mov eax, [edi+something]
, MMU / paging gestisce la traduzione degli indirizzi e genera un errore di pagina quando la pagina non viene trovata. Ciò ti consente di caricare la pagina fuori dallo spazio di archiviazione, se necessario.
Quindi l'accesso alla memoria non passa attraverso il kernel di per sé e come tale non può essere agganciato ed elaborato come un file in lettura o scrittura (le tue letture e le tue scritture vengono tradotte attraverso le appropriate chiamate di sistema nel file system appropriato In questo modo, il sistema operativo vede i dati mentre passa. Non è necessaria una chiamata di sistema per scrivere in RAM. È possibile crearne uno, ma funzionerà solo con i programmi che lo chiamano e quindi non con la maggior parte dei programmi).
Tuttavia, ciò non significa che un processo JIT non potrebbe farlo a nome di un'applicazione, o l'applicazione stessa non potrebbe mantenere i dati crittografati fino a quando non è necessario caricarla nei registri, decodificandola mentre passa sopra i dati.
In questo caso, sei interessato al problema SteveS copre bene - hai un problema di archiviazione chiave. La chiave stessa deve essere anche nella RAM da qualche parte. Questo è un problema di tartarughe fino alla fine - fondamentalmente è impossibile mantenere la chiave "sicura".
Infine, poiché essere in grado di leggere la RAM di un'altra applicazione richiede l'accesso in modalità supervisore alla CPU (ad esempio lo spazio del kernel), probabilmente si hanno problemi più grandi se si tratta di intercettazione del software. Se la tua preoccupazione è l'hardware, penso che la sicurezza fisica potrebbe essere un modo migliore per mitigare il rischio.
Modifica ho cercato documenti. Eccone uno chiamato CryptKeeper . La loro tecnica consiste nell'avere un grande "disco RAM" crittografato come file di scambio e scambiare tutte le loro pagine con quelle non utilizzate:
We mitigate this vulnerability with Cryptkeeper (CK), a
software-encrypted virtual memory manager. Traditional pro-
cessors cannot operate on encrypted data, so CK segments
RAM into a smaller working set called the Clear, and a
larger encrypted RAM device called the Crypt. As the working
space fills, pages are automatically swapped into the encrypted
portion of memory, and are decrypted on demand.
A quanto pare, le prestazioni non sono male, ma non penso che ci siano ancora implementazioni di questo.
Modifica 2 Quindi risulta che CryptKeeper ei meccanismi di crittografia OpenBSD Swap funzionano a un livello molto simile; in realtà non crittografa la memoria fisica ma utilizza la memoria fisica come una struttura di swap, forzando gli errori di pagina e crittografando / decifrando i dati in risoluzione.
MODIFICA dall'autore delle domande, dicembre 2018: AMD ora supporta l' estensione del set di istruzioni per le PMI che consente la crittografia hardware delle pagine RAM, oltre a TSME per la crittografia a piena memoria e SEV per l'uso con la memoria crittografata nella virtualizzazione. Ciò sembra abilitare la crittografia della memoria dell'intero sistema sulle moderne piattaforme AMD64.