הצפנה מבוססת-קבצים

‫Android 7.0 ואילך תומך בהצפנה מבוססת-קבצים (FBE). הצפנה מבוססת-קובץ מאפשרת להצפין קבצים שונים באמצעות מפתחות שונים שאפשר לפתוח בנפרד.

במאמר הזה מוסבר איך להפעיל הצפנה מבוססת-קבצים במכשירים חדשים ואיך אפליקציות מערכת יכולות להשתמש בממשקי ה-API של Direct Boot כדי להציע למשתמשים את החוויה הטובה והמאובטחת ביותר שאפשר.

כל המכשירים שמותקנת בהם מערכת ההפעלה Android בגרסה 10 ואילך חייבים להשתמש בהצפנה מבוססת-קובץ.

אתחול ישיר

הצפנה מבוססת-קובץ מאפשרת תכונה חדשה שהוצגה ב-Android 7.0 בשם Direct Boot. הפעלה ישירה מאפשרת למכשירים מוצפנים לבצע אתחול ישירות למסך הנעילה. בעבר, במכשירים מוצפנים שנעשה בהם שימוש בהצפנת דיסק מלאה (FDE), המשתמשים נדרשו לספק פרטי כניסה לפני שהייתה אפשרות לגשת לנתונים, ולכן הטלפון לא יכול היה לבצע פעולות, למעט הפעולות הבסיסיות ביותר. לדוגמה, שעונים מעוררים לא פעלו, שירותי הנגישות לא היו זמינים, והטלפונים לא יכלו לקבל שיחות, אלא רק לבצע פעולות בסיסיות של חיוג למקרי חירום.

עם ההשקה של הצפנה מבוססת-קבצים (FBE) וממשקי API חדשים שמאפשרים לאפליקציות לזהות הצפנה, אפשר להפעיל את האפליקציות האלה בהקשר מוגבל. זה יכול לקרות לפני שהמשתמשים מספקים את פרטי הכניסה שלהם, ועדיין לשמור על מידע פרטי של המשתמשים.

במכשיר עם הצפנה מבוססת-קבצים (FBE), לכל משתמש במכשיר יש שני מיקומי אחסון שזמינים לאפליקציות:

  • אחסון מוצפן של פרטי הכניסה (CE), שהוא מיקום האחסון שמוגדר כברירת מחדל, וזמין רק אחרי שהמשתמש פותח את הנעילה של המכשיר.
  • אחסון מוצפן במכשיר (DE), שהוא מיקום אחסון שזמין גם במצב אתחול ישיר וגם אחרי שהמשתמש פותח את הנעילה של המכשיר.

ההפרדה הזו הופכת את פרופילי העבודה למאובטחים יותר, כי היא מאפשרת להגן על יותר ממשתמש אחד בכל פעם, וההצפנה כבר לא מבוססת רק על סיסמה בזמן האתחול.

ה-API של אתחול ישיר מאפשר לאפליקציות עם מודעות להצפנה לגשת לכל אחד מהאזורים האלה. בוצעו שינויים במחזור החיים של האפליקציה כדי להתאים לצורך בהודעה לאפליקציות כששטח האחסון של CE של משתמש לא נעול בתגובה להזנת פרטי הכניסה הראשונים במסך הנעילה, או במקרה של פרופיל עבודה, כשמוצג אתגר שקשור לעבודה. במכשירים עם Android 7.0, חובה לתמוך בממשקי ה-API ובמחזורי החיים החדשים האלה, גם אם הם לא מטמיעים FBE. אבל בלי FBE, האחסון של DE ו-CE תמיד במצב לא נעול.

הטמעה מלאה של הצפנה מבוססת-קבצים במערכות הקבצים Ext4 ו-F2FS מסופקת ב-Android Open Source Project (AOSP) וצריך רק להפעיל אותה במכשירים שעומדים בדרישות. יצרנים שבוחרים להשתמש ב-FBE יכולים לבדוק דרכים לאופטימיזציה של התכונה על סמך המערכת על שבב (SoC) שבה נעשה שימוש.

כל החבילות הנדרשות ב-AOSP עודכנו כך שיתמכו בהפעלה ישירה. עם זאת, כשיצרני מכשירים משתמשים בגרסאות מותאמות אישית של האפליקציות האלה, הם רוצים לוודא שלפחות יש חבילות שמתאימות להפעלה ישירה ומספקות את השירותים הבאים:

  • שירותי טלפוניה וחייגן
  • שיטת קלט להזנת סיסמאות במסך הנעילה

דוגמאות ומקור

‫Android מספקת הטמעה לדוגמה של הצפנה מבוססת-קבצים, שבה vold ‏ (system/vold) מספק את הפונקציונליות לניהול מכשירי אחסון ונפחים ב-Android. הוספת FBE מספקת ל-vold כמה פקודות חדשות כדי לתמוך בניהול מפתחות עבור מפתחות CE ו-DE של כמה משתמשים. בנוסף לשינויים המרכזיים שבוצעו כדי להשתמש ביכולות ההצפנה מבוססת-הקבצים בליבת המערכת, בוצעו שינויים בחבילות מערכת רבות, כולל מסך הנעילה וממשק המערכת, כדי לתמוך בתכונות FBE ו-Direct Boot. למשל:

  • חייגן AOSP‏ (packages/apps/Dialer)
  • שעון שולחני (packages/apps/DeskClock)
  • LatinIME (packages/inputmethods/LatinIME)*
  • אפליקציית ההגדרות (packages/apps/Settings)*
  • SystemUI (frameworks/base/packages/SystemUI)*

* אפליקציות מערכת שמשתמשות במאפיין defaultToDeviceProtectedStorage manifest

דוגמאות נוספות לאפליקציות ולשירותים שמודעים להצפנה אפשר למצוא בהרצת הפקודה mangrep directBootAware בספריית המסגרות או החבילות של עץ המקור AOSP.

תלויות

כדי להשתמש בהטמעה של FBE ב-AOSP בצורה מאובטחת, המכשיר צריך לעמוד בתלות הבאה:

  • תמיכה בליבה בהצפנת Ext4 או בהצפנת F2FS.
  • תמיכה ב-KeyMint (או ב-Keymaster 1.0 ואילך). אין תמיכה ב-Keymaster 0.3 כי הוא לא מספק את היכולות הנדרשות או מבטיח הגנה מספקת למפתחות הצפנה.
  • צריך להטמיע את KeyMint/Keymaster ו-Gatekeeper בסביבת מחשוב אמינה (TEE) כדי לספק הגנה למפתחות הצפנת הנתונים, כך שמערכת הפעלה לא מורשית (מערכת הפעלה מותאמת אישית שהותקנה במכשיר) לא תוכל פשוט לבקש את מפתחות הצפנת הנתונים.
  • כדי לוודא שמערכת הפעלה לא מורשית לא יכולה לגשת למפתחות DE, צריך להשתמש ב-Hardware Root of Trust וב-Verified Boot שקשורים לאתחול של KeyMint.

הטמעה

קודם כל, צריך להגדיר אפליקציות כמו שעונים מעוררים, טלפון ותכונות נגישות כ-android:directBootAware בהתאם למסמכי המפתחים בנושא Direct Boot.

תמיכה בליבה

תמיכה בקרנל בהצפנה של Ext4 ו-F2FS זמינה בקרנלים המשותפים של Android, מגרסה 3.18 ואילך. כדי להפעיל אותו בגרעין בגרסה 5.1 ומעלה, משתמשים בפקודה:

CONFIG_FS_ENCRYPTION=y

בליבות ישנות יותר, משתמשים ב-CONFIG_EXT4_ENCRYPTION=y אם מערכת הקבצים של המכשיר היא Ext4, או ב-CONFIG_F2FS_FS_ENCRYPTION=y אם מערכת הקבצים של המכשיר היא F2FS.userdatauserdata

אם המכשיר שלכם תומך באחסון ניתן להרחבה או משתמש בהצפנת מטא-נתונים באחסון הפנימי, צריך להפעיל גם את אפשרויות ההגדרה של ליבת המערכת שנדרשות להצפנת מטא-נתונים, כמו שמתואר במסמכי ההצפנה של מטא-נתונים.

בנוסף לתמיכה פונקציונלית בהצפנת Ext4 או F2FS, יצרני המכשירים צריכים גם להפעיל האצת הצפנה כדי להאיץ את ההצפנה מבוססת-הקובץ ולשפר את חוויית המשתמש. לדוגמה, במכשירים מבוססי ARM64, אפשר להפעיל האצה של ARMv8 CE (Cryptography Extensions) על ידי הגדרת אפשרויות תצורת הליבה הבאות:

CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
CONFIG_CRYPTO_SHA2_ARM64_CE=y

כדי לשפר עוד יותר את הביצועים ולצמצם את צריכת החשמל, יצרני המכשירים יכולים גם להטמיע חומרה להצפנה מוטמעת, שמצפינה ומפענחת את הנתונים בזמן שהם בדרך אל או ממאגר הנתונים. ליבות נפוצות של Android (גרסה 4.14 ואילך) מכילות מסגרת שמאפשרת להשתמש בהצפנה מוטבעת כשיש תמיכה בחומרה ובמנהל התקן של הספק. כדי להפעיל את מסגרת ההצפנה המוטמעת, צריך להגדיר את אפשרויות התצורה הבאות של ליבת המערכת:

CONFIG_BLK_INLINE_ENCRYPTION=y
CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y

אם במכשיר שלכם נעשה שימוש באחסון מבוסס UFS, צריך להפעיל גם את ההגדרות הבאות:

CONFIG_SCSI_UFS_CRYPTO=y

אם המכשיר שלכם משתמש באחסון מבוסס-eMMC, צריך להפעיל גם את ההגדרות הבאות:

CONFIG_MMC_CRYPTO=y

הפעלת הצפנה מבוססת-קבצים

כדי להפעיל FBE במכשיר, צריך להפעיל אותו באחסון הפנימי (userdata). הפעלת FBE באחסון הפנימי מפעילה אותו גם באחסון הניתן להרחבה באופן אוטומטי, אבל אפשר לשנות את פורמט ההצפנה באחסון הניתן להרחבה אם יש צורך בכך.

אחסון פנימי

כדי להפעיל את FBE, מוסיפים את האפשרות fileencryption=contents_encryption_mode[:filenames_encryption_mode[:flags]] לעמודה fs_mgr_flags בשורה fstab עבור userdata. האפשרות הזו מגדירה את פורמט ההצפנה באחסון הפנימי. הוא מכיל עד שלושה פרמטרים שמופרדים באמצעות נקודתיים:

  • הפרמטר contents_encryption_mode מגדיר את האלגוריתם הקריפטוגרפי שמשמש להצפנת תוכן הקובץ. הערך יכול להיות aes-256-xts או adiantum. מגרסה Android 11 אפשר גם להשאיר את השדה הזה ריק כדי לציין את אלגוריתם ברירת המחדל, שהוא aes-256-xts.
  • הפרמטר filenames_encryption_mode מגדיר את האלגוריתם הקריפטוגרפי שמשמש להצפנת שמות הקבצים. הערך יכול להיות aes-256-cts, ‏aes-256-heh, adiantum או aes-256-hctr2. אם לא מציינים ערך, ברירת המחדל היא aes-256-cts אם contents_encryption_mode הוא aes-256-xts, או adiantum אם contents_encryption_mode הוא adiantum.
  • הפרמטר flags, שחדש ב-Android 11, הוא רשימה של דגלים שמופרדים באמצעות התו +. יש תמיכה בדגלים הבאים:
    • הדגל v1 בוחר במדיניות הצפנה מגרסה 1, והדגל v2 בוחר במדיניות הצפנה מגרסה 2. בגרסה 2 של מדיניות ההצפנה נעשה שימוש בפונקציית נגזרת מפתח בטוחה וגמישה יותר. ברירת המחדל היא v2 אם המכשיר הושק ב-Android 11 ומעלה (כפי שנקבע על ידי ro.product.first_api_level), או v1 אם המכשיר הושק ב-Android 10 ומטה.
    • הדגל inlinecrypt_optimized בוחר פורמט הצפנה שעבר אופטימיזציה לחומרה של הצפנה מוטבעת שלא מטפלת במספרים גדולים של מפתחות בצורה יעילה. הוא עושה זאת על ידי גזירה של מפתח הצפנה אחד בלבד לתוכן הקובץ לכל מפתח CE או DE, במקום אחד לכל קובץ. היצירה של וקטורי אתחול (IV) מותאמת בהתאם.
    • הדגל emmc_optimized דומה לדגל inlinecrypt_optimized, אבל הוא גם בוחר שיטה ליצירת וקטור אתחול שמגבילה את וקטורי האתחול ל-32 ביט. הדגל הזה צריך לשמש רק בחומרה להצפנה מוטבעת שתואמת למפרט JEDEC eMMC v5.2, ולכן תומכת רק ב-IVs של 32 ביט. במכשירי חומרה אחרים להצפנה מוטבעת, משתמשים ב-inlinecrypt_optimized במקום זאת. אסור להשתמש בדגל הזה באחסון מבוסס-UFS. במפרט UFS מותר להשתמש ב-IVs של 64 ביט.
    • במכשירים שתומכים במפתחות מוצפנים בחומרה, הדגל wrappedkey_v0 מאפשר שימוש במפתחות מוצפנים בחומרה עבור FBE. אפשר להשתמש באפשרות הזו רק בשילוב עם אפשרות ההרכבה inlinecrypt ועם הדגל inlinecrypt_optimized או emmc_optimized.
    • הדגל dusize_4k מאלץ את גודל יחידת נתוני ההצפנה להיות 4,096 בייט, גם אם גודל הבלוק של מערכת הקבצים הוא לא 4,096 בייט. גודל יחידת נתוני ההצפנה הוא רמת הפירוט של הצפנת תוכן הקובץ. הדגל הזה זמין החל מ-Android 15. אפשר להשתמש בדגל הזה רק כדי להפעיל שימוש בחומרה להצפנה מוטבעת שלא תומכת ביחידות נתונים גדולות מ-4,096 בייט, במכשיר שמשתמש בגודל דף גדול מ-4,096 בייט ומשתמש במערכת הקבצים f2fs.

אם אתם לא משתמשים בחומרה להצפנה מוטבעת, ההגדרה המומלצת לרוב המכשירים היא fileencryption=aes-256-xts. אם אתם משתמשים בחומרה להצפנה מוטבעת, ההגדרה המומלצת לרוב המכשירים היא fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized (או fileencryption=::inlinecrypt_optimized). במכשירים ללא האצת AES מכל סוג, אפשר להשתמש ב-Adiantum במקום ב-AES על ידי הגדרת fileencryption=adiantum.

החל מ-Android מגרסה 14, ‏ AES-HCTR2 הוא מצב ההצפנה המועדף של שמות קבצים במכשירים עם הוראות קריפטוגרפיה מואצת. עם זאת, רק ליבות חדשות יותר של Android תומכות ב-AES-HCTR2. בגרסת Android עתידית, מתוכנן שהמצב הזה יהפוך למצב ברירת המחדל להצפנת שמות קבצים. אם הליבה שלכם תומכת ב-AES-HCTR2, אפשר להפעיל אותה להצפנת שמות קבצים על ידי הגדרת filenames_encryption_mode ל-aes-256-hctr2. במקרה הפשוט ביותר, הפעולה הזו תתבצע באמצעות fileencryption=aes-256-xts:aes-256-hctr2.

במכשירים שהושקו עם Android גרסה 10 ומטה, אפשר להשתמש גם ב-fileencryption=ice כדי לציין את השימוש במצב ההצפנה של תוכן הקובץ FSCRYPT_MODE_PRIVATE. המצב הזה לא מיושם בליבות המשותפות של Android, אבל ספקים יכולים ליישם אותו באמצעות תיקונים מותאמים אישית של הליבה. הפורמט בדיסק שנוצר במצב הזה היה ספציפי לספק. במכשירים שמופעלת בהם מערכת Android מגרסה 11 ואילך, אי אפשר יותר להשתמש במצב הזה, וצריך להשתמש במקום זאת בפורמט הצפנה רגיל.

כברירת מחדל, הצפנת תוכן הקובץ מתבצעת באמצעות API להצפנה של ליבת Linux. אם רוצים להשתמש בחומרה להצפנה מוטבעת, צריך להוסיף גם את אפשרות ההרכבה inlinecrypt. לדוגמה, שורה מלאה של fstab יכולה להיראות כך:

/dev/block/by-name/userdata /data f2fs nodev,noatime,nosuid,errors=panic,inlinecrypt wait,fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized

אחסון שניתן להתאמה

מאז Android 9, אפשר להשתמש ב-FBE ובאחסון גמיש ביחד.

ציון האפשרות fileencryption fstab עבור userdata גם מפעיל באופן אוטומטי את FBE וגם את הצפנת המטא-נתונים באחסון הניתן להעברה. עם זאת, אפשר לשנות את הפורמטים של הצפנת FBE או מטא-נתונים באחסון הניתן להעברה על ידי הגדרת מאפיינים ב-PRODUCT_PROPERTY_OVERRIDES.

במכשירים שהושקו עם Android 11 ומעלה, משתמשים במאפיינים הבאים:

  • ro.crypto.volume.options (חדש ב-Android 11) בוחר בפורמט ההצפנה FBE באחסון מותאם. התחביר שלו זהה לתחביר של הארגומנט באפשרות fileencryption fstab, והוא משתמש באותם ערכי ברירת מחדל. ההמלצות לשימוש ב-fileencryption מפורטות למעלה.
  • ro.crypto.volume.metadata.encryption בוחר את פורמט ההצפנה של המטא-נתונים באחסון מותאם. מידע נוסף זמין במאמרי העזרה בנושא הצפנת מטא-נתונים.

במכשירים שהושקו עם Android מגרסה 10 ומטה, משתמשים במאפיינים הבאים:

  • ro.crypto.volume.contents_mode בוחר את מצב ההצפנה של התוכן. הערך הזה שווה לשדה הראשון שמופרד באמצעות נקודתיים של ro.crypto.volume.options.
  • ro.crypto.volume.filenames_mode בוחר את מצב ההצפנה של שמות הקבצים. הערך הזה שווה לערך בשדה השני שמופרד באמצעות נקודתיים ב-‎ ro.crypto.volume.options, אלא שברירת המחדל במכשירים שהושקו עם Android מגרסה 10 ומטה היא aes-256-heh. ברוב המכשירים, צריך לשנות את ההגדרה ל-aes-256-cts באופן מפורש.
  • ro.crypto.fde_algorithm ו-ro.crypto.fde_sector_size בוחרים את פורמט ההצפנה של המטא-נתונים באחסון המותאם. מידע נוסף זמין במאמרי העזרה בנושא הצפנת מטא-נתונים.

שילוב עם KeyMint

ה-HAL של KeyMint צריך להיות מופעל כחלק מהשיעור early_hal. הסיבה לכך היא ש-FBE דורש ש-KeyMint יהיה מוכן לטפל בבקשות בשלב האתחול post-fs-data, שבו vold מגדיר את המפתחות הראשוניים.

החרגת ספריות

init מחיל את מפתח ה-DE של המערכת על כל הספריות ברמה העליונה של /data, למעט ספריות שחייבות להיות לא מוצפנות, כמו הספרייה שמכילה את מפתח ה-DE של המערכת עצמו וספריות שמכילות ספריות CE או DE של משתמשים. מפתחות ההצפנה מוחלים באופן רקורסיבי, ואי אפשר לבטל אותם באמצעות ספריות משנה.

ב-Android מגרסה 11 ואילך, אפשר לשלוט במפתח init שחל על ספריות באמצעות הארגומנט encryption=<action> לפקודה mkdir בסקריפטים של init. הערכים האפשריים של <action> מתועדים בקובץ ה-README של שפת ההפעלה של Android.

ב-Android 10, פעולות ההצפנה initהיו מוצפנות במיקום הבא:

/system/extras/libfscrypt/fscrypt_init_extensions.cpp

ב-Android מגרסה 9 ומטה, המיקום היה:

/system/extras/ext4_utils/ext4_crypt_init_extensions.cpp

אפשר להוסיף חריגים כדי למנוע הצפנה של ספריות מסוימות. אם מתבצעים שינויים מהסוג הזה, יצרן המכשיר צריך לכלול כללי מדיניות של SELinux שמעניקים גישה רק לאפליקציות שצריכות להשתמש בספרייה הלא מוצפנת. הפעולה הזו אמורה להחריג את כל האפליקציות שלא בוטחות.

תרחיש השימוש היחיד הידוע שבו השימוש הזה מקובל הוא תמיכה ביכולות OTA מדור קודם.

תמיכה בהפעלה ישירה באפליקציות מערכת

הגדרת אפליקציות כך שיתמכו בהפעלה ישירה

כדי להקל על העברה מהירה של אפליקציות מערכת, יש שני מאפיינים חדשים שאפשר להגדיר ברמת האפליקציה. המאפיין defaultToDeviceProtectedStorage זמין רק באפליקציות מערכת. המאפיין directBootAware זמין לכולם.

<application
    android:directBootAware="true"
    android:defaultToDeviceProtectedStorage="true">

המאפיין directBootAware ברמת האפליקציה הוא קיצור דרך לסימון כל הרכיבים באפליקציה כרכיבים שתומכים בהצפנה.

המאפיין defaultToDeviceProtectedStorage מפנה את מיקום האחסון של האפליקציה שמוגדר כברירת מחדל לאחסון DE במקום לאחסון CE. אפליקציות מערכת שמשתמשות בדגל הזה צריכות לבדוק בקפידה את כל הנתונים שמאוחסנים במיקום ברירת המחדל, ולשנות את הנתיבים של נתונים רגישים כדי להשתמש באחסון CE. יצרני מכשירים שמשתמשים באפשרות הזו צריכים לבדוק בקפידה את הנתונים שהם מאחסנים כדי לוודא שהם לא מכילים מידע אישי.

כשמפעילים את המצב הזה, ממשקי ה-API הבאים של המערכת זמינים לניהול מפורש של הקשר שמגובה באחסון CE כשצריך, והם מקבילים לממשקי ה-API המקבילים שלהם שמוגנים על ידי המכשיר.

  • Context.createCredentialProtectedStorageContext()
  • Context.isCredentialProtectedStorage()

תמיכה בכמה משתמשים

כל משתמש בסביבה מרובת משתמשים מקבל מפתח הצפנה נפרד. כל משתמש מקבל שני מפתחות: מפתח DE ומפתח CE. משתמש 0 חייב להיכנס למכשיר קודם כי הוא משתמש מיוחד. ההגדרה הזו רלוונטית לשימוש בניהול מכשירים.

אפליקציות עם מודעות להצפנה יוצרות אינטראקציה בין משתמשים באופן הבא: INTERACT_ACROSS_USERS ו-INTERACT_ACROSS_USERS_FULL מאפשרות לאפליקציה לפעול אצל כל המשתמשים במכשיר. עם זאת, לאפליקציות האלה יש גישה רק לספריות מוצפנות ב-CE של משתמשים שכבר ביטלו את הנעילה.

יכול להיות שאפליקציה תוכל ליצור אינטראקציה חופשית בכל האזורים של פרופיל העבודה, אבל אם משתמש אחד ביטל את הנעילה, זה לא אומר שכל המשתמשים במכשיר ביטלו את הנעילה. האפליקציה צריכה לבדוק את הסטטוס הזה לפני שהיא מנסה לגשת לאזורים האלה.

לכל מזהה משתמש בפרופיל העבודה יש גם שני מפתחות: DE ו-CE. כשמבצעים את האתגר של פרופיל העבודה, הנעילה של המשתמש בפרופיל מבוטלת ו-KeyMint (ב-TEE) יכול לספק את מפתח ה-TEE של הפרופיל.

טיפול בעדכונים

מחיצת השחזור לא יכולה לגשת לאחסון שלא מוגן על ידי DE במחיצת userdata. מומלץ מאוד שמכשירים שמטמיעים FBE יתמכו בעדכוני OTA באמצעות עדכוני מערכת A/B. אפשר להחיל את העדכון דרך האוויר במהלך פעולה רגילה, ולכן אין צורך בשחזור כדי לגשת לנתונים בכונן המוצפן.

כשמשתמשים בפתרון OTA מדור קודם, שדורש שחזור כדי לגשת לקובץ ה-OTA במחיצה userdata:

  1. יוצרים ספרייה ברמה העליונה (לדוגמה, misc_ne) במחיצה userdata.
  2. מגדירים את הספרייה ברמה העליונה כך שלא תהיה מוצפנת (ראו החרגת ספריות).
  3. יוצרים ספרייה בתוך הספרייה ברמה העליונה כדי לאחסן חבילות OTA.
  4. מוסיפים כלל SELinux והקשרים של קבצים כדי לשלוט בגישה לספרייה הזו ולתוכן שלה. רק התהליך או האפליקציות שמקבלים עדכוני OTA יכולים לקרוא ולכתוב בספרייה הזו. לאף אפליקציה או תהליך אחרים לא אמורה להיות גישה לספרייה הזו.

אימות

כדי לוודא שהגרסה שהוטמעה של התכונה פועלת כמצופה, קודם מריצים את בדיקות ההצפנה הרבות של CTS, כמו DirectBootHostTest ו-EncryptionTest.

אם במכשיר מותקנת Android מגרסה 11 ואילך, מריצים גם את הפקודה vts_kernel_encryption_test:

atest vts_kernel_encryption_test

או:

vts-tradefed run vts -m vts_kernel_encryption_test

בנוסף, יצרני מכשירים יכולים לבצע את הבדיקות הידניות הבאות. במכשיר שבו מופעלת הצפנה מבוססת-קובץ (FBE):

  • בודקים ש-ro.crypto.state קיים
    • מוודאים ש-ro.crypto.state מוצפן
  • בודקים ש-ro.crypto.type קיים
    • מוודאים שהאפשרות ro.crypto.type מוגדרת לfile

בנוסף, בודקים יכולים לוודא שאחסון CE נעול לפני שהמכשיר נפתח בפעם הראשונה מאז ההפעלה. כדי לעשות את זה, משתמשים בגרסת userdebug או eng, מגדירים קוד אימות, קו ביטול נעילה או סיסמה למשתמש הראשי ומפעילים מחדש את המכשיר. לפני שמבטלים את הנעילה של המכשיר, מריצים את הפקודה הבאה כדי לבדוק את אחסון ה-CE של המשתמש הראשי. אם המכשיר משתמש במצב משתמש במערכת ללא GUI (ברוב המכשירים לרכב), המשתמש הראשי הוא משתמש 10, ולכן מריצים את הפקודה:

adb root; adb shell ls /data/user/10

במכשירים אחרים (רוב המכשירים שאינם Automotive), המשתמש הראשי הוא משתמש 0, ולכן מריצים:

adb root; adb shell ls /data/user/0

מוודאים ששמות הקבצים שמופיעים ברשימה מקודדים ב-Base64, מה שמצביע על כך ששמות הקבצים מוצפנים ושהמפתח לפענוח שלהם עדיין לא זמין. אם שמות הקבצים מופיעים בטקסט רגיל, יש בעיה.

יצרני מכשירים מוזמנים גם לבדוק את האפשרות להריץ במכשירים או בקרנלים שלהם את הבדיקות של fscrypt ב-Linux. הבדיקות האלה הן חלק מחבילת הבדיקות של מערכת הקבצים xfstests. עם זאת, בדיקות במעלה הזרם האלה לא נתמכות רשמית על ידי Android.

פרטי ההטמעה ב-AOSP

בקטע הזה מפורטים פרטים על ההטמעה של AOSP ומוסבר איך פועלת הצפנה מבוססת-קבצים. יצרני מכשירים לא צריכים לבצע שינויים כדי להשתמש בהצפנה ברמת הקובץ (FBE) ובאתחול ישיר במכשירים שלהם.

הצפנת fscrypt

ההטמעה ב-AOSP משתמשת בהצפנה מסוג fscrypt (שנתמכת על ידי ext4 ו-f2fs) בקרנל, ובדרך כלל היא מוגדרת כך:

  • הצפנת תוכן הקובץ באמצעות AES-256 במצב XTS
  • הצפנת שמות קבצים באמצעות AES-256 במצב CBC-CTS

יש גם תמיכה בהצפנת Adiantum. כשההצפנה באמצעות Adiantum מופעלת, גם תוכן הקובץ וגם שמות הקבצים מוצפנים באמצעות Adiantum.

‫fscrypt תומך בשתי גרסאות של מדיניות הצפנה: גרסה 1 וגרסה 2. גרסה 1 הוצאה משימוש, והדרישות של CDD למכשירים שמופעלת בהם מערכת Android מגרסה 11 ואילך תואמות רק לגרסה 2. מדיניות הצפנה מגרסה 2 משתמשת ב-HKDF-SHA512 כדי לגזור את מפתחות ההצפנה בפועל מהמפתחות שסופקו על ידי מרחב המשתמש.

מידע נוסף על fscrypt זמין במסמכי התיעוד של ליבת ה-upstream.

סוגי אחסון (storage classes)

בטבלה הבאה מפורטים מפתחות ה-FBE והספריות שהם מגנים עליהן:

סוג אחסון (storage class) תיאור מדריכים
ללא הצפנה ספריות ב-/data שלא ניתן להגן עליהן באמצעות FBE או שאין צורך להגן עליהן באמצעות FBE. במכשירים שבהם נעשה שימוש בהצפנת מטא-נתונים, הספריות האלה לא באמת לא מוצפנות, אלא מוגנות על ידי המפתח להצפנת מטא-נתונים, ששווה להצפנת המערכת.
  • /data/apex, לא כולל /data/apex/decompressed וגם /data/apex/ota_reserved שהם מערכת DE
  • /data/lost+found
  • /data/preloads
  • /data/unencrypted
  • כל הספריות שספריות המשנה שלהן משתמשות במפתחות שונים של FBE. לדוגמה, מכיוון שכל ספרייה /data/user/${user_id} משתמשת במפתח לכל משתמש, /data/user לא משתמשת במפתח בעצמה.
System DE נתונים מוצפנים במכשיר שלא מקושרים למשתמש מסוים
  • /data/apex/decompressed
  • /data/apex/ota_reserved
  • /data/app
  • /data/misc
  • /data/system
  • /data/vendor
  • כל שאר תיקיות המשנה של /data שלא מוזכרות בטבלה הזו כבעלות סיווג שונה
לכל אתחול קבצים זמניים של המערכת שלא צריכים לשרוד הפעלה מחדש /data/per_boot
משתמש CE (פנימי) נתונים מוצפנים באמצעות אישורים לכל משתמש באחסון הפנימי
  • /data/data (כתובת אימייל חלופית של /data/user/0)
  • /data/media/${user_id}
  • /data/misc_ce/${user_id}
  • /data/system_ce/${user_id}
  • /data/user/${user_id}
  • /data/vendor_ce/${user_id}
משתמש DE (פנימי) נתונים מוצפנים במכשיר לפי משתמש באחסון הפנימי
  • /data/misc_de/${user_id}
  • /data/system_de/${user_id}
  • /data/user_de/${user_id}
  • /data/vendor_de/${user_id}
משתמש CE (ניתן להטמעה) נתונים מוצפנים באמצעות אישורים לכל משתמש באחסון שניתן להתאמה
  • /mnt/expand/${volume_uuid}/media/${user_id}
  • /mnt/expand/${volume_uuid}/misc_ce/${user_id}
  • /mnt/expand/${volume_uuid}/user/${user_id}
משתמש DE (ניתן להעברה) נתונים מוצפנים במכשיר לכל משתמש באחסון שאפשר להעברה
  • /mnt/expand/${volume_uuid}/misc_de/${user_id}
  • /mnt/expand/${volume_uuid}/user_de/${user_id}

אחסון והגנה על מפתחות

כל מפתחות ה-FBE מנוהלים על ידי vold ומאוחסנים בצורה מוצפנת בדיסק, למעט המפתח לכל אתחול שלא מאוחסן בכלל. בטבלה הבאה מפורטים המיקומים שבהם מאוחסנים המפתחות השונים של FBE:

סוג מפתח מיקום המפתח סוג האחסון (storage class) של מיקום המפתח
מפתח DE של המערכת /data/unencrypted ללא הצפנה
מפתחות של משתמשים ב-CE (פנימיים) /data/misc/vold/user_keys/ce/${user_id} System DE
מפתחות של משתמש DE (פנימיים) /data/misc/vold/user_keys/de/${user_id} System DE
מפתחות CE (ניתנים להעברה) של משתמשים /data/misc_ce/${user_id}/vold/volume_keys/${volume_uuid} משתמש CE (פנימי)
מפתחות DE (ניתנים להעברה) של משתמשים /data/misc_de/${user_id}/vold/volume_keys/${volume_uuid} משתמש DE (פנימי)

כפי שמוצג בטבלה שלמעלה, רוב מפתחות ה-FBE מאוחסנים בספריות שמוצפנות על ידי מפתח FBE אחר. אי אפשר לבטל את הנעילה של מפתחות עד שמבטלים את הנעילה של סוג האחסון שמכיל אותם.

vold גם מחיל שכבת הצפנה על כל מפתחות ה-FBE. כל מפתח, מלבד מפתחות CE לאחסון פנימי, מוצפן באמצעות AES-256-GCM עם מפתח Keystore משלו שלא נחשף מחוץ ל-TEE. כך מוודאים שאי אפשר לבטל את הנעילה של מפתחות FBE אלא אם מערכת הפעלה מהימנה הופעלה, כפי שנאכף על ידי הפעלה מאומתת. נדרשת גם עמידות בפני חזרה לגרסה קודמת במפתח Keystore, שמאפשר למחוק בצורה מאובטחת מפתחות FBE במכשירים שבהם KeyMint תומך בעמידות בפני חזרה לגרסה קודמת. כגיבוי במקרה שאי אפשר לבצע שחזור, נעשה שימוש בגיבוב SHA-512 של 16,384 בייטים אקראיים שמאוחסנים בקובץ secdiscardable שמאוחסן לצד המפתח כ-Tag::APPLICATION_ID של מפתח Keystore. כדי לשחזר מפתח FBE, צריך לשחזר את כל הבייטים האלה.

מפתחות CE לאחסון פנימי מקבלים רמת הגנה חזקה יותר שמבטיחה שלא ניתן לבטל את הנעילה שלהם בלי לדעת את גורם הידע של מסך הנעילה (LSKF) של המשתמש (קוד אימות, קו ביטול נעילה או סיסמה), אסימון מאובטח לאיפוס קוד הגישה, או את המפתחות בצד הלקוח ובצד השרת לפעולת המשך לאחר הפעלה מחדש. אפשר ליצור אסימונים לאיפוס קוד הגישה רק עבור פרופילים של עבודה ומכשירים שמנוהלים באופן מלא.

כדי לעשות את זה, vold מצפין כל מפתח CE לאחסון פנימי באמצעות מפתח AES-256-GCM שנגזר מהסיסמה הסינתטית של המשתמש. הסיסמה הסינתטית היא סוד קריפטוגרפי בלתי ניתן לשינוי עם אנטרופיה גבוהה, שנוצר באופן אקראי לכל משתמש. ‫LockSettingsService ב-system_server מנהל את הסיסמה הסינתטית ואת הדרכים שבהן היא מוגנת.

כדי להגן על הסיסמה הסינתטית באמצעות LSKF,‏ LockSettingsService קודם כל מתבצעת הרחבה של LSKF באמצעות העברה דרך scrypt, במטרה להגיע לזמן של כ-25 אלפיות השנייה ולשימוש בזיכרון של כ-2 מיגה-בייט. מכיוון שמפתחות LSKF הם בדרך כלל קצרים, השלב הזה בדרך כלל לא מספק אבטחה רבה. שכבת האבטחה העיקרית היא Secure Element (SE) או הגבלת קצב העברת הנתונים (rate limiting) שמופעלת על ידי TEE, כפי שמתואר בהמשך.

אם במכשיר יש רכיב מאובטח (SE), המערכת LockSettingsService ממפה את ה-LSKF המורחב לסוד אקראי עם אנטרופיה גבוהה שמאוחסן ב-SE באמצעות Weaver HAL. ‫LockSettingsService מצפין את הסיסמה הסינתטית פעמיים: קודם באמצעות מפתח תוכנה שנגזר מ-LSKF המורחב ומסוד Weaver, ושנית באמצעות מפתח Keystore שלא קשור לאימות. ההגבלה הזו מונעת ניסיונות ניחוש של LSKF על ידי SE.

אם למכשיר אין SE, ‏ LockSettingsService משתמש במקום זאת ב-LSKF המורחב כסיסמה של Gatekeeper. ‫LockSettingsService ואז מצפין את הסיסמה הסינתטית פעמיים: קודם עם מפתח תוכנה שנגזר מה-LSKF המורחב ומהגיבוב של קובץ שאפשר למחוק, ושנית עם מפתח של מאגר המפתחות שקשור לרישום ב-Gatekeeper. ההגבלה הזו מופעלת על ידי TEE כדי להגביל את קצב הניסיונות לניחוש מפתחות LSKF.

כשמשנים את LSKF, ‏ LockSettingsService מוחק את כל המידע שמשויך לקשר בין הסיסמה הסינתטית לבין LSKF הישן. במכשירים שתומכים ב-Weaver או במפתחות של Keystore שעמידים בפני חזרה למצב הקודם, הפעולה הזו מבטיחה מחיקה מאובטחת של הקישור הישן. לכן, אמצעי ההגנה שמתוארים כאן מופעלים גם אם למשתמש אין LSKF.