Adiantum is an encryption method designed for devices running Android 9 and higher whose CPUs lack AES instructions. If you are shipping an ARM-based device with ARMv8 Cryptography Extensions or an x86-based device with AES-NI, you should not use Adiantum. AES is faster on those platforms.
For devices lacking these AES CPU instructions, Adiantum provides encryption on your device with very little performance overhead. For benchmarking numbers, see the Adiantum paper. For the benchmarking source to run on your hardware, see the Adiantum source on GitHub.
To enable Adiantum on a device running Android 9 or higher, you need to make kernel changes and userspace changes.
Kernel changes
Adiantum is supported by the Android common kernels, version 4.9 and higher.
If your device's kernel doesn't already have Adiantum support, cherry-pick the
changes listed below. If you're having trouble cherry-picking, devices using full-disk encryption (FDE) can exclude
the fscrypt:
patch.
Kernel version | Crypto and fscrypt patches | dm-crypt patch |
---|---|---|
4.19 | 4.19 kernel | dm-crypt patch
|
4.14 | 4.14 kernel | dm-crypt patch
|
4.9 | 4.9 kernel | dm-crypt patch
|
Enable Adiantum in your kernel
Android 11 and higher
If your device is launching with Android 11 or higher, enable the following settings in your device's kernel configuration:
CONFIG_CRYPTO_ADIANTUM=y CONFIG_FS_ENCRYPTION=y CONFIG_BLK_INLINE_ENCRYPTION=y CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y CONFIG_DM_DEFAULT_KEY=y
If your device is running a 32-bit ARM kernel, also enable NEON instructions to improve performance:
CONFIG_KERNEL_MODE_NEON=y CONFIG_CRYPTO_AES_ARM=y CONFIG_CRYPTO_CHACHA20_NEON=y CONFIG_CRYPTO_NHPOLY1305_NEON=y
Android 9 and 10
If your device is launching with Android 9 or 10, then slightly different kernel configuration settings are needed. Enable the following settings:
CONFIG_CRYPTO_ADIANTUM=y CONFIG_DM_CRYPT=y
If your device uses file-based encryption, also enable:
CONFIG_F2FS_FS_ENCRYPTION=y
Finally, if your device runs a 32-bit ARM kernel, enable NEON instructions to improve performance:
CONFIG_KERNEL_MODE_NEON=y CONFIG_CRYPTO_AES_ARM=y CONFIG_CRYPTO_CHACHA20_NEON=y CONFIG_CRYPTO_NHPOLY1305_NEON=y
Userspace changes
For devices running Android 10 or higher, the Adiantum userspace changes are already present.
For devices running Android 9, cherry-pick the following changes:
- cryptfs: Add Adiantum support
- cryptfs: Allow setting dm-crypt sector size
- cryptfs: round down dm-crypt device size to crypto sector boundary
- cryptfs: improve logging of dm-crypt device creation
- libfscrypt: Add Adiantum support
- fs_mgr_fstab: Add Adiantum support
Enable Adiantum in your device
First, ensure that your device has PRODUCT_SHIPPING_API_LEVEL
set
correctly to match the Android version it is launching with. For example, a
device launching with Android 11 must have
PRODUCT_SHIPPING_API_LEVEL := 30
. This is important because some of
the encryption settings have different defaults on different launch versions.
Devices with file-based encryption
To enable Adiantum file-based encryption on your device's internal storage, add
the following option to the last column (the fs_mgr_flags
column) of the row for the userdata
partition in the device's
fstab
file:
fileencryption=adiantum
If your device is launching with Android 11 or higher,
then enabling
metadata encryption is also required. To use Adiantum for metadata
encryption on internal storage, the fs_mgr_flags for
userdata
must also contain the following options:
metadata_encryption=adiantum,keydirectory=/metadata/vold/metadata_encryption
Next, enable Adiantum encryption on adoptable storage. To do this, set the
following system properties in PRODUCT_PROPERTY_OVERRIDES
:
For Android 11 and higher:
ro.crypto.volume.options=adiantum ro.crypto.volume.metadata.encryption=adiantum
For Android 9 and 10:
ro.crypto.volume.contents_mode=adiantum ro.crypto.volume.filenames_mode=adiantum ro.crypto.fde_algorithm=adiantum ro.crypto.fde_sector_size=4096
Finally, optionally add blk-crypto-fallback.num_keyslots=1
to the
kernel command line. This reduces memory usage slightly when Adiantum
metadata encryption is used. Before doing this, verify that the
inlinecrypt
mount option isn't specified in the fstab
.
If it is specified, remove it, since it isn't needed for Adiantum encryption,
and it causes performance problems when used in combination with
blk-crypto-fallback.num_keyslots=1
.
To verify that your implementation worked, take a bug report or run:
adb root
adb shell dmesg
If Adiantum is enabled correctly, you should see this in the kernel log:
fscrypt: Adiantum using implementation "adiantum(xchacha12-neon,aes-arm,nhpoly1305-neon)"
If you enabled metadata encryption, also run the following to verify that Adiantum metadata encryption is correctly enabled:
adb root
adb shell dmctl table userdata
The third field of the output should be
xchacha12,aes-adiantum-plain64
.
Devices with full-disk encryption
To enable Adiantum and improve its performance, set these properties in
PRODUCT_PROPERTY_OVERRIDES
:
ro.crypto.fde_algorithm=adiantum ro.crypto.fde_sector_size=4096
Setting fde_sector_size
to 4096 improves performance, but is not
required for Adiantum to work. To use this setting, the userdata partition must
begin at a 4096-byte aligned offset on-disk.
In the fstab
, for userdata set:
forceencrypt=footer
To verify that your implementation worked, take a bug report or run:
adb root
adb shell dmesg
If Adiantum is enabled correctly, you should see this in the kernel log:
device-mapper: crypt: adiantum(xchacha12,aes) using implementation "adiantum(xchacha12-neon,aes-arm,nhpoly1305-neon)"