การเข้ารหัสทั้งดิสก์คือกระบวนการเข้ารหัสข้อมูลผู้ใช้ทั้งหมดในอุปกรณ์ Android โดยใช้ คีย์ที่เข้ารหัส เมื่ออุปกรณ์เข้ารหัสแล้ว ข้อมูลทั้งหมดที่ผู้ใช้สร้างขึ้นจะ เข้ารหัสโดยอัตโนมัติก่อนบันทึกลงในดิสก์และการอ่านทั้งหมด ถอดรหัสข้อมูลโดยอัตโนมัติก่อนกลับไปยังกระบวนการเรียกใช้
เปิดตัวการเข้ารหัสทั้งดิสก์สำหรับ Android เวอร์ชัน 4.4 แต่เปิดตัว Android 5.0 ฟีเจอร์ใหม่ดังต่อไปนี้
- สร้างการเข้ารหัสที่รวดเร็ว ซึ่งจะเข้ารหัสเฉพาะบล็อกที่ใช้บนพาร์ติชันข้อมูล เพื่อหลีกเลี่ยงการเปิดเครื่องครั้งแรกที่ใช้เวลานาน เฉพาะระบบไฟล์ ext4 และ f2fs ปัจจุบันรองรับการเข้ารหัสที่รวดเร็ว
- เพิ่ม
forceencrypt
fstab Flag เพื่อเข้ารหัสเมื่อเปิดเครื่องครั้งแรก - เพิ่มการรองรับรูปแบบและการเข้ารหัสโดยไม่ต้องใช้รหัสผ่าน
- เพิ่มพื้นที่เก็บข้อมูลสนับสนุนฮาร์ดแวร์ของคีย์การเข้ารหัสโดยใช้ "เชื่อถือได้" ความสามารถในการลงชื่อของสภาพแวดล้อม (TEE) (เช่น ใน TrustZone) โปรดดูข้อมูลเพิ่มเติมในการจัดเก็บคีย์ที่เข้ารหัส รายละเอียด
ข้อควรระวัง: อุปกรณ์อัปเกรดเป็น Android 5.0 จากนั้น ที่เข้ารหัสอาจเปลี่ยนเป็นสถานะไม่เข้ารหัสโดยการรีเซ็ตข้อมูลเป็นค่าเริ่มต้น Android 5.0 ใหม่ อุปกรณ์ที่เข้ารหัสเมื่อเปิดเครื่องครั้งแรกจะเปลี่ยนกลับไปเป็นสถานะที่ไม่ได้เข้ารหัสไม่ได้
วิธีการทำงานของการเข้ารหัสแบบเต็มดิสก์ของ Android
การเข้ารหัสทั้งดิสก์ของ Android อิงตาม dm-crypt
ซึ่งเป็นเคอร์เนล
ที่ทำงานในเลเยอร์อุปกรณ์บล็อก เนื่องจาก
ซึ่งการเข้ารหัสจะใช้งานได้กับ Embedded MultiMediaCard (eMMC) และ
อุปกรณ์แฟลชที่คล้ายกันซึ่งนำเสนอตนเองต่อเคอร์เนลเป็นบล็อก
อุปกรณ์ การเข้ารหัสไม่สามารถทำได้ด้วย YAFFS ซึ่งจะติดต่อกับไฟล์ RAW โดยตรง
ชิปแฟลช NAND
อัลกอริทึมการเข้ารหัสคือ 128 Advanced Encryption Standard (AES) พร้อมด้วย Cipher-block Chaining (CBC) และ ESSIV:SHA256 คีย์หลักถูกเข้ารหัสด้วย AES 128 บิตผ่านการเรียกไปยังไลบรารี OpenSSL คุณต้องใช้ 128 บิตขึ้นไปเพื่อ คีย์ (ที่มี 256 เป็นคีย์ที่ไม่บังคับ)
หมายเหตุ: OEM สามารถใช้ 128 บิตขึ้นไปในการเข้ารหัสคีย์หลัก
ใน Android รุ่น 5.0 จะมีสถานะการเข้ารหัสอยู่ 4 ประเภทดังนี้
- ค่าเริ่มต้น
- PIN
- รหัสผ่าน
- รูปแบบ
เมื่อเปิดเครื่องครั้งแรก อุปกรณ์จะสร้างคีย์ต้นแบบ 128 บิตที่สร้างขึ้นแบบสุ่ม แล้วแฮชด้วยรหัสผ่านเริ่มต้น และเก็บ Salt รหัสผ่านเริ่มต้นคือ "default_password" อย่างไรก็ตาม แฮชที่เป็นผลลัพธ์จะมีการลงชื่อผ่าน TEE (เช่น TrustZone) ด้วย ซึ่งใช้แฮชของลายเซ็นในการเข้ารหัสคีย์หลัก
คุณสามารถค้นหารหัสผ่านเริ่มต้นที่กำหนดไว้ในโครงการโอเพนซอร์ส Android cryptfs.cpp
เมื่อผู้ใช้ตั้งค่า PIN/รหัสผ่านหรือรหัสผ่านในอุปกรณ์ จะมีเพียงคีย์ 128 บิตเท่านั้น จะมีการเข้ารหัสและจัดเก็บใหม่ (เช่น การเปลี่ยนแปลง PIN/รหัสผ่าน/รูปแบบของผู้ใช้จะไม่ทำให้เกิด เข้ารหัสข้อมูลผู้ใช้ซ้ำ) โปรดทราบว่า อุปกรณ์ที่มีการจัดการ อาจอยู่ภายใต้ข้อจำกัดของ PIN, รูปแบบ หรือรหัสผ่าน
init
และ vold
เป็นผู้จัดการการเข้ารหัส
init
เรียกใช้ vold
และ vold กำหนดพร็อพเพอร์ตี้ที่จะทริกเกอร์
เหตุการณ์ต่างๆ ใน init ส่วนอื่นๆ ของระบบ
ดูพร็อพเพอร์ตี้ในการดำเนินงานต่างๆ เช่น สถานะรายงาน ขอ
รหัสผ่าน หรือข้อความแจ้งให้รีเซ็ตเป็นค่าเริ่มต้นในกรณีที่เกิดข้อผิดพลาดร้ายแรง วิธีเรียกใช้
ฟีเจอร์การเข้ารหัสใน vold
ระบบจะใช้เครื่องมือบรรทัดคำสั่ง
คำสั่ง cryptfs
ของ vdc
: checkpw
,
restart
, enablecrypto
, changepw
cryptocomplete
, verifypw
, setfield
getfield
, mountdefaultencrypted
, getpwtype
getpw
และ clearpw
ในการเข้ารหัส ถอดรหัส หรือล้างข้อมูล /data
ให้/data
ต้องไม่ต่อเชื่อม แต่หากต้องการแสดงอินเทอร์เฟซผู้ใช้ (UI)
ต้องเริ่มต้นและเฟรมเวิร์กต้องมี /data
จึงจะทำงานได้ ถึง
แก้ไขปัญหาปริศนานี้ ระบบจะต่อเชื่อมระบบไฟล์ชั่วคราวใน /data
การดำเนินการนี้ช่วยให้ Android แจ้งเตือนให้ป้อนรหัสผ่าน แสดงความคืบหน้า หรือแนะนำข้อมูลได้
ล้างข้อมูลตามต้องการ สิ่งนี้ตั้งขีดจำกัดว่าเพื่อเปลี่ยนจาก
ระบบไฟล์ชั่วคราวให้เป็นระบบไฟล์ /data
ที่แท้จริง ระบบต้อง
หยุดทุกกระบวนการด้วยไฟล์ที่เปิดอยู่ในระบบไฟล์ชั่วคราว และเริ่มใหม่อีกครั้ง
ในระบบไฟล์ /data
จริง ในการดำเนินการนี้ บริการทั้งหมด
ต้องอยู่ใน 1 จาก 3 กลุ่มต่อไปนี้ core
, main
และ
late_start
core
: ไม่ต้องปิดเครื่องหลังจากเปิดเครื่องmain
: ปิดเครื่องแล้วรีสตาร์ทหลังจากป้อนรหัสผ่านดิสก์แล้วlate_start
: ไม่เริ่มทำงานจนกว่า/data
จะได้รับการถอดรหัสและต่อเชื่อม
หากต้องการทริกเกอร์การดำเนินการเหล่านี้ ระบบจะตั้งค่าพร็อพเพอร์ตี้ vold.decrypt
เป็น
สตริงต่างๆ
หากต้องการปิดใช้งานและรีสตาร์ทบริการ คำสั่ง init
มีดังนี้
class_reset
: หยุดบริการแต่อนุญาตให้เริ่มต้นใหม่ได้ด้วย class_startclass_start
: รีสตาร์ทบริการclass_stop
: หยุดบริการและเพิ่มแฟล็กSVC_DISABLED
บริการที่หยุดจะไม่ตอบสนองต่อclass_start
ขั้นตอน
อุปกรณ์ที่เข้ารหัสจะมี 4 ขั้นตอน อุปกรณ์จะได้รับการเข้ารหัสเพียงครั้งเดียว จากนั้นทำตามขั้นตอนการเปิดเครื่องตามปกติ
- วิธีเข้ารหัสอุปกรณ์ที่ไม่ได้เข้ารหัสก่อนหน้านี้
- เข้ารหัสอุปกรณ์ใหม่ด้วย
forceencrypt
: การเข้ารหัสที่บังคับ เมื่อเปิดเครื่องครั้งแรก (เริ่มต้นใน Android L) - เข้ารหัสอุปกรณ์ที่มีอยู่: การเข้ารหัสที่เริ่มต้นโดยผู้ใช้ (Android K และรุ่นก่อนหน้า)
- เข้ารหัสอุปกรณ์ใหม่ด้วย
- วิธีเปิดเครื่องที่เข้ารหัส
- การเริ่มต้นใช้งานอุปกรณ์ที่เข้ารหัสโดยไม่ต้องใช้รหัสผ่าน: การเปิดเครื่องอุปกรณ์ที่เข้ารหัสซึ่ง ไม่ได้ตั้งรหัสผ่าน (ใช้ได้กับอุปกรณ์ที่ใช้ Android 5.0 ขึ้นไป)
- การเริ่มต้นใช้งานอุปกรณ์ที่เข้ารหัสด้วยรหัสผ่าน: การเปิดเครื่องอุปกรณ์ที่เข้ารหัสซึ่ง ตั้งรหัสผ่านแล้ว
นอกจากทำตามขั้นตอนเหล่านี้แล้ว อุปกรณ์อาจเข้ารหัส /data
ไม่สำเร็จด้วย
เราจะอธิบายขั้นตอนแต่ละขั้นอย่างละเอียดที่ด้านล่าง
เข้ารหัสอุปกรณ์ใหม่ด้วยการบังคับใช้การเข้ารหัส
นี่เป็นการเปิดเครื่องครั้งแรกตามปกติสำหรับอุปกรณ์ Android 5.0
- ตรวจหาระบบไฟล์ที่ไม่ได้เข้ารหัสด้วยแฟล็ก
forceencrypt
/data
ไม่ได้เข้ารหัสแต่ต้องเป็นสมาชิกเนื่องจากforceencrypt
เป็นผู้กำหนด ยกเลิกการต่อเชื่อม/data
- เริ่มเข้ารหัส
/data
vold.decrypt = "trigger_encryption"
ทริกเกอร์init.rc
ซึ่งจะทำให้vold
เข้ารหัส/data
โดยไม่ใช้รหัสผ่าน (ไม่ได้ตั้งค่าไว้เนื่องจากควรเป็นอุปกรณ์ใหม่) - ต่อเชื่อม tmpfs
vold
ต่อเชื่อม tmpfs/data
(โดยใช้ตัวเลือก tmpfs จากro.crypto.tmpfs_options
) และตั้งค่าพร็อพเพอร์ตี้vold.encrypt_progress
เป็น 0vold
เตรียม tmpfs/data
สำหรับการเปิดเครื่องระบบที่เข้ารหัสและตั้งค่า พร็อพเพอร์ตี้vold.decrypt
ถึง:trigger_restart_min_framework
- แสดงเฟรมเวิร์กเพื่อแสดงความคืบหน้า
เนื่องจากอุปกรณ์ไม่มีข้อมูลที่จะเข้ารหัส แถบความคืบหน้าจะ ซึ่งมักจะไม่ปรากฏขึ้นเพราะการเข้ารหัสเกิดขึ้นเร็วมาก โปรดดู เข้ารหัสอุปกรณ์ที่มีอยู่เพื่อรับข้อมูลเพิ่มเติม รายละเอียดเกี่ยวกับ UI ความคืบหน้า
- เมื่อเข้ารหัส
/data
แล้ว ให้ลบเฟรมเวิร์กออกvold
กำหนดvold.decrypt
เป็นtrigger_default_encryption
ซึ่งเริ่มต้นdefaultcrypto
(ซึ่งจะเริ่มขั้นตอนด้านล่างเพื่อต่อเชื่อม ข้อมูลผู้ใช้ที่เข้ารหัสไว้เริ่มต้น)trigger_default_encryption
ตรวจสอบ ประเภทการเข้ารหัสเพื่อดูว่า/data
เข้ารหัสโดยมีหรือไม่มี รหัสผ่าน เนื่องจากอุปกรณ์ Android 5.0 ได้รับการเข้ารหัสเมื่อเปิดเครื่องครั้งแรก จึงควรมี ต้องไม่ตั้งรหัสผ่าน ดังนั้น เราจะถอดรหัสและต่อเชื่อม/data
- ต่อเชื่อม
/data
จากนั้น
init
จะต่อเชื่อม/data
บน tmpfs RAMDisk โดยใช้ พารามิเตอร์ที่ดึงมาจากro.crypto.tmpfs_options
ซึ่งตั้งค่าไว้ ในinit.rc
- เริ่มเฟรมเวิร์ก
vold
กำหนดvold.decrypt
เป็นtrigger_restart_framework
ซึ่งจะเริ่มการเปิดเครื่องตามปกติต่อไป ขั้นตอนได้
เข้ารหัสอุปกรณ์ที่มีอยู่
นี่คือสิ่งที่เกิดขึ้นเมื่อคุณเข้ารหัส Android K ที่ไม่ได้เข้ารหัสหรือเวอร์ชันก่อนหน้า อุปกรณ์ที่ย้ายข้อมูลไปยัง L แล้ว
กระบวนการนี้เริ่มต้นโดยผู้ใช้ และเรียกว่า "การเข้ารหัสภายใน" ใน โค้ด เมื่อผู้ใช้เลือกที่จะเข้ารหัสอุปกรณ์ UI จะตรวจสอบว่า ชาร์จแบตเตอรี่เต็มแล้ว และเสียบอะแดปเตอร์ AC อยู่เพื่อให้ชาร์จเพียงพอ เพื่อดำเนินขั้นตอนการเข้ารหัสให้เสร็จสิ้น
คำเตือน: หากอุปกรณ์หมดและปิดก่อนที่จะใช้งานจบ กำลังเข้ารหัส ข้อมูลไฟล์จะอยู่ในสถานะที่เข้ารหัสบางส่วน อุปกรณ์ต้อง รีเซ็ตเป็นค่าเริ่มต้น และข้อมูลทั้งหมดจะหายไป
หากต้องการเปิดใช้การเข้ารหัสในตัว vold
จะเริ่มวนซ้ำเพื่ออ่านแต่ละรายการ
ของอุปกรณ์บล็อกจริงแล้วเขียน
ไปยังอุปกรณ์บล็อกคริปโต vold
ตรวจสอบว่ามีภาคใดอยู่ใน
ก่อนที่จะอ่านและเขียน ซึ่งทำให้
การเข้ารหัสอย่างรวดเร็วยิ่งขึ้นบนอุปกรณ์ใหม่ที่มีข้อมูลน้อยหรือไม่มีเลย
สถานะของอุปกรณ์: ตั้งค่า ro.crypto.state = "unencrypted"
และเรียกใช้ทริกเกอร์ on nonencrypted
init
เพื่อเปิดเครื่องต่อ
- ตรวจสอบรหัสผ่าน
UI เรียก
vold
ด้วยคำสั่งcryptfs enablecrypto inplace
โดยที่passwd
คือรหัสผ่านล็อกหน้าจอของผู้ใช้ - ลบเฟรมเวิร์กออก
vold
ตรวจหาข้อผิดพลาด แสดงผล -1 หากเข้ารหัสไม่ได้ และ พิมพ์เหตุผลในบันทึก หากเข้ารหัสได้ ระบบจะตั้งค่าพร็อพเพอร์ตี้vold.decrypt
ไปยังtrigger_shutdown_framework
ซึ่งส่งผลให้init.rc
หยุดบริการในชั้นเรียนlate_start
และmain
- สร้างส่วนท้ายของคริปโต
- สร้างไฟล์เบรดครัมบ์
- รีบูต
- ตรวจหาไฟล์เบรดครัมบ์
- เริ่มเข้ารหัส
/data
จากนั้น
vold
ตั้งค่าการแมปคริปโต ซึ่งจะสร้างอุปกรณ์บล็อกคริปโตเสมือน ที่จับคู่กับอุปกรณ์บล็อกจริง แต่เข้ารหัสแต่ละภาคส่วนตามที่เขียนไว้ และถอดรหัสแต่ละส่วนขณะที่อ่าน จากนั้นvold
จะสร้างและเขียน ข้อมูลเมตาของคริปโต - ขณะเข้ารหัส ให้ต่อเชื่อม tmpfs
vold
ต่อเชื่อม tmpfs/data
(โดยใช้ตัวเลือก tmpfs จากro.crypto.tmpfs_options
) และตั้งค่าพร็อพเพอร์ตี้vold.encrypt_progress
ถึง 0vold
เตรียม tmpfs/data
สำหรับการเปิดเครื่องระบบที่เข้ารหัสและตั้งค่าพร็อพเพอร์ตี้vold.decrypt
ถึง:trigger_restart_min_framework
- แสดงเฟรมเวิร์กเพื่อแสดงความคืบหน้า
trigger_restart_min_framework
ทำให้init.rc
ถึง เริ่มต้นคลาสของบริการmain
เมื่อเฟรมเวิร์กเห็นว่าvold.encrypt_progress
ตั้งค่าเป็น 0 และจะแสดงแถบความคืบหน้า UI ซึ่งจะค้นหาพร็อพเพอร์ตี้ทุกๆ 5 วินาทีและอัปเดตแถบความคืบหน้า ลูปการเข้ารหัสจะอัปเดตvold.encrypt_progress
ทุกครั้ง เข้ารหัสอีกเปอร์เซ็นต์ของพาร์ติชัน - เมื่อเข้ารหัส
/data
แล้ว ให้อัปเดตส่วนท้ายของคริปโตเมื่อเข้ารหัส
/data
เรียบร้อยแล้วvold
จะลบ แฟล็กENCRYPTION_IN_PROGRESS
ในข้อมูลเมตาเมื่ออุปกรณ์ปลดล็อกเรียบร้อยแล้ว จะมีการใช้รหัสผ่านเพื่อ เข้ารหัสคีย์ต้นแบบและอัปเดตส่วนท้ายของ Crypto
หากการรีบูตล้มเหลวด้วยเหตุผลบางอย่าง
vold
จะตั้งค่าพร็อพเพอร์ตี้vold.encrypt_progress
ถึงerror_reboot_failed
และ UI ควรแสดงข้อความที่ขอให้ผู้ใช้กดปุ่มเพื่อ รีบูต กรณีนี้ไม่คาดคิดมาก่อน
การเริ่มใช้อุปกรณ์ที่เข้ารหัสด้วยการเข้ารหัสเริ่มต้น
นี่คือสิ่งที่เกิดขึ้นเมื่อคุณเปิดอุปกรณ์ที่เข้ารหัสโดยไม่มีรหัสผ่าน เนื่องจากอุปกรณ์ Android 5.0 ได้รับการเข้ารหัสเมื่อเปิดเครื่องครั้งแรก จึงไม่ควรตั้งค่าใดๆ รหัสผ่าน ดังนั้นจึงเป็นสถานะการเข้ารหัสเริ่มต้น
- ตรวจหา
/data
ที่เข้ารหัสโดยไม่มีรหัสผ่านตรวจพบว่าอุปกรณ์ Android มีการเข้ารหัสเนื่องจาก
/data
ไม่สามารถติดตั้งและหนึ่งใน Flagencryptable
หรือ ตั้งค่าforceencrypt
แล้วvold
กำหนดvold.decrypt
เป็นtrigger_default_encryption
ซึ่งเริ่มต้นdefaultcrypto
trigger_default_encryption
ตรวจสอบประเภทการเข้ารหัสเพื่อดูว่า/data
มีการเข้ารหัสกับ หรือ โดยไม่ต้องใช้รหัสผ่าน - ถอดรหัส /data
สร้างอุปกรณ์
dm-crypt
บนอุปกรณ์ที่บล็อก เพื่อให้อุปกรณ์ดังกล่าว พร้อมใช้งานแล้ว - ต่อเชื่อม /ข้อมูล
จากนั้น
vold
จะต่อเชื่อมพาร์ติชัน/data
จริงที่ถอดรหัสแล้ว จากนั้นจึงเตรียมพาร์ติชันใหม่ ตั้งค่าพร็อพเพอร์ตี้vold.post_fs_data_done
เป็น 0 แล้วตั้งค่าvold.decrypt
ไปยังtrigger_post_fs_data
การดำเนินการนี้จะทำให้init.rc
ทำงาน คำสั่งpost-fs-data
โดยจะสร้างไดเรกทอรีที่จำเป็น หรือลิงก์ แล้วตั้งค่าvold.post_fs_data_done
เป็น 1เมื่อ
vold
เห็น 1 ในพร็อพเพอร์ตี้นั้น ระบบจะตั้งค่าพร็อพเพอร์ตี้vold.decrypt
ถึง:trigger_restart_framework.
รายการนี้ ทำให้init.rc
เริ่มบริการในชั้นเรียนmain
อีกครั้ง และเริ่มบริการในชั้นเรียนlate_start
สำหรับ ระยะเวลาตั้งแต่เปิดเครื่อง - เริ่มเฟรมเวิร์ก
ตอนนี้เฟรมเวิร์กจะเปิดเครื่องบริการทั้งหมดโดยใช้
/data
ที่ถอดรหัสแล้ว และระบบพร้อมใช้งาน
การเริ่มใช้อุปกรณ์ที่เข้ารหัสโดยไม่มีการเข้ารหัสเริ่มต้น
นี่คือสิ่งที่เกิดขึ้นเมื่อคุณเปิดอุปกรณ์ที่เข้ารหัสและมีชุดอุปกรณ์ รหัสผ่าน รหัสผ่านของอุปกรณ์อาจเป็น PIN, รูปแบบ หรือรหัสผ่านก็ได้
- ตรวจหาอุปกรณ์ที่เข้ารหัสด้วยรหัสผ่าน
ตรวจพบว่าอุปกรณ์ Android ได้รับการเข้ารหัสเนื่องจากธง
ro.crypto.state = "encrypted"
vold
กำหนดvold.decrypt
เป็นtrigger_restart_min_framework
เนื่องจาก/data
เข้ารหัสด้วยรหัสผ่าน - ต่อเชื่อม tmpfs
init
กำหนดพร็อพเพอร์ตี้ 5 รายการเพื่อบันทึกตัวเลือกการต่อเชื่อมเริ่มต้น ที่ระบุสำหรับ/data
ที่มีพารามิเตอร์ที่ส่งจากinit.rc
vold
ใช้พร็อพเพอร์ตี้เหล่านี้เพื่อตั้งค่าการแมปคริปโตro.crypto.fs_type
ro.crypto.fs_real_blkdev
ro.crypto.fs_mnt_point
ro.crypto.fs_options
ro.crypto.fs_flags
(เลขฐานสิบหก 8 หลัก ASCII นำหน้าด้วย 0x)
- เริ่มเฟรมเวิร์กเพื่อขอรหัสผ่าน
เฟรมเวิร์กเริ่มต้นขึ้นและเห็นว่า
vold.decrypt
ได้รับการตั้งค่าเป็นtrigger_restart_min_framework
ซึ่งจะบอกเฟรมเวิร์กว่า การเปิดเครื่องในดิสก์/data
ของ tmpfs และจำเป็นต้องมีรหัสผ่านของผู้ใช้อย่างไรก็ตาม อันดับแรกต้องตรวจสอบว่าดิสก์ได้รับการเข้ารหัสอย่างถูกต้อง ทั้งนี้ ส่งคำสั่ง
cryptfs cryptocomplete
ไปยังvold
vold
แสดงผล 0 หากการเข้ารหัสเสร็จสมบูรณ์ แสดงผล -1 สำหรับข้อผิดพลาดภายใน หรือ -2 หากเข้ารหัสไม่สำเร็จvold
กำหนด โดยดูที่ข้อมูลเมตาของคริปโตสำหรับCRYPTO_ENCRYPTION_IN_PROGRESS
แจ้ง หากตั้งค่าไว้ ขั้นตอนการเข้ารหัสจะหยุดชะงักและจะไม่มี ข้อมูลที่ใช้ได้ในอุปกรณ์ หากvold
แสดงข้อผิดพลาด UI ควร แสดงข้อความให้ผู้ใช้รีบูตและรีเซ็ตอุปกรณ์เป็นค่าเริ่มต้น และให้ ให้ผู้ใช้กดเพื่อทำเช่นนั้น - ถอดรหัสข้อมูลด้วยรหัสผ่าน
เมื่อ
cryptfs cryptocomplete
สำเร็จ เฟรมเวิร์ก แสดง UI ที่ขอรหัสผ่านดิสก์ UI ตรวจสอบรหัสผ่านโดย กำลังส่งคำสั่งcryptfs checkpw
ไปยังvold
หาก รหัสผ่านถูกต้อง (ซึ่งทราบได้จากการต่อเชื่อม ถอดรหัส/data
ที่ตำแหน่งชั่วคราว แล้วยกเลิกการต่อเชื่อม)vold
จะบันทึกชื่อของอุปกรณ์บล็อกที่ถอดรหัสแล้วในพร็อพเพอร์ตี้ro.crypto.fs_crypto_blkdev
และแสดงสถานะ 0 ไปยัง UI หาก รหัสผ่านไม่ถูกต้อง รหัสผ่านจะแสดง -1 ใน UI - หยุดเฟรมเวิร์ก
UI สร้างกราฟิกเปิดเครื่องคริปโตแล้วโทรหา
vold
ด้วย คำสั่งcryptfs restart
vold
ตั้งค่าพร็อพเพอร์ตี้vold.decrypt
ถึงtrigger_reset_main
ซึ่งทำให้init.rc
เพื่อไปทำclass_reset main
การดำเนินการนี้จะหยุดบริการทั้งหมด ในคลาสหลัก ซึ่งทำให้สามารถยกเลิกการต่อเชื่อม tmpfs/data
- ต่อเชื่อม
/data
จากนั้น
vold
จะต่อเชื่อมพาร์ติชัน/data
จริงที่ถอดรหัสแล้ว และเตรียมพาร์ติชันใหม่ (ซึ่งอาจไม่เคยเตรียมไว้หาก มีการเข้ารหัสด้วยตัวเลือกล้างข้อมูล ซึ่งก่อนอื่นไม่รองรับ รุ่น) โดยจะตั้งค่าพร็อพเพอร์ตี้vold.post_fs_data_done
เป็น 0 แล้วตามด้วย ตั้งค่าvold.decrypt
เป็นtrigger_post_fs_data
ซึ่งทำให้init.rc
เพื่อเรียกใช้คำสั่งpost-fs-data
พวกเขาจะ สร้างไดเรกทอรีหรือลิงก์ที่จำเป็น แล้วตั้งค่าvold.post_fs_data_done
ต่อ 1 เมื่อvold
เห็น 1 ใน พร็อพเพอร์ตี้นั้นก็จะตั้งค่าพร็อพเพอร์ตี้vold.decrypt
เป็นtrigger_restart_framework
การดำเนินการนี้จะทำให้init.rc
เริ่มต้น บริการในชั้นเรียนmain
อีกครั้ง และเริ่มต้นบริการในชั้นเรียนด้วยlate_start
เป็นครั้งแรกนับตั้งแต่เปิดเครื่อง - เริ่มเฟรมเวิร์กอย่างเต็มรูปแบบ
ตอนนี้เฟรมเวิร์กจะเปิดเครื่องบริการทั้งหมดโดยใช้
/data
ที่ถอดรหัสแล้ว ระบบไฟล์และระบบพร้อมใช้งาน
ไม่สำเร็จ
อุปกรณ์ที่ถอดรหัสไม่สำเร็จอาจมีข้อผิดพลาดจากสาเหตุบางประการ อุปกรณ์ เริ่มต้นด้วยลำดับขั้นตอนปกติในการเปิดเครื่อง
- ตรวจหาอุปกรณ์ที่เข้ารหัสด้วยรหัสผ่าน
- ต่อเชื่อม tmpfs
- เริ่มเฟรมเวิร์กเพื่อขอรหัสผ่าน
แต่หลังจากที่เฟรมเวิร์กเปิดขึ้น อุปกรณ์อาจพบข้อผิดพลาดบางอย่าง ดังนี้
- รหัสผ่านตรงกันแต่ถอดรหัสข้อมูลไม่ได้
- ผู้ใช้ป้อนรหัสผ่านผิด 30 ครั้ง
หากข้อผิดพลาดเหล่านี้ยังไม่ได้รับการแก้ไข ให้แจ้งให้ผู้ใช้ล้างข้อมูลเป็นค่าเริ่มต้น
หาก vold
ตรวจพบข้อผิดพลาดในระหว่างกระบวนการเข้ารหัส และหาก
ยังไม่มีการทำลายข้อมูล และเฟรมเวิร์กพร้อมใช้งานแล้ว vold
ชุด
พร็อพเพอร์ตี้ vold.encrypt_progress
ไปยัง error_not_encrypted
UI จะแจ้งให้ผู้ใช้รีบูตและแจ้งเตือนกระบวนการเข้ารหัส
ไม่เคยเริ่มต้น หากข้อผิดพลาดเกิดขึ้นหลังจากที่เฟรมเวิร์กถูกแยกออกแล้ว แต่
ก่อนที่ UI ของแถบความคืบหน้าจะขึ้น vold
จะรีบูตระบบ ถ้า
การรีบูตล้มเหลว โดยตั้งค่า vold.encrypt_progress
เป็น
error_shutting_down
และส่งคืน -1 แต่จะไม่มีอะไร
เพื่อหาข้อผิดพลาด ซึ่งไม่คาดว่าจะเกิดขึ้น
หาก vold
ตรวจพบข้อผิดพลาดในระหว่างกระบวนการเข้ารหัส ระบบจะตั้งค่า
vold.encrypt_progress
ไปerror_partially_encrypted
และแสดงผลเป็น -1 UI ควรแสดงข้อความที่บอกว่าการเข้ารหัส
ล้มเหลวและให้ปุ่มสำหรับให้ผู้ใช้รีเซ็ตอุปกรณ์เป็นค่าเริ่มต้น
การจัดเก็บคีย์ที่เข้ารหัส
ระบบจะจัดเก็บคีย์ที่เข้ารหัสไว้ในข้อมูลเมตาของคริปโต การสนับสนุนฮาร์ดแวร์คือ โดยใช้ความสามารถในการลงชื่อของ Trusted Execution Environment (TEE) ก่อนหน้านี้ เราเข้ารหัสคีย์หลักด้วยคีย์ที่สร้างขึ้นโดยใช้ Scrypt รหัสผ่านของผู้ใช้และ Salt ที่เก็บไว้ เพื่อให้คีย์มีความยืดหยุ่น ต่อการโจมตีนอกกรอบ เราได้ขยายอัลกอริทึมนี้ด้วยการเซ็นคีย์ผลลัพธ์ ด้วยคีย์ TEE ที่เก็บไว้ จากนั้นลายเซ็นผลลัพธ์จะเปลี่ยนเป็น คีย์ความยาวโดยใช้การเข้ารหัสอีก 1 รายการ จากนั้นจะใช้คีย์นี้ในการเข้ารหัส และถอดรหัสมาสเตอร์คีย์ วิธีจัดเก็บคีย์นี้
- สร้างคีย์การเข้ารหัสดิสก์ 16 ไบต์แบบสุ่ม (DEK) และ Salt 16 ไบต์
- ใช้การเข้ารหัสกับรหัสผ่านผู้ใช้และ Salt เพื่อสร้างข้อมูลกลางขนาด 32 ไบต์ คีย์ 1 (IK1)
- แพด IK1 ที่มีขนาด 0 ไบต์ตามขนาดของคีย์ส่วนตัวที่ผูกกับฮาร์ดแวร์ (HBK) โดยเฉพาะอย่างยิ่ง เราจะเพิ่มค่าเป็น 00 || IK1 || 00..00 1 ไบต์, 32 IK1 ไบต์, 223 0 ไบต์
- เซ็นชื่อ IK1 ที่เพิ่มความหนาด้วย HBK เพื่อสร้าง IK2 ขนาด 256 ไบต์
- ใช้การเข้ารหัสกับ IK2 และ Salt (เกลือเดียวกับขั้นตอนที่ 2) เพื่อสร้าง IK3 ขนาด 32 ไบต์
- ใช้ 16 ไบต์แรกของ IK3 เป็น KEK และ 16 ไบต์สุดท้ายเป็น IV
- เข้ารหัส DEK ด้วย AES_CBC พร้อมด้วยคีย์ KEK และเวกเตอร์การเริ่มต้น IV
การเปลี่ยนรหัสผ่าน
เมื่อผู้ใช้เลือกที่จะเปลี่ยนหรือนำรหัสผ่านออกในการตั้งค่า UI จะส่ง
คำสั่ง cryptfs changepw
ไปยัง vold
และ
vold
จะเข้ารหัสคีย์มาสเตอร์ดิสก์อีกครั้งโดยใช้รหัสผ่านใหม่
คุณสมบัติการเข้ารหัส
vold
และ init
สื่อสารกันโดย
การตั้งค่าคุณสมบัติ รายการพร็อพเพอร์ตี้ที่พร้อมใช้งานสำหรับการเข้ารหัสมีดังนี้
พร็อพเพอร์ตี้ Vold
พร็อพเพอร์ตี้ | คำอธิบาย |
---|---|
vold.decrypt trigger_encryption |
เข้ารหัสไดรฟ์โดยไม่มี รหัสผ่าน |
vold.decrypt trigger_default_encryption |
ตรวจสอบไดรฟ์ว่ามีการเข้ารหัสโดยไม่ใช้รหัสผ่านหรือไม่
หากใช่ ให้ถอดรหัสและต่อเชื่อม
else ตั้งค่า vold.decrypt เป็นtrigger_restart_min_framework |
vold.decrypt trigger_reset_main |
ตั้งค่าโดย vold ให้ปิด UI ที่ขอรหัสผ่านดิสก์ |
vold.decrypt trigger_post_fs_data |
ตั้งค่าโดย vold เพื่อเตรียม /data ด้วยไดเรกทอรีที่จำเป็น และอื่นๆ |
vold.decrypt trigger_restart_framework |
กำหนดโดย vold เพื่อเริ่มต้นเฟรมเวิร์กและบริการทั้งหมดจริง |
vold.decrypt trigger_shutdown_framework |
ตั้งค่าโดย vold ให้ปิดเฟรมเวิร์กทั้งหมดเพื่อเริ่มการเข้ารหัส |
vold.decrypt trigger_restart_min_framework |
กำหนดโดย vold เพื่อเริ่มต้น
UI แถบความคืบหน้าสำหรับการเข้ารหัสหรือ
แจ้งให้ป้อนรหัสผ่าน โดยขึ้นอยู่กับ
ค่าของ ro.crypto.state |
vold.encrypt_progress |
เมื่อเฟรมเวิร์กเริ่มทำงาน หากมีการตั้งค่าพร็อพเพอร์ตี้นี้ ให้ป้อน โหมด UI ของแถบความคืบหน้า |
vold.encrypt_progress 0 to 100 |
UI ของแถบความคืบหน้าควร จะแสดงค่าเปอร์เซ็นต์ที่ตั้งไว้ |
vold.encrypt_progress error_partially_encrypted |
UI ของแถบความคืบหน้าควรแสดงข้อความว่าการเข้ารหัสล้มเหลว และ ให้ตัวเลือกแก่ผู้ใช้ในการ รีเซ็ตอุปกรณ์เป็นค่าเริ่มต้น |
vold.encrypt_progress error_reboot_failed |
UI แถบความคืบหน้าควรแสดงข้อความที่บอกว่าการเข้ารหัส เสร็จสมบูรณ์ และมอบปุ่มให้ผู้ใช้รีบูตอุปกรณ์ ข้อผิดพลาดนี้ ไม่คาดว่าจะเกิดขึ้น |
vold.encrypt_progress error_not_encrypted |
UI ของแถบความคืบหน้าควร แสดงข้อความที่บอกข้อผิดพลาด ไม่มีข้อมูลที่เข้ารหัส หรือ หากไม่พบ และให้ปุ่มเพื่อรีบูตระบบ |
vold.encrypt_progress error_shutting_down |
UI แถบความคืบหน้าไม่ทำงาน จึงไม่ทราบชัดเจนว่าใครจะตอบกลับ ข้อผิดพลาดนี้ได้ และยังไงก็ไม่ควรเกิดขึ้น |
vold.post_fs_data_done 0 |
ตั้งค่าโดย vold ก่อนการตั้งค่า vold.decrypt
ไปยัง trigger_post_fs_data |
vold.post_fs_data_done 1 |
ตั้งค่าโดย init.rc หรือ
init.rc หลังจากทำงานเสร็จ post-fs-data |
พร็อพเพอร์ตี้ init
พร็อพเพอร์ตี้ | คำอธิบาย |
---|---|
ro.crypto.fs_crypto_blkdev |
ตั้งค่าโดยคำสั่ง vold checkpw เพื่อใช้ในภายหลัง
ด้วยคำสั่ง vold restart |
ro.crypto.state unencrypted |
ตั้งค่าโดย init เพื่อบอกว่าระบบนี้กำลังทำงานพร้อมกับไฟล์ที่ไม่ได้เข้ารหัส
/data ro.crypto.state encrypted ตั้งค่าโดย init เพื่อพูด
ระบบนี้กำลังทำงานโดยมี /data ที่เข้ารหัส |
|
พร็อพเพอร์ตี้ทั้ง 5 นี้ตั้งค่าโดย
init เมื่อพยายามต่อเชื่อม /data กับพารามิเตอร์ที่ส่งจาก
init.rc vold ใช้ข้อมูลเหล่านี้เพื่อตั้งค่าการแมปคริปโต |
ro.crypto.tmpfs_options |
ตั้งค่าโดย init.rc พร้อมด้วยตัวเลือก init ที่ควรใช้เมื่อ
การต่อเชื่อมระบบไฟล์ tmpfs /data |
การดำเนินการเริ่มต้น
on post-fs-data on nonencrypted on property:vold.decrypt=trigger_reset_main on property:vold.decrypt=trigger_post_fs_data on property:vold.decrypt=trigger_restart_min_framework on property:vold.decrypt=trigger_restart_framework on property:vold.decrypt=trigger_shutdown_framework on property:vold.decrypt=trigger_encryption on property:vold.decrypt=trigger_default_encryption