Android 7.0 ขึ้นไปรองรับการเข้ารหัสตามไฟล์ (FBE) FBE ช่วยให้คุณเข้ารหัสไฟล์ต่างๆ ด้วยคีย์ที่แตกต่างกันซึ่งสามารถปลดล็อกแยกกันได้ คีย์เหล่านี้ใช้เพื่อเข้ารหัสทั้งเนื้อหาไฟล์และชื่อไฟล์ เมื่อใช้ FBE ระบบจะไม่เข้ารหัสข้อมูลอื่นๆ เช่น เลย์เอาต์ไดเรกทอรี ขนาดไฟล์ สิทธิ์ และเวลาสร้าง/แก้ไข ข้อมูลอื่นๆ เหล่านี้เรียกรวมกันว่าข้อมูลเมตาของระบบไฟล์
Android 9 เพิ่มการรองรับการเข้ารหัสข้อมูลเมตา เมื่อใช้การเข้ารหัสข้อมูลเมตา คีย์เดียวที่มีอยู่ในเวลาเปิดเครื่องจะเข้ารหัสเนื้อหาที่ไม่ได้เข้ารหัสโดย FBE คีย์นี้ได้รับการปกป้องโดย Keymaster ซึ่งได้รับการปกป้องโดยบูตที่ผ่านการยืนยัน
การเข้ารหัสข้อมูลเมตาจะเปิดใช้เสมอในพื้นที่เก็บข้อมูลที่สามารถนำมาใช้ได้เมื่อใดก็ตามที่เปิดใช้ FBE นอกจากนี้ยังเปิดใช้การเข้ารหัสข้อมูลเมตาบนที่จัดเก็บข้อมูลภายในได้ด้วย อุปกรณ์ที่เปิดตัวด้วย Android 11 ขึ้นไปต้องเปิดใช้การเข้ารหัสข้อมูลเมตาในที่จัดเก็บข้อมูลภายใน
การติดตั้งใช้งานในที่จัดเก็บข้อมูลภายใน
คุณตั้งค่าการเข้ารหัสข้อมูลเมตาบนที่จัดเก็บข้อมูลภายในของอุปกรณ์ใหม่ได้โดยการตั้งค่าระบบไฟล์ metadata
, เปลี่ยนลำดับเริ่มต้น และเปิดใช้การเข้ารหัสข้อมูลเมตาในไฟล์ fstab ของอุปกรณ์
สิ่งที่ต้องมีก่อน
คุณจะตั้งค่าการเข้ารหัสข้อมูลเมตาได้ก็ต่อเมื่อฟอร์แมตพาร์ติชันข้อมูลเป็นครั้งแรกเท่านั้น ฟีเจอร์นี้จึงมีไว้สำหรับอุปกรณ์ใหม่เท่านั้น และไม่ควรเปลี่ยนแปลงผ่าน OTA
การเข้ารหัสข้อมูลเมตากำหนดให้คุณต้องเปิดใช้โมดูล dm-default-key
ในเคอร์เนล ใน Android 11 ขึ้นไป
dm-default-key
ได้รับการสนับสนุนโดยเคอร์เนลทั่วไปของ Android เวอร์ชัน 4.14 ขึ้นไป 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
เมื่อไม่ได้ใช้ฮาร์ดแวร์การเข้ารหัสแบบอินไลน์ คุณควรเปิดใช้การเร่งแบบ CPU ที่พร้อมใช้งานด้วยตามคำแนะนำในเอกสาร FBE
ใน Android 10 และเก่ากว่านั้น dm-default-key
ไม่ได้รับการสนับสนุนโดยเคอร์เนลทั่วไปของ Android ดังนั้น ผู้ให้บริการจึงต้องติดตั้งใช้งาน dm-default-key
ตั้งค่าระบบไฟล์ข้อมูลเมตา
เนื่องจากระบบจะอ่านข้อมูลในพาร์ติชัน userdata ไม่ได้จนกว่าจะมีคีย์การเข้ารหัสข้อมูลเมตา ตารางพาร์ติชันจึงต้องจัดสรรพาร์ติชันแยกต่างหากที่เรียกว่า "พาร์ติชันข้อมูลเมตา" เพื่อจัดเก็บ Blob ของ Keymaster ที่ปกป้องคีย์นี้ พาร์ติชันข้อมูลเมตาควรมีขนาด 16 MB
fstab.hardware
ต้องมีรายการสำหรับไฟล์ระบบข้อมูลเมตาที่อยู่ในพาร์ติชันนั้นซึ่งจะติดตั้งที่ /metadata
รวมถึงแฟล็ก formattable
เพื่อให้แน่ใจว่าระบบจะฟอร์แมตไฟล์ดังกล่าวเมื่อบูต ระบบไฟล์ 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
การเปลี่ยนแปลงลําดับเริ่มต้น
เมื่อใช้การเข้ารหัสข้อมูลเมตา vold
ต้องทำงานอยู่ก่อนจึงจะต่อเชื่อม /data
ได้ เพื่อให้ข้อความเริ่มต้นเร็วพอ ให้เพิ่มข้อความต่อไปนี้ใน init.hardware.rc
# We need vold early for metadata encryption on early-fs start vold
Keymaster ต้องทำงานอยู่และพร้อมใช้งานก่อนที่ Init จะพยายามต่อเชื่อม /data
init.hardware.rc
ควรมีคำสั่ง mount_all
อยู่แล้วซึ่งต่อเชื่อม /data
ของตัวเองในข้อความ on
late-fs
ก่อนบรรทัดนี้ ให้เพิ่มคำสั่งเพื่อเรียกใช้บริการ 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
เปิดการเข้ารหัสข้อมูลเมตา
สุดท้ายให้เพิ่ม keydirectory=/metadata/vold/metadata_encryption
ลงในคอลัมน์ fs_mgr_flags ของรายการ fstab
สำหรับ userdata
ตัวอย่างเช่น บรรทัด 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 คุณจะเปิดใช้การเข้ารหัส Adiantum ได้โดยการตั้งค่า
metadata_encryption=adiantum
- ในอุปกรณ์ที่รองรับคีย์ที่ห่อด้วยฮาร์ดแวร์ คุณสร้างคีย์การเข้ารหัสข้อมูลเมตาได้โดยการตั้งค่า
metadata_encryption=aes-256-xts:wrappedkey_v0
(หรือเทียบเท่าmetadata_encryption=:wrappedkey_v0
เนื่องจากมีaes-256-xts
เป็นอัลกอริทึมเริ่มต้น)
เนื่องจากอินเทอร์เฟซเคอร์เนลกับ dm-default-key
มีการเปลี่ยนแปลงใน Android 11 คุณจึงต้องตรวจสอบว่าได้ตั้งค่าที่ถูกต้องสำหรับ PRODUCT_SHIPPING_API_LEVEL
ใน device.mk
ด้วย ตัวอย่างเช่น หากอุปกรณ์เปิดตัวด้วย Android 11 (API ระดับ 30) device.mk
ควรมีข้อมูลต่อไปนี้
PRODUCT_SHIPPING_API_LEVEL := 30
นอกจากนี้ คุณยังตั้งค่าพร็อพเพอร์ตี้ของระบบต่อไปนี้เพื่อบังคับใช้ dm-default-key
API ใหม่ได้โดยไม่ต้องคำนึงถึงระดับ 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
หากคุณลบล้างการตั้งค่าการเข้ารหัสเริ่มต้นโดยการตั้งค่าตัวเลือก metadata_encryption
ใน fstab
ของอุปกรณ์ เอาต์พุตจะแตกต่างจากข้างต้นเล็กน้อย เช่น หากคุณเปิดใช้การเข้ารหัส Adiantum ช่องที่ 3 จะเป็น xchacha12,aes-adiantum-plain64
แทนที่จะเป็น aes-xts-plain64
ถัดไป ให้เรียกใช้ vts_kernel_encryption_test เพื่อตรวจสอบความถูกต้องของการเข้ารหัสข้อมูลเมตาและ FBE
atest vts_kernel_encryption_test
หรือ
vts-tradefed run vts -m vts_kernel_encryption_test
ปัญหาทั่วไป
ในระหว่างการเรียก mount_all
ซึ่งจะต่อเชื่อมพาร์ติชัน /data
ที่เข้ารหัสข้อมูลเมตา init
จะเรียกใช้เครื่องมือ vdc เครื่องมือ vdc เชื่อมต่อกับ vold
ผ่าน binder
เพื่อตั้งค่าอุปกรณ์ที่เข้ารหัสข้อมูลเมตาและต่อเชื่อมพาร์ติชัน ตลอดระยะเวลาของการเรียกใช้นี้ init
ถูกบล็อก และพยายามอ่านหรือตั้งค่าการบล็อกพร็อพเพอร์ตี้ init
จนกว่าจะสิ้นสุด mount_all
หากในขั้นตอนนี้ ส่วนใดๆ ของงานของ vold
ถูกบล็อกทั้งทางตรงและทางอ้อมจากการอ่านหรือการตั้งค่าพร็อพเพอร์ตี้ จะส่งผลให้เกิดการติดตาย คุณต้องตรวจสอบว่า vold
อ่านคีย์ โต้ตอบกับ Keymaster และมาสก์ไดเรกทอรีข้อมูลได้โดยไม่ต้องโต้ตอบกับ init
เพิ่มเติม
หาก Keymaster ยังไม่เริ่มทำงานโดยสมบูรณ์เมื่อ mount_all
ทำงาน คีย์จะไม่ตอบสนองต่อ vold
จนกว่าจะอ่านพร็อพเพอร์ตี้บางอย่างจาก init
ซึ่งส่งผลให้มีการติดตายตามที่อธิบายไว้ การวาง exec_start wait_for_keymaster
เหนือการเรียกใช้ mount_all
ที่เกี่ยวข้องตามที่กำหนดไว้จะช่วยให้ Keymaster ทำงานล่วงหน้าได้อย่างสมบูรณ์และหลีกเลี่ยงการติดตายนี้
การกําหนดค่าพื้นที่เก็บข้อมูลแบบนํามาใช้ได้
ตั้งแต่ Android 9 เป็นต้นไป ระบบจะเปิดใช้การเข้ารหัสข้อมูลเมตารูปแบบหนึ่งเสมอในพื้นที่เก็บข้อมูลที่พร้อมใช้งานทุกครั้งที่เปิดใช้ FBE แม้ว่าจะไม่ได้เปิดใช้การเข้ารหัสข้อมูลเมตาในที่จัดเก็บข้อมูลภายในก็ตาม
ใน AOSP การใช้งานการเข้ารหัสข้อมูลเมตาในที่จัดเก็บแบบ Adoptable มี 2 รูปแบบ ได้แก่ การเข้ารหัสที่เลิกใช้งานแล้วซึ่งอิงตาม dm-crypt
และการเข้ารหัสที่ใหม่กว่าซึ่งอิงตาม dm-default-key
ตรวจสอบว่าคุณได้กำหนดค่าที่ถูกต้องสำหรับ PRODUCT_SHIPPING_API_LEVEL
ใน device.mk
เพื่อให้แน่ใจว่าได้เลือกการใช้งานที่ถูกต้องสำหรับอุปกรณ์ เช่น หากอุปกรณ์ของคุณเปิดตัวด้วย Android 11 (API ระดับ 30) device.mk
ควรมีสิ่งต่อไปนี้
PRODUCT_SHIPPING_API_LEVEL := 30
นอกจากนี้ คุณยังตั้งค่าพร็อพเพอร์ตี้ของระบบต่อไปนี้เพื่อบังคับใช้วิธีการเข้ารหัสข้อมูลเมตาของวอลุ่มแบบใหม่ (และนโยบาย FBE เริ่มต้นเวอร์ชันใหม่) โดยไม่คำนึงถึงระดับ API การจัดส่งได้
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
เช่นเดียวกับที่จัดเก็บข้อมูลภายใน ดูข้อกําหนดเบื้องต้นด้านบนเพื่อดูตัวเลือกการกําหนดค่าเคอร์เนลที่จะเปิดใช้ โปรดทราบว่าฮาร์ดแวร์การเข้ารหัสแบบอินไลน์ที่ทำงานในที่จัดเก็บข้อมูลภายในของอุปกรณ์อาจไม่พร้อมใช้งานในที่จัดเก็บข้อมูลแบบ Adoptable ดังนั้นคุณจึงอาจต้องใช้CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
โดยค่าเริ่มต้นdm-default-key
วิธีการเข้ารหัสข้อมูลเมตาของวอลุ่มจะใช้อัลกอริทึมการเข้ารหัส AES-256-XTS ที่มีเซกเตอร์การเข้ารหัสขนาด 4096 ไบต์ คุณลบล้างอัลกอริทึมได้โดยการตั้งค่าพร็อพเพอร์ตี้ระบบ ro.crypto.volume.metadata.encryption
ค่าของพร็อพเพอร์ตี้นี้มีไวยากรณ์เหมือนกับmetadata_encryption
ตัวเลือก fstab ที่อธิบายไว้ด้านบน เช่น ในอุปกรณ์ที่ไม่มี AES
เร่งความเร็ว คุณจะเปิดใช้การเข้ารหัส Adiantum ได้โดยการตั้งค่า
ro.crypto.volume.metadata.encryption=adiantum
วิธีเดิม
ในอุปกรณ์ที่ใช้ Android 10 หรือต่ำกว่า การเข้ารหัสข้อมูลเมตาในพื้นที่เก็บข้อมูลแบบนํามาใช้ได้จะใช้โมดูลเคอร์เนล dm-crypt
แทน dm-default-key
ดังนี้
CONFIG_DM_CRYPT=y
ซึ่งแตกต่างจากวิธีการ dm-default-key
เนื่องจากวิธีการ dm-crypt
จะเข้ารหัสเนื้อหาไฟล์ 2 ครั้ง ได้แก่ 1 ครั้งด้วยคีย์ FBE และ 1 ครั้งด้วยคีย์การเข้ารหัสข้อมูลเมตา การเข้ารหัส 2 ชั้นนี้ลดประสิทธิภาพและไม่จำเป็นต้องใช้เพื่อให้บรรลุเป้าหมายด้านความปลอดภัยของการเข้ารหัสข้อมูลเมตา เนื่องจาก Android ช่วยให้มั่นใจได้ว่าคีย์ FBE จะเข้าถึงได้ยากอย่างน้อยเท่ากับคีย์การเข้ารหัสข้อมูลเมตา ผู้ให้บริการปรับแต่งเคอร์เนลเพื่อหลีกเลี่ยงการเข้ารหัส 2 ครั้งได้ โดยเฉพาะอย่างยิ่งด้วยการใช้ตัวเลือก allow_encrypt_override
ที่ Android ส่งไปยัง dm-crypt
เมื่อตั้งค่าพร็อพเพอร์ตี้ของระบบ ro.crypto.allow_encrypt_override
เป็น true
เคอร์เนลทั่วไปของ Android ไม่รองรับการปรับแต่งเหล่านี้
โดยค่าเริ่มต้น วิธีการเข้ารหัสข้อมูลเมตาของวอลุ่ม dm-crypt
จะใช้อัลกอริทึมการเข้ารหัส AES-128-CBC กับ ESSIV และภาคคริปโตขนาด 512 ไบต์ ลบล้างได้โดยการตั้งค่าพร็อพเพอร์ตี้ระบบต่อไปนี้ (ซึ่งใช้สำหรับ FDE ด้วย)
ro.crypto.fde_algorithm
เลือกอัลกอริทึมการเข้ารหัสข้อมูลเมตา ตัวเลือกคือaes-128-cbc
และadiantum
ใช้ Adiantum ได้เมื่ออุปกรณ์ไม่มีการเร่ง AESro.crypto.fde_sector_size
เลือกขนาดกลุ่มคริปโต โดยตัวเลือกมีดังนี้ 512, 1024, 2048 และ 4096 สำหรับการเข้ารหัส Adiantum ให้ใช้ 4096