Liaison de version

Dans Keymaster 1, toutes les clés Keymaster étaient liées de manière cryptographique à l'appareil. Racine de confiance ou clé de démarrage validé. Dans Keymaster 2 et 3, clés sont également liées au système d'exploitation et au niveau de correctif de l'image système. Cela garantit qu’un attaquant qui découvre une faiblesse dans un ancien du système ou du logiciel TEE ne peut pas effectuer de rollback d'un appareil vers le et d'utiliser des clés créées avec la version la plus récente. De plus, lorsqu'une clé avec une version et un niveau de correctif donnés est utilisé sur un appareil vers une version ou un niveau de correctif plus récent, la clé est mise à niveau avant de pouvoir être utilisée, et la version précédente de la clé invalidée. De cette façon, lorsque l'appareil mises à niveau, les clés sont "cliquetis" avec l'appareil, mais toute de l'appareil à une version précédente, les clés seront inutilisable.

Pour soutenir la structure modulaire de Treble et rompre la liaison de system.img avec boot.img, Keymaster 4 a modifié le modèle de liaison de version de clé pour disposer des niveaux de correctif pour chaque partition. Cela permet de mettre à jour chaque partition de façon indépendante, tout en assurant une protection contre le rollback.

Sous Android 9, les éléments boot, system et vendor ont chacune leur propre niveau de correctif.

  • Les appareils dotés du démarrage validé Android (AVB) peuvent appliquer tous les niveaux de correctif et la version du système dans vbmeta, afin que le bootloader puisse les fournir à Keymaster. Pour les partitions enchaînées, les informations de version de la partition se trouver dans le vbmeta enchaîné. En général, les informations de version doivent figurer dans le fichier vbmeta struct contenant les données de validation (hachage ou hashtree) pour une partition donnée.
  • Sur les appareils sans AVB: <ph type="x-smartling-placeholder">
      </ph>
    • Les implémentations du démarrage validé doivent fournir un hachage de la version des métadonnées au bootloader, afin que celui-ci puisse fournir le hachage au Keymaster.
    • boot.img peut continuer à stocker le niveau du correctif dans l'en-tête
    • system.img peut continuer à stocker le niveau de correctif et la version de l'OS en lecture seule propriétés
    • vendor.img stocke le niveau du correctif dans la propriété de lecture seule. ro.vendor.build.version.security_patch
    • Le bootloader peut fournir un hachage de toutes les données validées par le démarrage validé à keymaster.
  • Dans Android 9, utilisez les tags suivants pour fournir des informations de version pour les partitions suivantes: <ph type="x-smartling-placeholder">
      </ph>
    • VENDOR_PATCH_LEVEL: partition vendor
    • BOOT_PATCH_LEVEL: partition boot
    • OS_PATCH_LEVEL et OS_VERSION: system. (OS_VERSION est supprimé des l'en-tête boot.img.
  • Les implémentations de Keymaster doivent traiter tous les niveaux de correctif indépendamment. Les clés sont utilisable si toutes les informations de version correspondent aux valeurs associées à une clé, et IKeymaster::upgradeDevice() passe à un niveau de correctif plus élevé si nécessaires.

Modifications HAL

Pour prendre en charge la liaison de version et l'attestation de version, Android 7.1 a ajouté le les tags Tag::OS_VERSION et Tag::OS_PATCHLEVEL, ainsi que méthodes configure et upgradeKey. Les tags de version sont automatiquement ajoutés par les implémentations Keymaster 2+ à toutes les nouvelles clés (ou mises à jour). De plus, toute tentative d'utilisation d'une clé n'ayant pas de système d'exploitation version ou niveau de correctif correspondant à la version actuelle du système d'exploitation ou au niveau de correctif, respectivement est rejetée avec ErrorCode::KEY_REQUIRES_UPGRADE.

Tag::OS_VERSION est une valeur UINT qui représente le les parties majeures, mineures et mineures d'une version du système Android comme MMmmss, où MM est la version majeure, mm est la version mineure et ss est la version mineure version. Par exemple, 6.1.2 est représenté par 060102.

Tag::OS_PATCHLEVEL est une valeur UINT qui représente le l'année et le mois de la dernière mise à jour du système, au format AAAAMM, où AAAA correspond au année à quatre chiffres et MM est le mois à deux chiffres. Par exemple, la date de mars 2016 est représenté par 201603.

Clé de mise à niveau

Pour permettre la mise à niveau des clés vers la nouvelle version du système d'exploitation et le nouveau niveau de correctif du système image, Android 7.1 a ajouté la méthode upgradeKey au HAL:

Keymaster 3

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

Keymaster 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 est la structure de l'appareil.
  • keyBlobToUpgrade est la clé qui doit être mise à niveau
  • upgradeParams sont les paramètres nécessaires à la mise à niveau de la clé. Ces inclura Tag::APPLICATION_ID et Tag::APPLICATION_DATA, qui sont nécessaires pour déchiffrer la clé blob, s'ils ont été fournis lors de la génération.
  • upgradedKeyBlob est le paramètre de sortie, utilisé pour renvoyer le blob de clé.

Si upgradeKey est appelé avec un blob de clé qui ne peut pas être analysé ou est incorrecte, elle renvoie ErrorCode::INVALID_KEY_BLOB. Si est appelé avec une clé dont le niveau de correctif est supérieur à la valeur système actuelle, la fonction renvoie ErrorCode::INVALID_ARGUMENT. S'il est appelé avec une clé dont la version de l'OS est supérieure à la valeur système actuelle, ainsi que la valeur système est non nulle, elle renvoie ErrorCode::INVALID_ARGUMENT. Version de l'OS les mises à niveau non nulles vers zéro sont autorisées. En cas d'erreurs communique avec le monde sécurisé, il renvoie une valeur d'erreur appropriée (par exemple, ErrorCode::SECURE_HW_ACCESS_DENIED, ErrorCode::SECURE_HW_BUSY). Sinon, il renvoie ErrorCode::OK et renvoie un nouveau blob de clé dans upgradedKeyBlob

keyBlobToUpgrade reste valide après upgradeKey et pourrait théoriquement être réutilisé si l'appareil était rétrogradé. Dans pratique, le keystore appelle généralement deleteKey sur le blob keyBlobToUpgrade peu de temps après l'appel à upgradeKey Si keyBlobToUpgrade avait un tag Tag::ROLLBACK_RESISTANT, puis upgradedKeyBlob doit l'avez également (et doivent donc résister aux rollbacks).

Configuration sécurisée

Pour implémenter la liaison de version, l'agent TA a besoin d'un moyen de recevoir en toute sécurité la version actuelle du système d'exploitation et le niveau de correctif (informations sur la version), et pour vous assurer que les informations reçues correspondent fortement à celles concernant du système d'exploitation.

Pour assurer la transmission sécurisée des informations de version à l'assistant, un OS_VERSION a été ajouté à l'en-tête de l'image de démarrage. Création de l'image de démarrage remplit automatiquement ce champ. OEM et personnes chargées de la mise en œuvre de Keymaster TA doivent travailler ensemble afin de modifier les bootloaders de l’appareil afin d’extraire la version de l'image de démarrage et les transmettre à l'assistant avant que l'image de démarrage est démarré. Ainsi, les pirates informatiques ne peuvent pas interférer avec le provisionnement des informations de version à l'assistant.

Il est également nécessaire de s'assurer que l'image système a la même version en tant qu'image de démarrage. C'est pourquoi la méthode "Configure" a été ajoutée au HAL keymaster:

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

L'argument params contient Tag::OS_VERSION et Tag::OS_PATCHLEVEL Cette méthode est appelée par les clients keymaster2. après avoir ouvert le HAL, mais avant d'appeler d'autres méthodes. Si une autre méthode est appelé avant la configuration, TA renvoie ErrorCode::KEYMASTER_NOT_CONFIGURED

La première fois que configure est appelé après le démarrage de l'appareil, doit vérifier que les informations de version fournies correspondent à celles fournies par le bootloader. Si les informations de version ne correspondent pas, configure renvoie ErrorCode::INVALID_ARGUMENT, et tous les autres méthodes Keymaster continuent de renvoyer ErrorCode::KEYMASTER_NOT_CONFIGURED Si les informations correspondent, configure renvoie ErrorCode::OK et un autre keymaster de ces méthodes commencent à fonctionner normalement.

Les appels suivants à configure renvoient la même valeur renvoyée par la premier appel, sans modifier l'état de keymaster. Notez que ce processus nécessite que toutes les OTA mettent à jour les images du système et de démarrage ; vous ne pouvez pas les mettre à jour séparément pour synchroniser les informations de version.

Parce que configure sera appelé par le système dont il est le contenu à valider, il y a peu de chances qu'un attaquant puisse compromettre l'image système et la forcer à fournir des informations de version qui correspond à l'image de démarrage, mais qui n'est pas la version réelle du système. La combinaison de la vérification de l'image de démarrage et de la validation dm-verity de l'image système contenu et le fait que configure est appelé très tôt dans le le démarrage du système devrait rendre cette fenêtre d’opportunité difficile à exploiter.