हार्डवेयर-लिपटे कुंजियाँ

अधिकांश डिस्क और फ़ाइल एन्क्रिप्शन सॉफ़्टवेयर की तरह, Android का स्टोरेज एन्क्रिप्शन पारंपरिक रूप से सिस्टम मेमोरी में मौजूद कच्ची एन्क्रिप्शन कुंजियों पर निर्भर करता है ताकि एन्क्रिप्शन किया जा सके। यहां तक ​​कि जब एन्क्रिप्शन सॉफ़्टवेयर के बजाय समर्पित हार्डवेयर द्वारा किया जाता है, तब भी सॉफ़्टवेयर को अभी भी अपरिष्कृत एन्क्रिप्शन कुंजियों को प्रबंधित करने की आवश्यकता होती है।

इसे परंपरागत रूप से एक समस्या के रूप में नहीं देखा जाता है क्योंकि कुंजी ऑफ़लाइन हमले के दौरान मौजूद नहीं होगी, जो मुख्य प्रकार का हमला है जिससे स्टोरेज एन्क्रिप्शन का बचाव करना है। हालांकि, अन्य प्रकार के हमलों, जैसे कोल्ड बूट हमलों और ऑनलाइन हमलों के खिलाफ बढ़ी हुई सुरक्षा प्रदान करने की इच्छा है, जहां एक हमलावर डिवाइस को पूरी तरह से समझौता किए बिना सिस्टम मेमोरी को लीक करने में सक्षम हो सकता है।

इस समस्या को हल करने के लिए, Android 11 ने हार्डवेयर-रैप कीज़ के लिए समर्थन पेश किया, जहाँ हार्डवेयर समर्थन मौजूद है। हार्डवेयर-रैप्ड कुंजियाँ स्टोरेज कुंजियाँ हैं जो केवल समर्पित हार्डवेयर के लिए अपरिष्कृत रूप में जानी जाती हैं; सॉफ्टवेयर केवल इन चाबियों को लिपटे (एन्क्रिप्टेड) ​​रूप में देखता है और काम करता है। यह हार्डवेयर भंडारण कुंजियों को उत्पन्न करने और आयात करने में सक्षम होना चाहिए, अस्थायी और दीर्घकालिक रूपों में भंडारण कुंजियों को लपेटना, उपकुंजियों को प्राप्त करना, सीधे एक उपकुंजी को एक इनलाइन क्रिप्टो इंजन में प्रोग्रामिंग करना और सॉफ्टवेयर के लिए एक अलग उपकुंजी वापस करना।

नोट : एक इनलाइन क्रिप्टो इंजन (या इनलाइन एन्क्रिप्शन हार्डवेयर ) हार्डवेयर को संदर्भित करता है जो डेटा को एन्क्रिप्ट/डिक्रिप्ट करता है जबकि यह स्टोरेज डिवाइस से/के रास्ते में होता है। आमतौर पर यह एक UFS या eMMC होस्ट कंट्रोलर होता है जो संबंधित JEDEC विनिर्देशन द्वारा परिभाषित क्रिप्टो एक्सटेंशन को लागू करता है।

डिज़ाइन

यह खंड हार्डवेयर-रैप्ड कुंजियों की विशेषता का डिज़ाइन प्रस्तुत करता है, जिसमें यह भी शामिल है कि इसके लिए कौन से हार्डवेयर समर्थन की आवश्यकता है। यह चर्चा फ़ाइल-आधारित एन्क्रिप्शन (FBE) पर केंद्रित है, लेकिन समाधान मेटाडेटा एन्क्रिप्शन पर भी लागू होता है।

सिस्टम मेमोरी में अपरिष्कृत एन्क्रिप्शन कुंजियों की आवश्यकता से बचने का एक तरीका यह होगा कि उन्हें केवल एक इनलाइन क्रिप्टो इंजन के की-स्लॉट में ही रखा जाए। हालाँकि, यह दृष्टिकोण कुछ समस्याओं में चलता है:

  • एन्क्रिप्शन कुंजियों की संख्या कुंजियों की संख्या से अधिक हो सकती है।
  • इनलाइन क्रिप्टो इंजन का उपयोग केवल डिस्क पर डेटा के पूर्ण ब्लॉक को एन्क्रिप्ट/डिक्रिप्ट करने के लिए किया जा सकता है। हालाँकि, FBE के मामले में, सॉफ़्टवेयर को अभी भी अन्य क्रिप्टोग्राफ़िक कार्य करने में सक्षम होने की आवश्यकता है जैसे कि फ़ाइल नाम एन्क्रिप्शन और प्रमुख पहचानकर्ता प्राप्त करना। इस अन्य कार्य को करने के लिए सॉफ़्टवेयर को अभी भी अपरिष्कृत FBE कुंजियों तक पहुँच की आवश्यकता होगी।

इन समस्याओं से बचने के लिए, इसके बजाय स्टोरेज कुंजियों को हार्डवेयर-रैप की गई कुंजियों में बनाया जाता है, जिन्हें केवल अलग किया जा सकता है और समर्पित हार्डवेयर द्वारा उपयोग किया जा सकता है। यह असीमित संख्या में चाबियों का समर्थन करने की अनुमति देता है। इसके अलावा, कुंजी पदानुक्रम को संशोधित किया गया है और आंशिक रूप से इस हार्डवेयर में ले जाया गया है, जो उपकुंजी को उन कार्यों के लिए सॉफ़्टवेयर में वापस करने की अनुमति देता है जो इनलाइन क्रिप्टो इंजन का उपयोग नहीं कर सकते हैं।

कुंजी पदानुक्रम

KDF (कुंजी व्युत्पत्ति फ़ंक्शन) जैसे HKDF का उपयोग करके कुंजियों को अन्य कुंजियों से प्राप्त किया जा सकता है, जिसके परिणामस्वरूप एक कुंजी पदानुक्रम होता है।

निम्नलिखित चित्र एफबीई के लिए एक सामान्य कुंजी पदानुक्रम दर्शाता है जब हार्डवेयर-लिपटे कुंजियों का उपयोग नहीं किया जाता है:

FBE कुंजी पदानुक्रम (मानक)
चित्र 1. FBE कुंजी पदानुक्रम (मानक)

एफबीई क्लास कुंजी अपरिष्कृत एन्क्रिप्शन कुंजी है जो एंड्रॉइड लिनक्स कर्नेल को एन्क्रिप्टेड निर्देशिकाओं के एक विशेष सेट को अनलॉक करने के लिए पास करती है, जैसे किसी विशेष एंड्रॉइड उपयोगकर्ता के लिए क्रेडेंशियल-एन्क्रिप्टेड स्टोरेज। (कर्नेल में, इस कुंजी को fscrypt मास्टर कुंजी कहा जाता है।) इस कुंजी से, कर्नेल निम्नलिखित उपकुंजियों को प्राप्त करता है:

  • प्रमुख पहचानकर्ता। यह एन्क्रिप्शन के लिए उपयोग नहीं किया जाता है, बल्कि एक कुंजी की पहचान करने के लिए उपयोग किया जाने वाला मान है जिसके साथ एक विशेष फ़ाइल या निर्देशिका सुरक्षित है।
  • फ़ाइल सामग्री एन्क्रिप्शन कुंजी
  • फ़ाइल नाम एन्क्रिप्शन कुंजी

इसके विपरीत, निम्नलिखित आरेख एफबीई के लिए प्रमुख पदानुक्रम को दर्शाता है जब हार्डवेयर-लिपटे कुंजियों का उपयोग किया जाता है:

FBE कुंजी पदानुक्रम (हार्डवेयर-लिपटे कुंजी के साथ)
चित्रा 2. एफबीई कुंजी पदानुक्रम (हार्डवेयर-लिपटे कुंजी के साथ)

पिछले मामले की तुलना में, कुंजी पदानुक्रम में एक अतिरिक्त स्तर जोड़ा गया है, और फ़ाइल सामग्री एन्क्रिप्शन कुंजी को स्थानांतरित कर दिया गया है। रूट नोड अभी भी उस कुंजी का प्रतिनिधित्व करता है जिसे Android एन्क्रिप्टेड निर्देशिकाओं के एक सेट को अनलॉक करने के लिए Linux को पास करता है। हालाँकि, अब वह कुंजी अस्थायी रूप से लिपटे हुए रूप में है, और इसका उपयोग करने के लिए इसे समर्पित हार्डवेयर में पास किया जाना चाहिए। इस हार्डवेयर को दो इंटरफेस को लागू करना चाहिए जो एक अस्थायी रूप से लपेटी गई कुंजी लेते हैं:

  • inline_encryption_key प्राप्त करने के लिए एक इंटरफ़ेस और इसे सीधे इनलाइन क्रिप्टो इंजन के कीस्लॉट में प्रोग्राम करें। यह फ़ाइल सामग्री को कच्ची कुंजी तक पहुंच वाले सॉफ़्टवेयर के बिना एन्क्रिप्ट/डिक्रिप्ट करने की अनुमति देता है। Android सामान्य कर्नेल में, यह इंटरफ़ेस blk_crypto_ll_ops::keyslot_program ऑपरेशन से मेल खाता है, जिसे स्टोरेज ड्राइवर द्वारा कार्यान्वित किया जाना चाहिए।
  • एक इंटरफ़ेस प्राप्त करने और वापस करने के लिए sw_secret ("सॉफ़्टवेयर रहस्य" - जिसे कुछ स्थानों पर "कच्चा रहस्य" भी कहा जाता है), जो कि वह कुंजी है जिसका उपयोग Linux फ़ाइल सामग्री एन्क्रिप्शन के अलावा अन्य सभी चीज़ों के लिए उपकुंजियों को प्राप्त करने के लिए करता है। Android सामान्य कर्नेल में, यह इंटरफ़ेस blk_crypto_ll_ops::derive_sw_secret ऑपरेशन से मेल खाता है, जिसे स्टोरेज ड्राइवर द्वारा कार्यान्वित किया जाना चाहिए।

रॉ स्टोरेज कुंजी से inline_encryption_key और sw_secret प्राप्त करने के लिए, हार्डवेयर को क्रिप्टोग्राफ़िक रूप से मजबूत KDF का उपयोग करना चाहिए। इस केडीएफ को क्रिप्टोग्राफी सर्वोत्तम प्रथाओं का पालन करना चाहिए; इसमें कम से कम 256 बिट्स की सुरक्षा ताकत होनी चाहिए, यानी बाद में उपयोग किए जाने वाले किसी भी एल्गोरिदम के लिए पर्याप्त। यह सुनिश्चित करने के लिए प्रत्येक प्रकार की उपकुंजी प्राप्त करते समय एक अलग लेबल, संदर्भ, और/या एप्लिकेशन-विशिष्ट सूचना स्ट्रिंग का उपयोग करना चाहिए ताकि यह गारंटी दी जा सके कि परिणामी उपकुंजियां क्रिप्टोग्राफ़िक रूप से पृथक हैं, यानी उनमें से किसी एक का ज्ञान किसी अन्य को प्रकट नहीं करता है। कुंजी खींचने की आवश्यकता नहीं है, क्योंकि कच्ची भंडारण कुंजी पहले से ही समान रूप से यादृच्छिक कुंजी है।

तकनीकी रूप से, सुरक्षा आवश्यकताओं को पूरा करने वाले किसी भी KDF का उपयोग किया जा सकता है। हालांकि, परीक्षण उद्देश्यों के लिए, उसी केडीएफ को टेस्ट कोड में फिर से लागू करना आवश्यक है। वर्तमान में, एक केडीएफ की समीक्षा और कार्यान्वयन किया गया है; यह vts_kernel_encryption_test के स्रोत कोड में पाया जा सकता है। यह अनुशंसा की जाती है कि हार्डवेयर इस KDF का उपयोग करें, जो PRF के रूप में AES-256-CMAC के साथ NIST SP 800-108 "काउंटर मोड में KDF" का उपयोग करता है। ध्यान दें कि संगत होने के लिए, एल्गोरिथम के सभी भाग समान होने चाहिए, जिसमें प्रत्येक उपकुंजी के लिए केडीएफ संदर्भों और लेबलों का चुनाव शामिल है।

कुंजी लपेटना

हार्डवेयर-रैप की गई चाबियों के सुरक्षा लक्ष्यों को पूरा करने के लिए, दो प्रकार के की रैपिंग को परिभाषित किया गया है:

  • अल्पकालिक रैपिंग : हार्डवेयर एक कुंजी का उपयोग करके कच्ची कुंजी को एन्क्रिप्ट करता है जो प्रत्येक बूट पर बेतरतीब ढंग से उत्पन्न होती है और सीधे हार्डवेयर के बाहर उजागर नहीं होती है।
  • लंबी अवधि की रैपिंग : हार्डवेयर हार्डवेयर में निर्मित एक अद्वितीय, स्थायी कुंजी का उपयोग करके कच्ची कुंजी को एन्क्रिप्ट करता है जो सीधे हार्डवेयर के बाहर उजागर नहीं होती है।

भंडारण को अनलॉक करने के लिए लिनक्स कर्नेल को दी गई सभी कुंजियाँ अस्थायी रूप से लपेटी गई हैं। यह सुनिश्चित करता है कि यदि कोई हमलावर सिस्टम मेमोरी से उपयोग में आने वाली कुंजी निकालने में सक्षम है, तो वह कुंजी न केवल ऑफ-डिवाइस, बल्कि रीबूट के बाद ऑन-डिवाइस भी अनुपयोगी होगी।

साथ ही, एंड्रॉइड को अभी भी डिस्क पर चाबियों के एन्क्रिप्टेड संस्करण को स्टोर करने में सक्षम होना चाहिए ताकि उन्हें पहले स्थान पर अनलॉक किया जा सके। इस उद्देश्य के लिए कच्ची चाबियां काम करेंगी। हालांकि, यह वांछनीय है कि कभी भी सिस्टम मेमोरी में कच्ची कुंजियाँ मौजूद न हों ताकि उन्हें कभी भी ऑफ-डिवाइस के उपयोग के लिए निकाला न जा सके, भले ही बूट समय पर निकाला गया हो। इस कारण से, दीर्घकालीन लपेटन की अवधारणा को परिभाषित किया गया है।

इन दो अलग-अलग तरीकों से लपेटे गए प्रबंधन कुंजी का समर्थन करने के लिए, हार्डवेयर को निम्नलिखित इंटरफेस को लागू करना चाहिए:

  • भंडारण कुंजियों को उत्पन्न करने और आयात करने के लिए इंटरफेस, उन्हें दीर्घकालिक लिपटे रूप में लौटाते हैं। इन इंटरफेस पर अप्रत्यक्ष रूप से कीमिंट के माध्यम से पहुंचा जा सकता है, और वे TAG_STORAGE_KEY कीमिंट टैग के अनुरूप हैं। "उत्पन्न" क्षमता का उपयोग vold द्वारा Android द्वारा उपयोग के लिए नई संग्रहण कुंजियाँ उत्पन्न करने के लिए किया जाता है, जबकि "आयात" क्षमता का उपयोग vts_kernel_encryption_test द्वारा परीक्षण कुंजियों को आयात करने के लिए किया जाता है।
  • एक लंबे समय तक लपेटी गई स्टोरेज कुंजी को अस्थायी रूप से लपेटी गई स्टोरेज कुंजी में बदलने के लिए एक इंटरफ़ेस। यह convertStorageKeyToEphemeral KeyMint विधि से संबंधित है। स्टोरेज को अनलॉक करने के लिए इस विधि का उपयोग vold और vts_kernel_encryption_test दोनों द्वारा किया जाता है।

कुंजी रैपिंग एल्गोरिथ्म एक कार्यान्वयन विवरण है, लेकिन इसे एक मजबूत AEAD का उपयोग करना चाहिए जैसे AES-256-GCM यादृच्छिक IVs के साथ।

सॉफ्टवेयर परिवर्तन की आवश्यकता है

AOSP के पास पहले से ही हार्डवेयर में लिपटे कुंजियों का समर्थन करने के लिए एक बुनियादी ढांचा है। इसमें vold जैसे उपयोक्तास्थान घटकों में समर्थन, साथ ही साथ blk-crypto , fscrypt और dm-default-key में Linux कर्नेल समर्थन शामिल है।

हालाँकि, कुछ कार्यान्वयन-विशिष्ट परिवर्तनों की आवश्यकता है।

कीमिंट बदलता है

डिवाइस के KeyMint कार्यान्वयन को convertStorageKeyToEphemeral का समर्थन करने और TAG_STORAGE_KEY पद्धति को लागू करने के लिए संशोधित किया जाना चाहिए।

convertStorageKeyToEphemeral में, exportKey के बजाय ExportKey का उपयोग किया गया था।

लिनक्स कर्नेल बदलता है

डिवाइस के इनलाइन क्रिप्टो इंजन के लिए Linux कर्नेल ड्राइवर को हार्डवेयर में लिपटी कुंजियों का समर्थन करने के लिए संशोधित किया जाना चाहिए।

android14 और उच्चतर कर्नेल के लिए, BLK_CRYPTO_KEY_TYPE_HW_WRAPPED को 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_CRYPTO_FEATURE_WRAPPED_KEYS को blk_keyslot_manager::features में सेट करें, 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 ) हार्डवेयर-रैप की गई कुंजियों के लिए समर्थन के कारण छोड़े नहीं गए थे, क्योंकि परीक्षण के परिणाम अभी भी "उत्तीर्ण" होंगे उस मामले में।

सक्षम करने से

एक बार जब डिवाइस का हार्डवेयर-रैप्ड कुंजी समर्थन ठीक से काम कर रहा है, तो आप Android को FBE और मेटाडेटा एन्क्रिप्शन के लिए उपयोग करने के लिए डिवाइस की fstab फ़ाइल में निम्न परिवर्तन कर सकते हैं:

  • एफबीई: fileencryption पैरामीटर में wrappedkey_v0 फ्लैग जोड़ें। उदाहरण के लिए, fileencryption=::inlinecrypt_optimized+wrappedkey_v0 का उपयोग करें। अधिक जानकारी के लिए, एफबीई दस्तावेज देखें।
  • मेटाडेटा एन्क्रिप्शन: wrappedkey_v0 फ्लैग को metadata_encryption पैरामीटर में जोड़ें। उदाहरण के लिए, metadata_encryption=:wrappedkey_v0 का उपयोग करें। अधिक विवरण के लिए, मेटाडेटा एन्क्रिप्शन दस्तावेज़ीकरण देखें।