การเข้ารหัสดิสก์แบบเต็ม

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

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

การเข้ารหัสแบบเต็มดิสก์ได้รับการแนะนำให้รู้จักกับ Android ใน 4.4 แต่ Android 5.0 ได้แนะนำคุณสมบัติใหม่เหล่านี้:

  • สร้างการเข้ารหัสที่รวดเร็ว ซึ่งเข้ารหัสเฉพาะบล็อกที่ใช้บนพาร์ติชั่นข้อมูลเพื่อหลีกเลี่ยงการบู๊ตครั้งแรกที่ใช้เวลานาน ขณะนี้มีเพียงระบบไฟล์ ext4 และ f2fs เท่านั้นที่รองรับการเข้ารหัสที่รวดเร็ว
  • เพิ่ม forceencrypt fstab เพื่อเข้ารหัสในการบูตครั้งแรก
  • เพิ่มการรองรับรูปแบบและการเข้ารหัสโดยไม่ต้องใช้รหัสผ่าน
  • เพิ่มที่เก็บข้อมูลฮาร์ดแวร์สำรองของคีย์การเข้ารหัสโดยใช้ความสามารถในการลงนามของ Trusted Execution Environment (TEE) (เช่นใน TrustZone) ดู การจัดเก็บคีย์ที่เข้ารหัส สำหรับรายละเอียดเพิ่มเติม

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

วิธีการทำงานของการเข้ารหัสทั้งดิสก์ของ Android

การเข้ารหัสดิสก์แบบเต็มของ Android ใช้ dm-crypt ซึ่งเป็นคุณสมบัติเคอร์เนลที่ทำงานที่เลเยอร์อุปกรณ์บล็อก ด้วยเหตุนี้ การเข้ารหัสจึงทำงานร่วมกับ Embedded MultiMediaCard ( eMMC) และอุปกรณ์แฟลชที่คล้ายกันซึ่งแสดงตัวต่อเคอร์เนลเป็นอุปกรณ์บล็อก YAFFS ไม่สามารถเข้ารหัสได้ ซึ่งพูดโดยตรงกับชิปแฟลช NAND แบบดิบ

อัลกอริธึมการเข้ารหัสคือ 128 Advanced Encryption Standard (AES) พร้อมด้วย cipher-block chaining (CBC) และ ESSIV:SHA256 มาสเตอร์คีย์ถูกเข้ารหัสด้วย AES 128 บิตผ่านการเรียกไปยังไลบรารี OpenSSL คุณต้องใช้ 128 บิตขึ้นไปสำหรับคีย์ (โดยที่ 256 เป็นทางเลือก)

หมายเหตุ: OEM สามารถใช้ 128 บิตหรือสูงกว่าในการเข้ารหัสมาสเตอร์คีย์

ในรุ่น Android 5.0 มีสถานะการเข้ารหัสสี่ประเภท:

  • ค่าเริ่มต้น
  • เข็มหมุด
  • รหัสผ่าน
  • ลวดลาย

เมื่อบู๊ตครั้งแรก อุปกรณ์จะสร้างมาสเตอร์คีย์ 128 บิตที่สร้างแบบสุ่ม จากนั้นแฮชด้วยรหัสผ่านเริ่มต้นและเก็บเกลือไว้ รหัสผ่านเริ่มต้นคือ: "default_password" อย่างไรก็ตาม แฮชผลลัพธ์ยังถูกเซ็นชื่อผ่าน TEE (เช่น TrustZone) ซึ่งใช้แฮชของลายเซ็นเพื่อเข้ารหัสมาสเตอร์คีย์

คุณสามารถค้นหารหัสผ่านเริ่มต้นที่กำหนดไว้ในไฟล์ cryptfs.cpp ของ Android Open Source Project

เมื่อผู้ใช้ตั้งค่า PIN/pass หรือรหัสผ่านบนอุปกรณ์ เฉพาะคีย์ 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 จริง ในการดำเนินการนี้ บริการทั้งหมดต้องอยู่ในหนึ่งในสามกลุ่ม: core , main และ late_start

  • core : ไม่เคยปิดตัวลงหลังจากเริ่มต้น
  • main : ปิดระบบแล้วรีสตาร์ทหลังจากป้อนรหัสผ่านดิสก์
  • late_start : ไม่เริ่มทำงานจนกว่า /data จะถูกถอดรหัสและติดตั้ง

เพื่อทริกเกอร์การดำเนินการเหล่านี้ คุณสมบัติ vold.decrypt ถูกตั้งค่าเป็น สตริงต่างๆ ในการฆ่าและเริ่มบริการใหม่ คำสั่ง init คือ:

  • class_reset : หยุดบริการ แต่อนุญาตให้เริ่มต้นใหม่ด้วย class_start
  • class_start : เริ่มบริการใหม่
  • class_stop : หยุดบริการและเพิ่มแฟล็ก SVC_DISABLED บริการที่หยุดไม่ตอบสนองต่อ class_start

กระแส

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

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

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

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

นี่เป็นการบู๊ตครั้งแรกตามปกติสำหรับอุปกรณ์ 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 เป็น trigger_restart_framework ซึ่งดำเนินการตามขั้นตอนการบู๊ตตามปกติ

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

นี่คือสิ่งที่จะเกิดขึ้นเมื่อคุณเข้ารหัส Android K ที่ไม่ได้เข้ารหัสหรืออุปกรณ์รุ่นก่อนหน้าซึ่งถูกย้ายไปยัง L

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

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

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

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

  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 จะตั้งค่าการทำแผนที่ crypto ซึ่งสร้างอุปกรณ์บล็อก crypto เสมือนที่จับคู่กับอุปกรณ์บล็อกจริง แต่เข้ารหัสแต่ละส่วนตามที่เขียน และถอดรหัสแต่ละส่วนในขณะที่อ่าน vold จะสร้างและเขียนข้อมูลเมตาของ crypto

  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 ของแถบความคืบหน้า ซึ่งจะสอบถามคุณสมบัตินั้นทุก ๆ ห้าวินาทีและอัปเดตแถบความคืบหน้า ลูปการเข้ารหัสจะอัพเดต vold.encrypt_progress ทุกครั้งที่เข้ารหัสอีกเปอร์เซ็นต์ของพาร์ติชั่น

  10. เมื่อ /data ถูกเข้ารหัส ให้อัปเดตส่วนท้ายของการเข้ารหัสลับ

    เมื่อ /data ถูกเข้ารหัสสำเร็จ vold จะล้างแฟล็ก ENCRYPTION_IN_PROGRESS ในข้อมูลเมตา

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

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

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

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

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

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

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

  2. ถอดรหัส /data

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

  3. เมานต์ /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 เป็นครั้งแรกนับตั้งแต่บูท

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

    ตอนนี้เฟรมเวิร์กเริ่มบริการทั้งหมดโดยใช้ decrypted /data และระบบก็พร้อมใช้งาน

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

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

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

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

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

  2. เมานต์ tmpfs

    init ตั้งค่าคุณสมบัติห้าประการเพื่อบันทึกตัวเลือกการเมานท์เริ่มต้นที่ให้ไว้สำหรับ /data พร้อมพารามิเตอร์ที่ส่งผ่านจาก init.rc vold ใช้คุณสมบัติเหล่านี้เพื่อตั้งค่าการทำแผนที่ crypto:

    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 (เลขฐานสิบหก ASCII 8 หลักนำหน้าด้วย 0x)
  3. เริ่มเฟรมเวิร์กเพื่อขอรหัสผ่าน

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

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

การจัดเก็บคีย์ที่เข้ารหัส

คีย์ที่เข้ารหัสจะถูกเก็บไว้ในข้อมูลเมตาของการเข้ารหัสลับ การสำรองข้อมูลฮาร์ดแวร์ดำเนินการโดยใช้ความสามารถในการลงนามของ Trusted Execution Environment (TEE) ก่อนหน้านี้ เราเข้ารหัสมาสเตอร์คีย์ด้วยคีย์ที่สร้างโดยการใช้การเข้ารหัสกับรหัสผ่านของผู้ใช้และเกลือที่เก็บไว้ เพื่อให้คีย์มีความยืดหยุ่นต่อการโจมตีแบบ off-box เราขยายอัลกอริทึมนี้โดยลงนามคีย์ผลลัพธ์ด้วยคีย์ TEE ที่เก็บไว้ ลายเซ็นผลลัพธ์จะถูกเปลี่ยนเป็นคีย์ความยาวที่เหมาะสมโดยแอปพลิเคชัน scrypt อีกหนึ่งโปรแกรม คีย์นี้จะใช้ในการเข้ารหัสและถอดรหัสมาสเตอร์คีย์ ในการจัดเก็บคีย์นี้:

  1. สร้างคีย์เข้ารหัสดิสก์ 16 ไบต์แบบสุ่ม (DEK) และเกลือ 16 ไบต์
  2. ใช้การเข้ารหัสกับรหัสผ่านผู้ใช้และเกลือเพื่อสร้างคีย์กลางขนาด 32 ไบต์ 1 (IK1)
  3. Pad IK1 ที่มีศูนย์ไบต์เท่ากับขนาดของคีย์ส่วนตัวที่ผูกกับฮาร์ดแวร์ (HBK) โดยเฉพาะอย่างยิ่ง เราใส่เป็น: 00 || IK1 || 00.00 น.; หนึ่งศูนย์ไบต์ 32 IK1 ไบต์ 223 ศูนย์ไบต์
  4. ลงชื่อเบาะ IK1 ด้วย HBK เพื่อสร้าง IK2 256 ไบต์
  5. ใช้ scrypt กับ IK2 และเกลือ (เกลือเดียวกับขั้นตอนที่ 2) เพื่อสร้าง IK3 ขนาด 32 ไบต์
  6. ใช้ 16 ไบต์แรกของ IK3 เป็น KEK และ 16 ไบต์สุดท้ายเป็น IV
  7. เข้ารหัส DEK ด้วย AES_CBC ด้วยคีย์ KEK และเวกเตอร์เริ่มต้น IV

การเปลี่ยนรหัสผ่าน

เมื่อผู้ใช้เลือกที่จะเปลี่ยนหรือลบรหัสผ่านในการตั้งค่า UI จะส่งคำสั่ง cryptfs changepw ไปที่ vold และ vold จะเข้ารหัสดิสก์มาสเตอร์คีย์อีกครั้งด้วยรหัสผ่านใหม่

คุณสมบัติการเข้ารหัส

vold และ init สื่อสารกันโดยการตั้งค่าคุณสมบัติ นี่คือรายการคุณสมบัติที่พร้อมใช้งานสำหรับการเข้ารหัส

คุณสมบัติของโวลด์

คุณสมบัติ คำอธิบาย
vold.decrypt trigger_encryption เข้ารหัสไดรฟ์โดยไม่ต้องใช้รหัสผ่าน
vold.decrypt trigger_default_encryption ตรวจสอบไดรฟ์เพื่อดูว่ามีการเข้ารหัสโดยไม่มีรหัสผ่านหรือไม่ หากใช่ ให้ถอดรหัสและติดตั้ง มิฉะนั้นให้ตั้งค่า 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

คุณสมบัติทั้งห้านี้ถูกกำหนดโดย init เมื่อพยายามเมานต์ /data ด้วยพารามิเตอร์ที่ส่งผ่านจาก init.rc vold ใช้สิ่งเหล่านี้เพื่อตั้งค่าการทำแผนที่ crypto
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