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_password
en el cryptfs.c
archivo 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 encryptable
o forceencrypt
está configurado.
vold
se establece vold.decrypt
en trigger_default_encryption
, que inicia el defaultcrypto
servicio. trigger_default_encryption
comprueba el tipo de cifrado para ver si / data está cifrado con o sin contraseña.
- Descifrar / datos
Crea el dm-crypt
dispositivo sobre el dispositivo de bloque para que esté listo para usar.
- Montaje / datos
vold
luego monta la partición descifrada real / datos y luego prepara la nueva partición. Establece la propiedad vold.post_fs_data_done
en 0
y luego establece vold.decrypt
en trigger_post_fs_data
. Esto hace init.rc
que ejecute sus post-fs-data
comandos. Crearán los directorios o enlaces necesarios y luego se establecerán vold.post_fs_data_done
en 1
.
Una vez que vold
ve el 1 de esa propiedad, que establece la propiedad vold.decrypt
a: trigger_restart_framework
. Esto hace init.rc
que los servicios se inicien main
nuevamente 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"
vold
se establece vold.decrypt
en trigger_restart_min_framework
porque / data se cifra con una contraseña.
- Monte tmpfs
init
establece cinco propiedades para guardar las opciones de montaje iniciales dadas para / datos con parámetros pasados desde init.rc
. vold
usa 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.decrypt
está configurado en trigger_restart_min_framework
. Esto le dice al framework que se está iniciando en un tmpfs /data
disco 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 cryptocomplete
a vold
. vold
devuelve 0 si el cifrado se completó con éxito, -1 en caso de error interno o -2 si el cifrado no se completó con éxito. vold
determina esto buscando en la metadata de cifrado la CRYPTO_ENCRYPTION_IN_PROGRESS
bandera. Si está configurado, el proceso de cifrado se interrumpió y no hay datos utilizables en el dispositivo.
Si vold
devuelve 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 cryptocomplete
tiene éxito, el marco muestra una IU que solicita la contraseña del disco. La IU verifica la contraseña enviando el comando cryptfs checkpw
a vold
. Si la contraseña es correcta (que se determina al montar con éxito el descifrado /data
en una ubicación temporal y luego desmontarlo), vold guarda el nombre del dispositivo de bloque descifrado en la propiedad ro.crypto.fs_crypto_blkdev
y 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
. vold
establece la propiedad vold.decrypt
en trigger_reset_main
, lo que hace init.rc
que lo haga class_reset main
. Esto detiene todos los servicios de la main
clase, lo que permite tmpfs /data
desmontarlos.
- Montaje / datos
vold
luego monta la /data
partició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_done
en 0
y luego establece vold.decrypt
en trigger_post_fs_data
. Esto hace init.rc
que se ejecute su post-fs-data commands
. Crearán los directorios o enlaces necesarios y luego se establecerán vold.post_fs_data_done
en 1
. Una vez que vold
ve el 1
en esa propiedad, establece la propiedad vold.decrypt
en trigger_restart_framework
. Esto hace init.rc
que los servicios se inicien main
nuevamente en clase y que también se inicien en clase late_start
por 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 scrypt
la 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
scrypt
a 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
scrypt
a 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.