פונקציות של KeyMint

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

הטמעה של KeyMint תומכת ב-16 פעולות בו-זמניות לפחות. מערכת Keystore משתמשת בעד 15 מפתחות, ומשאירה אחד לשימוש של vold להצפנת סיסמאות. אם יש 15 פעולות בתהליך ב-Keystore (הייתה קריאה ל-begin(), אבל לא הייתה קריאה ל-finish או ל-abort) והתקבלה בקשה להתחיל פעולה 16, המערכת קוראת ל-abort() בפעולה שהייתה בשימוש הכי פחות זמן כדי לצמצם את מספר הפעולות הפעילות ל-14 לפני הקריאה ל-begin() כדי להתחיל את הפעולה החדשה שהתבקשה.

אם צוינו Tag::APPLICATION_ID או Tag::APPLICATION_DATA במהלך יצירה או ייבוא של מפתח, קריאות אל begin() חייבות לכלול את התגים האלה עם הערכים שצוינו במקור בארגומנט params של השיטה הזו.

טיפול בשגיאות

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