Cifrado basado en archivos

Android 7.0 y versiones posteriores admiten el cifrado basado en archivos (FBE). El cifrado basado en archivos permite cifrar diferentes archivos con diferentes claves que se pueden desbloquear de forma independiente.

Este artículo describe cómo habilitar el cifrado basado en archivos en nuevos dispositivos y cómo las aplicaciones del sistema pueden usar las API de arranque directo para ofrecer a los usuarios la mejor y más segura experiencia posible.

Todos los dispositivos que se inician con Android 10 y versiones posteriores deben usar cifrado basado en archivos.

Arranque directo

El cifrado basado en archivos habilita una nueva característica introducida en Android 7.0 llamada Arranque directo . Direct Boot permite que los dispositivos encriptados arranquen directamente en la pantalla de bloqueo. Anteriormente, en dispositivos encriptados que usaban encriptación de disco completo (FDE), los usuarios debían proporcionar credenciales antes de poder acceder a los datos, lo que impedía que el teléfono realizara todas las operaciones excepto las más básicas. Por ejemplo, las alarmas no podían funcionar, los servicios de accesibilidad no estaban disponibles y los teléfonos no podían recibir llamadas, pero estaban limitados a operaciones básicas de marcación de emergencia.

Con la introducción del cifrado basado en archivos (FBE) y las nuevas API para que las aplicaciones reconozcan el cifrado, es posible que estas aplicaciones operen dentro de un contexto limitado. Esto puede ocurrir antes de que los usuarios hayan proporcionado sus credenciales mientras se sigue protegiendo la información privada del usuario.

En un dispositivo habilitado para FBE, cada usuario del dispositivo tiene dos ubicaciones de almacenamiento disponibles para las aplicaciones:

  • Almacenamiento de Credential Encrypted (CE), que es la ubicación de almacenamiento predeterminada y solo está disponible después de que el usuario haya desbloqueado el dispositivo.
  • Almacenamiento de dispositivo cifrado (DE), que es una ubicación de almacenamiento disponible tanto durante el modo de arranque directo como después de que el usuario haya desbloqueado el dispositivo.

Esta separación hace que los perfiles de trabajo sean más seguros porque permite proteger a más de un usuario a la vez, ya que el cifrado ya no se basa únicamente en una contraseña de arranque.

La API de arranque directo permite que las aplicaciones con reconocimiento de cifrado accedan a cada una de estas áreas. Hay cambios en el ciclo de vida de la aplicación para adaptarse a la necesidad de notificar a las aplicaciones cuando el almacenamiento de CE de un usuario está desbloqueado en respuesta al primer ingreso de credenciales en la pantalla de bloqueo, o en el caso de un perfil de trabajo que presenta un desafío laboral . Los dispositivos que ejecutan Android 7.0 deben ser compatibles con estas nuevas API y ciclos de vida, independientemente de si implementan o no FBE. Aunque, sin FBE, el almacenamiento DE y CE siempre estará en estado desbloqueado.

Se proporciona una implementación completa de cifrado basado en archivos en los sistemas de archivos Ext4 y F2FS en el Proyecto de código abierto de Android (AOSP) y solo debe habilitarse en dispositivos que cumplan con los requisitos. Es posible que los fabricantes que opten por usar FBE deseen explorar formas de optimizar la función en función del sistema en chip (SoC) utilizado.

Todos los paquetes necesarios en AOSP se han actualizado para reconocer el arranque directo. Sin embargo, cuando los fabricantes de dispositivos utilicen versiones personalizadas de estas aplicaciones, querrán asegurarse de que, como mínimo, haya paquetes compatibles con el arranque directo que brinden los siguientes servicios:

  • Servicios de Telefonía y Marcador
  • Método de entrada para ingresar contraseñas en la pantalla de bloqueo

Ejemplos y fuente

Android proporciona una implementación de referencia de cifrado basado en archivos, en la que vold ( system/vold ) proporciona la funcionalidad para administrar dispositivos y volúmenes de almacenamiento en Android. La adición de FBE proporciona a vold varios comandos nuevos para admitir la administración de claves para las claves CE y DE de múltiples usuarios. Además de los cambios principales para usar las capacidades de encriptación basadas en archivos en el kernel , muchos paquetes del sistema, incluidos LockScreen y SystemUI, se han modificado para admitir las funciones FBE y Direct Boot. Éstas incluyen:

  • Marcador AOSP (paquetes/aplicaciones/Marcador)
  • Reloj de escritorio (paquetes/aplicaciones/DeskClock)
  • LatinIME (paquetes/métodos de entrada/LatinIME)*
  • Aplicación de configuración (paquetes/aplicaciones/Configuración)*
  • SystemUI (marcos/base/paquetes/SystemUI)*

* Aplicaciones del sistema que usan el atributo de manifiesto defaultToDeviceProtectedStorage

Se pueden encontrar más ejemplos de aplicaciones y servicios que son compatibles con el cifrado ejecutando el comando mangrep directBootAware en el directorio de marcos o paquetes del árbol fuente de AOSP.

dependencias

Para usar la implementación AOSP de FBE de forma segura, un dispositivo debe cumplir con las siguientes dependencias:

  • Soporte de kernel para cifrado Ext4 o cifrado F2FS.
  • Soporte Keymaster con HAL versión 1.0 o superior. No hay soporte para Keymaster 0.3, ya que no proporciona las capacidades necesarias ni garantiza una protección suficiente para las claves de cifrado.
  • Keymaster/ Keystore y Gatekeeper deben implementarse en un entorno de ejecución de confianza (TEE) para brindar protección a las claves DE de modo que un sistema operativo no autorizado (sistema operativo personalizado instalado en el dispositivo) no pueda simplemente solicitar las claves DE.
  • Se requiere raíz de confianza de hardware y arranque verificado vinculado a la inicialización de Keymaster para garantizar que un sistema operativo no autorizado no pueda acceder a las claves DE.

Implementación

En primer lugar, las aplicaciones como los relojes de alarma, el teléfono y las funciones de accesibilidad deben hacerse android:directBootAware de acuerdo con la documentación del desarrollador de arranque directo .

Soporte del núcleo

El soporte de kernel para el cifrado Ext4 y F2FS está disponible en los kernels comunes de Android, versión 3.18 y superior. Para habilitarlo en un kernel que es la versión 5.1 o superior, utilice:

CONFIG_FS_ENCRYPTION=y

Para kernels más antiguos, use CONFIG_EXT4_ENCRYPTION=y si el sistema de archivos userdata de su dispositivo es Ext4, o use CONFIG_F2FS_FS_ENCRYPTION=y si el sistema de archivos userdata de su dispositivo es F2FS.

Si su dispositivo admitirá el almacenamiento adoptable o utilizará el cifrado de metadatos en el almacenamiento interno, habilite también las opciones de configuración del kernel necesarias para el cifrado de metadatos como se describe en la documentación de cifrado de metadatos .

Además del soporte funcional para el cifrado Ext4 o F2FS, los fabricantes de dispositivos también deberían habilitar la aceleración criptográfica para acelerar el cifrado basado en archivos y mejorar la experiencia del usuario. Por ejemplo, en dispositivos basados ​​en ARM64, la aceleración ARMv8 CE (Cryptography Extensions) se puede habilitar configurando las siguientes opciones de configuración del kernel:

CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
CONFIG_CRYPTO_SHA2_ARM64_CE=y

Para mejorar aún más el rendimiento y reducir el uso de energía, los fabricantes de dispositivos también pueden considerar implementar hardware de cifrado en línea , que cifra/descifra los datos mientras se encuentran en el camino hacia/desde el dispositivo de almacenamiento. Los núcleos comunes de Android (versión 4.14 y superior) contienen un marco que permite el uso de cifrado en línea cuando el hardware y el soporte del controlador del proveedor están disponibles. El marco de cifrado en línea se puede habilitar configurando las siguientes opciones de configuración del kernel:

CONFIG_BLK_INLINE_ENCRYPTION=y
CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y

Si su dispositivo usa almacenamiento basado en UFS, habilite también:

CONFIG_SCSI_UFS_CRYPTO=y

Si su dispositivo usa almacenamiento basado en eMMC, habilite también:

CONFIG_MMC_CRYPTO=y

Habilitación del cifrado basado en archivos

Habilitar FBE en un dispositivo requiere habilitarlo en el almacenamiento interno ( userdata ). Esto también habilita automáticamente FBE en almacenamiento adoptable; sin embargo, el formato de cifrado en el almacenamiento adoptable puede anularse si es necesario.

Almacenamiento interno

FBE se habilita agregando la opción fileencryption=contents_encryption_mode[:filenames_encryption_mode[:flags]] a la columna fs_mgr_flags de la línea fstab para userdata . Esta opción define el formato de cifrado en el almacenamiento interno. Contiene hasta tres parámetros separados por dos puntos:

  • El parámetro contents_encryption_mode define qué algoritmo criptográfico se utiliza para cifrar el contenido del archivo. Puede ser aes-256-xts o adiantum . Desde Android 11 también se puede dejar en blanco para especificar el algoritmo predeterminado, que es aes-256-xts .
  • El parámetro filenames_encryption_mode define qué algoritmo criptográfico se utiliza para cifrar los nombres de los archivos. Puede ser aes-256-cts , aes-256-heh , adiantum o aes-256-hctr2 . Si no se especifica, el valor predeterminado es aes-256-cts si contents_encryption_mode es aes-256-xts o adiantum si contents_encryption_mode es adiantum .
  • El parámetro flags , nuevo en Android 11, es una lista de banderas separadas por el carácter + . Se admiten las siguientes banderas:
    • El indicador v1 selecciona las políticas de cifrado de la versión 1; el indicador v2 selecciona las políticas de cifrado de la versión 2. Las políticas de cifrado de la versión 2 utilizan una función de derivación de claves más segura y flexible. El valor predeterminado es v2 si el dispositivo se lanzó en Android 11 o superior (según lo determinado por ro.product.first_api_level ), o v1 si el dispositivo se lanzó en Android 10 o inferior.
    • El indicador inlinecrypt_optimized selecciona un formato de cifrado que está optimizado para hardware de cifrado en línea que no maneja grandes cantidades de claves de manera eficiente. Lo hace derivando solo una clave de cifrado de contenido de archivo por clave CE o DE, en lugar de una por archivo. La generación de IV (vectores de inicialización) se ajusta en consecuencia.
    • El indicador emmc_optimized es similar a inlinecrypt_optimized , pero también selecciona un método de generación de IV que limita los IV a 32 bits. Este indicador solo debe usarse en hardware de cifrado en línea que cumpla con la especificación JEDEC eMMC v5.2 y, por lo tanto, solo admita IV de 32 bits. En otro hardware de cifrado en línea, use inlinecrypt_optimized en su lugar. Esta marca nunca debe usarse en almacenamiento basado en UFS; la especificación UFS permite el uso de IV de 64 bits.
    • En los dispositivos que admiten claves encapsuladas en hardware , la marca wrappedkey_v0 permite el uso de claves encapsuladas en hardware para FBE. Esto solo se puede usar en combinación con la opción de montaje inlinecrypt y el indicador inlinecrypt_optimized o emmc_optimized .

Si no utiliza hardware de cifrado en línea, la configuración recomendada para la mayoría de los dispositivos es fileencryption=aes-256-xts . Si utiliza hardware de cifrado en línea, la configuración recomendada para la mayoría de los dispositivos es fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized (o equivalente fileencryption=::inlinecrypt_optimized ). En dispositivos sin ningún tipo de aceleración AES, se puede usar Adiantum en lugar de AES configurando fileencryption=adiantum .

Desde Android 14 (AOSP experimental), AES-HCTR2 es el modo preferido de cifrado de nombres de archivo para dispositivos con instrucciones de criptografía aceleradas. Sin embargo, solo los kernels de Android más nuevos son compatibles con AES-HCTR2. En una futura versión de Android, está previsto que se convierta en el modo predeterminado para el cifrado de nombres de archivo. Si su kernel es compatible con AES-HCTR2, puede habilitarse para el cifrado de nombres de archivo configurando filenames_encryption_mode en aes-256-hctr2 . En el caso más simple, esto se haría con fileencryption=aes-256-xts:aes-256-hctr2 .

En dispositivos que se lanzaron con Android 10 o anterior, también se acepta fileencryption=ice para especificar el uso del modo de cifrado de contenido de archivo FSCRYPT_MODE_PRIVATE . Los núcleos comunes de Android no implementan este modo, pero los proveedores pueden implementarlo mediante parches de núcleo personalizados. El formato en disco producido por este modo era específico del proveedor. En los dispositivos que se inician con Android 11 o superior, este modo ya no está permitido y se debe usar un formato de cifrado estándar en su lugar.

De forma predeterminada, el cifrado del contenido de los archivos se realiza mediante la API de criptografía del kernel de Linux. Si desea utilizar hardware de cifrado en línea, agregue también la opción de montaje inlinecrypt . Por ejemplo, una línea fstab completa podría verse así:

/dev/block/by-name/userdata /data f2fs nodev,noatime,nosuid,errors=panic,inlinecrypt wait,fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized

Almacenamiento adoptable

Desde Android 9, FBE y el almacenamiento adoptable se pueden usar juntos.

Especificar la opción fstab fileencryption para userdata también habilita automáticamente el cifrado de metadatos y FBE en el almacenamiento adoptable. Sin embargo, puede anular los formatos de cifrado de metadatos o FBE en el almacenamiento adoptable configurando las propiedades en PRODUCT_PROPERTY_OVERRIDES .

En dispositivos que se lanzaron con Android 11 o superior, use las siguientes propiedades:

  • ro.crypto.volume.options (nuevo en Android 11) selecciona el formato de cifrado FBE en el almacenamiento adoptable. Tiene la misma sintaxis que el argumento de la opción fstab fileencryption y utiliza los mismos valores predeterminados. Consulte las recomendaciones para fileencryption anteriores para saber qué usar aquí.
  • ro.crypto.volume.metadata.encryption selecciona el formato de cifrado de metadatos en el almacenamiento adoptable. Consulte la documentación de cifrado de metadatos .

En dispositivos que se lanzaron con Android 10 o inferior, use las siguientes propiedades:

  • ro.crypto.volume.contents_mode selecciona el modo de cifrado de contenido. Esto es equivalente al primer campo separado por dos puntos de ro.crypto.volume.options .
  • ro.crypto.volume.filenames_mode selecciona el modo de cifrado de nombres de archivo. Esto es equivalente al segundo campo separado por dos puntos de ro.crypto.volume.options , excepto que el valor predeterminado en los dispositivos que se iniciaron con Android 10 o inferior es aes-256-heh . En la mayoría de los dispositivos, esto debe anularse explícitamente a aes-256-cts .
  • ro.crypto.fde_algorithm y ro.crypto.fde_sector_size seleccionan el formato de cifrado de metadatos en el almacenamiento adoptable. Consulte la documentación de cifrado de metadatos .

Integración con Keymaster

Keymaster HAL debe iniciarse como parte de la clase early_hal . Esto se debe a que FBE requiere que Keymaster esté listo para manejar las solicitudes en la fase de arranque post-fs-data , que es cuando vold configura las claves iniciales.

Excluyendo directorios

init aplica la clave DE del sistema a todos los directorios de nivel superior de /data , excepto los directorios que deben estar sin cifrar: el directorio que contiene la clave DE del sistema y los directorios que contienen los directorios CE o DE del usuario. Las claves de cifrado se aplican de forma recursiva y los subdirectorios no pueden anularlas.

En Android 11 y versiones posteriores, la clave que init aplica a los directorios puede controlarse mediante el argumento encryption=<action> del comando mkdir en los scripts de inicio. Los posibles valores de <action> están documentados en el LÉAME para el idioma de inicio de Android .

En Android 10, las acciones de cifrado init se codificaron en la siguiente ubicación:

/system/extras/libfscrypt/fscrypt_init_extensions.cpp

En Android 9 y versiones anteriores, la ubicación era:

/system/extras/ext4_utils/ext4_crypt_init_extensions.cpp

Es posible agregar excepciones para evitar que ciertos directorios se cifren. Si se realizan modificaciones de este tipo, el fabricante del dispositivo debe incluir políticas de SELinux que solo otorguen acceso a las aplicaciones que necesitan usar el directorio sin cifrar. Esto debería excluir todas las aplicaciones que no sean de confianza.

El único caso de uso aceptable conocido para esto es en apoyo de las capacidades OTA heredadas.

Compatibilidad con arranque directo en aplicaciones del sistema

Hacer que las aplicaciones sean conscientes del arranque directo

Para facilitar la migración rápida de las aplicaciones del sistema, hay dos nuevos atributos que se pueden configurar en el nivel de la aplicación. El atributo defaultToDeviceProtectedStorage solo está disponible para las aplicaciones del sistema. El atributo directBootAware está disponible para todos.

<application
    android:directBootAware="true"
    android:defaultToDeviceProtectedStorage="true">

El atributo directBootAware en el nivel de la aplicación es una forma abreviada de marcar todos los componentes de la aplicación como compatibles con el cifrado.

El atributo defaultToDeviceProtectedStorage redirige la ubicación de almacenamiento de la aplicación predeterminada para que apunte al almacenamiento DE en lugar de apuntar al almacenamiento CE. Las aplicaciones del sistema que usan este indicador deben auditar cuidadosamente todos los datos almacenados en la ubicación predeterminada y cambiar las rutas de los datos confidenciales para usar el almacenamiento CE. Los fabricantes de dispositivos que usan esta opción deben inspeccionar cuidadosamente los datos que están almacenando para asegurarse de que no contengan información personal.

Cuando se ejecuta en este modo, las siguientes API del sistema están disponibles para administrar explícitamente un contexto respaldado por almacenamiento CE cuando sea necesario, que son equivalentes a sus contrapartes protegidas por dispositivo.

  • Context.createCredentialProtectedStorageContext()
  • Context.isCredentialProtectedStorage()

Soporte para múltiples usuarios

Cada usuario en un entorno multiusuario obtiene una clave de cifrado separada. Cada usuario obtiene dos claves: una clave DE y una clave CE. El usuario 0 debe iniciar sesión en el dispositivo primero, ya que es un usuario especial. Esto es pertinente para los usos de administración de dispositivos .

Las aplicaciones con reconocimiento de cifrado interactúan entre los usuarios de esta manera: INTERACT_ACROSS_USERS e INTERACT_ACROSS_USERS_FULL permiten que una aplicación actúe entre todos los usuarios del dispositivo. Sin embargo, esas aplicaciones solo podrán acceder a directorios cifrados con CE para usuarios que ya están desbloqueados.

Una aplicación puede interactuar libremente en las áreas de DE, pero un usuario desbloqueado no significa que todos los usuarios del dispositivo estén desbloqueados. La aplicación debería comprobar este estado antes de intentar acceder a estas áreas.

Cada ID de usuario del perfil de trabajo también obtiene dos claves: DE y CE. Cuando se cumple el desafío laboral, el usuario del perfil se desbloquea y Keymaster (en TEE) puede proporcionar la clave TEE del perfil.

Manejo de actualizaciones

La partición de recuperación no puede acceder al almacenamiento protegido por DE en la partición de datos de usuario. Se recomienda encarecidamente que los dispositivos que implementan FBE admitan OTA mediante actualizaciones del sistema A/B . Como la OTA se puede aplicar durante el funcionamiento normal, no es necesario realizar una recuperación para acceder a los datos en la unidad cifrada.

Al usar una solución OTA heredada, que requiere recuperación para acceder al archivo OTA en la partición userdata :

  1. Cree un directorio de nivel superior (por ejemplo misc_ne ) en la partición userdata .
  2. Configure este directorio de nivel superior para que no esté cifrado (consulte Exclusión de directorios ).
  3. Cree un directorio dentro del directorio de nivel superior para almacenar paquetes OTA.
  4. Agregue una regla de SELinux y contextos de archivo para controlar el acceso a este directorio y su contenido. Solo el proceso o las aplicaciones que reciben actualizaciones OTA deben poder leer y escribir en este directorio. Ninguna otra aplicación o proceso debe tener acceso a este directorio.

Validación

Para asegurarse de que la versión implementada de la función funcione según lo previsto, primero ejecute las numerosas pruebas de cifrado CTS, como DirectBootHostTest y EncryptionTest .

Si el dispositivo ejecuta Android 11 o superior, también ejecute vts_kernel_encryption_test :

atest vts_kernel_encryption_test

o:

vts-tradefed run vts -m vts_kernel_encryption_test

Además, los fabricantes de dispositivos pueden realizar las siguientes pruebas manuales. En un dispositivo con FBE habilitado:

  • Compruebe que existe ro.crypto.state
    • Asegúrese de que ro.crypto.state esté encriptado
  • Compruebe que existe ro.crypto.type
    • Asegúrese de ro.crypto.type esté configurado en file

Además, los evaluadores pueden iniciar una instancia userdebug con una pantalla de bloqueo configurada en el usuario principal. Luego adb shell en el dispositivo y use su para convertirse en root. Asegúrese de que /data/data contenga nombres de archivos cifrados; si no es así, algo anda mal.

También se alienta a los fabricantes de dispositivos a explorar la ejecución de las pruebas de Linux upstream para fscrypt en sus dispositivos o kernels. Estas pruebas son parte del conjunto de pruebas del sistema de archivos xfstests. Sin embargo, estas pruebas ascendentes no son oficialmente compatibles con Android.

Detalles de implementación de AOSP

Esta sección proporciona detalles sobre la implementación de AOSP y describe cómo funciona el cifrado basado en archivos. No debería ser necesario que los fabricantes de dispositivos realicen ningún cambio aquí para usar FBE y Direct Boot en sus dispositivos.

cifrado fscrypt

La implementación de AOSP utiliza el cifrado "fscrypt" (compatible con ext4 y f2fs) en el núcleo y normalmente está configurado para:

  • Cifre el contenido del archivo con AES-256 en modo XTS
  • Cifrar nombres de archivos con AES-256 en modo CBC-CTS

El cifrado Adiantum también es compatible. Cuando el cifrado de Adiantum está habilitado, tanto el contenido como los nombres de los archivos se cifran con Adiantum.

fscrypt admite dos versiones de políticas de cifrado: versión 1 y versión 2. La versión 1 está en desuso y los requisitos de CDD para dispositivos que se inician con Android 11 y versiones posteriores solo son compatibles con la versión 2. Las políticas de cifrado de la versión 2 usan HKDF-SHA512 para derivar el claves de cifrado de las claves proporcionadas por el espacio de usuario.

Para obtener más información sobre fscrypt, consulte la documentación del núcleo original .

Clases de almacenamiento

La siguiente tabla enumera las claves FBE y los directorios que protegen con más detalle:

clase de almacenamiento Descripción Directorios
Sistema DE Datos encriptados del dispositivo no vinculados a un usuario en particular /data/system , /data/app , y varios otros subdirectorios de /data
por arranque Archivos de sistema efímeros que no necesitan sobrevivir a un reinicio /data/per_boot
Usuario CE (interno) Datos cifrados con credenciales por usuario en el almacenamiento interno
  • /data/data (alias de /data/user/0 )
  • /data/media/${user_id}
  • /data/misc_ce/${user_id}
  • /data/system_ce/${user_id}
  • /data/user/${user_id}
  • /data/vendor_ce/${user_id}
Usuario DE (interno) Datos cifrados por dispositivo por usuario en el almacenamiento interno
  • /data/misc_de/${user_id}
  • /data/system_de/${user_id}
  • /data/user_de/${user_id}
  • /data/vendor_de/${user_id}
Usuario CE (adoptable) Datos cifrados con credenciales por usuario en almacenamiento adoptable
  • /mnt/expand/${volume_uuid}/media/${user_id}
  • /mnt/expand/${volume_uuid}/misc_ce/${user_id}
  • /mnt/expand/${volume_uuid}/user/${user_id}
Usuario DE (adoptable) Datos cifrados por dispositivo por usuario en almacenamiento adoptable
  • /mnt/expand/${volume_uuid}/misc_de/${user_id}
  • /mnt/expand/${volume_uuid}/user_de/${user_id}

Almacenamiento y protección de claves

vold administra todas las claves de FBE y se almacenan cifradas en el disco, excepto la clave por arranque, que no se almacena en absoluto. La siguiente tabla enumera las ubicaciones en las que se almacenan las distintas claves FBE:

tipo de clave Ubicación clave Clase de almacenamiento de ubicación clave
Clave del sistema DE /data/unencrypted sin cifrar
Claves de usuario CE (internas) /data/misc/vold/user_keys/ce/${user_id} Sistema DE
Claves de usuario DE (internas) /data/misc/vold/user_keys/de/${user_id} Sistema DE
Claves de usuario CE (adoptables) /data/misc_ce/${user_id}/vold/volume_keys/${volume_uuid} Usuario CE (interno)
Claves de usuario DE (adoptables) /data/misc_de/${user_id}/vold/volume_keys/${volume_uuid} Usuario DE (interno)

Como se muestra en la tabla anterior, la mayoría de las claves de FBE se almacenan en directorios que están encriptados por otra clave de FBE. Las claves no se pueden desbloquear hasta que se haya desbloqueado la clase de almacenamiento que las contiene.

vold también aplica una capa de cifrado a todas las claves FBE. Todas las claves, además de las claves CE para el almacenamiento interno, se cifran con AES-256-GCM utilizando su propia clave Keystore que no está expuesta fuera del TEE. Esto garantiza que las claves FBE no se puedan desbloquear a menos que se haya iniciado un sistema operativo de confianza, tal como lo exige Verified Boot . La resistencia a la reversión también se solicita en la clave Keystore, lo que permite que las claves FBE se eliminen de forma segura en dispositivos donde Keymaster admite la resistencia a la reversión. Como alternativa de mejor esfuerzo para cuando la resistencia de reversión no está disponible, el hash SHA-512 de 16384 bytes aleatorios almacenados en el archivo secdiscardable almacenado junto con la clave se usa como la etiqueta de identificación de la aplicación de la clave Keystore. Todos estos bytes deben recuperarse para recuperar una clave FBE.

Las claves CE para el almacenamiento interno reciben un mayor nivel de protección que garantiza que no se puedan desbloquear sin conocer el factor de conocimiento de la pantalla de bloqueo (LSKF) del usuario (PIN, patrón o contraseña), un token de restablecimiento de código de acceso seguro o ambos del lado del cliente. y claves del lado del servidor para una operación de Resume-on-Reboot . Los tokens de restablecimiento de contraseña solo se pueden crear para perfiles de trabajo y dispositivos totalmente administrados .

Para lograr esto, vold encripta cada clave CE para el almacenamiento interno utilizando una clave AES-256-GCM derivada de la contraseña sintética del usuario. La contraseña sintética es un secreto criptográfico inmutable de alta entropía que se genera aleatoriamente para cada usuario. LockSettingsService en system_server administra la contraseña sintética y las formas en que se protege.

Para proteger la contraseña sintética con la LSKF, LockSettingsService primero extiende la LSKF pasándola a través de scrypt , con un objetivo de aproximadamente 25 ms y un uso de memoria de aproximadamente 2 MiB. Dado que los LSKF suelen ser cortos, este paso no suele proporcionar mucha seguridad. La capa principal de seguridad es el elemento seguro (SE) o límite de velocidad aplicado por TEE que se describe a continuación.

Si el dispositivo tiene un elemento seguro (SE), entonces LockSettingsService asigna el LSKF extendido a un secreto aleatorio de alta entropía almacenado en el SE usando Weaver HAL . LockSettingsService luego cifra la contraseña sintética dos veces: primero con una clave de software derivada del LSKF ampliado y el secreto de Weaver, y segundo con una clave del almacén de claves no vinculada a la autenticación. Esto proporciona una limitación de tasa impuesta por SE de conjeturas LSKF.

Si el dispositivo no tiene un SE, entonces LockSettingsService usa el LSKF ampliado como contraseña de Gatekeeper . LockSettingsService luego encripta la contraseña sintética dos veces: primero con una clave de software derivada de la LSKF ampliada y el hash de un archivo secdiscardable, y segundo con una clave Keystore que está vinculada a la autenticación de la inscripción de Gatekeeper. Esto proporciona una limitación de tasa impuesta por TEE de conjeturas LSKF.

Cuando se cambia la LSKF, LockSettingsService elimina toda la información asociada con el enlace de la contraseña sintética a la antigua LSKF. En los dispositivos que admiten Weaver o claves Keystore resistentes a la reversión, esto garantiza la eliminación segura de la vinculación anterior. Por esta razón, las protecciones descritas aquí se aplican incluso cuando el usuario no tiene una LSKF.

,

Android 7.0 y versiones posteriores admiten el cifrado basado en archivos (FBE). El cifrado basado en archivos permite cifrar diferentes archivos con diferentes claves que se pueden desbloquear de forma independiente.

Este artículo describe cómo habilitar el cifrado basado en archivos en nuevos dispositivos y cómo las aplicaciones del sistema pueden usar las API de arranque directo para ofrecer a los usuarios la mejor y más segura experiencia posible.

Todos los dispositivos que se inician con Android 10 y versiones posteriores deben usar cifrado basado en archivos.

Arranque directo

El cifrado basado en archivos habilita una nueva característica introducida en Android 7.0 llamada Arranque directo . Direct Boot permite que los dispositivos encriptados arranquen directamente en la pantalla de bloqueo. Anteriormente, en dispositivos encriptados que usaban encriptación de disco completo (FDE), los usuarios debían proporcionar credenciales antes de poder acceder a los datos, lo que impedía que el teléfono realizara todas las operaciones excepto las más básicas. Por ejemplo, las alarmas no podían funcionar, los servicios de accesibilidad no estaban disponibles y los teléfonos no podían recibir llamadas, pero estaban limitados a operaciones básicas de marcación de emergencia.

Con la introducción del cifrado basado en archivos (FBE) y las nuevas API para que las aplicaciones reconozcan el cifrado, es posible que estas aplicaciones operen dentro de un contexto limitado. Esto puede ocurrir antes de que los usuarios hayan proporcionado sus credenciales mientras se sigue protegiendo la información privada del usuario.

En un dispositivo habilitado para FBE, cada usuario del dispositivo tiene dos ubicaciones de almacenamiento disponibles para las aplicaciones:

  • Almacenamiento de Credential Encrypted (CE), que es la ubicación de almacenamiento predeterminada y solo está disponible después de que el usuario haya desbloqueado el dispositivo.
  • Almacenamiento de dispositivo cifrado (DE), que es una ubicación de almacenamiento disponible tanto durante el modo de arranque directo como después de que el usuario haya desbloqueado el dispositivo.

Esta separación hace que los perfiles de trabajo sean más seguros porque permite proteger a más de un usuario a la vez, ya que el cifrado ya no se basa únicamente en una contraseña de arranque.

La API de arranque directo permite que las aplicaciones con reconocimiento de cifrado accedan a cada una de estas áreas. Hay cambios en el ciclo de vida de la aplicación para adaptarse a la necesidad de notificar a las aplicaciones cuando el almacenamiento de CE de un usuario está desbloqueado en respuesta al primer ingreso de credenciales en la pantalla de bloqueo, o en el caso de un perfil de trabajo que presenta un desafío laboral . Los dispositivos que ejecutan Android 7.0 deben ser compatibles con estas nuevas API y ciclos de vida, independientemente de si implementan o no FBE. Aunque, sin FBE, el almacenamiento DE y CE siempre estará en estado desbloqueado.

Se proporciona una implementación completa de cifrado basado en archivos en los sistemas de archivos Ext4 y F2FS en el Proyecto de código abierto de Android (AOSP) y solo debe habilitarse en dispositivos que cumplan con los requisitos. Es posible que los fabricantes que opten por usar FBE deseen explorar formas de optimizar la función en función del sistema en chip (SoC) utilizado.

Todos los paquetes necesarios en AOSP se han actualizado para reconocer el arranque directo. Sin embargo, cuando los fabricantes de dispositivos utilicen versiones personalizadas de estas aplicaciones, querrán asegurarse de que, como mínimo, haya paquetes compatibles con el arranque directo que brinden los siguientes servicios:

  • Servicios de Telefonía y Marcador
  • Método de entrada para ingresar contraseñas en la pantalla de bloqueo

Ejemplos y fuente

Android proporciona una implementación de referencia de cifrado basado en archivos, en la que vold ( system/vold ) proporciona la funcionalidad para administrar dispositivos y volúmenes de almacenamiento en Android. La adición de FBE proporciona a vold varios comandos nuevos para admitir la administración de claves para las claves CE y DE de múltiples usuarios. Además de los cambios principales para usar las capacidades de encriptación basadas en archivos en el kernel , muchos paquetes del sistema, incluidos LockScreen y SystemUI, se han modificado para admitir las funciones FBE y Direct Boot. Éstas incluyen:

  • Marcador AOSP (paquetes/aplicaciones/Marcador)
  • Reloj de escritorio (paquetes/aplicaciones/DeskClock)
  • LatinIME (paquetes/métodos de entrada/LatinIME)*
  • Aplicación de configuración (paquetes/aplicaciones/Configuración)*
  • SystemUI (marcos/base/paquetes/SystemUI)*

* Aplicaciones del sistema que usan el atributo de manifiesto defaultToDeviceProtectedStorage

Se pueden encontrar más ejemplos de aplicaciones y servicios que son compatibles con el cifrado ejecutando el comando mangrep directBootAware en el directorio de marcos o paquetes del árbol fuente de AOSP.

dependencias

Para usar la implementación AOSP de FBE de forma segura, un dispositivo debe cumplir con las siguientes dependencias:

  • Soporte de kernel para cifrado Ext4 o cifrado F2FS.
  • Soporte Keymaster con HAL versión 1.0 o superior. No hay soporte para Keymaster 0.3, ya que no proporciona las capacidades necesarias ni garantiza una protección suficiente para las claves de cifrado.
  • Keymaster/ Keystore y Gatekeeper deben implementarse en un entorno de ejecución de confianza (TEE) para brindar protección a las claves DE de modo que un sistema operativo no autorizado (sistema operativo personalizado instalado en el dispositivo) no pueda simplemente solicitar las claves DE.
  • Se requiere raíz de confianza de hardware y arranque verificado vinculado a la inicialización de Keymaster para garantizar que un sistema operativo no autorizado no pueda acceder a las claves DE.

Implementación

En primer lugar, las aplicaciones como los relojes de alarma, el teléfono y las funciones de accesibilidad deben hacerse android:directBootAware de acuerdo con la documentación del desarrollador de arranque directo .

Soporte del núcleo

El soporte de kernel para el cifrado Ext4 y F2FS está disponible en los kernels comunes de Android, versión 3.18 y superior. Para habilitarlo en un kernel que es la versión 5.1 o superior, utilice:

CONFIG_FS_ENCRYPTION=y

Para kernels más antiguos, use CONFIG_EXT4_ENCRYPTION=y si el sistema de archivos userdata de su dispositivo es Ext4, o use CONFIG_F2FS_FS_ENCRYPTION=y si el sistema de archivos userdata de su dispositivo es F2FS.

Si su dispositivo admitirá el almacenamiento adoptable o utilizará el cifrado de metadatos en el almacenamiento interno, habilite también las opciones de configuración del kernel necesarias para el cifrado de metadatos como se describe en la documentación de cifrado de metadatos .

Además del soporte funcional para el cifrado Ext4 o F2FS, los fabricantes de dispositivos también deberían habilitar la aceleración criptográfica para acelerar el cifrado basado en archivos y mejorar la experiencia del usuario. Por ejemplo, en dispositivos basados ​​en ARM64, la aceleración ARMv8 CE (Cryptography Extensions) se puede habilitar configurando las siguientes opciones de configuración del kernel:

CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
CONFIG_CRYPTO_SHA2_ARM64_CE=y

To further improve performance and reduce power usage, device manufacturers may also consider implementing inline encryption hardware , which encrypts/decrypts the data while it is on the way to/from the storage device. The Android common kernels (version 4.14 and higher) contain a framework that allows inline encryption to be used when hardware and vendor driver support is available. The inline encryption framework can be enabled by setting the following kernel configuration options:

CONFIG_BLK_INLINE_ENCRYPTION=y
CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y

If your device uses UFS-based storage, also enable:

CONFIG_SCSI_UFS_CRYPTO=y

If your device uses eMMC-based storage, also enable:

CONFIG_MMC_CRYPTO=y

Enabling file-based encryption

Enabling FBE on a device requires enabling it on the internal storage ( userdata ). This also automatically enables FBE on adoptable storage; however, the encryption format on adoptable storage may be overridden if necessary.

Internal storage

FBE is enabled by adding the option fileencryption=contents_encryption_mode[:filenames_encryption_mode[:flags]] to the fs_mgr_flags column of the fstab line for userdata . This option defines the encryption format on internal storage. It contains up to three colon-separated parameters:

  • The contents_encryption_mode parameter defines which cryptographic algorithm is used to encrypt file contents. It can be either aes-256-xts or adiantum . Since Android 11 it can also be left empty to specify the default algorithm, which is aes-256-xts .
  • The filenames_encryption_mode parameter defines which cryptographic algorithm is used to encrypt file names. It can be either aes-256-cts , aes-256-heh , adiantum , or aes-256-hctr2 . If not specified, it defaults to aes-256-cts if contents_encryption_mode is aes-256-xts , or to adiantum if contents_encryption_mode is adiantum .
  • The flags parameter, new in Android 11, is a list of flags separated by the + character. The following flags are supported:
    • The v1 flag selects version 1 encryption policies; the v2 flag selects version 2 encryption policies. Version 2 encryption policies use a more secure and flexible key derivation function . The default is v2 if the device launched on Android 11 or higher (as determined by ro.product.first_api_level ), or v1 if the device launched on Android 10 or lower.
    • The inlinecrypt_optimized flag selects an encryption format that is optimized for inline encryption hardware that doesn't handle large numbers of keys efficiently. It does this by deriving just one file contents encryption key per CE or DE key, rather than one per file. The generation of IVs (initialization vectors) is adjusted accordingly.
    • The emmc_optimized flag is similar to inlinecrypt_optimized , but it also selects an IV generation method that limits IVs to 32 bits. This flag should only be used on inline encryption hardware that is compliant with the JEDEC eMMC v5.2 specification and therefore supports only 32-bit IVs. On other inline encryption hardware, use inlinecrypt_optimized instead. This flag should never be used on UFS-based storage; the UFS specification allows the use of 64-bit IVs.
    • On devices that support hardware-wrapped keys , the wrappedkey_v0 flag enables the use of hardware-wrapped keys for FBE. This can only be used in combination with the inlinecrypt mount option, and either the inlinecrypt_optimized or emmc_optimized flag.

If you aren't using inline encryption hardware the recommended setting for most devices is fileencryption=aes-256-xts . If you are using inline encryption hardware the recommended setting for most devices is fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized (or equivalently fileencryption=::inlinecrypt_optimized ). On devices without any form of AES acceleration, Adiantum may be used instead of AES by setting fileencryption=adiantum .

Since Android 14 (AOSP experimental), AES-HCTR2 is the preferred mode of filenames encryption for devices with accelerated cryptography instructions. However, only newer Android kernels support AES-HCTR2. In a future Android release, it is planned to become the default mode for filenames encryption. If your kernel has AES-HCTR2 support, it can be enabled for filenames encryption by setting filenames_encryption_mode to aes-256-hctr2 . In the simplest case this would be done with fileencryption=aes-256-xts:aes-256-hctr2 .

On devices that launched with Android 10 or lower, fileencryption=ice is also accepted to specify the use of the FSCRYPT_MODE_PRIVATE file contents encryption mode. This mode is unimplemented by the Android common kernels, but it could be implemented by vendors using custom kernel patches. The on-disk format produced by this mode was vendor-specific. On devices launching with Android 11 or higher, this mode is no longer allowed and a standard encryption format must be used instead.

By default, file contents encryption is done using the Linux kernel's cryptography API. If you want to use inline encryption hardware instead, also add the inlinecrypt mount option. For example, a full fstab line might look like:

/dev/block/by-name/userdata /data f2fs nodev,noatime,nosuid,errors=panic,inlinecrypt wait,fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized

Adoptable storage

Since Android 9, FBE and adoptable storage can be used together.

Specifying the fileencryption fstab option for userdata also automatically enables both FBE and metadata encryption on adoptable storage. However, you may override the FBE and/or metadata encryption formats on adoptable storage by setting properties in PRODUCT_PROPERTY_OVERRIDES .

On devices that launched with Android 11 or higher, use the following properties:

  • ro.crypto.volume.options (new in Android 11) selects the FBE encryption format on adoptable storage. It has the same syntax as the argument to the fileencryption fstab option, and it uses the same defaults. See the recommendations for fileencryption above for what to use here.
  • ro.crypto.volume.metadata.encryption selects the metadata encryption format on adoptable storage. See the metadata encryption documentation .

On devices that launched with Android 10 or lower, use the following properties:

  • ro.crypto.volume.contents_mode selects the contents encryption mode. This is equivalent to the first colon-separated field of ro.crypto.volume.options .
  • ro.crypto.volume.filenames_mode selects the filenames encryption mode. This is equivalent to the second colon-separated field of ro.crypto.volume.options , except that the default on devices that launched with Android 10 or lower is aes-256-heh . On most devices, this needs to be explicitly overridden to aes-256-cts .
  • ro.crypto.fde_algorithm and ro.crypto.fde_sector_size select the metadata encryption format on adoptable storage. See the metadata encryption documentation .

Integrating with Keymaster

The Keymaster HAL should be started as part of the early_hal class. This is because FBE requires that Keymaster be ready to handle requests by the post-fs-data boot phase, which is when vold sets up the initial keys.

Excluding directories

init applies the system DE key to all top-level directories of /data , except for directories that must be unencrypted: the directory that contains the system DE key itself, and directories that contain user CE or DE directories. Encryption keys apply recursively and cannot be overridden by subdirectories.

In Android 11 and higher, the key that init applies to directories can be controlled by the encryption=<action> argument to the mkdir command in init scripts. The possible values of <action> are documented in the README for the Android init language .

In Android 10, the init encryption actions were hardcoded into the following location:

/system/extras/libfscrypt/fscrypt_init_extensions.cpp

In Android 9 and earlier, the location was:

/system/extras/ext4_utils/ext4_crypt_init_extensions.cpp

It is possible to add exceptions to prevent certain directories from being encrypted at all. If modifications of this sort are made then the device manufacturer should include SELinux policies that only grant access to the applications that need to use the unencrypted directory. This should exclude all untrusted applications.

The only known acceptable use case for this is in support of legacy OTA capabilities.

Supporting Direct Boot in system applications

Making applications Direct Boot aware

To facilitate rapid migration of system apps, there are two new attributes that can be set at the application level. The defaultToDeviceProtectedStorage attribute is available only to system apps. The directBootAware attribute is available to all.

<application
    android:directBootAware="true"
    android:defaultToDeviceProtectedStorage="true">

The directBootAware attribute at the application level is shorthand for marking all components in the app as being encryption aware.

The defaultToDeviceProtectedStorage attribute redirects the default app storage location to point at DE storage instead of pointing at CE storage. System apps using this flag must carefully audit all data stored in the default location, and change the paths of sensitive data to use CE storage. Device manufactures using this option should carefully inspect the data that they are storing to ensure that it contains no personal information.

When running in this mode, the following System APIs are available to explicitly manage a Context backed by CE storage when needed, which are equivalent to their Device Protected counterparts.

  • Context.createCredentialProtectedStorageContext()
  • Context.isCredentialProtectedStorage()

Supporting multiple users

Each user in a multi-user environment gets a separate encryption key. Every user gets two keys: a DE and a CE key. User 0 must log into the device first as it is a special user. This is pertinent for Device Administration uses.

Crypto-aware applications interact across users in this manner: INTERACT_ACROSS_USERS and INTERACT_ACROSS_USERS_FULL allow an application to act across all the users on the device. However, those apps will be able to access only CE-encrypted directories for users that are already unlocked.

An application may be able to interact freely across the DE areas, but one user unlocked does not mean that all the users on the device are unlocked. The application should check this status before trying to access these areas.

Each work profile user ID also gets two keys: DE and CE. When the work challenge is met, the profile user is unlocked and the Keymaster (in TEE) can provide the profile's TEE key.

Handling updates

The recovery partition is unable to access the DE-protected storage on the userdata partition. Devices implementing FBE are strongly recommended to support OTA using A/B system updates . As the OTA can be applied during normal operation there is no need for recovery to access data on the encrypted drive.

When using a legacy OTA solution, which requires recovery to access the OTA file on the userdata partition:

  1. Create a top-level directory (for example misc_ne ) in the userdata partition.
  2. Configure this top-level directory to be unencrypted (see Excluding directories ).
  3. Create a directory within the top-level directory to hold OTA packages.
  4. Add an SELinux rule and file contexts to control access to this directory and it contents. Only the process or applications receiving OTA updates should be able to read and write to this directory. No other application or process should have access to this directory.

Validación

To ensure the implemented version of the feature works as intended, first run the many CTS encryption tests, such as DirectBootHostTest and EncryptionTest .

If the device is running Android 11 or higher, also run vts_kernel_encryption_test :

atest vts_kernel_encryption_test

or:

vts-tradefed run vts -m vts_kernel_encryption_test

In addition, device manufacturers may perform the following manual tests. On a device with FBE enabled:

  • Check that ro.crypto.state exists
    • Ensure ro.crypto.state is encrypted
  • Check that ro.crypto.type exists
    • Ensure ro.crypto.type is set to file

Additionally, testers can boot a userdebug instance with a lockscreen set on the primary user. Then adb shell into the device and use su to become root. Make sure /data/data contains encrypted filenames; if it does not, something is wrong.

Device manufacturers are also encouraged to explore running the upstream Linux tests for fscrypt on their devices or kernels. These tests are part of the xfstests filesystem test suite. However, these upstream tests are not offically supported by Android.

AOSP implementation details

This section provides details on the AOSP implementation and describes how file-based encryption works. It should not be necessary for device manufacturers to make any changes here to use FBE and Direct Boot on their devices.

fscrypt encryption

The AOSP implementation uses "fscrypt" encryption (supported by ext4 and f2fs) in the kernel and normally is configured to:

  • Encrypt file contents with AES-256 in XTS mode
  • Encrypt file names with AES-256 in CBC-CTS mode

Adiantum encryption is also supported. When Adiantum encryption is enabled, both file contents and file names are encrypted with Adiantum.

fscrypt supports two versions of encryption policies: version 1 and version 2. Version 1 is deprecated, and the CDD requirements for devices launching with Android 11 and higher are only compatible with version 2. Version 2 encryption policies use HKDF-SHA512 to derive the actual encryption keys from the userspace-supplied keys.

For more information about fscrypt, see the upstream kernel documentation .

Storage classes

The following table lists the FBE keys and the directories they protect in more detail:

Storage class Descripción Directories
System DE Device-encrypted data not tied to a particular user /data/system , /data/app , and various other subdirectories of /data
Per-boot Ephemeral system files that don't need to survive a reboot /data/per_boot
User CE (internal) Per-user credential-encrypted data on internal storage
  • /data/data (alias of /data/user/0 )
  • /data/media/${user_id}
  • /data/misc_ce/${user_id}
  • /data/system_ce/${user_id}
  • /data/user/${user_id}
  • /data/vendor_ce/${user_id}
User DE (internal) Per-user device-encrypted data on internal storage
  • /data/misc_de/${user_id}
  • /data/system_de/${user_id}
  • /data/user_de/${user_id}
  • /data/vendor_de/${user_id}
User CE (adoptable) Per-user credential-encrypted data on adoptable storage
  • /mnt/expand/${volume_uuid}/media/${user_id}
  • /mnt/expand/${volume_uuid}/misc_ce/${user_id}
  • /mnt/expand/${volume_uuid}/user/${user_id}
User DE (adoptable) Per-user device-encrypted data on adoptable storage
  • /mnt/expand/${volume_uuid}/misc_de/${user_id}
  • /mnt/expand/${volume_uuid}/user_de/${user_id}

Key storage and protection

All FBE keys are managed by vold and are stored encrypted on-disk, except for the per-boot key which is not stored at all. The following table lists the locations in which the various FBE keys are stored:

Key type Key location Storage class of key location
System DE key /data/unencrypted Unencrypted
User CE (internal) keys /data/misc/vold/user_keys/ce/${user_id} System DE
User DE (internal) keys /data/misc/vold/user_keys/de/${user_id} System DE
User CE (adoptable) keys /data/misc_ce/${user_id}/vold/volume_keys/${volume_uuid} User CE (internal)
User DE (adoptable) keys /data/misc_de/${user_id}/vold/volume_keys/${volume_uuid} User DE (internal)

As shown in the preceding table, most FBE keys are stored in directories that are encrypted by another FBE key. Keys cannot be unlocked until the storage class that contains them has been unlocked.

vold also applies a layer of encryption to all FBE keys. Every key besides CE keys for internal storage is encrypted with AES-256-GCM using its own Keystore key that is not exposed outside the TEE. This ensures that FBE keys cannot be unlocked unless a trusted operating system has booted, as enforced by Verified Boot . Rollback resistance is also requested on the Keystore key, which allows FBE keys to be securely deleted on devices where Keymaster supports rollback resistance. As a best-effort fallback for when rollback resistance is unavailable, the SHA-512 hash of 16384 random bytes stored in the secdiscardable file stored alongside the key is used as the application ID tag of the Keystore key. All these bytes need to be recovered to recover an FBE key.

CE keys for internal storage receive a stronger level of protection that ensures they cannot be unlocked without knowing either the user's Lock Screen Knowledge Factor (LSKF) (PIN, pattern, or password), a secure passcode reset token , or both the client-side and server-side keys for a Resume-on-Reboot operation. Passcode reset tokens are only allowed to be created for work profiles and fully managed devices .

To achieve this, vold encrypts each CE key for internal storage using an AES-256-GCM key derived from the user's synthetic password . The synthetic password is an immutable high-entropy cryptographic secret that is randomly generated for each user. LockSettingsService in system_server manages the synthetic password and the ways in which it is protected.

To protect the synthetic password with the LSKF, LockSettingsService first stretches the LSKF by passing it through scrypt , targeting a time of about 25 ms and a memory usage of about 2 MiB. Since LSKFs are usually short, this step usually does not provide much security. The main layer of security is the Secure Element (SE) or TEE-enforced ratelimiting described below.

If the device has a Secure Element (SE), then LockSettingsService maps the stretched LSKF to a high-entropy random secret stored in the SE using the Weaver HAL . LockSettingsService then encrypts the synthetic password twice: first with a software key derived from the stretched LSKF and the Weaver secret, and second with a non-auth-bound Keystore key. This provides SE-enforced ratelimiting of LSKF guesses.

If the device doesn't have a SE, then LockSettingsService instead uses the stretched LSKF as a Gatekeeper password. LockSettingsService then encrypts the synthetic password twice: first with a software key derived from the stretched LSKF and the hash of a secdiscardable file, and second with a Keystore key that is auth-bound to the Gatekeeper enrollment. This provides TEE-enforced ratelimiting of LSKF guesses.

When the LSKF is changed, LockSettingsService deletes all information associated with the binding of the synthetic password to the old LSKF. On devices that support Weaver or rollback resistant Keystore keys, this guarantees secure deletion of the old binding. For this reason, the protections described here are applied even when the user does not have an LSKF.