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

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

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

अगर एफ़बीई की सुविधा चालू होती है, तो डिवाइस के स्टोरेज में मेटाडेटा एन्क्रिप्ट (सुरक्षित) करने की सुविधा हमेशा चालू रहती है. मेटाडेटा एन्क्रिप्शन की सुविधा, इंटरनल स्टोरेज पर भी चालू की जा सकती है. लॉन्च किए गए डिवाइस 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, इनलाइन एन्क्रिप्शन हार्डवेयर का इस्तेमाल करता है (यह हार्डवेयर डेटा को एन्क्रिप्ट/डिक्रिप्ट करता है, जब वह स्टोरेज डिवाइस के रास्ते में होता है या उससे बाहर आता है) उपलब्ध हैं. अगर इनलाइन एन्क्रिप्शन हार्डवेयर का इस्तेमाल नहीं किया जा रहा है, तो यह भी ज़रूरी है कि आप कर्नेल के क्रिप्टोग्राफ़ी एपीआई के लिए फ़ॉलबैक को चालू करें:

CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y

जब इनलाइन एन्क्रिप्शन हार्डवेयर का इस्तेमाल नहीं किया जा रहा हो, तो आपको किसी भी उपलब्ध डिवाइस को भी चालू करना चाहिए सीपीयू के हिसाब से तेज़ी लाने की सुविधा, जैसा कि एफ़बीई दस्तावेज़ में दिया गया है.

Android 10 और उससे पहले के वर्शन में, Android के सामान्य कर्नेल पर dm-default-key काम नहीं करता था. इसलिए, 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

इनिट क्रम में बदलाव

मेटाडेटा एन्क्रिप्शन का इस्तेमाल करने पर, /data को माउंट करने से पहले vold चालू होना चाहिए. यह पक्का करने के लिए कि इसे जल्दी शुरू किया जाए, init.hardware.rc के लिए निम्न छंद:

# We need vold early for metadata encryption
on early-fs
    start vold

माउंट करने का प्रयास करने से पहले KeyMaster चालू और तैयार होना चाहिए /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 को इसके लिए fstab एंट्री का fs_mgr_flags कॉलम 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 ऐक्सेलरेशन की सुविधा नहीं है उन पर 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 ब्लॉक है और पढ़ने या सेट करने की कोशिश कर रहा है init प्रॉपर्टी mount_all खत्म होने तक ब्लॉक करें. अगर इस चरण में, vold के काम का कोई हिस्सा किसी प्रॉपर्टी को पढ़ने या सेट करने पर सीधे तौर पर या फिर अप्रत्यक्ष रूप से ब्लॉक हो जाता है, तो डेडलॉक की स्थिति बन जाती है. हां यह सुनिश्चित करना ज़रूरी है कि vold कुंजियां, KeyMaster के साथ इंटरैक्ट करना, और बिना किसी सूचना के डेटा डायरेक्ट्री को माउंट करना init के साथ और भी इंटरैक्ट करते हैं.

अगर mount_all के चलने पर, KeyMaster पूरी तरह से चालू नहीं हुआ है, तो यह काम नहीं करता vold का तब तक जवाब दें, जब तक कि उसमें init का नतीजा निकालने के लिए, सटीक डेडलॉक दिया गया है. स्थान exec_start wait_for_keymaster लक्ष्य से ज़्यादा mount_all को शुरू करने से पक्का होता है कि KeyMaster पूरी तरह से काम कर रहा है को रोका नहीं जा सकता है, इसलिए गड़बड़ी से बचा जा सकता है.

डिवाइस के स्टोरेज के लिए कॉन्फ़िगरेशन

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

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 वॉल्यूम मेटाडेटा को एन्क्रिप्ट (सुरक्षित) करने का तरीका यह 4096-बाइट क्रिप्टो सेक्टर के साथ, AES-256-XTS एन्क्रिप्शन एल्गोरिदम का इस्तेमाल करता है. ro.crypto.volume.metadata.encryption सिस्टम प्रॉपर्टी सेट करके, एल्गोरिदम को बदला जा सकता है. यह प्रॉपर्टी की वैल्यू और metadata_encryption का सिंटैक्स एक ही है fstab विकल्प को ऊपर बताया गया है. उदाहरण के लिए, जिन डिवाइसों में एईएस की जानकारी नहीं है ऐक्सलरेशन, ऐडिएंटम एन्क्रिप्शन को सेटिंग में जाकर चालू किया जा सकता है ro.crypto.volume.metadata.encryption=adiantum.

लेगसी तरीका

Android 10 या इससे पहले के वर्शन के साथ लॉन्च होने वाले डिवाइसों पर, मेटाडेटा डिवाइस के स्टोरेज को एन्क्रिप्ट (सुरक्षित) करने के लिए, dm-crypt कर्नेल मॉड्यूल का इस्तेमाल किया जाता है dm-default-key के बजाय:

CONFIG_DM_CRYPT=y

dm-default-key तरीके के उलट, dm-crypt तरीका इससे फ़ाइल का कॉन्टेंट दो बार एन्क्रिप्ट (सुरक्षित) होता है: एक बार FBE कुंजी से और एक बार मेटाडेटा एन्क्रिप्शन कुंजी पर जाएं. दो बार एन्क्रिप्ट करने से परफ़ॉर्मेंस पर असर पड़ता है. साथ ही, मेटाडेटा एन्क्रिप्ट करने के सुरक्षा लक्ष्यों को हासिल करने के लिए, ऐसा करना ज़रूरी नहीं है. ऐसा इसलिए है, क्योंकि Android यह पक्का करता है कि एफ़बीई पासकोड को हैक करना, मेटाडेटा एन्क्रिप्ट करने की पासकोड के बराबर ही मुश्किल हो. वेंडर, डबल एन्क्रिप्शन से बचने के लिए, कर्नेल में पसंद के मुताबिक बदलाव कर सकते हैं. इसके लिए, वे allow_encrypt_override विकल्प लागू कर सकते हैं. यह विकल्प, Android तब dm-crypt को पास करता है, जब सिस्टम प्रॉपर्टी ro.crypto.allow_encrypt_override को true पर सेट किया जाता है. Android के सामान्य कर्नेल में, ये कस्टमाइज़ेशन काम नहीं करते.

वॉल्यूम मेटाडेटा को एन्क्रिप्ट (सुरक्षित) करने का dm-crypt तरीका, डिफ़ॉल्ट रूप से ईएसएसआईवी और 512-बाइट वाले क्रिप्टो सेक्टर के साथ एईएस-128-सीबीसी एन्क्रिप्शन एल्गोरिदम. यह नीचे दिए गए सिस्टम की प्रॉपर्टी को सेट करके बदला जा सकता है (जो एफ़डीई के लिए इस्तेमाल किया जाता है):

  • ro.crypto.fde_algorithm, मेटाडेटा एन्क्रिप्शन एल्गोरिदम चुनता है. विकल्प aes-128-cbc और हैं adiantum. Adiantum का इस्तेमाल सिर्फ़ तब किया जा सकता है, जब डिवाइस में एईएस (AES) ऐक्सेलरेशन की सुविधा न हो.
  • ro.crypto.fde_sector_size, क्रिप्टो सेक्टर का साइज़ चुनता है. विकल्प 512, 1024, 2048, और 4096 हैं. एडिएंटम एन्क्रिप्शन के लिए, इसका इस्तेमाल करें 4096 है.