การรับรองคีย์และ ID

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

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

เพื่อแก้ไขปัญหานี้ Keymaster ได้แนะนำ การรับรองคีย์ ใน Android 7.0 (Keymaster 2) และการรับรอง ID ใน Android 8.0 (Keymaster 3)

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

การรับรองรหัสช่วยให้อุปกรณ์แสดงหลักฐานตัวระบุฮาร์ดแวร์ เช่น หมายเลขซีเรียลหรือ IMEI

การรับรองที่สำคัญ

เพื่อรองรับการรับรองคีย์ Android 7.1 ได้แนะนำชุดแท็ก ประเภท และวิธีการให้กับ HAL

แท็ก

  • Tag::ATTESTATION_CHALLENGE
  • Tag::INCLUDE_UNIQUE_ID
  • Tag::RESET_SINCE_ID_ROTATION

พิมพ์

คีย์มาสเตอร์ 2 และต่ำกว่า

typedef struct {
    keymaster_blob_t* entries;
    size_t entry_count;
} keymaster_cert_chain_t;

วิธีการ AttestKey

คีย์มาสเตอร์ 3

    attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams)
        generates(ErrorCode error, vec<vec<uint8_t>> certChain);

คีย์มาสเตอร์ 2 และต่ำกว่า

keymaster_error_t (*attest_key)(const struct keymaster2_device* dev,
        const keymaster_key_blob_t* key_to_attest,
        const keymaster_key_param_set_t* attest_params,
        keymaster_cert_chain_t* cert_chain);
  • dev คือโครงสร้างอุปกรณ์คีย์มาสเตอร์
  • keyToAttest คือคีย์ Blob ที่ส่งคืนจาก generateKey ซึ่งจะสร้างการรับรอง
  • attestParams คือรายการพารามิเตอร์ที่จำเป็นสำหรับการรับรอง ซึ่งรวมถึง Tag::ATTESTATION_CHALLENGE และอาจเป็น Tag::RESET_SINCE_ID_ROTATION ตลอดจน Tag::APPLICATION_ID และ Tag::APPLICATION_DATA สองอันหลังจำเป็นในการถอดรหัสคีย์หยดหากระบุไว้ในระหว่างการสร้างคีย์
  • certChain เป็นพารามิเตอร์เอาต์พุต ซึ่งส่งคืนอาร์เรย์ของใบรับรอง รายการ 0 คือใบรับรองการรับรอง ซึ่งหมายความว่าจะรับรองคีย์จาก keyToAttest และมีส่วนขยายการรับรอง

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

ใบรับรองการรับรอง

ใบรับรองการรับรองคือใบรับรอง X.509 มาตรฐาน โดยมีส่วนขยายการรับรองเพิ่มเติมซึ่งมีคำอธิบายของคีย์ที่รับรอง ใบรับรองมีการลงนามด้วย คีย์รับรอง ที่ได้รับการรับรอง คีย์การรับรองอาจใช้อัลกอริทึมที่แตกต่างจากคีย์ที่กำลังรับรอง

ใบรับรองการรับรองมีช่องในตารางด้านล่างและไม่สามารถมีช่องเพิ่มเติมได้ บางฟิลด์ระบุค่าฟิลด์คงที่ การทดสอบ CTS จะตรวจสอบว่าเนื้อหาใบรับรองตรงตามที่กำหนดไว้ทุกประการ

ลำดับใบรับรอง

ชื่อฟิลด์ (ดู RFC 5280 ) ค่า
tbsใบรับรอง ลำดับใบรับรอง TBSC
อัลกอริธึมลายเซ็น AlgorithmIdentifier ของอัลกอริทึมที่ใช้ในการลงนามคีย์:
ECDSA สำหรับคีย์ EC, RSA สำหรับคีย์ RSA
ค่าลายเซ็น BIT STRING ลายเซ็นคำนวณบนใบรับรอง tbsCertificate ที่เข้ารหัส ASN.1 DER

ลำดับใบรับรอง TBSC

ชื่อฟิลด์ (ดู RFC 5280 ) ค่า
version จำนวนเต็ม 2 (หมายถึงใบรับรอง v3)
serialNumber INTEGER 1 (ค่าคงที่: เหมือนกันใน ทุก ใบรับรอง)
signature AlgorithmIdentifier ของอัลกอริทึมที่ใช้ในการลงนามคีย์: ECDSA สำหรับคีย์ EC, RSA สำหรับคีย์ RSA
issuer เหมือนกับช่องเรื่องของคีย์การรับรองแบบแบตช์
validity SEQUENCE ของสองวันที่ ซึ่งมีค่าของ Tag::ACTIVE_DATETIME และ Tag::USAGE_EXPIRE_DATETIME ค่าเหล่านั้นอยู่ในหน่วยมิลลิวินาทีตั้งแต่วันที่ 1 มกราคม 1970 ดู RFC 5280 สำหรับการแสดงวันที่ที่ถูกต้องในใบรับรอง
หากไม่มี Tag::ACTIVE_DATETIME ให้ใช้ค่าของ Tag::CREATION_DATETIME หากไม่มี Tag::USAGE_EXPIRE_DATETIME ให้ใช้วันหมดอายุของใบรับรองคีย์การรับรองแบบแบตช์
subject CN = "รหัส Android Keystore" (ค่าคงที่: เหมือนกันใน ทุก ใบรับรอง)
subjectPublicKeyInfo SubjectPublicKeyInfo มีกุญแจสาธารณะที่ได้รับการรับรอง
extensions/Key Usage digitalSignature: ตั้งค่าว่าคีย์มีวัตถุประสงค์ KeyPurpose::SIGN หรือ KeyPurpose::VERIFY บิตอื่นๆ ทั้งหมดไม่ได้ตั้งค่า
extensions/CRL Distribution Points มูลค่าจะแจ้งภายหลัง
extensions/"attestation" OID คือ 1.3.6.1.4.1.11129.2.1.17; เนื้อหาถูกกำหนดไว้ในส่วนส่วนขยายการรับรองด้านล่าง เช่นเดียวกับส่วนขยายใบรับรอง X.509 ทั้งหมด เนื้อหาจะแสดงเป็น OCTET_STRING ซึ่งมีการเข้ารหัส DER ของ SEQUENCE การรับรอง

การขยายเวลารับรอง

ส่วนขยาย attestation ประกอบด้วยคำอธิบายที่สมบูรณ์ของการอนุญาตคีย์มาสเตอร์ที่เกี่ยวข้องกับคีย์ ในโครงสร้างที่สอดคล้องโดยตรงกับรายการการอนุญาตที่ใช้ใน Android และคีย์มาสเตอร์ HAL แต่ละแท็กในรายการการอนุญาตจะแสดงด้วยรายการ ASN.1 SEQUENCE ซึ่งแท็กไว้อย่างชัดเจนด้วยหมายเลขแท็กคีย์มาสเตอร์ แต่มีการปกปิดประเภท (บิตลำดับสูงสี่บิต)

ตัวอย่างเช่น ใน Keymaster 3 Tag::PURPOSE ถูกกำหนดใน types.hal เป็น ENUM_REP | 1 . สำหรับส่วนขยายการรับรอง ค่า ENUM_REP จะถูกลบออก โดยเหลือแท็ก 1 (สำหรับ Keymaster 2 และต่ำกว่า KM_TAG_PURPOSE ถูกกำหนดไว้ใน keymaster_defs.h.)

ค่าต่างๆ ได้รับการแปลอย่างตรงไปตรงมาเป็นประเภท ASN.1 ตามตารางนี้:

ประเภทคีย์มาสเตอร์ ประเภท ASN.1
ENUM จำนวนเต็ม
ENUM_REP SET ของจำนวนเต็ม
UINT จำนวนเต็ม
UINT_REP SET ของจำนวนเต็ม
ULONG จำนวนเต็ม
ULONG_REP SET ของจำนวนเต็ม
DATE INTEGER (มิลลิวินาทีตั้งแต่ 1 มกราคม 1970 00:00:00 GMT)
BOOL NULL (ในคีย์มาสเตอร์ แท็กปัจจุบันหมายถึงจริง ขาดหายไปหมายถึงเท็จ
ความหมายเดียวกันนี้ใช้กับการเข้ารหัส ASN.1)
BIGNUM ไม่ได้ใช้ในปัจจุบัน ดังนั้นจึงไม่มีการกำหนดแผนที่
BYTES OCTET_STRING

สคีมา

เนื้อหาส่วนขยายการรับรองอธิบายโดยสคีมา ASN.1 ต่อไปนี้

KeyDescription ::= SEQUENCE {
  attestationVersion         INTEGER, # KM2 value is 1. KM3 value is 2. KM4 value is 3.
  attestationSecurityLevel   SecurityLevel,
  keymasterVersion           INTEGER,
  keymasterSecurityLevel     SecurityLevel,
  attestationChallenge       OCTET_STRING,
  uniqueId                   OCTET_STRING,
  softwareEnforced           AuthorizationList,
  teeEnforced                AuthorizationList,
}

SecurityLevel ::= ENUMERATED {
  Software                   (0),
  TrustedEnvironment         (1),
  StrongBox                  (2),
}

AuthorizationList ::= SEQUENCE {
  purpose                     [1] EXPLICIT SET OF INTEGER OPTIONAL,
  algorithm                   [2] EXPLICIT INTEGER OPTIONAL,
  keySize                     [3] EXPLICIT INTEGER OPTIONAL.
  digest                      [5] EXPLICIT SET OF INTEGER OPTIONAL,
  padding                     [6] EXPLICIT SET OF INTEGER OPTIONAL,
  ecCurve                     [10] EXPLICIT INTEGER OPTIONAL,
  rsaPublicExponent           [200] EXPLICIT INTEGER OPTIONAL,
  rollbackResistance          [303] EXPLICIT NULL OPTIONAL, # KM4
  activeDateTime              [400] EXPLICIT INTEGER OPTIONAL
  originationExpireDateTime   [401] EXPLICIT INTEGER OPTIONAL
  usageExpireDateTime         [402] EXPLICIT INTEGER OPTIONAL
  noAuthRequired              [503] EXPLICIT NULL OPTIONAL,
  userAuthType                [504] EXPLICIT INTEGER OPTIONAL,
  authTimeout                 [505] EXPLICIT INTEGER OPTIONAL,
  allowWhileOnBody            [506] EXPLICIT NULL OPTIONAL,
  trustedUserPresenceRequired [507] EXPLICIT NULL OPTIONAL, # KM4
  trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, # KM4
  unlockedDeviceRequired      [509] EXPLICIT NULL OPTIONAL, # KM4
  allApplications             [600] EXPLICIT NULL OPTIONAL,
  applicationId               [601] EXPLICIT OCTET_STRING OPTIONAL,
  creationDateTime            [701] EXPLICIT INTEGER OPTIONAL,
  origin                      [702] EXPLICIT INTEGER OPTIONAL,
  rollbackResistant           [703] EXPLICIT NULL OPTIONAL, # KM2 and KM3 only.
  rootOfTrust                 [704] EXPLICIT RootOfTrust OPTIONAL,
  osVersion                   [705] EXPLICIT INTEGER OPTIONAL,
  osPatchLevel                [706] EXPLICIT INTEGER OPTIONAL,
  attestationApplicationId    [709] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdBrand          [710] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdDevice         [711] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdProduct        [712] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdSerial         [713] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdImei           [714] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdMeid           [715] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdManufacturer   [716] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdModel          [717] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  vendorPatchLevel            [718] EXPLICIT INTEGER OPTIONAL, # KM4
  bootPatchLevel              [719] EXPLICIT INTEGER OPTIONAL, # KM4
}

RootOfTrust ::= SEQUENCE {
  verifiedBootKey            OCTET_STRING,
  deviceLocked               BOOLEAN,
  verifiedBootState          VerifiedBootState,
  verifiedBootHash           OCTET_STRING, # KM4
}

VerifiedBootState ::= ENUMERATED {
  Verified                   (0),
  SelfSigned                 (1),
  Unverified                 (2),
  Failed                     (3),
}

ฟิลด์คำอธิบายคีย์

ฟิลด์ keymasterVersion และ attestationChallenge จะถูกระบุตำแหน่ง แทนที่จะเป็นแท็ก ดังนั้นแท็กในรูปแบบที่เข้ารหัสจะระบุเฉพาะประเภทฟิลด์เท่านั้น ฟิลด์ที่เหลือจะถูกแท็กโดยปริยายตามที่ระบุไว้ในสคีมา

ชื่อฟิลด์ พิมพ์ ค่า
attestationVersion จำนวนเต็ม เวอร์ชันของสคีมาการรับรอง: 1, 2 หรือ 3
attestationSecurity ระดับความปลอดภัย ระดับความปลอดภัยของการรับรองนี้ คุณสามารถรับการรับรองซอฟต์แวร์ของคีย์ที่สนับสนุนฮาร์ดแวร์ได้ การรับรองดังกล่าวไม่สามารถเชื่อถือได้หากระบบ Android ถูกบุกรุก
keymasterVersion จำนวนเต็ม เวอร์ชันของอุปกรณ์คีย์มาสเตอร์: 0, 1, 2, 3 หรือ 4
keymasterSecurity ระดับความปลอดภัย ระดับความปลอดภัยของการใช้งานคีย์มาสเตอร์
attestationChallenge OCTET_STRING ค่าของ Tag::ATTESTATION_CHALLENGE ระบุในคำขอรับรอง
uniqueId OCTET_STRING รหัสที่ไม่ซ้ำซึ่งเป็นทางเลือก แสดงหากคีย์มี Tag::INCLUDE_UNIQUE_ID
softwareEnforced รายการอนุญาต การอนุญาตคีย์มาสเตอร์ทางเลือกที่ไม่ได้บังคับใช้โดย TEE ถ้ามี
teeEnforced รายการอนุญาต ทางเลือก การอนุญาต Keymaster ที่บังคับใช้โดย TEE ถ้ามี

เขตข้อมูลรายการอนุญาต

ฟิลด์ AuthorizationList เป็นทางเลือกทั้งหมดและระบุด้วยค่าแท็กคีย์มาสเตอร์ โดยมีบิตประเภทถูกพรางไว้ การติดแท็กที่ชัดเจนถูกใช้เพื่อให้ฟิลด์ต่างๆ มีแท็กที่ระบุประเภท ASN.1 เพื่อให้แยกวิเคราะห์ได้ง่ายขึ้น

สำหรับรายละเอียดเกี่ยวกับค่าของแต่ละฟิลด์ โปรดดูที่ types.hal สำหรับ Keymaster 3 และ keymaster_defs.h สำหรับ Keymaster 2 และด้านล่าง ชื่อแท็กคีย์มาสเตอร์ถูกแปลงเป็นชื่อฟิลด์โดยละเว้นคำนำหน้า KM_TAG และเปลี่ยนส่วนที่เหลือเป็นตัวพิมพ์แบบคาเมล ดังนั้น Tag::KEY_SIZE จึงกลายเป็น keySize

ฟิลด์ RootOfTrust

ฟิลด์ RootOfTrust ถูกระบุตำแหน่ง

ชื่อฟิลด์ พิมพ์ ค่า
verifiedBootKey OCTET_STRING แฮชที่ปลอดภัยของคีย์ที่ใช้ในการตรวจสอบอิมเมจระบบ แนะนำให้ใช้ SHA-256
deviceLocked บูลีน เป็นจริงหากบูตโหลดเดอร์ถูกล็อค ซึ่งหมายความว่าสามารถแฟลชได้เฉพาะอิมเมจที่เซ็นชื่อเท่านั้น และการตรวจสอบการบูตที่ได้รับการยืนยันก็เสร็จสิ้น
verifiedBootState ตรวจสอบ BootState แล้ว สถานะของการบูตที่ตรวจสอบแล้ว
verifiedBootHash OCTET_STRING สรุปข้อมูลทั้งหมดที่ได้รับการคุ้มครองโดย Verified Boot สำหรับอุปกรณ์ที่ใช้ Android Verified Boot ของ Verified Boot ค่านี้ประกอบด้วยไดเจสต์ของ โครงสร้าง VBMeta หรือโครงสร้างข้อมูลเมตาของ Verified Boot หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับวิธีการคำนวณค่านี้ โปรดดูที่VBMeta Digest

ค่า VerifiedBootState

ค่าของ verifiedBootState มีความหมายดังต่อไปนี้:

ค่า ความหมาย
Verified บ่งชี้ถึงความน่าเชื่อถือแบบครบวงจรที่ขยายจากบูตโหลดเดอร์ไปยังพาร์ติชันที่ได้รับการตรวจสอบ รวมถึงบูตโหลดเดอร์ พาร์ติชันสำหรับบูต และพาร์ติชันที่ได้รับการตรวจสอบทั้งหมด
ในสถานะนี้ ค่า verifiedBootKey คือแฮชของใบรับรองแบบฝัง ซึ่งหมายความว่าใบรับรองที่ไม่สามารถเปลี่ยนแปลงได้ถูกเบิร์นลงใน ROM
สถานะนี้สอดคล้องกับสถานะการบูต สีเขียว ตามที่ระบุไว้ในเอกสาร ประกอบขั้นตอนการบูตที่ตรวจสอบแล้ว
SelfSigned บ่งชี้ว่าพาร์ติชันสำหรับเริ่มระบบได้รับการตรวจสอบโดยใช้ใบรับรองแบบฝัง และลายเซ็นนั้นถูกต้อง โปรแกรมโหลดบูตจะแสดงคำเตือนและลายนิ้วมือของคีย์สาธารณะก่อนที่จะอนุญาตให้กระบวนการบูตดำเนินการต่อ
ในสถานะนี้ ค่า verifiedBootKey คือแฮชของใบรับรองที่ลงนามด้วยตนเอง
สถานะนี้สอดคล้องกับสถานะการบูต สีเหลือง ตามที่ระบุไว้ในเอกสาร ประกอบขั้นตอนการบูตที่ตรวจสอบแล้ว
Unverified บ่งชี้ว่าอุปกรณ์อาจได้รับการแก้ไขอย่างอิสระ ความสมบูรณ์ของอุปกรณ์เป็นหน้าที่ของผู้ใช้เพื่อตรวจสอบนอกแบนด์ Bootloader จะแสดงคำเตือนแก่ผู้ใช้ก่อนที่จะอนุญาตให้กระบวนการบู๊ตดำเนินต่อไป
ในสถานะนี้ ค่า verifiedBootKey ว่างเปล่า
สถานะนี้สอดคล้องกับสถานะการบูต สีส้ม ตามที่ระบุไว้ในเอกสาร ประกอบขั้นตอนการบูตที่ตรวจสอบแล้ว
Failed แสดงว่าอุปกรณ์ไม่ผ่านการตรวจสอบ จริงๆ แล้วไม่มีใบรับรองการรับรองที่มีค่านี้ เนื่องจากในสถานะนี้โปรแกรมโหลดบูตจะหยุดทำงาน รวมไว้ที่นี่เพื่อความสมบูรณ์
สถานะนี้สอดคล้องกับสถานะการบูต สีแดง ตามที่ระบุไว้ในเอกสาร ประกอบขั้นตอนการบูตที่ตรวจสอบแล้ว

ค่าระดับความปลอดภัย

ค่าของ securityLevel มีความหมายดังต่อไปนี้:

ค่า ความหมาย
Software รหัสที่สร้างหรือจัดการองค์ประกอบที่เกี่ยวข้อง (เอกสารรับรองหรือคีย์) จะถูกนำไปใช้ในระบบ Android และอาจเปลี่ยนแปลงได้หากระบบนั้นถูกบุกรุก
TrustedEnvironment รหัสที่สร้างหรือจัดการองค์ประกอบที่เกี่ยวข้อง (เอกสารรับรองหรือคีย์) จะถูกนำไปใช้ใน Trusted Execution Environment (TEE) อาจมีการเปลี่ยนแปลงได้หาก TEE ถูกบุกรุก แต่ TEE มีความทนทานสูงต่อการประนีประนอมจากระยะไกล และทนทานต่อการประนีประนอมจากการโจมตีด้วยฮาร์ดแวร์โดยตรงในระดับปานกลาง
StrongBox รหัสที่สร้างหรือจัดการองค์ประกอบที่เกี่ยวข้อง (เอกสารรับรองหรือคีย์) จะถูกนำไปใช้ในโมดูลความปลอดภัยของฮาร์ดแวร์เฉพาะ อาจมีการเปลี่ยนแปลงได้หากโมดูลความปลอดภัยของฮาร์ดแวร์ถูกบุกรุก แต่มีความทนทานสูงต่อการประนีประนอมจากระยะไกล และมีความทนทานสูงต่อการประนีประนอมจากการโจมตีด้วยฮาร์ดแวร์โดยตรง

ID ไม่ซ้ำกัน

รหัสเฉพาะคือค่า 128 บิตที่ใช้ระบุอุปกรณ์ แต่ในระยะเวลาที่จำกัดเท่านั้น ค่าจะถูกคำนวณด้วย:

HMAC_SHA256(T || C || R, HBK)

ที่ไหน:

  • T คือ "ค่าตัวนับชั่วคราว" ซึ่งคำนวณโดยการหารค่าของ Tag::CREATION_DATETIME ด้วย 2592000000 โดยให้ทิ้งเศษที่เหลือ T เปลี่ยนทุกๆ 30 วัน (2592000000 = 30 * 24 * 60 * 60 * 1,000)
  • C คือค่าของ Tag::APPLICATION_ID
  • R คือ 1 หาก Tag::RESET_SINCE_ID_ROTATION มีอยู่ในพารามิเตอร์ attest_params ของการเรียก attest_key หรือ 0 หากไม่มีแท็ก
  • HBK เป็นความลับเฉพาะที่เกี่ยวข้องกับฮาร์ดแวร์ซึ่งเป็นที่รู้จักใน Trusted Execution Environment และไม่เคยเปิดเผยโดยสิ่งนี้ ข้อมูลลับประกอบด้วยเอนโทรปีอย่างน้อย 128 บิตและไม่ซ้ำกันในแต่ละอุปกรณ์ (ความน่าจะเป็นที่ไม่ซ้ำใครเป็นที่ยอมรับได้เมื่อมีเอนโทรปี 128 บิต) HBK ควรได้มาจากวัสดุหลักที่หลอมรวมผ่าน HMAC หรือ AES_CMAC

ตัดทอนเอาต์พุต HMAC_SHA256 ให้เป็น 128 บิต

คีย์การรับรองและใบรับรอง

สองคีย์, หนึ่ง RSA และหนึ่ง ECDSA และห่วงโซ่ใบรับรองที่เกี่ยวข้อง ได้รับการจัดเตรียมอย่างปลอดภัยในอุปกรณ์

Android 12 เปิดตัวการจัดเตรียมคีย์ระยะไกล และ Android 13 กำหนดให้อุปกรณ์ใช้งาน การจัดเตรียมคีย์ระยะไกลมอบอุปกรณ์ในภาคสนามที่มีใบรับรองการรับรอง ECDSA P256 ต่อแอปพลิเคชัน ใบรับรองเหล่านี้มีอายุสั้นกว่าใบรับรองที่จัดเตรียมโดยโรงงาน

IMEI หลายรายการ

Android 14 เพิ่มการรองรับ IMEI หลายรายการในบันทึกการรับรองคีย์ Android OEM สามารถใช้คุณลักษณะนี้ได้โดยการเพิ่มแท็ก KeyMint สำหรับ IMEI ที่สอง เป็นเรื่องปกติมากขึ้นเรื่อยๆ สำหรับอุปกรณ์ที่มีวิทยุเซลลูลาร์หลายเครื่อง และขณะนี้ OEM สามารถรองรับอุปกรณ์ที่มี IMEI สองตัวได้

OEM จำเป็นต้องมี IMEI รอง หากมีอยู่ในอุปกรณ์ เพื่อจัดเตรียมการใช้งาน KeyMint เพื่อให้การใช้งานเหล่านั้นสามารถยืนยันได้ในลักษณะเดียวกับที่พวกเขายืนยันกับ IMEI แรก

การรับรองบัตรประจำตัว

Android 8.0 มีการสนับสนุนเพิ่มเติมสำหรับการรับรอง ID สำหรับอุปกรณ์ที่มี Keymaster 3 การรับรอง ID ช่วยให้อุปกรณ์สามารถแสดงหลักฐานตัวระบุฮาร์ดแวร์ เช่น หมายเลขซีเรียลหรือ IMEI แม้ว่าจะเป็นคุณสมบัติเสริม ขอแนะนำอย่างยิ่งให้การใช้งาน Keymaster 3 ทั้งหมดให้การสนับสนุน เนื่องจากความสามารถในการพิสูจน์ตัวตนของอุปกรณ์ทำให้กรณีการใช้งาน เช่น การกำหนดค่าระยะไกลแบบไม่ต้องสัมผัสที่แท้จริงมีความปลอดภัยมากขึ้น (เพราะด้านระยะไกลสามารถมั่นใจได้ กำลังพูดคุยกับอุปกรณ์ที่ถูกต้อง ไม่ใช่อุปกรณ์ที่ปลอมแปลงข้อมูลประจำตัว)

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

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

คุณสมบัติการจัดเก็บ

พื้นที่จัดเก็บข้อมูลที่เก็บตัวระบุอุปกรณ์จะต้องมีคุณสมบัติเหล่านี้:

  • ค่าที่ได้รับจากตัวระบุดั้งเดิมของอุปกรณ์จะถูกคัดลอกไปยังที่จัดเก็บข้อมูลก่อนที่อุปกรณ์จะออกจากโรงงาน
  • เมธอด destroyAttestationIds() สามารถทำลายสำเนาของข้อมูลที่ได้รับจากตัวระบุนี้อย่างถาวร การทำลายล้างอย่างถาวรหมายถึงข้อมูลจะถูกลบออกอย่างสมบูรณ์ ดังนั้นทั้งการรีเซ็ตเป็นค่าจากโรงงานหรือขั้นตอนอื่นใดที่ดำเนินการบนอุปกรณ์จะไม่สามารถกู้คืนได้ นี่เป็นสิ่งสำคัญอย่างยิ่งสำหรับอุปกรณ์ที่ผู้ใช้ปลดล็อคโปรแกรมโหลดบูตและเปลี่ยนซอฟต์แวร์ระบบและแก้ไขตัวระบุที่ส่งคืนโดยเฟรมเวิร์ก Android
  • สิ่งอำนวยความสะดวก RMA ควรมีความสามารถในการสร้างสำเนาใหม่ของข้อมูลที่ได้รับจากตัวระบุฮาร์ดแวร์ ด้วยวิธีนี้ อุปกรณ์ที่ผ่าน RMA จะสามารถดำเนินการรับรอง ID ได้อีกครั้ง กลไกที่ใช้โดยสิ่งอำนวยความสะดวก RMA จะต้องได้รับการปกป้องเพื่อให้ผู้ใช้ไม่สามารถเรียกใช้ได้ด้วยตนเอง เนื่องจากจะทำให้พวกเขาได้รับการรับรอง ID ที่ถูกปลอมแปลง
  • ไม่มีรหัสอื่นใดนอกจากแอปที่เชื่อถือได้ของ Keymaster ใน TEE ที่สามารถอ่านข้อมูลที่ได้รับจากตัวระบุที่เก็บไว้ในที่จัดเก็บข้อมูล
  • ที่เก็บข้อมูลมีหลักฐานการงัดแงะ: หากเนื้อหาของที่เก็บข้อมูลได้รับการแก้ไข TEE จะถือว่ามันเหมือนกับว่าสำเนาของเนื้อหาถูกทำลายและปฏิเสธความพยายามในการรับรอง ID ทั้งหมด ซึ่งดำเนินการโดยการลงนามหรือ MACing ที่เก็บข้อมูล ตามที่อธิบายไว้ด้านล่าง
  • ที่เก็บข้อมูลไม่มีตัวระบุดั้งเดิม เนื่องจากการรับรอง ID เกี่ยวข้องกับการท้าทาย ผู้โทรจะระบุตัวระบุที่จะยืนยันเสมอ TEE เพียงแต่ต้องตรวจสอบว่าค่าเหล่านี้ตรงกับค่าที่มีอยู่เดิม การจัดเก็บแฮชที่ปลอดภัยของค่าดั้งเดิมแทนค่าจะทำให้สามารถตรวจสอบได้

การก่อสร้าง

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

S = D || HMAC(HBK, D)

ที่ไหน:

  • D = HMAC(HBK, ID 1 ) || HMAC(HBK, ID 2 ) || ... || HMAC(HBK, ID n )
  • HMAC คือโครงสร้าง HMAC ที่มีแฮชที่ปลอดภัยที่เหมาะสม (แนะนำ SHA-256)
  • HBK คือคีย์ที่ผูกกับฮาร์ดแวร์ซึ่งไม่ได้ใช้เพื่อวัตถุประสงค์อื่นใด
  • ID 1 ...ID n คือค่า ID ดั้งเดิม การเชื่อมโยงค่าเฉพาะกับดัชนีเฉพาะนั้นขึ้นอยู่กับการใช้งาน เนื่องจากอุปกรณ์ที่แตกต่างกันจะมีจำนวนตัวระบุที่แตกต่างกัน
  • || แสดงถึงการต่อข้อมูล

เนื่องจากเอาต์พุต HMAC มีขนาดคงที่ จึงไม่จำเป็นต้องมีส่วนหัวหรือโครงสร้างอื่นเพื่อให้สามารถค้นหาแฮช ID แต่ละรายการหรือ HMAC ของ D นอกเหนือจากการตรวจสอบค่าที่ให้มาเพื่อดำเนินการรับรองแล้ว การใช้งานจำเป็นต้องตรวจสอบความถูกต้องของ S โดยแยก D ออกจาก S , คำนวณ HMAC(HBK, D) และเปรียบเทียบกับค่าใน S เพื่อตรวจสอบว่าไม่มีการแก้ไข/เสียหาย ID แต่ละรายการ นอกจากนี้ การใช้งานต้องใช้การเปรียบเทียบเวลาคงที่สำหรับองค์ประกอบ ID แต่ละรายการและการตรวจสอบความถูกต้องของ S เวลาในการเปรียบเทียบจะต้องคงที่โดยไม่คำนึงถึงจำนวน ID ที่ให้มา และการจับคู่ที่ถูกต้องของส่วนใด ๆ ของการทดสอบ

ตัวระบุฮาร์ดแวร์

การรับรอง ID รองรับตัวระบุฮาร์ดแวร์ต่อไปนี้:

  1. ชื่อแบรนด์ที่ Build.BRAND ส่งคืนใน Android
  2. ชื่ออุปกรณ์ตามที่ Build.DEVICE ส่งคืนใน Android
  3. ชื่อผลิตภัณฑ์ที่ส่งคืนโดย Build.PRODUCT ใน Android
  4. ชื่อผู้ผลิต ตามที่ Build.MANUFACTURER ส่งคืนใน Android
  5. ชื่อรุ่นตามที่ Build.MODEL ส่งคืนใน Android
  6. หมายเลขซีเรียล
  7. IMEI ของวิทยุทั้งหมด
  8. MEID ของวิทยุทั้งหมด

เพื่อรองรับการรับรองรหัสอุปกรณ์ อุปกรณ์จะยืนยันตัวระบุเหล่านี้ อุปกรณ์ทั้งหมดที่ใช้ Android มีหกเครื่องแรกและจำเป็นสำหรับคุณสมบัตินี้ในการทำงาน หากอุปกรณ์มีวิทยุเซลลูลาร์ในตัว อุปกรณ์นั้นจะต้องรองรับการรับรอง IMEI และ/หรือ MEID ของวิทยุด้วย

มีการร้องขอการรับรอง ID โดยดำเนินการรับรองคีย์และรวมถึงตัวระบุอุปกรณ์เพื่อยืนยันในคำขอ ตัวระบุถูกแท็กเป็น:

  • ATTESTATION_ID_BRAND
  • ATTESTATION_ID_DEVICE
  • ATTESTATION_ID_PRODUCT
  • ATTESTATION_ID_MANUFACTURER
  • ATTESTATION_ID_MODEL
  • ATTESTATION_ID_SERIAL
  • ATTESTATION_ID_IMEI
  • ATTESTATION_ID_MEID

ตัวระบุที่จะยืนยันคือสตริงไบต์ที่เข้ารหัส UTF-8 รูปแบบนี้ใช้กับตัวระบุที่เป็นตัวเลขด้วย ตัวระบุแต่ละตัวที่จะยืนยันจะแสดงเป็นสตริงที่เข้ารหัส UTF-8

หากอุปกรณ์ไม่รองรับการรับรองรหัส (หรือก่อนหน้านี้มีการเรียก destroyAttestationIds() และอุปกรณ์ไม่สามารถยืนยันรหัสได้อีกต่อไป) คำขอรับรองคีย์ใดๆ ที่มีแท็กเหล่านี้ตั้งแต่หนึ่งแท็กขึ้นไปจะล้มเหลวด้วย ErrorCode::CANNOT_ATTEST_IDS

หากอุปกรณ์รองรับการรับรอง ID และมีแท็กข้างต้นอย่างน้อยหนึ่งแท็กรวมอยู่ในคำขอการรับรองคีย์ TEE จะตรวจสอบตัวระบุที่มาพร้อมกับแต่ละแท็กตรงกับสำเนาของตัวระบุฮาร์ดแวร์ หากตัวระบุตั้งแต่หนึ่งตัวขึ้นไปไม่ตรงกัน การรับรองทั้งหมดจะล้มเหลวด้วย ErrorCode::CANNOT_ATTEST_IDS ถูกต้องสำหรับแท็กเดียวกันที่จะใส่หลายครั้ง ข้อมูลนี้อาจเป็นประโยชน์ เช่น เมื่อยืนยัน IMEI: อุปกรณ์อาจมีวิทยุหลายเครื่องที่มี IMEI หลายเครื่อง คำขอรับรองจะใช้ได้หากค่าที่ให้มาพร้อมกับ ATTESTATION_ID_IMEI แต่ละรายการตรงกับวิทยุรายการใดรายการหนึ่งของอุปกรณ์ เช่นเดียวกับแท็กอื่นๆ ทั้งหมด

หากการรับรองสำเร็จ รหัสที่ได้รับการรับรองจะถูกเพิ่มลงใน ส่วนขยายการรับรอง (OID 1.3.6.1.4.1.11129.2.1.17) ของใบรับรองการรับรองที่ออกให้ โดยใช้ สคีมาจากด้านบน การเปลี่ยนแปลงจากสคีมารับรอง Keymaster 2 เป็น ตัวหนา พร้อมความคิดเห็น

จาวา API

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