Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.
Se usó la API de Cloud Translation para traducir esta página.
Switch to English

Almacén de claves respaldado por hardware

La disponibilidad de un entorno de ejecución confiable en un sistema en un chip (SoC) ofrece una oportunidad para que los dispositivos Android proporcionen servicios de seguridad sólidos y respaldados por hardware al sistema operativo Android, a los servicios de la plataforma e incluso a las aplicaciones de terceros. Los desarrolladores que buscan las extensiones específicas de Android deben ir a android.security.keystore .

Antes de Android 6.0, Android ya tenía una API de servicios de cifrado simple, respaldada por hardware, proporcionada por las versiones 0.2 y 0.3 de Keymaster Hardware Abstraction Layer (HAL). Keystore proporcionó operaciones de verificación y firma digital, además de la generación e importación de pares de claves de firma asimétrica. Esto ya está implementado en muchos dispositivos, pero hay muchos objetivos de seguridad que no se pueden lograr fácilmente con solo una API de firma. Keystore en Android 6.0 amplía la API de Keystore para proporcionar una gama más amplia de capacidades.

En Android 6.0, Keystore agregó primitivas criptográficas simétricas , AES y HMAC, y un sistema de control de acceso para claves respaldadas por hardware. Los controles de acceso se especifican durante la generación de la clave y se aplican durante la vida útil de la clave. Las claves se pueden restringir para que se puedan usar solo después de que el usuario se haya autenticado y solo para fines específicos o con parámetros criptográficos específicos. Para obtener más información, consulte las páginas de Funciones y etiquetas de autorización .

Además de ampliar la gama de primitivas criptográficas, Keystore en Android 6.0 agrega lo siguiente:

  • Un esquema de control de uso para permitir que el uso de claves sea limitado, para mitigar el riesgo de compromiso de seguridad debido al uso indebido de claves
  • Un esquema de control de acceso para permitir la restricción de claves a usuarios específicos, clientes y un rango de tiempo definido

En Android 7.0, Keymaster 2 agregó soporte para la certificación de claves y el enlace de versiones. La atestación de clave proporciona certificados de clave pública que contienen una descripción detallada de la clave y sus controles de acceso, para hacer que la existencia de la clave en hardware seguro y su configuración sea verificable de forma remota.

El enlace de versión vincula las claves al sistema operativo y la versión del nivel de parche. Esto asegura que un atacante que descubre una debilidad en una versión anterior del sistema o software TEE no puede revertir un dispositivo a la versión vulnerable y usar claves creadas con la versión más nueva. Además, cuando se utiliza una clave con una versión y un nivel de parche determinados en un dispositivo que se ha actualizado a una versión más reciente o un nivel de parche, la clave se actualiza antes de que pueda usarse y la versión anterior de la clave se invalida. A medida que se actualiza el dispositivo, las teclas se mueven hacia adelante junto con el dispositivo, pero cualquier reversión del dispositivo a una versión anterior hace que las teclas no se puedan utilizar.

En Android 8.0, Keymaster 3 pasó de la capa de abstracción de hardware (HAL) de estructura C de estilo antiguo a la interfaz HAL de C ++ generada a partir de una definición en el nuevo lenguaje de definición de interfaz de hardware (HIDL). Como parte del cambio, muchos de los tipos de argumentos cambiaron, aunque los tipos y métodos tienen una correspondencia uno a uno con los tipos antiguos y los métodos de estructura HAL. Consulte la página de Funciones para obtener más detalles.

Además de esta revisión de la interfaz, Android 8.0 amplía la función de certificación de Keymaster 2 para admitir la certificación de ID . La atestación de identificación proporciona un mecanismo limitado y opcional para dar fe de los identificadores de hardware, como el número de serie del dispositivo, el nombre del producto y la identificación del teléfono (IMEI / MEID). Para implementar esta adición, cambie el esquema de atestación ASN.1 para agregar atestación de ID. Las implementaciones de Keymaster necesitan encontrar alguna forma segura de recuperar los elementos de datos relevantes, así como definir un mecanismo para deshabilitar la función de forma segura y permanente.

En Android 9, las actualizaciones incluyen:

  • Actualización a Keymaster 4
  • Soporte para elementos seguros integrados
  • Soporte para importación segura de claves
  • Soporte para cifrado 3DES
  • Cambios en el enlace de versiones para que boot.img y system.img tengan versiones configuradas por separado para permitir actualizaciones independientes

Glosario

A continuación, se ofrece una descripción general rápida de los componentes del almacén de claves y sus relaciones.

AndroidKeystore es el componente y la API de Android Framework que utilizan las aplicaciones para acceder a la funcionalidad de Keystore. Se implementa como una extensión de las API estándar de Java Cryptography Architecture y consta de código Java que se ejecuta en el propio espacio de proceso de la aplicación. AndroidKeystore satisface las solicitudes de aplicaciones para el comportamiento del almacén de claves enviándolas al demonio del almacén de claves.

El demonio del almacén de claves es un demonio del sistema Android que proporciona acceso a todas las funciones del almacén de claves a través de una API de Binder . Es responsable de almacenar "blobs de claves", que contienen el material de la clave secreta real, cifrado para que Keystore pueda almacenarlo pero no usarlo ni revelarlo.

keymasterd es un servidor HIDL que proporciona acceso al Keymaster TA. (Este nombre no está estandarizado y tiene fines conceptuales).

Keymaster TA (aplicación confiable) es el software que se ejecuta en un contexto seguro, con mayor frecuencia en TrustZone en un ARM SoC, que proporciona todas las operaciones seguras del almacén de claves, tiene acceso a la materia prima de la clave, valida todas las condiciones de control de acceso en las claves etc.

LockSettingsService es el componente del sistema Android responsable de la autenticación del usuario, tanto la contraseña como la huella digital. No es parte del almacén de claves, pero es relevante porque muchas operaciones de claves del almacén de claves requieren autenticación del usuario. LockSettingsService interactúa con Gatekeeper TA y Fingerprint TA para obtener tokens de autenticación, que proporciona al demonio del almacén de claves y que, en última instancia, son consumidos por la aplicación Keymaster TA.

Gatekeeper TA (aplicación confiable) es otro componente que se ejecuta en el contexto seguro, que es responsable de autenticar las contraseñas de los usuarios y generar tokens de autenticación que se utilizan para demostrarle al Keymaster TA que se realizó una autenticación para un usuario en particular en un momento determinado.

Fingerprint TA (aplicación confiable) es otro componente que se ejecuta en el contexto seguro y es responsable de autenticar las huellas digitales del usuario y generar tokens de autenticación que se utilizan para demostrarle al Keymaster TA que se realizó una autenticación para un usuario en particular en un momento determinado.

Arquitectura

La API de Android Keystore y el Keymaster HAL subyacente proporcionan un conjunto básico pero adecuado de primitivas criptográficas para permitir la implementación de protocolos utilizando claves de acceso controlado y respaldadas por hardware.

Keymaster HAL es una biblioteca de carga dinámica proporcionada por el OEM que utiliza el servicio de almacén de claves para proporcionar servicios criptográficos respaldados por hardware. Para mantener las cosas seguras, las implementaciones de HAL no realizan operaciones sensibles en el espacio del usuario, ni siquiera en el espacio del kernel. Las operaciones sensibles se delegan a un procesador seguro al que se accede a través de alguna interfaz del kernel. La arquitectura resultante se ve así:

Acceso a Keymaster

Figura 1. Acceso a Keymaster

Dentro de un dispositivo Android, el "cliente" de Keymaster HAL consta de varias capas (por ejemplo, aplicación, marco, demonio de almacén de claves), pero que se pueden ignorar a los efectos de este documento. Esto significa que la API de Keymaster HAL descrita es de bajo nivel, utilizada por componentes internos de la plataforma y no expuesta a los desarrolladores de aplicaciones. La API de nivel superior se describe en el sitio para desarrolladores de Android .

El propósito de Keymaster HAL no es implementar los algoritmos sensibles a la seguridad, sino solo ordenar y desarmar solicitudes al mundo seguro. El formato de cable está definido por la implementación.

Compatibilidad con versiones anteriores

Keymaster 1 HAL es completamente incompatible con los HAL lanzados anteriormente, por ejemplo, Keymaster 0.2 y 0.3. Para facilitar la interoperabilidad en dispositivos que ejecutan Android 5.0 y versiones anteriores que se lanzaron con los Keymaster HAL más antiguos, Keystore proporciona un adaptador que implementa Keymaster 1 HAL con llamadas a la biblioteca de hardware existente. El resultado no puede proporcionar la gama completa de funciones en Keymaster 1 HAL. En particular, solo admite algoritmos RSA y ECDSA, y el adaptador realiza toda la aplicación de autorización de claves en el mundo no seguro.

Keymaster 2 simplificó aún más la interfaz HAL al eliminar los métodos get_supported_* y permitir que el método finish() acepte la entrada. Esto reduce el número de viajes de ida y vuelta al TEE en los casos en los que la entrada está disponible de una vez y simplifica la implementación del descifrado AEAD.

En Android 8.0, Keymaster 3 pasó de la estructura C de estilo antiguo HAL a la interfaz C ++ HAL generada a partir de una definición en el nuevo lenguaje de definición de interfaz de hardware (HIDL). Se crea una implementación de HAL de nuevo estilo subclasificando la clase IKeymasterDevice generada e implementando los métodos virtuales puros. Como parte del cambio, muchos de los tipos de argumentos han cambiado, aunque los tipos y métodos tienen una correspondencia de uno a uno con los tipos antiguos y los métodos de estructura HAL.

Descripción general de HIDL

El lenguaje de definición de interfaz de hardware (HIDL) proporciona un mecanismo de implementación independiente del lenguaje para especificar interfaces de hardware. Las herramientas HIDL actualmente admiten la generación de interfaces C ++ y Java. Se espera que la mayoría de los implementadores de Trusted Execution Environment (TEE) encuentren las herramientas de C ++ más convenientes, por lo que este documento solo analiza la representación de C ++.

Las interfaces HIDL consisten en un conjunto de métodos, expresados ​​como:

  methodName(INPUT ARGUMENTS) generates (RESULT ARGUMENTS);

Hay varios tipos predefinidos y los HAL pueden definir nuevos tipos enumerados y de estructura. Para obtener más detalles sobre HIDL, consulte la sección de referencia .

Un método de ejemplo del Keymaster 3 IKeymasterDevice.hal es:

generateKey(vec<KeyParameter> keyParams)
        generates(ErrorCode error, vec<uint8_t> keyBlob,
                  KeyCharacteristics keyCharacteristics);

Este es el equivalente de lo siguiente del keymaster2 HAL:

keymaster_error_t (*generate_key)(
        const struct keymaster2_device* dev,
        const keymaster_key_param_set_t* params,
        keymaster_key_blob_t* key_blob,
        keymaster_key_characteristics_t* characteristics);

En la versión HIDL, el argumento dev se elimina porque está implícito. El argumento params ya no es una estructura que contiene un puntero que hace referencia a una matriz de objetos key_parameter_t , sino un vec (vector) que contiene objetos KeyParameter . Los valores devueltos se enumeran en la cláusula " generates ", incluido un vector de valores uint8_t para el blob de claves.

El método virtual de C ++ generado por el compilador HIDL es:

Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams,
                         generateKey_cb _hidl_cb) override;

Donde generate_cb es un puntero de función definido como:

std::function<void(ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
                   const KeyCharacteristics& keyCharacteristics)>

Es decir, generate_cb es una función que toma los valores de retorno enumerados en la cláusula generate. La clase de implementación HAL anula este método generateKey y llama al puntero de la función generate_cb para devolver el resultado de la operación al llamador. Tenga en cuenta que la llamada al puntero de función es sincrónica . El llamador llama a generateKey y generateKey llama al puntero de función suministrado, que se ejecuta hasta el final, devolviendo el control a la implementación generateKey , que luego vuelve al llamador.

Para obtener un ejemplo detallado, consulte la implementación predeterminada en hardware/interfaces/keymaster/3.0/default/KeymasterDevice.cpp . La implementación predeterminada proporciona compatibilidad con versiones anteriores para dispositivos con keymaster0, keymaster1 o keymaster2 HALS de estilo antiguo.