ใน Keymaster 1 คีย์คีย์มาสเตอร์ทั้งหมดถูกผูกไว้แบบเข้ารหัสกับอุปกรณ์ Root of Trust หรือคีย์ Verified Boot ใน Keymaster 2 และ 3 ปุ่มทั้งหมดจะเชื่อมโยงกับระบบปฏิบัติการและระดับแพตช์ของอิมเมจระบบด้วย สิ่งนี้ทำให้แน่ใจได้ว่าผู้โจมตีที่ค้นพบจุดอ่อนในระบบเวอร์ชันเก่าหรือซอฟต์แวร์ TEE จะไม่สามารถย้อนกลับอุปกรณ์กลับไปเป็นเวอร์ชันที่มีช่องโหว่และใช้คีย์ที่สร้างด้วยเวอร์ชันที่ใหม่กว่าได้ นอกจากนี้ เมื่อใช้คีย์ที่มีเวอร์ชันและระดับแพตช์ที่กำหนดบนอุปกรณ์ที่ได้รับการอัปเกรดเป็นเวอร์ชันใหม่หรือระดับแพตช์ คีย์จะได้รับการอัปเกรดก่อนจึงจะสามารถใช้งานได้ และคีย์เวอร์ชันก่อนหน้าจะใช้งานไม่ได้ ด้วยวิธีนี้ เมื่ออุปกรณ์ได้รับการอัปเกรด ปุ่มจะ "วงล้อ" ไปข้างหน้าพร้อมกับอุปกรณ์ แต่การพลิกอุปกรณ์กลับไปเป็นรุ่นก่อนหน้าจะทำให้ปุ่มใช้งานไม่ได้
เพื่อรองรับโครงสร้างโมดูลาร์ของ Treble และแยกการเชื่อมโยง system.img เป็น boot.img Keymaster 4 จึงเปลี่ยนรูปแบบการเชื่อมโยงเวอร์ชันคีย์ให้มีระดับแพตช์แยกกันสำหรับแต่ละพาร์ติชัน ซึ่งช่วยให้แต่ละพาร์ติชั่นสามารถอัพเดตแยกกันได้ ในขณะที่ยังคงให้การป้องกันการย้อนกลับ
ใน Android 9 boot
system
และ vendor
ต่างก็มีระดับแพตช์ของตัวเอง
- อุปกรณ์ที่มี Android Verified Boot (AVB) สามารถใส่ระดับแพตช์และเวอร์ชันของระบบทั้งหมดไว้ใน vbmeta ได้ ดังนั้นโปรแกรมโหลดบูตจึงสามารถมอบให้กับ Keymaster ได้ สำหรับพาร์ติชันที่ถูกเชน ข้อมูลเวอร์ชันสำหรับพาร์ติชันจะอยู่ใน chained vbmeta โดยทั่วไป ข้อมูลเวอร์ชันควรอยู่ใน
vbmeta struct
ที่มีข้อมูลการตรวจสอบ (แฮชหรือแฮชทรี) สำหรับพาร์ติชันที่กำหนด - บนอุปกรณ์ที่ไม่มี AVB:
- การใช้งาน Verified Boot จำเป็นต้องจัดเตรียมแฮชของข้อมูลเมตาของเวอร์ชันให้กับ bootloader เพื่อให้ bootloader สามารถจัดเตรียมแฮชให้กับ Keymaster ได้
-
boot.img
สามารถจัดเก็บระดับแพตช์ในส่วนหัวต่อไปได้ -
system.img
สามารถจัดเก็บระดับแพตช์และเวอร์ชันระบบปฏิบัติการต่อไปได้ในคุณสมบัติอ่านอย่างเดียว -
vendor.img
เก็บระดับแพตช์ไว้ในคุณสมบัติอ่านอย่างเดียวro.vendor.build.version.security_patch
- bootloader สามารถจัดเตรียมแฮชของข้อมูลทั้งหมดที่ได้รับการตรวจสอบโดยการบูตที่ตรวจสอบแล้วให้กับคีย์มาสเตอร์
- ใน Android 9 ให้ใช้แท็กต่อไปนี้เพื่อระบุข้อมูลเวอร์ชันสำหรับพาร์ติชันต่อไปนี้:
-
VENDOR_PATCH_LEVEL
: พาร์ติชันvendor
-
BOOT_PATCH_LEVEL
: พาร์ติชันboot
บูต -
OS_PATCH_LEVEL
และOS_VERSION
: พาร์ติชันsystem
(OS_VERSION
ถูกลบออกจากส่วนหัวboot.img
-
- การใช้งาน Keymaster ควรปฏิบัติต่อระดับแพตช์ทั้งหมดอย่างเป็นอิสระ คีย์สามารถใช้งานได้หากข้อมูลเวอร์ชันทั้งหมดตรงกับค่าที่เกี่ยวข้องกับคีย์ และ
IKeymaster::upgradeDevice()
จะเปลี่ยนเป็นระดับแพตช์ที่สูงกว่าหากจำเป็น
การเปลี่ยนแปลงของฮาล
เพื่อรองรับการผูกเวอร์ชันและการรับรองเวอร์ชัน 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 คือปีที่มีตัวเลขสี่หลัก และ MM คือเดือนที่มีตัวเลขสองหลัก เช่น มีนาคม 2016 จะแสดงเป็น 201603
อัพเกรดคีย์
หากต้องการอนุญาตให้อัปเกรดคีย์เป็นเวอร์ชันระบบปฏิบัติการใหม่และระดับแพตช์ของอิมเมจระบบ Android 7.1 ได้เพิ่มวิธี upgradeKey
ให้กับ HAL:
คีย์มาสเตอร์ 3
upgradeKey(vec keyBlobToUpgrade, vec upgradeParams) generates(ErrorCode error, vec upgradedKeyBlob);
คีย์มาสเตอร์ 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
ซึ่งจำเป็นในการถอดรหัสคีย์บล็อบ หากมีการระบุไว้ระหว่างการสร้าง -
upgradedKeyBlob
เป็นพารามิเตอร์เอาต์พุต ใช้เพื่อส่งคืนคีย์ Blob ใหม่
หากเรียก upgradeKey
ด้วยคีย์ Blob ที่ไม่สามารถแยกวิเคราะห์ได้หรือไม่ถูกต้อง จะส่งคืน ErrorCode::INVALID_KEY_BLOB
หากถูกเรียกด้วยคีย์ที่มีระดับแพตช์มากกว่าค่ากำหนดของระบบปัจจุบัน จะส่งกลับ ErrorCode::INVALID_ARGUMENT
หากถูกเรียกด้วยคีย์ที่มีเวอร์ชันระบบปฏิบัติการมากกว่าค่ากำหนดของระบบปัจจุบัน และค่ากำหนดของระบบไม่เป็นศูนย์ จะส่งกลับ ErrorCode::INVALID_ARGUMENT
อนุญาตให้อัปเกรดเวอร์ชันระบบปฏิบัติการจากที่ไม่ใช่ศูนย์เป็นศูนย์ได้ ในกรณีที่มีข้อผิดพลาดในการสื่อสารกับโลกที่ปลอดภัย ระบบจะส่งกลับค่าข้อผิดพลาดที่เหมาะสม (เช่น ErrorCode::SECURE_HW_ACCESS_DENIED
, ErrorCode::SECURE_HW_BUSY
) มิฉะนั้นจะส่งคืน ErrorCode::OK
และส่งคืนคีย์หยดใหม่ใน upgradedKeyBlob
keyBlobToUpgrade
ยังคงใช้ได้หลังจากการเรียก upgradeKey
และในทางทฤษฎีสามารถใช้งานได้อีกครั้งหากอุปกรณ์ถูกดาวน์เกรด ในทางปฏิบัติ โดยทั่วไปที่เก็บคีย์จะเรียก deleteKey
บน keyBlobToUpgrade
blob ไม่นานหลังจากการเรียกไปยัง upgradeKey
หาก keyBlobToUpgrade
มีแท็ก Tag::ROLLBACK_RESISTANT
ดังนั้น upgradedKeyBlob
ก็ควรมีเช่นกัน (และควรต้านทานการย้อนกลับ)
การกำหนดค่าที่ปลอดภัย
หากต้องการใช้การเชื่อมโยงเวอร์ชัน คีย์มาสเตอร์ TA จำเป็นต้องมีวิธีการรับเวอร์ชันระบบปฏิบัติการปัจจุบันและระดับแพตช์ (ข้อมูลเวอร์ชัน) อย่างปลอดภัย และเพื่อให้แน่ใจว่าข้อมูลที่ได้รับตรงกับข้อมูลเกี่ยวกับระบบที่ทำงานอยู่อย่างยิ่ง
เพื่อรองรับการส่งข้อมูลเวอร์ชันไปยัง TA อย่างปลอดภัย จึงได้มีการเพิ่ม ฟิลด์ OS_VERSION
ลงในส่วนหัวของอิมเมจสำหรับบูต สคริปต์สร้างอิมเมจสำหรับบูตจะเติมฟิลด์นี้โดยอัตโนมัติ OEM และผู้ใช้งาน TA คีย์มาสเตอร์จำเป็นต้องทำงานร่วมกันเพื่อแก้ไขบูทโหลดเดอร์ของอุปกรณ์เพื่อแยกข้อมูลเวอร์ชันจากอิมเมจสำหรับบูทและส่งต่อไปยัง TA ก่อนที่ระบบที่ไม่ปลอดภัยจะถูกบูท สิ่งนี้ทำให้แน่ใจได้ว่าผู้โจมตีไม่สามารถแทรกแซงการจัดเตรียมข้อมูลเวอร์ชันให้กับ TA ได้
นอกจากนี้ยังจำเป็นเพื่อให้แน่ใจว่าอิมเมจระบบมีข้อมูลเวอร์ชันเดียวกันกับอิมเมจสำหรับบูต ด้วยเหตุนี้จึงมีการเพิ่มวิธีการกำหนดค่าให้กับคีย์มาสเตอร์ 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 แต่ก่อนที่จะเรียกเมธอดอื่นใด หากมีการเรียกเมธอดอื่นก่อนกำหนดค่า TA จะส่งกลับ ErrorCode::KEYMASTER_NOT_CONFIGURED
ครั้งแรกที่ configure
ถูกเรียกหลังจากอุปกรณ์บู๊ต ควรตรวจสอบว่าข้อมูลเวอร์ชันที่ให้มาตรงกับที่ Bootloader ให้มา หากข้อมูลเวอร์ชันไม่ตรงกัน configure
ส่งคืน ErrorCode::INVALID_ARGUMENT
และวิธีการคีย์มาสเตอร์อื่นๆ ทั้งหมดจะส่งคืน ErrorCode::KEYMASTER_NOT_CONFIGURED
ต่อไป หากข้อมูลตรงกัน ให้ configure
ค่าส่งคืน ErrorCode::OK
และวิธีการคีย์มาสเตอร์อื่นๆ จะเริ่มทำงานตามปกติ
การเรียกครั้งต่อไปเพื่อ configure
จะส่งคืนค่าเดิมที่ส่งคืนโดยการเรียกครั้งแรก และไม่เปลี่ยนสถานะของคีย์มาสเตอร์ โปรดทราบว่ากระบวนการนี้ต้องการให้ OTA ทั้งหมดอัปเดตทั้งระบบและอิมเมจสำหรับบูต ไม่สามารถอัปเดตแยกกันเพื่อเก็บข้อมูลเวอร์ชันให้ตรงกันได้
เนื่องจากระบบจะเรียกใช้ configure
ซึ่งมีเนื้อหาที่ต้องการตรวจสอบ จึงมีหน้าต่างโอกาสที่แคบสำหรับผู้โจมตีที่จะโจมตีอิมเมจของระบบและบังคับให้ระบุข้อมูลเวอร์ชันที่ตรงกับอิมเมจสำหรับบูต แต่ไม่ใช่ข้อมูลจริง รุ่นของระบบ การรวมกันของการตรวจสอบอิมเมจสำหรับบูต การตรวจสอบความถูกต้อง dm-verity ของเนื้อหาอิมเมจระบบ และความจริงที่ว่าการ configure
ถูกเรียกตั้งแต่เนิ่นๆ ในการบูตระบบควรทำให้หน้าต่างแห่งโอกาสนี้ยากต่อการใช้ประโยชน์