การติดตั้งใช้งาน dm-verity

Android 4.4 ขึ้นไปรองรับการเปิดเครื่องที่ได้รับการยืนยันผ่านตัวเลือก ฟีเจอร์เคอร์เนลของ Device-mapper-verity (dm-verity) ซึ่งให้ความโปร่งใส การตรวจสอบความสมบูรณ์ของอุปกรณ์ที่บล็อก dm-verity ช่วยป้องกัน Rootkits แบบถาวร ที่สามารถระงับสิทธิ์รูทและบุกรุกอุปกรณ์ ช่วงเวลานี้ ช่วยให้ผู้ใช้ Android มั่นใจได้ว่าเมื่อเปิดอุปกรณ์ ว่าอยู่ในเครื่องเดียวกันหรือไม่ เพื่อระบุว่ามีการใช้ครั้งล่าสุดเมื่อใด

แอปที่อาจเป็นอันตราย (PHA) ที่มีสิทธิ์รูทสามารถซ่อนจาก โปรแกรมตรวจจับและมาสก์ตนเอง ซอฟต์แวร์การรูทสามารถทำได้ เนื่องจากมักได้รับสิทธิ์มากกว่าเครื่องมือตรวจสอบ ซึ่งทำให้ ซอฟต์แวร์ที่จะ "โกหก" โปรแกรมตรวจจับ

ฟีเจอร์ dm-verity ให้คุณดูอุปกรณ์บล็อก ซึ่งก็คือพื้นที่เก็บข้อมูลเบื้องหลัง ของระบบไฟล์ และพิจารณาว่าตรงกับที่คาดไว้หรือไม่ การกำหนดค่า ซึ่งทำได้โดยใช้ระบบแฮชทรีแบบเข้ารหัส สำหรับทุกบล็อก (โดยปกติคือ 4K) โดยจะมีแฮช SHA256

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

dm-verity-hash-table

รูปที่ 1 ตารางแฮช dm-verity

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

การดำเนินการ

การป้องกัน dm-verity อยู่ในเคอร์เนล ดังนั้นหากซอฟต์แวร์การรูททำให้ซอฟต์แวร์ ระบบก่อนเคอร์เนลจะปรากฏขึ้น จะรักษาสิทธิ์การเข้าถึงนั้นไว้ เพื่อลดปัญหานี้ ผู้ผลิตส่วนใหญ่จะตรวจสอบเคอร์เนลด้วยคีย์ที่ฝังลงในอุปกรณ์ กุญแจดังกล่าวจะเปลี่ยนไม่ได้เมื่ออุปกรณ์ออกจากโรงงานแล้ว

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

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

แต่ dm-verity จะยืนยันการบล็อกทีละรายการและเฉพาะเมื่อ เข้าถึงแล้ว เมื่ออ่านลงในหน่วยความจำ ระบบจะแฮชบล็อกพร้อมกัน แฮชคือ จากนั้นจึงยืนยันโครงสร้าง และเพราะการอ่านบล็อกนั้นมีค่าใช้จ่ายสูง เวลาในการตอบสนองที่ได้จากการยืนยันระดับบล็อกนี้คือ น้อยมาก

หากการยืนยันไม่สำเร็จ อุปกรณ์จะสร้างข้อผิดพลาด I/O ซึ่งบ่งชี้ว่าเกิดการบล็อก ไม่สามารถอ่าน ซึ่งจะปรากฏราวกับว่าระบบไฟล์ได้รับความเสียหาย อย่างที่เป็น ที่คาดไว้

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

การแก้ไขข้อผิดพลาดในการส่งต่อ

Android 7.0 ขึ้นไปปรับปรุงประสิทธิภาพการทำงานจริงของ DM ด้วยข้อผิดพลาดการส่งต่อ ที่ถูกต้อง (FEC) การใช้งาน AOSP เริ่มต้นด้วย Reed-Solomon สำหรับการแก้ไขข้อผิดพลาดและใช้ เทคนิคที่เรียกว่าการแทรกสอด เพื่อลดโอเวอร์เฮดของพื้นที่และเพิ่ม จำนวนการบล็อกที่เสียหาย ซึ่งสามารถกู้คืนได้ ดูรายละเอียดเพิ่มเติมเกี่ยวกับ FEC ได้ที่ การเปิดเครื่องที่ได้รับการยืนยันอย่างเข้มงวดโดยมีการแก้ไขข้อผิดพลาด

การใช้งาน

สรุป

  1. สร้างอิมเมจระบบ ext4
  2. สร้างแผนผังแฮชสำหรับรูปภาพนั้น
  3. สร้างตาราง DM-verity สําหรับแฮชทรีดังกล่าว
  4. ลงนามในตาราง dm-verity เพื่อสร้างตาราง ลายเซ็น
  5. จัดกลุ่มลายเซ็นตารางและตาราง DM-verity ลงในข้อมูลเมตาจริง
  6. เชื่อมต่ออิมเมจระบบ ข้อมูลเมตาจริง และแฮชทรี

ดูโปรเจ็กต์ Chromium - การเปิดเครื่องที่ได้รับการยืนยัน เพื่อดูคำอธิบายโดยละเอียดของแผนผังแฮชและตาราง DM-verity

กำลังสร้างแฮชทรี

ตามที่อธิบายไว้ในบทนำ แผนผังแฮชเป็นส่วนประกอบสำคัญใน dm-verity เครื่องมือ cryptsetup จะ สร้างแฮชทรีให้คุณ อีกทางเลือกหนึ่งคือ การกำหนดที่เข้ากันได้มีดังต่อไปนี้

<your block device name> <your block device name> <block size> <block size> <image size in blocks> <image size in blocks + 8> <root hash> <salt>

ในการสร้างแฮช อิมเมจระบบจะถูกแยกที่เลเยอร์ 0 เป็นบล็อกขนาด 4K แต่ละบล็อก กำหนดแฮช SHA256 แล้ว เลเยอร์ 1 สร้างขึ้นจากการรวมเฉพาะแฮช SHA256 เหล่านั้น เป็นบล็อก 4k จะได้ภาพมีขนาดเล็กลงมาก มีการสร้างเลเยอร์ 2 ในลักษณะเดียวกันกับแฮช SHA256 ของเลเยอร์ 1

ดำเนินการจนกว่าจะรวมแฮช SHA256 ของเลเยอร์ก่อนหน้าได้พอดี บล็อก เมื่อได้รับ SHA256 ของบล็อกดังกล่าว คุณจะมีแฮชรากของโครงสร้าง

ขนาดของแฮชทรี (และการใช้งานพื้นที่ในดิสก์ที่เกี่ยวข้อง) จะแตกต่างกันไป ของพาร์ติชันที่ได้รับการยืนยัน ในทางปฏิบัติ ขนาดของแฮชต้นไม้ มักมีขนาดเล็ก มักไม่ถึง 30 MB

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

หากต้องการสร้างแฮชทรี ให้เชื่อมต่อแฮชของเลเยอร์ 2 เข้ากับแฮชของเลเยอร์เหล่านั้น 1, เลเยอร์ที่ 3 จะแฮชลงบนเลเยอร์ 2 และต่อไปเรื่อยๆ เขียนทั้งหมดนี้ ลงดิสก์ โปรดทราบว่าข้อมูลนี้ไม่ได้อ้างอิงเลเยอร์ 0 ของแฮชราก

กล่าวโดยสรุปคือ อัลกอริทึมทั่วไปในการสร้างแฮชทรีมีดังนี้

  1. เลือก Salt แบบสุ่ม (การเข้ารหัสเลขฐานสิบหก)
  2. แยกอิมเมจระบบเป็นบล็อก 4K
  3. รับแฮช SHA256 (แบบเค็ม) สำหรับแต่ละบล็อก
  4. เชื่อมต่อแฮชเหล่านี้เพื่อสร้างระดับ
  5. ขยายระดับด้วย 0s ถึงขอบเขตบล็อก 4K
  6. เชื่อมต่อระดับกับแผนผังแฮช
  7. ทำขั้นตอนที่ 2-6 ซ้ำโดยใช้ระดับก่อนหน้าเป็นแหล่งข้อมูลสำหรับขั้นตอนถัดไปจนถึง คุณมีแฮชเพียงรายการเดียว

ผลลัพธ์ที่ได้คือแฮชเดียวซึ่งเป็นแฮชราก นี่และเกลือของคุณ ใช้ระหว่างการสร้างตารางการแมปเวอร์ชัน dm-verity ของคุณ

การสร้างตารางการแมปเวอร์ชัน DM-verity

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

โปรดดู cryptsetup สำหรับ คำอธิบายโดยละเอียดของช่องตารางการแมปเป้าหมายความถูกต้อง

การลงนามในตาราง DM-verity

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

วิธียืนยันพาร์ติชันด้วยลายเซ็นและคีย์ผสมนี้

  1. เพิ่มคีย์ RSA-2048 ในรูปแบบที่เข้ากันได้กับ libmincrypt ลงใน พาร์ติชัน /boot เวลา /verity_key ระบุตำแหน่งของกุญแจที่ใช้ในการยืนยัน แผนผังแฮช
  2. ใน fstab ของรายการที่เกี่ยวข้อง ให้เพิ่ม verify ในแฟล็ก fs_mgr

จัดกลุ่มลายเซ็นตารางเป็นข้อมูลเมตา

จัดกลุ่มลายเซ็นตารางและตาราง DM-verity เป็นข้อมูลเมตายืนยัน ภาพรวม บล็อกของข้อมูลเมตาได้รับการกำหนดเวอร์ชัน ดังนั้นอาจขยายขนาด เช่น เพื่อเพิ่ม ลายเซ็นหรือเปลี่ยนลำดับ

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

โปรดตรวจสอบว่าคุณไม่ได้เลือกที่จะยืนยันพาร์ติชันที่ไม่ได้รับการยืนยัน หากใช่ หากไม่มีตัวเลขพิเศษนี้ จะทำให้กระบวนการยืนยันตัวตนหยุดลง หมายเลขนี้ คล้ายกับ:
0XB001B001

ค่าไบต์ในเลขฐาน 16 มีดังนี้

  • ไบต์แรก = b0
  • ไบต์ที่สอง = 01
  • ไบต์ที่สาม = b0
  • ไบต์ที่ 4 = 01

แผนภาพต่อไปนี้แสดงรายละเอียดของข้อมูลเมตาการตรวจสอบความถูกต้อง

<magic number>|<version>|<signature>|<table length>|<table>|<padding>
\-------------------------------------------------------------------/
\----------------------------------------------------------/   |
                            |                                  |
                            |                                 32K
                       block content

และตารางนี้จะอธิบายช่องข้อมูลเมตาเหล่านั้น

ตาราง 1 ช่องข้อมูลเมตาจริง

ช่อง วัตถุประสงค์ ขนาด ค่า
ตัวเลขมหัศจรรย์ ใช้โดย fs_mgr เป็นการตรวจสอบความถูกต้อง 4 ไบต์ 0XB001B001
เวอร์ชัน ที่ใช้กำหนดเวอร์ชันการบล็อกข้อมูลเมตา 4 ไบต์ ปัจจุบัน 0
ลายเซ็น ลายเซ็นของตารางในรูปแบบเสริม PKCS1.5 256 ไบต์
ความยาวตาราง ความยาวของตาราง dm-verity ในหน่วยไบต์ 4 ไบต์
โต๊ะ ตาราง DM-verity ที่อธิบายไว้ก่อนหน้านี้ ไบต์ความยาวตาราง
padding โครงสร้างนี้บุนวม 0 ถึง 32 กิโลไบต์ 0

การเพิ่มประสิทธิภาพมาตรฐาน DM

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

  • ในเคอร์เนล ให้เปิด NEON SHA-2 สำหรับ ARMv7 และ SHA-2 ส่วนขยายสำหรับ ARMv8
  • ทดสอบกับข้อมูลที่อ่านล่วงหน้าและ prefetch_cluster ที่แตกต่างกัน เพื่อหาการกำหนดค่าที่ดีที่สุดสำหรับอุปกรณ์ของคุณ