Fungsi KeyMint

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

Penyalahgunaan API

Pemanggil dapat membuat kunci KeyMint dengan otorisasi yang valid sebagai parameter API, tetapi hal ini akan membuat kunci yang dihasilkan tidak aman atau tidak dapat digunakan. Implementasi KeyMint tidak diperlukan untuk gagal dalam kasus tersebut atau mengeluarkan diagnostik. Penggunaan kunci yang terlalu kecil, spesifikasi parameter input yang tidak relevan, penggunaan kembali 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 kumpulan yang digunakan oleh implementasi KeyMint untuk menghasilkan angka acak, untuk kunci dan IV.

Implementasi KeyMint harus mencampurkan entropi yang disediakan ke dalam kumpulannya dengan aman, yang juga harus berisi entropi yang dihasilkan secara internal dari generator angka acak hardware. Penggabungan harus ditangani sehingga penyerang yang memiliki kontrol penuh atas bit yang disediakan addRngEntropy atau bit yang dihasilkan hardware (tetapi tidak keduanya) tidak memiliki keunggulan yang 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 secara 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 disertakan dalam parameter kunci, tag ini akan dihapus dari karakteristik yang ditampilkan sehingga nilainya tidak dapat ditemukan dengan memeriksa keyblob yang ditampilkan. Namun, kunci 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

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

Implementasi KeyMint menampilkan materi kunci yang dibuat atau diimpor ke pemanggil sebagai keyblob, 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 rollback jika hardware aman memastikan bahwa kunci yang dihapus tidak dapat dipulihkan nanti. 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 ini biasanya adalah blok memori yang dilindungi replay (RPMB). Karena jumlah kunci yang dapat dibuat pada dasarnya tidak terbatas dan penyimpanan tepercaya yang digunakan untuk ketahanan rollback mungkin memiliki ukuran terbatas, penerapan dapat membuat permintaan gagal untuk membuat kunci yang tahan rollback saat penyimpanan penuh.

begin

Titik entri begin() memulai operasi kriptografis menggunakan kunci yang ditentukan, untuk tujuan yang ditentukan, dengan parameter yang ditentukan (sesuai kebutuhan). Fungsi ini menampilkan objek Binder IKeyMintOperation baru yang digunakan untuk menyelesaikan operasi. Selain itu, nilai tantangan ditampilkan yang digunakan sebagai bagian dari token autentikasi dalam operasi yang diautentikasi.

Implementasi KeyMint mendukung minimal 16 operasi serentak. Keystore menggunakan hingga 15, menyisakan satu untuk vold yang akan digunakan 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 paling jarang 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 awalnya dalam argumen params ke metode ini.

Penanganan error

Jika metode di IKeyMintOperation menampilkan kode error selain ErrorCode::OK, operasi akan dibatalkan dan objek Binder operasi akan dibatalkan validasinya. Setiap 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 autentikasi dalam argumen authToken. Untuk memastikan token valid, penerapan KeyMint:

  • Memverifikasi tanda tangan HMAC pada token autentikasi.
  • Memeriksa apakah token berisi ID pengguna aman yang cocok dengan ID 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(). Implementasi hanya dapat memvalidasi token satu kali.