מאגר המפתחות מספק מקום מאובטח יותר ליצירה, לאחסון ולשימוש של מפתחות קריפטוגרפיים באופן מבוקר. כשאחסון מפתחות מבוסס-חומרה זמין ומשומש, חומר המפתחות מאובטח יותר מפני חילוץ מהמכשיר, ו-Keymaster אוכף הגבלות שקשה לעקוף.
עם זאת, זה נכון רק אם ידוע שהמפתחות של מאגר המפתחות נמצאים באחסון שמגובה בחומרה. ב-Keymaster 1, לא הייתה דרך לאפליקציות או לשרתים מרוחקים לאמת בצורה אמינה אם זה המצב. הדימון של מאגר המפתחות טען את HAL של Keymaster שזמין, והאמין לכל מה ש-HAL אמר לגבי גיבוי המפתחות בחומרה.
כדי לפתור את הבעיה הזו, הוספנו ל-Keymaster את אימות המפתחות ב-Android 7.0 (Keymaster 2) ואת אימות הזהויות ב-Android 8.0 (Keymaster 3).
המטרה של אימות מפתחות היא דרך לקבוע בצורה מדויקת אם זוג מפתחות אסימטריים מגובה בחומרה, מהם המאפיינים של המפתח ואילו אילוצים יחולו על השימוש בו.
אימות המזהה מאפשר למכשיר לספק הוכחה למזהי החומרה שלו, כמו מספר סידורי או IMEI.
אימות עם מפתח
כדי לתמוך באימות (attestation) של מפתחות, מערכת Android 7.0 הוסיפה ל-HAL קבוצה של תגים, סוג ושיטה.
תגים
Tag::ATTESTATION_CHALLENGE
Tag::INCLUDE_UNIQUE_ID
Tag::RESET_SINCE_ID_ROTATION
סוג השידור
Keymaster 2 וגרסאות קודמות
typedef struct { keymaster_blob_t* entries; size_t entry_count; } keymaster_cert_chain_t;
השיטה AttestKey
Keymaster 3
attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams) generates(ErrorCode error, vec<vec<uint8_t>> certChain);
Keymaster 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
הוא המבנה של מכשיר ה-Keymaster.keyToAttest
הוא blob המפתח שמוחזרים מ-generateKey
, שעבורו נוצר האימות.attestParams
היא רשימה של כל הפרמטרים הנדרשים לאימות. למשל,Tag::ATTESTATION_CHALLENGE
וייתכן גםTag::RESET_SINCE_ID_ROTATION
, וגםTag::APPLICATION_ID
ו-Tag::APPLICATION_DATA
. שתיהן נדרשות לפענוח של ה-blob של המפתח אם הם צוינו במהלך יצירת המפתח.certChain
הוא פרמטר הפלט, שמחזיר מערך של אישורים. הערך 0 הוא אישור האימות, כלומר הוא מאמת את המפתח מ-keyToAttest
ומכיל את התוסף לאימות.
ה-method attestKey
נחשבת כפעולה של מפתח ציבורי במפתח המאומת, כי אפשר לקרוא לה בכל שלב והיא לא צריכה לעמוד במגבלות ההרשאות. לדוגמה, אם המפתח המאומת מחייב אימות משתמש לשימוש, אפשר ליצור אימות בלי אימות משתמש.
אישור אימות (attestation)
אישור האימות הוא אישור X.509 רגיל, עם תוסף אימות אופציונלי שמכיל תיאור של המפתח המאומת. האישור חתום באמצעות מפתח אימות מאושר. מפתח האימות עשוי להשתמש באלגוריתם שונה מהמפתח שמאמתים.
אישור האימות מכיל את השדות שמפורטים בטבלה שלמטה, ואי אפשר לכלול בו שדות נוספים. בשדות מסוימים מצוין ערך שדה קבוע. בדיקות CTS מאמתות שתוכן האישור זהה לתוכן שהוגדר.
SEQUENCE של אישור
שם השדה (לפרטים: RFC 5280) | ערך |
---|---|
tbsCertificate | TBSCertificate SEQUENCE |
signatureAlgorithm | מזהה האלגוריתם שמשמש לחתימה על המפתח: ECDSA למפתחות EC, RSA למפתחות RSA. |
signatureValue | BIT string, חתימה שמחושבת ב-tbsCertificate בקידוד ASN.1 DER. |
רצף TBSCertificate
שם השדה (לפרטים: RFC 5280) | ערך |
---|---|
version |
INTEGER 2 (המשמעות היא אישור v3) |
serialNumber |
INTEGER 1 (ערך קבוע: זהה בכל האישורים) |
signature |
AlgorithmIdentifier של האלגוריתם שמשמש לחתימה על המפתח: ECDSA למפתחות EC, RSA למפתחות RSA. |
issuer |
זהה לשדה הנושא של מפתח האימות (attestation) של האצווה. |
validity |
רצף של שני תאריכים, שמכיל את הערכים של 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 Key" (ערך קבוע: זהה בכל האישורים) |
subjectPublicKeyInfo |
SubjectPublicKeyInfo שמכיל מפתח ציבורי מאומת. |
extensions/Key Usage |
חתימה דיגיטלית: מוגדרת אם למפתח יש מטרה 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 של רצף האימות. |
תוסף אימות (attestation)
התוסף attestation
כולל OID 1.3.6.1.4.1.11129.2.1.17
. הוא מכיל מידע על זוג המפתחות שמאומת ועל מצב המכשיר בזמן יצירת המפתח.
סוגי התגים של Keymaster/KeyMint שמוגדרים במפרט הממשק של AIDL מתורגמים לסוגי ASN.1 באופן הבא:
סוג Keymaster/KeyMint | סוג ASN.1 | הערות |
---|---|---|
ENUM |
INTEGER |
|
ENUM_REP |
SET of INTEGER |
|
UINT |
INTEGER |
|
UINT_REP |
SET of INTEGER |
|
ULONG |
INTEGER |
|
ULONG_REP |
SET of INTEGER |
|
DATE |
INTEGER |
אלפיות השנייה מאז 1 בינואר 1970, 00:00:00 (שעון גריניץ'). |
BOOL |
NULL |
נוכחות התג פירושה true, והיעדרו פירושו false. |
BIGNUM |
אין תגים מהסוג הזה, לכן לא מוגדר מיפוי. | |
BYTES |
OCTET_STRING |
סכימה
תוכן התוסף לאימות מתארים באמצעות הסכימה הבאה של ASN.1:
גרסה 300
KeyDescription ::= SEQUENCE { attestationVersion 300, attestationSecurityLevel SecurityLevel, keyMintVersion INTEGER, keyMintSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, hardwareEnforced 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, mgfDigest [203] EXPLICIT SET OF INTEGER OPTIONAL, rollbackResistance [303] EXPLICIT NULL OPTIONAL, earlyBootOnly [305] EXPLICIT NULL OPTIONAL, activeDateTime [400] EXPLICIT INTEGER OPTIONAL, originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL, usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL, usageCountLimit [405] 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, trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, unlockedDeviceRequired [509] EXPLICIT NULL OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL, bootPatchLevel [719] EXPLICIT INTEGER OPTIONAL, deviceUniqueAttestation [720] EXPLICIT NULL OPTIONAL, attestationIdSecondImei [723] EXPLICIT OCTET_STRING OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, verifiedBootHash OCTET_STRING, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
גרסה 200
KeyDescription ::= SEQUENCE { attestationVersion 200, attestationSecurityLevel SecurityLevel, keyMintVersion INTEGER, keyMintSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, hardwareEnforced 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, mgfDigest [203] EXPLICIT SET OF INTEGER OPTIONAL, rollbackResistance [303] EXPLICIT NULL OPTIONAL, earlyBootOnly [305] EXPLICIT NULL OPTIONAL, activeDateTime [400] EXPLICIT INTEGER OPTIONAL, originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL, usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL, usageCountLimit [405] 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, trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, unlockedDeviceRequired [509] EXPLICIT NULL OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL, bootPatchLevel [719] EXPLICIT INTEGER OPTIONAL, deviceUniqueAttestation [720] EXPLICIT NULL OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, verifiedBootHash OCTET_STRING, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
גרסה 100
KeyDescription ::= SEQUENCE { attestationVersion 100, attestationSecurityLevel SecurityLevel, keyMintVersion INTEGER, keyMintSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, hardwareEnforced 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, mgfDigest [203] EXPLICIT SET OF INTEGER OPTIONAL, rollbackResistance [303] EXPLICIT NULL OPTIONAL, earlyBootOnly [305] EXPLICIT NULL OPTIONAL, activeDateTime [400] EXPLICIT INTEGER OPTIONAL, originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL, usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL, usageCountLimit [405] 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, trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, unlockedDeviceRequired [509] EXPLICIT NULL OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL, bootPatchLevel [719] EXPLICIT INTEGER OPTIONAL, deviceUniqueAttestation [720] EXPLICIT NULL OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, verifiedBootHash OCTET_STRING, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
גרסה 4
KeyDescription ::= SEQUENCE { attestationVersion 4, attestationSecurityLevel SecurityLevel, keymasterVersion INTEGER, keymasterSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, hardwareEnforced 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, earlyBootOnly [305] EXPLICIT NULL OPTIONAL, 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, trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, unlockedDeviceRequired [509] EXPLICIT NULL OPTIONAL, allApplications [600] EXPLICIT NULL OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL, bootPatchLevel [719] EXPLICIT INTEGER OPTIONAL, deviceUniqueAttestation [720] EXPLICIT NULL OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, verifiedBootHash OCTET_STRING, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
גרסה 3
KeyDescription ::= SEQUENCE { attestationVersion 3, attestationSecurityLevel SecurityLevel, keymasterVersion INTEGER, keymasterSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, hardwareEnforced 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, 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, trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, unlockedDeviceRequired [509] EXPLICIT NULL OPTIONAL, allApplications [600] EXPLICIT NULL OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL, bootPatchLevel [719] EXPLICIT INTEGER OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, verifiedBootHash OCTET_STRING, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
גרסה 2
KeyDescription ::= SEQUENCE { attestationVersion 2, attestationSecurityLevel SecurityLevel, keymasterVersion INTEGER, keymasterSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, hardwareEnforced AuthorizationList, } SecurityLevel ::= ENUMERATED { Software (0), TrustedEnvironment (1), } 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, 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, allApplications [600] EXPLICIT NULL OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rollbackResistant [703] EXPLICIT NULL OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
גרסה 1
KeyDescription ::= SEQUENCE { attestationVersion 1, attestationSecurityLevel SecurityLevel, keymasterVersion INTEGER, keymasterSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, hardwareEnforced AuthorizationList, } SecurityLevel ::= ENUMERATED { Software (0), TrustedEnvironment (1), } 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, 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, allApplications [600] EXPLICIT NULL OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rollbackResistant [703] EXPLICIT NULL OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
שדות KeyDescription
-
attestationVersion
-
גרסת הסכימה של ASN.1.
ערך הגרסה של Keymaster/KeyMint 1 גרסה 2.0 של Keymaster 2 גרסה 3.0 של Keymaster 3 גרסה 4.0 של Keymaster 4 גרסה 4.1 של Keymaster 100 גרסה 1.0 של KeyMint 200 KeyMint גרסה 2.0 300 גרסה 3.0 של KeyMint -
attestationSecurityLevel
-
רמת האבטחה של המיקום שבו המפתח המאומת מאוחסן.
-
keymasterVersion
מתוךkeyMintVersion
-
גרסת ההטמעה של שיטת הפשטת החומרה (HAL) של Keymaster/KeyMint.
ערך גרסת Keymaster/KeyMint 2 גרסה 2.0 של Keymaster 3 גרסה 3.0 של Keymaster 4 גרסה 4.0 של Keymaster 41 גרסה 4.1 של Keymaster 100 גרסה 1.0 של KeyMint 200 KeyMint גרסה 2.0 300 גרסה 3.0 של KeyMint -
keymasterSecurityLevel
מתוךkeyMintSecurityLevel
- רמת האבטחה של הטמעת Keymaster/KeyMint.
-
attestationChallenge
- האתגר שסופק בזמן יצירת המפתח.
-
uniqueId
- מזהה מכשיר רגיש לפרטיות שאפליקציות מערכת יכולות לבקש בזמן יצירת המפתח. אם לא מבקשים את המזהה הייחודי, השדה הזה יהיה ריק. פרטים נוספים זמינים בקטע מזהה ייחודי.
-
softwareEnforced
-
רשימת ההרשאות של Keymaster/KeyMint שנאכפת על ידי מערכת Android. המידע הזה נאסף או נוצר על ידי קוד בפלטפורמה, ונשמר במחיצה המערכתית של המכשיר. אפשר לסמוך עליו כל עוד פועלת במכשיר מערכת הפעלה שתואמת למודל האבטחה של פלטפורמת Android (כלומר, תוכנת האתחול של המכשיר נעולה ו-
verifiedBootState
הואVerified
). -
hardwareEnforced
- רשימת ההרשאות של Keymaster/KeyMint, שמופעל על ידי סביבת המחשוב המאובטחת (TEE) או על ידי StrongBox של המכשיר. המידע הזה נאסף או נוצר על ידי קוד בחומרה המאובטחת, והפלטפורמה לא שולטת בו. לדוגמה, המידע יכול להגיע מתוכנת האתחול או דרך ערוץ תקשורת מאובטח שלא כולל אמון בפלטפורמה.
ערכים של רמת אבטחה
הערך של SecurityLevel
מציין את מידת העמידות של רכיב שקשור ל-Keystore (לדוגמה, צמד מפתחות ואימות) להתקפה.
ערך | משמעות |
---|---|
Software |
מאובטח כל עוד מערכת Android במכשיר עומדת בדרישות של
מודל האבטחה של הפלטפורמה של Android
(כלומר, תוכנת האתחול של המכשיר נעולה ומאפיין
verifiedBootState הוא
Verified ). |
TrustedEnvironment |
מאובטח כל עוד סביבת המחשוב המאובטחת (TEE) לא נפרצה. דרישות הבידוד של TEEs מוגדרות בקטעים 9.11 [C-1-1] עד [C-1-4] במסמך הגדרת התאימות של Android. לסביבות TEE יש עמידות גבוהה מאוד מפני פגיעה מרחוק, ועמידות בינונית מפני פגיעה כתוצאה מתקיפה ישירה בחומרה. |
StrongBox |
מאובטח כל עוד StrongBox לא נפרץ. StrongBox מוטמעת ברכיב מאובטח שדומה למודול אבטחה של חומרה. דרישות ההטמעה של StrongBox מוגדרות בקטע 9.11.2 במסמך הגדרת התאימות של Android. ל-StrongBox יש עמידות גבוהה בפני פריצה מרחוק ופריצה באמצעות התקפה ישירה של החומרה (לדוגמה, פגיעה פיזית והתקפות ערוץ צדדי). |
השדות של AuthorizationList
כל שדה תואם לתג הרשאה של Keymaster/KeyMint ממפרט הממשק של AIDL.
המפרט הוא מקור האמינות לגבי תגי ההרשאה: המשמעות שלהם, הפורמט של התוכן שלהם, אם הם צפויים להופיע בשדות softwareEnforced
או hardwareEnforced
באובייקט KeyDescription
, אם הם לא יכולים להופיע יחד עם תוויות אחרות וכו'. כל השדות של AuthorizationList
הם אופציונליים.
לכל שדה יש תג EXPLICIT
ספציפי להקשר, ששווה למספר התג Keymaster/KeyMint, שמאפשר ייצוג קומפקטי יותר של הנתונים ב-AuthorizationList
. לכן, מנתח ה-ASN.1 צריך לדעת את סוג הנתונים הצפוי לכל תג ספציפי להקשר. לדוגמה,
Tag::USER_AUTH_TYPE
מוגדר כ-ENUM | 504
. בהסכימה של התוסף לאימות, השדה purpose
ב-AuthorizationList
מצוין בתור userAuthType [504] EXPLICIT INTEGER OPTIONAL
. לכן, הקידוד של ASN.1 יכיל את התג 504
שספציפי להקשר במקום את תג הכיתה UNIVERSAL
לסוג ASN.1 INTEGER
, שהוא 10
.
-
purpose
-
תואם לתג ההרשאה
Tag::PURPOSE
, שבו נעשה שימוש בערך מזהה של תג 1. -
algorithm
-
תואם לתג ההרשאה
Tag::ALGORITHM
, שבו נעשה שימוש בערך 2 של מזהה התג.באובייקט
AuthorizationList
של אימות (attestation), ערך האלגוריתם הוא תמידRSA
אוEC
. -
keySize
-
תואם לתג ההרשאה
Tag::KEY_SIZE
, שבו נעשה שימוש בערך מזהה תג של 3. -
digest
-
תואם לתג ההרשאה
Tag::DIGEST
, שבו מזהה התג הוא 5. -
padding
-
תואם לתג ההרשאה
Tag::PADDING
, שבו נעשה שימוש בערך מזהה תג של 6. -
ecCurve
-
תואם לתג ההרשאה
Tag::EC_CURVE
, שמשתמש בערך של מזהה התג 10.קבוצת הפרמטרים שמשמשת ליצירת זוג מפתחות של עקומה אליפטית (EC), שמשתמש ב-ECDSA לחתימה ולאימות, בתוך מאגר המפתחות של מערכת Android.
-
rsaPublicExponent
-
תואם לתג ההרשאה
Tag::RSA_PUBLIC_EXPONENT
, שמשתמש בערך מזהה תג של 200. -
mgfDigest
-
הצגה רק בגרסת אימות (attestation) של מפתח >= 100.
תואם לתג ההרשאהTag::RSA_OAEP_MGF_DIGEST
של KeyMint, שמשתמש בערך מזהה תג של 203. -
rollbackResistance
-
השדה הזה קיים רק בגרסה 3 ואילך של אימות המפתחות.
תואם לתג ההרשאה
Tag::ROLLBACK_RESISTANCE
, שמשתמש בערך מזהה תג של 303. -
earlyBootOnly
-
השדה הזה קיים רק בגרסה 4 ואילך של אימות המפתחות.
תואם לתג ההרשאה
Tag::EARLY_BOOT_ONLY
, שמשתמש בערך מזהה תג של 305. -
activeDateTime
-
תואם לתג ההרשאה
Tag::ACTIVE_DATETIME
, שמשתמש בערך מזהה תג של 400. -
originationExpireDateTime
-
תואם לתג ההרשאה של
Tag::ORIGINATION_EXPIRE_DATETIME
Keymaster, שמשתמש בערך מזהה תג של 401. -
usageExpireDateTime
-
תואם לתג ההרשאה
Tag::USAGE_EXPIRE_DATETIME
, שבו נעשה שימוש בערך מזהה תג של 402. -
usageCountLimit
-
תואם לתג ההרשאה
Tag::USAGE_COUNT_LIMIT
, שבו נעשה שימוש בערך מזהה התג 405. -
noAuthRequired
-
תואם לתג ההרשאה
Tag::NO_AUTH_REQUIRED
, שמשתמש בערך מזהה תג של 503. -
userAuthType
-
תואם לתג ההרשאה
Tag::USER_AUTH_TYPE
, שמשתמש בערך של מזהה התג 504. -
authTimeout
-
תואם לתג ההרשאה
Tag::AUTH_TIMEOUT
, שכולל ערך מזהה התג 505. -
allowWhileOnBody
-
תואם לתג ההרשאה
Tag::ALLOW_WHILE_ON_BODY
, שמשתמש בערך מזהה תג של 506.מאפשרת להשתמש במפתח לאחר פרק הזמן הקצוב לאימות, אם המשתמשים עדיין עונדים את המכשיר על הגוף. חשוב לזכור שחיישן מאובטח בגוף קובע אם המכשיר משוחק על הגוף של המשתמש.
-
trustedUserPresenceRequired
-
השדה הזה קיים רק בגרסה 3 ואילך של אימות המפתחות.
תואם לתג ההרשאה
Tag::TRUSTED_USER_PRESENCE_REQUIRED
, שבו נעשה שימוש בערך מזהה תג של 507.קובעת שאפשר להשתמש במפתח הזה רק אם המשתמש סיפק הוכחה נוכחות פיזית. דוגמאות לכך:
- למפתח StrongBox, לחצן חומרה שמחובר לחוט למסמר במכשיר StrongBox.
- במפתח TEE, אימות טביעת אצבע מספק הוכחה לנוכחות כל עוד ל-TEE יש שליטה בלעדית בסורק והוא מבצע את תהליך ההתאמה של טביעת האצבע.
-
trustedConfirmationRequired
-
השדה הזה קיים רק בגרסה 3 ואילך של אימות המפתחות.
תואם לתג ההרשאה
Tag::TRUSTED_CONFIRMATION_REQUIRED
, שבו נעשה שימוש בערך מזהה תג של 508.מציין שאפשר להשתמש במפתח רק אם המשתמש מספק אישור של הנתונים שעליו לחתום באמצעות אסימון אישור. למידע נוסף על קבלת אישור מהמשתמשים, ראו אישור מוגן ב-Android.
הערה: התג הזה רלוונטי רק למפתחות שמשתמשים במטרה
SIGN
. -
unlockedDeviceRequired
-
השדה הזה קיים רק בגרסה 3 ואילך של אימות המפתחות.
תואם לתג ההרשאה
Tag::UNLOCKED_DEVICE_REQUIRED
, שבו נעשה שימוש בערך מזהה תג של 509. -
allApplications
-
תואם לתג ההרשאה
Tag::ALL_APPLICATIONS
, שמשתמש בערך מזהה תג של 600.מציין אם כל האפליקציות במכשיר יכולות לגשת לזוג המפתחות.
-
applicationId
-
תואם לתג ההרשאה
Tag::APPLICATION_ID
, שמשתמש בערך מזהה תג של 601. -
creationDateTime
-
תואם לתג ההרשאה
Tag::CREATION_DATETIME
, שמשתמש בערך מזהה תג של 701. -
origin
-
תואם לתג ההרשאה
Tag::ORIGIN
, שבו נעשה שימוש בערך מזהה תג של 702. -
rollbackResistant
-
השדה הזה קיים רק בגרסאות 1 ו-2 של אימות המפתחות.
תואם לתג ההרשאה
Tag::ROLLBACK_RESISTANT
, שמשתמש בערך מזהה תג של 703. -
rootOfTrust
-
תואם לתג ההרשאה
Tag::ROOT_OF_TRUST
, שמשתמש בערך מזהה תג של 704.פרטים נוספים זמינים בקטע שמתאר את מבנה הנתונים של RootOfTrust.
-
osVersion
-
תואם לתג ההרשאה
Tag::OS_VERSION
, שמשתמש בערך מזהה תג של 705.הגרסה של מערכת ההפעלה של Android שמשויכת ל-Keymaster, שצוינה כמספר שלם בן שש ספרות. לדוגמה, הגרסה 8.1.0 מיוצגת כ-080100.
רק גרסה 1.0 ואילך של Keymaster כוללת את הערך הזה ברשימת ההרשאות.
-
osPatchLevel
-
תואם לתג ההרשאה
Tag::PATCHLEVEL
, שמשתמש בערך של מזהה התג 706.החודש והשנה שמשויכים לתיקון האבטחה שבו נעשה שימוש ב-Keymaster, שצוינו כמספר שלם בן שש ספרות. לדוגמה, התיקון של אוגוסט 2018 מיוצג בתור 201808.
רק גרסה 1.0 ואילך של Keymaster כוללת את הערך הזה ברשימת ההרשאות.
-
attestationApplicationId
-
השדה הזה קיים רק בגרסאות של אימות מפתחות שמספרן גבוה מ-2.
תואם לתג ההרשאה של Keymaster
Tag::ATTESTATION_APPLICATION_ID
, שמשתמש בערך מזהה תג של 709.פרטים נוספים זמינים בקטע שמתאר את מבנה הנתונים של AttestationApplicationId.
-
attestationIdBrand
-
השדה הזה קיים רק בגרסאות של אימות מפתחות שמספרן גבוה מ-2.
תואם לתג Keymaster
Tag::ATTESTATION_ID_BRAND
, שמשתמש בערך מזהה תג של 710. -
attestationIdDevice
-
השדה הזה קיים רק בגרסאות של אימות מפתחות שמספרן גבוה מ-2.
תואם לתג Keymaster
Tag::ATTESTATION_ID_DEVICE
, שבו נעשה שימוש בערך מזהה תג של 711. -
attestationIdProduct
-
השדה הזה קיים רק בגרסאות של אימות מפתחות שמספרן גבוה מ-2.
תואם לתג Keymaster
Tag::ATTESTATION_ID_PRODUCT
, שמשתמש בערך של מזהה התג 712. -
attestationIdSerial
-
הצגה רק בגרסאות אימות (attestation) של מפתח >= 2.
תואם לתג Keymaster
Tag::ATTESTATION_ID_SERIAL
, שמשתמש בערך מזהה תג של 713. -
attestationIdImei
-
השדה הזה קיים רק בגרסאות של אימות מפתחות שמספרן גבוה מ-2.
תואם לתג ההרשאה
Tag::ATTESTATION_ID_IMEI
, שמשתמש בערך מזהה תג של 714. -
attestationIdMeid
-
הצגה רק בגרסאות אימות (attestation) של מפתח >= 2.
תואם לתג ההרשאה
Tag::ATTESTATION_ID_MEID
, שמשתמש בערך מזהה תג של 715. -
attestationIdManufacturer
-
הצגה רק בגרסאות אימות (attestation) של מפתח >= 2.
תואם לתג ההרשאה
Tag::ATTESTATION_ID_MANUFACTURER
, שמשתמש בערך מזהה תג של 716. -
attestationIdModel
-
השדה הזה קיים רק בגרסאות של אימות מפתחות שמספרן גבוה מ-2.
תואם לתג ההרשאה
Tag::ATTESTATION_ID_MODEL
, שמשתמש בערך של מזהה התג 717. -
vendorPatchLevel
-
השדה הזה קיים רק בגרסאות של אימות מפתחות בגרסה 3 ואילך.
תואם לתג ההרשאה
Tag::VENDOR_PATCHLEVEL
, שמשתמש בערך מזהה תג של 718.מציינת את רמת תיקון האבטחה של תמונת הספק שצריכה להיות מותקנת במכשיר כדי שאפשר יהיה להשתמש במפתח הזה. הערך מופיע בפורמט YYYYMMDD, והוא מייצג את התאריך של תיקון האבטחה של הספק. לדוגמה, אם מפתח נוצר במכשיר Android שבו מותקן תיקון האבטחה של הספק מ-1 באוגוסט 2018, הערך הזה יהיה 20180801.
-
bootPatchLevel
-
השדה הזה קיים רק בגרסאות של אימות מפתחות בגרסה 3 ואילך.
תואם לתג ההרשאה
Tag::BOOT_PATCHLEVEL
, שמשתמש בערך מזהה תג של 719.מציינת את רמת תיקון האבטחה של תמונת הליבה שצריך להתקין במכשיר כדי שאפשר יהיה להשתמש במפתח הזה. הערך מופיע בפורמט YYYYMMDD, שמייצג את התאריך של התיקון לאבטחת המערכת. לדוגמה, אם מפתח נוצר במכשיר Android שבו מותקן תיקון האבטחה של המערכת מ-5 באוגוסט 2018, הערך הזה יהיה 20180805.
-
deviceUniqueAttestation
-
השדה הזה קיים רק בגרסאות של אימות מפתחות שמספרן גבוה מ-4.
תואם לתג ההרשאה
Tag::DEVICE_UNIQUE_ATTESTATION
, שבו נעשה שימוש בערך מזהה תג של 720. -
attestationIdSecondImei
-
קיים רק בגרסאות אימות (attestation) של מפתח >= 300.
תואם לתג ההרשאה
Tag::ATTESTATION_ID_SECOND_IMEI
, שמשתמש בערך מזהה תג של 723.
שדות RootOfTrust
-
verifiedBootKey
- גיבוב מאובטח של המפתח הציבורי המשמש לאימות התקינות והאותנטיות של כל הקוד שמופעל במהלך אתחול המכשיר, כחלק מהפעלה מאומתת. מומלץ להשתמש ב-SHA-256.
-
deviceLocked
-
האם תוכנת האתחול של המכשיר נעולה. הערך
true
מציין שהמכשיר הפעיל קובץ אימג' חתום שאומת בהצלחה על ידי Verified Boot. -
verifiedBootState
- מצב ההפעלה המאומתת של המכשיר.
-
verifiedBootHash
- סיכום של כל הנתונים שמוגנים על ידי Verified Boot. במכשירים שנעשה בהם שימוש בהטמעה של קובצי העזר הפעלה מאומתת של Android, השדה הזה מכיל את תקציר VBMeta.
ערכים של VerifiedBootState
ערך | מצב האתחול התואם | משמעות |
---|---|---|
Verified |
GREEN |
שרשרת אמון מלאה נמשכת מ-Root of Trust שמוגן בחומרה, דרך מנהל האתחול וכל המחיצות שמאומתות על ידי הפעלה מאומתת.
במצב הזה, השדה verifiedBootKey מכיל את הגיבוב של Root of Trust מוטמע, שהוא האישור שמוטמע ב-ROM של המכשיר על ידי יצרן המכשיר במפעל. |
SelfSigned |
YELLOW |
זהה ל-Verified , מלבד העובדה שהאימות בוצע באמצעות Root of Trust שהוגדר על ידי המשתמש במקום Root of Trust שהוטמע על ידי היצרן במפעל.
במצב הזה, השדה verifiedBootKey מכיל את הגיבוב של המפתח הציבורי שהוגדר על ידי המשתמש. |
Unverified |
ORANGE |
תוכנת האתחול של המכשיר לא נעולה, לכן לא ניתן ליצור שרשרת אמון. ניתן לשנות את המכשיר באופן חופשי, כך שהמשתמשים צריכים לאמת
את תקינות המכשיר מחוץ למסגרת. במצב הזה, השדה verifiedBootKey מכיל 32 בייטים של אפסים. |
Failed |
RED |
האימות של המכשיר נכשל. במצב הזה, אין הבטחות
לגבי התוכן של השדות האחרים של RootOfTrust . |
AttestationApplicationId
השדה הזה משקף את ההנחה של פלטפורמת Android לגבי האפליקציות שמותר להן להשתמש בחומר המפתח הסודי במסגרת האימות. הוא יכול להכיל כמה חבילות רק אם כמה חבילות משתפות את אותו מזהה UID. השדה AttestationApplicationId
ב-AuthorizationList
הוא מסוג OCTET_STRING
והפורמט שלו תואם לסכימה הבאה של ASN.1:
AttestationApplicationId ::= SEQUENCE { package_infos SET OF AttestationPackageInfo, signature_digests SET OF OCTET_STRING, } AttestationPackageInfo ::= SEQUENCE { package_name OCTET_STRING, version INTEGER, }
package_infos
-
קבוצת אובייקטים של
AttestationPackageInfo
, שבכל אחד מהם מופיע שם החבילה ומספר הגרסה. signature_digests
-
קבוצה של סיכומי SHA-256 של אישורי החתימה של האפליקציה. לאפליקציה יכולות להיות כמה שרשראות אישורים של מפתחות חתימה. לכל אחד מהם, האישור מסוג 'עלה' מפורט וממוקם בשדה
signature_digests
. שם השדה מטעה, כי הנתונים המגובבים הם אישורי החתימה של האפליקציה, ולא החתימות של האפליקציה, כי השם שלו נקבע לפי המחלקהSignature
שמוחזרת על ידי קריאה ל-getPackageInfo()
. קטע הקוד הבא מציג קבוצה לדוגמה:{SHA256(PackageInfo.signature[0]), SHA256(PackageInfo.signature[1]), ...}
מזהה ייחודי
המזהה הייחודי הוא ערך של 128 ביט שמזהה את המכשיר, אבל לפרק זמן מוגבל בלבד. הערך מחושב באמצעות:
HMAC_SHA256(T || C || R, HBK)
איפה:
T
הוא 'ערך המונה הזמני', שמחושב על ידי חלוקת הערך שלTag::CREATION_DATETIME
ב-2592000000, בלי שאריות. הערך שלT
משתנה כל 30 יום (2592000000 = 30 * 24 * 60 * 60 * 1000).C
הוא הערך שלTag::APPLICATION_ID
- הערך של
R
הוא 1 אם הערך שלTag::RESET_SINCE_ID_ROTATION
מופיע בפרמטר attest_params בקריאה ל-attest_key, או 0 אם התג לא מופיע. HBK
הוא סוד ייחודי שמקושר לחומרה, שידוע לסביבת המחשוב האמינה (TEE) ושאף פעם לא נחשף על ידה. הסוד מכיל לפחות 128 ביט של אנטרופיה והוא ייחודי למכשיר הספציפי (ייחודיות סטטיסטית מקובלת בהתחשב ב-128 הביט של האנטרופיה). צריך להפיק את ה-HBK מחומר מפתח משולב באמצעות HMAC או AES_CMAC.
חותכים את הפלט של HMAC_SHA256 ל-128 ביטים.
מפתחות ואישורי אימות
שני מפתחות, RSA אחד ו-ECDSA אחד, ושרשראות האישורים התואמות, מוקצים למכשיר באופן מאובטח.
ב-Android 12 הושק השירות Remote Key Provisioning, וב-Android 13 המכשירים חייבים ליישם אותו. להקצאת מפתחות מרחוק יש מכשירים בשדה עם אישורי אימות (attestation) ECDSA P256 לכל אפליקציה. תוקף האישורים האלה קצר יותר מתוקף האישורים שהוקצתה במפעל.
מספרי IMEI מרובים
ב-Android 14 נוספה תמיכה במספר מזהי IMEI ברשומת Android Key Attestation. יצרני ציוד מקורי יכולים להטמיע את התכונה הזו על ידי הוספה של תג KeyMint למספר IMEI שני. יותר ויותר מכשירים עם מספר מכשירי רדיו סלולריים יכולים לתמוך עכשיו במכשירים עם שני מספרי IMEI.
יצרני ציוד מקורי(OEM) צריכים להקצות מספר IMEI משני, אם הוא קיים במכשירים שלהם, להטמעות של KeyMint, כדי שההטמעות האלה יוכלו לאמת אותו באותו אופן שבו הן מאמתות את המספר IMEI הראשון.
אימות זהות
Android 8.0 כולל תמיכה אופציונלית באימות זהויות במכשירים עם Keymaster 3. אימות המזהה מאפשר למכשיר לספק הוכחה למזהי החומרה, כמו מספר סידורי או IMEI. זו תכונה אופציונלית, אבל מומלץ מאוד שכל הטמעות Keymaster 3 יספקו תמיכה בה, כי היכולת להוכיח את זהות המכשיר מאפשרת תרחישים לדוגמה כמו הגדרה מרחוק אמיתית ללא מגע (zero-touch) להיות מאובטחים יותר (כי הצד המרוחק יכול להיות בטוח שהוא מתקשר עם המכשיר הנכון, ולא עם מכשיר שמתחזה לזהות שלו).
אימות הזהות פועל על ידי יצירת עותקים של מזהי החומרה של המכשיר, שרק לסביבת הביצועים המאובטחת (TEE) יש גישה אליהם לפני שהמכשיר יוצא מהמפעל. משתמש יכול לפתוח את נעילת האתחול של המכשיר ולשנות את תוכנת המערכת ואת המזהים שמדווחים על ידי מסגרות Android. אי אפשר לבצע מניפולציה על עותקי המזהים שנשמרים ב-TEE בדרך הזו, וכך מוודאים שאימות מזהה המכשיר יתבצע רק למזהי החומרה המקוריים של המכשיר, וכך אפשר למנוע ניסיונות זיופים.
ממשק ה-API הראשי לאימות הזהות מבוסס על מנגנון האימות הקיים של המפתחות, שהוצג ב-Keymaster 2. כששולחים בקשה לאישור אימות למפתח שנמצא בחזקת keymaster, מבצע הקריאה החוזרת יכול לבקש לכלול את מזהי החומרה של המכשיר במטא-נתונים של אישור האימות. אם המפתח נשמר ב-TEE, האישור מקשר חזרה ל-root of trust ידוע. הנמען של אישור כזה יכול לוודא שהאישור ותוכן שלו, כולל מזהי החומרה, נכתבו על ידי ה-TEE. כשמתבקשים לכלול מזהי חומרה באישור האימות, ה-TEE מאמת רק את המזהים שנשמרים באחסון שלו, כפי שהם מאוכלסים במפעל.
מאפייני אחסון
האחסון שמכיל את מזהי המכשיר צריך לכלול את המאפיינים הבאים:
- הערכים שמתקבלים מהמזהים המקוריים של המכשיר מועתקים לאחסון לפני שהמכשיר יוצא מהמפעל.
- שיטת
destroyAttestationIds()
יכולה להשמיד באופן סופי את העותק הזה של הנתונים שמבוססים על המזהה. 'השמדה סופית' פירושה שהנתונים הוסרו לחלוטין, כך שאין אפשרות לשחזר אותם באמצעות איפוס להגדרות המקוריות או כל תהליך אחר שמתבצע במכשיר. זה חשוב במיוחד במכשירים שבהם משתמש ביטל את הנעילה של תוכנת האתחול, שינה את תוכנת המערכת וגם את המזהים שמוחזרים על ידי frameworks של Android. - למתקני ה-RMA צריכה להיות אפשרות ליצור עותקים חדשים של הנתונים שמבוססים על מזהה החומרה. כך מכשיר שעובר תיקון RMA יכול לבצע שוב אימות זהות. המנגנון שבו משתמשים במתקני RMA צריך להיות מוגן כדי שמשתמשים לא יוכלו להפעיל אותו בעצמם, כי זה יאפשר להם לקבל אימותים של מזהים מזויפים.
- אף קוד מלבד האפליקציה המהימנה של Keymaster ב-TEE לא יכול לקרוא את הנתונים שנגזרים מהמזהה ונשמרים באחסון.
- האחסון מוגן מפני פגיעה: אם התוכן באחסון השתנה, ה-TEE מתייחס אליו כאילו העותקים של התוכן הושמדו, ומסרב לכל ניסיונות האימות של הזהות. כדי לעשות את זה, צריך חתימה או MAC של האחסון כפי שמתואר בהמשך.
- האחסון לא מכיל את המזהים המקוריים. מאחר שתיקוף הזהות כרוך באתגר, מבצע הקריאה תמיד מספק את המזהים שצריך לאמת. צוות ה-TEE צריך רק לוודא שהערכים האלה תואמים לערכים שהיו להם במקור. כדי לבצע את האימות הזה, שומרים גיבוב מאובטח של הערכים המקוריים במקום את הערכים עצמם.
בנייה
כדי ליצור הטמעה עם המאפיינים שצוינו למעלה, שומרים את הערכים שמבוססים על המזהה ביצירה הבאה S. אין לאחסן עותקים אחרים של ערכי המזהים, מלבד במקומות הרגילים במערכת, שבהם הבעלים של המכשיר יכול לשנות אותם באמצעות הרשאת root:
S = D || HMAC(HBK, D)
איפה:
D = HMAC(HBK, ID1) || HMAC(HBK, ID2) || ... || HMAC(HBK, IDn)
HMAC
הוא מבנה ה-HMAC עם גיבוב מאובטח מתאים (מומלץ להשתמש ב-SHA-256)HBK
הוא מפתח שקשור לחומרה ולא משמש לשום מטרה אחרתID1...IDn
הם ערכי המזהה המקוריים. השיוך של ערך מסוים למדד מסוים תלוי בהטמעה, כי למכשירים שונים יש מספרים שונים של מזהים.||
מייצג שרשור
מכיוון שפלטי ה-HMAC הם בגודל קבוע, אין צורך בכותרות או במבנה אחר כדי למצוא גיבובים של מזהים ספציפיים או את ה-HMAC של D. בנוסף לבדיקת הערכים שסופקו כדי לבצע אימות, ההטמעות צריכות לאמת את S על ידי חילוץ D מ-S, חישוב HMAC(HBK, D) והשוואה לערך ב-S כדי לוודא שאף מזהה ספציפי לא השתנה או פגום. בנוסף, בהטמעות צריך להשתמש בהשוואות בזמן אמת לכל רכיבי המזהה הנפרדים ולאימות של S. זמן ההשוואה חייב להיות קבוע, ללא קשר למספר המזהים שסופקו ולתוצאת ההתאמה של כל חלק בבדיקה.
מזהי חומרה
אימות הזהות תומך במזהי החומרה הבאים:
- שם המותג, כפי שהוחזר על ידי
Build.BRAND
ב-Android - שם המכשיר, כפי שהוחזר על ידי
Build.DEVICE
ב-Android - שם המוצר, כפי שהוחזר על ידי
Build.PRODUCT
ב-Android - שם היצרן, כפי שהוחזר על ידי
Build.MANUFACTURER
ב-Android - שם הדגם, כפי שהוחזר על ידי
Build.MODEL
ב-Android - מספר סידורי
- מספרי ה-IMEI של כל מכשירי הרדיו
- MEID של כל מכשירי הרדיו
כדי לתמוך באימות של מזהה המכשיר, המכשיר מאמת את המזהים האלה. בכל המכשירים עם Android יש את 6 הראשונות והם נדרשים כדי שהתכונה תפעל. אם יש במכשיר תדרי רדיו סלולריים משולבים, המכשיר צריך גם לתמוך באימות עם מספרי ה-IMEI ו/או ה-MEID של מכשירי הרדיו.
כדי לבצע אימות זהות, מבצעים אימות מפתח וכוללים בבקשה את מזהי המכשיר לאימות. המזהים מתויגים בתור:
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
.
אם המכשיר תומך באימות (attestation) באמצעות מזהה, ולפחות אחד מהתגים שלמעלה נכלל בבקשת אימות למפתח, ה-TEE מאמת שהמזהה שסופק עם כל אחד מהתגים תואם לעותק של מזהי החומרה שלו. אם מזהה אחד או יותר לא תואם, האימות כולו נכשל עם ErrorCode::CANNOT_ATTEST_IDS
. מותר לספק את אותו תג כמה פעמים. האפשרות הזו יכולה להיות שימושית, למשל, כשמאמתים מספרי IMEI: במכשיר יכולים להיות כמה מכשירי רדיו עם כמה מספרי IMEI. בקשת אימות תקפה אם הערך שצוין בכל ATTESTATION_ID_IMEI
תואם לאחד ממכשירי הרדיו של המכשיר. אותו הדבר חל על כל התגים האחרים.
אם האימות (attestation) מצליח, המזהים המאומתים מתווספים לתוסף האימות (attestation) (OID 1.3.6.1.4.1.11129.2.1.17) של אישור האימות שהונפק, באמצעות הסכימה שלמעלה. השינויים מהסכימה של אימות Keymaster 2 מודגשים בכתב מודגש עם הערות.
Java API
הקטע הזה מיועד למטרות מידע בלבד. מי שמטמיע את Keymaster לא מטמיע את Java API ולא משתמש בו. המידע הזה זמין כדי לעזור למטמיעים להבין איך האפליקציות משתמשות בתכונה. רכיבי המערכת עשויים להשתמש בו בצורה שונה, ולכן חשוב מאוד לא להתייחס לקטע הזה כאל רכיב נורמלי.