Android 7.0 और इसके बाद के वर्शन पर, फ़ाइल-आधारित एन्क्रिप्शन (FBE) की सुविधा काम करती है. एफ़बीई की मदद से, अलग-अलग फ़ाइलों को अलग-अलग कुंजियों से एन्क्रिप्ट किया जा सकता है. साथ ही, उन्हें अलग-अलग अनलॉक किया जा सकता है. इन कुंजियों का इस्तेमाल, फ़ाइल के कॉन्टेंट और फ़ाइल के नाम, दोनों को एन्क्रिप्ट (सुरक्षित) करने के लिए किया जाता है. एफ़बीई का इस्तेमाल करने पर, डायरेक्ट्री लेआउट, फ़ाइल का साइज़, अनुमतियां, और बनाने/बदलाव करने का समय जैसी अन्य जानकारी एन्क्रिप्ट नहीं की जाती. इस तरह की अन्य जानकारी को फ़ाइल सिस्टम मेटाडेटा कहा जाता है.
Android 9 में, मेटाडेटा एन्क्रिप्ट (सुरक्षित) करने की सुविधा जोड़ी गई है. मेटाडेटा एन्क्रिप्ट (सुरक्षित) करने के तरीके से, बूट के समय मौजूद एक कुंजी ही उस कॉन्टेंट को एन्क्रिप्ट (सुरक्षित) करती है जिसे एफ़बीई ने एन्क्रिप्ट (सुरक्षित) नहीं किया है. इस कुंजी को Keymaster की मदद से सुरक्षित किया जाता है. Keymaster को, पुष्टि किए गए बूट की मदद से सुरक्षित किया जाता है.
एफ़बीई चालू होने पर, अडॉप्ट किए जा सकने वाले स्टोरेज पर मेटाडेटा एन्क्रिप्शन हमेशा चालू रहता है. मेटाडेटा एन्क्रिप्शन की सुविधा, इंटरनल स्टोरेज पर भी चालू की जा सकती है. Android 11 या इसके बाद के वर्शन के साथ लॉन्च होने वाले डिवाइसों के डिवाइस के स्टोरेज में, मेटाडेटा एन्क्रिप्शन की सुविधा चालू होनी चाहिए.
डिवाइस के स्टोरेज में लागू करना
नए डिवाइसों के इंटरनल स्टोरेज पर मेटाडेटा को एन्क्रिप्ट (सुरक्षित) करने का तरीका सेट अप किया जा सकता है.
इसके लिए, metadata
फ़ाइल सिस्टम सेट अप करें, इनिट क्रम को बदलें, और डिवाइस की fstab फ़ाइल में मेटाडेटा एन्क्रिप्ट (सुरक्षित) करने की सुविधा चालू करें.
ज़रूरी शर्तें
मेटाडेटा एन्क्रिप्ट करने की सुविधा सिर्फ़ तब सेट अप की जा सकती है, जब डेटा पार्टिशन को पहली बार फ़ॉर्मैट किया गया हो. इसलिए, यह सुविधा सिर्फ़ नए डिवाइसों के लिए है. ओटीए में इसे बदलना नहीं चाहिए.
मेटाडेटा एन्क्रिप्शन के लिए ज़रूरी है कि आपके कर्नेल में 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
, इनलाइन एन्क्रिप्शन हार्डवेयर (हार्डवेयर जो स्टोरेज डिवाइस से डेटा को भेजने/पाने के दौरान उसे एन्क्रिप्ट/डिक्रिप्ट करता है) का इस्तेमाल करता है. हालांकि, यह सुविधा सिर्फ़ तब उपलब्ध होती है, जब यह हार्डवेयर मौजूद हो. अगर इनलाइन एन्क्रिप्शन हार्डवेयर का इस्तेमाल नहीं किया जा रहा है, तो यह भी ज़रूरी है कि आप कर्नेल के क्रिप्टोग्राफ़ी एपीआई के लिए फ़ॉलबैक चालू करें:
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
अगर इनलाइन एन्क्रिप्शन हार्डवेयर का इस्तेमाल नहीं किया जा रहा है, तो आपको एफ़बीई दस्तावेज़ में दिए गए सुझावों के मुताबिक, सीपीयू की मदद से तेज़ी लाने वाली किसी उपलब्ध सुविधा को भी चालू करना चाहिए.
Android 10 और उससे पहले के वर्शन में, dm-default-key
के साथ Android का सामान्य कर्नेल काम नहीं करता था. इसलिए, dm-default-key
को लागू करना वेंडर के ऊपर था.
मेटाडेटा फ़ाइल सिस्टम सेट अप करना
मेटाडेटा एन्क्रिप्शन कुंजी मौजूद होने तक, उपयोगकर्ता डेटा के पार्टीशन में कुछ भी नहीं पढ़ा जा सकता. इसलिए, इस कुंजी को सुरक्षित करने वाले कीमास्टर ब्लॉब को सेव करने के लिए पार्टिशन टेबल को "मेटाडेटा पार्टिशन" नाम से एक अलग पार्टीशन अलग रखना होगा. मेटाडेटा का पार्टीशन 16 एमबी का होना चाहिए.
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 क्रम में बदलाव
मेटाडेटा एन्क्रिप्शन का इस्तेमाल करते समय, /data
को माउंट करने से पहले
vold
का चालू होना ज़रूरी है. यह पक्का करने के लिए कि यह प्रोसेस समय से शुरू हो, init.hardware.rc
में यह स्टैंश जोड़ें:
# We need vold early for metadata encryption on early-fs start vold
init के /data
को माउंट करने की कोशिश करने से पहले, Keymaster चालू और तैयार होना चाहिए.
init.hardware.rc
में पहले से ही mount_all
निर्देश होना चाहिए, जो on
late-fs
स्टैंश में /data
को माउंट करता है. इस लाइन से पहले, 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
को userdata
की fstab
एंट्री के fs_mgr_flags कॉलम में जोड़ें. उदाहरण के लिए, पूरी 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 ऐक्सेलरेशन की सुविधा नहीं है उन पर
metadata_encryption=adiantum
सेटिंग की मदद से, Adiantum एन्क्रिप्शन को चालू किया जा सकता है. - जिन डिवाइसों पर हार्डवेयर-रैप की गई कुंजियां के साथ काम करता है उन पर,
मेटाडेटा एन्क्रिप्शन कुंजी को हार्डवेयर-रैप किया जा सकता है. इसके लिए,
metadata_encryption=aes-256-xts:wrappedkey_v0
(या इसके बराबर हीmetadata_encryption=:wrappedkey_v0
को सेट करें, क्योंकिaes-256-xts
डिफ़ॉल्ट एल्गोरिदम है).
Android 11 में dm-default-key
के लिए, कर्नेल इंटरफ़ेस बदल गया है. इसलिए, आपको यह भी पक्का करना होगा कि आपने device.mk
में PRODUCT_SHIPPING_API_LEVEL
के लिए सही वैल्यू सेट की हो. उदाहरण के लिए, अगर आपका डिवाइस Android 11 (एपीआई लेवल 30) के साथ लॉन्च होता है, तो device.mk
में ये चीज़ें होनी चाहिए:
PRODUCT_SHIPPING_API_LEVEL := 30
शिपिंग एपीआई के लेवल के बावजूद, नए dm-default-key
एपीआई का इस्तेमाल करने के लिए, यहां दी गई सिस्टम प्रॉपर्टी भी सेट की जा सकती है:
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
अगर आपने डिवाइस के fstab
में metadata_encryption
विकल्प सेट करके, एन्क्रिप्शन की डिफ़ॉल्ट सेटिंग को बदल दिया है, तो आउटपुट ऊपर दिए गए आउटपुट से थोड़ा अलग होगा. उदाहरण के लिए, अगर आपने Adiantum एन्क्रिप्शन चालू किया है, तो तीसरा फ़ील्ड aes-xts-plain64
के बजाय xchacha12,aes-adiantum-plain64
होगा.
इसके बाद, मेटाडेटा एन्क्रिप्शन और एफ़बीई के सही होने की पुष्टि करने के लिए, vts_kernel_encryption_test को चलाएं:
atest vts_kernel_encryption_test
या:
vts-tradefed run vts -m vts_kernel_encryption_test
सामान्य समस्याएं
mount_all
को कॉल करने के दौरान, init
vdc टूल को चलाता है. mount_all
, एन्क्रिप्ट किए गए मेटाडेटा वाला /data
पार्टीशन माउंट करता है. मेटाडेटा एन्क्रिप्ट (सुरक्षित) किए गए डिवाइस को सेट अप करने और पार्टीशन को माउंट करने के लिए, vdc टूल binder
के ज़रिए vold
से कनेक्ट होता है. इस कॉल के दौरान, init
को ब्लॉक कर दिया जाता है. साथ ही, mount_all
के पूरा होने तक init
प्रॉपर्टी को पढ़ने या सेट करने की कोशिशों को ब्लॉक कर दिया जाता है.
अगर इस चरण में, vold
के काम का कोई हिस्सा किसी प्रॉपर्टी को पढ़ने या सेट करने पर सीधे तौर पर या फिर अप्रत्यक्ष रूप से ब्लॉक हो जाता है, तो डेडलॉक की स्थिति बन जाती है. यह पक्का करना ज़रूरी है कि vold
की मदद से कुंजियां पढ़ने, कीमास्टर से इंटरैक्ट करने, और init
की मदद से इंटरैक्ट किए बिना डेटा डायरेक्ट्री को माउंट करने का काम पूरा हो सके.
अगर mount_all
के चलने के दौरान Keymaster पूरी तरह से शुरू नहीं होता है, तो वह vold
के जवाब तब तक नहीं देता, जब तक कि वह init
से कुछ प्रॉपर्टी नहीं पढ़ लेता. इस वजह से, ऊपर बताई गई समस्या आती है. exec_start wait_for_keymaster
को तय किए गए mount_all
के ऊपर रखने से यह पक्का हो जाता है कि KeyMaster पहले से पूरी तरह से काम कर रहा है और इसलिए इस डेडलॉक से बचा जा सकता है.
एडॉप्टेबल स्टोरेज पर कॉन्फ़िगरेशन
Android 9 के बाद, FBE चालू होने पर, अडॉप्ट किए जा सकने वाले स्टोरेज पर मेटाडेटा एन्क्रिप्शन का कोई फ़ॉर्म हमेशा चालू रहता है. भले ही, इंटरनल स्टोरेज पर मेटाडेटा एन्क्रिप्शन चालू न हो.
एओएसपी में, डिवाइस के स्टोरेज के लिए, मेटाडेटा एन्क्रिप्शन को दो तरह से लागू किया जाता है: पहला, dm-crypt
के हिसाब से काम नहीं करता और दूसरा, dm-default-key
पर आधारित है. यह पक्का करने के लिए कि आपके डिवाइस के लिए सही तरीके से लागू किया गया है, पक्का करें कि आपने device.mk
में PRODUCT_SHIPPING_API_LEVEL
के लिए सही वैल्यू सेट की हो. उदाहरण के लिए, अगर आपका डिवाइस Android 11 (एपीआई लेवल 30) के साथ लॉन्च होता है, तो device.mk
में ये चीज़ें होनी चाहिए:
PRODUCT_SHIPPING_API_LEVEL := 30
शिपिंग एपीआई के लेवल के बावजूद, वॉल्यूम मेटाडेटा को एन्क्रिप्ट करने के नए तरीके (और एफ़बीई की नई डिफ़ॉल्ट नीति के वर्शन) का इस्तेमाल करने के लिए, यहां दी गई सिस्टम प्रॉपर्टी भी सेट की जा सकती हैं:
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
वॉल्यूम मेटाडेटा को एन्क्रिप्ट (सुरक्षित) करने का तरीका, डिफ़ॉल्ट रूप से 4096-बाइट वाले क्रिप्टो सेक्टर के साथ AES-256-XTS एन्क्रिप्शन एल्गोरिदम का इस्तेमाल करता है. ro.crypto.volume.metadata.encryption
सिस्टम प्रॉपर्टी सेट करके, एल्गोरिदम को बदला जा सकता है. इस प्रॉपर्टी की वैल्यू का सिंटैक्स, ऊपर बताए गए metadata_encryption
fstab विकल्प जैसा ही है. उदाहरण के लिए, जिन डिवाइसों में एईएस प्रोसेसिंग की सुविधा नहीं है उन पर ro.crypto.volume.metadata.encryption=adiantum
सेट करके, Adiantum एन्क्रिप्शन चालू किया जा सकता है.
लेगसी तरीका
Android 10 या इससे पहले के वर्शन वाले डिवाइसों पर, डिवाइस में पहले से मौजूद स्टोरेज में मेटाडेटा को एन्क्रिप्ट करने के लिए, dm-default-key
के बजाय dm-crypt
कर्नेल मॉड्यूल का इस्तेमाल किया जाता है:
CONFIG_DM_CRYPT=y
dm-default-key
तरीके के मुकाबले, dm-crypt
तरीके से फ़ाइल का कॉन्टेंट दो बार एन्क्रिप्ट होता है: एक बार एफ़बीई कुंजी से और एक बार मेटाडेटा एन्क्रिप्शन कुंजी से. दो बार एन्क्रिप्ट करने से परफ़ॉर्मेंस पर असर पड़ता है. साथ ही, मेटाडेटा एन्क्रिप्ट करने के सुरक्षा लक्ष्यों को हासिल करने के लिए, ऐसा करना ज़रूरी नहीं है. ऐसा इसलिए है, क्योंकि Android यह पक्का करता है कि एफ़बीई कुंजियों को कम से कम उतना ही मुश्किल हो जितना मेटाडेटा एन्क्रिप्ट करने की कुंजी को. वेंडर, डबल एन्क्रिप्शन से बचने के लिए, कर्नेल में पसंद के मुताबिक बदलाव कर सकते हैं. इसके लिए, वे allow_encrypt_override
विकल्प लागू कर सकते हैं. यह विकल्प, Android तब dm-crypt
को पास करता है, जब सिस्टम प्रॉपर्टी ro.crypto.allow_encrypt_override
को true
पर सेट किया जाता है.
ये कस्टमाइज़ेशन Android सामान्य कर्नेल के ज़रिए काम नहीं करते हैं.
डिफ़ॉल्ट रूप से, dm-crypt
वॉल्यूम मेटाडेटा एन्क्रिप्शन का तरीका, एईएस-128-सीबीसी एन्क्रिप्शन एल्गोरिदम का इस्तेमाल करता है. इसमें ईएसएसआईवी और 512-बाइट क्रिप्टो सेक्टर शामिल होते हैं. इसे बदला जा सकता है. इसके लिए, यहां दी गई सिस्टम प्रॉपर्टी सेट करें. इनका इस्तेमाल एफ़डीई के लिए भी किया जाता है:
ro.crypto.fde_algorithm
, मेटाडेटा को एन्क्रिप्ट करने का एल्गोरिदम चुनता है. आपके पासaes-128-cbc
औरadiantum
में से किसी एक को चुनने का विकल्प है. Adiantum का इस्तेमाल सिर्फ़ तब किया जा सकता है, जब डिवाइस में एईएस (AES) ऐक्सेलरेशन की सुविधा न हो.ro.crypto.fde_sector_size
, क्रिप्टो सेक्टर का साइज़ चुनता है. आपके पास 512, 1024, 2048, और 4096 का विकल्प है. एडिएन्टम एन्क्रिप्शन के लिए, 4096 का इस्तेमाल करें.