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

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 ที่สามารถอ่านได้จนกว่าจะมีคีย์การเข้ารหัสข้อมูลเมตา ตารางพาร์ติชันจึงต้องแยกพาร์ติชันที่เรียกว่า "พาร์ติชันข้อมูลเมตา" ไว้สำหรับจัดเก็บคีย์มาสเตอร์ blobs ที่ปกป้องคีย์นี้ พาร์ติชันข้อมูลเมตาควรมีขนาด 16MB

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 จะถูกเมาท์ เพื่อให้แน่ใจว่าสตาร์ทได้เร็วพอ ให้เพิ่ม stanza ต่อไปนี้ใน init.hardware.rc :

# We need vold early for metadata encryption
on early-fs
    start vold

Keymaster ต้องทำงานและพร้อมก่อนที่จะเริ่มเมานต์ /data

init.hardware.rc ควรมีคำสั่ง mount_all อยู่แล้วซึ่งเมานต์ /data เองใน stanza ของ 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 ฟิลด์ที่สามจะเป็น 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 over 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 มีการใช้งานการเข้ารหัสข้อมูลเมตาสองแบบบนพื้นที่เก็บข้อมูลที่นำมาใช้ได้: แบบที่เลิกใช้แล้วซึ่งใช้ 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 เช่นเดียวกับที่จัดเก็บข้อมูลภายใน ดู ข้อกำหนดเบื้องต้น ด้านบนสำหรับตัวเลือกการกำหนดค่าเคอร์เนลที่จะเปิดใช้งาน โปรดทราบว่าฮาร์ดแวร์การเข้ารหัสแบบอินไลน์ที่ทำงานบนที่เก็บข้อมูลภายในของอุปกรณ์อาจไม่พร้อมใช้งานบนที่เก็บข้อมูลที่ปรับใช้ได้ ดังนั้นจึงอาจต้องใช้ CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y

ตามค่าเริ่มต้น วิธีการเข้ารหัสข้อมูลเมตาของไดรฟ์ข้อมูล dm-default-key ใช้อัลกอริธึมการเข้ารหัส AES-256-XTS พร้อมเซกเตอร์ crypto ขนาด 4096 ไบต์ สามารถแทนที่อัลกอริทึมได้โดยการตั้งค่าคุณสมบัติระบบ ro.crypto.volume.metadata.encryption ค่าของคุณสมบัตินี้มีไวยากรณ์เหมือนกับตัวเลือก fstab metadata_encryption ที่อธิบายไว้ข้างต้น ตัวอย่างเช่น ในอุปกรณ์ที่ไม่มีการเร่งความเร็ว AES การเข้ารหัส Adiantum อาจเปิดใช้งานได้โดยการตั้ง ro.crypto.volume.metadata.encryption=adiantum

วิธีดั้งเดิม

บนอุปกรณ์ที่เปิดตัวด้วย Android 10 หรือต่ำกว่า การเข้ารหัสข้อมูลเมตาบนที่เก็บข้อมูลที่ปรับใช้ได้จะใช้โมดูลเคอร์เนล dm-crypt แทนที่จะเป็น dm-default-key :

CONFIG_DM_CRYPT=y

ไม่เหมือนกับวิธี dm-default-key วิธี dm-crypt ทำให้เนื้อหาไฟล์ถูกเข้ารหัสสองครั้ง: ครั้งแรกด้วยคีย์ 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 เลือกขนาดเซกเตอร์ crypto ตัวเลือกคือ 512, 1024, 2048 และ 4096 สำหรับการเข้ารหัส Adiantum ให้ใช้ 4096