في Keymaster 1، كانت جميع مفاتيح Keymaster مرتبطة بالتشفير بجذر الثقة أو بمفتاح "التحقّق من صحة التمهيد" على الجهاز. في الإصدارَين 2 و3 من Keymaster، تكون جميع المفاتيح مرتبطة أيضًا بنظام التشغيل ومستوى تصحيح صورة النظام. ويضمن ذلك ألا يتمكّن المهاجم الذي يكتشف ثغرة أمنية في إصدار قديم من نظام التشغيل أو برنامج TEE من إعادة الجهاز إلى الإصدار المعرَّض للخطر واستخدام المفاتيح التي تم إنشاؤها باستخدام الإصدار الأحدث. بالإضافة إلى ذلك، عند استخدام مفتاح بإصدار ومستوى تصحيح محدّدين على جهاز تمت ترقيته إلى إصدار أو مستوى تصحيح أحدث، تتم ترقية المفتاح قبل استخدامه، ويتم إبطال الإصدار السابق من المفتاح. وبهذه الطريقة، عند ترقية الجهاز، يتم نقل المفاتيح إلى الإصدار الأحدث مع الجهاز، ولكن عند إعادة الجهاز إلى إصدار سابق، تصبح المفاتيح غير قابلة للاستخدام.
لإتاحة بنية Treble النمطية وإلغاء ربط system.img بـ boot.img، غيّر Keymaster 4 نموذج ربط إصدار المفتاح ليتضمّن مستويات تصحيح منفصلة لكل قسم. ويتيح ذلك تحديث كل قسم بشكل مستقل مع توفير الحماية من العودة إلى الإصدارات السابقة.
لتنفيذ ربط الإصدار هذا، يحتاج تطبيق KeyMint الموثوق (TA) إلى طريقة آمنة لتلقّي إصدار نظام التشغيل الحالي ومستويات التصحيح، ولضمان تطابق المعلومات التي يتلقّاها مع جميع المعلومات المتعلّقة بالنظام قيد التشغيل.
- يمكن للأجهزة التي تتضمّن ميزة "التشغيل المتحقّق منه من خلال 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
للسماح بترقية المفاتيح إلى إصدار نظام التشغيل ومستوى التصحيح الجديدين لصورة النظام، أضاف 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
، ويمكن نظريًا استخدامه مرة أخرى في حال تم الرجوع إلى إصدار أقدم من الجهاز. في
التطبيق العملي، يستدعي keystore عادةً deleteKey
على
كائن keyBlobToUpgrade
الثنائي الكبير بعد وقت قصير من استدعاء
upgradeKey
. إذا كان keyBlobToUpgrade
يتضمّن العلامة Tag::ROLLBACK_RESISTANT
، يجب أن يتضمّنها upgradedKeyBlob
أيضًا (ويجب أن يكون مقاومًا لعمليات الرجوع إلى الإصدار السابق).
الضبط الآمن
لتنفيذ ربط الإصدار، يجب أن يتوفّر لدى Keymaster TA طريقة لتلقّي إصدار نظام التشغيل ومستوى تصحيحه الحاليين (معلومات الإصدار) بشكل آمن، ولضمان تطابق المعلومات التي يتلقّاها بشكل كبير مع المعلومات المتعلّقة بالنظام قيد التشغيل.
لإتاحة إرسال معلومات الإصدار بشكل آمن إلى TA، تمت إضافة OS_VERSION
حقل إلى عنوان صورة التشغيل. يملأ نص برمجة إنشاء صورة التشغيل هذا الحقل تلقائيًا. على مصنّعي المعدات الأصلية ومطوّري Keymaster 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 التي تعمل بإصدار أقدم من 0x0A
بعد فتح طبقة HAL، ولكن قبل استدعاء أي طرق أخرى. إذا تم استدعاء أي طريقة أخرى قبل configure، ستعرض البيئة الموثوقة ErrorCode::KEYMASTER_NOT_CONFIGURED
.
عند استدعاء configure
للمرة الأولى بعد تشغيل الجهاز، يجب التحقّق من أنّ معلومات الإصدار المقدَّمة تتطابق مع المعلومات التي قدّمها برنامج التشغيل. إذا لم تتطابق معلومات الإصدار، ستعرض الدالة configure
القيمة ErrorCode::INVALID_ARGUMENT
، وستواصل جميع دوال Keymaster الأخرى عرض القيمة ErrorCode::KEYMASTER_NOT_CONFIGURED
. إذا كانت المعلومات متطابقة،
ستعرض configure
القيمة ErrorCode::OK
، وستبدأ طرق Keymaster الأخرى في العمل بشكل طبيعي.
تعرض عمليات الاستدعاء اللاحقة للدالة configure
القيمة نفسها التي عرضتها عملية الاستدعاء الأولى، ولا تغيّر حالة Keymaster.
بما أنّ النظام هو الذي يستدعي configure
، وهو الذي من المفترض أن يتحقّق من صحة محتواه، فإنّ هناك فرصة ضئيلة للمهاجمين لاختراق صورة النظام وإجبارها على تقديم معلومات الإصدار التي تتطابق مع صورة التشغيل، ولكنّها ليست الإصدار الفعلي للنظام. إنّ الجمع بين التحقّق من صحة صورة التشغيل والتحقّق من صحة محتويات صورة النظام باستخدام dm-verity وحقيقة أنّ configure
يتم استدعاؤه في وقت مبكر جدًا من عملية تشغيل النظام يجب أن يجعل استغلال هذه الثغرة أمرًا صعبًا.