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