Keystore المدعومة بالأجهزة

يوفر توفر بيئة تنفيذ موثوقة في نظام على شريحة (SoC) فرصة لأجهزة Android لتوفير خدمات أمان قوية ومدعومة بالأجهزة لنظام التشغيل Android وخدمات النظام الأساسي وحتى لتطبيقات الجهات الخارجية. يجب على المطورين الذين يسعون للحصول على امتدادات خاصة بـ Android الانتقال إلى android.security.keystore .

قبل Android 6.0 ، كان لدى Android بالفعل واجهة برمجة تطبيقات خدمات تشفير بسيطة مدعومة بالأجهزة ، يتم توفيرها بواسطة الإصدارين 0.2 و 0.3 من Keymaster Hardware Abstraction Layer (HAL). قدمت Keystore عمليات التوقيع والتحقق الرقمية ، بالإضافة إلى إنشاء واستيراد أزواج مفاتيح التوقيع غير المتماثلة. تم تنفيذ هذا بالفعل على العديد من الأجهزة ، ولكن هناك العديد من أهداف الأمان التي لا يمكن تحقيقها بسهولة باستخدام توقيع API فقط. قام Keystore في Android 6.0 بتوسيع Keystore API لتوفير نطاق أوسع من الإمكانات.

في Android 6.0 ، أضاف Keystore أساسيات التشفير المتماثل ، AES و HMAC ، ونظام التحكم في الوصول للمفاتيح المدعومة بالأجهزة. يتم تحديد عناصر التحكم في الوصول أثناء إنشاء المفتاح ويتم فرضها طوال عمر المفتاح. يمكن تقييد استخدام المفاتيح فقط بعد مصادقة المستخدم ، ولأغراض محددة فقط أو باستخدام معلمات تشفير محددة. لمزيد من المعلومات ، راجع صفحات علامات التفويض والوظائف .

بالإضافة إلى توسيع نطاق أساسيات التشفير ، أضاف Keystore في Android 6.0 ما يلي:

  • نظام التحكم في الاستخدام للسماح بتحديد استخدام المفتاح ، للتخفيف من مخاطر الاختراق الأمني ​​بسبب إساءة استخدام المفاتيح
  • نظام التحكم في الوصول لتمكين تقييد المفاتيح لمستخدمين معينين وعملاء ونطاق زمني محدد

في Android 7.0 ، أضاف Keymaster 2 دعمًا للمصادقة الرئيسية وربط الإصدار. يوفر التصديق على المفتاح شهادات المفاتيح العامة التي تحتوي على وصف مفصل للمفتاح وعناصر التحكم في الوصول الخاصة به ، لجعل وجود المفتاح في الأجهزة الآمنة وتكوينه قابلاً للتحقق عن بُعد.

ربط الإصدار يربط المفاتيح بنظام التشغيل وإصدار مستوى التصحيح. يضمن ذلك أن المهاجم الذي يكتشف نقطة ضعف في إصدار قديم من النظام أو برنامج TEE لا يمكنه إعادة الجهاز إلى الإصدار الضعيف واستخدام المفاتيح التي تم إنشاؤها باستخدام الإصدار الأحدث. بالإضافة إلى ذلك ، عند استخدام مفتاح بإصدار معين ومستوى تصحيح على جهاز تمت ترقيته إلى إصدار أحدث أو مستوى تصحيح ، تتم ترقية المفتاح قبل إمكانية استخدامه وإبطال الإصدار السابق من المفتاح. أثناء ترقية الجهاز ، "تضاعف" المفاتيح للأمام مع الجهاز ، ولكن أي ارتداد للجهاز إلى إصدار سابق يتسبب في أن تصبح المفاتيح غير قابلة للاستخدام.

في Android 8.0 ، انتقل Keymaster 3 من طبقة تجريد الأجهزة ذات البنية C القديمة (HAL) إلى واجهة C ++ HAL التي تم إنشاؤها من تعريف في لغة تعريف واجهة الأجهزة الجديدة (HIDL). كجزء من التغيير ، تم تغيير العديد من أنواع الوسائط ، على الرغم من أن الأنواع والطرق لها تطابق واحد لواحد مع الأنواع القديمة وطرق HAL Struct. انظر صفحة الوظائف لمزيد من التفاصيل.

بالإضافة إلى مراجعة الواجهة هذه ، قام Android 8.0 بتوسيع ميزة التصديق في Keymaster 2 لدعم توثيق الهوية . يوفر إثبات الهوية آلية محدودة واختيارية للتصديق بقوة على معرفات الأجهزة ، مثل الرقم التسلسلي للجهاز واسم المنتج ومعرف الهاتف (IMEI / MEID). لتنفيذ هذه الإضافة ، قام Android 8.0 بتغيير مخطط شهادة ASN.1 لإضافة شهادة ID. تحتاج تطبيقات Keymaster إلى إيجاد طريقة آمنة لاسترداد عناصر البيانات ذات الصلة ، بالإضافة إلى تحديد آلية لتعطيل الميزة بشكل آمن ودائم.

في Android 9 ، تضمنت التحديثات:

  • التحديث إلى Keymaster 4
  • دعم العناصر الآمنة المضمنة
  • دعم استيراد المفتاح الآمن
  • دعم تشفير 3DES
  • التغييرات في ربط الإصدار بحيث يكون لكل من boot.img و system.img إصدارات محددة بشكل منفصل للسماح بالتحديثات المستقلة

قائمة المصطلحات

فيما يلي نظرة عامة سريعة على مكونات Keystore وعلاقاتها.

AndroidKeystore هو Android Framework API والمكون الذي تستخدمه التطبيقات للوصول إلى وظائف Keystore. يتم تنفيذه كامتداد لواجهات برمجة تطبيقات Java Cryptography Architecture القياسية ، ويتكون من كود Java يعمل في مساحة العملية الخاصة بالتطبيق. يفي AndroidKeystore بطلبات التطبيق الخاصة بسلوك Keystore عن طريق إعادة توجيهها إلى البرنامج الخفي لـ keystore.

برنامج keystore daemon هو برنامج خفي لنظام Android يوفر الوصول إلى جميع وظائف Keystore عبر Binder API . إنه مسؤول عن تخزين "النقاط الرئيسية" ، التي تحتوي على مادة المفتاح السري الفعلي ، المشفرة حتى يتمكن Keystore من تخزينها دون استخدامها أو الكشف عنها.

keymasterd هو خادم HIDL يوفر الوصول إلى Keymaster TA. (هذا الاسم ليس موحدًا ولأغراض مفاهيمية.)

Keymaster TA (تطبيق موثوق به) هو البرنامج الذي يتم تشغيله في سياق آمن ، غالبًا في TrustZone على ARM SoC ، والذي يوفر جميع عمليات Keystore الآمنة ، ولديه حق الوصول إلى مادة المفتاح الخام ، والتحقق من صحة جميع شروط التحكم في الوصول على المفاتيح ، إلخ.

LockSettingsService هو مكون نظام Android المسؤول عن مصادقة المستخدم ، وكل من كلمة المرور وبصمة الإصبع. إنه ليس جزءًا من Keystore ، ولكنه ذو صلة لأن العديد من عمليات مفتاح Keystore تتطلب مصادقة المستخدم. تتفاعل LockSettingsService مع Gatekeeper TA و Fingerprint TA للحصول على رموز المصادقة ، التي توفرها لخادم keystore ، والتي يستهلكها تطبيق Keymaster TA في النهاية.

Gatekeeper TA (تطبيق موثوق به) هو مكون آخر يعمل في السياق الآمن ، وهو مسؤول عن مصادقة كلمات مرور المستخدم وإنشاء رموز المصادقة المميزة المستخدمة لإثبات Keymaster TA أن المصادقة قد تم إجراؤها لمستخدم معين في وقت معين.

Fingerprint TA (تطبيق موثوق به) هو مكون آخر يعمل في السياق الآمن وهو مسؤول عن مصادقة بصمات أصابع المستخدم وإنشاء رموز المصادقة المميزة المستخدمة لإثبات Keymaster TA أن المصادقة قد تم إجراؤها لمستخدم معين في وقت معين.

بنيان

توفر واجهة برمجة تطبيقات Android Keystore و Keymaster HAL الأساسي مجموعة أساسية ولكن مناسبة من أساسيات التشفير للسماح بتنفيذ البروتوكولات باستخدام مفاتيح التحكم في الوصول والمدعومة من الأجهزة.

Keymaster HAL هي مكتبة قابلة للتحميل ديناميكيًا توفرها الشركة المصنعة للمعدات الأصلية وتستخدمها خدمة Keystore لتقديم خدمات تشفير مدعومة بالأجهزة. للحفاظ على أمان الأشياء ، لا تؤدي تطبيقات HAL أي عمليات حساسة في مساحة المستخدم ، أو حتى في مساحة kernel. يتم تفويض العمليات الحساسة إلى معالج آمن يتم الوصول إليه من خلال بعض واجهات kernel. تبدو البنية الناتجة كما يلي:

الوصول إلى Keymaster

الشكل 1. الوصول إلى Keymaster

داخل جهاز Android ، يتكون "العميل" لـ Keymaster HAL من طبقات متعددة (مثل التطبيق ، والإطار ، و Keystore daemon) ، ولكن يمكن تجاهل ذلك لأغراض هذا المستند. هذا يعني أن Keymaster HAL API الموصوفة منخفضة المستوى ، وتستخدمها المكونات الداخلية للنظام الأساسي ، ولا تتعرض لمطوري التطبيقات. يتم وصف واجهة برمجة التطبيقات ذات المستوى الأعلى على موقع مطور Android .

الغرض من Keymaster HAL ليس تنفيذ خوارزميات حساسة للأمان ولكن فقط لتنظيم الطلبات وإلغاء تنظيمها في العالم الآمن. يتم تحديد تنسيق السلك حسب التنفيذ.

التوافق مع الإصدارات السابقة

Keymaster 1 HAL غير متوافق تمامًا مع HALs التي تم إصدارها مسبقًا ، مثل Keymaster 0.2 و 0.3. لتسهيل التشغيل البيني على الأجهزة التي تعمل بنظام Android 5.0 والإصدارات الأقدم التي تم إطلاقها مع Keymaster HALs الأقدم ، يوفر Keystore محولًا يقوم بتنفيذ Keymaster 1 HAL مع المكالمات إلى مكتبة الأجهزة الموجودة. لا يمكن أن توفر النتيجة النطاق الكامل للوظائف في Keymaster 1 HAL. على وجه الخصوص ، فهو يدعم فقط خوارزميات RSA و ECDSA ، ويتم تنفيذ جميع عمليات إنفاذ ترخيص المفتاح بواسطة المهايئ ، في العالم غير الآمن.

قام Keymaster 2 بتبسيط واجهة HAL بشكل أكبر عن طريق إزالة أساليب get_supported_* والسماح لطريقة finish() بقبول الإدخال. هذا يقلل من عدد الرحلات ذهابًا وإيابًا إلى TEE في الحالات التي يكون فيها الإدخال متاحًا دفعة واحدة ، ويبسط تنفيذ فك تشفير AEAD.

في Android 8.0 ، انتقل Keymaster 3 من الطراز القديم C- بنية HAL إلى واجهة C ++ HAL التي تم إنشاؤها من تعريف في لغة تعريف واجهة الأجهزة الجديدة (HIDL). يتم إنشاء تطبيق HAL بأسلوب جديد عن طريق التصنيف الفرعي لفئة IKeymasterDevice التي تم إنشاؤها وتنفيذ الأساليب الافتراضية البحتة. كجزء من التغيير ، تم تغيير العديد من أنواع الوسائط ، على الرغم من أن الأنواع والطرق لها تطابق واحد لواحد مع الأنواع القديمة وطرق HAL Struct.

نظرة عامة HIDL

توفر لغة تعريف واجهة الأجهزة (HIDL) آلية تنفيذ مستقلة عن اللغة لتحديد واجهات الأجهزة. تدعم أدوات HIDL حاليًا إنشاء واجهات C ++ و Java. من المتوقع أن يجد معظم منفذي بيئة التنفيذ الموثوقة (TEE) أدوات C ++ أكثر ملاءمة ، لذلك يناقش هذا المستند تمثيل C ++ فقط.

تتكون واجهات HIDL من مجموعة من الأساليب ، يتم التعبير عنها على النحو التالي:

  methodName(INPUT ARGUMENTS) generates (RESULT ARGUMENTS);

هناك أنواع مختلفة محددة مسبقًا ، ويمكن لـ HALs تحديد أنواع هيكلية ومعدودة جديدة. لمزيد من التفاصيل حول HIDL ، راجع قسم المرجع .

طريقة المثال من Keymaster 3 IKeymasterDevice.hal هي:

generateKey(vec<KeyParameter> keyParams)
        generates(ErrorCode error, vec<uint8_t> keyBlob,
                  KeyCharacteristics keyCharacteristics);

هذا يعادل ما يلي من keymaster2 HAL:

keymaster_error_t (*generate_key)(
        const struct keymaster2_device* dev,
        const keymaster_key_param_set_t* params,
        keymaster_key_blob_t* key_blob,
        keymaster_key_characteristics_t* characteristics);

في إصدار HIDL ، تمت إزالة وسيطة dev ، لأنها ضمنية. لم تعد الوسيطة params عبارة عن هيكل يحتوي على مؤشر يشير إلى مصفوفة من كائنات key_parameter_t ، بل يمثل vec (متجه) يحتوي على كائنات KeyParameter . يتم سرد قيم الإرجاع في عبارة " generates " ، بما في ذلك متجه قيم uint8_t لقاعدة البيانات الثنائية الكبيرة.

الطريقة الافتراضية C ++ التي تم إنشاؤها بواسطة مترجم HIDL هي:

Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams,
                         generateKey_cb _hidl_cb) override;

حيث يكون generateKey_cb هو مؤشر دالة مُعرَّف على النحو التالي:

std::function<void(ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
                   const KeyCharacteristics& keyCharacteristics)>

أي ، generateKey_cb هي دالة تأخذ قيم الإرجاع المدرجة في جملة الإنشاء. تتجاوز فئة تطبيق HAL أسلوب generateKey هذا وتستدعي مؤشر دالة generateKey_cb لإرجاع نتيجة العملية إلى المستدعي. لاحظ أن استدعاء مؤشر الوظيفة متزامن . تستدعي مكالمات الطالب generateKey واستدعاء generateKey لمؤشر الوظيفة الموفر ، والذي يتم تنفيذه حتى الاكتمال ، ويعيد التحكم إلى تنفيذ generateKey ، والذي يعود بعد ذلك إلى المتصل.

للحصول على مثال مفصل ، راجع التنفيذ الافتراضي في hardware/interfaces/keymaster/3.0/default/KeymasterDevice.cpp . يوفر التطبيق الافتراضي التوافق مع الإصدارات السابقة للأجهزة ذات النمط القديم keymaster0 أو keymaster1 أو keymaster2 HALS.

صلاحية التحكم صلاحية الدخول

القاعدة الأساسية للتحكم في الوصول إلى Keystore هي أن لكل تطبيق مساحة اسم خاصة به. لكن لكل قاعدة استثناء. يحتوي Keystore على بعض الخرائط ذات الترميز الثابت التي تسمح لمكونات نظام معينة بالوصول إلى بعض مساحات الأسماء الأخرى. هذه أداة حادة جدًا من حيث أنها تمنح عنصرًا واحدًا تحكمًا كاملاً في مساحة اسم أخرى. ثم هناك مسألة مكونات البائع كعملاء لـ Keystore. ليس لدينا حاليًا طريقة لإنشاء مساحة اسم لمكونات البائعين ، على سبيل المثال ، طالب WPA.

من أجل استيعاب مكونات البائع وتعميم التحكم في الوصول دون استثناءات مشفرة ، يقدم Keystore 2.0 المجالات ومساحات أسماء SELinux.

مجالات Keystore

باستخدام نطاقات Keystore ، يمكننا فصل مساحات الأسماء عن معرفات UID. يجب على العملاء الذين يصلون إلى مفتاح في Keystore تحديد النطاق ومساحة الاسم والاسم المستعار الذي يريدون الوصول إليه. بناءً على هذه المجموعة وهوية المتصل ، يمكننا تحديد المفتاح الذي يريد المتصل الوصول إليه وما إذا كان لديه الأذونات المناسبة.

نقدم خمس معلمات للمجال تحكم كيفية الوصول إلى المفاتيح. يتحكمون في دلالات معلمة مساحة الاسم لواصف المفتاح وكيفية تنفيذ التحكم في الوصول.

  • DOMAIN_APP : يغطي نطاق التطبيق السلوك القديم. يستخدم Java Keystore SPI هذا المجال افتراضيًا. عند استخدام هذا المجال ، يتم تجاهل وسيطة مساحة الاسم ويتم استخدام UID الخاص بالمستدعي بدلاً من ذلك. يتم التحكم في الوصول إلى هذا المجال بواسطة تسمية Keystore إلى class keystore_key في سياسة SELinux.
  • DOMAIN_SELINUX : يشير هذا المجال إلى أن مساحة الاسم لها تسمية في سياسة SELinux. يتم البحث عن معامل مساحة الاسم وترجمته إلى سياق الهدف ، ويتم إجراء فحص الإذن لسياق SELinux الذي يستدعي لفئة keystore_key . عندما يتم إنشاء الإذن للعملية المحددة ، يتم استخدام المجموعة الكاملة للبحث عن المفتاح.
  • DOMAIN_GRANT : يشير مجال المنحة إلى أن معلمة مساحة الاسم هي معرف منحة. تم تجاهل معلمة الاسم المستعار. يتم إجراء عمليات التحقق من SELinux عند إنشاء المنحة. يتحقق المزيد من التحكم في الوصول فقط مما إذا كان المعرف الفريد للمتصل يطابق UID الحاصل على المنحة المطلوبة.
  • DOMAIN_KEY_ID : يشير هذا المجال إلى أن معلمة مساحة الاسم هي معرف مفتاح فريد. ربما تم إنشاء المفتاح نفسه باستخدام DOMAIN_APP أو DOMAIN_SELINUX . يتم إجراء التحقق من الإذن بعد تحميل domain namespace من قاعدة البيانات الأساسية بنفس الطريقة كما لو تم تحميل blob بواسطة المجال ومساحة الاسم ومجموعة الاسم المستعار. الأساس المنطقي لمجال معرف المفتاح هو الاستمرارية. عند الوصول إلى مفتاح بالاسم المستعار ، قد تعمل المكالمات اللاحقة على مفاتيح مختلفة ، لأنه ربما تم إنشاء مفتاح جديد أو استيراده وربطه بهذا الاسم المستعار. معرف المفتاح ، ومع ذلك ، لا يتغير أبدا. لذلك عند استخدام مفتاح بواسطة معرف المفتاح بعد تحميله من قاعدة بيانات Keystore باستخدام الاسم المستعار مرة واحدة ، يمكن للمرء التأكد من أنه نفس المفتاح طالما أن معرف المفتاح لا يزال موجودًا. لا يتم عرض هذه الوظيفة لمطوري التطبيقات. بدلاً من ذلك ، يتم استخدامه داخل Android Keystore SPI لتوفير تجربة أكثر اتساقًا حتى عند استخدامه بشكل متزامن بطريقة غير آمنة.
  • DOMAIN_BLOB : يشير مجال blob إلى أن المتصل يدير blob بنفسه. يستخدم هذا للعملاء الذين يحتاجون إلى الوصول إلى Keystore قبل تحميل قسم البيانات. يتم تضمين ملف البيانات الثنائية الكبيرة في حقل البيانات blob الكبيرة لواصف المفاتيح.

باستخدام مجال SELinux ، يمكننا منح مكونات البائع الوصول إلى مساحات أسماء Keystore محددة جدًا والتي يمكن مشاركتها بواسطة مكونات النظام مثل مربع حوار الإعدادات.

سياسة SELinux لـ keystore_key

يتم تكوين تسميات مساحة الاسم باستخدام ملف keystore2_key_context .
يقوم كل سطر في هذه الملفات بتعيين معرف مساحة اسم رقمي لملصق SELinux. على سبيل المثال،

# wifi_key is a keystore2_key namespace intended to be used by wpa supplicant and
# Settings to share keystore keys.
102            u:object_r:wifi_key:s0

بعد إعداد مساحة اسم مفتاح جديدة بهذه الطريقة ، يمكننا منح الوصول إليها عن طريق إضافة سياسة مناسبة. على سبيل المثال ، للسماح لـ wpa_supplicant بالحصول على المفاتيح واستخدامها في مساحة الاسم الجديدة ، سنضيف السطر التالي إلى hal_wifi_supplicant.te :

allow hal_wifi_supplicant wifi_key:keystore2_key { get, use };

بعد إعداد مساحة الاسم الجديدة ، يمكن استخدام AndroidKeyStore كالمعتاد تقريبًا. الاختلاف الوحيد هو أنه يجب تحديد معرف مساحة الاسم. لتحميل واستيراد المفاتيح من وإلى Keystore ، يتم تحديد معرف مساحة الاسم باستخدام AndroidKeyStoreLoadStoreParameter . على سبيل المثال،

import android.security.keystore2.AndroidKeyStoreLoadStoreParameter;
import java.security.KeyStore;

KeyStore keystore = KeyStore.getInstance("AndroidKeyStore");
keystore.load(new AndroidKeyStoreLoadStoreParameter(102));

لإنشاء مفتاح في مساحة اسم معينة ، يجب إعطاء معرف مساحة الاسم باستخدام KeyGenParameterSpec.Builder#setNamespace():

import android.security.keystore.KeyGenParameterSpec;
KeyGenParameterSpec.Builder specBuilder = new KeyGenParameterSpec.Builder();
specBuilder.setNamespace(102);

يمكن استخدام ملفات السياق التالية لتكوين مساحات أسماء Keystore 2.0 SELinux. يحتوي كل قسم على نطاق محجوز مختلف من 10000 معرف مساحة اسم لتجنب التصادمات.

تقسيم يتراوح ملفات التكوين
نظام 0 ... 9999
/system/etc/selinux/keystore2_key_contexts, /plat_keystore2_key_contexts
نظام موسع 10000 ... 19999
/system_ext/etc/selinux/system_ext_keystore2_key_contexts, /system_ext_keystore2_key_contexts
منتج 20000 ... 29999
/product/etc/selinux/product_keystore2_key_contexts, /product_keystore2_key_contexts
بائع 30000 ... 39999
/vendor/etc/selinux/vendor_keystore2_key_contexts, /vendor_keystore2_key_contexts

يطلب العميل المفتاح عن طريق طلب نطاق SELinux ومساحة الاسم الافتراضية المطلوبة ، في هذه الحالة "wifi_key" ، من خلال معرفه الرقمي.

علاوة على ذلك ، تم تحديد مساحات الأسماء التالية. إذا استبدلت القواعد الخاصة ، فيشير الجدول التالي إلى المعرف الفريد العمومي (UID) الذي استخدموه للتوافق مع القواعد الخاصة.

معرف مساحة الاسم تسمية وثيقة التأمين المعرف الفريد وصف
0 su_key غير متاح مفتاح المستخدم الفائق. تستخدم فقط للاختبار على بنيات userdebug و eng. غير ذي صلة ببنيات المستخدم.
1 shell_key غير متاح Namespace المتاحة للقصف. تستخدم في الغالب للاختبار ، ولكن يمكن استخدامها في إنشاءات المستخدم أيضًا من سطر الأوامر.
100 vold_key غير متاح مخصص للاستخدام من قبل vold.
101 odsing_key غير متاح مستخدمة بواسطة البرنامج الخفي للتوقيع على الجهاز.
102 wifi_key AID_WIFI (1010) يستخدمه نظام Wifi لنظام Android بما في ذلك wpa_supplicant.
120 استئناف_على_إعادة_التمهيد_مفتاح AID_SYSTEM (1000) يستخدمه خادم نظام Android لدعم الاستئناف عند إعادة التشغيل.

نواقل الوصول

لقد مضى وقت طويل على keystore_key لفئة SELinux وبعض الأذونات ، مثل verify أو sign فقدت معناها. هذه هي المجموعة الجديدة من الأذونات ، keystore2_key ، التي سيفرضها Keystore 2.0.

إذن معنى
delete تم الفحص عند إزالة المفاتيح من Keystore.
get_info يتم فحصه عند طلب البيانات الوصفية للمفتاح.
grant يحتاج المتصل إلى هذا الإذن لإنشاء منحة للمفتاح في السياق الهدف.
manage_blob يمكن للمتصل استخدام DOMAIN_BLOB على مساحة اسم SELinux المحددة ، وبالتالي يدير النقط المزدوجة بنفسه. هذا مفيد بشكل خاص لـ vold.
rebind يتحكم هذا الإذن في إمكانية ارتداد الاسم المستعار إلى مفتاح جديد. هذا مطلوب للإدراج ويعني أنه سيتم حذف المفتاح المرتبط مسبقًا. إنه في الأساس إذن إدخال ، لكنه يلتقط دلالات keystore بشكل أفضل.
req_forced_op قد ينشئ العملاء الذين لديهم هذا الإذن عمليات غير قابلة للتنفيذ ، ولا يفشل إنشاء العملية أبدًا ما لم يتم أخذ جميع فتحات التشغيل من خلال عمليات غير قابلة للتشغيل.
update مطلوب لتحديث المكون الفرعي للمفتاح.
use تم التحقق منه عند إنشاء عملية Keymint التي تستخدم المادة الأساسية ، على سبيل المثال ، للتوقيع ، en / فك التشفير.
use_dev_id مطلوبة عند إنشاء معلومات تعريف الجهاز ، مثل تصديق معرف الجهاز.

بالإضافة إلى ذلك ، قمنا بتقسيم مجموعة من أذونات تخزين المفاتيح غير المحددة الرئيسية في keystore2 لفئة أمان SELinux:

إذن معنى
add_auth مطلوب بواسطة موفر المصادقة مثل Gatekeeper أو BiometricsManager لإضافة رموز المصادقة.
clear_ns كان هذا الإذن سابقًا clear_uid ، يسمح لغير مالك مساحة الاسم بحذف جميع المفاتيح في مساحة الاسم هذه.
list مطلوب من قبل النظام لتعداد المفاتيح حسب الخصائص المختلفة ، مثل الملكية أو حدود المصادقة. هذا الإذن غير مطلوب من قبل المتصلين الذين يعددون مساحات الأسماء الخاصة بهم. هذا مشمول بإذن get_info .
lock يسمح هذا الإذن بقفل Keystore ، أي طرد المفتاح الرئيسي ، بحيث تصبح مفاتيح المصادقة غير قابلة للاستخدام وغير قابلة للإنشاء.
reset يسمح هذا الإذن بإعادة تعيين Keystore إلى إعدادات المصنع الافتراضية ، وحذف جميع المفاتيح غير الحيوية لعمل نظام التشغيل Android.
unlock هذا الإذن مطلوب لمحاولة إلغاء قفل المفتاح الرئيسي لمفاتيح المصادقة المرتبطة.
و

يوفر توفر بيئة تنفيذ موثوقة في نظام على شريحة (SoC) فرصة لأجهزة Android لتوفير خدمات أمان قوية ومدعومة بالأجهزة لنظام التشغيل Android وخدمات النظام الأساسي وحتى لتطبيقات الجهات الخارجية. يجب على المطورين الذين يسعون للحصول على امتدادات خاصة بـ Android الانتقال إلى android.security.keystore .

قبل Android 6.0 ، كان لدى Android بالفعل واجهة برمجة تطبيقات خدمات تشفير بسيطة مدعومة بالأجهزة ، يتم توفيرها بواسطة الإصدارين 0.2 و 0.3 من Keymaster Hardware Abstraction Layer (HAL). قدمت Keystore عمليات التوقيع والتحقق الرقمية ، بالإضافة إلى إنشاء واستيراد أزواج مفاتيح التوقيع غير المتماثلة. تم تنفيذ هذا بالفعل على العديد من الأجهزة ، ولكن هناك العديد من أهداف الأمان التي لا يمكن تحقيقها بسهولة باستخدام توقيع API فقط. قام Keystore في Android 6.0 بتوسيع Keystore API لتوفير نطاق أوسع من الإمكانات.

في Android 6.0 ، أضاف Keystore أساسيات التشفير المتماثل ، AES و HMAC ، ونظام التحكم في الوصول للمفاتيح المدعومة بالأجهزة. يتم تحديد عناصر التحكم في الوصول أثناء إنشاء المفتاح ويتم فرضها طوال عمر المفتاح. يمكن تقييد استخدام المفاتيح فقط بعد مصادقة المستخدم ، ولأغراض محددة فقط أو باستخدام معلمات تشفير محددة. لمزيد من المعلومات ، راجع صفحات علامات التفويض والوظائف .

بالإضافة إلى توسيع نطاق أساسيات التشفير ، أضاف Keystore في Android 6.0 ما يلي:

  • نظام التحكم في الاستخدام للسماح بتحديد استخدام المفتاح ، للتخفيف من مخاطر الاختراق الأمني ​​بسبب إساءة استخدام المفاتيح
  • نظام التحكم في الوصول لتمكين تقييد المفاتيح لمستخدمين معينين وعملاء ونطاق زمني محدد

في Android 7.0 ، أضاف Keymaster 2 دعمًا للمصادقة الرئيسية وربط الإصدار. يوفر التصديق على المفتاح شهادات المفاتيح العامة التي تحتوي على وصف مفصل للمفتاح وعناصر التحكم في الوصول الخاصة به ، لجعل وجود المفتاح في الأجهزة الآمنة وتكوينه قابلاً للتحقق عن بُعد.

ربط الإصدار يربط المفاتيح بنظام التشغيل وإصدار مستوى التصحيح. يضمن ذلك أن المهاجم الذي يكتشف نقطة ضعف في إصدار قديم من النظام أو برنامج TEE لا يمكنه إعادة الجهاز إلى الإصدار الضعيف واستخدام المفاتيح التي تم إنشاؤها باستخدام الإصدار الأحدث. بالإضافة إلى ذلك ، عند استخدام مفتاح بإصدار معين ومستوى تصحيح على جهاز تمت ترقيته إلى إصدار أحدث أو مستوى تصحيح ، تتم ترقية المفتاح قبل إمكانية استخدامه وإبطال الإصدار السابق من المفتاح. أثناء ترقية الجهاز ، "تضاعف" المفاتيح للأمام مع الجهاز ، ولكن أي ارتداد للجهاز إلى إصدار سابق يتسبب في أن تصبح المفاتيح غير قابلة للاستخدام.

في Android 8.0 ، انتقل Keymaster 3 من طبقة تجريد الأجهزة ذات البنية C القديمة (HAL) إلى واجهة C ++ HAL التي تم إنشاؤها من تعريف في لغة تعريف واجهة الأجهزة الجديدة (HIDL). كجزء من التغيير ، تم تغيير العديد من أنواع الوسائط ، على الرغم من أن الأنواع والطرق لها تطابق واحد لواحد مع الأنواع القديمة وطرق HAL Struct. انظر صفحة الوظائف لمزيد من التفاصيل.

بالإضافة إلى مراجعة الواجهة هذه ، قام Android 8.0 بتوسيع ميزة التصديق في Keymaster 2 لدعم توثيق الهوية . يوفر إثبات الهوية آلية محدودة واختيارية للتصديق بقوة على معرفات الأجهزة ، مثل الرقم التسلسلي للجهاز واسم المنتج ومعرف الهاتف (IMEI / MEID). لتنفيذ هذه الإضافة ، قام Android 8.0 بتغيير مخطط شهادة ASN.1 لإضافة شهادة ID. تحتاج تطبيقات Keymaster إلى إيجاد طريقة آمنة لاسترداد عناصر البيانات ذات الصلة ، بالإضافة إلى تحديد آلية لتعطيل الميزة بشكل آمن ودائم.

في Android 9 ، تضمنت التحديثات:

  • التحديث إلى Keymaster 4
  • دعم العناصر الآمنة المضمنة
  • دعم استيراد المفتاح الآمن
  • دعم تشفير 3DES
  • التغييرات في ربط الإصدار بحيث يكون لكل من boot.img و system.img إصدارات محددة بشكل منفصل للسماح بالتحديثات المستقلة

قائمة المصطلحات

فيما يلي نظرة عامة سريعة على مكونات Keystore وعلاقاتها.

AndroidKeystore هو Android Framework API والمكون الذي تستخدمه التطبيقات للوصول إلى وظائف Keystore. يتم تنفيذه كامتداد لواجهات برمجة تطبيقات Java Cryptography Architecture القياسية ، ويتكون من كود Java يعمل في مساحة العملية الخاصة بالتطبيق. يفي AndroidKeystore بطلبات التطبيق الخاصة بسلوك Keystore عن طريق إعادة توجيهها إلى البرنامج الخفي لـ keystore.

برنامج keystore daemon هو برنامج خفي لنظام Android يوفر الوصول إلى جميع وظائف Keystore عبر Binder API . إنه مسؤول عن تخزين "النقاط الرئيسية" ، التي تحتوي على مادة المفتاح السري الفعلي ، المشفرة حتى يتمكن Keystore من تخزينها دون استخدامها أو الكشف عنها.

keymasterd هو خادم HIDL يوفر الوصول إلى Keymaster TA. (هذا الاسم ليس موحدًا ولأغراض مفاهيمية.)

Keymaster TA (تطبيق موثوق به) هو البرنامج الذي يتم تشغيله في سياق آمن ، غالبًا في TrustZone على ARM SoC ، والذي يوفر جميع عمليات Keystore الآمنة ، ولديه حق الوصول إلى مادة المفتاح الخام ، والتحقق من صحة جميع شروط التحكم في الوصول على المفاتيح ، إلخ.

LockSettingsService هو مكون نظام Android المسؤول عن مصادقة المستخدم ، وكل من كلمة المرور وبصمة الإصبع. إنه ليس جزءًا من Keystore ، ولكنه ذو صلة لأن العديد من عمليات مفتاح Keystore تتطلب مصادقة المستخدم. تتفاعل LockSettingsService مع Gatekeeper TA و Fingerprint TA للحصول على رموز المصادقة ، التي توفرها لخادم keystore ، والتي يستهلكها تطبيق Keymaster TA في النهاية.

Gatekeeper TA (تطبيق موثوق به) هو مكون آخر يعمل في السياق الآمن ، وهو مسؤول عن مصادقة كلمات مرور المستخدم وإنشاء رموز المصادقة المميزة المستخدمة لإثبات Keymaster TA أن المصادقة قد تم إجراؤها لمستخدم معين في وقت معين.

Fingerprint TA (تطبيق موثوق به) هو مكون آخر يعمل في السياق الآمن وهو مسؤول عن مصادقة بصمات أصابع المستخدم وإنشاء رموز المصادقة المميزة المستخدمة لإثبات Keymaster TA أن المصادقة قد تم إجراؤها لمستخدم معين في وقت معين.

بنيان

توفر واجهة برمجة تطبيقات Android Keystore و Keymaster HAL الأساسي مجموعة أساسية ولكن مناسبة من أساسيات التشفير للسماح بتنفيذ البروتوكولات باستخدام مفاتيح التحكم في الوصول والمدعومة من الأجهزة.

Keymaster HAL هي مكتبة قابلة للتحميل ديناميكيًا توفرها الشركة المصنعة للمعدات الأصلية وتستخدم بواسطة خدمة Keystore لتقديم خدمات تشفير مدعومة بالأجهزة. للحفاظ على أمان الأشياء ، لا تؤدي تطبيقات HAL أي عمليات حساسة في مساحة المستخدم ، أو حتى في مساحة kernel. يتم تفويض العمليات الحساسة إلى معالج آمن يتم الوصول إليه من خلال بعض واجهات kernel. تبدو البنية الناتجة كما يلي:

الوصول إلى Keymaster

الشكل 1. الوصول إلى Keymaster

داخل جهاز Android ، يتكون "العميل" لـ Keymaster HAL من طبقات متعددة (مثل التطبيق ، والإطار ، و Keystore daemon) ، ولكن يمكن تجاهل ذلك لأغراض هذا المستند. هذا يعني أن Keymaster HAL API الموصوفة منخفضة المستوى ، وتستخدمها المكونات الداخلية للنظام الأساسي ، ولا تتعرض لمطوري التطبيقات. يتم وصف واجهة برمجة التطبيقات ذات المستوى الأعلى على موقع مطور Android .

الغرض من Keymaster HAL ليس تنفيذ خوارزميات حساسة للأمان ولكن فقط لتنظيم الطلبات وإلغاء تنظيمها في العالم الآمن. يتم تحديد تنسيق السلك حسب التنفيذ.

التوافق مع الإصدارات السابقة

Keymaster 1 HAL غير متوافق تمامًا مع HALs التي تم إصدارها مسبقًا ، مثل Keymaster 0.2 و 0.3. لتسهيل التشغيل البيني على الأجهزة التي تعمل بنظام Android 5.0 والإصدارات الأقدم التي تم إطلاقها مع Keymaster HALs الأقدم ، يوفر Keystore محولًا يقوم بتنفيذ Keymaster 1 HAL مع المكالمات إلى مكتبة الأجهزة الموجودة. لا يمكن أن توفر النتيجة النطاق الكامل للوظائف في Keymaster 1 HAL. على وجه الخصوص ، فهو يدعم فقط خوارزميات RSA و ECDSA ، ويتم تنفيذ جميع عمليات إنفاذ ترخيص المفتاح بواسطة المهايئ ، في العالم غير الآمن.

قام Keymaster 2 بتبسيط واجهة HAL بشكل أكبر عن طريق إزالة أساليب get_supported_* والسماح لطريقة finish() بقبول الإدخال. هذا يقلل من عدد الرحلات ذهابًا وإيابًا إلى TEE في الحالات التي يكون فيها الإدخال متاحًا دفعة واحدة ، ويبسط تنفيذ فك تشفير AEAD.

في Android 8.0 ، انتقل Keymaster 3 من الطراز القديم C- بنية HAL إلى واجهة C ++ HAL التي تم إنشاؤها من تعريف في لغة تعريف واجهة الأجهزة الجديدة (HIDL). يتم إنشاء تطبيق HAL بأسلوب جديد عن طريق التصنيف الفرعي لفئة IKeymasterDevice التي تم إنشاؤها وتنفيذ الأساليب الافتراضية البحتة. كجزء من التغيير ، تم تغيير العديد من أنواع الوسائط ، على الرغم من أن الأنواع والطرق لها تطابق واحد لواحد مع الأنواع القديمة وطرق HAL Struct.

نظرة عامة HIDL

توفر لغة تعريف واجهة الأجهزة (HIDL) آلية تنفيذ مستقلة عن اللغة لتحديد واجهات الأجهزة. تدعم أدوات HIDL حاليًا إنشاء واجهات C ++ و Java. من المتوقع أن يجد معظم منفذي بيئة التنفيذ الموثوقة (TEE) أدوات C ++ أكثر ملاءمة ، لذلك يناقش هذا المستند تمثيل C ++ فقط.

تتكون واجهات HIDL من مجموعة من الأساليب ، يتم التعبير عنها على النحو التالي:

  methodName(INPUT ARGUMENTS) generates (RESULT ARGUMENTS);

هناك أنواع مختلفة محددة مسبقًا ، ويمكن لـ HALs تحديد أنواع هيكلية ومعدودة جديدة. لمزيد من التفاصيل حول HIDL ، راجع قسم المرجع .

طريقة المثال من Keymaster 3 IKeymasterDevice.hal هي:

generateKey(vec<KeyParameter> keyParams)
        generates(ErrorCode error, vec<uint8_t> keyBlob,
                  KeyCharacteristics keyCharacteristics);

هذا يعادل ما يلي من keymaster2 HAL:

keymaster_error_t (*generate_key)(
        const struct keymaster2_device* dev,
        const keymaster_key_param_set_t* params,
        keymaster_key_blob_t* key_blob,
        keymaster_key_characteristics_t* characteristics);

في إصدار HIDL ، تمت إزالة وسيطة dev ، لأنها ضمنية. لم تعد الوسيطة params عبارة عن هيكل يحتوي على مؤشر يشير إلى مصفوفة من كائنات key_parameter_t ، بل يمثل vec (متجه) يحتوي على كائنات KeyParameter . يتم سرد قيم الإرجاع في عبارة " generates " ، بما في ذلك متجه قيم uint8_t لقاعدة البيانات الثنائية الكبيرة.

الطريقة الافتراضية C ++ التي تم إنشاؤها بواسطة مترجم HIDL هي:

Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams,
                         generateKey_cb _hidl_cb) override;

حيث يكون generateKey_cb هو مؤشر دالة مُعرَّف على النحو التالي:

std::function<void(ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
                   const KeyCharacteristics& keyCharacteristics)>

أي ، generateKey_cb هي دالة تأخذ قيم الإرجاع المدرجة في جملة الإنشاء. تتجاوز فئة تطبيق HAL أسلوب generateKey هذا وتستدعي مؤشر دالة generateKey_cb لإرجاع نتيجة العملية إلى المستدعي. لاحظ أن استدعاء مؤشر الوظيفة متزامن . تستدعي مكالمات الطالب generateKey واستدعاء إنشاء المفتاح لمؤشر الوظيفة generateKey ، والذي يتم تنفيذه حتى الاكتمال ، ويعيد التحكم إلى تنفيذ generateKey ، والذي يعود بعد ذلك إلى المتصل.

للحصول على مثال مفصل ، راجع التنفيذ الافتراضي في hardware/interfaces/keymaster/3.0/default/KeymasterDevice.cpp . يوفر التطبيق الافتراضي التوافق مع الإصدارات السابقة للأجهزة ذات النمط القديم keymaster0 أو keymaster1 أو keymaster2 HALS.

صلاحية التحكم صلاحية الدخول

القاعدة الأساسية للتحكم في الوصول إلى Keystore هي أن لكل تطبيق مساحة اسم خاصة به. لكن لكل قاعدة استثناء. يحتوي Keystore على بعض الخرائط ذات الترميز الثابت التي تسمح لمكونات نظام معينة بالوصول إلى بعض مساحات الأسماء الأخرى. هذه أداة حادة جدًا من حيث أنها تمنح عنصرًا واحدًا تحكمًا كاملاً في مساحة اسم أخرى. ثم هناك مسألة مكونات البائع كعملاء لـ Keystore. ليس لدينا حاليًا طريقة لإنشاء مساحة اسم لمكونات البائعين ، على سبيل المثال ، طالب WPA.

من أجل استيعاب مكونات البائع وتعميم التحكم في الوصول دون استثناءات مشفرة ، يقدم Keystore 2.0 المجالات ومساحات أسماء SELinux.

مجالات Keystore

باستخدام نطاقات Keystore ، يمكننا فصل مساحات الأسماء عن معرفات UID. يجب على العملاء الذين يصلون إلى مفتاح في Keystore تحديد النطاق ومساحة الاسم والاسم المستعار الذي يريدون الوصول إليه. بناءً على هذه المجموعة وهوية المتصل ، يمكننا تحديد المفتاح الذي يريد المتصل الوصول إليه وما إذا كان لديه الأذونات المناسبة.

نقدم خمس معلمات للمجال تحكم كيفية الوصول إلى المفاتيح. يتحكمون في دلالات معلمة مساحة الاسم لواصف المفتاح وكيفية تنفيذ التحكم في الوصول.

  • DOMAIN_APP : يغطي نطاق التطبيق السلوك القديم. يستخدم Java Keystore SPI هذا المجال افتراضيًا. عند استخدام هذا المجال ، يتم تجاهل وسيطة مساحة الاسم ويتم استخدام UID الخاص بالمستدعي بدلاً من ذلك. يتم التحكم في الوصول إلى هذا المجال بواسطة تسمية Keystore إلى class keystore_key في سياسة SELinux.
  • DOMAIN_SELINUX : يشير هذا المجال إلى أن مساحة الاسم لها تسمية في سياسة SELinux. يتم البحث عن معامل مساحة الاسم وترجمته إلى سياق الهدف ، ويتم إجراء فحص الإذن لسياق SELinux الذي يستدعي لفئة keystore_key . عندما يتم إنشاء الإذن للعملية المحددة ، يتم استخدام المجموعة الكاملة للبحث عن المفتاح.
  • DOMAIN_GRANT : يشير مجال المنحة إلى أن معلمة مساحة الاسم هي معرف منحة. تم تجاهل معلمة الاسم المستعار. SELinux checks are performed when the grant is created. Further access control only checks if the caller UID matches the grantees UID of the requested grant.
  • DOMAIN_KEY_ID : This domain indicates that the namespace parameter is a unique key id. The key itself may have been created with DOMAIN_APP or DOMAIN_SELINUX . The permission check is performed after the domain and the namespace have been loaded from the key database in the same way as if the blob was loaded by the domain, namespace, and alias tuple. The rationale for the key id domain is continuity. When accessing a key by alias, subsequent calls may operate on different keys, because a new key may have been generated or imported and bound to this alias. The key id, however, never changes. So when using a key by key id after it has been loaded from the Keystore database using the alias once, one can be certain that it is the same key as long as the key id still exists. This functionality is not exposed to app developers. Instead, it is used within the Android Keystore SPI to provide a more consistent experience even when used concurrently in an unsafe way.
  • DOMAIN_BLOB : The blob domain indicates that the caller manages the blob by itself. This is used for clients that need to access the Keystore before the data partition is mounted. The key blob is included in the blob field of the key descriptor.

Using the SELinux domain, we can give vendor components access to very specific Keystore namespaces which can be shared by system components such as the settings dialog.

SELinux policy for keystore_key

Namespace labels are configured using the keystore2_key_context file.
Each line in these files maps a numeric namespace id to an SELinux label. For example,

# wifi_key is a keystore2_key namespace intended to be used by wpa supplicant and
# Settings to share keystore keys.
102            u:object_r:wifi_key:s0

After having set up a new key namespace in this way, we can give access to it by adding an appropriate policy. For example, to allow wpa_supplicant to get and use keys in the new namespace we would add the following line to hal_wifi_supplicant.te :

allow hal_wifi_supplicant wifi_key:keystore2_key { get, use };

After setting up the new namespace, AndroidKeyStore can be used almost as usual. The only difference is that the namespace ID must be specified. For loading and importing keys from and into Keystore, the namespace id is specified using the AndroidKeyStoreLoadStoreParameter . For example,

import android.security.keystore2.AndroidKeyStoreLoadStoreParameter;
import java.security.KeyStore;

KeyStore keystore = KeyStore.getInstance("AndroidKeyStore");
keystore.load(new AndroidKeyStoreLoadStoreParameter(102));

To generate a key in a given namespace, the namespace id must be given using KeyGenParameterSpec.Builder#setNamespace():

import android.security.keystore.KeyGenParameterSpec;
KeyGenParameterSpec.Builder specBuilder = new KeyGenParameterSpec.Builder();
specBuilder.setNamespace(102);

The following context files may be used to configure Keystore 2.0 SELinux namespaces. Each partition has a different reserved range of 10,000 namespace ids to avoid collisions.

Partition Range Config files
System 0 ... 9,999
/system/etc/selinux/keystore2_key_contexts, /plat_keystore2_key_contexts
Extended System 10,000 ... 19,999
/system_ext/etc/selinux/system_ext_keystore2_key_contexts, /system_ext_keystore2_key_contexts
Product 20,000 ... 29,999
/product/etc/selinux/product_keystore2_key_contexts, /product_keystore2_key_contexts
Vendor 30,000 ... 39,999
/vendor/etc/selinux/vendor_keystore2_key_contexts, /vendor_keystore2_key_contexts

The client requests the key by requesting the SELinux domain and the desired virtual namespace, in this case "wifi_key" , by its numeric id.

Above that, the following namespaces have been defined. If they replace special rules, the following table indicates the UID they used to correspond to.

Namespace ID SEPolicy Label UID وصف
0 su_key N/A Super user key. Only used for testing on userdebug and eng builds. Not relevant on user builds.
1 shell_key N/A Namespace available to shell. Mostly used for testing, but can be used on user builds as well from the command line.
100 vold_key N/A Intended for use by vold.
101 odsing_key N/A Used by the on-device signing daemon.
102 wifi_key AID_WIFI(1010) Used by Android's Wifi sybsystem including wpa_supplicant.
120 resume_on_reboot_key AID_SYSTEM(1000) Used by Android's system server to support resume on reboot.

Access Vectors

The SELinux class keystore_key has aged quite a bit and some of the permissions, such as verify or sign have lost their meaning. Here is the new set of permissions, keystore2_key , that Keystore 2.0 will enforce.

إذن Meaning
delete Checked when removing keys from Keystore.
get_info Checked when a key's metadata is requested.
grant The caller needs this permission to create a grant to the key in the target context.
manage_blob The caller may use DOMAIN_BLOB on the given SELinux namespace, thereby managing blobs by itself. This is specifically useful for vold.
rebind This permission controls if an alias may be rebound to a new key. This is required for insertion and implies that the previously bound key will be deleted. It is basically an insert permission, but it captures the semantic of keystore better.
req_forced_op Clients with this permission may create unpruneable operations, and operation creation never fails unless all operation slots are taken by unpruneable operations.
update Required to update the subcomponent of a key.
use Checked when creating a Keymint operation that uses the key material, eg, for signing, en/decryption.
use_dev_id Required when generating device identifying information, such as device id attestation.

Additionally, we split out a set of non key specific keystore permissions in the SELinux security class keystore2 :

إذن Meaning
add_auth Required by authentication provider such as Gatekeeper or BiometricsManager for adding auth tokens.
clear_ns Formerly clear_uid, this permission allows a non owner of a namespace to delete all keys in that namespace.
list Required by the system for enumerating keys by various properties, such as ownership or auth boundedness. This permission is not required by callers enumerating their own namespaces. This is covered by the get_info permission.
lock This permission allows to lock Keystore, that is, evict the master key, such that auth bound keys become unusable and uncreatable.
reset This permission allows to reset Keystore to factory default, deleting all keys that are not vital to the functioning of the Android OS.
unlock This permission is required to attempt to unlock the master key for auth bound keys.