الإصدار ملزم

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

لدعم بنية Treble المعيارية وكسر ارتباط system.img بـ boot.img ، قام Keymaster 4 بتغيير نموذج ربط الإصدار الرئيسي ليكون له مستويات تصحيح منفصلة لكل قسم. يسمح هذا بتحديث كل قسم بشكل مستقل ، مع الاستمرار في توفير الحماية من التراجع.

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

  • يمكن للأجهزة التي تعمل بنظام Android Verified Boot (AVB) وضع جميع مستويات التصحيح وإصدار النظام في vbmeta ، لذلك يمكن أن يوفرها برنامج bootloader لـ Keymaster. بالنسبة للأقسام المقيدة ، ستكون معلومات الإصدار للقسم في vbmeta المتسلسل. بشكل عام ، يجب أن تكون معلومات الإصدار في vbmeta struct التي تحتوي على بيانات التحقق (التجزئة أو التجزئة) لقسم معين.
  • على الأجهزة التي لا تحتوي على AVB:
    • تحتاج تطبيقات التمهيد الذي تم التحقق منه إلى توفير تجزئة للبيانات الوصفية للإصدار إلى أداة تحميل التشغيل ، بحيث يمكن لمحمل الإقلاع توفير التجزئة لـ Keymaster.
    • يمكن boot.img متابعة تخزين مستوى التصحيح في الرأس
    • يمكن system.img الاستمرار في تخزين مستوى التصحيح وإصدار نظام التشغيل في خصائص للقراءة فقط
    • يخزن vendor.img مستوى التصحيح في خاصية القراءة فقط ro.vendor.build.version.security_patch .
    • يمكن أن يوفر برنامج bootloader تجزئة لجميع البيانات التي تم التحقق من صحتها بواسطة التمهيد المتحقق منه إلى المسؤول الرئيسي.
  • في 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.

مفتاح الترقية

للسماح بترقية المفاتيح إلى إصدار نظام التشغيل الجديد ومستوى التصحيح لصورة النظام ، أضاف 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 هي معلمة الإخراج ، تُستخدم لإرجاع blob الرئيسي الجديد.

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

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

تكوين آمن

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

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

من الضروري أيضًا التأكد من أن صورة النظام لها نفس معلومات الإصدار مثل صورة التمهيد. تحقيقا لهذه الغاية ، تمت إضافة طريقة التكوين إلى keymaster HAL:

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 ، ولكن قبل استدعاء أي طرق أخرى. إذا تم استدعاء أي طريقة أخرى قبل التكوين ، فإن TA ترجع ErrorCode::KEYMASTER_NOT_CONFIGURED .

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

تُرجع الاستدعاءات اللاحقة configure نفس القيمة التي تم إرجاعها بواسطة الاستدعاء الأول ، ولا تغير حالة keymaster. لاحظ أن هذه العملية سوف تتطلب أن تقوم جميع OTAs بتحديث كل من صور النظام والتمهيد ؛ لا يمكن تحديثها بشكل منفصل من أجل الحفاظ على مزامنة معلومات الإصدار.

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