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.