Perlindungan Isi GPU-Based
Topik ini menjelaskan kemampuan perlindungan konten video yang dapat disediakan driver grafis.
- Pendahuluan
- Gambaran Umum Proses Pendekodean
- Mengenkripsi Buffer Video Terkompresi untuk Decoder
- Mengirim Perintah Saluran Terautentikasi
- Mengirim Kueri Saluran Terautentikasi
- Topik terkait
Pengantar
Diagram berikut menunjukkan tampilan yang disederhanakan tentang bagaimana konten video yang dilindungi berjalan melalui alur yang akan dirender.
Catatan
Jalur Media Terproteksi (PMP) tidak digambarkan dalam diagram ini. Aliran data yang ditampilkan di sini mungkin terjadi dalam proses PMP, atau dalam proses aplikasi.
Dekoder menerima data video terenkripsi dan terkompresi dari sumber eksternal. Diasumsikan juga dekoder juga menerima kunci kriptografi untuk mendekripsi data ini. Topik ini tidak menjelaskan pertukaran kunci antara sumber video dan dekoder, tetapi PMP menentukan satu mekanisme yang mungkin. GPU tidak terlibat pada tahap ini.
Untuk pendekodean yang dipercepat perangkat keras, dekoder perangkat lunak meneruskan konten video terkompresi ke GPU. Untuk melindungi konten ini, dekoder mengenkripsi ulang data, biasanya menggunakan AES-CTR, sebelum meneruskannya ke akselerator perangkat keras. Mekanisme pertukaran kunci didefinisikan antara dekoder dan driver grafis.
Bingkai video yang didekodekan disimpan dalam memori video, umumnya di jelaskan. Pada titik ini, bingkai diproses dan kemudian disajikan. Ada dua opsi utama untuk presentasi.
- Bingkai dapat disajikan menggunakan overlay perangkat keras. Untuk informasi selengkapnya, lihat Dukungan Overlay Perangkat Keras.
- Bingkai dapat disajikan oleh Desktop Window Manage (DWM) menggunakan permukaan bersama.
Langkah terakhir adalah menampilkan bingkai pada monitor, yang mungkin memerlukan perlindungan tautan antara kartu grafis dan perangkat tampilan. Contoh perlindungan tautan adalah High-Bandwidth Digital Content Protection (HDCP). Perlindungan tautan dikonfigurasi menggunakan Output Protection Manager (OPM). Topik ini tidak menjelaskan OPM; untuk informasi selengkapnya, lihat Menggunakan Manajer Perlindungan Output.
Gambaran Umum Proses Pendekodean
Selama pendekodean yang dipercepat perangkat keras, dekoder perangkat lunak harus meneruskan data video terkompresi ke kartu grafis. Untuk konten premium, data ini biasanya harus dienkripsi, menggunakan enkripsi kunci simetris, sebelum dikirim ke GPU.
Untuk mengenkripsi video untuk pendekodean, dekoder perangkat lunak menggunakan antarmuka berikut:
- IDirectXVideoDecoder. Mewakili perangkat dekoder DXVA, juga disebut akselerator.
- IDirect3DCryptoSession9. Mewakili sesi kriptografi, yang menyediakan kunci enkripsi.
- IDirect3DAuthenticatedChannel9. Mewakili saluran terautentikasi, yang memungkinkan dekoder perangkat lunak untuk mengaitkan sesi kriptografi dengan dekoder DXVA.
Semua antarmuka ini diperoleh dari perangkat Direct3D, sebagai berikut:
Antarmuka | Pembuatan |
---|---|
IDirectXVideoDecoder | Panggil IDirectXVideoDecoderService::CreateVideoDecoder. Perangkat dekoder DXVA diidentifikasi oleh GUID profil DXVA. |
IDirect3DCryptoSession9 | Panggil IDirect3DDevice9Video::CreateCryptoSession. |
IDirect3DAuthenticatedChannel9 | Panggil IDirect3DDevice9Video::CreateAuthenticatedChannel. |
Catatan
Untuk mendapatkan penunjuk ke antarmuka IDirect3DDevice9Video , panggil QueryInterface pada perangkat D3D9Ex.
Saluran terautentikasi menyediakan saluran komunikasi tepercaya antara dekoder perangkat lunak dan driver. Saluran komunikasi berfungsi sebagai berikut:
- Driver menyediakan rantai sertifikat X.509 yang sertifikat akarnya ditandatangani oleh Microsoft.
- Sertifikat berisi kunci umum RSA untuk driver.
- Dekoder perangkat lunak menggunakan kunci umum untuk mengirim kunci sesi AES 128-bit kepada driver.
- Dekoder perangkat lunak mengirim kueri dan perintah ke saluran yang diautentikasi.
- Kunci sesi digunakan untuk menghitung kode autentikasi pesan (MAC) untuk kueri dan perintah. Driver menggunakan MAC untuk memverifikasi integritas data kueri/perintah, dan dekoder perangkat lunak menggunakannya untuk memverifikasi integritas data respons dari driver.
Mengenkripsi Buffer Video Terkompresi untuk Decoder
Berikut adalah gambaran umum tingkat tinggi dari proses enkripsi dan pendekodean:
Dekoder perangkat lunak menerima aliran data terenkripsi dari sumber video. Dekoder mendekripsi aliran ini.
Dekoder perangkat lunak menegosiasikan kunci sesi dengan sesi kriptografi.
Dekoder perangkat lunak menggunakan saluran terautentikasi untuk mengaitkan sesi kriptografi dengan perangkat dekoder DXVA.
Dekoder perangkat lunak menempatkan data terkompresi dalam buffer DXVA yang didapatkannya dari perangkat dekoder DXVA (akselerator). Untuk konten yang dilindungi, encoder perangkat lunak mengenkripsi data yang dimasukkan ke dalam buffer DXVA, menggunakan kunci sesi untuk enkripsi.
Catatan
Beberapa driver menggunakan kunci konten, bukan kunci sesi, untuk enkripsi. Kunci konten dapat berubah dari satu bingkai ke bingkai berikutnya.
Dekoder mengirimkan buffer terkompresi terenkripsi ke akselerator. Untuk AES-CTR, dekoder juga melewati vektor inisialisasi. Jika kunci konten digunakan, dekoder meneruskan kunci konten, dienkripsi menggunakan kunci sesi.
Direct3D memiliki dukungan standar untuk AES-CTR 128-bit, tetapi dirancang untuk memperluas ke jenis enkripsi tambahan.
Lima bagian berikutnya memberikan langkah-langkah yang lebih rinci.
- 1. Mengkueri Kemampuan Perlindungan Konten Driver
- 2. Mengonfigurasi Saluran Terautentikasi
- 3. Mengonfigurasi Sesi Kriptografi
- 4. Dapatkan Handel ke Perangkat DXVA Decoder
- 5. Kaitkan DXVA Decoder dengan Sesi Kriptografi
1. Mengkueri Kemampuan Perlindungan Konten Driver
Sebelum mencoba menerapkan enkripsi, dapatkan kemampuan perlindungan konten driver.
- Dapatkan pointer ke perangkat Direct3D 9.
- Panggil QueryInterface untuk antarmuka IDirect3DDevice9Video .
- Panggil IDirect3DDevice9Video::GetContentProtectionCaps. Metode ini mengisi struktur D3DCONTENTPROTECTIONCAPS dengan kemampuan perlindungan konten driver.
Secara khusus, cari kemampuan berikut:
- Jika anggota Caps berisi bendera D3DCPCAPS_SOFTWARE atau D3DCPCAPS_HARDWARE , driver dapat melakukan enkripsi.
- Anggota KeyExchangeType menentukan cara melakukan pertukaran kunci untuk kunci sesi.
- Jika anggota Caps berisi bendera D3DCPCAPS_CONTENTKEY , driver menggunakan kunci konten terpisah untuk enkripsi. Ini penting ketika Anda membuat kunci sesi.
Kemampuan tambahan ditunjukkan pada anggota Caps .
2. Mengonfigurasi Saluran Terautentikasi
Langkah selanjutnya adalah mengonfigurasi saluran yang diautentikasi.
Panggil IDirect3DDevice9Video::CreateAuthenticatedChannel untuk membuat saluran yang diautentikasi. Untuk parameter ChannelType , tentukan jenis saluran yang cocok dengan kemampuan driver.
- Jenis saluran D3DAUTHENTICATEDCHANNEL_DRIVER_SOFTWARE sesuai dengan D3DCPCAPS_SOFTWARE.
- Jenis saluran D3DAUTHENTICATEDCHANNEL_DRIVER_HARDWARE sesuai dengan D3DCPCAPS_HARDWARE.
Metode CreateAuthenticatedChannel mengembalikan pointer ke antarmuka IDirect3DAuthenticatedChannel9 bersama dengan handel ke saluran. Handel digunakan nanti untuk mengaitkan sesi kriptografi dengan saluran yang diautentikasi.
Panggil IDirect3DAuthenticatedChannel9::GetCertificateSize untuk mendapatkan ukuran sertifikat X.509 driver. Alokasikan buffer dengan ukuran yang diperlukan.
Panggil IDirect3DAuthenticatedChannel9::GetCertificate untuk mendapatkan sertifikat. Metode menyalin sertifikat ke dalam buffer yang dialokasikan pada langkah sebelumnya.
Verifikasi bahwa sertifikat driver ditandatangani oleh Microsoft dan belum dicabut.
Dapatkan kunci umum dari sertifikat.
Buat kunci sesi RSA acak. Kunci sesi ini digunakan untuk menandatangani data yang dikirim ke saluran terautentikasi. Enkripsi kunci sesi menggunakan kunci umum driver.
Panggil IDirect3DAuthenticatedChannel9::NegotiateKeyExchange untuk mengirim kunci sesi terenkripsi ke driver.
Inisialisasi saluran aman sebagai berikut:
- Isi struktur D3DAUTHENTICATEDCHANNEL_CONFIGUREINITIALIZE seperti yang dijelaskan dalam dokumentasi.
- Kirim perintah D3DAUTHENTICATEDCONFIGURE_INITIALIZE dengan memanggil IDirect3DAuthenticatedChannel9::Configure seperti yang dijelaskan di bagian Mengirim Perintah Saluran Terautentikasi. Perintah ini berisi nomor urutan awal untuk perintah dan kueri yang dikirim ke saluran terautentikasi.
Verifikasi jenis saluran dengan mengirim kueri D3DAUTHENTICATEDQUERY_CHANNELTYPE ke saluran terautentikasi, seperti yang dijelaskan di bagian Mengirim Kueri Saluran Terautentikasi. Periksa apakah jenis saluran cocok dengan apa yang Anda tentukan dalam metode CreateAuthenticatedChannel .
3. Mengonfigurasi Sesi Kriptografi
Selanjutnya, konfigurasikan sesi kriptografi dan buat kunci sesi.
- Panggil IDirect3DDevice9Video::CreateCryptoSession untuk membuat sesi kriptografi. Metode ini mengembalikan penunjuk ke antarmuka IDirect3DCryptoSession9 dan bersama dengan handel ke sesi kriptografi.
- Panggil IDirect3DCryptoSession9::GetCertificateSize untuk mendapatkan ukuran sertifikat X.509 driver. Alokasikan buffer dengan ukuran yang diperlukan.
- Panggil IDirect3DCryptoSession9::GetCertificate untuk mendapatkan sertifikat. Metode menyalin sertifikat ke dalam buffer yang dialokasikan pada langkah sebelumnya.
- Verifikasi bahwa sertifikat driver ditandatangani oleh Microsoft dan belum dicabut.
- Dapatkan kunci umum dari sertifikat.
- Buat kunci sesi RSA acak. Ini adalah kunci sesi terpisah dari kunci sesi saluran yang diautentikasi. Enkripsi kunci sesi menggunakan kunci umum driver.
- Panggil IDirect3DCryptoSession9::NegotiateKeyExchange untuk mengirim kunci sesi terenkripsi ke driver.
- Jika kemampuan perlindungan konten menyertakan D3DCPCAPS_CONTENTKEY, buat kunci konten RSA acak. Ini akan digunakan nanti dalam proses pendekodean.
4. Dapatkan Handel ke Perangkat DXVA Decoder
Untuk langkah berikutnya, Anda akan memerlukan handel ke perangkat dekoder DXVA. Untuk mendapatkan handel ini, isi struktur DXVA2_DecodeExecuteParams sebagai berikut:
HANDLE hDecodeDeviceHandle;
DXVA2_DecodeExecuteParams execParams = {0};
DXVA2_DecodeExtensionData ExtensionExecute = {0};
execParams.NumCompBuffers = 0;
execParams.pCompressedBuffers = NULL;
execParams.pExtensionData = &ExtensionExecute;
ExtensionExecute.Function = DXVA2_DECODE_GET_DRIVER_HANDLE;
ExtensionExecute.pPrivateInputData = NULL;
ExtensionExecute.PrivateInputDataSize = 0;
ExtensionExecute.pPrivateOutputData = &hDecodeDeviceHandle;
ExtensionExecute.PrivateOutputDataSize = sizeof(HANDLE);
Atur anggota pExtensionData dari struktur DXVA2_DecodeExecuteParams ke alamat struktur DXVA2_DecodeExtensionData .
Dalam struktur DXVA2_DecodeExtensionData , atur anggota Fungsi ke DXVA2_DECODE_GET_DRIVER_HANDLE. Atur pPrivateOutputData ke alamat buffer yang cukup besar untuk menyimpan nilai HANDLE . (Dalam contoh sebelumnya, buffer ini adalah variabel hDecodeDeviceHandle .)
Kemudian panggil IDirectXVideoDecoder::Execute dan berikan alamat struktur DXVA2_DecodeExecuteParams . Handel ke dekoder DXVA dikembalikan dalam pPrivateOutputData.
5. Kaitkan DXVA Decoder dengan Sesi Kriptografi
Selanjutnya, kaitkan perangkat dekoder DXVA dengan perangkat Direct3D dan sesi kriptografi, sebagai berikut:
- Dapatkan handel ke perangkat dekoder DXVA, seperti yang dijelaskan di bagian sebelumnya.
- Dapatkan handel ke perangkat Direct3D, dengan mengirim kueri D3DAUTHENTICATEDQUERY_DEVICEHANDLE ke saluran yang diautentikasi.
- Isi struktur D3DAUTHENTICATEDCHANNEL_CONFIGURECRYPTOSESSION dengan informasi berikut:
- Atur anggota DXVA2DecodeHandle ke handel ke perangkat dekoder DXVA.
- Atur anggota CryptoSessionHandle ke handel ke sesi kriptografi. Handel ini dikembalikan oleh metode IDirect3DDevice9Video::CreateCryptoSession .
- Atur anggota DeviceHandle ke handel perangkat Direct3D.
- Panggil IDirect3DAuthenticatedChannel9::Configure untuk mengirim perintah D3DAUTHENTICATEDCONFIGURE_CRYPTOSESSION ke saluran yang diautentikasi.
Diagram berikut mengilustrasikan pertukaran handel:
Dekoder perangkat lunak sekarang dapat menggunakan kunci sesi kriptografi untuk mengenkripsi buffer video terkompresi. Setiap buffer terkompresi akan memiliki vektor inisialisasi sendiri (IV) yang ditentukan dalam anggota pvPVPState dari struktur DXVA2_DecodeBufferDesc .
Mengirim Perintah Saluran Terautentikasi
Sekumpulan perintah ditentukan untuk mengonfigurasi saluran yang diautentikasi dan mengatur berbagai perlindungan konten. Untuk daftar perintah, lihat Perintah Perlindungan Konten.
Untuk mengirim perintah ke saluran terautentikasi, lakukan langkah-langkah berikut.
- Isi struktur data input. Struktur data ini selalu merupakan struktur D3DAUTHENTICATEDCHANNEL_CONFIGURE_INPUT diikuti dengan bidang tambahan. Isi struktur D3DAUTHENTICATEDCHANNEL_CONFIGURE_INPUT seperti yang diperlihatkan dalam tabel berikut ini.
Anggota | Deskripsi |
---|---|
omac | Lewati bidang ini untuk saat ini. |
ConfigureType | GUID yang mengidentifikasi perintah. Untuk daftar perintah, lihat Perintah Perlindungan Konten. |
hChannel | Handel ke saluran yang diautentikasi. |
SequenceNumber | Nomor urut. Nomor urutan pertama ditentukan dengan mengirim perintah D3DAUTHENTICATEDCONFIGURE_INITIALIZE . Setiap kali Anda mengirim perintah lain, tingkatkan angka ini dengan 1. Nomor urut menjaga terhadap serangan pemutaran ulang.
Catatan: Dua nomor urutan terpisah digunakan, satu untuk perintah dan satu untuk kueri. |
- Hitung tag OMAC untuk blok data yang muncul setelah anggota omac struktur input. Kemudian salin nilai tag ini ke anggota omac .
- Panggil IDirect3DAuthenticatedChannel9::Configure.
- Driver menempatkan output dari perintah dalam struktur D3DAUTHENTICATEDCHANNEL_CONFIGURE_OUTPUT .
- Hitung tag OMAC untuk blok data yang muncul setelah anggota omac dari struktur output. Bandingkan ini dengan nilai anggota omac . Gagal jika tidak cocok.
- Bandingkan nilai anggota ConfigureType, hChannel, dan SequenceNumber dalam struktur output dengan nilai Anda untuk anggota tersebut. Gagal jika tidak cocok.
- Tingkatkan nomor urut untuk perintah berikutnya.
Mengirim Kueri Saluran Terautentikasi
Sekumpulan kueri ditentukan untuk mengambil informasi tentang saluran yang diautentikasi. Untuk daftar kueri, lihat Kueri Perlindungan Konten.
Untuk mengirim perintah ke saluran terautentikasi, lakukan langkah-langkah berikut.
- Isi struktur data input. Struktur data ini selalu merupakan struktur D3DAUTHENTICATEDCHANNEL_QUERY_INPUT , mungkin diikuti oleh bidang tambahan. Isi struktur D3DAUTHENTICATEDCHANNEL_QUERY_INPUT seperti yang diperlihatkan dalam tabel berikut ini.
Anggota | Deskripsi |
---|---|
QueryType | GUID yang mengidentifikasi kueri. Untuk daftar kueri, lihat Kueri Perlindungan Konten. |
hChannel | Handel ke saluran terautentikasi. |
SequenceNumber | Nomor urut. Nomor urut pertama ditentukan dengan mengirim perintah D3DAUTHENTICATEDCONFIGURE_INITIALIZE . Setiap kali Anda mengirim kueri lain, naikkan angka ini sebesar 1. Nomor urut menjaga dari serangan pemutaran ulang.
Catatan: Dua nomor urutan terpisah digunakan, satu untuk perintah dan satu untuk kueri. |
- Panggil IDirect3DAuthenticatedChannel9::Query.
- Driver menempatkan output dari kueri dalam struktur D3DAUTHENTICATEDCHANNEL_QUERY_OUTPUT . Struktur ini diikuti oleh bidang tambahan, tergantung pada jenis kueri.
- Hitung tag OMAC untuk blok data yang muncul setelah anggota omac struktur output. Bandingkan ini dengan nilai anggota omac . Gagal jika tidak cocok.
- Bandingkan nilai anggota ConfigureType, hChannel, dan SequenceNumber dalam struktur output terhadap nilai Anda untuk anggota tersebut. Gagal jika tidak cocok.
- Tahapkan nomor urut untuk kueri berikutnya.