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) של המזהה יש תמיכה במזהי החומרה הבאים:
- שם המותג, כפי שהוחזר על ידי
Build.BRAND
ב-Android - שם המכשיר, כפי שהוחזר על ידי
Build.DEVICE
ב-Android - שם המוצר, כפי שהוחזר על ידי
Build.PRODUCT
ב-Android - שם היצרן, כפי שהוחזר על ידי
Build.MANUFACTURER
ב-Android - שם הדגם, כפי שהוחזר על ידי
Build.MODEL
ב-Android - מספר סידורי
- מספרי IMEI של כל מכשירי הרדיו
- 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. המידע הזה נועד לעזור למטמיעים להבין באופן שבו אפליקציות משתמשות בתכונה. יכול להיות שרכיבי המערכת ישתמשו בו אחרת, ולכן חשוב מאוד שלא יתייחסו לקטע הזה כרגיל.