Android מגרסה 7.0 ואילך תומך בהצפנה מבוססת-קובץ (FBE). הצפנה מבוססת-קובץ מאפשרת להצפין קבצים שונים באמצעות מפתחות שונים, שאפשר לבטל את הנעילה שלהם בנפרד.
במאמר הזה נסביר איך מפעילים הצפנה מבוססת-קובץ במכשירים חדשים, ואיך אפליקציות מערכת יכולות להשתמש בממשקי Direct Boot API כדי לספק למשתמשים את החוויה הטובה והבטוחה ביותר.
כל המכשירים שיושקו עם Android מגרסה 10 ואילך חייבים להשתמש בהצפנה מבוססת-קובץ.
Direct Boot
הצפנה מבוססת-קובץ מאפשרת להשתמש בתכונה חדשה שהושקה ב-Android 7.0 שנקראת Direct Boot. הפעלה ישירה מאפשרת למכשירים מוצפנים להפעיל את עצמם ישירות למסך הנעילה. בעבר, במכשירים מוצפנים באמצעות הצפנת דיסק מלאה (FDE), המשתמשים היו צריכים לספק פרטי כניסה כדי לגשת לנתונים, וכך למנוע מהטלפון לבצע את כל הפעולות מלבד הפעולות הבסיסיות ביותר. לדוגמה, לא ניתן היה להפעיל את ההתראות, שירותי הנגישות לא היו זמינים והטלפונים לא יכלו לקבל שיחות, אלא רק לבצע פעולות בסיסיות של חיוג למקרה חירום.
בעקבות ההשקה של הצפנה מבוססת-קובץ (FBE) וממשקי API חדשים שמאפשרים לאפליקציות לזהות את ההצפנה, האפליקציות האלה יכולות לפעול בהקשר מוגבל. זה יכול לקרות לפני שהמשתמשים סיפקו את פרטי הכניסה שלהם, תוך שמירה על פרטי המשתמשים הפרטיים.
במכשיר עם תמיכה ב-FBE, לכל משתמש במכשיר יש שני מיקומי אחסון שזמינים לאפליקציות:
- אחסון של פרטי כניסה מוצפנים (CE), שהוא מיקום האחסון שמוגדר כברירת מחדל, וזמין רק אחרי שהמשתמש פותח את נעילת המכשיר.
- אחסון Device Encrypted (DE), שהוא מיקום אחסון שזמין גם במצב Direct Boot וגם אחרי שהמשתמש פותח את נעילת המכשיר.
ההפרדה הזו מאפשרת להגן על יותר ממשתמש אחד בכל פעם, כי ההצפנה כבר לא מבוססת רק על סיסמה בזמן האתחול.
Direct Boot 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) כדי לספק הגנה למפתחות ה-DE, כך שמערכת הפעלה לא מורשית (מערכת הפעלה מותאמת אישית שנדלקה במכשיר) לא תוכל לבקש את מפתחות ה-DE בקלות.
- כדי לוודא שלמערכת הפעלה לא מורשית לא תהיה גישה למפתחות DE, נדרשים Root of Trust בחומרה ואתחול מאומת שמקושרים לאינטליגנציה של Keymaster.
הטמעה
קודם כול, אפליקציות כמו שעונים מעוררים, טלפון ותכונות נגישות צריכות להיות מוגדרות כ-android:directBootAware בהתאם למסמכי העזרה למפתחים בנושא Direct Boot.
תמיכה בליבה
תמיכה בליבה להצפנת Ext4 ו-F2FS זמינה בליבות הנפוצות של 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 נעשה שימוש בפונקציית הפקת מפתחות מאובטחת וגמישה יותר. ברירת המחדל היא v2 אם המכשיר הושק ב-Android 11 ואילך (כפי שנקבע על ידיro.product.first_api_level
), או v1 אם המכשיר הושק ב-Android 10 ומטה. - הדגל
inlinecrypt_optimized
בוחר פורמט הצפנה שמותאם לחומרה של הצפנה בתוך שורה (inline) שלא מטפלת ביעילות במספרים גדולים של מפתחות. לשם כך, המערכת יוצרת רק מפתח אחד להצפנת תוכן הקובץ לכל מפתח CE או DE, במקום מפתח אחד לכל קובץ. היצירה של IVs (וקטורי אתחול) מותאמת בהתאם. - הדגל
emmc_optimized
דומה לדגלinlinecrypt_optimized
, אבל הוא גם בוחר שיטת יצירת IV שמגבילה את ה-IVs ל-32 ביט. צריך להשתמש בדגל הזה רק בחומרה של הצפנה בתוך שורה שתואמת למפרט JEDEC eMMC v5.2, ולכן תומכת רק ב-IVs של 32 ביט. בחומרה אחרת של הצפנה מוטמעת, צריך להשתמש ב-inlinecrypt_optimized
במקום זאת. אסור להשתמש בדגל הזה באחסון שמבוסס על UFS. מפרט ה-UFS מאפשר להשתמש ב-IVs של 64 ביט. - במכשירים שתומכים במפתחות שמוגדרים בחומרה, הדגל
wrappedkey_v0
מאפשר להשתמש במפתחות שמוגדרים בחומרה ל-FBE. אפשר להשתמש באפשרות הזו רק בשילוב עם אפשרות הטעינהinlinecrypt
, ועם הדגלinlinecrypt_optimized
אוemmc_optimized
. - הדגל
dusize_4k
מאלץ את הגודל של יחידת נתוני ההצפנה להיות 4096 בייטים, גם אם גודל הבלוק של מערכת הקבצים הוא לא 4096 בייטים. גודל יחידת נתוני ההצפנה הוא רמת הפירוט של הצפנת תוכן הקובץ. הדגל הזה זמין החל מגרסה 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
.
החל מגרסה 14 של Android, 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
אחסון שניתן להתאמה
החל מגרסה 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
צריך להפעיל את Keymaster HAL כחלק מהקלאס 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. יצרני המכשירים שמשתמשים באפשרות הזו צריכים לבדוק בקפידה את הנתונים שהם שומרים כדי לוודא שהם לא מכילים מידע אישי.
כשהאפליקציה פועלת במצב הזה, ה-System APIs הבאים זמינים לניהול מפורש של הקשר שמגובה באחסון של CE לפי הצורך, והם מקבילים ל-counterparts שלהם שמוגנים במכשיר.
Context.createCredentialProtectedStorageContext()
Context.isCredentialProtectedStorage()
תמיכה במספר משתמשים
כל משתמש בסביבה עם כמה משתמשים מקבל מפתח הצפנה נפרד. כל משתמש מקבל שני מפתחות: מפתח DE ומפתח CE. משתמש 0 חייב להתחבר למכשיר קודם, כי הוא משתמש מיוחד. ההגדרה הזו רלוונטית לשימוש בניהול מכשירים.
אפליקציות עם תמיכה בקריפטוגרפיה יוצרות אינטראקציה בין משתמשים באופן הבא: INTERACT_ACROSS_USERS
ו-INTERACT_ACROSS_USERS_FULL
מאפשרים לאפליקציה לפעול בכל המשתמשים במכשיר. עם זאת, לאפליקציות האלה יש גישה רק לספריות מוצפנות ב-CE של משתמשים שכבר נפתח הנעילה שלהם.
יכול להיות שאפליקציה תוכל לבצע אינטראקציה באופן חופשי באזורי ה-DE, אבל אם נעילה של משתמש אחד בוטלה, זה לא אומר שנעילה של כל המשתמשים במכשיר בוטלה. האפליקציה צריכה לבדוק את הסטטוס הזה לפני שהיא מנסה לגשת לאזורים האלה.
לכל מזהה משתמש בפרופיל העבודה מוקצים גם שני מפתחות: DE ו-CE. כשהאתגר של העבודה מתקבל, נעילת המשתמש בפרופיל נפתחת ו-Keymaster (ב-TEE) יכול לספק את מפתח ה-TEE של הפרופיל.
טיפול בעדכונים
למחיצה לשחזור אין גישה לאחסון המוגן באמצעות DE במחיצה userdata. מומלץ מאוד שתהיה תמיכה ב-OTA במכשירים שמטמיעים FBE באמצעות עדכוני מערכת A/B. מכיוון שאפשר להחיל את העדכון האווירי במהלך הפעולה הרגילה, אין צורך בשחזור כדי לגשת לנתונים בכונן המוצפן.
כשמשתמשים בפתרון OTA מדור קודם, שדורש שחזור כדי לגשת לקובץ ה-OTA במחיצה userdata
:
- יוצרים ספרייה ברמה העליונה (לדוגמה
misc_ne
) במחיצהuserdata
. - מגדירים את הספרייה ברמה העליונה הזו ללא הצפנה (ראו החרגת ספריות).
- יוצרים ספרייה בתוך הספרייה ברמה העליונה כדי לאחסן חבילות OTA.
- מוסיפים כלל 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 במכשירים או בליבות שלהם. הבדיקות האלה הן חלק מחבילת הבדיקות של מערכת הקבצים xfstests. עם זאת, Android לא תומכת באופן רשמי בבדיקות האלה של קוד מקור.
פרטי ההטמעה ב-AOSP
בקטע הזה מפורטים פרטים על ההטמעה ב-AOSP ומוסבר איך פועלת ההצפנה מבוססת-הקובץ. יצרני המכשירים לא צריכים לבצע שינויים כאן כדי להשתמש ב-FBE וב-Direct Boot במכשירים שלהם.
הצפנת fscrypt
ההטמעה של AOSP משתמשת בהצפנה מסוג 'fscrypt' (שתומכת ב-ext4 וב-f2fs) בליבה, ובדרך כלל מוגדרת כך:
- הצפנת תוכן הקובץ באמצעות AES-256 במצב XTS
- הצפנת שמות קבצים באמצעות AES-256 במצב CBC-CTS
יש גם תמיכה בהצפנת Adiantum. כשההצפנה של Adiantum מופעלת, גם תוכן הקבצים וגם שמות הקבצים מוצפנים באמצעות Adiantum.
fscrypt תומך בשתי גרסאות של מדיניות הצפנה: גרסה 1 וגרסה 2. הגרסה הראשונה הוצאה משימוש, ודרישות ה-CDD למכשירים שמושקעים עם Android מגרסה 11 ואילך תואמות רק לגרסה השנייה. כללי מדיניות ההצפנה של גרסה 2 משתמשים ב-HKDF-SHA512 כדי להפיק את מפתחות ההצפנה בפועל מהמפתחות שסופקו במרחב המשתמש.
מידע נוסף על fscrypt זמין במסמכי התיעוד של הליבה.
סוגי אחסון (storage classes)
בטבלה הבאה מפורטים מפתחות ה-FBE והספריות שהם מגינים עליהן בפירוט:
סוג אחסון (storage class) | תיאור | מדריכים |
---|---|---|
ללא הצפנה | ספריות ב-/data שאי אפשר או שאין צורך להגן עליהן באמצעות FBE. במכשירים שמשתמשים בהצפנת מטא-נתונים, הספריות האלה לא מוצפנות באמת, אלא מוגנות על ידי מפתח ההצפנה של המטא-נתונים, שהוא שווה ערך ל-DE של המערכת. |
|
System DE | נתונים מוצפנים במכשיר שלא מקושרים למשתמש מסוים |
|
לכל הפעלה | קבצי מערכת זמניים שלא צריכים לשרוד הפעלה מחדש | /data/per_boot |
CE של משתמש (פנימי) | נתונים מוצפנים לפי פרטי כניסה של משתמשים באחסון פנימי |
|
משתמש DE (פנימי) | נתונים מוצפנים במכשיר לכל משתמש באחסון הפנימי |
|
CE של משתמש (ניתן לאימוץ) | נתונים מוצפנים של פרטי כניסה לכל משתמש באחסון שניתן להתאמה |
|
משתמש DE (ניתן לאימוץ) | נתונים מוצפנים במכשיר לכל משתמש באחסון שניתן לאימוץ |
|
אחסון והגנה על מפתחות
כל מפתחות ה-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 בצורה מאובטחת במכשירים שבהם 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, כפי שמתואר בהמשך.
אם במכשיר יש רכיב מאובטח (SE), הפונקציה LockSettingsService
ממפה את ה-LSKF המורחב לסוד אקראי בעל אנטרופי גבוה שמאוחסן ב-SE באמצעות Weaver HAL. לאחר מכן, LockSettingsService
מצפין את הסיסמה הסינתטית פעמיים: קודם עם מפתח תוכנה שמבוסס על LSKF המורחב ועל הסוד של Weaver, ולאחר מכן עם מפתח Keystore לא קשור לאימות. כך אפשר להגביל את הקצב של ניחושים של LSKF באמצעות אכיפת SE.
אם אין במכשיר SE, המערכת של LockSettingsService
משתמשת ב-LSKF המותאם כסיסמה של Gatekeeper. לאחר מכן, LockSettingsService
מצפין את הסיסמה הסינתטית פעמיים: קודם עם מפתח תוכנה שמבוסס על ה-LSKF המורחב ועל הגיבוב של קובץ שניתן להשמדה באופן מאובטח, ולאחר מכן עם מפתח Keystore שמקושר לאימות להרשמה ב-Gatekeeper. כך אפשר להגביל את הקצב של ניחושים של LSKF באמצעות אכיפה ב-TEE.
כשמשנים את ה-LSKF, LockSettingsService
מוחקת את כל המידע שמשויך לקישור של הסיסמה הסינתטית ל-LSKF הישן. במכשירים שתומכים במפתחות של Weaver או במפתחות Keystore עמידים בהחזרה למצב הקודם, הפעולה הזו מבטיחה מחיקה מאובטחת של הקישור הישן. לכן, ההגנות שמתוארות כאן חלות גם אם למשתמש אין מפתח LSKF.