Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.
此页面由 Cloud Translation API 翻译。
Switch to English

Enlace de versión

En Keymaster 1, todas las claves del maestro de claves estaban vinculadas criptográficamente a la raíz de confianza del dispositivo, o la clave de inicio verificada. En Keymaster 2 y 3, todas las claves también están vinculadas al sistema operativo y al nivel de parche de la imagen del sistema. Esto asegura que un atacante que descubre una debilidad en una versión antigua del sistema o software TEE no puede revertir un dispositivo a la versión vulnerable y utilizar claves creadas con la versión más nueva. Además, cuando se usa una clave con una versión y un nivel de parche determinados en un dispositivo que se ha actualizado a una versión o nivel de parche más reciente, la clave se actualiza antes de que pueda usarse y la versión anterior de la clave se invalida. De esta manera, a medida que se actualiza el dispositivo, las teclas se moverán hacia adelante junto con el dispositivo, pero cualquier reversión del dispositivo a una versión anterior hará que las teclas no se puedan utilizar.

Para admitir la estructura modular de Treble y romper el enlace de system.img con boot.img, Keymaster 4 cambió el modelo de enlace de la versión clave para tener niveles de parche separados para cada partición. Esto permite que cada partición se actualice de forma independiente, sin dejar de ofrecer protección contra la reversión.

En Android 9, vendor particiones de boot , system y vendor tienen su propio nivel de parche.

  • Los dispositivos con Android Verified Boot (AVB) pueden poner todos los niveles de parche y la versión del sistema en vbmeta, por lo que el gestor de arranque puede proporcionarlos a Keymaster. Para las particiones encadenadas, la información de la versión de la partición estará en el archivo vbmeta encadenado. En general, la información de la versión debe estar en la vbmeta struct que contiene los datos de verificación (hash o hashtree) para una partición determinada.
  • En dispositivos sin AVB:
    • Las implementaciones de arranque verificado deben proporcionar un hash de los metadatos de la versión al cargador de arranque, de modo que el cargador de arranque pueda proporcionar el hash a Keymaster.
    • boot.img puede continuar almacenando el nivel de parche en el encabezado
    • system.img puede continuar almacenando el nivel de parche y la versión del sistema operativo en propiedades de solo lectura
    • vendor.img almacena el nivel de parche en la propiedad de solo lectura ro.vendor.build.version.security_patch .
    • El cargador de arranque puede proporcionar un hash de todos los datos validados por un arranque verificado a keymaster.
  • En Android 9, use las siguientes etiquetas para proporcionar información de versión para las siguientes particiones:
    • VENDOR_PATCH_LEVEL : partición de vendor
    • BOOT_PATCH_LEVEL : partición de boot
    • OS_PATCH_LEVEL y OS_VERSION : partición del system . ( OS_VERSION se elimina del encabezado boot.img .
  • Las implementaciones de Keymaster deben tratar todos los niveles de parche de forma independiente. Las claves se pueden usar si toda la información de la versión coincide con los valores asociados con una clave, e IKeymaster::upgradeDevice() pasa a un nivel de parche más alto si es necesario.

Cambios de HAL

Para admitir el enlace de la versión y la certificación de la versión, Android 7.1 agregó las etiquetas Tag::OS_VERSION y Tag::OS_PATCHLEVEL y los métodos configure y upgradeKey . Las implementaciones de Keymaster 2+ agregan automáticamente las etiquetas de versión a todas las claves recién generadas (o actualizadas). Además, cualquier intento de usar una clave que no tenga una versión del sistema operativo o un nivel de parche que coincida con la versión del sistema operativo actual o el nivel de parche, respectivamente, se rechaza con ErrorCode::KEY_REQUIRES_UPGRADE .

Tag::OS_VERSION es un valor UINT que representa las porciones mayor, menor y sub-menor de una versión del sistema Android como MMmmss, donde MM es la versión principal, mm es la versión menor y ss es la versión sub-menor. Por ejemplo, 6.1.2 se representaría como 060102.

Tag::OS_PATCHLEVEL es un valor UINT que representa el año y el mes de la última actualización del sistema como AAAAMM, donde AAAA es el año de cuatro dígitos y MM es el mes de dos dígitos. Por ejemplo, marzo de 2016 se representaría como 201603.

UpgradeKey

Para permitir que las claves se actualicen a la nueva versión del sistema operativo y al nivel de parche de la imagen del sistema, Android 7.1 agregó el método upgradeKey a la HAL:

Maestro de llaves 3

    upgradeKey(vec keyBlobToUpgrade, vec upgradeParams)
        generates(ErrorCode error, vec upgradedKeyBlob);

Maestro de llaves 2

keymaster_error_t (*upgrade_key)(const struct keymaster2_device* dev,
    const keymaster_key_blob_t* key_to_upgrade,
    const keymaster_key_param_set_t* upgrade_params,
    keymaster_key_blob_t* upgraded_key);
  • dev es la estructura del dispositivo
  • keyBlobToUpgrade es la clave que debe actualizarse
  • upgradeParams son parámetros necesarios para actualizar la clave. Estos incluirán Tag::APPLICATION_ID y Tag::APPLICATION_DATA , que son necesarios para descifrar el blob de claves, si se proporcionaron durante la generación.
  • upgradedKeyBlob es el parámetro de salida, que se utiliza para devolver el nuevo blob de claves.

Si se llama a upgradeKey con un blob de claves que no se puede analizar o no es válido, devuelve ErrorCode::INVALID_KEY_BLOB . Si se llama con una clave cuyo nivel de parche es mayor que el valor actual del sistema, devuelve ErrorCode::INVALID_ARGUMENT . Si se llama con una clave cuya versión del sistema operativo es mayor que el valor del sistema actual, y el valor del sistema es distinto de cero, devuelve ErrorCode::INVALID_ARGUMENT . Se permiten actualizaciones de la versión del sistema operativo desde cero a cero. En caso de errores de comunicación con el mundo seguro, devuelve un valor de error apropiado (por ejemplo, ErrorCode::SECURE_HW_ACCESS_DENIED , ErrorCode::SECURE_HW_BUSY ). De lo contrario, devuelve ErrorCode::OK y devuelve un nuevo blob de claves en upgradedKeyBlob .

keyBlobToUpgrade sigue siendo válido después de la llamada de upgradeKey y, en teoría, podría usarse de nuevo si el dispositivo fuera degradado. En la práctica, el almacén de claves generalmente llama a deleteKey en el blob keyBlobToUpgrade poco después de la llamada a upgradeKey . Si keyBlobToUpgrade tenía la etiqueta Tag::ROLLBACK_RESISTANT , entonces upgradedKeyBlob debería tenerla también (y debería ser resistente a la reversión).

Configuración segura

Para implementar el enlace de versiones, el administrador de claves TA necesita una forma de recibir de forma segura la versión actual del sistema operativo y el nivel de parche (información de la versión), y asegurarse de que la información que recibe coincida con la información sobre el sistema en ejecución.

Para admitir la entrega segura de información de la versión al TA, se ha agregado un campo OS_VERSION al encabezado de la imagen de inicio. La secuencia de comandos de creación de la imagen de arranque completa automáticamente este campo. Los OEM y los implementadores de Keymaster TA deben trabajar juntos para modificar los cargadores de arranque del dispositivo para extraer la información de la versión de la imagen de arranque y pasarla al TA antes de que se inicie el sistema no seguro. Esto asegura que los atacantes no puedan interferir con el suministro de información de la versión al TA.

También es necesario asegurarse de que la imagen del sistema tenga la misma información de versión que la imagen de arranque. Con ese fin, se ha agregado el método de configuración al keymaster HAL:

keymaster_error_t (*configure)(const struct keymaster2_device* dev,
  const keymaster_key_param_set_t* params);

El argumento params contiene Tag::OS_VERSION y Tag::OS_PATCHLEVEL . Los clientes de keymaster2 llaman a este método después de abrir el HAL, pero antes de llamar a cualquier otro método. Si se llama a cualquier otro método antes de configure, el TA devuelve ErrorCode::KEYMASTER_NOT_CONFIGURED .

La primera vez que se llama a configure después de que se inicia el dispositivo, debe verificar que la información de la versión proporcionada coincide con la proporcionada por el cargador de arranque. Si la información de la versión no coincide, configure devuelve ErrorCode::INVALID_ARGUMENT , y todos los demás métodos keymaster continúan devolviendo ErrorCode::KEYMASTER_NOT_CONFIGURED . Si la información coincide, configure devuelve ErrorCode::OK , y otros métodos keymaster comenzarán a funcionar normalmente.

Las siguientes llamadas para configure devuelven el mismo valor devuelto por la primera llamada y no cambian el estado de keymaster. Tenga en cuenta que este proceso REQUERIRÁ que todas las OTA actualicen las imágenes de arranque y del sistema; no se pueden actualizar por separado para mantener sincronizada la información de la versión.

Debido a que configure será llamado por el sistema cuyo contenido se pretende validar, existe una pequeña ventana de oportunidad para que un atacante comprometa la imagen del sistema y lo obligue a proporcionar información de versión que coincida con la imagen de arranque, pero que no es la real. versión del sistema. La combinación de la verificación de la imagen de arranque, la validación de dm-verity del contenido de la imagen del sistema y el hecho de que configure se llame muy temprano en el arranque del sistema debería hacer que esta ventana de oportunidad sea difícil de aprovechar.