ใน Keymaster 1 คีย์ Keymaster ทั้งหมดจะเชื่อมโยงกับอุปกรณ์ Root of Trust หรือคีย์การบูตที่ยืนยันแล้วด้วยการเข้ารหัส ใน Keymaster 2 และ 3 คีย์ทั้งหมดจะเชื่อมโยงกับระบบปฏิบัติการและระดับแพตช์ของอิมเมจระบบด้วย ซึ่งจะช่วยให้มั่นใจได้ว่าผู้โจมตีที่ค้นพบจุดอ่อนในซอฟต์แวร์ระบบหรือ TEE เวอร์ชันเก่า จะไม่สามารถย้อนอุปกรณ์กลับไปใช้เวอร์ชันที่มีช่องโหว่ และใช้คีย์ที่สร้างด้วยเวอร์ชันใหม่กว่าได้ นอกจากนี้ เมื่อมีการใช้คีย์ ที่มีเวอร์ชันและระดับแพตช์ที่กำหนดในอุปกรณ์ที่อัปเกรด เป็นเวอร์ชันหรือระดับแพตช์ที่ใหม่กว่า ระบบจะอัปเกรดคีย์ก่อนจึงจะใช้งานได้ และจะทำให้คีย์เวอร์ชันก่อนหน้าใช้งานไม่ได้ ด้วยวิธีนี้ เมื่อมีการอัปเกรดอุปกรณ์ คีย์จะ *เลื่อน* ไปข้างหน้าพร้อมกับอุปกรณ์ แต่การเปลี่ยนอุปกรณ์กลับไปเป็นรุ่นก่อนหน้าจะทำให้คีย์ใช้งานไม่ได้
เพื่อรองรับโครงสร้างแบบโมดูลของ Treble และยกเลิกการเชื่อมโยง system.img กับ boot.img Keymaster 4 จึงเปลี่ยนรูปแบบการเชื่อมโยงเวอร์ชันคีย์ให้มี ระดับแพตช์แยกกันสำหรับแต่ละพาร์ติชัน ซึ่งจะช่วยให้อัปเดตแต่ละพาร์ติชัน แยกกันได้ ขณะที่ยังคงให้การปกป้องการย้อนกลับ
หากต้องการใช้การเชื่อมโยงเวอร์ชันนี้ แอปที่เชื่อถือได้ของ KeyMint (TA) ต้องมีวิธีรับเวอร์ชันของระบบปฏิบัติการและระดับแพตช์ปัจจุบันอย่างปลอดภัย รวมถึงต้องตรวจสอบว่าข้อมูลที่ได้รับตรงกับข้อมูลทั้งหมดเกี่ยวกับระบบที่กำลังทำงาน
- อุปกรณ์ที่มีการบูตที่ยืนยันแล้วของ Android (AVB) สามารถใส่ระดับแพตช์ทั้งหมด
และเวอร์ชันของระบบใน vbmeta เพื่อให้ Bootloader สามารถระบุข้อมูลดังกล่าวให้กับ
Keymaster ได้ สำหรับพาร์ติชันที่เชื่อมโยง ข้อมูลเวอร์ชันของพาร์ติชันจะอยู่ใน
vbmeta ที่เชื่อมโยง โดยทั่วไป ข้อมูลเวอร์ชันควรอยู่ใน
vbmeta struct
ที่มีข้อมูลการยืนยัน (แฮชหรือ แฮชทรี) สำหรับพาร์ติชันที่กำหนด - ในอุปกรณ์ที่ไม่มี AVB ให้ทำดังนี้
- การติดตั้งใช้งานการเปิดเครื่องที่ได้รับการยืนยันต้องระบุแฮชของข้อมูลเมตาเวอร์ชัน ให้กับ Bootloader เพื่อให้ Bootloader ระบุแฮชให้กับ Keymaster ได้
boot.img
จัดเก็บระดับแพตช์ในส่วนหัวต่อไปได้system.img
สามารถจัดเก็บระดับแพตช์และเวอร์ชันของระบบปฏิบัติการในพร็อพเพอร์ตี้แบบอ่านอย่างเดียวต่อไปได้vendor.img
จะจัดเก็บระดับแพตช์ในพร็อพเพอร์ตี้แบบอ่านอย่างเดียวro.vendor.build.version.security_patch
- Bootloader สามารถระบุแฮชของข้อมูลทั้งหมดที่ Verified Boot ตรวจสอบแล้ว ไปยัง Keymaster ได้
- ใน Android 9 ให้ใช้แท็กต่อไปนี้เพื่อระบุข้อมูลเวอร์ชันสำหรับพาร์ติชันต่อไปนี้
VENDOR_PATCH_LEVEL
: พาร์ติชันvendor
BOOT_PATCH_LEVEL
: พาร์ติชันboot
OS_PATCH_LEVEL
และOS_VERSION
: พาร์ติชันsystem
(ระบบนำOS_VERSION
ออกจาก ส่วนหัวของboot.img
-
การติดตั้งใช้งาน Keymaster ควรจัดการระดับแพตช์ทั้งหมดแยกกัน คีย์จะใช้ได้หากข้อมูลเวอร์ชันทั้งหมดตรงกับค่าที่เชื่อมโยงกับคีย์ และ
IKeymaster::upgradeDevice()
จะอัปเกรดเป็นระดับแพตช์ที่สูงขึ้นหากจำเป็น
การเปลี่ยนแปลง HAL
Android 7.1 ได้เพิ่มแท็ก
Tag::OS_VERSION
และ Tag::OS_PATCHLEVEL
รวมถึงเมธอด
configure
และ upgradeKey
เพื่อรองรับการเชื่อมโยงเวอร์ชันและการรับรองเวอร์ชัน การติดตั้งใช้งาน Keymaster 2 ขึ้นไปจะเพิ่มแท็กเวอร์ชัน
ลงในคีย์ที่สร้างขึ้นใหม่ทั้งหมด
(หรือคีย์ที่อัปเดต) โดยอัตโนมัติ นอกจากนี้ ความพยายามใดๆ ในการใช้คีย์ที่ไม่มีเวอร์ชันหรือระดับแพตช์ของระบบปฏิบัติการที่ตรงกับเวอร์ชันหรือระดับแพตช์ของระบบปฏิบัติการปัจจุบันจะถูกปฏิเสธพร้อมกับ ErrorCode::KEY_REQUIRES_UPGRADE
Tag::OS_VERSION
คือค่า UINT
ที่แสดงส่วนหลัก ส่วนย่อย และส่วนย่อยย่อยของเวอร์ชันระบบ Android เป็น MMmmss
โดยที่ MM คือเวอร์ชันหลัก, mm คือเวอร์ชันย่อย และ ss คือเวอร์ชันย่อยย่อย
เช่น 6.1.2 จะแสดงเป็น 060102
Tag::OS_PATCHLEVEL
คือค่า UINT
ที่แสดงถึง
ปีและเดือนของการอัปเดตระบบครั้งล่าสุดในรูปแบบ YYYYMM โดย YYYY คือ
ปี 4 หลัก และ MM คือเดือน 2 หลัก เช่น เดือนมีนาคม 2016 จะแสดงเป็น 201603
UpgradeKey
Android 7.1 ได้เพิ่มเมธอด upgradeKey
ลงใน HAL เพื่ออนุญาตให้อัปเกรดคีย์เป็นระบบปฏิบัติการเวอร์ชันใหม่และระดับแพตช์ของอิมเมจระบบ
Keymaster 3
upgradeKey(vec keyBlobToUpgrade, vec upgradeParams) generates(ErrorCode error, vec upgradedKeyBlob);
Keymaster 2
keymaster_error_t (*upgrade_key)(const struct keymaster2_device* dev, const keymaster_key_blob_t* key_to_upgrade, const keymaster_key_param_set_t* upgrade_params, keymaster_key_blob_t* upgraded_key);
dev
คือโครงสร้างอุปกรณ์keyBlobToUpgrade
คือคีย์ที่ต้องอัปเกรดupgradeParams
คือพารามิเตอร์ที่จำเป็นในการอัปเกรดคีย์ ซึ่งรวมถึงTag::APPLICATION_ID
และTag::APPLICATION_DATA
ซึ่งจำเป็นต่อการถอดรหัส Blob ของคีย์ หากมีการระบุไว้ในระหว่างการสร้างupgradedKeyBlob
คือพารามิเตอร์เอาต์พุตที่ใช้เพื่อส่งคืน ก้อนข้อมูลคีย์ใหม่
หากเรียกใช้ upgradeKey
ด้วย Blob คีย์ที่แยกวิเคราะห์ไม่ได้หรือ
ไม่ถูกต้อง ระบบจะแสดงผล ErrorCode::INVALID_KEY_BLOB
หากเรียกใช้ด้วยคีย์ที่มีระดับแพตช์สูงกว่าค่าระบบปัจจุบัน
ฟังก์ชันจะแสดงผล ErrorCode::INVALID_ARGUMENT
หากเรียกใช้ด้วยคีย์
ที่มีเวอร์ชันของระบบปฏิบัติการสูงกว่าค่าปัจจุบันของระบบ และค่าของระบบ
ไม่ใช่ 0 ฟังก์ชันจะแสดงผล ErrorCode::INVALID_ARGUMENT
อนุญาตให้อัปเกรดเวอร์ชันของระบบปฏิบัติการ
จากเวอร์ชันที่ไม่ใช่ 0 เป็น 0 ในกรณีที่เกิดข้อผิดพลาด
ในการสื่อสารกับโลกที่ปลอดภัย ฟังก์ชันจะแสดงผลค่าข้อผิดพลาดที่เหมาะสม (เช่น
ErrorCode::SECURE_HW_ACCESS_DENIED
,
ErrorCode::SECURE_HW_BUSY
) มิฉะนั้น ฟังก์ชันจะแสดงผล
ErrorCode::OK
และแสดงผลคีย์ Blob ใหม่ใน
upgradedKeyBlob
keyBlobToUpgrade
จะยังคงใช้งานได้หลังจากที่โทรหา upgradeKey
และในทางทฤษฎีแล้วสามารถนำกลับมาใช้ได้อีกหากมีการดาวน์เกรดอุปกรณ์ ในทางปฏิบัติ โดยทั่วไปแล้ว Keystore จะเรียก deleteKey
ใน
Blob keyBlobToUpgrade
หลังจากเรียก upgradeKey
ไม่นาน หาก keyBlobToUpgrade
มีแท็ก
Tag::ROLLBACK_RESISTANT
upgradedKeyBlob
ก็ควรมีแท็กดังกล่าวด้วย (และควรป้องกันการย้อนกลับได้)
การกำหนดค่าที่ปลอดภัย
หากต้องการใช้การเชื่อมโยงเวอร์ชัน TA ของ Keymaster ต้องมีวิธีรับเวอร์ชันและระดับแพตช์ของระบบปฏิบัติการปัจจุบัน (ข้อมูลเวอร์ชัน) อย่างปลอดภัย และต้องตรวจสอบว่าข้อมูลที่ได้รับตรงกับข้อมูลเกี่ยวกับระบบที่กำลังทำงานอยู่
เราได้เพิ่มOS_VERSION
ฟิลด์ลงในส่วนหัวของรูปภาพการบูตเพื่อรองรับการส่งข้อมูลเวอร์ชันไปยัง TA อย่างปลอดภัย สคริปต์การสร้างอิมเมจการบูต
จะกรอกข้อมูลในช่องนี้โดยอัตโนมัติ OEM และผู้ใช้ TA ของ Keymaster
ต้องทำงานร่วมกันเพื่อแก้ไข Bootloader ของอุปกรณ์เพื่อดึงข้อมูลเวอร์ชัน
จากอิมเมจการบูตและส่งไปยัง TA ก่อนที่จะบูตระบบที่ไม่ปลอดภัย
ซึ่งจะช่วยให้มั่นใจได้ว่าผู้โจมตีจะไม่สามารถรบกวนการจัดสรร
ข้อมูลเวอร์ชันให้กับ TA
นอกจากนี้ คุณยังต้องตรวจสอบว่าอิมเมจระบบมีข้อมูลเวอร์ชัน เดียวกันกับอิมเมจการบูต ด้วยเหตุนี้ เราจึงเพิ่มเมธอด configure ลงใน Keymaster HAL ดังนี้
keymaster_error_t (*configure)(const struct keymaster2_device* dev, const keymaster_key_param_set_t* params);
อาร์กิวเมนต์ params
มี Tag::OS_VERSION
และ Tag::OS_PATCHLEVEL
ไคลเอ็นต์ keymaster2 จะเรียกใช้เมธอดนี้
หลังจากเปิด HAL แต่ก่อนที่จะเรียกใช้เมธอดอื่นๆ หากมีการเรียกใช้เมธอดอื่นก่อน configure TA จะแสดงผล ErrorCode::KEYMASTER_NOT_CONFIGURED
เมื่อเรียกใช้ configure
เป็นครั้งแรกหลังจากที่อุปกรณ์บูตแล้ว ฟังก์ชันนี้ควรตรวจสอบว่าข้อมูลเวอร์ชันที่ระบุตรงกับข้อมูลที่บูตโหลดเดอร์ระบุหรือไม่ หากข้อมูลเวอร์ชันไม่ตรงกัน
configure
จะแสดง ErrorCode::INVALID_ARGUMENT
และเมธอด Keymaster อื่นๆ ทั้งหมดจะยังคงแสดง
ErrorCode::KEYMASTER_NOT_CONFIGURED
หากข้อมูลตรงกัน
configure
จะส่งคืน ErrorCode::OK
และวิธีการอื่นๆ ของ Keymaster
จะเริ่มทำงานตามปกติ
การเรียกใช้ configure
ครั้งต่อๆ ไปจะแสดงค่าเดียวกับที่การเรียกใช้ครั้งแรกแสดง และจะไม่เปลี่ยนสถานะของ Keymaster
เนื่องจากระบบจะเรียกใช้ configure
ซึ่งมีเนื้อหาที่ต้องการตรวจสอบ จึงมีโอกาสน้อยที่ผู้โจมตีจะบุกรุกอิมเมจของระบบและบังคับให้แสดงข้อมูลเวอร์ชันที่ตรงกับอิมเมจการบูต แต่ไม่ใช่เวอร์ชันจริงของระบบ
การรวมการยืนยันอิมเมจการเปิดเครื่อง การตรวจสอบ dm-verity ของเนื้อหาอิมเมจระบบ
และข้อเท็จจริงที่ว่าconfigure
จะเรียกใช้ตั้งแต่เนิ่นๆ ในการ
เปิดเครื่องระบบควรทำให้การใช้ประโยชน์จากช่องโหว่นี้เป็นไปได้ยาก