Android 7.0 y versiones posteriores admiten el cifrado basado en archivos (FBE). FBE permite cifrar diferentes archivos con diferentes claves que se pueden desbloquear de forma independiente. Estas claves se utilizan para cifrar tanto el contenido como los nombres de los archivos. Cuando se utiliza FBE, otra información, como diseños de directorios, tamaños de archivos, permisos y tiempos de creación/modificación, no se cifra. En conjunto, esta otra información se conoce como metadatos del sistema de archivos.
Android 9 introdujo soporte para el cifrado de metadatos. Con el cifrado de metadatos, una única clave presente en el momento del arranque cifra cualquier contenido que no esté cifrado por FBE. Esta clave está protegida por Keymaster, que a su vez está protegida por un arranque verificado.
El cifrado de metadatos siempre está habilitado en el almacenamiento adoptable siempre que FBE esté habilitado. El cifrado de metadatos también se puede habilitar en el almacenamiento interno. Los dispositivos lanzados con Android 11 o superior deben tener habilitado el cifrado de metadatos en el almacenamiento interno.
Implementación en almacenamiento interno
Puede configurar el cifrado de metadatos en el almacenamiento interno de nuevos dispositivos configurando el sistema de archivos de metadata
, cambiando la secuencia de inicio y habilitando el cifrado de metadatos en el archivo fstab del dispositivo.
requisitos previos
El cifrado de metadatos solo se puede configurar cuando la partición de datos se formatea por primera vez. Como resultado, esta función es solo para dispositivos nuevos; esto no es algo que una OTA deba cambiar.
El cifrado de metadatos requiere que el módulo dm-default-key
esté habilitado en su kernel. En Android 11 y versiones posteriores, dm-default-key
es compatible con los núcleos comunes de Android, versión 4.14 y versiones posteriores. Esta versión de dm-default-key
utiliza un marco de cifrado independiente del proveedor y del hardware denominado blk-crypto .
Para habilitar dm-default-key
, use:
CONFIG_BLK_INLINE_ENCRYPTION=y CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y CONFIG_DM_DEFAULT_KEY=y
dm-default-key
utiliza hardware de cifrado en línea (hardware que cifra/descifra datos mientras se encuentran en el camino hacia/desde el dispositivo de almacenamiento) cuando está disponible. Si no va a utilizar hardware de cifrado en línea, también es necesario habilitar una alternativa a la API de criptografía del kernel:
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
Cuando no utilice hardware de cifrado en línea, también debe habilitar cualquier aceleración basada en CPU disponible como se recomienda en la documentación de FBE .
En Android 10 y versiones anteriores, dm-default-key
no era compatible con el kernel común de Android. Por lo tanto, dependía de los proveedores implementar dm-default-key
.
Configurar el sistema de archivos de metadatos
Debido a que no se puede leer nada en la partición de datos de usuario hasta que la clave de cifrado de metadatos esté presente, la tabla de partición debe reservar una partición separada llamada "partición de metadatos" para almacenar los blobs de keymaster que protegen esta clave. La partición de metadatos debe ser de 16 MB.
fstab.hardware
debe incluir una entrada para el sistema de archivos de metadatos que vive en esa partición montándolo en /metadata
, incluida la formattable
para asegurarse de que esté formateado en el momento del arranque. El sistema de archivos f2fs no funciona en particiones más pequeñas; recomendamos usar ext4 en su lugar. Por ejemplo:
/dev/block/bootdevice/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard wait,check,formattable
Para asegurarse de que exista el punto de montaje /metadata
, agregue la siguiente línea a BoardConfig-common.mk
:
BOARD_USES_METADATA_PARTITION := true
Cambios en la secuencia de inicio
Cuando se usa el cifrado de metadatos, vold
debe estar ejecutándose antes de que se monte /data
. Para asegurarse de que se inicia lo suficientemente pronto, agregue la siguiente estrofa a init.hardware.rc
:
# We need vold early for metadata encryption on early-fs start vold
Keymaster debe estar ejecutándose y listo antes de que init intente montar /data
.
init.hardware.rc
ya debería contener una instrucción mount_all
que monta /data
en la estrofa on late-fs
. Antes de esta línea, agregue la directiva para ejecutar el servicio 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
Activar el cifrado de metadatos
Finalmente, agregue keydirectory=/metadata/vold/metadata_encryption
a la columna fs_mgr_flags de la entrada fstab
para userdata
. Por ejemplo, una línea fstab completa podría verse así:
/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
De forma predeterminada, el algoritmo de cifrado de metadatos en el almacenamiento interno es AES-256-XTS. Esto se puede anular configurando la opción metadata_encryption
, también en la columna fs_mgr_flags :
- En dispositivos que carecen de aceleración AES, el cifrado Adiantum se puede habilitar configurando
metadata_encryption=adiantum
. - En los dispositivos que admiten claves encapsuladas en hardware , la clave de cifrado de metadatos se puede encapsular en hardware configurando
metadata_encryption=aes-256-xts:wrappedkey_v0
(o de manera equivalentemetadata_encryption=:wrappedkey_v0
, ya queaes-256-xts
es el algoritmo predeterminado).
Debido a que la interfaz del kernel para dm-default-key
cambió en Android 11, también debe asegurarse de haber establecido el valor correcto para PRODUCT_SHIPPING_API_LEVEL
en device.mk
. Por ejemplo, si su dispositivo se inicia con Android 11 (nivel de API 30), device.mk
debe contener:
PRODUCT_SHIPPING_API_LEVEL := 30
También puede configurar la siguiente propiedad del sistema para forzar el uso de la nueva API dm-default-key
independientemente del nivel de API de envío:
PRODUCT_PROPERTY_OVERRIDES += \ ro.crypto.dm_default_key.options_format.version=2
Validación
Para verificar que el cifrado de metadatos esté habilitado y funcione correctamente, ejecute las pruebas que se describen a continuación. También tenga en cuenta los problemas comunes que se describen a continuación.
Pruebas
Comience ejecutando el siguiente comando para verificar que el cifrado de metadatos esté habilitado en el almacenamiento interno:
adb root
adb shell dmctl table userdata
La salida debe ser similar 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
Si anuló la configuración de cifrado predeterminada configurando la opción metadata_encryption
en el fstab
del dispositivo, la salida diferirá ligeramente de la anterior. Por ejemplo, si habilitó el cifrado Adiantum , el tercer campo será xchacha12,aes-adiantum-plain64
en lugar de aes-xts-plain64
.
A continuación, ejecute vts_kernel_encryption_test para verificar la exactitud del cifrado de metadatos y FBE:
atest vts_kernel_encryption_test
o:
vts-tradefed run vts -m vts_kernel_encryption_test
Problemas comunes
Durante la llamada a mount_all
, que monta la partición /data
cifrada con metadatos, init
ejecuta la herramienta vdc. La herramienta vdc se conecta a vold
over binder
para configurar el dispositivo cifrado con metadatos y montar la partición. Mientras dure esta llamada, init
estará bloqueado y los intentos de leer o establecer las propiedades de init
se bloquearán hasta que finalice mount_all
. Si, en esta etapa, cualquier parte del trabajo de vold
está directa o indirectamente bloqueada al leer o configurar una propiedad, se producirá un interbloqueo. Es importante asegurarse de que vold
pueda completar el trabajo de leer las claves, interactuar con Keymaster y montar el directorio de datos sin interactuar más con init
.
Si Keymaster no se inicia por completo cuando se ejecuta mount_all
, no responderá a vold
hasta que haya leído ciertas propiedades de init
, lo que dará como resultado exactamente el interbloqueo descrito. Colocar exec_start wait_for_keymaster
encima de la invocación relevante mount_all
como se establece asegura que Keymaster se está ejecutando completamente por adelantado y así evita este punto muerto.
Configuración en almacenamiento adoptable
Desde Android 9, una forma de encriptación de metadatos siempre está habilitada en el almacenamiento adoptable siempre que FBE esté habilitado, incluso cuando la encriptación de metadatos no esté habilitada en el almacenamiento interno.
En AOSP, hay dos implementaciones de cifrado de metadatos en almacenamiento adoptable: una obsoleta basada en dm-crypt
y una más nueva basada en dm-default-key
. Para garantizar que se seleccione la implementación correcta para su dispositivo, asegúrese de haber establecido el valor correcto para PRODUCT_SHIPPING_API_LEVEL
en device.mk
. Por ejemplo, si su dispositivo se inicia con Android 11 (nivel de API 30), device.mk
debe contener:
PRODUCT_SHIPPING_API_LEVEL := 30
También puede configurar las siguientes propiedades del sistema para forzar el uso del nuevo método de cifrado de metadatos de volumen (y la nueva versión predeterminada de la política FBE) independientemente del nivel de API de envío:
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
Método actual
En los dispositivos que se inician con Android 11 o superior, el cifrado de metadatos en el almacenamiento adoptable utiliza el módulo de kernel dm-default-key
, al igual que en el almacenamiento interno. Consulte los requisitos previos anteriores para saber qué opciones de configuración del kernel habilitar. Tenga en cuenta que el hardware de cifrado en línea que funciona en el almacenamiento interno del dispositivo puede no estar disponible en el almacenamiento adoptable y, por lo tanto, es posible que se requiera CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
.
De forma predeterminada, el método de cifrado de metadatos de volumen dm-default-key
utiliza el algoritmo de cifrado AES-256-XTS con sectores criptográficos de 4096 bytes. El algoritmo se puede anular configurando la propiedad del sistema ro.crypto.volume.metadata.encryption
. El valor de esta propiedad tiene la misma sintaxis que la opción metadata_encryption
fstab descrita anteriormente. Por ejemplo, en dispositivos que carecen de aceleración AES, el cifrado Adiantum se puede habilitar configurando ro.crypto.volume.metadata.encryption=adiantum
.
Método heredado
En los dispositivos que se inician con Android 10 o inferior, el cifrado de metadatos en el almacenamiento adoptable utiliza el módulo de kernel dm-crypt
en lugar de dm-default-key
:
CONFIG_DM_CRYPT=y
A diferencia del método dm-default-key
, el método dm-crypt
hace que el contenido del archivo se cifre dos veces: una vez con una clave FBE y otra vez con la clave de cifrado de metadatos. Este doble cifrado reduce el rendimiento y no es necesario para lograr los objetivos de seguridad del cifrado de metadatos, ya que Android garantiza que las claves de FBE sean al menos tan difíciles de comprometer como la clave de cifrado de metadatos. Los proveedores pueden personalizar el kernel para evitar el doble cifrado, en particular mediante la implementación de la opción allow_encrypt_override
que Android pasará a dm-crypt
cuando la propiedad del sistema ro.crypto.allow_encrypt_override
se establezca en true
. Estas personalizaciones no son compatibles con el kernel común de Android.
De forma predeterminada, el método de cifrado de metadatos de volumen dm-crypt
utiliza el algoritmo de cifrado AES-128-CBC con ESSIV y sectores criptográficos de 512 bytes. Esto se puede anular configurando las siguientes propiedades del sistema (que también se usan para FDE):
-
ro.crypto.fde_algorithm
selecciona el algoritmo de cifrado de metadatos. Las opciones sonaes-128-cbc
yadiantum
. Adiantum solo se puede usar si el dispositivo carece de aceleración AES. -
ro.crypto.fde_sector_size
selecciona el tamaño del sector criptográfico. Las opciones son 512, 1024, 2048 y 4096. Para el cifrado Adiantum, utilice 4096.