בדף הזה מופיעים פרטים והנחיות נוספים שיעזרו למטמיעים של שכבת החומרה להפשטה (HAL) של KeyMint. המסמך הראשי בנושא HAL הוא מפרט הממשק של AIDL.
שימוש לרעה ב-API
מבצעי הקריאה יכולים ליצור מפתחות KeyMint עם הרשאות שתקפות כפרמטרים של API, אבל גורמות לכך שהמפתחות שייווצרו לא יהיו מאובטחים או בלתי ניתנים לשימוש. הטמעות של KeyMint לא חייבות להיכשל במקרים כאלה או להנפיק אבחון. לא צריך לאבחן באמצעות הטמעות שימוש במפתחות קטנים מדי, ציון פרמטרים לא רלוונטיים של קלט, שימוש חוזר ב-IV או ב-nonce, יצירת מפתחות ללא מטרה (ולכן חסרי תועלת) וכו'.
האפליקציות, המסגרת ו-Android Keystore אחראים לוודא שהקריאות למודולים של KeyMint הגיוניות ומועילות.
נקודת הכניסה addRngEntropy
נקודת הכניסה addRngEntropy
מוסיפה אנטרופיה שסופקה על ידי מבצע הקריאה למאגר שבו משתמשת ההטמעה של KeyMint ליצירת מספרים אקראיים, למפתחות ול-IV.
הטמעות של KeyMint צריכות לערבב באופן מאובטח את האנטרופיה שסופקה במאגר שלהן, שחייב להכיל גם אנטרופיה שנוצרה באופן פנימי ממחולל מספרים אקראיים לחומרה. יש לטפל בערבוב כך שלתוקף שיש לו שליטה מלאה על הביטים שסופקו על ידי addRngEntropy
או על הביטים שנוצרו בחומרה (אבל לא על שניהם) לא יהיה יתרון משמעותי בחיזוי הביטים שנוצרו ממאגר האנטרופיה.
מאפיינים עיקריים
כל אחד מהמנגנונים (generateKey
, importKey
ו-importWrappedKey
) שיוצרים מפתחות של KeyMint מחזיר את המאפיינים של המפתח החדש שנוצר, מחולקים בהתאם לרמות האבטחה שמאכפות כל מאפיין. המאפיינים המוחזרים כוללים את כל הפרמטרים שצוינו ליצירת המפתח, מלבד Tag::APPLICATION_ID
ו-Tag::APPLICATION_DATA
.
אם התגים האלה כלולים בפרמטרים של המפתח, הם יוסרו מהמאפיינים המוחזרים כדי שלא ניתן יהיה למצוא את הערכים שלהם על ידי בדיקת ה-keyblob המוחזר. עם זאת, הם מקושרים באופן קריפטוגרפי ל-keyblob, כך שאם לא יסופקו הערכים הנכונים בזמן השימוש במפתח, השימוש יכשל. באופן דומה, הערך Tag::ROOT_OF_TRUST
קשור באופן קריפטוגרפי למפתח, אבל אי אפשר לציין אותו במהלך יצירת המפתח או הייבוא שלו, והוא אף פעם לא מוחזר.
בנוסף לתגים שסופקו, ההטמעה של KeyMint מוסיפה גם את Tag::ORIGIN
, שמציין את האופן שבו המפתח נוצר (KeyOrigin::GENERATED
, KeyOrigin::IMPORTED
או KeyOrigin::SECURELY_IMPORTED
).
עמידות לרולבק
האפשרות Tag::ROLLBACK_RESISTANCE
מציינת עמידות בפני חזרה לאחור, כלומר אחרי שמוחקים מפתח באמצעות deleteKey
או deleteAllKeys
, החומרה המאובטחת מוודאת שלא ניתן יהיה להשתמש בו שוב.
הטמעות של KeyMint מחזירות לחומר המפתח שנוצר או שיובא למבצע הקריאה החוזרת כ-keyblob, טופס מוצפן ומאומת. כש-Keystore מחק את ה-keyblob, המפתח נעלם, אבל תוקף שהצליח לאחזר בעבר את חומר המפתח יכול לשחזר אותו למכשיר.
מפתח עמיד בפני חזרה לאחור אם החומרה המאובטחת מבטיחה שלא ניתן יהיה לשחזר מפתחות שנמחקו מאוחר יותר. בדרך כלל עושים זאת על ידי אחסון של מטא-נתונים נוספים של המפתח במיקום מהימן שלא ניתן לבצע בו מניפולציה על ידי תוקף. במכשירים ניידים, המנגנון שמשמש לכך הוא בדרך כלל בלוקים של זיכרון מוגן מפני הפעלה חוזרת (RPMB). מכיוון שמספר המפתחות שאפשר ליצור הוא למעשה בלתי מוגבל, ויכול להיות שהגודל של האחסון המהימן שמשמש להתנגדות לשחזור לאחור מוגבל, ההטמעה עשויה לדחות בקשות ליצירת מפתחות עם התנגדות לשחזור לאחור כשהאחסון מלא.
התחלה
נקודת הכניסה begin()
מתחילה פעולה קריפטוגרפית באמצעות המפתח שצוין, למטרה שצוינה, עם הפרמטרים שצוינו (לפי הצורך). הפונקציה מחזירה אובייקט חדש של Binder מסוג IKeyMintOperation
, שמשמש להשלמתה של הפעולה. בנוסף, מוחזר ערך אתגר שמשמש כחלק מאסימון האימות בפעולות מאומתות.
הטמעה של KeyMint תומכת לפחות ב-16 פעולות בו-זמנית. מערכת Keystore משתמשת ב-15 מפתחות לכל היותר, כך שאחד מהם נשאר ל-vold
לצורך הצפנת סיסמאות. כשיש ב-Keystore 15 פעולות מתמשכות (begin()
הופעל, אבל finish
או abort
לא הופעלו) ומגיעה בקשה להתחיל פעולה 16, המערכת קוראת ל-abort()
על הפעולה שבה לא נעשה שימוש לאחרונה כדי להפחית את מספר הפעולות הפעילות ל-14, ואז קוראת ל-begin()
כדי להתחיל את הפעולה שהתבקשה.
אם Tag::APPLICATION_ID
או Tag::APPLICATION_DATA
צוינו במהלך יצירת המפתח או הייבוא שלו, הקריאות ל-begin()
חייבות לכלול את התגים האלה עם הערכים שצוינו במקור בארגומנט params
של השיטה הזו.
טיפול בשגיאות
אם שיטה ב-IKeyMintOperation
מחזירה קוד שגיאה שאינו ErrorCode::OK
, הפעולה מבוטלת והאובייקט של Operation Binder לא תקף. כל שימוש עתידי באובייקט יחזיר את הערך ErrorCode::INVALID_OPERATION_HANDLE
.
אכיפה של הרשאות
אכיפת ההרשאות למפתחות מתבצעת בעיקר ב-begin()
. היוצא מן הכלל היחיד הוא מקרה שבו למפתח יש ערך Tag::USER_SECURE_ID
אחד או יותר, ואין לו ערך Tag::AUTH_TIMEOUT
.
במקרה כזה, המפתח דורש הרשאה לכל פעולה, והשיטות update()
או finish()
מקבלות אסימון אימות בארגומנט authToken
. כדי לוודא שהאסימון תקין, ההטמעה של KeyMint:
- אימות החתימה של HMAC על אסימון האימות.
- בודק שהטוקן מכיל מזהה משתמש מאובטח שתואם למזהה שמשויך למפתח.
- הפונקציה בודקת שסוג האימות של האסימון תואם ל-
Tag::USER_AUTH_TYPE
של המפתח. - בודק שהטוקן מכיל את ערך האתגר של הפעולה הנוכחית בשדה האתגר.
אם התנאים האלה לא מתקיימים, הפונקציה KeyMint מחזירה את הערך ErrorCode::KEY_USER_NOT_AUTHENTICATED
.
מבצע הקריאה מספק את אסימון האימות בכל קריאה ל-update()
ול-finish()
. אפשר לאמת את האסימון בהטמעה רק פעם אחת.