Keystore با پشتیبانی سخت افزار

در دسترس بودن یک محیط اجرایی قابل اعتماد در یک سیستم بر روی یک تراشه (SoC) فرصتی را برای دستگاه‌های Android فراهم می‌کند تا خدمات امنیتی قوی و سخت‌افزاری را برای سیستم‌عامل Android، خدمات پلت‌فرم و حتی برنامه‌های شخص ثالث ارائه کنند. برنامه‌نویسانی که به دنبال برنامه‌های افزودنی مخصوص Android هستند باید به android.security.keystore مراجعه کنند.

قبل از اندروید 6.0، اندروید یک API خدمات رمزنگاری ساده و سخت افزاری داشت که توسط نسخه های 0.2 و 0.3 لایه انتزاعی سخت افزار Keymaster (HAL) ارائه شده بود. Keystore عملیات امضای دیجیتال و تأیید، به علاوه تولید و واردات جفت کلید امضای نامتقارن را ارائه می‌کرد. این در حال حاضر بر روی بسیاری از دستگاه ها اجرا شده است، اما اهداف امنیتی بسیاری وجود دارد که به راحتی تنها با یک API امضا نمی توان به آنها دست یافت. Keystore در Android 6.0 API Keystore را گسترش داد تا طیف وسیع تری از قابلیت ها را ارائه دهد.

در Android 6.0، Keystore رمزنگاری های اولیه متقارن ، AES و HMAC و یک سیستم کنترل دسترسی برای کلیدهای سخت افزاری را اضافه کرد. کنترل های دسترسی در طول تولید کلید مشخص می شوند و برای طول عمر کلید اجرا می شوند. کلیدها فقط پس از احراز هویت کاربر و فقط برای اهداف مشخص یا با پارامترهای رمزنگاری مشخص قابل استفاده هستند محدود شوند. برای اطلاعات بیشتر، به صفحات مجوز و برچسب ها مراجعه کنید.

علاوه بر گسترش دامنه رمزنگاری اولیه، Keystore در Android 6.0 موارد زیر را اضافه کرد:

  • یک طرح کنترل استفاده برای محدود کردن استفاده از کلید، برای کاهش خطر به خطر افتادن امنیت به دلیل استفاده نادرست از کلیدها
  • یک طرح کنترل دسترسی برای فعال کردن محدودیت کلیدها برای کاربران مشخص، مشتریان، و محدوده زمانی تعریف شده

در اندروید 7.0، Keymaster 2 پشتیبانی از گواهی کلید و اتصال نسخه را اضافه کرد. تأیید کلید، گواهی‌های کلید عمومی را ارائه می‌کند که حاوی شرح مفصلی از کلید و کنترل‌های دسترسی آن است تا وجود کلید در سخت‌افزار امن و پیکربندی آن از راه دور قابل تأیید باشد.

Version binding کلیدها را به سیستم عامل و نسخه سطح وصله متصل می کند. این تضمین می کند که مهاجمی که ضعفی را در نسخه قدیمی سیستم یا نرم افزار TEE کشف می کند، نمی تواند دستگاه را به نسخه آسیب پذیر برگرداند و از کلیدهای ایجاد شده با نسخه جدیدتر استفاده کند. علاوه بر این، هنگامی که کلیدی با یک نسخه معین و سطح وصله روی دستگاهی استفاده می‌شود که به نسخه جدیدتر یا سطح وصله ارتقا یافته است، کلید قبل از اینکه بتوان از آن استفاده کرد ارتقا داده می‌شود و نسخه قبلی کلید باطل می‌شود. با ارتقای دستگاه، کلیدها همراه با دستگاه به جلو حرکت می‌کنند، اما هرگونه بازگشت دستگاه به نسخه قبلی باعث می‌شود کلیدها غیرقابل استفاده باشند.

در اندروید 8.0، Keymaster 3 از لایه انتزاعی سخت افزاری ساختار C قدیمی (HAL) به رابط C++ HAL که از تعریفی در زبان تعریف رابط سخت افزاری جدید (HIDL) ایجاد شده بود، انتقال یافت. به عنوان بخشی از تغییر، بسیاری از انواع آرگومان ها تغییر کردند، اگرچه انواع و روش ها مطابقت یک به یک با انواع قدیمی و روش های ساختار HAL دارند. برای جزئیات بیشتر به صفحه توابع مراجعه کنید.

علاوه بر این ویرایش رابط، Android 8.0 ویژگی تأیید Keymaster 2 را برای پشتیبانی از تأیید شناسه گسترش داد. گواهی شناسه مکانیزم محدود و اختیاری را برای تأیید قوی شناسه های سخت افزاری مانند شماره سریال دستگاه، نام محصول و شناسه تلفن (IMEI / MEID) ارائه می دهد. برای پیاده سازی این افزوده، Android 8.0 طرح گواهی ASN.1 را برای افزودن گواهی ID تغییر داد. پیاده‌سازی‌های Keymaster باید راهی مطمئن برای بازیابی اقلام داده‌های مربوطه و همچنین تعریف مکانیزمی برای غیرفعال کردن ایمن و دائمی این ویژگی پیدا کنند.

در اندروید 9، به روز رسانی ها شامل:

  • به روز رسانی به Keymaster 4
  • پشتیبانی از عناصر امن جاسازی شده
  • پشتیبانی از واردات کلید امن
  • پشتیبانی از رمزگذاری 3DES
  • تغییرات در binding نسخه به طوری که boot.img و system.img به طور جداگانه نسخه هایی را تنظیم کرده اند تا امکان به روز رسانی مستقل را فراهم کنند.

واژه نامه

در اینجا یک مرور سریع از اجزای Keystore و روابط آنها ارائه شده است.

AndroidKeystore API و جزء Android Framework است که توسط برنامه ها برای دسترسی به عملکرد Keystore استفاده می شود. این به عنوان یک افزونه برای APIهای استاندارد معماری رمزنگاری جاوا پیاده سازی شده است و از کد جاوا تشکیل شده است که در فضای فرآیند خود برنامه اجرا می شود. AndroidKeystore درخواست‌های برنامه برای رفتار Keystore را با ارسال آن‌ها به شبح keystore برآورده می‌کند.

شبح کیستور یک دیمون سیستم اندرویدی است که دسترسی به تمام عملکردهای کیستور را از طریق Binder API فراهم می‌کند. مسئول ذخیره کردن «حباب‌های کلید» است که حاوی مواد کلید مخفی واقعی است، به طوری که Keystore بتواند آنها را ذخیره کند اما از آنها استفاده یا فاش نکند.

keymasterd یک سرور HIDL است که دسترسی به Keymaster TA را فراهم می کند. (این نام استاندارد نیست و برای اهداف مفهومی است.)

Keymaster TA (برنامه مورد اعتماد) نرم افزاری است که در یک زمینه ایمن اجرا می شود، اغلب در TrustZone روی یک SoC ARM، که تمام عملیات Keystore امن را فراهم می کند، به مواد کلید خام دسترسی دارد، همه شرایط کنترل دسترسی کلیدها را تأیید می کند. ، و غیره.

LockSettingsService جزء سیستم اندروید است که مسئول احراز هویت کاربر، رمز عبور و اثر انگشت است. این بخشی از Keystore نیست، اما مرتبط است زیرا بسیاری از عملیات کلید Keystore نیاز به احراز هویت کاربر دارند. LockSettingsService با Gatekeeper TA و Fingerprint TA تعامل می کند تا توکن های احراز هویت را به دست آورد که در اختیار دیمون keystore قرار می دهد و در نهایت توسط برنامه Keymaster TA مصرف می شود.

Gatekeeper TA (برنامه مورد اعتماد) مؤلفه دیگری است که در زمینه امن اجرا می شود و مسئول احراز هویت رمزهای عبور کاربر و تولید نشانه های احراز هویت است که برای اثبات به Keymaster TA استفاده می شود که احراز هویت برای یک کاربر خاص در یک مقطع زمانی خاص انجام شده است.

اثر انگشت TA (برنامه مورد اعتماد) مؤلفه دیگری است که در زمینه امن اجرا می شود و مسئول احراز هویت اثر انگشت کاربر و تولید نشانه های احراز هویت است که برای اثبات به Keymaster TA استفاده می شود که احراز هویت برای یک کاربر خاص در یک مقطع زمانی خاص انجام شده است.

معماری

Android Keystore API و Keymaster HAL زیربنایی، مجموعه‌ای اساسی اما کافی از رمزنگاری‌های اولیه را فراهم می‌کنند تا امکان اجرای پروتکل‌ها با استفاده از کلیدهای کنترل‌شده با دسترسی سخت‌افزاری را فراهم کنند.

Keymaster HAL یک کتابخانه OEM با قابلیت بارگذاری پویا است که توسط سرویس Keystore برای ارائه خدمات رمزنگاری سخت افزاری استفاده می شود. برای حفظ امنیت، پیاده سازی های HAL هیچ عملیات حساسی را در فضای کاربر یا حتی در فضای هسته انجام نمی دهند. عملیات حساس به یک پردازنده ایمن واگذار می شود که از طریق برخی از رابط های هسته قابل دسترسی است. معماری حاصل به این صورت است:

دسترسی به Keymaster

شکل 1. دسترسی به Keymaster

در یک دستگاه Android، "کلینت" Keymaster HAL از چندین لایه (به عنوان مثال برنامه، فریمورک، شبح Keystore) تشکیل شده است، اما برای اهداف این سند می توان از آن چشم پوشی کرد. این بدان معنی است که Keymaster HAL API در سطح پایینی است، توسط مؤلفه‌های داخلی پلتفرم استفاده می‌شود و در معرض توسعه‌دهندگان برنامه قرار نمی‌گیرد. API سطح بالاتر در سایت توسعه دهنده Android توضیح داده شده است.

هدف Keymaster HAL پیاده سازی الگوریتم های حساس به امنیت نیست، بلکه فقط مارشال و حذف درخواست ها به دنیای امن است. قالب سیم پیاده سازی شده است.

سازگاری با نسخه های قبلی

Keymaster 1 HAL کاملاً با HAL های منتشر شده قبلی، به عنوان مثال Keymaster 0.2 و 0.3 ناسازگار است. برای تسهیل قابلیت همکاری در دستگاه‌های دارای Android نسخه 5.0 و نسخه‌های قدیمی‌تر که با Keymaster HAL‌های قدیمی‌تر راه‌اندازی شده‌اند، Keystore آداپتوری ارائه می‌کند که Keymaster 1 HAL را با فراخوانی به کتابخانه سخت‌افزار موجود پیاده‌سازی می‌کند. نتیجه نمی تواند طیف کاملی از عملکردها را در Keymaster 1 HAL ارائه دهد. به طور خاص، فقط از الگوریتم‌های RSA و ECDSA پشتیبانی می‌کند و تمام اجرای مجوزهای کلیدی توسط آداپتور در دنیای غیر ایمن انجام می‌شود.

Keymaster 2 رابط HAL را با حذف متدهای get_supported_* ساده‌تر کرد و به متد finish() اجازه داد ورودی را بپذیرد. این باعث کاهش تعداد رفت و برگشت به TEE در مواردی می شود که ورودی به یکباره در دسترس است و اجرای رمزگشایی AEAD را ساده می کند.

در اندروید 8.0، Keymaster 3 از ساختار قدیمی HAL به رابط C++ HAL که از تعریفی در زبان تعریف رابط سخت افزاری جدید (HIDL) ایجاد شده بود، انتقال یافت. یک پیاده سازی HAL به سبک جدید با زیرکلاس بندی کلاس IKeymasterDevice تولید شده و پیاده سازی روش های مجازی خالص ایجاد می شود. به عنوان بخشی از تغییر، بسیاری از انواع آرگومان ها تغییر کرده اند، اگرچه انواع و روش ها مطابقت یک به یک با انواع قدیمی و روش های ساختار HAL دارند.

نمای کلی HIDL

زبان تعریف رابط سخت افزاری (HIDL) مکانیزمی مستقل از زبان پیاده سازی برای تعیین رابط های سخت افزاری ارائه می دهد. ابزار HIDL در حال حاضر از تولید رابط های C++ و جاوا پشتیبانی می کند. انتظار می‌رود که اکثر پیاده‌کننده‌های Trusted Execution Environment (TEE) ابزار C++ را راحت‌تر بیابند، بنابراین این سند فقط نمایش C++ را مورد بحث قرار می‌دهد.

رابط های HIDL شامل مجموعه ای از روش ها هستند که به صورت زیر بیان می شوند:

  methodName(INPUT ARGUMENTS) generates (RESULT ARGUMENTS);

انواع مختلفی از پیش تعریف شده وجود دارد، و HAL ها می توانند انواع جدید برشماری و ساختاری را تعریف کنند. برای جزئیات بیشتر در مورد 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 تابعی است که مقادیر بازگشتی فهرست شده در عبارت generate را می گیرد. کلاس پیاده سازی 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، می توانیم فضاهای نام را از UID ها جدا کنیم. مشتریانی که به یک کلید در Keystore دسترسی دارند، باید دامنه، فضای نام و نام مستعاری را که می خواهند به آن دسترسی داشته باشند، مشخص کنند. بر اساس این تاپل و هویت تماس گیرنده، می توانیم تعیین کنیم که تماس گیرنده به کدام کلید می خواهد دسترسی داشته باشد و آیا مجوزهای مناسبی دارد یا خیر.

ما پنج پارامتر دامنه را معرفی می کنیم که نحوه دسترسی به کلیدها را کنترل می کند. آنها معنای پارامتر فضای نام توصیفگر کلید و نحوه کنترل دسترسی را کنترل می کنند.

  • DOMAIN_APP : دامنه برنامه رفتار قدیمی را پوشش می دهد. Java Keystore SPI به طور پیش فرض از این دامنه استفاده می کند. وقتی از این دامنه استفاده می شود، آرگومان فضای نام نادیده گرفته می شود و به جای آن از UID تماس گیرنده استفاده می شود. دسترسی به این دامنه توسط برچسب Keystore به کلاس keystore_key در خط مشی SELinux کنترل می شود.
  • DOMAIN_SELINUX : این دامنه نشان می دهد که فضای نام دارای یک برچسب در خط مشی SELinux است. پارامتر فضای نام جستجو می شود و به یک زمینه هدف ترجمه می شود و یک بررسی مجوز برای متن فراخوانی SELinux برای کلاس keystore_key انجام می شود. هنگامی که مجوز برای عملیات داده شده ایجاد شد، تاپل کامل برای جستجوی کلید استفاده می شود.
  • DOMAIN_GRANT : دامنه اعطایی نشان می دهد که پارامتر فضای نام یک شناسه گرنت است. پارامتر مستعار نادیده گرفته می شود. بررسی های SELinux زمانی انجام می شود که کمک هزینه ایجاد شود. کنترل دسترسی بیشتر فقط بررسی می کند که آیا UID تماس گیرنده با UID دریافت کنندگان کمک هزینه درخواستی مطابقت دارد یا خیر.
  • DOMAIN_KEY_ID : این دامنه نشان می دهد که پارامتر فضای نام یک شناسه کلید منحصر به فرد است. ممکن است خود کلید با DOMAIN_APP یا DOMAIN_SELINUX ایجاد شده باشد. بررسی مجوز پس از بارگیری domain و namespace از پایگاه داده کلید انجام می شود، به همان روشی که گویی حباب توسط دامنه، فضای نام و نام مستعار بارگذاری شده است. منطق دامنه شناسه کلید تداوم است. هنگام دسترسی به یک کلید با نام مستعار، تماس‌های بعدی ممکن است روی کلیدهای مختلف عمل کنند، زیرا ممکن است کلید جدیدی تولید یا وارد شده باشد و به این نام مستعار متصل شده باشد. با این حال، شناسه کلید هرگز تغییر نمی کند. بنابراین هنگام استفاده از شناسه کلید به کلید پس از بارگیری آن از پایگاه داده Keystore با استفاده از نام مستعار، می توان مطمئن بود که تا زمانی که شناسه کلید هنوز وجود دارد، همان کلید است. این قابلیت در معرض توسعه دهندگان برنامه نیست. در عوض، از آن در Android Keystore SPI استفاده می‌شود تا تجربه‌ای ثابت‌تر را ارائه دهد، حتی زمانی که به طور همزمان به روشی ناامن استفاده می‌شود.
  • DOMAIN_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 ... 9,999
/system/etc/selinux/keystore2_key_contexts, /plat_keystore2_key_contexts
سیستم توسعه یافته 10,000 ... 19,999
/system_ext/etc/selinux/system_ext_keystore2_key_contexts, /system_ext_keystore2_key_contexts
تولید - محصول 20,000 ... 29,999
/product/etc/selinux/product_keystore2_key_contexts, /product_keystore2_key_contexts
فروشنده 30,000 ... 39,999
/vendor/etc/selinux/vendor_keystore2_key_contexts, /vendor_keystore2_key_contexts

کلاینت با درخواست دامنه SELinux و فضای نام مجازی مورد نظر، در این مورد "wifi_key" توسط شناسه عددی خود، کلید را درخواست می کند.

بالاتر از آن فضاهای نام زیر تعریف شده است. اگر آنها جایگزین قوانین خاصی شوند، جدول زیر UID مورد استفاده برای مطابقت را نشان می دهد.

شناسه فضای نام برچسب SEPolicy UID شرح
0 su_key N/A کلید کاربر فوق العاده فقط برای آزمایش بر روی userdebug و ساخت های eng استفاده می شود. مربوط به ساخت های کاربر نیست.
1 پوسته_کلید N/A فضای نام موجود برای پوسته. بیشتر برای آزمایش استفاده می شود، اما می تواند در ساخت های کاربر نیز از خط فرمان استفاده شود.
100 vold_key N/A در نظر گرفته شده برای استفاده توسط ولد.
101 odsing_key N/A توسط دیمون امضای روی دستگاه استفاده می شود.
102 wifi_key AID_WIFI (1010) توسط سیستم فای اندروید از جمله wpa_supplicant استفاده می شود.
120 resume_on_reboot_key AID_SYSTEM (1000) توسط سرور سیستم اندروید برای پشتیبانی از رزومه در راه اندازی مجدد استفاده می شود.

بردارهای دسترسی

keystore_key کلاس SELinux کمی قدیمی شده است و برخی از مجوزها مانند verify یا sign معنی خود را از دست داده اند. در اینجا مجموعه جدیدی از مجوزها، keystore2_key است که Keystore 2.0 اعمال خواهد کرد.

اجازه معنی
delete هنگام برداشتن کلیدها از Keystore بررسی شد.
get_info زمانی که فراداده یک کلید درخواست می شود بررسی می شود.
grant تماس‌گیرنده به این مجوز نیاز دارد تا یک اعطای کمک به کلید در زمینه هدف ایجاد کند.
manage_blob تماس گیرنده ممکن است از DOMAIN_BLOB در فضای نام SELinux داده شده استفاده کند، در نتیجه حباب ها را به تنهایی مدیریت می کند. این به طور خاص برای ولد مفید است.
rebind این مجوز کنترل می کند که آیا نام مستعار ممکن است به یک کلید جدید بازگردانده شود. این برای درج لازم است و به این معنی است که کلید قبلاً محدود شده حذف خواهد شد. این اساساً یک مجوز درج است، اما معنایی ذخیره کلید را بهتر نشان می دهد.
req_forced_op مشتریان با این مجوز ممکن است عملیات غیرقابل هرس ایجاد کنند، و ایجاد عملیات هرگز با شکست مواجه نمی شود مگر اینکه تمام شکاف های عملیات توسط عملیات غیرقابل هرس گرفته شوند.
update برای به روز رسانی جزء فرعی یک کلید لازم است.
use هنگام ایجاد یک عملیات Keymint که از مواد کلیدی استفاده می کند، به عنوان مثال، برای امضا، رمزگشایی/رمزگشایی، بررسی می شود.
use_dev_id هنگام تولید اطلاعات شناسایی دستگاه، مانند تأیید شناسه دستگاه، لازم است.

علاوه بر این، ما مجموعه ای از مجوزهای ذخیره کلید غیر کلیدی را در keystore2 کلاس امنیتی SELinux تقسیم می کنیم:

اجازه معنی
add_auth توسط ارائه‌دهنده احراز هویت مانند Gatekeeper یا BiometricsManager برای افزودن نشانه‌های احراز هویت مورد نیاز است.
clear_ns این مجوز که قبلا clear_uid بود، به یک غیر مالک فضای نام اجازه می دهد تا همه کلیدهای آن فضای نام را حذف کند.
list مورد نیاز سیستم برای شمارش کلیدها بر اساس ویژگی های مختلف، مانند مالکیت یا محدودیت اعتبار. این مجوز برای تماس گیرندگانی که فضای نام خود را شماره می کنند، لازم نیست. این توسط مجوز get_info پوشش داده می شود.
lock این مجوز امکان قفل کردن Keystore را فراهم می‌کند، یعنی کلید اصلی را خارج می‌کند، به طوری که کلیدهای auth bound غیرقابل استفاده و غیرقابل ایجاد شوند.
reset این مجوز امکان بازنشانی Keystore را به پیش‌فرض کارخانه، حذف تمام کلیدهایی که برای عملکرد سیستم عامل اندروید حیاتی نیستند، می‌دهد.
unlock این مجوز برای تلاش برای باز کردن قفل کلید اصلی برای کلیدهای محدود شده مورد نیاز است.
،

در دسترس بودن یک محیط اجرایی قابل اعتماد در یک سیستم بر روی یک تراشه (SoC) فرصتی را برای دستگاه‌های Android فراهم می‌کند تا خدمات امنیتی قوی و سخت‌افزاری را برای سیستم‌عامل Android، خدمات پلت‌فرم و حتی برنامه‌های شخص ثالث ارائه کنند. برنامه‌نویسانی که به دنبال برنامه‌های افزودنی مخصوص Android هستند باید به android.security.keystore مراجعه کنند.

قبل از اندروید 6.0، اندروید یک API خدمات رمزنگاری ساده و سخت افزاری داشت که توسط نسخه های 0.2 و 0.3 لایه انتزاعی سخت افزار Keymaster (HAL) ارائه شده بود. Keystore عملیات امضای دیجیتال و تأیید، به علاوه تولید و واردات جفت کلید امضای نامتقارن را ارائه می‌کرد. این در حال حاضر بر روی بسیاری از دستگاه ها اجرا شده است، اما اهداف امنیتی بسیاری وجود دارد که به راحتی تنها با یک API امضا نمی توان به آنها دست یافت. Keystore در Android 6.0 API Keystore را گسترش داد تا طیف وسیع تری از قابلیت ها را ارائه دهد.

در Android 6.0، Keystore رمزنگاری های اولیه متقارن ، AES و HMAC و یک سیستم کنترل دسترسی برای کلیدهای سخت افزاری را اضافه کرد. کنترل های دسترسی در طول تولید کلید مشخص می شوند و برای طول عمر کلید اجرا می شوند. کلیدها فقط پس از احراز هویت کاربر و فقط برای اهداف مشخص یا با پارامترهای رمزنگاری مشخص قابل استفاده هستند محدود شوند. برای اطلاعات بیشتر، به صفحات مجوز و برچسب ها مراجعه کنید.

علاوه بر گسترش دامنه رمزنگاری اولیه، Keystore در Android 6.0 موارد زیر را اضافه کرد:

  • یک طرح کنترل استفاده برای محدود کردن استفاده از کلید، برای کاهش خطر به خطر افتادن امنیت به دلیل استفاده نادرست از کلیدها
  • یک طرح کنترل دسترسی برای فعال کردن محدودیت کلیدها برای کاربران مشخص، مشتریان، و محدوده زمانی تعریف شده

در اندروید 7.0، Keymaster 2 پشتیبانی از گواهی کلید و اتصال نسخه را اضافه کرد. تأیید کلید، گواهی‌های کلید عمومی را ارائه می‌کند که حاوی شرح مفصلی از کلید و کنترل‌های دسترسی آن است تا وجود کلید در سخت‌افزار امن و پیکربندی آن از راه دور قابل تأیید باشد.

Version binding کلیدها را به سیستم عامل و نسخه سطح وصله متصل می کند. این تضمین می کند که مهاجمی که ضعفی را در نسخه قدیمی سیستم یا نرم افزار TEE کشف می کند، نمی تواند دستگاه را به نسخه آسیب پذیر برگرداند و از کلیدهای ایجاد شده با نسخه جدیدتر استفاده کند. علاوه بر این، هنگامی که کلیدی با یک نسخه معین و سطح وصله روی دستگاهی استفاده می‌شود که به نسخه جدیدتر یا سطح وصله ارتقا یافته است، کلید قبل از اینکه بتوان از آن استفاده کرد ارتقا داده می‌شود و نسخه قبلی کلید باطل می‌شود. با ارتقای دستگاه، کلیدها همراه با دستگاه به جلو حرکت می‌کنند، اما هرگونه بازگشت دستگاه به نسخه قبلی باعث می‌شود کلیدها غیرقابل استفاده باشند.

در اندروید 8.0، Keymaster 3 از لایه انتزاعی سخت افزاری ساختار C قدیمی (HAL) به رابط C++ HAL که از تعریفی در زبان تعریف رابط سخت افزاری جدید (HIDL) ایجاد شده بود، انتقال یافت. به عنوان بخشی از تغییر، بسیاری از انواع آرگومان ها تغییر کردند، اگرچه انواع و روش ها مطابقت یک به یک با انواع قدیمی و روش های ساختار HAL دارند. برای جزئیات بیشتر به صفحه توابع مراجعه کنید.

علاوه بر این ویرایش رابط، Android 8.0 ویژگی تأیید Keymaster 2 را برای پشتیبانی از تأیید شناسه گسترش داد. گواهی شناسه مکانیزم محدود و اختیاری را برای تأیید قوی شناسه های سخت افزاری مانند شماره سریال دستگاه، نام محصول و شناسه تلفن (IMEI / MEID) ارائه می دهد. برای پیاده سازی این افزوده، Android 8.0 طرح گواهی ASN.1 را برای افزودن گواهی ID تغییر داد. پیاده‌سازی‌های Keymaster باید راهی مطمئن برای بازیابی اقلام داده‌های مربوطه و همچنین تعریف مکانیزمی برای غیرفعال کردن ایمن و دائمی این ویژگی پیدا کنند.

در اندروید 9، به روز رسانی ها شامل:

  • به روز رسانی به Keymaster 4
  • پشتیبانی از عناصر امن جاسازی شده
  • پشتیبانی از واردات کلید امن
  • پشتیبانی از رمزگذاری 3DES
  • تغییرات در binding نسخه به طوری که boot.img و system.img به طور جداگانه نسخه هایی را تنظیم کرده اند تا امکان به روز رسانی مستقل را فراهم کنند.

واژه نامه

در اینجا یک مرور سریع از اجزای Keystore و روابط آنها ارائه شده است.

AndroidKeystore API و جزء Android Framework است که توسط برنامه ها برای دسترسی به عملکرد Keystore استفاده می شود. این به عنوان یک افزونه برای APIهای استاندارد معماری رمزنگاری جاوا پیاده سازی شده است و از کد جاوا تشکیل شده است که در فضای فرآیند خود برنامه اجرا می شود. AndroidKeystore درخواست‌های برنامه برای رفتار Keystore را با ارسال آن‌ها به شبح keystore برآورده می‌کند.

شبح کیستور یک دیمون سیستم اندرویدی است که دسترسی به تمام عملکردهای کیستور را از طریق Binder API فراهم می‌کند. مسئول ذخیره کردن «حباب‌های کلید» است که حاوی مواد کلید مخفی واقعی است، به طوری که Keystore بتواند آنها را ذخیره کند اما از آنها استفاده یا فاش نکند.

keymasterd یک سرور HIDL است که دسترسی به Keymaster TA را فراهم می کند. (این نام استاندارد نیست و برای اهداف مفهومی است.)

Keymaster TA (برنامه مورد اعتماد) نرم افزاری است که در یک زمینه ایمن اجرا می شود، اغلب در TrustZone روی یک SoC ARM، که تمام عملیات Keystore امن را فراهم می کند، به مواد کلید خام دسترسی دارد، همه شرایط کنترل دسترسی کلیدها را تأیید می کند. ، و غیره.

LockSettingsService جزء سیستم اندروید است که مسئول احراز هویت کاربر، رمز عبور و اثر انگشت است. این بخشی از Keystore نیست، اما مرتبط است زیرا بسیاری از عملیات کلید Keystore نیاز به احراز هویت کاربر دارند. LockSettingsService با Gatekeeper TA و Fingerprint TA تعامل می کند تا توکن های احراز هویت را به دست آورد که در اختیار دیمون keystore قرار می دهد و در نهایت توسط برنامه Keymaster TA مصرف می شود.

Gatekeeper TA (برنامه مورد اعتماد) مؤلفه دیگری است که در زمینه امن اجرا می شود و مسئول احراز هویت رمزهای عبور کاربر و تولید نشانه های احراز هویت است که برای اثبات به Keymaster TA استفاده می شود که احراز هویت برای یک کاربر خاص در یک مقطع زمانی خاص انجام شده است.

اثر انگشت TA (برنامه مورد اعتماد) مؤلفه دیگری است که در زمینه امن اجرا می شود و مسئول احراز هویت اثر انگشت کاربر و تولید نشانه های احراز هویت است که برای اثبات به Keymaster TA استفاده می شود که احراز هویت برای یک کاربر خاص در یک مقطع زمانی خاص انجام شده است.

معماری

Android Keystore API و Keymaster HAL زیربنایی، مجموعه‌ای اساسی اما کافی از رمزنگاری‌های اولیه را فراهم می‌کنند تا امکان اجرای پروتکل‌ها با استفاده از کلیدهای کنترل‌شده با دسترسی سخت‌افزاری را فراهم کنند.

Keymaster HAL یک کتابخانه OEM با قابلیت بارگذاری پویا است که توسط سرویس Keystore برای ارائه خدمات رمزنگاری سخت افزاری استفاده می شود. برای حفظ امنیت، پیاده سازی های HAL هیچ عملیات حساسی را در فضای کاربر یا حتی در فضای هسته انجام نمی دهند. عملیات حساس به یک پردازنده ایمن واگذار می شود که از طریق برخی از رابط های هسته قابل دسترسی است. معماری حاصل به این صورت است:

دسترسی به Keymaster

شکل 1. دسترسی به Keymaster

در یک دستگاه Android، "کلینت" Keymaster HAL از چندین لایه (به عنوان مثال برنامه، فریمورک، شبح Keystore) تشکیل شده است، اما برای اهداف این سند می توان از آن چشم پوشی کرد. این بدان معنی است که Keymaster HAL API در سطح پایینی است، توسط مؤلفه‌های داخلی پلتفرم استفاده می‌شود و در معرض توسعه‌دهندگان برنامه قرار نمی‌گیرد. API سطح بالاتر در سایت توسعه دهنده Android توضیح داده شده است.

هدف Keymaster HAL پیاده سازی الگوریتم های حساس به امنیت نیست، بلکه فقط مارشال و حذف درخواست ها به دنیای امن است. قالب سیم پیاده سازی شده است.

سازگاری با نسخه های قبلی

Keymaster 1 HAL کاملاً با HAL های منتشر شده قبلی، به عنوان مثال Keymaster 0.2 و 0.3 ناسازگار است. برای تسهیل قابلیت همکاری در دستگاه‌های دارای Android نسخه 5.0 و نسخه‌های قدیمی‌تر که با Keymaster HAL‌های قدیمی‌تر راه‌اندازی شده‌اند، Keystore آداپتوری ارائه می‌کند که Keymaster 1 HAL را با فراخوانی به کتابخانه سخت‌افزار موجود پیاده‌سازی می‌کند. نتیجه نمی تواند طیف کاملی از عملکردها را در Keymaster 1 HAL ارائه دهد. به طور خاص، فقط از الگوریتم‌های RSA و ECDSA پشتیبانی می‌کند و تمام اجرای مجوزهای کلیدی توسط آداپتور در دنیای غیر ایمن انجام می‌شود.

Keymaster 2 رابط HAL را با حذف متدهای get_supported_* ساده‌تر کرد و به متد finish() اجازه داد ورودی را بپذیرد. این باعث کاهش تعداد رفت و برگشت به TEE در مواردی می شود که ورودی به یکباره در دسترس است و اجرای رمزگشایی AEAD را ساده می کند.

در اندروید 8.0، Keymaster 3 از ساختار قدیمی HAL به رابط C++ HAL که از تعریفی در زبان تعریف رابط سخت افزاری جدید (HIDL) ایجاد شده بود، انتقال یافت. یک پیاده سازی HAL به سبک جدید با زیرکلاس بندی کلاس IKeymasterDevice تولید شده و پیاده سازی روش های مجازی خالص ایجاد می شود. به عنوان بخشی از تغییر، بسیاری از انواع آرگومان ها تغییر کرده اند، اگرچه انواع و روش ها مطابقت یک به یک با انواع قدیمی و روش های ساختار HAL دارند.

نمای کلی HIDL

زبان تعریف رابط سخت افزاری (HIDL) مکانیزمی مستقل از زبان پیاده سازی برای تعیین رابط های سخت افزاری ارائه می دهد. ابزار HIDL در حال حاضر از تولید رابط های C++ و جاوا پشتیبانی می کند. انتظار می‌رود که اکثر پیاده‌کننده‌های Trusted Execution Environment (TEE) ابزار C++ را راحت‌تر بیابند، بنابراین این سند فقط نمایش C++ را مورد بحث قرار می‌دهد.

رابط های HIDL شامل مجموعه ای از روش ها هستند که به صورت زیر بیان می شوند:

  methodName(INPUT ARGUMENTS) generates (RESULT ARGUMENTS);

انواع مختلفی از پیش تعریف شده وجود دارد، و HAL ها می توانند انواع جدید برشماری و ساختاری را تعریف کنند. برای جزئیات بیشتر در مورد 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 تابعی است که مقادیر بازگشتی فهرست شده در عبارت generate را می گیرد. کلاس پیاده سازی 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، می توانیم فضاهای نام را از UID ها جدا کنیم. مشتریانی که به یک کلید در Keystore دسترسی دارند، باید دامنه، فضای نام و نام مستعاری را که می خواهند به آن دسترسی داشته باشند، مشخص کنند. بر اساس این تاپل و هویت تماس گیرنده، می توانیم تعیین کنیم که تماس گیرنده به کدام کلید می خواهد دسترسی داشته باشد و آیا مجوزهای مناسبی دارد یا خیر.

ما پنج پارامتر دامنه را معرفی می کنیم که نحوه دسترسی به کلیدها را کنترل می کند. آنها معنای پارامتر فضای نام توصیفگر کلید و نحوه کنترل دسترسی را کنترل می کنند.

  • DOMAIN_APP : دامنه برنامه رفتار قدیمی را پوشش می دهد. Java Keystore SPI به طور پیش فرض از این دامنه استفاده می کند. وقتی از این دامنه استفاده می شود، آرگومان فضای نام نادیده گرفته می شود و به جای آن از UID تماس گیرنده استفاده می شود. دسترسی به این دامنه توسط برچسب Keystore به کلاس 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
فروشنده 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.