אימות (attestation) של מפתחות ומזהים

‏Keystore הוא מקום מאובטח יותר ליצירה, לאחסון ולשימוש במפתחות קריפטוגרפיים באופן מבוקר. כשאחסון מפתחות מבוסס-חומרה זמין ומשומש, חומר המפתחות מאובטח יותר מפני חילוץ מהמכשיר, ו-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 ומכיל את התוסף לאימות.

השיטה attestKey נחשבת לפעולה של מפתח ציבורי על המפתח המאומת, כי אפשר להפעיל אותה בכל שלב והיא לא צריכה לעמוד באילוצים של הרשאה. לדוגמה, אם צריך לאמת את המשתמש כדי להשתמש במפתח המאומת, אפשר ליצור אימות ללא אימות המשתמש.

אישור אימות (attestation)

אישור האימות הוא אישור X.509 סטנדרטי, עם תוסף אימות (attestation) אופציונלי שמכיל תיאור של המפתח המאומת. האישור חתום באמצעות מפתח אימות מאושר. יכול להיות שמפתח האימות ישתמש באלגוריתם שונה מזה של המפתח שעליו מתבצע האימות.

אישור האימות מכיל את השדות שמפורטים בטבלה שלמטה, ואי אפשר לכלול בו שדות נוספים. בשדות מסוימים מצוין ערך שדה קבוע. בדיקות CTS מאמתות שתוכן האישור בדיוק כפי שהוגדר.

רצף אישור

שם השדה (ראו RFC 5280) ערך
tbsCertificate TBSCertificate SEQUENCE
signatureAlgorithm מזהה האלגוריתם שמשמש לחתימה על המפתח:
ECDSA למפתחות EC, ‏ RSA למפתחות RSA.
signatureValue מחרוזת ביט, חתימה שמחושבת על tbsCertificate בקידוד ASN.1 DER.

TBSCertificate SEQUENCE

שם השדה (ראו RFC 5280) ערך
version INTEGER 2 (המשמעות היא אישור v3)
serialNumber INTEGER 1 (ערך קבוע: זהה בכל האישורים)
signature AlgorithmIdentifier של האלגוריתם שמשמש לחתימה על המפתח: ECDSA למפתחות EC,‏ RSA למפתחות RSA.
issuer זהה לשדה הנושא של מפתח האימות באצווה.
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 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. בתוסף האימות (attestation), מסירים את הערך 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 (ב-keymaster, אם התג קיים, הערך הוא true, ואם הוא חסר, הערך הוא false.
אותם סמנטיקה חלים על קידוד 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 רמת האבטחה של האימות הזה. אפשר לקבל אימות תוכנה של מפתחות שמגובים בחומרה. אי אפשר לסמוך על אימותים כאלה אם מערכת 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 VerifiedBootState מצב ההפעלה המאומתת.
verifiedBootHash OCTET_STRING סיכום של כל הנתונים שמוגנים על ידי Verified Boot. במכשירים שמשתמשים בהטמעה של Android Verified Boot לאתחול מאומת, הערך הזה מכיל את הסיכום של המבנה VBMeta או את מבנה המטא-נתונים של אתחול מאומת. למידע נוסף על אופן חישוב הערך הזה, אפשר לעיין ב-The VBMeta Digest

ערכים של VerifiedBootState

הערכים של verifiedBootState הם:

ערך משמעות
Verified מציין שרשרת אמון מלאה שמגיעה מתוכנת האתחול למחיצות מאומתות, כולל תוכנת האתחול, מחיצת האתחול וכל המחיצות המאומתות.
במצב הזה, הערך verifiedBootKey הוא הגיבוב של האישור המוטמע, כלומר האישור שלא ניתן לשינוי צרב ב-ROM.
המצב הזה תואם למצב האתחול הירוק שמתואר במסמכים של תהליך האתחול המאומת.
SelfSigned מציין שמחיצת האתחול אומתה באמצעות האישור המוטמע, ושהחתימה חוקית. מנהל האתחול מציג אזהרה ואת טביעת האצבע של המפתח הציבורי לפני שהוא מאפשר להמשיך בתהליך האתחול.
במצב הזה, הערך של verifiedBootKey הוא הגיבוב של האישור החתום בחתימה עצמית.
המצב הזה תואם למצב האתחול צהוב שמתואר במסמכים של תהליך האתחול המאומת.
Unverified מציין שאפשר לשנות את המכשיר באופן חופשי. התקינות של המכשיר נותרת למשתמש לאמת מחוץ למסגרת. תוכנת האתחול מציגה אזהרה למשתמש לפני שהיא מאפשרת להמשיך בתהליך האתחול.
במצב הזה, הערך של verifiedBootKey ריק.
המצב הזה תואם למצב ההפעלה כתום כפי שמתועד במסמכי התיעוד של תהליך האתחול המאומת.
Failed הסמל הזה מציין שהמכשיר נכשל באימות. אף אישור אימות לא מכיל את הערך הזה, כי במצב הזה מנהל האתחול מושהה. היא מופיעה כאן כדי לשמור על שלמותה.
המצב הזה תואם למצב האתחול אדום שמתואר במסמכים של תהליך האתחול המאומת.

ערכים של רמת אבטחה

הערכים של securityLevel הם:

ערך משמעות
Software הקוד שיוצר או מנהל את הרכיב הרלוונטי (אימות או מפתח) מוטמע במערכת Android, ויכול להשתנות אם המערכת נפרצה.
TrustedEnvironment הקוד שיוצר או מנהל את הרכיב הרלוונטי (אימות או מפתח) מוטמע בסביבת מחשוב אמינה (TEE). הוא עלול להשתנות אם 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 הוא סוד ייחודי שקשור לחומרה, וידוע לסביבת הביצוע המהימנה ואף פעם לא נחשף. הסוד מכיל לפחות 128 ביט של אנטרופיה והוא ייחודי למכשיר הספציפי (ייחודיות סטטיסטית מקובלת בהתחשב ב-128 הביט של האנטרופיה). צריך להפיק את ה-HBK מחומר מפתח משולב באמצעות HMAC או AES_CMAC.

חותכים את הפלט של HMAC_SHA256 ל-128 ביטים.

מפתחות ואישורים של אימות (attestation)

שני מפתחות, אחד של RSA ו-ECDSA אחד, ושרשראות האישורים המתאימות, מוקצים באופן מאובטח במכשיר.

ב-Android 12 חדש: הקצאת מפתחות מרחוק, וכדי להשתמש ב-Android 13 צריך להטמיע את התכונה במכשירים. להקצאת מפתחות מרחוק יש מכשירים בשדה עם אישורי אימות (attestation) ECDSA P256 לכל אפליקציה. התוקף של האישורים האלה קצר יותר מהאישורים שהוקצו על ידי היצרן.

מספרי IMEI מרובים

ב-Android 14 נוספה תמיכה במספר מזהי IMEI ברשומת Android Key Attestation. יצרני ציוד מקורי יכולים להטמיע את התכונה הזו על ידי הוספת תג KeyMint למספר IMEI שני. יותר ויותר מכשירים עם מספר מכשירי רדיו סלולריים יכולים לתמוך עכשיו במכשירים עם שני מספרי IMEI.

ליצרני ציוד מקורי(OEM) צריך להיות מספר IMEI משני, אם הוא קיים במכשירים שלהם, ולהקצות אותם להטמעות KeyMint כדי שההטמעות האלה יוכלו לאמת זאת באותו אופן שבו הם מאמתים את ה-IMEI הראשון

אימות זהות

מערכת Android 8.0 כוללת תמיכה אופציונלית באימות (attestation) של מזהה במכשירים עם Keymaster 3. אימות הזהות מאפשר למכשיר לספק הוכחה למזהי החומרה שלו, כמו המספר הסידורי או ה-IMEI. זו תכונה אופציונלית, אבל מומלץ מאוד שכל הטמעות Keymaster 3 יספקו תמיכה בה, כי היכולת להוכיח את זהות המכשיר מאפשרת תרחישים לדוגמה כמו הגדרה מרחוק אמיתית ללא מגע (zero-touch) להיות מאובטחים יותר (כי הצד המרוחק יכול להיות בטוח שהוא מתקשר עם המכשיר הנכון, ולא עם מכשיר שמתחזה לזהות שלו).

אימות הזהות פועל על ידי יצירת עותקים של מזהי החומרה של המכשיר, שרק לסביבת הביצועים המאובטחת (TEE) יש גישה אליהם לפני שהמכשיר יוצא מהמפעל. המשתמש יכול לבטל את הנעילה של תוכנת האתחול של המכשיר ולשנות את תוכנת המערכת ואת המזהים שדווחו על ידי frameworks של 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. זמן ההשוואה חייב להיות קבוע, ללא קשר למספר המזהים שסופקו ולתוצאת ההתאמה של כל חלק בבדיקה.

מזהי חומרה

אימות הזהות תומך במזהי החומרה הבאים:

  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 של מכשירי הרדיו.

אימות המזהה מתבצע על ידי ביצוע אימות עם מפתח שכולל את מזהי המכשיר לצורך אימות בבקשה. המזהים מתויגים בתור:

  • 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.

אם המכשיר לא תומך באימות (attestation) באמצעות מזהה (או שכבר בוצעה קריאה ל-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 ולא משתמש בו. המידע הזה זמין כדי לעזור למטמיעים להבין איך האפליקציות משתמשות בתכונה. רכיבי המערכת עשויים להשתמש בו בצורה שונה, ולכן חשוב מאוד לא להתייחס לקטע הזה כאל רכיב נורמלי.