Keystore menyediakan tempat yang lebih aman untuk membuat, menyimpan, dan menggunakan kriptografi kunci dengan cara yang terkendali. Ketika penyimpanan kunci yang didukung perangkat keras tersedia dan digunakan, materi kunci lebih aman terhadap ekstraksi dari perangkat, dan Keymaster memberlakukan pembatasan yang sulit untuk ditundukkan.
Akan tetapi, ini hanya berlaku jika kunci keystore diketahui ada di penyimpanan yang didukung hardware. Di Keymaster 1, tidak ada cara untuk aplikasi atau server jarak jauh untuk secara andal memverifikasi apakah hal ini yang terjadi. Daemon keystore memuat {i>keymaster<i} HAL yang tersedia dan percaya apa pun yang dikatakan HAL terkait dengan dukungan perangkat keras pada kunci.
Untuk mengatasi hal ini, Keymaster memperkenalkan pengesahan kunci di Android 7.0 (Keymaster 2) dan ID pengesahan di Android 8.0 (Keymaster 3).
Pengesahan kunci bertujuan untuk memberikan cara untuk memperkuat menentukan apakah pasangan kunci asimetris didukung perangkat keras, properti apa kunci tersebut, dan batasan apa yang diterapkan pada penggunaannya.
Pengesahan ID memungkinkan perangkat untuk memberikan bukti ID perangkat kerasnya, seperti nomor seri atau IMEI.
Pengesahan kunci
Untuk mendukung pengesahan kunci, Android 7.0 memperkenalkan serangkaian tag, tipe, dan ke HAL.
Tag
Tag::ATTESTATION_CHALLENGE
Tag::INCLUDE_UNIQUE_ID
Tag::RESET_SINCE_ID_ROTATION
Jenis
Keymaster 2 dan yang lebih lama
typedef struct { keymaster_blob_t* entries; size_t entry_count; } keymaster_cert_chain_t;
Metode AttestKey
Keymaster 3
attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams) generates(ErrorCode error, vec<vec<uint8_t>> certChain);
Keymaster 2 dan yang lebih lama
keymaster_error_t (*attest_key)(const struct keymaster2_device* dev, const keymaster_key_blob_t* key_to_attest, const keymaster_key_param_set_t* attest_params, keymaster_cert_chain_t* cert_chain);
dev
adalah struktur perangkat keymaster.keyToAttest
adalah blob kunci yang ditampilkan darigenerateKey
tempat pengesahan akan dibuat.attestParams
adalah daftar parameter yang diperlukan untuk pengesahan. Ini mencakupTag::ATTESTATION_CHALLENGE
dan mungkinTag::RESET_SINCE_ID_ROTATION
, sertaTag::APPLICATION_ID
danTag::APPLICATION_DATA
. Tujuan dua hal terakhir diperlukan untuk membongkar enkripsi blob kunci jika telah ditentukan selama pembuatan kunci.certChain
adalah parameter output, yang menampilkan array CA {i>root<i}. Entri 0 adalah sertifikat pengesahan, yang berarti menjamin kunci darikeyToAttest
dan berisi atribut pengesahan.
Metode attestKey
dianggap sebagai operasi kunci publik di
yang disahkan, karena dapat dipanggil
kapan saja dan tidak perlu memenuhi
batasan otorisasi tertentu. Misalnya, jika kunci yang disahkan memerlukan
untuk digunakan, pengesahan
dapat dibuat tanpa izin pengguna
autentikasi.
Sertifikat pengesahan
Sertifikat pengesahan adalah sertifikat X.509 standar, dengan pengesahan yang berisi deskripsi kunci yang disahkan. Tujuan sertifikat ditandatangani dengan kunci pengesahan tersertifikasi. Kunci pengesahan dapat menggunakan algoritma yang berbeda dengan kunci yang disahkan.
Sertifikat pengesahan berisi kolom-kolom dalam tabel di bawah ini dan tidak dapat berisi kolom tambahan. Beberapa kolom menentukan nilai kolom tetap. CTS tes memvalidasi bahwa isi sertifikat sama persis dengan yang ditetapkan.
Sertifikat SEQUENCE
Nama kolom (lihat RFC 5280) | Nilai |
---|---|
tbsCertificate | SEQUENCE Sertifikat TBS |
Algoritma tanda tangan | AlgoritmeIdentifier algoritma yang digunakan untuk menandatangani kunci: ECDSA untuk kunci EC, RSA untuk kunci RSA. |
signatureValue | BIT STRING, tanda tangan dihitung pada tbsCertificate berenkode ASN.1 DER. |
SEQUENCE TBSCertificate
Nama kolom (lihat RFC 5280) | Nilai |
---|---|
version |
INTEGER 2 (berarti sertifikat v3) |
serialNumber |
BILANGAN BULAT 1 (nilai tetap: sama di semua sertifikat) |
signature |
AlgorithmIdentifier algoritma yang digunakan untuk menandatangani kunci: ECDSA untuk kunci EC, RSA untuk kunci RSA. |
issuer |
Sama dengan kolom subjek kunci pengesahan batch. |
validity |
SEQUENCE dua tanggal, yang berisi nilai
Tag::ACTIVE_DATETIME dan
Tag::USAGE_EXPIRE_DATETIME.
Nilai tersebut dalam milidetik sejak 1 Januari 1970.
Lihat RFC 5280 untuk jawaban benar
serta representasi tanggal
dalam sertifikat. Jika Tag::ACTIVE_DATETIME tidak ada, gunakan nilai
Tag::CREATION_DATETIME . Jika
Tag::USAGE_EXPIRE_DATETIME tidak ada, gunakan masa berlaku
tanggal sertifikat kunci pengesahan batch. |
subject |
CN = "Kunci Keystore Android" (nilai tetap: sama di semua sertifikat) |
subjectPublicKeyInfo |
SubjectPublicKeyInfo berisi kunci publik yang telah disahkan. |
extensions/Key Usage |
digitalSignature: disetel jika kunci memiliki tujuan KeyPurpose::SIGN atau
KeyPurpose::VERIFY . Semua bit lainnya tidak disetel. |
extensions/CRL Distribution Points |
Nilai Ditentukan Nanti |
extensions/"attestation" |
OID-nya adalah 1.3.6.1.4.1.11129.2.1.17; konten didefinisikan dalam Bagian Ekstensi Pengesahan di bawah. Seperti semua Ekstensi sertifikat X.509, konten dinyatakan sebagai OCTET_STRING yang berisi encoding DER dari pengesahan SEQUENCE. |
Ekstensi pengesahan
Ekstensi attestation
berisi deskripsi lengkap keymaster
otorisasi yang terkait dengan kunci, dalam struktur yang secara langsung sesuai
ke daftar otorisasi seperti yang digunakan dalam Android dan HAL keymaster. Setiap tag di
daftar otorisasi direpresentasikan oleh ASN.1 SEQUENCE
entri, secara eksplisit
diberi tag dengan nomor tag keymaster, tetapi dengan deskriptor jenis (empat
bit urutan) disamarkan.
Misalnya, di Keymaster 3, Tag::PURPOSE
didefinisikan dalam
types.hal sebagai ENUM_REP | 1
. Untuk ekstensi pengesahan,
nilai ENUM_REP
dihapus, menyisakan tag 1
.
(Untuk Keymaster 2 dan yang lebih lama, KM_TAG_PURPOSE
didefinisikan di
keymaster_defs.h.)
Nilai diterjemahkan dengan mudah ke jenis ASN.1, per tabel ini:
Jenis Keymaster | Jenis ASN.1 |
---|---|
ENUM |
BILANGAN BULAT |
ENUM_REP |
SET INTEGER |
UINT |
BILANGAN BULAT |
UINT_REP |
SET INTEGER |
ULONG |
BILANGAN BULAT |
ULONG_REP |
SET INTEGER |
DATE |
INTEGER (milidetik sejak 1 Januari 1970 00:00:00 GMT) |
BOOL |
NULL (di keymaster, tag ada berarti benar, tidak ada berarti salah. Semantik yang sama berlaku untuk encoding ASN.1) |
BIGNUM |
Tidak digunakan saat ini, jadi tidak ada pemetaan yang ditentukan |
BYTES |
OKTET_STRING |
Skema
Konten ekstensi pengesahan dijelaskan oleh skema ASN.1 berikut.
KeyDescription ::= SEQUENCE { attestationVersion INTEGER, # KM2 value is 1. KM3 value is 2. KM4 value is 3. attestationSecurityLevel SecurityLevel, keymasterVersion INTEGER, keymasterSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, teeEnforced AuthorizationList, } SecurityLevel ::= ENUMERATED { Software (0), TrustedEnvironment (1), StrongBox (2), } AuthorizationList ::= SEQUENCE { purpose [1] EXPLICIT SET OF INTEGER OPTIONAL, algorithm [2] EXPLICIT INTEGER OPTIONAL, keySize [3] EXPLICIT INTEGER OPTIONAL. digest [5] EXPLICIT SET OF INTEGER OPTIONAL, padding [6] EXPLICIT SET OF INTEGER OPTIONAL, ecCurve [10] EXPLICIT INTEGER OPTIONAL, rsaPublicExponent [200] EXPLICIT INTEGER OPTIONAL, rollbackResistance [303] EXPLICIT NULL OPTIONAL, # KM4 activeDateTime [400] EXPLICIT INTEGER OPTIONAL originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL noAuthRequired [503] EXPLICIT NULL OPTIONAL, userAuthType [504] EXPLICIT INTEGER OPTIONAL, authTimeout [505] EXPLICIT INTEGER OPTIONAL, allowWhileOnBody [506] EXPLICIT NULL OPTIONAL, trustedUserPresenceRequired [507] EXPLICIT NULL OPTIONAL, # KM4 trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, # KM4 unlockedDeviceRequired [509] EXPLICIT NULL OPTIONAL, # KM4 allApplications [600] EXPLICIT NULL OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rollbackResistant [703] EXPLICIT NULL OPTIONAL, # KM2 and KM3 only. rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, # KM3 vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL, # KM4 bootPatchLevel [719] EXPLICIT INTEGER OPTIONAL, # KM4 } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, verifiedBootHash OCTET_STRING, # KM4 } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
Kolom KeyDescription
keymasterVersion
dan attestationChallenge
kolom diidentifikasi
secara posisi, bukan berdasarkan tag, sehingga tag dalam bentuk yang dienkode hanya menentukan
jenis kolom. Bidang yang tersisa secara implisit diberi tag sebagaimana ditentukan dalam
skema.
Nama kolom | Jenis | Nilai |
---|---|---|
attestationVersion |
BILANGAN BULAT | Versi skema pengesahan: 1, 2, atau 3. |
attestationSecurity |
SecurityLevel | Level keamanan pengesahan ini. Dimungkinkan untuk mendapatkan perangkat lunak pengesahan kunci yang didukung perangkat keras. Pengesahan tersebut tidak dapat dipercaya jika Sistem Android disusupi. |
keymasterVersion |
BILANGAN BULAT | Versi perangkat keymaster: 0, 1, 2, 3, atau 4. |
keymasterSecurity |
SecurityLevel | Tingkat keamanan implementasi keymaster. |
attestationChallenge |
OKTET_STRING | Nilai Tag::ATTESTATION_CHALLENGE , ditetapkan ke permintaan pengesahan. |
uniqueId |
OKTET_STRING | ID unik opsional, ada jika kunci memiliki
Tag::INCLUDE_UNIQUE_ID |
softwareEnforced |
AuthorizationList | Opsional, otorisasi {i>keymaster<i} yang tidak diberlakukan oleh TEE, jika ini. |
teeEnforced |
AuthorizationList | Opsional, otorisasi Keymaster yang diberlakukan oleh TEE, jika ada. |
Kolom AuthorizationList
Kolom AuthorizationList
bersifat opsional dan diidentifikasi
oleh nilai tag {i>keymaster<i}, dengan
bit{i> <i}jenis bit yang disamarkan.
Pemberian tag eksplisit digunakan sehingga kolom juga berisi tag yang menunjukkan
jenis ASN.1, untuk penguraian yang lebih mudah.
Untuk mengetahui detail tentang nilai setiap kolom, lihat types.hal
untuk Keymaster 3 dan
keymaster_defs.h
untuk Keymaster 2 dan yang lebih lama. Nama tag Keymaster
diubah menjadi nama kolom dengan menghilangkan KM_TAG
dan mengubah awalan
sisanya menjadi camel case, sehingga Tag::KEY_SIZE
menjadi
keySize
.
Kolom RootOfTrust
Kolom RootOfTrust
diidentifikasi secara posisi.
Nama kolom | Jenis | Nilai |
---|---|---|
verifiedBootKey |
OKTET_STRING | Hash aman dari kunci yang digunakan untuk memverifikasi image sistem. SHA-256 direkomendasikan. |
deviceLocked |
BOOLEAN | Benar jika bootloader terkunci, yang berarti hanya image yang ditandatangani di-flash, dan bahwa pemeriksaan {i> booting<i} terverifikasi telah selesai. |
verifiedBootState |
VerifiedBootState | Status booting terverifikasi. |
verifiedBootHash |
OKTET_STRING | Ringkasan semua data yang dilindungi oleh Booting Terverifikasi. Untuk perangkat yang menggunakan implementasi Booting Terverifikasi Android, nilai ini berisi ringkasan VBMeta struct, atau Booting Terverifikasi struktur {i>metadata<i}. Untuk mempelajari lebih lanjut cara menghitung nilai ini, lihat Ringkasan VBMeta |
Nilai VerifiedBootState
Nilai verifiedBootState
memiliki arti berikut:
Nilai | Arti |
---|---|
Verified |
Menunjukkan rantai kepercayaan lengkap yang diperluas dari bootloader ke terverifikasi
partisi, termasuk bootloader, partisi booting, dan semua
partisi. Dalam status ini, nilai verifiedBootKey adalah hash dari objek yang disematkan
sertifikat, yang berarti sertifikat yang
tidak dapat diubah yang dimasukkan ke dalam ROM.Status ini sesuai dengan status booting hijau seperti yang didokumentasikan dalam dokumentasi alur booting terverifikasi. |
SelfSigned |
Menunjukkan bahwa partisi booting telah diverifikasi menggunakan sematan
sertifikatnya, dan
tanda tangannya valid. Bootloader akan menampilkan
peringatan dan
sidik jari kunci publik sebelum
mengizinkan proses {i>boot<i} untuk dilanjutkan.
Dalam status ini, nilai verifiedBootKey adalah hash dari penandatanganan mandiri
CA {i>root<i}.Status ini sesuai dengan status booting kuning seperti yang didokumentasikan dalam dokumentasi alur booting terverifikasi. |
Unverified |
Menunjukkan bahwa perangkat dapat dimodifikasi secara bebas. Integritas perangkat diserahkan
pengguna untuk memverifikasi {i>out-of-band<i}. Bootloader akan menampilkan peringatan kepada pengguna
sebelum melanjutkan proses {i>booting<i}. Dalam status ini, nilai verifiedBootKey kosong.Status ini sesuai dengan status booting oranye seperti yang didokumentasikan dalam dokumentasi alur booting terverifikasi. |
Failed |
Menunjukkan bahwa perangkat gagal diverifikasi. Tidak ada sertifikat pengesahan
sebenarnya berisi nilai ini, karena dalam keadaan ini {i>bootloader<i} akan berhenti. Penting
disertakan di sini untuk kelengkapan. Status ini sesuai dengan status booting merah seperti yang didokumentasikan dalam dokumentasi alur booting terverifikasi. |
Nilai SecurityLevel
Nilai securityLevel
memiliki arti berikut:
Nilai | Arti |
---|---|
Software |
Kode yang membuat atau mengelola elemen yang relevan (pengesahan atau kunci) diimplementasikan dalam sistem Android dan dapat diubah jika sistem itu disusupi. |
TrustedEnvironment |
Kode yang membuat atau mengelola elemen yang relevan (pengesahan atau ) diimplementasikan dalam Trusted Execution Environment (TEE). Bisa jadi diubah jika TEE disusupi, tetapi TEE sangat tahan terhadap ancaman disusupi dan cukup tahan terhadap kompromi dari serangan perangkat keras langsung. |
StrongBox |
Kode yang membuat atau mengelola elemen yang relevan (pengesahan atau ) diimplementasikan dalam modul keamanan hardware khusus. Bisa jadi diubah jika modul keamanan hardware disusupi, tetapi keamanannya sangat tahan terhadap penyusupan jarak jauh dan sangat tahan terhadap penyusupan melalui serangan perangkat keras. |
ID unik
ID Unik adalah nilai 128-bit yang mengidentifikasi perangkat, tetapi hanya untuk periode waktu terbatas. Nilainya dihitung dengan:
HMAC_SHA256(T || C || R, HBK)
Dalam hal ini:
T
adalah "nilai penghitung sementara", yang dihitung dengan membagi nilaiTag::CREATION_DATETIME
sebesar 2592000000, menurunkan jumlah sisa.T
berubah setiap 30 hari (2592000000 = 30 * 24 * 60 * 60 * 1000).C
adalah nilaiTag::APPLICATION_ID
R
adalah 1 jikaTag::RESET_SINCE_ID_ROTATION
adalah yang ada dalam parameter attest_params ke panggilan attest_key, atau 0 jika tag tidak ada.HBK
adalah rahasia unik yang terikat hardware dan dikenal oleh {i>Execution Environment<i} dan tidak pernah diungkapkan olehnya. Rahasia berisi setidaknya 128 bit entropi dan bersifat unik untuk setiap perangkat (probabilistik) sehingga keunikan dapat diterima mengingat entropi 128 bit). HBK seharusnya berasal dari materi kunci gabungan melalui HMAC atau AES_CMAC.
Memotong output HMAC_SHA256 menjadi 128 bit.
Kunci pengesahan dan sertifikat
Dua kunci, satu RSA dan satu ECDSA, dan rantai sertifikat terkait, dengan aman dan disediakan ke dalam perangkat.
Android 12 memperkenalkan Penyediaan Kunci Jarak Jauh, dan Android 13 memerlukan perangkat menerapkannya. {i>Remote Key Provisioning<i} menyediakan perangkat di lapangan dengan per aplikasi, sertifikat pengesahan ECDSA P256. Sertifikat ini merupakan lebih singkat daripada sertifikat yang disediakan pabrik.
Beberapa IMEI
Android 14 menambahkan dukungan untuk beberapa IMEI dalam Catatan Pengesahan Kunci Android. OEM dapat menerapkan fitur ini dengan menambahkan tag KeyMint untuk IMEI kedua. Semakin banyak perangkat yang memiliki beberapa radio seluler dan OEM kini dapat mendukung perangkat dengan dua IMEI.
OEM wajib memiliki IMEI sekunder, jika ada di perangkatnya, untuk disediakan ke implementasi KeyMint sehingga implementasi tersebut dapat mengesahkannya dengan cara yang sama seperti saat mereka mengesahkan IMEI pertama
Pengesahan ID
Android 8.0 menyertakan dukungan opsional untuk pengesahan ID bagi perangkat dengan Keymaster 3. Pengesahan ID memungkinkan perangkat memberikan bukti hardware-nya seperti nomor seri atau IMEI. Meskipun merupakan fitur opsional, sangat disarankan agar semua implementasi Keymaster 3 menyediakan dukungan untuknya karena kemampuan membuktikan identitas perangkat memungkinkan kasus penggunaan seperti konfigurasi jarak jauh zero-touch agar lebih aman (karena sisi jarak jauh dapat pastikan perangkat itu berbicara dengan perangkat yang tepat, bukan perangkat yang melakukan spoofing identitas).
Pengesahan ID berfungsi dengan membuat salinan ID hardware perangkat yang hanya dapat diakses oleh Trusted Execution Environment (TEE) sebelum perangkat meninggalkan pabrik. Pengguna dapat membuka kunci bootloader perangkat dan mengubah software sistem dan ID yang dilaporkan oleh framework Android. Tujuan salinan ID yang dipegang oleh TEE tidak dapat dimanipulasi dengan cara ini, untuk memastikan bahwa pengesahan ID perangkat hanya akan mengesahkan persyaratan pengenal perangkat keras yang asli sehingga menggagalkan upaya {i>spoofing<i}.
Platform API utama untuk pengesahan ID dibangun di atas kunci yang ada mekanisme pengesahan yang diperkenalkan dengan Keymaster 2. Saat meminta sertifikat pengesahan untuk kunci yang dipegang oleh keymaster, pemanggil dapat meminta bahwa ID perangkat keras perangkat disertakan dalam pengesahan metadata sertifikat. Jika kunci tersebut disimpan di TEE, sertifikat akan rantai kembali ke akar kepercayaan yang diketahui. Penerima sertifikat tersebut dapat memverifikasi bahwa sertifikat dan kontennya, termasuk perangkat kerasnya, pengenal, ditulis oleh TEE. Saat diminta untuk menyertakan hardware pengidentifikasi dalam sertifikat pengesahan, TEE hanya mengesahkan pengenal yang disimpan di penyimpanannya, seperti yang diisi di lantai pabrik.
Properti penyimpanan
Penyimpanan yang menyimpan ID perangkat harus memiliki properti berikut:
- Nilai yang berasal dari ID asli perangkat akan disalin ke penyimpanan sebelum perangkat meninggalkan pabrik.
- Metode
destroyAttestationIds()
dapat menghancurkan salinan data yang berasal dari ID ini. Pemusnahan permanen berarti pemusnahan data dihapus sepenuhnya, jadi bukan {i> factory reset<i} atau metode lain prosedur yang dilakukan pada perangkat tersebut dapat memulihkannya. Hal ini terutama penting untuk perangkat di mana pengguna telah membuka {i>bootloader<i} dan mengubah software sistem dan memodifikasi ID yang ditampilkan oleh Android framework. - Fasilitas RMA harus memiliki kemampuan untuk membuat salinan baru dari data yang berasal dari ID perangkat keras. Dengan cara ini, perangkat yang melewati RMA bisa melakukan pengesahan ID lagi. Tujuan mekanisme yang digunakan oleh fasilitas RMA harus dilindungi sehingga pengguna tidak dapat memanggilnya sendiri, karena hal itu memungkinkan mereka untuk mendapatkan pengesahan atas ID yang di-spoofing.
- Tidak ada kode selain aplikasi tepercaya Keymaster di TEE yang dapat membaca data yang diperoleh dari pengenal yang disimpan dalam penyimpanan.
- Penyimpanan dapat diutak-atik: Jika isi penyimpanan telah dimodifikasi, TEE memperlakukannya sama seperti jika salinan konten itu dihancurkan dan menolak semua upaya pengesahan ID. Hal ini diterapkan dengan menandatangani atau membuat MAC penyimpanan seperti yang dijelaskan di bawah.
- Penyimpanan tidak menyimpan ID asli. Karena pengesahan ID melibatkan tantangan, pemanggil selalu menyediakan pengidentifikasi untuk disahkan. TEE hanya perlu memverifikasi bahwa ini cocok dengan nilai-nilai yang awalnya. Menyimpan {i>hash<i} yang aman dari nilai asli, bukan nilai tersebut akan mengaktifkan verifikasi ini.
Konstruksi
Untuk membuat implementasi yang memiliki properti yang tercantum di atas, simpan elemen Nilai yang berasal dari ID dalam konstruksi S berikut. Jangan simpan salinan lain dari nilai ID, kecuali tempat yang normal dalam sistem, yang saat ini pemilik perangkat dapat memodifikasi dengan rooting:
S = D || HMAC(HBK, D)
dalam hal ini:
D = HMAC(HBK, ID1) || HMAC(HBK, ID2) || ... || HMAC(HBK, IDn)
HMAC
adalah konstruksi HMAC dengan hash aman yang sesuai (SHA-256 direkomendasikan)HBK
adalah kunci terikat hardware yang tidak digunakan untuk tujuan lainID1...IDn
adalah nilai ID asli; asosiasi nilai tertentu ke indeks tertentu tergantung pada implementasi, perangkat yang berbeda akan memiliki jumlah ID yang berbeda||
mewakili penyambungan
Karena {i>output<i} HMAC berukuran tetap, tidak ada {i>header<i} atau struktur lainnya yang diperlukan untuk dapat menemukan {i> hash ID<i} individu, atau HMAC D. Selain itu hingga memeriksa nilai yang diberikan untuk melakukan pengesahan, implementasi harus memvalidasi S dengan mengekstrak D dari S, mengomputasi HMAC(HBK, D) dan membandingkannya dengan nilai di S untuk memverifikasi bahwa tidak ada ID individu yang diubah/rusak. Selain itu, implementasinya harus menggunakan perbandingan waktu konstan untuk semua ID individual dan validasi S. Waktu perbandingan harus konstan terlepas dari jumlah ID yang diberikan dan kesesuaian yang benar dari setiap bagian dari tes.
Pengidentifikasi hardware
Pengesahan ID mendukung ID hardware berikut:
- Nama merek, seperti yang ditampilkan oleh
Build.BRAND
di Android - Nama perangkat, seperti yang ditampilkan oleh
Build.DEVICE
di Android - Nama produk, seperti yang ditampilkan oleh
Build.PRODUCT
di Android - Nama produsen, seperti yang ditampilkan oleh
Build.MANUFACTURER
di Android - Nama model, seperti yang ditampilkan oleh
Build.MODEL
di Android - Nomor seri
- IMEI semua radio
- MEID semua radio
Untuk mendukung pengesahan ID perangkat, perangkat mengesahkan ID ini. Semua perangkat yang menjalankan Android memiliki enam yang pertama dan itu diperlukan untuk ini fitur berfungsi. Jika perangkat memiliki radio seluler terintegrasi, perangkat juga harus mendukung pengesahan IMEI dan/atau MEID radio.
Pengesahan ID diminta dengan melakukan pengesahan kunci dan menyertakan pengenal perangkat yang akan dibuktikan dalam permintaan. ID tersebut diberi tag sebagai:
ATTESTATION_ID_BRAND
ATTESTATION_ID_DEVICE
ATTESTATION_ID_PRODUCT
ATTESTATION_ID_MANUFACTURER
ATTESTATION_ID_MODEL
ATTESTATION_ID_SERIAL
ATTESTATION_ID_IMEI
ATTESTATION_ID_MEID
ID yang akan disahkan adalah string byte berenkode UTF-8. Format ini berlaku untuk pengenal numerik. Setiap pengidentifikasi yang akan disahkan dinyatakan sebagai String berenkode UTF-8.
Jika perangkat tidak mendukung pengesahan ID (atau
destroyAttestationIds()
telah dipanggil sebelumnya dan perangkat tidak dapat
mengesahkan ID-nya), setiap permintaan
pengesahan kunci yang menyertakan satu atau lebih
tag ini gagal dengan ErrorCode::CANNOT_ATTEST_IDS
.
Jika perangkat mendukung pengesahan ID dan satu atau lebih tag di atas memiliki
disertakan dalam permintaan pengesahan kunci, TEE memverifikasi pengenal
yang diberikan dengan setiap tag sesuai
dengan salinan ID perangkat kerasnya. Jika
satu atau lebih pengenal tidak cocok, seluruh pengesahan gagal dengan
ErrorCode::CANNOT_ATTEST_IDS
. Tag yang sama valid untuk
yang diberikan beberapa kali. Hal ini dapat berguna, misalnya, saat membuktikan IMEI:
Perangkat mungkin memiliki beberapa radio dengan beberapa IMEI. Permintaan pengesahan bersifat
valid jika nilai yang diberikan dengan setiap ATTESTATION_ID_IMEI
cocok
salah satu radio perangkat. Hal yang sama berlaku untuk semua tag lainnya.
Jika pengesahan berhasil, ID yang disahkan ditambahkan ke ekstensi pengesahan (OID 1.3.6.1.4.1.11129.2.1.17) dari sertifikat pengesahan yang dikeluarkan, menggunakan skema dari contoh di atas. Perubahan dari Keymaster 2 skema pengesahan dicetak tebal, dengan komentar.
API Java
Bagian ini hanya berfungsi sebagai informasi. Para implementasi Keymaster mengimplementasikan atau menggunakan Java API. Ini diberikan untuk membantu pelaksana memahami bagaimana fitur tersebut digunakan oleh aplikasi. Komponen sistem dapat menggunakannya secara berbeda, itulah sebabnya sangat penting bagian ini tidak diperlakukan sebagai normatif.