मेटाडेटा एन्क्रिप्ट (सुरक्षित) करना

Android 7.0 और इसके बाद के वर्शन पर, अलग-अलग फ़ाइलों को अलग-अलग तरीकों से एन्क्रिप्ट करने का तरीका (FBE) काम करता है. एफ़बीई की मदद से, अलग-अलग फ़ाइलों को अलग-अलग कुंजियों से एन्क्रिप्ट किया जा सकता है. साथ ही, उन्हें अलग-अलग अनलॉक किया जा सकता है. इन कुंजियों का इस्तेमाल, फ़ाइल के कॉन्टेंट और नाम, दोनों को एन्क्रिप्ट करने के लिए किया जाता है. एफ़बीई का इस्तेमाल करने पर, डायरेक्ट्री लेआउट, फ़ाइल का साइज़, अनुमतियां, और बनाने/बदलाव करने का समय जैसी अन्य जानकारी एन्क्रिप्ट नहीं की जाती. इस तरह की अन्य जानकारी को फ़ाइल सिस्टम मेटाडेटा कहा जाता है.

Android 9 में, मेटाडेटा एन्क्रिप्ट (सुरक्षित) करने की सुविधा जोड़ी गई है. मेटाडेटा एन्क्रिप्शन की मदद से, बूट के समय मौजूद एक कुंजी, उस कॉन्टेंट को एन्क्रिप्ट करती है जो एफ़बीई से एन्क्रिप्ट नहीं किया गया है. इस कुंजी को Keymaster की मदद से सुरक्षित किया जाता है. Keymaster को, पुष्टि किए गए बूट की मदद से सुरक्षित किया जाता है.

एफ़बीई चालू होने पर, अडॉप्टेबल स्टोरेज में मेटाडेटा एन्क्रिप्ट (सुरक्षित) करने की सुविधा हमेशा चालू रहती है. मेटाडेटा को एन्क्रिप्ट (सुरक्षित) करने की सुविधा, इंटरनल स्टोरेज पर भी चालू की जा सकती है. Android 11 या इसके बाद के वर्शन के साथ लॉन्च होने वाले डिवाइसों में, इंटरनल स्टोरेज में मेटाडेटा एन्क्रिप्शन की सुविधा चालू होनी चाहिए.

डिवाइस के स्टोरेज में लागू करना

नए डिवाइसों के इंटरनल स्टोरेज में मेटाडेटा एन्क्रिप्शन सेट अप किया जा सकता है. इसके लिए, metadata फ़ाइल सिस्टम सेट अप करें, init क्रम बदलें, और डिवाइस की fstab फ़ाइल में मेटाडेटा एन्क्रिप्शन चालू करें.

ज़रूरी शर्तें

मेटाडेटा एन्क्रिप्शन को सिर्फ़ तब सेट अप किया जा सकता है, जब डेटा सेगमेंट को पहली बार फ़ॉर्मैट किया गया हो. इसलिए, यह सुविधा सिर्फ़ नए डिवाइसों के लिए है. इसे ओटीए (Over-The-Air) से बदला नहीं जा सकता.

मेटाडेटा एन्क्रिप्ट (सुरक्षित) करने के लिए, आपके kernel में 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

मेटाडेटा एन्क्रिप्ट (सुरक्षित) करने की सुविधा चालू करना

आखिर में, userdata के लिए fstab एंट्री के fs_mgr_flags कॉलम में keydirectory=/metadata/vold/metadata_encryption जोड़ें. उदाहरण के लिए, 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, कुंजियों को पढ़ने, Keymaster के साथ इंटरैक्ट करने, और init के साथ इंटरैक्ट किए बिना डेटा डायरेक्ट्री को माउंट करने का काम पूरा कर सके.

अगर mount_all के चलने के दौरान Keymaster पूरी तरह से शुरू नहीं होता है, तो वह vold के जवाब तब तक नहीं देता, जब तक कि वह init से कुछ प्रॉपर्टी नहीं पढ़ लेता. इस वजह से, ऊपर बताई गई समस्या आती है. exec_start wait_for_keymaster को mount_all के ऊपर रखकर, यह पक्का किया जा सकता है कि Keymaster पहले से ही पूरी तरह से काम कर रहा है. इससे, डेडलॉक की समस्या से बचा जा सकता है.

एडॉप्टेबल स्टोरेज पर कॉन्फ़िगरेशन

Android 9 के बाद, FBE चालू होने पर, अडॉप्ट किए जा सकने वाले स्टोरेज पर मेटाडेटा एन्क्रिप्शन का कोई फ़ॉर्म हमेशा चालू रहता है. भले ही, इंटरनल स्टोरेज पर मेटाडेटा एन्क्रिप्शन चालू न हो.

AOSP में, इस्तेमाल किए जा सकने वाले स्टोरेज पर मेटाडेटा एन्क्रिप्शन के दो तरीके हैं: 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 वॉल्यूम के मेटाडेटा को एन्क्रिप्ट करने के तरीके में, 4,096-बाइट वाले क्रिप्टो सेक्टर के साथ 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 का इस्तेमाल करें.