مثل معظم برامج تشفير الأقراص والملفات، يتيح تشفير مساحة التخزين في Android يعتمد عادةً على مفاتيح التشفير الأولية المتوفّرة في ذاكرة النظام بحيث يمكن تنفيذ التشفير. حتى في حال تنفيذ التشفير باستخدام أجهزة مخصّصة بدلاً من البرامج، لا يزال على البرامج بشكل عام إدارة مفاتيح التشفير الأولية.
لا يُعتبَر ذلك عادةً مشكلة لأنّ المفاتيح لن تكون متوفّرة أثناء هجوم بلا إنترنت، وهو النوع الرئيسي من الهجمات التي يهدف تشفير التخزين إلى حمايتك منها. ومع ذلك، هناك رغبة في توفير حماية مُحسنة ضد أنواع أخرى من الهجمات، مثل هجمات التشغيل البارد ، والهجمات على الإنترنت التي قد يتمكّن فيها المهاجم من تسريب ذاكرة النظام بدون اختراق الجهاز بالكامل.
لحلّ هذه المشكلة، وفّر نظام التشغيل Android 11 مفتاح تشفير مُدمج في الجهاز، حيث يتوفّر دعم الأجهزة. مفاتيح الأجهزة المُغلفة هي مفاتيح تخزين لا يمكن الاطّلاع عليها إلا في شكلها الأصلي باستخدام الأجهزة المخصّصة، ولا يمكن للبرامج الاطّلاع على هذه المفاتيح والتعامل معها إلا في شكلها المغلف (المشفَّر). يجب أن تكون هذه الأجهزة قادرة على إنشاء مفاتيح التخزين واستيرادها، وتغليف مفاتيح التخزين بأشكال مؤقتة وطويلة المدى، واستخراج مفاتيح فرعية، وبرمجة مفتاح فرعي واحد مباشرةً في محرك تشفير مضمّن، وتقديم مفتاح فرعي منفصل إلى البرنامج.
ملاحظة: يكون هناك محرك تشفير مضمّن (أو مضمّن). أجهزة التشفير) إلى أجهزة تعمل على تشفير/فك تشفير البيانات أثناء هو في طريقه إلى/من جهاز التخزين. وعادةً ما يكون هذا العنصر هو UFS أو وحدة تحكّم مضيفة في eMMC تطبّق الإضافات المشفّرة التي تحدّدها مواصفات JEDEC المقابلة.
التصميم
يعرض هذا القسم تصميم ميزة مفاتيح التشفير المُدارة بالأجهزة، بما في ذلك متطلبات التوافق مع الأجهزة. تركز هذه المناقشة على التشفير المستند إلى الملفات (FBE)، إلا أن الحل على بيانات التعريف التشفير أيضًا.
تتمثل إحدى طرق تجنب الحاجة إلى مفاتيح التشفير الأولية في ذاكرة النظام في وتحتفظ بها فقط في خانات المفاتيح في محرك التشفير المضمّن. ومع ذلك، تواجه هذه الصعوبة بعض المشاكل:
- قد يتجاوز عدد مفاتيح التشفير عدد خانات المفاتيح.
- لا يمكن استخدام محركات التشفير المضمنة سوى لتشفير/فك تشفير الكتل الكاملة لـ البيانات على القرص. ومع ذلك، في حال استخدام ميزة "التشفير من جهة العميل"، يجب أن يظل بإمكان البرنامج تنفيذ عمليات تشفير أخرى، مثل تشفير أسماء الملفات واستخراج معرّفات مفاتيح التشفير. ستظل البرامج بحاجة إلى الوصول إلى مفاتيح FBE الأولية للقيام بهذا العمل الآخر.
لتجنب هذه المشكلات، يتم بدلاً من ذلك تحويل مفاتيح التخزين إلى المفاتيح التي يتم لفّها بالأجهزة، والتي لا يمكن فكّ فكّها واستخدامها من قِبل الأجهزة المخصصة. ويتيح ذلك إمكانية استخدام عدد غير محدود من المفاتيح. بالإضافة إلى ذلك، يتم تعديل التسلسل الهرمي للمفتاح ونقله جزئيًا إلى هذا الجهاز، مما يسمح بإرجاع مفتاح فرعي إلى البرنامج للمهام التي لا يمكنها استخدام محرك تشفير مضمّن.
التدرّج الهرمي الرئيسي
يمكن اشتقاق المفاتيح من مفاتيح أخرى باستخدام دالة اشتقاق المفاتيح (KDF)، مثل HKDF، مما يؤدي إلى إنشاء تسلسل هرمي للمفاتيح.
يوضّح الرسم البياني التالي التسلسل الهرمي المعتاد للمفاتيح في ميزة "التشفير من جهة العميل" عندمالا يتم استخدام مفاتيح مُغلفة بالأجهزة:
مفتاح فئة FBE هو مفتاح التشفير الأوّلي الذي يمرره Android إلى ملف Linux kernel لفتح قفل مجموعة معيّنة من الدلائل المشفّرة، مثل storage المشفّر باستخدام بيانات الاعتماد لمستخدم معيّن على 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، وتتطابق مع علامة
TAG_STORAGE_KEY
KeyMint. زر "إنشاء" يستخدمvold
هذه القدرة لإنشاء مساحة تخزين جديدة. للاستخدام بواسطة Android، بينما سيؤدي استخدام مفتاح "الاستيراد" القدرة علىvts_kernel_encryption_test
لاستيراد مفاتيح الاختبار. - واجهة لتحويل مفتاح تخزين ملف مُغلف على المدى الطويل إلى
مفتاح تخزين ملف مُغلف بشكل مؤقت ويتوافق ذلك مع طريقة
convertStorageKeyToEphemeral
KeyMint. يتم استخدام هذه الطريقة بواسطةvold
وvts_kernel_encryption_test
بالترتيب لفتح قفل مساحة التخزين.
تعتبر خوارزمية التفاف المفتاح من تفاصيل التنفيذ، ولكن يجب أن تستخدم AEAD قوي مثل AES-256-GCM مع قيم IV عشوائية.
يجب إجراء تغييرات على البرامج
يحتوي 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: إضافة علامة
wrappedkey_v0
إلى مَعلمةfileencryption
. على سبيل المثال، استخدمfileencryption=::inlinecrypt_optimized+wrappedkey_v0
لمزيد من التفاصيل، يُرجى الاطّلاع على مستندات FBE . - تشفير البيانات الوصفية: أضِف علامة
wrappedkey_v0
إلى مَعلمةmetadata_encryption
. على سبيل المثال، يمكنك استخدامmetadata_encryption=:wrappedkey_v0
. لمزيد من التفاصيل، اطّلِع على مستندات تشفير البيانات الوصفية.