ตั้งแต่ Android 12 เป็นต้นไป โมดูลรันไทม์ Android (ART) จะเป็นโมดูลหลัก การอัปเดตโมดูลอาจกำหนดให้ต้องสร้างอาร์ติแฟกต์การคอมไพล์ล่วงหน้า (AOT) ของไฟล์ JAR บูตแคมพ์และเซิร์ฟเวอร์ระบบขึ้นมาใหม่ เนื่องจากรายการต่างๆ เหล่านี้มีความละเอียดอ่อนด้านความปลอดภัย Android 12 จึงใช้ฟีเจอร์ที่เรียกว่าการลงนามในอุปกรณ์เพื่อป้องกันไม่ให้มีการเปลี่ยนแปลงรายการเหล่านี้ หน้านี้อธิบายสถาปัตยกรรมการรับรองในอุปกรณ์และการโต้ตอบกับฟีเจอร์ความปลอดภัยอื่นๆ ของ Android
การออกแบบระดับสูง
การรับรองในอุปกรณ์ประกอบด้วยองค์ประกอบหลัก 2 อย่าง ได้แก่
odrefresh
เป็นส่วนหนึ่งของโมดูล ART Mainline มีหน้าที่รับผิดชอบในการสร้างอาร์ติแฟกต์รันไทม์ โดยจะตรวจสอบอาร์ติแฟกต์ที่มีอยู่เทียบกับเวอร์ชันที่ติดตั้งของโมดูล ART, jar ของบูตคลาส และ jar ของเซิร์ฟเวอร์ระบบ เพื่อพิจารณาว่าอาร์ติแฟกต์เป็นเวอร์ชันล่าสุดหรือต้องสร้างใหม่ หากต้องสร้างใหม่odrefresh
จะสร้างและจัดเก็บodsign
เป็นไบนารีที่เป็นส่วนหนึ่งของแพลตฟอร์ม Android โดยจะทำงานระหว่างการบูตช่วงต้นทันทีหลังจากมีการต่อเชื่อมพาร์ติชัน/data
หน้าที่หลักของodrefresh
คือเรียกใช้odrefresh
เพื่อตรวจสอบว่าต้องสร้างหรืออัปเดตอาร์ติแฟกต์หรือไม่ สําหรับอาร์ติแฟกต์ใหม่หรือที่อัปเดตซึ่งodrefresh
สร้างขึ้นodsign
จะคํานวณฟังก์ชันแฮช ผลลัพธ์ของการประมวลผลแฮชดังกล่าวเรียกว่าข้อมูลสรุปไฟล์ สำหรับอาร์ติแฟกต์ที่มีอยู่แล้วodsign
จะยืนยันว่าข้อมูลสรุปของอาร์ติแฟกต์ที่มีอยู่ตรงกับข้อมูลสรุปที่odsign
คำนวณไว้ก่อนหน้านี้ ซึ่งช่วยให้มั่นใจว่าไม่มีการเปลี่ยนแปลงไฟล์
ในกรณีที่เกิดข้อผิดพลาด เช่น เมื่อข้อมูลสรุปของไฟล์ไม่ตรงกัน odrefresh
และ odsign
จะทิ้งอาร์ติแฟกต์ที่มีอยู่ทั้งหมดใน /data
และพยายามสร้างอาร์ติแฟกต์เหล่านั้นอีกครั้ง หากไม่สำเร็จ ระบบจะกลับไปใช้โหมด JIT
odrefresh
และ odsign
ได้รับการปกป้องโดย dm-verity
และเป็นส่วนหนึ่งของเชนการบูตที่ได้รับการยืนยันของ Android
การคํานวณข้อมูลสรุปไฟล์ด้วย fs-verity
fs-verity เป็นฟีเจอร์ของเคอร์เนล Linux ที่ใช้การตรวจสอบข้อมูลไฟล์ตาม Merkle Tree การเปิดใช้ fs-verity ในไฟล์จะทำให้ระบบไฟล์สร้างต้นไม้ Merkle บนข้อมูลของไฟล์โดยใช้แฮช SHA-256 จัดเก็บไว้ในตำแหน่งที่ซ่อนอยู่ข้างไฟล์ และทําเครื่องหมายไฟล์เป็นแบบอ่านอย่างเดียว fs-verity จะยืนยันข้อมูลของไฟล์กับต้นไม้ Merkle โดยอัตโนมัติตามคําขอขณะที่อ่าน fs-verity จะทำให้แฮชรูทของต้นไม้ Merkle พร้อมใช้งานเป็นค่าที่เรียกว่าข้อมูลสรุปไฟล์ fs-verity และ fs-verity จะตรวจสอบว่าข้อมูลที่อ่านจากไฟล์สอดคล้องกับข้อมูลสรุปไฟล์นี้
odsign
ใช้ fs-verity เพื่อปรับปรุงประสิทธิภาพการบูตโดยเพิ่มประสิทธิภาพการตรวจสอบสิทธิ์การเข้ารหัสของอาร์ติแฟกต์ที่คอมไพล์ในอุปกรณ์ในเวลาบูต เมื่อสร้างอาร์ติแฟกต์แล้ว odsign
จะเปิดใช้ fs-verity ในอาร์ติแฟกต์นั้น เมื่อ odsign
ยืนยันอาร์ติแฟกต์ ระบบจะยืนยันข้อมูลสรุปไฟล์ fs-verity แทนแฮชไฟล์แบบเต็ม ซึ่งทำให้ไม่ต้องอ่านและแฮชข้อมูลทั้งหมดของอาร์ติแฟกต์ในเวลาบูต ข้อมูลอาร์ติแฟกต์จะได้รับการแฮชตามคําขอโดย fs-verity แทนขณะใช้งาน โดยแบ่งเป็นแต่ละบล็อก
ในอุปกรณ์ที่เคอร์เนลไม่รองรับ fs-verity odsign
จะเปลี่ยนไปใช้การประมวลผลข้อมูลสรุปไฟล์ในพื้นที่ผู้ใช้ odsign
ใช้อัลกอริทึมแฮชที่อิงตาม Merkle Tree เดียวกันกับ fs-verity ดังนั้นข้อมูลสรุปจะเหมือนกันในทุกกรณี
อุปกรณ์ทุกเครื่องที่เปิดตัวด้วย Android 11 ขึ้นไปจำเป็นต้องใช้ fs-verity
พื้นที่เก็บข้อมูลของข้อมูลสรุปไฟล์
odsign
จะจัดเก็บข้อมูลสรุปไฟล์ของอาร์ติแฟกต์ไว้ในไฟล์แยกต่างหากชื่อ
odsign.info
odsign.info
ได้รับการเซ็นชื่อด้วยคีย์การเซ็นชื่อที่มีพร็อพเพอร์ตี้ด้านความปลอดภัยที่สำคัญเพื่อให้แน่ใจว่าไม่มีการดัดแปลง odsign.info
โดยเฉพาะอย่างยิ่ง คีย์จะสร้างขึ้นและใช้ได้ในช่วงการบูตระยะแรกเท่านั้น ซึ่งจะมีเพียงโค้ดที่เชื่อถือได้เท่านั้นที่ทำงานอยู่ ดูรายละเอียดได้ที่คีย์การรับรองที่เชื่อถือได้
การยืนยันข้อมูลสรุปไฟล์
ในการบูตทุกครั้ง หาก odrefresh
พิจารณาว่าอาร์ติแฟกต์ที่มีอยู่เป็นเวอร์ชันล่าสุด odsign
จะตรวจสอบว่าไฟล์ไม่ได้ถูกดัดแปลงตั้งแต่สร้าง odsign
ดำเนินการนี้โดยการยืนยันข้อมูลสรุปไฟล์ ก่อนอื่น ระบบจะยืนยันลายเซ็นของ odsign.info
หากลายเซ็นถูกต้อง odsign
จะยืนยันว่าข้อมูลสรุปของไฟล์แต่ละไฟล์ตรงกับข้อมูลสรุปที่เกี่ยวข้องใน odsign.info
คีย์การลงชื่อที่เชื่อถือได้
Android 12 เปิดตัวฟีเจอร์คีย์สโตร์ใหม่ที่เรียกว่า "คีย์ระยะการบูต" ซึ่งจะจัดการกับข้อกังวลด้านความปลอดภัยต่อไปนี้
- อะไรป้องกันไม่ให้ผู้โจมตีใช้คีย์การรับรองของเราเพื่อรับรอง
odsign.info
เวอร์ชันของตนเอง - อะไรป้องกันไม่ให้ผู้โจมตีสร้างคีย์ Signing ของตนเองและใช้คีย์ดังกล่าวเพื่อรับรอง
odsign.info
เวอร์ชันของตนเอง
คีย์ระยะการบูตจะแบ่งวงจรการบูตของ Android เป็นระดับต่างๆ และเชื่อมโยงการสร้างและการใช้คีย์กับระดับที่ระบุด้วยการเข้ารหัส odsign
จะสร้างคีย์การรับรองในระดับต้นๆ เมื่อมีเพียงโค้ดที่เชื่อถือได้เท่านั้นที่ทำงานอยู่ ซึ่งได้รับการปกป้องผ่าน dm-verity
ระดับระยะการบูตจะนับจาก 0 ถึงตัวเลขพิเศษ 1000000000 ในระหว่างกระบวนการบูตของ Android คุณสามารถเพิ่มระดับการบูตได้โดยการตั้งค่าพร็อพเพอร์ตี้ของระบบจาก init.rc
ตัวอย่างเช่น โค้ดต่อไปนี้จะตั้งค่าระดับการบูตเป็น 10
setprop keystore.boot_level 10
ลูกค้าของคีย์สโตร์สามารถสร้างคีย์ที่เชื่อมโยงกับระดับการบูตที่เฉพาะเจาะจงได้ ตัวอย่างเช่น หากคุณสร้างคีย์สำหรับระดับการบูต 10 คีย์นั้นจะใช้ได้ก็ต่อเมื่ออุปกรณ์อยู่ในระดับการบูต 10 เท่านั้น
odsign
ใช้ระดับการบูต 30 และคีย์การรับรองที่สร้างจะเชื่อมโยงกับระดับการบูตนั้น ก่อนใช้คีย์เพื่อรับรองอาร์ติแฟกต์ odsign
จะยืนยันว่าคีย์นั้นเชื่อมโยงกับระดับการบูต 30
ซึ่งจะช่วยป้องกัน 2 รูปแบบการโจมตีที่อธิบายไว้ก่อนหน้านี้ในส่วนนี้
- ผู้โจมตีจะใช้คีย์ที่สร้างขึ้นไม่ได้ เนื่องจากเมื่อผู้โจมตีมีโอกาสเรียกใช้โค้ดที่เป็นอันตราย ระดับการบูตจะเพิ่มขึ้นเกิน 30 และ Keystore จะปฏิเสธการดำเนินการที่ใช้คีย์
- ผู้โจมตีจะสร้างคีย์ใหม่ไม่ได้ เนื่องจากเมื่อผู้โจมตีมีโอกาสเรียกใช้โค้ดที่เป็นอันตราย ระดับการบูตจะเพิ่มขึ้นเกิน 30 และ Keystore จะปฏิเสธที่จะสร้างคีย์ใหม่ที่มีระดับการบูตดังกล่าว หากผู้โจมตีสร้างคีย์ใหม่ที่ไม่ได้เชื่อมโยงกับระดับการบูต 30
odsign
จะปฏิเสธคีย์นั้น
คีย์สโตร์ช่วยให้มั่นใจได้ว่าระดับการบูตได้รับการบังคับใช้อย่างถูกต้อง ส่วนต่อไปนี้จะอธิบายรายละเอียดเพิ่มเติมเกี่ยวกับวิธีดำเนินการนี้สำหรับ Keymaster เวอร์ชันต่างๆ
การติดตั้งใช้งาน Keymaster 4.0
Keymaster เวอร์ชันต่างๆ จะจัดการการใช้งานคีย์ระยะการบูตแตกต่างกัน ในอุปกรณ์ที่มี TEE/Strongbox ของ Keymaster 4.0 ทาง Keymaster จะจัดการการติดตั้งใช้งานดังนี้
- ในการบูตครั้งแรก คีย์สโตร์จะสร้างคีย์แบบสมมาตร K0 โดยตั้งค่าแท็ก
MAX_USES_PER_BOOT
เป็น1
ซึ่งหมายความว่าคุณจะใช้คีย์ได้เพียงครั้งเดียวต่อการบูต - ในระหว่างการบูต หากระดับการบูตเพิ่มขึ้น ระบบจะสร้างคีย์ใหม่สำหรับระดับการบูตนั้นจาก K0 โดยใช้ฟังก์ชัน HKDF:
Ki+i=HKDF(Ki, "some_fixed_string")
เช่น หากคุณเปลี่ยนจากระดับการบูต 0 เป็นระดับการบูต 10 ระบบจะเรียกใช้ HKDF 10 ครั้งเพื่อดึงข้อมูล K10 จาก K0 เมื่อระดับการบูตเปลี่ยนแปลง ระบบจะลบคีย์สำหรับระดับการบูตก่อนหน้าออกจากหน่วยความจำ และคีย์ที่เชื่อมโยงกับระดับการบูตก่อนหน้าจะใช้งานไม่ได้อีกต่อไป
คีย์ K0 เป็นคีย์
MAX_USES_PER_BOOT=1
ซึ่งหมายความว่าคุณจะใช้คีย์นั้นในภายหลังในการบูตไม่ได้เช่นกัน เนื่องจากจะมีการเปลี่ยนระดับการบูตอย่างน้อย 1 ครั้ง (ไปยังระดับการบูตสุดท้าย) เสมอ
เมื่อไคลเอ็นต์คีย์สโตร์ เช่น odsign
ขอสร้างคีย์ในบูตระดับ i
ระบบจะเข้ารหัส Blob ของไคลเอ็นต์ด้วยคีย์ Ki
เนื่องจาก Ki
ไม่พร้อมใช้งานหลังจากระดับการบูต i
ระบบจึงสร้างหรือถอดรหัสคีย์นี้ไม่ได้ในขั้นตอนการบูตในภายหลัง
การติดตั้งใช้งาน Keymaster 4.1 และ KeyMint 1.0
การติดตั้งใช้งาน Keymaster 4.1 และ KeyMint 1.0 ส่วนใหญ่จะเหมือนกับการติดตั้งใช้งาน Keymaster 4.0 ความแตกต่างหลักคือ K0 ไม่ใช่คีย์ MAX_USES_PER_BOOT
แต่เป็นคีย์ EARLY_BOOT_ONLY
ซึ่งเปิดตัวใน Keymaster 4.1 คุณใช้คีย์ EARLY_BOOT_ONLY
ได้ในช่วงเริ่มต้นของบูตเท่านั้น เมื่อไม่มีโค้ดที่ไม่น่าเชื่อถือทำงานอยู่ ซึ่งจะเพิ่มการป้องกันอีกชั้นหนึ่ง: ในการใช้งาน Keymaster 4.0 ผู้โจมตีที่เข้าถึงระบบไฟล์และ SELinux ได้จะแก้ไขฐานข้อมูลคีย์สโตร์เพื่อสร้างคีย์ MAX_USES_PER_BOOT=1
ของตนเองเพื่อใช้ลงนามในอาร์ติแฟกต์ได้ การใช้ Keymaster 4.1 และ KeyMint 1.0 จะทำให้การโจมตีดังกล่าวเป็นไปไม่ได้ เนื่องจากEARLY_BOOT_ONLY
ระบบจะสร้างคีย์ได้ในช่วงการบูตระยะแรกเท่านั้น
คอมโพเนนต์สาธารณะของคีย์การลงชื่อที่เชื่อถือได้
odsign
ดึงข้อมูลคอมโพเนนต์คีย์สาธารณะของคีย์การลงนามจากคีย์สโตร์
อย่างไรก็ตาม คีออสเทอร์จะไม่ดึงข้อมูลคีย์สาธารณะนั้นจาก TEE/SE ที่มีคีย์ส่วนตัวที่เกี่ยวข้อง แต่ระบบจะดึงข้อมูลคีย์สาธารณะจากฐานข้อมูลในดิสก์ของตนเองแทน ซึ่งหมายความว่าผู้โจมตีที่เข้าถึงระบบไฟล์ได้อาจแก้ไขฐานข้อมูลคีย์สโตร์ให้มีคีย์สาธารณะซึ่งเป็นส่วนหนึ่งของคู่คีย์สาธารณะ/ส่วนตัวภายใต้การควบคุมของตน
odsign
จะสร้างคีย์ HMAC เพิ่มเติมที่มีระดับการบูตเดียวกับคีย์การลงชื่อเพื่อป้องกันการโจมตีนี้ จากนั้นเมื่อสร้างคีย์การลงนาม odsign
จะใช้คีย์ HMAC นี้เพื่อสร้างลายเซ็นของคีย์สาธารณะและจัดเก็บลายเซ็นนั้นไว้ในดิสก์ เมื่อบูตเครื่องครั้งต่อๆ ไป ระบบจะเรียกข้อมูลคีย์สาธารณะของคีย์การลงนามโดยใช้คีย์ HMAC เพื่อยืนยันว่าลายเซ็นบนดิสก์ตรงกับลายเซ็นของคีย์สาธารณะที่เรียกข้อมูล หากตรงกัน แสดงว่าคีย์สาธารณะเชื่อถือได้ เนื่องจากคีย์ HMAC ใช้ได้เฉพาะในระดับการบูตช่วงต้นเท่านั้น จึงไม่สามารถสร้างขึ้นโดยผู้โจมตี