Le Full-Disk Encryption est le processus de codage de toutes les données utilisateur sur un appareil Android en utilisant 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 engager sur le disque et toutes les lectures décryptent automatiquement les données avant de les renvoyer au processus d’appel.
Le cryptage complet du disque a été introduit dans Android en 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 beaucoup de temps. Seuls les systèmes de fichiers ext4 et f2fs supportent actuellement le cryptage rapide.
- Ajouté l’indicateur
forceencrypt
fstab pour crypter au premier démarrage. - Ajouté le support des motifs et du chiffrement sans mot de passe.
- Ajouté le stockage soutenu par le matériel de la clé de chiffrement en utilisant 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 et ensuite chiffrés peuvent être remis dans un état non chiffré par une réinitialisation des données d’usine. Les nouveaux appareils Android 5.0 cryptés au premier démarrage ne peuvent pas être ramenés à un état non crypté.
- Comment fonctionne le cryptage de disque complet Android
- Flows
- Crypter un nouveau dispositif avec forceencrypt
- Chiffrer un appareil existant
- Démarrer un appareil crypté avec un cryptage par défaut
- Démarrage d’un périphérique crypté sans cryptage par défaut
- Échec
- Stockage de la clé chiffrée
- Changement du mot de passe
- Propriétés de chiffrement
- Vold properties
- init properties
- Actions init
Comment fonctionne le cryptage de disque complet Android
Le cryptage de disque complet Android est basé sur dm-crypt
, qui est une fonctionnalité du noyau qui fonctionne à la couche de périphérique de bloc. Pour cette raison, le cryptage fonctionne avec Embedded MultiMediaCard (eMMC) et des dispositifs flash similaires qui se présentent au noyau comme des dispositifs de bloc. Le cryptage n’est pas possible avec YAFFS, qui parle directement à une puce flash NAND brute.
L’algorithme de chiffrement est 128 Advanced Encryption Standard (AES) avec un 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).
Note : les OEM peuvent utiliser 128 bits ou plus pour chiffrer la clé maîtresse.
Dans la version Android 5.0, il existe quatre types d’états de chiffrement :
- défaut
- PIN
- mot de passe
- pattern
Au premier démarrage, l’appareil crée une clé maîtresse de 128 bits générée de façon aléatoire, puis la hachure 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é par un TEE (tel que TrustZone),qui utilise un hachage de la signature pour chiffrer la clé maîtresse.
Vous pouvez trouver le mot de passe par défaut défini dans le projet Android Open Source cryptfs.cppfile.
Lorsque l’utilisateur définit le PIN/pass ou le mot de passe sur l’appareil, seule la clé de 128 bits est re-cryptée et stockée. (ie. les changements de PIN/pass/mot de passe de l’utilisateur ne causent PAS le re-cryptage des données de l’utilisateur.) Notez que les dispositifs gérés peuvent être soumis à des restrictions de PIN, de motif ou de mot de passe.
Le cryptage 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 signaler l’état, demander un mot de passe ou demander une réinitialisation en cas d’erreur fatale. Pour invoquer les fonctionnalités de chiffrement dans vold
, le système utilise les commandes cryptfs
de l’outil de ligne de commandevdc
: checkpw
,restart
, enablecrypto
, changepw
,cryptocomplete
, verifypw
, setfield
,getfield
, mountdefaultencrypted
, getpwtype
,getpw
, et clearpw
.
Pour chiffrer, déchiffrer ou effacer /data
, /data
ne doit pas être monté. Cependant, afin d’afficher une interface utilisateur (UI), le framework doit démarrer et le framework a besoin de /data
pour fonctionner. Pour résoudre cette énigme, un système de fichiers temporaire est monté sur /data
, ce qui permet à Android de demander des mots de passe, d’afficher la progression ou de suggérer un nettoyage des données si nécessaire. Cela impose une limitation : pour passer du système de fichiers temporaire au vrai système de fichiers /data
, le système doit arrêter tous les processus ayant des fichiers ouverts sur le système de fichiers temporaire et redémarrer ces processus sur le vrai système de fichiers /data
. Pour ce faire, tous les services doivent être dans l’un des trois groupes suivants : core
, main
, etlate_start
.
-
core
: Ne jamais s’arrêter après le démarrage. -
main
: S’arrêter puis redémarrer après la saisie du mot de passe du disque. -
late_start
: Ne démarre pas avant que/data
ait été décrypté et monté.
Pour déclencher ces actions, la propriété vold.decrypt
est définie sur diverses chaînes de caractères.Pour tuer et redémarrer les services, les commandes init
sont :
-
class_reset
: Arrête un service mais permet de le redémarrer avec class_start. -
class_start
: Redémarre un service. -
class_stop
: Arrête un service et ajoute un drapeauSVC_DISABLED
. Les services arrêtés ne répondent pas àclass_start
.
Flows
Il existe quatre flux pour un périphérique crypté. Un périphérique est crypté une seule foiset suit ensuite un flux de démarrage normal.
- Crypter un périphérique précédemment non crypté :
- Cryptez un nouveau périphérique avec
forceencrypt
: Cryptage obligatoire au premier démarrage (à partir d’Android L). - Crypter un appareil existant : Cryptage à l’initiative de l’utilisateur (Android K et antérieurs).
- Cryptez un nouveau périphérique avec
- Démarrer un appareil crypté :
- Démarrer un appareil crypté sans mot de passe : Démarrage d’un appareil crypté qui n’a pas de mot de passe défini (pertinent pour les appareils fonctionnant sous Android 5.0 et plus).
- Démarrer un périphérique crypté avec un mot de passe : Démarrage d’un périphérique crypté qui a un mot de passe défini.
En plus de ces flux, le dispositif peut également échouer à crypter /data
.Chacun des flux est expliqué en détail ci-dessous.
Crypter un nouveau dispositif avec forceencrypt
C’est le premier démarrage normal pour un dispositif Android 5.0 device.
- Detecter un système de fichiers non crypté avec le drapeau
forceencrypt
/data
n’est pas crypté mais doit l’être carforceencrypt
l’impose.Démonter/data
. - Commencez à crypter
/data
vold.decrypt = "trigger_encryption"
déclencheinit.rc
,ce qui amèneravold
à crypter/data
sans mot de passe.(Aucun est défini parce que ce devrait être un nouveau périphérique.) - Mount tmpfs
vold
monte un tmpfs/data
(en utilisant les options tmpfs dero.crypto.tmpfs_options
) et définit la propriétévold.encrypt_progress
à 0.vold
prépare le tmpfs/data
pour le démarrage d’un système crypté et définit la propriétévold.decrypt
à :trigger_restart_min_framework
- Faire apparaître le cadre pour montrer la progression
Parce que le périphérique n’a pratiquement pas de données à crypter, la barre de progression n’apparaîtra souvent pas réellement parce que le cryptage se produit si rapidement. VoirEncrypter un périphérique existant pour plus de détails sur l’interface utilisateur de progression.
- Lorsque
/data
est crypté, démonter le frameworkvold
définitvold.decrypt
àtrigger_default_encryption
qui démarre le servicedefaultcrypto
. (Cela lance le flux ci-dessous pour monter 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 apassword. Puisque les périphériques Android 5.0 sont chiffrés au premier démarrage, il ne devrait pas y avoir de mot de passe défini ; par conséquent, nous déchiffrons et montons/data
. - Mount
/data
init
monte ensuite/data
sur un RAMDisk tmpfs en utilisant des paramètres qu’il récupère dero.crypto.tmpfs_options
, qui est défini dansinit.rc
. - Démarre le framework
Règle
vold
àtrigger_restart_framework
, quicontinue le processus de démarrage habituel.
Chiffrer un appareil existant
C’est ce qui se passe lorsque vous chiffrez un appareil Android K ou antérieur non chiffré qui a été migré vers L.
Ce processus est initié par l’utilisateur et est appelé « chiffrement sur place » dans le code. Lorsqu’un utilisateur choisit de chiffrer 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 chiffrement.
Avertissement : Si l’appareil manque d’énergie et s’éteint avant d’avoir terminé le chiffrement, les données des fichiers sont laissées dans un état partiellement chiffré. Le dispositif doit être réinitialisé en usine et toutes les données sont perdues.
Pour activer le cryptage en place, vold
démarre une boucle pour lire chaque secteur du dispositif de bloc réel et ensuite l’écrire dans le dispositif de bloc cryptographique. vold
vérifie si un secteur est en cours d’utilisation avant de le lire et de l’écrire, ce qui rend le chiffrement beaucoup plus rapide sur un nouveau périphérique qui a peu ou pas de données.
État du périphérique : Définir ro.crypto.state = "unencrypted"
et exécuter le déclencheur on nonencrypted
init
pour continuer le démarrage.
- Vérifier le mot de passe
L’interface utilisateur appelle
vold
avec la commandecryptfs enablecrypto inplace
oùpasswd
est le mot de passe de l’écran de verrouillage de l’utilisateur. - Démonter le framework
vold
vérifie les erreurs, renvoie -1 s’il ne peut pas chiffrer, et imprime une raison dans le journal. S’il peut chiffrer, il définit la propriétévold.decrypt
àtrigger_shutdown_framework
. Cela amèneinit.rc
à arrêter les services des classeslate_start
etmain
. - Créer un pied de page cryptographique
- Créer un fichier fil d’Ariane
- Redémarrer
- Détecter le fichier fil d’Ariane
- Commencer à crypter
/data
vold
puis met en place le mappage cryptographique, qui crée un dispositif de bloc cryptographique virtuel qui se mappe sur le dispositif de bloc réel mais crypte chaque secteur lorsqu’il est écrit, et décrypte chaque secteur lorsqu’il est lu.vold
crée et écrit ensuite les métadonnées cryptographiques. - Pendant qu’il chiffre, mount tmpfs
vold
monte un tmpfs/data
(en utilisant les options tmpfs dero.crypto.tmpfs_options
) et définit la propriétévold.encrypt_progress
à 0.vold
prépare le tmpfs/data
pour le démarrage d’un système crypté et définit la propriétévold.decrypt
à :trigger_restart_min_framework
- Faire apparaître le framework pour montrer la progression
trigger_restart_min_framework
fait démarrerinit.rc
la classe de servicesmain
. Lorsque le framework voit quevold.encrypt_progress
est défini à 0, il fait apparaître 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 à jourvold.encrypt_progress
chaque fois qu’elle chiffre un autre pourcentage de la partition. - Lorsque
/data
est chiffré, mettre à jour le pied de page cryptographiqueLorsque
/data
est chiffré avec succès,vold
efface l’indicateurENCRYPTION_IN_PROGRESS
dans les métadonnées.Lorsque le dispositif est déverrouillé avec succès, le mot de passe est alors utilisé pour chiffrer 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
àerror_reboot_failed
et l’interface utilisateur devrait afficher un message demandant à l’utilisateur d’appuyer sur un bouton pour redémarrer. On ne s’attend pas à ce que cela se produise jamais.
Démarrer un appareil crypté avec un 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 cryptés au premier démarrage, il ne devrait pas y avoir de setpassword et c’est donc l’état de cryptage par défaut.
- Détecter un
/data
crypté sans mot de passeDétecter que le périphérique Android est crypté parce que
/data
ne peut pas être monté et qu’un des drapeauxencryptable
ouforceencrypt
est défini.vold
définitvold.decrypt
àtrigger_default_encryption
, ce qui démarre le servicedefaultcrypto
.trigger_default_encryption
vérifie le type de chiffrement pour voir si/data
est chiffré avec ou sans mot de passe. - Décrypte /data
Crée le périphérique
dm-crypt
sur le périphérique de bloc afin que le périphérique soit prêt à être utilisé. - Monte /data
vold
monte ensuite la partition réelle/data
décryptée puis prépare la nouvelle partition. Il définit la propriétévold.post_fs_data_done
à 0 puis définitvold.decrypt
àtrigger_post_fs_data
. Cela permet àinit.rc
d’exécuter ses commandespost-fs-data
. Elles créeront tous les répertoires ou liens nécessaires et mettront ensuitevold.post_fs_data_done
à 1.Une fois que
vold
voit le 1 dans cette propriété, il met la propriétévold.decrypt
à :trigger_restart_framework.
Ceci amèneinit.rc
à démarrer à nouveau les services de la classemain
et également à démarrer les services de la classelate_start
pour la première fois depuis le démarrage. - Démarrer le framework
Maintenant le framework démarre tous ses services en utilisant le
/data
décrypté,et le système est prêt à être utilisé.
Démarrage d’un périphérique crypté sans cryptage par défaut
C’est ce qui se passe lorsque vous démarrez un périphérique crypté qui a un setpassword. Le mot de passe du périphérique peut être un pin, un motif ou un mot de passe.
- Détecter un périphérique crypté avec un mot de passe
Détecter que le périphérique Android est crypté car le drapeau
ro.crypto.state = "encrypted"
vold
définitvold.decrypt
àtrigger_restart_min_framework
parce que/data
estcrypté avec un mot de passe. - Monter tmpfs
init
définit cinq propriétés pour enregistrer les options de montage initialesdonnées pour/data
avec les paramètres passés depuisinit.rc
.vold
utilise ces propriétés pour configurer le mappage cryptographique :-
ro.crypto.fs_type
-
ro.crypto.fs_real_blkdev
-
ro.crypto.fs_mnt_point
-
ro.crypto.fs_options
-
ro.crypto.fs_flags
(nombre hexagonal ASCII à 8 chiffres précédé de 0x)
-
- Démarrer le framework pour demander le mot de passe
Le framework démarre et voit que
vold.decrypt
est défini surtrigger_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 de l’utilisateur.En premier lieu, cependant, il doit s’assurer que le disque a été correctement crypté. Il envoie la commande
cryptfs cryptocomplete
àvold
.vold
renvoie 0 si le chiffrement a été effectué avec succès, -1 en cas d’erreur interne, ou-2 si le chiffrement n’a pas été effectué avec succès.vold
détermine cela en recherchant dans les métadonnées cryptographiques le drapeauCRYPTO_ENCRYPTION_IN_PROGRESS
. S’il est défini, le processus de chiffrement a été interrompu, et il y a des données nousables sur le périphérique. Sivold
renvoie une erreur, l’interface utilisateur devrait afficher un message à l’utilisateur pour redémarrer et réinitialiser l’appareil, et donner à l’utilisateur un bouton à presser pour le faire. - Décrypter les données avec le mot de passe
Une fois que
cryptfs cryptocomplete
est réussi, le cadre affiche une interface utilisateur demandant le mot de passe du disque. L’interface utilisateur vérifie le mot de passe en envoyant la commandecryptfs checkpw
àvold
. Si le mot de passe est correct (ce qui est déterminé en montant avec succès le/data
décrypté à un emplacement temporaire, puis en le démontant),vold
enregistre le nom du périphérique de bloc décrypté dans la propriétéro.crypto.fs_crypto_blkdev
et renvoie le statut 0 à l’interface utilisateur. Si le mot de passe est incorrect, il renvoie -1 à l’IU. - Arrêter le cadre
L’IU met en place un graphique de démarrage cryptographique et appelle ensuite
vold
avec la commandecryptfs restart
.vold
définit la propriétévold.decrypt
àtrigger_reset_main
, ce qui amèneinit.rc
à faireclass_reset main
. Cela arrête tous les services de la classe principale, ce qui permet de démonter le tmpfs/data
. - Mount
/data
vold
monte alors la partition réelle/data
déchiffrée et prépare la nouvelle partition (qui peut ne jamais avoir été préparée si elle a été chiffrée avec l’option wipe, qui n’est pas supportée sur la firstrelease). Il définit la propriétévold.post_fs_data_done
à 0 et ensuitevold.decrypt
àtrigger_post_fs_data
. Cela permet àinit.rc
d’exécuter ses commandespost-fs-data
. Elles créeront tous les répertoires ou liens nécessaires et mettrontvold.post_fs_data_done
à 1. Une fois quevold
voit le 1 dans cette propriété, il met la propriétévold.decrypt
àtrigger_restart_framework
. Ceci fait queinit.rc
démarre à nouveau les services de la classemain
et démarre également les services de la classelate_start
pour la première fois depuis le démarrage. - Start full framework
Maintenant le framework démarre tous ses services en utilisant le
/data
filesystem décrypté, et le système est prêt à être utilisé.
Échec
Un périphérique qui ne parvient pas à se décrypter peut être défectueux pour plusieurs raisons. Le périphérique démarre avec la série normale d’étapes pour démarrer :
- Détecter le périphérique crypté avec un mot de passe
- Monter tmpfs
- Démarrer le framework pour demander le mot de passe
Mais après l’ouverture du framework, le périphérique peut rencontrer certaines erreurs :
- Mot de passe correspond mais ne peut pas décrypter les données
- L’utilisateur entre un mauvais mot de passe 30 fois
Si ces erreurs ne sont pas résolues, demander à l’utilisateur de procéder à un effacement 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 en place, vold
définit la propriété vold.encrypt_progress
à error_not_encrypted
.L’interface utilisateur demande à l’utilisateur de redémarrer et l’avertit que le processus de cryptage n’a jamais commencé. Si l’erreur se produit après que le cadre a été démoli, mais avant que l’interface utilisateur de la barre de progression soit en place, vold
redémarre le système. Si le redémarrage échoue, il met vold.encrypt_progress
àerror_shutting_down
et renvoie -1 ; mais il n’y aura rien pour attraper l’erreur. On ne s’attend pas à ce que cela se produise.
Si vold
détecte une erreur pendant le processus de chiffrement, il met vold.encrypt_progress
à 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é chiffrée
La clé chiffrée est stockée dans les métadonnées cryptographiques. La sauvegarde matérielle est mise en œuvre en utilisant la capacité de signature de Trusted Execution Environment (TEE).Auparavant, nous avons chiffré 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 hors-boîte, 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é :
- Générer une clé de chiffrement de disque aléatoire de 16 octets (DEK) et un sel de 16 octets.
- Appliquer scrypt au mot de passe utilisateur et au sel pour produire la clé intermédiaire 1 (IK1) de 32 octets.
- Paqueter IK1 avec zéro octet à la taille de la clé privée liée au matériel (HBK).Plus précisément, nous pad comme : 00 || IK1 || 00..00 ; un octet zéro, 32 octets IK1, 223 octets zéro.
- Sign a paddé IK1 avec HBK pour produire IK2 de 256 octets.
- Appliquer scrypt à IK2 et sel (même sel que l’étape 2) pour produire 32 octets IK3.
- Utiliser les 16 premiers octets de IK3 comme KEK et les 16 derniers octets comme IV.
- Encryptez DEK avec AES_CBC, avec la clé KEK, et le vecteur d’initialisation IV.
Changement du mot de passe
Lorsqu’un utilisateur choisit de changer ou de supprimer son mot de passe dans les paramètres, l’interface utilisateur envoie la commande cryptfs changepw
à vold
, etvold
ré-encrypte la clé maîtresse 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 cryptage.
Vold properties
Property | Description |
---|---|
vold.decrypt trigger_encryption |
Cryptez le lecteur sans mot de passe. |
vold.decrypt trigger_default_encryption |
Vérifier le lecteur pour voir s’il est crypté sans mot de passe.S’il l’est, le décrypter et le monter,sinon définir vold.decrypt à trigger_restart_min_framework. |
vold.decrypt trigger_reset_main |
Set by vold to shutdown the UI asking for the disk password. |
vold.decrypt trigger_post_fs_data |
Set by vold to prep /data with necessary directories, and al. |
vold.decrypt trigger_restart_framework |
Set by vold to start the real framework and all services. |
vold.decrypt trigger_shutdown_framework |
Set by vold to shutdown the full framework to start encryption. |
vold.decrypt trigger_restart_min_framework |
Set by vold to start theprogress bar UI for encryption orprompt for password, depending on the value of ro.crypto.state . |
vold.encrypt_progress |
Lorsque le framework démarre, si cette propriété est définie, entre dans le mode de la barre de progression UI. |
vold.encrypt_progress 0 to 100 |
La barre de progression UI doit afficher la valeur du pourcentage défini. |
vold.encrypt_progress error_partially_encrypted |
L’interface utilisateur de la barre de progression devrait afficher un message indiquant que le cryptage a échoué, et donner à l’utilisateur une option pour réinitialiser l’appareil en usine. |
vold.encrypt_progress error_reboot_failed |
L’interface utilisateur de la barre de progression devrait 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 devrait afficher un message disant 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, donc on ne sait pas qui répondra à cette erreur. Et elle ne devrait jamais se produire de toute façon. |
vold.post_fs_data_done 0 |
Réglé par vold juste avant de régler vold.decrypt sur trigger_post_fs_data . |
vold.post_fs_data_done 1 |
Réglé par init.rc ou init.rc juste après avoir terminé la tâche post-fs-data . |
init properties
Property | Description |
---|---|
ro.crypto.fs_crypto_blkdev |
Set par la commande vold checkpw pour une utilisation ultérieure par la commande vold restart . |
ro.crypto.state unencrypted |
Défini par init pour dire que ce système fonctionne avec un /data ro.crypto.state encrypted non crypté. Défini par init pour dire que ce système fonctionne avec un /data crypté. |
|
Ces cinq propriétés sont définies par init lorsqu’il essaie de monter /data avec des paramètres transmis par init.rc . vold les utilise pour configurer le mappage cryptographique. |
ro.crypto.tmpfs_options |
Définies par init.rc avec les options que init doit utiliser lors du montage du système de fichiers tmpfs /data . |
Actions init
.