Authentication

Android usa el concepto de claves criptográficas controladas por la autenticación del usuario que requiere los siguientes componentes:

  • Proveedor de servicios y almacenamiento de claves criptográficas. Almacena claves criptográficas y proporciona rutinas de criptografía estándar sobre esas claves. Android admite un almacén de claves con respaldo de hardware y Keymaster para servicios criptográficos, incluida la criptografía con respaldo de hardware para el almacenamiento de claves que puede incluir un entorno de ejecución confiable (TEE) o un elemento seguro (SE), como Strongbox.
  • Autenticadores de usuarios. Certificar la presencia del usuario o la autenticación correcta Android admite Gatekeeper para la autenticación con PIN, patrón o contraseña, y Fingerprint para la autenticación con huellas dactilares. Los dispositivos que se envían con Android 9 y versiones posteriores pueden usar BiometricPrompt como un único punto de integración para huellas dactilares y datos biométricos adicionales. Estos componentes comunican su estado de autenticación con el servicio de almacén de claves a través de un canal autenticado. (El sistema Android Keystore a nivel del framework también está respaldado por el servicio de almacén de claves).

Los componentes de Gatekeeper, Fingerprint y Biometric funcionan con Keystore y otros componentes para admitir el uso de tokens de autenticación (AuthTokens) respaldados por hardware.

Inscripción

En el primer inicio del dispositivo después de un restablecimiento de la configuración de fábrica, todos los autenticadores están preparados para recibir inscripciones de credenciales del usuario. En un principio, un usuario debe inscribir un PIN, un patrón o una contraseña con Gatekeeper. Esta inscripción inicial crea un identificador seguro (SID) de usuario de 64 bits generado de forma aleatoria que sirve como identificador para el usuario y como token de vinculación para su material criptográfico. Este SID del usuario está vinculado criptográficamente a su contraseña. Las autenticaciones correctas en Gatekeeper generan AuthTokens que contienen el SID del usuario de esa contraseña.

Un usuario que quiera cambiar una credencial debe presentar una credencial existente. Si se verifica correctamente una credencial existente, el SID del usuario asociado con la credencial existente se transfiere a la credencial nueva, lo que le permite al usuario seguir accediendo a las claves después de cambiar una credencial. Si un usuario no presenta una credencial existente, la credencial nueva se inscribe con un SID de usuario completamente aleatorio. El usuario puede acceder al dispositivo, pero las claves creadas con el SID del usuario anterior se pierden de forma permanente. Esto se conoce como inscripción no confiable.

En circunstancias normales, el framework de Android no permite una inscripción no confiable, por lo que la mayoría de los usuarios nunca verán esta funcionalidad. Sin embargo, los restablecimientos de contraseña forzosos, ya sea por parte de un administrador del dispositivo o de un atacante, pueden provocar que esto suceda.

Autenticación

Después de que un usuario configura una credencial y recibe un SID de usuario, puede iniciar la autenticación, que comienza cuando un usuario proporciona un PIN, un patrón, una contraseña o una huella dactilar. Todos los componentes del TEE comparten una clave secreta que usan para autenticar los mensajes de los demás.

Flujo de autenticación
Figura 1: Flujo de autenticación
  1. Un usuario proporciona un método de autenticación y el servicio asociado realiza una solicitud al daemon asociado.
    • Para el PIN, el patrón o la contraseña, LockSettingsService hace una solicitud a gatekeeperd.
    • Los flujos de autenticación basados en biometría dependen de la versión de Android. En dispositivos que ejecutan Android 8.x y versiones anteriores, FingerprintService realiza una solicitud a fingerprintd. En dispositivos que ejecutan Android 9 y versiones posteriores, BiometricPrompt realiza una solicitud al daemon biométrico apropiado (por ejemplo, fingerprintd para huellas dactilares o faced para rostro) con la clase BiometricManager adecuada, como FingerprintManager o FaceManager. Independientemente de la versión, la autenticación biométrica se realiza de forma asíncrona después de que se envía la solicitud.
  2. El daemon envía datos a su contraparte, que genera un AuthToken:
    • Para la autenticación de PIN, patrón o contraseña, gatekeeperd envía el hash de PIN, patrón o contraseña a Gatekeeper en el TEE. Si la autenticación en el TEE se realiza correctamente, el gatekeeper en el TEE envía un AuthToken que contiene el SID del usuario correspondiente (firmado con la clave HMAC de AuthToken) a su contraparte en el SO Android.
    • Para la autenticación con huellas dactilares, fingerprintd escucha los eventos de huellas dactilares y envía los datos a Fingerprint en el TEE. Si la autenticación en el TEE se realiza correctamente, la huella digital en el TEE envía un AuthToken (firmado con la clave HMAC de AuthToken) a su contraparte en el SO Android.
    • Para otras autenticaciones biométricas, el daemon de biometría correspondiente escucha el evento biométrico y lo envía al componente TEE biométrico correspondiente.
  3. El daemon recibe un AuthToken firmado y lo pasa al servicio de almacén de claves a través de una extensión de la interfaz de Binder del servicio de almacén de claves. (gatekeeperd también notifica al servicio de almacén de claves cuando se vuelve a bloquear el dispositivo y cuando cambia la contraseña del dispositivo).
  4. El servicio de almacén de claves pasa los AuthTokens a Keymaster y los verifica con la clave compartida con el gatekeeper y el componente TEE biométrico compatible. Keymaster confía en la marca de tiempo del token como el último tiempo de autenticación y basa una decisión de lanzamiento de clave (para permitir que una app use la clave) en la marca de tiempo.

Formato de AuthToken

Para garantizar el uso compartido de tokens y la compatibilidad entre idiomas y componentes, el formato AuthToken se describe en hw_auth_token.h. El formato es un protocolo de serialización simple con campos de tamaño fijo.

Campo Tipo Obligatorio Descripción
Versión de AuthToken 1 byte Etiqueta de grupo para todos los campos que se indican a continuación.
Desafío Número entero de 64 bits sin firma No Un número entero aleatorio para evitar ataques de reinyección. Por lo general, es el ID de una operación criptográfica solicitada. Actualmente, lo usan las autorizaciones de huellas dactilares de transacciones. Si está presente, AuthToken solo es válido para las operaciones de criptografía que contienen el mismo desafío.
SID del usuario Número entero de 64 bits sin firma Es un identificador de usuario no repetitivo vinculado criptográficamente a todas las claves asociadas con la autenticación del dispositivo. Para obtener más información, consulta Gatekeeper.
ID del autenticador (ASID) Número entero de 64 bits sin firma en orden de red No Es el identificador que se usa para vincularse a una política de autenticador específica. Todos los autenticadores tienen su propio valor de ASID que pueden cambiar según sus propios requisitos.
Tipo de autenticador Número entero de 32 bits sin firma en orden de red
  • 0x00 es Gatekeeper.
  • 0x01 es la huella digital.
Marca de tiempo Número entero de 64 bits sin firma en orden de red Es el tiempo (en milisegundos) desde el inicio del sistema más reciente.
HMAC de AuthToken (SHA-256) BLOB de 256 bits MAC SHA-256 con clave de todos los campos, excepto el campo HMAC

Flujo de inicio del dispositivo

Cada vez que se inicia un dispositivo, se debe generar la clave HMAC de AuthToken y compartirla con todos los componentes de TEE (Gatekeeper, Keymaster y los trustlets de biometría compatibles). Por lo tanto, para obtener mayor protección contra los ataques de repetición, la clave HMAC debe generarse de forma aleatoria cada vez que se reinicia el dispositivo.

El protocolo para compartir esta clave HMAC con todos los componentes es una función de implementación que depende de la plataforma. La clave nunca debe estar disponible fuera del TEE. Si un SO TEE carece de un mecanismo de comunicación interprocesos (IPC) interno y necesita transferir los datos a través del SO no confiable, la transferencia se debe realizar a través de un protocolo de intercambio de claves seguro.

El sistema operativo Trusty, que se ejecuta junto con Android, es un ejemplo de un TEE, pero se pueden usar otros TEE en su lugar. Trusty usa un sistema IPC interno para comunicarse directamente entre Keymaster y Gatekeeper, o el trustlet biométrico adecuado. La clave HMAC se mantiene solo en Keymaster. Fingerprint y Gatekeeper solicitan la clave a Keymaster para cada uso y no conservan ni almacenan en caché el valor.

Como algunos TEE carecen de una infraestructura de IPC, no se produce ninguna comunicación entre las applets en el TEE. Esto también permite que el servicio de almacén de claves rechace rápidamente las solicitudes que están destinadas a fallar, ya que tiene conocimiento de la tabla de autenticación en el sistema, lo que ahorra un IPC potencialmente costoso en el TEE.