Android מגרסה 7.0 ואילך תומך בהצפנה מבוססת-קובץ (FBE). הצפנה כזו מאפשרת להצפין קבצים שונים באמצעות מפתחות שונים, כך שיהיה אפשר לבטל את הנעילה שלהם בנפרד. המפתחות האלה משמשים להצפנה של תוכן הקובץ וגם של שמות הקבצים. כשמשתמשים ב-FBE, מידע אחר, כמו פריסות של ספריות, גדלים של קבצים, הרשאות וזמני יצירה או שינוי, לא מוצפן. ביחד, המידע הנוסף הזה נקרא מטא-נתונים של מערכת הקבצים.
ב-Android 9 נוספה תמיכה בהצפנת מטא-נתונים. בהצפנת מטא-נתונים, מפתח יחיד שקיים בזמן האתחול מצפין את כל התוכן שלא מוצפן על ידי FBE. המפתח הזה מוגן על ידי KeyMint (לשעבר Keymaster), שמוגן על ידי Verified Boot.
הצפנת מטא-נתונים תמיד מופעלת באחסון שניתן להתאמה כשהצפנת FBE מופעלת. אפשר גם להפעיל הצפנת מטא-נתונים באחסון הפנימי. במכשירים שהושקו עם Android מגרסה 11 ואילך, צריך להפעיל הצפנת מטא-נתונים באחסון הפנימי.
הטמעה באחסון פנימי
כדי להגדיר הצפנת מטא-נתונים באחסון הפנימי של מכשירים חדשים, צריך להגדיר את מערכת הקבצים metadata
, לשנות את רצף ההפעלה ולהפעיל את הצפנת המטא-נתונים בקובץ 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 ומטה, לא הייתה תמיכה ב-dm-default-key
בליבת Android הנפוצה. לכן, היה על הספקים להטמיע את dm-default-key
.
הגדרת מערכת קבצים של מטא-נתונים
מכיוון שאי אפשר לקרוא שום דבר במחיצת נתוני המשתמשים עד שמפתח ההצפנה של המטא-נתונים קיים, בטבלת המחיצות צריך להקצות מחיצה נפרדת שנקראת מחיצת המטא-נתונים לאחסון של ה-blob של KeyMint שמגן על המפתח הזה. מחיצת המטא-נתונים צריכה להיות בגודל 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
שינויים ברצף ההפעלה
כשמשתמשים בהצפנת מטא-נתונים, צריך להפעיל את vold
לפני שמפעילים את /data
. כדי לוודא שההפעלה תתבצע מספיק זמן מראש, מוסיפים את הפסקה הבאה ל-init.hardware.rc
:
# We need vold early for metadata encryption on early-fs start vold
המערכת צריכה להפעיל את KeyMint ולהכין אותה לפני שהיא מנסה להפעיל את /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
, ללא קשר לרמת ה-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
יכול להשלים את הפעולות של קריאת המפתחות, אינטראקציה עם KeyMint והרכבת ספריית הנתונים בלי אינטראקציה נוספת עם init
.
אם KeyMint לא מופעל באופן מלא כשמריצים את mount_all
, הוא לא מגיב ל-vold
עד שהוא קורא מאפיינים מסוימים מ-init
, וכתוצאה מכך נוצר בדיוק מצב הקיפאון שמתואר. הצבת exec_start wait_for_keymaster
מעל הקריאה הרלוונטית ל-mount_all
כפי שמוגדרת מבטיחה ש-KeyMint יפעל באופן מלא מראש, וכך נמנעת חסימה.
הגדרה באחסון שניתן להתאמה
מאז 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 עם מגזרים קריפטוגרפיים של 4,096 בייט. אפשר לשנות את האלגוריתם על ידי הגדרת מאפיין המערכת ro.crypto.volume.metadata.encryption
. התחביר של הערך של המאפיין הזה זהה לזה של אפשרות ה-fstab metadata_encryption
שמתוארת למעלה. לדוגמה, במכשירים שאין בהם האצת 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
שאנדרואיד מעבירה אל dm-crypt
כשמאפיין המערכת ro.crypto.allow_encrypt_override
מוגדר לערך true
.
ההתאמות האישיות האלה לא נתמכות על ידי ליבת Android הנפוצה.
כברירת מחדל, שיטת ההצפנה של מטא-נתונים של נפח dm-crypt
משתמשת באלגוריתם ההצפנה AES-128-CBC עם ESSIV ועם מגזרים קריפטוגרפיים של 512 בייט. אפשר לשנות את ההגדרה הזו על ידי הגדרת מאפייני המערכת הבאים (שמשמשים גם להצפנת נתונים מלאה):
-
ro.crypto.fde_algorithm
בוחרים את אלגוריתם ההצפנה של המטא-נתונים. האפשרויות הןaes-128-cbc
ו-adiantum
. אפשר להשתמש ב-Adiantum רק אם במכשיר אין האצת AES. -
ro.crypto.fde_sector_size
בוחרת את גודל הסקטור המוצפן. האפשרויות הן 512, 1024, 2048 ו-4096. להצפנת Adiantum, משתמשים ב-4096.