Ketersediaan Trusted Execution Environment (TEE) dalam sistem di chip (SoC) memberikan peluang bagi perangkat Android untuk menyediakan layanan keamanan yang kuat dan didukung hardware, ke Android OS, layanan platform, dan bahkan ke aplikasi pihak ketiga (dalam bentuk ekstensi khusus Android ke Java Cryptography Architecture standar, lihat KeyGenParameterSpec).
Glosarium
Berikut ringkasan singkat komponen Keystore dan hubungannya.
AndroidKeyStore- Android Framework API dan komponen yang digunakan
oleh aplikasi untuk mengakses fungsi Keystore. API ini adalah implementasi dari
Java Cryptography Architecture standar, tetapi juga menambahkan ekstensi khusus Android
dan terdiri dari kode Java yang berjalan di ruang proses aplikasi sendiri.
AndroidKeyStorememenuhi permintaan aplikasi untuk perilaku Keystore dengan meneruskannya ke daemon keystore. - daemon keystore
- Daemon sistem Android yang menyediakan akses ke semua fungsi Keystore melalui Binder API. Daemon ini bertanggung jawab untuk menyimpan keyblob yang dibuat oleh implementasi KeyMint (atau Keymaster) yang mendasarinya, yang berisi materi kunci rahasia, dienkripsi sehingga Keystore dapat menyimpannya, tetapi tidak menggunakannya atau mengungkapkannya.
- Layanan KeyMint HAL
- Server AIDL yang mengimplementasikan
IKeyMintDeviceHAL, yang menyediakan akses ke KeyMint TA yang mendasarinya. - Aplikasi tepercaya KeyMint (TA)
- Software yang berjalan dalam konteks yang aman, paling sering di TrustZone pada ARM SoC, yang menyediakan semua operasi kriptografi yang aman. Aplikasi ini memiliki akses ke materi kunci mentah, dan memvalidasi semua kondisi kontrol akses pada kunci sebelum mengizinkan penggunaannya.
LockSettingsService- Komponen sistem Android yang bertanggung jawab atas autentikasi pengguna, baik sandi maupun
sidik jari. Komponen ini bukan bagian dari Keystore, tetapi relevan karena Keystore mendukung konsep
kunci terikat autentikasi: kunci yang hanya dapat digunakan jika pengguna telah diautentikasi.
LockSettingsServiceberinteraksi dengan Gatekeeper TA dan Fingerprint TA untuk mendapatkan token autentikasi, yang diberikannya ke daemon keystore, dan yang digunakan oleh KeyMint TA. - Gatekeeper TA
- Komponen yang berjalan di lingkungan aman yang bertanggung jawab untuk mengautentikasi sandi pengguna dan membuat token autentikasi yang digunakan untuk membuktikan kepada KeyMint TA bahwa autentikasi telah dilakukan untuk pengguna tertentu pada waktu tertentu.
- Fingerprint TA
- Komponen yang berjalan di lingkungan aman yang bertanggung jawab untuk mengautentikasi sidik jari pengguna dan membuat token autentikasi yang digunakan untuk membuktikan kepada KeyMint TA bahwa autentikasi telah dilakukan untuk pengguna tertentu pada waktu tertentu.
Arsitektur
Android Keystore API dan KeyMint HAL yang mendasarinya menyediakan kumpulan primitif kriptografi dasar tetapi memadai untuk memungkinkan penerapan protokol menggunakan kunci yang didukung hardware dan dikontrol aksesnya.
KeyMint HAL adalah layanan yang disediakan OEM yang digunakan oleh layanan Keystore untuk menyediakan layanan kriptografi yang didukung hardware. Untuk menjaga keamanan materi kunci pribadi, implementasi HAL tidak melakukan operasi sensitif apa pun di ruang pengguna, atau bahkan di ruang kernel. Sebagai gantinya, layanan KeyMint HAL yang berjalan di Android mendelegasikan operasi sensitif ke TA yang berjalan di beberapa jenis lingkungan yang aman, biasanya dengan mengumpulkan dan mengurai permintaan dalam beberapa format kabel yang ditentukan implementasinya.
Arsitektur yang dihasilkan terlihat seperti ini:
Gambar 1. Akses ke KeyMint.
KeyMint HAL API memiliki level rendah, digunakan oleh komponen internal platform, dan tidak diekspos ke developer aplikasi. Java API level yang lebih tinggi yang tersedia untuk aplikasi dijelaskan di situs Android Developer.
Kontrol akses
Android Keystore menyediakan komponen pusat untuk penyimpanan dan penggunaan kunci kriptografi yang didukung hardware, baik untuk aplikasi maupun untuk komponen sistem lainnya. Oleh karena itu, akses ke setiap kunci biasanya dibatasi untuk aplikasi atau komponen sistem yang membuat kunci.
Domain Keystore
Untuk mendukung kontrol akses ini, kunci diidentifikasi ke Keystore dengan deskriptor kunci. Deskriptor kunci ini menunjukkan domain yang dimiliki deskriptor, bersama dengan identitas dalam domain tersebut.
Aplikasi Android mengakses Keystore menggunakan Java Cryptography Architecture standar, yang mengidentifikasi kunci dengan alias string. Metode identifikasi ini dipetakan ke domain APP Keystore secara internal; UID pemanggil juga disertakan untuk membedakan kunci dari aplikasi yang berbeda, sehingga mencegah satu aplikasi mengakses kunci aplikasi lain.
Secara internal, kode framework juga menerima ID kunci numerik unik setelah kunci dimuat. ID numerik ini digunakan sebagai ID untuk deskriptor kunci dalam domain KEY_ID. Namun, kontrol akses masih dilakukan: meskipun satu aplikasi menemukan ID kunci untuk kunci aplikasi lain, aplikasi tersebut tidak dapat menggunakannya dalam keadaan normal.
Namun, aplikasi dapat memberikan penggunaan kunci ke aplikasi lain (seperti yang diidentifikasi oleh UID). Operasi pemberian ini menampilkan ID pemberian unik, yang digunakan sebagai ID untuk deskriptor kunci dalam domain GRANT. Sekali lagi, kontrol akses masih dilakukan: meskipun aplikasi ketiga menemukan ID pemberian untuk kunci penerima, aplikasi tersebut tidak dapat menggunakannya.
Keystore juga mendukung dua domain lain untuk deskriptor kunci, yang digunakan untuk komponen sistem lain dan tidak tersedia untuk kunci yang dibuat aplikasi:
- Domain
BLOBmenunjukkan bahwa tidak ada ID untuk kunci dalam deskriptor kunci; sebagai gantinya, deskriptor kunci menyimpan keyblob itu sendiri dan klien menangani penyimpanan keyblob. Domain ini digunakan oleh klien (misalnya,vold) yang perlu mengakses Keystore sebelum partisi data dipasang. - Domain
SELINUXmemungkinkan komponen sistem berbagi kunci, dengan akses yang diatur oleh ID numerik yang sesuai dengan label SELinux (lihat kebijakan SELinux untuk keystore_key).
Kebijakan SELinux untuk keystore_key
Nilai ID yang digunakan untuk deskriptor kunci Domain::SELINUX dikonfigurasi dalam file kebijakan SELinux keystore2_key_context.
Setiap baris dalam file ini memetakan numerik ke label SELinux, misalnya:
# 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
Komponen yang memerlukan akses ke kunci dengan ID 102 dalam domain SELINUX harus memiliki kebijakan SELinux yang sesuai. Misalnya, untuk mengizinkan wpa_supplicant mendapatkan dan menggunakan kunci ini, tambahkan baris berikut ke hal_wifi_supplicant.te:
allow hal_wifi_supplicant wifi_key:keystore2_key { get, use };
ID numerik untuk kunci Domain::SELINUX dibagi menjadi rentang untuk mendukung partisi yang berbeda tanpa konflik:
| Partisi | Rentang | File konfigurasi |
|---|---|---|
| Sistem | 0 ... 9.999 | /system/etc/selinux/keystore2_key_contexts, /plat_keystore2_key_contexts
|
| Sistem Diperpanjang | 10.000 ... 19.999 | /system_ext/etc/selinux/system_ext_keystore2_key_contexts, /system_ext_keystore2_key_contexts
|
| Produk | 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
|
Nilai spesifik berikut telah ditentukan untuk partisi sistem:
| ID Ruangnama | Label SEPolicy | UID | Deskripsi |
|---|---|---|---|
| 0 | su_key |
T/A | Kunci super user. Hanya digunakan untuk pengujian pada build userdebug dan eng. Tidak relevan pada build pengguna. |
| 1 | shell_key |
T/A | Ruang nama tersedia untuk shell. Sebagian besar digunakan untuk pengujian, tetapi juga dapat digunakan pada build pengguna dari command line. |
| 100 | vold_key |
T/A | Ditujukan untuk digunakan oleh vold. |
| 101 | odsign_key |
T/A | Digunakan oleh daemon penandatanganan di perangkat. |
| 102 | wifi_key |
AID_WIFI(1010) |
Digunakan oleh subsistem Wi-Fi Android, termasuk wpa_supplicant. |
| 103 | locksettings_key |
T/A | Digunakan oleh LockSettingsService |
| 120 | resume_on_reboot_key |
AID_SYSTEM(1000) |
Digunakan oleh server sistem Android untuk mendukung resume saat memulai ulang. |
Vektor akses
Keystore memungkinkan kontrol atas operasi yang dapat dilakukan pada kunci, selain mengontrol akses keseluruhan ke kunci. Izin keystore2_key
dijelaskan dalam
file KeyPermission.aidl.
Izin sistem
Selain kontrol akses per kunci yang dijelaskan dalam kebijakan SELinux untuk keystore_key, tabel berikut menjelaskan izin SELinux lainnya yang diperlukan untuk melakukan berbagai operasi sistem dan pemeliharaan:
| Izin | Arti |
|---|---|
add_auth
|
Diperlukan untuk menambahkan token autentikasi ke Keystore; digunakan oleh penyedia autentikasi seperti Gatekeeper atau BiometricManager. |
clear_ns
|
Diperlukan untuk menghapus semua kunci dalam namespace tertentu; digunakan sebagai operasi pemeliharaan saat aplikasi di-uninstal. |
list
|
Diperlukan oleh sistem untuk menghitung kunci berdasarkan berbagai properti, seperti kepemilikan atau apakah kunci tersebut terikat autentikasi. Izin ini tidak diperlukan oleh pemanggil yang menghitung namespace mereka sendiri (yang tercakup dalam izin get_info). |
lock
|
Diperlukan untuk memberi tahu keystore bahwa perangkat dikunci, yang pada gilirannya akan mengeluarkan kunci super untuk memastikan bahwa kunci terikat autentikasi tidak tersedia. |
unlock
|
Diperlukan untuk memberi tahu keystore bahwa perangkat tidak terkunci, sehingga memulihkan akses ke kunci super yang melindungi kunci terikat autentikasi. |
reset
|
Diperlukan untuk mereset Keystore ke default pabrik, menghapus semua kunci yang tidak penting untuk fungsi Android OS. |
Histori
Di Android 5 dan yang lebih rendah, Android memiliki API layanan kriptografi sederhana yang didukung hardware, yang disediakan oleh hardware abstraction layer (HAL) Keymaster versi 0.2 dan 0.3. Keystore menyediakan operasi penandatanganan dan verifikasi digital, serta pembuatan dan impor pasangan kunci penandatanganan asimetris. Hal ini sudah diterapkan di banyak perangkat, tetapi ada banyak tujuan keamanan yang tidak dapat dicapai dengan mudah hanya dengan API tanda tangan. Android 6.0 memperluas Keystore API untuk menyediakan berbagai kemampuan yang lebih luas.
Android 6.0
Di Android 6.0, Keymaster 1.0 menambahkan primitif kriptografi simetris, AES dan HMAC, serta sistem kontrol akses untuk kunci yang didukung hardware. Kontrol akses ditentukan selama pembuatan kunci dan diterapkan selama masa aktif kunci. Kunci dapat dibatasi agar hanya dapat digunakan setelah pengguna diautentikasi, dan hanya untuk tujuan tertentu atau dengan parameter kriptografi tertentu.
Selain memperluas rentang primitif kriptografi, Keystore di Android 6.0 menambahkan hal berikut:
- Skema kontrol penggunaan untuk memungkinkan penggunaan kunci dibatasi, guna mengurangi risiko kompromi keamanan karena penyalahgunaan kunci
- Skema kontrol akses untuk memungkinkan pembatasan kunci ke pengguna, klien, dan rentang waktu tertentu
Android 7.0
Di Android 7.0, Keymaster 2 menambahkan dukungan untuk pengesahan kunci dan pengikatan versi.
Pengesahan kunci menyediakan sertifikat kunci publik yang berisi deskripsi mendetail tentang kunci dan kontrol aksesnya, untuk membuat keberadaan kunci dalam hardware yang aman dan konfigurasinya dapat diverifikasi dari jarak jauh.
Pengikatan versi mengikat kunci ke sistem operasi dan versi tingkat patch. Hal ini memastikan bahwa penyerang yang menemukan kelemahan dalam versi lama sistem atau software TEE tidak dapat mengembalikan perangkat ke versi yang rentan dan menggunakan kunci yang dibuat dengan versi yang lebih baru. Selain itu, saat kunci dengan versi dan tingkat patch tertentu digunakan di perangkat yang telah diupgrade ke versi atau tingkat patch yang lebih baru, kunci akan diupgrade sebelum dapat digunakan, dan versi kunci sebelumnya akan dibatalkan. Saat perangkat diupgrade, kunci akan diupgrade bersama dengan perangkat, tetapi setiap pengembalian perangkat ke rilis sebelumnya akan menyebabkan kunci tidak dapat digunakan.
Android 8.0
Di Android 8.0, Keymaster 3 bertransisi dari HAL struktur C gaya lama ke antarmuka HAL C++ yang dihasilkan dari definisi dalam hardware interface definition language (HIDL) baru. Sebagai bagian dari perubahan ini, banyak jenis argumen yang berubah, meskipun jenis dan metode memiliki korespondensi satu-ke-satu dengan jenis lama dan metode struct HAL.
Selain revisi antarmuka ini, Android 8.0 memperluas fitur pengesahan Keymaster 2 untuk mendukung pengesahan ID. Pengesahan ID menyediakan mekanisme terbatas dan opsional untuk mengesahkan ID hardware dengan kuat, seperti nomor seri perangkat, nama produk, dan ID ponsel (IMEI atau MEID). Untuk menerapkan penambahan ini, Android 8.0 mengubah skema pengesahan ASN.1 untuk menambahkan pengesahan ID. Implementasi Keymaster perlu menemukan cara yang aman untuk mengambil item data yang relevan, serta menentukan mekanisme untuk menonaktifkan fitur secara aman dan permanen.
Android 9
Di Android 9, update mencakup:
- Update ke Keymaster 4
- Dukungan untuk Secure Element tersemat
- Dukungan untuk impor kunci yang aman
- Dukungan untuk enkripsi 3DES
- Perubahan pada pengikatan versi sehingga
boot.imgdansystem.imgmemiliki versi yang ditetapkan secara terpisah untuk memungkinkan update independen
Android 10
Android 10 memperkenalkan Keymaster HAL versi 4.1, yang menambahkan:
- Dukungan untuk kunci yang hanya dapat digunakan saat perangkat tidak terkunci
- Dukungan untuk kunci yang hanya dapat digunakan pada tahap booting awal
- Dukungan opsional untuk kunci penyimpanan yang dienkapsulasi hardware
- Dukungan opsional untuk pengesahan unik perangkat di StrongBox
Android 12
Android 12 memperkenalkan KeyMint HAL baru, yang menggantikan Keymaster HAL tetapi menyediakan fungsi yang serupa. Selain semua fitur di atas, KeyMint HAL juga mencakup:
- Dukungan untuk perjanjian kunci ECDH
- Dukungan untuk kunci pengesahan yang ditentukan pengguna
- Dukungan untuk kunci dengan jumlah penggunaan terbatas
Android 12 juga menyertakan versi baru daemon sistem keystore, yang ditulis ulang di Rust dan dikenal sebagai keystore2
Android 13
Android 13 menambahkan KeyMint HAL v2, yang menambahkan dukungan untuk Curve25519 untuk penandatanganan dan perjanjian kunci.