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

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

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

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

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

डिज़ाइन

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

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

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

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

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

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

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

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

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

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

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

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

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

  • प्राप्त करने के लिए एक अंतरफलक inline_encryption_key और सीधे इनलाइन क्रिप्टो इंजन के एक keyslot में यह कार्यक्रम। यह फ़ाइल सामग्री को कच्ची कुंजी तक पहुंच वाले सॉफ़्टवेयर के बिना एन्क्रिप्ट/डिक्रिप्ट करने की अनुमति देता है। एंड्रॉयड आम कर्नेल में, करने के लिए इस इंटरफेस मेल खाती 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, जो का उपयोग करता है NIST सपा 800-108 "काउंटर मोड में KDF" के साथ एईएस 256 CMAC पीआरएफ के रूप में। ध्यान दें कि संगत होने के लिए, एल्गोरिथम के सभी भाग समान होने चाहिए, जिसमें प्रत्येक उपकुंजी के लिए केडीएफ संदर्भों और लेबलों की पसंद शामिल है।

कुंजी लपेटना

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

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

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

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

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

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

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

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

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

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

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

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

Keymaster में, exportKey के बजाय इस्तेमाल किया गया था convertStorageKeyToEphemeral

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

डिवाइस की इनलाइन क्रिप्टो इंजन के लिए लिनक्स कर्नेल ड्राइवर सेट करने के लिए संशोधित किया जाना चाहिए 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 FBE और मेटाडाटा एन्क्रिप्शन के लिए एंड्रॉयड उपयोग यह सुनिश्चित करने के लिए फ़ाइल:

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