Fungsi KeyMint

Halaman ini memberikan detail dan panduan tambahan untuk membantu penerapan hardware abstraction layer (HAL) KeyMint. Dokumentasi utama untuk HAL adalah spesifikasi antarmuka AIDL.

Penyalahgunaan API

Pemanggil dapat membuat kunci KeyMint dengan otorisasi yang valid sebagai parameter API, tetapi yang membuat kunci yang dihasilkan tidak aman atau tidak dapat digunakan. Implementasi KeyMint tidak diwajibkan untuk gagal dalam kasus tersebut atau mengeluarkan diagnostik. Penggunaan kunci yang terlalu kecil, spesifikasi parameter input yang tidak relevan, penggunaan ulang IV atau nonce, pembuatan kunci tanpa tujuan (sehingga tidak berguna), dan sejenisnya tidak boleh didiagnosis oleh implementasi.

Aplikasi, framework, dan Android Keystore bertanggung jawab untuk memastikan bahwa panggilan ke modul KeyMint masuk akal dan berguna.

Titik entri addRngEntropy

Titik entri addRngEntropy menambahkan entropi yang disediakan pemanggil ke pool yang digunakan oleh implementasi KeyMint untuk menghasilkan angka acak, untuk kunci dan IV.

Implementasi KeyMint harus mencampur entropy yang diberikan secara aman ke dalam pool-nya, yang juga harus berisi entropy yang dihasilkan secara internal dari generator angka acak hardware. Pencampuran harus ditangani sehingga penyerang yang memiliki kontrol penuh atas bit yang disediakan addRngEntropy atau bit yang dihasilkan hardware (tetapi tidak keduanya) tidak memiliki keuntungan signifikan dalam memprediksi bit yang dihasilkan dari kumpulan entropi.

Karakteristik utama

Setiap mekanisme (generateKey, importKey, dan importWrappedKey) yang membuat kunci KeyMint menampilkan karakteristik kunci yang baru dibuat, yang dibagi dengan tepat ke dalam tingkat keamanan yang menerapkan setiap karakteristik. Karakteristik yang ditampilkan mencakup semua parameter yang ditentukan untuk pembuatan kunci, kecuali Tag::APPLICATION_ID dan Tag::APPLICATION_DATA. Jika tag ini disertakan dalam parameter utama, tag tersebut akan dihapus dari karakteristik yang ditampilkan sehingga nilainya tidak dapat ditemukan dengan memeriksa keyblob yang ditampilkan. Namun, nilai tersebut terikat secara kriptografis ke keyblob, sehingga jika nilai yang benar tidak diberikan saat kunci digunakan, penggunaan akan gagal. Demikian pula, Tag::ROOT_OF_TRUST terikat secara kriptografis ke kunci, tetapi tidak dapat ditentukan selama pembuatan atau impor kunci dan tidak pernah ditampilkan.

Selain tag yang disediakan, implementasi KeyMint juga menambahkan Tag::ORIGIN, yang menunjukkan cara kunci dibuat (KeyOrigin::GENERATED, KeyOrigin::IMPORTED, atau KeyOrigin::SECURELY_IMPORTED).

Ketahanan rollback

Ketahanan terhadap rollback ditunjukkan dengan Tag::ROLLBACK_RESISTANCE, dan berarti bahwa setelah kunci dihapus dengan deleteKey atau deleteAllKeys, hardware yang aman memastikan kunci tersebut tidak dapat digunakan lagi.

Implementasi KeyMint menampilkan materi kunci yang dibuat atau diimpor ke pemanggil sebagai keyblob, yaitu bentuk terenkripsi dan diautentikasi. Saat Keystore menghapus keyblob, kunci akan hilang, tetapi penyerang yang sebelumnya berhasil mengambil materi kunci berpotensi memulihkannya ke perangkat.

Kunci tahan terhadap rollback jika hardware yang aman memastikan bahwa kunci yang dihapus tidak dapat dipulihkan di kemudian hari. Hal ini umumnya dilakukan dengan menyimpan metadata kunci tambahan di lokasi tepercaya yang tidak dapat dimanipulasi oleh penyerang. Di perangkat seluler, mekanisme yang digunakan untuk hal ini biasanya adalah blok memori yang dilindungi dari pemutaran ulang (RPMB). Karena jumlah kunci yang dapat dibuat pada dasarnya tidak terbatas dan penyimpanan tepercaya yang digunakan untuk ketahanan terhadap rollback mungkin terbatas ukurannya, penerapan dapat gagal memenuhi permintaan untuk membuat kunci yang tahan terhadap rollback saat penyimpanan penuh.

begin

Titik entri begin() memulai operasi kriptografi menggunakan kunci yang ditentukan, untuk tujuan yang ditentukan, dengan parameter yang ditentukan (sebagaimana mestinya). Fungsi ini menampilkan objek Binder IKeyMintOperation baru yang digunakan untuk menyelesaikan operasi. Selain itu, nilai tantangan yang dikembalikan digunakan sebagai bagian dari token otentikasi dalam operasi yang diautentikasi.

Implementasi KeyMint mendukung minimal 16 operasi serentak. Keystore menggunakan hingga 15, sehingga menyisakan satu untuk digunakan vold untuk enkripsi sandi. Jika Keystore memiliki 15 operasi yang sedang berlangsung (begin() telah dipanggil, tetapi finish atau abort belum dipanggil) dan menerima permintaan untuk memulai operasi ke-16, Keystore akan memanggil abort() pada operasi yang terakhir digunakan untuk mengurangi jumlah operasi aktif menjadi 14 sebelum memanggil begin() untuk memulai operasi yang baru diminta.

Jika Tag::APPLICATION_ID atau Tag::APPLICATION_DATA ditentukan selama pembuatan atau impor kunci, panggilan ke begin() harus menyertakan tag tersebut dengan nilai yang ditentukan semula dalam argumen params ke metode ini.

Penanganan error

Jika metode pada IKeyMintOperation menampilkan kode error selain ErrorCode::OK, operasi akan dibatalkan dan objek Binder operasi akan dibatalkan. Penggunaan objek di masa mendatang akan menampilkan ErrorCode::INVALID_OPERATION_HANDLE.

Penerapan otorisasi

Penerapan otorisasi kunci dilakukan terutama di begin(). Satu-satunya pengecualian adalah jika kunci memiliki satu atau beberapa nilai Tag::USER_SECURE_ID, dan tidak memiliki nilai Tag::AUTH_TIMEOUT.

Dalam hal ini, kunci memerlukan otorisasi per operasi, dan metode update() atau finish() menerima token otorisasi dalam argumen authToken. Untuk memastikan bahwa token valid, penerapan KeyMint:

  • Memverifikasi tanda tangan HMAC pada token auth.
  • Memeriksa apakah token berisi ID pengguna aman yang cocok dengan ID pengguna yang terkait dengan kunci.
  • Memeriksa apakah jenis autentikasi token cocok dengan Tag::USER_AUTH_TYPE kunci.
  • Memeriksa apakah token berisi nilai tantangan untuk operasi saat ini di kolom tantangan.

Jika kondisi ini tidak terpenuhi, KeyMint akan menampilkan ErrorCode::KEY_USER_NOT_AUTHENTICATED.

Pemanggil memberikan token autentikasi ke setiap panggilan ke update() dan finish(). Penerapan hanya dapat memvalidasi token satu kali.