الإصدار ملزم

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

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

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

  • يمكن للأجهزة التي تحتوي على Android Verified Boot (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() إلى مستوى تصحيح أعلى إذا لزم الأمر.

تغييرات هال

لدعم ربط الإصدار ومصادقة الإصدار، أضاف 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:

سيد المفاتيح 3

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

مفتاح المفاتيح 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 blob بعد وقت قصير من استدعاء upgradeKey . إذا كان لدى keyBlobToUpgrade علامة Tag::ROLLBACK_RESISTANT ، فيجب أن تحتوي upgradedKeyBlob عليها أيضًا (ويجب أن تكون مقاومة للتراجع).

التكوين الآمن

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

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

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

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

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