Bagaimana cara mengenkripsi byte menggunakan modul TPM mesin?
CryptProtectData
Windows menyediakan API (relatif) sederhana untuk mengenkripsi blob menggunakan CryptProtectData
API, yang dapat kita bungkus dengan fungsi yang mudah digunakan:
public Byte[] ProtectBytes(Byte[] plaintext)
{
//...
}
Detailnya ProtectBytes
kurang penting daripada gagasan yang bisa Anda gunakan dengan cukup mudah:
- berikut adalah byte yang saya ingin dienkripsi oleh kunci rahasia yang disimpan di
System
- kembalikan gumpalan terenkripsi itu
Blob yang dikembalikan adalah struktur dokumentasi tidak berdokumen yang berisi semua yang diperlukan untuk mendekripsi dan mengembalikan data asli (algoritme hash, algoritme sandi, garam, tanda tangan HMAC, dll).
Untuk kelengkapannya, berikut ini contoh implementasi pseudocode ProtectBytes
yang menggunakan Crypt API
to protect bytes:
public Byte[] ProtectBytes(Byte[] plaintext)
{
//Setup our n-byte plaintext blob
DATA_BLOB dataIn;
dataIn.cbData = plaintext.Length;
dataIn.pbData = Addr(plaintext[0]);
DATA_BLOB dataOut;
//dataOut = EncryptedFormOf(dataIn)
BOOL bRes = CryptProtectData(
dataIn,
null, //data description (optional PWideChar)
null, //optional entropy (PDATA_BLOB)
null, //reserved
null, //prompt struct
CRYPTPROTECT_UI_FORBIDDEN || CRYPTPROTECT_LOCAL_MACHINE,
ref dataOut);
if (!bRes) then
{
DWORD le = GetLastError();
throw new Win32Error(le, "Error calling CryptProtectData");
}
//Copy ciphertext from dataOut blob into an actual array
bytes[] result;
SetLength(result, dataOut.cbData);
CopyMemory(dataOut.pbData, Addr(result[0]), dataOut.cbData);
//When you have finished using the DATA_BLOB structure, free its pbData member by calling the LocalFree function
LocalFree(HANDLE(dataOut.pbData)); //LocalFree takes a handle, not a pointer. But that's what the SDK says.
}
Bagaimana melakukan hal yang sama dengan TPM?
Kode di atas berguna untuk mengenkripsi data hanya untuk mesin lokal. Data dienkripsi menggunakan System
akun sebagai penghasil kunci ( detail, meski menarik, tidak penting ). Hasil akhirnya adalah saya dapat mengenkripsi data (misalnya kunci master enkripsi hard drive) yang hanya dapat didekripsi oleh mesin lokal.
Sekarang saatnya untuk mengambil satu langkah lebih jauh. Saya ingin mengenkripsi beberapa data (misalnya kunci master enkripsi hard drive) yang hanya dapat didekripsi oleh TPM lokal. Dengan kata lain, saya ingin mengganti Qualcomm Trusted Execution Environment ( TEE ) dalam diagram blok di bawah ini untuk Android, dengan TPM di Windows:
Catatan : Saya menyadari bahwa TPM tidak melakukan penandatanganan data (atau jika demikian, tidak menjamin bahwa penandatanganan data yang sama akan memberikan keluaran biner yang sama setiap saat). Itulah mengapa saya bersedia mengganti "penandatanganan RSA" dengan "mengenkripsi blob 256-bit dengan kunci terikat perangkat keras" .
Jadi dimana kodenya?
Masalahnya adalah bahwa pemrograman TPM sama sekali tidak terdokumentasi di MSDN . Tidak ada API yang tersedia untuk melakukan operasi apa pun. Alih-alih Anda harus menemukan sendiri salinan Tumpukan Perangkat Lunak Grup Komputasi Tepercaya (alias TSS) , cari tahu perintah apa yang akan dikirim ke TPM, dengan payload, dalam urutan apa, dan panggil fungsi Tbsip_Submit_Command Window untuk mengirimkan perintah secara langsung:
TBS_RESULT Tbsip_Submit_Command(
_In_ TBS_HCONTEXT hContext,
_In_ TBS_COMMAND_LOCALITY Locality,
_In_ TBS_COMMAND_PRIORITY Priority,
_In_ const PCBYTE *pabCommand,
_In_ UINT32 cbCommand,
_Out_ PBYTE *pabResult,
_Inout_ UINT32 *pcbOutput
);
Windows tidak memiliki API tingkat yang lebih tinggi untuk melakukan tindakan.
Ini setara moral mencoba membuat file teks dengan mengeluarkan perintah SATA I / O ke hard drive Anda .
Kenapa tidak pakai celana saja
Trusted Computing Group (TCG) menentukan API mereka sendiri: TCB Software Stack (TSS) . Implementasi API ini dibuat oleh beberapa orang, dan disebut TrouSerS . Seorang pria kemudian memindahkan proyek itu ke Windows .
Masalah dengan kode itu adalah bahwa ia tidak portabel ke dunia Windows. Misalnya, Anda tidak dapat menggunakannya dari Delphi, Anda tidak dapat menggunakannya dari C #. Ini membutuhkan:
- OpenSSL
- pThread
Saya hanya ingin kode mengenkripsi sesuatu dengan TPM saya.
Hal di atas CryptProtectData
tidak membutuhkan apa pun selain apa yang ada di dalam tubuh fungsi.
Apa kode yang setara untuk mengenkripsi data menggunakan TPM? Seperti yang telah dicatat orang lain, Anda mungkin harus membaca ketiga manual TPM, dan membuat sendiri blob . Ini mungkin melibatkan TPM_seal
perintah. Meskipun saya pikir saya tidak ingin menyegel data, saya rasa saya ingin mengikatnya :
Binding - mengenkripsi data menggunakan kunci ikat TPM, kunci RSA unik yang diturunkan dari kunci penyimpanan. Sealing - mengenkripsi data dengan cara yang mirip dengan pengikatan, tetapi juga menentukan keadaan di mana TPM harus berada agar data dapat didekripsi (tidak disegel)
Saya mencoba membaca tiga volume yang diperlukan untuk menemukan 20 baris kode yang saya butuhkan:
Tapi saya tidak tahu apa yang saya baca. Jika ada tutorial atau contoh apa pun, saya mungkin bisa mencobanya. Tapi aku benar-benar tersesat.
Jadi kami meminta Stackoverflow
Dengan cara yang sama saya dapat memberikan:
Byte[] ProtectBytes_Crypt(Byte[] plaintext)
{
//...
CryptProtectData(...);
//...
}
dapatkah seseorang memberikan padanan yang sesuai:
Byte[] ProtectBytes_TPM(Byte[] plaintext)
{
//...
Tbsip_Submit_Command(...);
Tbsip_Submit_Command(...);
Tbsip_Submit_Command(...);
//...snip...
Tbsip_Submit_Command(...);
//...
}
yang melakukan hal yang sama, kecuali kunci yang dikunci di System
LSA, dikunci di TPM?
Mulai Riset
Saya tidak tahu persis apa artinya bind . Tetapi melihat TPM Utama - Perintah Bagian 3 - Spesifikasi Versi 1.2, ada penyebutan bind :
10.3 TPM_UnBind
TPM_UnBind mengambil blob data yang merupakan hasil dari perintah Tspi_Data_Bind dan mendekripsinya untuk diekspor ke Pengguna. Penelepon harus mengizinkan penggunaan kunci yang akan mendekripsi blob yang masuk. TPM_UnBind beroperasi pada basis blok-demi-blok, dan tidak memiliki gagasan tentang hubungan apa pun antara satu blok dan lainnya.
Apa yang membingungkan adalah ada adalah tidak ada Tspi_Data_Bind
perintah.
Upaya Penelitian
Sungguh mengerikan bagaimana tidak seorang pun pernah repot-repot mendokumentasikan TPM atau operasinya. Seolah-olah mereka menghabiskan waktu mereka datang dengan ini keren hal untuk bermain dengan, tetapi tidak mau berurusan dengan langkah yang menyakitkan sehingga dapat digunakan untuk sesuatu.
Dimulai dengan buku gratis (sekarang) A Practical Guide to TPM 2.0: Using the Trusted Platform Module in the New Age of Security :
Bab 3 - Tutorial Cepat di TPM 2.0
TPM memiliki akses ke kunci pribadi yang dibuat sendiri, sehingga dapat mengenkripsi kunci dengan kunci publik dan kemudian menyimpan blob yang dihasilkan pada hard disk. Dengan cara ini, TPM dapat menyimpan kunci dalam jumlah yang hampir tidak terbatas yang tersedia untuk digunakan tetapi tidak menyia-nyiakan penyimpanan internal yang berharga. Kunci yang disimpan pada hard disk dapat dihapus, tetapi mereka juga dapat dicadangkan, yang bagi para perancang tampaknya merupakan pertukaran yang dapat diterima.
Bagaimana cara mengenkripsi kunci dengan kunci publik TPM?
Bab 4 - Aplikasi yang Ada yang Menggunakan TPM
Aplikasi Yang Harus Menggunakan TPM tetapi Tidak
Dalam beberapa tahun terakhir, jumlah aplikasi berbasis web mengalami peningkatan. Diantaranya adalah backup dan penyimpanan berbasis web. Sejumlah besar perusahaan sekarang menawarkan layanan seperti itu, tetapi sejauh yang kami ketahui, tidak ada klien untuk layanan ini yang mengizinkan pengguna mengunci kunci layanan cadangan ke TPM. Jika ini dilakukan, alangkah baiknya jika kunci TPM itu sendiri dicadangkan dengan menduplikasinya di beberapa mesin. Ini tampaknya menjadi peluang bagi pengembang.
Bagaimana cara pengembang mengunci kunci TPM?
Bab 9 - Heirarki
GUNAKAN KASUS: MENYIMPAN SANDI LOGIN
File kata sandi biasa menyimpan hash kata sandi yang diasinkan. Verifikasi terdiri dari salting dan hashing kata sandi yang diberikan dan membandingkannya dengan nilai yang disimpan. Karena kalkulasi tidak menyertakan rahasia, itu tunduk pada serangan offline pada file kata sandi.
Kasus penggunaan ini menggunakan kunci HMAC yang dibuat TPM. File kata sandi menyimpan HMAC dari kata sandi asin. Verifikasi terdiri dari salting dan HMACing kata sandi yang disediakan dan membandingkannya dengan nilai yang disimpan. Karena penyerang offline tidak memiliki kunci HMAC, penyerang tidak dapat melakukan serangan dengan melakukan kalkulasi.
Ini bisa berhasil. Jika TPM memiliki kunci HMAC rahasia, dan hanya TPM saya yang mengetahui kunci HMAC tersebut, saya dapat mengganti "Masuk (alias enkripsi TPM dengan kunci pribadinya)" dengan "HMAC". Tapi kemudian di baris berikutnya dia membalikkan dirinya sepenuhnya:
TPM2_Create, dengan menentukan kunci HMAC
Bukan rahasia TPM jika saya harus menentukan kunci HMAC. Fakta bahwa kunci HMAC bukanlah rahasia masuk akal ketika Anda menyadari bahwa ini adalah bab tentang utilitas kriptografi yang disediakan TPM. Daripada Anda harus menulis SHA2, AES, HMAC, atau RSA sendiri, Anda dapat menggunakan kembali apa yang sudah ada di TPM.
Bab 10 - Kunci
Sebagai perangkat keamanan, kemampuan aplikasi untuk menggunakan kunci sekaligus menjaganya tetap aman di perangkat perangkat keras adalah kekuatan terbesar TPM. TPM dapat menghasilkan dan mengimpor kunci yang dibuat secara eksternal. Ini mendukung kunci asimetris dan simetris.
Luar biasa! Bagaimana Anda melakukannya!?
Generator Kunci
Bisa dibilang, kekuatan terbesar TPM adalah kemampuannya untuk menghasilkan kunci kriptografik dan melindungi rahasianya dalam batasan perangkat keras. Generator kunci didasarkan pada generator nomor acak TPM sendiri dan tidak bergantung pada sumber keacakan eksternal. Dengan demikian, ia menghilangkan kelemahan berdasarkan perangkat lunak yang lemah dengan sumber entropi yang tidak mencukupi.
Apakah TPM memiliki kemampuan untuk membuat kunci kriptografi dan melindungi rahasianya dalam batasan perangkat keras? Bagaimana caranya?
Bab 12 - Register Konfigurasi Platform
PCR untuk Otorisasi
GUNAKAN KASUS: SEALING KUNCI ENKRIPSI HARD DISK KE NEGARA PLATFORM
Aplikasi enkripsi disk penuh jauh lebih aman jika TPM melindungi kunci enkripsi daripada jika disimpan di disk yang sama, hanya dilindungi oleh sandi. Pertama, perangkat keras TPM memiliki perlindungan anti-palu (lihat Bab 8 untuk penjelasan rinci tentang perlindungan serangan kamus TPM), membuat serangan brute force pada sandi tidak praktis. Kunci yang hanya dilindungi oleh perangkat lunak jauh lebih rentan terhadap kata sandi yang lemah. Kedua, kunci perangkat lunak yang disimpan di disk jauh lebih mudah untuk dicuri. Ambil disk (atau cadangan dari disk), dan Anda mendapatkan kuncinya. Ketika TPM memegang kunci, seluruh platform, atau setidaknya disk dan motherboard, harus dicuri.
Penyegelan memungkinkan kunci untuk dilindungi tidak hanya dengan kata sandi tetapi juga oleh kebijakan. Kebijakan tipikal mengunci kunci ke nilai PCR (status perangkat lunak) saat ini pada saat penyegelan. Ini mengasumsikan bahwa status saat boot pertama kali tidak terganggu. Malware prainstal apa pun yang ada pada boot pertama akan diukur ke dalam PCR, dan dengan demikian kuncinya akan disegel ke status perangkat lunak yang disusupi. Perusahaan yang kurang percaya mungkin memiliki gambar disk standar dan segel ke PCR yang mewakili gambar itu. Nilai PCR ini akan dihitung sebelumnya pada platform yang mungkin lebih tepercaya. Perusahaan yang lebih canggih akan menggunakan TPM2_PolicyAuthorize, dan menyediakan beberapa tiket yang mengesahkan sekumpulan nilai PCR tepercaya. Lihat Bab 14 untuk penjelasan rinci tentang otorisasi kebijakan dan penerapannya untuk memecahkan masalah kerapuhan PCR.
Meskipun kata sandi juga bisa melindungi kunci, ada keuntungan keamanan bahkan tanpa kata sandi kunci TPM. Penyerang dapat mem-boot platform tanpa memberikan kata sandi TPM, tetapi tidak dapat masuk tanpa nama pengguna dan kata sandi OS. Keamanan OS melindungi data. Penyerang dapat mem-boot OS alternatif, katakanlah dari live DVD atau USB stick daripada dari hard drive, untuk melewati keamanan login OS. Namun, konfigurasi boot dan perangkat lunak yang berbeda ini akan mengubah nilai PCR. Karena PCR baru ini tidak akan cocok dengan nilai yang disegel, TPM tidak akan melepaskan kunci dekripsi, dan hard drive tidak dapat didekripsi.
Luar biasa! Inilah kasus penggunaan yang kebetulan saya inginkan. Ini juga merupakan kasus penggunaan TPM yang digunakan Microsoft. Bagaimana saya melakukannya!?
Jadi saya membaca seluruh buku itu, dan tidak ada yang berguna. Yang cukup mengesankan karena 375 halaman. Anda bertanya-tanya apa isi buku itu - dan melihat ke belakang, saya tidak tahu.
Jadi kami menyerah pada panduan definitif untuk memprogram TPM, dan beralih ke beberapa dokumentasi dari Microsoft:
Dari Toolkit Penyedia Kripto Platform TPM Microsoft . Itu menyebutkan dengan tepat apa yang ingin saya lakukan:
The Endorsement Key atau EK
EK dirancang untuk menyediakan pengenal kriptografi yang andal untuk platform. Perusahaan mungkin memelihara basis data Kunci Pengesahan milik TPM dari semua PC di perusahaan mereka, atau pengontrol kain pusat data mungkin memiliki basis data TPM di semua bilah. Di Windows, Anda dapat menggunakan penyedia NCrypt yang dijelaskan di bagian "Penyedia Platform Crypto di Windows 8" untuk membaca bagian publik dari EK.
Di suatu tempat di dalam TPM terdapat kunci pribadi RSA. Kunci itu terkunci di sana - tidak akan pernah terlihat oleh dunia luar. Saya ingin TPM menandatangani sesuatu dengan kunci privatnya (yaitu mengenkripsinya dengan kunci privat).
Jadi saya ingin operasi paling dasar yang mungkin ada:
Enkripsi sesuatu dengan kunci pribadi Anda. Saya bahkan belum (belum) meminta hal-hal yang lebih rumit:
- "menyegel" itu berdasarkan status PCR
- membuat kunci dan menyimpannya dalam memroy yang mudah menguap atau tidak mudah menguap
- membuat kunci simetris dan mencoba memuatnya ke TPM
Saya meminta operasi paling dasar yang dapat dilakukan TPM. Mengapa tidak mungkin mendapatkan informasi apa pun tentang cara melakukannya?
Saya bisa mendapatkan data acak
Saya kira saya sedang fasih ketika saya mengatakan penandatanganan RSA adalah hal paling dasar yang dapat dilakukan TPM. Hal paling mendasar yang dapat diminta oleh TPM adalah memberi saya byte acak. Bahwa saya telah menemukan cara melakukannya:
public Byte[] GetRandomBytesTPM(int desiredBytes)
{
//The maximum random number size is limited to 4,096 bytes per call
Byte[] result = new Byte[desiredBytes];
BCRYPT_ALG_HANDLE hAlgorithm;
BCryptOpenAlgorithmProvider(
out hAlgorithm,
BCRYPT_RNG_ALGORITHM, //AlgorithmID: "RNG"
MS_PLATFORM_CRYPTO_PROVIDER, //Implementation: "Microsoft Platform Crypto Provider" i.e. the TPM
0 //Flags
);
try
{
BCryptGenRandom(hAlgorithm, @result[0], desiredBytes, 0);
}
finally
{
BCryptCloseAlgorithmProvider(hAlgorithm);
}
return result;
}
Hal Yang Menarik
Saya menyadari volume orang yang menggunakan TPM sangat rendah. Itulah mengapa tidak ada orang di Stackoverflow yang memiliki jawabannya. Jadi saya tidak bisa terlalu serakah dalam mendapatkan solusi untuk masalah umum saya. Namun hal yang sangat ingin saya lakukan adalah "menyegel" beberapa data:
- menyajikan TPM beberapa data (misalnya 32 byte materi kunci)
- meminta TPM mengenkripsi data, mengembalikan beberapa struktur blob yang buram
- kemudian minta TPM untuk mendekripsi blob tersebut
- dekripsi hanya akan berfungsi jika register PCR TPM sama seperti pada saat enkripsi.
Dengan kata lain:
Byte[] ProtectBytes_TPM(Byte[] plaintext, Boolean sealToPcr)
{
//...
}
Byte[] UnprotectBytes_TPM(Byte[] protectedBlob)
{
//...
}
Cryptography Next Gen (Cng, aka BCrypt) mendukung TPM
API Kriptografi asli di Windows dikenal sebagai API Kripto.
Dimulai dengan Windows Vista, Crypto API telah diganti dengan Cryptography API: Next Generation (secara internal dikenal sebagai BestCrypt , disingkat BCrypt , jangan disamakan dengan algoritma hashing kata sandi ).
Windows dikirimkan dengan dua penyedia BCrypt :
- Microsoft Primitive Provider (
MS_PRIMITIVE_PROVIDER
) default : Implementasi perangkat lunak default dari semua primitif (hashing, enkripsi simetris, tanda tangan digital, dll) - Microsoft Platform Crypto Provider (
MS_PLATFORM_CRYPTO_PROVIDER
): Penyedia yang menyediakan akses TPM
The Landasan Crypto penyedia tidak didokumentasikan di MSDN, tetapi memiliki dokumentasi dari situs 2012 Microsoft Research:
Perangkat Penyedia Crypto Platform TPM
Penyedia dan Alat Kripto Platform TPM berisi kode contoh, utilitas, dan dokumentasi untuk menggunakan fungsionalitas terkait TPM di Windows 8. Subsistem yang dijelaskan mencakup penyedia kripto platform Crypto-Next-Gen (CNG) yang didukung TPM, dan bagaimana penyedia layanan pengesahan dapat menggunakan fitur Windows baru. Baik sistem berbasis TPM1.2 dan TPM2.0 didukung.
Tampaknya niat Microsoft adalah untuk menampilkan fungsionalitas crypto TPM dengan Penyedia Crypto Platform Microsoft dari Cryptography NG API.
Enkripsi kunci publik menggunakan Microsoft BCrypt
Mengingat bahwa:
- saya ingin melakukan enkripsi asimetris RSA (menggunakan TPM)
- Microsoft BestCrypt mendukung enkripsi asimetris RSA
- Microsoft BestCrypt memiliki Penyedia TPM
satu cara ke depan adalah mencari cara untuk melakukan penandatanganan digital menggunakan Microsoft Cryptography Next Gen API .
Langkah saya selanjutnya adalah membuat kode untuk melakukan enkripsi di BCrypt, dengan kunci publik RSA, menggunakan penyedia standar ( MS_PRIMITIVE_PROVIDER
). Misalnya:
modulus
: 0xDC 67 FA F4 9E F2 72 1D 45 2C B4 80 79 06 A0 94 27 50 8209 DD 67 CE 57 B8 6C 4A 4F 40 9F D2 D1 69 FB 995D 85 0C 07 A1 F9 47 1B 56 16 6E F6 7F B9 CF 2A 58 36 37 99 29 AA 4F A8 12 E8 4F C7 82 2B 9D 72 2A 9C DE 6F C2 EE 12 6D CF F0 F2 B8 C4 DD 7C 5C 1A C8 17 51 A9 AC DF 08 22 04 9D 2B D7 F9 4B 09 DE 9A EB 5C 51 1A D8 F8 F9 56 9E F8 FB 37 9B 3F D3 74 65 24 0D FF 34 75 57 A4 F5 BF 55publicExponent
: 65537
Dengan kode yang berfungsi, saya mungkin dapat beralih menggunakan TPM Provider ( MS_PLATFORM_CRYPTO_PROVIDER
).
2/22/2016: Dan dengan Apple yang dipaksa untuk membantu mendekripsi data pengguna, muncul minat baru tentang cara membuat TPM melakukan tugas paling sederhana yang diciptakannya - mengenkripsi sesuatu.
Ini kira-kira sama dengan semua orang yang memiliki mobil, tetapi tidak ada yang tahu bagaimana memulainya. Ini dapat melakukan hal-hal yang sangat berguna dan keren, jika saja kita dapat melewati Langkah 1 .
Bonus Membaca
sumber
Jawaban:
Primer
Berikut ini adalah tentang TPM 1.2. Ingatlah bahwa Microsoft memerlukan TPM 2.0 untuk semua versi Windows di masa mendatang. Generasi 2.0 secara fundamental berbeda dengan 1.2
Tidak ada solusi satu baris karena prinsip desain TPM. Pikirkan TPM sebagai mikrokontroler dengan sumber daya terbatas. Tujuan desain utamanya adalah menjadi murah, namun tetap aman. Jadi TPM telah merobek semua logika yang tidak diperlukan untuk operasi yang aman. Jadi TPM hanya berfungsi ketika Anda memiliki setidaknya beberapa perangkat lunak yang lebih atau kurang gemuk , mengeluarkan banyak perintah dalam urutan yang benar. Dan urutan perintah tersebut mungkin menjadi sangat kompleks. Itulah mengapa TCG menentukan TSS dengan API yang ditentukan dengan baik. Jika Anda ingin menggunakan Java, bahkan ada API Java tingkat tinggi . Saya tidak mengetahui proyek serupa untuk C # / .net
Pengembangan
Dalam kasus Anda, saya sarankan Anda melihat TPM perangkat lunak IBM.
Dalam paketnya Anda akan menemukan 3 komponen yang sangat berguna:
Anda tidak memerlukan emulator TPM software, Anda juga dapat terhubung ke HW TPM mesin. Namun, Anda dapat mencegat perintah yang dikeluarkan dan melihat tanggapannya, sehingga mempelajari bagaimana mereka dirakit dan bagaimana mereka sesuai dengan spesifikasi perintah.
Level tinggi
Prasyarat:
Untuk menutup blob, Anda perlu melakukan hal berikut:
Untuk membuka segel, Anda perlu:
Anda dapat menyimpan key-blob dalam struktur data yang Anda gunakan untuk menyimpan byte yang dilindungi.
Sebagian besar perintah TPM yang Anda butuhkan adalah perintah resmi. Oleh karena itu, Anda perlu membuat sesi otorisasi jika diperlukan. AFAIR itu kebanyakan sesi OSAP.
Perintah TPM
Saat ini saya tidak dapat menjalankan versi debug, jadi saya tidak dapat memberikan urutan persisnya kepada Anda. Jadi pertimbangkan ini sebagai daftar perintah tidak berurutan yang harus Anda gunakan:
TPM_OSAP
TPM_CreateWrapKey
TPM_LoadKey2
TPM_Seal
Jika Anda ingin membaca nilai PCR saat ini juga:
TPM_PCRRead
sumber
Kunci Terpercaya dan Terenkripsi
Kunci Terpercaya dan Terenkripsi adalah dua jenis kunci baru yang ditambahkan ke layanan key ring kernel yang ada. Kedua jenis baru ini adalah kunci simetris dengan panjang variabel, dan dalam kedua kasus semua kunci dibuat di kernel, dan ruang pengguna hanya melihat, menyimpan, dan memuat gumpalan terenkripsi. Kunci Tepercaya memerlukan ketersediaan chip Trusted Platform Module (TPM) untuk keamanan yang lebih baik, sementara Kunci Terenkripsi dapat digunakan di sistem apa pun. Semua blob tingkat pengguna, ditampilkan dan dimuat dalam hex ascii untuk kenyamanan, dan diverifikasi integritasnya.
Kunci Tepercaya menggunakan TPM untuk menghasilkan dan menyegel kunci. Kunci disegel di bawah kunci RSA 2048 bit di TPM, dan secara opsional disegel ke nilai PCR (pengukuran integritas) yang ditentukan, dan hanya dibuka oleh TPM, jika PCR dan verifikasi integritas blob cocok. Kunci Tepercaya yang dimuat dapat diperbarui dengan nilai PCR baru (di masa mendatang), sehingga kunci mudah dimigrasi ke nilai pcr baru, seperti saat kernel dan initramf diperbarui. Kunci yang sama dapat memiliki banyak blob yang disimpan dengan nilai PCR yang berbeda, sehingga banyak boot dapat dengan mudah didukung.
Secara default, kunci tepercaya disegel di bawah SRK, yang memiliki nilai otorisasi default (20 nol). Ini dapat diatur pada waktu takeownership dengan utilitas celana ini:
tpm_takeownership -u -z
.keyctl print
mengembalikan salinan hex ascii dari kunci tersegel, yang dalam format TPM_STORED_DATA standar. Panjang kunci untuk kunci baru selalu dalam satuan byte. Kunci Tepercaya dapat berukuran 32 - 128 byte (256 - 1024 bit), batas atas adalah sesuai dengan panjang kunci SRK (RSA) 2048 bit, dengan semua struktur / bantalan yang diperlukan.Kunci terenkripsi tidak bergantung pada TPM, dan lebih cepat, karena menggunakan AES untuk enkripsi / dekripsi. Kunci baru dibuat dari nomor acak yang dihasilkan kernel, dan dienkripsi / didekripsi menggunakan kunci 'master' yang ditentukan. Kunci 'master' bisa berupa kunci-tepercaya atau jenis kunci-pengguna. Kerugian utama dari kunci terenkripsi adalah jika kunci tersebut tidak di-root pada kunci tepercaya, kunci tersebut hanya seaman kunci pengguna yang mengenkripsinya. Oleh karena itu, kunci pengguna master harus dimuat dengan cara seaman mungkin, sebaiknya di awal boot.
Bagian kunci terenkripsi yang didekripsi dapat berisi kunci simetris sederhana atau struktur yang lebih kompleks. Format struktur yang lebih kompleks adalah khusus aplikasi, yang diidentifikasi dengan 'format'.
Contoh penggunaan kunci tepercaya dan terenkripsi
Buat dan simpan kunci tepercaya bernama "kmk" dengan panjang 32 byte:
Muat kunci tepercaya dari blob yang disimpan:
Ulangi kunci tepercaya di bawah nilai pcr baru:
Konsumen awal kunci tepercaya adalah EVM, yang pada saat boot membutuhkan kunci simetris berkualitas tinggi untuk perlindungan HMAC atas metadata file. Penggunaan kunci tepercaya memberikan jaminan kuat bahwa kunci EVM tidak diganggu oleh masalah level pengguna, dan ketika disegel ke nilai PCR booting tertentu, melindungi dari serangan boot dan offline. Buat dan simpan kunci "evm" yang dienkripsi menggunakan kunci tepercaya "kmk" di atas:
opsi 1: menghilangkan 'format'
opsi 2: secara eksplisit mendefinisikan 'format' sebagai 'default'
Muat kunci terenkripsi "evm" dari blob yang disimpan:
Penggunaan lain untuk kunci tepercaya dan terenkripsi, seperti untuk disk dan enkripsi file diantisipasi. Secara khusus, format baru 'ecryptfs' telah ditentukan untuk menggunakan kunci terenkripsi untuk memasang sistem file eCryptfs. Detail lebih lanjut tentang penggunaan dapat ditemukan di file 'Documentation / security / keys-ecryptfs.txt'.
sumber
Documentation/security/keys-ecryptfs.tx
Tergantung pada niat dan keadaan Anda:
Masing-masing kasus penggunaan ini (dan masih banyak lagi) - atau kombinasinya - menyajikan jalur implementasi yang berbeda. Pikirkan TPM sebagai pisau Swiss Army untuk perangkat kriptografi: tidak banyak yang tidak dapat Anda lakukan dengannya, tetapi kemudahan penggunaan mempengaruhi keserbagunaan itu. Pertanyaannya terus berpindah antara mengenkripsi, menandatangani, dan mengunci konfigurasi sistem, tetapi bagian utama dari jawaban ini akan mempertimbangkan perintah Seal untuk memenuhi sebagian besar kebutuhan yang dijelaskan dalam pertanyaan.
Untuk inilah perintah Bind (digantikan oleh perintah Buat untuk TPM 2). Anda memuat kunci yang berasal dari kunci terikat TPM dan mengenkripsinya (atau langsung dengan kunci terikat perangkat keras). Dengan cara ini data hanya dapat didekripsi dengan akses ke TPM yang sama.
Tidak yakin apakah mereplikasi seluruh proses ini adalah ide yang bagus. Pertama, tidak perlu menggunakan operasi penandatanganan di mana pun dalam proses. Tampaknya, pada saat Android 5 sedang dikembangkan, file API Keystore terbatas pada operasi penandatanganan dan verifikasi. Dugaan terbaik saya adalah bahwa tim enkripsi disk melakukan yang terbaik untuk bekerja dengan apa yang mereka miliki dan merancang algoritme di mana salah satu kunci perantara diturunkan dengan operasi penandatanganan , menggunakan kunci TEE yang tersimpan, sehingga mengikat seluruh proses ke perangkat keras- kunci terikat hanya tersedia di platform - karena penandatanganan adalah satu-satunya cara untuk melakukannya pada saat itu. Namun, Anda tidak perlu membatasi diri dengan cara seperti itu jika memiliki akses ke TPM, yang memberi Anda kemampuan lebih dari yang Anda tahu dibutuhkan!
Ini salah, kedua versi penandatanganan dukungan TPM.
Ini tidak masuk akal. Penandatanganan data yang sama dengan kunci yang sama akan menghasilkan tanda tangan yang sama. Anda mungkin mengacaukan operasi penandatanganan dengan operasi kutipan, yang akan mencampurkan nonce.
Ini sebenarnya harus menjadi opsi yang disukai, meskipun keduanya dimungkinkan dengan TPM. Lihat di atas.
Sayangnya tidak banyak yang bisa didokumentasikan. Win API terbatas pada beberapa fungsi TBS yang satu levelnya dihapus dari driver.
Sebenarnya, tidak, jika Anda memiliki TSS, Anda tidak perlu menggunakannya
Tbsip_submit_Command()
. Itulah inti dari memiliki TSS - detail tingkat rendah disarikan.Masih berlaku untuk TPM 1, tetapi untuk TPM 2 ada TSS.MSR .
Benar.
Tidak jelas apakah ini adalah tantangan yang tidak dapat diatasi. Mengakses TrouSerS melalui interop sebaiknya lebih disukai daripada menulis ulang semua kode penataan data. Juga, ada
doTSS
saat menulis pertanyaan.Pertanyaan tersebut berisi kutipan yang menjelaskan perbedaan antara kedua perintah tersebut, jadi seharusnya tidak ada banyak kebingungan. Penyegelan mirip dengan pengikatan, dengan tambahan kendala bahwa status sistem harus sama agar data dapat dibuka.
Pertama, perlu diperhatikan bahwa ada dua versi utama TPM, yang sama sekali tidak kompatibel satu sama lain. Jadi hampir tidak ada kode yang Anda tulis untuk TPM 1 yang akan berfungsi untuk TPM 2. API TBS adalah satu-satunya kode umum di antara keduanya dan, agar adil bagi Microsoft, ini mungkin salah satu alasan mengapa API tersebut tidak pernah berkembang. Bagian utama dari jawaban akan menampilkan kode untuk TPM 1 karena dua alasan:
Kedua, mari kita buat pertanyaannya lebih spesifik. Saya menafsirkannya kembali sebagai berikut:
Perintah Seal paling cocok untuk ini, karena menjalankan fungsi yang sama dengan perintah Bind ketika ukuran pilihan PCR diatur ke nol, tetapi pilihan PCR dapat dengan mudah diubah untuk menyertakan PCR yang Anda inginkan. Itu membuat orang bertanya-tanya mengapa perintah Bind dimasukkan dalam spesifikasi sama sekali, dan seperti yang dicatat itu telah dihapus dalam spesifikasi TPM 2 dan keduanya digabungkan dalam satu perintah Buat.
Berikut adalah kode C # untuk menggunakan perintah TPM 1.2 Seal untuk mengenkripsi data hanya dengan fungsi TBS (catatan: kode ini belum teruji dan tidak mungkin bekerja tanpa debugging) :
Analisis Kode:
Ini adalah beberapa dari sedikit fungsi yang tersedia di Tbs.h dan satu-satunya yang akan kami gunakan di sini. Mereka pada dasarnya memungkinkan Anda untuk membuka pegangan ke perangkat dan berkomunikasi dengannya dengan mengirim dan menerima byte mentah.
TPM adalah big endian, Windows adalah little endian. Jadi urutan byte harus dibalik untuk setiap data yang kami kirim. Kita hanya perlu mengkhawatirkan pembalikan unsigned int 32-bit dan 16-bit di sini.
Di sini kita menggunakan Tbsi_Context_Create () untuk membuka pegangan untuk berbicara dengan TPM. The
TBS_CONTEXT_PARAMS
parameter hanya C struct dengan satu unsigned 32-bit int bidang yang harus di set ke 1 untuk berbicara dengan TPM 1.2 misalnya, dan bahwa apa yang kita set ke.Ini ditentukan sebagai ukuran buffer minimum dalam Spesifikasi Klien PC TPM . Ini akan lebih dari cukup untuk kebutuhan kita di sini.
TPM 1.2 Spec Part 3 mengatakan hal berikut:
Kita perlu mengenkripsi XOR parameter "rahasia" ini menggunakan nonce yang dihasilkan selama sesi OSAP. Salah satu pegangan masukan perintah Seal juga merupakan pegangan OSAP:
Jadi kita perlu membuat sesi OSAP ini terlebih dahulu. OSAP dijelaskan di mana mencampurkan data otorisasi objek dengan nonce yang dihasilkan di setiap sisi untuk mencegah serangan balasan. Oleh karena itu, "rahasia bersama" hanya diketahui oleh dua pihak dalam sesi ini: pihak yang memulai sesi (pengguna) dan pihak yang menerimanya (TPM); juga, kedua belah pihak harus memiliki data otorisasi objek yang sama agar "rahasia bersama" menjadi sama; selain itu, "rahasia bersama" yang digunakan dalam satu sesi akan menjadi tidak valid di sesi lain. Diagram dari spesifikasi ini menjelaskan prosesnya: TPM 1.2 Spesifikasi Bagian 1 . OSAP, atau Object-Specific Authorization Protocol, diciptakan untuk menangani kasus penggunaan di mana Anda ingin menggunakan objek TPM yang memerlukan otorisasi beberapa kali, tetapi tidak ingin memberikan otorisasi setiap kali: sesi OSAP digunakan, yang bergantung pada pada konsep "rahasia bersama", yang merupakan HMAC
Kami tidak akan menggunakan beberapa sesi dalam kasus khusus ini (pada kenyataannya, parameter itu diabaikan dengan perintah Seal!) Dan kunci yang akan kami gunakan tidak memerlukan otorisasi, tetapi sayangnya kami masih terikat oleh spesifikasi untuk membuat OSAP sidang.
Operand perintah TPM_OSAP adalah:
Setiap perintah TPM 1.2 ditata seperti ini:
Tag adalah nilai dua byte yang menunjukkan apakah yang berikut adalah masukan atau keluaran, dan apakah ada nilai data autentikasi yang mengikuti parameter perintah. Untuk TPM_OSAP, tagnya harus TPM_TAG_RQU_COMMAND (0x00C1) sesuai spesifikasi, yang berarti "perintah tanpa otorisasi".
Ukuran adalah nilai empat byte yang menentukan ukuran perintah dalam byte, termasuk tag dan ukuran itu sendiri. Kami akan menetapkan nilai ini nanti, setelah kami menghitungnya.
Kode perintah adalah nilai empat byte yang server sebagai ID perintah: ini memberi tahu TPM bagaimana menafsirkan perintah lainnya. Kode perintah kami di sini adalah TPM_OSAP (0x0000000B).
Dua hal berikutnya yang harus ditetapkan adalah tipe entitas dan nilai entitas. Karena kami ingin menggunakan kunci yang sudah ada di TPM, kami akan menggunakan jenis entitas "SRK" (0x0004), dan karena kami bekerja dengan asumsi bahwa TPM telah dimiliki, dapat diasumsikan bahwa ia telah SRK dimuat di bawah pegangan permanen 0x40000000 sesuai spesifikasi, jadi kita akan menggunakan nilai pegangan permanen ini untuk nilai entitas kita. (SRK adalah singkatan dari "Storage Root Key" dan merupakan kunci root dari mana sebagian besar kunci milik TPM lainnya berasal)
Akhirnya kami menghitung ukuran perintah dan mengaturnya, dan mengirim perintah.
Data yang seharusnya kami dapatkan kembali dari TPM di TPM_OSAP adalah:
Jadi kami kembali:
Kami mengekstrak nilai-nilai itu dan menyimpannya dalam variabel.
Kemudian kami menghitung "rahasia bersama". Sesuai spesifikasi, nilai yang masuk ke dalam penghitungan adalah dua nonce OSAP (satu dihasilkan oleh pengguna dan satu dihasilkan oleh TPM) dan nilai otorisasi untuk kunci yang ingin kita gunakan - SRK. Sesuai ketentuan, nilai autentikasi SRK adalah "autentikasi terkenal": buffer 20 byte yang dikosongkan. Secara teknis, seseorang dapat mengubah nilai ini ke sesuatu yang lain saat mengambil kepemilikan TPM, tetapi hal ini tidak dilakukan dalam praktiknya, sehingga kami dapat dengan aman mengasumsikan nilai "autentikasi terkenal" adalah baik.
Selanjutnya mari kita lihat apa yang masuk ke dalam perintah TPM_Seal:
Sebagian besar parameter ini mudah dibuat, kecuali dua di antaranya:
encAuth
danpubAuth
. Mari kita lihat satu per satu.encAuth
adalah "AuthData terenkripsi untuk data tersegel." AuthData kami di sini adalah "auth terkenal" dari sebelumnya, tapi ya kami masih harus mengenkripsinya. Karena kami menggunakan sesi OSAP, sesi itu dienkripsi mengikuti ADIP, atau Protokol Penyisipan Data Otorisasi. Dari spesifikasi: "ADIP memungkinkan pembuatan entitas baru dan penyisipan aman dari entitas baru AuthData. Transmisi AuthData baru menggunakan enkripsi dengan kunci berdasarkan rahasia bersama dari sesi OSAP." Selain itu: "Untuk algoritme enkripsi XOR wajib, pembuat membuat kunci enkripsi menggunakan hash SHA-1 dari rahasia bersama OSAP dan nonce sesi. Pembuat XOR mengenkripsi AuthData baru menggunakan kunci enkripsi sebagai pad satu kali dan mengirimkan data terenkripsi ini bersama dengan permintaan pembuatan ke TPM. "Diagram berikut menjelaskan bagaimana ADIP beroperasi:
pubAuth
adalah "Intisari sesi otorisasi untuk input dan keyHandle." Bagian 1 dari spesifikasi, di "Deklarasi Parameter untuk Contoh OIAP dan OSAP" menjelaskan cara menafsirkan tabel parameter TPM_Seal di atas: "Kolom HMAC # merinci parameter yang digunakan dalam penghitungan HMAC. Parameter 1S, 2S, dll. Digabungkan dan di-hash ke inParamDigest atau outParamDigest, secara implisit disebut 1H1 dan mungkin 1H2 jika ada dua sesi otorisasi. Untuk sesi pertama, 1H1, 2H1, 3H1, dan 4H1 digabungkan dan HMAC'ed. Untuk sesi kedua, 1H2, 2H2, 3H2, dan 4H2 digabungkan dan HMAC'ed. " Jadi kita harusencAuth
mencirikan teks biasa, ukurannya, ukuran info PCR, dari atas dan ordinal TPM_Seal, dan kemudian HMAC dengan dua nonce dan "lanjutkan sesi" boolean menggunakan OSAP "Menyatukan semuanya dalam diagram:
Perhatikan bagaimana kami menyetel "ukuran info PCR" ke nol dalam kode ini, karena kami hanya ingin mengenkripsi data tanpa menguncinya ke status sistem. Namun, memberikan struktur "info PCR" jika perlu adalah hal yang sepele.
Akhirnya kami membuat perintah dan mengirimkannya.
Kami menggunakan fungsi Tbsip_Context_Close () untuk menutup pegangan komunikasi kami.
Kami mengembalikan tanggapan apa adanya di sini. Idealnya Anda ingin membalikkan byte lagi dan memvalidasinya dengan menghitung ulang
resAuth
nilainya untuk mencegah serangan man-in-the-middle.Ini karena Tspi_Data_Bind adalah perintah TSS, bukan perintah TPM. Alasannya karena tidak memerlukan rahasia (hanya public key yang digunakan) sehingga bisa dilakukan tanpa melibatkan TPM. Hal ini menyebabkan kebingungan, dan bahkan perintah yang tidak memerlukan rahasia sekarang disertakan dalam spesifikasi TPM 2.
Tergantung pada versi TPM. Dengan perintah TPM_CreateWrapKey untuk TPM 1.2. Dengan perintah TPM2_Create untuk TPM 2.
Buatlah itu di TPM, atau bungkus, atau gunakan metode lain yang tersedia.
Teks di buku itu membingungkan. Anda tidak menentukan kunci HMAC , Anda menentukan bahwa Anda menginginkan kunci HMAC .
Tidak, itu tidak masuk akal. Kuncinya adalah rahasia.
Ada perintah untuk membuat kunci atau mengimpornya untuk kedua versi TPM. Untuk TPM 1 hanya ada satu kunci root - SRK - tempat Anda dapat membuat hierarki kunci dengan membuat kunci yang digabungkan. Dengan TPM 2 Anda dapat memiliki beberapa kunci utama, atau akar,.
Lihat di atas.
Mungkin tergantung pada jenis drive. Dalam kasus drive non-SED, kunci enkripsi drive mungkin dibungkus dengan kunci TPM. Dalam kasus drive SED, kata sandi Admin1 (atau semacamnya) disegel dengan TPM.
EK bukanlah kunci penandatanganan - ini adalah kunci enkripsi. Namun, ini bukan kunci enkripsi untuk tujuan umum: ini hanya dapat digunakan dalam konteks tertentu .
Lihat di atas.
sumber
Saat tertulis
ini TIDAK berarti memberikan kunci HMAC - ini berarti "menunjuk ke kunci HMAC yang ingin Anda gunakan" .
TPM dapat menggunakan kunci HMAC dalam jumlah yang hampir tidak terbatas, seperti yang ditunjukkan di buku ini. Anda harus memberi tahu TPM mana yang akan digunakan.
sumber