रीबूट होने पर फिर से शुरू करना

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 की सुविधा चालू करने के लिए, आपको ऐसा करने की ज़रूरत नहीं है. ऐसा इसलिए, क्योंकि ये एचएएल का इस्तेमाल नहीं करते हैं.

बैकग्राउंड

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_k को वापस पाने के लिए, इसे सर्वर को भेजता है.K_s
    • K_k और K_s का इस्तेमाल, डिस्क पर सेव किए गए एसपी को डिक्रिप्ट करने के लिए किया जाता है.
    • Android, एसपी का इस्तेमाल करके सीई स्टोरेज को अनलॉक करता है. इससे ऐप्लिकेशन को सामान्य तरीके से शुरू किया जा सकता है.
    • K_k और K_s को खारिज कर दिया जाता है.

आपके फ़ोन को सुरक्षित रखने वाले अपडेट, आपके हिसाब से सही समय पर हो सकते हैं. जैसे, जब आप सो रहे हों.

SIM-PIN replay

कुछ मामलों में, सिम कार्ड के पिन कोड की पुष्टि कैश मेमोरी से की जाती है. इसे सिम-पिन रीप्ले कहा जाता है.

जिस सिम कार्ड के लिए पिन चालू है उसे बिना किसी रुकावट के पिन कोड की पुष्टि (सिम-पिन रीप्ले) करनी होगी. ऐसा तब करना होगा, जब डिवाइस को बिना किसी की मदद के रीबूट किया गया हो. इससे सेल्युलर कनेक्टिविटी वापस आ जाएगी. यह कनेक्टिविटी, फ़ोन कॉल, एसएमएस मैसेज, और डेटा सेवाओं के लिए ज़रूरी है. सिम पिन और उससे मैच करने वाली सिम कार्ड की जानकारी (आईसीसीआईडी और सिम स्लॉट नंबर) को सुरक्षित तरीके से एक साथ सेव किया जाता है. स्टोर किए गए पिन को सिर्फ़ तब वापस पाया जा सकता है और पुष्टि के लिए इस्तेमाल किया जा सकता है, जब डिवाइस अपने-आप रीबूट हो जाए. अगर डिवाइस सुरक्षित है, तो सिम पिन को 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 से इस एचएएल का इस्तेमाल नहीं किया जा सकता.

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 को लागू करने के तरीके दो कैटगरी में आते हैं:

  1. अगर SoC हार्डवेयर, रीबूट करने पर भी रैम के डेटा को सेव रखने की सुविधा देता है, तो ओईएम, एओएसपी में डिफ़ॉल्ट तौर पर लागू होने वाली सुविधा (डिफ़ॉल्ट रैम एस्क्रो) का इस्तेमाल कर सकते हैं.
  2. अगर डिवाइस का हार्डवेयर या SoC, सुरक्षित हार्डवेयर एन्क्लेव (एक अलग सुरक्षा कोप्रोसेसर, जिसमें अपनी रैम और रोम होती है) के साथ काम करता है, तो उसे ये काम भी करने होंगे:
    • मुख्य सीपीयू के रीबूट होने का पता लगा सके.
    • आपके पास ऐसा हार्डवेयर टाइमर सोर्स होना चाहिए जो रीबूट करने पर भी बना रहे. इसका मतलब है कि एनक्लेव को रीबूट का पता लगाना होगा. साथ ही, रीबूट से पहले सेट किए गए टाइमर की समयसीमा खत्म करनी होगी.
    • एन्क्लेव रैम/रॉम में एस्क्रो की गई कुंजी को सेव करने की सुविधा. इससे ऑफ़लाइन हमलों से कुंजी को वापस नहीं पाया जा सकता. इसे RoR कुंजी को इस तरह से सेव करना चाहिए कि अंदरूनी लोगों या हमलावरों के लिए इसे वापस पाना मुमकिन न हो.

डिफ़ॉल्ट रैम एस्क्रो

AOSP में, रैम परसिस्टेंस का इस्तेमाल करके RoR HAL को लागू किया गया है. इसके लिए, ओईएम को यह पक्का करना होगा कि उनके एसओसी, रीबूट करने पर भी रैम परसिस्टेंस की सुविधा के साथ काम करते हों. कुछ सिस्टम ऑन चिप (एसओसी), रीबूट करने पर रैम के कॉन्टेंट को सेव नहीं कर पाते. इसलिए, ओईएम को सलाह दी जाती है कि वे इस डिफ़ॉल्ट एचएएल को चालू करने से पहले, अपने एसओसी पार्टनर से सलाह लें. इसकी कैननिकल रेफ़रंस जानकारी, यहां दिए गए सेक्शन में मौजूद है.

RoR का इस्तेमाल करके ओटीए अपडेट करने का फ़्लो

RoR को लागू करने के लिए, फ़ोन पर मौजूद OTA क्लाइंट ऐप्लिकेशन के पास Manifest.permission.REBOOT और Manifest.permission.RECOVERY अनुमतियां होनी चाहिए, ताकि वह ज़रूरी तरीकों को कॉल कर सके. ज़रूरी शर्तें पूरी होने के बाद, अपडेट करने का तरीका यहां दिया गया है:

  1. ओटीए क्लाइंट ऐप्लिकेशन, अपडेट डाउनलोड करता है.
  2. OTA क्लाइंट ऐप्लिकेशन, RecoverySystem#prepareForUnattendedUpdate को कॉल करता है. इससे उपयोगकर्ता को अगली बार डिवाइस अनलॉक करने के दौरान, लॉक स्क्रीन पर पिन, पैटर्न या पासवर्ड डालने के लिए कहा जाता है.
  3. उपयोगकर्ता, लॉकस्क्रीन पर डिवाइस को अनलॉक करता है. इसके बाद, डिवाइस अपडेट लागू करने के लिए तैयार हो जाता है.
  4. OTA क्लाइंट ऐप्लिकेशन, RecoverySystem#rebootAndApply को कॉल करता है. इससे डिवाइस तुरंत रीबूट हो जाता है.

इस प्रोसेस के आखिर में, डिवाइस रीबूट हो जाता है और RoR मेकैनिज़्म, एन्क्रिप्ट (CE) किए गए क्रेडेंशियल स्टोरेज को अनलॉक कर देता है. ऐप्लिकेशन के लिए, यह एक सामान्य उपयोगकर्ता अनलॉक के तौर पर दिखता है. इसलिए, उन्हें सभी सिग्नल मिलते हैं. जैसे, 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 है. आपको यह पक्का करना होगा कि 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