ज़्यादातर डिस्क और फ़ाइल एन्क्रिप्ट (सुरक्षित) करने वाले सॉफ़्टवेयर की तरह, Android का स्टोरेज एन्क्रिप्ट (सुरक्षित) करने वाला सिस्टम, आम तौर पर सिस्टम मेमोरी में मौजूद एन्क्रिप्ट (सुरक्षित) करने की रॉ कुंजियों पर निर्भर करता है, ताकि एन्क्रिप्ट (सुरक्षित) करने की प्रोसेस पूरी की जा सके. एन्क्रिप्ट (सुरक्षित) करने के बाद भी सॉफ़्टवेयर के बजाय समर्पित हार्डवेयर के ज़रिए, सॉफ़्टवेयर के लिए आम तौर पर रॉ एन्क्रिप्शन की कुंजियों को मैनेज करें.
आम तौर पर, इसे समस्या के तौर पर नहीं देखा जाता, क्योंकि इसमें कुंजियां मौजूद नहीं होती हैं की वजह से होता है. यह मुख्य रूप से उस हमले के दौरान होता है, एन्क्रिप्ट (सुरक्षित) करने का मकसद सुरक्षित है. हालांकि, विज्ञापन देने वालों को यह समझने में मदद मिलेगी कि अन्य तरह के हमलों से सुरक्षा बढ़ती है, जैसे कि कोल्ड बूट हमले और ऐसे ऑनलाइन हमले जिनसे कोई हमलावर सिस्टम को लीक कर सकता हो मेमोरी से समझौता नहीं किया जा सकता.
इस समस्या को हल करने के लिए, Android 11 पर सहायता उपलब्ध कराई गई हार्डवेयर से रैप की गई कुंजियों के लिए, जहां हार्डवेयर की सुविधा मौजूद होती है. हार्डवेयर के साथ रैप की गई कुंजियां, स्टोरेज की ऐसी कुंजियां होती हैं जिन्हें सिर्फ़ रॉ रूप में जाना जाता है खास तरह का हार्डवेयर; सॉफ़्टवेयर केवल इन कुंजियों को रैप करके देखता और उनके साथ काम करता है (एन्क्रिप्ट किया गया) फ़ॉर्म. यह हार्डवेयर, स्टोरेज पासकोड जनरेट और इंपोर्ट करने, स्टोरेज पासकोड को कुछ समय के लिए और लंबे समय तक इस्तेमाल करने के फ़ॉर्म में रैप करने, सब-पासकोड जनरेट करने, किसी सब-पासकोड को सीधे इनलाइन क्रिप्टो इंजन में प्रोग्राम करने, और सॉफ़्टवेयर को अलग सब-पासकोड दिखाने की सुविधा देना चाहिए.
ध्यान दें: इनलाइन क्रिप्टो इंजन (या इनलाइन एन्क्रिप्शन हार्डवेयर) से ऐसे हार्डवेयर का मतलब है जो स्टोरेज डिवाइस से डेटा को भेजने या पाने के दौरान, उसे एन्क्रिप्ट/डिक्रिप्ट करता है. आम तौर पर, यह एक यूएफ़एस या ईएमएमसी होस्ट कंट्रोलर होता है, जो संबंधित जेईडीईसी स्पेसिफ़िकेशन के मुताबिक क्रिप्टो एक्सटेंशन लागू करता है.
डिज़ाइन
इस सेक्शन में, हार्डवेयर-रैप की गई कुंजियों की सुविधा का डिज़ाइन दिखाया गया है. इसमें, ये सुविधाएं भी शामिल हैं इसके लिए किस तरह के हार्डवेयर की मदद की ज़रूरत होती है. इस बातचीत में, फ़ाइल पर आधारित एन्क्रिप्शन (एफ़बीई) पर फ़ोकस किया गया है. हालांकि, समाधान मेटाडेटा पर लागू होता है एन्क्रिप्ट करने का तरीका भी बताया है.
सिस्टम मेमोरी में एन्क्रिप्शन कुंजी का इस्तेमाल न करने का एक तरीका यह है कि उन्हें सिर्फ़ इनलाइन क्रिप्टो इंजन के कीस्लॉट में ही रखें. हालांकि, इस इस तरीके में कुछ समस्याएं आती हैं:
- एन्क्रिप्ट करने वाली कुंजियों की संख्या, कीस्लॉट की संख्या से ज़्यादा हो सकती है.
- इनलाइन क्रिप्टो इंजन का इस्तेमाल, डिस्क पर मौजूद डेटा के पूरे ब्लॉक को एन्क्रिप्ट/डिक्रिप्ट करने के लिए ही किया जा सकता है. हालांकि, एफ़बीई के मामले में, सॉफ़्टवेयर को अब भी क्रिप्टोग्राफ़ी से जुड़े अन्य काम करने की ज़रूरत होती है. जैसे, फ़ाइल के नाम को एन्क्रिप्ट करना और मुख्य आइडेंटिफ़ायर का पता लगाना. सॉफ़्टवेयर को अभी भी रॉ एफ़बीई कुंजियों के ऐक्सेस की ज़रूरत होगी, यह दूसरा काम करें.
इन समस्याओं से बचने के लिए, स्टोरेज पासकोड को हार्डवेयर से रैप की गई पासकोड में बदल दिया जाता है. इन्हें सिर्फ़ खास हार्डवेयर से अनलॉक और इस्तेमाल किया जा सकता है. इससे, अनलिमिटेड नंबर की चाबियां इस्तेमाल की जा सकती हैं. तय सीमा में इसके अलावा, की हैरारकी में बदलाव किया गया है और वह कुछ हद तक इस हार्डवेयर में चला गया है, इसकी मदद से, सबकी को उन टास्क के लिए सॉफ़्टवेयर में वापस भेजा जा सकता है जो इनलाइन क्रिप्टो इंजन.
कुंजी की हैरारकी
KDF (कुंजी बनाने वाला फ़ंक्शन), जैसे कि HKDF का इस्तेमाल करके, एक कुंजी से दूसरी कुंजी बनाई जा सकती है. इससे कुंजी की हैरारकी बनती है.
नीचे दिया गया डायग्राम, एफ़बीई के लिए मुख्य क्रम को दिखाता है. ऐसा तब होता है, जब हार्डवेयर-रैप की गई कुंजियों का इस्तेमाल नहीं किया जाता:
FBE क्लास कुंजी एक रॉ एन्क्रिप्शन की (कुंजी) होती है, जिसे Android Linux को पास करता है कर्नेल के ज़रिए, एन्क्रिप्ट (सुरक्षित) की गई डायरेक्ट्री के खास सेट को अनलॉक करें, जैसे कि किसी खास Android उपयोगकर्ता के लिए क्रेडेंशियल को एन्क्रिप्ट (सुरक्षित) किया गया स्टोरेज. (कर्नेल में, यह कुंजी को fscrypt मास्टर कुंजी कहा जाता है.) इस कुंजी से, कर्नेल ये सबकी:
- कुंजी का आइडेंटिफ़ायर. इसका इस्तेमाल एन्क्रिप्ट (सुरक्षित) करने के लिए नहीं किया जाता, बल्कि यह एक वैल्यू है इसका इस्तेमाल उस कुंजी की पहचान करने के लिए किया जाता है जिससे कोई खास फ़ाइल या डायरेक्ट्री होती है सुरक्षित रखा गया.
- फ़ाइल का कॉन्टेंट एन्क्रिप्ट करने की कुंजी
- फ़ाइल नामों को एन्क्रिप्ट करने की कुंजी
इसके उलट, नीचे दिए गए डायग्राम में, हार्डवेयर की मदद से एन्क्रिप्ट की गई कुंजियों का इस्तेमाल करने पर, एफ़बीई के लिए कुंजी की हैरारकी दिखाई गई है:
पहले के मामले की तुलना में, पासकोड के लेवल में एक और लेवल जोड़ा गया है. साथ ही, फ़ाइल के कॉन्टेंट को एनक्रिप्ट करने के लिए इस्तेमाल होने वाले पासकोड को दूसरी जगह ले जाया गया है. रूट नोड अब भी उस कुंजी को दिखाता है जिसे Android, एन्क्रिप्ट की गई डायरेक्ट्री के सेट को अनलॉक करने के लिए Linux को पास करता है. हालांकि, अब कुंजी बहुत कम समय के लिए है और इसे इस्तेमाल करने के लिए, इसे खास तौर पर काम करने वाले हार्डवेयर को भेजना ज़रूरी होता है. इस हार्डवेयर को दो इंटरफ़ेस लागू करें, जो कुछ समय के लिए रैप की गई कुंजी लेते हैं:
inline_encryption_key
का पता लगाने और उसे सीधे तौर पर, इनलाइन क्रिप्टो इंजन के पासकोड में प्रोग्राम करने के लिए एक इंटरफ़ेस. इससे फ़ाइल चुनने की अनुमति मिलती है सॉफ़्टवेयर का ऐक्सेस न होने के बावजूद, एन्क्रिप्ट/डिक्रिप्ट की जाने वाली सामग्री बटन दबाएं. Android के सामान्य कर्नेल में, यह इंटरफ़ेसblk_crypto_ll_ops::keyslot_program
कार्रवाई, जो यह होनी चाहिए स्टोरेज ड्राइवर की ओर से लागू किया जाता है.sw_secret
पाने और पाने के लिए एक इंटरफ़ेस ("सॉफ़्टवेयर सीक्रेट" -- इसे "रॉ सीक्रेट" भी कहा जाता है ही नहीं, बल्कि यह ऐसी कुंजी है जो फ़ाइल के कॉन्टेंट के अलावा, Linux अन्य सभी चीज़ों के लिए सब-की हासिल करने के लिए, Linux का इस्तेमाल करता है एन्क्रिप्ट करने का तरीका. Android के सामान्य कर्नेल में, यह इंटरफ़ेसblk_crypto_ll_ops::derive_sw_secret
कार्रवाई, जो यह होनी चाहिए स्टोरेज ड्राइवर की ओर से लागू किया जाता है.
वैल्यू से inline_encryption_key
और sw_secret
को हासिल करने के लिए
रॉ स्टोरेज कुंजी के लिए, हार्डवेयर को क्रिप्टोग्राफ़िक तौर पर मज़बूत KDF का इस्तेमाल करना चाहिए. यह केडीएफ़
क्रिप्टोग्राफ़ी के सबसे सही तरीकों का पालन करना चाहिए; इसकी सुरक्षा क्षमता इतने होनी चाहिए:
कम से कम 256 बिट, यानी कि बाद में इस्तेमाल किए जाने वाले किसी भी एल्गोरिदम के लिए काफ़ी होते हैं. इसे किसी
जब अलग-अलग लेबल, संदर्भ, और ऐप्लिकेशन से जुड़ी खास जानकारी स्ट्रिंग होती है, तो
हर तरह की सबकी को डेरिवेटिव से बनाया जाता है, ताकि यह गारंटी दी जा सके कि सबकी
वे क्रिप्टोग्राफ़िक तरीके से अलग-अलग हो जाते हैं. इसका मतलब है कि उनमें से किसी एक के बारे में
अन्य. कुंजी को खींचने की ज़रूरत नहीं है, क्योंकि मूल मेमोरी कुंजी पहले से ही
एक ही जैसी रैंडम कुंजी.
तकनीकी तौर पर, सुरक्षा की शर्तों को पूरा करने वाले किसी भी केडीएफ़ का इस्तेमाल किया जा सकता है.
हालांकि, टेस्टिंग के लिए, उसी केडीएफ़ को फिर से लागू करना ज़रूरी है
टेस्ट कोड. फ़िलहाल, एक केडीएफ़ की समीक्षा हो चुकी है और उसे लागू कर दिया गया है. इसे vts_kernel_encryption_test
के सोर्स कोड में देखा जा सकता है.
हमारा सुझाव है कि हार्डवेयर इस KDF का इस्तेमाल करें. यह केडीएफ़, एनआईएसटी एसपी 800-108 "काउंटर मोड में केडीएफ़ का इस्तेमाल करता है. साथ ही, पीआरएफ़ के तौर पर AES-256-CMAC का इस्तेमाल करता है. ध्यान रखें कि एक साथ काम करने के लिए,
एल्गोरिदम के हिस्से एक जैसे होने चाहिए. इनमें, केडीएफ़ कॉन्टेक्स्ट के विकल्प भी शामिल हैं
और लेबल जोड़ने की अनुमति दें.
पासकोड को रैप करना
हार्डवेयर से सुरक्षित की गई कुंजियों के लिए सुरक्षा से जुड़े लक्ष्यों को पूरा करने के लिए, कुंजी को सुरक्षित करने के दो तरीके तय किए गए हैं:
- कुछ समय के लिए रैपिंग: हार्डवेयर, कुंजी का इस्तेमाल करके रॉ कुंजी को एन्क्रिप्ट (सुरक्षित) करता है जो हर बूट पर रैंडम तरीके से जनरेट होता है. साथ ही, इसे सीधे बिना अनुमति के सार्वजनिक नहीं किया जाता जैसी चीज़ों को हार्डवेयर के बाहर रखा जाता है.
- लंबे समय तक चलने वाली रैपिंग: हार्डवेयर, रॉ पासकोड को एन्क्रिप्ट करता है. इसके लिए, वह हार्डवेयर में पहले से मौजूद एक यूनीक और पर्सिस्टेंट पासकोड का इस्तेमाल करता है. यह पासकोड, हार्डवेयर के बाहर सीधे तौर पर नहीं दिखता.
स्टोरेज को अनलॉक करने के लिए, Linux कर्नेल को भेजी गई सभी कुंजियां हैं कुछ समय के लिए रैप किया गया. इससे यह सुनिश्चित होता है कि अगर कोई हमलावर तो वह कुंजी न सिर्फ़ उपयोग में रहती है, बल्कि डिवाइस से बंद किया है, लेकिन फिर से चालू होने के बाद डिवाइस पर भी.
साथ ही, Android को डिस्क पर कुंजियों का एन्क्रिप्ट (सुरक्षित) किया गया वर्शन सेव करना होगा, ताकि उन्हें पहले अनलॉक किया जा सके. इस काम के लिए, रॉ की काम करेंगी. हालांकि, यह जानना होगा कि आपके पास कुंजियां सिस्टम की मेमोरी में मौजूद होती हैं, ताकि उन्हें कभी भी निकाला न जा सके डिवाइस से बाहर इस्तेमाल नहीं किया जा सकता, भले ही उसे बूट के समय निकाला गया हो. इस वजह से, कॉन्सेप्ट के हिसाब से रैप किया जाता है.
इन दो अलग-अलग तरीकों से रैप की गई कुंजियों को मैनेज करने के लिए, हार्डवेयर को ये इंटरफ़ेस लागू करने होंगे:
- स्टोरेज कुंजियां जनरेट और इंपोर्ट करने के लिए इंटरफ़ेस. साथ ही, उन्हें वापस लौटाना
लंबे समय तक रैपर किया जाता है. इन इंटरफ़ेस को सीधे तौर पर, इसके ज़रिए ऐक्सेस नहीं किया जाता
KeyMint है और ये
TAG_STORAGE_KEY
KeyMint टैग से संबंधित हैं. "जनरेट करें"vold
, नई स्टोरेज जनरेट करने के लिए सुविधा का इस्तेमाल करता है "इंपोर्ट" करते समय, Android के इस्तेमाल करने के लिए पासकोड क्षमता का इस्तेमाल इनके लिए किया जाता है जांच कुंजियां इंपोर्ट करने के लिएvts_kernel_encryption_test
. - लंबे समय तक इस्तेमाल होने वाली स्टोरेज कुंजी को, कुछ समय के लिए इस्तेमाल होने वाली स्टोरेज कुंजी में बदलने के लिए इंटरफ़ेस. यह
convertStorageKeyToEphemeral
कीमिंट तरीका. इस तरीके का इस्तेमाल किया जाता हैvold
औरvts_kernel_encryption_test
, दोनों के हिसाब से क्रम में डिवाइस के स्टोरेज को अनलॉक करने के लिए.
कुंजी रैपिंग एल्गोरिदम, लागू करने की जानकारी है, लेकिन इसे मज़बूत AEAD, जैसे AES-256-GCM रैंडम IVs के साथ.
सॉफ़्टवेयर में बदलाव करना ज़रूरी है
AOSP में, हार्डवेयर में सुरक्षित की गई कुंजियों के साथ काम करने के लिए, पहले से ही बुनियादी फ़्रेमवर्क मौजूद है. यह
इसमें यूज़रस्पेस कॉम्पोनेंट, जैसे कि vold
में भी सहायता शामिल है.
blk-crypto, fscrypt और में Linux कर्नेल सहायता के तौर पर
dm-default-key है.
हालांकि, लागू करने से जुड़ी जानकारी में कुछ बदलाव करने की ज़रूरत है.
KeyMint में हुए बदलाव
डिवाइस के KeyMint को लागू करने के तरीके में बदलाव किया जाना चाहिए, ताकि
TAG_STORAGE_KEY
और
convertStorageKeyToEphemeral
तरीका.
KeyMaster में, इसके बजाय exportKey
का इस्तेमाल किया गया
convertStorageKeyToEphemeral
.
Linux कर्नेल में बदलाव
डिवाइस के इनलाइन क्रिप्टो इंजन के लिए, Linux कर्नेल ड्राइवर में बदलाव करना होगा, ताकि हार्डवेयर में सुरक्षित की गई कुंजियों का इस्तेमाल किया जा सके.
android14
और उसके बाद के वर्शन वाले कर्नेल के लिए,
blk_crypto_profile::key_types_supported
में BLK_CRYPTO_KEY_TYPE_HW_WRAPPED
सेट करें,
blk_crypto_ll_ops::keyslot_program
और blk_crypto_ll_ops::keyslot_evict
को हार्डवेयर में सुरक्षित की गई कुंजियों को प्रोग्राम करने/हटाने की सुविधा दें, और
blk_crypto_ll_ops::derive_sw_secret
लागू करें.
android12
और android13
कर्नेल के लिए,
blk_keyslot_manager::features
में BLK_CRYPTO_FEATURE_WRAPPED_KEYS
सेट करें,
blk_ksm_ll_ops::keyslot_program
और blk_ksm_ll_ops::keyslot_evict
को हार्डवेयर में सुरक्षित की गई कुंजियों को प्रोग्राम करने/हटाने की सुविधा दें, और
blk_ksm_ll_ops::derive_raw_secret
लागू करें.
android11
कर्नेल के लिए,
BLK_CRYPTO_FEATURE_WRAPPED_KEYS
को सेट करो
keyslot_manager::features
में,
keyslot_mgmt_ll_ops::keyslot_program
बनाओ
और keyslot_mgmt_ll_ops::keyslot_evict
प्रोग्रामिंग/हार्डवेयर में लिपटी हुई कुंजियों को हटाने में मदद करने के लिए,
और keyslot_mgmt_ll_ops::derive_raw_secret
को लागू करें.
टेस्ट करना
हालांकि, एन्क्रिप्ट (सुरक्षित) करने के मुकाबले हार्डवेयर में रैप की गई कुंजियों की मदद से, डेटा एन्क्रिप्ट (सुरक्षित) करने की सुविधा की जांच करना ज़्यादा मुश्किल है
नहीं है, तो अभी भी परीक्षण कुंजी आयात करके परीक्षण किया जा सकता है और
हार्डवेयर से जुड़ी कुंजी व्युत्पन्न की प्रक्रिया को फिर से लागू करना. यह लागू किया गया है
vts_kernel_encryption_test
में. इस टेस्ट को करने के लिए,
चलाएं:
atest -v vts_kernel_encryption_test
टेस्ट लॉग पढ़ें और पुष्टि करें कि हार्डवेयर पर सेव की गई कुंजियों के टेस्ट केस (उदाहरण के लिए,
FBEPolicyTest.TestAesInlineCryptOptimizedHwWrappedKeyPolicy
और
DmDefaultKeyTest.TestHwWrappedKey
) को, हार्डवेयर पर सेव की गई कुंजियों के लिए सहायता का पता न चलने की वजह से स्किप न किया गया हो. ऐसा इसलिए, क्योंकि इस मामले में टेस्ट के नतीजे अब भी "पास" हैं.
कुंजियां सक्षम करें
जब डिवाइस की हार्डवेयर में रैप की गई कुंजी से जुड़ी सहायता सही तरीके से काम करने लगे, तो
डिवाइस की fstab
फ़ाइल में ये बदलाव करें
Android इसका इस्तेमाल, एफ़बीई और मेटाडेटा को एन्क्रिप्ट (सुरक्षित) करने के लिए करता है:
- FBE:
wrappedkey_v0
फ़्लैग कोfileencryption
पैरामीटर. उदाहरण के लिए,fileencryption=::inlinecrypt_optimized+wrappedkey_v0
का इस्तेमाल करें. इसके लिए ज़्यादा जानकारी के लिए, एफ़बीई देखें दस्तावेज़ में दिया गया है. - मेटाडेटा एन्क्रिप्शन:
metadata_encryption
पैरामीटर मेंwrappedkey_v0
फ़्लैग जोड़ें. उदाहरण के लिए,metadata_encryption=:wrappedkey_v0
का इस्तेमाल करें. ज़्यादा जानकारी के लिए, यह देखें मेटाडेटा एन्क्रिप्ट (सुरक्षित) करने का दस्तावेज़.