מערכת המשנה של Gatekeeper מבצעת אימות של תבנית או סיסמה של המכשיר בסביבת מחשוב אמינה (TEE). Gatekeeper רושם ומאמת סיסמאות באמצעות מפתח סודי שמגודר בחומרה. בנוסף, Gatekeeper מגביל את מספר הניסיונות החוזרים לאימות שנכשלו, ועליו לסרב לטפל בבקשות על סמך זמן קצוב לתפוגה ומספר ניסיונות חוזרים שנכשלו.
כשמשתמשים מאמתים את הסיסמאות שלהם, Gatekeeper פולט אסימון אימות שמחותם במפתח HMAC לכל אתחול שזמין רק לרכיבים מאובטחים. האסימון הזה נשלח ל-Keystore המבוסס על חומרה. כלומר, אסימון אימות של Gatekeeper מודיע ל-Keystore שאפשר להשתמש באפליקציות במפתחות שמקושרים לאימות (לדוגמה, מפתחות שנוצרו על ידי אפליקציות).
ארכיטקטורה
מערכת Gatekeeper כוללת שלושה רכיבים עיקריים:
gatekeeperd
(דמוין של שומרת) – שירות Binder ב-C++ ב-Android שמכיל לוגיקה שאינה תלויה בפלטפורמה, שמטמיעה את ממשק ה-AIDL שלIGateKeeperService
על סמך הטמעה בסיסית שלIGatekeeper
שמותאמת לספק.- שירות שכבת ההפשטה של החומרה (HAL) של שער – הטמעה ספציפית לספק של ממשק AIDL
IGatekeeper
. שירות ה-HAL הזה פועל ב-Android, אבל הפונקציונליות של הליבה של Gatekeeper צריכה לפעול בסביבה מאובטחת, ולכן בדרך כלל היא מתקשרת עם ה-TA של Gatekeeper. - אפליקציה מהימנה של שומר (TA) – הטמעה ספציפית לספק שפועלת ב-TEE ומבצעת את אימות הסיסמה או התבנית בפועל.
ה-LockSettingsService
שולח בקשה (דרך Binder) שמגיעה לדימון gatekeeperd
ב-Android OS. לאחר מכן, הדימון (daemon) של gatekeeperd
שולח בקשה לשירות HAL של IGatekeeper
, והבקשה מגיעה בתורו ל-TA המקביל של Gatekeeper ב-TEE:

איור 1. תהליך אימות ברמה גבוהה על ידי GateKeeper.
הדימון gatekeeperd
מעניק לממשקי ה-API של מסגרת Android גישה ל-HAL, ומשתתף בדיווח על אימותים של המכשיר ל-Keystore.
הדימון gatekeeperd
פועל בתהליך נפרד, בנפרד משרת המערכת.
הטמעת HAL
הדימון gatekeeperd
משתמש ב-HAL של IGatekeeper
כדי לבצע אינטראקציה עם ה-TA הבסיסי של Gatekeeper לצורך אימות סיסמה. הטמעת ה-TA של Gatekeeper חייבת לאפשר חתימה (הרשמה) ואימות של blobs. כל ההטמעות אמורות לפעול בהתאם לפורמט הסטנדרטי של אסימון האימות (HardwareAuthToken
) שנוצר בכל אימות סיסמה מוצלח. לפרטים על התוכן והסמנטיקה של HardwareAuthToken
, ראו ההגדרה של HardwareAuthToken.aidl
.
הטמעות של IGatekeeper
HAL על ידי ספקים חייבות ליישם את הפונקציות enroll
ו-verify
:
- ה-method
enroll
מקבל blob של סיסמה, חותם עליו ומחזיר את החתימה ככינוי. ה-blob המוחזר (מקריאה ל-enroll
) צריך להיות בעל המבנה שמתואר ב-system/gatekeeper/include/gatekeeper/password_handle.h
. - הפונקציה
verify
צריכה להשוות בין החתימה שנוצרה על ידי הסיסמה שצוינה, ולוודא שהיא תואמת למזהה הסיסמה הרשום.
אסור לשנות את המפתח שמשמש להרשמה ולאימות, וצריך להיות אפשרי להפיק אותו מחדש בכל הפעלה של המכשיר.
Trusty והטמעות אחרות
מערכת ההפעלה Trusty היא מערכת הפעלה מהימנה בקוד פתוח של Google לסביבות TEE, והיא מכילה הטמעה מאושרת של Gatekeeper. עם זאת, כל מערכת הפעלה של TEE יכולה להטמיע את Gatekeeper כל עוד ל-TEE יש גישה למפתח עקבי שמבוסס על חומרה ולשעון מונוטוני מאובטח שמתקתק במצב השהיה.
Trusty משתמש במערכת IPC פנימית כדי לתקשר סוד משותף ישירות בין KeyMint לבין ההטמעה של Trusty ב-Gatekeeper (Trusty Gatekeeper). הסוד המשותף הזה משמש לחתימה על אסימוני אימות שנשלחים ל-Keystore כדי לספק אימותים של אימות סיסמה. Trusty Gatekeeper מבקש את המפתח מ-KeyMint בכל שימוש, ולא שומר את הערך או מאחסן אותו במטמון. אפשר לשתף את הסוד הזה בכל דרך שלא פוגעת באבטחה.
מפתח ה-HMAC שמשמש להרשמה ולאימות של סיסמאות נגזר ונשמר אך ורק ב-Gatekeeper.
ב-Android יש הטמעה גנרית של Gatekeeper ב-C++ שצריך רק להוסיף לה תוכניות עבודה ספציפיות למכשיר כדי להשלים אותה. ההטמעה של Trusty מבוססת על ההטמעה הזו. כדי להטמיע שומר TEE עם קוד ספציפי למכשיר ל-TEE, אפשר לעיין בפונקציות ובתגובות שבקובץ system/gatekeeper/include/gatekeeper/gatekeeper.h
. האחריות העיקרית של ההטמעה התואמת כוללת:
- תאימות ל-HAL של
IGatekeeper
. - אסימוני האימות שמוחזרים צריכים להיות בפורמט שמתאים למפרט
HardwareAuthToken
(המתואר במאמרHardwareAuthToken.aidl
). - שומר ה-TEE צריך להיות מסוגל לשתף מפתח HMAC עם KeyMint באמצעות אחת מהאפשרויות הבאות:
- הסכם על סוד משותף: Gatekeeper יכול להשתתף במשא ומתן על מפתח ה-HMAC בכל הפעלה על ידי הטמעת ה-HAL
ISharedSecret
. לשם כך, צריך שגם ל-Gatekeeper וגם ל-KeyMint תהיה גישה לסוד משותף ששותף מראש. - גישה ישירה: Gatekeeper יכול לאחזר את מפתח ה-HMAC מ-KeyMint באמצעות מנגנון תקשורת פנימי בין תהליכים ב-TEE, על פי דרישה או בשימוש הראשון (לאחר מכן הוא נשמר במטמון).
- הסכם על סוד משותף: Gatekeeper יכול להשתתף במשא ומתן על מפתח ה-HMAC בכל הפעלה על ידי הטמעת ה-HAL
מזהי משתמשים מאובטחים (SID)
SID של משתמש הוא הייצוג של המשתמש ב-TEE (ללא קשר חזק למזהה משתמש ב-Android). ה-SID נוצר באמצעות מחולל מספרים פסאודו-אקראיים (PRNG) קריפטוגרפיים בכל פעם שמשתמש רושם סיסמה חדשה בלי לספק סיסמה קודמת. התהליך הזה נקרא הרשמה מחדש לא מהימנה, והוא מתרחש בדרך כלל רק כשמשתמש מגדיר סיסמה או דפוס בפעם הראשונה.
הרשמה מחדש מהימנה מתרחשת כשמשתמש מספק סיסמה קודמת תקפה, למשל כשמשנים את הסיסמה. במקרה כזה, ה-SID של המשתמש מועבר למזהה הסיסמה החדש, תוך שמירה על המפתחות שהיו מקושרים אליו.
מזהה המשתמש (SID) נכלל באימות ה-HMAC יחד עם הסיסמה במזהה הסיסמה כשהיא נרשמת.
מזהי ה-SID של המשתמשים כלולים ב-HardwareAuthToken
שמוחזר על ידי הפונקציה verify()
, והם משויכים לכל המפתחות של Keystore שמקושרים לאימות (פרטים על הפורמט HardwareAuthToken
ועל Keystore מופיעים במאמר אימות).
חשוב לזכור שכאשר קריאה לא מהימנה לפונקציה enroll()
משנה את ה-SID של המשתמש, הקריאה הופכת את המפתחות שמקושרים לאותה סיסמה ללא שימוש. תוקפים יכולים לשנות את הסיסמה של המכשיר אם הם שולטים במערכת ההפעלה Android, אבל הם הורסים במהלך התהליך מפתחות רגישים שמוגנים ברמה הבסיסית (root).
בקשה לוויסות נתונים
שומר הסף צריך להיות מסוגל לצמצם באופן מאובטח את מספר הניסיונות לפריצה בכוח על פרטי הכניסה של המשתמש. כפי שמוצג ב-GatekeeperVerifyResponse.aidl
, ה-HAL מאפשר להחזיר זמן קצוב לתפוגה באלפיות השנייה. הזמן הקצוב מאפשר ללקוח לדעת שלא כדאי לבצע קריאה חוזרת ל-Gatekeeper עד שחלף הזמן הקצוב.
שרת Gatekeeper לא אמור לטפל בבקשות אם יש זמן קצוב לתפוגה בהמתנה.
שומר הכניסה צריך לכתוב מונה כישלונות לפני אימות הסיסמה של המשתמש. אם אימות הסיסמה מצליח, מונה הכשלים אמור להימחק. כך אפשר למנוע התקפות שמונעות צמצום קצב העברת הנתונים על ידי השבתת ה-MMC המוטמע (eMMC) אחרי שליחת קריאה ל-verify
. הפונקציה enroll
מאמתת גם את הסיסמה של המשתמש (אם היא סופקה), וצריך להגביל את הקצב שלה באותו אופן.
אם המכשיר תומך בכך, מומלץ מאוד לכתוב את מונה הכשל לאחסון מאובטח. אם המכשיר לא תומך בהצפנה מבוססת-קובץ, או אם האחסון המאובטח איטי מדי, יכול להיות שההטמעות ישתמשו ישירות ב-Replay Protected Memory Block (RPMB).