สถาปัตยกรรมการรับรองในอุปกรณ์

ตั้งแต่ 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 จะจัดการการติดตั้งใช้งานดังนี้

  1. ในการบูตครั้งแรก คีย์สโตร์จะสร้างคีย์แบบสมมาตร K0 โดยตั้งค่าแท็ก MAX_USES_PER_BOOT เป็น 1 ซึ่งหมายความว่าคุณจะใช้คีย์ได้เพียงครั้งเดียวต่อการบูต
  2. ในระหว่างการบูต หากระดับการบูตเพิ่มขึ้น ระบบจะสร้างคีย์ใหม่สำหรับระดับการบูตนั้นจาก K0 โดยใช้ฟังก์ชัน HKDF: Ki+i=HKDF(Ki, "some_fixed_string") เช่น หากคุณเปลี่ยนจากระดับการบูต 0 เป็นระดับการบูต 10 ระบบจะเรียกใช้ HKDF 10 ครั้งเพื่อดึงข้อมูล K10 จาก K0
  3. เมื่อระดับการบูตเปลี่ยนแปลง ระบบจะลบคีย์สำหรับระดับการบูตก่อนหน้าออกจากหน่วยความจำ และคีย์ที่เชื่อมโยงกับระดับการบูตก่อนหน้าจะใช้งานไม่ได้อีกต่อไป

    คีย์ 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 ใช้ได้เฉพาะในระดับการบูตช่วงต้นเท่านั้น จึงไม่สามารถสร้างขึ้นโดยผู้โจมตี