Di Keymaster 1, semua kunci keymaster terikat secara kriptografis ke perangkat Root of Trust , atau kunci Boot Terverifikasi. Di Keymaster 2 dan 3, semua kunci juga terikat ke sistem operasi dan tingkat patch dari citra sistem. Ini memastikan bahwa penyerang yang menemukan kelemahan dalam sistem versi lama atau perangkat lunak TEE tidak dapat mengembalikan perangkat ke versi yang rentan dan menggunakan kunci yang dibuat dengan versi yang lebih baru. Selain itu, ketika kunci dengan versi dan level tambalan tertentu digunakan pada perangkat yang telah ditingkatkan ke versi atau tingkat tambalan yang lebih baru, kunci dimutakhirkan sebelum dapat digunakan, dan versi kunci sebelumnya menjadi tidak valid. Dengan cara ini, saat perangkat ditingkatkan, kunci akan "bergerak" maju bersama dengan perangkat, tetapi setiap pengembalian perangkat ke rilis sebelumnya akan menyebabkan kunci tidak dapat digunakan.
Untuk mendukung struktur modular Treble dan memutuskan pengikatan system.img ke boot.img, Keymaster 4 mengubah model pengikatan versi kunci untuk memiliki level tambalan terpisah untuk setiap partisi. Ini memungkinkan setiap partisi diperbarui secara independen, sambil tetap memberikan perlindungan rollback.
Di Android 9, partisi boot
, system
, dan vendor
masing-masing memiliki level patchnya sendiri.
- Perangkat dengan Android Verified Boot (AVB) dapat menempatkan semua level patch dan versi sistem di vbmeta, sehingga bootloader dapat memberikannya ke Keymaster. Untuk partisi berantai, info versi untuk partisi akan berada di vbmeta berantai. Secara umum, informasi versi harus berada di
vbmeta struct
yang berisi data verifikasi (hash atau hashtree) untuk partisi tertentu. - Pada perangkat tanpa AVB:
- Implementasi Boot Terverifikasi perlu memberikan hash dari metadata versi ke bootloader, sehingga bootloader dapat memberikan hash ke Keymaster.
-
boot.img
dapat terus menyimpan level patch di header -
system.img
dapat terus menyimpan level patch dan versi OS di properti read-only -
vendor.img
menyimpan level patch di properti read-onlyro.vendor.build.version.security_patch
. - Bootloader dapat memberikan hash dari semua data yang divalidasi oleh boot terverifikasi ke keymaster.
- Di Android 9, gunakan tag berikut untuk menyediakan informasi versi untuk partisi berikut:
-
VENDOR_PATCH_LEVEL
: partisivendor
-
BOOT_PATCH_LEVEL
: partisiboot
-
OS_PATCH_LEVEL
danOS_VERSION
: partisisystem
. (OS_VERSION
dihapus dari headerboot.img
.
-
- Implementasi keymaster harus memperlakukan semua level patch secara independen. Kunci dapat digunakan jika semua info versi cocok dengan nilai yang terkait dengan kunci, dan
IKeymaster::upgradeDevice()
bergulir ke tingkat patch yang lebih tinggi jika diperlukan.
Perubahan HAL
Untuk mendukung pengikatan versi dan pengesahan versi, Android 7.1 menambahkan tag Tag::OS_VERSION
dan Tag::OS_PATCHLEVEL
serta metode configure
dan upgradeKey
. Tag versi secara otomatis ditambahkan oleh implementasi Keymaster 2+ ke semua kunci yang baru dibuat (atau diperbarui). Selanjutnya, setiap upaya untuk menggunakan kunci yang masing-masing tidak memiliki versi OS atau level patch yang cocok dengan versi OS sistem atau level patch saat ini, ditolak dengan ErrorCode::KEY_REQUIRES_UPGRADE
.
Tag::OS_VERSION
adalah nilai UINT
yang mewakili bagian mayor, minor, dan sub-minor dari versi sistem Android sebagai MMmmss, di mana MM adalah versi mayor, mm adalah versi minor, dan ss adalah versi sub-minor. Misalnya 6.1.2 akan direpresentasikan sebagai 060102.
Tag::OS_PATCHLEVEL
adalah nilai UINT
yang mewakili tahun dan bulan dari pembaruan terakhir ke sistem sebagai YYYYMM, di mana YYYY adalah tahun empat digit dan MM adalah bulan dua digit. Misalnya, Maret 2016 akan direpresentasikan sebagai 201603.
UpgradeKey
Untuk mengizinkan kunci diupgrade ke versi OS baru dan tingkat patch dari citra sistem, Android 7.1 menambahkan metode upgradeKey
ke HAL:
Ketua 3
upgradeKey(vec keyBlobToUpgrade, vec upgradeParams) generates(ErrorCode error, vec upgradedKeyBlob);
Master kunci 2
keymaster_error_t (*upgrade_key)(const struct keymaster2_device* dev, const keymaster_key_blob_t* key_to_upgrade, const keymaster_key_param_set_t* upgrade_params, keymaster_key_blob_t* upgraded_key);
-
dev
adalah struktur perangkat -
keyBlobToUpgrade
adalah kunci yang perlu ditingkatkan -
upgradeParams
adalah parameter yang diperlukan untuk memutakhirkan kunci. Ini akan mencakupTag::APPLICATION_ID
danTag::APPLICATION_DATA
, yang diperlukan untuk mendekripsi gumpalan kunci, jika diberikan selama pembuatan. -
upgradedKeyBlob
adalah parameter keluaran, digunakan untuk mengembalikan gumpalan kunci baru.
Jika upgradeKey
dipanggil dengan gumpalan kunci yang tidak dapat diuraikan atau tidak valid, ia mengembalikan ErrorCode::INVALID_KEY_BLOB
. Jika dipanggil dengan kunci yang tingkat tambalannya lebih besar dari nilai sistem saat ini, ia mengembalikan ErrorCode::INVALID_ARGUMENT
. Jika dipanggil dengan kunci yang versi OS-nya lebih besar dari nilai sistem saat ini, dan nilai sistem bukan nol, ia mengembalikan ErrorCode::INVALID_ARGUMENT
. Upgrade versi OS dari bukan nol ke nol diperbolehkan. Jika terjadi kesalahan saat berkomunikasi dengan dunia aman, ia mengembalikan nilai kesalahan yang sesuai (misalnya ErrorCode::SECURE_HW_ACCESS_DENIED
, ErrorCode::SECURE_HW_BUSY
). Jika tidak, ia mengembalikan ErrorCode::OK
dan mengembalikan gumpalan kunci baru di upgradedKeyBlob
.
keyBlobToUpgrade
tetap valid setelah panggilan upgradeKey
, dan secara teoritis dapat digunakan lagi jika perangkat diturunkan. Dalam praktiknya, keystore umumnya memanggil deleteKey
pada blob keyBlobToUpgrade
segera setelah panggilan ke upgradeKey
. Jika keyBlobToUpgrade
memiliki tag Tag::ROLLBACK_RESISTANT
, maka upgradedKeyBlob
juga harus memilikinya (dan harus tahan terhadap rollback).
Konfigurasi aman
Untuk menerapkan pengikatan versi, TA keymaster memerlukan cara untuk menerima versi OS dan level patch (informasi versi) saat ini dengan aman, dan untuk memastikan bahwa informasi yang diterimanya sangat cocok dengan informasi tentang sistem yang sedang berjalan.
Untuk mendukung pengiriman informasi versi yang aman ke TA, bidang OS_VERSION
telah ditambahkan ke header image boot. Skrip pembuatan gambar boot secara otomatis mengisi bidang ini. OEM dan pelaksana TA keymaster perlu bekerja sama untuk memodifikasi bootloader perangkat untuk mengekstrak informasi versi dari image boot dan meneruskannya ke TA sebelum sistem yang tidak aman di-boot. Ini memastikan bahwa penyerang tidak dapat mengganggu penyediaan informasi versi ke TA.
Penting juga untuk memastikan bahwa citra sistem memiliki informasi versi yang sama dengan citra boot. Untuk itu, metode configure telah ditambahkan ke keymaster HAL:
keymaster_error_t (*configure)(const struct keymaster2_device* dev, const keymaster_key_param_set_t* params);
Argumen params
berisi Tag::OS_VERSION
dan Tag::OS_PATCHLEVEL
. Metode ini dipanggil oleh klien keymaster2 setelah membuka HAL, tetapi sebelum memanggil metode lain. Jika ada metode lain yang dipanggil sebelum mengkonfigurasi, TA mengembalikan ErrorCode::KEYMASTER_NOT_CONFIGURED
.
configure
pertama kali dipanggil setelah perangkat melakukan booting, itu harus memverifikasi bahwa informasi versi yang diberikan cocok dengan apa yang disediakan oleh bootloader. Jika informasi versi tidak cocok, configure
kembali ErrorCode::INVALID_ARGUMENT
, dan semua metode keymaster lainnya terus mengembalikan ErrorCode::KEYMASTER_NOT_CONFIGURED
. Jika informasi cocok, configure
mengembalikan ErrorCode::OK
, dan metode keymaster lainnya mulai berfungsi secara normal.
Panggilan berikutnya untuk configure
mengembalikan nilai yang sama yang dikembalikan oleh panggilan pertama, dan tidak mengubah status keymaster. Perhatikan bahwa proses ini akan MEMBUTUHKAN bahwa semua OTA memperbarui gambar sistem dan boot; mereka tidak dapat diperbarui secara terpisah untuk menjaga agar informasi versi tetap sinkron.
Karena configure
akan dipanggil oleh sistem yang isinya dimaksudkan untuk divalidasi, ada peluang sempit bagi penyerang untuk mengkompromikan citra sistem dan memaksanya untuk memberikan informasi versi yang cocok dengan citra boot, tetapi bukan yang sebenarnya. versi sistem. Kombinasi verifikasi gambar boot, validasi dm-verity dari konten gambar sistem, dan fakta bahwa configure
dipanggil sangat awal pada boot sistem akan membuat jendela peluang ini sulit untuk dieksploitasi.