המשך לאחר הפעלה מחדש

ב-Android 11, אפשר להחיל עדכוני OTA באמצעות מנגנונים של עדכון A/B או של עדכון A/B וירטואלי, בשילוב עם שיטות המחלקה RecoverSystem. אחרי שהמכשיר הופעל מחדש כדי להחיל עדכון OTA, המשך ההפעלה לאחר ההפעלה (RoR) מבטל את הנעילה של האחסון בהצפנת פרטי כניסה (CE).

שותפים יכולים להתאים את התהליך הזה עם תכונת מערכת OTA שמחילה עדכונים כשהמכשיר צפוי להיות ללא פעילות ב-Android 11, אבל שותפים עם Android 12 לא צריכים תכונה נוספת של מערכת OTA. תהליך RoR מספק למשתמשים אבטחה ונוחות נוספות, כי ניתן לבצע את העדכונים בזמן שהמכשירים לא פעילים, ואילו פונקציות העדכון מרובה הלקוחות ומבוססות-השרת של Android 12 מספקות אבטחה ברמת החומרה של המכשיר.

צריך לתת לפיצ'ר android.hardware.reboot_escrow הרשאת גישה למכשיר כדי לתמוך ב-RoR ב-Android 11, אבל לא צריך לעשות את זה כדי להפעיל RoR מבוסס-שרת ב-Android 12 ואילך, כי ב-HAL לא נעשה שימוש ב-HAL.

ברקע

החל מ-Android 7, מערכת Android תומכת בהפעלה ישירה, שמאפשרת לאפליקציות במכשיר להתחיל לפעול לפני שהמשתמש מבטל את הנעילה של אחסון CE. ההטמעה של תמיכה באתחול ישיר סיפקה למשתמשים חוויה טובה יותר לפני שהיה צריך להזין את גורם הידע במסך הנעילה (LSKF) אחרי ההפעלה.

פרוטוקול RoR מאפשר לבטל את הנעילה של אחסון CE של כל האפליקציות במכשיר, כולל אפליקציות שלא תומכות בהפעלה ישירה, כשמתבצעת הפעלה מחדש בעקבות עדכון OTA. התכונה הזו מאפשרת למשתמשים לקבל התראות מכל האפליקציות שמותקנות במכשירים שלהם, אחרי ההפעלה מחדש.

מודל של איום

הטמעה של RoR חייבת להבטיח שכשמכשיר נופל לידיים של תוקף, קשה מאוד לתוקפים לשחזר את הנתונים בהצפנת CE של המשתמש, גם אם המכשיר מופעל, אחסון CE לא נעול והמכשיר פתוח על ידי המשתמש אחרי קבלת עדכון OTA. ההתנגדות למתקפות פנימיים חייבת להיות יעילה, גם אם התוקף מקבל גישה למפתחות החתימה הקריפטוגרפיים של השידור.

באופן ספציפי, אסור לקרוא אחסון CE על ידי תוקף שהמכשיר מחזיק בו פיזית, ושיש לו את היכולות והמגבלות הבאות:

יכולות

  • יכולים להשתמש במפתח החתימה של כל ספק או חברה כדי לחתום על הודעות שרירותיות.
  • עלול לגרום למכשיר לקבל עדכון OTA.
  • ניתן לשנות את הפעולה של כל חומרה (כמו מעבד אפליקציות או זיכרון Flash), למעט כפי שמפורט בקטע מגבלות שבהמשך. (עם זאת, שינוי כזה כולל גם עיכוב של שעה אחת לפחות וגם מחזור כוח שמשרוס את תוכן ה-RAM.)

מגבלות

  • לא ניתן לשנות את הפעולה של חומרה עמידה בפני שינויים (לדוגמה, Titan M).
  • לא ניתן לקרוא את זיכרון ה-RAM של המכשיר בשידור חי.
  • לא ניתן לנחש את פרטי הכניסה של המשתמש (קוד אימות, קו ביטול נעילה, סיסמה) או לגרום להם להזין אותם.

הפתרון

מערכת העדכון של RoR ל-Android 12 מספקת אבטחה מפני תוקפים מתוחכמים מאוד. היא עושה זאת כשהסיסמאות וקודי האימות במכשיר נשארים במכשיר – הם אף פעם לא נשלחים לשרתים של Google ולא מאוחסנים בהם. זוהי סקירה כללית של התהליך שבו אפשר לוודא שרמות האבטחה המסופקות דומות למערכת RoR מבוססת חומרה ברמת המכשיר:

  • מערכת Android מחילה אמצעי הגנה קריפטוגרפיים על נתונים שמאוחסנים במכשיר.
  • כל הנתונים מוגנים באמצעות מפתחות שמאוחסנים בסביבת הביצוע המהימנה (TEE).
  • צוות TEE משחרר את המפתחות רק אם מערכת ההפעלה שפועלת עוברת אימות קריפטוגרפי (הפעלה מאומתת).
  • שירות RoR שפועל בשרתי Google מאבטח את נתוני ה-CE על ידי אחסון סוד שאפשר לאחזר לזמן מוגבל בלבד. זה עובד בכל הסביבה העסקית של Android.
  • מפתח קריפטוגרפי, המוגן באמצעות קוד אימות של המשתמש, משמש לביטול הנעילה של המכשיר ולפענוח של אחסון ה-CE.
    • לאחר תזמון הפעלה מחדש במהלך לילה, Android מבקש מהמשתמש להזין את קוד האימות שלו ואז מחשב סיסמה סינתטית (SP).
    • לאחר מכן, הוא מצפין את ספק השירות (SP) פעמיים: פעם אחת באמצעות מפתח K_s שמאוחסן ב-RAM, ופעם נוספת באמצעות מפתח K_k שמאוחסן ב-TEE.
    • ספק השירות (SP) שמוצפן כפול מאוחסן בכונן וה-SP נמחק מה-RAM. שני המפתחות נוצרו מחדש ומשמשים להפעלה מחדש אחת בלבד.
  • כשיגיע הזמן להפעיל מחדש, Android מפקיד את K_s לשרת. הקבלה עם K_k מוצפנת לפני שהיא מאוחסנת בדיסק.
  • לאחר ההפעלה מחדש, מערכת Android משתמשת ב-K_k כדי לפענח את הקבלה, ואז שולחת אותה לשרת כדי לאחזר את K_s.
    • K_k ו-K_s משמשים לפענוח ה-SP שמאוחסן בדיסק.
    • Android משתמש ב-SP כדי לבטל את הנעילה של אחסון CE ולאפשר הפעלה רגילה של האפליקציה.
    • K_k ו-K_s נמחקו.

העדכונים ששומרים על אבטחת הטלפון יכולים להתבצע בזמן שנוח לכם: בזמן השינה.

הפעלה חוזרת של קוד האימות של כרטיס ה-SIM

בתנאים מסוימים, קוד האימות של כרטיס ה-SIM מאומת מתוך מטמון, תהליך שנקרא הפעלה חוזרת של קוד האימות של כרטיס ה-SIM.

כרטיס SIM שהופעל בו קוד אימות צריך גם לעבור אימות חלק של קוד אימות (הפעלה מחדש של כרטיס SIM) אחרי הפעלה מחדש ללא השגחה, כדי לשחזר את החיבור לרשת הסלולרית (נדרשת לשיחות טלפון, להודעות SMS ולשירותי נתונים). קוד האימות של ה-SIM והפרטים של כרטיס ה-SIM התואם (ה-ICCID ומספר החריץ של ה-SIM) מאוחסנים יחד באופן מאובטח. אפשר לאחזר את קוד האימות שנשמר ולהשתמש בו לאימות רק אחרי הפעלה מחדש ללא השגחה. אם המכשיר מאובטח, קוד האימות של ה-SIM מאוחסן עם מפתחות שמוגנים על ידי ה-LSKF. אם קוד האימות מופעל בכרטיס ה-SIM, אינטראקציה עם שרת ה-RoR מחייבת חיבור Wi-Fi לצורך עדכון OTA ו-RoR מבוסס-שרת, כדי להבטיח פונקציונליות בסיסית (עם קישוריות סלולרית) אחרי ההפעלה מחדש.

קוד האימות של כרטיס ה-SIM מוצפן מחדש ומאוחסן בכל פעם שהמשתמש מפעיל, מאמת או משנה אותו בהצלחה. קוד האימות של כרטיס ה-SIM נמחק אם מתרחש אחד מהמצבים הבאים:

  • כרטיס ה-SIM מוסר או מתאפס.
  • המשתמש משבית את קוד האימות.
  • בוצעה הפעלה מחדש שלא ביוזמת RoR.

אפשר להשתמש בקוד האימות של כרטיס ה-SIM המאוחסן רק פעם אחת לאחר הפעלה מחדש ביוזמת ה-RoR, ורק למשך זמן קצר מאוד (20 שניות) – אם הפרטים של כרטיס ה-SIM תואמים. קוד האימות של כרטיס ה-SIM השמור אף פעם לא נשלח מאפליקציית טלפוניה Manager ולא ניתן לאחזר אותו באמצעות מודולים חיצוניים.

הנחיות להטמעה

ב-Android 12, פונקציות RoR מבוססות-שרת וריבוי לקוחות מספקות עומס קל יותר על שותפים כשהם דוחפים עדכוני OTA. עדכונים נחוצים יכולים להתרחש בזמן השבתה נוחות של המכשיר, למשל במהלך שעות שינה ייעודיות.

כדי להבטיח שעדכוני OTA לא יפריעו למשתמשים במהלך פרק הזמן הזה, כדאי להשתמש במצב כהה כדי לצמצם את פליטות האור. כדי לעשות זאת, צריך לבקש מתוכנת האתחול של המכשיר לחפש את המחרוזת 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)

אתם לא צריכים להטמיע את זה, כי טכנולוגיית HAL הוצאה משימוש החל מ-Android 12.

מנהל טלפוניה

לקוח ה-OTA מפעיל את ה-API של המערכת TelephonyManager כשבקרוב תתבצע הפעלה מחדש ב-Android 12. ה-API הזה מעביר את כל קודי האימות שנשמרו במטמון מהמצב AVAILABLE למצב REBOOT_READY. ה-System API 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()

ממשק ה-API של מערכת טלפוניה נמצא בשימוש על ידי חבילות APK בעלות הרשאות.

בדיקה

כדי לבדוק את ה-API החדש, מריצים את הפקודה הבאה:

    adb shell cmd phone unattended-reboot

הפקודה הזו פועלת רק כשהמעטפת פועלת ברמה הבסיסית (adb root).

Android 11 בלבד

שאר הדף הזה רלוונטי ל-Android 11.

החל מיולי 2020, הטמעות של RoR HAL מתחלקות לשתי קטגוריות:

  1. אם חומרת ה-SoC תומכת בהתמדה של זיכרון RAM בהפעלות מחדש, יצרני ציוד מקורי יכולים להשתמש בהטמעת ברירת המחדל ב-AOSP (ברירת המחדל של שמירת RAM ב-RAM).
  2. אם חומרת המכשיר או ה-SoC תומכים ב-enclave של חומרה מאובטחת (מעבד עזר נפרד לאבטחה עם RAM ו-ROM משלו), צריך גם לבצע את הפעולות הבאות:
    • זיהוי של הפעלה מחדש של המעבד (CPU) הראשי.
    • מקור טיימר לחומרה שממשיך לפעול בכל הפעלה מחדש. כלומר, המובלעת צריכה להיות מסוגלת לזהות את ההפעלה מחדש ולפקוע טיימר שהוגדר לפני האתחול.
    • תמיכה באחסון מפתח בנאמנות ב-RAM/ROM של המובלת כך שאי אפשר לשחזר אותו באמצעות התקפות אופליין. צריך לאחסן את מפתח ה-RoR בצורה שלא תאפשר לגורמים פנימיים או לתוקפים לשחזר אותו.

ברירת מחדל של נאמנות RAM

ב-AOSP יש הטמעה של RoR HAL באמצעות שימוש מתמיד ב-RAM. כדי שזה יעבוד, יצרני ציוד מקורי צריכים לוודא שרכיבי ה-SoC שלהם תומכים בהתמדה של זיכרון RAM בכל הפעלה מחדש. חלק מרכיבי ה-SoC לא יכולים לשמור תוכן RAM במהלך הפעלה מחדש, לכן מומלץ ליצרני ציוד מקורי להתייעץ עם שותפי ה-SoC שלהם לפני שמפעילים את ברירת המחדל של HAL. ההפניה הקנונית לאפשרות הזו בקטע הבא.

זרימה של עדכון OTA באמצעות RoR

לאפליקציית הלקוח מסוג OTA בטלפון צריכות להיות ההרשאות Manifest.permission.REBOOT ו-Manifest.permission.RECOVERY כדי לקרוא ל-methods הנדרשות להטמעת RoR. כשצריך אותה דרישה מוקדמת, תהליך העדכון מתנהל לפי השלבים הבאים:

  1. אפליקציית לקוח OTA מורידה את העדכון.
  2. אפליקציית לקוח OTA מפעילה קריאה ל-RecoverySystem#prepareForUnattendedUpdate, וגורמת למשתמש לקבל בקשה להזנת קוד האימות, קו ביטול הנעילה או הסיסמה במסך הנעילה במהלך ביטול הנעילה הבא.
  3. המשתמש מבטל את נעילת המכשיר במסך הנעילה, והמכשיר מוכן להפעלת העדכון.
  4. אפליקציית לקוח OTA מפעילה קריאה ל-RecoverySystem#rebootAndApply, ומפעילה באופן מיידי הפעלה מחדש.

בסוף התהליך הזה, המכשיר יופעל מחדש ומנגנון RoR יבטל את הנעילה של האחסון המוצפן של פרטי הכניסה (CE). כשמדובר באפליקציות, ביטול הנעילה מופיע כביטול נעילה רגיל של המשתמש, כך שהן מקבלות את כל האותות שהם מקבלים בדרך כלל, כמו ACTION_LOCKED_BOOT_COMPLETED ו-ACTION_BOOT_COMPLETED.

שינוי הגדרות של מוצר

מוצר שמסומן כתומך ב-RoR ב-Android 11 צריך לכלול הטמעה של אתחול Escrow HAL ולכלול את קובץ ה-XML של סימון המאפיינים. הטמעת ברירת המחדל פועלת היטב במכשירים שמשתמשים בהפעלה מחדש במצב ביניים (כשהחשמל ל-DRAM נשאר מופעל בזמן ההפעלה מחדש).

סמן תכונת הפקדה מחדש בנאמנות

גם סמן התכונה חייב להיות:

PRODUCT_COPY_FILES += \
    frameworks/native/data/etc/android.hardware.reboot_escrow.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.reboot_escrow.xml

הטמעת HAL של הפעלה מחדש בנאמנות כברירת מחדל

כדי להשתמש בהטמעת ברירת המחדל, צריך להזמין 65536 (0x10,000) בייטים. אף פעם אל תכתבו את הבייטים האלה לאחסון לא תנודתי, כדי להבטיח שמאפייני האבטחה יישמרו.

שינויים בעץ של מכשיר הליבה של 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