Cryptage 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 crypté, toutes les données créées par l'utilisateur sont automatiquement cryptées avant de les enregistrer sur le disque et toutes les lectures décryptent automatiquement les données avant de les renvoyer au processus d'appel.

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éation d'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 beaucoup de temps. Seuls les systèmes de fichiers ext4 et f2fs prennent actuellement en charge le cryptage rapide.
  • Ajouté le forceencrypt drapeau fstab pour chiffrer le 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é cryptée pour plus de détails.

Attention: Les appareils mis à niveau vers Android 5.0 et cryptées peuvent être retournés à un état non chiffré par remise à zéro des données d'usine. Les nouveaux appareils Android 5.0 chiffrés au premier démarrage ne peuvent pas revenir à un état non chiffré.

Fonctionnement du chiffrement complet du disque Android

Android chiffrement intégral du disque est basé sur dm-crypt , qui est une caractéristique du noyau qui fonctionne sur la couche de dispositif de bloc. De ce fait , les travaux de chiffrement avec MultiMediaCard intégré (eMMC) et les périphériques flash similaires qui se présentent au noyau comme périphériques de bloc. Le cryptage n'est pas possible avec YAFFS, qui communique directement avec une puce flash NAND brute.

L'algorithme de cryptage est 128 Advanced Encryption Standard (AES) avec cipher-block chaining (CBC) et ESSIV:SHA256. La clé principale est cryptée avec AES 128 bits via des appels à la bibliothèque OpenSSL. Vous devez utiliser 128 bits ou plus pour la clé (avec 256 étant facultatif).

Note: Les OEM peuvent utiliser pour chiffrer la clé maître 128 bits ou plus.

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

  • défaut
  • ÉPINGLER
  • le 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 l'Android Open Source Project cryptfs.cpp fichier.

Lorsque l'utilisateur définit le code PIN/le mot de passe ou le mot de passe sur l'appareil, seule la clé 128 bits est recryptée et stockée. (c. -à- utilisateur. PIN / pass / changements de modèle ne causent pas de re-cryptage des données utilisateurs.) Notez que périphérique géré peut être soumis à NIP, motif ou restrictions de mot de passe.

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

Pour crypter, décrypter ou effacer /data , /data ne doivent pas être montés. Toutefois, afin de montrer une interface utilisateur (UI), le cadre doit commencer et le cadre nécessite des /data exécuter. Pour résoudre ce casse - tête, 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 des la limitation que pour passer du système de fichiers temporaire au vrai /data système de fichiers, le système doit arrêter tous les processus avec les fichiers ouverts sur le système de fichiers temporaire et redémarrer ces processus sur le réel /data système de fichiers. Pour ce faire, tous les services doivent être dans l' un des trois groupes: core , main et late_start .

  • core : Ne jamais fermer après le démarrage.
  • main : Arrêter, puis redémarrez après le mot de passe du disque est entré.
  • late_start : Ne commence qu'après des /data a été décrypté et monté.

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

  • class_reset : Arrête un service , mais permet de redémarrer avec class_start.
  • class_start : Redémarre un service.
  • class_stop : Arrête un service et ajoute un SVC_DISABLED drapeau. Nous nous sommes arrêtés services ne répondent pas à class_start .

Les flux

Il existe quatre flux pour un appareil chiffré. Un appareil n'est chiffré qu'une seule fois, puis suit un flux de démarrage normal.

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

En plus de ces flux, le dispositif 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 cryptés avec forceencrypt drapeau

    /data ne sont pas chiffrées mais doit être parce que forceencrypt mandats qui lui sont . Démontez /data .

  2. Début cryptage /data

    vold.decrypt = "trigger_encryption" déclencheurs init.rc , ce qui entraînera vold pour crypter /data sans mot de passe. (Aucun n'est défini car il devrait s'agir d'un nouvel appareil.)

  3. Monter les 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 à 0. vold prepepares tmpfs /data pour le démarrage d' un système crypté et définit la propriété vold.decrypt à: trigger_restart_min_framework

  4. Afficher le cadre pour montrer les progrès

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

  5. Lorsque /data sont cryptées, descendre le cadre

    vold ensembles vold.decrypt à trigger_default_encryption qui démarre le defaultcrypto services. (Cela commence le flux ci - dessous pour monter un défaut userdata crypté.) trigger_default_encryption vérifie le type de cryptage pour voir si /data sont cryptées 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 ; par conséquent , nous décryptons et le mont /data .

  6. Mont /data

    init puis monte /data sur un disque virtuel en utilisant les paramètres tmpfs il ramasse de ro.crypto.tmpfs_options , qui est situé dans init.rc .

  7. Démarrer le cadre

    Set vold à trigger_restart_framework , qui poursuit le processus de démarrage habituelle.

Crypter un appareil existant

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

Ce processus est lancé par l'utilisateur et est appelé « chiffrement 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 de puissance pour terminer le processus de cryptage.

Attention: Si l'appareil est à court de puissance et se ferme vers le bas avant qu'il ait fini encryptage, les données de fichier est laissé dans un état partiellement crypté. L'appareil doit être réinitialisé aux paramètres d'usine et toutes les données sont perdues.

Pour activer le cryptage inplace, vold démarre une boucle pour lire chaque secteur du dispositif de bloc réel puis écrire sur le périphérique bloc Crypto. vold vérifie si un secteur est utilisé avant de lire et écrire, ce qui rend le cryptage beaucoup plus rapide sur un nouvel appareil qui a peu à aucune donnée.

É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émonter le cadre

    vold vérifie les erreurs, renvoie -1 si elle ne peut pas chiffrer, et imprime une raison dans le journal. Si elle ne peut chiffrer, il définit la propriété vold.decrypt à trigger_shutdown_framework . Cela provoque init.rc d'arrêter les services dans les classes late_start et main .

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

    vold établit alors la cartographie Crypto, ce qui crée un périphérique bloc Crypto virtuel des cartes sur le périphérique bloc réel , mais chaque secteur encrypte comme il est écrit, et déchiffre chaque secteur comme il est lu. vold crée alors et écrit les métadonnées Crypto.

  8. Pendant le cryptage, montez tmpfs

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

  9. Afficher le cadre pour montrer les progrès

    trigger_restart_min_framework provoque init.rc pour démarrer la main classe de services. Lorsque le cadre voit que vold.encrypt_progress est réglé sur 0, il affiche la barre de progression interface utilisateur, qui interroge cette propriété toutes les cinq secondes et met à jour une barre de progression. Les mises à jour de la boucle de cryptage vold.encrypt_progress chaque fois qu'il encrypte un autre pour cent de la partition.

  10. Lorsque /data sont cryptées, mettez à jour le pied de page Crypto

    Lorsque /data sont cryptées avec succès, vold efface le drapeau 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 crypto est mis à jour.

    Si le redémarrage échoue pour une raison quelconque, vold définit la propriété vold.encrypt_progress à 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émarrage d'un appareil crypté avec le cryptage par défaut

C'est ce qui se passe lorsque vous démarrez un appareil crypté sans mot de passe. Parce que les appareils Android 5.0 sont chiffrés au premier démarrage, il devrait y avoir aucun mot de passe de jeu et donc c'est l'état de chiffrement par défaut.

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

    Détecter que le dispositif parce que les applications sont cryptées /data ne peuvent pas être montés et l' un des drapeaux encryptable ou forceencrypt est défini.

    vold ensembles vold.decrypt à trigger_default_encryption , qui démarre le defaultcrypto service. trigger_default_encryption vérifie le type de cryptage pour voir si /data sont cryptées avec ou sans mot de passe.

  2. Décrypter /données

    Crée le dm-crypt dispositif sur le dispositif de bloc de sorte que le dispositif est prêt à être utilisé.

  3. Monter /données

    vold puis monte le déchiffré réel /data partition et prépare ensuite la nouvelle partition. Il définit la propriété vold.post_fs_data_done à 0 et définit ensuite vold.decrypt à trigger_post_fs_data . Cela provoque init.rc d'exécuter ses post-fs-data des commandes. Ils vont créer des répertoires ou des liens nécessaires et puis ensemble vold.post_fs_data_done à 1.

    Une fois que vold voit le 1 dans cette propriété, il définit la propriété vold.decrypt à: trigger_restart_framework. Cela provoque init.rc pour lancer des services dans la classe main à nouveau et commencer également des services en classe late_start pour la première fois depuis le démarrage.

  4. Démarrer le cadre

    Maintenant , les bottes cadre tous ses services en utilisant les décryptées /data , et le système est prêt à l' emploi.

Démarrage d'un appareil crypté sans cryptage par défaut

C'est ce qui se passe lorsque vous démarrez un appareil crypté avec un mot de passe défini. Le mot de passe de l'appareil peut être une épingle, un motif ou un mot de passe.

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

    Détectera que l'appareil Android est crypté , car le drapeau ro.crypto.state = "encrypted"

    vold ensembles vold.decrypt à trigger_restart_min_framework car les /data sont cryptées avec un mot de passe.

  2. Monter les tmpfs

    init fixe cinq propriétés pour enregistrer les options de montage initiales données pour /data avec des paramètres transmis de init.rc . vold utilise ces propriétés pour configurer la cartographie Crypto:

    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 (ASCII 8 chiffres nombre hexadécimal précédé de 0x)
  3. Démarrer le framework pour demander le mot de passe

    Le cadre démarre et voit que vold.decrypt est réglé sur trigger_restart_min_framework . Cela indique le cadre qu'il démarre sur un tmpfs /data disque et dont il a besoin pour obtenir le mot de passe de l' 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 cryptage a été complété avec succès, -1 en cas d' erreur interne ou -2 si le cryptage n'a pas été complété avec succès. vold détermine en regardant dans les métadonnées pour la crypto CRYPTO_ENCRYPTION_IN_PROGRESS drapeau. S'il est défini, le processus de cryptage a été interrompu et il n'y a aucune donnée utilisable sur l'appareil. Si vold renvoie une erreur, l'interface utilisateur doit afficher un message à l'utilisateur de redémarrer et usine réinitialiser l'appareil, et donner à l'utilisateur un bouton à presser pour le faire.

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

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

  5. Arrêter le cadre

    Les puts de l' interface utilisateur jusqu'à un démarrage Crypto graphique et appelle ensuite vold avec la commande cryptfs restart . vold définit la propriété vold.decrypt à trigger_reset_main , ce qui provoque init.rc à faire class_reset main . Cela empêche tous les services dans la classe principale, ce qui permet aux tmpfs /data à être démonté.

  6. Mont /data

    vold puis monte le déchiffré réel /data partition et prépare la nouvelle partition (qui ne peut jamais avoir été préparé si elle a été chiffré avec l'option lingette, qui ne sont pas pris en charge sur la première version). Il définit la propriété vold.post_fs_data_done à 0 et définit ensuite vold.decrypt à trigger_post_fs_data . Cela provoque init.rc d'exécuter ses post-fs-data des commandes. Ils vont créer tous les répertoires nécessaires ou des liens, puis ensemble vold.post_fs_data_done à 1. Une fois que vold voit le 1 dans cette propriété, il définit la propriété vold.decrypt à trigger_restart_framework . Cela provoque init.rc pour lancer des services dans la classe main à nouveau et commencer également des services en classe late_start pour la première fois depuis le démarrage.

  7. Démarrer le cadre complet

    Maintenant , les bottes cadre tous ses services en utilisant le déchiffré /data système de fichiers, et le système est prêt à l' emploi.

É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 les tmpfs
  3. Démarrer le framework pour demander le mot de passe

Mais une fois le framework ouvert, l'appareil peut rencontrer des erreurs :

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

Si ces erreurs ne sont pas résolus, inviter l' utilisateur à effacer usine:

Si vold détecte une erreur au cours du processus de cryptage, et si aucune donnée n'a été détruit encore et le cadre est en place, vold définit la propriété vold.encrypt_progress à error_not_encrypted . L'interface utilisateur invite l'utilisateur à redémarrer et l'alerte que le processus de cryptage n'a jamais démarré. Si l'erreur se produit après que le cadre a été démoli, mais avant que la barre de progression interface utilisateur est en place, vold va redémarrer le système. Si le redémarrage échoue, il met vold.encrypt_progress à error_shutting_down et retourne -1; mais il n'y aura rien pour attraper l'erreur. Cela ne devrait pas se produire.

Si vold détecte une erreur au cours du processus de chiffrement, il met vold.encrypt_progress à error_partially_encrypted et retourne -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é chiffrée est stockée dans les métadonnées de chiffrement. La sauvegarde matérielle est mise en œuvre à l'aide de la capacité de signature de Trusted Execution Environment (TEE). Auparavant, nous cryptions 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ésiliente contre les 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 application supplémentaire de scrypt. Cette clé est ensuite utilisée pour chiffrer et déchiffrer 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 de l'utilisateur et au sel pour produire la clé intermédiaire 1 de 32 octets (IK1).
  3. Complétez IK1 avec zéro octet jusqu'à la taille de la clé privée liée au matériel (HBK). Spécifiquement, nous remplissons comme : 00 || IK1 || 00..00 ; un octet zéro, 32 octets IK1, 223 octets zéro.
  4. Signez IK1 rembourré avec HBK pour produire IK2 de 256 octets.
  5. Appliquez scrypt à IK2 et salt (le même sel qu'à 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 leur mot de passe dans les paramètres, l'interface utilisateur envoie la commande cryptfs changepw à vold , et vold rechiffre la clé principale du disque avec le nouveau mot de passe.

Propriétés de chiffrement

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

Propriétés de Vold

Biens La description
vold.decrypt trigger_encryption Chiffrez 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. Le cas échéant, Décrypter et monter, ensemble d' autre vold.decrypt à 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 pour préparer /data avec les répertoires nécessaires, et al.
vold.decrypt trigger_restart_framework Défini par vold pour démarrer le véritable 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 barre de progression pour le cryptage ou le mot de passe rapide, en fonction de la valeur de ro.crypto.state .
vold.encrypt_progress Au démarrage du framework, si cette propriété est définie, entrez dans le mode UI 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 aux paramètres d'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é chiffré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 ne s'exécute pas, il n'est donc pas clair qui répondra à cette erreur. Et cela ne devrait jamais arriver de toute façon.
vold.post_fs_data_done 0 Défini par vold juste avant la mise en vold.decrypt à trigger_post_fs_data .
vold.post_fs_data_done 1 Set par init.rc ou init.rc juste après avoir terminé la tâche post-fs-data .

propriétés d'initialisation

Biens La description
ro.crypto.fs_crypto_blkdev Défini par la vold commande checkpw pour une utilisation ultérieure par la vold commande restart .
ro.crypto.state unencrypted Set par init dire ce système est en cours d' exécution avec un non crypté /data ro.crypto.state encrypted . Défini par init dire ce système est en cours d' exécution avec un crypté /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 quand il essaie de monter /data avec les paramètres transmis depuis init.rc . vold utilise pour configurer la cartographie Crypto.
ro.crypto.tmpfs_options Set par init.rc avec les options d' initialisation doit utiliser lors du montage du tmpfs /data système de fichiers.

Actions d'initialisation

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