Pengikatan Versi

Di Keymaster 1, semua kunci keymaster terikat secara kriptografis ke Root of Trust perangkat, atau kunci Boot Terverifikasi. Di Keymaster 2 dan 3, semua kunci juga terikat pada sistem operasi dan level patch image sistem. Hal ini memastikan bahwa penyerang yang menemukan kelemahan pada 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 tingkat patch tertentu digunakan pada perangkat yang telah ditingkatkan ke versi atau tingkat patch yang lebih baru, kunci tersebut akan ditingkatkan sebelum dapat digunakan, dan versi kunci sebelumnya menjadi tidak valid. Dengan cara ini, saat perangkat ditingkatkan, kunci akan "bergerak maju" bersama dengan perangkat, namun setiap pengembalian perangkat ke rilis sebelumnya akan menyebabkan kunci tidak dapat digunakan.

Untuk mendukung struktur modular Treble dan memutus pengikatan system.img ke boot.img, Keymaster 4 mengubah model pengikatan versi kunci agar memiliki tingkat patch terpisah untuk setiap partisi. Hal ini memungkinkan setiap partisi diperbarui secara independen, sambil tetap memberikan perlindungan rollback.

Di Android 9, partisi boot , system , dan vendor masing-masing memiliki tingkat patchnya sendiri.

  • Perangkat dengan Android Verified Boot (AVB) dapat menempatkan semua level patch dan versi sistem di vbmeta, sehingga bootloader dapat menyediakannya ke Keymaster. Untuk partisi yang dirantai, info versi untuk partisi tersebut akan ada di vbmeta yang dirantai. Secara umum, informasi versi harus ada dalam vbmeta struct yang berisi data verifikasi (hash atau hashtree) untuk partisi tertentu.
  • Pada perangkat tanpa AVB:
    • Implementasi Boot Terverifikasi perlu memberikan hash 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-only ro.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 memberikan informasi versi untuk partisi berikut:
    • VENDOR_PATCH_LEVEL : partisi vendor
    • BOOT_PATCH_LEVEL : partisi boot
    • OS_PATCH_LEVEL dan OS_VERSION : partisi system . ( OS_VERSION dihapus dari header boot.img .
  • Implementasi Keymaster harus menangani 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 tidak memiliki versi OS atau tingkat patch yang cocok dengan versi OS sistem atau tingkat patch saat ini, akan 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, dengan 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 pembaruan terakhir sistem sebagai YYYYMM, dengan YYYY adalah empat digit tahun dan MM adalah dua digit bulan. Misalnya, Maret 2016 akan direpresentasikan sebagai 201603.

Tingkatkan Kunci

Untuk memungkinkan kunci diupgrade ke versi OS baru dan level patch image sistem, Android 7.1 menambahkan metode upgradeKey ke HAL:

Pemimpin kunci 3

    upgradeKey(vec keyBlobToUpgrade, vec upgradeParams)
        generates(ErrorCode error, vec upgradedKeyBlob);

Pemimpin 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 mencakup Tag::APPLICATION_ID dan Tag::APPLICATION_DATA , yang diperlukan untuk mendekripsi blob kunci, jika disediakan selama pembuatan.
  • upgradedKeyBlob adalah parameter output, yang digunakan untuk mengembalikan gumpalan kunci baru.

Jika upgradeKey dipanggil dengan gumpalan kunci yang tidak dapat diurai atau tidak valid, ia akan mengembalikan ErrorCode::INVALID_KEY_BLOB . Jika dipanggil dengan kunci yang level patchnya lebih besar dari nilai sistem saat ini, ia akan 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 akan mengembalikan ErrorCode::INVALID_ARGUMENT . Peningkatan versi OS dari bukan nol ke nol diperbolehkan. Jika terjadi kesalahan saat berkomunikasi dengan dunia aman, ia akan mengembalikan nilai kesalahan yang sesuai (misalnya ErrorCode::SECURE_HW_ACCESS_DENIED , ErrorCode::SECURE_HW_BUSY ). Jika tidak, ia akan 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 versinya. 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 rollback).

Konfigurasi aman

Untuk menerapkan pengikatan versi, TA keymaster memerlukan cara untuk menerima versi OS saat ini dan tingkat patch (informasi versi) dengan aman, dan untuk memastikan bahwa informasi yang diterima sangat cocok dengan informasi tentang sistem yang berjalan.

Untuk mendukung pengiriman informasi versi yang aman ke TA, kolom 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 guna mengekstrak informasi versi dari image boot dan meneruskannya ke TA sebelum sistem yang tidak aman di-boot. Hal ini memastikan bahwa penyerang tidak dapat mengganggu penyediaan informasi versi ke TA.

Penting juga untuk memastikan bahwa image sistem memiliki informasi versi yang sama dengan image boot. Untuk itu, metode konfigurasi 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 lainnya. Jika ada metode lain yang dipanggil sebelum konfigurasi, TA akan mengembalikan ErrorCode::KEYMASTER_NOT_CONFIGURED .

configure pertama kali dipanggil setelah perangkat melakukan booting, konfigurasi tersebut harus memverifikasi bahwa informasi versi yang diberikan cocok dengan apa yang disediakan oleh bootloader. Jika informasi versi tidak cocok, configure pengembalian ErrorCode::INVALID_ARGUMENT , dan semua metode keymaster lainnya terus mengembalikan ErrorCode::KEYMASTER_NOT_CONFIGURED . Jika informasinya cocok, configure pengembalian ErrorCode::OK , dan metode keymaster lainnya mulai berfungsi normal.

Panggilan berikutnya untuk configure mengembalikan nilai yang sama yang dikembalikan oleh panggilan pertama, dan tidak mengubah status keymaster. Perhatikan bahwa proses ini mengharuskan semua OTA memperbarui sistem dan image booting; mereka tidak dapat diperbarui secara terpisah untuk menjaga informasi versi tetap sinkron.

Karena configure akan dipanggil oleh sistem yang isinya ingin divalidasi, terdapat peluang sempit bagi penyerang untuk menyusupi citra sistem dan memaksanya memberikan informasi versi yang cocok dengan citra boot, namun bukan yang sebenarnya. versi sistem. Kombinasi verifikasi image boot, validasi dm-verity dari konten image sistem, dan fakta bahwa configure dipanggil di awal boot sistem akan membuat jendela peluang ini sulit untuk dieksploitasi.