Verified Boot richiede la verifica crittografica di tutto il codice eseguibile e dei dati
che fanno parte della versione di Android in fase di avvio prima che vengano utilizzati. Sono inclusi
il kernel (caricato dalla partizione boot
), l'albero dei dispositivi (caricato
dalla partizione dtbo
), la partizione system
,
la partizione vendor
e così via.
Le partizioni piccole, come boot
e dtbo
, che vengono lette
solo una volta vengono in genere verificate caricando l'intero contenuto in memoria e
calcolandone l'hash. Il valore hash calcolato viene quindi confrontato con il
valore hash previsto. Se il valore non corrisponde, Android non verrà caricato.
Per maggiori dettagli, vedi Flusso di avvio.
Le partizioni più grandi che non possono essere caricate in memoria (ad esempio, i file system) potrebbero utilizzare un albero hash in cui la verifica è un processo continuo che si verifica durante il caricamento dei dati in memoria. In questo caso, l'hash radice dell'albero hash viene calcolato durante l'esecuzione e viene confrontato con il valore hash radice previsto. Android include il driver dm-verity per verificare partizioni più grandi. Se a un certo punto l'hash radice calcolato non corrisponde al valore hash radice previsto, i dati non vengono utilizzati e Android entra in uno stato di errore. Per maggiori dettagli, vedi Corruzione di dm-verity.
Gli hash previsti vengono in genere memorizzati alla fine o all'inizio di ogni partizione verificata, in una partizione dedicata o in entrambi. Fondamentalmente, questi hash sono firmati (direttamente o indirettamente) dalla radice di attendibilità. Ad esempio, l'implementazione di AVB supporta entrambi gli approcci. Per maggiori dettagli, consulta Avvio verificato di Android.
Protezione rollback
Anche con una procedura di aggiornamento completamente sicura, è possibile che un exploit del kernel Android non persistente installi manualmente una versione precedente e più vulnerabile di Android, riavvii il sistema nella versione vulnerabile e poi utilizzi quella versione di Android per installare un exploit persistente. Da quel momento, l'aggressore diventa proprietario permanente del dispositivo e può fare qualsiasi cosa, inclusa la disattivazione degli aggiornamenti.
La protezione contro questa classe di attacchi è chiamata Rollback Protection. La protezione dal rollback viene in genere implementata utilizzando un archivio antimanomissione per registrare la versione più recente di Android e rifiutando l'avvio di Android se la versione è precedente a quella registrata. Le versioni vengono in genere monitorate in base alla partizione.
Per maggiori dettagli su come AVB gestisce le protezioni di rollback, consulta il file README di AVB.
Gestire gli errori di verifica
La verifica può non riuscire all'avvio (ad esempio, se l'hash calcolato sulla partizione boot
non corrisponde all'hash previsto) o in fase di runtime (ad esempio, se dm-verity rileva un errore di verifica sulla partizione system
). Se la verifica non va a buon fine all'avvio, il dispositivo
non può avviarsi e l'utente finale deve seguire i passaggi per ripristinarlo.
Se la verifica non riesce in fase di runtime, il flusso è un po' più complicato. Se il
dispositivo utilizza dm-verity, deve essere configurato in modalità restart
. In modalità
restart
, se si verifica un errore di verifica, il dispositivo viene
riavviato immediatamente con un flag specifico impostato per indicare il motivo. Il bootloader
dovrebbe notare questo flag e passare a dm-verity per utilizzare la modalità I/O Error
(eio
) e rimanere in questa modalità finché non viene installato un nuovo aggiornamento.
Durante l'avvio in modalità eio
, il dispositivo mostra una schermata di errore
che informa l'utente che è stata rilevata una corruzione e che il dispositivo potrebbe non
funzionare correttamente. La schermata viene visualizzata finché l'utente non la chiude. In modalità
eio
il driver dm-verity non riavvia il dispositivo se viene rilevato un
errore di verifica, ma viene restituito un errore EIO e l'app deve gestire l'errore.
L'intento è che venga eseguito l'aggiornamento del sistema (in modo da poter installare un nuovo sistema operativo senza errori di danneggiamento) o che l'utente possa recuperare il maggior numero possibile di dati dal dispositivo. Una volta installato il nuovo sistema operativo, il boot loader
rileva il sistema operativo appena installato e torna alla modalità restart
.