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

‏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 היא רשימה של כל הפרמטרים הנדרשים לאימות. למשל, Tag::ATTESTATION_CHALLENGE וייתכן גם Tag::RESET_SINCE_ID_ROTATION, וגם Tag::APPLICATION_ID ו-Tag::APPLICATION_DATA. שני האחרונים נדרשים כדי לפענח את ה-blob של המפתח, אם הם צוינו במהלך יצירת המפתח.
  • certChain הוא פרמטר הפלט, שמחזיר מערך של אישורים. הערך 0 הוא אישור האימות, כלומר הוא מאמת את המפתח מ-keyToAttest ומכיל את התוסף לאימות.

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

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

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

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

SEQUENCE של אישור

שם השדה (ראו 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 זהה לשדה הנושא של מפתח האימות (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 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 יש 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
200KeyMint גרסה 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
200KeyMint גרסה 2.0
300גרסה 3.0 של KeyMint
keymasterSecurityLevel מתוך keyMintSecurityLevel
רמת האבטחה של הטמעת Keymaster/KeyMint.
attestationChallenge
האתגר שסופק בזמן יצירת המפתח.
uniqueId
מזהה מכשיר רגיש לפרטיות שאפליקציות מערכת יכולות לבקש בזמן יצירת המפתח. אם לא מבקשים את המזהה הייחודי, השדה הזה יהיה ריק. פרטים נוספים זמינים בקטע מזהה ייחודי.
softwareEnforced
רשימת ההרשאות של Keymaster/KeyMint שנאכפת על ידי מערכת Android. המידע הזה נאסף או נוצר על ידי קוד בפלטפורמה, ונשמר במחיצה המערכתית של המכשיר. אפשר לסמוך עליו כל עוד פועלת במכשיר מערכת הפעלה שתואמת למודל האבטחה של פלטפורמת Android (כלומר, תוכנת האתחול של המכשיר נעולה ו-verifiedBootState הוא Verified).
hardwareEnforced
רשימת ההרשאות של Keymaster/KeyMint, שמופעל על ידי סביבת המחשוב המאובטחת (TEE) או על ידי StrongBox של המכשיר. המידע הזה נאסף או נוצר על ידי קוד בחומרה המאובטחת, והפלטפורמה לא שולטת בו. לדוגמה, המידע יכול להגיע מה-bootloader או דרך ערוץ תקשורת מאובטח שלא מחייב אמון בפלטפורמה.

ערכים של SecurityLevel

הערך של 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 של אימות, הערך של האלגוריתם הוא תמיד 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

השדה הזה קיים רק בגרסה 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

השדה הזה קיים רק בגרסאות של אימות מפתחות שמספרן גבוה מ-2.

תואם לתג Keymaster‏ Tag::ATTESTATION_ID_SERIAL, שמשתמש בערך מזהה תג של 713.

attestationIdImei

השדה הזה קיים רק בגרסאות של אימות מפתחות שמספרן גבוה מ-2.

תואם לתג ההרשאה Tag::ATTESTATION_ID_IMEI, שמשתמש בערך מזהה תג של 714.

attestationIdMeid

השדה הזה קיים רק בגרסאות של אימות מפתחות שמספרן גבוה מ-2.

תואם לתג ההרשאה Tag::ATTESTATION_ID_MEID, שמשתמש בערך מזהה תג של 715.

attestationIdManufacturer

השדה הזה קיים רק בגרסאות של אימות מפתחות שמספרן גבוה מ-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

השדה הזה קיים רק בגרסאות של אימות מפתחות שמספרן גבוה מ-300.

תואם לתג ההרשאה Tag::ATTESTATION_ID_SECOND_IMEI, שמשתמש בערך מזהה תג של 723.

שדות RootOfTrust

verifiedBootKey
גיבוב מאובטח של המפתח הציבורי המשמש לאימות התקינות והאותנטיות של כל הקוד שמופעל במהלך אתחול המכשיר, כחלק מהאתחול המאומת. מומלץ להשתמש ב-SHA-256.
deviceLocked
אם תוכנת האתחול של המכשיר נעולה. הערך true מציין שהמכשיר הפעיל קובץ אימג' חתום שאומת בהצלחה על ידי Verified Boot.
verifiedBootState
מצב ההפעלה המאומתת של המכשיר.
verifiedBootHash
סיכום של כל הנתונים שמוגנים על ידי Verified Boot. במכשירים שמשתמשים בהטמעה של Android Verified Boot, השדה הזה מכיל את ה-digest של 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 האימות של המכשיר נכשל. במצב כזה, אין garanties על התוכן של שדות 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 המכשירים חייבים ליישם אותו. שירות הקצאת מפתחות מרחוק מספק למכשירים בשטח אישורי אימות ECDSA P256 לכל אפליקציה. תוקף האישורים האלה קצר יותר מתוקף האישורים שהוקצתה במפעל.

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

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

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

תוסף של פרטי הקצאה

למפַתח של פרטי הקצאת ההרשאות יש OID‏ 1.3.6.1.4.1.11129.2.1.30. התוסף מספק מידע על המכשיר שידוע לשרת ההקצאה.

סכימה

התוסף עומד בהסכימה הבאה של CDDL:

  {
        1 : int,   ; certificates issued
  }

המפה לא מחולקת לגרסאות, וניתן להוסיף לה שדות אופציונליים חדשים.

certs_issued

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

אימות זהות

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

מזהי חומרה

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

  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.

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