Lingkungan Eksekusi Tepercaya pada contoh Intel SGX. Prinsip dasar dalam istilah sederhana. "Halo Dunia!"

Artikel ini ditujukan terutama untuk spesialis pemula yang hanya

mulai meneliti metode dan cara untuk memastikan keamanan informasi dari kode program yang dapat dieksekusi. Cepat atau lambat, semua pengembang perangkat lunak dan insinyur sistem menghadapi tugas seperti itu, yang terjadi di salah satu proyek Sistem Altiriks, dalam kerangka di mana perlu untuk mengimplementasikan eksekusi yang aman dari kode program dalam lingkungan yang tidak terlindungi secara kondisional. Untuk tujuan ini, selain metode dan cara yang sudah terkenal dan dijelaskan dengan baik untuk melindungi informasi, teknologi Trusted Execution Environment (TEE), yang jarang digunakan dalam proyek Rusia, atau, dalam bahasa Rusia, teknologi lingkungan eksekusi tepercaya, dipilih. Khususnya dalam artikel ini, kami memutuskan untuk menjelaskan contoh praktis penggunaan casing prosesor Intel untuk lingkungan eksekusi kode tepercaya (Intel Software Guard Extensions atau SGX).



Waktu proses tepercaya tidak hanya didukung oleh prosesor dari pabrikan tertentu. Selain itu, TEE didukung oleh sejumlah prosesor AMD (Secure Execution Environment, Secure Technology), prosesor ARM (TrustZone), dan prosesor RISC-V. Selain itu, TEE didukung oleh mainframe IBM Z modern. Kami memilih Intel SGX sebagai contoh karena kami percaya bahwa pada saat penulisan ini (musim panas 2020) prosesor Intel adalah yang paling populer dan tersedia untuk pemula di wilayah pasca-Soviet. Untuk daftar lengkap model prosesor Intel yang mendukung Intel SGX, kunjungi situs web Intel di bawah spesifikasi produk Intel (ARK) dengan memilih teknologi yang sesuai untuk mencari. Dan ya, mungkin manfaatkan emulasi Intel SGX untuk tujuan pendidikan atau penelitian.Bekerja dengan beberapa emulasi ini mengungkapkan sejumlah kesulitan dalam menyiapkannya. Anda juga perlu memahami bahwa untuk proyek "pertempuran" yang sebenarnya, tidak ada persaingan teknologi yang didasarkan pada fungsionalitas peralatan, tentu saja, dapat diterima.



Setiap umpan balik Anda, terutama dengan komentar dan tambahan dari spesialis yang sudah memiliki pengalaman dalam menggunakan TEE dalam proyek mereka, atau dengan pertanyaan dari mereka yang baru mulai membenamkan diri dalam teknologi ini, akan berkontribusi pada pengungkapan yang lebih mendetail tentang topik ini di artikel berikut. Terima kasih sebelumnya!



pengantar



Pertanyaan utama yang kami tanyakan di awal perjalanan menjelajahi lingkungan runtime tepercaya adalah: dapatkah kami mempercayai komponen sistem komputer? Dan jika kita bisa, bagaimana caranya? Pengembang, dan khususnya insinyur Intel, memberikan jawaban tegas untuk pertanyaan ini: tidak seorang pun kecuali Intel itu sendiri. Apa artinya ini? Saya mengusulkan untuk memahami ini lebih detail.



Cincin hak istimewa



Untuk tujuan keamanan, komponen sistem komputer mana pun dibagi menurut tingkat hak istimewa. Semua sistem modern berdasarkan prosesor Intel dan tidak hanya memiliki sistem cincin hak istimewa. Dari eksternal ke internal, ada perluasan otoritas untuk kode yang saat ini sedang diproses oleh prosesor.





Nomor cincin 3. Cincin luar berisi semua aplikasi pengguna yang kami gunakan di komputer dalam kehidupan sehari-hari, mereka memiliki tingkat akses terendah.

Cincin No. 2 dan No. 1. Sistem operasi dan driver perangkat berada di level ini.

Nomor dering 0. Mode pengawas. Di sinilah kernel sistem operasi (manajemen periferal, alokasi sumber daya antar proses) berada, serta driver sistem.

Nomor dering-1. Hypervisor. Bertanggung jawab atas alokasi sumber daya jika beberapa sistem operasi berjalan di komputer pada saat yang sama, dan juga bertanggung jawab untuk mengisolasi mereka.

Nomor dering-2.Mode Manajemen Sistem (SMM - Mode Manajemen Sistem). Mengelola catu daya sistem, mengelola kartu ekspansi.



Kita dapat membentuk lebih banyak cincin untuk membatasi kekuatan komponen hierarki, menciptakan sistem yang semakin kompleks dan dimuat. Namun, ini hanya akan membuat pekerjaan penyerang lebih mudah: semakin kompleks sistemnya, semakin mudah menemukan kerentanan di dalamnya. Tetapi bagaimana Anda dapat memberikan lapisan keamanan ekstra di tempat yang Anda butuhkan? Jawabannya adalah satu kata.



Kantong



Tugas utama penyerang adalah mendapatkan tingkat hak istimewa yang akan memberinya akses ke sumber daya sistem yang diperlukan. Jika ini adalah rahasia dari aplikasi korban, maka aplikasi berbahaya tersebut membutuhkan tingkat akses yang bertanggung jawab untuk menyimpan rahasia dalam sistem. Ini menunjukkan kesimpulan bahwa pengelolaan rahasia aplikasi harus dipercayakan ke ring terdalam, karena akses di sana adalah yang paling sulit dari semuanya. Namun, pendekatan ini telah dipikirkan ulang. Sekarang semua rahasia disimpan pada tingkat yang sama dengan aplikasi pengguna, serta kode yang mengelola rahasia ini dalam satu syarat: tidak ada, sama sekali tidak ada, kecuali prosesor, yang dapat mengaksesnya. Program dan data seolah-olah dikemas ke dalam sebuah penyimpanan, dalam hal ini penyimpanan ini disebut enklave (Enklave - tertutup, terkunci),kunci yang hanya dimiliki oleh prosesor.





Aplikasi yang bekerja dengan lingkungan tepercaya



Semakin sederhana sistem, semakin sedikit kode yang dikandungnya, semakin sulit untuk membukanya berdasarkan lubang keamanan (kita tidak berbicara tentang sistem yang secara fundamental tidak terlindungi), kita mendapatkan aksioma tertentu: kode yang bekerja dengan sebuah rahasia harus sesederhana dan sesingkat mungkin. Mengemas seluruh kode program ke dalam suatu enklaf tidak praktis, sehingga aplikasi yang menggunakan enklaf harus dibagi menjadi dua bagian: "dipercaya" dan "tidak tepercaya". Yang terpercaya menyimpan enklave (mungkin ada beberapa di antaranya), dan yang tidak terpercaya menyimpan kode program utama.



Bagian terpercaya adalah sekumpulan fungsi dan prosedur yang disebut ECALL (Enclave Call). Tanda tangan dari fungsi tersebut harus ditulis dalam file header khusus, dan implementasinya dalam file kode sumber. Secara umum, pendekatannya mirip dengan apa yang kami gunakan untuk penulisan tajuk biasa, namun, dalam konteks ini, bahasa khusus C-like EDL (Enclave Definition Language) digunakan. Penting juga untuk menulis prototipe dari fungsi-fungsi yang dapat dipanggil dari dalam enklaf, fungsi tersebut disebut OCALL (Panggilan Luar). Prototipe ditulis dalam header yang sama dengan fungsi ECALL, dan implementasinya, tidak seperti ECALL, ditulis sesuai di bagian aplikasi yang tidak tepercaya.

Kode tepercaya dan tidak tepercaya terikat secara kaku dengan sertifikasi menggunakan protokol Diffie-Hellman. Prosesor bertanggung jawab atas prosedur penandatanganan, di mana kunci pertukaran informasi disimpan, yang diperbarui setiap kali sistem di-boot ulang. Konten enklaf disimpan di memori bersama yang digunakan oleh aplikasi pengguna, tetapi penyimpanannya dienkripsi. Hanya prosesor yang dapat mendekripsi konten. Di dunia yang ideal, di mana kode enklave ditulis tanpa bug tunggal, dan semua perangkat keras bekerja persis seperti yang diinginkan pabrikan dan tidak ada yang lain, kami akan mendapatkan sistem universal yang sepenuhnya aman. Keuntungan utama dari sistem ini adalah eksekusi bagian rahasia pada prosesor yang sama di mana semua program lain, termasuk program pengguna, dijalankan.



Namun, dalam beberapa tahun terakhir, sejumlah besar kerentanan mikroarsitektur prosesor modern telah muncul di hadapan khalayak luas, memungkinkan akses ke bagian dalam enklave: Foreshadow (kerentanan kelas momok), SGAxe, Zombieload, CacheOut, dan banyak lainnya. Tidak ada jaminan bahwa daftar ini tidak akan diisi ulang dengan kerentanan perangkat keras serius lainnya, yang perbaikan perangkat lunaknya tidak dapat disebut "tambalan" perangkat lunak. Mungkin kita akan hidup untuk melihat waktu ketika arsitektur prosesor yang benar-benar baru akan dihadirkan kepada dunia, di mana semua kekurangan akan diperbaiki, tetapi untuk saat ini, ada baiknya berbicara tentang apa yang kita miliki. Dan saat ini kami memiliki alat serbaguna dan canggih yang secara dramatis meningkatkan keamanan sistem saat ini. Membesarkan begitu banyakyang diterapkan dalam satu interpretasi atau lainnya di miliaran perangkat di seluruh dunia: dari jam tangan pintar, ponsel cerdas hingga kelompok komputasi yang sangat besar.



Halo Dunia!



Mari beralih dari teori ke praktik. Mari kita tulis program kecil yang mengimplementasikan tugas yang sudah kanonik: cetak string "Hello world!" Dalam interpretasi ini, kami juga akan menunjukkan tempat dari mana pesan tersebut akan dikirim.



Pertama, Anda perlu mengunduh dan menginstal SDK untuk bekerja dengan SGX dari situs web resmi. Untuk mengunduh, Anda harus melalui prosedur pendaftaran sederhana. Pada tahap instalasi, Anda akan diminta untuk mengintegrasikan paket pengembangan ke versi VS yang tersedia di komputer Anda, lakukan ini. Semuanya siap untuk keberhasilan implementasi proyek pertama Anda menggunakan SGX.





Luncurkan VS dan buat proyek Intel SGX.





Kami memilih nama untuk proyek dan solusinya dan menunggu "berikutnya".



Selanjutnya, Anda akan diminta untuk memilih konfigurasi proyek, jangan ubah apa pun, biarkan nilai yang semula diusulkan.







Kemudian tambahkan proyek lain ke solusi yang dibuat: aplikasi konsol C ++ biasa.

Hasilnya, gambar berikut akan muncul di kotak dialog proyek:







Maka Anda perlu menautkan enklaf ke bagian yang tidak tepercaya. Klik kanan pada proyek "Bagian tidak tepercaya".







Selanjutnya, Anda perlu mengubah beberapa properti proyek.



gambar






Ini harus dilakukan agar program dapat bekerja dengan benar. Kami mengulangi langkah-langkah untuk kedua proyek tersebut.



Juga perlu untuk menunjukkan proyek utama di properti solusi.





Selesai, program kami siap diimplementasikan.



Program ini akan memiliki 3 file yang akan kita kerjakan: Enclave.edl (header yang sama), Enclave.cpp (implementasi ECALLs dijabarkan), Untrusted Part.cpp (file proyek utama adalah bagian yang tidak tepercaya). Mari kita masukkan



kode berikut ke dalam file:



Untusted Part.cpp:



#define ENCLAVE_FILE "Enclave.signed.dll" //,     

#include "sgx_urts.h" // ,           
#include "Enclave_u.h" //   
#include "stdio.h"

void print_string(char* buf) //OCALL     -   
{
	printf("ocall output: %s\n", buf);
}

int main()
{
	sgx_enclave_id_t eid; // id ,      ,    id
	sgx_status_t ret = SGX_SUCCESS; //        
	sgx_launch_token_t token = { 0 }; //    
	int updated = 0; //      
	const int BUF_LEN = 30; //  ,     

	ret = sgx_create_enclave(ENCLAVE_FILE, SGX_DEBUG_FLAG, &token, &updated, &eid, NULL); //  

	if (ret != SGX_SUCCESS)
	{
		printf("Failed to create enclave with error number: %#x\n", ret); //  
		return 0;
	}
	char buf[BUF_LEN]; //  ,      

	enclaveChat(eid, buf, BUF_LEN); // ECALL  

	printf("\noutput form main(): %s\n", buf); //  
}


Enclave.edl:



enclave {
    from "sgx_tstdc.edl" import *;

    trusted {
        /* define ECALLs here. */
        public void enclaveChat([out, size=len] char* str, size_t len);
        /*   ,    . OUT -   ,   
                , out     .
           ,          ,
                 .
        */
    };

    untrusted {
        /* define OCALLs here. */
        void print_string([in, string] char* buf); //  ,     
    };
};


Enclave.cpp:



#include "Enclave_t.h"

#include "sgx_trts.h"
#include <cstring>

void enclaveChat(char* str, size_t len)
{
	char* secret = "Hello from better place"; //   

	memcpy(str, secret, len); //   ,  

	print_string(secret); // OCALL-  
}


Tekan f7 - buat solusi, lalu ctrl + f5 untuk menjalankan.



Jika Anda mendapatkan error seperti ini:





pastikan Intel SGX diaktifkan di BIOS: Bios: Keamanan / IntelSGX / Diaktifkan.



Jika tidak ada kesalahan, dan di depan layar pada konsol, Anda melihat baris berikut:





... selamat, program pertama Anda dengan teknologi Intel SGX sudah siap. Saya harap komentar dalam kode itu komprehensif untuk dipahami, jika tidak, Anda selalu dapat mengajukan pertanyaan di sini di komentar atau di pesan pribadi.



All Articles