Di Keymaster 1, semua kunci Keymaster terikat secara kriptografis ke Root of Trust perangkat, atau kunci Booting Terverifikasi. Di Keymaster 2 dan 3, semua kunci juga terikat ke sistem operasi dan tingkat patch image sistem. Hal ini memastikan bahwa penyerang yang menemukan kelemahan dalam software sistem atau TEE versi lama 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 tersebut akan diupgrade sebelum dapat digunakan, dan versi kunci sebelumnya akan dibatalkan. Dengan cara ini, saat perangkat diupgrade, kunci *ratchet* akan maju bersama perangkat, tetapi setiap pengembalian perangkat ke rilis sebelumnya akan menyebabkan kunci tidak dapat digunakan.
Untuk mendukung struktur modular Treble dan memutus binding system.img ke boot.img, Keymaster 4 mengubah model binding versi kunci agar memiliki tingkat patch terpisah untuk setiap partisi. Hal ini memungkinkan setiap partisi diupdate secara independen, sekaligus tetap memberikan perlindungan rollback.
Untuk menerapkan binding versi ini, aplikasi tepercaya (TA) KeyMint memerlukan cara untuk menerima versi OS dan tingkat patch saat ini secara aman, dan untuk memastikan bahwa informasi yang diterimanya cocok dengan semua informasi tentang sistem yang sedang berjalan.
- Perangkat dengan Booting Terverifikasi Android (AVB) dapat menempatkan semua level patch
dan versi sistem di vbmeta, sehingga bootloader dapat menyediakannya untuk
Keymaster. Untuk partisi berantai, info versi untuk partisi ada
di vbmeta berantai. Secara umum, informasi versi harus ada di
vbmeta structyang berisi data verifikasi (hash atau pohon hash) untuk partisi tertentu. - Di perangkat tanpa AVB:
- Implementasi Booting Terverifikasi harus menyediakan hash metadata versi ke bootloader, sehingga bootloader dapat memberikan hash ke Keymaster.
boot.imgdapat terus menyimpan tingkat patch di headersystem.imgdapat terus menyimpan tingkat patch dan versi OS di properti hanya bacavendor.imgmenyimpan tingkat patch di properti hanya bacaro.vendor.build.version.security_patch.- Bootloader dapat memberikan hash semua data yang divalidasi oleh Booting Terverifikasi ke Keymaster.
- Di Android 9, gunakan tag berikut untuk memberikan informasi versi bagi
partisi berikut:
VENDOR_PATCH_LEVEL: PartisivendorBOOT_PATCH_LEVEL: PartisibootOS_PATCH_LEVELdanOS_VERSION: Partisisystem. (OS_VERSIONdihapus dari headerboot.img.
-
Implementasi Keymaster harus memperlakukan semua level patch secara terpisah. Kunci dapat
digunakan jika semua info versi cocok dengan nilai yang terkait dengan kunci, dan
IKeymaster::upgradeDevice()di-roll 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
ditambahkan secara otomatis oleh implementasi Keymaster 2+ ke semua kunci yang baru dibuat
(atau diupdate). Selain itu, setiap upaya untuk menggunakan kunci yang tidak memiliki versi OS atau tingkat patch yang cocok dengan versi OS atau tingkat patch sistem saat ini, akan ditolak dengan ErrorCode::KEY_REQUIRES_UPGRADE.
Tag::OS_VERSION adalah nilai UINT yang merepresentasikan
bagian utama, minor, dan sub-minor dari versi sistem Android sebagai MMmmss,
dengan MM adalah versi utama, mm adalah versi minor, dan ss adalah versi
sub-minor. Misalnya, 6.1.2 akan ditampilkan sebagai 060102.
Tag::OS_PATCHLEVEL adalah nilai UINT yang merepresentasikan
tahun dan bulan update terakhir pada sistem sebagai YYYYMM, dengan YYYY adalah
tahun empat digit dan MM adalah bulan dua digit. Misalnya, Maret 2016 akan ditampilkan sebagai 201603.
UpgradeKey
Untuk mengizinkan kunci diupgrade ke versi OS dan tingkat patch baru image sistem, Android 7.1 menambahkan metode upgradeKey ke HAL:
Keymaster 3
upgradeKey(vec keyBlobToUpgrade, vec upgradeParams)
generates(ErrorCode error, vec upgradedKeyBlob);
Keymaster 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);
devadalah struktur perangkatkeyBlobToUpgradeadalah kunci yang perlu diupgradeupgradeParamsadalah parameter yang diperlukan untuk mengupgrade kunci. Hal ini mencakupTag::APPLICATION_IDdanTag::APPLICATION_DATA, yang diperlukan untuk mendekripsi blob kunci, jika disediakan selama pembuatan.upgradedKeyBlobadalah parameter output, yang digunakan untuk menampilkan blob kunci baru.
Jika upgradeKey dipanggil dengan blob kunci yang tidak dapat diuraikan atau
tidak valid, upgradeKey akan menampilkan ErrorCode::INVALID_KEY_BLOB. Jika dipanggil dengan kunci yang tingkat patch-nya lebih besar dari nilai sistem saat ini, fungsi ini akan menampilkan ErrorCode::INVALID_ARGUMENT. Jika dipanggil dengan kunci yang versi OS-nya lebih besar dari nilai sistem saat ini, dan nilai sistemnya bukan nol, maka akan menampilkan ErrorCode::INVALID_ARGUMENT. Upgrade versi OS dari bukan nol ke nol diizinkan. Jika terjadi error saat berkomunikasi dengan secure world, fungsi ini akan menampilkan nilai error yang sesuai (misalnya, ErrorCode::SECURE_HW_ACCESS_DENIED, ErrorCode::SECURE_HW_BUSY). Jika tidak, fungsi ini akan menampilkan ErrorCode::OK dan menampilkan blob kunci baru di upgradedKeyBlob.
keyBlobToUpgrade tetap valid setelah panggilan upgradeKey, dan secara teoretis dapat digunakan lagi jika perangkat di-downgrade. 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 tingkat patch saat ini (informasi versi) secara 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, kolom OS_VERSION telah ditambahkan ke header image booting. Skrip build image boot
akan otomatis mengisi kolom ini. OEM dan penerap TA Keymaster
harus bekerja sama untuk mengubah bootloader perangkat guna mengekstrak informasi
versi dari image boot dan meneruskannya ke TA sebelum sistem yang tidak aman
di-booting. Hal ini memastikan bahwa penyerang tidak dapat mengganggu penyediaan informasi versi ke TA.
Selain itu, perlu dipastikan bahwa image sistem memiliki informasi versi yang sama dengan image booting. 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 metode lain
dipanggil sebelum mengonfigurasi, TA akan menampilkan
ErrorCode::KEYMASTER_NOT_CONFIGURED.
Saat configure dipanggil pertama kali setelah perangkat melakukan booting, configure harus memverifikasi bahwa informasi versi yang diberikan cocok dengan yang diberikan oleh bootloader. Jika informasi versi tidak cocok,
configure akan menampilkan ErrorCode::INVALID_ARGUMENT, dan semua
metode Keymaster lainnya akan terus menampilkan
ErrorCode::KEYMASTER_NOT_CONFIGURED. Jika informasi cocok,
configure akan menampilkan ErrorCode::OK, dan metode Keymaster
lainnya akan mulai berfungsi normal.
Panggilan berikutnya ke configure menampilkan nilai yang sama dengan yang ditampilkan oleh
panggilan pertama, dan tidak mengubah status Keymaster.
Karena configure dipanggil oleh sistem yang kontennya akan divalidasi, ada peluang kecil bagi penyerang untuk membahayakan image sistem dan memaksanya memberikan informasi versi yang cocok dengan image boot, tetapi bukan versi sebenarnya dari sistem. Kombinasi verifikasi image booting, validasi dm-verity dari konten image sistem, dan fakta bahwa configure dipanggil sangat awal dalam booting sistem akan membuat peluang eksploitasi ini sulit dilakukan.