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

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

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

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

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

डिज़ाइन

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

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

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

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

प्रमुख पदानुक्रम

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

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

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

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

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

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

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

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

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

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

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

कुंजी लपेटना

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

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

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

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

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

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

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

सॉफ़्टवेयर परिवर्तन आवश्यक

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

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

कीमिंट परिवर्तन

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

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

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

डिवाइस के इनलाइन क्रिप्टो इंजन के लिए लिनक्स कर्नेल ड्राइवर को BLK_CRYPTO_FEATURE_WRAPPED_KEYS सेट करने के लिए संशोधित किया जाना चाहिए, keyslot_program() और keyslot_evict() ऑपरेशंस को प्रोग्रामिंग/हार्डवेयर-रैप्ड की को बेदखल करना, और derive_raw_secret() ऑपरेशन को लागू करना चाहिए।

परिक्षण

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

atest -v vts_kernel_encryption_test

परीक्षण लॉग पढ़ें और सत्यापित करें कि हार्डवेयर से लिपटे कुंजी परीक्षण मामलों (जैसे FBEPolicyTest.TestAesInlineCryptOptimizedHwWrappedKeyPolicy और DmDefaultKeyTest.TestHwWrappedKey ) को हार्डवेयर-लिपटे कुंजियों के समर्थन के कारण नहीं छोड़ा गया था, क्योंकि परीक्षण के परिणाम अभी भी "पास" होंगे उस मामले में।

सक्षम करने से

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

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