การเข้ารหัสทั้งดิสก์

การเข้ารหัสทั้งดิสก์คือกระบวนการเข้ารหัสข้อมูลผู้ใช้ทั้งหมดในอุปกรณ์ 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_start
  • class_start: รีสตาร์ทบริการ
  • class_stop: หยุดบริการและเพิ่มแฟล็ก SVC_DISABLED บริการที่หยุดจะไม่ตอบสนองต่อ class_start

ขั้นตอน

อุปกรณ์ที่เข้ารหัสจะมี 4 ขั้นตอน อุปกรณ์จะได้รับการเข้ารหัสเพียงครั้งเดียว จากนั้นทำตามขั้นตอนการเปิดเครื่องตามปกติ

  • วิธีเข้ารหัสอุปกรณ์ที่ไม่ได้เข้ารหัสก่อนหน้านี้
    • เข้ารหัสอุปกรณ์ใหม่ด้วย forceencrypt: การเข้ารหัสที่บังคับ เมื่อเปิดเครื่องครั้งแรก (เริ่มต้นใน Android L)
    • เข้ารหัสอุปกรณ์ที่มีอยู่: การเข้ารหัสที่เริ่มต้นโดยผู้ใช้ (Android K และรุ่นก่อนหน้า)
  • วิธีเปิดเครื่องที่เข้ารหัส
    • การเริ่มต้นใช้งานอุปกรณ์ที่เข้ารหัสโดยไม่ต้องใช้รหัสผ่าน: การเปิดเครื่องอุปกรณ์ที่เข้ารหัสซึ่ง ไม่ได้ตั้งรหัสผ่าน (ใช้ได้กับอุปกรณ์ที่ใช้ Android 5.0 ขึ้นไป)
    • การเริ่มต้นใช้งานอุปกรณ์ที่เข้ารหัสด้วยรหัสผ่าน: การเปิดเครื่องอุปกรณ์ที่เข้ารหัสซึ่ง ตั้งรหัสผ่านแล้ว

นอกจากทำตามขั้นตอนเหล่านี้แล้ว อุปกรณ์อาจเข้ารหัส /data ไม่สำเร็จด้วย เราจะอธิบายขั้นตอนแต่ละขั้นอย่างละเอียดที่ด้านล่าง

เข้ารหัสอุปกรณ์ใหม่ด้วยการบังคับใช้การเข้ารหัส

นี่เป็นการเปิดเครื่องครั้งแรกตามปกติสำหรับอุปกรณ์ Android 5.0

  1. ตรวจหาระบบไฟล์ที่ไม่ได้เข้ารหัสด้วยแฟล็ก forceencrypt

    /data ไม่ได้เข้ารหัสแต่ต้องเป็นสมาชิกเนื่องจาก forceencrypt เป็นผู้กำหนด ยกเลิกการต่อเชื่อม /data

  2. เริ่มเข้ารหัส /data

    vold.decrypt = "trigger_encryption" ทริกเกอร์ init.rc ซึ่งจะทำให้ vold เข้ารหัส /data โดยไม่ใช้รหัสผ่าน (ไม่ได้ตั้งค่าไว้เนื่องจากควรเป็นอุปกรณ์ใหม่)

  3. ต่อเชื่อม tmpfs

    vold ต่อเชื่อม tmpfs /data (โดยใช้ตัวเลือก tmpfs จาก ro.crypto.tmpfs_options) และตั้งค่าพร็อพเพอร์ตี้ vold.encrypt_progress เป็น 0 vold เตรียม tmpfs /data สำหรับการเปิดเครื่องระบบที่เข้ารหัสและตั้งค่า พร็อพเพอร์ตี้ vold.decrypt ถึง: trigger_restart_min_framework

  4. แสดงเฟรมเวิร์กเพื่อแสดงความคืบหน้า

    เนื่องจากอุปกรณ์ไม่มีข้อมูลที่จะเข้ารหัส แถบความคืบหน้าจะ ซึ่งมักจะไม่ปรากฏขึ้นเพราะการเข้ารหัสเกิดขึ้นเร็วมาก โปรดดู เข้ารหัสอุปกรณ์ที่มีอยู่เพื่อรับข้อมูลเพิ่มเติม รายละเอียดเกี่ยวกับ UI ความคืบหน้า

  5. เมื่อเข้ารหัส /data แล้ว ให้ลบเฟรมเวิร์กออก

    vold กำหนด vold.decrypt เป็น trigger_default_encryption ซึ่งเริ่มต้น defaultcrypto (ซึ่งจะเริ่มขั้นตอนด้านล่างเพื่อต่อเชื่อม ข้อมูลผู้ใช้ที่เข้ารหัสไว้เริ่มต้น) trigger_default_encryption ตรวจสอบ ประเภทการเข้ารหัสเพื่อดูว่า /data เข้ารหัสโดยมีหรือไม่มี รหัสผ่าน เนื่องจากอุปกรณ์ Android 5.0 ได้รับการเข้ารหัสเมื่อเปิดเครื่องครั้งแรก จึงควรมี ต้องไม่ตั้งรหัสผ่าน ดังนั้น เราจะถอดรหัสและต่อเชื่อม /data

  6. ต่อเชื่อม /data

    จากนั้น init จะต่อเชื่อม /data บน tmpfs RAMDisk โดยใช้ พารามิเตอร์ที่ดึงมาจาก ro.crypto.tmpfs_options ซึ่งตั้งค่าไว้ ใน init.rc

  7. เริ่มเฟรมเวิร์ก

    vold กำหนด vold.decrypt เป็น trigger_restart_framework ซึ่งจะเริ่มการเปิดเครื่องตามปกติต่อไป ขั้นตอนได้

เข้ารหัสอุปกรณ์ที่มีอยู่

นี่คือสิ่งที่เกิดขึ้นเมื่อคุณเข้ารหัส Android K ที่ไม่ได้เข้ารหัสหรือเวอร์ชันก่อนหน้า อุปกรณ์ที่ย้ายข้อมูลไปยัง L แล้ว

กระบวนการนี้เริ่มต้นโดยผู้ใช้ และเรียกว่า "การเข้ารหัสภายใน" ใน โค้ด เมื่อผู้ใช้เลือกที่จะเข้ารหัสอุปกรณ์ UI จะตรวจสอบว่า ชาร์จแบตเตอรี่เต็มแล้ว และเสียบอะแดปเตอร์ AC อยู่เพื่อให้ชาร์จเพียงพอ เพื่อดำเนินขั้นตอนการเข้ารหัสให้เสร็จสิ้น

คำเตือน: หากอุปกรณ์หมดและปิดก่อนที่จะใช้งานจบ กำลังเข้ารหัส ข้อมูลไฟล์จะอยู่ในสถานะที่เข้ารหัสบางส่วน อุปกรณ์ต้อง รีเซ็ตเป็นค่าเริ่มต้น และข้อมูลทั้งหมดจะหายไป

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

สถานะของอุปกรณ์: ตั้งค่า ro.crypto.state = "unencrypted" และเรียกใช้ทริกเกอร์ on nonencrypted init เพื่อเปิดเครื่องต่อ

  1. ตรวจสอบรหัสผ่าน

    UI เรียก vold ด้วยคำสั่ง cryptfs enablecrypto inplace โดยที่ passwd คือรหัสผ่านล็อกหน้าจอของผู้ใช้

  2. ลบเฟรมเวิร์กออก

    vold ตรวจหาข้อผิดพลาด แสดงผล -1 หากเข้ารหัสไม่ได้ และ พิมพ์เหตุผลในบันทึก หากเข้ารหัสได้ ระบบจะตั้งค่าพร็อพเพอร์ตี้ vold.decrypt ไปยัง trigger_shutdown_framework ซึ่งส่งผลให้ init.rc หยุดบริการในชั้นเรียน late_start และ main

  3. สร้างส่วนท้ายของคริปโต
  4. สร้างไฟล์เบรดครัมบ์
  5. รีบูต
  6. ตรวจหาไฟล์เบรดครัมบ์
  7. เริ่มเข้ารหัส /data

    จากนั้น vold ตั้งค่าการแมปคริปโต ซึ่งจะสร้างอุปกรณ์บล็อกคริปโตเสมือน ที่จับคู่กับอุปกรณ์บล็อกจริง แต่เข้ารหัสแต่ละภาคส่วนตามที่เขียนไว้ และถอดรหัสแต่ละส่วนขณะที่อ่าน จากนั้น vold จะสร้างและเขียน ข้อมูลเมตาของคริปโต

  8. ขณะเข้ารหัส ให้ต่อเชื่อม tmpfs

    vold ต่อเชื่อม tmpfs /data (โดยใช้ตัวเลือก tmpfs จาก ro.crypto.tmpfs_options) และตั้งค่าพร็อพเพอร์ตี้ vold.encrypt_progress ถึง 0 vold เตรียม tmpfs /dataสำหรับการเปิดเครื่องระบบที่เข้ารหัสและตั้งค่าพร็อพเพอร์ตี้ vold.decrypt ถึง: trigger_restart_min_framework

  9. แสดงเฟรมเวิร์กเพื่อแสดงความคืบหน้า

    trigger_restart_min_framework ทำให้ init.rc ถึง เริ่มต้นคลาสของบริการ main เมื่อเฟรมเวิร์กเห็นว่า vold.encrypt_progress ตั้งค่าเป็น 0 และจะแสดงแถบความคืบหน้า UI ซึ่งจะค้นหาพร็อพเพอร์ตี้ทุกๆ 5 วินาทีและอัปเดตแถบความคืบหน้า ลูปการเข้ารหัสจะอัปเดต vold.encrypt_progress ทุกครั้ง เข้ารหัสอีกเปอร์เซ็นต์ของพาร์ติชัน

  10. เมื่อเข้ารหัส /data แล้ว ให้อัปเดตส่วนท้ายของคริปโต

    เมื่อเข้ารหัส /data เรียบร้อยแล้ว vold จะลบ แฟล็ก ENCRYPTION_IN_PROGRESS ในข้อมูลเมตา

    เมื่ออุปกรณ์ปลดล็อกเรียบร้อยแล้ว จะมีการใช้รหัสผ่านเพื่อ เข้ารหัสคีย์ต้นแบบและอัปเดตส่วนท้ายของ Crypto

    หากการรีบูตล้มเหลวด้วยเหตุผลบางอย่าง vold จะตั้งค่าพร็อพเพอร์ตี้ vold.encrypt_progress ถึง error_reboot_failed และ UI ควรแสดงข้อความที่ขอให้ผู้ใช้กดปุ่มเพื่อ รีบูต กรณีนี้ไม่คาดคิดมาก่อน

การเริ่มใช้อุปกรณ์ที่เข้ารหัสด้วยการเข้ารหัสเริ่มต้น

นี่คือสิ่งที่เกิดขึ้นเมื่อคุณเปิดอุปกรณ์ที่เข้ารหัสโดยไม่มีรหัสผ่าน เนื่องจากอุปกรณ์ Android 5.0 ได้รับการเข้ารหัสเมื่อเปิดเครื่องครั้งแรก จึงไม่ควรตั้งค่าใดๆ รหัสผ่าน ดังนั้นจึงเป็นสถานะการเข้ารหัสเริ่มต้น

  1. ตรวจหา /data ที่เข้ารหัสโดยไม่มีรหัสผ่าน

    ตรวจพบว่าอุปกรณ์ Android มีการเข้ารหัสเนื่องจาก /data ไม่สามารถติดตั้งและหนึ่งใน Flag encryptable หรือ ตั้งค่า forceencrypt แล้ว

    vold กำหนด vold.decrypt เป็น trigger_default_encryption ซึ่งเริ่มต้น defaultcrypto trigger_default_encryption ตรวจสอบประเภทการเข้ารหัสเพื่อดูว่า /data มีการเข้ารหัสกับ หรือ โดยไม่ต้องใช้รหัสผ่าน

  2. ถอดรหัส /data

    สร้างอุปกรณ์ dm-crypt บนอุปกรณ์ที่บล็อก เพื่อให้อุปกรณ์ดังกล่าว พร้อมใช้งานแล้ว

  3. ต่อเชื่อม /ข้อมูล

    จากนั้น 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 สำหรับ ระยะเวลาตั้งแต่เปิดเครื่อง

  4. เริ่มเฟรมเวิร์ก

    ตอนนี้เฟรมเวิร์กจะเปิดเครื่องบริการทั้งหมดโดยใช้ /data ที่ถอดรหัสแล้ว และระบบพร้อมใช้งาน

การเริ่มใช้อุปกรณ์ที่เข้ารหัสโดยไม่มีการเข้ารหัสเริ่มต้น

นี่คือสิ่งที่เกิดขึ้นเมื่อคุณเปิดอุปกรณ์ที่เข้ารหัสและมีชุดอุปกรณ์ รหัสผ่าน รหัสผ่านของอุปกรณ์อาจเป็น PIN, รูปแบบ หรือรหัสผ่านก็ได้

  1. ตรวจหาอุปกรณ์ที่เข้ารหัสด้วยรหัสผ่าน

    ตรวจพบว่าอุปกรณ์ Android ได้รับการเข้ารหัสเนื่องจากธง ro.crypto.state = "encrypted"

    vold กำหนด vold.decrypt เป็น trigger_restart_min_framework เนื่องจาก/data เข้ารหัสด้วยรหัสผ่าน

  2. ต่อเชื่อม tmpfs

    init กำหนดพร็อพเพอร์ตี้ 5 รายการเพื่อบันทึกตัวเลือกการต่อเชื่อมเริ่มต้น ที่ระบุสำหรับ /data ที่มีพารามิเตอร์ที่ส่งจาก init.rc vold ใช้พร็อพเพอร์ตี้เหล่านี้เพื่อตั้งค่าการแมปคริปโต

    1. ro.crypto.fs_type
    2. ro.crypto.fs_real_blkdev
    3. ro.crypto.fs_mnt_point
    4. ro.crypto.fs_options
    5. ro.crypto.fs_flags (เลขฐานสิบหก 8 หลัก ASCII นำหน้าด้วย 0x)
  3. เริ่มเฟรมเวิร์กเพื่อขอรหัสผ่าน

    เฟรมเวิร์กเริ่มต้นขึ้นและเห็นว่า vold.decrypt ได้รับการตั้งค่าเป็น trigger_restart_min_framework ซึ่งจะบอกเฟรมเวิร์กว่า การเปิดเครื่องในดิสก์ /data ของ tmpfs และจำเป็นต้องมีรหัสผ่านของผู้ใช้

    อย่างไรก็ตาม อันดับแรกต้องตรวจสอบว่าดิสก์ได้รับการเข้ารหัสอย่างถูกต้อง ทั้งนี้ ส่งคำสั่ง cryptfs cryptocomplete ไปยัง vold vold แสดงผล 0 หากการเข้ารหัสเสร็จสมบูรณ์ แสดงผล -1 สำหรับข้อผิดพลาดภายใน หรือ -2 หากเข้ารหัสไม่สำเร็จ vold กำหนด โดยดูที่ข้อมูลเมตาของคริปโตสำหรับCRYPTO_ENCRYPTION_IN_PROGRESS แจ้ง หากตั้งค่าไว้ ขั้นตอนการเข้ารหัสจะหยุดชะงักและจะไม่มี ข้อมูลที่ใช้ได้ในอุปกรณ์ หาก vold แสดงข้อผิดพลาด UI ควร แสดงข้อความให้ผู้ใช้รีบูตและรีเซ็ตอุปกรณ์เป็นค่าเริ่มต้น และให้ ให้ผู้ใช้กดเพื่อทำเช่นนั้น

  4. ถอดรหัสข้อมูลด้วยรหัสผ่าน

    เมื่อ cryptfs cryptocomplete สำเร็จ เฟรมเวิร์ก แสดง UI ที่ขอรหัสผ่านดิสก์ UI ตรวจสอบรหัสผ่านโดย กำลังส่งคำสั่ง cryptfs checkpw ไปยัง vold หาก รหัสผ่านถูกต้อง (ซึ่งทราบได้จากการต่อเชื่อม ถอดรหัส /data ที่ตำแหน่งชั่วคราว แล้วยกเลิกการต่อเชื่อม) vold จะบันทึกชื่อของอุปกรณ์บล็อกที่ถอดรหัสแล้วในพร็อพเพอร์ตี้ ro.crypto.fs_crypto_blkdev และแสดงสถานะ 0 ไปยัง UI หาก รหัสผ่านไม่ถูกต้อง รหัสผ่านจะแสดง -1 ใน UI

  5. หยุดเฟรมเวิร์ก

    UI สร้างกราฟิกเปิดเครื่องคริปโตแล้วโทรหา vold ด้วย คำสั่ง cryptfs restart vold ตั้งค่าพร็อพเพอร์ตี้ vold.decrypt ถึง trigger_reset_main ซึ่งทำให้ init.rc เพื่อไปทำ class_reset main การดำเนินการนี้จะหยุดบริการทั้งหมด ในคลาสหลัก ซึ่งทำให้สามารถยกเลิกการต่อเชื่อม tmpfs /data

  6. ต่อเชื่อม /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 เป็นครั้งแรกนับตั้งแต่เปิดเครื่อง

  7. เริ่มเฟรมเวิร์กอย่างเต็มรูปแบบ

    ตอนนี้เฟรมเวิร์กจะเปิดเครื่องบริการทั้งหมดโดยใช้ /data ที่ถอดรหัสแล้ว ระบบไฟล์และระบบพร้อมใช้งาน

ไม่สำเร็จ

อุปกรณ์ที่ถอดรหัสไม่สำเร็จอาจมีข้อผิดพลาดจากสาเหตุบางประการ อุปกรณ์ เริ่มต้นด้วยลำดับขั้นตอนปกติในการเปิดเครื่อง

  1. ตรวจหาอุปกรณ์ที่เข้ารหัสด้วยรหัสผ่าน
  2. ต่อเชื่อม tmpfs
  3. เริ่มเฟรมเวิร์กเพื่อขอรหัสผ่าน

แต่หลังจากที่เฟรมเวิร์กเปิดขึ้น อุปกรณ์อาจพบข้อผิดพลาดบางอย่าง ดังนี้

  • รหัสผ่านตรงกันแต่ถอดรหัสข้อมูลไม่ได้
  • ผู้ใช้ป้อนรหัสผ่านผิด 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 รายการ จากนั้นจะใช้คีย์นี้ในการเข้ารหัส และถอดรหัสมาสเตอร์คีย์ วิธีจัดเก็บคีย์นี้

  1. สร้างคีย์การเข้ารหัสดิสก์ 16 ไบต์แบบสุ่ม (DEK) และ Salt 16 ไบต์
  2. ใช้การเข้ารหัสกับรหัสผ่านผู้ใช้และ Salt เพื่อสร้างข้อมูลกลางขนาด 32 ไบต์ คีย์ 1 (IK1)
  3. แพด IK1 ที่มีขนาด 0 ไบต์ตามขนาดของคีย์ส่วนตัวที่ผูกกับฮาร์ดแวร์ (HBK) โดยเฉพาะอย่างยิ่ง เราจะเพิ่มค่าเป็น 00 || IK1 || 00..00 1 ไบต์, 32 IK1 ไบต์, 223 0 ไบต์
  4. เซ็นชื่อ IK1 ที่เพิ่มความหนาด้วย HBK เพื่อสร้าง IK2 ขนาด 256 ไบต์
  5. ใช้การเข้ารหัสกับ IK2 และ Salt (เกลือเดียวกับขั้นตอนที่ 2) เพื่อสร้าง IK3 ขนาด 32 ไบต์
  6. ใช้ 16 ไบต์แรกของ IK3 เป็น KEK และ 16 ไบต์สุดท้ายเป็น IV
  7. เข้ารหัส 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 ที่เข้ารหัส

ro.crypto.fs_type
ro.crypto.fs_real_blkdev
ro.crypto.fs_mnt_point
ro.crypto.fs_options
ro.crypto.fs_flags

พร็อพเพอร์ตี้ทั้ง 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