Qu'est-ce Direct Boot ?

A la découverte de Direct Boot : une des fonctionnalités d'Android 7.0 (Nougat) !

Comme son numéro l'indique, Android Nougat 7.0, est une version majeure du système d'exploitation maintenu et développé par Google. Notifications améliorées, multi-fenêtre, Doze on the go... le géant de recherche a mis l'accent sur les nouveautés.

Une des fonctionnalités méconnues se nomme Direct Boot. Les explications du père d'Android à son sujet sont loin d'être claires et cet article va essayer (en toute modestie) de vous expliquer les avantages et les inconvénients de cette nouvelle solution.

Une question de chiffrement

Le chiffrement des terminaux Android est loin d'être une nouvelle fonctionnalité, dans la mesure où elle fût introduite il y a plusieurs années déjà avec Android 3.0 (Honeycomb). Sans rentrer spécifiquement dans les détails, le chiffrement sur Android s'est amélioré de manière notable sur les versions 4.4 (KitKat), 5.0 (Lollipop) et enfin 7.0 (Nougat).

Le chiffrement des données implique logiquement une réduction des performances du système. Cela explique pourquoi Google a mis plusieurs années avant de rendre ce point obligatoire. Plus spécifiquement Android 5.0 (Lollipop) aurait dû voir l'ensemble des nouveaux terminaux chiffrés au premier démarrage, mais de nombreux constructeurs n'ont pas joué le jeu : Samsung en tête avec son Galaxy S6.

Cette situation s’est toutefois réglée depuis Android 6.0 (Marshmallow), puisque Google exige désormais que l'ensemble des nouveaux smartphones & tablettes soient directement chiffrés. En revanche, les terminaux qui n'étaient pas chiffrés sous Android 5.0, ne le seront pas sur les versions supérieures sans l'intervention de l'utilisateur.

Une situation problématique

Sur un smartphone, il faut différencier deux types de mot de passe : celui demandé à l'utilisateur pour déverrouiller son écran, de celui nécessaire pour déchiffrer.

Avant qu'Android 5.0 ne soit disponible, le chiffrement exigeait un mot de passe ou un code PIN. Celui-ci était alors demandé au démarrage du terminal sur un écran bloquant le lancement, appelé démarrage sécurisé. Sur cet écran, une version très limitée du système est en fonctionnement, car les données ne sont pas déchiffrées et sont donc inaccessibles.

Ecran de saisie du mot de passe pour déchiffrer (démarrage sécurisé)

Seulement ce système bridé et bloquant présente un problème : si votre application doit faire des actions au démarrage, il faudra forcément avoir saisi ce mot de passe et laissé le système démarrer.

Imaginez par exemple que le téléphone ait dû redémarrer de manière impromptue pendant la nuit, l'alarme pour vous réveiller le matin ne sera pas activée... et vous serez alors probablement en retard. Une situation qui aura mis plus de six années avant d’être résolue grâce à Android Nougat !

Le chiffrement sur Android

Depuis Lollipop

Depuis Android 5.0, il est possible de choisir un schéma en plus des codes pin et mot de passe pour le chiffrement. En toute logique, l'écran dit de démarrage sécurisé gère également la saisie du schéma.

Mais l'utilisateur peut également opter pour aucun verrouillage ou un déverrouillage par balayage (swipe). Dans ce cas, le téléphone chiffré démarrera sans même demander la saisie d'un mot de passe. Concrètement depuis Android 5.0, l'OS génère un mot de passe par défaut dès lors qu'il n'est pas un schéma / code pin / mot de passe. De cette manière, Android va automatiquement déchiffrer les données au démarrage sans l'intervention de l'utilisateur.

Depuis Android 5.0, l'écran de démarrage sécurisé est optionnel

Toujours depuis Android Lollipop, il est possible de désactiver l'écran de démarrage sécurisé, quel que soit le type de verrouillage sélectionné (y compris les schéma / code pin / mot de passe). Dans ce cas, le mot de passe utilisé pour chiffrer les données est celui par défaut du système, alors que celui pour déverrouiller le téléphone reste celui qu'aura sélectionné l'utilisateur. Adopter ce choix n'est pas recommandé, car le chiffrement des données perd grandement de son intérêt.

Depuis Nougat

Avant Android 7.0, le chiffrement était de type Full Disk Encryption (FDE), c'est-à-dire que toutes les données étaient chiffrées avec le même mot de passe. Depuis Nougat, on passe au chiffrement de type File-Based Encryption (FBE), c'est-à-dire que chaque fichier peut être chiffré différemment.

On pourrait croire que l'ensemble des terminaux sur Android Nougat vont automatiquement bénéficier du FBE. Mais ce n'est pas le cas ! En effet, si votre terminal a effectué une migration depuis une autre version d'Android qui utilisait le FDE, il conservera ce même type de chiffrement. Situation encore plus étrange, si vous flashez une factory image d'un Nexus 5X sur Nougat par exemple, vous aurez encore le FDE et non pas le FBE.

Il est toutefois possible de changer de type de chiffrement, mais cela nécessitera obligatoirement la perte des données, car l'ensemble des partitions sont réinitialisées. Pour cela, il faut passer par les options pour les développeurs pour effectuer ce changement :

  • Paramètres -> Options pour les développeurs -> Convertir en chiffrement basé sur un fichier

Il est également possible de le faire via adb :

adb reboot bootloader fastboot --wipe-and-use-fbe

Direct Boot

Android Nougat apporte la fonctionnalité nommée Direct Boot. Son rôle est de permettre aux applications Android qui le désirent, mais surtout le nécessitent, de pouvoir s'exécuter lors du processus de démarrage. La situation de blocage qu'il y avait jusqu'alors avec l'écran de démarrage sécurisé disparaît, car il n'existe plus.

Cette fonctionnalité concerne toutefois un nombre limité d'applications, car peu de cas de figures nécessitent un lancement avant que le stockage ne soit déchiffré. Concrètement, on note la présence de Direct Boot grâce à la notification "Des fonctionnalités peuvent être limitées" au lancement du terminal :

Sur Android Nougat, l'écran de démarrage sécurisé disparaît au profit de celui de Direct Boot. Les applications tierces peuvent par exemple publier des notifications.

Lancer son application pendant Direct Boot

Pour qu'une application puisse être exécutée pendant Direct Boot, il faut ajouter sur les receivers, services et providers l'attribut :

android:directBootAware="true"

Notez qu'il est possible de le mettre également sur les Activity, mais cela n'a aucun effet.

Enfin, il est également possible d'apposer l'attribut sur le tag application, mais seules les applications "système" peuvent l'utiliser. Pour les applications classiques (c'est-à-dire celles téléchargées par l'utilisateur sur le Google Play par exemple), l'ajout de cet attribut sur le tag application n'aura strictement aucun effet.

Outre l'attribut directBootAware, il faut également écouter un nouvel Intent : android.intent.action.LOCKED_BOOT_COMPLETED. Il signifie que le téléphone est lancé, mais que le stockage n'a pas encore été déchiffré.

Accéder au stockage pendant Direct Boot

Lorsque Direct Boot est actif, le stockage principal n'est pas disponible, car l'on attend le déchiffrement de ce dernier. La raison pour laquelle Android Nougat est passé vers le FBE (File-Based Encryption) est justement pour permettre aux applications d'avoir une partie du stockage utilisable au démarrage.

Pour cela, les application compatibles avec Direct Boot vont désormais devoir gérer deux stockages :

  • le Credential Encrypted (CE) storage : stockage classique, disponible uniquement après le premier déverrouillage
  • le Device Encrypted (DE) storage : nouveau stockage, disponible avant et après le premier déverrouillage

Le DE est donc un endroit où il ne faut surtout pas déposer des données personnelles, car elles sont publiques. Si vous perdez votre téléphone, une personne aura accès à ces informations. Il est donc important de ne stocker que le strict minimum, avant de continuer l'exécution normale via le Credential Encrypted storage.

Pour utiliser le DE, il faut tout simplement demander un nouveau contexte qui va pointer sur celui-ci :

Context context = ContextCompat.createDeviceProtectedStorageContext(srcContext);

Sur ce dernier, on peut ensuite effectuer les opérations sur le disque comme d'habitude.

Trois autres méthodes sont utiles :

ContextCompat.isDeviceProtectedStorage(context);

qui permet de savoir si le téléphone comporte une stockage DE, c'est-à-dire qu'il a le chiffrement FBE.

Enfin si vous voulez facilement déplacer une base de données ou les préférences d'un stockage à un autre, vous pouvez vous référer à ces instructions :

context.moveDatabaseFrom(srcContext, "dbName");
context.moveSharedPreferencesFrom(srcContext, "prefName");

Notez qu'à chaque fois l'intégralité des données sont déplacées. Si vous souhaitez faire du différentiel, c'est à vous de le gérer à la main.

Tester Direct Boot

Si vous avez un téléphone qui ne possède pas le bon type de chiffrement et que vous ne souhaitez pas perdre l'intégralité de vos données, il existe une émulation du mode Direct Boot. Pour cela, il faut exécuter les commandes suivantes :

  • adb shell sm set-emulate-fbe true : pour l'activer
  • adb shell sm set-emulate-fbe false : pour le désactiver

L'évolution des Intent

Avant Nougat

Jusqu'à présent, les applications pouvaient s'abonner à l'Intent android.intent.action.BOOT_COMPLETED afin qu'elles soient informées dès le démarrage du téléphone. Une restriction s'applique à son usage : l'utilisation de la permission android.permission.RECEIVE_BOOT_COMPLETED qui est automatiquement accordée même depuis Marshmallow.
Autre restriction depuis Android 3.1 (Honeycomb) : l'application doit avoir été lancée une première fois, sans quoi elle ne recevra jamais l'Intent.

Avant Nougat, cet Intent est envoyé par le système dès que l'animation de démarrage est terminée, c'est-à-dire une fois que le système est complètement lancé. A ce moment là, les données sur le disque sont forcément accessibles, car soit l'utilisateur a saisi le mot de passe de chiffrement, soit l'OS a utilisé celui par défaut.

Depuis Nougat

Sur Android 7.0 (Nougat), l'introduction de Direct Boot va envoyer dès le boot (après l'animation de démarrage) android.intent.action.LOCKED_BOOT_COMPLETED quel que soit le type de chiffrement. Ensuite, il faut distinguer deux cas : les terminaux qui utilisent le nouveau type chiffrement et les anciens.

Full Disk Encryption = pas de Direct Boot

Si le type de chiffrement est de type Full Disk Encryption (FDE), les terminaux ne bénéficient pas de Direct Boot. La situation est similaire aux versions précédentes d’Android et il est même possible d’avoir le fameux écran de démarrage sécurisé. L'Intent android.intent.action.BOOT_COMPLETED sera envoyé juste après celui de Direct Boot, car le stockage est déjà accessible.

Par conséquent, si le téléphone ou la tablette possède l'ancien type de chiffrement, il n'y a quasiment aucun changement de comportement.

File Based Encryption = Direct Boot

Si en revanche vous avez le File Based Encryption, l'Intent android.intent.action.BOOT_COMPLETED ne sera émis qu'à partir du moment où l'utilisateur aura donné le mot pour déchiffrer.

En résumé

Si l'on résume, il existe trois cas de figure :

Avant Nougat

Depuis Android 5.0, l'écran de démarrage sécurisé est optionnel

Avec Nougat et l'ancien chiffrement (FDE)

Avec Nougat et l'ancien chiffrement Full Disk Encryption

Avec Nougat et le nouveau chiffrement (FBE)

Avec Nougat et le nouveau chiffrement File-Based Encryption

L'arrivée de Direct Boot chamboule légèrement android.intent.action.BOOT_COMPLETED, mais l'ensemble des applications continueront de fonctionner, car l'information sera simplement transmise plus tard.

Direct Boot est donc une fonctionnalité qui ne concerne qu'une infime proportion des applications. En effet seules celles devant être lancées avant la saisie du mot de passe pour déchiffrer sont concernées. Par ailleurs le fait qu'il faille un chiffrement de type File Based Encryption va engendrer une propagation très lente de cette nouveauté (plusieurs années probablement).