يتضمّن نواة GKI
وحدة نواة Linux تُسمى fips140.ko
تتوافق مع متطلبات
FIPS 140-3
لوحدات البرامج التشفيرية. يمكن إرسال هذه الوحدة للحصول على شهادة FIPS
إذا كان المنتج الذي يستخدم نواة GKI يتطلّب ذلك.
يجب استيفاء متطلبات معيار FIPS 140-3 التالية على وجه الخصوص قبل استخدام إجراءات التشفير:
- يجب أن تتحقّق الوحدة من سلامتها قبل إتاحة خوارزميات التشفير.
- يجب أن تُجري الوحدة اختبارات ذاتية للتحقق من خوارزميات التشفير المعتمَدة قبل إتاحتها.
سبب استخدام وحدة نواة منفصلة
تستند عملية التحقّق من معيار FIPS 140-3 إلى فكرة أنّه بعد اعتماد وحدة تستند إلى البرامج أو الأجهزة، لا يتم تغييرها مطلقًا. وفي حال تغييره، يجب إعادة اعتماده. لا يتطابق ذلك بسهولة مع عمليات تطوير البرامج المُستخدَمة اليوم، ونتيجةً لهذا الشرط، تم تصميم وحدات برامج FIPS بشكلٍ عام للتركيز بشكلٍ وثيق على المكوّنات المشفّرة قدر الإمكان، لضمان عدم تطلب التغييرات غير المرتبطة بعلم التشفير إعادة تقييم التشفير.
من المفترض أن يتم تحديث نواة GKI بانتظام طوال فترة استخدامها المتوافقة. ويجعل ذلك من غير الممكن أن تكون النواة بأكملها ضمن حدود وحدة FIPS ، لأنّه يجب إعادة اعتماد هذه الوحدة عند كل تحديث لنواة. سيؤدي تحديد "وحدة FIPS" لتكون مجموعة فرعية من صورة النواة إلى تخفيف هذه المشكلة، ولكنّه لن يحلّها، لأنّ المحتوى الثنائي ل"وحدة FIPS" سيظلّ يتغيّر بشكلٍ متكرّر أكثر من اللازم.
قبل الإصدار 6.1 من kernel، كان هناك اعتبار آخر وهو أنّه تم تجميع GKI مع تفعيل ميزة LTO (تحسين وقت الربط)، لأنّ LTO كان شرطًا أساسيًا لاستخدام ميزة سلامة تدفق التحكّم التي تشكّل ميزة أمان مهمة.
لذلك، يتم تجميع كل الرموز البرمجية التي تخضع لمتطلبات FIPS 140-3
في وحدة نواة منفصلة fips140.ko
تعتمد فقط على واجهة مستقرة
يتم عرضها من خلال مصدر نواة GKI الذي تم إنشاؤها منه. ويعني ذلك
أنّه يمكن استخدام الوحدة مع إصدارات مختلفة من GKI من الجيل
نفسه، وأنّه يجب تعديلها وإعادة إرسالها للحصول على الاعتماد فقط
في حال إصلاح أي مشاكل في الرمز البرمجي الذي تحمله الوحدة نفسها.
حالات استخدام الوحدة
يحتوي نواة GKI نفسها على رمز يعتمد على إجراءات التشفير التي يتم أيضًا تجميعها في وحدة نواة FIPS 140-3. لذلك، لا يتم نقل وحدات معالجة التشفير المضمّنة خارج نواة GKI، بل يتم نسخها إلى الوحده. عند تحميل الوحدة، تتم إبطال تسجيل وحدات التشفير المضمّنة من Linux CryptoAPI ويتم استبدالها بوحدات التشفير التي تحملها الوحدة.
وهذا يعني أنّ وحدة fips140.ko
اختيارية تمامًا، ولا يُنصح بنشرها إلا إذا كانت شهادة FIPS 140-3 مطلوبة. بالإضافة إلى ذلك،
لا توفّر الوحدة أي إمكانات إضافية، ومن المحتمل أن يؤدي تحميلها بدون داعٍ إلى أثرٍ في وقت التشغيل فقط، بدون تقديم أي فائدة.
كيفية نشر الوحدة
يمكن دمج الوحدة في إصدار Android باتّباع الخطوات التالية:
- أضِف اسم الوحدة إلى
BOARD_VENDOR_RAMDISK_KERNEL_MODULES
. يؤدي ذلك إلى نسخ العبارة module إلى ذاكرة الوصول العشوائي (RAM) الخاصة بالمورِّد. - أضِف اسم الوحدة إلى
BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD
. يؤدي ذلك إلى إضافة اسم الوحدة إلىmodules.load
في الهدف. يحتويmodules.load
على قائمة بالوحدات التي يحمّلهاinit
عند التمهيد للجهاز.
التحقّق الذاتي من السلامة
تأخذ وحدة نواة FIPS 140-3 تجزئة HMAC-SHA256 للفقرتَين .code
و.rodata
الخاصتَين بها في وقت تحميل الوحدة، وتقارنها بالتجزئة
المسجّلة في الوحدة. يحدث ذلك بعد أن يُجري أداة تحميل وحدات Linux
التعديلات المعتادة، مثل معالجة إعادة تحديد المواقع في ملف ELF و
تصحيح البدائل للأخطاء في وحدة المعالجة المركزية في هذه الأقسام. يتم اتّخاذ الخطوات التالية
الإضافية لضمان إمكانية إعادة إنتاج الخلاصة
بشكل صحيح:
- يتم الاحتفاظ بعمليات إعادة تحديد المواقع في ELF داخل الوحدة حتى يمكن تطبيقها في الاتجاه المعاكس على إدخال HMAC.
- تُلغي الوحدة أيّ تصحيحات رمز أجراها kernel لميزة Dynamic Shadow Call Stack. على وجه التحديد، تستبدل الوحدة أي تعليمات تؤدي إلى الدفع أو الإخراج من تسلسل استدعاء الظل بتعليمات رمز مصادقة المؤشر (PAC) التي كانت متوفّرة في الأصل.
- يتم إيقاف جميع عمليات تصحيح الرموز البرمجية الأخرى للوحدة، بما في ذلك المفاتيح الثابتة وبالتالي نقاط التتبّع بالإضافة إلى أدوات الربط الخاصة بالمورّدين.
الاختبارات الذاتية ذات الإجابات المعروفة
يجب أن تُجري أي خوارزميات مُطبَّقة تخضع لمتطلبات FIPS 140-3 اختبارًا ذاتيًا للإجابة المعروفة قبل استخدامها. وفقًا لـ FIPS 140-3 إرشادات التنفيذ 10.3.A، يكون متجه اختبار واحد لكل خوارزمية باستخدام أي من أطوال المفاتيح المتوافقة كافئًا للتشفير، ما دام يتم اختبار كل من التشفير وفك التشفير.
تتضمّن Linux CryptoAPI مفهومًا لأولويات الخوارزميات، حيث قد تتعايش عدة عمليات تنفيذ (مثل عملية تستخدم تعليمات تشفير خاصة وعملية احتياطية لوحدات المعالجة المركزية التي لا تنفّذ هذه التعليمات) للخوارزمية نفسها. وبالتالي، هناك حاجة إلى اختبار جميع عمليات تنفيذ الخطوة الحسابية نفسها. هذا الإجراء ضروري لأنّ Linux CryptoAPI يسمح بتخطّي الاختيار القائم على الأولوية، واختيار خوارزمية ذات أولوية أقل بدلاً من ذلك.
الخوارزميات المضمّنة في الوحدة
في ما يلي جميع الخوارزميات المضمّنة في وحدة FIPS 140-3.
ينطبق ذلك على فروع android12-5.10
وandroid13-5.10
وandroid13-5.15
وandroid14-5.15
وandroid14-6.1
وandroid15-6.6
للنواة، مع ملاحظة اختلافات بين إصدارات النواة عند الاقتضاء.
خوارزمية | عمليات التنفيذ | يمكن الموافقة عليها | التعريف |
---|---|---|---|
aes |
aes-generic وaes-arm64 وaes-ce ومكتبة AES |
نعم | التشفير العادي للكتلة باستخدام مفتاح التشفير AES، بدون وضع تشغيل: تتوفّر جميع أحجام المفاتيح (128 بت و192 بت و256 بت). يمكن إنشاء جميع عمليات التنفيذ باستثناء تنفيذ المكتبة باستخدام وضع تشغيل من خلال نموذج. |
cmac(aes) |
cmac (نموذج)، cmac-aes-neon ، cmac-aes-ce |
نعم | AES-CMAC: تتوفّر جميع أحجام مفاتيح AES. يمكن إنشاء نموذج cmac باستخدام أيّ تنفيذ لـ aes باستخدام cmac(<aes-impl>) . أما عمليات التنفيذ الأخرى، فهي مستقلة. |
ecb(aes) |
ecb (نموذج)، ecb-aes-neon ، ecb-aes-neonbs ، ecb-aes-ce |
نعم | AES-ECB: تتوفّر جميع أحجام مفاتيح AES. يمكن إنشاء نموذج ecb باستخدام أيّ تنفيذ لـ aes باستخدام ecb(<aes-impl>) . أما عمليات التنفيذ الأخرى، فهي مستقلة. |
cbc(aes) |
cbc (نموذج)، cbc-aes-neon ، cbc-aes-neonbs ، cbc-aes-ce |
نعم | AES-CBC: تتوفّر جميع أحجام مفاتيح AES. يمكن إنشاء نموذج cbc باستخدام أيّ تنفيذ لـ aes باستخدام ctr(<aes-impl>) . أما عمليات التنفيذ الأخرى، فهي مستقلة. |
cts(cbc(aes)) |
cts (نموذج)، cts-cbc-aes-neon ، cts-cbc-aes-ce |
نعم | AES-CBC-CTS أو AES-CBC مع سرقة النص المشفَّر: الرمز المتفق عليه هو CS3 ، ويتم تبديل الكتلتين الأخيرتين من النص المشفَّر بدون قيد أو شرط. جميع أحجام مفاتيح التشفير بتنسيق AES متوافقة. يمكن إنشاء نموذج cts باستخدام أيّ تنفيذ لـ cbc باستخدام cts(<cbc(aes)-impl>) . وتكون عمليات التنفيذ الأخرى مستقلة. |
ctr(aes) |
ctr (نموذج)، ctr-aes-neon ، ctr-aes-neonbs ، ctr-aes-ce |
نعم | AES-CTR: تتوفّر جميع أحجام مفاتيح AES. يمكن إنشاء نموذج ctr باستخدام أيّ تنفيذ لـ aes باستخدام ctr(<aes-impl>) . أما عمليات التنفيذ الأخرى، فهي مستقلة. |
xts(aes) |
xts (نموذج)، xts-aes-neon ، xts-aes-neonbs ، xts-aes-ce |
نعم | AES-XTS: في الإصدار 6.1 من kernel والإصدارات الأقدم، تكون جميع أحجام مفاتيح AES متوافقة. وفي الإصدار 6.6 من kernel والإصدارات الأحدث، تكون فقط AES-128 وAES-256 متوافقة. يمكن إنشاء نموذج xts باستخدام أيّ تنفيذ لـ ecb(aes) باستخدام xts(<ecb(aes)-impl>) . أما عمليات التنفيذ الأخرى، فهي مستقلة. تُنفِّذ جميع عمليات التنفيذ عملية التحقّق من المفتاح الضعيف التي يتطلّبها معيار FIPS، أي أنّه يتم رفض مفاتيح XTS التي يكون نصفها الأول والثاني متساويين. |
gcm(aes) |
gcm (نموذج)، gcm-aes-ce |
لا1 | AES-GCM: تتوفّر جميع أحجام مفاتيح AES. لا يمكن استخدام سوى قيم IV التي تبلغ 96 بت. كما هو الحال مع جميع أوضاع AES الأخرى في هذه الوحدة، يتحمّل المُتصل مسؤولية تقديم قيم IV. يمكن إنشاء نموذج gcm باستخدام أي عمليات تنفيذ لـ ctr(aes) وghash باستخدام gcm_base(<ctr(aes)-impl>,<ghash-impl>) . أما عمليات التنفيذ الأخرى، فهي مستقلة. |
sha1 |
"sha1-generic " و"sha1-ce " |
نعم | دالة التجزئة المشفّرة SHA-1 |
sha224 |
"sha224-generic " و"sha224-arm64 " و"sha224-ce " |
نعم | وظيفة التجزئة المشفّرة SHA-224: تتم مشاركة الرمز مع SHA-256. |
sha256 |
sha256-generic وsha256-arm64 وsha256-ce ومكتبة SHA-256 |
نعم | دالة التجزئة التشفيرية SHA-256: يتم توفير واجهة مكتبة لدالة SHA-256 بالإضافة إلى واجهة CryptoAPI العادية. تستخدم واجهة هذه المكتبة طريقة تنفيذ مختلفة. |
sha384 |
"sha384-generic " و"sha384-arm64 " و"sha384-ce " |
نعم | وظيفة التجزئة المشفّرة SHA-384: تتم مشاركة الرمز مع SHA-512. |
sha512 |
"sha512-generic " و"sha512-arm64 " و"sha512-ce " |
نعم | دالة التجزئة المشفّرة SHA-512 |
sha3-224 |
sha3-224-generic |
نعم | دالة التجزئة المشفّرة SHA3-224 لا يتوفّر هذا الخيار إلا في الإصدار 6.6 من kernel والإصدارات الأحدث. |
sha3-256 |
sha3-256-generic |
نعم | كما هو الحال في الإجراء السابق، ولكن مع طول الملخّص الذي يبلغ 256 بت (SHA3-256). تستخدم جميع أطوال الملخّصات طريقة تنفيذ Keccak نفسها. |
sha3-384 |
sha3-384-generic |
نعم | القيمة نفسها السابقة، ولكن بطول خلاصة 384 بت (SHA3-384) تستخدم جميع أطوال الملخّصات طريقة تنفيذ Keccak نفسها. |
sha3-512 |
sha3-512-generic |
نعم | القيمة نفسها كما في الخطوة السابقة، ولكن بطول 512 بت (SHA3-512). تستخدم جميع أطوال الملخّصات طريقة تنفيذ Keccak نفسها. |
hmac |
hmac (نموذج) |
نعم | HMAC (رمز مصادقة الرسائل باستخدام التجزئة المفتاحية): يمكن إنشاء نموذج hmac باستخدام أي خوارزمية SHA أو تنفيذ باستخدام hmac(<sha-alg>) أو hmac(<sha-impl>) . |
stdrng |
drbg_pr_hmac_sha1 ، drbg_pr_hmac_sha256 ، drbg_pr_hmac_sha384 ، drbg_pr_hmac_sha512 |
نعم | تمّ إنشاء مثيل لدالة HMAC_DRBG باستخدام دالة التجزئة المُسمّاة وتفعيل ميزة مقاومة التوقّعات: يتم تضمين عمليات التحقّق من الصحة. يحصل مستخدمو هذه الواجهة على نُسخ من دالة DRBG. |
stdrng |
drbg_nopr_hmac_sha1 ، drbg_nopr_hmac_sha256 ، drbg_nopr_hmac_sha384 ، drbg_nopr_hmac_sha512 |
نعم | تتشابه مع خوارزميات drbg_pr_* ، ولكن مع إيقاف ميزة "مقاومة التوقّعات". تتم مشاركة الرمز مع السعر المتغير المقاوم للتوقّعات. في إصدار kernel 5.10، يكون معرّف DRBG drbg_nopr_hmac_sha256 هو الأعلى أولوية. في الإصدار 5.15 من kernel والإصدارات الأحدث، يكون drbg_pr_hmac_sha512 . |
jitterentropy_rng |
jitterentropy_rng |
لا | Jitter RNG، إما الإصدار 2.2.0 (الإصدار 6.1 من kernel والإصدارات الأقدم) أو الإصدار 3.4.0 (الإصدار 6.6 من kernel والإصدارات الأحدث) يحصل مستخدمو هذه الواجهة على نُسخ Jitter RNG الخاصة بهم. ولا تُعيد استخدام النُسخ التي تستخدمها وظائف "التوليد المبرمَج للأرقام العشوائية". |
xcbc(aes) |
"xcbc-aes-neon " و"xcbc-aes-ce " |
لا | |
xctr(aes) |
"xctr-aes-neon " و"xctr-aes-ce " |
لا | لا يتوفّر هذا الخيار إلا في الإصدار 5.15 من kernel والإصدارات الأحدث. |
cbcmac(aes) |
"cbcmac-aes-neon " و"cbcmac-aes-ce " |
لا | |
essiv(cbc(aes),sha256) |
"essiv-cbc-aes-sha256-neon " و"essiv-cbc-aes-sha256-ce " |
لا |
إنشاء الوحدة من المصدر
بالنسبة إلى الإصدار 14 من نظام التشغيل Android والإصدارات الأحدث (بما في ذلك
android-mainline
)، يمكنك إنشاء وحدة fips140.ko
من المصدر باستخدام
الأوامر التالية.
إنشاء حِزم باستخدام Bazel:
tools/bazel run //common:fips140_dist
إنشاء التطبيق باستخدام
build.sh
(الإصدار القديم):BUILD_CONFIG=common/build.config.gki.aarch64.fips140 build/build.sh
تُجري هذه الأوامر عملية إنشاء كاملة تشمل النواة وfips140.ko
الوحدة مع تضمين محتوى خلاصة HMAC-SHA256.
إرشادات المستخدم النهائي
إرشادات موظّف إدارة العملات المشفّرة
لتشغيل وحدة النواة، يجب حصر نظام التشغيل في وضع تشغيل عامل تشغيل واحد. يعالج نظام Android هذا الأمر تلقائيًا باستخدام الأجهزة المخصّصة لإدارة الذاكرة في المعالج.
لا يمكن تثبيت وحدة النواة بشكل منفصل، بل يتم تضمينها كجزء من برمجية الثابتة للجهاز ويتم تحميلها تلقائيًا عند بدء التشغيل. ولا يعمل إلا في أحد الأوضاع الموافَق عليها.
يمكن لمسؤول التشفير إجراء الاختبارات الذاتية في أي وقت من خلال إعادة تشغيل الجهاز.
إرشادات المستخدِم
مستخدم وحدة النواة هو مكونات النواة الأخرى التي تحتاج إلى استخدام خوارزميات التشفير. لا توفّر وحدة النواة منطقًا إضافيًا في استخدام الخوارزميات، ولا تخزّن أي مَعلمات بعد الوقت اللازم لتنفيذ عملية تشفير.
يقتصر استخدام الخوارزميات لأغراض الامتثال لمعيار FIPS على
الخوارزميات الموافَق عليها. لاستيفاء متطلبات "مؤشر الخدمة" في معيار FIPS 140-3، يوفّر الرمز البرمجي للوحدة دالة fips140_is_approved_service
تشير إلى ما إذا تمت الموافقة على إحدى الخوارزميات.
أخطاء الاختبار الذاتي
في حال تعذُّر الاختبار الذاتي، تؤدي وحدة النواة إلى تعطُّل النواة وعدم مواصلة الجهاز عملية التمهيد. إذا لم تؤدِ إعادة تشغيل الجهاز إلى حلّ المشكلة، يجب تشغيل الجهاز في وضع الاسترداد لتصحيح المشكلة من خلال إعادة فلاش الجهاز.
-
من المتوقّع أن تكون عمليات تنفيذ AES-GCM في الوحدة "خوارزمية موافَق عليها" ولكن ليس "وحدة موافَق عليها". ويمكن التحقّق منها، ولكن لا يمكن اعتبار AES-GCM خوارزمية موافَق عليها من وجهة نظر وحدة FIPS. ويعود السبب في ذلك إلى أنّ متطلبات وحدة FIPS لبروتوكول GCM غير متوافقة مع عمليات تنفيذ GCM التي لا تنشئ أرقام التحقق الخاصة بها. ↩