Enable adiantum

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:

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)"