Android מגרסה 7.0 ואילך תומך בהצפנה מבוססת-קובץ (FBE). FBE מאפשר להצפין קבצים שונים באמצעות מפתחות שונים, שאפשר לבטל את הנעילה שלהם בנפרד. המפתחות האלה משמשים להצפנת תוכן הקבצים וגם שמות הקבצים. כשמשתמשים ב-FBE, מידע אחר, כמו פריסות של ספריות, גדלי קבצים, הרשאות וזמנים של יצירה/שינוי, לא מוצפן. המידע הזה נקרא 'מטא-נתונים של מערכת הקבצים'.
בגרסה Android 9 נוספה תמיכה בהצפנת מטא-נתונים. בהצפנת המטא-נתונים, מפתח יחיד שנמצא בזמן האתחול מצפין את כל התוכן שלא מוצפן על ידי FBE. המפתח הזה מוגן על ידי Keymaster, שמוגן בתורו על ידי אתחול מאומת.
הצפנת המטא-נתונים תמיד מופעלת באחסון שניתן לאימוץ כש-FBE מופעל. אפשר להפעיל הצפנה של מטא-נתונים גם באחסון הפנימי. במכשירים שמושקעים עם Android מגרסה 11 ואילך, צריכה להיות מופעלת הצפנת מטא-נתונים באחסון הפנימי.
הטמעה באחסון פנימי
כדי להגדיר הצפנת מטא-נתונים באחסון הפנימי של מכשירים חדשים, צריך להגדיר את מערכת הקבצים metadata
, לשנות את רצף ה-init ולהפעיל את הצפנת המטא-נתונים בקובץ fstab של המכשיר.
דרישות מוקדמות
אפשר להגדיר הצפנה של מטא-נתונים רק בפעם הראשונה שמפורמטים את מחיצה הנתונים. לכן, התכונה הזו מיועדת רק למכשירים חדשים, והיא לא אמורה להשתנות דרך עדכון OTA.
כדי להצפין את המטא-נתונים, צריך להפעיל את המודול dm-default-key
בליבה. ב-Android מגרסה 11 ואילך, dm-default-key
נתמך בליבות הנפוצות של Android, מגרסה 4.14 ואילך. בגרסה הזו של dm-default-key
נעשה שימוש במסגרת הצפנה שאינה תלויה בחומרה ובספק, שנקראת blk-crypto.
כדי להפעיל את dm-default-key
, משתמשים ב-:
CONFIG_BLK_INLINE_ENCRYPTION=y CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y CONFIG_DM_DEFAULT_KEY=y
כשהדבר אפשרי, dm-default-key
משתמש בחומרה להצפנה בתוך שורה (חומרה שמצפינה או מפענחת נתונים בזמן שהם בדרך אל מכשיר האחסון או ממנו). אם אתם לא משתמשים בחומרה של הצפנה מוטמעת, צריך גם להפעיל חזרה ל-API הקריפטוגרפי של הליבה:
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
אם לא משתמשים בחומרה של הצפנה בתוך שורה, צריך גם להפעיל את כל ההאצות הזמינות שמבוססות על מעבד (CPU), כפי שמומלץ במסמכי התיעוד של FBE.
ב-Android 10 ובגרסאות קודמות, הליבה המשותפת של Android לא תמכה ב-dm-default-key
. לכן, הספקים היו צריכים להטמיע את dm-default-key
.
הגדרת מערכת קבצים של מטא-נתונים
מכיוון שאי אפשר לקרוא שום דבר במחיצה של נתוני המשתמש עד שמופיע מפתח ההצפנה של המטא-נתונים, צריך להקצות מחיצה נפרדת בטבלת המחיצות שנקראת 'מחיצה של מטא-נתונים', כדי לאחסן את ה-blobs של Keymaster שמגינים על המפתח הזה. מחיצת המטא-נתונים צריכה להיות בגודל 16MB.
fstab.hardware
חייב לכלול רשומה של מערכת הקבצים של המטא-נתונים שנמצאת במחיצה הזו, שמאחזרת אותה ב-/metadata
, כולל הדגל formattable
כדי לוודא שהיא תפורמט בזמן האתחול. מערכת הקבצים f2fs לא פועלת במחיצות קטנות יותר. מומלץ להשתמש ב-ext4 במקום זאת. לדוגמה:
/dev/block/bootdevice/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard wait,check,formattable
כדי לוודא שנקודה /metadata
קיימת, מוסיפים את השורה הבאה ל-BoardConfig-common.mk
:
BOARD_USES_METADATA_PARTITION := true
שינויים ברצף ה-init
כשמשתמשים בהצפנת מטא-נתונים, צריך להפעיל את vold
לפני שמרכבים את /data
. כדי לוודא שהיא תתחיל מספיק מוקדם, מוסיפים את הבית הבא לקובץ init.hardware.rc
:
# We need vold early for metadata encryption on early-fs start vold
Keymaster צריך לפעול ולהיות מוכן לפני ש-init מנסה לטעון את /data
.
init.hardware.rc
כבר צריך להכיל הוראה mount_all
שמרכיבה את /data
בעצמה בסטנזה on
late-fs
. לפני השורה הזו, מוסיפים את ההוראה להפעלת השירות wait_for_keymaster
:
on late-fs … # Wait for keymaster exec_start wait_for_keymaster # Mount RW partitions which need run fsck mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --late
הפעלת הצפנת המטא-נתונים
לבסוף, מוסיפים את keydirectory=/metadata/vold/metadata_encryption
לעמודה fs_mgr_flags של הערך fstab
עבור userdata
. לדוגמה, שורה מלאה ב-fstab עשויה להיראות כך:
/dev/block/bootdevice/by-name/userdata /data f2fs noatime,nosuid,nodev,discard,inlinecrypt latemount,wait,check,fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized,keydirectory=/metadata/vold/metadata_encryption,quota,formattable
כברירת מחדל, אלגוריתם ההצפנה של המטא-נתונים באחסון הפנימי הוא AES-256-XTS. אפשר לשנות את ההגדרה הזו על ידי הגדרת האפשרות metadata_encryption
גם בעמודה fs_mgr_flags:
- במכשירים שאין בהם האצה של AES, אפשר להפעיל את הצפנת Adiantum באמצעות ההגדרה
metadata_encryption=adiantum
. - במכשירים שתומכים במפתחות מוצפנים בחומרה, אפשר להגדיר את המפתח להצפנת המטא-נתונים כמפתח מוצפן בחומרה על ידי הגדרת הערך
metadata_encryption=aes-256-xts:wrappedkey_v0
(או הערך המקבילmetadata_encryption=:wrappedkey_v0
, כיaes-256-xts
הוא אלגוריתם ברירת המחדל).
מאחר שממשק הליבה ל-dm-default-key
השתנה ב-Android 11, צריך גם לוודא שהגדרתם את הערך הנכון ל-PRODUCT_SHIPPING_API_LEVEL
ב-device.mk
. לדוגמה, אם המכשיר מופעל עם Android 11 (רמת API 30), השדה device.mk
צריך להכיל את הפרטים הבאים:
PRODUCT_SHIPPING_API_LEVEL := 30
אפשר גם להגדיר את מאפיין המערכת הבא כדי לאלץ את השימוש ב-API החדש dm-default-key
ללא קשר לרמת ה-Shipping API:
PRODUCT_PROPERTY_OVERRIDES += \ ro.crypto.dm_default_key.options_format.version=2
אימות
כדי לוודא שהצפנת המטא-נתונים מופעלת ופועלת כמו שצריך, מריצים את הבדיקות שמתוארות בהמשך. חשוב גם לשים לב לבעיות הנפוצות שמתוארות בהמשך.
בדיקות
מתחילים בהרצת הפקודה הבאה כדי לוודא שהצפנת המטא-נתונים מופעלת באחסון הפנימי:
adb root
adb shell dmctl table userdata
הפלט אמור להיראות כך:
Targets in the device-mapper table for userdata: 0-4194304: default-key, aes-xts-plain64 - 0 252:2 0 3 allow_discards sector_size:4096 iv_large_sectors
אם שיניתם את הגדרות ברירת המחדל של ההצפנה על ידי הגדרת האפשרות metadata_encryption
בקובץ fstab
של המכשיר, הפלט יהיה שונה במקצת מהקודם. לדוגמה, אם הפעלתם את הצפנת Adiantum, השדה השלישי יהיה xchacha12,aes-adiantum-plain64
במקום aes-xts-plain64
.
לאחר מכן, מריצים את vts_kernel_encryption_test כדי לוודא שההצפנה של המטא-נתונים ו-FBE תקינים:
atest vts_kernel_encryption_test
או:
vts-tradefed run vts -m vts_kernel_encryption_test
בעיות נפוצות
במהלך הקריאה ל-mount_all
, שמטמיעה את המחיצה /data
שמוגדרת בהצפנת מטא-נתונים, init
מפעיל את הכלי vdc. הכלי vdc מתחבר ל-vold
דרך binder
כדי להגדיר את המכשיר עם ההצפנה של המטא-נתונים ולטעון את המחיצה. למשך כל הקריאה, init
נחסם, וניסיון לקרוא או להגדיר את המאפיינים של init
ייחסם עד ש-mount_all
יסתיים.
אם בשלב הזה חלק כלשהו מהעבודה של vold
חסום באופן ישיר או עקיף בקריאה או בהגדרה של נכס, נוצר נעילה מרובת משתתפים. חשוב לוודא ש-vold
יכול להשלים את העבודה של קריאת המפתחות, האינטראקציה עם Keymaster והרכבת ספריית הנתונים בלי אינטראקציה נוספת עם init
.
אם Keymaster לא מופעל במלואו כשהפעולה mount_all
פועלת, הוא לא מגיב ל-vold
עד שהוא קורא מאפיינים מסוימים מ-init
, וכתוצאה מכך נוצרת בדיוק נקודת הקיפאון המתוארת. הצבת exec_start wait_for_keymaster
מעל להפעלה הרלוונטית של mount_all
, כפי שמתואר, מבטיחה ש-Keymaster יפעל במלואו מראש, וכך ימנע את התקיעה.
הגדרה של אחסון שניתן להתאמה
מאז Android 9, תמיד מופעלת צורה כלשהי של הצפנת מטא-נתונים באחסון מתאים כש-FBE מופעל, גם אם הצפנת המטא-נתונים לא מופעלת באחסון הפנימי.
ב-AOSP יש שתי הטמעות של הצפנת מטא-נתונים באחסון מתאים: הטמעה שהוצאה משימוש שמבוססת על dm-crypt
, והטמעה חדשה יותר שמבוססת על dm-default-key
. כדי לוודא שבחרתם את ההטמעה המתאימה למכשיר, חשוב לוודא שהגדרתם את הערך הנכון של PRODUCT_SHIPPING_API_LEVEL
בקובץ device.mk
. לדוגמה, אם המכשיר מופעל עם Android 11 (רמת API 30), השדה device.mk
צריך להכיל את הפרטים הבאים:
PRODUCT_SHIPPING_API_LEVEL := 30
אפשר גם להגדיר את מאפייני המערכת הבאים כדי לאלץ את השימוש בשיטת ההצפנה החדשה של מטא-נתונים בנפח (וגם בגרסה החדשה של מדיניות ברירת המחדל של FBE), ללא קשר לרמת ה-API למשלוח:
PRODUCT_PROPERTY_OVERRIDES += \ ro.crypto.volume.metadata.method=dm-default-key \ ro.crypto.dm_default_key.options_format.version=2 \ ro.crypto.volume.options=::v2
השיטה הנוכחית
במכשירים שמריצים Android מגרסה 11 ואילך, ההצפנה של המטא-נתונים באחסון שניתן להתאמה מתבצעת באמצעות מודול הליבה dm-default-key
, בדיוק כמו באחסון הפנימי. בדרישויות המוקדמות שלמעלה מפורטות אפשרויות ההגדרה של הליבה שצריך להפעיל. חשוב לזכור שחומרת הצפנה בקוד שעובדת באחסון הפנימי של המכשיר עשויה להיות לא זמינה באחסון שניתן להתאמה, ולכן יכול להיות שיהיה צורך ב-CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
.
כברירת מחדל, שיטת ההצפנה של המטא-נתונים של נפח dm-default-key
מתבססת על אלגוריתם ההצפנה AES-256-XTS עם פלחי קריפטוגרפיה בגודל 4096 בייטים. אפשר לשנות את האלגוריתם על ידי הגדרת מאפיין המערכת ro.crypto.volume.metadata.encryption
. התחביר של הערך של המאפיין הזה זהה לזה של האפשרות metadata_encryption
ב-fstab שמתוארת למעלה. לדוגמה, במכשירים בלי האצת AES, אפשר להפעיל הצפנת Adiantum באמצעות ההגדרה ro.crypto.volume.metadata.encryption=adiantum
.
שיטת קודמת
במכשירים שהושקעו עם Android מגרסה 10 ומטה, ההצפנה של המטא-נתונים באחסון שניתן להתאמה מתבצעת באמצעות מודול הליבה dm-crypt
במקום dm-default-key
:
CONFIG_DM_CRYPT=y
בניגוד לשיטה dm-default-key
, בשיטה dm-crypt
תוכן הקובץ מוצפן פעמיים: פעם אחת באמצעות מפתח FBE ופעם אחת באמצעות מפתח ההצפנה של המטא-נתונים. ההצפנה הכפולה הזו מורידה את הביצועים, והיא לא נדרשת כדי להשיג את יעדי האבטחה של הצפנת המטא-נתונים, כי Android מבטיחה שקשה לפרוץ למפתחות FBE לפחות כמו למפתח ההצפנה של המטא-נתונים. ספקים יכולים לבצע התאמות אישיות של הליבה כדי להימנע מההצפנה הכפולה, במיוחד על ידי הטמעת האפשרות allow_encrypt_override
שמערכת Android מעבירה ל-dm-crypt
כשמאפיין המערכת ro.crypto.allow_encrypt_override
מוגדר ל-true
.
הליבה המשותפת של Android לא תומכת בהתאמות אישיות כאלה.
כברירת מחדל, שיטת ההצפנה של המטא-נתונים של נפח האחסון dm-crypt
משתמשת באלגוריתם ההצפנה AES-128-CBC עם ESSIV וקטעי קריפטוגרפיה של 512 בייטים. אפשר לשנות את ההגדרה הזו על ידי הגדרת מאפייני המערכת הבאים (שמשמשים גם ל-FDE):
ro.crypto.fde_algorithm
בוחר את אלגוריתם ההצפנה של המטא-נתונים. האפשרויות הןaes-128-cbc
ו-adiantum
. אפשר להשתמש ב-Adiantum רק אם במכשיר אין האצה של AES.ro.crypto.fde_sector_size
בוחרת את הגודל של סקטור הקריפטו. האפשרויות הן 512, 1024, 2048 ו-4096. להצפנה של Adiantum, צריך להשתמש ב-4096.