L'avvio verificato richiede la verifica crittografica di tutto il codice eseguibile e dei dati che fanno parte della versione di Android avviata prima che venga utilizzata. Ciò include il kernel (caricato dalla partizione boot
), l'albero dei dispositivi (caricato dalla partizione dtbo
), la partizione system
, la partizione vendor
e così via.
Piccole partizioni, come boot
e dtbo
, che vengono lette solo una volta, vengono generalmente verificate caricando l'intero contenuto in memoria e quindi calcolandone l'hash. Questo valore hash calcolato viene quindi confrontato con il valore hash previsto . Se il valore non corrisponde, Android non verrà caricato. Per ulteriori dettagli, vedere Flusso di avvio .
Partizioni più grandi che non si adattano alla memoria (come i file system) possono utilizzare un albero hash in cui la verifica è un processo continuo che avviene mentre i dati vengono caricati in memoria. In questo caso, l'hash root dell'albero hash viene calcolato durante il runtime e confrontato con il valore hash root previsto . Android include il driver dm-verity per verificare partizioni più grandi. Se a un certo punto l'hash root calcolato non corrisponde al valore hash root previsto , i dati non vengono utilizzati e Android entra in uno stato di errore. Per ulteriori dettagli, vedere corruzione di dm-verity .
Gli hash previsti vengono generalmente archiviati alla fine o all'inizio di ciascuna partizione verificata, in una partizione dedicata o in entrambi. Fondamentalmente, questi hash sono firmati (direttamente o indirettamente) dalla radice della fiducia. Ad esempio, l'implementazione AVB supporta entrambi gli approcci, vedere Android Verified Boot per i dettagli.
Protezione antiritorno
Anche con un processo di aggiornamento completamente sicuro, è possibile che un exploit del kernel Android non persistente installi manualmente una versione precedente e più vulnerabile di Android, si riavvii nella versione vulnerabile e quindi utilizzi quella versione di Android per installare un exploit persistente. Da lì l'aggressore possiede permanentemente il dispositivo e può fare qualsiasi cosa, incluso disabilitare gli aggiornamenti.
La protezione contro questa classe di attacchi si chiama Rollback Protection . La protezione di rollback viene in genere implementata utilizzando un'archiviazione a prova di manomissione per registrare la versione più recente di Android e rifiutando di avviare Android se è inferiore alla versione registrata. Le versioni vengono in genere monitorate in base alla partizione.
Per ulteriori dettagli su come AVB gestisce le protezioni di rollback, vedere AVB README .
Gestione degli errori di verifica
La verifica può fallire al momento dell'avvio (ad esempio, se l'hash calcolato sulla partizione boot
non corrisponde all'hash previsto) o al momento dell'esecuzione (ad esempio, se dm-verity rileva un errore di verifica sulla partizione system
). Se la verifica fallisce al momento dell'avvio, il dispositivo non potrà avviarsi e l'utente finale dovrà eseguire i passaggi per ripristinare il dispositivo.
Se la verifica fallisce in fase di esecuzione, il flusso è un po' più complicato. Se il dispositivo utilizza dm-verity, deve essere configurato in modalità restart
. In modalità restart
, se viene riscontrato un errore di verifica, il dispositivo viene immediatamente riavviato con un flag specifico impostato per indicarne il motivo. Il boot loader dovrebbe notare questo flag e passare dm-verity alla modalità Errore I/O ( eio
) e rimanere in questa modalità fino all'installazione di un nuovo aggiornamento.
Quando si avvia in modalità eio
, il dispositivo mostra una schermata di errore che informa l'utente che è stato rilevato un danneggiamento 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 riavvierà il dispositivo se si verifica un errore di verifica, ma verrà restituito un errore EIO e l'applicazione dovrà gestire l'errore.
L'intento è che il programma di aggiornamento del sistema venga eseguito (in modo da poter installare un nuovo sistema operativo senza errori di corruzione) oppure che l'utente possa ottenere la maggior quantità 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
.