Pada artikel sebelumnya, kami melihat perangkat keras TrustZone dan pengoperasian mekanisme Secure Monitor. Hari ini kita akan fokus pada OS tepercaya (TEE) dan aplikasinya. Dan jika terakhir kali ada hal-hal tingkat yang sangat rendah, sekarang semuanya akan berada pada tingkat yang sangat tinggi - pada tingkat sistem operasi.
Apa itu TEE?
Apa itu TEE? Ini adalah lingkungan eksekusi tepercaya (Lingkungan Eksekusi Tepercaya), pertama-tama - ini adalah lingkungan eksekusi program. Kami menggambarkannya dalam hal fungsi dan properti, tetapi tidak dalam arti pemrograman, tetapi dalam arti filosofis.
Misalnya, kereta api jarak jauh, kereta api dan taksi memiliki salah satu fungsi terpenting - untuk mengangkut orang. Tetapi menurut sifat mereka, mereka berbeda, misalnya: kereta membawa antar kota, kereta listrik - luar kota, dan taksi - terutama di kota. Melatih dan melatih tiket, taksi - no. Dan sebagainya.
Fungsi TEE adalah untuk menyimpan beberapa data secara aman untuk kami dan meluncurkan aplikasi untuk kami. Kami ingin mengirimkan perintah TEE: luncurkan aplikasi ini dan itu, ambil data ini dan itu dan lakukan ini dan itu dengannya. Pada saat yang sama, kami tidak dapat melihat kode aplikasi, serta data. Kami hanya akan mendapatkan hasilnya. Interaksi dengan TEE sangat mirip dengan RPC.
Fungsi ini sangat ideal untuk berbagai kriptografi, misalnya, untuk penandatanganan elektronik: kunci disimpan dalam TEE, dan kami meminta TEE untuk menandatangani data yang dikirimkan dengan kunci yang disimpan dalam TEE. Kami mendapatkan hasilnya, tetapi tidak memiliki akses ke kunci.
TEE memiliki sejumlah properti, tetapi yang utama adalah: a) kami percaya implementasinya, dan b) TEE terpisah dari OS utama perangkat, dilindungi, sulit untuk dipatahkan atau dipatahkan. Ada properti lain, tapi kami menyebutnya OS tepercaya untuk hal itu. Properti b) hal yang paling penting adalah TEE terpisah dan sulit untuk dipatahkan, yaitu dilindungi.
Jika Anda melihat TEE melalui prisma fungsi dan properti, menjadi jelas bahwa TEE bahkan bukan tentang TrustZone. TrustZone adalah salah satu cara untuk memisahkan TEE dari OS utama (tamu).
Opsi implementasi TEE
Jika sifat utama TEE adalah sifatnya yang terpisah dan sulit untuk dihancurkan, maka kita dapat menemukan berbagai opsi untuk menerapkan TEE:
- Gunakan TrustZone - kami mendapatkan pemisahan TEE dan OS utama dalam inti prosesor yang sama.
- Jalankan TEE pada inti yang terpisah dalam sistem pada sebuah chip dan berkomunikasi dengannya melalui antarmuka perangkat keras. Beberapa prosesor khusus memiliki inti tepercaya terpisah untuk menjalankan TEE, tetapi Anda tidak dapat membelinya di toko. Tetapi Anda dapat mengambil kristal dual-core, misalnya, Cortex-A + Cortex-M0 / M4 dan menjalankannya pada Cortex-M TEE.
- Jalankan TEE dalam chip yang terpisah dan buat koneksi yang aman dengannya melalui antarmuka eksternal, misalnya, SPI atau SMbus. Untuk melindungi komunikasi, gunakan metode kriptografi.
Metode ini digunakan ketika Anda membuat koneksi dengan kartu pintar, seperti kartu pembayaran plastik chip-on-chip. Dalam arti tertentu, TEE dieksekusi dalam chip, karena atas permintaan kami, sangat percaya diri melakukan transaksi keuangan, menyimpan data, dll.
Metode yang sama digunakan dalam TPM (Trusted Platform Module) arsitektur PC modern.
Kami hanya akan berbicara tentang implementasi TEE di TrustZone, karena ini adalah versi yang sangat umum dari implementasi TEE. Tetapi banyak dari hal di atas akan berlaku untuk TEE secara umum.
TEE sebagai OS
Dalam artikel-artikel sebelumnya, kita sepanjang waktu menyebut TEE sebagai OS tepercaya dan mengatakan bahwa itu mirip dengan sistem operasi nyata.
Tanpa berpura-pura menjadi umum, kami mengatakan bahwa sebagian besar TEE memiliki:
- aplikasi dan proses: TEE dapat mengunduh aplikasi dan menjalankannya;
- pemisahan memori proses dan kernel: digunakan oleh MMU untuk melindungi ruang memori proses dan untuk melindungi memori inti TEE;
- utas, interaksi proses;
- penyimpanan data.
Anda dapat menghasilkan versi TEE yang lebih terpotong, misalnya, tanpa memuat aplikasi dinamis, tanpa interaksi proses, tanpa utas, tetapi aplikasi itu sendiri, penyimpanan data dan pemisahan memori proses dan ruang kernel akan tetap.
Teks tersembunyiContoh TEE terpotong dapat dilihat sekarang di proyek ARM Trusted Firmware-M untuk generasi baru mikrokontroler Cortex-M pada platform ARMv8-M. Ini adalah TEE yang dilucuti, sekarang ada dukungan untuk mikrokontroler pada inti Cortex-M23 dan Cortex-M33. Ini adalah mikrokontroler berbasis flash, kira-kira setara dengan Cortex-M0 dan Cortex-M3, tetapi dengan dukungan TrustZone. Mereka memiliki sedikit RAM, program ini berjalan terutama dari Flash, dan oleh karena itu di TEE tidak ada pemuatan program yang dinamis. Saat ini, TF-M juga single-threaded.
Antarmuka Perangkat Lunak TEE
Untuk berinteraksi dengan komponen perangkat lunak lain, TEE memiliki API:
- TEE menyediakan API untuk program melalui panggilan sistem (Panggilan Supervisor, perintah SVC);
- TEE menyediakan API untuk Dunia Normal melalui panggilan ke Secure Monitor (perintah SMC).
Melalui panggilan sistem, program menyimpan data dan memanggil fungsi OS. Seperti halnya OS yang layak, TEE mencoba untuk mengabstraksi program dari perangkat keras ke tingkat tertentu.
Sebagai contoh, abstrak Linux bekerja dengan file melalui buka, baca, tulis, tutup panggilan - semua fungsi stdio pada dasarnya jatuh pada panggilan sistem OS. Dan TEE juga memungkinkan aplikasinya untuk bekerja dengan data yang disimpan melalui panggilan yang secara abstrak menyimpan dan memuat objek (blok data) ke dalam penyimpanan. TEE juga dapat menyediakan beberapa fungsi kriptografi di tingkat sistem, dll.
Ada seperangkat spesifikasi
GlobalPlatform untuk TEE, mereka menggambarkan API, persyaratan, skenario penggunaan, dll.
API TEE inti untuk programnya dijelaskan dalam Spesifikasi API Inti Internal TEE. Ini menjelaskan fungsi penyimpanan data, fungsi kriptografi, dll. Dan "TEE Client API" menjelaskan cara memanggil aplikasi dari Normal World.
Jika TEE Anda mengimplementasikan API ini, menulis aplikasi untuk itu akan sangat mudah. Berkat satu API, portabilitas program juga diimplementasikan.
Perbedaan antara TEE dan OS biasa
Dua perbedaan utama antara TEE dan Linux dan sistem operasi umum lainnya yang kita kenal adalah:
- TEE melakukan tindakan bukan pada perintah pengguna, tetapi pada perintah dari Dunia Normal;
- TEE di TrustZone tidak memiliki penjadwal sendiri.
Dalam OS biasa, pengguna menghasilkan beberapa input - memasuki perintah, klik pada ikon, dan OS memproses input ini, mentransfernya ke program, dan program memprosesnya. Dalam versi server, input tidak berasal dari pengguna, tetapi dari klien tertentu, kemungkinan besar melalui jaringan. Tetapi OS, bertindak berdasarkan input eksternal.
TEE tidak memproses data eksternal atau mentransfernya ke aplikasi. Alih-alih, itu memproses perintah dan data yang dikirimkan dari Dunia Normal melalui TEE Client API, dan itu hampir semuanya. Ternyata TEE bertindak untuk OS karena beberapa pustaka dengan antarmuka RPC, yang fungsinya disebut. Setelah memproses fungsinya, TEE mungkin tidak melakukan apa-apa.
Perbedaan kedua mengikuti dari yang pertama. TEE Trustee berbagi waktu CPU dengan Normal World dan disebut sebagai perpustakaan. TEE tidak terus-menerus mengalokasikan waktu prosesor untuk dirinya sendiri, TEE menghabiskan waktu sebanyak yang dibutuhkan untuk menyelesaikan permintaan dan kemudian mentransfer kontrol ke Dunia Normal. Dan jika demikian, maka dia seharusnya tidak memiliki penjadwal sendiri - dia membutuhkan penjadwal OS tamu.
Penjadwal OS utama mentransfer kontrol ke TEE secara tidak langsung:
- scheduler mengatur tugas yang harus diselesaikan;
- tugas memanggil panggilan sistem kernel;
- panggilan sistem memanggil TEE, jika perlu;
- TEE bekerja selama diperlukan untuk menyelesaikan permintaan dan mengembalikan kontrol ke Dunia Normal.
Aplikasi TEE
Aplikasi yang berjalan di TEE disebut trustlets - mirip dengan applet yang berjalan di kartu pintar.
Kutipan dari Wikipedia:
Applet (Eng. Applet dari aplikasi - aplikasi dan -let - sufiks diminutif) adalah komponen perangkat lunak yang tidak lengkap yang bekerja dalam konteks aplikasi lain yang berbobot penuh, dirancang untuk satu tugas sempit dan tidak memiliki nilai dalam isolasi dari aplikasi dasar.
Trustlet adalah Applet Tepercaya. Ini adalah program untuk TEE, seperti yang telah kami ketahui, ini berkomunikasi dengan TEE melalui panggilan sistem, memiliki siklus hidup, dll.
Tapi tetap saja, namanya menunjukkan bahwa itu adalah komponen yang tidak mandiri. Di sini, independensi diekspresikan dalam fakta bahwa trustlet akan melakukan panggilan dari Dunia Normal, dan kemudian memutuskan sambungan bersama dengan TEE. Jika ia berputar dalam loop tak terbatas, inti prosesor akan berhenti berfungsi sebagai OS, dan semuanya pada akhirnya akan hang. Tetapi program untuk OS biasa dapat berputar dalam satu lingkaran tanpa akhir dan menambang untuk menghitung beberapa tugas, ini benar-benar normal untuk program tersebut. Dalam hal ini, ia tidak tergantung pada trustlet.
Trustlet harus memiliki semacam pengenal sehingga Dunia Normal dapat menyebutnya. Merupakan kebiasaan untuk memberikan trustlet sebagai UUID - pengidentifikasi unik.
Siklus Hidup Trustlet
Pertimbangkan bagaimana trastlet diluncurkan dan perintah dijalankan.
Adalah logis untuk memuat trustlet ke dalam memori dan mulai bekerja, tetapi dalam API Klien TEE GlobalPlatform, untuk memulai trustlet, Anda perlu membuat konteks dan membuat sesi dengan trustlet.
Menciptakan konteks adalah pembentukan koneksi antara Dunia Normal dan TEE. Dalam hal ini, spesifikasi GlobalPlatform mengasumsikan bahwa perangkat dapat memiliki beberapa TEE, dan pada saat membuat konteks, Anda dapat memilih TEE mana yang akan dihubungi.
Di API Klien TEE GlobalPlatform, fungsi disediakan untuk ini:
TEEC_Result TEEC_InitializeContext (const char * name, TEEC_Context * context)
Fungsi ini dipanggil dari aplikasi Dunia Normal. Di sini namanya menunjukkan TEE yang dapat dipilih. Jika kami menginginkan TEE secara default atau yakin bahwa kami hanya memiliki satu TEE, kami mengganti NULL. Dalam konteks, konteks yang dibuat disimpan.
Setelah membuat konteks, Anda perlu membuat sesi dengan kepercayaan. Di sini UUID trustlet berguna bagi kita. Untuk melakukan ini, fungsinya disebut:
TEEC_Result TEEC_OpenSession (
TEEC_Context * context, TEEC_Session * session,
const TEEC_UUID * tujuan, koneksi uint32_t metode,
kekosongan * koneksi data, operasi TEEC_Operation *,
uint32_t * returnOrigin)
Sesi setara dengan bekerja dengan instance program dalam OS reguler: ada banyak contoh program yang sama di OS, dan mereka akan bekerja secara independen. Tetapi ada banyak sesi di TEE, dan pada dasarnya, ini adalah koneksi ke contoh unik trustlet dalam memori. Dalam hal ini, area kode kemungkinan besar akan sama, dipetakan melalui MMU ke memori berbagai proses. Tetapi setiap proses akan memiliki area data sendiri, yang memungkinkan instance untuk bekerja secara independen. Sama seperti di Linux.
Ketika TEEC_OpenSession dipanggil, konteks dan UUID kepercayaan tujuan ditransmisikan sebagai input. Sesi yang ditetapkan akan disimpan dalam "sesi". Beberapa parameter selanjutnya kami tidak akan mempertimbangkan, mereka tidak begitu penting untuk dipahami.
Pada saat sesi dibuat, trustlet dapat dimuat ke dalam memori. Inilah yang terjadi dengan aplikasi pada sistem operasi. Dalam TEE besar, linker bertanggung jawab untuk ini, ia mengunduh gambar biner dari trustlet, ini adalah file ELF yang ditandatangani. Jika ini adalah TEE kecil, trustlet seharusnya sudah dimuat ke dalam memori - ini dapat dihubungkan secara statis atau, untuk mikrokontroler flash, ditulis ke memori flash di alamat yang ditentukan.
Mari kita asumsikan bahwa kita memiliki TEE besar dan kita perlu memuat trustlet ke dalam memori. Dari mana asalnya? Pada prinsipnya, TEE pada saat memuat membutuhkan objek dengan UUID tertentu, dan mekanisme untuk memperoleh objek ini dapat berupa:
- objek mungkin sudah ada dalam memori;
- objek dapat ditempatkan secara statis dalam memori-flash (untuk mikrokontroler-flash);
- objek dapat dihubungkan secara statis dengan TEE - untuk trustlets sistem;
- akhirnya, Anda dapat mengunduh file ke RAM dari sistem file, atau bahkan melalui jaringan.
Tanyakan kepada diri sendiri nanti, bagaimana TEE ini mengunduh data dari sistem file atau melalui jaringan? !!!
Setelah mengunduh gambar trustlet, tanda tangan digitalnya diverifikasi. Sistem sertifikat digunakan, dan TEE akan memverifikasi bahwa kepercayaan tersebut ditandatangani oleh pihak yang dipercayai oleh TEE. Ini sangat penting karena menghilangkan kemungkinan mengunduh trustlet palsu dengan beberapa malware.
Ketika gambar trustlet diterima dan tanda tangan diverifikasi, TEE membuat ruang alamat untuk instance trustlet dalam MMU, dan linker memuat area kode ke dalam memori, memetakannya ke ruang alamat trustlet dan menginisialisasi area data. Hasilnya adalah instance trustlet yang sepenuhnya diinisialisasi untuk bekerja dengan aplikasi panggilan khusus - ini adalah pembuatan sesi.
Setelah sesi dibuat, trustlet dalam kesiapan penuh dan dapat menjalankan permintaan dari aplikasi panggilan. Untuk memanggil fungsi trustlet dari OS, fungsi tersebut digunakan:
TEEC_Result TEEC_InvokeCommand (
Sesi TEEC_Session *,
commandint uint32_t,
Operasi TEEC_Operation *,
uint32_t * returnOrigin)
Di sini, "sesi" menunjukkan sesi kami, yaitu instance TEE dan instance trustlet yang sedang kami tangani.
"CommandID" menunjukkan fungsi yang disebut trustlet. Ini adalah fungsi trustlet, bukan fungsi TEE. Semua kepedulian TEE adalah memulai trustlet dan mengirim perintah, dan nomor commandID mana yang akan ditugaskan untuk berkomunikasi dengan trustlet terserah Anda, tidak ada aturan atau daftar fungsi global.
Jika Anda perlu meneruskan parameter ke fungsi yang dipanggil, mereka dilewatkan melalui operasi - ini adalah penunjuk ke struktur TEEC_Operation. Kami tidak akan terlalu mendalam sekarang, cukup perhatikan bahwa struktur ini berisi hingga 4 parameter fungsi (tipe TEEC_Parameter). Parameter dapat berupa TEEC_Value sederhana atau penunjuk ke memori. Parameter juga memiliki tipifikasi dalam arah: TEEC_VALUE_INPUT (input), TEEC_VALUE_OUTPUT (output), atau TEEC_VALUE_INOUT (dua arah).
Jika kita meneruskan sebuah pointer ke struktur TEEC_Operation, pertama-tama kita harus menginisialisasi: setel semua nilai dan arah. Setelah panggilan selesai, kami dapat memeriksa nilai yang dikembalikan dalam struktur ini (untuk TEEC_VALUE_OUTPUT dan TEEC_VALUE_INOUT).
Selama sesi, kita dapat memanggil fungsi trustlet sebanyak yang kita butuhkan. Di akhir pekerjaan, Anda harus mengakhiri sesi dan melepaskan konteks dengan menelepon TEEC_CloseSession dan TEEC_FinalizeContext.
Semua ini sangat mengingatkan pada RPC, kan? Pada prinsipnya, semua operasi dengan TEE dirancang sebagai RPC, dan berkat ini, Anda dapat bekerja dengan berbagai implementasi TEE: di TrustZone, di inti yang terpisah, dalam chip yang terpisah.
Pemohon
Di atas, kami bertanya pada diri sendiri: bagaimana TEE mengunduh data dari sistem file atau melalui jaringan?
Jika Anda memikirkannya, TEE sendiri tidak memiliki akses ke sistem file OS. Artinya, TEE yang diterapkan di TrustZone dapat memiliki akses seperti itu, tetapi kemudian harus membaginya dengan Dunia Normal, dan ini tidak begitu sederhana. Sebagai contoh, Linux secara konstan bekerja dengan sistem file, dan kondisi saat ini hanya dalam memori kernel Linux, dan bukan pada disk. Jika TEE ingin melakukan intervensi dan bekerja dengan sistem file secara paralel, itu akan sangat sulit. Dengan berbagi jaringan yang sama.
Selain itu, TEE adalah OS yang agak kecil, dan itu tidak menguntungkan untuk mengimplementasikan driver level rendah untuk bekerja dengan media, dengan pengontrol jaringan, dan mendukung tumpukan jaringan atau driver FS. Selain itu, ini sangat meningkatkan permukaan serangan - akan ada kesempatan untuk memecahkan TEE dengan menyelipkan inode yang tidak biasa pada ext2 atau sesuatu seperti itu. Kami tidak menginginkan itu.
Karena itu, ketika OS dimulai, yang disebut Supplicant dimuat - sebuah program asisten. Itu selalu terhubung ke TEE, dan TEE menggunakannya untuk mengakses sumber daya Dunia Normal.
Oleh karena itu, jika TEE ingin mengunduh gambar trustlet dari sistem file, itu memanggil Supplicant:
TEE: Bagaimana dengan objek dengan UUID seperti itu?
Pemohon: (Memuat objek dari sistem file) Maaf, tuan!Tentu saja, panggilan semacam itu harus diperiksa keamanannya. Dalam hal ini, kami memverifikasi tanda tangan di trustlet dan hampir tidak mengambil risiko - apakah tanda tangan itu benar dan trustlet tersebut berfungsi, atau tanda tangannya salah. Artinya, kami mengambil risiko - mungkin tidak ada trustlet, Pemasok tidak boleh diluncurkan, tetapi ini adalah bagian lain dari model ancaman.
Perpustakaan userspace
Antarmuka program (panggilan ke TEEC_OpenSession, dll.) Diimplementasikan menggunakan perpustakaan yang mentransmisikan panggilan dari tingkat aplikasi ke TEE.
Saat menerapkan TEE di TrustZone, untuk ini, perpustakaan harus terlebih dahulu mentransfer panggilan ke level kernel OS, karena hanya kernel OS yang dapat memanggil SMC (Secure Monitor Call).
Dalam bundel Linux + OP-TEE, pustaka userspace adalah libteec. Itu menerjemahkan panggilan GlobalPlatform TEE Client API ke driver kernel melalui operasi ioctl pada file perangkat: ketika OS dimulai, modul kernel (driver) dimuat, driver membuat file perangkat. Dengan membuka file perangkat dengan libteec, program pengguna dapat bekerja dengan TEE Client API.
Artinya, desain ini berfungsi:
Aplikasi> libteec> file perangkat> driver kernel> SMC> TEE> trust.
Contoh trustlet
Inilah cara kerjanya dalam aplikasi nyata:

Di sini, trustlet digunakan untuk menandatangani dokumen secara elektronik. Sebuah program dari Linux memanggil trustlet, untuk tujuan yang konteks TEE dibuat, sesi dengan trustlet, data untuk penandatanganan dikirimkan, dan tanda tangan elektronik dikembalikan.
Kesimpulan
Dalam artikel ini, kami menemukan TEE dan wali amanat apa. Kami bertemu dengan TEE API dan belajar bagaimana trustlets dipanggil.
Kami sengaja mengesampingkan banyak hal, seperti menggunakan Memori Bersama dan menulis trastlets, karena artikel itu tidak berpura-pura menjadi panduan lengkap.
Jika Anda tertarik dengan topik TEE, maka lanjutkan belajar sendiri: Anda bisa mulai dengan mempelajari spesifikasi GlobalPlatform atau dengan menjelajahi OP-TEE. Anda juga dapat mengirimkan resume yang bertanda βTrustZoneβ kepada kami.