ที่เก็บคีย์ที่ได้รับการสนับสนุนจากฮาร์ดแวร์

ความพร้อมใช้งานของสภาพแวดล้อมการดำเนินการที่เชื่อถือได้ในระบบบนชิป (SoC) เปิดโอกาสให้อุปกรณ์ Android ให้บริการความปลอดภัยที่แข็งแกร่งซึ่งสนับสนุนด้วยฮาร์ดแวร์สำหรับระบบปฏิบัติการ Android บริการแพลตฟอร์ม และแม้แต่แอปของบุคคลที่สาม นักพัฒนาที่กำลังมองหาส่วนขยายของ Android เฉพาะควรจะไป android.security.keystore

ก่อน Android 6.0 นั้น Android มี API บริการเข้ารหัสลับแบบเรียบง่ายที่ได้รับการสนับสนุนจากฮาร์ดแวร์อยู่แล้ว ซึ่งให้บริการโดย Keymaster Hardware Abstraction Layer (HAL) เวอร์ชัน 0.2 และ 0.3 Keystore จัดเตรียมการเซ็นชื่อแบบดิจิทัลและการดำเนินการตรวจสอบ บวกกับการสร้างและนำเข้าคู่คีย์การเซ็นชื่อแบบอสมมาตร มีการใช้งานแล้วในอุปกรณ์จำนวนมาก แต่มีเป้าหมายด้านความปลอดภัยมากมายที่ไม่สามารถทำได้ง่ายๆ ด้วย API ลายเซ็นเท่านั้น Keystore ใน Android 6.0 ขยาย Keystore API เพื่อมอบความสามารถที่หลากหลายยิ่งขึ้น

ใน Android 6.0 Keystore เพิ่ม สมมาตรวิทยาการเข้ารหัสลับ , AES และ HMAC และระบบควบคุมการเข้าถึงสำหรับคีย์ฮาร์ดแวร์ได้รับการสนับสนุน มีการระบุการควบคุมการเข้าถึงระหว่างการสร้างคีย์และบังคับใช้ตลอดอายุของคีย์ คีย์สามารถถูกจำกัดให้ใช้งานได้หลังจากที่ผู้ใช้ได้รับการตรวจสอบสิทธิ์แล้วเท่านั้น และเพื่อวัตถุประสงค์ที่ระบุหรือด้วยพารามิเตอร์การเข้ารหัสที่ระบุเท่านั้น สำหรับข้อมูลเพิ่มเติมโปรดดูที่ การอนุญาตแท็ก และ ฟังก์ชั่น หน้า

นอกจากการขยายขอบเขตของการเข้ารหัสดั้งเดิมแล้ว Keystore ใน Android 6.0 ยังเพิ่มสิ่งต่อไปนี้:

  • รูปแบบการควบคุมการใช้งานเพื่อจำกัดการใช้คีย์ เพื่อลดความเสี่ยงของการประนีประนอมด้านความปลอดภัยอันเนื่องมาจากการใช้คีย์ในทางที่ผิด
  • รูปแบบการควบคุมการเข้าถึงเพื่อเปิดใช้งานการจำกัดคีย์สำหรับผู้ใช้ที่ระบุ ไคลเอนต์ และช่วงเวลาที่กำหนด

ใน Android 7.0 Keymaster 2 ได้เพิ่มการสนับสนุนสำหรับการรับรองคีย์และการเชื่อมโยงเวอร์ชัน พยานสำคัญ ให้ใบรับรองกุญแจสาธารณะที่มีรายละเอียดของที่สำคัญและการควบคุมการเข้าถึงในการที่จะทำให้การดำรงอยู่ที่สำคัญในฮาร์ดแวร์รักษาความปลอดภัยและการกำหนดค่าของระยะไกลตรวจสอบได้

รุ่นที่มีผลผูกพัน กุญแจผูกกับระบบปฏิบัติการและรุ่นแพทช์ระดับ เพื่อให้แน่ใจว่าผู้โจมตีที่ค้นพบจุดอ่อนในระบบเวอร์ชันเก่าหรือซอฟต์แวร์ TEE จะไม่สามารถย้อนกลับอุปกรณ์เป็นเวอร์ชันที่มีช่องโหว่และใช้คีย์ที่สร้างด้วยเวอร์ชันที่ใหม่กว่าได้ นอกจากนี้ เมื่อใช้คีย์ที่มีเวอร์ชันและระดับแพตช์ที่กำหนดบนอุปกรณ์ที่ได้รับการอัปเกรดเป็นเวอร์ชันใหม่กว่าหรือระดับแพตช์ คีย์จะถูกอัปเกรดก่อนจึงจะสามารถใช้งานได้ และคีย์เวอร์ชันก่อนหน้าจะใช้งานไม่ได้ เมื่อมีการอัปเกรดอุปกรณ์ คีย์จะ "วงล้อ" ไปข้างหน้าพร้อมกับอุปกรณ์ แต่การย้อนกลับของอุปกรณ์ไปเป็นรุ่นก่อนหน้าจะทำให้คีย์ใช้งานไม่ได้

ใน Android 8.0 Keymaster 3 ได้เปลี่ยนจาก C-structure Hardware Abstraction Layer (HAL) แบบเก่าไปเป็นอินเทอร์เฟซ C++ HAL ที่สร้างขึ้นจากคำจำกัดความใน Hardware Interface Definition Language (HIDL) ใหม่ ส่วนหนึ่งของการเปลี่ยนแปลงนั้น ประเภทของอาร์กิวเมนต์จำนวนมากเปลี่ยนไป แม้ว่าประเภทและเมธอดจะมีการโต้ตอบแบบหนึ่งต่อหนึ่งกับประเภทเก่าและเมธอดโครงสร้าง HAL ดู ฟังก์ชั่น หน้าสำหรับรายละเอียดเพิ่มเติม

นอกจากนี้ในการแก้ไขอินเตอร์เฟซนี้ Android 8.0 ขยายคุณลักษณะการรับรอง Keymaster 2 เพื่อสนับสนุน ID รับรอง การรับรอง ID มีกลไกที่จำกัดและเป็นทางเลือกสำหรับการยืนยันตัวระบุฮาร์ดแวร์อย่างเข้มงวด เช่น หมายเลขซีเรียลของอุปกรณ์ ชื่อผลิตภัณฑ์ และ ID ของโทรศัพท์ (IMEI / MEID) ในการดำเนินการเพิ่มเติมนี้ Android 8.0 ได้เปลี่ยนสคีมาการรับรอง ASN.1 เพื่อเพิ่มการรับรอง ID การใช้งานคีย์มาสเตอร์จำเป็นต้องหาวิธีที่ปลอดภัยในการดึงรายการข้อมูลที่เกี่ยวข้อง รวมทั้งกำหนดกลไกสำหรับการปิดใช้งานคุณลักษณะนี้อย่างปลอดภัยและถาวร

ใน Android 9 การอัปเดตรวมถึง:

  • Update เพื่อ Keymaster 4
  • รองรับองค์ประกอบความปลอดภัยที่ฝังตัว
  • รองรับการนำเข้าคีย์ที่ปลอดภัย
  • รองรับการเข้ารหัส 3DES
  • การเปลี่ยนแปลงการเชื่อมโยงเวอร์ชันเพื่อให้ boot.img และ system.img มีการตั้งค่าเวอร์ชันแยกกันเพื่อให้สามารถอัปเดตได้อย่างอิสระ

อภิธานศัพท์

นี่คือภาพรวมโดยย่อของส่วนประกอบ Keystore และความสัมพันธ์ของพวกเขา

AndroidKeystore เป็น API Android กรอบและองค์ประกอบที่ใช้โดยปพลิเคชันในการเข้าถึงฟังก์ชันการทำงาน Keystore มันถูกนำไปใช้เป็นส่วนเสริมของ Java Cryptography Architecture API มาตรฐาน และประกอบด้วยโค้ด Java ที่ทำงานในพื้นที่กระบวนการของแอปเอง AndroidKeystore ตอบสนองการร้องขอ app สำหรับพฤติกรรม Keystore โดยการส่งพวกเขาไปยังภูตเก็บคีย์

ภูต keystore เป็นภูตระบบ Android ที่ให้การเข้าถึงฟังก์ชันการทำงานทั้งหมด Keystore ผ่าน Binder API มีหน้าที่รับผิดชอบในการจัดเก็บ "key blobs" ซึ่งมีเนื้อหาคีย์ลับจริง เข้ารหัสเพื่อให้ Keystore สามารถจัดเก็บได้ แต่จะไม่ใช้หรือเปิดเผยข้อมูลดังกล่าว

keymasterd เป็นเซิร์ฟเวอร์ HIDL ที่ให้การเข้าถึง Keymaster TA (ชื่อนี้ไม่ได้มาตรฐานและมีไว้เพื่อวัตถุประสงค์ในเชิงแนวคิด)

Keymaster TA (แอพลิเคชันที่เชื่อถือได้) เป็นซอฟต์แวร์ที่ใช้ในบริบทของการรักษาความปลอดภัยบ่อยที่สุดใน TrustZone บน ARM SoC ที่ให้บริการทั้งหมดของการดำเนินงาน Keystore การรักษาความปลอดภัยที่มีการเข้าถึงเนื้อหาที่สำคัญดิบตรวจสอบทั้งหมดที่มีเงื่อนไขการควบคุมการเข้าถึงบนแป้น ฯลฯ

LockSettingsService เป็นส่วนประกอบของระบบ Android รับผิดชอบในการตรวจสอบผู้ใช้ทั้งรหัสผ่านและลายนิ้วมือ ไม่ใช่ส่วนหนึ่งของ Keystore แต่มีความเกี่ยวข้องเนื่องจากการดำเนินการคีย์ของ Keystore จำนวนมากต้องการการพิสูจน์ตัวตนผู้ใช้ LockSettingsService ปฏิสัมพันธ์กับยาม TA TA และลายนิ้วมือที่จะได้รับสัญญาณการตรวจสอบซึ่งมันให้กับภูต keystore และที่มีการบริโภคในท้ายที่สุดโดยการประยุกต์ใช้ Keymaster TA

ยาม TA (แอพลิเคชันที่เชื่อถือได้) เป็นส่วนประกอบอื่นที่ใช้ในบริบทของการรักษาความปลอดภัยซึ่งเป็นผู้รับผิดชอบในการตรวจสอบผู้ใช้รหัสผ่านและสร้างการตรวจสอบโทเค็นที่ใช้ในการพิสูจน์ให้ Keymaster TA ว่าการตรวจสอบได้รับการทำเพื่อผู้ใช้เฉพาะที่จุดโดยเฉพาะอย่างยิ่งในเวลาที่

ลายนิ้วมือ TA (แอพลิเคชันที่เชื่อถือได้) เป็นส่วนประกอบอื่นที่ใช้ในบริบทที่เชื่อถือได้ซึ่งเป็นผู้รับผิดชอบในการตรวจสอบลายนิ้วมือของผู้ใช้และการสร้างการตรวจสอบโทเค็นที่ใช้ในการพิสูจน์ให้ Keymaster TA ว่าการตรวจสอบได้รับการทำเพื่อผู้ใช้เฉพาะที่จุดโดยเฉพาะอย่างยิ่งในเวลาที่

สถาปัตยกรรม

Android Keystore API และ Keymaster HAL พื้นฐานจัดเตรียมชุดการเข้ารหัสลับพื้นฐานแต่เพียงพอ เพื่อให้สามารถปรับใช้โปรโตคอลได้โดยใช้คีย์ที่ควบคุมการเข้าถึงและมีฮาร์ดแวร์สำรอง

Keymaster HAL เป็นไลบรารีที่โหลดได้แบบไดนามิกที่จัดหาโดย OEM ซึ่งใช้โดยบริการ Keystore เพื่อให้บริการเข้ารหัสลับที่ฮาร์ดแวร์สนับสนุน เพื่อรักษาความปลอดภัย การใช้งาน HAL จะไม่ดำเนินการใดๆ ที่ละเอียดอ่อนในพื้นที่ผู้ใช้ หรือแม้แต่ในพื้นที่เคอร์เนล การดำเนินการที่ละเอียดอ่อนจะมอบหมายให้กับโปรเซสเซอร์ที่ปลอดภัยซึ่งเข้าถึงได้ผ่านอินเทอร์เฟซเคอร์เนลบางส่วน สถาปัตยกรรมที่ได้จะมีลักษณะดังนี้:

เข้าถึงคีย์มาสเตอร์

รูปที่ 1 การเข้าถึง Keymaster

ภายในอุปกรณ์ Android "ไคลเอ็นต์" ของ Keymaster HAL ประกอบด้วยหลายเลเยอร์ (เช่น แอป กรอบงาน Keystore daemon) แต่สามารถละเว้นได้สำหรับวัตถุประสงค์ของเอกสารนี้ ซึ่งหมายความว่า Keymaster HAL API ที่อธิบายนั้นเป็นระดับต่ำ ใช้โดยส่วนประกอบภายในแพลตฟอร์ม และไม่เปิดเผยต่อนักพัฒนาแอป ระดับสูงกว่า API อธิบายไว้ใน เว็บไซต์ของนักพัฒนาซอฟต์แวร์ Android

วัตถุประสงค์ของ Keymaster HAL ไม่ใช่เพื่อนำอัลกอริธึมที่ไวต่อการรักษาความปลอดภัยไปใช้ แต่เพื่อส่งคำขอของจอมพลและที่ไม่ประสงค์ออกนามไปยังโลกที่ปลอดภัยเท่านั้น รูปแบบเส้นลวดถูกกำหนดไว้สำหรับการนำไปใช้งาน

ความเข้ากันได้กับรุ่นก่อนหน้า

Keymaster 1 HAL เข้ากันไม่ได้กับ HAL ที่เผยแพร่ก่อนหน้านี้อย่างสมบูรณ์ เช่น Keymaster 0.2 และ 0.3 เพื่ออำนวยความสะดวกในการทำงานร่วมกันบนอุปกรณ์ที่ใช้ Android 5.0 และรุ่นก่อนหน้าที่เปิดตัวพร้อมกับ Keymaster HAL รุ่นเก่า Keystore ได้จัดเตรียมอะแดปเตอร์ที่ใช้ Keymaster 1 HAL พร้อมการเรียกไปยังไลบรารีฮาร์ดแวร์ที่มีอยู่ ผลลัพธ์ไม่สามารถให้ฟังก์ชันการทำงานทั้งหมดใน Keymaster 1 HAL ได้ โดยเฉพาะอย่างยิ่ง สนับสนุนเฉพาะอัลกอริธึม RSA และ ECDSA และการบังคับใช้การให้สิทธิ์คีย์ทั้งหมดดำเนินการโดยอแด็ปเตอร์ ในโลกที่ไม่ปลอดภัย

Keymaster 2 ง่ายต่ออินเตอร์เฟซ HAL โดยการลบ get_supported_* วิธีการและให้ finish() วิธีการที่จะยอมรับการป้อนข้อมูล ซึ่งจะช่วยลดจำนวนการเดินทางไปกลับ TEE ในกรณีที่อินพุตพร้อมใช้งานทั้งหมดในคราวเดียว และทำให้การใช้งานการถอดรหัส AEAD ง่ายขึ้น

ใน Android 8.0 Keymaster 3 ได้เปลี่ยนจาก HAL โครงสร้าง C แบบเก่าไปเป็นอินเทอร์เฟซ C++ HAL ที่สร้างจากคำจำกัดความใน Hardware Interface Definition Language (HIDL) ใหม่ การดำเนิน HAL แบบใหม่ถูกสร้างขึ้นโดย subclassing ที่สร้าง IKeymasterDevice การเรียนและการใช้วิธีเสมือนบริสุทธิ์ ส่วนหนึ่งของการเปลี่ยนแปลง ประเภทของอาร์กิวเมนต์จำนวนมากได้เปลี่ยนไป แม้ว่าประเภทและเมธอดจะมีความสอดคล้องแบบหนึ่งต่อหนึ่งกับประเภทเก่าและเมธอดโครงสร้าง HAL

ภาพรวม HIDL

ภาษาข้อกำหนดอินเทอร์เฟซสำหรับฮาร์ดแวร์ (HIDL) จัดเตรียมกลไกการใช้งานที่ไม่ขึ้นกับภาษาสำหรับการระบุอินเทอร์เฟซของฮาร์ดแวร์ ปัจจุบันเครื่องมือ HIDL รองรับการสร้างอินเทอร์เฟซ C ++ และ Java เป็นที่คาดว่าผู้ปรับใช้ Trusted Execution Environment (TEE) ส่วนใหญ่จะพบว่าเครื่องมือ C++ สะดวกกว่า ดังนั้นเอกสารนี้จึงอธิบายเฉพาะการแสดง C++

อินเทอร์เฟซ HIDL ประกอบด้วยชุดของเมธอด ซึ่งแสดงเป็น:

  methodName(INPUT ARGUMENTS) generates (RESULT ARGUMENTS);

มีหลายประเภทที่กำหนดไว้ล่วงหน้า และ HAL สามารถกำหนดประเภทการแจงนับและโครงสร้างใหม่ได้ สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับ HIDL ดูที่ ส่วนอ้างอิง

วิธีการเช่นจาก Keymaster 3 IKeymasterDevice.hal คือ:

generateKey(vec<KeyParameter> keyParams)
        generates(ErrorCode error, vec<uint8_t> keyBlob,
                  KeyCharacteristics keyCharacteristics);

ซึ่งเทียบเท่ากับสิ่งต่อไปนี้จาก keymaster2 HAL:

keymaster_error_t (*generate_key)(
        const struct keymaster2_device* dev,
        const keymaster_key_param_set_t* params,
        keymaster_key_blob_t* key_blob,
        keymaster_key_characteristics_t* characteristics);

ในรุ่น HIDL ที่ dev อาร์กิวเมนต์จะถูกลบออกเพราะมันเป็นนัย params อาร์กิวเมนต์เป็นไม่ struct ที่มีตัวชี้อ้างอิงอาร์เรย์ของ key_parameter_t วัตถุ แต่ vec (เวกเตอร์) ที่มี KeyParameter วัตถุ ค่าที่ส่งคืนมีการระบุไว้ในส่วน "การ generates " ข้อรวมทั้งเวกเตอร์ของ uint8_t ค่าสำหรับหยดที่สำคัญ

เมธอดเสมือน C++ ที่สร้างโดยคอมไพเลอร์ HIDL คือ:

Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams,
                         generateKey_cb _hidl_cb) override;

ที่ไหน generate_cb เป็นตัวชี้ฟังก์ชันหมายถึง:

std::function<void(ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
                   const KeyCharacteristics& keyCharacteristics)>

นั่นคือ generate_cb เป็นฟังก์ชั่นที่ใช้ค่าที่ส่งคืนที่ระบุไว้ในข้อที่สร้าง ชั้นการดำเนินงาน HAL แทนที่นี้ generateKey วิธีการและเรียก generate_cb ชี้ฟังก์ชันที่จะกลับผลของการดำเนินการไปยังผู้โทร หมายเหตุ: การเรียกตัวชี้ฟังก์ชันเป็นซิงโคร โทรเรียก generateKey และ generateKey เรียกตัวชี้ฟังก์ชั่นที่ให้มาซึ่งดำเนินการให้แล้วเสร็จกลับไปควบคุม generateKey การดำเนินงานซึ่งจากนั้นกลับไปที่โทร

สำหรับตัวอย่างดูรายละเอียดการดำเนินการเริ่มต้นใน hardware/interfaces/keymaster/3.0/default/KeymasterDevice.cpp การใช้งานเริ่มต้นช่วยให้ใช้งานร่วมกันได้แบบย้อนหลังสำหรับอุปกรณ์ที่มีคีย์มาสเตอร์แบบเก่า, คีย์มาสเตอร์1 หรือคีย์มาสเตอร์2 HALS

การควบคุมการเข้าถึง

กฎพื้นฐานที่สุดของการควบคุมการเข้าถึง Keystore คือแต่ละแอพมีเนมสเปซของตัวเอง แต่สำหรับกฎทุกข้อมีข้อยกเว้น Keystore มีแผนที่แบบฮาร์ดโค้ดบางส่วนที่อนุญาตให้ส่วนประกอบระบบบางอย่างเข้าถึงเนมสเปซอื่นๆ บางอย่างได้ นี่เป็นเครื่องมือที่ตรงไปตรงมามากโดยให้องค์ประกอบหนึ่งควบคุมเนมสเปซอื่นได้อย่างสมบูรณ์ และจากนั้นก็มีเรื่องขององค์ประกอบของผู้ขายในฐานะลูกค้าของ Keystore ขณะนี้เราไม่มีทางสร้างเนมสเปซสำหรับส่วนประกอบของผู้จำหน่าย เช่น ผู้ร้องขอ WPA

เพื่อรองรับองค์ประกอบของผู้จัดจำหน่ายและควบคุมการเข้าถึงทั่วไปโดยไม่มีข้อยกเว้นแบบกำหนดค่าตายตัว Keystore 2.0 จึงแนะนำโดเมนและเนมสเปซ SELinux

โดเมนที่เก็บคีย์

ด้วยโดเมน Keystore เราสามารถแยกเนมสเปซออกจาก UID ไคลเอ็นต์ที่เข้าถึงคีย์ใน Keystore ต้องระบุโดเมน เนมสเปซ และนามแฝงที่ต้องการเข้าถึง จากทูเพิลนี้และข้อมูลประจำตัวของผู้โทร เราสามารถกำหนดได้ว่าคีย์ใดที่ผู้โทรต้องการเข้าถึงและมีสิทธิ์ที่เหมาะสมหรือไม่

เราแนะนำพารามิเตอร์โดเมนห้ารายการซึ่งควบคุมวิธีการเข้าถึงคีย์ พวกเขาควบคุมความหมายของพารามิเตอร์เนมสเปซของตัวอธิบายคีย์และวิธีดำเนินการควบคุมการเข้าถึง

  • DOMAIN_APP : โดเมน app ครอบคลุมพฤติกรรมเดิม Java Keystore SPI ใช้โดเมนนี้เป็นค่าเริ่มต้น เมื่อใช้โดเมนนี้ อาร์กิวเมนต์เนมสเปซจะถูกละเว้นและใช้ UID ของผู้โทรแทน การเข้าถึงโดเมนนี้จะถูกควบคุมโดยฉลาก Keystore ในชั้นเรียน keystore_key ในนโยบาย SELinux
  • DOMAIN_SELINUX : โดเมนนี้บ่งชี้ว่า namespace มีฉลากในนโยบาย SELinux พารามิเตอร์ namespace จะเงยหน้าขึ้นและแปลเป็นบริบทเป้าหมายและการตรวจสอบได้รับอนุญาตจะดำเนินการสำหรับบริบท SELinux เรียกร้องให้ keystore_key ระดับ เมื่อได้รับอนุญาตสำหรับการดำเนินการที่กำหนด ทูเพิลแบบเต็มจะถูกใช้สำหรับการค้นหาคีย์
  • DOMAIN_GRANT : โดเมนทุนบ่งชี้ว่าพารามิเตอร์ namespace เป็นตัวระบุทุน พารามิเตอร์นามแฝงจะถูกละเว้น การตรวจสอบ SELinux จะดำเนินการเมื่อมีการสร้างเงินช่วยเหลือ การควบคุมการเข้าถึงเพิ่มเติมจะตรวจสอบว่า UID ของผู้โทรตรงกับ UID ของผู้รับสิทธิ์ของการให้สิทธิ์ที่ร้องขอหรือไม่
  • DOMAIN_KEY_ID : โดเมนนี้บ่งชี้ว่าพารามิเตอร์ namespace เป็นรหัสคีย์ที่ไม่ซ้ำกัน ที่สำคัญตัวเองอาจได้รับการสร้างขึ้นด้วย DOMAIN_APP หรือ DOMAIN_SELINUX การตรวจสอบได้รับอนุญาตจะดำเนินการหลังจากที่ domain และ namespace ได้รับการโหลดจากฐานข้อมูลที่สำคัญในทางเดียวกันเช่นถ้าหยดถูกโหลดโดยโดเมน namespace และนามแฝง tuple เหตุผลสำหรับโดเมนรหัสคีย์คือความต่อเนื่อง เมื่อเข้าถึงคีย์โดยใช้นามแฝง การเรียกที่ตามมาอาจทำงานบนคีย์ที่แตกต่างกัน เนื่องจากคีย์ใหม่อาจถูกสร้างหรือนำเข้าและผูกกับนามแฝงนี้ รหัสคีย์จะไม่เปลี่ยนแปลง ดังนั้นเมื่อใช้คีย์โดยคีย์ id หลังจากที่โหลดจากฐานข้อมูล Keystore โดยใช้นามแฝงเพียงครั้งเดียว เราสามารถมั่นใจได้ว่าคีย์นั้นเป็นคีย์เดียวกันตราบเท่าที่ยังมีรหัสคีย์อยู่ นักพัฒนาแอปจะไม่เปิดเผยฟังก์ชันนี้ แต่จะใช้ภายใน Android Keystore SPI เพื่อมอบประสบการณ์ที่สอดคล้องกันมากขึ้น แม้ว่าจะใช้งานพร้อมกันในลักษณะที่ไม่ปลอดภัยก็ตาม
  • DOMAIN_BLOB : โดเมนหยดบ่งชี้ว่าผู้ที่โทรมาจัดการหยดด้วยตัวเอง ใช้สำหรับไคลเอ็นต์ที่ต้องการเข้าถึง Keystore ก่อนที่จะเมาต์พาร์ติชั่นข้อมูล หยดที่สำคัญรวมอยู่ใน blob ด้านการให้คำอธิบายที่สำคัญ

เมื่อใช้โดเมน SELinux เราสามารถให้คอมโพเนนต์ของผู้จำหน่ายเข้าถึงเนมสเปซของ Keystore ที่เฉพาะเจาะจงมาก ซึ่งสามารถแชร์โดยคอมโพเนนต์ของระบบ เช่น กล่องโต้ตอบการตั้งค่า

นโยบาย SELinux สำหรับ keystore_key

ป้าย namespace มีการกำหนดค่าใช้ keystore2_key_context ไฟล์
แต่ละบรรทัดในไฟล์เหล่านี้จับคู่รหัสเนมสเปซที่เป็นตัวเลขกับเลเบล SELinux ตัวอย่างเช่น,

# wifi_key is a keystore2_key namespace intended to be used by wpa supplicant and
# Settings to share keystore keys.
102            u:object_r:wifi_key:s0

หลังจากตั้งค่าเนมสเปซคีย์ใหม่ด้วยวิธีนี้แล้ว เราสามารถให้สิทธิ์เข้าถึงได้โดยเพิ่มนโยบายที่เหมาะสม ตัวอย่างเช่นการอนุญาตให้ wpa_supplicant จะได้รับและใช้ปุ่มใน namespace ใหม่ที่เราจะเพิ่มบรรทัดต่อไปนี้ hal_wifi_supplicant.te :

allow hal_wifi_supplicant wifi_key:keystore2_key { get, use };

หลังจากตั้งค่าเนมสเปซใหม่แล้ว AndroidKeyStore สามารถใช้งานได้เกือบตามปกติ ข้อแตกต่างเพียงอย่างเดียวคือต้องระบุ ID เนมสเปซ สำหรับการโหลดและนำเข้าคีย์จากและเป็น Keystore รหัสระบุ Namespace ไว้ใช้ AndroidKeyStoreLoadStoreParameter ตัวอย่างเช่น,

import android.security.keystore2.AndroidKeyStoreLoadStoreParameter;
import java.security.KeyStore;

KeyStore keystore = KeyStore.getInstance("AndroidKeyStore");
keystore.load(new AndroidKeyStoreLoadStoreParameter(102));

ในการสร้างที่สำคัญใน namespace ที่กำหนดรหัส namespace จะต้องได้รับการใช้ KeyGenParameterSpec.Builder#setNamespace():

import android.security.keystore.KeyGenParameterSpec;
KeyGenParameterSpec.Builder specBuilder = new KeyGenParameterSpec.Builder();
specBuilder.setNamespace(102);

ไฟล์บริบทต่อไปนี้อาจใช้เพื่อกำหนดค่าเนมสเปซ Keystore 2.0 SELinux แต่ละพาร์ติชันมีช่วงที่สงวนไว้ 10,000 ID เนมสเปซที่แตกต่างกันเพื่อหลีกเลี่ยงการชนกัน

พาร์ทิชัน พิสัย ไฟล์คอนฟิก
ระบบ 0 ... 9,999
/system/etc/selinux/keystore2_key_contexts, /plat_keystore2_key_contexts
ระบบขยาย 10,000 ... 19,999
/system_ext/etc/selinux/system_ext_keystore2_key_contexts, /system_ext_keystore2_key_contexts
ผลิตภัณฑ์ 20,000 ... 29,999
/product/etc/selinux/product_keystore2_key_contexts, /product_keystore2_key_contexts
ผู้ขาย 30,000 ... 39,999
/vendor/etc/selinux/vendor_keystore2_key_contexts, /vendor_keystore2_key_contexts

ไคลเอ็นต์ร้องขอกุญแจโดยการร้องขอโดเมน SELinux และต้องการ namespace เสมือนจริงในกรณีนี้ "wifi_key" โดยรหัสตัวเลขของ

ข้างต้นนั้น มีการกำหนดเนมสเปซต่อไปนี้ หากแทนที่กฎพิเศษ ตารางต่อไปนี้จะระบุ UID ที่ใช้เพื่อสอดคล้อง

เนมสเปซ ID ป้ายกำกับ SEPolicy UID คำอธิบาย
0 su_key ไม่มี คีย์ผู้ใช้ขั้นสูง ใช้สำหรับทดสอบกับ userdebug และ eng builds เท่านั้น ไม่เกี่ยวข้องกับการสร้างผู้ใช้
1 shell_key ไม่มี เนมสเปซที่พร้อมใช้งานสำหรับเชลล์ ส่วนใหญ่ใช้สำหรับการทดสอบ แต่สามารถใช้กับบิลด์ผู้ใช้ได้เช่นกันจากบรรทัดคำสั่ง
100 vold_key ไม่มี มีไว้สำหรับการใช้งานโดย vold.
101 odsing_key ไม่มี ใช้โดย daemon การลงนามบนอุปกรณ์
102 wifi_key AID_WIFI(1010) ใช้โดยระบบ Wifi syb ของ Android รวมถึง wpa_supplicant
120 ประวัติย่อ_on_reboot_key AID_SYSTEM(1000) ใช้โดยเซิร์ฟเวอร์ระบบของ Android เพื่อรองรับการทำงานต่อเมื่อรีบูต

เข้าถึงเวกเตอร์

ชั้น SELinux keystore_key มีอายุไม่น้อยและบางส่วนของสิทธิ์เช่น verify หรือ sign ได้สูญเสียความหมายของพวกเขา นี่คือชุดใหม่ของสิทธิ์ keystore2_key ที่ Keystore 2.0 จะบังคับใช้

การอนุญาต ความหมาย
delete ตรวจสอบเมื่อลบคีย์ออกจาก Keystore
get_info ตรวจสอบเมื่อมีการร้องขอข้อมูลเมตาของคีย์
grant ผู้โทรต้องการการอนุญาตนี้เพื่อสร้างการให้สิทธิ์แก่คีย์ในบริบทเป้าหมาย
manage_blob โทรอาจจะใช้ DOMAIN_BLOB บนให้ SELinux namespace จึงจัดการ blobs ด้วยตัวเอง สิ่งนี้มีประโยชน์สำหรับ vold โดยเฉพาะ
rebind สิทธิ์นี้จะควบคุมว่านามแฝงอาจถูกรีบาวด์ไปยังคีย์ใหม่หรือไม่ สิ่งนี้จำเป็นสำหรับการแทรกและบอกเป็นนัยว่าคีย์ที่ผูกไว้ก่อนหน้านี้จะถูกลบ โดยพื้นฐานแล้วเป็นการอนุญาตการแทรก แต่จะจับความหมายของที่เก็บคีย์ได้ดีกว่า
req_forced_op ไคลเอนต์ที่ได้รับอนุญาตนี้อาจสร้างการดำเนินการที่ไม่สามารถป้องกันได้ และการสร้างการดำเนินการจะไม่มีวันล้มเหลว เว้นแต่ว่าช่องการทำงานทั้งหมดจะถูกดำเนินการโดยการดำเนินการที่ไม่สามารถป้องกันได้
update จำเป็นต้องอัพเดตองค์ประกอบย่อยของคีย์
use ตรวจสอบเมื่อสร้างการดำเนินการ Keymint ที่ใช้วัสดุหลัก เช่น สำหรับการเซ็นชื่อ เข้ารหัส/เข้ารหัส
use_dev_id จำเป็นเมื่อสร้างข้อมูลระบุอุปกรณ์ เช่น การรับรองรหัสอุปกรณ์

นอกจากนี้เราแยกออกมาจากชุดของสิทธิ์เฉพาะ keystore ที่สำคัญไม่ใช่ใน SELinux ระดับการรักษาความปลอดภัย keystore2 :

การอนุญาต ความหมาย
add_auth จำเป็นต้องใช้โดยผู้ให้บริการตรวจสอบสิทธิ์ เช่น Gatekeeper หรือ BiometricsManager สำหรับการเพิ่มโทเค็นการตรวจสอบสิทธิ์
clear_ns เดิมชื่อ clear_uid การอนุญาตนี้อนุญาตให้ผู้ที่ไม่ใช่เจ้าของเนมสเปซลบคีย์ทั้งหมดในเนมสเปซนั้น
list ระบบต้องการสำหรับการแจงนับคีย์ตามคุณสมบัติต่างๆ เช่น ความเป็นเจ้าของหรือขอบเขตการตรวจสอบสิทธิ์ สิทธิ์นี้ไม่จำเป็นโดยผู้เรียกที่ระบุเนมสเปซของตนเอง นี้ได้รับการคุ้มครองโดย get_info ได้รับอนุญาต
lock การอนุญาตนี้อนุญาตให้ล็อก Keystore นั่นคือ ขับไล่มาสเตอร์คีย์ เพื่อให้คีย์ที่ผูกกับการตรวจสอบสิทธิ์ใช้งานไม่ได้และไม่สามารถสร้างขึ้นได้
reset การอนุญาตนี้อนุญาตให้รีเซ็ต Keystore เป็นค่าเริ่มต้นจากโรงงาน โดยจะลบคีย์ทั้งหมดที่ไม่สำคัญต่อการทำงานของ Android OS
unlock สิทธิ์นี้จำเป็นต้องพยายามปลดล็อกมาสเตอร์คีย์สำหรับคีย์ที่ผูกกับการตรวจสอบสิทธิ์