Metadata Encryption | Android Open Source Project
Android 9 introduce defend for metadata encoding. With metadata encoding, a individual key award at kick clock encrypts whatever message is not encrypted by FBE. This key is protected by Keymaster, which in turn is protected by verify boot .
Metadata encoding is always enabled on adoptable storage whenever FBE is enabled. Metadata encoding can besides be enabled on home storage. Devices launched with Android 11 or higher must have metadata encoding on home memory enabled .
Implementation on internal storage
You can set up metadata encoding on the internal storehouse of modern devices by setting up the metadata
filesystem, changing the init sequence, and enabling metadata encoding in the device ‘s fstab file.
Prerequisites
Metadata encoding can entirely be set up when the datum partition is beginning formatted. As a resultant role, this have is only for new devices ; this is not something an OTA should change .
Metadata encoding requires that the dm-default-key
module be enabled in your kernel. In Android 11 and higher, dm-default-key
is supported by the Android common kernels, version 4.14 and higher. This version of dm-default-key
uses a hardware and vendor-independent encoding framework called blk-crypto .
To enable dm-default-key
, practice :
CONFIG_BLK_INLINE_ENCRYPTION=y CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y CONFIG_DM_DEFAULT_KEY=y
dm-default-key
uses inline encoding hardware ( hardware that encrypts/decrypts data while it is on the way to/from the repositing device ) when available. If you will not be using inline encoding hardware, it is besides necessity to enable a disengagement to the kernel ‘s cryptography API :
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
When not using inline encoding hardware you should besides enable any available CPU-based acceleration as recommended in the FBE documentation .
In Android 10 and lower, dm-default-key
was not supported by the Android common kernel. It was therefore up to vendors to implement dm-default-key
.
Set up metadata filesystem
Because nothing in the userdata partition can be read until the metadata encoding key is present, the partition table must set aside a separate partition called the “ metadata division ” for storing the keymaster blob that protect this key. The metadata partition should be 16MB .
fstab.hardware
must include an submission for the metadata filesystem that lives on that partition mounting it at /metadata
, including the formattable
flag to ensure it is formatted at boot time. The f2fs filesystem does not work on smaller partitions ; we recommend using ext4 alternatively. For exemplar :
/dev/block/bootdevice/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard wait,check,formattable
To ensure the /metadata
mount decimal point exists, add the be note to BoardConfig-common.mk
:
BOARD_USES_METADATA_PARTITION := true
Changes to the init sequence
When metadata encoding is used, vold
must be running before /data
is mounted. To ensure that it is started early enough, add the follow stanza to init.hardware.rc
:
# We need vold early for metadata encryption on early-fs start vold
Keymaster must be running and ready before init attempts to mount /data
.
init.hardware.rc
should already contain a mount_all
teaching which mounts /data
itself in the on
stanza. Before this line, add the directive to exec the
late-fswait_for_keymaster
service :
on late-fs … # Wait for keymaster exec_start wait_for_keymaster # Mount RW partitions which need run fsck mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --late
Switching on metadata encryption
ultimately add keydirectory=/metadata/vold/metadata_encryption
to the fs_mgr_flags column of the fstab
entrance for userdata
. For example, a full fstab argumentation might look like :
/dev/block/bootdevice/by-name/userdata /data f2fs noatime,nosuid,nodev,discard,inlinecrypt latemount,wait,check,fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized,keydirectory=/metadata/vold/metadata_encryption,quota,formattable
By default option, the metadata encoding algorithm on internal storage is AES-256-XTS. This can be overridden by setting the metadata_encryption
option, besides in the fs_mgr_flags column :
- On devices that lack AES acceleration, Adiantum encryption may be
enabled by settingmetadata_encryption=adiantum
. - On devices that support hardware-wrapped keys,
the metadata encryption key can be made hardware-wrapped by setting
metadata_encryption=aes-256-xts:wrappedkey_v0
(or
equivalentlymetadata_encryption=:wrappedkey_v0
, as
aes-256-xts
is the default algorithm).
Because the kernel interface to dm-default-key
changed in Android 11, you besides need to ensure that you have set the decline prize for PRODUCT_SHIPPING_API_LEVEL
in device.mk
. For exercise, if your device launches with Android 11 ( API level 30 ), device.mk
should contain :
PRODUCT_SHIPPING_API_LEVEL := 30
You can besides set the follow system property to force the manipulation of the new dm-default-key
API careless of shipping API grade :
PRODUCT_PROPERTY_OVERRIDES += \ ro.crypto.dm_default_key.options_format.version=2
Validation
To verify that metadata encoding is enabled and is working correctly, run the tests described below. besides be mindful of the coarse issues described below .
Tests
Start by running the surveil command to verify that metadata encoding is enabled on home storage :
adb root
adb shell dmctl table userdata
The output should be exchangeable to :
Targets in the device-mapper table for userdata: 0-4194304: default-key, aes-xts-plain64 - 0 252:2 0 3 allow_discards sector_size:4096 iv_large_sectors
If you overrode the default encoding settings by setting the metadata_encryption
option in the device ‘s fstab
, then the output will differ slightly from the above. For example, if you enabled Adiantum encoding, then the third base field will be xchacha12,aes-adiantum-plain64
alternatively of aes-xts-plain64
.
following, run vts_kernel_encryption_test to verify the correctness of metadata encoding and FBE :
atest vts_kernel_encryption_test
or :
vts-tradefed run vts -m vts_kernel_encryption_test
Common issues
During the call to mount_all
, which mounts the metadata-encrypted /data
partition, init
executes the vdc cock. The vdc tool connects to vold
over binder
to set up the metadata-encrypted device and mount the division. For the duration of this address, init
is blocked, and attempts to either read or set init
properties will block until mount_all
finishes. If, at this stage, any region of vold
‘s make is immediately or indirectly blocked on learn or setting a property, deadlock will result. It is crucial to ensure that vold
can complete the work of reading the keys, interacting with Keymaster, and mounting the data directory without interacting further with init
.
If Keymaster is not fully started when mount_all
runs, it will not respond to vold
until it has read sealed properties from init
, resulting in precisely the deadlock described. Placing exec_start wait_for_keymaster
above the relevant mount_all
invocation as set out ensures that Keymaster is fully running in advance and so avoids this deadlock .
Configuration on adoptable storage
Since Android 9, a mannequin of metadata encoding is always enabled on adoptable storage whenever FBE is enabled, evening when metadata encoding is not enabled on inner storage .
In AOSP, there are two implementations of metadata encoding on adoptable memory : a deprecate one based on dm-crypt
, and a newer one based on dm-default-key
. To ensure that the chastise execution is selected for your device, ensure that you have set the right value for PRODUCT_SHIPPING_API_LEVEL
in device.mk
. For example, if your device launches with Android 11 ( API level 30 ), device.mk
should contain :
PRODUCT_SHIPPING_API_LEVEL := 30
You can besides set the pursue system properties to force the practice of the newfangled volume metadata encoding method ( and the new default FBE policy version ) careless of shipping API level :
PRODUCT_PROPERTY_OVERRIDES += \ ro.crypto.volume.metadata.method=dm-default-key \ ro.crypto.dm_default_key.options_format.version=2 \ ro.crypto.volume.options=::v2
Current method
On devices launching with Android 11 or higher, metadata encoding on adoptable storage uses the dm-default-key
kernel module, just like on inner storage. See the prerequisites above for which kernel shape options to enable. Note that inline encoding hardware that works on the device ‘s internal storage may be unavailable on adoptable storage, and therefore CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
may be required .
By nonpayment, the dm-default-key
volume metadata encoding method acting uses the AES-256-XTS encoding algorithm with 4096-byte crypto sectors. The algorithm can be overridden by setting the ro.crypto.volume.metadata.encryption
system property. This place ‘s value has the same syntax as the metadata_encryption
fstab option described above. For example, on devices that lack AES acceleration, Adiantum encoding may be enabled by setting ro.crypto.volume.metadata.encryption=adiantum
.
Legacy method
On devices launching with Android 10 or lower, metadata encoding on adoptable repositing uses the dm-crypt
kernel module preferably than dm-default-key
:
CONFIG_DM_CRYPT=y
Unlike the dm-default-key
method, the dm-crypt
method acting causes file contents to be encrypted twice : once with a FBE key and once with the metadata encoding keystone. This double encoding reduces performance and is not required to achieve the security goals of metadata encoding, since Android ensures that FBE keys are at least equally hard to compromise as the metadata encoding key. Vendors can make kernel customizations to avoid the double encoding, in particular by implementing the allow_encrypt_override
choice which Android will pass to dm-crypt
when the system property ro.crypto.allow_encrypt_override
is set to true
. These customizations are not supported by the Android common kernel .
By default, the dm-crypt
volume metadata encoding method acting uses the AES-128-CBC encoding algorithm with ESSIV and 512-byte crypto sectors. This can be overridden by setting the keep up system properties ( which are besides used for FDE ) :
ro.crypto.fde_algorithm
selects the metadata encryption
algorithm. The choices areaes-128-cbc
and
adiantum
. Adiantum may be used only if the
device lacks AES acceleration.ro.crypto.fde_sector_size
selects the crypto sector size.
The choices are 512, 1024, 2048, and 4096. For Adiantum encryption, use
4096.