Pengesahan Kunci dan ID

Keystore menyediakan tempat yang lebih aman untuk membuat, menyimpan, dan menggunakan kunci kriptografi dengan cara yang terkendali. Ketika penyimpanan kunci yang didukung perangkat keras tersedia dan digunakan, material kunci menjadi lebih aman terhadap ekstraksi dari perangkat, dan Keymaster menerapkan pembatasan yang sulit untuk ditumbangkan.

Namun hal ini hanya berlaku jika kunci keystore diketahui berada dalam penyimpanan yang didukung perangkat keras. Di Keymaster 1, tidak ada cara bagi aplikasi atau server jarak jauh untuk memverifikasi secara andal apakah ini masalahnya. Daemon keystore memuat HAL keymaster yang tersedia dan memercayai apa pun yang dikatakan HAL sehubungan dengan dukungan perangkat keras terhadap kunci.

Untuk mengatasi hal ini, Keymaster memperkenalkanpengesahan kunci di Android 7.0 (Keymaster 2) dan pengesahan ID di Android 8.0 (Keymaster 3).

Pengesahan kunci bertujuan untuk memberikan cara untuk menentukan dengan pasti apakah pasangan kunci asimetris didukung perangkat keras, apa saja properti kunci tersebut, dan batasan apa yang diterapkan pada penggunaannya.

Pengesahan ID memungkinkan perangkat memberikan bukti pengidentifikasi perangkat kerasnya, seperti nomor seri atau IMEI.

Pengesahan kunci

Untuk mendukung pengesahan kunci, Android 7.1 memperkenalkan serangkaian tag, jenis, dan metode ke HAL.

Tag

  • Tag::ATTESTATION_CHALLENGE
  • Tag::INCLUDE_UNIQUE_ID
  • Tag::RESET_SINCE_ID_ROTATION

Jenis

Keymaster 2 dan di bawahnya

typedef struct {
    keymaster_blob_t* entries;
    size_t entry_count;
} keymaster_cert_chain_t;

metode AttestKey

Pemimpin kunci 3

    attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams)
        generates(ErrorCode error, vec<vec<uint8_t>> certChain);

Keymaster 2 dan di bawahnya

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 gumpalan kunci yang dikembalikan dari generateKey yang pengesahannya akan dibuat.
  • attestParams adalah daftar parameter apa pun yang diperlukan untuk pengesahan. Ini termasuk Tag::ATTESTATION_CHALLENGE dan mungkin Tag::RESET_SINCE_ID_ROTATION , serta Tag::APPLICATION_ID dan Tag::APPLICATION_DATA . Dua yang terakhir diperlukan untuk mendekripsi blob kunci jika ditentukan selama pembuatan kunci.
  • certChain adalah parameter keluaran, yang mengembalikan serangkaian sertifikat. Entri 0 adalah sertifikat pengesahan, artinya sertifikat tersebut mengesahkan kunci dari keyToAttest dan berisi ekstensi pengesahan.

Metode attestKey dianggap sebagai operasi kunci publik pada kunci yang dibuktikan, karena dapat dipanggil kapan saja dan tidak perlu memenuhi batasan otorisasi. Misalnya, jika kunci yang disahkan memerlukan autentikasi pengguna untuk digunakan, pengesahan dapat dibuat tanpa autentikasi pengguna.

Sertifikat pengesahan

Sertifikat pengesahan adalah sertifikat standar X.509, dengan ekstensi pengesahan opsional yang berisi deskripsi kunci yang dibuktikan. Sertifikat ditandatangani dengan kunci pengesahan bersertifikat. Kunci pengesahan mungkin menggunakan algoritma yang berbeda dari kunci yang dibuktikan.

Sertifikat pengesahan berisi bidang pada tabel di bawah dan tidak boleh berisi bidang tambahan apa pun. Beberapa bidang menentukan nilai bidang tetap. Tes CTS memvalidasi bahwa konten sertifikat persis seperti yang ditentukan.

URUTAN Sertifikat

Nama bidang (lihat RFC 5280 ) Nilai
Sertifikat tbs URUTAN Sertifikat TBSC
algoritma tanda tangan AlgorithmIdentifier algoritma yang digunakan untuk menandatangani kunci:
ECDSA untuk kunci EC, RSA untuk kunci RSA.
Nilai tanda tangan BIT STRING, tanda tangan dihitung pada Sertifikat tbs yang dikodekan DER ASN.1.

URUTAN Sertifikat TBSC

Nama bidang (lihat RFC 5280 ) Nilai
version INTEGER 2 (berarti sertifikat v3)
serialNumber INTEGER 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 seperti bidang subjek kunci pengesahan batch.
validity URUTAN dua tanggal, berisi nilai Tag::ACTIVE_DATETIME dan Tag::USAGE_EXPIRE_DATETIME . Nilai tersebut dalam milidetik sejak 1 Januari 1970. Lihat RFC 5280 untuk representasi tanggal yang benar dalam sertifikat.
Jika Tag::ACTIVE_DATETIME tidak ada, gunakan nilai Tag::CREATION_DATETIME . Jika Tag::USAGE_EXPIRE_DATETIME tidak ada, gunakan tanggal kedaluwarsa sertifikat kunci pengesahan batch.
subject CN = "Android Keystore Key" (nilai tetap: sama di semua sertifikat)
subjectPublicKeyInfo SubjectPublicKeyInfo berisi kunci publik yang dibuktikan.
extensions/Key Usage digitalSignature: ditetapkan jika kunci memiliki tujuan KeyPurpose::SIGN atau KeyPurpose::VERIFY . Semua bit lainnya tidak disetel.
extensions/CRL Distribution Points Nilai TBD
extensions/"attestation" OIDnya adalah 1.3.6.1.4.1.11129.2.1.17; kontennya ditentukan di bagian Ekstensi Pengesahan di bawah. Seperti semua ekstensi sertifikat X.509, konten direpresentasikan sebagai OCTET_STRING yang berisi pengkodean DER dari SEQUENCE pengesahan.

Ekstensi pengesahan

Ekstensi attestation berisi deskripsi lengkap tentang otorisasi keymaster yang terkait dengan kunci, dalam struktur yang secara langsung sesuai dengan daftar otorisasi seperti yang digunakan di Android dan HAL keymaster. Setiap tag dalam daftar otorisasi diwakili oleh entri ASN.1 SEQUENCE , yang secara eksplisit ditandai dengan nomor tag keymaster, namun dengan deskriptor tipe (empat bit tingkat tinggi) yang disembunyikan.

Misalnya, di Keymaster 3, Tag::PURPOSE didefinisikan di Types.hal sebagai ENUM_REP | 1 . Untuk ekstensi pengesahan, nilai ENUM_REP dihilangkan, meninggalkan tag 1 . (Untuk Keymaster 2 dan di bawahnya, KM_TAG_PURPOSE didefinisikan di keymaster_defs.h.)

Nilai diterjemahkan dengan cara yang mudah ke tipe ASN.1, sesuai tabel ini:

Tipe master kunci tipe ASN.1
ENUM BILANGAN BULAT
ENUM_REP SET BULAT BULAT
UINT BILANGAN BULAT
UINT_REP SET BULAT BULAT
ULONG BILANGAN BULAT
ULONG_REP SET BULAT BULAT
DATE INTEGER (milidetik sejak 1 Januari 1970 00:00:00 GMT)
BOOL NULL (dalam keymaster, tag present berarti benar, absen berarti salah.
Semantik yang sama berlaku untuk pengkodean ASN.1)
BIGNUM Saat ini tidak digunakan, 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,
  applicationId               [601] EXPLICIT OCTET_STRING 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),
}

Bidang Deskripsi Kunci

Bidang keymasterVersion dan attestationChallenge diidentifikasi secara posisi, bukan berdasarkan tag, sehingga tag dalam formulir yang dikodekan hanya menentukan jenis bidang. Bidang lainnya secara implisit diberi tag seperti yang ditentukan dalam skema.

Nama bidang Jenis Nilai
attestationVersion BILANGAN BULAT Versi skema pengesahan: 1, 2, atau 3.
attestationSecurity Tingkat keamanan Tingkat keamanan pengesahan ini. Dimungkinkan untuk mendapatkan pengesahan perangkat lunak atas kunci yang didukung perangkat keras. Pengesahan seperti itu tidak dapat dipercaya jika sistem Android disusupi.
keymasterVersion BILANGAN BULAT Versi perangkat keymaster: 0, 1, 2, 3, atau 4.
keymasterSecurity Tingkat keamanan Tingkat keamanan implementasi keymaster.
attestationChallenge OKTET_STRING Nilai Tag::ATTESTATION_CHALLENGE , ditentukan untuk permintaan pengesahan.
uniqueId OKTET_STRING ID unik opsional, ada jika kunci memiliki Tag::INCLUDE_UNIQUE_ID
softwareEnforced Daftar Otorisasi Opsional, otorisasi keymaster yang tidak diberlakukan oleh TEE, jika ada.
teeEnforced Daftar Otorisasi Opsional, otorisasi Keymaster yang diberlakukan oleh TEE, jika ada.

Bidang Daftar Otorisasi

Bidang AuthorizationList semuanya opsional dan diidentifikasi berdasarkan nilai tag keymaster, dengan jenis bit yang disembunyikan. Penandaan eksplisit digunakan sehingga bidang juga berisi tag yang menunjukkan tipe ASN.1, untuk memudahkan penguraian.

Untuk detail tentang nilai setiap bidang, types.hal untuk Keymaster 3 dan keymaster_defs.h untuk Keymaster 2 dan di bawahnya. Nama tag keymaster diubah menjadi nama kolom dengan menghilangkan awalan KM_TAG dan mengubah sisanya menjadi huruf besar/kecil, sehingga Tag::KEY_SIZE menjadi keySize .

Bidang RootOfTrust

Bidang RootOfTrust diidentifikasi secara posisi.

Nama bidang Jenis Nilai
verifiedBootKey OKTET_STRING Hash aman dari kunci yang digunakan untuk memverifikasi citra sistem. SHA-256 direkomendasikan.
deviceLocked BOOLEAN Benar jika bootloader terkunci, yang berarti hanya gambar yang ditandatangani yang dapat di-flash, dan pemeriksaan boot terverifikasi telah selesai.
verifiedBootState Status Boot Terverifikasi Status boot terverifikasi.
verifiedBootHash OKTET_STRING Intisari semua data yang dilindungi oleh Boot Terverifikasi. Untuk perangkat yang menggunakan implementasi Boot Terverifikasi Android dari Boot Terverifikasi, nilai ini berisi ringkasan struct VBMeta , atau struktur metadata Boot Terverifikasi. Untuk mempelajari selengkapnya tentang cara menghitung nilai ini, lihat The VBMeta Digest

Nilai VerifiedBootState

Nilai dari verifiedBootState memiliki arti sebagai berikut:

Nilai Arti
Verified Menunjukkan rantai kepercayaan penuh yang membentang dari bootloader hingga partisi terverifikasi, termasuk bootloader, partisi boot, dan semua partisi terverifikasi.
Dalam keadaan ini, nilai verifiedBootKey adalah hash dari sertifikat yang tertanam, yang berarti sertifikat yang tidak dapat diubah dibakar ke dalam ROM.
Status ini sesuai dengan status boot hijau seperti yang didokumentasikan dalam dokumentasi alur boot terverifikasi .
SelfSigned Menunjukkan partisi boot telah diverifikasi menggunakan sertifikat yang tertanam, dan tanda tangannya valid. Bootloader menampilkan peringatan dan sidik jari kunci publik sebelum mengizinkan proses booting dilanjutkan.
Dalam keadaan ini, nilai verifiedBootKey adalah hash dari sertifikat penandatanganan mandiri.
Status ini sesuai dengan status boot kuning seperti yang didokumentasikan dalam dokumentasi alur boot terverifikasi .
Unverified Menunjukkan perangkat dapat dimodifikasi secara bebas. Integritas perangkat diserahkan kepada pengguna untuk memverifikasi out-of-band. Bootloader menampilkan peringatan kepada pengguna sebelum mengizinkan proses booting dilanjutkan.
Dalam keadaan ini nilai verifiedBootKey kosong.
Status ini sesuai dengan status boot oranye seperti yang didokumentasikan dalam dokumentasi alur boot terverifikasi .
Failed Menunjukkan perangkat telah gagal verifikasi. Tidak ada sertifikat pengesahan yang benar-benar berisi nilai ini, karena dalam keadaan ini bootloader terhenti. Disertakan di sini untuk kelengkapan.
Status ini sesuai dengan status boot merah seperti yang didokumentasikan dalam dokumentasi alur boot terverifikasi .

Nilai Tingkat Keamanan

Nilai securityLevel memiliki arti sebagai berikut:

Nilai Arti
Software Kode yang membuat atau mengelola elemen yang relevan (pengesahan atau kunci) diterapkan di sistem Android dan dapat diubah jika sistem tersebut disusupi.
TrustedEnvironment Kode yang membuat atau mengelola elemen yang relevan (pengesahan atau kunci) diimplementasikan dalam Lingkungan Eksekusi Tepercaya (TEE). Hal ini dapat diubah jika TEE disusupi, namun TEE sangat tahan terhadap penyusupan jarak jauh dan cukup tahan terhadap penyusupan oleh serangan perangkat keras langsung.
StrongBox Kode yang membuat atau mengelola elemen yang relevan (pengesahan atau kunci) diimplementasikan dalam modul keamanan perangkat keras khusus. Ini dapat diubah jika modul keamanan perangkat keras disusupi, namun modul ini sangat tahan terhadap penyusupan jarak jauh dan sangat tahan terhadap penyusupan melalui serangan perangkat keras langsung.

Identitas unik

ID Unik adalah nilai 128-bit yang mengidentifikasi perangkat, namun hanya untuk jangka waktu terbatas. Nilainya dihitung dengan:

HMAC_SHA256(T || C || R, HBK)

Di mana:

  • T adalah "nilai penghitung sementara", dihitung dengan membagi nilai Tag::CREATION_DATETIME dengan 2592000000, menghilangkan sisanya. T berubah setiap 30 hari (2592000000 = 30*24*60*60*1000).
  • C adalah nilai Tag::APPLICATION_ID
  • R bernilai 1 jika Tag::RESET_SINCE_ID_ROTATION ada di parameter attest_params pada panggilan attest_key, atau 0 jika tag tidak ada.
  • HBK adalah rahasia unik yang terikat pada perangkat keras yang diketahui oleh Lingkungan Eksekusi Tepercaya dan tidak pernah diungkapkan olehnya. Rahasianya berisi setidaknya 128 bit entropi dan unik untuk masing-masing perangkat (keunikan probabilistik dapat diterima mengingat 128 bit entropi). HBK harus berasal dari material kunci yang menyatu melalui HMAC atau AES_CMAC.

Pangkas keluaran HMAC_SHA256 menjadi 128 bit.

Kunci pengesahan dan sertifikat

Dua kunci, satu RSA dan satu ECDSA, serta rantai sertifikat terkait, disediakan dengan aman ke dalam perangkat.

Android 12 memperkenalkan Penyediaan Kunci Jarak Jauh, dan Android 13 mengharuskan perangkat menerapkannya. Penyediaan Kunci Jarak Jauh memberi perangkat di lapangan sertifikat pengesahan ECDSA P256 per aplikasi. Sertifikat ini berumur lebih pendek dibandingkan sertifikat yang disediakan pabrik.

Beberapa IMEI

Android 14 menambahkan dukungan untuk beberapa IMEI di data Pengesahan Kunci Android. OEM dapat menerapkan fitur ini dengan menambahkan tag KeyMint untuk IMEI kedua. Kini semakin umum perangkat memiliki beberapa radio seluler dan OEM kini dapat mendukung perangkat dengan dua IMEI.

OEM diharuskan memiliki IMEI sekunder, jika ada di perangkat mereka, untuk disediakan ke implementasi KeyMint sehingga implementasi tersebut dapat membuktikannya dengan cara yang sama seperti mereka membuktikan IMEI pertama

pengesahan identitas

Android 8.0 menyertakan dukungan opsional untuk pengesahan ID untuk perangkat dengan Keymaster 3. Pengesahan ID memungkinkan perangkat memberikan bukti pengidentifikasi perangkat kerasnya, seperti nomor seri atau IMEI. Meskipun merupakan fitur opsional, sangat disarankan agar semua implementasi Keymaster 3 memberikan dukungannya karena kemampuan untuk membuktikan identitas perangkat memungkinkan kasus penggunaan seperti konfigurasi jarak jauh zero-touch yang sebenarnya menjadi lebih aman (karena pihak jarak jauh dapat memastikannya). sedang berbicara dengan perangkat yang tepat, bukan perangkat yang memalsukan identitasnya).

Pengesahan ID berfungsi dengan membuat salinan pengidentifikasi perangkat keras perangkat yang hanya dapat diakses oleh Trusted Execution Environment (TEE) sebelum perangkat meninggalkan pabrik. Pengguna dapat membuka kunci bootloader perangkat dan mengubah perangkat lunak sistem serta pengidentifikasi yang dilaporkan oleh kerangka kerja Android. Salinan pengidentifikasi yang disimpan oleh TEE tidak dapat dimanipulasi dengan cara ini, sehingga memastikan bahwa pengesahan ID perangkat hanya akan membuktikan pengidentifikasi perangkat keras asli perangkat sehingga menggagalkan upaya spoofing.

Permukaan API utama untuk pengesahan ID dibangun di atas mekanisme pengesahan kunci yang sudah ada yang diperkenalkan dengan Keymaster 2. Saat meminta sertifikat pengesahan untuk kunci yang dipegang oleh keymaster, pemanggil dapat meminta agar pengidentifikasi perangkat keras perangkat disertakan dalam metadata sertifikat pengesahan. Jika kunci disimpan di TEE, sertifikat akan dirantai kembali ke akar kepercayaan yang diketahui. Penerima sertifikat tersebut dapat memverifikasi bahwa sertifikat dan isinya, termasuk pengidentifikasi perangkat keras, ditulis oleh TEE. Ketika diminta untuk menyertakan pengidentifikasi perangkat keras dalam sertifikat pengesahan, TEE hanya mengesahkan pengidentifikasi yang disimpan dalam penyimpanannya, seperti yang diisi di lantai pabrik.

Properti penyimpanan

Penyimpanan yang menyimpan pengidentifikasi perangkat harus memiliki properti berikut:

  • Nilai yang diperoleh dari pengidentifikasi asli perangkat disalin ke penyimpanan sebelum perangkat meninggalkan pabrik.
  • Metode destroyAttestationIds() dapat secara permanen menghancurkan salinan data turunan pengidentifikasi ini. Penghancuran permanen berarti data dihapus seluruhnya sehingga reset pabrik atau prosedur lain apa pun yang dilakukan pada perangkat tidak dapat memulihkannya. Hal ini sangat penting terutama untuk perangkat yang penggunanya telah membuka kunci bootloader dan mengubah perangkat lunak sistem serta memodifikasi pengidentifikasi yang dikembalikan oleh kerangka kerja Android.
  • Fasilitas RMA harus memiliki kemampuan untuk menghasilkan salinan baru dari data yang berasal dari pengidentifikasi perangkat keras. Dengan cara ini, perangkat yang melewati RMA dapat melakukan pengesahan ID kembali. Mekanisme yang digunakan oleh fasilitas RMA harus dilindungi sehingga pengguna tidak dapat memintanya sendiri, karena hal ini akan memungkinkan mereka memperoleh pengesahan ID palsu.
  • Tidak ada kode selain aplikasi tepercaya Keymaster di TEE yang dapat membaca data turunan pengidentifikasi yang disimpan di penyimpanan.
  • Penyimpanannya tahan terhadap kerusakan: Jika konten penyimpanan telah diubah, TEE akan memperlakukannya sama seperti jika salinan konten telah dimusnahkan dan menolak semua upaya pengesahan ID. Hal ini diterapkan dengan menandatangani atau MACing penyimpanan seperti yang dijelaskan di bawah ini .
  • Penyimpanan tidak menyimpan pengidentifikasi asli. Karena pengesahan ID melibatkan suatu tantangan, penelepon selalu memberikan pengidentifikasi untuk dibuktikan. TEE hanya perlu memverifikasi bahwa nilai tersebut sesuai dengan nilai aslinya. Menyimpan hash aman dari nilai asli, bukan nilai, memungkinkan verifikasi ini.

Konstruksi

Untuk membuat implementasi yang memiliki properti yang tercantum di atas, simpan nilai turunan ID dalam konstruksi S berikut. Jangan simpan salinan nilai ID lainnya, kecuali di tempat normal dalam sistem, yang dapat diubah oleh pemilik perangkat dengan melakukan rooting:

S = D || HMAC(HBK, D)

Di mana:

  • D = HMAC(HBK, ID 1 ) || HMAC(HBK, ID 2 ) || ... || HMAC(HBK, ID n )
  • HMAC adalah konstruksi HMAC dengan hash aman yang sesuai (disarankan SHA-256)
  • HBK adalah kunci yang terikat perangkat keras yang tidak digunakan untuk tujuan lain apa pun
  • ID 1 ...ID n adalah nilai ID asli; pengaitan nilai tertentu ke indeks tertentu bergantung pada implementasi, karena perangkat yang berbeda akan memiliki jumlah pengidentifikasi yang berbeda
  • || melambangkan penggabungan

Karena keluaran HMAC berukuran tetap, tidak ada header atau struktur lain yang diperlukan untuk dapat menemukan hash ID individual, atau HMAC dari D. Selain memeriksa nilai yang diberikan untuk melakukan pengesahan, implementasi perlu memvalidasi S dengan mengekstraksi D dari S , menghitung HMAC(HBK, D) dan membandingkannya dengan nilai di S untuk memverifikasi bahwa tidak ada ID individual yang dimodifikasi/rusak. Selain itu, implementasi harus menggunakan perbandingan waktu konstan untuk semua elemen ID individual dan validasi S. Waktu perbandingan harus konstan terlepas dari jumlah ID yang diberikan dan kecocokan yang benar pada setiap bagian pengujian.

Pengidentifikasi perangkat keras

Pengesahan ID mendukung pengidentifikasi perangkat keras berikut:

  1. Nama merek, seperti yang dikembalikan oleh Build.BRAND di Android
  2. Nama perangkat, seperti yang dikembalikan oleh Build.DEVICE di Android
  3. Nama produk, seperti yang dikembalikan oleh Build.PRODUCT di Android
  4. Nama pabrikan, seperti yang dikembalikan oleh Build.MANUFACTURER di Android
  5. Nama model, seperti yang dikembalikan oleh Build.MODEL di Android
  6. Nomor seri
  7. IMEI semua radio
  8. MEID dari semua radio

Untuk mendukung pengesahan ID perangkat, perangkat membuktikan pengidentifikasi ini. Semua perangkat yang menjalankan Android memiliki enam perangkat pertama dan perangkat tersebut diperlukan agar fitur ini dapat berfungsi. Jika perangkat memiliki radio seluler terintegrasi, perangkat tersebut juga harus mendukung pengesahan IMEI dan/atau MEID radio tersebut.

Pengesahan ID diminta dengan melakukan pengesahan kunci dan menyertakan pengidentifikasi perangkat untuk dibuktikan dalam permintaan. Pengidentifikasi ditandai 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

Pengidentifikasi yang akan dibuktikan adalah string byte yang dikodekan UTF-8. Format ini juga berlaku untuk pengidentifikasi numerik. Setiap pengidentifikasi yang akan dibuktikan dinyatakan sebagai string yang dikodekan UTF-8.

Jika perangkat tidak mendukung pengesahan ID (atau destroyAttestationIds() telah dipanggil sebelumnya dan perangkat tidak dapat lagi membuktikan ID-nya), permintaan pengesahan kunci apa pun yang menyertakan satu atau beberapa tag ini akan gagal dengan ErrorCode::CANNOT_ATTEST_IDS .

Jika perangkat mendukung pengesahan ID dan satu atau lebih tag di atas telah disertakan dalam permintaan pengesahan kunci, TEE akan memverifikasi pengidentifikasi yang disertakan dengan masing-masing tag cocok dengan salinan pengidentifikasi perangkat kerasnya. Jika satu atau lebih pengidentifikasi tidak cocok, seluruh pengesahan gagal dengan ErrorCode::CANNOT_ATTEST_IDS . Valid jika tag yang sama diberikan beberapa kali. Hal ini dapat berguna, misalnya, saat mengesahkan IMEI: Perangkat mungkin memiliki beberapa radio dengan beberapa IMEI. Permintaan pengesahan valid jika nilai yang diberikan bersama setiap ATTESTATION_ID_IMEI cocok dengan salah satu radio perangkat. Hal yang sama berlaku untuk semua tag lainnya.

Jika pengesahan berhasil, ID yang dibuktikan ditambahkan ke ekstensi pengesahan (OID 1.3.6.1.4.1.11129.2.1.17) dari sertifikat pengesahan yang diterbitkan, menggunakan skema dari atas . Perubahan dari skema pengesahan Keymaster 2 dicetak tebal , dengan komentar.

API Jawa

Bagian ini hanya bersifat informasi. Pelaksana Keymaster tidak mengimplementasikan atau menggunakan Java API. Hal ini disediakan untuk membantu pelaksana memahami bagaimana fitur tersebut digunakan oleh aplikasi. Komponen sistem mungkin menggunakannya secara berbeda, oleh karena itu penting agar bagian ini tidak diperlakukan sebagai normatif.