Crittografia dei metadati

Android 7.0 e versioni successive supportano la crittografia basata su file (FBE). FBE consente di crittografare file diversi con chiavi diverse che possono essere sbloccate in modo indipendente. Queste chiavi vengono utilizzate per crittografare sia il contenuto che i nomi dei file. Quando viene utilizzato FBE, altre informazioni, come layout di directory, dimensioni dei file, autorizzazioni e orari di creazione/modifica, non vengono crittografate. Collettivamente, queste altre informazioni sono note come metadati del filesystem.

Android 9 ha introdotto il supporto per la crittografia dei metadati. Con la crittografia dei metadati, una singola chiave presente al momento dell'avvio crittografa qualsiasi contenuto non crittografato da FBE. Questa chiave è protetta da Keymaster, che a sua volta è protetta da avvio verificato.

La crittografia dei metadati è sempre abilitata nell'archiviazione adottabile ogni volta che FBE è abilitato. La crittografia dei metadati può essere abilitata anche sulla memoria interna. I dispositivi avviati con Android 11 o versioni successive devono avere la crittografia dei metadati nella memoria interna abilitata.

Implementazione sulla memoria interna

Puoi configurare la crittografia dei metadati nella memoria interna dei nuovi dispositivi configurando il file system metadata , modificando la sequenza di inizializzazione e abilitando la crittografia dei metadati nel file fstab del dispositivo.

Prerequisiti

La crittografia dei metadati può essere configurata solo quando la partizione dati viene formattata per la prima volta. Di conseguenza, questa funzionalità è solo per i nuovi dispositivi; questo non è qualcosa che un'OTA dovrebbe cambiare.

La crittografia dei metadati richiede che il modulo dm-default-key sia abilitato nel kernel. In Android 11 e versioni successive, dm-default-key è supportato dai kernel comuni di Android, versione 4.14 e successive. Questa versione di dm-default-key utilizza un framework di crittografia indipendente dall'hardware e dal fornitore chiamato blk-crypto .

Per abilitare dm-default-key , utilizzare:

CONFIG_BLK_INLINE_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y
CONFIG_DM_DEFAULT_KEY=y

dm-default-key utilizza l'hardware di crittografia in linea (hardware che crittografa/decrittografa i dati mentre sono in viaggio da/verso il dispositivo di archiviazione) quando disponibile. Se non utilizzerai l'hardware di crittografia in linea, è anche necessario abilitare un fallback all'API di crittografia del kernel:

CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y

Quando non si utilizza l'hardware di crittografia in linea, è necessario abilitare anche l'eventuale accelerazione basata sulla CPU disponibile, come consigliato nella documentazione di FBE .

In Android 10 e versioni precedenti, dm-default-key non era supportato dal kernel comune di Android. Spettava quindi ai fornitori implementare dm-default-key .

Configura il file system dei metadati

Poiché non è possibile leggere nulla nella partizione dei dati utente finché non è presente la chiave di crittografia dei metadati, la tabella delle partizioni deve riservare una partizione separata denominata "partizione dei metadati" per archiviare i BLOB del keymaster che proteggono questa chiave. La partizione dei metadati dovrebbe essere 16 MB.

fstab.hardware deve includere una voce per il filesystem di metadati che risiede su quella partizione montandolo su /metadata , incluso il flag formattable per garantire che sia formattato al momento dell'avvio. Il filesystem f2fs non funziona su partizioni più piccole; consigliamo invece di utilizzare ext4. Per esempio:

/dev/block/bootdevice/by-name/metadata              /metadata          ext4        noatime,nosuid,nodev,discard                          wait,check,formattable

Per garantire che il punto di montaggio /metadata esista, aggiungi la seguente riga a BoardConfig-common.mk :

BOARD_USES_METADATA_PARTITION := true

Modifiche alla sequenza di inizializzazione

Quando viene utilizzata la crittografia dei metadati, vold deve essere in esecuzione prima che /data venga montato. Per garantire che venga avviato con sufficiente anticipo, aggiungere la seguente stanza a init.hardware.rc :

# We need vold early for metadata encryption
on early-fs
    start vold

Keymaster deve essere in esecuzione e pronto prima che init tenti di montare /data .

init.hardware.rc dovrebbe già contenere un'istruzione mount_all che monta /data stesso nella stanza on late-fs . Prima di questa riga, aggiungi la direttiva per eseguire il servizio wait_for_keymaster :

on late-fs
   … 
    # Wait for keymaster
    exec_start wait_for_keymaster

    # Mount RW partitions which need run fsck
    mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --late

Attivazione della crittografia dei metadati

Infine aggiungi keydirectory=/metadata/vold/metadata_encryption alla colonna fs_mgr_flags della voce fstab per userdata . Ad esempio, una riga fstab completa potrebbe assomigliare a:

/dev/block/bootdevice/by-name/userdata              /data              f2fs        noatime,nosuid,nodev,discard,inlinecrypt latemount,wait,check,fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized,keydirectory=/metadata/vold/metadata_encryption,quota,formattable

Per impostazione predefinita, l'algoritmo di crittografia dei metadati sulla memoria interna è AES-256-XTS. Questo può essere sovrascritto impostando l'opzione metadata_encryption , anche nella colonna fs_mgr_flags :

  • Sui dispositivi privi di accelerazione AES, la crittografia Adiantum può essere abilitata impostando metadata_encryption=adiantum .
  • Sui dispositivi che supportano le chiavi con wrapper hardware , è possibile rendere la chiave di crittografia dei metadati con wrapper hardware impostando metadata_encryption=aes-256-xts:wrappedkey_v0 (o in modo equivalente metadata_encryption=:wrappedkey_v0 , poiché aes-256-xts è l'algoritmo predefinito).

Poiché l'interfaccia del kernel in dm-default-key è cambiata in Android 11, devi anche assicurarti di aver impostato il valore corretto per PRODUCT_SHIPPING_API_LEVEL in device.mk . Ad esempio, se il tuo dispositivo si avvia con Android 11 (livello API 30), device.mk dovrebbe contenere:

PRODUCT_SHIPPING_API_LEVEL := 30

Puoi anche impostare la seguente proprietà di sistema per forzare l'uso della nuova API dm-default-key indipendentemente dal livello dell'API di spedizione:

PRODUCT_PROPERTY_OVERRIDES += \
    ro.crypto.dm_default_key.options_format.version=2

Validazione

Per verificare che la crittografia dei metadati sia abilitata e funzioni correttamente, esegui i test descritti di seguito. Tieni inoltre presente i problemi comuni descritti di seguito.

Test

Inizia eseguendo il comando seguente per verificare che la crittografia dei metadati sia abilitata nella memoria interna:

adb root
adb shell dmctl table userdata

L'output dovrebbe essere simile a:

Targets in the device-mapper table for userdata:
0-4194304: default-key, aes-xts-plain64 - 0 252:2 0 3 allow_discards sector_size:4096 iv_large_sectors

Se sovrascrivi le impostazioni di crittografia predefinite impostando l'opzione metadata_encryption nel fstab del dispositivo, l'output sarà leggermente diverso da quello sopra. Ad esempio, se hai abilitato la crittografia Adiantum , il terzo campo sarà xchacha12,aes-adiantum-plain64 invece di aes-xts-plain64 .

Successivamente, esegui vts_kernel_encryption_test per verificare la correttezza della crittografia dei metadati e di FBE:

atest vts_kernel_encryption_test

O:

vts-tradefed run vts -m vts_kernel_encryption_test

Problemi comuni

Durante la chiamata a mount_all , che monta la partizione /data crittografata con metadati, init esegue lo strumento vdc. Lo strumento vdc si connette a vold over binder per configurare il dispositivo crittografato con metadati e montare la partizione. Per la durata di questa chiamata, init è bloccato e i tentativi di leggere o impostare le proprietà init verranno bloccati fino al termine di mount_all . Se, in questa fase, qualsiasi parte del lavoro di vold è direttamente o indirettamente bloccata durante la lettura o l'impostazione di una proprietà, si verificherà una situazione di stallo. È importante assicurarsi che vold possa completare il lavoro di lettura delle chiavi, interazione con Keymaster e montaggio della directory dei dati senza interagire ulteriormente con init .

Se Keymaster non è completamente avviato quando viene eseguito mount_all , non risponderà a vold finché non avrà letto determinate proprietà da init , risultando esattamente nello stallo descritto. Posizionando exec_start wait_for_keymaster sopra l'invocazione mount_all rilevante come stabilito, si garantisce che Keymaster sia completamente in esecuzione in anticipo e quindi si evita questo stallo.

Configurazione sullo storage adottabile

A partire da Android 9, una forma di crittografia dei metadati è sempre abilitata sullo spazio di archiviazione adottabile ogni volta che FBE è abilitato, anche quando la crittografia dei metadati non è abilitata sullo spazio di archiviazione interno.

In AOSP, esistono due implementazioni della crittografia dei metadati sullo storage adottabile: una deprecata basata su dm-crypt e una più recente basata su dm-default-key . Per assicurarti che sia selezionata l'implementazione corretta per il tuo dispositivo, assicurati di aver impostato il valore corretto per PRODUCT_SHIPPING_API_LEVEL in device.mk . Ad esempio, se il tuo dispositivo si avvia con Android 11 (livello API 30), device.mk dovrebbe contenere:

PRODUCT_SHIPPING_API_LEVEL := 30

Puoi anche impostare le seguenti proprietà di sistema per forzare l'utilizzo del nuovo metodo di crittografia dei metadati del volume (e della nuova versione della policy FBE predefinita) indipendentemente dal livello API di spedizione:

PRODUCT_PROPERTY_OVERRIDES += \
    ro.crypto.volume.metadata.method=dm-default-key \
    ro.crypto.dm_default_key.options_format.version=2 \
    ro.crypto.volume.options=::v2

Metodo attuale

Sui dispositivi avviati con Android 11 o versioni successive, la crittografia dei metadati sullo spazio di archiviazione adottabile utilizza il modulo kernel dm-default-key , proprio come sullo spazio di archiviazione interno. Vedi i prerequisiti sopra per sapere quali opzioni di configurazione del kernel abilitare. Tieni presente che l'hardware di crittografia in linea che funziona sulla memoria interna del dispositivo potrebbe non essere disponibile sulla memoria adottabile e quindi CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y potrebbe essere richiesto.

Per impostazione predefinita, il metodo di crittografia dei metadati del volume dm-default-key utilizza l'algoritmo di crittografia AES-256-XTS con settori crittografici da 4096 byte. L'algoritmo può essere sovrascritto impostando la proprietà di sistema ro.crypto.volume.metadata.encryption . Il valore di questa proprietà ha la stessa sintassi dell'opzione fstab metadata_encryption descritta sopra. Ad esempio, sui dispositivi privi di accelerazione AES, la crittografia Adiantum può essere abilitata impostando ro.crypto.volume.metadata.encryption=adiantum .

Metodo legacy

Sui dispositivi avviati con Android 10 o versioni precedenti, la crittografia dei metadati sullo spazio di archiviazione adottabile utilizza il modulo kernel dm-crypt anziché dm-default-key :

CONFIG_DM_CRYPT=y

A differenza del metodo dm-default-key , il metodo dm-crypt fa sì che il contenuto del file venga crittografato due volte: una volta con una chiave FBE e una volta con la chiave di crittografia dei metadati. Questa doppia crittografia riduce le prestazioni e non è necessaria per raggiungere gli obiettivi di sicurezza della crittografia dei metadati, poiché Android garantisce che le chiavi FBE siano difficili da compromettere almeno quanto la chiave di crittografia dei metadati. I fornitori possono personalizzare il kernel per evitare la doppia crittografia, in particolare implementando l' allow_encrypt_override che Android passerà a dm-crypt quando la proprietà di sistema ro.crypto.allow_encrypt_override è impostata su true . Queste personalizzazioni non sono supportate dal kernel comune di Android.

Per impostazione predefinita, il metodo di crittografia dei metadati del volume dm-crypt utilizza l'algoritmo di crittografia AES-128-CBC con ESSIV e settori crittografici da 512 byte. Questo può essere ignorato impostando le seguenti proprietà di sistema (utilizzate anche per FDE):

  • ro.crypto.fde_algorithm seleziona l'algoritmo di crittografia dei metadati. Le scelte sono aes-128-cbc e adiantum . Adiantum può essere utilizzato solo se il dispositivo non dispone di accelerazione AES.
  • ro.crypto.fde_sector_size seleziona la dimensione del settore crittografico. Le scelte sono 512, 1024, 2048 e 4096. Per la crittografia Adiantum, utilizzare 4096.