Je cite le manuel Android ici , mais:
REMARQUE:
La source que j'ai utilisée n'est pas directement pertinente pour Marshmallow mais concerne Lollipop et les versions supérieures.
TL: DR
Je vais répondre aux questions du PO maintenant. Les détails techniques suivront.
La clé de chiffrement par défaut provient d'une source matérielle (une puce similaire à un TPM) et du mot de passe par défaut d'AOSP défini comme default_password
dans le cryptfs.c
fichier source, voir ci-dessous.
Oui, pas seulement la valeur par défaut, mais tout mot de passe est transformé en clé et est stocké sur une puce de type TPM, appelée TEE (abréviation de "Trusted Execution Environment", voir ci-dessous pour plus de détails).
Un pirate disposant d'un accès UART / JTAG aux puces sur le SoC de l'appareil pourrait techniquement avoir accès à la clé TEE, ou un noyau personnalisé peut divulguer ces informations à un pirate. Certaines agences à 3 lettres dans les théories du complot peuvent éventuellement s'associer avec l'OEM pour obtenir ces noyaux non sécurisés utilisés dans les appareils de production, mais je ne mettrais pas beaucoup de magasins à côté. Encore une fois, consultez la dernière section de cette réponse pour plus de détails.
La seule chose qui empêche un pirate d'accéder à la clé est la quantité d'efforts nécessaires pour le faire.
- La vérification du hachage (somme de contrôle) du firmware (appelé "Verified Boot" par Google) est en fait effectuée sur et au-dessus de Lollipop par défaut (et est disponible à partir de JellyBean 4.3), par un module de noyau appelé
dm-verity
. Cependant, cela est indépendant du statut de chiffrement.
Source: guide de sécurité AOSP ici .
- À propos du processus impliqué dans le décryptage du système avec un mot de passe personnalisé, voir ci-dessous. Je vais juste vous dire ici que le mot de passe utilisateur est impliqué à la fois dans la création et l'utilisation de la clé de cryptage.
Aperçu
Au 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 du 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.c du projet Open Source Android .
Lorsque l'utilisateur définit le code PIN / passe ou le mot de passe sur l'appareil, seule la clé de 128 bits est rechiffrée et stockée. (c.-à-d. que les changements de code PIN / passe / modèle utilisateur ne provoquent PAS le rechiffrement de la partition de données utilisateur.)
Démarrage d'un appareil chiffré avec le chiffrement par défaut
C'est ce qui se produit 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.
- Détectez les données chiffrées / sans mot de passe
Détectez que l'appareil Android est crypté 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 defaultcrypto
service. trigger_default_encryption
vérifie le type de cryptage pour voir si / data est crypté avec ou sans mot de passe.
- Déchiffrer / données
Crée le dm-crypt
périphérique sur le périphérique bloc afin que le périphérique soit prêt à être utilisé.
- Montage / données
vold
monte ensuite la partition réelle / données 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 provoque l' init.rc
exécution de ses post-fs-data
commandes. Ils vont créer des répertoires ou des liens nécessaires et mis vold.post_fs_data_done
à 1
.
Une fois vold
voit le 1 dans cette propriété, il définit la propriété vold.decrypt
à: trigger_restart_framework
. Cela provoque init.rc
le redémarrage des services dans la classe main
et le démarrage des services dans la classe late_start pour la première fois depuis le démarrage.
- Cadre de démarrage
Maintenant, le framework démarre tous ses services en utilisant les données décryptées et le système est prêt à l'emploi.
Démarrage d'un appareil chiffré sans chiffrement par défaut
C'est ce qui se produit lorsque vous démarrez un appareil crypté avec un mot de passe défini. Le mot de passe de l'appareil peut être une broche, un motif ou un mot de passe.
- Détecter l'appareil crypté avec un mot de passe
Détectez que l'appareil Android est crypté car l'indicateur ro.crypto.state = "encrypted"
vold
est défini vold.decrypt
sur trigger_restart_min_framework
/ data est crypté avec un mot de passe.
- Monter tmpfs
init
définit cinq propriétés pour enregistrer les options de montage initiales données pour / data avec des paramètres transmis depuis init.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
(Numéro hexadécimal ASCII à 8 chiffres précédé de 0x)
- Démarrer le framework pour demander le mot de passe
Le cadre démarre et voit qu'il vold.decrypt
est réglé sur trigger_restart_min_framework
. Cela indique au framework qu'il démarre sur un tmpfs /data
disque 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 cryptage s'est terminé avec succès, -1 en cas d'erreur interne ou -2 si le cryptage n'a pas été effectué avec succès. vold
détermine cela en recherchant le CRYPTO_ENCRYPTION_IN_PROGRESS
drapeau dans les métadonnées cryptographiques . 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 le périphérique en usine, et donner à l'utilisateur un bouton à appuyer pour le faire.
- Déchiffrer les données avec un mot de passe
Une fois cryptfs cryptocomplete
réussi, 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 (qui est déterminé en montant avec succès le déchiffré /data
à un emplacement temporaire, puis en le démontant), 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.
- Arrêter le cadre
L'interface utilisateur met en place un graphique de démarrage crypto, puis appelle vold avec la commande cryptfs restart
. vold
définit la propriété vold.decrypt
à trigger_reset_main
, ce qui provoque le init.rc
faire class_reset main
. Cela arrête tous les services de la main
classe, ce qui permet de les tmpfs /data
démonter.
- Montage / données
vold
monte ensuite la /data
partition réelle déchiffrée et prépare la nouvelle partition (qui n'aurait peut-être jamais été préparée si elle avait été chiffrée avec l'option d'effacement, qui n'est pas prise en charge dans 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 provoque l' init.rc
exécution de son post-fs-data commands
. Ils vont créer des répertoires ou des liens nécessaires et mis vold.post_fs_data_done
à 1
. Une fois que le vold
voit 1
dans cette propriété, il définit la propriété vold.decrypt
sur trigger_restart_framework
. Cela provoque init.rc
le redémarrage des services en classe main
et le démarrage des services en classe late_start
pour la première fois depuis le démarrage.
- Démarrer le framework complet
Maintenant, le framework démarre tous ses services en utilisant le système de fichiers décrypté / données, et le système est prêt à l'emploi.
Stockage de la clé cryptée
La clé chiffrée est stockée dans les métadonnées cryptographiques. La sauvegarde matérielle est implémentée à 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é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 chiffrer et déchiffrer la clé principale. Pour stocker cette clé:
- Générez une clé de chiffrement de disque (DEK) aléatoire de 16 octets et un sel de 16 octets.
- Appliquez
scrypt
au mot de passe utilisateur et au sel pour produire la clé intermédiaire 32 octets 1 (IK1).
- 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.
- Signe rempli IK1 avec HBK pour produire 256 octets IK2.
- Appliquer
scrypt
sur IK2 et sel (même sel que l'étape 2) pour produire IK3 32 octets.
- Utilisez les 16 premiers octets de IK3 comme KEK et les 16 derniers octets comme IV.
- Chiffrez DEK avec AES_CBC, avec la clé KEK et le vecteur d'initialisation IV.