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

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

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

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

הפעלה ישירה

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

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

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

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

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

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

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

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

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

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

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

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

* אפליקציות מערכת שמשתמשות במאפיין המניפסט defaultToDeviceProtectedStorage

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

יחסי תלות

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

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

הטמעה

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

תמיכה בליבה

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

CONFIG_FS_ENCRYPTION=y

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

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

בנוסף לתמיכה פונקציונלית בהצפנת 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. מגרסה 11 של Android אפשר גם להשאיר את השדה ריק כדי לציין את אלגוריתם ברירת המחדל, שהוא 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 של מדיניות ההצפנה משתמשת בפונקציה נגזרת מפתחות מאובטחת וגמישה יותר. ברירת המחדל היא אם המכשיר הופעל ב-Android מגרסה 11 ואילך (כפי שנקבע על ידי ro.product.first_api_level), או 1 אם המכשיר הושק ב-Android 10 ומטה.
    • הדגל inlinecrypt_optimized בוחר פורמט הצפנה שמותאם לחומרה של הצפנה בתוך שורה (inline) שלא מטפלת ביעילות במספרים גדולים של מפתחות. לשם כך, המערכת יוצרת רק מפתח אחד להצפנת תוכן הקובץ לכל מפתח CE או DE, במקום מפתח אחד לכל קובץ. היצירה של IVs (וקטורי אתחול) מותאמת בהתאם.
    • הדגל emmc_optimized דומה ל-inlinecrypt_optimized, אבל הוא בוחר גם בשיטת יצירת IV שמגבילה את ה-IV ל-32 ביט. יש להשתמש בדגל הזה רק בחומרה להצפנה מוטבעת שתואמת למפרט של JEDEC eMMC v5.2 ולכן תומכת רק ברשת IV של 32 ביט. בחומרה אחרת של הצפנה מוטמעת, צריך להשתמש ב-inlinecrypt_optimized במקום זאת. אסור להשתמש בדגל הזה באחסון שמבוסס על UFS. מפרט ה-UFS מאפשר להשתמש ב-IVs של 64 ביט.
    • במכשירים שתומכים במפתחות עטופים בחומרה, הדגל wrappedkey_v0 מאפשר את השימוש במפתחות ארוזים בחומרה ל-FBE. אפשר להשתמש באפשרות הזו רק בשילוב עם אפשרות הטעינה inlinecrypt, ועם הדגל inlinecrypt_optimized או emmc_optimized.
    • הדגל dusize_4k מאלץ את גודל יחידת הנתונים של ההצפנה להיות 4,096 בייט גם כאשר גודל הבלוק של מערכת הקבצים אינו 4,096 בייטים. גודל יחידת הנתונים להצפנה הוא רמת הפירוט של הצפנת תוכן הקובץ. הדגל הזה זמין החל מגרסה 15 של Android. צריך להשתמש בדגל הזה רק כדי לאפשר שימוש בחומרה של הצפנה בתוך שורה שלא תומכת ביחידות נתונים גדולות מ-4096 בייטים, במכשיר שבו גודל הדף גדול מ-4096 בייטים והוא משתמש במערכת הקבצים 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, הוא מתוכנן להפוך למצב ברירת המחדל להצפנת שמות קבצים. אם בליבה (kernel) יש תמיכה ב-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

אחסון מותאם

החל מגרסה 9 של Android, אפשר להשתמש ב-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 בוחרים את הפורמט להצפנת המטא-נתונים באחסון מותאם. קראו את מאמרי העזרה להצפנת מטא-נתונים.

שילוב עם Keymaster

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

החרגת ספריות

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

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

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

/system/extras/libfscrypt/fscrypt_init_extensions.cpp

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

/system/extras/ext4_utils/ext4_crypt_init_extensions.cpp

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

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

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

איך מגדירים לאפליקציות תמיכה ב-Direct Boot

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

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

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

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

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

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

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

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

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

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

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

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

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

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

במכשירים אחרים (רוב המכשירים שאינם לכלי רכב), המשתמש הראשי הוא משתמש 0, ולכן צריך להריץ את הפקודה:

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

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

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

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

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

הצפנת fscrypt

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

  • הצפנת תוכן הקובץ באמצעות 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. במכשירים עם הצפנת מטא-נתונים, הספריות האלה לא מוצפנות באמת. במקום זאת, הן מוגנות באמצעות מפתח ההצפנה של המטא-נתונים, שמקביל ל-System DE.
  • /data/apex, לא כולל /data/apex/decompressed ו-/data/apex/ota_reserved שהם מערכת DE
  • /data/lost+found
  • /data/preloads
  • /data/unencrypted
  • כל הספריות שספריות המשנה שלהן משתמשות במפתחות FBE שונים. לדוגמה, מכיוון שכל ספרייה של /data/user/${user_id} משתמשת במפתח לכל משתמש, ב-/data/user לא נעשה שימוש במפתח.
מערכת 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} מערכת 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 בצורה מאובטחת במכשירים שבהם Keymaster תומך בהתנגדות לשחזור לאחור. כחלופה ללא התחייבות לתוצאה במקרה שההגנה מפני ביטול החזרה לאחור לא זמינה, המערכת משתמשת בגיבוב SHA-512 של 16,384 בייטים אקראיים שמאוחסנים בקובץ secdiscardable ששמור לצד המפתח, בתור תג מזהה האפליקציה של מפתח ה-Keystore. צריך לשחזר את כל הבייטים האלה כדי לשחזר מפתח FBE.

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

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

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

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

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

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