Keystore הוא מקום מאובטח יותר ליצירה, לאחסון ולשימוש במפתחות קריפטוגרפיים באופן מבוקר. כשאחסון מפתחות מבוסס-חומרה זמין ומשומש, חומר המפתחות מאובטח יותר מפני חילוץ מהמכשיר, ו-Keymaster אוכף הגבלות שקשה לעקוף.
עם זאת, זה נכון רק אם ידוע שהמפתחות של מאגר המפתחות נמצאים באחסון שמבוסס על חומרה. ב-Keymaster 1 לא הייתה לאפליקציות או לשרתים מרוחקים אפשרות לאמת בצורה מהימנה אם זה המצב. הדימון של מאגר המפתחות טען את HAL של Keymaster שזמין, והאמין לכל מה ש-HAL אמר לגבי גיבוי המפתחות בחומרה.
כדי לפתור את הבעיה הזו, הוספנו ל-Keymaster את אימות המפתחות ב-Android 7.0 (Keymaster 2) ואת אימות הזהויות ב-Android 8.0 (Keymaster 3).
מטרת האימות של מפתחות היא לספק דרך לקבוע באופן חזק אם צמד מפתחות אסימטרי נתמך בחומרה, מהם המאפיינים של המפתח ואילו אילוצים חלים על השימוש בו.
אימות הזהות מאפשר למכשיר לספק הוכחה למזהי החומרה שלו, כמו המספר הסידורי או ה-IMEI.
אימות עם מפתח
כדי לתמוך באימות מפתחות, ב-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
הוא רשימה של הפרמטרים שדרושים לאימות (attestation). למשל,Tag::ATTESTATION_CHALLENGE
וייתכן גםTag::RESET_SINCE_ID_ROTATION
, וגםTag::APPLICATION_ID
ו-Tag::APPLICATION_DATA
. שני האחרונים נדרשים כדי לפענח את ה-blob של המפתח, אם הם צוינו במהלך יצירת המפתח.certChain
הוא פרמטר הפלט, שמחזיר מערך של אישורים. הערך 0 הוא אישור האימות, כלומר הוא מאמת את המפתח מ-keyToAttest
ומכיל את התוסף לאימות.
השיטה attestKey
נחשבת לפעולה של מפתח ציבורי על המפתח המאומת, כי אפשר להפעיל אותה בכל שלב והיא לא צריכה לעמוד באילוצים של הרשאה. לדוגמה, אם המפתח המאומת מחייב אימות משתמש לשימוש, אפשר ליצור אימות בלי אימות משתמש.
אישור אימות (attestation)
אישור האימות הוא אישור X.509 רגיל, עם תוסף אימות אופציונלי שמכיל תיאור של המפתח המאומת. האישור חתום באמצעות מפתח אימות (attestation) מאושר. יכול להיות שמפתח האימות ישתמש באלגוריתם שונה מזה של המפתח שעליו מתבצע האימות.
אישור האימות מכיל את השדות שמפורטים בטבלה שלמטה, ואי אפשר לכלול בו שדות נוספים. בחלק מהשדות מצוין ערך קבוע בשדה. בדיקות CTS מאמתות שתוכן האישור זהה לתוכן שהוגדר.
SEQUENCE של אישור
שם השדה (ראו RFC 5280) | ערך |
---|---|
tbsCertificate | TBSCertificate SEQUENCE |
signatureAlgorithm | מזהה האלגוריתם שמשמש לחתימה על המפתח: ECDSA למפתחות EC, RSA למפתחות RSA. |
signatureValue | BIT string, חתימה שמחושבת ב-tbsCertificate בקידוד ASN.1 DER. |
TBSCertificate SEQUENCE
שם השדה (ראו 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' (ערך קבוע: זהה בכל האישורים) |
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 של רצף האימות. |
תוסף אימות (attestation)
התוסף attestation
מכיל תיאור מלא של ההרשאות של keymaster המשויכות למפתח, במבנה שתואם ישירות לרשימות ההרשאות שבשימוש ב-Android וב-HAL של keymaster. כל תג ברשימת הרשאות מיוצג על ידי רשומת SEQUENCE
של ASN.1, שמתויגת במפורש במספר תג המאסטר, אבל באופן מוסווה את מתאר הסוג (ארבעה ביטים בסדר גבוה).
לדוגמה, ב-Keymaster 3, הערך Tag::PURPOSE
מוגדר ב-types.hal בתור ENUM_REP | 1
. בהרחבה לאימות, הערך ENUM_REP
מוסר ומתקבל רק התג 1
.
(ב-Keymaster 2 ומטה, KM_TAG_PURPOSE
מוגדר ב-keymaster_defs.h.)
הערכים מתורגמים באופן ישיר לסוגי ASN.1, בהתאם לטבלה הבאה:
סוג Keymaster | סוג ASN.1 |
---|---|
ENUM |
מספר שלם |
ENUM_REP |
קבוצה של מספרים שלמים |
UINT |
מספר שלם |
UINT_REP |
קבוצה של מספרים שלמים |
ULONG |
מספר שלם |
ULONG_REP |
קבוצה של מספרים שלמים |
DATE |
INTEGER (מילישניות מ-1 בינואר 1970 00:00:00 GMT) |
BOOL |
NULL (במנהל המפתחות, המשמעות של תג נוכחי היא True, 'חסר' פירושו 'לא נכון'. אותה סמנטיקה חלה על הקידוד ASN.1) |
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
השדות keymasterVersion
ו-attestationChallenge
מזוהים לפי מיקום ולא לפי תג, כך שהתגים בטופס המקודד מציינים רק את סוג השדה. שאר השדות מתויגים באופן משתמע כפי שצוין בסכימה.
שם השדה | סוג | ערך |
---|---|---|
attestationVersion |
מספר שלם | הגרסה של הסכימה לאימות: 1, 2 או 3. |
attestationSecurity |
SecurityLevel | רמת האבטחה של האימות הזה. אפשר לקבל אימותי תוכנה (attestation) של תוכנות של מפתחות שמגובים בחומרה. אי אפשר לסמוך על אימותים כאלה אם מערכת Android נפרצה. |
keymasterVersion |
מספר שלם | הגרסה של מכשיר Keymaster: 0, 1, 2, 3 או 4. |
keymasterSecurity |
SecurityLevel | רמת האבטחה של הטמעת Keymaster. |
attestationChallenge |
OCTET_STRING | הערך של Tag::ATTESTATION_CHALLENGE שצוין בבקשת האימות. |
uniqueId |
OCTET_STRING | מזהה ייחודי אופציונלי, מופיע אם המפתח מכיל את הערך Tag::INCLUDE_UNIQUE_ID |
softwareEnforced |
AuthorizationList | הרשאות אופציונליות של Keymaster שלא נאכפות על ידי ה-TEE, אם יש כאלה. |
teeEnforced |
AuthorizationList | אופציונלי, הרשאות Keymaster שנאכפות על ידי ה-TEE, אם יש כאלה. |
שדות של AuthorizationList
כל השדות של AuthorizationList
הם אופציונליים ומזוהים לפי ערך התג של keymaster, כאשר ביט הסווג מוסתר.
נעשה שימוש בתיוג מפורש כך שהשדות מכילים גם תג שמציין את סוג ה-ASN.1 שלהם, לניתוח קל יותר.
פרטים על הערכים של כל שדה זמינים במאמר types.hal
לגבי Keymaster 3, ובמאמר keymaster_defs.h
לגבי Keymaster 2 ואילך. שמות התגים של Keymaster הוסבו לשמות שדות על ידי השמטת הקידומת KM_TAG
ושינוי החלק הנותר ל-camel case, כך ש-Tag::KEY_SIZE
הפך ל-keySize
.
שדות RootOfTrust
השדות RootOfTrust
מזוהים במיקום.
שם השדה | סוג | ערך |
---|---|---|
verifiedBootKey |
OCTET_STRING | גיבוב מאובטח של המפתח שמשמש לאימות קובץ האימג' של המערכת. מומלץ להשתמש ב-SHA-256. |
deviceLocked |
בוליאני | הערך True מופיע אם מנהל האתחול נעול, כלומר אפשר להריץ רק אימג'ים חתמומים, והבדיקה של ההפעלה המאומתת בוצעה. |
verifiedBootState |
VerifyBootState | מצב ההפעלה המאומתת. |
verifiedBootHash |
OCTET_STRING | סיכום של כל הנתונים שמוגנים על ידי Verified Boot. במכשירים שמשתמשים בהטמעה של Android Verified Boot לאתחול מאומת, הערך הזה מכיל את הסיכום של המבנה VBMeta או את מבנה המטא-נתונים של אתחול מאומת. מידע נוסף על אופן החישוב של הערך הזה זמין במאמר The VBMeta Digest |
ערכים של VerifiedBootState
הערכים של verifiedBootState
הם:
ערך | משמעות |
---|---|
Verified |
מציין שרשרת אמון מלאה שמתחילה מתוכנת האתחול וממשיכה למחיצות מאומתות, כולל תוכנת האתחול, מחיצת האתחול וכל המחיצות המאומתות. במצב הזה, הערך של verifiedBootKey הוא הגיבוב של האישור המוטמע, כלומר האישור שלא ניתן לשינוי שנצרב ב-ROM.המצב הזה תואם למצב האתחול הירוק שמתואר במסמכים של תהליך האתחול המאומת. |
SelfSigned |
המשמעות היא שחומת האתחול אומתה באמצעות האישור המוטמע, והחתימת תקינה. מנהל האתחול מציג אזהרה ואת טביעת האצבע של המפתח הציבורי לפני שהוא מאפשר להמשיך בתהליך האתחול.
במצב הזה, הערך verifiedBootKey הוא הגיבוב של אישור החתימה העצמית.המצב הזה תואם למצב ההפעלה צהוב כפי שמתועד במסמכי התיעוד של תהליך האתחול המאומת. |
Unverified |
מציין שאפשר לשנות את המכשיר באופן חופשי. תקינות המכשיר נשארת למשתמש כדי לבצע אימות מחוץ למסגרת. תוכנת האתחול מציגה אזהרה למשתמש לפני שהיא מאפשרת להמשיך בתהליך האתחול. במצב הזה, הערך של verifiedBootKey ריק.המצב הזה תואם למצב ההפעלה כתום שמתואר במסמכים של תהליך ההפעלה המאומתת. |
Failed |
מציין שהאימות של המכשיר נכשל. אף אישור אימות לא מכיל את הערך הזה, כי במצב הזה מנהל האתחול מושהה. היא מופיעה כאן כדי לשמור על שלמותה. המצב הזה תואם למצב ההפעלה האדום כמו שמתואר במאמרי העזרה של תהליך האתחול המאומת. |
ערכים של SecurityLevel
הערכים של securityLevel
הם:
ערך | משמעות |
---|---|
Software |
הקוד שיוצר או מנהל את הרכיב הרלוונטי (אימות או מפתח) מוטמע במערכת Android, ויכול להשתנות אם המערכת נפרצה. |
TrustedEnvironment |
הקוד שיוצר או מנהל את הרכיב הרלוונטי (אימות או מפתח) מוטמע בסביבת מחשוב אמינה (TEE). ניתן לשנות אותו אם מכשיר ה-TEE נפגע, אבל הוא עמיד מאוד בפני פריצה מרחוק ועמיד באופן מתון לפריצה באמצעות התקפת חומרה ישירה. |
StrongBox |
הקוד שיוצר או מנהל את הרכיב הרלוונטי (אימות או מפתח) מוטמע במודול ייעודי לאבטחת חומרה. הוא יכול להשתנות אם מודול האבטחה של החומרה נפרץ, אבל הוא עמיד מאוד בפני פריצה מרחוק ועמיד מאוד בפני פריצה באמצעות התקפת חומרה ישירה. |
מזהה ייחודי
המזהה הייחודי הוא ערך של 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 המכשירים חייבים ליישם אותו. שירות הקצאת מפתחות מרחוק מספק למכשירים בשטח אישורי אימות ECDSA P256 לכל אפליקציה. תוקף האישורים האלה קצר יותר מתוקף האישורים שהוקצתה במפעל.
מספרי IMEI מרובים
ב-Android 14 נוספה תמיכה במספר מספרי IMEI ברשומת האימות של מפְתח של Android. יצרני ציוד מקורי יכולים להטמיע את התכונה הזו על ידי הוספת תג KeyMint למספר IMEI שני. יותר ויותר מכשירים כוללים כמה מכשירי רדיו סלולריים, ו-OEM יכולים עכשיו לתמוך במכשירים עם שני מספרי IMEI.
יצרני ציוד מקורי(OEM) צריכים להקצות מספר IMEI משני, אם הוא קיים במכשירים שלהם, להטמעות של KeyMint, כדי שההטמעות האלה יוכלו לאמת אותו באותו אופן שבו הן מאמתות את המספר IMEI הראשון.
אימות זהות
מערכת Android 8.0 כוללת תמיכה אופציונלית באימות (attestation) של מזהה במכשירים עם Keymaster 3. אימות הזהות מאפשר למכשיר לספק הוכחה למזהי החומרה שלו, כמו המספר הסידורי או ה-IMEI. זו תכונה אופציונלית, אבל מומלץ מאוד שכל הטמעות Keymaster 3 יספקו תמיכה בה, כי היכולת להוכיח את זהות המכשיר מאפשרת תרחישים לדוגמה כמו הגדרה מרחוק אמיתית ללא מגע (zero-touch) להיות מאובטחים יותר (כי הצד המרוחק יכול להיות בטוח שהוא מתקשר עם המכשיר הנכון, ולא עם מכשיר שמתחזה לזהות שלו).
אימות הזהות פועל על ידי יצירת עותקים של מזהי החומרה של המכשיר, שרק לסביבת הביצועים המאובטחת (TEE) יש גישה אליהם לפני שהמכשיר יוצא מהמפעל. משתמש יכול לפתוח את נעילת האתחול של המכשיר ולשנות את תוכנת המערכת ואת המזהים שמדווחים על ידי מסגרות Android. אי אפשר לבצע מניפולציה על עותקי המזהים שנשמרים ב-TEE בדרך הזו, וכך מוודאים שאימות מזהה המכשיר יתבצע רק למזהי החומרה המקוריים של המכשיר, וכך אפשר למנוע ניסיונות זיופים.
ממשק ה-API הראשי לאימות הזהות מבוסס על מנגנון האימות הקיים של המפתחות, שהוצג ב-Keymaster 2. כשמבקשים אישור אימות למפתח שנמצא ב-keymaster, מבצע הקריאה החוזרת יכול לבקש שמזהי החומרה של המכשיר ייכללו במטא-נתונים של אישור האימות. אם המפתח נשמר ב-TEE, האישור מקשר חזרה ל-root of trust ידוע. הנמען של אישור כזה יכול לוודא שהאישור ותוכן שלו, כולל מזהי החומרה, נכתבו על ידי ה-TEE. כשמתבקשים לכלול מזהי חומרה באישור האימות, ה-TEE מאמת רק את המזהים שנשמרים באחסון שלו, כפי שהם מאוכלסים במפעל.
מאפייני האחסון
לאחסון שמכיל את המזהים של המכשיר צריכים להיות המאפיינים הבאים:
- הערכים שמתקבלים מהמזהים המקוריים של המכשיר מועתקים לאחסון לפני שהמכשיר יוצא מהמפעל.
- שיטת
destroyAttestationIds()
יכולה להשמיד באופן סופי את העותק הזה של הנתונים שמבוססים על המזהה. הרס קבוע פירושו שהנתונים יוסרו לחלוטין, כך שלא ניתן יהיה לשחזר אותם באמצעות איפוס להגדרות המקוריות וכל תהליך אחר שמבוצע במכשיר. זה חשוב במיוחד במכשירים שבהם משתמש נעל את מנהל האתחול ושינה את תוכנת המערכת ושינה את המזהים שמוחזרים על ידי מסגרות 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 כוללים את ששת הרכיבים הראשונים, והם נחוצים כדי שהתכונה הזו תפעל. אם יש במכשיר תדרי רדיו סלולריים משולבים, המכשיר צריך גם לתמוך באימות עם מספרי ה-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
.
אם המכשיר תומך באימות זהויות, ושהתוויות שלמעלה כלולות בבקשה לאימות מפתח, ה-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 ולא משתמש בו. המידע הזה עוזר להטמעה להבין איך אפליקציות משתמשות בתכונה. רכיבי המערכת עשויים להשתמש בו בצורה שונה, ולכן חשוב מאוד לא להתייחס לקטע הזה כאל רכיב נורמלי.