ใน 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 ดังนั้น bootloader สามารถจัดเตรียมให้กับ Keymaster ได้ สำหรับพาร์ติชันที่ถูกล่ามโซ่ ข้อมูลเวอร์ชันสำหรับพาร์ติชันจะอยู่ใน vbmeta ที่ถูกล่ามโซ่ โดยทั่วไป ข้อมูลเวอร์ชันควรอยู่ในโครงสร้าง
vbmeta struct
ที่มีข้อมูลการตรวจสอบ (hash หรือ hashtree) สำหรับพาร์ติชันที่กำหนด - บนอุปกรณ์ที่ไม่มี AVB:
- การใช้งาน Boot ที่ตรวจสอบแล้วจำเป็นต้องจัดเตรียมแฮชของข้อมูลเมตาเวอร์ชันให้กับ bootloader เพื่อให้ bootloader สามารถจัดเตรียมแฮชให้กับ Keymaster
-
boot.img
สามารถจัดเก็บระดับแพตช์ต่อไปในส่วนหัว -
system.img
สามารถจัดเก็บระดับแพตช์และเวอร์ชัน OS ต่อไปในคุณสมบัติแบบอ่านอย่างเดียวได้ -
vendor.img
เก็บระดับแพตช์ไว้ในคุณสมบัติอ่านอย่างเดียวro.vendor.build.version.security_patch
- โปรแกรมโหลดบูตสามารถจัดเตรียมแฮชของข้อมูลทั้งหมดที่ตรวจสอบแล้วโดยการบูตที่ยืนยันไปยังคีย์มาสเตอร์
- ใน 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 คือปีที่มีตัวเลขสี่หลัก และ 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
เป็นพารามิเตอร์เอาต์พุต ใช้เพื่อส่งคืนคีย์บล็อบใหม่
ถ้า upgradeKey
ถูกเรียกด้วย key blob ที่ไม่สามารถแยกวิเคราะห์หรือไม่ถูกต้อง มันจะส่งคืน ErrorCode::INVALID_KEY_BLOB
หากมีการเรียกด้วยคีย์ที่มีระดับแพตช์มากกว่าค่าระบบปัจจุบัน จะส่งคืน ErrorCode::INVALID_ARGUMENT
หากมีการเรียกด้วยคีย์ที่มีเวอร์ชันระบบปฏิบัติการมากกว่าค่าระบบปัจจุบัน และค่าของระบบไม่ใช่ศูนย์ ฟังก์ชันจะส่งคืน ErrorCode::INVALID_ARGUMENT
อนุญาตให้อัปเกรดเวอร์ชันระบบปฏิบัติการจากที่ไม่ใช่ศูนย์เป็นศูนย์ได้ ในกรณีที่มีข้อผิดพลาดในการสื่อสารกับโลกที่ปลอดภัย จะแสดงค่าความผิดพลาดที่เหมาะสม (เช่น ErrorCode::SECURE_HW_ACCESS_DENIED
, ErrorCode::SECURE_HW_BUSY
) มิฉะนั้น จะส่งคืน ErrorCode::OK
และส่งคืน key blob ใหม่ใน upgradedKeyBlob
keyBlobToUpgrade
ยังคงใช้ได้หลังจากการเรียก upgradeKey
และในทางทฤษฎีสามารถนำมาใช้อีกครั้งได้หากอุปกรณ์ถูกดาวน์เกรด ในทางปฏิบัติ โดยทั่วไปที่เก็บคีย์จะเรียก deleteKey
บน keyBlobToUpgrade
blob ไม่นานหลังจากการเรียก upgradeKey
หาก keyBlobToUpgrade
มีแท็ก Tag::ROLLBACK_RESISTANT
ดังนั้น upgradedKeyBlob
ควรมีเช่นกัน (และควรป้องกันการย้อนกลับ)
การกำหนดค่าที่ปลอดภัย
ในการปรับใช้การเชื่อมโยงเวอร์ชัน Keymaster TA ต้องการวิธีรับเวอร์ชันระบบปฏิบัติการปัจจุบันและระดับแพตช์อย่างปลอดภัย (ข้อมูลเวอร์ชัน) และเพื่อให้แน่ใจว่าข้อมูลที่ได้รับนั้นตรงกับข้อมูลเกี่ยวกับระบบที่ทำงานอยู่อย่างยิ่ง
เพื่อรองรับการส่งข้อมูลเวอร์ชันไปยัง TA อย่างปลอดภัย เราได้เพิ่ม ฟิลด์ OS_VERSION
ลงในส่วนหัวของอิมเมจสำหรับบูต สคริปต์บิลด์อิมเมจสำหรับบูตจะเติมฟิลด์นี้โดยอัตโนมัติ OEM และผู้ปรับใช้ TA ของคีย์มาสเตอร์จำเป็นต้องทำงานร่วมกันเพื่อแก้ไข bootloaders ของอุปกรณ์เพื่อดึงข้อมูลเวอร์ชันจากอิมเมจสำหรับบูตและส่งไปยัง TA ก่อนบูตระบบที่ไม่ปลอดภัย เพื่อให้แน่ใจว่าผู้โจมตีไม่สามารถแทรกแซงการจัดเตรียมข้อมูลเวอร์ชันให้กับ TA
นอกจากนี้ยังจำเป็นต้องตรวจสอบให้แน่ใจว่าอิมเมจระบบมีข้อมูลเวอร์ชันเดียวกันกับอิมเมจสำหรับบูต ด้วยเหตุนี้ วิธีการกำหนดค่าจึงถูกเพิ่มใน 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 แต่ก่อนที่จะเรียกใช้เมธอดอื่น หากมีการเรียกวิธีอื่นก่อนกำหนดค่า TA จะส่งกลับ ErrorCode::KEYMASTER_NOT_CONFIGURED
การ configure
ครั้งแรกถูกเรียกหลังจากบูตอุปกรณ์ ควรตรวจสอบว่าข้อมูลเวอร์ชันที่ให้มาตรงกับข้อมูลที่ bootloader ให้มา หากข้อมูลเวอร์ชันไม่ตรงกัน configure
จะส่งคืน ErrorCode::INVALID_ARGUMENT
และวิธีการคีย์มาสเตอร์อื่น ๆ ทั้งหมดจะส่งคืน ErrorCode::KEYMASTER_NOT_CONFIGURED
หากข้อมูลตรงกัน configure
จะส่งคืน ErrorCode::OK
และวิธีการคีย์มาสเตอร์อื่น ๆ เริ่มทำงานตามปกติ
การเรียกครั้งต่อไปเพื่อ configure
จะคืนค่าเดิมที่ส่งคืนโดยการโทรครั้งแรก และไม่เปลี่ยนสถานะของคีย์มาสเตอร์ โปรดทราบว่ากระบวนการนี้จะกำหนดให้ OTA ทั้งหมดอัปเดตทั้งอิมเมจของระบบและบูต ไม่สามารถอัปเดตแยกต่างหากเพื่อให้ข้อมูลเวอร์ชันตรงกัน
เนื่องจากระบบจะเรียก configure
ซึ่งมีเนื้อหาที่ต้องการตรวจสอบ จึงมีโอกาสที่ผู้โจมตีจะประนีประนอมกับอิมเมจระบบและบังคับให้ให้ข้อมูลเวอร์ชันที่ตรงกับอิมเมจสำหรับเริ่มระบบซึ่งไม่ใช่ข้อมูลจริง รุ่นของระบบ การรวมกันของการตรวจสอบอิมเมจสำหรับบูต การตรวจสอบความถูกต้อง dm-verity ของเนื้อหาอิมเมจระบบ และความจริงที่ว่าการ configure
นั้นถูกเรียกเร็วมากในการบู๊ตระบบ จะทำให้หน้าต่างแห่งโอกาสนี้ยากต่อการใช้ประโยชน์