אימות עם מפתחות ומזהים

Keystore מספק מקום מאובטח יותר ליצירה, לאחסון ולשימוש בתוכן קריפטוגרפי באופן מבוקר. כשזמין אחסון מפתחות שמגובה באמצעות חומרה חומר המפתח מאובטח יותר מפני חילוץ מהמכשיר. Keymaster אוכפת הגבלות שקשה לשנות.

עם זאת, זה נכון רק אם ידוע שהמפתחות של מאגר המפתחות נמצאים אחסון שמגובה בחומרה. ב-Keymaster 1, לא הייתה דרך לאפליקציות או שרתים מרוחקים כדי לאמת בצורה אמינה אם זה המצב. הדימון (daemon) של מאגר המפתחות טען את HAL הזמין ב-Keymaster, והאמין מה שה-HAL אמר ביחס לגיבוי חומרה של מפתחות.

כדי לפתור את הבעיה, Keymaster השיק אימות מפתחות (attestation) ב-Android 7.0 (Keymaster 2) וב-ID אימות (attestation) ב-Android 8.0 (Keymaster 3).

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

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

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

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

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

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

רצף אישור

שם השדה (מידע נוסף זמין כאן: RFC 5280) ערך
tbsCertificate TBSCertificate SEQUENCE
signatureAlgorithm אלגוריתם של אלגוריתם המשמש לחתימה על מפתח:
ECDSA למפתחות EC ו-RSA למפתחות RSA.
signatureValue BIT string, חתימה שמחושבת ב-tbsCertificate ASN.1 DER.

רצף TBSCertificate

שם השדה (מידע נוסף זמין כאן: RFC 5280) ערך
version INTEGER 2 (פירוש הדבר הוא אישור v3)
serialNumber INTEGER 1 (ערך קבוע: זהה בכל האישורים)
signature אלגוריתם המזהה של האלגוריתם המשמש לחתימה על המפתח: ECDSA למפתחות EC, RSA למפתחות RSA.
issuer זהה לשדה הנושא של מפתח האימות באצווה.
validity רצף של שני תאריכים, שמכילים את הערכים של תג::ACTIVE_DATETIME ו Tag::USAGE_DFP_DATETIME. הערכים האלה נמצאים באלפיות שנייה מאז 1 בינואר 1970. מידע נכון מופיע ב-RFC 5280 התאריך המוצג באישורים.
אם Tag::ACTIVE_DATETIME לא קיים, צריך להשתמש בערך של Tag::CREATION_DATETIME. אם המיקום Tag::USAGE_EXPIRE_DATETIME לא נמצא, יש להשתמש בתאריך התפוגה התאריך של האישור של מפתח האימות באצווה.
subject CN = "מפתח Android Keystore" (ערך קבוע: זהה בכל האישורים)
subjectPublicKeyInfo SubjectPublicKeyInfo שמכיל מפתח ציבורי מאומת.
extensions/Key Usage חתימה דיגיטלית: מוגדרת אם למפתח יש מטרה KeyPurpose::SIGN או KeyPurpose::VERIFY. כל שאר הביטים לא הוגדרו.
extensions/CRL Distribution Points טרם נקבע הערך
extensions/"attestation" ה-OID הוא 1.3.6.1.4.1.11129.2.1.17; התוכן מוגדר בקטע 'תוספים לאימות (attestation)' שבהמשך. כמו בכל הפעולות תוספי אישור X.509, התוכן מיוצג בתור OCTET_STRING שמכיל קידוד DER של האימות SEQUENCE.

תוסף אימות (attestation)

התוסף attestation מכיל תיאור מלא של מנהל המפתח הרשאות המשויכות למפתח, במבנה שמתאים באופן ישיר לרשימות ההרשאות כמו ב-Android וב-Keymaster HAL. כל תג ב- רשימת הרשאות מיוצגת על ידי SEQUENCE ASN.1 ערך מפורש מתויגת באמצעות מספר תג Keymaster, אבל עם מתאר הסוג (ארבעה גדלים התממה של כל הזמנה).

לדוגמה, ב-Keymaster 3, Tag::PURPOSE מוגדר ב- type.hal בתור ENUM_REP | 1. לתוסף האימות, הערך ENUM_REP הוסר, והתג 1 נשאר. (ב-Keymaster 2 ומטה, KM_TAG_PURPOSE מוגדר ב- keymaster_defs.h.)

הערכים מתורגמים באופן פשוט לסוגי ASN.1, לפי הטבלה הבאה:

סוג מאסטר מפתח סוג 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 הבאה.

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

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

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

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

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

שדות KeyDescription

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

שם השדה סוג ערך
attestationVersion מספר שלם גרסה של סכימת האימות (attestation): 1, 2 או 3.
attestationSecurity רמת אבטחה רמת האבטחה של האימות (attestation). אפשר לקבל תוכנות אימותים (attestation) של מפתחות שמגובים בחומרה. לא ניתן להסתמך על אימותים כאלה אם מערכת Android נפגעה.
keymasterVersion מספר שלם הגרסה של מכשיר Keymaster: 0, 1, 2, 3 או 4.
keymasterSecurity רמת אבטחה רמת האבטחה של הטמעת Keymaster.
attestationChallenge OCTET_STRING הערך של Tag::ATTESTATION_CHALLENGE, מצוין בבקשת האימות.
uniqueId OCTET_STRING מזהה ייחודי אופציונלי, מוצג אם למפתח יש Tag::INCLUDE_UNIQUE_ID
softwareEnforced רשימת הרשאות אופציונלי: הרשאות Keymaster שאינן נאכפות על ידי ה-TEE, אם כלשהו.
teeEnforced רשימת הרשאות אופציונלי, הרשאות Keymaster שנאכפות על ידי ה-TEE, אם יש כאלה.

השדות של AuthorizationList

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

לפרטים על הערכים של כל שדה, אפשר לעיין ב-types.hal ל-Keymaster 3 ול- keymaster_defs.h ל-Keymaster 2 ומטה. שמות של תגי Keymaster הומרו לשמות של שדות על ידי השמטת KM_TAG ומשנה את הקידומת והשארית למקרים של גמלים, כך ש-Tag::KEY_SIZE הפך keySize.

שדות RootOfTrust

השדות RootOfTrust מזוהים במיקום.

שם השדה סוג ערך
verifiedBootKey OCTET_STRING גיבוב (hash) מאובטח של המפתח שמשמש לאימות תמונת המערכת. אלגוריתם SHA-256 מומלץ.
deviceLocked בוליאני הערך הוא True אם תוכנת האתחול נעולה, כלומר, רק תמונות חתומות להבהב, ובדיקת האתחול המאומתת הסתיימה.
verifiedBootState VerifyBootState מצב ההפעלה המאומתת.
verifiedBootHash OCTET_STRING תקציר של כל הנתונים שמוגנים על ידי 'הפעלה מאומתת'. במכשירים שמשתמשים בהם הטמעת האתחול המאומת של Android של 'הפעלה מאומתת', הערך הזה מכיל את התקציר של מבנה VBMeta או ההפעלה המאומתת של מטא-נתונים. כדי לקבל מידע נוסף על אופן חישוב הערך הזה, אפשר לעיין במאמר תקציר VBMeta

ערכי VerifyBootState

לערכים של verifiedBootState יש את המשמעויות הבאות:

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

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

לערכים של 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 * 1,000).
  • 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 ביט.

מפתחות אימות וגם אישורים

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

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

מספר מספרי IMEI

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

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

אימות (attestation) באמצעות תעודה מזהה

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

האימות (attestation) באמצעות מזהה יוצר עותקים של מזהי החומרה של המכשיר שרק סביבת הביצוע המהימנה (TEE) יכולה לגשת לפני המכשיר יוצא מהמפעל. משתמש יכול לבטל את נעילת תוכנת האתחול של המכשיר ולשנות את תוכנת המערכת והמזהים המדווחים על ידי frameworks של Android. לא ניתן לשנות עותקים של המזהים שנמצאים ב-TEE בצורה הזו, וידוא שאימות מזהה המכשיר יאומת רק מזהי חומרה מקוריים שמונעים ניסיונות זיוף.

פלטפורמת ה-API הראשית לאימות הזהות מבוססת על המפתח הקיים מנגנון האימות שנוסף ב-Keymaster 2. כאשר מבקשים אישור אימות (attestation) למפתח שנמצא ב-Keymaster, מבצע הקריאה החוזרת יוכל לבקש שמזהי החומרה של המכשיר יהיו כלולים באימות המטא-נתונים של האישור. אם המפתח נמצא בסביבת TEE, האישור בחזרה לשורש נאמן ידוע. מקבל האישור יכול אימות שהאישור והתוכן שלו, כולל החומרה נכתבו על ידי TEE. כשמוצגת בקשה לכלול חומרה במזהים באישור האימות, ה-TEE מאמת רק מזהים ששמורים באחסון שלו, כפי שמאוכלסים בקומת המפעל.

מאפייני האחסון

האחסון שמכיל את מזהי המכשיר צריך לכלול את המאפיינים הבאים:

  • הערכים שנגזרים מהמזהים המקוריים של המכשיר מועתקים אל ואחסון לפני יציאת המכשיר מהמפעל.
  • השיטה destroyAttestationIds() יכולה להרוס לתמיד העותק הזה של הנתונים שנגזרו מהמזהה. הרס קבוע פירושו הנתונים הוסרו לגמרי, כך שלא מתבצע איפוס להגדרות המקוריות שבוצעו במכשיר, יכולים לשחזר אותו. במיוחד חשוב במכשירים שבהם משתמש ביטל את הנעילה של תוכנת האתחול וביצע שינויים תוכנת המערכת ושינתה את המזהים שמוחזרים על ידי Android של מסגרות.
  • למתקני RMA צריכה להיות אפשרות: ליצור עותקים חדשים של הנתונים שנובעים ממזהה החומרה. כך, מכשיר שעובר דרך RMA יכול לבצע שוב אימות (attestation) באמצעות מזהה. חייבים להגן על המנגנון שמשמש את מתקני ה-RMA כדי שמשתמשים לא יוכלו להפעיל אותו בעצמו, וכך הם יוכלו לקבל אימותים מזהים מזויפים.
  • אף קוד מלבד האפליקציה המהימנה של Keymaster ב-TEE לא יכול לקרוא את נתונים שנגזרים מהמזהים ונשמרים באחסון.
  • האחסון ברור: אם התוכן של האחסון אבד צוות ה-TEE מתייחס אליו כאילו היו עותקים של התוכן הוא מושמד ודוחה את כל ניסיונות האימות של התעודה המזהה. הוא מיושם על ידי חתימה או MAC של האחסון כפי שמתואר שלמטה.
  • נפח האחסון לא מכיל את המזהים המקוריים. כי אימות (attestation) באמצעות תעודה מזהה כרוך באתגר, המתקשר תמיד מספק את המזהים אומת. צוות ה-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. זמן ההשוואה חייב להיות קבוע, ללא קשר מספר המזהים שסיפקתם ואת ההתאמה הנכונה של כל חלק בבדיקה.

מזהי חומרה

באימות (attestation) של המזהה יש תמיכה במזהי החומרה הבאים:

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

כדי לתמוך באימות (attestation) של מזהה המכשיר, המכשיר מאמת את המזהים האלה. הכול במכשירים שבהם פועלת מערכת Android יש את 6 הראשונים, והם נדרשים כדי שהתכונה תפעל. אם יש במכשיר רדיו סלולרי משולב, צריכה לתמוך באימות של מספרי ה-IMEI או ה-MEID של מכשירי הרדיו.

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

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

המזהה לאימות הוא מחרוזת בייטים בקידוד UTF-8. הפורמט הזה חל על מזהים מספריים. כל מזהה לאימות מבוטא מחרוזת בקידוד UTF-8.

אם המכשיר לא תומך באימות באמצעות מזהה (או בוצעה שיחה בעבר אל destroyAttestationIds() והמכשיר לא יכול לאמת יותר את המזהים שלו), כל בקשת אימות של מפתח שכוללת אחד או יותר התגים האלה נכשלים עם ErrorCode::CANNOT_ATTEST_IDS.

אם המכשיר תומך באימות (attestation) של מזהה, ובאחד או יותר מהתגים שלמעלה כלולה בבקשת אימות של מפתח, מכשיר ה-TEE מאמת את המזהה שכל אחד מהתגים מספק תואם לעותק של מזהי החומרה שלו. אם המיקום אחד או יותר מהמזהים לא תואמים, האימות כולו נכשל עם ErrorCode::CANNOT_ATTEST_IDS מותר להשתמש באותו תג סופקו כמה פעמים. האפשרות הזו יכולה להיות שימושית, לדוגמה, כשאתם מאמתים מספרי IMEI: למכשיר יכולים להיות כמה מכשירי רדיו עם כמה מספרי IMEI. בקשת אימות היא חוקי אם הערך שצוין לכל ATTESTATION_ID_IMEI תואם את אחד ממכשירי הרדיו של המכשיר. אותו עיקרון חל על כל שאר התגים.

אם האימות הצליח, המזהים המאומתים יתווספו אל תוסף אימות (attestation) (OID 1.3.6.1.4.1.11129.2.1.17) של אישור האימות שהונפק, באמצעות הסכימה שלמעלה. שינויים מ-Keymaster 2 סכימת האימות (attestation) מודגשת עם תגובות.

API ל-Java

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