Device Encrypted Storage And Direct Boot Mode In Android
By: Lam Pham
Tags: Mobile, Android, AndroidDev, Mobile Security, Android Security

Device Encrypted Storage And Direct Boot Mode In Android

Photo by Meghraj Neupane on Unsplash

In Android, when a phone is powered on but the user has not unlocked the device yet, most user applications and user data are not accessible.

Prior to Android 7, the system was designed to be inactive during this state; no user action can take place, only system services could be launched normally. Fortunately, from Android 7, to respond to the demand of some particular functionalities like alarms or reminders, Google has introduced Direct Boot mode that enables a quick access to these components.

The purpose of Direct Boot mode is to get access to data when device is not unlocked.

But why is data not accessible when device is in this state?

1. Data encryption — FDE and FBE.

Android is actually one of the most-used Operating Systems. Besides potential vulnerabilities in software and hardware, Android also faces the risk of physical device loss.

Protecting user data even when the device is out of user’s control is one of the aims of Google Android Team.

To do that, they integrate a data encryption mechanism.

Basically, Android encrypts automatically all user data on the disk when the phone is powered off and uses user PIN/password/pattern to decrypt data when the user unlocks the phone after booting the device.

Just to be clear, it only encrypts user data which is the data in /data folder.

To do that, Android uses FDE and FBE mechanisms. In the context of this article, we don’t dive into the details of these methods; however, if you are curious about them as well as some other security models of Android, feel free to refer to this article for more information.

In other words, user data is unavailable by any means until the user logs in (only the first time after the phone is rebooted) with PIN/password/pattern. Event if the user doesn’t set a key lock, he still has to swipe the lock screen (but please lock your phone).

That’s the reason for the introduction of Direct Boot mode.

2. Direct Boot mode

Direct Boot, introduced from Android 7, is the new name for the moment after device performs a verified boot and before user get logged in using PIN or password.

In Android 6 and before, data is only stored in a default area where they remain credential-encrypted after finishing booting. This storage is called Credential Encrypted Storage(CES). You would have to unlock the phone to decrypt data and get the accessibility.

To support Direct Boot mode, Android 7 adds up a secondary storage which is known as Device Encrypted Storage (DES). Data in this storage is also encrypted using a different key than user PIN or password; this key is tied to the physical device and is available following a successful boot. Thus, the decryption process takes place as soon as the device is on and data is accessible right after that.

This is a very nice design from Google to keep things secured and convenient at the same time.

3. Make components executable in Direct Boot mode.

Apps or components aren’t, by default, allowed to run in Direct Boot mode. The only way to launch them is to declare in AndroidManifest the attribute android:directBootAware as true for these components:

<activity android:name=".MainActivity"

android:directBootAware="true"/>

If you want to actively listen to the boot process in order to launch components, you should register the BroadcastReceiver android.intent.action.LOCKED_BOOT_COMPLETED . This action is invoked while the device is still in “locked” state:

<activity android:name=".MainActivity"

android:directBootAware="true">

<intent-filter>

<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />

</intent-filter>

</activity>

This action requires RECEIVED_BOOT_COMPLETED permission:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

You can also subscribe to device unlocked state by registering this event:

<activity android:name=".MainActivity"

android:directBootAware="true">

<intent-filter>

<action android:name="android.intent.action.USER_UNLOCKED" />

</intent-filter>

</activity>

4. Store data in Device Encrypted Storage.

To get access to data in Direct Boot mode, we have to store data in DES. It’s pretty simple to do this. Just like the default storage manipulation, with DES, everything stays the same except a special context provided by calling createDeviceProtectedStorageContext() :

// create device protected storage context

val context = createDeviceProtectedStorageContext() // SharePreference

context.getSharedPreferences("DeviceProtectedStorage", Context.MODE_PRIVATE)



// Files

context.openFileOutput("sample.txt", MODE_PRIVATE) // Database

Room.databaseBuilder(context, AppDatabase::class.java, "database-name").build()

We can also migrate data from CES to DES :

// Migrate SharePreference file "token" from CE to DE storage

context.moveSharedPreferencesFrom(sourceContext,"token") // Migrate Database "database" from CE to DE storage context.moveDatabaseFrom(sourceContext,"database") // sourceContext : The source context which contains the existing shared preferences to move.

Actually, there isn’t any public api in Android framework to move a file from CE to DE storage (as for SharePreference and Database). However, we can use a simple work-around to achieve the goal:

val fileInCE = File("${context.dataDir}/files/$fileName")

val fileInDE = File("${context.createDeviceProtectedStorageContext().dataDir}/files/$fileName")

fileInCE.renameTo(fileInDE)

5. File hierarchy.

Since Credential Encrypted Storage and Device Encrypted Storage don’t use the same key to encrypt/decrypt data, they are isolated in different folders. While CES is located in /data/user , you can find DES in data/user_de :

File hierarchy

There are further filesystem isolations in /data/misc and /data/system .

5. Direct Boot pitfalls.

Direct Boot gives us the power to do some cool stuffs. However, fundamentally, it partially breaks the Android Security Models to support some use-cases. Therefore, it could be a trap if you don’t understand the concept correctly.

As a developer, we need to carefully decide where to store data.