הזמינות של סביבת ביצוע מהימנה (TEE) במערכת על שבב (SoC) מאפשרת למכשירי Android לספק שירותי אבטחה חזקים שמגובים בחומרה למערכת ההפעלה של Android, לשירותי הפלטפורמה ואפילו לאפליקציות של צד שלישי (בצורה של תוספים ספציפיים ל-Android לארכיטקטורת ההצפנה הרגילה של Java, ראו KeyGenParameterSpec).
מילון מונחים
הנה סקירה כללית מהירה של רכיבי Keystore והקשרים ביניהם.
AndroidKeyStore- ה-API והרכיב של Android Framework שמשמשים אפליקציות כדי לגשת לפונקציונליות של Keystore. הספרייה הזו היא הטמעה של ממשקי ה-API של תקן Java Cryptography Architecture, אבל היא גם מוסיפה תוספים ספציפיים ל-Android ומורכבת מקוד Java שפועל במרחב התהליכים של האפליקציה.
AndroidKeyStoreממלא בקשות לאפליקציות להתנהגות של מאגר מפתחות על ידי העברתן לדמון של מאגר המפתחות. - keystore daemon
- An Android system daemon that provides access to all Keystore functionality through a Binder API. הדמון הזה אחראי לאחסון של keyblobs שנוצרו על ידי ההטמעה הבסיסית של KeyMint (או Keymaster), שמכילים את חומר המפתח הסודי, מוצפן כך ש-Keystore יכול לאחסן אותם אבל לא להשתמש בהם או לחשוף אותם.
- KeyMint HAL service
- שרת AIDL שמטמיע את
IKeyMintDeviceHAL, ומספק גישה ל-KeyMint TA הבסיסי. - אפליקציה מהימנה (TA) של KeyMint
- תוכנה שפועלת בהקשר מאובטח, לרוב ב-TrustZone ב-ARM SoC, שמספקת את כל הפעולות הקריפטוגרפיות המאובטחות. לאפליקציה הזו יש גישה לחומר המפתח הגולמי, והיא מאמתת את כל תנאי בקרת הגישה במפתחות לפני שהיא מאפשרת את השימוש בהם.
LockSettingsService- רכיב מערכת Android שאחראי על אימות משתמשים, באמצעות סיסמה וטביעת אצבע. הוא לא חלק מ-Keystore, אבל הוא רלוונטי כי Keystore תומך במושג של מפתחות שקשורים לאימות: מפתחות שאפשר להשתמש בהם רק אם המשתמש עבר אימות.
LockSettingsServiceמתקשר עם Gatekeeper TA ו-Fingerprint TA כדי לקבל אסימוני אימות, שהוא מספק לדימון של מאגר המפתחות, והם נצרכים על ידי KeyMint TA. - Gatekeeper TA
- הרכיב שפועל בסביבה המאובטחת שאחראי לאימות הסיסמאות של המשתמשים וליצירת טוקנים לאימות. הטוקנים האלה משמשים כדי להוכיח ל-KeyMint TA שבוצע אימות עבור משתמש מסוים בנקודת זמן מסוימת.
- Fingerprint TA
- הרכיב שפועל בסביבה המאובטחת שאחראי לאימות טביעות האצבע של המשתמשים וליצירת טוקנים לאימות. הטוקנים האלה משמשים כדי להוכיח ל-KeyMint TA שבוצע אימות למשתמש מסוים בנקודת זמן מסוימת.
ארכיטקטורה
Android Keystore API ו-KeyMint HAL הבסיסי, אבל המספיק, מספקים קבוצה של פרימיטיבים קריפטוגרפיים שמאפשרים הטמעה של פרוטוקולים באמצעות מפתחות מגובים בחומרה עם בקרת גישה.
KeyMint HAL הוא שירות שסופק על ידי יצרן ציוד מקורי (OEM) ומשמש את שירות Keystore כדי לספק שירותים קריפטוגרפיים שמגובים בחומרה. כדי לשמור על אבטחת חומר המפתח הפרטי, הטמעות של HAL לא מבצעות פעולות רגישות במרחב המשתמש, או אפילו במרחב הליבה. במקום זאת, שירות KeyMint HAL שפועל ב-Android מעביר פעולות רגישות ל-TA שפועל בסביבה מאובטחת כלשהי, בדרך כלל על ידי המרה של בקשות לפורמט נתונים והמרה חזרה לפורמט המקורי בפורמט נתונים שמוגדר בהטמעה.
הארכיטקטורה שמתקבלת נראית כך:
איור 1. גישה ל-KeyMint.
ממשק KeyMint HAL API הוא ברמה נמוכה, והוא נמצא בשימוש של רכיבים פנימיים של הפלטפורמה ולא חשוף למפתחי אפליקציות. Java API ברמה גבוהה יותר שזמין לאפליקציות מתואר באתר למפתחי Android.
בקרת גישה
Android Keystore מספק רכיב מרכזי לאחסון ולשימוש במפתחות קריפטוגרפיים שמגובים בחומרה, גם לאפליקציות וגם לרכיבי מערכת אחרים. לכן, הגישה לכל מפתח בודד מוגבלת בדרך כלל לאפליקציה או לרכיב המערכת שיצרו את המפתח.
דומיינים של מאגרי מפתחות
כדי לתמוך בבקרת הגישה הזו, המפתחות מזוהים ב-Keystore באמצעות מתאר מפתח. מתאר המפתח הזה מציין דומיין שאליו המתאר שייך, יחד עם זהות בתוך הדומיין הזה.
אפליקציות ל-Android ניגשות ל-Keystore באמצעות ארכיטקטורת ההצפנה הרגילה של Java, שמזהה מפתחות באמצעות מחרוזת כינוי. השיטה הזו של
זיהוי ממופה לדומיין של מאגר המפתחות APP באופן פנימי. בנוסף, מזהה המשתמש של המתקשר כלול כדי להבחין בין מפתחות מאפליקציות שונות, וכך למנוע מאפליקציה אחת לגשת למפתחות של אפליקציה אחרת.
באופן פנימי, קוד המסגרות מקבל גם מזהה מפתח מספרי ייחודי אחרי טעינת המפתח. המזהה המספרי הזה משמש כמזהה של תיאורי מפתחות בדומיין KEY_ID. עם זאת, עדיין מתבצעת בקרת גישה: גם אם אפליקציה אחת מגלה מזהה מפתח של מפתח של אפליקציה אחרת, היא לא יכולה להשתמש בו בנסיבות רגילות.
עם זאת, אפליקציה יכולה להעניק שימוש במפתח לאפליקציה אחרת (שמזוהה באמצעות UID). פעולת ההרשאה הזו מחזירה מזהה הרשאה ייחודי, שמשמש כמזהה של תיאורי מפתחות בדומיין GRANT. שוב, בקרת הגישה עדיין מתבצעת: גם אם אפליקציה שלישית מגלה את מזהה ההרשאה של מפתח של מקבל הרשאה, היא לא יכולה להשתמש בו.
ב-Keystore יש גם תמיכה בשני דומיינים אחרים לתיאורי מפתחות, שמשמשים רכיבי מערכת אחרים ולא זמינים למפתחות שנוצרו על ידי אפליקציות:
- הדומיין
BLOBמציין שאין מזהה למפתח במתאר המפתח, אלא שמתאר המפתח מכיל את ה-keyblob עצמו, והלקוח מטפל באחסון ה-keyblob. השיטה הזו משמשת לקוחות (לדוגמה,vold) שצריכים לגשת ל-Keystore לפני שהמחיצה של הנתונים מותקנת. - הדומיין
SELINUXמאפשר לרכיבי המערכת לשתף מפתחות, והגישה כפופה למזהה מספרי שתואם לתווית SELinux (ראו מדיניות SELinux עבור keystore_key).
מדיניות SELinux עבור keystore_key
ערכי המזהים שמשמשים לתיאורי מפתחות של Domain::SELINUX מוגדרים בקובץ המדיניות של keystore2_key_context SELinux.
כל שורה בקבצים האלה ממפה מספר לתווית SELinux, לדוגמה:
# wifi_key is a keystore2_key namespace intended to be used by wpa supplicant and # Settings to share Keystore keys. 102 u:object_r:wifi_key:s0
רכיב שזקוק לגישה למפתח עם מזהה 102 בדומיין SELINUX חייב להיות בעל מדיניות SELinux תואמת. לדוגמה, כדי לאפשר ל-wpa_supplicant לקבל את המפתחות האלה ולהשתמש בהם, מוסיפים את השורה הבאה ל-hal_wifi_supplicant.te:
allow hal_wifi_supplicant wifi_key:keystore2_key { get, use };
המזהים המספריים של מפתחות Domain::SELINUX מחולקים לטווחים כדי לתמוך במחיצות שונות ללא התנגשויות:
| מחיצה | טווח | קובצי הגדרה |
|---|---|---|
| מערכת | 0 ... 9,999 | /system/etc/selinux/keystore2_key_contexts, /plat_keystore2_key_contexts
|
| מערכת מורחבת | 10,000 ... 19,999 | /system_ext/etc/selinux/system_ext_keystore2_key_contexts, /system_ext_keystore2_key_contexts
|
| מוצר | 20,000 ... 29,999 | /product/etc/selinux/product_keystore2_key_contexts, /product_keystore2_key_contexts
|
| ספק | 30,000 ... 39,999 | /vendor/etc/selinux/vendor_keystore2_key_contexts, /vendor_keystore2_key_contexts
|
הערכים הספציפיים הבאים הוגדרו עבור מחיצת המערכת:
| מזהה מרחב שמות | תווית SEPolicy | UID | תיאור |
|---|---|---|---|
| 0 | su_key |
לא רלוונטי | מפתח משתמש על. הוא משמש רק לבדיקות בגרסאות userdebug ו-eng. לא רלוונטי בגרסאות למשתמשים. |
| 1 | shell_key |
לא רלוונטי | מרחב שמות שזמין למעטפת. הפקודה הזו משמשת בעיקר לבדיקות, אבל אפשר להשתמש בה גם בגרסאות למשתמשים משורת הפקודה. |
| 100 | vold_key |
לא רלוונטי | מיועד לשימוש על ידי vold. |
| 101 | odsign_key |
לא רלוונטי | משמש את הדמון של החתימה במכשיר. |
| 102 | wifi_key |
AID_WIFI(1010) |
משמש את מערכת המשנה של ה-Wi-Fi ב-Android, כולל wpa_supplicant. |
| 103 | locksettings_key |
לא רלוונטי | בשימוש על ידי LockSettingsService |
| 120 | resume_on_reboot_key |
AID_SYSTEM(1000) |
הפרמטר הזה משמש את שרת המערכת של Android כדי לתמוך בהמשך הפעולה אחרי הפעלה מחדש. |
גישה לווקטורים
מאגר המפתחות מאפשר שליטה בפעולות שאפשר לבצע במפתח, בנוסף לשליטה בגישה הכוללת למפתח. ההרשאות keystore2_key
מתוארות בקובץ KeyPermission.aidl.
הרשאות מערכת
בנוסף לבקרות הגישה לכל מפתח שמתוארות במאמר מדיניות SELinux עבור keystore_key, בטבלה הבאה מתוארות הרשאות SELinux אחרות שנדרשות לביצוע פעולות שונות במערכת ולתחזוקה:
| הרשאה | משמעות |
|---|---|
add_auth
|
נדרש להוספת טוקנים של אימות ל-Keystore. משמש ספקי אימות כמו Gatekeeper או BiometricManager. |
clear_ns
|
נדרש למחיקת כל המפתחות במרחב שמות ספציפי. משמש כפעולת תחזוקה כשמסירים אפליקציות. |
list
|
המערכת דורשת את הערך הזה כדי למנות מפתחות לפי מאפיינים שונים, כמו בעלות או אם הם קשורים לאימות. ההרשאה הזו לא נדרשת למתקשרים שמפרטים את מרחבי השמות שלהם (ההרשאה get_info מכסה את זה). |
lock
|
נדרש כדי להודיע ל-keystore שהמכשיר ננעל, מה שגורם להוצאת מפתחות-על כדי לוודא שמפתחות שקשורים לאימות לא זמינים. |
unlock
|
נדרש כדי להודיע למאגר המפתחות שהמכשיר נפתח, ולשחזר את הגישה למפתחות-העל שמגנים על מפתחות שקשורים לאימות. |
reset
|
נדרש לאיפוס של Keystore להגדרות המקוריות, למחיקה של כל המפתחות שלא חיוניים לפעולה של מערכת ההפעלה Android. |
היסטוריה
ב-Android 5 ומטה, ל-Android היה API פשוט של שירותים קריפטוגרפיים עם גיבוי חומרה, שסופק על ידי גרסאות 0.2 ו-0.3 של שכבת הפשטת החומרה (HAL) של Keymaster. ה-Keystore סיפק פעולות של חתימה דיגיטלית ואימות, וגם יצירה וייבוא של זוגות מפתחות חתימה אסימטריים. ההגדרה הזו כבר מיושמת במכשירים רבים, אבל יש הרבה יעדי אבטחה שלא ניתן להשיג בקלות רק באמצעות API של חתימה. ב-Android 6.0 הורחב ה-API של מאגר המפתחות כדי לספק מגוון רחב יותר של יכולות.
Android 6.0
ב-Android 6.0, Keymaster 1.0 הוסיף פרימיטיבים קריפטוגרפיים סימטריים, AES ו-HMAC, ומערכת בקרת גישה למפתחות מגובים בחומרה. אמצעי בקרת הגישה מוגדרים במהלך יצירת המפתח ומאוכפים למשך חיי המפתח. אפשר להגביל את השימוש במפתחות כך שיהיה אפשרי רק אחרי שהמשתמש עבר אימות, ורק למטרות ספציפיות או עם פרמטרים קריפטוגרפיים ספציפיים.
בנוסף להרחבת טווח הפרימיטיבים הקריפטוגרפיים, ב-Keystore ב-Android 6.0 נוספו התכונות הבאות:
- תוכנית לבקרת שימוש כדי לאפשר הגבלת שימוש במפתחות, במטרה לצמצם את הסיכון לפגיעה באבטחה בגלל שימוש לרעה במפתחות
- תוכנית לבקרת גישה שמאפשרת להגביל את המפתחות למשתמשים וללקוחות ספציפיים, ולטווח זמן מוגדר
Android 7.0
ב-Android 7.0, Keymaster 2 הוסיף תמיכה באימות מפתחות ובקישור גרסאות.
אימות מפתח מספק אישורים של מפתחות ציבוריים שמכילים תיאור מפורט של המפתח ואמצעי בקרת הגישה שלו, כדי לאפשר אימות מרחוק של קיום המפתח בחומרה מאובטחת ושל ההגדרה שלו.
קישור גרסה מקשר מפתחות לגרסת מערכת ההפעלה ולגרסת רמת התיקון. כך מובטח שתוקף שמגלה חולשה בגרסה ישנה של המערכת או של תוכנת TEE לא יוכל להחזיר מכשיר לגרסה הפגיעה ולהשתמש במפתחות שנוצרו באמצעות הגרסה החדשה יותר. בנוסף, כשמשתמשים במפתח עם גרסה מסוימת ורמת תיקון מסוימת במכשיר ששודרג לגרסה חדשה יותר או לרמת תיקון חדשה יותר, המפתח משודרג לפני שאפשר להשתמש בו, והגרסה הקודמת של המפתח הופכת ללא תקפה. במהלך השדרוג של המכשיר, המפתחות מתקדמים יחד עם המכשיר, אבל אם המכשיר חוזר לגרסה קודמת, אי אפשר להשתמש במפתחות.
Android 8.0
ב-Android 8.0, Keymaster 3 עבר מ-HAL בסגנון הישן של מבנה C אל ממשק C++ HAL שנוצר מהגדרה בשפה החדשה להגדרת ממשק חומרה (HIDL). במסגרת השינוי, הרבה מסוגי הארגומנטים השתנו, אבל יש התאמה בין הסוגים והשיטות לבין הסוגים הישנים והשיטות של מבנה ה-HAL.
בנוסף לשינוי בממשק הזה, ב-Android 8.0 הורחבה תכונת האימות של Keymaster 2 כדי לתמוך באימות מזהה. אימות מזהה מספק מנגנון מוגבל ואופציונלי לאימות חזק של מזהי חומרה, כמו מספר סידורי של מכשיר, שם מוצר ומזהה טלפון (IMEI או MEID). כדי להטמיע את התוספת הזו, ב-Android 8.0 שונה סכמת האישור של ASN.1 כדי להוסיף אישור מזהה. הטמעות של Keymaster צריכות למצוא דרך מאובטחת לאחזור פריטי הנתונים הרלוונטיים, וגם להגדיר מנגנון להשבתה מאובטחת וקבועה של התכונה.
Android 9
ב-Android 9, העדכונים כללו:
- עדכון לגרסה Keymaster 4
- תמיכה ברכיבים מאובטחים מוטמעים
- תמיכה ביבוא מאובטח של מפתחות
- תמיכה בהצפנת 3DES
- שינויים בקשירת הגרסה כך של-
boot.imgול-system.imgיש גרסאות מוגדרות בנפרד כדי לאפשר עדכונים עצמאיים
Android 10
ב-Android 10 הוצגה גרסה 4.1 של Keymaster HAL, שנוספו לה:
- תמיכה במפתחות שאפשר להשתמש בהם רק כשהמכשיר לא נעול
- תמיכה במפתחות שאפשר להשתמש בהם רק בשלבים של אתחול מוקדם
- תמיכה אופציונלית במפתחות אחסון מוצפנים בחומרה
- תמיכה אופציונלית באימות ייחודי למכשיר ב-StrongBox
12 Android
ב-Android 12 הוצג KeyMint HAL חדש, שמחליף את Keymaster HAL אבל מספק פונקציונליות דומה. בנוסף לכל התכונות שצוינו למעלה, ה-HAL של KeyMint כולל גם:
- תמיכה בהסכם מפתח ECDH
- תמיכה במפתחות אימות שצוינו על ידי המשתמש
- תמיכה במפתחות עם מספר מוגבל של שימושים
Android 12 כולל גם גרסה חדשה של דמון מערכת מאגר המפתחות, שנכתבה מחדש ב-Rust ונקראת keystore2
Android 13
ב-Android 13 נוספה גרסה 2 של KeyMint HAL, שכוללת תמיכה ב-Curve25519 לחתימה ולהסכמה על מפתח.