Android 7.0 이상에서는 파일 기반 암호화(FBE)를 지원합니다. FBE를 사용하면 개별적으로 잠금 해제 가능한 여러 키를 사용하여 여러 파일을 암호화할 수 있습니다. 이러한 키는 파일 콘텐츠와 파일 이름을 암호화하는 데 사용됩니다. FBE를 사용하면 디렉터리 레이아웃, 파일 크기, 권한 및 생성/수정 시간과 같은 다른 정보는 암호화되지 않습니다. 이러한 다른 정보를 총칭하여 파일 시스템 메타데이터라고 합니다.
Android 9부터 메타데이터 암호화가 지원됩니다. 메타데이터 암호화를 사용하면 부팅 시 존재하는 단일 키로 FBE에서 암호화되지 않은 모든 콘텐츠를 암호화합니다. 이 키는 자체 검사 부팅에서 보호하는 Keymaster를 통해 보호됩니다.
메타데이터 암호화는 FBE가 사용 설정될 때마다 항상 어답터블 스토리지에서 사용 설정됩니다. 메타데이터 암호화는 내부 저장소에서도 사용 설정될 수 있습니다. Android 11 이상으로 출시된 기기에는 내부 저장소에 메타데이터 암호화가 사용 설정되어 있어야 합니다.
내부 저장소에서 구현
metadata
파일 시스템을 설정하고 init 순서를 변경하며 기기의 fstab 파일에서 메타데이터 암호화를 사용 설정하여 새 기기의 내부 저장소에 메타데이터 암호화를 설정할 수 있습니다.
기본 요건
메타데이터 암호화는 데이터 파티션이 처음 포맷될 때만 설정할 수 있습니다. 따라서 이 기능은 새 기기에만 사용할 수 있으며 OTA로 변경해야 하는 것이 아닙니다.
메타데이터 암호화를 사용하려면 커널에서 dm-default-key
모듈을 사용 설정해야 합니다. Android 11 이상에서는 Android 일반 커널 버전 4.14 이상에서 dm-default-key
를 지원합니다. 이 dm-default-key
버전은 하드웨어 및 공급업체와는 무관한 blk-crypto라는 암호화 프레임워크를 사용합니다.
dm-default-key
를 사용 설정하려면 다음을 사용하세요.
CONFIG_BLK_INLINE_ENCRYPTION=y CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y CONFIG_DM_DEFAULT_KEY=y
dm-default-key
는 가능한 경우 인라인 암호화 하드웨어(저장소 기기와 데이터를 송수신하는 동안 데이터를 암호화/복호화하는 하드웨어)를 사용합니다. 인라인 암호화 하드웨어를 사용하지 않는다면 다음과 같이 커널의 암호화 API에 폴백을 사용 설정해야 합니다.
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
또한 인라인 암호화 하드웨어를 사용하지 않는 경우 FBE 문서에서 권장하는 대로 사용 가능한 CPU 기반 가속을 사용 설정해야 합니다.
Android 10 이하에서는 Android 일반 커널에서 dm-default-key
를 지원하지 않습니다. 따라서 dm-default-key
구현은 공급업체가 결정합니다.
메타데이터 파일 시스템 설정
메타데이터 암호화 키가 존재할 때까지는 사용자 데이터 파티션의 어떠한 데이터도 읽을 수 없습니다. 따라서 파티션 테이블에서는 '메타데이터 파티션'이라는 별도의 파티션을 지정하여 이 키를 보호하는 Keymaster blob를 저장해야 합니다. 메타데이터 파티션은 16MB여야 합니다.
fstab.hardware
는 부팅 시 포맷을 시행하는 formattable
플래그와 함께 /metadata
로 메타데이터 파일 시스템을 마운트하는 파티션의 메타데이터 파일 시스템 항목을 포함해야 합니다. f2fs 파일 시스템은 작은 파티션에서 작동하지 않으므로 대신 ext4를 사용하는 것이 좋습니다. 예:
/dev/block/bootdevice/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard wait,check,formattable
/metadata
마운트 지점이 있도록 하려면 BoardConfig-common.mk
에 다음 행을 추가합니다.
BOARD_USES_METADATA_PARTITION := true
init 순서 변경
메타데이터 암호화를 사용한다면 /data
가 마운트되기 전에 vold
가 실행되어야 합니다. 충분히 일찍 시작되도록 하려면 init.hardware.rc
에 다음 스탠자를 추가합니다.
# We need vold early for metadata encryption on early-fs start vold
init에서 /data
마운트를 시도하기 전에 Keymaster가 실행 및 준비되어 있어야 합니다.
init.hardware.rc
는 on
late-fs
스탠자에 /data
자체를 마운트하는 mount_all
지침을 이미 포함하고 있어야 합니다. 이 행 앞에 다음과 같이 wait_for_keymaster
서비스를 실행하는 지시어를 추가합니다.
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
메타데이터 암호화 전환
마지막으로 userdata
의 fstab
항목에서 fs_mgr_flags 열에 keydirectory=/metadata/vold/metadata_encryption
을 추가합니다. 예를 들어 전체 fstab 행은 다음과 같습니다.
/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
기본적으로 내부 저장소의 메타데이터 암호화 알고리즘은 AES-256-XTS입니다. 이는 다음과 같이 metadata_encryption
옵션을 설정하여 재정의할 수 있으며 fs_mgr_flags 열에서도 마찬가지입니다.
- AES 가속이 없는 기기에서는
metadata_encryption=adiantum
을 설정하여 Adiantum 암호화를 사용 설정할 수 있습니다. - 하드웨어 래핑 키를 지원하는 기기에서
metadata_encryption=aes-256-xts:wrappedkey_v0
을 설정하여 메타데이터 암호화 키를 하드웨어 래핑 키로 만들 수 있습니다(또는aes-256-xts
가 기본 알고리즘이므로 이에 상응하는metadata_encryption=:wrappedkey_v0
설정).
Android 11에서 dm-default-key
로의 커널 인터페이스가 변경되었으므로 device.mk
에서 PRODUCT_SHIPPING_API_LEVEL
에 올바른 값을 설정했는지도 확인해야 합니다. 예를 들어 기기가 Android 11(API 수준 30)으로 출시되는 경우 device.mk
에는 다음이 포함되어야 합니다.
PRODUCT_SHIPPING_API_LEVEL := 30
배송 API 수준에 관계없이 다음과 같은 시스템 속성을 설정하여 새 dm-default-key
API를 강제로 사용할 수도 있습니다.
PRODUCT_PROPERTY_OVERRIDES += \ ro.crypto.dm_default_key.options_format.version=2
유효성 검사
아래에 설명된 테스트를 실행하여 메타데이터 암호화를 사용 설정했고 올바르게 작동 중인지 확인합니다. 또한 아래의 일반적인 문제에도 유의하세요.
테스트
다음 명령어를 실행하여 내부 저장소에서 메타데이터 암호화가 사용 설정되어 있는지 확인하세요.
adb root
adb shell dmctl table userdata
출력은 다음과 비슷해야 합니다.
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
기기의 fstab
에서 metadata_encryption
옵션을 설정하여 기본 암호화 설정을 재정의했다면 출력이 위와 조금 달라집니다. 예를 들어 Adiantum 암호화를 사용 설정했다면 세 번째 필드는 aes-xts-plain64
대신 xchacha12,aes-adiantum-plain64
가 됩니다.
그런 다음 vts_kernel_encryption_test를 실행하여 메타데이터 암호화와 FBE가 정확한지 확인합니다.
atest vts_kernel_encryption_test
또는:
vts-tradefed run vts -m vts_kernel_encryption_test
일반적인 문제
메타데이터로 암호화된 /data
파티션을 마운트하는 mount_all
을 호출하는 동안 init
는 vdc 도구를 실행합니다. vdc 도구는 binder
를 통해 vold
에 연결하여 메타데이터로 암호화할 기기를 설정하고 파티션을 마운트합니다. 이 호출이 실행되는 동안 init
가 차단되며 init
속성을 읽거나 설정하려는 시도는 mount_all
이 완료될 때까지 차단됩니다.
이 단계에서 vold
작업 일부가 속성을 읽거나 설정하는 중에 직간접적으로 차단된다면 교착 상태가 발생합니다. vold
에서 키를 읽고 Keymaster와 상호작용하고 init
와의 추가적인 상호작용 없이 데이터 디렉터리를 마운트하는 작업을 완료하도록 하는 것이 중요합니다.
mount_all
이 실행될 때 Keymaster가 완전히 시작되지 않았다면 Keymaster는 init
의 특정 속성을 읽을 때까지 vold
에 응답하지 않으며 이로 인해 앞서 설명한 교착 상태가 발생합니다. 명시된 대로 관련 mount_all
호출 위에 exec_start wait_for_keymaster
를 배치하면 Keymaster가 사전에 완전히 실행되므로 이러한 교착 상태가 발생하지 않습니다.
어답터블 스토리지의 구성
Android 9부터는 내부 저장소에서 메타데이터 암호화가 사용 설정되어 있지 않더라도 FBE가 사용 설정될 때마다 어답터블 스토리지에서 항상 메타데이터 암호화 양식이 사용 설정됩니다.
AOSP에는 어답터블 스토리지에 메타데이터 암호화가 두 가지로 구현되어 있습니다.
dm-crypt
를 기반으로 한 지원되지 않는 구현과
dm-default-key
를 기반으로 한 새로운 구현입니다. 기기에 올바른 구현이 선택되도록 하려면
device.mk
에서 PRODUCT_SHIPPING_API_LEVEL
에 올바른 값을 설정해야 합니다. 예를 들어 기기가 Android 11(API 수준 30)으로 출시되는 경우 device.mk
에는 다음이 포함되어야 합니다.
PRODUCT_SHIPPING_API_LEVEL := 30
배송 API 수준에 관계없이 다음과 같은 시스템 속성을 설정하여 새로운 볼륨 메타데이터 암호화 메서드 및 새로운 기본 FBE 정책 버전을 강제로 사용할 수도 있습니다.
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
현재 메서드
Android 11 이상으로 출시되는 기기는 내부 저장소의 경우와 같이 어답터블 스토리지의 메타데이터 암호화에서 dm-default-key
커널 모듈을 사용합니다. 위의 기본 요건에서 사용 설정할 커널 구성 옵션을 확인하세요. 기기의 내부 저장소에서 작동하는 인라인 암호화 하드웨어는 어답터블 스토리지에서 사용할 수 없으므로 CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
가 필요할 수 있습니다.
기본적으로 dm-default-key
볼륨 메타데이터 암호화 메서드는 4,096바이트 암호화 섹터를 적용한 AES-256-XTS 암호화 알고리즘을 사용합니다. 알고리즘은 ro.crypto.volume.metadata.encryption
시스템 속성을 설정하여 재정의할 수 있습니다. 이 속성의 값에는 위에 설명된 metadata_encryption
fstab 옵션과 동일한 구문이 있습니다. 예를 들어, AES 가속이 없는 기기에서는 ro.crypto.volume.metadata.encryption=adiantum
을 설정하여 Adiantum 암호화를 사용 설정할 수 있습니다.
기존 메서드
Android 10 이하로 출시되는 기기는 어답터블 스토리지의 메타데이터 암호화에서 dm-default-key
가 아닌 dm-crypt
커널 모듈을 사용합니다.
CONFIG_DM_CRYPT=y
dm-default-key
메서드와 달리 dm-crypt
메서드는 파일 콘텐츠를 두 번 암호화합니다. 즉, 한 번은 FBE 키로, 한 번은 메타데이터 암호화 키로 암호화합니다. Android에서 최소 메타데이터 암호화 키만큼 FBE 키의 안정성을 보장하므로 이러한 이중 암호화는 성능을 저해할 뿐 메타데이터 암호화의 보안 목표를 달성하는 데 필요하지 않습니다. 공급업체는 커널 맞춤설정을 통해 이중 암호화를 사용하지 않을 수 있으며 특히 시스템 속성인 ro.crypto.allow_encrypt_override
가 true
로 설정될 때 Android에서 dm-crypt
에 전달할 allow_encrypt_override
옵션을 구현하여 커널을 맞춤설정하면 됩니다.
이러한 맞춤설정은 Android 일반 커널에서 지원되지 않습니다.
기본적으로 dm-crypt
볼륨 메타데이터 암호화 메서드는 ESSIV 및 512바이트 암호화 섹터가 적용된 AES-128-CBC 암호화 알고리즘을 사용합니다. 이는 다음 시스템 속성(FDE에도 사용됨)을 설정하여 재정의할 수 있습니다.
ro.crypto.fde_algorithm
은 메타데이터 암호화 알고리즘을 선택합니다.aes-128-cbc
와adiantum
중에서 선택할 수 있습니다. 기기에 AES 가속이 없는 경우에만 Adiantum을 사용할 수 있습니다.ro.crypto.fde_sector_size
는 암호화 섹터 크기를 선택합니다. 512, 1,024, 2,048, 4,096 중에서 선택할 수 있습니다. Adiantum 암호화에는 4,096을 사용합니다.