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.userdata
userdata
אם המכשיר שלכם תומך באחסון ניתן להרחבה או משתמש בהצפנת מטא-נתונים באחסון הפנימי, צריך להפעיל גם את אפשרויות ההגדרה של ליבת המערכת שנדרשות להצפנת מטא-נתונים, כמו שמתואר במסמכי ההצפנה של מטא-נתונים.
בנוסף לתמיכה פונקציונלית בהצפנת 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
:
- יוצרים ספרייה ברמה העליונה (לדוגמה,
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 של המשתמש הראשי. אם המכשיר משתמש במצב משתמש במערכת ללא 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. במכשירים שבהם נעשה שימוש בהצפנת מטא-נתונים, הספריות האלה לא באמת לא מוצפנות, אלא מוגנות על ידי המפתח להצפנת מטא-נתונים, ששווה להצפנת המערכת. |
|
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 במכשירים שבהם 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.