Google s'est engagé à promouvoir l'équité raciale pour les communautés noires. Regarde comment.
Cette page a été traduite par l'API Cloud Translation.
Switch to English

Chiffrement complet du disque

Le cryptage complet du disque est le processus d'encodage de toutes les données utilisateur sur un appareil Android à l'aide d'une clé cryptée. Une fois qu'un appareil est chiffré, toutes les données créées par l'utilisateur sont automatiquement chiffrées avant d'être validées sur le disque et toutes les lectures déchiffrent automatiquement les données avant de les renvoyer au processus appelant.

Le chiffrement complet du disque a été introduit dans Android dans la version 4.4, mais Android 5.0 a introduit ces nouvelles fonctionnalités:

  • Créé un cryptage rapide, qui crypte uniquement les blocs utilisés sur la partition de données pour éviter que le premier démarrage ne prenne trop de temps. Seuls les systèmes de fichiers ext4 et f2fs prennent actuellement en charge le chiffrement rapide.
  • Ajout de l' forceencrypt fstab forceencrypt pour chiffrer au premier démarrage.
  • Ajout de la prise en charge des modèles et du cryptage sans mot de passe.
  • Ajout du stockage matériel de la clé de chiffrement à l'aide de la capacité de signature de Trusted Execution Environment (TEE) (comme dans une TrustZone). Voir Stockage de la clé chiffrée pour plus de détails.

Attention: les appareils mis à niveau vers Android 5.0 puis chiffrés peuvent être remis dans un état non chiffré par la réinitialisation des données d'usine. Les nouveaux appareils Android 5.0 chiffrés au premier démarrage ne peuvent pas être remis dans un état non chiffré.

Fonctionnement du chiffrement complet du disque Android

Le chiffrement du disque complet Android est basé sur dm-crypt , qui est une fonctionnalité du noyau qui fonctionne au niveau de la couche de périphérique bloc. Pour cette raison, le cryptage fonctionne avec la MultiMediaCard intégrée ( eMMC) et les périphériques flash similaires qui se présentent au noyau comme des périphériques de bloc. Le chiffrement n'est pas possible avec YAFFS, qui communique directement avec une puce flash NAND brute.

L'algorithme de chiffrement est 128 Advanced Encryption Standard (AES) avec enchaînement de blocs de chiffrement (CBC) et ESSIV: SHA256. La clé principale est chiffrée avec AES 128 bits via des appels à la bibliothèque OpenSSL. Vous devez utiliser 128 bits ou plus pour la clé (256 étant facultatif).

Remarque: les OEM peuvent utiliser 128 bits ou plus pour chiffrer la clé principale.

Dans la version Android 5.0, il existe quatre types d'états de chiffrement:

  • défaut
  • ÉPINGLE
  • mot de passe
  • modèle

Lors du premier démarrage, l'appareil crée une clé principale de 128 bits générée de manière aléatoire, puis la hache avec un mot de passe par défaut et un sel stocké. Le mot de passe par défaut est: "default_password" Cependant, le hachage résultant est également signé via un TEE (tel que TrustZone), qui utilise un hachage de la signature pour crypter la clé principale.

Vous pouvez trouver le mot de passe par défaut défini dans le fichier cryptfs.cpp du projet Open Source Android .

Lorsque l'utilisateur définit le code PIN / mot de passe ou le mot de passe sur l'appareil, seule la clé de 128 bits est rechiffrée et stockée. (c'est-à-dire que les modifications du code PIN / mot de passe / modèle utilisateur ne provoquent PAS le rechiffrement des données utilisateur.) Notez que le périphérique géré peut être soumis à des restrictions de code PIN, de modèle ou de mot de passe.

Le chiffrement est géré par init et vold . init appelle vold et vold définit des propriétés pour déclencher des événements dans init. D'autres parties du système examinent également les propriétés pour effectuer des tâches telles que l'état du rapport, demander un mot de passe ou demander une réinitialisation d'usine en cas d'erreur fatale. Pour appeler les fonctions de chiffrement dans vold , le système utilise les commandes vdc outil de ligne de commande cryptfs : checkpw , restart , enablecrypto , changepw , cryptocomplete , verifypw , setfield , getfield , mountdefaultencrypted , getpwtype , getpw et clearpw .

Pour crypter, décrypter ou effacer /data , /data ne doit pas être monté. Cependant, pour afficher n'importe quelle interface utilisateur (UI), le framework doit démarrer et le framework nécessite /data pour s'exécuter. Pour résoudre cette énigme, un système de fichiers temporaire est monté sur /data . Cela permet à Android de demander des mots de passe, d'afficher la progression ou de suggérer un effacement des données si nécessaire. Il impose la limitation que pour passer du système de fichiers temporaire au système de fichiers true /data , le système doit arrêter chaque processus avec des fichiers ouverts sur le système de fichiers temporaire et redémarrer ces processus sur le système de fichiers real /data . Pour ce faire, tous les services doivent être dans l'un des trois groupes suivants: core , main et late_start .

  • core : ne jamais arrêter après le démarrage.
  • main : Arrêtez puis redémarrez après la saisie du mot de passe du disque.
  • late_start : ne démarre pas tant que /data n'a pas été décrypté et monté.

Pour déclencher ces actions, la propriété vold.decrypt est définie sur différentes chaînes . Pour arrêter et redémarrer les services, les commandes init sont:

  • class_reset : class_reset un service mais lui permet d'être redémarré avec class_start.
  • class_start : redémarre un service.
  • class_stop : class_stop un service et ajoute un indicateur SVC_DISABLED . Les services class_start ne répondent pas à class_start .

Les flux

Il existe quatre flux pour un appareil chiffré. Un périphérique est chiffré une seule fois, puis suit un flux de démarrage normal.

  • Crypter un appareil précédemment non crypté:
    • Crypter un nouvel appareil avec forceencrypt : cryptage obligatoire au premier démarrage (à partir d'Android L).
    • Crypter un appareil existant: cryptage lancé par l'utilisateur (Android K et versions antérieures).
  • Démarrez un appareil chiffré:
    • Démarrage d'un appareil chiffré sans mot de passe: démarrage d'un appareil chiffré sans mot de passe défini (pertinent pour les appareils exécutant Android 5.0 et versions ultérieures).
    • Démarrage d'un appareil chiffré avec un mot de passe: démarrage d'un appareil chiffré avec un mot de passe défini.

En plus de ces flux, l'appareil peut également ne pas crypter /data . Chacun des flux est expliqué en détail ci-dessous.

Crypter un nouvel appareil avec forceencrypt

Il s'agit du premier démarrage normal pour un appareil Android 5.0.

  1. Détecter le système de fichiers non chiffré avec l'indicateur forceencrypt

    /data n'est pas chiffré mais doit l'être car forceencrypt le commande. Démonter /data .

  2. Commencer le chiffrement /data

    vold.decrypt = "trigger_encryption" déclenche init.rc , ce qui vold à crypter /data sans mot de passe. (Aucun n'est défini car il doit s'agir d'un nouveau périphérique.)

  3. Monter tmpfs

    vold monte un tmpfs /data (en utilisant les options tmpfs de ro.crypto.tmpfs_options ) et définit la propriété vold.encrypt_progress sur 0. vold prépare le tmpfs /data pour démarrer un système chiffré et définit la propriété vold.decrypt sur: trigger_restart_min_framework

  4. Apportez un cadre pour montrer les progrès

    Étant donné que l'appareil n'a pratiquement pas de données à crypter, la barre de progression n'apparaîtra souvent pas car le cryptage se produit si rapidement. Voir Crypter un appareil existant pour plus de détails sur l'interface utilisateur de progression.

  5. Lorsque /data est chiffré, supprimez le framework

    vold définit vold.decrypt sur trigger_default_encryption qui démarre le service defaultcrypto . (Cela démarre le flux ci-dessous pour le montage des données utilisateur cryptées par défaut.) trigger_default_encryption vérifie le type de cryptage pour voir si /data est crypté avec ou sans mot de passe. Étant donné que les appareils Android 5.0 sont chiffrés au premier démarrage, aucun mot de passe ne doit être défini; donc nous déchiffrons et montons /data .

  6. Monter /data

    init monte ensuite /data sur un RAMDisk tmpfs en utilisant les paramètres qu'il récupère de ro.crypto.tmpfs_options , qui est défini dans init.rc

  7. Démarrer le cadre

    Définissez vold sur trigger_restart_framework , qui continue le processus de démarrage habituel.

Crypter un appareil existant

C'est ce qui se produit lorsque vous cryptez un appareil Android K non chiffré ou antérieur qui a été migré vers L.

Ce processus est lancé par l'utilisateur et est appelé «cryptage en place» dans le code. Lorsqu'un utilisateur choisit de crypter un appareil, l'interface utilisateur s'assure que la batterie est complètement chargée et que l'adaptateur secteur est branché afin qu'il y ait suffisamment d'énergie pour terminer le processus de cryptage.

Avertissement: si l'appareil tombe en panne de courant et s'éteint avant d'avoir terminé le chiffrement, les données du fichier restent dans un état partiellement chiffré. L'appareil doit être réinitialisé aux paramètres d'usine et toutes les données sont perdues.

Pour activer le cryptage en place, vold démarre une boucle pour lire chaque secteur du périphérique bloc réel, puis l'écrire sur le périphérique bloc crypto. vold vérifie si un secteur est en cours d'utilisation avant de le lire et de l'écrire, ce qui accélère le chiffrement sur un nouvel appareil qui ne contient que peu ou pas de données.

État du dispositif: Set ro.crypto.state = "unencrypted" et exécuter le on nonencrypted d' init déclencheur pour poursuivre le démarrage.

  1. Vérifier le mot de passe

    L'interface utilisateur appelle vold avec la commande cryptfs enablecrypto inplacepasswd est le mot de passe de l'écran de verrouillage de l'utilisateur.

  2. Démontez le cadre

    vold vérifie les erreurs, renvoie -1 s'il ne peut pas chiffrer et affiche une raison dans le journal. S'il peut chiffrer, il définit la propriété vold.decrypt sur trigger_shutdown_framework . Cela amène init.rc à arrêter les services dans les classes late_start et main .

  3. Créer un pied de page crypto
  4. Créer un fichier de fil d'Ariane
  5. Redémarrer
  6. Détecter le fichier de fil d'Ariane
  7. Commencer le chiffrement /data

    vold configure ensuite le mappage cryptographique, qui crée un périphérique de bloc de cryptage virtuel qui mappe sur le périphérique de bloc réel mais crypte chaque secteur au fur et à mesure qu'il est écrit, et déchiffre chaque secteur au fur et à mesure de sa lecture. vold crée et écrit ensuite les métadonnées cryptographiques.

  8. Pendant le chiffrement, montez tmpfs

    vold monte un tmpfs /data (en utilisant les options tmpfs de ro.crypto.tmpfs_options ) et définit la propriété vold.encrypt_progress sur 0. vold prépare le tmpfs /data pour démarrer un système chiffré et définit la propriété vold.decrypt sur: trigger_restart_min_framework

  9. Apportez un cadre pour montrer les progrès

    trigger_restart_min_framework amène init.rc à démarrer la classe main de services. Lorsque le framework voit que vold.encrypt_progress est défini sur 0, il affiche l'interface utilisateur de la barre de progression, qui interroge cette propriété toutes les cinq secondes et met à jour une barre de progression. La boucle de chiffrement met à jour vold.encrypt_progress chaque fois qu'elle crypte un autre pourcentage de la partition.

  10. Lorsque /data est crypté, mettez à jour le pied de page crypto

    Lorsque /data est chiffré avec succès, vold efface l'indicateur ENCRYPTION_IN_PROGRESS dans les métadonnées.

    Lorsque l'appareil est déverrouillé avec succès, le mot de passe est ensuite utilisé pour crypter la clé principale et le pied de page cryptographique est mis à jour.

    Si le redémarrage échoue pour une raison quelconque, vold définit la propriété vold.encrypt_progress sur error_reboot_failed et l'interface utilisateur doit afficher un message demandant à l'utilisateur d'appuyer sur un bouton pour redémarrer. Cela ne devrait jamais se produire.

Démarrer un appareil chiffré avec le chiffrement par défaut

C'est ce qui se passe lorsque vous démarrez un appareil chiffré sans mot de passe. Étant donné que les appareils Android 5.0 sont chiffrés au premier démarrage, aucun mot de passe ne doit être défini et il s'agit donc de l'état de chiffrement par défaut .

  1. Détecter les /data chiffrées sans mot de passe

    Détectez que l'appareil Android est chiffré car /data ne peut pas être monté et l'un des indicateurs encryptable ou forceencrypt est défini.

    vold définit vold.decrypt sur trigger_default_encryption , qui démarre le service defaultcrypto . trigger_default_encryption vérifie le type de chiffrement pour voir si /data est chiffré avec ou sans mot de passe.

  2. Décrypter / données

    Crée le périphérique dm-crypt sur le périphérique bloc afin que le périphérique soit prêt à être utilisé.

  3. Monter / données

    vold monte ensuite la partition réel /data déchiffrée, puis prépare la nouvelle partition. Il définit la propriété vold.post_fs_data_done sur 0, puis définit vold.decrypt sur trigger_post_fs_data . Cela oblige init.rc à exécuter ses commandes post-fs-data . Ils créeront tous les répertoires ou liens nécessaires, puis vold.post_fs_data_done sur 1.

    Une fois que vold voit le 1 dans cette propriété, il définit la propriété vold.decrypt sur: trigger_restart_framework. Cela oblige init.rc à redémarrer les services dans la classe main et à démarrer également les services dans la classe late_start pour la première fois depuis le démarrage.

  4. Démarrer le cadre

    Maintenant, le framework démarre tous ses services en utilisant les /data déchiffrées, et le système est prêt à être utilisé.

Démarrage d'un appareil chiffré sans chiffrement par défaut

C'est ce qui se produit lorsque vous démarrez un appareil chiffré avec un mot de passe défini. Le mot de passe de l'appareil peut être un code PIN, un modèle ou un mot de passe.

  1. Détecter l'appareil crypté avec un mot de passe

    Détectez que l'appareil Android est chiffré car l'indicateur ro.crypto.state = "encrypted"

    vold définit vold.decrypt sur trigger_restart_min_framework car /data est chiffré avec un mot de passe.

  2. Monter tmpfs

    init définit cinq propriétés pour enregistrer les options de montage initiales données pour /data avec les paramètres transmis depuis init.rc vold utilise ces propriétés pour configurer le mappage cryptographique:

    1. ro.crypto.fs_type
    2. ro.crypto.fs_real_blkdev
    3. ro.crypto.fs_mnt_point
    4. ro.crypto.fs_options
    5. ro.crypto.fs_flags (numéro hexadécimal à 8 chiffres ASCII précédé de 0x)
  3. Démarrer le framework pour demander le mot de passe

    Le framework démarre et voit que vold.decrypt est défini sur trigger_restart_min_framework . Cela indique au framework qu'il démarre sur un disque tmpfs /data et qu'il doit obtenir le mot de passe utilisateur.

    Cependant, il doit d'abord s'assurer que le disque a été correctement chiffré. Il envoie la commande cryptfs cryptocomplete à vold . vold renvoie 0 si le chiffrement s'est terminé avec succès, -1 en cas d'erreur interne ou -2 si le chiffrement n'a pas été exécuté avec succès. vold détermine cela en recherchant dans les métadonnées cryptographiques l'indicateur CRYPTO_ENCRYPTION_IN_PROGRESS . S'il est défini, le processus de cryptage a été interrompu et il n'y a pas de données utilisables sur l'appareil. Si vold renvoie une erreur, l'interface utilisateur doit afficher un message à l'utilisateur pour redémarrer et réinitialiser l'appareil aux paramètres d'usine, et donner à l'utilisateur un bouton sur lequel appuyer pour le faire.

  4. Décrypter les données avec mot de passe

    Une fois que cryptfs cryptocomplete réussit, le framework affiche une interface utilisateur demandant le mot de passe du disque. L'interface utilisateur vérifie le mot de passe en envoyant la commande cryptfs checkpw à vold . Si le mot de passe est correct (ce qui est déterminé en montant avec succès les /data déchiffrées à un emplacement temporaire, puis en les vold ), vold enregistre le nom du périphérique de bloc déchiffré dans la propriété ro.crypto.fs_crypto_blkdev et renvoie l'état 0 à l'interface utilisateur . Si le mot de passe est incorrect, il renvoie -1 à l'interface utilisateur.

  5. Arrêter le cadre

    L'interface utilisateur vold un graphique de démarrage cryptographique, puis appelle vold avec la commande cryptfs restart . vold définit la propriété vold.decrypt sur trigger_reset_main , ce qui oblige init.rc à faire class_reset main . Cela arrête tous les services de la classe principale, ce qui permet de démonter le tmpfs /data .

  6. Monter /data

    vold monte ensuite la partition réel /data déchiffrée et prépare la nouvelle partition (qui n'a peut-être jamais été préparée si elle a été chiffrée avec l'option wipe, qui n'est pas prise en charge lors de la première version). Il définit la propriété vold.post_fs_data_done sur 0, puis définit vold.decrypt sur trigger_post_fs_data . Cela oblige init.rc à exécuter ses commandes post-fs-data . Ils créeront tous les répertoires ou liens nécessaires, puis vold.post_fs_data_done sur 1. Une fois que vold voit le 1 dans cette propriété, il définit la propriété vold.decrypt sur trigger_restart_framework . Cela oblige init.rc à redémarrer les services dans la classe main et à démarrer également les services dans la classe late_start pour la première fois depuis le démarrage.

  7. Démarrer le cadre complet

    Maintenant, le framework démarre tous ses services en utilisant le système de fichiers décrypté /data , et le système est prêt à être utilisé.

Échec

Un appareil qui ne parvient pas à déchiffrer peut être défectueux pour plusieurs raisons. L'appareil commence par la série normale d'étapes pour démarrer:

  1. Détecter l'appareil crypté avec un mot de passe
  2. Monter tmpfs
  3. Démarrer le framework pour demander le mot de passe

Mais après l'ouverture du framework, l'appareil peut rencontrer des erreurs:

  • Le mot de passe correspond mais ne peut pas déchiffrer les données
  • L'utilisateur entre 30 fois un mauvais mot de passe

Si ces erreurs ne sont pas résolues, invitez l'utilisateur à effacer les paramètres d'usine :

Si vold détecte une erreur pendant le processus de cryptage, et si aucune donnée n'a encore été détruite et que le framework est opérationnel, vold définit la propriété vold.encrypt_progress sur error_not_encrypted . L'interface utilisateur invite l'utilisateur à redémarrer et lui signale que le processus de chiffrement n'a jamais démarré. Si l'erreur se produit après que le framework a été démantelé, mais avant que l'interface utilisateur de la barre de progression ne soit vold , vold redémarrera le système. Si le redémarrage échoue, il définit vold.encrypt_progress sur error_shutting_down et renvoie -1; mais il n'y aura rien pour attraper l'erreur. Cela ne devrait pas se produire.

Si vold détecte une erreur pendant le processus de chiffrement, il définit vold.encrypt_progress sur error_partially_encrypted et renvoie -1. L'interface utilisateur doit alors afficher un message indiquant que le cryptage a échoué et fournir un bouton permettant à l'utilisateur de réinitialiser l'appareil en usine.

Stockage de la clé cryptée

La clé cryptée est stockée dans les métadonnées cryptographiques. Le support matériel est mis en œuvre à l'aide de la capacité de signature TEE (Trusted Execution Environment). Auparavant, nous chiffrions la clé principale avec une clé générée en appliquant scrypt au mot de passe de l'utilisateur et au sel stocké. Afin de rendre la clé résistante aux attaques off-box, nous étendons cet algorithme en signant la clé résultante avec une clé TEE stockée. La signature résultante est ensuite transformée en une clé de longueur appropriée par une autre application de scrypt. Cette clé est ensuite utilisée pour crypter et décrypter la clé principale. Pour stocker cette clé:

  1. Générez une clé de chiffrement de disque (DEK) aléatoire de 16 octets et un sel de 16 octets.
  2. Appliquez scrypt au mot de passe utilisateur et au salt pour produire la clé intermédiaire 1 de 32 octets (IK1).
  3. Remplissez IK1 avec zéro octet à la taille de la clé privée liée au matériel (HBK). Plus précisément, nous remplissons comme: 00 || IK1 || 00..00; un octet zéro, 32 octets IK1, 223 octets zéro.
  4. Le signe a complété IK1 avec HBK pour produire un IK2 de 256 octets.
  5. Appliquez un scrypt sur IK2 et du sel (même sel que l'étape 2) pour produire un IK3 de 32 octets.
  6. Utilisez les 16 premiers octets de IK3 comme KEK et les 16 derniers octets comme IV.
  7. Crypter DEK avec AES_CBC, avec clé KEK et vecteur d'initialisation IV.

Changer le mot de passe

Lorsqu'un utilisateur choisit de modifier ou de supprimer son mot de passe dans les paramètres, l'interface utilisateur envoie la commande cryptfs changepw à vold et vold re-crypte la clé principale du disque avec le nouveau mot de passe.

Propriétés de chiffrement

vold et init communiquent entre eux en définissant des propriétés. Voici une liste des propriétés disponibles pour le chiffrement.

Propriétés Vold

Propriété La description
vold.decrypt trigger_encryption Cryptez le lecteur sans mot de passe.
vold.decrypt trigger_default_encryption Vérifiez le lecteur pour voir s'il est crypté sans mot de passe. Si c'est le cas, décryptez-le et montez-le, sinon définissez vold.decrypt sur trigger_restart_min_framework.
vold.decrypt trigger_reset_main Défini par vold pour arrêter l'interface utilisateur en demandant le mot de passe du disque.
vold.decrypt trigger_post_fs_data Défini par vold sur prep /data avec les répertoires nécessaires, et al.
vold.decrypt trigger_restart_framework Défini par vold pour démarrer le vrai framework et tous les services.
vold.decrypt trigger_shutdown_framework Défini par vold pour arrêter le framework complet pour démarrer le chiffrement.
vold.decrypt trigger_restart_min_framework Défini par vold pour démarrer l'interface utilisateur de la barre de progression pour le chiffrement ou demander le mot de passe, selon la valeur de ro.crypto.state .
vold.encrypt_progress Lorsque l'infrastructure démarre, si cette propriété est définie, entrez dans le mode d'interface utilisateur de la barre de progression.
vold.encrypt_progress 0 to 100 L'interface utilisateur de la barre de progression doit afficher la valeur de pourcentage définie.
vold.encrypt_progress error_partially_encrypted L'interface utilisateur de la barre de progression doit afficher un message indiquant que le cryptage a échoué et donner à l'utilisateur la possibilité de réinitialiser l'appareil en usine.
vold.encrypt_progress error_reboot_failed L'interface utilisateur de la barre de progression doit afficher un message indiquant que le cryptage est terminé et donner à l'utilisateur un bouton pour redémarrer l'appareil. Cette erreur ne devrait pas se produire.
vold.encrypt_progress error_not_encrypted L'interface utilisateur de la barre de progression doit afficher un message indiquant qu'une erreur s'est produite, qu'aucune donnée n'a été cryptée ou perdue, et donner à l'utilisateur un bouton pour redémarrer le système.
vold.encrypt_progress error_shutting_down L'interface utilisateur de la barre de progression n'est pas en cours d'exécution, il est donc difficile de savoir qui répondra à cette erreur. Et cela ne devrait jamais arriver de toute façon.
vold.post_fs_data_done 0 vold par vold juste avant de définir vold.decrypt sur trigger_post_fs_data .
vold.post_fs_data_done 1 init.rc par init.rc ou init.rc juste après avoir terminé la tâche post-fs-data .

propriétés init

Propriété La description
ro.crypto.fs_crypto_blkdev vold par la commande checkpw pour une utilisation ultérieure par la commande vold restart .
ro.crypto.state unencrypted Défini par init pour indiquer que ce système fonctionne avec un état non chiffré /data ro.crypto.state encrypted . Défini par init pour indiquer que ce système fonctionne avec un fichier /data .

ro.crypto.fs_type
ro.crypto.fs_real_blkdev
ro.crypto.fs_mnt_point
ro.crypto.fs_options
ro.crypto.fs_flags

Ces cinq propriétés sont définies par init lorsqu'il essaie de monter /data avec des paramètres transmis depuis init.rc vold utilise pour configurer le mappage cryptographique.
ro.crypto.tmpfs_options init.rc par init.rc avec les options que init doit utiliser lors du montage du système de fichiers tmpfs /data .

Actions d'initiation

on post-fs-data
on nonencrypted
on property:vold.decrypt=trigger_reset_main
on property:vold.decrypt=trigger_post_fs_data
on property:vold.decrypt=trigger_restart_min_framework
on property:vold.decrypt=trigger_restart_framework
on property:vold.decrypt=trigger_shutdown_framework
on property:vold.decrypt=trigger_encryption
on property:vold.decrypt=trigger_default_encryption