Encriptación basada en archivos

Android 7.0 y versiones posteriores son compatibles con la encriptación basada en archivos (FBE). La encriptación basada en archivos permite encriptar diferentes archivos con distintas 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 inicio directo para ofrecer a los usuarios la mejor experiencia y segura posible.

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

Inicio directo

La encriptación basada en archivos habilita una función nueva que se introdujo en Android 7.0, llamada inicio directo. El inicio directo 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 podían funcionar, los servicios de accesibilidad no estaban disponibles y los teléfonos no podían recibir llamadas, pero se limitaron solo a las operaciones básicas del marcador de emergencia.

Con la introducción de la encriptación basada en archivos (FBE) y las nuevas APIs para que las apps estén al tanto de la encriptación, estas apps pueden funcionar dentro de un contexto limitado. Esto puede suceder 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 proteger a más de un usuario a la vez, ya que la encriptación ya no se basa solo en una contraseña de tiempo de inicio.

La API de inicio directo permite que las apps con reconocimiento de encriptación accedan a cada una de estas áreas. Existen cambios en el ciclo de vida de la app para adaptarse a la necesidad de notificar a las apps cuando el almacenamiento 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 proporcione una desafío de trabajo. Los dispositivos que ejecutan Android 7.0 deben admitir estas APIs y estos ciclos de vida nuevos independientemente de si implementan o no el FBE. Sin embargo, sin FBE, el almacenamiento de DE y CE siempre está en estado desbloqueado.

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 los dispositivos que cumplan con los requisitos. Los fabricantes que eligen usar el FBE pueden explorar formas de optimizar la función según el sistema en chip (SoC) usado.

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, quieren asegurarse de que haya, como mínimo, 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 capacidades de encriptación basadas en archivos en el kernel, muchos paquetes del sistema, incluidas la pantalla de bloqueo y la SystemUI, se modificaron para admitir las funciones de inicio directo y FBE. Por ejemplo:

  • Teléfono del AOSP (paquetes/apps/Teléfono)
  • Reloj de escritorio (paquetes/apps/Reloj de escritorio)
  • LatinIME (packages/inputmethods/LatinIME)*
  • App de Configuración (paquetes/apps/configuración)*
  • SystemUI (frameworks/base/packages/SystemUI)*

* Apps del sistema que usan el atributo del manifiesto defaultToDeviceProtectedStorage

Puedes encontrar más ejemplos de apps y servicios con reconocimiento de encriptación ejecutando 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 de kernel para la encriptación Ext4 y F2FS está disponible en los kernels comunes de Android, versión 3.18 y posteriores. Para habilitarlo en un kernel de la versión 5.1 o posterior, usa lo siguiente:

CONFIG_FS_ENCRYPTION=y

En el caso de 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 el almacenamiento adoptable o usa la 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 posteriores) contienen un framework que permite usar la encriptación intercalada cuando está disponible el hardware y los controladores del proveedor. 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, también habilita lo siguiente:

CONFIG_MMC_CRYPTO=y

Habilitar 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 de los archivos. Puede ser aes-256-xts o adiantum. Como Android 11, también puede dejarse vacío 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 y 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 determina ro.product.first_api_level) o v1 si el dispositivo se inició en Android 10 o versiones anteriores.
    • La marca inlinecrypt_optimized selecciona un formato de encriptación que está optimizado para el hardware de encriptación intercalado que no controla grandes cantidades de claves de manera eficiente. Para ello, obtiene una sola clave de encriptación 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.
    • 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 intercalada que cumpla con la especificación JEDEC eMMC v5.2 y, por lo tanto, solo admite IV de 32 bits. En otro hardware de encriptación intercalada, usa inlinecrypt_optimized. Esta marca nunca debe usarse en el almacenamiento basado en UFS; la especificación de UFS permite el uso de IV 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 obliga a que el tamaño de la unidad de datos de encriptación sea 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 a partir de Android 15. Esta marca solo debe usarse para habilitar el uso de hardware de encriptación intercalada que no admite unidades de datos de más de 4, 096 bytes en un dispositivo que usa un tamaño de página superior a 4096 bytes y que utiliza 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.

A partir de Android 14, AES-HCTR2 es el modo preferido de encriptación de nombres de archivo 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 configurando 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 de 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 disco producido por este modo era específico del proveedor. En dispositivos que se lanzan 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 del archivo 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 de forma automática el FBE y la encriptación de metadatos en el almacenamiento adoptable. Sin embargo, puedes anular los formatos de encriptación de metadatos o FBE en el almacenamiento adoptable si configuras las propiedades en PRODUCT_PROPERTY_OVERRIDES.

En los 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 los 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 dispositivos que se iniciaron con Android 10 o versiones anteriores es aes-256-heh. En la mayoría de los dispositivos, se debe anular explícitamente como 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 de encriptación de metadatos.

Cómo realizar la integración con Keymaster

La HAL de Keymaster debe iniciarse como parte de la clase early_hal. Esto se debe a que el 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 necesiten 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 compatibilidad con 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 los usuarios.

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

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

El atributo defaultToDeviceProtectedStorage redirecciona la ubicación predeterminada del almacenamiento de la app para que apunte al almacenamiento DE, en lugar de apuntar al 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()

Admitir 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 primero al dispositivo, 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 directorios con encriptación CE para 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 debería verificar este estado antes de intentar acceder a esas á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 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 OTA se puede aplicar durante el funcionamiento normal, no es necesario que la recuperación acceda 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 a 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 numerosas pruebas de encriptación del 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 de Automotive), 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 enumerados estén codificados en Base64, lo que indica que los nombres de archivo 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 del AOSP

En esta sección, se proporcionan detalles sobre la implementación de AOSP y se describe el funcionamiento de la encriptación basada en archivos. No debería ser necesario que los fabricantes de dispositivos realicen ningún cambio aquí para usar el 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 la encriptación Adiantum está habilitada, tanto el contenido como los nombres de los archivos se encriptan con Adiantum.

fscrypt admite dos versiones de políticas de encriptación: versión 1 y versión 2. La versión 1 dejó de estar disponible, y los requisitos del CDD para dispositivos que se lanzan 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 muestran con más detalle las claves de FBE y los directorios que protegen:

Clase de almacenamiento Descripción Directorios
Sin encriptación Directorios de /data que no pueden o no necesitan estar protegidos por FBE. En los dispositivos que usan encriptación de metadatos, estos directorios no están encriptados, sino que están protegidos por la clave de encriptación de metadatos, que es equivalente a System DE.
  • /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 claves FBE diferentes. Por ejemplo, como cada directorio /data/user/${user_id} usa una clave por usuario, /data/user no usa ninguna clave en sí.
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 del dispositivo encriptados 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
Tecla DE del sistema /data/unencrypted Sin encriptación
Claves CE (internas) del usuario /data/misc/vold/user_keys/ce/${user_id} Sistema DE
Claves DE (internas) del usuario /data/misc/vold/user_keys/de/${user_id} Sistema DE
Claves de CE del usuario (adoptable) /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 haya desbloqueado la clase de almacenamiento que las contiene.

vold también aplica una capa de encriptación a todas las claves de FBE. Cada clave, excepto las claves CE para el almacenamiento interno, se encripta con AES-256-GCM con su propia clave de Keystore que no está expuesta 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 del FBE se borren de forma segura en los 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. Se deben recuperar todos estos bytes 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 inmutable de alta entropía que se genera de forma aleatoria para cada usuario. LockSettingsService en system_server administra la contraseña sintética y las formas en que está protegida.

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 proporciona 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 extendido a un secreto aleatorio de alta entropía almacenado en el SE mediante la HAL de Weaver. Luego, LockSettingsService encripta la contraseña sintética dos veces: primero con una clave de software derivada del LSKF extendido y el secreto de Weaver, y, luego, con una clave del 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 extendido y el hash de un archivo que se puede desconectar, y, luego, con una clave del almacén de claves que está vinculada de autenticación a la inscripción de Gatekeeper. Esto proporciona un límite de frecuencia aplicado por el TEE de las suposiciones 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.