در اندروید ۱۱، بهروزرسانیهای OTA را میتوان با استفاده از مکانیسمهای بهروزرسانی A/B یا بهروزرسانی مجازی A/B ، همراه با متدهای کلاس RecoverySystem ، اعمال کرد. پس از راهاندازی مجدد دستگاه برای اعمال بهروزرسانی OTA، Resume-on-Reboot (RoR) قفل حافظه رمزگذاریشده اعتبارنامه (CE) دستگاه را باز میکند.
اگرچه شرکا میتوانند این فرآیند را با یک ویژگی سیستم OTA که بهروزرسانیها را در زمان انتظار برای غیرفعال بودن دستگاه در اندروید ۱۱ اعمال میکند، جفت کنند، اما در اندروید ۱۲ شرکا به ویژگی سیستم OTA اضافی نیاز ندارند. فرآیند RoR امنیت و راحتی بیشتری را برای کاربران فراهم میکند زیرا بهروزرسانیها را میتوان در زمانهای غیرفعال بودن دستگاه انجام داد، در حالی که قابلیتهای بهروزرسانی چند کلاینتی و مبتنی بر سرور اندروید ۱۲ در کنار هم، امنیت از نوع سختافزاری دستگاه را فراهم میکنند.
اگرچه برای پشتیبانی از RoR در اندروید ۱۱، باید مجوز دستگاه را برای ویژگی android.hardware.reboot_escrow ارائه دهید، اما برای فعال کردن RoR مبتنی بر سرور در اندروید ۱۲ و بالاتر نیازی به انجام این کار ندارید، زیرا آنها از HAL استفاده نمیکنند.
پیشینه
با شروع اندروید ۷، اندروید از قابلیت بوت مستقیم (Direct Boot) پشتیبانی کرد که به برنامههای روی دستگاه اجازه میدهد قبل از باز شدن قفل حافظه CE توسط کاربر، راهاندازی شوند. پیادهسازی پشتیبانی از بوت مستقیم، قبل از اینکه کاربر نیاز به وارد کردن فاکتور دانش قفل صفحه (LSKF) پس از بوت داشته باشد، تجربه بهتری را برای کاربران فراهم کرد.
RoR اجازه میدهد تا قفل حافظه CE تمام برنامههای روی دستگاه، از جمله برنامههایی که از بوت مستقیم پشتیبانی نمیکنند، هنگام راهاندازی مجدد پس از بهروزرسانی OTA، باز شود. این ویژگی به کاربران امکان میدهد پس از راهاندازی مجدد، از تمام برنامههای نصب شده خود اعلان دریافت کنند.
مدل تهدید
پیادهسازی RoR باید تضمین کند که وقتی دستگاهی به دست مهاجم میافتد، بازیابی دادههای رمزگذاریشده با CE کاربر برای مهاجم بسیار دشوار باشد، حتی اگر دستگاه روشن باشد، حافظه CE قفلگشایی شده باشد و دستگاه پس از دریافت بهروزرسانی OTA توسط کاربر قفلگشایی شود. مقاومت در برابر حمله داخلی باید مؤثر باشد، حتی اگر مهاجم به کلیدهای امضای رمزنگاری پخششده دسترسی پیدا کند.
به طور خاص، حافظه CE نباید توسط مهاجمی که دستگاه را به صورت فیزیکی در اختیار دارد و دارای این قابلیتها و محدودیتها است، خوانده شود:
قابلیتها
- میتواند از کلید امضای هر فروشنده یا شرکتی برای امضای پیامهای دلخواه استفاده کند.
- میتواند باعث شود دستگاه بهروزرسانی OTA دریافت کند.
- میتواند عملکرد هر سختافزاری (مانند پردازنده برنامه یا حافظه فلش) را تغییر دهد - به جز مواردی که در محدودیتهای زیر به تفصیل شرح داده شده است. (با این حال، چنین تغییری شامل تأخیر حداقل یک ساعته و یک چرخه روشن/خاموش است که محتویات RAM را از بین میبرد.)
محدودیتها
- نمیتوان عملکرد سختافزار مقاوم در برابر دستکاری (مثلاً Titan M) را تغییر داد.
- نمیتوانم رم دستگاه زنده را بخوانم.
- نمیتواند اطلاعات کاربری (پین، الگو، رمز عبور) را حدس بزند یا به هر طریق دیگری باعث ورود آنها شود.
راه حل
سیستم بهروزرسانی RoR اندروید ۱۲ امنیت را در برابر مهاجمان بسیار پیچیده فراهم میکند و این کار را در حالی انجام میدهد که رمزهای عبور و پینهای روی دستگاه روی دستگاه باقی میمانند - آنها هرگز به سرورهای گوگل ارسال یا ذخیره نمیشوند. این مروری بر فرآیندی است که تضمین میکند سطوح امنیتی ارائه شده مشابه یک سیستم RoR مبتنی بر سختافزار و در سطح دستگاه است:
- اندروید از دادههای ذخیره شده در دستگاه، محافظتهای رمزنگاریشده اعمال میکند.
- تمام دادهها توسط کلیدهای ذخیره شده در محیط اجرای قابل اعتماد (TEE) محافظت میشوند.
- TEE فقط در صورتی کلیدها را منتشر میکند که سیستم عامل در حال اجرا، احراز هویت رمزنگاری ( بوت تأیید شده ) را با موفقیت پشت سر بگذارد.
- سرویس RoR که روی سرورهای گوگل اجرا میشود، با ذخیره یک راز که فقط برای مدت محدودی قابل بازیابی است، دادههای CE را ایمن میکند. این قابلیت در سراسر اکوسیستم اندروید کار میکند.
- یک کلید رمزنگاری، که توسط پین کاربر محافظت میشود، برای باز کردن قفل دستگاه و رمزگشایی حافظه CE استفاده میشود.
- وقتی یک ریبوت شبانه برنامهریزی میشود، اندروید از کاربر میخواهد پین خود را وارد کند، سپس یک رمز عبور ترکیبی (SP) محاسبه میکند.
- سپس SP را دو بار رمزگذاری میکند: یک بار با کلید
K_sکه در RAM ذخیره شده است، و بار دیگر با کلیدK_kکه در TEE ذخیره شده است. - SP رمزگذاریشدهی دوگانه روی دیسک ذخیره میشود و SP از RAM پاک میشود. هر دو کلید به تازگی تولید میشوند و فقط برای یک بار راهاندازی مجدد استفاده میشوند.
- وقتی زمان ریبوت فرا میرسد، اندروید
K_sبه سرور میسپارد. رسید حاویK_kقبل از ذخیره شدن روی دیسک رمزگذاری میشود. - پس از راهاندازی مجدد، اندروید از
K_kبرای رمزگشایی رسید استفاده میکند، سپس آن را برای بازیابیK_sبه سرور ارسال میکند.-
K_kوK_sبرای رمزگشایی SP ذخیره شده روی دیسک استفاده میشوند. - اندروید از SP برای باز کردن قفل حافظه CE و اجازه راهاندازی عادی برنامهها استفاده میکند.
-
K_kوK_sکنار گذاشته میشوند.
-
بهروزرسانیهایی که امنیت گوشی شما را حفظ میکنند، میتوانند در زمانی که برای شما مناسب است، انجام شوند: هنگام خواب.
بازپخش پین سیمکارت
تحت شرایط خاص، کد پین سیمکارت از طریق حافظه پنهان (cache) تأیید میشود، فرآیندی که به آن SIM-PIN replay میگویند.
سیمکارتی که پین فعال دارد، پس از راهاندازی مجدد بدون نیاز به مراقبت، باید یک تأیید کد پین یکپارچه (بازپخش سیمکارت-پین) را نیز پشت سر بگذارد تا اتصال تلفن همراه (که برای تماسهای تلفنی، پیامکها و سرویسهای داده مورد نیاز است) بازیابی شود. پین سیمکارت و اطلاعات سیمکارت منطبق با آن (ICCID و شماره اسلات سیمکارت) به طور ایمن در کنار هم ذخیره میشوند. پین ذخیره شده تنها پس از راهاندازی مجدد بدون نیاز به مراقبت موفق، قابل بازیابی و استفاده برای تأیید است. اگر دستگاه ایمن باشد، پین سیمکارت با کلیدهای محافظت شده توسط LSKF ذخیره میشود. اگر پین سیمکارت فعال باشد، تعامل با سرور RoR برای بهروزرسانی OTA و RoR مبتنی بر سرور، نیاز به اتصال WiFi دارد که عملکرد اولیه (با اتصال تلفن همراه) را پس از راهاندازی مجدد تضمین میکند.
هر بار که کاربر با موفقیت پین سیمکارت را فعال، تأیید یا تغییر دهد، دوباره رمزگذاری و ذخیره میشود. در صورت بروز هر یک از موارد زیر، پین سیمکارت حذف میشود:
- سیم کارت برداشته یا تنظیم مجدد شده است.
- کاربر پین را غیرفعال میکند.
- یک راهاندازی مجدد بدون RoR رخ داده است.
پین ذخیره شده سیم کارت فقط یک بار پس از راه اندازی مجدد با RoR و فقط برای مدت زمان بسیار کوتاهی (20 ثانیه) قابل استفاده است - در صورتی که جزئیات سیم کارت مطابقت داشته باشد. پین ذخیره شده سیم کارت هرگز از برنامه TelephonyManager خارج نمی شود و توسط ماژول های خارجی قابل بازیابی نیست.
دستورالعملهای اجرایی
در اندروید ۱۲، توابع RoR مبتنی بر چند کلاینت و سرور، هنگام ارسال بهروزرسانیهای OTA، بار کمتری را برای شرکا فراهم میکنند. بهروزرسانیهای لازم میتوانند در زمانهای خرابی دستگاه، مانند ساعات خواب تعیینشده، انجام شوند.
برای اطمینان از اینکه بهروزرسانیهای OTA در چنین بازههای زمانی باعث اختلال در کاربران نمیشوند، از حالت تاریک برای کاهش انتشار نور استفاده کنید. برای انجام این کار، از بوتلودر دستگاه بخواهید که دلیل رشتهای unattended را جستجو کند. اگر unattended true باشد، دستگاه را در حالت تاریک قرار دهید. توجه داشته باشید که کاهش انتشار صدا و نور وظیفه هر سازنده اصلی (OEM) است.
اگر در حال ارتقا به اندروید ۱۲ هستید یا دستگاههای اندروید ۱۲ را راهاندازی کردهاید، برای پیادهسازی قابلیت جدید RoR نیازی به انجام کاری ندارید.
یک فراخوانی جدید در جریان چند کلاینتی وجود دارد، isPreparedForUnattendedUpdate ، که در زیر نشان داده شده است:
@RequiresPermission(anyOf = {android.Manifest.permission.RECOVERY,
android.Manifest.permission.REBOOT})
public static boolean isPreparedForUnattendedUpdate(@NonNull Context context)
نیازی به پیادهسازی این مورد نیست، زیرا HAL از اندروید ۱۲ منسوخ شده است.
مدیر تلفن
کلاینت OTA در اندروید ۱۲، زمانی که راهاندازی مجدد قریبالوقوع باشد، API سیستم TelephonyManager را فراخوانی میکند. این API تمام کدهای پین ذخیرهشده در حافظه پنهان را از حالت AVAILABLE به حالت REBOOT_READY منتقل میکند. API سیستم TelephonyManager توسط مجوز REBOOT Manifest موجود محافظت میشود.
/**
* 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 سیستم TelephonyManager توسط APK های ممتاز استفاده میشود.
آزمایش
برای آزمایش API جدید، این دستور را اجرا کنید:
adb shell cmd phone unattended-reboot این دستور فقط زمانی کار میکند که پوسته (shell) با دسترسی root ( adb root ) اجرا شود.
فقط اندروید ۱۱
ادامه این صفحه مربوط به اندروید ۱۱ است.
از ژوئیه ۲۰۲۰، پیادهسازیهای RoR HAL در دو دسته قرار میگیرند:
- اگر سختافزار SoC از پایداری رم در طول راهاندازی مجدد پشتیبانی کند، تولیدکنندگان اصلی تجهیزات (OEM) میتوانند از پیادهسازی پیشفرض در AOSP ( Default RAM Escrow ) استفاده کنند.
- اگر سختافزار دستگاه یا SoC از یک محدوده سختافزاری امن (یک پردازنده کمکی امنیتی مجزا با RAM و ROM مخصوص به خود) پشتیبانی کند، علاوه بر این، باید موارد زیر را نیز انجام دهد:
- قادر به تشخیص راهاندازی مجدد پردازنده اصلی باشید.
- یک منبع تایمر سختافزاری داشته باشید که در طول راهاندازی مجدد همچنان پابرجا بماند. یعنی، enclave باید بتواند راهاندازی مجدد را تشخیص دهد و تایمر تنظیمشده قبل از راهاندازی مجدد را منقضی کند.
- پشتیبانی از ذخیره کلید سپردهگذاری شده در رم/رام enclave به گونهای که با حملات آفلاین قابل بازیابی نباشد. باید کلید RoR را به گونهای ذخیره کند که بازیابی آن برای افراد داخلی یا مهاجمان غیرممکن باشد.
سپرده پیشفرض رم
AOSP پیادهسازی RoR HAL را با استفاده از پایداری رم دارد. برای اینکه این قابلیت کار کند، تولیدکنندگان اصلی تجهیزات (OEM) باید اطمینان حاصل کنند که SoC های آنها از پایداری رم در طول راهاندازی مجدد پشتیبانی میکنند. برخی از SoC ها قادر به حفظ محتوای رم در طول راهاندازی مجدد نیستند، بنابراین به تولیدکنندگان اصلی تجهیزات توصیه میشود قبل از فعال کردن این HAL پیشفرض، با شرکای SoC خود مشورت کنند. مرجع اصلی برای این مورد در بخش زیر آمده است.
جریان بهروزرسانی OTA با استفاده از RoR
برنامه کلاینت OTA روی گوشی باید مجوزهای Manifest.permission.REBOOT و Manifest.permission.RECOVERY را داشته باشد تا بتواند متدهای لازم برای پیادهسازی RoR را فراخوانی کند. با در نظر گرفتن این پیشنیاز، روند بهروزرسانی از این مراحل پیروی میکند:
- برنامه کلاینت OTA بهروزرسانی را دانلود میکند.
- برنامه کلاینت OTA،
RecoverySystem#prepareForUnattendedUpdateرا فراخوانی میکند که باعث میشود کاربر در طول باز کردن قفل بعدی، پین، الگو یا رمز عبور خود را روی صفحه قفل وارد کند. - کاربر قفل دستگاه را از روی صفحه قفل باز میکند و دستگاه آماده اعمال بهروزرسانی است.
- برنامه کلاینت OTA،
RecoverySystem#rebootAndApplyرا فراخوانی میکند که بلافاصله باعث راهاندازی مجدد میشود.
در پایان این جریان، دستگاه مجدداً راهاندازی میشود و مکانیزم RoR حافظه رمزگذاریشدهی اعتبارنامه (CE) را باز میکند. برای برنامهها، این به عنوان باز کردن قفل کاربر عادی به نظر میرسد، بنابراین آنها تمام سیگنالهایی مانند ACTION_LOCKED_BOOT_COMPLETED و ACTION_BOOT_COMPLETED را که معمولاً دریافت میکنند، دریافت میکنند.
تغییر پیکربندیهای محصول
محصولی که به عنوان پشتیبانی کننده از ویژگی RoR در اندروید ۱۱ علامت گذاری شده است، باید شامل پیادهسازی RebootEscrow 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 در حالت راهاندازی مجدد با سپردن (escrow)
برای استفاده از پیادهسازی پیشفرض، باید ۶۵۵۳۶ (۰x۱۰۰۰۰) بایت رزرو کنید. هرگز این بایتها را در حافظه غیرفرار ننویسید تا از حفظ ویژگیهای امنیتی اطمینان حاصل شود.
تغییرات درخت دستگاه هسته لینوکس
در درخت دستگاه هسته لینوکس، شما باید برای یک ناحیه 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