ربط الإصدار

في الإصدار 1 من Keymaster، كانت جميع مفاتيح Keymaster مرتبطة تشفيريًا بجذر الثقة في الجهاز أو مفتاح Verified Boot. في Keymaster 2 و3، يتم أيضًا ربط كل المفاتيح بنظام التشغيل ومستوى التصحيح لصورة النظام. يضمن ذلك أنّ المهاجم الذي يكتشف ثغرة أمنية في إصدار قديم من نظام التشغيل أو برنامج TEE لا يمكنه إعادة الجهاز إلى الإصدار المعنيّ بالثغرة الأمنية واستخدام المفاتيح التي تم إنشاؤها باستخدام الإصدار الأحدث. بالإضافة إلى ذلك، عند استخدام مفتاح بإصدار ومستوى تصحيح معيّنين على جهاز تمت ترقيته إلى إصدار أحدث أو مستوى تصحيح أحدث، تتم ترقية المفتاح قبل أن يتم استخدامه، ويصبح الإصدار السابق من المفتاح غير صالح. بهذه الطريقة، عند ترقية الجهاز، يتم ترقية المفاتيح أيضًا، ولكن إذا تم إعادة الجهاز إلى إصدار سابق، لن تعود المفاتيح قابلة للاستخدام.

لدعم البنية المُركّبة لنظام Treble وإلغاء ربط نظام التشغيل system.img بالملف boot.img، غيّر Keymaster 4 نموذج ربط إصدار المفتاح ليكون هناك مستويات تصحيح منفصلة لكل قسم. يتيح ذلك تعديل كل قسم بشكل مستقل، مع الحفاظ على ميزة الحماية من العودة إلى الإصدارات السابقة.

في Android 9، يكون لكل من الأقسام boot وsystem وvendor مستوى تصحيح خاص به.

  • يمكن للأجهزة التي تتضمّن ميزة "التمهيد التحقق منه" في Android (AVB) وضع جميع مستويات التصحيح وإصدار النظام في vbmeta، حتى يتمكّن برنامج الإقلاع من إتاحتها لتطبيق Keymaster. بالنسبة إلى الأقسام المتسلسلة، تكون معلومات الإصدار الخاصة بالقسم في ملف vbmeta المتسلسل. بشكل عام، يجب أن تكون معلومات الإصدار في العنصر vbmeta struct الذي يحتوي على بيانات التحقّق (التجزئة أو شجرة التجزئة) لقسم معيّن.
  • على الأجهزة التي لا تتضمّن بروتوكول AVB:
    • يجب أن تقدّم عمليات تنفيذ ميزة "التمهيد التحقق منه" تجزئة للبيانات الوصفية للإصدار إلى أداة الإقلاع، حتى تتمكّن أداة الإقلاع من تقديم التجزئة إلى Keymaster.
    • يمكن أن يستمر boot.img في تخزين مستوى التصحيح في العنوان.
    • يمكن system.img مواصلة تخزين مستوى التصحيح وإصدار نظام التشغيل في المواقع التي يمكن فقط قراءتها
    • تخزِّن vendor.img مستوى التصحيح في السمة للقراءة فقط ro.vendor.build.version.security_patch.
    • يمكن أن يقدّم أداة تحميل التشغيل تجزئة لجميع البيانات التي تم التحقّق منها من خلال عملية التشغيل التي تم التحقّق منها إلى Keymaster.
  • في Android 9، استخدِم العلامات التالية لتقديم معلومات الإصدار للأقسام التالية:
    • VENDOR_PATCH_LEVEL: قسم vendor
    • BOOT_PATCH_LEVEL: قسم boot
    • OS_PATCH_LEVEL وOS_VERSION: قسم system (تمّت إزالة OS_VERSION من عنوان boot.img.
  • يجب أن تتعامل عمليات تنفيذ Keymaster مع جميع مستويات التصحيح بشكل مستقل. تكون المفاتيح قابلة للاستخدام إذا كانت جميع معلومات الإصدار تتطابق مع القيم المرتبطة بمفتاح، ويقوم IKeymaster::upgradeDevice() بالترقية إلى مستوى تصحيح أعلى إذا لزم الأمر.

تغييرات HAL

لدعم ربط الإصدار وإثبات ملكيته، أضاف نظام التشغيل Android 7.1 العلامات Tag::OS_VERSION وTag::OS_PATCHLEVEL وconfigure وupgradeKey. تتم إضافة علامات الإصدار تلقائيًا من خلال عمليات تنفيذ Keymaster 2 والإصدارات الأحدث إلى جميع المفاتيح التي تم إنشاؤها (أو تعديلها) حديثًا. بالإضافة إلى ذلك، يتم رفض أي محاولة لاستخدام مفتاح ليس لديه إصدار أو مستوى تصحيح لنظام التشغيل يتطابقان مع إصدار أو مستوى تصحيح نظام التشغيل الحاليين، على التوالي، باستخدام ErrorCode::KEY_REQUIRES_UPGRADE.

Tag::OS_VERSION هي قيمة UINT تمثّل الإصدار الرئيسي والثانوي والفرعي لإصدار نظام Android على النحو MMmmss، حيث يشير MM إلى الإصدار الرئيسي وmm إلى الإصدار الثانوي وss إلى الإصدار الفرعي. على سبيل المثال، سيتم تمثيل الإصدار 6.1.2 على النحو التالي: 060102.

Tag::OS_PATCHLEVEL هي قيمة UINT تمثّل السنة والشهر لآخر تحديث للنظام بالتنسيق YYYYMM، حيث يشير YYYY إلى السنة المكوّنة من أربعة أرقام وMM إلى الشهر المكوّن من رقمين. على سبيل المثال، سيتم تمثيل شهر آذار (مارس) 2016 بالتنسيق 201603.

UpgradeKey

للسماح بترقية المفاتيح إلى إصدار نظام التشغيل الجديد ومستوى تصحيح أخطاء ملف ‎.img للنظام، أضاف Android 7.1 طريقة upgradeKey إلى HAL:

Keymaster 3

    upgradeKey(vec keyBlobToUpgrade, vec upgradeParams)
        generates(ErrorCode error, vec upgradedKeyBlob);

Keymaster 2

keymaster_error_t (*upgrade_key)(const struct keymaster2_device* dev,
    const keymaster_key_blob_t* key_to_upgrade,
    const keymaster_key_param_set_t* upgrade_params,
    keymaster_key_blob_t* upgraded_key);
  • dev هي بنية الجهاز
  • keyBlobToUpgrade هو المفتاح الذي يجب ترقيته.
  • upgradeParams هي مَعلمات مطلوبة لترقية المفتاح. وتشمل هذه العناصر Tag::APPLICATION_ID و Tag::APPLICATION_DATA، وهما عنصران ضروريان لفك تشفير ملف رمز مفتاح التشفير، إذا تم تقديمهما أثناء الإنشاء.
  • upgradedKeyBlob هي مَعلمة الإخراج المستخدَمة لعرض وحدة تخزين مفتاح جديدة.

إذا تمّ استدعاء upgradeKey باستخدام ملفّ مضغوط للمفتاح لا يمكن تحليله أو كان غير صالح، يتمّ عرض ErrorCode::INVALID_KEY_BLOB. إذا كان يتم استدعاؤه باستخدام مفتاح يكون مستوى التصحيح فيه أكبر من قيمة النظام الحالية، يعرض القيمة ErrorCode::INVALID_ARGUMENT. إذا تمّت الدعوة باستخدام مفتاح يكون إصدار نظام التشغيل فيه أكبر من قيمة النظام الحالية، وقيمة النظام غير صفرية، يتم عرض ErrorCode::INVALID_ARGUMENT. يُسمح بترقية إصدار نظام التشغيل من قيمة غير صفرية إلى صفر. في حال حدوث أخطاء عند التواصل مع العالم الآمن، يتم عرض قيمة خطأ مناسبة (على سبيل المثال، ErrorCode::SECURE_HW_ACCESS_DENIED، ErrorCode::SECURE_HW_BUSY). بخلاف ذلك، يتم عرض ErrorCode::OK وعرض ملف نصي جديد للمفتاح في upgradedKeyBlob.

تظل keyBlobToUpgrade صالحة بعد upgradeKey إلغاء الترقية، ويمكن نظريًا استخدامها مرة أخرى في حال تم الرجوع إلى إصدار سابق من الجهاز. في الممارسة، يُطلِق ملف تخزين المفاتيح بشكل عام deleteKey على ملف keyBlobToUpgrade بعد وقت قصير من طلب upgradeKey. إذا كانت keyBlobToUpgrade تحتوي على العلامة Tag::ROLLBACK_RESISTANT، يجب أن تحتوي upgradedKeyBlob على العلامة أيضًا (ويجب أن تكون مقاومة للرجوع إلى الإصدار السابق).

الضبط الآمن

لتنفيذ عملية ربط الإصدار، يحتاج مشرف أمان مفتاح التشفير إلى طريقة لتلقّي إصدار نظام التشغيل الحالي ومستوى التصحيح (معلومات الإصدار) بشكل آمن، ولضمان أنّه تتطابق المعلومات التي يتلقّاها بشكل كبير مع المعلومات حول النظام الذي يعمل.

لتسهيل إرسال معلومات الإصدار بأمان إلى أداة تحليل الأداء، تمت إضافة OS_VERSIONحقل إلى عنوان صورة التمهيد. يُعبِّئ ملف برمجي لإنشاء صورة التمهيد هذا الحقل تلقائيًا. على المصنّعين الأصليّين للأجهزة ومقدّمي خدمات الأمان في مفتاح الالتقاط العمل معًا لتعديل برامج تشغيل الجهاز لاستخراج معلومات الإصدار من صورة التمهيد ونقلها إلى خدمات الأمان في مفتاح الالتقاط قبل التمهيد لنظام التشغيل غير الآمن. ويضمن ذلك عدم تمكّن المهاجمين من التدخل في عملية توفير معلومات الإصدار لوحدة التحكّم في حدود الجلسة.

من الضروري أيضًا التأكّد من أنّ صورة النظام تتضمّن معلومات الإصدار نفسها المتوفّرة في صورة التمهيد. ولهذا الغرض، تمت إضافة طريقة الضبط إلى HAL الخاص بـ Keymaster:

keymaster_error_t (*configure)(const struct keymaster2_device* dev,
  const keymaster_key_param_set_t* params);

تحتوي الوسيطة params على Tag::OS_VERSION و Tag::OS_PATCHLEVEL. يُطلِق عملاء Keymaster2 هذه الطريقة بعد فتح HAL، ولكن قبل استدعاء أي طرق أخرى. إذا تم استدعاء أي طريقة أخرى قبل configure، يعرض TA ErrorCode::KEYMASTER_NOT_CONFIGURED.

عند استدعاء configure لأول مرة بعد تشغيل الجهاز، يجب أن يتحقّق من أنّ معلومات الإصدار المقدَّمة مطابقة لما قدّمه مشغّل الإقلاع. وفي حال عدم تطابق معلومات الإصدار، يعرض configure القيمة ErrorCode::INVALID_ARGUMENT، وتستمر جميع الطرق الرئيسية الأخرى في عرض ErrorCode::KEYMASTER_NOT_CONFIGURED. إذا كانت المعلومات متطابقة، يعرض configureErrorCode::OK، وتبدأ طُرق configuremaster keymaster الأخرى في العمل بشكلٍ طبيعي.

تُعرِض المكالمات اللاحقة إلى configure القيمة نفسها التي عرضتها المكالمة الأولى، ولا تغيّر حالة Keymaster.

بما أنّ النظام الذي يتم التحقّق من صحة محتوياته هو الذي يستدعي configure، فإنّ هناك فرصة ضئيلة أمام المهاجم لاختراق صورة النظام وإجباره على تقديم معلومات الإصدار التي تطابق صورة التمهيد، ولكنّها ليست الإصدار الفعلي للنظام. إنّ المزيج بين التحقّق من صورة التمهيد والتحقّق من صحة dm-verity لمحتوى صورة النظام، وكون configure يتم استدعاؤه في مرحلة مبكرة جدًا من التمهيد، من المفترض أن يجعل من الصعب استغلال هذه الفرصة.