Android 7.0 y las versiones posteriores admiten la encriptación basada en archivos (FBE). La FBE permite que se encripten diferentes archivos con diferentes claves que se pueden desbloquear de forma independiente. Estas claves se usan para encriptar el contenido y los nombres de los archivos. Cuando se usa FBE, no se encripta otra información, como los diseños de directorios, los tamaños de archivos, los permisos y los tiempos de creación o modificación. En conjunto, esta otra información se conoce como metadatos del sistema de archivos.
Android 9 introdujo la compatibilidad con la encriptación de metadatos. Con la encriptación de metadatos, una sola clave presente al momento del inicio encripta el contenido que no está encriptado por FBE. KeyMint (antes Keymaster) protege esta clave, que, a su vez, está protegida por el inicio verificado.
La encriptación de metadatos siempre está habilitada en el almacenamiento adaptable cuando FBE está habilitado. La encriptación de metadatos también se puede habilitar en el almacenamiento interno. Los dispositivos lanzados con Android 11 o versiones posteriores deben tener habilitada la encriptación de metadatos en el almacenamiento interno.
Implementación en el almacenamiento interno
Para configurar la encriptación de metadatos en el almacenamiento interno de dispositivos nuevos, configura el sistema de archivos metadata, cambia la secuencia de inicialización y habilita la encriptación de metadatos en el archivo fstab del dispositivo.
Requisitos previos
La encriptación de metadatos solo se puede configurar cuando se formatea por primera vez la partición de datos. Como resultado, esta función es solo para dispositivos nuevos, y no es algo que una OTA deba cambiar.
La encriptación de metadatos requiere que el módulo dm-default-key esté habilitado en tu kernel. En Android 11 y versiones posteriores, los kernels comunes de Android admiten dm-default-key, versión 4.14 y versiones posteriores. Esta versión de dm-default-key usa un framework de encriptación independiente del hardware y del proveedor llamado blk-crypto.
Para habilitar dm-default-key, usa lo siguiente:
CONFIG_BLK_INLINE_ENCRYPTION=y CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y CONFIG_DM_DEFAULT_KEY=y
dm-default-key usa hardware de encriptación intercalada (hardware que encripta o desencripta datos durante el trayecto hacia el dispositivo de almacenamiento o desde él) cuando está disponible. Si no usas hardware de encriptación intercalada, también es necesario habilitar una alternativa a la API de criptografía del kernel:
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
Cuando no uses hardware de encriptación intercalada, también debes habilitar cualquier aceleración disponible basada en CPU, como se recomienda en la documentación de FBE.
En Android 10 y versiones anteriores, el kernel común de Android no admitía dm-default-key. Por lo tanto, dependía de los proveedores implementar dm-default-key.
Configura el sistema de archivos de metadatos
Como no se puede leer nada en la partición userdata hasta que esté presente la clave de encriptación de metadatos, la tabla de particiones debe reservar una partición separada llamada partición de metadatos para almacenar los objetos binarios de KeyMint 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 reside en esa partición y la monta en /metadata, incluida la marca formattable para garantizar que se formatee en el momento del inicio. El sistema de archivos f2fs no funciona en particiones más pequeñas. Te recomendamos que uses ext4 en su lugar. Por ejemplo:
/dev/block/bootdevice/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard wait,check,formattable
Para asegurarte de que exista el punto de activación /metadata, agrega la siguiente línea a BoardConfig-common.mk:
BOARD_USES_METADATA_PARTITION := true
Cambios en la secuencia de inicialización
Cuando se usa la encriptación de metadatos, vold debe ejecutarse antes de que se monte /data. Para asegurarte de que se inicie lo suficientemente temprano, agrega la siguiente estrofa a init.hardware.rc:
# We need vold early for metadata encryption
on early-fs
start vold
KeyMint debe estar en ejecución y listo antes de que init intente montar /data.
init.hardware.rc ya debería contener una mount_all
instrucción que monte /data en la estrofa on
late-fs. Antes de esta línea, agrega 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
Activa la encriptación de metadatos
Por último, agrega 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 de la siguiente manera:
/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 encriptación de metadatos en el almacenamiento interno es AES-256-XTS. Esto se puede anular si se configura la opción metadata_encryption, también en la columna fs_mgr_flags:
- En los dispositivos que no tienen aceleración AES, la encriptación Adiantum se puede
habilitar si se configura
metadata_encryption=adiantum. En los dispositivos que admiten claves de encriptación intercalada envueltas en hardware, la clave de encriptación de metadatos se puede envolver en hardware si se configura
metadata_encryption=aes-256-xts:wrappedkeyometadata_encryption=aes-256-xts:wrappedkey_v0.wrappedkeyes la versión moderna.wrappedkey_v0solo se debe usar en dispositivos que no admitenwrappedkeyo que ya se lanzaron conwrappedkey_v0. Para obtener más información, consulta Cómo habilitar claves envueltas.En cualquier caso, se puede omitir
aes-256-xtsporque es el algoritmo predeterminado. Por ejemplo,metadata_encryption=:wrappedkeyequivale ametadata_encryption=aes-256-xts:wrappedkey.
Debido a que la interfaz del kernel para dm-default-key cambió en Android 11, también debes asegurarte de haber configurado el valor correcto para PRODUCT_SHIPPING_API_LEVEL en device.mk. Por ejemplo, si tu dispositivo se lanza con Android 11 (nivel de API 30), device.mk debe contener lo siguiente:
PRODUCT_SHIPPING_API_LEVEL := 30
También puedes configurar la siguiente propiedad del sistema para forzar el uso de la nueva API de 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 la encriptación de metadatos esté habilitada y funcione correctamente, ejecuta las pruebas que se describen a continuación. También ten en cuenta los problemas comunes que se describen a continuación.
Pruebas
Comienza por ejecutar el siguiente comando para verificar que la encriptación de metadatos esté habilitada en el almacenamiento interno:
adb rootadb shell dmctl table userdata
El resultado debería ser similar al siguiente:
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 anulaste la configuración de encriptación predeterminada configurando la opción metadata_encryption en el fstab del dispositivo, el resultado difiere ligeramente de lo anterior. Por ejemplo, si habilitaste la encriptación Adiantum, el tercer
campo es xchacha12,aes-adiantum-plain64 en lugar de
aes-xts-plain64.
A continuación, ejecuta vts_kernel_encryption_test para verificar la exactitud de la encriptación 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 encriptada con metadatos, init ejecuta la herramienta vdc. La herramienta vdc se conecta a vold a través de binder para configurar el dispositivo encriptado con metadatos y montar la partición. Mientras dure esta llamada, init se bloqueará y los intentos de leer o configurar las propiedades de init se bloquearán hasta que finalice mount_all.
Si, en esta etapa, alguna parte del trabajo de vold se bloquea directa o indirectamente en la lectura o configuración de una propiedad, se produce un interbloqueo. Es importante asegurarse de que vold pueda completar el trabajo de leer las claves, interactuar con KeyMint y montar el directorio de datos sin interactuar más con init.
Si KeyMint no se inicia por completo cuando se ejecuta mount_all, no responde a vold hasta que haya leído ciertas propiedades de init, lo que genera exactamente el interbloqueo descrito. Colocar exec_start wait_for_keymaster sobre la invocación mount_all pertinente, como se establece, garantiza que KeyMint se ejecute por completo con anticipación y, por lo tanto, evita este interbloqueo.
Configuración en el almacenamiento adaptable
Desde Android 9, siempre se habilita una forma de encriptación de metadatos en el almacenamiento adaptable cuando FBE está habilitado, incluso cuando la encriptación de metadatos no está habilitada en el almacenamiento interno.
En AOSP, existen dos implementaciones de encriptación de metadatos en el almacenamiento adaptable: una obsoleta basada en dm-crypt y una más reciente basada en dm-default-key. Para asegurarte de que se seleccione la implementación correcta para tu dispositivo, asegúrate de haber configurado el valor correcto para PRODUCT_SHIPPING_API_LEVEL en device.mk. Por ejemplo, si tu dispositivo se lanza con Android 11 (nivel de API 30), device.mk debe contener lo siguiente:
PRODUCT_SHIPPING_API_LEVEL := 30
También puedes configurar las siguientes propiedades del sistema para forzar el uso del nuevo método de encriptación de metadatos de volumen (y la nueva versión de política de FBE predeterminada) 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 lanzan con Android 11 o versiones posteriores, la encriptación de metadatos en el almacenamiento adaptable usa el módulo del kernel dm-default-key, al igual que en el almacenamiento interno. Consulta los requisitos previos anteriores para conocer las opciones de configuración del kernel
que se deben habilitar. Ten en cuenta que el hardware de encriptación intercalada que funciona en el almacenamiento interno del dispositivo podría no estar disponible en el almacenamiento adaptable y, por lo tanto, podría ser necesario CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y.
De forma predeterminada, el método de encriptación de metadatos de volumen dm-default-key usa el algoritmo de encriptación AES-256-XTS con sectores criptográficos de 4096 bytes. El algoritmo se puede anular si se configura la propiedad del sistema ro.crypto.volume.metadata.encryption. El valor de esta propiedad tiene la misma sintaxis que la opción fstab metadata_encryption que se describió anteriormente. Por ejemplo, en los dispositivos que no tienen aceleración AES, se puede habilitar la encriptación Adiantum
si se configura
ro.crypto.volume.metadata.encryption=adiantum.
Método heredado
En los dispositivos que se lanzan con Android 10 y versiones anteriores, la encriptación de metadatos en el almacenamiento adaptable usa el módulo del 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 encripte dos veces: una con una clave FBE y otra con la clave de encriptación de metadatos. Esta doble encriptación reduce el rendimiento y no es necesaria para alcanzar los objetivos de seguridad de la encriptación de metadatos, ya que Android garantiza que las claves FBE sean al menos tan difíciles de vulnerar como la clave de encriptación de metadatos. Los proveedores pueden realizar personalizaciones del kernel para evitar la doble
encriptación, en particular, mediante la implementación de la
allow_encrypt_override opción que Android pasa a
dm-crypt cuando la propiedad del sistema
ro.crypto.allow_encrypt_override se establece en true.
El kernel común de Android no admite estas personalizaciones.
De forma predeterminada, el método de encriptación de metadatos de volumen dm-crypt usa el algoritmo de encriptación AES-128-CBC con ESSIV y sectores criptográficos de 512 bytes. Esto se puede anular si se configuran las siguientes propiedades del sistema (que también se usan para FDE):
ro.crypto.fde_algorithmselecciona el algoritmo de encriptación de metadatos. Las opciones sonaes-128-cbcyadiantum. Adiantum solo se puede usar si el dispositivo no tiene aceleración AES.ro.crypto.fde_sector_sizeselecciona el tamaño del sector criptográfico. Las opciones son 512, 1024, 2048 y 4096. Para la encriptación Adiantum, usa 4096.