Estoy citando el Manual de Android aquí , pero:
NOTA:
La fuente que he usado no es directamente relevante para Marshmallow pero es relevante para Lollipop y superior.
TL: DR
Solo abordaré las preguntas del OP ahora. Los detalles técnicos seguirán.
La clave de cifrado predeterminada proviene de una fuente de hardware (un chip similar a un TPM) y la contraseña predeterminada de AOSP definida como default_passworden el cryptfs.carchivo fuente, ver más abajo.
Sí, no solo el valor predeterminado, sino que cualquier contraseña se convierte en una clave y se almacena en un chip similar a TPM, llamado TEE (abreviatura de "Entorno de ejecución de confianza", consulte a continuación para obtener más detalles).
Un pirata informático con acceso UART / JTAG a los chips en el SoC del dispositivo técnicamente podría obtener acceso a la clave TEE, o un núcleo personalizado puede filtrar esta información a un pirata informático. Algunas agencias de 3 letras en teorías de conspiración posiblemente se pueden asociar con el OEM para hacer que estos núcleos inseguros se utilicen en dispositivos de producción, pero no dejaría muchas tiendas. Nuevamente, vea la última sección de esta respuesta para más detalles.
Lo único que impide que un pirata informático tenga acceso a la clave es la gran cantidad de esfuerzo necesario para hacerlo.
- De hecho, la comprobación del hash (suma de comprobación) del firmware (llamado "arranque verificado" por Google) se realiza en Lollipop y por encima (por defecto, y está disponible desde JellyBean 4.3 en adelante), mediante un módulo del núcleo llamado
dm-verity. Sin embargo, esto es independiente del estado de cifrado.
Fuente: guía de seguridad de AOSP aquí .
- Sobre el proceso involucrado en descifrar el sistema con una contraseña personalizada, consulte a continuación. Te diré aquí que la contraseña del usuario está involucrada tanto en la creación como en el uso de la clave de cifrado.
Visión general
En el primer arranque, el dispositivo crea una clave maestra de 128 bits generada aleatoriamente y luego la codifica con una contraseña predeterminada y sal almacenada. La contraseña predeterminada es: "default_password". Sin embargo, el hash resultante también se firma a través de un TEE (como TrustZone), que utiliza un hash de la firma para cifrar la clave maestra.
Puede encontrar la contraseña predeterminada definida en el archivo cryptfs.c de Android Open Source Project .
Cuando el usuario establece el PIN / pase o contraseña en el dispositivo, solo la clave de 128 bits se vuelve a cifrar y se almacena. (es decir, los cambios de PIN / pase / patrón de usuario NO provocan el encriptado de la partición de datos de usuario).
Iniciar un dispositivo cifrado con cifrado predeterminado
Esto es lo que sucede cuando inicia un dispositivo encriptado sin contraseña. Debido a que los dispositivos Android 5.0 se cifran en el primer inicio, no debe haber una contraseña establecida y, por lo tanto, este es el estado de cifrado predeterminado.
- Detecta datos cifrados sin contraseña
Detecta que el dispositivo Android está encriptado porque / datos no se pueden montar y uno de los indicadores encryptableo forceencryptestá configurado.
voldse establece vold.decrypten trigger_default_encryption, que inicia el defaultcryptoservicio. trigger_default_encryptioncomprueba el tipo de cifrado para ver si / data está cifrado con o sin contraseña.
- Descifrar / datos
Crea el dm-cryptdispositivo sobre el dispositivo de bloque para que esté listo para usar.
- Montaje / datos
voldluego monta la partición descifrada real / datos y luego prepara la nueva partición. Establece la propiedad vold.post_fs_data_doneen 0y luego establece vold.decrypten trigger_post_fs_data. Esto hace init.rcque ejecute sus post-fs-datacomandos. Crearán los directorios o enlaces necesarios y luego se establecerán vold.post_fs_data_doneen 1.
Una vez que voldve el 1 de esa propiedad, que establece la propiedad vold.decrypta: trigger_restart_framework. Esto hace init.rcque los servicios se inicien mainnuevamente en clase y que también se inicien en clase late_start por primera vez desde el arranque.
- Iniciar marco
Ahora, el marco inicia todos sus servicios utilizando el descifrado / datos, y el sistema está listo para usar.
Iniciar un dispositivo cifrado sin cifrado predeterminado
Esto es lo que sucede cuando inicia un dispositivo cifrado que tiene una contraseña establecida. La contraseña del dispositivo puede ser un pin, patrón o contraseña.
- Detectar dispositivo cifrado con una contraseña
Detecta que el dispositivo Android está encriptado porque la bandera ro.crypto.state = "encrypted"
voldse establece vold.decrypten trigger_restart_min_frameworkporque / data se cifra con una contraseña.
- Monte tmpfs
initestablece cinco propiedades para guardar las opciones de montaje iniciales dadas para / datos con parámetros pasados desde init.rc. voldusa estas propiedades para configurar el mapeo criptográfico:
ro.crypto.fs_type
ro.crypto.fs_real_blkdev
ro.crypto.fs_mnt_point
ro.crypto.fs_options
ro.crypto.fs_flags (Número hexadecimal ASCII de 8 dígitos precedido por 0x)
- Inicie el marco para solicitar la contraseña
El marco se inicia y ve que vold.decryptestá configurado en trigger_restart_min_framework. Esto le dice al framework que se está iniciando en un tmpfs /datadisco y que necesita obtener la contraseña del usuario.
Primero, sin embargo, debe asegurarse de que el disco esté encriptado correctamente. Envía el comando cryptfs cryptocompletea vold. volddevuelve 0 si el cifrado se completó con éxito, -1 en caso de error interno o -2 si el cifrado no se completó con éxito. volddetermina esto buscando en la metadata de cifrado la CRYPTO_ENCRYPTION_IN_PROGRESSbandera. Si está configurado, el proceso de cifrado se interrumpió y no hay datos utilizables en el dispositivo.
Si volddevuelve un error, la interfaz de usuario debe mostrar un mensaje al usuario para reiniciar y restablecer de fábrica el dispositivo, y darle al usuario un botón para presionar para hacerlo.
- Descifrar datos con contraseña
Una vez que cryptfs cryptocompletetiene éxito, el marco muestra una IU que solicita la contraseña del disco. La IU verifica la contraseña enviando el comando cryptfs checkpwa vold. Si la contraseña es correcta (que se determina al montar con éxito el descifrado /dataen una ubicación temporal y luego desmontarlo), vold guarda el nombre del dispositivo de bloque descifrado en la propiedad ro.crypto.fs_crypto_blkdevy devuelve el estado 0 a la IU. Si la contraseña es incorrecta, devuelve -1 a la IU.
- Stop framework
La interfaz de usuario muestra un gráfico de arranque criptográfico y luego llama a vold con el comando cryptfs restart. voldestablece la propiedad vold.decrypten trigger_reset_main, lo que hace init.rcque lo haga class_reset main. Esto detiene todos los servicios de la mainclase, lo que permite tmpfs /datadesmontarlos.
- Montaje / datos
voldluego monta la /datapartición real descifrada y prepara la nueva partición (que tal vez nunca se haya preparado si estaba encriptada con la opción de borrado, que no es compatible con la primera versión). Establece la propiedad vold.post_fs_data_doneen 0y luego establece vold.decrypten trigger_post_fs_data. Esto hace init.rcque se ejecute su post-fs-data commands. Crearán los directorios o enlaces necesarios y luego se establecerán vold.post_fs_data_doneen 1. Una vez que voldve el 1en esa propiedad, establece la propiedad vold.decrypten trigger_restart_framework. Esto hace init.rcque los servicios se inicien mainnuevamente en clase y que también se inicien en clase late_startpor primera vez desde el inicio.
- Iniciar marco completo
Ahora, el marco inicia todos sus servicios utilizando el sistema de archivos descifrado / datos, y el sistema está listo para su uso.
Almacenar la clave encriptada
La clave cifrada se almacena en los metadatos criptográficos. El respaldo de hardware se implementa utilizando la capacidad de firma de Trusted Execution Environment (TEE). Anteriormente, ciframos la clave maestra con una clave generada aplicando scryptla contraseña del usuario y la sal almacenada.
Para que la clave sea resistente a los ataques fuera de la caja, ampliamos este algoritmo firmando la clave resultante con una clave TEE almacenada. La firma resultante se convierte en una clave de longitud apropiada por una aplicación más de scrypt. Esta clave se usa para cifrar y descifrar la clave maestra. Para almacenar esta clave:
- Genere clave de cifrado de disco aleatorio de 16 bytes (DEK) y sal de 16 bytes.
- Aplique
scrypta la contraseña de usuario y la sal para producir la clave intermedia de 32 bytes 1 (IK1).
- Rellene IK1 con cero bytes al tamaño de la clave privada vinculada al hardware (HBK). Específicamente, rellenamos como: 00 || IK1 || 00..00; un byte cero, 32 bytes IK1, 223 bytes cero.
- Firme IK1 acolchado con HBK para producir IK2 de 256 bytes.
- Aplique
scrypta IK2 y sal (la misma sal que en el paso 2) para producir IK3 de 32 bytes.
- Use los primeros 16 bytes de IK3 como KEK y los últimos 16 bytes como IV.
- Cifre DEK con AES_CBC, con la clave KEK y el vector de inicialización IV.