يتوافق الإصدار 4.4 من Android والإصدارات الأحدث مع ميزة "التمهيد المتحقّق منه" من خلال ميزة "جهاز التعيين-التحقّق من الصحة" (dm-verity) الاختيارية في نواة النظام، والتي توفّر فحصًا شفافًا لسلامة الأجهزة التي تتضمّن وحدات تخزين. تساعد ميزة dm-verity في منع أدوات الاختراق الثابتة التي يمكنها الاحتفاظ بامتيازات الجذر والاعتداء على الأجهزة. تساعد هذه الميزة مستخدمي Android في التأكّد من أنّ الجهاز في الحالة نفسها عند تشغيله كما كان عليه في آخر مرة تم استخدامه فيها.
يمكن للتطبيقات التي قد تتسبّب بضرر (PHA) التي تمتلك امتيازات الجذر إخفاء نفسها عن برامج الكشف أو إخفاء هويتها بأي طريقة أخرى. يمكن لبرنامج الوصول إلى الجذر تنفيذ هذا الإجراء لأنّه غالبًا ما يكون لديه امتيازات أكثر من برامج رصد عمليات الوصول إلى الجذر، ما يتيح لبرنامج الوصول إلى الجذر "الكذب" على برامج رصد عمليات الوصول إلى الجذر.
تتيح لك ميزة dm-verity الاطّلاع على جهاز تخزين بالكتل، وهو طبقة التخزين الأساسية لنظام الملفات، وتحديد ما إذا كان يتطابق مع الإعدادات المتوقّعة. ويتم ذلك باستخدام شجرة تجزئة التشفير. لكلّ كتلة (عادةً 4 كيلوبايت)، تتوفّر تجزئة SHA256.
بما أنّ قيم التجزئة يتم تخزينها في شجرة من الصفحات، يجب الوثوق فقط بقيمة التجزئة "الرئيسية" في المستوى الأعلى للتحقّق من بقية الشجرة. إنّ إمكانية تعديل أيّ من الكتل تؤدي إلى كسر التجزئة المشفّرة. اطّلِع على الرسم البياني التالي للاطّلاع على وصف لهذه البنية.

الشكل 1: جدول تجزئة dm-verity
يتم تضمين مفتاح عام في قسم التمهيد، ويجب أن يُثبت صحة المفتاح خارجيًا من قِبل الشركة المصنّعة للجهاز. يُستخدَم هذا المفتاح للتحقّق من صحة التوقيع على قيمة التجزئة هذه والتأكّد من حماية قسم النظام في الجهاز وعدم تغييره.
العملية
تتوفر ميزة الحماية dm-verity في النواة. وبالتالي، إذا اخترق برنامج الحصول على إذن الوصول إلى الجذر النظام قبل ظهور النواة، سيحتفظ هذا البرنامج بإذن الوصول. للحدّ من هذا الخطر، تتحقّق معظم الشركات المصنّعة من النواة باستخدام مفتاح محفوظ في الجهاز. لا يمكن تغيير هذا المفتاح بعد خروج الجهاز من المصنع.
يستخدم المصنّعون هذا المفتاح للتحقّق من التوقيع في أداة التمهيد المستوى الأول، والتي تتحقّق بدورها من التوقيع في المستويات اللاحقة، أداة التمهيد للتطبيقات وفي النهاية في النواة. على كلّ مصنع يريد الاستفادة من ميزة التشغيل المتحقَّق منه أن يتوفّر لديه طريقة للتحقّق من سلامة النواة. بافتراض أنّه تم التحقّق من سلامته، يمكن للنواة الاطّلاع على جهاز تخزين ملف برمجي والتحقّق منه أثناء تركيبه.
تتمثل إحدى طرق التحقّق من جهاز تخزين الكتل في تجزئة محتوياته مباشرةً ومقارنتها بقيمة مخزّنة. ومع ذلك، يمكن أن تؤدي محاولة التحقّق من جهاز تخزين بلوكات بالكامل إلى استغراق فترة طويلة واستهلاك الكثير من طاقة الجهاز. ستستغرق الأجهزة فترات طويلة لبدء التشغيل، ثم يتم استنزاف طاقتها بشكل كبير قبل استخدامها.
بدلاً من ذلك، تتحقّق أداة dm-verity من الكتل بشكلٍ فردي وعند الوصول إلى كل كتلة فقط. عند القراءة في الذاكرة، يتم تجزئة الكتلة بشكل موازٍ. تتم بعد ذلك صحة التجزئة في أعلى الشجرة. وبما أنّ قراءة الكتلة عملية تتعلّق بتكلفة عالية، فإنّ وقت الاستجابة الذي ينتج عن عملية التحقّق هذه على مستوى الكتلة هو رمزي مقارنةً بغيرها.
إذا تعذّر إثبات الملكية، يُنشئ الجهاز خطأ I/O يشير إلى أنّه لا يمكن قراءة الكتلة. يبدو أنّ نظام الملفات قد تلف، كما هو متوقّع.
قد تختار التطبيقات المتابعة بدون البيانات الناتجة، مثلاً عندما لا تكون هذه النتائج مطلوبة لوظيفة التطبيق الأساسية. ومع ذلك، إذا تعذّر على التطبيق المتابعة بدون البيانات، سيتعطّل.
تصحيح الأخطاء التلقائي
يعمل الإصدار 7.0 من نظام التشغيل Android والإصدارات الأحدث على تحسين ثبات dm-verity من خلال تصحيح الخطأ المتعلّق بالمستقبل (FEC). يبدأ تنفيذ AOSP باستخدام رمز تصحيح الأخطاء الشائع Reed-Solomon ويطبّق تقنية تدعى التداخل لتقليل مساحة التخزين الإضافية وزيادة عدد الكتل التالفة التي يمكن استردادها. لمزيد من التفاصيل حول تصحيح الأخطاء، يُرجى الاطّلاع على مقالة التشغيل المتحقّق منه بشكل صارم مع تصحيح الأخطاء.التنفيذ
ملخّص
- أنشئ صورة نظام ext4.
- أنشئ شجرة تجزئة لهذه الصورة.
- أنشئ جدول dm-verity لشجرة التجزئة هذه.
- وقِّع على جدول dm-verity لإنشاء توقيع الجدول.
- حِزم توقيع الجدول وجدول dm-verity في البيانات الوصفية لنظام verity
- اربط صورة النظام والبيانات الوصفية لنظام التحقّق وشجرة التجزئة.
اطّلِع على مشاريع Chromium - التشغيل المُتحقّق منه لحصول على وصف تفصيلي لشجرة التجزئة وجدول dm-verity.
إنشاء شجرة التجزئة
كما هو موضّح في المقدّمة، شجرة التجزئة هي جزء لا يتجزأ من dm-verity. تنشئ أداة cryptsetup شجرة تجزئة لك. بدلاً من ذلك، يمكنك تحديد جهاز متوافق هنا:
<your block device name> <your block device name> <block size> <block size> <image size in blocks> <image size in blocks + 8> <root hash> <salt>
لإنشاء التجزئة، يتم تقسيم صورة النظام في الطبقة 0 إلى وحدات 4 كيلوبايت، ويتم تعيين تجزئة SHA256 لكل منها. يتم إنشاء الطبقة 1 من خلال دمج تجزئات SHA256 هذه فقط في وحدات بدقة 4K، ما يؤدي إلى الحصول على صورة أصغر بكثير. يتم تشكيل الطبقة 2 بالطريقة نفسها، باستخدام تجزئات SHA256 للطبقة 1.
ويتم ذلك إلى أن تصبح تجزئات SHA256 للطبقة السابقة قابلة للاحتواء في ملف واحد. عند الحصول على تجزئة SHA256 لهذه الكتلة، ستحصل على تجزئة الجذر للشجرة.
يختلف حجم شجرة التجزئة (واستخدام مساحة القرص المقابل) تبعًا لحجم القسم الذي تم التحقّق منه. من الناحية العملية، يكون حجم أشجار التجزئة عادةً صغيرًا، وغالبًا ما يكون أقل من 30 ميغابايت.
إذا كان لديك كتلة في طبقة لم يتم ملؤها بالكامل بشكل طبيعي من خلال التجزئات للطبقة السابقة، عليك تعبئتها بالأصفار لتحقيق الدقة المتوقّعة التي تبلغ 4K. يتيح لك ذلك معرفة أنّه لم تتم إزالة شجرة التجزئة، ولكن تم إكمالها بدلاً من ذلك ببيانات فارغة.
لإنشاء شجرة التجزئة، يمكنك تسلسل تجزئات الطبقة 2 مع تجزئات الطبقة 1، وتجزئات الطبقة 3 مع تجزئات الطبقة 2، وهكذا. اكتب كل ذلك على القرص. تجدر الإشارة إلى أنّ هذا لا يشير إلى الطبقة 0 من التجزئة الجذرية.
للتلخيص، في ما يلي الخوارزمية العامة لإنشاء شجرة التجزئة:
- اختَر مكوّن تشويش عشوائيًا (ترميز سداسي عشري).
- أزِل تشويش صورة النظام إلى وحدات 4K.
- احصل على تجزئة SHA256 (المعدّلة) لكل كتلة.
- ادمج هذه التجزئات لإنشاء مستوى.
- أضِف أصفارًا إلى المستوى حتى تصل إلى حدود 4K.
- اربط المستوى بشجرة التجزئة.
- كرِّر الخطوات من 2 إلى 6 باستخدام المستوى السابق كمصدر للمستوى التالي إلى أن تتوفّر لديك سلسلة تتبُّع واحدة فقط.
والنتيجة هي تجزئة واحدة، وهي تجزئة الجذر. ويتم استخدام هذا المفتاح وملف التمويه أثناء إنشاء جدول الربط في dm-verity.
إنشاء جدول الربط dm-verity
أنشئ جدول الربط dm-verity الذي يحدِّد جهاز الكتلة (أو الهدف)
للنواة وموقع شجرة التجزئة (وهي القيمة نفسها). يُستخدَم هذا
التعيين لإنشاء fstab
وبدء تشغيله. يحدِّد الجدول أيضًا
حجم الكتل وhash_start، وهو موقع بدء شجرة التجزئة
(على وجه التحديد، رقم الكتلة من بداية الصورة).
راجِع cryptsetup للحصول على وصف detailed لجدول ربط أهداف verity.
توقيع جدول dm-verity
وقِّع على جدول dm-verity لإنشاء توقيع جدول. عند التحقّق من ملف مشاركة ، يتم أولاً التحقّق من توقيع الجدول. ويتم ذلك باستخدام مفتاح في صورة التمهيد في موقع ثابت. يتم عادةً تضمين المفاتيح في أنظمة الإنشاء لدى المصنّعين لتضمينها تلقائيًا على الأجهزة في موقع ثابت.
للتحقّق من القسم باستخدام هذا التوقيع ومجموعة المفاتيح:
- أضِف مفتاح RSA-2048 بتنسيق متوافق مع libmincrypt إلى
قسم
/boot
في/verity_key
. حدِّد موقع المفتاح المستخدَم للتحقّق من شجرة التجزئة. - في ملف fstab للملفّ المعنيّ، أضِف
verify
إلى علاماتfs_mgr
.
تجميع توقيع الجدول في البيانات الوصفية
حِزم توقيع الجدول وجدول dm-verity في البيانات الوصفية لنظام verity يتم إنشاء إصدارات من كل ملف من ملفات البيانات الوصفية كي يمكن تمديدها، مثلاً لإضافة نوع توقيع ثاني أو تغيير بعض الترتيبات.
للتحقّق من صحة البيانات، يتم ربط رقم سحري بكل مجموعة من البيانات الوصفية للجدول يساعد في تحديد الجدول. وبما أنّ الطول مضمّن في عنوان صورة نظام ext4، يوفر ذلك طريقة للبحث عن البيانات الوصفية بدون معرفة محتوى البيانات نفسها.
يضمن ذلك عدم اختيارك التحقّق من قسم لم يتم إثبات ملكيته. إذا كان الأمر كذلك، يؤدي عدم توفّر هذا الرقم السحرية إلى إيقاف عملية إثبات الملكية. يشبه هذا الرقم
0xb001b001
.
قيم البايت في النظام الست عشري هي:
- أول بايت = b0
- البايت الثاني = 01
- البايت الثالث = b0
- البايت الرابع = 01
يوضّح الرسم البياني التالي تفاصيل بيانات التعريف الخاصة بميزة "التحقّق من صحة المحتوى":
<magic number>|<version>|<signature>|<table length>|<table>|<padding> \-------------------------------------------------------------------/ \----------------------------------------------------------/ | | | | 32K block content
ويوضّح هذا الجدول حقول البيانات الوصفية هذه.
الجدول 1: التحقّق من حقول البيانات الوصفية
الحقل | الغرض | الحجم | القيمة |
---|---|---|---|
الرقم السّحري | يستخدمه fs_mgr كإجراء للتحقّق من الصحة | 4 بايت | 0xb001b001 |
إصدار | تُستخدَم لتحديد إصدار مجموعة البيانات الوصفية. | 4 بايت | حاليًا 0 |
التوقيع | توقيع الجدول بتنسيق PKCS1.5 المُضاف إليه بيانات زائدة | 256 بايت | |
طول الجدول | طول جدول dm-verity بالبايت | 4 بايت | |
مائدة | جدول dm-verity الموضّح سابقًا | عدد وحدات البايت لطول الجدول | |
padding | يتمّ تعبئة هذه البنية بـ 0 ليصبح طولها 32 ألفًا. | 0 |
تحسين dm-verity
للحصول على أفضل أداء من dm-verity، عليك إجراء ما يلي:
- في النواة، فعِّل NEON SHA-2 لمعالج ARMv7 وSHA-2 إضافات لمعالج ARMv8.
- جرِّب إعدادات مختلفة لميزة "القراءة مسبقًا" وprefetch_cluster للعثور على أفضل إعدادات لجهازك.