चिप पर सिस्टम (एसओसी) में एक विश्वसनीय निष्पादन वातावरण की उपलब्धता एंड्रॉइड डिवाइसों को एंड्रॉइड ओएस, प्लेटफ़ॉर्म सेवाओं और यहां तक कि तीसरे पक्ष के ऐप्स को हार्डवेयर-समर्थित, मजबूत सुरक्षा सेवाएं प्रदान करने का अवसर प्रदान करती है। एंड्रॉइड-विशिष्ट एक्सटेंशन चाहने वाले डेवलपर्स को android.security.keystore पर जाना चाहिए।
एंड्रॉइड 6.0 से पहले, एंड्रॉइड के पास पहले से ही एक सरल, हार्डवेयर-समर्थित क्रिप्टो सेवा एपीआई थी, जो कीमास्टर हार्डवेयर एब्स्ट्रैक्शन लेयर (एचएएल) के संस्करण 0.2 और 0.3 द्वारा प्रदान की गई थी। कीस्टोर ने डिजिटल हस्ताक्षर और सत्यापन संचालन, साथ ही असममित हस्ताक्षर कुंजी जोड़े की पीढ़ी और आयात प्रदान किया। यह पहले से ही कई उपकरणों पर लागू किया गया है, लेकिन कई सुरक्षा लक्ष्य हैं जिन्हें केवल हस्ताक्षर एपीआई के साथ आसानी से हासिल नहीं किया जा सकता है। एंड्रॉइड 6.0 में कीस्टोर ने क्षमताओं की एक विस्तृत श्रृंखला प्रदान करने के लिए कीस्टोर एपीआई का विस्तार किया।
एंड्रॉइड 6.0 में, कीस्टोर ने सममित क्रिप्टोग्राफ़िक प्रिमिटिव , एईएस और एचएमएसी और हार्डवेयर-समर्थित कुंजियों के लिए एक एक्सेस कंट्रोल सिस्टम जोड़ा। पहुंच नियंत्रण कुंजी निर्माण के दौरान निर्दिष्ट किए जाते हैं और कुंजी के जीवनकाल के लिए लागू किए जाते हैं। उपयोगकर्ता के प्रमाणित होने के बाद ही कुंजियों को प्रयोग करने योग्य होने तक सीमित किया जा सकता है, और केवल निर्दिष्ट उद्देश्यों के लिए या निर्दिष्ट क्रिप्टोग्राफ़िक मापदंडों के साथ। अधिक जानकारी के लिए, प्राधिकरण टैग और फ़ंक्शन पृष्ठ देखें।
क्रिप्टोग्राफ़िक प्रिमिटिव की सीमा का विस्तार करने के अलावा, एंड्रॉइड 6.0 में कीस्टोर ने निम्नलिखित जोड़ा:
- कुंजी के दुरुपयोग के कारण सुरक्षा समझौते के जोखिम को कम करने के लिए कुंजी के उपयोग को सीमित करने की अनुमति देने के लिए एक उपयोग नियंत्रण योजना
- निर्दिष्ट उपयोगकर्ताओं, ग्राहकों और एक निर्धारित समय सीमा के लिए कुंजियों के प्रतिबंध को सक्षम करने के लिए एक पहुंच नियंत्रण योजना
एंड्रॉइड 7.0 में, कीमास्टर 2 ने कुंजी सत्यापन और संस्करण बाइंडिंग के लिए समर्थन जोड़ा। कुंजी सत्यापन सार्वजनिक कुंजी प्रमाणपत्र प्रदान करता है जिसमें सुरक्षित हार्डवेयर में कुंजी के अस्तित्व और उसके कॉन्फ़िगरेशन को दूरस्थ रूप से सत्यापन योग्य बनाने के लिए कुंजी और उसके पहुंच नियंत्रण का विस्तृत विवरण होता है।
वर्जन बाइंडिंग कुंजियों को ऑपरेटिंग सिस्टम और पैच लेवल वर्जन से बांधता है। यह सुनिश्चित करता है कि एक हमलावर जो सिस्टम के पुराने संस्करण या टीईई सॉफ़्टवेयर में कमजोरी का पता लगाता है, वह किसी डिवाइस को कमजोर संस्करण में वापस नहीं ला सकता है और नए संस्करण के साथ बनाई गई कुंजियों का उपयोग नहीं कर सकता है। इसके अलावा, जब किसी दिए गए संस्करण और पैच स्तर वाली कुंजी का उपयोग किसी डिवाइस पर किया जाता है जिसे नए संस्करण या पैच स्तर पर अपग्रेड किया गया है, तो कुंजी को उपयोग करने से पहले अपग्रेड किया जाता है, और कुंजी का पिछला संस्करण अमान्य हो जाता है। जैसे ही डिवाइस को अपग्रेड किया जाता है, कुंजियाँ डिवाइस के साथ आगे की ओर "रैचेट" हो जाती हैं, लेकिन पिछले रिलीज़ में डिवाइस के किसी भी प्रत्यावर्तन के कारण कुंजियाँ अनुपयोगी हो जाती हैं।
एंड्रॉइड 8.0 में, कीमास्टर 3 पुरानी शैली के सी-स्ट्रक्चर हार्डवेयर एब्स्ट्रैक्शन लेयर (एचएएल) से नए हार्डवेयर इंटरफेस डेफिनिशन लैंग्वेज (एचआईडीएल) में एक परिभाषा से उत्पन्न सी ++ एचएएल इंटरफ़ेस में परिवर्तित हो गया। परिवर्तन के हिस्से के रूप में, कई तर्क प्रकार बदल गए, हालांकि प्रकारों और विधियों में पुराने प्रकारों और एचएएल संरचना विधियों के साथ एक-से-एक पत्राचार होता है। अधिक विवरण के लिए फ़ंक्शन पृष्ठ देखें।
इस इंटरफ़ेस संशोधन के अलावा, एंड्रॉइड 8.0 ने आईडी सत्यापन का समर्थन करने के लिए कीमास्टर 2 की सत्यापन सुविधा को बढ़ाया। आईडी सत्यापन हार्डवेयर पहचानकर्ताओं, जैसे डिवाइस सीरियल नंबर, उत्पाद का नाम और फोन आईडी (आईएमईआई / एमईआईडी) को दृढ़ता से प्रमाणित करने के लिए एक सीमित और वैकल्पिक तंत्र प्रदान करता है। इस अतिरिक्त को लागू करने के लिए, एंड्रॉइड 8.0 ने आईडी सत्यापन जोड़ने के लिए ASN.1 सत्यापन स्कीमा को बदल दिया। कीमास्टर कार्यान्वयन को प्रासंगिक डेटा आइटम पुनर्प्राप्त करने के लिए कुछ सुरक्षित तरीके खोजने की आवश्यकता है, साथ ही सुविधा को सुरक्षित और स्थायी रूप से अक्षम करने के लिए एक तंत्र को परिभाषित करना होगा।
Android 9 में, अपडेट शामिल हैं:
- कीमास्टर 4 में अपडेट करें
- एम्बेडेड सुरक्षित तत्वों के लिए समर्थन
- सुरक्षित कुंजी आयात के लिए समर्थन
- 3DES एन्क्रिप्शन के लिए समर्थन
- संस्करण बाइंडिंग में परिवर्तन ताकि Boot.img और system.img के पास स्वतंत्र अपडेट की अनुमति देने के लिए अलग-अलग संस्करण सेट हों
शब्दकोष
यहां कीस्टोर घटकों और उनके संबंधों का एक त्वरित अवलोकन दिया गया है।
AndroidKeystore Android फ्रेमवर्क API और घटक है जिसका उपयोग ऐप्स द्वारा Keystore कार्यक्षमता तक पहुंचने के लिए किया जाता है। इसे मानक जावा क्रिप्टोग्राफी आर्किटेक्चर एपीआई के विस्तार के रूप में कार्यान्वित किया गया है, और इसमें जावा कोड शामिल है जो ऐप की अपनी प्रक्रिया स्थान में चलता है। AndroidKeystore
कीस्टोर व्यवहार के लिए ऐप अनुरोधों को कीस्टोर डेमॉन पर अग्रेषित करके पूरा करता है।
कीस्टोर डेमॉन एक एंड्रॉइड सिस्टम डेमॉन है जो बाइंडर एपीआई के माध्यम से सभी कीस्टोर कार्यक्षमता तक पहुंच प्रदान करता है। यह "की ब्लॉब्स" को संग्रहीत करने के लिए ज़िम्मेदार है, जिसमें वास्तविक गुप्त कुंजी सामग्री होती है, जिसे एन्क्रिप्ट किया जाता है ताकि कीस्टोर उन्हें संग्रहीत कर सके लेकिन उनका उपयोग या खुलासा नहीं कर सके।
कीमास्टर्ड एक एचआईडीएल सर्वर है जो कीमास्टर टीए तक पहुंच प्रदान करता है। (यह नाम मानकीकृत नहीं है और वैचारिक उद्देश्यों के लिए है।)
कीमास्टर टीए (विश्वसनीय एप्लिकेशन) एक सुरक्षित संदर्भ में चलने वाला सॉफ्टवेयर है, जो अक्सर एआरएम एसओसी पर ट्रस्टज़ोन में चलता है, जो सभी सुरक्षित कीस्टोर संचालन प्रदान करता है, कच्चे कुंजी सामग्री तक पहुंच रखता है, कुंजी पर सभी एक्सेस नियंत्रण शर्तों को मान्य करता है , वगैरह।
LockSettingsService एंड्रॉइड सिस्टम घटक है जो पासवर्ड और फिंगरप्रिंट दोनों के उपयोगकर्ता प्रमाणीकरण के लिए जिम्मेदार है। यह कीस्टोर का हिस्सा नहीं है, लेकिन प्रासंगिक है क्योंकि कई कीस्टोर कुंजी संचालन के लिए उपयोगकर्ता प्रमाणीकरण की आवश्यकता होती है। LockSettingsService
प्रमाणीकरण टोकन प्राप्त करने के लिए गेटकीपर टीए और फ़िंगरप्रिंट टीए के साथ इंटरैक्ट करता है, जो यह कीस्टोर डेमॉन को प्रदान करता है, और जो अंततः कीमास्टर टीए एप्लिकेशन द्वारा उपभोग किया जाता है।
गेटकीपर टीए (विश्वसनीय एप्लिकेशन) सुरक्षित संदर्भ में चलने वाला एक अन्य घटक है, जो उपयोगकर्ता पासवर्ड को प्रमाणित करने और प्रमाणीकरण टोकन उत्पन्न करने के लिए जिम्मेदार है, जिसका उपयोग कीमास्टर टीए को यह साबित करने के लिए किया जाता है कि किसी विशेष उपयोगकर्ता के लिए किसी विशेष समय पर प्रमाणीकरण किया गया था।
फ़िंगरप्रिंट टीए (विश्वसनीय एप्लिकेशन) सुरक्षित संदर्भ में चलने वाला एक अन्य घटक है जो उपयोगकर्ता फ़िंगरप्रिंट को प्रमाणित करने और कीमास्टर टीए को साबित करने के लिए प्रमाणीकरण टोकन उत्पन्न करने के लिए ज़िम्मेदार है कि किसी विशेष उपयोगकर्ता के लिए किसी विशेष समय पर प्रमाणीकरण किया गया था।
वास्तुकला
एंड्रॉइड कीस्टोर एपीआई और अंतर्निहित कीमास्टर एचएएल एक्सेस-नियंत्रित, हार्डवेयर-समर्थित कुंजियों का उपयोग करके प्रोटोकॉल के कार्यान्वयन की अनुमति देने के लिए क्रिप्टोग्राफ़िक प्राइमेटिव्स का एक बुनियादी लेकिन पर्याप्त सेट प्रदान करता है।
कीमास्टर एचएएल एक OEM-प्रदत्त, गतिशील रूप से लोड करने योग्य लाइब्रेरी है जिसका उपयोग हार्डवेयर-समर्थित क्रिप्टोग्राफ़िक सेवाएं प्रदान करने के लिए कीस्टोर सेवा द्वारा किया जाता है। चीजों को सुरक्षित रखने के लिए, एचएएल कार्यान्वयन उपयोगकर्ता स्थान या यहां तक कि कर्नेल स्थान में कोई संवेदनशील संचालन नहीं करता है। संवेदनशील संचालन कुछ कर्नेल इंटरफ़ेस के माध्यम से पहुंचने वाले एक सुरक्षित प्रोसेसर को सौंपे जाते हैं। परिणामी वास्तुकला इस तरह दिखती है:

चित्र 1. कीमास्टर तक पहुंच
एंड्रॉइड डिवाइस के भीतर, कीमास्टर एचएएल के "क्लाइंट" में कई परतें होती हैं (उदाहरण के लिए ऐप, फ्रेमवर्क, कीस्टोर डेमॉन), लेकिन इस दस्तावेज़ के प्रयोजनों के लिए इसे अनदेखा किया जा सकता है। इसका मतलब यह है कि वर्णित कीमास्टर एचएएल एपीआई निम्न-स्तरीय है, जिसका उपयोग प्लेटफ़ॉर्म-आंतरिक घटकों द्वारा किया जाता है, और ऐप डेवलपर्स के संपर्क में नहीं आता है। उच्च स्तरीय एपीआई का वर्णन एंड्रॉइड डेवलपर साइट पर किया गया है।
कीमास्टर एचएएल का उद्देश्य सुरक्षा-संवेदनशील एल्गोरिदम को लागू करना नहीं है, बल्कि सुरक्षित दुनिया के लिए केवल मार्शल और अनमर्शल अनुरोध करना है। वायर प्रारूप कार्यान्वयन-परिभाषित है।
पिछले संस्करणों के साथ संगतता
कीमास्टर 1 एचएएल पहले जारी एचएएल के साथ पूरी तरह से असंगत है, उदाहरण के लिए कीमास्टर 0.2 और 0.3। पुराने कीमास्टर एचएएल के साथ लॉन्च किए गए एंड्रॉइड 5.0 और इससे पहले के उपकरणों पर इंटरऑपरेबिलिटी की सुविधा के लिए, कीस्टोर एक एडाप्टर प्रदान करता है जो मौजूदा हार्डवेयर लाइब्रेरी में कॉल के साथ कीमास्टर 1 एचएएल को कार्यान्वित करता है। परिणाम कीमास्टर 1 एचएएल में कार्यक्षमता की पूरी श्रृंखला प्रदान नहीं कर सकता है। विशेष रूप से, यह केवल आरएसए और ईसीडीएसए एल्गोरिदम का समर्थन करता है, और सभी प्रमुख प्राधिकरण प्रवर्तन गैर-सुरक्षित दुनिया में एडाप्टर द्वारा किया जाता है।
कीमास्टर 2 ने get_supported_*
विधियों को हटाकर और finish()
विधि को इनपुट स्वीकार करने की अनुमति देकर एचएएल इंटरफ़ेस को और सरल बनाया। यह उन मामलों में टीईई में राउंड ट्रिप की संख्या कम कर देता है जहां इनपुट एक ही बार में उपलब्ध होता है, और एईएडी डिक्रिप्शन के कार्यान्वयन को सरल बनाता है।
एंड्रॉइड 8.0 में, कीमास्टर 3 पुरानी शैली के सी-स्ट्रक्चर एचएएल से नए हार्डवेयर इंटरफेस डेफिनिशन लैंग्वेज (एचआईडीएल) में एक परिभाषा से उत्पन्न सी ++ एचएएल इंटरफ़ेस में परिवर्तित हो गया। उत्पन्न IKeymasterDevice
वर्ग को उपवर्गित करके और शुद्ध आभासी तरीकों को लागू करके एक नई शैली का HAL कार्यान्वयन बनाया गया है। परिवर्तन के हिस्से के रूप में, कई तर्क प्रकार बदल गए हैं, हालांकि प्रकार और विधियों में पुराने प्रकारों और एचएएल संरचना विधियों के साथ एक-से-एक पत्राचार होता है।
एचआईडीएल सिंहावलोकन
हार्डवेयर इंटरफ़ेस डेफिनिशन लैंग्वेज (HIDL) हार्डवेयर इंटरफ़ेस निर्दिष्ट करने के लिए एक कार्यान्वयन भाषा-स्वतंत्र तंत्र प्रदान करता है। HIDL टूलिंग वर्तमान में C++ और Java इंटरफ़ेस के निर्माण का समर्थन करती है। यह उम्मीद की जाती है कि अधिकांश विश्वसनीय निष्पादन पर्यावरण (टीईई) कार्यान्वयनकर्ता सी++ टूलींग को अधिक सुविधाजनक पाएंगे, इसलिए यह दस्तावेज़ केवल सी++ प्रतिनिधित्व पर चर्चा करता है।
HIDL इंटरफ़ेस में विधियों का एक सेट शामिल है, जिसे इस प्रकार व्यक्त किया गया है:
methodName(INPUT ARGUMENTS) generates (RESULT ARGUMENTS);
विभिन्न पूर्व-परिभाषित प्रकार हैं, और एचएएल नए प्रगणित और संरचना प्रकारों को परिभाषित कर सकते हैं। एचआईडीएल पर अधिक जानकारी के लिए संदर्भ अनुभाग देखें।
Keymaster 3 IKeymasterDevice.hal
से एक उदाहरण विधि है:
generateKey(vec<KeyParameter> keyParams) generates(ErrorCode error, vec<uint8_t> keyBlob, KeyCharacteristics keyCharacteristics);
यह keymaster2 HAL से निम्नलिखित के समतुल्य है:
keymaster_error_t (*generate_key)( const struct keymaster2_device* dev, const keymaster_key_param_set_t* params, keymaster_key_blob_t* key_blob, keymaster_key_characteristics_t* characteristics);
HIDL संस्करण में, dev
तर्क हटा दिया गया है, क्योंकि यह अंतर्निहित है। params
तर्क अब एक संरचना नहीं है जिसमें key_parameter_t
ऑब्जेक्ट की एक सरणी को संदर्भित करने वाला पॉइंटर होता है, बल्कि एक vec
(वेक्टर) होता है जिसमें KeyParameter
ऑब्जेक्ट होते हैं। रिटर्न मान " generates
" खंड में सूचीबद्ध हैं, जिसमें कुंजी ब्लॉब के लिए uint8_t
मानों का एक वेक्टर भी शामिल है।
HIDL कंपाइलर द्वारा उत्पन्न C++ वर्चुअल विधि है:
Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams, generateKey_cb _hidl_cb) override;
जहां generateKey_cb
एक फ़ंक्शन पॉइंटर है जिसे इस प्रकार परिभाषित किया गया है:
std::function<void(ErrorCode error, const hidl_vec<uint8_t>& keyBlob, const KeyCharacteristics& keyCharacteristics)>
यानी, generateKey_cb
एक फ़ंक्शन है जो जेनरेट क्लॉज में सूचीबद्ध रिटर्न मान लेता है। एचएएल कार्यान्वयन वर्ग इस generateKey
विधि को ओवरराइड करता है और कॉलर को ऑपरेशन के परिणाम वापस करने के लिए generateKey_cb
फ़ंक्शन पॉइंटर को कॉल करता है। ध्यान दें कि फ़ंक्शन पॉइंटर कॉल सिंक्रोनस है। कॉलर generateKey
कॉल करता है और generateKey
आपूर्ति किए गए फ़ंक्शन पॉइंटर को कॉल करता है, जो पूरा होने पर निष्पादित होता है, generateKey
कार्यान्वयन पर नियंत्रण लौटाता है, जो फिर कॉलर के पास वापस आ जाता है।
विस्तृत उदाहरण के लिए, hardware/interfaces/keymaster/3.0/default/KeymasterDevice.cpp
में डिफ़ॉल्ट कार्यान्वयन देखें। डिफ़ॉल्ट कार्यान्वयन पुराने शैली के keymaster0, keymaster1, या keymaster2 HALS वाले उपकरणों के लिए पश्चगामी संगतता प्रदान करता है।
अभिगम नियंत्रण
कीस्टोर एक्सेस कंट्रोल का सबसे बुनियादी नियम यह है कि प्रत्येक ऐप का अपना नेमस्पेस होता है। लेकिन हर नियम का एक अपवाद होता है. कीस्टोर में कुछ हार्ड-कोडित मानचित्र हैं जो कुछ सिस्टम घटकों को कुछ अन्य नामस्थानों तक पहुंचने की अनुमति देते हैं। यह एक बहुत ही कुंद उपकरण है जिसमें यह एक घटक को दूसरे नामस्थान पर पूर्ण नियंत्रण देता है। और फिर कीस्टोर के ग्राहकों के रूप में विक्रेता घटकों का मामला है। वर्तमान में हमारे पास विक्रेता घटकों के लिए नामस्थान स्थापित करने का कोई तरीका नहीं है, उदाहरण के लिए, WPA निवेदक।
विक्रेता घटकों को समायोजित करने और हार्ड-कोडित अपवादों के बिना पहुंच नियंत्रण को सामान्य बनाने के लिए, कीस्टोर 2.0 डोमेन और SELinux नेमस्पेस पेश करता है।
कीस्टोर डोमेन
कीस्टोर डोमेन के साथ, हम यूआईडी से नेमस्पेस को अलग कर सकते हैं। कीस्टोर में कुंजी तक पहुंचने वाले ग्राहकों को उस डोमेन, नेमस्पेस और उपनाम को निर्दिष्ट करना होगा जिसे वे एक्सेस करना चाहते हैं। इस टपल और कॉलर की पहचान के आधार पर हम यह निर्धारित कर सकते हैं कि कॉलर किस कुंजी तक पहुंचना चाहता है और क्या उसके पास उचित अनुमतियां हैं।
हम पांच डोमेन पैरामीटर पेश करते हैं जो नियंत्रित करते हैं कि कुंजियों तक कैसे पहुंचा जा सकता है। वे कुंजी डिस्क्रिप्टर के नेमस्पेस पैरामीटर के शब्दार्थ को नियंत्रित करते हैं और एक्सेस नियंत्रण कैसे किया जाता है।
-
DOMAIN_APP
: ऐप डोमेन पुराने व्यवहार को कवर करता है। जावा कीस्टोर एसपीआई डिफ़ॉल्ट रूप से इस डोमेन का उपयोग करता है। जब इस डोमेन का उपयोग किया जाता है, तो नेमस्पेस तर्क को नजरअंदाज कर दिया जाता है और इसके बजाय कॉलर के यूआईडी का उपयोग किया जाता है। इस डोमेन तक पहुंच को SELinux नीति में क्लासkeystore_key
के लिए Keystore लेबल द्वारा नियंत्रित किया जाता है। -
DOMAIN_SELINUX
: यह डोमेन इंगित करता है कि नेमस्पेस में SELinux नीति में एक लेबल है। नेमस्पेस पैरामीटर को देखा जाता है और लक्ष्य संदर्भ में अनुवादित किया जाता है, औरkeystore_key
वर्ग के लिए SELinux संदर्भ को कॉल करने के लिए अनुमति जांच की जाती है। जब दिए गए ऑपरेशन के लिए अनुमति स्थापित हो जाती है, तो कुंजी लुकअप के लिए पूर्ण टपल का उपयोग किया जाता है। -
DOMAIN_GRANT
: अनुदान डोमेन इंगित करता है कि नेमस्पेस पैरामीटर एक अनुदान पहचानकर्ता है। उपनाम पैरामीटर को नजरअंदाज कर दिया गया है। अनुदान निर्मित होने पर SELinux जाँच की जाती है। आगे पहुंच नियंत्रण केवल यह जांचता है कि कॉलर यूआईडी अनुरोधित अनुदान के अनुदान प्राप्तकर्ता यूआईडी से मेल खाता है या नहीं। -
DOMAIN_KEY_ID
: यह डोमेन इंगित करता है कि नेमस्पेस पैरामीटर एक अद्वितीय कुंजी आईडी है। कुंजी स्वयंDOMAIN_APP
याDOMAIN_SELINUX
के साथ बनाई गई हो सकती है। अनुमति की जांचdomain
औरnamespace
कुंजी डेटाबेस से उसी तरह लोड करने के बाद की जाती है जैसे कि ब्लॉब को डोमेन, नेमस्पेस और उपनाम टपल द्वारा लोड किया गया था। कुंजी आईडी डोमेन का औचित्य निरंतरता है। किसी कुंजी को उपनाम से एक्सेस करते समय, बाद की कॉलें अलग-अलग कुंजी पर काम कर सकती हैं, क्योंकि एक नई कुंजी उत्पन्न या आयात की जा सकती है और इस उपनाम से जुड़ी हो सकती है। हालाँकि, कुंजी आईडी कभी नहीं बदलती। इसलिए जब कुंजी को एक बार उपनाम का उपयोग करके कीस्टोर डेटाबेस से लोड करने के बाद कुंजी आईडी द्वारा उपयोग किया जाता है, तो कोई निश्चित हो सकता है कि यह वही कुंजी है जब तक कुंजी आईडी अभी भी मौजूद है। यह कार्यक्षमता ऐप डेवलपर्स के सामने नहीं आती है। इसके बजाय, असुरक्षित तरीके से एक साथ उपयोग किए जाने पर भी अधिक सुसंगत अनुभव प्रदान करने के लिए इसका उपयोग एंड्रॉइड कीस्टोर एसपीआई के भीतर किया जाता है। -
DOMAIN_BLOB
: ब्लॉब डोमेन इंगित करता है कि कॉल करने वाला ब्लॉब को स्वयं प्रबंधित करता है। इसका उपयोग उन ग्राहकों के लिए किया जाता है जिन्हें डेटा विभाजन माउंट होने से पहले कीस्टोर तक पहुंचने की आवश्यकता होती है। कुंजी ब्लॉब कुंजी डिस्क्रिप्टर केblob
फ़ील्ड में शामिल है।
SELinux डोमेन का उपयोग करके, हम विक्रेता घटकों को बहुत विशिष्ट कीस्टोर नेमस्पेस तक पहुंच प्रदान कर सकते हैं जिन्हें सेटिंग्स डायलॉग जैसे सिस्टम घटकों द्वारा साझा किया जा सकता है।
keystore_key के लिए SELinux नीति
नेमस्पेस लेबल keystore2_key_context
फ़ाइल का उपयोग करके कॉन्फ़िगर किए गए हैं।
इन फ़ाइलों की प्रत्येक पंक्ति एक संख्यात्मक नेमस्पेस आईडी को SELinux लेबल पर मैप करती है। उदाहरण के लिए,
# wifi_key is a keystore2_key namespace intended to be used by wpa supplicant and # Settings to share keystore keys. 102 u:object_r:wifi_key:s0
इस तरह से एक नया कुंजी नामस्थान स्थापित करने के बाद, हम एक उपयुक्त नीति जोड़कर उस तक पहुंच प्रदान कर सकते हैं। उदाहरण के लिए, wpa_supplicant
नए नेमस्पेस में कुंजियाँ प्राप्त करने और उपयोग करने की अनुमति देने के लिए हम hal_wifi_supplicant.te
में निम्नलिखित पंक्ति जोड़ेंगे:
allow hal_wifi_supplicant wifi_key:keystore2_key { get, use };
नया नेमस्पेस सेट करने के बाद, AndroidKeyStore का उपयोग लगभग हमेशा की तरह किया जा सकता है। अंतर केवल इतना है कि नेमस्पेस आईडी निर्दिष्ट होनी चाहिए। कीस्टोर से और उसमें कुंजी लोड करने और आयात करने के लिए, नेमस्पेस आईडी को AndroidKeyStoreLoadStoreParameter
का उपयोग करके निर्दिष्ट किया गया है। उदाहरण के लिए,
import android.security.keystore2.AndroidKeyStoreLoadStoreParameter; import java.security.KeyStore; KeyStore keystore = KeyStore.getInstance("AndroidKeyStore"); keystore.load(new AndroidKeyStoreLoadStoreParameter(102));
किसी दिए गए नेमस्पेस में एक कुंजी उत्पन्न करने के लिए, नेमस्पेस आईडी KeyGenParameterSpec.Builder#setNamespace():
import android.security.keystore.KeyGenParameterSpec; KeyGenParameterSpec.Builder specBuilder = new KeyGenParameterSpec.Builder(); specBuilder.setNamespace(102);
Keystore 2.0 SELinux नेमस्पेस को कॉन्फ़िगर करने के लिए निम्नलिखित संदर्भ फ़ाइलों का उपयोग किया जा सकता है। टकराव से बचने के लिए प्रत्येक विभाजन में 10,000 नेमस्पेस आईडी की एक अलग आरक्षित सीमा होती है।
PARTITION | श्रेणी | कॉन्फ़िग फ़ाइलें |
---|---|---|
प्रणाली | 0 ... 9,999 | /system/etc/selinux/keystore2_key_contexts, /plat_keystore2_key_contexts |
विस्तारित प्रणाली | 10,000 ... 19,999 | /system_ext/etc/selinux/system_ext_keystore2_key_contexts, /system_ext_keystore2_key_contexts |
उत्पाद | 20,000 ... 29,999 | /product/etc/selinux/product_keystore2_key_contexts, /product_keystore2_key_contexts |
विक्रेता | 30,000 ... 39,999 | /vendor/etc/selinux/vendor_keystore2_key_contexts, /vendor_keystore2_key_contexts |
क्लाइंट SELinux डोमेन और वांछित वर्चुअल नेमस्पेस का अनुरोध करके कुंजी का अनुरोध करता है, इस मामले में "wifi_key"
, इसकी संख्यात्मक आईडी द्वारा।
उसके ऊपर, निम्नलिखित नामस्थान परिभाषित किए गए हैं। यदि वे विशेष नियमों को प्रतिस्थापित करते हैं, तो निम्न तालिका उस यूआईडी को इंगित करती है जिसका वे उपयोग करते थे।
नेमस्पेस आईडी | एसईपॉलिसी लेबल | यूआईडी | विवरण |
---|---|---|---|
0 | su_key | एन/ए | सुपर उपयोगकर्ता कुंजी. केवल userdebug और eng बिल्ड पर परीक्षण के लिए उपयोग किया जाता है। उपयोगकर्ता निर्माण पर प्रासंगिक नहीं है. |
1 | शेल_की | एन/ए | शेल के लिए नेमस्पेस उपलब्ध है। अधिकतर परीक्षण के लिए उपयोग किया जाता है, लेकिन कमांड लाइन से उपयोगकर्ता बिल्ड पर भी इसका उपयोग किया जा सकता है। |
100 | vold_key | एन/ए | वॉल्ड द्वारा उपयोग के लिए अभिप्रेत है। |
101 | odsing_key | एन/ए | ऑन-डिवाइस साइनिंग डेमॉन द्वारा उपयोग किया जाता है। |
102 | वाईफ़ाई_कुंजी | AID_WIFI(1010) | wpa_supplicant सहित Android के Wifi सिबसिस्टम द्वारा उपयोग किया जाता है। |
120 | पुनरारंभ_ऑन_रिबूट_कुंजी | सहायता_प्रणाली(1000) | रिबूट पर रिज्यूमे का समर्थन करने के लिए एंड्रॉइड के सिस्टम सर्वर द्वारा उपयोग किया जाता है। |
वेक्टर तक पहुंचें
SELinux वर्ग keystore_key
काफी पुराना हो गया है और कुछ अनुमतियाँ, जैसे verify
या sign
, अपना अर्थ खो चुकी हैं। यहां अनुमतियों का नया सेट keystore2_key
है, जिसे Keystore 2.0 लागू करेगा।
अनुमति | अर्थ |
---|---|
delete | कीस्टोर से चाबियाँ हटाते समय जाँच की गई। |
get_info | जब कुंजी के मेटाडेटा का अनुरोध किया जाता है तो जाँच की जाती है। |
grant | लक्ष्य संदर्भ में कुंजी के लिए अनुदान बनाने के लिए कॉल करने वाले को इस अनुमति की आवश्यकता होती है। |
manage_blob | कॉल करने वाला व्यक्ति दिए गए SELinux नेमस्पेस पर DOMAIN_BLOB उपयोग कर सकता है, जिससे ब्लॉब्स को स्वयं प्रबंधित किया जा सकता है। यह वॉल्ड के लिए विशेष रूप से उपयोगी है. |
rebind | यह अनुमति नियंत्रित करती है कि क्या किसी उपनाम को नई कुंजी में दोबारा जोड़ा जा सकता है। यह सम्मिलन के लिए आवश्यक है और इसका तात्पर्य है कि पहले से बंधी कुंजी हटा दी जाएगी। यह मूल रूप से एक सम्मिलित अनुमति है, लेकिन यह कीस्टोर के अर्थ को बेहतर ढंग से पकड़ती है। |
req_forced_op | इस अनुमति वाले ग्राहक अप्राप्य ऑपरेशन बना सकते हैं, और ऑपरेशन निर्माण तब तक विफल नहीं होता जब तक कि सभी ऑपरेशन स्लॉट अप्राप्य ऑपरेशन द्वारा नहीं ले लिए जाते। |
update | किसी कुंजी के उपघटक को अद्यतन करने के लिए आवश्यक है. |
use | कीमिंट ऑपरेशन बनाते समय जाँच की गई जो मुख्य सामग्री का उपयोग करता है, उदाहरण के लिए, हस्ताक्षर करने, एन/डिक्रिप्शन के लिए। |
use_dev_id | डिवाइस पहचान संबंधी जानकारी, जैसे डिवाइस आईडी सत्यापन, उत्पन्न करते समय आवश्यक है। |
इसके अतिरिक्त, हमने SELinux सुरक्षा वर्ग keystore2
में गैर-कुंजी विशिष्ट कीस्टोर अनुमतियों के एक सेट को विभाजित किया है:
अनुमति | अर्थ |
---|---|
add_auth | ऑथेंटिकेशन टोकन जोड़ने के लिए गेटकीपर या बायोमेट्रिक्स मैनेजर जैसे प्रमाणीकरण प्रदाता द्वारा आवश्यक है। |
clear_ns | पूर्व में Clear_uid, यह अनुमति किसी नामस्थान के गैर-मालिक को उस नामस्थान की सभी कुंजियाँ हटाने की अनुमति देती है। |
list | विभिन्न संपत्तियों, जैसे स्वामित्व या प्रमाणीकरण सीमा के आधार पर कुंजियों की गणना करने के लिए सिस्टम द्वारा आवश्यक। कॉल करने वालों को अपने स्वयं के नामस्थानों की गणना करने के लिए इस अनुमति की आवश्यकता नहीं है। यह get_info अनुमति द्वारा कवर किया गया है। |
lock | यह अनुमति कीस्टोर को लॉक करने की अनुमति देती है, अर्थात, मास्टर कुंजी को बाहर निकाल देती है, जिससे कि ऑथ बाउंड कुंजियाँ अनुपयोगी और अनुपयोगी हो जाती हैं। |
reset | यह अनुमति कीस्टोर को फ़ैक्टरी डिफ़ॉल्ट पर रीसेट करने की अनुमति देती है, और उन सभी कुंजियों को हटा देती है जो एंड्रॉइड ओएस के कामकाज के लिए महत्वपूर्ण नहीं हैं। |
unlock | ऑथ बाउंड कुंजियों के लिए मास्टर कुंजी को अनलॉक करने का प्रयास करने के लिए यह अनुमति आवश्यक है। |
चिप पर सिस्टम (एसओसी) में एक विश्वसनीय निष्पादन वातावरण की उपलब्धता एंड्रॉइड डिवाइसों को एंड्रॉइड ओएस, प्लेटफ़ॉर्म सेवाओं और यहां तक कि तीसरे पक्ष के ऐप्स को हार्डवेयर-समर्थित, मजबूत सुरक्षा सेवाएं प्रदान करने का अवसर प्रदान करती है। एंड्रॉइड-विशिष्ट एक्सटेंशन चाहने वाले डेवलपर्स को android.security.keystore पर जाना चाहिए।
एंड्रॉइड 6.0 से पहले, एंड्रॉइड के पास पहले से ही एक सरल, हार्डवेयर-समर्थित क्रिप्टो सेवा एपीआई थी, जो कीमास्टर हार्डवेयर एब्स्ट्रैक्शन लेयर (एचएएल) के संस्करण 0.2 और 0.3 द्वारा प्रदान की गई थी। कीस्टोर ने डिजिटल हस्ताक्षर और सत्यापन संचालन, साथ ही असममित हस्ताक्षर कुंजी जोड़े की पीढ़ी और आयात प्रदान किया। यह पहले से ही कई उपकरणों पर लागू किया गया है, लेकिन कई सुरक्षा लक्ष्य हैं जिन्हें केवल हस्ताक्षर एपीआई के साथ आसानी से हासिल नहीं किया जा सकता है। एंड्रॉइड 6.0 में कीस्टोर ने क्षमताओं की एक विस्तृत श्रृंखला प्रदान करने के लिए कीस्टोर एपीआई का विस्तार किया।
एंड्रॉइड 6.0 में, कीस्टोर ने सममित क्रिप्टोग्राफ़िक प्रिमिटिव , एईएस और एचएमएसी और हार्डवेयर-समर्थित कुंजियों के लिए एक एक्सेस कंट्रोल सिस्टम जोड़ा। पहुंच नियंत्रण कुंजी निर्माण के दौरान निर्दिष्ट किए जाते हैं और कुंजी के जीवनकाल के लिए लागू किए जाते हैं। उपयोगकर्ता के प्रमाणित होने के बाद ही कुंजियों को प्रयोग करने योग्य होने तक सीमित किया जा सकता है, और केवल निर्दिष्ट उद्देश्यों के लिए या निर्दिष्ट क्रिप्टोग्राफ़िक मापदंडों के साथ। अधिक जानकारी के लिए, प्राधिकरण टैग और फ़ंक्शन पृष्ठ देखें।
क्रिप्टोग्राफ़िक प्रिमिटिव की सीमा का विस्तार करने के अलावा, एंड्रॉइड 6.0 में कीस्टोर ने निम्नलिखित जोड़ा:
- कुंजी के दुरुपयोग के कारण सुरक्षा समझौते के जोखिम को कम करने के लिए कुंजी के उपयोग को सीमित करने की अनुमति देने के लिए एक उपयोग नियंत्रण योजना
- निर्दिष्ट उपयोगकर्ताओं, ग्राहकों और एक निर्धारित समय सीमा के लिए कुंजियों के प्रतिबंध को सक्षम करने के लिए एक पहुंच नियंत्रण योजना
एंड्रॉइड 7.0 में, कीमास्टर 2 ने कुंजी सत्यापन और संस्करण बाइंडिंग के लिए समर्थन जोड़ा। कुंजी सत्यापन सार्वजनिक कुंजी प्रमाणपत्र प्रदान करता है जिसमें सुरक्षित हार्डवेयर में कुंजी के अस्तित्व और उसके कॉन्फ़िगरेशन को दूरस्थ रूप से सत्यापन योग्य बनाने के लिए कुंजी और उसके पहुंच नियंत्रण का विस्तृत विवरण होता है।
वर्जन बाइंडिंग कुंजियों को ऑपरेटिंग सिस्टम और पैच लेवल वर्जन से बांधता है। यह सुनिश्चित करता है कि एक हमलावर जो सिस्टम के पुराने संस्करण या टीईई सॉफ़्टवेयर में कमजोरी का पता लगाता है, वह किसी डिवाइस को कमजोर संस्करण में वापस नहीं ला सकता है और नए संस्करण के साथ बनाई गई कुंजियों का उपयोग नहीं कर सकता है। इसके अलावा, जब किसी दिए गए संस्करण और पैच स्तर वाली कुंजी का उपयोग किसी डिवाइस पर किया जाता है जिसे नए संस्करण या पैच स्तर पर अपग्रेड किया गया है, तो कुंजी को उपयोग करने से पहले अपग्रेड किया जाता है, और कुंजी का पिछला संस्करण अमान्य हो जाता है। जैसे ही डिवाइस को अपग्रेड किया जाता है, कुंजियाँ डिवाइस के साथ आगे की ओर "रैचेट" हो जाती हैं, लेकिन पिछले रिलीज़ में डिवाइस के किसी भी प्रत्यावर्तन के कारण कुंजियाँ अनुपयोगी हो जाती हैं।
एंड्रॉइड 8.0 में, कीमास्टर 3 पुरानी शैली के सी-स्ट्रक्चर हार्डवेयर एब्स्ट्रैक्शन लेयर (एचएएल) से नए हार्डवेयर इंटरफेस डेफिनिशन लैंग्वेज (एचआईडीएल) में एक परिभाषा से उत्पन्न सी ++ एचएएल इंटरफ़ेस में परिवर्तित हो गया। परिवर्तन के हिस्से के रूप में, कई तर्क प्रकार बदल गए, हालांकि प्रकारों और विधियों में पुराने प्रकारों और एचएएल संरचना विधियों के साथ एक-से-एक पत्राचार होता है। अधिक विवरण के लिए फ़ंक्शन पृष्ठ देखें।
इस इंटरफ़ेस संशोधन के अलावा, एंड्रॉइड 8.0 ने आईडी सत्यापन का समर्थन करने के लिए कीमास्टर 2 की सत्यापन सुविधा को बढ़ाया। आईडी सत्यापन हार्डवेयर पहचानकर्ताओं, जैसे डिवाइस सीरियल नंबर, उत्पाद का नाम और फोन आईडी (आईएमईआई / एमईआईडी) को दृढ़ता से प्रमाणित करने के लिए एक सीमित और वैकल्पिक तंत्र प्रदान करता है। इस अतिरिक्त को लागू करने के लिए, एंड्रॉइड 8.0 ने आईडी सत्यापन जोड़ने के लिए ASN.1 सत्यापन स्कीमा को बदल दिया। कीमास्टर कार्यान्वयन को प्रासंगिक डेटा आइटम पुनर्प्राप्त करने के लिए कुछ सुरक्षित तरीके खोजने की आवश्यकता है, साथ ही सुविधा को सुरक्षित और स्थायी रूप से अक्षम करने के लिए एक तंत्र को परिभाषित करना होगा।
Android 9 में, अपडेट शामिल हैं:
- कीमास्टर 4 में अपडेट करें
- एम्बेडेड सुरक्षित तत्वों के लिए समर्थन
- सुरक्षित कुंजी आयात के लिए समर्थन
- 3DES एन्क्रिप्शन के लिए समर्थन
- संस्करण बाइंडिंग में परिवर्तन ताकि Boot.img और system.img के पास स्वतंत्र अपडेट की अनुमति देने के लिए अलग-अलग संस्करण सेट हों
शब्दकोष
यहां कीस्टोर घटकों और उनके संबंधों का एक त्वरित अवलोकन दिया गया है।
AndroidKeystore Android फ्रेमवर्क API और घटक है जिसका उपयोग ऐप्स द्वारा Keystore कार्यक्षमता तक पहुंचने के लिए किया जाता है। इसे मानक जावा क्रिप्टोग्राफी आर्किटेक्चर एपीआई के विस्तार के रूप में कार्यान्वित किया गया है, और इसमें जावा कोड शामिल है जो ऐप की अपनी प्रक्रिया स्थान में चलता है। AndroidKeystore
कीस्टोर व्यवहार के लिए ऐप अनुरोधों को कीस्टोर डेमॉन पर अग्रेषित करके पूरा करता है।
कीस्टोर डेमॉन एक एंड्रॉइड सिस्टम डेमॉन है जो बाइंडर एपीआई के माध्यम से सभी कीस्टोर कार्यक्षमता तक पहुंच प्रदान करता है। यह "की ब्लॉब्स" को संग्रहीत करने के लिए ज़िम्मेदार है, जिसमें वास्तविक गुप्त कुंजी सामग्री होती है, जिसे एन्क्रिप्ट किया जाता है ताकि कीस्टोर उन्हें संग्रहीत कर सके लेकिन उनका उपयोग या खुलासा नहीं कर सके।
कीमास्टर्ड एक एचआईडीएल सर्वर है जो कीमास्टर टीए तक पहुंच प्रदान करता है। (यह नाम मानकीकृत नहीं है और वैचारिक उद्देश्यों के लिए है।)
कीमास्टर टीए (विश्वसनीय एप्लिकेशन) एक सुरक्षित संदर्भ में चलने वाला सॉफ्टवेयर है, जो अक्सर एआरएम एसओसी पर ट्रस्टज़ोन में चलता है, जो सभी सुरक्षित कीस्टोर संचालन प्रदान करता है, कच्चे कुंजी सामग्री तक पहुंच रखता है, कुंजी पर सभी एक्सेस नियंत्रण शर्तों को मान्य करता है , वगैरह।
LockSettingsService एंड्रॉइड सिस्टम घटक है जो पासवर्ड और फिंगरप्रिंट दोनों के उपयोगकर्ता प्रमाणीकरण के लिए जिम्मेदार है। यह कीस्टोर का हिस्सा नहीं है, लेकिन प्रासंगिक है क्योंकि कई कीस्टोर कुंजी संचालन के लिए उपयोगकर्ता प्रमाणीकरण की आवश्यकता होती है। LockSettingsService
प्रमाणीकरण टोकन प्राप्त करने के लिए गेटकीपर टीए और फ़िंगरप्रिंट टीए के साथ इंटरैक्ट करता है, जो यह कीस्टोर डेमॉन को प्रदान करता है, और जो अंततः कीमास्टर टीए एप्लिकेशन द्वारा उपभोग किया जाता है।
गेटकीपर टीए (विश्वसनीय एप्लिकेशन) सुरक्षित संदर्भ में चलने वाला एक अन्य घटक है, जो उपयोगकर्ता पासवर्ड को प्रमाणित करने और प्रमाणीकरण टोकन उत्पन्न करने के लिए जिम्मेदार है, जिसका उपयोग कीमास्टर टीए को यह साबित करने के लिए किया जाता है कि किसी विशेष उपयोगकर्ता के लिए किसी विशेष समय पर प्रमाणीकरण किया गया था।
फ़िंगरप्रिंट टीए (विश्वसनीय एप्लिकेशन) सुरक्षित संदर्भ में चलने वाला एक अन्य घटक है जो उपयोगकर्ता फ़िंगरप्रिंट को प्रमाणित करने और कीमास्टर टीए को साबित करने के लिए प्रमाणीकरण टोकन उत्पन्न करने के लिए ज़िम्मेदार है कि किसी विशेष उपयोगकर्ता के लिए किसी विशेष समय पर प्रमाणीकरण किया गया था।
वास्तुकला
एंड्रॉइड कीस्टोर एपीआई और अंतर्निहित कीमास्टर एचएएल एक्सेस-नियंत्रित, हार्डवेयर-समर्थित कुंजियों का उपयोग करके प्रोटोकॉल के कार्यान्वयन की अनुमति देने के लिए क्रिप्टोग्राफ़िक प्राइमेटिव्स का एक बुनियादी लेकिन पर्याप्त सेट प्रदान करता है।
कीमास्टर एचएएल एक OEM-प्रदत्त, गतिशील रूप से लोड करने योग्य लाइब्रेरी है जिसका उपयोग हार्डवेयर-समर्थित क्रिप्टोग्राफ़िक सेवाएं प्रदान करने के लिए कीस्टोर सेवा द्वारा किया जाता है। चीजों को सुरक्षित रखने के लिए, एचएएल कार्यान्वयन उपयोगकर्ता स्थान या यहां तक कि कर्नेल स्थान में कोई संवेदनशील संचालन नहीं करता है। संवेदनशील संचालन कुछ कर्नेल इंटरफ़ेस के माध्यम से पहुंचने वाले एक सुरक्षित प्रोसेसर को सौंपे जाते हैं। परिणामी वास्तुकला इस तरह दिखती है:

चित्र 1. कीमास्टर तक पहुंच
एंड्रॉइड डिवाइस के भीतर, कीमास्टर एचएएल के "क्लाइंट" में कई परतें होती हैं (उदाहरण के लिए ऐप, फ्रेमवर्क, कीस्टोर डेमॉन), लेकिन इस दस्तावेज़ के प्रयोजनों के लिए इसे अनदेखा किया जा सकता है। इसका मतलब यह है कि वर्णित कीमास्टर एचएएल एपीआई निम्न-स्तरीय है, जिसका उपयोग प्लेटफ़ॉर्म-आंतरिक घटकों द्वारा किया जाता है, और ऐप डेवलपर्स के संपर्क में नहीं आता है। उच्च स्तरीय एपीआई का वर्णन एंड्रॉइड डेवलपर साइट पर किया गया है।
कीमास्टर एचएएल का उद्देश्य सुरक्षा-संवेदनशील एल्गोरिदम को लागू करना नहीं है, बल्कि सुरक्षित दुनिया के लिए केवल मार्शल और अनमर्शल अनुरोध करना है। वायर प्रारूप कार्यान्वयन-परिभाषित है।
पिछले संस्करणों के साथ संगतता
कीमास्टर 1 एचएएल पहले जारी एचएएल के साथ पूरी तरह से असंगत है, उदाहरण के लिए कीमास्टर 0.2 और 0.3। पुराने कीमास्टर एचएएल के साथ लॉन्च किए गए एंड्रॉइड 5.0 और इससे पहले के उपकरणों पर इंटरऑपरेबिलिटी की सुविधा के लिए, कीस्टोर एक एडाप्टर प्रदान करता है जो मौजूदा हार्डवेयर लाइब्रेरी में कॉल के साथ कीमास्टर 1 एचएएल को कार्यान्वित करता है। परिणाम कीमास्टर 1 एचएएल में कार्यक्षमता की पूरी श्रृंखला प्रदान नहीं कर सकता है। विशेष रूप से, यह केवल आरएसए और ईसीडीएसए एल्गोरिदम का समर्थन करता है, और सभी प्रमुख प्राधिकरण प्रवर्तन गैर-सुरक्षित दुनिया में एडाप्टर द्वारा किया जाता है।
कीमास्टर 2 ने get_supported_*
विधियों को हटाकर और finish()
विधि को इनपुट स्वीकार करने की अनुमति देकर एचएएल इंटरफ़ेस को और सरल बनाया। यह उन मामलों में टीईई में राउंड ट्रिप की संख्या कम कर देता है जहां इनपुट एक ही बार में उपलब्ध होता है, और एईएडी डिक्रिप्शन के कार्यान्वयन को सरल बनाता है।
एंड्रॉइड 8.0 में, कीमास्टर 3 पुरानी शैली के सी-स्ट्रक्चर एचएएल से नए हार्डवेयर इंटरफेस डेफिनिशन लैंग्वेज (एचआईडीएल) में एक परिभाषा से उत्पन्न सी ++ एचएएल इंटरफ़ेस में परिवर्तित हो गया। उत्पन्न IKeymasterDevice
वर्ग को उपवर्गित करके और शुद्ध आभासी तरीकों को लागू करके एक नई शैली का HAL कार्यान्वयन बनाया गया है। परिवर्तन के हिस्से के रूप में, कई तर्क प्रकार बदल गए हैं, हालांकि प्रकार और विधियों में पुराने प्रकारों और एचएएल संरचना विधियों के साथ एक-से-एक पत्राचार होता है।
एचआईडीएल सिंहावलोकन
हार्डवेयर इंटरफ़ेस डेफिनिशन लैंग्वेज (HIDL) हार्डवेयर इंटरफ़ेस निर्दिष्ट करने के लिए एक कार्यान्वयन भाषा-स्वतंत्र तंत्र प्रदान करता है। HIDL टूलिंग वर्तमान में C++ और Java इंटरफ़ेस के निर्माण का समर्थन करती है। यह उम्मीद की जाती है कि अधिकांश विश्वसनीय निष्पादन पर्यावरण (टीईई) कार्यान्वयनकर्ता सी++ टूलींग को अधिक सुविधाजनक पाएंगे, इसलिए यह दस्तावेज़ केवल सी++ प्रतिनिधित्व पर चर्चा करता है।
HIDL इंटरफ़ेस में विधियों का एक सेट शामिल है, जिसे इस प्रकार व्यक्त किया गया है:
methodName(INPUT ARGUMENTS) generates (RESULT ARGUMENTS);
विभिन्न पूर्व-परिभाषित प्रकार हैं, और एचएएल नए प्रगणित और संरचना प्रकारों को परिभाषित कर सकते हैं। एचआईडीएल पर अधिक जानकारी के लिए संदर्भ अनुभाग देखें।
Keymaster 3 IKeymasterDevice.hal
से एक उदाहरण विधि है:
generateKey(vec<KeyParameter> keyParams) generates(ErrorCode error, vec<uint8_t> keyBlob, KeyCharacteristics keyCharacteristics);
यह keymaster2 HAL से निम्नलिखित के समतुल्य है:
keymaster_error_t (*generate_key)( const struct keymaster2_device* dev, const keymaster_key_param_set_t* params, keymaster_key_blob_t* key_blob, keymaster_key_characteristics_t* characteristics);
HIDL संस्करण में, dev
तर्क हटा दिया गया है, क्योंकि यह अंतर्निहित है। params
तर्क अब एक संरचना नहीं है जिसमें key_parameter_t
ऑब्जेक्ट की एक सरणी को संदर्भित करने वाला पॉइंटर होता है, बल्कि एक vec
(वेक्टर) होता है जिसमें KeyParameter
ऑब्जेक्ट होते हैं। रिटर्न मान " generates
" खंड में सूचीबद्ध हैं, जिसमें कुंजी ब्लॉब के लिए uint8_t
मानों का एक वेक्टर भी शामिल है।
HIDL कंपाइलर द्वारा उत्पन्न C++ वर्चुअल विधि है:
Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams, generateKey_cb _hidl_cb) override;
जहां generateKey_cb
एक फ़ंक्शन पॉइंटर है जिसे इस प्रकार परिभाषित किया गया है:
std::function<void(ErrorCode error, const hidl_vec<uint8_t>& keyBlob, const KeyCharacteristics& keyCharacteristics)>
यानी, generateKey_cb
एक फ़ंक्शन है जो जेनरेट क्लॉज में सूचीबद्ध रिटर्न मान लेता है। एचएएल कार्यान्वयन वर्ग इस generateKey
विधि को ओवरराइड करता है और कॉलर को ऑपरेशन के परिणाम वापस करने के लिए generateKey_cb
फ़ंक्शन पॉइंटर को कॉल करता है। ध्यान दें कि फ़ंक्शन पॉइंटर कॉल सिंक्रोनस है। कॉलर generateKey
कॉल करता है और generateKey
आपूर्ति किए गए फ़ंक्शन पॉइंटर को कॉल करता है, जो पूरा होने पर निष्पादित होता है, generateKey
कार्यान्वयन पर नियंत्रण लौटाता है, जो फिर कॉलर के पास वापस आ जाता है।
विस्तृत उदाहरण के लिए, hardware/interfaces/keymaster/3.0/default/KeymasterDevice.cpp
में डिफ़ॉल्ट कार्यान्वयन देखें। डिफ़ॉल्ट कार्यान्वयन पुराने शैली के keymaster0, keymaster1, या keymaster2 HALS वाले उपकरणों के लिए पश्चगामी संगतता प्रदान करता है।
अभिगम नियंत्रण
कीस्टोर एक्सेस कंट्रोल का सबसे बुनियादी नियम यह है कि प्रत्येक ऐप का अपना नेमस्पेस होता है। लेकिन हर नियम का एक अपवाद होता है. कीस्टोर में कुछ हार्ड-कोडित मानचित्र हैं जो कुछ सिस्टम घटकों को कुछ अन्य नामस्थानों तक पहुंचने की अनुमति देते हैं। यह एक बहुत ही कुंद उपकरण है जिसमें यह एक घटक को दूसरे नामस्थान पर पूर्ण नियंत्रण देता है। और फिर कीस्टोर के ग्राहकों के रूप में विक्रेता घटकों का मामला है। वर्तमान में हमारे पास विक्रेता घटकों के लिए नामस्थान स्थापित करने का कोई तरीका नहीं है, उदाहरण के लिए, WPA निवेदक।
विक्रेता घटकों को समायोजित करने और हार्ड-कोडित अपवादों के बिना पहुंच नियंत्रण को सामान्य बनाने के लिए, कीस्टोर 2.0 डोमेन और SELinux नेमस्पेस पेश करता है।
कीस्टोर डोमेन
कीस्टोर डोमेन के साथ, हम यूआईडी से नेमस्पेस को अलग कर सकते हैं। कीस्टोर में कुंजी तक पहुंचने वाले ग्राहकों को उस डोमेन, नेमस्पेस और उपनाम को निर्दिष्ट करना होगा जिसे वे एक्सेस करना चाहते हैं। इस टपल और कॉलर की पहचान के आधार पर हम यह निर्धारित कर सकते हैं कि कॉलर किस कुंजी तक पहुंचना चाहता है और क्या उसके पास उचित अनुमतियां हैं।
हम पांच डोमेन पैरामीटर पेश करते हैं जो नियंत्रित करते हैं कि कुंजियों तक कैसे पहुंचा जा सकता है। वे कुंजी डिस्क्रिप्टर के नेमस्पेस पैरामीटर के शब्दार्थ को नियंत्रित करते हैं और एक्सेस नियंत्रण कैसे किया जाता है।
-
DOMAIN_APP
: ऐप डोमेन पुराने व्यवहार को कवर करता है। जावा कीस्टोर एसपीआई डिफ़ॉल्ट रूप से इस डोमेन का उपयोग करता है। जब इस डोमेन का उपयोग किया जाता है, तो नेमस्पेस तर्क को नजरअंदाज कर दिया जाता है और इसके बजाय कॉलर के यूआईडी का उपयोग किया जाता है। इस डोमेन तक पहुंच को SELinux नीति में क्लासkeystore_key
के लिए Keystore लेबल द्वारा नियंत्रित किया जाता है। -
DOMAIN_SELINUX
: यह डोमेन इंगित करता है कि नेमस्पेस में SELinux नीति में एक लेबल है। नेमस्पेस पैरामीटर को देखा जाता है और लक्ष्य संदर्भ में अनुवादित किया जाता है, औरkeystore_key
वर्ग के लिए SELinux संदर्भ को कॉल करने के लिए अनुमति जांच की जाती है। जब दिए गए ऑपरेशन के लिए अनुमति स्थापित हो जाती है, तो कुंजी लुकअप के लिए पूर्ण टपल का उपयोग किया जाता है। -
DOMAIN_GRANT
: अनुदान डोमेन इंगित करता है कि नेमस्पेस पैरामीटर एक अनुदान पहचानकर्ता है। The alias parameter is ignored. SELinux checks are performed when the grant is created. Further access control only checks if the caller UID matches the grantees UID of the requested grant. -
DOMAIN_KEY_ID
: This domain indicates that the namespace parameter is a unique key id. The key itself may have been created withDOMAIN_APP
orDOMAIN_SELINUX
. The permission check is performed after thedomain
and thenamespace
have been loaded from the key database in the same way as if the blob was loaded by the domain, namespace, and alias tuple. The rationale for the key id domain is continuity. When accessing a key by alias, subsequent calls may operate on different keys, because a new key may have been generated or imported and bound to this alias. The key id, however, never changes. So when using a key by key id after it has been loaded from the Keystore database using the alias once, one can be certain that it is the same key as long as the key id still exists. This functionality is not exposed to app developers. Instead, it is used within the Android Keystore SPI to provide a more consistent experience even when used concurrently in an unsafe way. -
DOMAIN_BLOB
: The blob domain indicates that the caller manages the blob by itself. This is used for clients that need to access the Keystore before the data partition is mounted. The key blob is included in theblob
field of the key descriptor.
Using the SELinux domain, we can give vendor components access to very specific Keystore namespaces which can be shared by system components such as the settings dialog.
SELinux policy for keystore_key
Namespace labels are configured using the keystore2_key_context
file.
Each line in these files maps a numeric namespace id to an SELinux label. For example,
# wifi_key is a keystore2_key namespace intended to be used by wpa supplicant and # Settings to share keystore keys. 102 u:object_r:wifi_key:s0
After having set up a new key namespace in this way, we can give access to it by adding an appropriate policy. For example, to allow wpa_supplicant
to get and use keys in the new namespace we would add the following line to hal_wifi_supplicant.te
:
allow hal_wifi_supplicant wifi_key:keystore2_key { get, use };
After setting up the new namespace, AndroidKeyStore can be used almost as usual. The only difference is that the namespace ID must be specified. For loading and importing keys from and into Keystore, the namespace id is specified using the AndroidKeyStoreLoadStoreParameter
. For example,
import android.security.keystore2.AndroidKeyStoreLoadStoreParameter; import java.security.KeyStore; KeyStore keystore = KeyStore.getInstance("AndroidKeyStore"); keystore.load(new AndroidKeyStoreLoadStoreParameter(102));
To generate a key in a given namespace, the namespace id must be given using KeyGenParameterSpec.Builder#setNamespace():
import android.security.keystore.KeyGenParameterSpec; KeyGenParameterSpec.Builder specBuilder = new KeyGenParameterSpec.Builder(); specBuilder.setNamespace(102);
The following context files may be used to configure Keystore 2.0 SELinux namespaces. Each partition has a different reserved range of 10,000 namespace ids to avoid collisions.
Partition | Range | Config files |
---|---|---|
प्रणाली | 0 ... 9,999 | /system/etc/selinux/keystore2_key_contexts, /plat_keystore2_key_contexts |
Extended System | 10,000 ... 19,999 | /system_ext/etc/selinux/system_ext_keystore2_key_contexts, /system_ext_keystore2_key_contexts |
Product | 20,000 ... 29,999 | /product/etc/selinux/product_keystore2_key_contexts, /product_keystore2_key_contexts |
विक्रेता | 30,000 ... 39,999 | /vendor/etc/selinux/vendor_keystore2_key_contexts, /vendor_keystore2_key_contexts |
The client requests the key by requesting the SELinux domain and the desired virtual namespace, in this case "wifi_key"
, by its numeric id.
Above that, the following namespaces have been defined. If they replace special rules, the following table indicates the UID they used to correspond to.
Namespace ID | SEPolicy Label | UID | विवरण |
---|---|---|---|
0 | su_key | N/A | Super user key. Only used for testing on userdebug and eng builds. Not relevant on user builds. |
1 | shell_key | N/A | Namespace available to shell. Mostly used for testing, but can be used on user builds as well from the command line. |
100 | vold_key | N/A | Intended for use by vold. |
101 | odsing_key | N/A | Used by the on-device signing daemon. |
102 | wifi_key | AID_WIFI(1010) | Used by Android's Wifi sybsystem including wpa_supplicant. |
120 | resume_on_reboot_key | AID_SYSTEM(1000) | Used by Android's system server to support resume on reboot. |
Access Vectors
The SELinux class keystore_key
has aged quite a bit and some of the permissions, such as verify
or sign
have lost their meaning. Here is the new set of permissions, keystore2_key
, that Keystore 2.0 will enforce.
Permission | Meaning |
---|---|
delete | Checked when removing keys from Keystore. |
get_info | Checked when a key's metadata is requested. |
grant | The caller needs this permission to create a grant to the key in the target context. |
manage_blob | The caller may use DOMAIN_BLOB on the given SELinux namespace, thereby managing blobs by itself. This is specifically useful for vold. |
rebind | This permission controls if an alias may be rebound to a new key. This is required for insertion and implies that the previously bound key will be deleted. It is basically an insert permission, but it captures the semantic of keystore better. |
req_forced_op | Clients with this permission may create unpruneable operations, and operation creation never fails unless all operation slots are taken by unpruneable operations. |
update | Required to update the subcomponent of a key. |
use | Checked when creating a Keymint operation that uses the key material, eg, for signing, en/decryption. |
use_dev_id | Required when generating device identifying information, such as device id attestation. |
Additionally, we split out a set of non key specific keystore permissions in the SELinux security class keystore2
:
Permission | Meaning |
---|---|
add_auth | Required by authentication provider such as Gatekeeper or BiometricsManager for adding auth tokens. |
clear_ns | Formerly clear_uid, this permission allows a non owner of a namespace to delete all keys in that namespace. |
list | Required by the system for enumerating keys by various properties, such as ownership or auth boundedness. This permission is not required by callers enumerating their own namespaces. This is covered by the get_info permission. |
lock | This permission allows to lock Keystore, that is, evict the master key, such that auth bound keys become unusable and uncreatable. |
reset | This permission allows to reset Keystore to factory default, deleting all keys that are not vital to the functioning of the Android OS. |
unlock | This permission is required to attempt to unlock the master key for auth bound keys. |