Clés enveloppées dans le matériel

Comme la plupart des logiciels de chiffrement de disque et de fichiers, le chiffrement du stockage d'Android repose traditionnellement sur les clés de chiffrement brutes présentes dans la mémoire système pour que le chiffrement puisse être effectué. Même lorsque le chiffrement est effectué par matériel dédié plutôt que par logiciel, les logiciels doivent généralement gérer les clés de chiffrement brutes.

En général, cela n'est pas considéré comme un problème, car les clés ne sont pas présentes. lors d'une attaque hors ligne, qui est le principal type d'attaque contre laquelle le chiffrement est destiné à protéger. Cependant, nous souhaitons fournir une protection accrue contre d'autres types d'attaques, tels que le démarrage à froid ; les attaques et les attaques en ligne qui pourraient permettre à un pirate informatique de fuir un système mémoire sans compromettre complètement l’appareil.

Pour résoudre ce problème, Android 11 est compatible pour les clés encapsulées dans le matériel, où la compatibilité matérielle est assurée. Les clés encapsulées matériellement sont des clés de stockage connues uniquement sous forme brute pour du matériel dédié, le logiciel ne voit et fonctionne ces clés qu'encapsulées (chiffré). Ce matériel doit être capable de générer et d'importer les clés de stockage, les encapsuler dans des formes éphémères et à long terme, en programmant directement une sous-clé dans un moteur de chiffrement intégré renvoyant une sous-clé distincte au logiciel.

Remarque: Un moteur de chiffrement intégré (ou intégré matériel de chiffrement) fait référence au matériel qui chiffre/déchiffre les données elle est en chemin vers/depuis le périphérique de stockage. Il s'agit généralement d'un hôte UFS ou eMMC qui implémente les extensions cryptographiques définies par le gestionnaire Spécification JEDEC.

Conception

Cette section présente la conception de touches encapsulées, y compris la compatibilité matérielle requise pour cela. Cet article porte sur le chiffrement basé sur les fichiers (FBE), s'applique aux métadonnées le chiffrement.

Une façon d'éviter d'avoir besoin des clés de chiffrement brutes dans la mémoire système consisterait à ne les conserve que dans les fentes d’un moteur de chiffrement intégré. Toutefois, rencontre quelques problèmes:

  • Le nombre de clés de chiffrement peut dépasser le nombre d'emplacements de clés.
  • Les moteurs de chiffrement intégrés ne peuvent être utilisés que pour chiffrer/déchiffrer des blocs entiers les données sur le disque. Toutefois, dans le cas de FBE, le logiciel doit toujours être capable effectuer d'autres tâches cryptographiques telles que le chiffrement des noms de fichiers et la dérivation de la clé identifiants. Le logiciel aurait toujours besoin d’accéder aux clés FBE brutes pour pouvoir pour effectuer cette autre tâche.

Pour éviter ces problèmes, les clés de stockage sont plutôt converties clés encapsulées dans le matériel, qui ne peuvent être désencapsulées et utilisées que par du matériel dédié. Cela permet de prendre en charge un nombre illimité de clés. Dans la hiérarchie des clés est modifiée et partiellement déplacée vers ce matériel, qui permet de renvoyer une sous-clé au logiciel pour des tâches qui ne peuvent pas utiliser un et un moteur de chiffrement intégré.

Hiérarchie des clés

Les clés peuvent être dérivées d'autres clés à l'aide d'une fonction KDF (fonction de dérivation de clé) comme HKDF. ce qui génère une hiérarchie de clés.

Le schéma suivant illustre une hiérarchie de clés typique pour FBE : les clés encapsulées matériellement ne sont pas utilisées:

Hiérarchie des clés FBE (standard)
Image 1. Hiérarchie des clés FBE (standard)

La clé de classe FBE est la clé de chiffrement brute qu'Android transmet au système pour déverrouiller un ensemble particulier de répertoires chiffrés, le stockage chiffré par identifiants pour un utilisateur Android donné. (Dans le noyau, est appelée clé principale fscrypt.) À partir de cette clé, le noyau dérive les sous-clés suivantes:

  • Identifiant de clé. Il ne s'agit pas d'un chiffrement, mais d'une valeur utilisé pour identifier la clé avec laquelle un fichier ou un répertoire spécifique est protégées.
  • Clé de chiffrement du contenu du fichier
  • Clé de chiffrement des noms de fichiers

En revanche, le schéma suivant illustre la hiérarchie des clés pour FBE quand sont utilisées:

Hiérarchie des clés FBE (avec clé encapsulée matériellement)
Figure 2 : Hiérarchie des clés FBE (avec clé encapsulée matériellement)

Par rapport au cas précédent, un niveau supplémentaire a été ajouté à la clé et la clé de chiffrement du contenu du fichier a été déplacée. La racine représente toujours la clé qu'Android transmet à Linux pour déverrouiller un ensemble des répertoires chiffrés. Cependant, maintenant que cette clé est encapsulée de manière éphémère, pour être utilisé, il doit être transmis à du matériel dédié. Ce matériel doit implémenter deux interfaces utilisant une clé encapsulée de manière éphémère:

  • Une interface pour dériver inline_encryption_key et directement le programmer dans un emplacement clé du moteur de chiffrement intégré. Cela permet aux fichiers le contenu doit être chiffré/déchiffré sans que le logiciel ait accès aux données . Dans les noyaux courants Android, cette interface correspond au l'opération blk_crypto_ll_ops::keyslot_program, qui doit être implémentée par le pilote de stockage.
  • Une interface pour obtenir et renvoyer sw_secret ("logiciel secret également appelé "secret brut", à certains endroits), qui est la clé Linux utilise pour dériver les sous-clés pour tout autre chose que le contenu des fichiers le chiffrement. Dans les noyaux courants Android, cette interface correspond au l'opération blk_crypto_ll_ops::derive_sw_secret, qui doit être implémentée par le pilote de stockage.

Pour obtenir inline_encryption_key et sw_secret à partir de la clé de stockage brute, le matériel doit utiliser un KDF sécurisé de manière cryptographique. Ce KDF respecter les bonnes pratiques en matière de cryptographie ; son niveau de sécurité doit être de d'au moins 256 bits, c'est-à-dire suffisamment pour tout algorithme utilisé ultérieurement. Il doit également utiliser une chaîne distincte d'étiquette, de contexte et/ou d'information spécifique à l'application lorsque dériver chaque type de sous-clé afin de garantir que les sous-clés qui en résultent sont isolés de manière cryptographique, c'est-à-dire que la connaissance de l'un d'entre eux ne révèle aucune autre. Aucun étirement de clé n'est requis, car la clé de stockage brute est déjà de manière uniformément aléatoire.

Techniquement, n'importe quel fichier KDF répondant aux exigences de sécurité peut être utilisé. Toutefois, à des fins de test, il est nécessaire de réimplémenter le même fichier KDF dans code de test. Actuellement, un KDF a été examiné et implémenté. il peut être trouvé dans le code source de vts_kernel_encryption_test. Il est recommandé d'utiliser ce KDF pour le matériel. Celui-ci utilise le document NIST SP 800-108 "KDF in Counter Mode" (KDF en mode compteur) avec l'encodage AES-256-CMAC en tant que PRF. Notez que pour des raisons de compatibilité, tous certaines parties de l'algorithme doivent être identiques, y compris le choix des contextes KDF et des étiquettes pour chaque sous-clé.

Encapsulation de clé

Pour atteindre les objectifs de sécurité des clés encapsulées dans le matériel, deux types d'encapsulation de clés sont définies:

  • Encapsulation éphémère: le matériel chiffre la clé brute à l'aide d'une clé. généré de manière aléatoire à chaque démarrage et non directement exposé en dehors du matériel.
  • Encapsulation à long terme: le matériel chiffre la clé brute à l'aide d'un clé unique et persistante intégrée au matériel, qui n'est pas directement exposées à l'extérieur du matériel.

Toutes les clés transmises au noyau Linux pour déverrouiller le stockage sont encapsulés de manière éphémère. Ainsi, si un pirate informatique est en mesure d'extraire clé en cours d'utilisation depuis la mémoire système, elle sera non seulement inutilisable hors de l’appareil, mais aussi sur l’appareil après un redémarrage.

Dans le même temps, Android doit toujours pouvoir stocker une version chiffrée des clés sur le disque afin qu'elles puissent être déverrouillées en premier lieu. Les données brutes de clés de sécurité fonctionnent à cet effet. Cependant, il est souhaitable de ne jamais avoir sont présentes dans la mémoire système, afin qu'elles ne puissent jamais être extraites être utilisées hors de l'appareil, même si elles sont extraites au démarrage. Pour cette raison, le concept de l'encapsulation à long terme.

Pour prendre en charge la gestion des clés encapsulées de ces deux manières différentes, le matériel doit implémenter les interfaces suivantes:

  • Interfaces permettant de générer et d'importer des clés de stockage, en les renvoyant encapsulée à long terme. Ces interfaces sont accessibles indirectement via KeyMint et ils correspondent à la balise KeyMint TAG_STORAGE_KEY. La commande "generate" vold utilise cette fonctionnalité pour générer un nouvel espace de stockage pour Android, tandis que la commande "import" la fonctionnalité est utilisée par vts_kernel_encryption_test pour importer des clés de test.
  • Une interface permettant de convertir une clé de stockage encapsulée à long terme en clé de stockage encapsulée de manière éphémère. Cela correspond au Méthode KeyMint convertStorageKeyToEphemeral. Cette méthode est utilisée par vold et vts_kernel_encryption_test dans l'ordre pour déverrouiller l'espace de stockage.

L'algorithme d'encapsulation de clé est un détail d'implémentation, mais il doit utiliser un AEAD fort comme AES-256-GCM avec des vecteurs d'initialisation aléatoires.

Modifications logicielles requises

AOSP dispose déjà d'un framework de base pour la prise en charge des clés encapsulées dans le matériel. Ce est compatible avec les composants d'espace utilisateur tels que vold, ainsi que comme la compatibilité du noyau Linux avec blk-crypto, fscrypt et dm-default-key.

Toutefois, certaines modifications spécifiques à l'implémentation sont nécessaires.

Modifications apportées à KeyMint

L'implémentation KeyMint de l'appareil doit être modifiée afin de prendre en charge TAG_STORAGE_KEY et implémenter la convertStorageKeyToEphemeral.

Dans Keymaster, exportKey a été utilisé au lieu de convertStorageKeyToEphemeral

Modifications du noyau Linux

Le pilote du noyau Linux pour le moteur de chiffrement intégré de l'appareil doit être modifié pour prendre en charge les clés encapsulées dans le matériel.

Pour les noyaux android14 et supérieurs, définir BLK_CRYPTO_KEY_TYPE_HW_WRAPPED à blk_crypto_profile::key_types_supported, faire blk_crypto_ll_ops::keyslot_program et blk_crypto_ll_ops::keyslot_evict prendre en charge la programmation et l'éviction de clés encapsulées dans du matériel ; et implémenter blk_crypto_ll_ops::derive_sw_secret.

Pour les noyaux android12 et android13, définir BLK_CRYPTO_FEATURE_WRAPPED_KEYS à blk_keyslot_manager::features, faire blk_ksm_ll_ops::keyslot_program et blk_ksm_ll_ops::keyslot_evict prendre en charge la programmation et l'éviction de clés encapsulées dans du matériel ; et implémenter blk_ksm_ll_ops::derive_raw_secret.

Pour les noyaux android11, définir BLK_CRYPTO_FEATURE_WRAPPED_KEYS à keyslot_manager::features, faire keyslot_mgmt_ll_ops::keyslot_program et keyslot_mgmt_ll_ops::keyslot_evict prendre en charge la programmation et l'éviction de clés encapsulées dans du matériel ; et implémenter keyslot_mgmt_ll_ops::derive_raw_secret.

Tests

Bien que le chiffrement à l'aide de clés encapsulées dans le matériel soit plus difficile à tester que le chiffrement avec des clés standards, il est toujours possible d'effectuer un test en important une clé de test la dérivation des clés effectuée par le matériel. Elle est implémentée dans vts_kernel_encryption_test. Pour exécuter ce test, exécuter:

atest -v vts_kernel_encryption_test

Lisez le journal de test et vérifiez que les scénarios de test clés encapsulés dans le matériel (par exemple, FBEPolicyTest.TestAesInlineCryptOptimizedHwWrappedKeyPolicy et DmDefaultKeyTest.TestHwWrappedKey) n'ont pas été ignorées en raison de la compatibilité pour les clés encapsulées dans le matériel qui ne sont pas détectées, car les résultats des tests "réussi" dans ce cas.

Activation

Une fois que la prise en charge des clés encapsulées matérielle de l'appareil fonctionne correctement, vous pouvez apportez les modifications suivantes au fichier fstab de l'appareil pour Android l'utilise pour les FBE et le chiffrement des métadonnées:

  • FBE: ajoutez l'indicateur wrappedkey_v0 au Paramètre fileencryption. Par exemple, utilisez fileencryption=::inlinecrypt_optimized+wrappedkey_v0 Pour pour en savoir plus, consultez les documentation.
  • Chiffrement des métadonnées: ajoutez l'option wrappedkey_v0 au Paramètre metadata_encryption. Par exemple, utilisez metadata_encryption=:wrappedkey_v0 Pour en savoir plus, consultez les métadonnées sur le chiffrement.