การเข้ารหัสข้อมูลเมตา

Android 7.0 ขึ้นไปรองรับการเข้ารหัสตามไฟล์ (FBE) FBE ช่วยให้คุณเข้ารหัสไฟล์ต่างๆ ด้วยคีย์ที่แตกต่างกันซึ่งสามารถปลดล็อกแยกกันได้ คีย์เหล่านี้ใช้เพื่อเข้ารหัสทั้งเนื้อหาไฟล์และชื่อไฟล์ เมื่อใช้ FBE ระบบจะไม่เข้ารหัสข้อมูลอื่นๆ เช่น เลย์เอาต์ไดเรกทอรี ขนาดไฟล์ สิทธิ์ และเวลาสร้าง/แก้ไข รวมกัน ข้อมูลนี้เรียกว่าข้อมูลเมตาของระบบไฟล์

Android 9 เพิ่มการรองรับการเข้ารหัสข้อมูลเมตา เมื่อใช้การเข้ารหัสข้อมูลเมตา คีย์เดียวที่มีอยู่ในระบบขณะเปิดเครื่องจะเข้ารหัสเนื้อหาที่ไม่ได้เข้ารหัสโดย FBE คีย์นี้ได้รับการปกป้องโดย Keymaster ซึ่งจะ การเปิดเครื่องมีการป้องกันโดยการเปิดเครื่องที่ได้รับการยืนยัน

ระบบจะเปิดใช้การเข้ารหัสข้อมูลเมตาในพื้นที่เก็บข้อมูลที่พร้อมใช้งานเสมอเมื่อเปิดใช้ FBE นอกจากนี้ยังเปิดใช้การเข้ารหัสข้อมูลเมตาบนที่จัดเก็บข้อมูลภายในได้ด้วย เปิดตัวอุปกรณ์แล้ว สำหรับ Android 11 ขึ้นไปต้องมีการเข้ารหัสข้อมูลเมตา เปิดที่จัดเก็บข้อมูลภายในไว้

การใช้งานกับที่จัดเก็บข้อมูลภายใน

คุณสามารถตั้งค่าการเข้ารหัสข้อมูลเมตาในที่จัดเก็บข้อมูลภายในของอุปกรณ์ใหม่ได้โดยดำเนินการดังนี้ ตั้งค่าระบบไฟล์ metadata เปลี่ยนลำดับ init และ เปิดใช้การเข้ารหัสข้อมูลเมตาในไฟล์ 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

การเปลี่ยนแปลงลำดับ init

เมื่อใช้การเข้ารหัสข้อมูลเมตา ต้องทำงาน 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-keyAPI ใหม่ได้โดยไม่คำนึงถึงระดับ 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 สมบูรณ์ ทำงานล่วงหน้าและเพื่อหลีกเลี่ยงการติดตายนี้

การกําหนดค่าในพื้นที่เก็บข้อมูลแบบ Adoptable

ตั้งแต่ 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 ขึ้นไป การเข้ารหัสข้อมูลเมตาในพื้นที่เก็บข้อมูลแบบ Adoptable จะใช้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 ครั้ง คือ ครั้งแรกด้วยคีย์ FBE และอีกครั้งใช้กับ คีย์การเข้ารหัสข้อมูลเมตา การเข้ารหัสแบบคู่นี้จะลดประสิทธิภาพและ เพื่อให้บรรลุเป้าหมายด้านความปลอดภัยของการเข้ารหัสข้อมูลเมตา เนื่องจาก Android เพื่อให้มั่นใจว่าคีย์ FBE ตรวจจับช่องโหว่ได้ยากเท่ากับข้อมูลเมตา คีย์การเข้ารหัส ผู้ให้บริการสามารถปรับแต่งเคอร์เนลเพื่อหลีกเลี่ยง โดยเฉพาะอย่างยิ่งด้วยการใช้ ตัวเลือก 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 ได้ก็ต่อเมื่ออุปกรณ์ไม่มีการเร่ง AES
  • ro.crypto.fde_sector_size เลือกขนาดภาคคริปโต ตัวเลือกได้แก่ 512, 1024, 2048 และ 4096 สำหรับการเข้ารหัส Adiantum ให้ใช้ 4096