مثل معظم برامج تشفير الأقراص والملفات، يعتمد ميزة "تشفير مساحة التخزين" في Android بشكلٍ أساسي على توفُّر مفاتيح التشفير الأولية في ذاكرة النظام كي يتمكّن الجهاز من إجراء التشفير. حتى في حال التشفير باستخدام أجهزة مخصصة بدلاً من برامج، تظل البرامج بشكل عام بحاجة إلى وإدارة مفاتيح التشفير الأولية.
لا يُعتبَر ذلك عادةً مشكلة لأنّ المفاتيح لن تكون متوفّرة أثناء هجوم بلا إنترنت، وهو النوع الرئيسي من الهجمات التي يهدف تشفير التخزين إلى حمايتك منها. ومع ذلك، هناك رغبة في تقديم زيادة الحماية ضد أنواع الهجمات الأخرى، مثل التشغيل على البارد والهجمات على الإنترنت والهجمات على الإنترنت التي قد يتمكن فيها المهاجم من تسريب النظام بدون تعريض الجهاز للخطر بشكل كامل.
لحلّ هذه المشكلة، وفّر نظام التشغيل Android 11 مفتاح تشفير مُدمج في الجهاز، وذلك في الأجهزة التي تتوفّر فيها هذه الميزة. المفاتيح المغلفة بالأجهزة هي مفاتيح تخزين لا تُعرف إلا بشكلها الأولي أجهزة مخصصة لا يرى البرنامج هذه المفاتيح ويعمل معها إلا ملفات تعريف الارتباط (المشفر). يجب أن يكون هذا الجهاز قادرًا على إنشاء واستيراد ومفاتيح التخزين والتفاف مفاتيح التخزين في أشكال مؤقتة وطويلة الأجل واشتقاق وبرمجة مفتاح فرعي واحد مباشرةً في محرك تشفير مضمَّن إرجاع مفتاح فرعي منفصل إلى البرنامج.
ملاحظة: يكون هناك محرك تشفير مضمّن (أو مضمّن). أجهزة التشفير) إلى أجهزة تعمل على تشفير/فك تشفير البيانات أثناء هو في طريقه إلى/من جهاز التخزين. عادةً ما يكون مضيف UFS أو eMMC وحدة تحكّم تنفّذ إضافات العملات المشفّرة المحدّدة من خلال مواصفات JEDEC.
التصميم
يعرض هذا القسم تصميم ميزة المفاتيح المغلفة، بما في ذلك وما هو دعم الأجهزة المطلوب لذلك. تركّز هذه المناقشة على التشفير على مستوى الملفات (FBE)، ولكن ينطبق الحلّ أيضًا على تشفير البيانات الوصفية.
إحدى الطرق لتجنُّب الحاجة إلى مفاتيح التشفير الأوّلية في ذاكرة النظام هي الاحتفاظ بها فقط في خانات المفاتيح الخاصة بمحرك التشفير المضمّن. ومع ذلك، بعض المشكلات وهي:
- قد يتجاوز عدد مفاتيح التشفير عدد خانات المفاتيح.
- لا يمكن استخدام محرّكات التشفير المضمّنة إلا لتشفير/فك تشفير مجموعات كاملة من البيانات على القرص. ومع ذلك، في حال استخدام ميزة "التشفير من جهة العميل"، يجب أن يظل بإمكان البرنامج تنفيذ عمليات تشفير أخرى، مثل تشفير أسماء الملفات واستخراج معرّفات مفاتيح التشفير. سيظلّ على البرنامج الوصول إلى مفاتيح FBE الأوّلية لكي تتمكّن من تنفيذ هذه المهام الأخرى.
لتجنُّب هذه المشاكل، يتم تحويل مفاتيح التخزين بدلاً من ذلك إلى مفاتيح مُغلفة بالأجهزة، ولا يمكن إزالة الغلاف واستخدامها إلا باستخدام أجهزة مخصّصة. ويتيح ذلك إمكانية استخدام عدد غير محدود من المفاتيح. بالإضافة إلى ذلك، يتم تعديل التسلسل الهرمي للمفتاح ونقله جزئيًا إلى هذا الجهاز، مما يسمح بإرجاع مفتاح فرعي إلى البرنامج للمهام التي لا يمكنها استخدام محرك تشفير مضمّن.
التدرّج الهرمي للمفاتيح
يمكن اشتقاق المفاتيح من مفاتيح أخرى باستخدام دالة اشتقاق المفاتيح (KDF)، مثل HKDF، مما يؤدي إلى إنشاء تسلسل هرمي للمفاتيح.
يصور الرسم التخطيطي التالي تسلسلاً هرميًا نموذجيًا لـ FBE عندما لا يتم استخدام المفاتيح المغلفة على أجهزة الكمبيوتر:
مفتاح فئة FBE هو مفتاح التشفير الأولي الذي يمرره Android إلى نظام التشغيل Linux لفتح قفل مجموعة معينة من الأدلة المشفرة، مثل التخزين المشفّر باستخدام بيانات الاعتماد لمستخدم Android معيّن. (في النواة، هذه مفتاح fscrypt الرئيسي). تستخرج النواة من هذا المفتاح المفاتيح الفرعية التالية:
- معرّف المفتاح لا يتم استخدام هذه القيمة للتشفير، وإنما هي قيمة يُستخدم لتحديد المفتاح الذي يتم استخدامه لتحديد ملف أو دليل معين محمي.
- مفتاح تشفير محتوى الملف
- مفتاح تشفير أسماء الملفات
في المقابل، يوضِّح المخطّط التالي التسلسل الهرمي للمفاتيح في ميزة "التشفير من جهة العميل" عند استخدام مفاتيح مُغلفة بالأجهزة:
مقارنةً بالحالة السابقة، تمت إضافة مستوى إضافي إلى التسلسل الهرمي للمفتاح ، وتم نقل مفتاح تشفير محتوى الملف. الجذر لا تزال العقدة تمثل المفتاح الذي يمرره Android إلى Linux لإلغاء قفل مجموعة من الأدلة المشفرة. ومع ذلك، أصبح هذا المفتاح الآن في شكل ملف مؤقت، ويجب تمريره إلى جهاز مخصّص لاستخدامه. يجب أن ينفذ هذا الجهاز واجهتَين تأخذان مفتاحًا ملفوفًا بشكل مؤقت:
- واجهة واحدة لاستخراج
inline_encryption_key
وبرمجته مباشرةً في خانة مفتاح من محرّك التشفير المضمّن يتيح ذلك تشفير/فك تشفير محتويات الملف بدون أن يتمكّن البرنامج من الوصول إلى مفتاح التشفير العميق. في نواة Android الشائعة، تتوافق هذه الواجهة مع عمليةblk_crypto_ll_ops::keyslot_program
التي يجب أن ينفّذها برنامج تشغيل مساحة التخزين. - واجهة واحدة لاستخراج
sw_secret
(يُشار إليه أيضًا باسم "مفتاح البرنامج" أو "المفتاح الأساسي" في بعض الأماكن) وإعادته، وهو المفتاح الذي يستخدمه نظام التشغيل Linux لاستخراج المفاتيح الفرعية لكل ما عدا تشفير محتويات الملفات في نواة Android الشائعة، تتوافق هذه الواجهة مع عمليةblk_crypto_ll_ops::derive_sw_secret
التي يجب أن ينفذها برنامج تشغيل مساحة التخزين.
لاشتقاق inline_encryption_key
وsw_secret
من
مفتاح تخزين أولي، يجب على الجهاز استخدام KDF قوي التشفير. ملف KDF هذا
أن يتّبع أفضل ممارسات التشفير يجب أن تكون قوة الأمان في
256 بت على الأقل، وهذا يكفي لأي خوارزمية يتم استخدامها لاحقًا. يجب أيضًا استخدام
تصنيف وسياق وسلسلة معلومات خاصة بالتطبيق عند
لاستنباط كل نوع من المفاتيح الفرعية لضمان أن المفاتيح الفرعية الناتجة
معزولة بطريقة تشفير، أي أن معرفة إحداها لا تكشف عن أي منها
آخر. ولا يلزم تمديد المفتاح، لأنّ مفتاح التخزين الأوّلي هو مفتاح
عشوائي بشكلٍ موحّد.
من الناحية الفنية، يمكن استخدام أي KDF يستوفي متطلبات الأمان.
ومع ذلك، لأغراض الاختبار، من الضروري إعادة تنفيذ دالة KDF نفسها في
رمز الاختبار. تمّت حاليًا مراجعة دالة KDF واحدة وتنفيذها، ويمكن العثور عليها
في رمز المصدر لـ vts_kernel_encryption_test
.
ننصح باستخدام جهاز KDF هذا الذي يستخدم NIST SP 800-108 "KDF في وضع العدّاد" مع AES-256-CMAC بصفته PRF. لاحظ أنه لكي تكون متوافقة، يجب
أن تكون أجزاء الخوارزمية متطابقة، بما في ذلك اختيار سياقات KDF
والتسميات لكل مفتاح فرعي.
لف المفتاح
هناك نوعان من التفاف المفاتيح، وذلك لتحقيق الأهداف الأمنية للمفاتيح المغلفة بالأجهزة. محددة:
- الالتفاف المؤقت: يشفِّر الجهاز المفتاح الأولي باستخدام مفتاح. يتم إنشاؤه عشوائيًا عند كل تشغيل ولا يتم الكشف عنه بشكل مباشر خارج الجهاز.
- التفاف المفتاح على المدى الطويل: يشفِّر الجهاز المفتاح الأوّلي باستخدام مفتاح فريد ودائم مضمّن في الجهاز ولا يتم الكشف عنه مباشرةً خارج الجهاز.
يتم ملفّفة جميع المفاتيح التي يتم تمريرها إلى نواة Linux لفتح قفل مساحة التخزين بشكل مؤقت. يضمن ذلك أنّه إذا تمكّن المهاجم من استخراج مفتاح قيد الاستخدام من ذاكرة النظام، لن يكون هذا المفتاح قابلاً للاستخدام خارج الجهاز فحسب، بل على الجهاز أيضًا بعد إعادة تشغيله.
في الوقت نفسه، لا يزال Android بحاجة إلى أن يتمكّن من تخزين نسخة مشفّرة. المفاتيح الموجودة على القرص حتى يمكن إلغاء قفلها في المقام الأول. البيانات الأولية ستعمل المفاتيح لهذا الغرض. ومع ذلك، يُفضّل عدم استخدام البيانات الأوّلية أن تكون المفاتيح موجودة في ذاكرة النظام إطلاقًا، وبالتالي لا يمكن استخراجها سيتم استخدامه خارج الجهاز، حتى إذا تم استخراجه في وقت التشغيل. لهذا السبب، تم تصميم مفهوم الالتفاف على المدى الطويل.
ولتتمكّن من إدارة المفاتيح المُغلفة بهذه الطريقتَين مختلفتَين، يجب أن ينفذ الجهاز الواجهات التالية:
- واجهات لإنشاء مفاتيح التخزين واستيرادها، وإعادتها في شكل ملف مُغلف
على المدى الطويل يتم الوصول إلى هذه الواجهات بشكلٍ غير مباشر من خلال
KeyMint، وتتوافق مع علامة KeyMint
TAG_STORAGE_KEY
. يستخدمvold
إمكانية "الإنشاء" لإنشاء مفاتيح تخزين جديدة لاستخدامها في Android، بينما يستخدمvts_kernel_encryption_test
إمكانية "الاستيراد" لاستيراد مفاتيح اختبارية. - واجهة لتحويل مفتاح تخزين ملف مُغلف على المدى الطويل إلى
مفتاح تخزين ملف مُغلف بشكل مؤقت يتجاوب هذا مع
convertStorageKeyToEphemeral
طريقة KeyMint. وتستخدم كل منvold
وvts_kernel_encryption_test
هذه الطريقة لفتح مساحة التخزين.
تُعدّ خوارزمية لفّ المفاتيح من تفاصيل التنفيذ، ولكن يجب أن تستخدِم خوارزمية AEAD قوية مثل AES-256-GCM مع أرقام البدء العشوائية.
يجب إجراء تغييرات على البرامج
يحتوي AOSP على إطار عمل أساسي لدعم المفاتيح المغلفة بالأجهزة. هذا النمط
الدعم في مكونات مساحة المستخدم، مثل vold
، بالإضافة إلى
دعم نواة Linux في blk-crypto وfscrypt
مفتاح dm-default.
ومع ذلك، يجب إجراء بعض التغييرات الخاصة بعملية التنفيذ.
تغييرات KeyMint
يجب تعديل عملية تنفيذ KeyMint للجهاز للتوافق
TAG_STORAGE_KEY
وتنفيذ
طريقة convertStorageKeyToEphemeral
.
في Keymaster، تم استخدام exportKey
بدلاً من
convertStorageKeyToEphemeral
تغييرات نواة Linux
يجب تعديل برنامج تشغيل نواة Linux لمحرك التشفير المضمّن في الجهاز. لإتاحة استخدام المفاتيح المغلفة بالأجهزة.
بالنسبة إلى نواة android14
والإصدارات الأحدث،
عليك ضبط BLK_CRYPTO_KEY_TYPE_HW_WRAPPED
في blk_crypto_profile::key_types_supported
،
وإتاحة blk_crypto_ll_ops::keyslot_program
وblk_crypto_ll_ops::keyslot_evict
لبرمجة/إلغاء مفاتيح التشفير المُغلفة بالأجهزة،
وتنفيذ blk_crypto_ll_ops::derive_sw_secret
.
بالنسبة إلى نواةَي android12
وandroid13
،
اضبط BLK_CRYPTO_FEATURE_WRAPPED_KEYS
في blk_keyslot_manager::features
،
وأدخِل blk_ksm_ll_ops::keyslot_program
وblk_ksm_ll_ops::keyslot_evict
لتفعيل برمجة/إلغاء مفاتيح التشفير المُغلفة بالأجهزة،
وطبِّق blk_ksm_ll_ops::derive_raw_secret
.
بالنسبة إلى android11
نواة،
تحديد BLK_CRYPTO_FEATURE_WRAPPED_KEYS
في keyslot_manager::features
،
إنشاء keyslot_mgmt_ll_ops::keyslot_program
وkeyslot_mgmt_ll_ops::keyslot_evict
دعم البرمجة/التخلص من المفاتيح المغلفة بالأجهزة،
وتنفيذ keyslot_mgmt_ll_ops::derive_raw_secret
.
الاختبار
رغم أن عملية التشفير باستخدام مفاتيح ملفوفة للأجهزة يصعُب اختبارها أكثر من التشفير.
باستخدام مفاتيح قياسية، يظل من الممكن الاختبار عن طريق استيراد مفتاح اختبار
إعادة تنفيذ اشتقاق المفتاح الذي يفعله الجهاز. يتم تنفيذ ذلك
في vts_kernel_encryption_test
. لإجراء هذا الاختبار،
التشغيل:
atest -v vts_kernel_encryption_test
اقرأ سجلّ الاختبار وتأكَّد من أنّ حالات اختبار المفاتيح المغلفة بالأجهزة (على سبيل المثال،
FBEPolicyTest.TestAesInlineCryptOptimizedHwWrappedKeyPolicy
و
لم يتم تخطي DmDefaultKeyTest.TestHwWrappedKey
) بسبب الدعم
عدم رصد المفاتيح المغلفة على أجهزة أخرى، لأنّ نتائج الاختبار لا تزال
"تم بنجاح" في هذه الحالة.
تفعيل المفاتيح
بعد عمل دعم المفتاح المغلف بالجهاز بشكل صحيح، يمكنك
عليك إجراء التغييرات التالية على ملف fstab
للجهاز لإجراء
يستخدمه Android لتشفير FBE وتشفير البيانات الوصفية:
- FBE: إضافة علامة
wrappedkey_v0
إلى مَعلمةfileencryption
. على سبيل المثال، يمكنك استخدامfileencryption=::inlinecrypt_optimized+wrappedkey_v0
. لمزيد من التفاصيل، يُرجى الاطّلاع على مستندات FBE . - تشفير البيانات الوصفية: أضِف العلامة
wrappedkey_v0
إلى المَعلمةmetadata_encryption
. على سبيل المثال، استخدمmetadata_encryption=:wrappedkey_v0
لمزيد من التفاصيل، يُرجى الاطّلاع على مستندات تشفير البيانات الوصفية.