Encriptación basada en archivos

Android 7.0 y versiones posteriores admiten la encriptación basada en archivos (FBE). La encriptación basada en archivos permite encriptar diferentes archivos con diferentes claves que se pueden desbloquear de forma independiente.

En este artículo, se describe cómo habilitar la encriptación basada en archivos en dispositivos nuevos y cómo las apps del sistema pueden usar las APIs de Direct Boot para ofrecer a los usuarios la mejor experiencia posible y la más segura.

Todos los dispositivos que se lanzan con Android 10 y versiones posteriores deben usar la encriptación basada en archivos.

Inicio directo

La encriptación basada en archivos habilita una nueva función que se introdujo en Android 7.0, llamada Inicio directo. Direct Boot permite que los dispositivos encriptados se inicien directamente en la pantalla de bloqueo. Anteriormente, en los 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 funcionaban, los servicios de accesibilidad no estaban disponibles y los teléfonos no podían recibir llamadas, pero se limitaban a las operaciones básicas del selector de emergencia.

Con la introducción de la encriptación basada en archivos (FBE) y nuevas APIs para que las apps conozcan la encriptación, es posible que estas apps funcionen en un contexto limitado. Esto puede ocurrir antes de que los usuarios proporcionen sus credenciales y, al mismo tiempo, proteger su información privada.

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

  • Almacenamiento encriptado por credenciales (CE), que es la ubicación de almacenamiento predeterminada y solo está disponible después de que el usuario desbloquea el dispositivo.
  • Almacenamiento encriptado por dispositivo (DE), que es una ubicación de almacenamiento disponible tanto durante el modo de inicio directo como después de que el usuario desbloquea el dispositivo.

Esta separación hace que los perfiles de trabajo sean más seguros, ya que permite que se proteja a más de un usuario a la vez, ya que la encriptación ya no se basa solo en una contraseña de inicio.

La API de Direct Boot permite que las apps que admiten encriptación accedan a cada una de estas áreas. Se realizaron cambios en el ciclo de vida de la app para adaptarse a la necesidad de notificar a las apps cuando el almacenamiento de CE de un usuario se desbloquea en respuesta a la primera entrada de credenciales en la pantalla de bloqueo o, en el caso del perfil de trabajo, cuando se proporciona un desafío de trabajo. Los dispositivos que ejecutan Android 7.0 deben admitir estas nuevas APIs y estos nuevos ciclos de vida, independientemente de si implementan FBE o no. Sin embargo, sin FBE, el almacenamiento de DE y CE siempre está en estado de desbloqueo.

En el Proyecto de código abierto de Android (AOSP), se proporciona una implementación completa de la encriptación basada en archivos en los sistemas de archivos Ext4 y F2FS, y solo se debe habilitar en dispositivos que cumplan con los requisitos. Los fabricantes que elijan usar FBE pueden explorar formas de optimizar la función según el sistema en chip (SoC) que se use.

Todos los paquetes necesarios en AOSP se actualizaron para admitir el inicio directo. Sin embargo, cuando los fabricantes de dispositivos usan versiones personalizadas de estas apps, desean asegurarse de que, como mínimo, haya paquetes compatibles con el inicio directo que proporcionen 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 la encriptación basada en archivos, en la que vold (system/vold) proporciona la funcionalidad para administrar dispositivos de almacenamiento y volúmenes en Android. La adición de FBE proporciona a vold varios comandos nuevos para admitir la administración de claves de los usuarios CE y DE de varios usuarios. Además de los cambios principales para usar las funciones de encriptación basada en archivos en el kernel, se modificaron muchos paquetes del sistema, incluida la pantalla de bloqueo y SystemUI, para admitir las funciones de FBE y de inicio directo. Por ejemplo:

  • Marcador del AOSP (packages/apps/Dialer)
  • Reloj de escritorio (packages/apps/DeskClock)
  • LatinIME (packages/inputmethods/LatinIME)*
  • App de Configuración (packages/apps/Settings)*
  • SystemUI (frameworks/base/packages/SystemUI)*

* Apps del sistema que usan el atributo del manifiesto defaultToDeviceProtectedStorage

Para encontrar más ejemplos de apps y servicios que admiten la encriptación, ejecuta el comando mangrep directBootAware en el directorio de frameworks o paquetes del árbol de fuentes de AOSP.

Dependencias

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

  • Compatibilidad con el kernel para la encriptación Ext4 o F2FS
  • Compatibilidad con Keymaster con la versión 1.0 de HAL o una posterior No se admite Keymaster 0.3, ya que no proporciona las capacidades necesarias ni garantiza una protección suficiente para las claves de encriptación.
  • Keymaster/Keystore y Gatekeeper deben implementarse en un entorno de ejecución confiable (TEE) para proporcionar protección a las claves de DE, de modo que un SO no autorizado (SO personalizado grabado en el dispositivo) no pueda simplemente solicitar las claves de DE.
  • Se requiere la raíz de confianza de hardware y el inicio verificado vinculados a la inicialización de Keymaster para garantizar que un sistema operativo no autorizado no pueda acceder a las claves de DE.

Implementación

En primer lugar, las apps como las alarmas, el teléfono y las funciones de accesibilidad deben tener android:directBootAware según la documentación para desarrolladores de Direct Boot.

Compatibilidad con kernel

La compatibilidad del kernel con la encriptación Ext4 y F2FS está disponible en los kernels comunes de Android, versión 3.18 y versiones posteriores. Para habilitarlo en un kernel de la versión 5.1 o una posterior, usa lo siguiente:

CONFIG_FS_ENCRYPTION=y

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

Si tu dispositivo admite almacenamiento adoptable o usa encriptación de metadatos en el almacenamiento interno, también habilita las opciones de configuración del kernel necesarias para la encriptación de metadatos, como se describe en la documentación de encriptación de metadatos.

Además de la compatibilidad funcional con la encriptación Ext4 o F2FS, los fabricantes de dispositivos también deben habilitar la aceleración criptográfica para acelerar la encriptación basada en archivos y mejorar la experiencia del usuario. Por ejemplo, en dispositivos basados en ARM64, se puede habilitar la aceleración de ARMv8 CE (Extensiones de criptografía) 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 consumo de energía, los fabricantes de dispositivos también pueden considerar implementar hardware de encriptación intercalado, que encripta o desencripta los datos mientras se envían o reciben desde el dispositivo de almacenamiento. Los kernels comunes de Android (versión 4.14 y versiones posteriores) contienen un framework que permite usar la encriptación intercalada cuando hay compatibilidad con el hardware y los controladores de proveedores. Para habilitar el framework de encriptación intercalada, configura las siguientes opciones de configuración del kernel:

CONFIG_BLK_INLINE_ENCRYPTION=y
CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y

Si tu dispositivo usa almacenamiento basado en UFS, también habilita lo siguiente:

CONFIG_SCSI_UFS_CRYPTO=y

Si tu dispositivo usa almacenamiento basado en eMMC, habilita lo siguiente:

CONFIG_MMC_CRYPTO=y

Habilita la encriptación basada en archivos

Para habilitar la FBE en un dispositivo, debes habilitarla en el almacenamiento interno (userdata). Esto también habilita automáticamente la FBE en el almacenamiento adoptable. Sin embargo, el formato de encriptación en el almacenamiento adoptable se puede anular si es necesario.

Almacenamiento interno

Para habilitar FBE, agrega 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 encriptación 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 usa para encriptar el contenido del archivo. Puede ser aes-256-xts o adiantum. A partir de 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 usa para encriptar los nombres de archivo. 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 marcas separadas por el carácter +. Se admiten las siguientes marcas:
    • La marca v1 selecciona las políticas de encriptación de la versión 1. La marca v2 selecciona las políticas de encriptación de la versión 2. Las políticas de encriptación de la versión 2 usan una función de derivación de claves más segura y flexible. El valor predeterminado es v2 si el dispositivo se inició en Android 11 o versiones posteriores (según lo determine ro.product.first_api_level) o v1 si se inició en Android 10 o versiones anteriores.
    • La marca inlinecrypt_optimized selecciona un formato de encriptación optimizado para el hardware de encriptación intercalado que no controla grandes cantidades de claves de manera eficiente. Para ello, deriva una sola clave de encriptación de contenido de archivo por clave de CE o DE, en lugar de una por archivo. La generación de IVs (vectores de inicialización) se ajusta según corresponda.
    • La marca emmc_optimized es similar a inlinecrypt_optimized, pero también selecciona un método de generación de IV que limita los IVs a 32 bits. Esta marca solo debe usarse en hardware de encriptación intercalado que cumpla con la especificación JEDEC eMMC v5.2 y, por lo tanto, solo admita IVs de 32 bits. En otro hardware de encriptación intercalada, usa inlinecrypt_optimized. Esta marca nunca debe usarse en el almacenamiento basado en UFS, ya que la especificación de UFS permite el uso de IVs de 64 bits.
    • En los dispositivos que admiten llaves empaquetadas en hardware, la marca wrappedkey_v0 habilita el uso de llaves empaquetadas en hardware para FBE. Solo se puede usar en combinación con la opción de activación inlinecrypt y la marca inlinecrypt_optimized o emmc_optimized.
    • La marca dusize_4k fuerza el tamaño de la unidad de datos de encriptación a ser de 4,096 bytes, incluso cuando el tamaño del bloque del sistema de archivos no es de 4,096 bytes. El tamaño de la unidad de datos de encriptación es el nivel de detalle de la encriptación del contenido del archivo. Esta marca está disponible desde Android 15. Esta marca solo debe usarse para habilitar el uso de hardware de encriptación intercalado que no admita unidades de datos mayores que 4096 bytes, en un dispositivo que use un tamaño de página superior a 4096 bytes y que use el sistema de archivos f2fs.

Si no usas hardware de encriptación intercalada, el parámetro de configuración recomendado para la mayoría de los dispositivos es fileencryption=aes-256-xts. Si usas hardware de encriptación intercalado, el parámetro de configuración recomendado para la mayoría de los dispositivos es fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized (o fileencryption=::inlinecrypt_optimized de manera equivalente). En dispositivos sin ninguna forma de aceleración de AES, se puede usar Adiantum en lugar de AES configurando fileencryption=adiantum.

Desde Android 14, AES-HCTR2 es el modo preferido de encriptación de nombres de archivos para dispositivos con instrucciones de criptografía acelerada. Sin embargo, solo los kernels de Android más recientes admiten AES-HCTR2. En una versión futura de Android, se planea que se convierta en el modo predeterminado para la encriptación de nombres de archivo. Si tu kernel es compatible con AES-HCTR2, se puede habilitar para la encriptación de nombres de archivo si configuras filenames_encryption_mode como 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 versiones anteriores, también se acepta fileencryption=ice para especificar el uso del modo de encriptación del contenido de archivos FSCRYPT_MODE_PRIVATE. Los kernels comunes de Android no implementan este modo, pero los proveedores pueden implementarlo con parches de kernel personalizados. El formato en el disco que producía este modo era específico del proveedor. En los dispositivos que se inician con Android 11 o versiones posteriores, ya no se permite este modo y, en su lugar, se debe usar un formato de encriptación estándar.

De forma predeterminada, la encriptación del contenido de los archivos se realiza con la API de criptografía del kernel de Linux. Si quieres usar hardware de encriptación intercalado, también añade la opción de activación inlinecrypt. Por ejemplo, una línea fstab completa podría verse de la siguiente manera:

/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

A partir de Android 9, se pueden usar juntos FBE y el almacenamiento adoptable.

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

En dispositivos que se lanzaron con Android 11 o versiones posteriores, usa las siguientes propiedades:

  • ro.crypto.volume.options (nuevo en Android 11) selecciona el formato de encriptación FBE en el almacenamiento adoptable. Tiene la misma sintaxis que el argumento de la opción fstab fileencryption y usa los mismos valores predeterminados. Consulta las recomendaciones para fileencryption que se indican más arriba para saber qué usar aquí.
  • ro.crypto.volume.metadata.encryption selecciona el formato de encriptación de metadatos en el almacenamiento adoptable. Consulta la documentación sobre la encriptación de metadatos.

En dispositivos que se lanzaron con Android 10 o versiones anteriores, usa las siguientes propiedades:

  • ro.crypto.volume.contents_mode selecciona el modo de encriptación del contenido. Esto equivale al primer campo separado por dos puntos de ro.crypto.volume.options.
  • ro.crypto.volume.filenames_mode selecciona el modo de encriptación de los nombres de archivo. Esto equivale al segundo campo separado por dos puntos de ro.crypto.volume.options, excepto que el valor predeterminado en los dispositivos que se lanzaron con Android 10 o versiones anteriores es aes-256-heh. En la mayoría de los dispositivos, esto se debe anular de forma explícita a aes-256-cts.
  • ro.crypto.fde_algorithm y ro.crypto.fde_sector_size seleccionan el formato de encriptación de metadatos en el almacenamiento adoptable. Consulta la documentación sobre la encriptación de metadatos.

Cómo realizar la integración con Keymaster

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

Cómo excluir directorios

init aplica la clave de DE del sistema a todos los directorios de nivel superior de /data, excepto los directorios que deben estar sin encriptar, como el directorio que contiene la clave de DE del sistema y los directorios que contienen directorios de CE o DE del usuario. Las claves de encriptación se aplican de forma recursiva y no se pueden anular con subdirectorios.

En Android 11 y versiones posteriores, el argumento encryption=<action> del comando mkdir en las secuencias de comandos de init puede controlar la clave que init aplica a los directorios. Los valores posibles de <action> se documentan en el archivo readme del lenguaje init de Android.

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

/system/extras/libfscrypt/fscrypt_init_extensions.cpp

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

/system/extras/ext4_utils/ext4_crypt_init_extensions.cpp

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

El único caso de uso aceptable conocido para esto es la compatibilidad con las funciones OTA heredadas.

Cómo admitir el inicio directo en apps del sistema

Cómo hacer que las apps reconozcan el inicio directo

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

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

El atributo directBootAware a nivel de la app es un atajo para marcar todos los componentes de la app como con reconocimiento de encriptación.

El atributo defaultToDeviceProtectedStorage redirecciona la ubicación de almacenamiento predeterminada de la app para que apunte al almacenamiento de DE en lugar de apuntar al almacenamiento de CE. Las apps del sistema que usan esta marca deben auditar cuidadosamente todos los datos almacenados en la ubicación predeterminada y cambiar las rutas de acceso de los datos sensibles para usar el almacenamiento de CE. Los fabricantes de dispositivos que usan esta opción deben inspeccionar cuidadosamente los datos que almacenan para asegurarse de que no contengan información personal.

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

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

Admite varios usuarios

Cada usuario de un entorno multiusuario obtiene una clave de encriptación independiente. Cada usuario obtiene dos claves: una clave DE y una CE. El usuario 0 debe acceder al dispositivo primero, ya que es un usuario especial. Esto es pertinente para los usos de Administración de dispositivos.

Las apps que admiten criptografía interactúan con los usuarios de la siguiente manera: INTERACT_ACROSS_USERS y INTERACT_ACROSS_USERS_FULL permiten que una app actúe en todos los usuarios del dispositivo. Sin embargo, esas apps solo pueden acceder a los directorios encriptados por CE para los usuarios que ya están desbloqueados.

Es posible que una app pueda interactuar libremente en las áreas de DE, pero que un usuario desbloqueado no signifique que todos los usuarios del dispositivo estén desbloqueados. La app debe verificar este estado antes de intentar acceder a estas áreas.

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

Cómo controlar las actualizaciones

La partición de recuperación no puede acceder al almacenamiento protegido por DE en la partición de datos del usuario. Se recomienda que los dispositivos que implementen FBE admitan actualizaciones inalámbricas con actualizaciones del sistema A/B. Como la actualización OTA se puede aplicar durante el funcionamiento normal, no es necesario realizar la recuperación para acceder a los datos de la unidad encriptada.

Cuando se usa una solución OTA heredada, que requiere recuperación para acceder al archivo OTA en la partición userdata, haz lo siguiente:

  1. Crea un directorio de nivel superior (por ejemplo, misc_ne) en la partición userdata.
  2. Configura este directorio de nivel superior para que no esté encriptado (consulta Cómo excluir directorios).
  3. Crea un directorio dentro del directorio de nivel superior para contener los paquetes OTA.
  4. Agrega una regla de SELinux y contextos de archivos para controlar el acceso a este directorio y su contenido. Solo el proceso o las apps que reciben actualizaciones OTA deberían poder leer y escribir en este directorio. Ninguna otra app o proceso debería tener acceso a este directorio.

Validación

Para asegurarte de que la versión implementada de la función funcione según lo previsto, primero ejecuta las muchas pruebas de encriptación de CTS, como DirectBootHostTest y EncryptionTest.

Si el dispositivo ejecuta Android 11 o una versión posterior, también ejecuta vts_kernel_encryption_test:

atest vts_kernel_encryption_test

O bien:

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 habilitada, haz lo siguiente:

  • Comprueba que exista ro.crypto.state
    • Asegúrate de que ro.crypto.state esté encriptado
  • Comprueba que exista ro.crypto.type
    • Asegúrate de que ro.crypto.type esté configurado como file.

Además, los verificadores pueden verificar que el almacenamiento de CE esté bloqueado antes de que el dispositivo se desbloquee por primera vez desde el inicio. Para ello, usa una compilación userdebug o eng, establece un PIN, un patrón o una contraseña en el usuario principal y reinicia el dispositivo. Antes de desbloquear el dispositivo, ejecuta el siguiente comando para verificar el almacenamiento de CE del usuario principal. Si el dispositivo usa el modo de usuario del sistema sin interfaz gráfica (la mayoría de los dispositivos para la industria automotriz), el usuario principal es el usuario 10, por lo que debes ejecutar lo siguiente:

adb root; adb shell ls /data/user/10

En otros dispositivos (la mayoría de los dispositivos que no son de Automotive), el usuario principal es el usuario 0, por lo que debes ejecutar lo siguiente:

adb root; adb shell ls /data/user/0

Verifica que los nombres de archivo que se muestran estén codificados en Base64, lo que indica que están encriptados y que la clave para desencriptarlos aún no está disponible. Si los nombres de los archivos aparecen en texto sin formato, significa que hay un problema.

También se recomienda a los fabricantes de dispositivos que exploren la ejecución de las pruebas de Linux upstream para fscrypt en sus dispositivos o kernels. Estas pruebas forman parte del conjunto de pruebas del sistema de archivos xfstests. Sin embargo, Android no admite oficialmente estas pruebas upstream.

Detalles de la implementación de AOSP

En esta sección, se proporcionan detalles sobre la implementación de AOSP y se describe cómo funciona la encriptación basada en archivos. No debería ser necesario que los fabricantes de dispositivos realicen ningún cambio aquí para usar FBE y el inicio directo en sus dispositivos.

Encriptación de fscrypt

La implementación de AOSP usa la encriptación "fscrypt" (compatible con ext4 y f2fs) en el kernel y, por lo general, se configura para lo siguiente:

  • Encripta el contenido de los archivos con AES-256 en modo XTS
  • Encripta los nombres de archivo con AES-256 en modo CBC-CTS

También se admite la encriptación Adiantum. Cuando se habilita la encriptación Adiantum, el contenido y los nombres de los archivos se encriptan con Adiantum.

fscrypt admite dos versiones de políticas de encriptación: la versión 1 y la 2. La versión 1 dejó de estar disponible, y los requisitos del CDD para dispositivos que se inician con Android 11 y versiones posteriores solo son compatibles con la versión 2. Las políticas de encriptación de la versión 2 usan HKDF-SHA512 para derivar las claves de encriptación reales de las claves proporcionadas por el espacio de usuario.

Para obtener más información sobre fscrypt, consulta la documentación del kernel upstream.

Clases de almacenamiento

En la siguiente tabla, se enumeran las claves de FBE y los directorios que protegen con más detalle:

Clase de almacenamiento Descripción Directorios
Sin encriptación Directorios en /data que no se pueden proteger con FBE o que no es necesario que se protejan con FBE En los dispositivos que usan encriptación de metadatos, estos directorios no están realmente desencriptados, sino que están protegidos por la clave de encriptación de metadatos, que es equivalente a la DE del sistema.
  • /data/apex, excepto /data/apex/decompressed y /data/apex/ota_reserved, que son DE del sistema
  • /data/lost+found
  • /data/preloads
  • /data/unencrypted
  • Todos los directorios cuyos subdirectorios usan diferentes claves de FBE Por ejemplo, como cada directorio /data/user/${user_id} usa una clave por usuario, /data/user no usa ninguna clave.
DE del sistema Datos encriptados por el dispositivo que no están vinculados a un usuario en particular
  • /data/apex/decompressed
  • /data/apex/ota_reserved
  • /data/app
  • /data/misc
  • /data/system
  • /data/vendor
  • Todos los demás subdirectorios de /data que esta tabla no menciona como que tienen una clase diferente
Por inicio Archivos del sistema efímeros que no necesitan sobrevivir a un reinicio /data/per_boot
CE del usuario (interno) Datos encriptados por 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 encriptados por el 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}
CE del usuario (adoptable) Datos encriptados con credenciales por usuario en el almacenamiento adoptable
  • /mnt/expand/${volume_uuid}/media/${user_id}
  • /mnt/expand/${volume_uuid}/misc_ce/${user_id}
  • /mnt/expand/${volume_uuid}/user/${user_id}
DE del usuario (adoptable) Datos encriptados por el dispositivo por usuario en el 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 las almacena encriptadas en el disco, excepto la clave por inicio, que no se almacena. En la siguiente tabla, se enumeran las ubicaciones en las que se almacenan las diferentes claves de FBE:

Tipo de clave Ubicación de la clave Clase de almacenamiento de la ubicación de la clave
Clave de DE del sistema /data/unencrypted Sin encriptación
Claves de CE (internas) del usuario /data/misc/vold/user_keys/ce/${user_id} DE del sistema
Claves de DE (internas) del usuario /data/misc/vold/user_keys/de/${user_id} DE del sistema
Claves de CE (adoptables) del usuario /data/misc_ce/${user_id}/vold/volume_keys/${volume_uuid} CE del usuario (interno)
Claves de DE (adoptables) del usuario /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 con otra clave de FBE. Las claves no se pueden desbloquear hasta que se desbloquee la clase de almacenamiento que las contiene.

vold también aplica una capa de encriptación a todas las claves de FBE. Todas las claves, además de las claves de CE para el almacenamiento interno, se encriptan con AES-256-GCM con su propia clave de Keystore que no se expone fuera del TEE. Esto garantiza que las claves de FBE no se puedan desbloquear, a menos que se haya iniciado un sistema operativo de confianza, como lo aplica el inicio verificado. También se solicita la resistencia a la reversión en la clave del almacén de claves, lo que permite que las claves de FBE se borren de forma segura en dispositivos en los que Keymaster admite la resistencia a la reversión. Como resguardo de mejor esfuerzo para cuando la resistencia a la reversión no está disponible, el hash SHA-512 de 16384 bytes aleatorios almacenados en el archivo secdiscardable junto con la clave se usa como la etiqueta de ID de app de la clave de Keystore. Todos estos bytes deben recuperarse para recuperar una clave de FBE.

Las claves de CE para el almacenamiento interno reciben un nivel de protección más sólido que garantiza que no se puedan desbloquear sin conocer el factor de conocimiento de la pantalla bloqueada (LSKF) del usuario (PIN, patrón o contraseña), un token de restablecimiento de contraseña seguro o las claves del cliente y del servidor para una operación de reanudación al reiniciar. Solo se pueden crear tokens de restablecimiento de contraseña para perfiles de trabajo y dispositivos completamente administrados.

Para lograrlo, vold encripta cada clave de CE para el almacenamiento interno con una clave AES-256-GCM derivada de la contraseña sintética del usuario. La contraseña sintética es un secreto criptográfico de alta entropía inmutable que se genera de forma aleatoria 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 el LSKF, LockSettingsService primero estira el LSKF pasándolo a través de scrypt, con un tiempo de alrededor de 25 ms y un uso de memoria de alrededor de 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 el límite de frecuencia que se aplica con TEE, que se describe a continuación.

Si el dispositivo tiene un elemento seguro (SE), LockSettingsService asigna el LSKF estirado a un secreto aleatorio de alta entropía almacenado en el SE con el HAL de Weaver. Luego, LockSettingsService encripta la contraseña sintética dos veces: primero, con una clave de software derivada del LSKF estirado y el secreto de Weaver, y, segundo, con una clave de almacén de claves no vinculada a la autenticación. Esto proporciona un límite de frecuencia aplicado por SE de las conjeturas de LSKF.

Si el dispositivo no tiene un SE, LockSettingsService usa el LSKF estirado como una contraseña de Gatekeeper. Luego, LockSettingsService encripta la contraseña sintética dos veces: primero, con una clave de software derivada del LSKF estirado y el hash de un archivo secdiscardable, y, segundo, con una clave de almacén de claves que está vinculada a la autenticación de la inscripción de Gatekeeper. Esto proporciona un límite de frecuencia aplicado por TEE de las conjeturas de LSKF.

Cuando se cambia el LSKF, LockSettingsService borra toda la información asociada con la vinculación de la contraseña sintética al LSKF anterior. En los dispositivos que admiten claves de Keystore resistentes a Weaver o reversiones, esto garantiza la eliminación segura de la vinculación anterior. Por este motivo, las protecciones que se describen aquí se aplican incluso cuando el usuario no tiene un LSKF.