हार्डवेयर-बैक्ड कीस्टोर

सिस्टम ऑन चिप (SoC) में भरोसेमंद एक्सीक्यूशन एनवायरमेंट की उपलब्धता से, Android डिवाइसों को Android OS, प्लैटफ़ॉर्म की सेवाओं, और यहां तक कि तीसरे पक्ष के ऐप्लिकेशन को हार्डवेयर की मदद से, बेहतर सुरक्षा सेवाएं देने का मौका मिलता है. Android के लिए खास एक्सटेंशन पाने वाले डेवलपर को android.security.keystore पर जाना चाहिए.

Android 6.0 से पहले, Android में पहले से ही एक आसान और हार्डवेयर पर आधारित क्रिप्टो सेवाओं का एपीआई था. इसे Keymaster Hardware Abstraction Layer (HAL) के 0.2 और 0.3 वर्शन से उपलब्ध कराया गया था. कीस्टोर में डिजिटल हस्ताक्षर और पुष्टि करने के ऑपरेशन की सुविधा होती है. साथ ही, इसमें असिमेट्रिक साइनिंग पासकोड जोड़े और इंपोर्ट किए जा सकते हैं. यह सुविधा कई डिवाइसों पर पहले से ही लागू है. हालांकि, सुरक्षा से जुड़े कई लक्ष्यों को सिर्फ़ हस्ताक्षर वाले एपीआई की मदद से आसानी से हासिल नहीं किया जा सकता. Android 6.0 में Keystore ने Keystore API को बेहतर बनाया है, ताकि ज़्यादा सुविधाएं दी जा सकें.

Android 6.0 में, Keystore में सिमेट्रिक क्रिप्टोग्राफ़िक प्राइमिटिव, एईएस, और एचएमएससी जोड़े गए हैं. साथ ही, इसमें हार्डवेयर की मदद से सुरक्षित की गई कुंजियों के लिए ऐक्सेस कंट्रोल सिस्टम भी जोड़ा गया है. ऐक्सेस कंट्रोल, पासकोड जनरेट करने के दौरान तय किए जाते हैं और पासकोड के पूरे जीवनकाल के लिए लागू होते हैं. पासकोड को इस तरह से सेट किया जा सकता है कि उपयोगकर्ता की पुष्टि होने के बाद ही उसे इस्तेमाल किया जा सके. साथ ही, पासकोड का इस्तेमाल सिर्फ़ तय किए गए कामों के लिए या तय किए गए क्रिप्टोग्राफ़िक पैरामीटर के साथ किया जा सके. ज़्यादा जानकारी के लिए, अनुमति टैग पेज देखें.

क्रिप्टोग्राफ़िक प्राइमिटिव की रेंज को बढ़ाने के अलावा, Android 6.0 में मौजूद Keystore में ये चीज़ें जोड़ी गई हैं:

  • कुंजी के इस्तेमाल को सीमित करने की अनुमति देने के लिए, इस्तेमाल कंट्रोल करने की योजना. इससे, कुंजियों के गलत इस्तेमाल की वजह से, सुरक्षा से जुड़े जोखिम को कम किया जा सकता है
  • ऐक्सेस कंट्रोल स्कीम, जिसकी मदद से चुनिंदा उपयोगकर्ताओं, क्लाइंट, और तय की गई समयसीमा के लिए पासकोड पर पाबंदी लगाई जा सकती है

Android 7.0 में, Keymaster 2 ने कुंजी की पुष्टि करने और वर्शन को बांधने की सुविधा जोड़ी है. कुंजी की पुष्टि करने की सुविधा से, सार्वजनिक कुंजी के सर्टिफ़िकेट मिलते हैं. इनमें कुंजी और उसके ऐक्सेस कंट्रोल के बारे में पूरी जानकारी होती है. इससे, सुरक्षित हार्डवेयर में कुंजी मौजूद होने और उसके कॉन्फ़िगरेशन की पुष्टि, रिमोट से की जा सकती है.

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

Android 8.0 में, Keymaster 3 को पुराने स्टाइल के C-स्ट्रक्चर वाले हार्डवेयर एब्स्ट्रैक्शन लेयर (एचएएल) से, C++ एचएएल इंटरफ़ेस पर ट्रांसफ़र किया गया. यह इंटरफ़ेस, नई हार्डवेयर इंटरफ़ेस डेफ़िनिशन लैंग्वेज (एचआईडीएल) में मौजूद डेफ़िनिशन से जनरेट किया गया है. इस बदलाव के तहत, कई तरह के आर्ग्युमेंट बदल गए हैं. हालांकि, टाइप और तरीकों का एक-एक मैच, पुराने टाइप और HAL स्ट्रक्चर के तरीकों से होता है.

इंटरफ़ेस में किए गए इस बदलाव के अलावा, Android 8.0 में Keymaster 2 की पुष्टि करने की सुविधा को बढ़ाया गया है, ताकि आईडी की पुष्टि की जा सके. आईडी की पुष्टि करने की सुविधा, हार्डवेयर आइडेंटिफ़ायर की पुष्टि करने के लिए सीमित और वैकल्पिक तरीका उपलब्ध कराती है. जैसे, डिवाइस का सीरियल नंबर, प्रॉडक्ट का नाम, और फ़ोन आईडी (IMEI / MEID). इस सुविधा को लागू करने के लिए, Android 8.0 ने आईडी की पुष्टि करने के लिए, ASN.1 पुष्टि करने के स्कीमा में बदलाव किया है. Keymaster को लागू करने के लिए, ज़रूरी डेटा आइटम को वापस पाने का कोई सुरक्षित तरीका ढूंढना होगा. साथ ही, इस सुविधा को सुरक्षित और हमेशा के लिए बंद करने का तरीका भी तय करना होगा.

Android 9 में ये अपडेट शामिल थे:

  • Keymaster 4 पर अपडेट करना
  • एम्बेड किए गए सुरक्षित एलिमेंट के लिए सहायता
  • सुरक्षित पासकोड इंपोर्ट करने की सुविधा
  • 3DES एन्क्रिप्शन की सुविधा
  • वर्शन बाइंडिंग में बदलाव किए गए हैं, ताकि boot.img और system.img के लिए अलग-अलग वर्शन सेट किए जा सकें. इससे, अलग-अलग अपडेट करने की सुविधा मिलती है

शब्दावली

यहां पासकोड के कॉम्पोनेंट और उनके बीच के संबंधों के बारे में खास जानकारी दी गई है.

AndroidKeystore, Android फ़्रेमवर्क एपीआई और कॉम्पोनेंट है. इसका इस्तेमाल, ऐप्लिकेशन में Keystore की सुविधाओं को ऐक्सेस करने के लिए किया जाता है. इसे स्टैंडर्ड Java Cryptography Architecture APIs के एक्सटेंशन के तौर पर लागू किया जाता है. इसमें Java कोड होता है, जो ऐप्लिकेशन के प्रोसेस स्पेस में चलता है. AndroidKeystore, कीस्टोर के व्यवहार के लिए ऐप्लिकेशन के अनुरोधों को कीस्टोर डेमन पर फ़ॉरवर्ड करके उन्हें पूरा करता है.

keystore डेमन, Android सिस्टम डेमन है. यह Binder API की मदद से, Keystore की सभी सुविधाओं का ऐक्सेस देता है. यह "की ब्लॉब" को सेव करने के लिए ज़िम्मेदार है. इनमें एन्क्रिप्ट (सुरक्षित) की गई असली पासकोड होती है, ताकि कीस्टोर उन्हें सेव कर सके, लेकिन उनका इस्तेमाल न कर सके या उन्हें ज़ाहिर न कर सके.

keymasterd एक HIDL सर्वर है, जो Keymaster TA का ऐक्सेस देता है. (यह नाम स्टैंडर्ड नहीं है और इसे सिर्फ़ कॉन्सेप्ट के लिए इस्तेमाल किया जाता है.)

Keymaster TA (भरोसेमंद ऐप्लिकेशन) एक ऐसा सॉफ़्टवेयर है जो सुरक्षित कॉन्टेक्स्ट में काम करता है. आम तौर पर, यह ARM SoC पर TrustZone में काम करता है. यह Keystore के सभी सुरक्षित ऑपरेशन उपलब्ध कराता है. साथ ही, पासकोड के रॉ कॉन्टेंट का ऐक्सेस रखता है और पासकोड के ऐक्सेस कंट्रोल की सभी शर्तों की पुष्टि करता है.

LockSettingsService, Android सिस्टम का वह कॉम्पोनेंट है जो उपयोगकर्ता की पुष्टि करने के लिए ज़िम्मेदार होता है. इसमें पासवर्ड और फ़िंगरप्रिंट, दोनों शामिल हैं. यह Keystore का हिस्सा नहीं है, लेकिन यह ज़रूरी है, क्योंकि Keystore की कई कुंजियों के कामों के लिए, उपयोगकर्ता की पुष्टि करना ज़रूरी होता है. पुष्टि करने वाले टोकन पाने के लिए, LockSettingsService Gatekeeper TA और फ़िंगरप्रिंट TA के साथ इंटरैक्ट करता है. ये टोकन, वह keystore डेमन को उपलब्ध कराता है. आखिर में, इन्हें Keymaster TA ऐप्लिकेशन इस्तेमाल करता है.

Gatekeeper TA (भरोसेमंद ऐप्लिकेशन), सुरक्षित कॉन्टेक्स्ट में चलने वाला एक और कॉम्पोनेंट है. यह उपयोगकर्ता के पासवर्ड की पुष्टि करता है और पुष्टि करने वाले टोकन जनरेट करता है. इन टोकन का इस्तेमाल, Keymaster TA को यह साबित करने के लिए किया जाता है कि किसी खास समय पर किसी खास उपयोगकर्ता की पुष्टि की गई थी.

फ़िंगरप्रिंट टीए (भरोसेमंद ऐप्लिकेशन), सुरक्षित कॉन्टेक्स्ट में चलने वाला एक और कॉम्पोनेंट है. यह उपयोगकर्ता के फ़िंगरप्रिंट की पुष्टि करने और पुष्टि करने वाले टोकन जनरेट करने के लिए ज़िम्मेदार होता है. इन टोकन का इस्तेमाल, Keymaster टीए को यह साबित करने के लिए किया जाता है कि किसी खास समय पर किसी खास उपयोगकर्ता की पुष्टि की गई थी.

भवन निर्माण

Android Keystore API और उसमें मौजूद Keymaster HAL, क्रिप्टोग्राफ़िक प्राइमिटिव का बुनियादी, लेकिन ज़रूरत के मुताबिक सेट उपलब्ध कराता है. इससे, ऐक्सेस कंट्रोल करने वाली और हार्डवेयर की मदद से काम करने वाली कुंजियों का इस्तेमाल करके, प्रोटोकॉल लागू किए जा सकते हैं.

Keymaster HAL, OEM की ओर से उपलब्ध कराई गई एक लाइब्रेरी है. इसे डाइनैमिक तौर पर लोड किया जा सकता है. इसका इस्तेमाल, Keystore सेवा करती है. इससे, हार्डवेयर की मदद से क्रिप्टोग्राफ़िक सेवाएं मिलती हैं. चीज़ों को सुरक्षित रखने के लिए, एचएएल लागू करने वाले उपयोगकर्ता स्पेस या कर्नेल स्पेस में कोई भी संवेदनशील कार्रवाई नहीं करते. संवेदनशील ऑपरेशन, किसी सुरक्षित प्रोसेसर को सौंपे जाते हैं. इस प्रोसेसर को, कुछ कर्नेल इंटरफ़ेस के ज़रिए ऐक्सेस किया जाता है. इससे मिलने वाला आर्किटेक्चर कुछ ऐसा दिखता है:

Keymaster का ऐक्सेस

पहली इमेज. Keymaster का ऐक्सेस

Android डिवाइस में, Keymaster HAL के "क्लाइंट" में कई लेयर होती हैं. उदाहरण के लिए, ऐप्लिकेशन, फ़्रेमवर्क, Keystore डेमन. हालांकि, इस दस्तावेज़ के मकसद के लिए, इन लेयर को अनदेखा किया जा सकता है. इसका मतलब है कि यहां बताया गया Keymaster HAL API, लो-लेवल का है. इसका इस्तेमाल प्लैटफ़ॉर्म के अंदरूनी कॉम्पोनेंट करते हैं. इसे ऐप्लिकेशन डेवलपर के लिए उपलब्ध नहीं कराया जाता. ज़्यादा लेवल वाले एपीआई के बारे में Android Developers साइट पर बताया गया है.

Keymaster HAL का मकसद, सुरक्षा से जुड़े संवेदनशील एल्गोरिदम लागू करना नहीं है. इसका मकसद, सिर्फ़ सुरक्षित वर्ल्ड में अनुरोधों को मार्शल और अनमार्शल करना है. वायर फ़ॉर्मैट, लागू करने के तरीके के हिसाब से तय होता है.

पिछले वर्शन के साथ काम करना

Keymaster 1 HAL, पहले रिलीज़ किए गए HAL के साथ पूरी तरह से काम नहीं करता. उदाहरण के लिए, Keymaster 0.2 और 0.3. Android 5.0 और उससे पहले के वर्शन पर काम करने वाले डिवाइसों पर, एक-दूसरे के साथ काम करने की सुविधा देने के लिए, Keystore एक अडैप्टर उपलब्ध कराता है. यह अडैप्टर, मौजूदा हार्डवेयर लाइब्रेरी के कॉल के साथ Keymaster 1 HAL को लागू करता है. इस वजह से, Keymaster 1 एचएएल में सभी सुविधाएं काम नहीं करतीं. खास तौर पर, यह सिर्फ़ आरएसए और ईसीडीएसए एल्गोरिदम के साथ काम करता है. साथ ही, असुरक्षित दुनिया में, कुंजी की अनुमति देने की सभी कार्रवाइयां अडैप्टर करता है.

Keymaster 2 ने get_supported_* तरीकों को हटाकर और finish() तरीके को इनपुट स्वीकार करने की अनुमति देकर, HAL इंटरफ़ेस को और आसान बना दिया है. इससे उन मामलों में टीईई के राउंड ट्रिप की संख्या कम हो जाती है जहां इनपुट एक साथ उपलब्ध होता है. साथ ही, एईएडी डिक्रिप्शन को लागू करना आसान हो जाता है.

Android 8.0 में, Keymaster 3 को पुराने स्टाइल के C-structure HAL से C++ HAL इंटरफ़ेस पर ट्रांसफ़र किया गया. यह इंटरफ़ेस, नई हार्डवेयर इंटरफ़ेस डेफ़िनिशन लैंग्वेज (HIDL) में मौजूद डेफ़िनिशन से जनरेट किया गया है. जनरेट की गई IKeymasterDevice क्लास को सबक्लास करके और पूरी तरह वर्चुअल तरीकों को लागू करके, एचएएल के नए स्टाइल को लागू किया जाता है. इस बदलाव के तहत, कई तरह के आर्ग्युमेंट बदल गए हैं. हालांकि, टाइप और तरीकों का पुराने टाइप और HAL स्ट्रक्चर के तरीकों के साथ एक-एक का संबंध है.

HIDL के बारे में खास जानकारी

हार्डवेयर इंटरफ़ेस डेफ़िनिशन लैंग्वेज (HIDL), हार्डवेयर इंटरफ़ेस की जानकारी देने के लिए, लागू करने की एक ऐसी सुविधा उपलब्ध कराती है जो किसी भी भाषा पर निर्भर नहीं करती. फ़िलहाल, HIDL टूल, C++ और Java इंटरफ़ेस जनरेट करने की सुविधा देता है. हमें उम्मीद है कि ट्रस्टेड एक्ज़ीक्यूशन एनवायरमेंट (टीईई) लागू करने वाले ज़्यादातर लोगों को C++ टूल इस्तेमाल करना ज़्यादा आसान लगेगा. इसलिए, इस पेज पर सिर्फ़ C++ के बारे में बताया गया है.

HIDL इंटरफ़ेस में तरीकों का एक सेट होता है, जिसे इस तरह दिखाया जाता है:

  methodName(INPUT ARGUMENTS) generates (RESULT ARGUMENTS);

पहले से तय किए गए कई टाइप हैं. साथ ही, एचएएल में नए एनोटेट किए गए और स्ट्रक्चर टाइप तय किए जा सकते हैं. HIDL के बारे में ज़्यादा जानकारी के लिए, रेफ़रंस सेक्शन देखें.

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 एचएएलएस हैं.

ऐक्सेस कंट्रोल

पासकोड के ऐक्सेस कंट्रोल का सबसे बुनियादी नियम यह है कि हर ऐप्लिकेशन का अपना नेमस्पेस होता है. हालांकि, हर नियम के लिए एक अपवाद होता है. कीस्टोर में कुछ हार्ड-कोड किए गए मैप होते हैं. इनकी मदद से, सिस्टम के कुछ कॉम्पोनेंट कुछ अन्य नेमस्पेस ऐक्सेस कर सकते हैं. यह एक बहुत ही बेअसर टूल है, क्योंकि यह एक कॉम्पोनेंट को दूसरे नेमस्पेस पर पूरा कंट्रोल देता है. इसके अलावा, वेंडर के कॉम्पोनेंट को पासकोड के क्लाइंट के तौर पर इस्तेमाल करने की सुविधा भी है. फ़िलहाल, हमारे पास वेंडर कॉम्पोनेंट के लिए नेमस्पेस तय करने का कोई तरीका नहीं है. उदाहरण के लिए, WPA supplicant.

वेंडर कॉम्पोनेंट को शामिल करने और हार्ड कोड किए गए अपवादों के बिना ऐक्सेस कंट्रोल को सामान्य बनाने के लिए, Keystore 2.0 में डोमेन और SELinux नेमस्पेस जोड़े गए हैं.

कीस्टोर डोमेन

पासकोड डोमेन की मदद से, हम नेमस्पेस को यूआईडी से अलग कर सकते हैं. पासकोड में मौजूद किसी पासकोड को ऐक्सेस करने वाले क्लाइंट को वह डोमेन, नेमस्पेस, और उपनाम बताना होगा जिसे उन्हें ऐक्सेस करना है. इस टुपल और कॉलर की पहचान के आधार पर, हम यह तय कर सकते हैं कि कॉलर को किस पासकोड को ऐक्सेस करना है और उसके पास सही अनुमतियां हैं या नहीं.

हम पांच डोमेन पैरामीटर पेश कर रहे हैं. इनसे यह तय होता है कि कुंजियों को कैसे ऐक्सेस किया जा सकता है. ये की डिस्क्रिप्टर के नेमस्पेस पैरामीटर के सेमेटिक्स और ऐक्सेस कंट्रोल के तरीके को कंट्रोल करते हैं.

  • DOMAIN_APP: ऐप्लिकेशन डोमेन, लेगसी व्यवहार को कवर करता है. Java Keystore SPI, डिफ़ॉल्ट रूप से इस डोमेन का इस्तेमाल करता है. इस डोमेन का इस्तेमाल करने पर, नेमस्पेस आर्ग्युमेंट को अनदेखा कर दिया जाता है और कॉलर के UID का इस्तेमाल किया जाता है. इस डोमेन का ऐक्सेस, SELinux नीति में क्लास keystore_key के लिए, पासकोड के लेबल से कंट्रोल किया जाता है.
  • DOMAIN_SELINUX: इस डोमेन से पता चलता है कि नेमस्पेस में, SELinux नीति में कोई लेबल है. नेमस्पेस पैरामीटर को खोजा जाता है और टारगेट कॉन्टेक्स्ट में बदल दिया जाता है. साथ ही, keystore_key क्लास के लिए कॉल करने वाले SELinux कॉन्टेक्स्ट के लिए अनुमति की जांच की जाती है. जब दिए गए ऑपरेशन के लिए अनुमति मिल जाती है, तो कुंजी लुकअप के लिए पूरे ट्यूपल का इस्तेमाल किया जाता है.
  • DOMAIN_GRANT: अनुदान का डोमेन यह दिखाता है कि नेमस्पेस पैरामीटर, अनुदान का आइडेंटिफ़ायर है. आलियास पैरामीटर को अनदेखा किया जाता है. अनुमति बनाने के दौरान, SELinux की जांच की जाती है. ऐक्सेस कंट्रोल की सुविधा, सिर्फ़ यह जांच करती है कि कॉल करने वाले का यूआईडी, अनुरोध किए गए अनुदान के फ़ायदा पाने वाले व्यक्ति के यूआईडी से मेल खाता है या नहीं.
  • DOMAIN_KEY_ID: इस डोमेन से पता चलता है कि नेमस्पेस पैरामीटर एक यूनीक पासकोड आईडी है. हो सकता है कि पासकोड को DOMAIN_APP या DOMAIN_SELINUX से बनाया गया हो. अनुमति की जांच, domain और namespace को पासकोड डेटाबेस से लोड करने के बाद की जाती है. यह जांच उसी तरह की जाती है जैसे डोमेन, नेमस्पेस, और उपनाम टपल से ब्लॉब लोड किया जाता है. पासकोड के डोमेन को बनाए रखने की वजह यह है कि किसी कुंजी को उपनाम से ऐक्सेस करने पर, इसके बाद के कॉल अलग-अलग कुंजियों पर काम कर सकते हैं. ऐसा इसलिए, क्योंकि हो सकता है कि कोई नई कुंजी जनरेट की गई हो या इंपोर्ट की गई हो और इस उपनाम से बंधी हो. हालांकि, पासकोड कभी नहीं बदलता. इसलिए, किसी कुंजी को आइडेंटिफ़ायर के ज़रिए इस्तेमाल करने पर, यह पक्का किया जा सकता है कि यह वही कुंजी है. ऐसा तब तक किया जा सकता है, जब तक कि कुंजी का आईडी मौजूद है. यह सुविधा, ऐप्लिकेशन डेवलपर के लिए उपलब्ध नहीं है. इसके बजाय, इसका इस्तेमाल Android Keystore SPI में किया जाता है, ताकि एक साथ कई डिवाइसों पर सुरक्षित तरीके से इस्तेमाल करने पर भी एक जैसा अनुभव मिल सके.
  • 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 की एक अलग रिज़र्व रेंज तय की जाती है, ताकि एक ही आईडी का इस्तेमाल न हो.

सेगमेंट सीमा कॉन्फ़िगरेशन फ़ाइलें
सिस्टम 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" के लिए संख्या वाला आईडी.

इसके अलावा, यहां दिए गए नेमस्पेस तय किए गए हैं. अगर ये खास नियमों की जगह लेते हैं, तो नीचे दी गई टेबल में वह यूआईडी दिखता है जिससे ये नियम जुड़े थे.

नेमस्पेस ID SEPolicy लेबल यूआईडी ब्यौरा
0 su_key लागू नहीं सुपर उपयोगकर्ता कुंजी. इसका इस्तेमाल सिर्फ़ userdebug और eng बिल्ड पर टेस्टिंग के लिए किया जाता है. उपयोगकर्ता के बिल्ड पर लागू नहीं होता.
1 shell_key लागू नहीं शेल के लिए उपलब्ध नेमस्पेस. इसका इस्तेमाल ज़्यादातर टेस्टिंग के लिए किया जाता है. हालांकि, कमांड लाइन से उपयोगकर्ता के बिल्ड पर भी इसका इस्तेमाल किया जा सकता है.
100 vold_key लागू नहीं इसका इस्तेमाल vold के लिए किया जाता है.
101 odsing_key लागू नहीं इसका इस्तेमाल, डिवाइस पर साइन करने वाले डेमन प्रोग्राम करता है.
102 wifi_key AID_WIFI(1010) इसका इस्तेमाल, Android के वाई-फ़ाई सिस्टम और wpa_supplicant के साथ किया जाता है.
120 resume_on_reboot_key AID_SYSTEM(1000) इसका इस्तेमाल, Android के सिस्टम सर्वर में रीबूट होने के बाद, वीडियो चलाने की सुविधा को चालू करने के लिए किया जाता है.

ऐक्सेस वेक्टर

SELinux क्लास keystore_key काफ़ी पुराना हो गया है और verify या sign जैसी कुछ अनुमतियों का मतलब अब नहीं रह गया है. यहां अनुमतियों का नया सेट, keystore2_key दिया गया है, जिसे Keystore 2.0 लागू करता है.

अनुमति मतलब
delete पासकोड को पासवर्ड के तौर पर इस्तेमाल करने के लिए, पासकोड को पासवर्ड के तौर पर सेट करना ज़रूरी है.
get_info कुंजी के मेटाडेटा का अनुरोध किए जाने पर, इसकी जांच की जाती है.
grant टारगेट कॉन्टेक्स्ट में पासकोड के लिए अनुदान बनाने के लिए, कॉल करने वाले व्यक्ति को इस अनुमति की ज़रूरत होती है.
manage_blob कॉलर, दिए गए SELinux नेमस्पेस पर DOMAIN_BLOB का इस्तेमाल कर सकता है. इससे, ब्लॉब अपने-आप मैनेज हो जाते हैं. यह सुविधा खास तौर पर, vold के लिए मददगार है.
rebind इस अनुमति से यह कंट्रोल किया जाता है कि किसी उपनाम को नई कुंजी से रीबाउंड किया जा सकता है या नहीं. इसे डालने के लिए ज़रूरी है. इससे पता चलता है कि पहले से बाउंड की गई कुंजी मिटा दी गई है. यह एक डालने की अनुमति है, लेकिन यह पासकोड के सेमेटिक को बेहतर तरीके से कैप्चर करता है.
req_forced_op जिन क्लाइंट के पास यह अनुमति होती है वे ऐसे ऑपरेशन बना सकते हैं जिन्हें काटा नहीं जा सकता. साथ ही, जब तक सभी ऑपरेशन स्लॉट, काटे नहीं जा सकने वाले ऑपरेशन के लिए इस्तेमाल नहीं कर लिए जाते, तब तक ऑपरेशन बनाने में कभी कोई समस्या नहीं आती.
update किसी कुंजी के सब-कॉम्पोनेंट को अपडेट करने के लिए ज़रूरी है.
use इस विकल्प को तब चुना जाता है, जब कोई ऐसा Keymint ऑपरेशन बनाया जा रहा हो जिसमें पासकोड का इस्तेमाल किया जाता हो. उदाहरण के लिए, साइन करने, एन्क्रिप्ट (सुरक्षित) करने, और डिक्रिप्ट (सुरक्षित करने की प्रक्रिया को वापस पहले जैसा करना) करने के लिए.
use_dev_id डिवाइस की पहचान करने वाली जानकारी जनरेट करते समय ज़रूरी है. जैसे, डिवाइस आईडी की पुष्टि.

इसके अलावा, हमने SELinux सुरक्षा क्लास keystore2 में, कुंजी से जुड़ी अनुमतियों के अलावा, अन्य कुंजीस्टोर की अनुमतियों के एक सेट को अलग किया है:

अनुमति मतलब
add_auth पुष्टि करने वाले टूल जोड़ने के लिए, पुष्टि करने की सेवा देने वाली कंपनी, जैसे कि Gatekeeper या BiometricsManager के लिए ज़रूरी है.
clear_ns पहले इसे clear_uid कहा जाता था. इस अनुमति की मदद से, नेमस्पेस का मालिकाना हक न रखने वाला व्यक्ति भी उस नेमस्पेस में मौजूद सभी कुंजियों को मिटा सकता है.
list सिस्टम को अलग-अलग प्रॉपर्टी के हिसाब से, कुंजियों की गिनती करने के लिए इसकी ज़रूरत होती है. जैसे, मालिकाना हक या पुष्टि की सीमा. कॉल करने वाले को अपने नेमस्पेस की जानकारी देने के लिए, इस अनुमति की ज़रूरत नहीं होती. इसकी अनुमति, get_info की अनुमति के तहत दी जाती है.
lock इस अनुमति से, पासकोड को लॉक किया जा सकता है. इसका मतलब है कि पासकोड को हटा दिया जाएगा, ताकि पुष्टि करने के लिए इस्तेमाल की जाने वाली कुंजियों का इस्तेमाल न किया जा सके और न ही उन्हें बनाया जा सके.
reset इस अनुमति की मदद से, पासकोड को फ़ैक्ट्री डिफ़ॉल्ट पर रीसेट किया जा सकता है. साथ ही, Android OS के काम करने के लिए ज़रूरी नहीं होने वाली सभी कुंजियों को मिटाया जा सकता है.
unlock पुष्टि करने के लिए इस्तेमाल होने वाली कुंजियों के लिए, मुख्य कुंजी को अनलॉक करने के लिए यह अनुमति ज़रूरी है.