Menggunakan Manajer Perlindungan Output

Topik ini menjelaskan cara menggunakan Output Protection Manager (OPM) untuk melindungi konten video saat melakukan perjalanan melalui konektor fisik ke perangkat tampilan. Topik ini berisi bagian berikut:

Konten video premium biasanya dienkripsi untuk melindunginya dari duplikasi yang tidak sah. Tentu saja, video harus didekripsi sebelum ditampilkan. Bingkai yang didekripsi dan tidak dikompresi kemudian harus melakukan perjalanan melintasi konektor fisik ke perangkat tampilan. Penyedia konten mungkin mengharuskan bingkai video dilindungi pada saat ini, saat mereka melakukan perjalanan di seluruh konektor fisik.

Berbagai mekanisme perlindungan ada untuk tujuan ini, termasuk High-Bandwidth Digital Content Protection (HDCP) dan DisplayPort Content Protection (DPCP) untuk output digital; dan Copy Generation Management System - Analog (CGMS-A) untuk output analog. Umumnya, mekanisme ini melibatkan enkripsi atau pengacak sinyal sebelum masuk ke layar.

OPM memungkinkan aplikasi untuk menerapkan mekanisme perlindungan konten pada output video. Menggunakan OPM, aplikasi mengirimkan perintah dan permintaan status ke driver grafis melalui saluran yang tepercaya dan aman. OPM memungkinkan aplikasi untuk:

  • Verifikasi bahwa driver grafis telah ditandatangani oleh Microsoft.
  • Siapkan saluran komunikasi tepercaya dengan driver.
  • Menerapkan mekanisme perlindungan konten pada output fisik.

OPM menggantikan Certified Output Protection Protocol (COPP) dan menggunakan API serupa. Untuk kompatibilitas mundur, antarmuka OPM dapat meniru antarmuka COPP. Perbedaan antara OPM dan COPP meliputi:

  • OPM menggunakan sertifikat X.509, sementara COPP menggunakan format sertifikat kepemilikan.
  • OPM mendukung pengulang HDCP.
  • Aplikasi yang menggunakan OPM tidak perlu mengurai pesan perpanjangan sistem (SRM) HDCP.
  • OPM dapat digunakan ketika tampilan grafis menggunakan mode kloning. COPP tidak mendukung mode kloning.

Jika aplikasi Anda menggunakan jalur media yang dilindungi (PMP) untuk memutar konten video, Anda tidak perlu menggunakan OPM API, karena PMP melakukan semua panggilan OPM yang diperlukan. OPM API tersedia untuk aplikasi yang tidak menggunakan PMP.

OPM tersedia di Windows Vista dan yang lebih baru, tetapi API tidak dibuat publik sampai Windows 7. Untuk menggunakan OPM dalam aplikasi, Anda harus memiliki header dan file pustaka dari Windows 7 SDK. Anda tidak perlu mendistribusikan ulang DLL apa pun untuk menggunakan OPM di Windows Vista atau Windows Server 2008.

Output Video

Adaptor grafis dapat memiliki lebih dari satu output fisik, masing-masing dengan kemampuannya sendiri. Sebelum aplikasi memutar konten yang dilindungi, aplikasi harus mengatur mekanisme perlindungan yang sesuai pada setiap output video yang terkait dengan kartu grafis yang akan menampilkan video. Mekanisme perlindungan mana yang akan diterapkan akan bergantung pada aturan penggunaan untuk konten.

Setiap output video diwakili oleh instans antarmuka IOPMVideoOutput . Anda dapat menggunakan perangkat Direct3D atau handel monitor untuk mendapatkan output video.

Menggunakan perangkat Direct3D:

  1. Dapatkan penunjuk IDirect3DDevice9 untuk perangkat Direct3D yang akan digunakan aplikasi Anda untuk membuat permukaan untuk menahan bingkai video.
  2. Panggil fungsi OPMGetVideoOutputsFromIDirect3DDevice9Object. Fungsi ini mengalokasikan array pointer IOPMVideoOutput , satu untuk setiap output.

Menggunakan handel monitor:

  1. Panggil EnumDisplayMonitors untuk mendapatkan handel HMONITOR yang sesuai dengan jendela video. Beberapa monitor dapat dikaitkan dengan jendela yang sama, sehingga Anda mungkin mendapatkan beberapa handel HMONITOR .
  2. Untuk setiap handel monitor, panggil OPMGetVideoOutputsFromHMONITOR. Fungsi ini mengalokasikan array pointer IOPMVideoOutput , satu untuk setiap output.

Menginisialisasi Sesi OPM

Sebelum aplikasi mengirim perintah OPM atau permintaan status, aplikasi harus memverifikasi bahwa output video tepercaya dan membuat kunci sesi. Kunci sesi digunakan untuk menandatangani data yang ditukar antara aplikasi dan driver grafis.

OPM API mendefinisikan jabat tangan yang membangun kepercayaan dan mengatur kunci sesi. Anda harus melakukan jabat tangan ini untuk setiap instans antarmuka IOPMVideoOutput , sebagai berikut:

  1. Panggil IOPMVideoOutput::StartInitialization. Metode ini mengambil dua bagian data:

    • Angka acak, dihasilkan oleh driver. Anda akan menggunakan nomor ini untuk menyelesaikan jabat tangan.
    • Rantai sertifikat X.509 driver.
  2. Verifikasi bahwa rantai sertifikat telah ditandatangani oleh Microsoft.

    Catatan

    Pencabutan sertifikat berada di luar cakupan OPM.

     

  3. Dapatkan kunci umum driver dari rantai sertifikat.

  4. Buat kunci sesi AES 128-bit.

  5. Hasilkan dua angka 32-bit acak:

    • Nomor urutan awal untuk permintaan status OPM.
    • Nomor urutan awal untuk perintah OPM.

    Angka-angka ini harus dihasilkan menggunakan generator angka pseudo-random yang aman secara kriptografis, seperti CryptGenRandom.

  6. Salin nomor acak driver (diperoleh pada langkah 1), kunci sesi, dan dua nomor urutan ke dalam struktur OPM_ENCRYPTED_INITIALIZATION_PARAMETERS, seperti yang dijelaskan dalam IOPMVideoOutput::FinishInitialization.

  7. Enkripsi struktur OPM_ENCRYPTED_INITIALIZATION_PARAMETERS dengan RSAES-OAEP, menggunakan kunci umum driver, yang ditemukan dalam sertifikat driver.

  8. Panggil IOPMVideoOutput::FinishInitialization.

Mengirim Permintaan Status OPM

Permintaan status OPM mengembalikan informasi tentang output video, seperti jenis konektor fisik dan tingkat perlindungan saat ini. Untuk daftar jenis permintaan, lihat Permintaan Status OPM.

Untuk mengirim permintaan status, lakukan langkah-langkah berikut.

  1. Inisialisasi struktur OPM_GET_INFO_PARAMETERS seperti yang diperlihatkan dalam tabel berikut.

    Anggota Deskripsi
    omac Lewati bidang ini untuk saat ini.
    rnRandomNumber Angka acak 128-bit yang aman secara kriptografis. Setiap kali Anda membuat permintaan status, selalu hasilkan angka acak baru, bahkan jika Anda membuat permintaan yang sama. Simpan angka dalam variabel, karena Anda harus merujuknya nanti.
    guidInformation GUID yang mengidentifikasi permintaan status. Untuk daftar permintaan status, lihat Permintaan Status OPM.
    ulSequenceNumber Nomor urut. Untuk permintaan status pertama, gunakan nomor urutan awal yang Anda tentukan dalam metode IOPMVideoOutput::FinishInitialization (langkah 5 menginisialisasi Sesi OPM.) Setiap kali Anda membuat permintaan status lain, tingkatkan angka ini sebesar 1.
    abParameters Array byte yang berisi data input tambahan untuk permintaan tersebut. Format data input tercantum dalam topik referensi untuk setiap permintaan status.
    cbParametersSize Ukuran data yang valid dalam array abParameters . Konten array lainnya tidak terdefinisi.

     

  2. Hitung MAC CBC satu kunci (OMAC-1) untuk menghitung hash untuk blok data yang muncul setelah anggota omac , lalu atur anggota omac ke nilai ini. Lihat Kode Contoh OPM.

  3. Panggil metode IOPMVideoOutput::GetInformation. Teruskan penunjuk ke struktur OPM_GET_INFO_PARAMETERS dan penunjuk ke struktur OPM_REQUESTED_INFORMATION. Respons driver ditulis ke struktur OPM_REQUESTED_INFORMATION .

    • Anggota omac dari struktur ini berisi OMAC yang dihitung untuk data yang mengikuti anggota ini.
    • Anggota abRequestedInformation adalah array byte yang berisi data output untuk respons. Format data output tercantum dalam topik referensi untuk setiap permintaan status.
  4. Hitung OMAC untuk struktur OPM_REQUESTED_INFORMATION, tidak termasuk anggota omac. Verifikasi bahwa OMAC cocok dengan nilai di anggota omac .

  5. Pastikan anggota cbRequestedInformationSize dari struktur OPM_REQUESTED_INFORMATION memberikan ukuran yang benar untuk data output. Misalnya, data output untuk kueri OPM_GET_CONNECTOR_TYPE adalah struktur OPM_STANDARD_INFORMATION, sehingga nilai cbRequestedInformationSize harus sizeof(OPM_STANDARD_INFORMATION).

  6. Transmisikan anggota abRequestedInformation dari struktur OPM_REQUESTED_INFORMATION ke struktur data output yang benar. Misalnya, jika permintaan status OPM_GET_CONNECTOR_TYPE, transmisikan abRequestedInformation ke struktur OPM_STANDARD_INFORMATION.

  7. Pastikan anggota rnRandomNumber dari struktur data output cocok dengan nilai rnRandomNumber dari langkah 1.

  8. Periksa anggota ulStatusFlags dari struktur data output, seperti yang dijelaskan dalam Menangani Output Video yang Dinonaktifkan.

Jika salah satu pemeriksaan dalam langkah 5–8 gagal, aplikasi harus berhenti menampilkan konten yang dilindungi.

Mengirim Perintah OPM

Perintah OPM digunakan untuk mengatur tingkat perlindungan dan pengaturan lain pada output video. Mengirim perintah OPM mirip dengan mengirim permintaan status, kecuali tidak ada data respons dari driver. Untuk daftar perintah, lihat Perintah OPM.

Untuk mengirim perintah OPM, lakukan langkah-langkah berikut.

  1. Isi struktur OPM_CONFIGURE_PARAMETERS seperti yang diperlihatkan dalam tabel berikut ini.

    Anggota Deskripsi
    omac Lewati bidang ini untuk saat ini.
    guidSetting GUID yang mengidentifikasi perintah. Untuk daftar perintah, lihat Perintah OPM.
    ulSequenceNumber Nomor urut. Untuk perintah pertama, gunakan nomor urutan awal yang Anda tentukan dalam metode IOPMVideoOutput::FinishInitialization (langkah 5 menginisialisasi Sesi OPM.) Setiap kali Anda mengirim perintah lain, tingkatkan angka ini dengan 1.
    abParameters Array byte yang berisi data input tambahan untuk perintah . Format data input tercantum dalam topik referensi untuk setiap perintah.
    cbSettingDataSize Ukuran data yang valid dalam array abParameters . Konten array lainnya tidak terdefinisi.

     

  2. Hitung OMAC untuk blok data yang muncul setelah anggota omac , lalu atur anggota omac ke nilai ini.

  3. Panggil IOPMVideoOutput::Configure.

Untuk sebagian besar perintah, ada permintaan status terkait yang mengembalikan status perintah. Misalnya, perintah OPM_SET_PROTECTION_LEVEL mengatur tingkat perlindungan, dan perintah OPM_GET_VIRTUAL_PROTECTION_LEVEL mendapatkan tingkat perlindungan saat ini.

Menangani Output Video yang Dinonaktifkan

Output video dapat menonaktifkan dirinya sendiri kapan saja untuk mencegah penggunaan konten video yang tidak sah. Ini mungkin terjadi karena mekanisme perlindungan berhenti berfungsi, karena driver mendeteksi perubahan, atau karena tampilan terputus dari konektor fisik. Saat output video dinonaktifkan, tidak ada bingkai video yang ditampilkan.

Saat perlindungan konten diaktifkan, aplikasi harus secara berkala (setidaknya sekali setiap 2 detik) melakukan langkah-langkah berikut.

  1. Panggil IOPMVideoOutput::GetInformation untuk mengirim permintaan status OPM_GET_ACTUAL_PROTECTION_LEVEL atau OPM_GET_VIRTUAL_PROTECTION_LEVEL. Data pengembalian untuk kedua perintah adalah struktur OPM_STANDARD_INFORMATION.
  2. Periksa anggota ulInformation dari struktur OPM_STANDARD_INFORMATION. Anggota ini berisi bendera yang menunjukkan apakah perlindungan konten masih diaktifkan. Jika perlindungan konten nonaktif, segera hentikan pemutaran video.
  3. Jika perlindungan konten aktif, periksa anggota ulStatusFlags dari struktur OPM_STANDARD_INFORMATION . Jika tidak ada bendera yang diatur, output video berfungsi dengan benar. Jika tidak, output video dinonaktifkan.

Bendera berikut didefinisikan untuk ulStatusFlags.

Bendera Deskripsi
OPM_STATUS_LINK_LOST Perlindungan output berhenti berfungsi karena alasan tertentu; misalnya, perangkat tampilan mungkin dilepas dari konektor. Hentikan pemutaran dan matikan semua mekanisme perlindungan output.
OPM_STATUS_RENEGOTIATION_REQUIRED Aplikasi harus membangun kembali sesi OPM. Respons sebagai berikut:
  1. Hentikan pemutaran.
  2. Matikan semua mekanisme perlindungan.
  3. Rilis antarmuka IOPMVideoOutput.
  4. Buat ulang semua permukaan video.
  5. Buat objek OPM baru dan coba membangun kembali perlindungan konten. Jika gagal, tampilkan pesan kesalahan kepada pengguna. Jangan memutar konten video lagi.
OPM_STATUS_REVOKED_HDCP_DEVICE_ATTACHED Bendera ini hanya berlaku ketika HDCP digunakan, dan menunjukkan adanya perangkat HDCP yang dicabut. Hentikan pemutaran dan matikan semua mekanisme perlindungan pada output video ini. Saat bendera ini diatur, bendera OPM_STATUS_LINK_LOST juga diatur.
OPM_STATUS_REVOKED_HDCP_DEVICE_ATTACHED Driver telah mendeteksi perubahan. Hentikan pemutaran, dan jangan putar video lagi menggunakan output video ini. Sebaiknya berhenti menggunakan output video lainnya, karena sistem mungkin disusupi.

 

Menggunakan HDCP untuk Melindungi Konten

Bagian ini menjelaskan cara mengaktifkan perlindungan output HDCP menggunakan OPM. Berikut adalah kerangka umum langkah-langkah yang harus diambil aplikasi. Detail diberikan nanti di bagian ini.

  1. Aplikasi mungkin harus memberikan SRM ke output video. Mekanisme untuk menerima SRM berada di luar cakupan antarmuka OPM. Misalnya, SRM mungkin dikirimkan sebagai bagian dari aliran siaran.
  2. Aplikasi ini memungkinkan perlindungan output HDCP.
  3. Aplikasi memutar konten video. Secara berkala, aplikasi melakukan polling driver untuk memastikan HDCP aktif.
  4. Ketika pemutaran selesai, aplikasi menonaktifkan HDCP.

Mengatur SRM

Untuk mengatur SRM, lakukan langkah-langkah berikut.

  1. Menginisialisasi struktur OPM_SET_HDCP_SRM_PARAMETERS dengan nomor versi SRM.
  2. Simpan SRM dalam variabel.
  3. Kirim perintah OPM_SET_HDCP_SRM ke output video. Gunakan prosedur yang dijelaskan dalam Mengirim Perintah OPM.
  4. Kirim permintaan status OPM_GET_CURRENT_HDCP_SRM_VERSION ke output video. Gunakan prosedur yang dijelaskan dalam Mengirim Permintaan Status OPM. Permintaan status ini tidak memiliki data input, sehingga konten anggota abParameters dari struktur OPM_GET_INFO_PARAMETERS tidak ditentukan.
  5. Ketika metode IOPMVideoOutput::GetInformation kembali, array abRequestedInformation dalam struktur OPM_REQUESTED_INFORMATION berisi struktur OPM_STANDARD_INFORMATION. Anggota ulInformation dari struktur ini berisi nomor versi SRM saat ini. Nilai ini harus sama dengan nilai dari langkah 2.

Mengaktifkan HDCP

Untuk mengaktifkan HDCP, lakukan langkah-langkah berikut.

  1. Inisialisasi struktur OPM_SET_PROTECTION_LEVEL_PARAMETERS dengan nilai berikut:
    • ulProtectionType = OPM_PROTECTION_TYPE_HDCP
    • ulProtectionLevel = OPM_HDCP_ON
    • Dicadangkan = 0
    • Reserved2 = 0
  2. Kirim perintah OPM_SET_PROTECTION_LEVEL. Data input dalam array abParameters adalah struktur OPM_SET_PROTECTION_LEVEL_PARAMETERS .
  3. Kirim permintaan status OPM_GET_VIRTUAL_PROTECTION_LEVEL untuk memeriksa apakah HDCP diaktifkan. 4 byte pertama anggota abParameters dari struktur OPM_GET_INFO_PARAMETERS berisi nilai OPM_PROTECTION_TYPE_HDCP.

Saat metode GetInformation kembali, array abRequestedInformation dalam struktur OPM_REQUESTED_INFORMATION berisi struktur OPM_STANDARD_INFORMATION. Anggota ulInformation dari struktur ini berisi nilai dari enumerasi OPM_HDCP_PROTECTION_LEVEL. Jika nilai sama dengan OPM_HDCP_ON, itu berarti HDCP diaktifkan. Jika tidak, ulangi langkah 1–2 hingga HDCP diaktifkan, atau terjadi kesalahan. (Ingatlah untuk menaikkan nomor urut dan menghasilkan angka acak baru setiap kali.)

Biasanya dibutuhkan antara 100 dan 200 milidetik untuk mengaktifkan HDCP, tetapi bisa memakan waktu lebih lama. Jangan berasumsi bahwa HDCP diaktifkan sampai Anda telah memverifikasinya.

Ketika aplikasi selesai memutar konten yang dilindungi, matikan HDCP. Langkah-langkahnya sama dengan untuk mengaktifkan HDCP, tetapi pada langkah 1, atur ulProtectionLevel ke OPM_HDCP_OFF.

Catatan

Jangan aktifkan HDCP jika jenis konektor OPM_CONNECTOR_TYPE_DISPLAYPORT_EMBEDDED. (Lihat Opm Koneksi atur Jenis Bendera.)

 

Manajer Perlindungan Output