Android 11 में, A/B अपडेट या वर्चुअल A/B अपडेट के साथ-साथ RecoverySystem क्लास के तरीकों का इस्तेमाल करके, ओटीए अपडेट लागू किए जा सकते हैं. ओटीए अपडेट लागू करने के लिए डिवाइस के रीबूट होने के बाद, Resume-on-Reboot (RoR) सुविधा, डिवाइस के क्रेडेंशियल एन्क्रिप्ट (सीई) स्टोरेज को अनलॉक करती है.
हालांकि, पार्टनर इस प्रोसेस को ओटीए सिस्टम की ऐसी सुविधा के साथ जोड़ सकते हैं जो Android 11 में डिवाइस के इस्तेमाल में न होने पर अपडेट लागू करती है. वहीं, Android 12 में पार्टनर को ओटीए सिस्टम की किसी अतिरिक्त सुविधा की ज़रूरत नहीं होती. RoR प्रोसेस से उपयोगकर्ताओं को ज़्यादा सुरक्षा और सुविधा मिलती है. ऐसा इसलिए, क्योंकि डिवाइस के इस्तेमाल में न होने पर अपडेट किए जा सकते हैं. वहीं, Android 12 में मल्टी-क्लाइंट और सर्वर पर आधारित अपडेट की सुविधाएं एक साथ मिलकर, डिवाइस के हार्डवेयर लेवल की सुरक्षा उपलब्ध कराती हैं.
Android 11 में RoR की android.hardware.reboot_escrow
सुविधा के लिए, आपको डिवाइस की अनुमति देनी होगी. हालांकि, Android 12 और उसके बाद के वर्शन में
सर्वर पर आधारित RoR की सुविधा चालू करने के लिए, आपको ऐसा करने की ज़रूरत नहीं है. ऐसा इसलिए, क्योंकि ये
HAL का इस्तेमाल नहीं करते.
बैकग्राउंड
Android 7 से, Android में डायरेक्ट बूट की सुविधा काम करती है. इससे डिवाइस पर मौजूद ऐप्लिकेशन, उपयोगकर्ता के CE स्टोरेज को अनलॉक करने से पहले ही शुरू हो जाते हैं. डायरेक्ट बूट की सुविधा लागू करने से, उपयोगकर्ताओं को लॉक स्क्रीन नॉलेज फ़ैक्टर (एलएसकेएफ़) डालने से पहले बेहतर अनुभव मिला.
RoR की मदद से, डिवाइस पर मौजूद सभी ऐप्लिकेशन के CE स्टोरेज को अनलॉक किया जा सकता है. इनमें वे ऐप्लिकेशन भी शामिल हैं जो OTA अपडेट के बाद रीबूट होने पर, डायरेक्ट बूट की सुविधा के साथ काम नहीं करते. इस सुविधा की मदद से, उपयोगकर्ता रीबूट करने के बाद, इंस्टॉल किए गए सभी ऐप्लिकेशन से सूचनाएं पा सकते हैं.
थ्रेट मॉडल
RoR को लागू करने के दौरान यह पक्का किया जाना चाहिए कि जब कोई डिवाइस हमलावर के हाथ लग जाए, तो हमलावर के लिए उपयोगकर्ता के CE-एन्क्रिप्ट (सुरक्षित) किए गए डेटा को वापस पाना बहुत मुश्किल हो. भले ही, डिवाइस चालू हो, CE स्टोरेज अनलॉक हो, और ओटीए अपडेट मिलने के बाद उपयोगकर्ता ने डिवाइस को अनलॉक कर दिया हो. इनसाइडर अटैक से बचाव करने की सुविधा, तब भी असरदार होनी चाहिए, जब हमलावर को ब्रॉडकास्ट के लिए इस्तेमाल की जाने वाली क्रिप्टोग्राफ़िक साइनिंग कुंजियों का ऐक्सेस मिल जाए.
खास तौर पर, सीई स्टोरेज को ऐसा हमलावर नहीं पढ़ सकता जिसके पास डिवाइस का ऐक्सेस हो. साथ ही, उसमें ये क्षमताएं और सीमाएं हों:
सुविधाएं
- आर्बिट्रेरी मैसेज को साइन करने के लिए, किसी भी वेंडर या कंपनी की साइनिंग कुंजी का इस्तेमाल कर सकता है.
- इससे डिवाइस को ओटीए अपडेट मिल सकता है.
- किसी भी हार्डवेयर (जैसे कि ऐप्लिकेशन प्रोसेसर या फ़्लैश मेमोरी) के काम करने के तरीके में बदलाव कर सकता है. हालांकि, ऐसा सिर्फ़ सीमाएं सेक्शन में बताई गई शर्तों के मुताबिक किया जा सकता है. (हालांकि, इस तरह के बदलाव में कम से कम एक घंटे की देरी होती है. साथ ही, पावर साइकल की वजह से रैम का कॉन्टेंट मिट जाता है.)
सीमाएं
- छेड़छाड़ से सुरक्षित हार्डवेयर (उदाहरण के लिए, Titan M) के काम करने के तरीके में बदलाव नहीं किया जा सकता.
- लाइव डिवाइस की रैम नहीं पढ़ी जा सकती.
- उपयोगकर्ता के क्रेडेंशियल (पिन, पैटर्न, पासवर्ड) का अनुमान नहीं लगाया जा सकता हो या उन्हें किसी और तरीके से डाला नहीं जा सकता हो.
समाधान
Android 12 के RoR अपडेट सिस्टम से, बहुत ज़्यादा खतरनाक हमलावरों से सुरक्षा मिलती है. साथ ही, उपयोगकर्ता के डिवाइस पर मौजूद पासवर्ड और पिन, डिवाइस पर ही रहते हैं. इन्हें कभी भी Google के सर्वर पर न तो भेजा जाता है और न ही सेव किया जाता है. यहां उस प्रोसेस के बारे में खास जानकारी दी गई है जिससे यह पक्का किया जाता है कि सुरक्षा के लेवल, हार्डवेयर पर आधारित डिवाइस-लेवल के RoR सिस्टम के जैसे ही हों:
- Android, डिवाइस पर सेव किए गए डेटा पर क्रिप्टोग्राफ़िक सुरक्षा लागू करता है.
- सभी डेटा को ट्रस्टेड एक्ज़ीक्यूशन एनवायरमेंट (टीईई) में सेव की गई कुंजियों से सुरक्षित रखा जाता है.
- टीईई, कुंजियों को सिर्फ़ तब रिलीज़ करता है, जब चालू ऑपरेटिंग सिस्टम, क्रिप्टोग्राफ़िक पुष्टि (वेरिफ़ाइड बूट) पास कर लेता है.
- Google के सर्वर पर चल रही RoR सेवा, CE डेटा को सुरक्षित रखती है. इसके लिए, यह एक सीक्रेट सेव करती है. इसे सिर्फ़ कुछ समय के लिए वापस पाया जा सकता है. यह सुविधा, Android के सभी डिवाइसों पर काम करती है.
- डिवाइस को अनलॉक करने और सीई स्टोरेज को डिक्रिप्ट करने के लिए, क्रिप्टोग्राफ़िक कुंजी का इस्तेमाल किया जाता है. इसे उपयोगकर्ता के पिन से सुरक्षित किया जाता है.
- जब रात में डिवाइस को रीबूट करने का समय तय किया जाता है, तो Android उपयोगकर्ता को अपना पिन डालने के लिए कहता है. इसके बाद, वह सिंथेटिक पासवर्ड (एसपी) का हिसाब लगाता है.
- इसके बाद, यह एसपी को दो बार एन्क्रिप्ट करता है: पहली बार रैम में सेव की गई कुंजी
K_sसे और दूसरी बार टीईई में सेव की गई कुंजीK_kसे. - डबल-एन्क्रिप्ट (सुरक्षित) किए गए एसपी को डिस्क पर सेव किया जाता है. साथ ही, एसपी को रैम से मिटा दिया जाता है. दोनों कुंजियां नई जनरेट की जाती हैं और इनका इस्तेमाल सिर्फ़ एक बार रीबूट करने के लिए किया जाता है.
- जब रीबूट करने का समय होता है, तो Android, सर्वर को
K_sसौंप देता है.K_kवाली रसीद को डिस्क पर सेव करने से पहले एन्क्रिप्ट (सुरक्षित) किया जाता है. - रिबूट करने के बाद, Android रसीद को डिक्रिप्ट करने के लिए
K_kका इस्तेमाल करता है. इसके बाद,K_sपाने के लिए इसे सर्वर को भेजता है.- डिस्क पर सेव किए गए एसपी को डिक्रिप्ट करने के लिए,
K_kऔरK_sका इस्तेमाल किया जाता है. - Android, एसपी का इस्तेमाल करके सीई स्टोरेज को अनलॉक करता है. इससे ऐप्लिकेशन को सामान्य तरीके से शुरू किया जा सकता है.
K_kऔरK_sको खारिज कर दिया जाता है.
- डिस्क पर सेव किए गए एसपी को डिक्रिप्ट करने के लिए,
आपके फ़ोन को सुरक्षित रखने वाले अपडेट, आपके हिसाब से सही समय पर हो सकते हैं. जैसे, जब आप सो रहे हों.
सिम पिन फिर से डालें
कुछ मामलों में, सिम कार्ड के पिन कोड की पुष्टि कैश मेमोरी से की जाती है. इसे सिम-पिन रीप्ले कहा जाता है.
अगर किसी सिम कार्ड के लिए पिन चालू है, तो बिना किसी रुकावट के पिन कोड की पुष्टि (सिम-पिन रीप्ले) होना भी ज़रूरी है. ऐसा तब होता है, जब डिवाइस को बिना किसी की मदद के रीबूट किया जाता है. इससे मोबाइल नेटवर्क से कनेक्ट होने की सुविधा वापस मिलती है. यह सुविधा, फ़ोन कॉल, एसएमएस मैसेज, और डेटा सेवाओं के लिए ज़रूरी है. सिम पिन और उससे जुड़ी सिम कार्ड की जानकारी (आईसीसीआईडी और सिम स्लॉट नंबर) को एक साथ सुरक्षित तरीके से सेव किया जाता है. स्टोर किए गए पिन को सिर्फ़ तब वापस पाया जा सकता है और पुष्टि के लिए इस्तेमाल किया जा सकता है, जब डिवाइस बिना किसी रुकावट के रीबूट हो जाए. अगर डिवाइस सुरक्षित है, तो सिम पिन को LSKF से सुरक्षित की गई कुंजियों के साथ सेव किया जाता है. अगर सिम का पिन चालू है, तो RoR सर्वर के साथ इंटरैक्ट करने के लिए, वाई-फ़ाई कनेक्शन ज़रूरी है. ऐसा OTA अपडेट और सर्वर पर आधारित RoR के लिए ज़रूरी है. इससे रीबूट के बाद, मोबाइल नेटवर्क कनेक्टिविटी के साथ बुनियादी फ़ंक्शन काम करते हैं.
जब भी उपयोगकर्ता सिम पिन को चालू करता है, उसकी पुष्टि करता है या उसमें बदलाव करता है, तब सिम पिन को फिर से एन्क्रिप्ट (सुरक्षित) किया जाता है और सेव किया जाता है. इनमें से कोई भी स्थिति होने पर, सिम का पिन हटा दिया जाता है:
- सिम हटा दिया गया है या उसे रीसेट कर दिया गया है.
- उपयोगकर्ता पिन बंद कर देता है.
- RoR के अलावा किसी और वजह से रीबूट किया गया है.
स्टोर किए गए सिम पिन का इस्तेमाल, RoR की वजह से रीबूट होने के बाद सिर्फ़ एक बार किया जा सकता है. साथ ही, इसका इस्तेमाल सिर्फ़ कुछ समय (20 सेकंड) के लिए किया जा सकता है. अगर सिम कार्ड की जानकारी मेल खाती है, तो ही ऐसा किया जा सकता है. सेव किया गया सिम पिन, TelephonyManager ऐप्लिकेशन से कभी बाहर नहीं जाता. साथ ही, इसे बाहरी मॉड्यूल से वापस नहीं पाया जा सकता.
लागू करने के दिशा-निर्देश
Android 12 में, मल्टी-क्लाइंट और सर्वर पर आधारित RoR फ़ंक्शन, OTA अपडेट पुश करते समय पार्टनर पर कम लोड डालते हैं. ज़रूरी अपडेट, डिवाइस के बंद रहने के दौरान हो सकते हैं. जैसे, सोने के लिए तय किए गए समय के दौरान.
यह पक्का करने के लिए कि इस दौरान ओटीए अपडेट से उपयोगकर्ताओं को कोई परेशानी न हो, लाइट उत्सर्जन को कम करने के लिए डार्क मोड का इस्तेमाल करें. इसके लिए, डिवाइस के बूटलोडर को स्ट्रिंग reason unattended खोजने के लिए कहें. अगर unattended true है, तो डिवाइस को गहरे रंग वाले मोड में रखें. ध्यान दें कि आवाज़ और रोशनी के उत्सर्जन को कम करने की ज़िम्मेदारी हर ओईएम की होती है.
अगर आपको Android 12 पर अपग्रेड करना है या Android 12 वाले डिवाइस लॉन्च करने हैं, तो RoR की नई सुविधा को लागू करने के लिए आपको कुछ भी करने की ज़रूरत नहीं है.
मल्टी-क्लाइंट फ़्लो में एक नया कॉल, isPreparedForUnattendedUpdate, है. इसके बारे में यहां बताया गया है:
@RequiresPermission(anyOf = {android.Manifest.permission.RECOVERY,
android.Manifest.permission.REBOOT})
public static boolean isPreparedForUnattendedUpdate(@NonNull Context context)
आपको इसे लागू करने की ज़रूरत नहीं है, क्योंकि Android 12 से HAL का इस्तेमाल बंद कर दिया गया है.
TelephonyManager
Android 12 में, रीबूट करने से पहले OTA क्लाइंट, TelephonyManager सिस्टम एपीआई को कॉल करता है. यह एपीआई, कैश मेमोरी में सेव किए गए सभी पिन कोड को AVAILABLE स्थिति से REBOOT_READY स्थिति में ले जाता है. TelephonyManager सिस्टम एपीआई को मौजूदा REBOOT मेनिफ़ेस्ट की अनुमति से सुरक्षित किया जाता है.
/**
* The unattended reboot was prepared successfully.
* @hide
*/
@SystemApi
public static final int PREPARE_UNATTENDED_REBOOT_SUCCESS = 0;
/**
* The unattended reboot was prepared, but the user will need to manually
* enter the PIN code of at least one SIM card present in the device.
* @hide
*/
@SystemApi
public static final int PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED = 1;
/**
* The unattended reboot was not prepared due to generic error.
* @hide
*/
@SystemApi
public static final int PREPARE_UNATTENDED_REBOOT_ERROR = 2;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"PREPARE_UNATTENDED_REBOOT_"},
value = {
PREPARE_UNATTENDED_REBOOT_SUCCESS,
PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED,
PREPARE_UNATTENDED_REBOOT_ERROR
})
public @interface PrepareUnattendedRebootResult {}
/**
* Prepare TelephonyManager for an unattended reboot. The reboot is
* required to be done shortly after the API is invoked.
*
* Requires system privileges.
*
* <p>Requires Permission:
* {@link android.Manifest.permission#REBOOT}
*
* @return {@link #PREPARE_UNATTENDED_REBOOT_SUCCESS} in case of success.
* {@link #PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED} if the device contains
* at least one SIM card for which the user needs to manually enter the PIN
* code after the reboot. {@link #PREPARE_UNATTENDED_REBOOT_ERROR} in case
* of error.
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.REBOOT)
@PrepareUnattendedRebootResult
public int prepareForUnattendedReboot()
TelephonyManager सिस्टम एपीआई का इस्तेमाल, खास अधिकार वाले APK करते हैं.
जांच करना
नए एपीआई की जांच करने के लिए, यह निर्देश चलाएं:
adb shell cmd phone unattended-rebootयह कमांड सिर्फ़ तब काम करती है, जब शेल को रूट (adb root) के तौर पर चलाया जा रहा हो.
सिर्फ़ Android 11 के लिए
इस पेज का बाकी हिस्सा, Android 11 पर लागू होता है.
जुलाई 2020 से, RoR HAL को लागू करने के तरीके को दो कैटगरी में बांटा गया है:
- अगर एसओसी हार्डवेयर, रीबूट करने पर भी रैम के डेटा को सेव रखने की सुविधा देता है, तो ओईएम, एओएसपी में डिफ़ॉल्ट तौर पर लागू की गई सुविधा (डिफ़ॉल्ट रैम एस्क्रो) का इस्तेमाल कर सकते हैं.
- अगर डिवाइस का हार्डवेयर या SoC, सुरक्षित हार्डवेयर एन्क्लेव (एक अलग सुरक्षा कोप्रोसेसर, जिसमें अपनी रैम और रोम होती है) के साथ काम करता है, तो उसे यह भी करना होगा:
- मुख्य सीपीयू के रीबूट होने का पता लगा सके.
- आपके पास ऐसा हार्डवेयर टाइमर सोर्स होना चाहिए जो रीबूट करने पर भी बना रहे. इसका मतलब है कि एनक्लेव को रीबूट का पता लगाना होगा. साथ ही, रीबूट से पहले सेट किए गए टाइमर की समयसीमा खत्म करनी होगी.
- एन्क्लेव रैम/रॉम में एस्क्रो की गई कुंजी को सेव करने की सुविधा होनी चाहिए, ताकि ऑफ़लाइन हमलों से इसे वापस न पाया जा सके. इसे RoR कुंजी को इस तरह से सेव करना चाहिए कि अंदरूनी लोगों या हमलावरों के लिए इसे वापस पाना नामुमकिन हो.
डिफ़ॉल्ट रैम एस्क्रो
AOSP में, रैम परसिस्टेंस का इस्तेमाल करके RoR HAL को लागू किया गया है. इसके लिए, ओईएम को यह पक्का करना होगा कि उनके एसओसी, रीबूट करने पर भी रैम परसिस्टेंस की सुविधा के साथ काम करते हों. कुछ सिस्टम ऑन चिप (एसओसी), रीबूट करने पर रैम के कॉन्टेंट को सेव नहीं कर पाते. इसलिए, ओईएम को सलाह दी जाती है कि वे इस डिफ़ॉल्ट एचएएल को चालू करने से पहले, अपने एसओसी पार्टनर से सलाह लें. इसकी कैननिकल जानकारी, यहां दिए गए सेक्शन में मौजूद है.
RoR का इस्तेमाल करके, ओटीए अपडेट करने का फ़्लो
RoR को लागू करने के लिए, फ़ोन पर मौजूद OTA क्लाइंट ऐप्लिकेशन के पास Manifest.permission.REBOOT और Manifest.permission.RECOVERY अनुमतियां होनी चाहिए, ताकि वह ज़रूरी तरीकों को कॉल कर सके. ज़रूरी शर्तें पूरी होने के बाद, अपडेट करने का तरीका यहां बताया गया है:
- ओटीए क्लाइंट ऐप्लिकेशन, अपडेट डाउनलोड करता है.
- OTA क्लाइंट ऐप्लिकेशन,
RecoverySystem#prepareForUnattendedUpdateको कॉल करता है. इससे उपयोगकर्ता को अगली बार डिवाइस अनलॉक करते समय, लॉक स्क्रीन पर अपना पिन, पैटर्न या पासवर्ड डालने के लिए कहा जाता है. - उपयोगकर्ता, लॉकस्क्रीन पर डिवाइस को अनलॉक करता है. इसके बाद, डिवाइस पर अपडेट लागू किया जा सकता है.
- OTA क्लाइंट ऐप्लिकेशन,
RecoverySystem#rebootAndApplyको कॉल करता है. इससे डिवाइस तुरंत रीबूट हो जाता है.
इस प्रोसेस के आखिर में, डिवाइस रीबूट हो जाता है और RoR मेकैनिज़्म, क्रेडेंशियल एन्क्रिप्ट (सीई) किए गए स्टोरेज को अनलॉक कर देता है. ऐप्लिकेशन के लिए, यह सामान्य उपयोगकर्ता के अनलॉक करने जैसा होता है. इसलिए, उन्हें सभी सिग्नल मिलते हैं. जैसे, ACTION_LOCKED_BOOT_COMPLETED और ACTION_BOOT_COMPLETED.
प्रॉडक्ट कॉन्फ़िगरेशन में बदलाव करना
Android 11 में RoR सुविधा के साथ काम करने वाले प्रॉडक्ट में, RebootEscrow HAL का इस्तेमाल किया जाना चाहिए. साथ ही, इसमें सुविधा मार्कर वाली एक्सएमएल फ़ाइल भी शामिल होनी चाहिए. डिफ़ॉल्ट तौर पर लागू की गई सुविधा, उन डिवाइसों पर अच्छी तरह से काम करती है जो वार्म रीबूट का इस्तेमाल करते हैं. वार्म रीबूट में, रीबूट के दौरान DRAM को पावर मिलती रहती है.
रीबूट एस्क्रो सुविधा मार्कर
सुविधा मार्कर भी मौजूद होना चाहिए:
PRODUCT_COPY_FILES += \
frameworks/native/data/etc/android.hardware.reboot_escrow.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.reboot_escrow.xml
रीबूट एस्क्रो एचएएल को लागू करने का डिफ़ॉल्ट तरीका
डिफ़ॉल्ट तरीके से लागू करने के लिए, आपको 65,536 (0x10000) बाइट रिज़र्व करने होंगे. इन बाइट को कभी भी नॉन-वॉलटाइल स्टोरेज में न लिखें, ताकि सुरक्षा से जुड़ी प्रॉपर्टी बनी रहें.
Linux कर्नेल डिवाइस ट्री में बदलाव
Linux कर्नल के डिवाइस ट्री में, आपको pmem क्षेत्र के लिए मेमोरी रिज़र्व करनी होगी.
यहां दिए गए उदाहरण में, 0x50000000 को रिज़र्व करने का तरीका बताया गया है:
reserved-memory {
my_reservation@0x50000000 {
no-map;
reg = <0x50000000 0x10000>;
}
}
reboot_escrow@0 {
compatible = "pmem-region";
reg = <0x50000000 0x10000>;
};
पुष्टि करें कि आपके पास ब्लॉक डायरेक्ट्री में एक नया डिवाइस है. उसका नाम /dev/block/pmem0 (जैसे, pmem1 या pmem2) है.
Device.mk में बदलाव
मान लें कि पिछले चरण में इस्तेमाल किए गए आपके नए डिवाइस का नाम pmem0 है. आपको यह पक्का करना होगा कि vendor/<oem>/<product>/device.mk में ये नई एंट्री जोड़ी गई हों:
# Resume on Reboot support
PRODUCT_PROPERTY_OVERRIDES += \
ro.rebootescrow.device=/dev/block/pmem0
PRODUCT_PACKAGES += \
android.hardware.rebootescrow-service.default
SELinux के नियम
इन नई एंट्री को डिवाइस के file_contexts में जोड़ें:
/dev/block/pmem0 u:object_r:rebootescrow_device:s0
/vendor/bin/hw/android\.hardware\.rebootescrow-service\.default u:object_r:hal_rebootescrow_default_exec:s0