Android 7.0 y versiones posteriores admiten la encriptación basada en archivos (FBE). La encriptación basada en archivos permite que diferentes archivos se encripten con diferentes claves que se pueden desbloquear de forma independiente.
En este artículo, se describe cómo habilitar el cifrado basado 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 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 introducida 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 la encriptación de disco completo (FDE), los usuarios debían proporcionar credenciales antes de poder acceder a cualquier dato, 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, sino que se limitaban 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 conozcan la encriptación, es posible que estas apps operen dentro de un contexto limitado. Esto puede ocurrir antes de que los usuarios proporcionen sus credenciales y, al mismo tiempo, proteger la información privada del usuario.
En un dispositivo habilitado para FBE, cada usuario del dispositivo tiene dos ubicaciones de almacenamiento disponibles para las apps:
- Almacenamiento encriptado con 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 únicamente en una contraseña de tiempo de arranque.
La API de Direct Boot permite que las apps con reconocimiento de encriptación accedan a cada una de estas áreas. Se realizaron cambios en el ciclo de vida de la app para satisfacer la necesidad de notificar a las apps cuando el almacenamiento de CE de un usuario se desbloquea en respuesta al primer ingreso de credenciales en la pantalla de bloqueo o, en el caso del perfil de trabajo, cuando se proporciona un desafío laboral. Los dispositivos que ejecutan Android 7.0 deben admitir estas nuevas APIs y ciclos de vida, independientemente de si implementan o no el FBE. Sin embargo, sin FBE, el almacenamiento 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 debe habilitarse en los dispositivos que cumplen con los requisitos. Los fabricantes que eligen usar FBE pueden explorar formas de optimizar la función según el sistema en chip (SoC) que se utilice.
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, 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 incorporación de FBE proporciona a vold varios comandos nuevos para admitir la administración de claves para las claves 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, se modificaron muchos paquetes del sistema, como la pantalla de bloqueo y SystemUI, para admitir las funciones de FBE y Direct Boot. 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 de manifiesto defaultToDeviceProtectedStorage
Para ver más ejemplos de apps y servicios que tienen en cuenta el cifrado, ejecuta el comando mangrep directBootAware
en el directorio de frameworks o paquetes del árbol de fuentes de AOSP.
Dependencias
Para usar de forma segura la implementación de FBE del AOSP, un dispositivo debe cumplir con las siguientes dependencias:
- Compatibilidad del kernel con la encriptación Ext4 o F2FS
- Compatibilidad con KeyMint (o Keymaster 1.0 o versiones posteriores) No se admite Keymaster 0.3, ya que no proporciona las capacidades necesarias ni garantiza la protección suficiente para las claves de encriptación.
- KeyMint/Keymaster y Gatekeeper se deben implementar en un entorno de ejecución confiable (TEE) para proteger las claves de DE, de modo que un SO no autorizado (SO personalizado instalado en el dispositivo) no pueda solicitar las claves de DE.
- Se requiere una raíz de confianza de hardware y un inicio verificado vinculados a la inicialización de KeyMint para garantizar que un sistema operativo no autorizado no pueda acceder a las claves de DE.
Implementación
En primer lugar, las apps como los relojes con alarma, el teléfono y las funciones de accesibilidad deben configurarse como android:directBootAware según la documentación para desarrolladores de Direct Boot.
Compatibilidad con kernel
La compatibilidad del kernel con el cifrado 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 el siguiente comando:
CONFIG_FS_ENCRYPTION=y
En el caso de los 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 adaptable o usa la encriptación de metadatos en el almacenamiento interno, también debes habilitar las opciones de configuración del kernel necesarias para la encriptación de metadatos, como se describe en la documentación sobre la encriptación de metadatos.
Además de la compatibilidad funcional con el cifrado Ext4 o F2FS, los fabricantes de dispositivos también deben 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, se puede habilitar la aceleración de ARMv8 CE (extensiones de criptografía) configurando las siguientes opciones 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 en línea, que encripta y desencripta los datos mientras se transfieren hacia y 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 en línea cuando hay compatibilidad con el hardware y el controlador del proveedor. Para habilitar el framework de encriptación intercalada, establece 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
Habilita la encriptación basada en archivos
Para habilitar el FBE en un dispositivo, debes habilitarlo en el almacenamiento interno (userdata
). Esto también habilita automáticamente el FBE en el almacenamiento adaptable. Sin embargo, el formato de encriptación en el almacenamiento adaptable 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 seraes-256-xts
oadiantum
. Desde Android 11, también se puede dejar vacío para especificar el algoritmo predeterminado, que esaes-256-xts
. - El parámetro
filenames_encryption_mode
define qué algoritmo criptográfico se usa para encriptar los nombres de los archivos. Puede seraes-256-cts
,aes-256-heh
,adiantum
oaes-256-hctr2
. Si no se especifica, el valor predeterminado esaes-256-cts
sicontents_encryption_mode
esaes-256-xts
, o bienadiantum
sicontents_encryption_mode
esadiantum
. - El parámetro
flags
, que es nuevo en Android 11, es una lista de marcas separadas por el carácter+
. Se admiten las siguientes marcas:- La marca
v1
selecciona políticas de encriptación de la versión 1, mientras que la marcav2
selecciona 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 lanzó con Android 11 o una versión posterior (según lo determinaro.product.first_api_level
) o v1 si el dispositivo se lanzó con Android 10 o una versión anterior. - La marca
inlinecrypt_optimized
selecciona un formato de encriptación optimizado para el hardware de encriptación intercalada que no controla grandes cantidades de claves de manera eficiente. Para ello, deriva solo una clave de encriptación de contenido de archivo por clave de CE o DE, en lugar de una por archivo. La generación de IV (vectores de inicialización) se ajusta según corresponda. - La marca
emmc_optimized
es similar ainlinecrypt_optimized
, pero también selecciona un método de generación de IV que limita los IV a 32 bits. Esta marca solo se debe usar en hardware de encriptación intercalada que cumpla con la especificación JEDEC eMMC v5.2 y, por lo tanto, solo admita IV de 32 bits. En otro hardware de encriptación intercalada, usainlinecrypt_optimized
. Esta marca nunca se debe usar en el almacenamiento basado en UFS, ya que la especificación de UFS permite el uso de IV de 64 bits. - En los dispositivos que admiten claves protegidas por hardware, la marca
wrappedkey_v0
habilita el uso de claves protegidas por hardware para el FBE. Solo se puede usar en combinación con la opción de montajeinlinecrypt
y la marcainlinecrypt_optimized
oemmc_optimized
. - La marca
dusize_4k
fuerza el tamaño de la unidad de datos de encriptación a 4096 bytes, incluso cuando el tamaño del bloque del sistema de archivos no es de 4096 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 se debe usar para habilitar el uso de hardware de encriptación intercalada que no admite unidades de datos mayores que 4,096 bytes en un dispositivo que usa un tamaño de página mayor que 4,096 bytes y que usa el sistema de archivos f2fs.
- La marca
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 intercalada, 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 forma equivalente). En los 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 archivos. Si tu kernel admite AES-HCTR2, puedes habilitarlo para la encriptación de nombres de archivos 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 los dispositivos que se lanzaron con Android 10 y versiones anteriores, también se acepta fileencryption=ice
para especificar el uso del modo de encriptación del contenido del archivo FSCRYPT_MODE_PRIVATE
. Los kernels comunes de Android no implementan este modo, pero los proveedores podrían hacerlo con parches de kernel personalizados. El formato en disco que producía este modo era específico del proveedor. En los dispositivos que se lanzan con Android 11 o versiones posteriores, este modo ya no está permitido 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, en cambio, quieres usar hardware de encriptación intercalada, agrega 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, se pueden usar juntos el FBE y el almacenamiento adaptable.
Si especificas la opción fileencryption
de fstab para userdata
, también se habilitarán automáticamente el FBE y el cifrado de metadatos en el almacenamiento adaptable. Sin embargo, puedes anular los formatos de encriptación de FBE o de metadatos en el almacenamiento adaptable 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ónfileencryption
de fstab y usa los mismos valores predeterminados. Consulta las recomendaciones parafileencryption
más arriba para saber qué usar aquí.ro.crypto.volume.metadata.encryption
selecciona el formato de encriptación de metadatos en el almacenamiento adaptable. Consulta la documentación sobre la encriptación de metadatos.
En los dispositivos que se lanzaron con Android 10 y versiones anteriores, usa las siguientes propiedades:
ro.crypto.volume.contents_mode
selecciona el modo de encriptación de contenido. Esto equivale al primer campo separado por dos puntos dero.crypto.volume.options
.ro.crypto.volume.filenames_mode
selecciona el modo de encriptación de nombres de archivos. Esto equivale al segundo campo separado por dos puntos dero.crypto.volume.options
, excepto que el valor predeterminado en los dispositivos que se lanzaron con Android 10 y versiones anteriores esaes-256-heh
. En la mayoría de los dispositivos, esto debe anularse explícitamente aaes-256-cts
.ro.crypto.fde_algorithm
yro.crypto.fde_sector_size
seleccionan el formato de encriptación de metadatos en el almacenamiento externo. Consulta la documentación sobre la encriptación de metadatos.
Integración con KeyMint
El HAL de KeyMint debe iniciarse como parte de la clase early_hal
.
Esto se debe a que FBE requiere que KeyMint esté listo para controlar solicitudes en la fase de arranque post-fs-data
, que es cuando vold
configura las claves iniciales.
Excluir directorios
init
aplica la clave DE del sistema a todos los directorios de nivel superior de /data
, excepto a los directorios que deben estar sin encriptar, como el directorio que contiene la clave DE del sistema y los directorios que contienen directorios CE o DE del usuario. Las claves de encriptación se aplican de forma recursiva y no se pueden anular en los subdirectorios.
En Android 11 y versiones posteriores, la clave que init
aplica a los directorios se puede controlar con el argumento encryption=<action>
del comando mkdir
en los secuencias de comandos de inicialización. Los valores posibles de <action>
se documentan en el README del lenguaje de inicialización de Android.
En Android 10, las acciones de encriptación de init
se codificaron de forma rígida 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 se encripten ciertos directorios. 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 no confiables.
El único caso de uso aceptable conocido para esto es el de la compatibilidad con las capacidades heredadas de OTA.
Compatibilidad con el inicio directo en apps del sistema
Haz que las apps admitan el inicio directo
Para facilitar la migración rápida de las apps del sistema, hay dos atributos nuevos que se pueden establecer 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 una abreviatura 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 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 usen 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 Context 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 en un entorno multiusuario obtiene una clave de encriptación independiente. Cada usuario obtiene dos claves: una de DE y otra de CE. El usuario 0 debe acceder al dispositivo primero, ya que es un usuario especial. Esto es pertinente para los usos de la administración de dispositivos.
Las apps compatibles con criptomonedas interactúan entre 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 con CE para los usuarios que ya están desbloqueados.
Es posible que una app pueda interactuar libremente en todas las áreas del DE, pero que un usuario desbloqueado no significa 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 obtiene dos claves: DE y CE. Cuando se cumple el desafío de trabajo, se desbloquea el usuario del perfil y KeyMint (en el TEE) puede proporcionar la clave del 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 userdata. Se recomienda que los dispositivos que implementen FBE admitan actualizaciones OTA con 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 de la unidad encriptada.
Cuando se usa una solución de OTA heredada, que requiere recuperación para acceder al archivo de OTA en la partición userdata
, haz lo siguiente:
- Crea un directorio de nivel superior (por ejemplo,
misc_ne
) en la particiónuserdata
. - Configura este directorio de nivel superior para que no esté encriptado (consulta Exclusión de directorios).
- Crea un directorio dentro del directorio de nivel superior para almacenar los paquetes de OTA.
- 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 deben poder leer y escribir en este directorio. Ninguna otra app o proceso debe 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, ejecuta también 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 habilitado, haz lo siguiente:
- Comprueba que exista
ro.crypto.state
.- Asegúrate de que
ro.crypto.state
esté encriptado
- Asegúrate de que
- Comprueba que exista
ro.crypto.type
.- Asegúrate de que
ro.crypto.type
esté configurado comofile
.
- Asegúrate de que
Además, los verificadores pueden comprobar que el almacenamiento de CE esté bloqueado antes de que se desbloquee el dispositivo por primera vez desde el arranque. Para ello, usa una compilación de 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 automóviles), el usuario principal es el usuario 10, por lo que debes ejecutar el siguiente comando:
adb root; adb shell ls /data/user/10
En otros dispositivos (la mayoría de los que no son para automóviles), el usuario principal es el usuario 0, por lo que debes ejecutar el siguiente comando:
adb root; adb shell ls /data/user/0
Verifica que los nombres de archivo que se indican 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 del AOSP y se describe cómo funciona la encriptación basada en archivos. Los fabricantes de dispositivos no deberían tener que realizar ningún cambio aquí para usar el FBE y el arranque 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 de la siguiente manera:
- Encripta el contenido del archivo con AES-256 en modo XTS
- Encripta los nombres de archivos con AES-256 en modo CBC-CTS
También se admite la encriptación Adiantum. Cuando se habilita la encriptación Adiantum, tanto el contenido como 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 versión 2. La versión 1 dejó de estar disponible, y los requisitos del CDD para los 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 del 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 no es necesario hacerlo. En los dispositivos que usan encriptación de metadatos, estos directorios no están realmente sin encriptar, sino que están protegidos por la clave de encriptación de metadatos, que es equivalente a la DE del sistema. |
|
Sistema DE | Datos encriptados en el dispositivo que no están vinculados a un usuario en particular |
|
Por inicio | Archivos del sistema efímeros que no necesitan sobrevivir a un reinicio | /data/per_boot |
CE del usuario (interno) | Datos encriptados con credenciales por usuario en el almacenamiento interno |
|
Usuario DE (interno) | Datos encriptados por dispositivo y por usuario en el almacenamiento interno |
|
CE del usuario (adoptable) | Datos encriptados con credenciales por usuario en el almacenamiento adaptable |
|
Usuario DE (adoptable) | Datos encriptados por dispositivo y por usuario en el almacenamiento externo |
|
Almacenamiento y protección de claves
vold
administra todas las claves de FBE, y estas se almacenan encriptadas en el disco, excepto la clave por inicio, que no se almacena en absoluto. En la siguiente tabla, se enumeran las ubicaciones en las que se almacenan las distintas claves de FBE:
Tipo de clave | Ubicación de la llave | Clase de almacenamiento de la ubicación de la clave |
---|---|---|
Clave de DE del sistema | /data/unencrypted |
Sin encriptación |
Claves de CE del usuario (internas) | /data/misc/vold/user_keys/ce/${user_id} |
Sistema DE |
Claves de DE del usuario (internas) | /data/misc/vold/user_keys/de/${user_id} |
Sistema DE |
Claves de CE del usuario (adoptables) | /data/misc_ce/${user_id}/vold/volume_keys/${volume_uuid} |
CE del usuario (interno) |
Llaves de DE del usuario (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 encriptados por 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, excepto las de CE para el almacenamiento interno, se encriptan con AES-256-GCM usando 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, según lo exige el inicio verificado. También se solicita 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 los dispositivos en los que KeyMint admite la resistencia a la reversión. Como alternativa de mejor esfuerzo cuando no hay resistencia a la reversión disponible, el hash SHA-512 de 16,384 bytes aleatorios almacenados en el archivo secdiscardable
que se almacena junto con la clave se usa como el Tag::APPLICATION_ID
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 bloqueo de pantalla (LSKF) del usuario (PIN, patrón o contraseña), un token de restablecimiento de código seguro o las claves del cliente y del servidor para una operación de reanudación tras el reinicio. Solo se pueden crear tokens de restablecimiento de contraseñas para perfiles de trabajo y dispositivos completamente administrados.
Para lograr esto, 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 se protege.
Para proteger la contraseña sintética con la LSKF, LockSettingsService
primero extiende la LSKF pasándola por scrypt
, con un tiempo objetivo de alrededor de 25 ms y un uso de memoria de alrededor de 2 MiB. Dado que las LSKF suelen ser cortas, este paso no suele proporcionar mucha seguridad. La capa principal de seguridad es el elemento seguro (SE) o la limitación de velocidad aplicada por el 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 con el HAL de Weaver. Luego, LockSettingsService
encripta la contraseña sintética dos veces: primero con una clave de software derivada de la LSKF extendida y el secreto de Weaver, y segundo con una clave de Keystore no vinculada a la autenticación. Esto proporciona un límite de frecuencia aplicado por SE para las suposiciones de LSKF.
Si el dispositivo no tiene un SE, LockSettingsService
usa la LSKF extendida como 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 descartable de seguridad, y segundo con una clave de Keystore que está vinculada por autenticación al registro de Gatekeeper. Esto proporciona un límite de frecuencia aplicado por el TEE para las suposiciones de LSKF.
Cuando se cambia la LSKF, LockSettingsService
borra toda la información asociada a la vinculación de la contraseña sintética con la LSKF anterior. En los dispositivos que admiten claves de Keystore resistentes a Weaver o a la reversión, 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 una LSKF.