启用 Adiantum

Adiantum 是一种加密方法,专为搭载 Android 9 及更高版本且 CPU 缺少 AES 指令的设备而设计。如果您要发布基于 ARM 且具有 ARMv8 Cryptography Extensions 的设备或基于 x86 且具有 AES-NI 的设备,则不应使用 Adiantum。在这些平台上,AES 的速度更快。

对于缺少这些 AES CPU 指令的设备,Adiantum 可在您的设备上提供加密,且性能开销极小。有关基准评测数据,请参阅 Adiantum 论文。如需在您的硬件上运行基准评测来源,请参阅 GitHub 上的 Adiantum 源代码

要在搭载 Android 9 或更高版本的设备上启用 Adiantum,您需要进行内核更改和用户空间更改。

内核更改

Android 通用内核(版本 4.9 及更高版本)支持 Adiantum。

如果您的设备的内核尚不支持 Adiantum,请选择以下列出的更改。如果您在选择时遇到问题,使用全盘加密 (FDE) 的设备可以排除 fscrypt: 补丁。

内核版本 加密和 fscrypt 补丁 dm-crypt 补丁
4.19 4.19 内核 dm-crypt 补丁
4.14 4.14 内核 dm-crypt 补丁
4.9 4.9 内核 dm-crypt 补丁

在您的内核中启用 Adiantum

Android 11 及更高版本

如果您的设备要发布 Android 11 或更高版本,请在您设备的内核配置中启用以下设置

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

如果您的设备运行的是 32 位 ARM 内核,另请启用 NEON 指令以提高性能

CONFIG_KERNEL_MODE_NEON=y
CONFIG_CRYPTO_AES_ARM=y
CONFIG_CRYPTO_CHACHA20_NEON=y
CONFIG_CRYPTO_NHPOLY1305_NEON=y

Android 9 和 10

如果您的设备要发布 Android 9 或 10,则需要稍微不同的内核配置设置。启用以下设置

CONFIG_CRYPTO_ADIANTUM=y
CONFIG_DM_CRYPT=y

如果您的设备使用基于文件的加密,另请启用

CONFIG_F2FS_FS_ENCRYPTION=y

最后,如果您的设备运行的是 32 位 ARM 内核,请启用 NEON 指令以提高性能

CONFIG_KERNEL_MODE_NEON=y
CONFIG_CRYPTO_AES_ARM=y
CONFIG_CRYPTO_CHACHA20_NEON=y
CONFIG_CRYPTO_NHPOLY1305_NEON=y

用户空间更改

对于运行 Android 10 或更高版本的设备,Adiantum 用户空间更改已存在。

对于运行 Android 9 的设备,请选择以下更改

在您的设备上启用 Adiantum

首先,确保您的设备的 PRODUCT_SHIPPING_API_LEVEL 设置正确,以匹配其发布的 Android 版本。例如,发布 Android 11 的设备必须具有 PRODUCT_SHIPPING_API_LEVEL := 30。这一点很重要,因为某些加密设置在不同的发布版本上具有不同的默认值。

使用基于文件的加密的设备

要在您设备的内部存储设备上启用 Adiantum 基于文件的加密,请将以下选项添加到设备 fstab 文件中 userdata 分区的行的最后一列(fs_mgr_flags 列)

fileencryption=adiantum

如果您的设备要发布 Android 11 或更高版本,则还需要启用元数据加密。要在内部存储设备上使用 Adiantum 进行元数据加密,userdatafs_mgr_flags 还必须包含以下选项

metadata_encryption=adiantum,keydirectory=/metadata/vold/metadata_encryption

接下来,在可采纳存储设备上启用 Adiantum 加密。为此,请在 PRODUCT_PROPERTY_OVERRIDES 中设置以下系统属性

对于 Android 11 及更高版本

ro.crypto.volume.options=adiantum
ro.crypto.volume.metadata.encryption=adiantum

对于 Android 9 和 10

ro.crypto.volume.contents_mode=adiantum
ro.crypto.volume.filenames_mode=adiantum
ro.crypto.fde_algorithm=adiantum
ro.crypto.fde_sector_size=4096

最后,可以选择将 blk-crypto-fallback.num_keyslots=1 添加到内核命令行。当使用 Adiantum 元数据加密时,这会稍微减少内存使用量。在执行此操作之前,请验证 inlinecrypt 挂载选项是否未在 fstab 中指定。如果已指定,请将其删除,因为它对于 Adiantum 加密不是必需的,并且与 blk-crypto-fallback.num_keyslots=1 结合使用时会导致性能问题。

要验证您的实现是否有效,请获取错误报告或运行

adb root
adb shell dmesg

如果 Adiantum 已正确启用,您应该会在内核日志中看到以下内容

fscrypt: Adiantum using implementation "adiantum(xchacha12-neon,aes-arm,nhpoly1305-neon)"

如果您启用了元数据加密,另请运行以下命令来验证 Adiantum 元数据加密是否已正确启用

adb root
adb shell dmctl table userdata

输出的第三个字段应为 xchacha12,aes-adiantum-plain64

使用全盘加密的设备

要启用 Adiantum 并提高其性能,请在 PRODUCT_PROPERTY_OVERRIDES 中设置以下属性

ro.crypto.fde_algorithm=adiantum
ro.crypto.fde_sector_size=4096

fde_sector_size 设置为 4096 可以提高性能,但 Adiantum 工作不需要此设置。要使用此设置,userdata 分区必须以磁盘上 4096 字节对齐的偏移量开头。

fstab 中,为 userdata 设置

forceencrypt=footer

要验证您的实现是否有效,请获取错误报告或运行

adb root
adb shell dmesg

如果 Adiantum 已正确启用,您应该会在内核日志中看到以下内容

device-mapper: crypt: adiantum(xchacha12,aes) using implementation "adiantum(xchacha12-neon,aes-arm,nhpoly1305-neon)"