Поделиться через


Использование диспетчера защиты выходных данных

В этом разделе описывается, как использовать диспетчер защиты выходных данных (OPM) для защиты видеосодержимого по мере перемещения по физическому соединителю на отображаемое устройство. Этот раздел состоит из следующих подразделов.

Содержимое видео класса Premium обычно шифруется, чтобы защитить его от несанкционированного дублирования. Конечно, перед отображением видео необходимо расшифровать. Расшифрованные несжатые кадры должны затем перемещаться по физическому соединителю на отображаемое устройство. Поставщики содержимого могут требовать, чтобы видеокадры были защищены на этом этапе, так как они перемещаются по физическому соединителю.

Для этого существуют различные механизмы защиты, в том числе защита цифрового содержимого с высокой пропускной способностью (HDCP) и защита содержимого DisplayPort (DPCP) для цифровых выходных данных; и система управления поколением копирования — аналоговый (CGMS-A) для аналоговых выходных данных. Как правило, эти механизмы включают шифрование или скрабирование сигнала перед переходом на дисплей.

OPM позволяет приложению применять механизмы защиты содержимого в выходных данных видео. С помощью OPM приложение отправляет команды и запросы состояния на графический драйвер через доверенный, безопасный канал. OPM позволяет приложению:

  • Убедитесь, что графический драйвер подписан корпорацией Майкрософт.
  • Настройте доверенный канал связи с драйвером.
  • Применение механизмов защиты содержимого для физических выходных данных.

OPM заменяет сертифицированный протокол защиты выходных данных (COPP) и использует аналогичный API. Для обратной совместимости интерфейс OPM может эмулировать интерфейс COPP. Различия между OPM и COPP включают следующие:

  • OPM использует сертификаты X.509, а КОПП использует собственный формат сертификата.
  • OPM поддерживает ретрансляторы HDCP.
  • Приложения, использующие OPM, не должны анализировать сообщения о продлении системы HDCP (SRMs).
  • OPM можно использовать, если графический дисплей использует режим клонирования. COPP не поддерживает режим клонирования.

Если приложение использует защищенный путь к мультимедиа (PMP) для воспроизведения видеоконтента, вам не нужно использовать API OPM, так как PMP делает все необходимые вызовы OPM. API OPM доступен для приложений, которые не используют PMP.

OPM доступен в Windows Vista и более поздних версиях, но API не был открыт до Windows 7. Чтобы использовать OPM в приложении, необходимо иметь заголовки и файлы библиотеки из пакета SDK для Windows 7. Вам не нужно распространять библиотеки DLL для использования OPM в Windows Vista или Windows Server 2008.

Выходные данные видео

Графический адаптер может иметь несколько физических выходных данных, каждый из которых имеет собственные возможности. Прежде чем приложение воспроизводит защищенное содержимое, оно должно задать соответствующие механизмы защиты для каждого вывода видео, связанного с графическим карта, который будет отображать видео. Какие механизмы защиты будут применяться, зависят от правил использования содержимого.

Каждый вывод видео представлен экземпляром интерфейса IOPMVideoOutput . Для получения выходных данных видео можно использовать устройство Direct3D или дескриптор монитора.

Использование устройства Direct3D:

  1. Получите указатель IDirect3Device9 на устройство Direct3D, которое приложение будет использовать для создания поверхностей для хранения видеокадров.
  2. Вызовите функцию OPMGetVideoOutputsFromIDirect3DDevice9Object . Эта функция выделяет массив указателей IOPMVideoOutput , по одному для каждого вывода.

Использование дескрипторов монитора:

  1. Вызовите EnumDisplayMonitors, чтобы получить дескрипторы HMONITOR, соответствующие окну видео. Несколько мониторов могут быть связаны с тем же окном, поэтому можно получить несколько дескрипторов HMONITOR .
  2. Для каждого дескриптора монитора вызовите OPMGetVideoOutputsFromHMONITOR. Эта функция выделяет массив указателей IOPMVideoOutput , по одному для каждого вывода.

Инициализация сеанса OPM

Прежде чем приложение отправляет команды OPM или запросы состояния, необходимо убедиться, что выходные данные видео доверенны и устанавливаются ключ сеанса. Ключ сеанса используется для подписывания данных, обменяющихся между приложением и графическим драйвером.

API OPM определяет подтверждение, которое устанавливает доверие и задает ключ сеанса. Это подтверждение необходимо выполнить для каждого экземпляра интерфейса IOPMVideoOutput , как показано ниже.

  1. Вызов IOPMVideoOutput ::StartInitialization. Этот метод извлекает два фрагмента данных:

    • Случайное число, созданное драйвером. Это число будет использоваться для завершения подтверждения.
    • Цепочка сертификатов X.509 драйвера.
  2. Убедитесь, что цепочка сертификатов подписана корпорацией Майкрософт.

    Примечание.

    Отзыв сертификата находится за пределами область OPM.

     

  3. Получите открытый ключ драйвера из цепочки сертификатов.

  4. Создайте 128-разрядный ключ сеанса AES.

  5. Создайте два случайных 32-разрядных числа:

    • Начальный номер последовательности для запросов состояния OPM.
    • Начальный порядковый номер для команд OPM.

    Эти числа необходимо создать с помощью криптографически защищенного генератора псевдослучайного числа, например CryptGenRandom.

  6. Скопируйте случайное число драйвера (полученное на шаге 1), ключ сеанса и два номера последовательности в структуру OPM_ENCRYPTED_INITIALIZATION_PARAMETERS, как описано в разделе IOPMVideoOutput::FinishInitialization.

  7. Зашифруйте структуру OPM_ENCRYPTED_INITIALIZATION_PARAMETERS с помощью RSAES-OAEP, используя открытый ключ драйвера, который находится в сертификате драйвера.

  8. Вызов IOPMVideoOutput::FinishInitialization.

Отправка запросов о состоянии OPM

Запросы состояния OPM возвращают сведения о выходных данных видео, таких как тип физического соединителя и текущий уровень защиты. Список типов запросов см. в разделе "Запросы состояния OPM".

Чтобы отправить запрос состояния, выполните следующие действия.

  1. Инициализировать структуру OPM_GET_INFO_PARAMETERS, как показано в следующей таблице.

    Элемент Description
    omac Пропустите это поле сейчас.
    rnRandomNumber Криптографически безопасное 128-разрядное случайное число. Каждый раз, когда вы выполняете запрос состояния, всегда генерируйте новое случайное число, даже если вы выполняете тот же запрос. Сохраните номер в переменной, так как вам потребуется ссылаться на него позже.
    guidInformation GUID, определяющий запрос состояния. Список запросов состояния см. в разделе "Запросы состояния OPM".
    ulSequenceNumber Порядковый номер. Для первого запроса состояния используйте начальный порядковый номер, указанный в методе IOPMVideoOutput::FinishInitialization (шаг 5 инициализации сеанса OPM).) Каждый раз, когда вы выполняете другой запрос состояния, увеличьте это число на 1.
    abParameters Массив байтов, содержащий дополнительные входные данные для запроса. Формат входных данных указан в справочном разделе для каждого запроса состояния.
    cbParametersSize Размер допустимых данных в массиве abParameters . Содержимое остального массива не определено.

     

  2. Вычислите один ключ CBC MAC (OMAC-1), чтобы вычислить хэш для блока данных, который отображается после элемента omac, а затем задайте элемент omac для этого значения. См . пример кода OPM.

  3. Вызовите метод IOPMVideoOutput::GetInformation. Передайте указатель на структуру OPM_GET_INFO_PARAMETERS и указатель на OPM_REQUESTED_INFORMATION структуру. Ответ драйвера записывается в структуру OPM_REQUESTED_INFORMATION .

    • Элемент omac этой структуры содержит OMAC , вычисляемый для данных, следующих за этим элементом.
    • Элемент abRequestedInformation — это массив байтов, содержащий выходные данные для ответа. Формат выходных данных указан в справочном разделе для каждого запроса состояния.
  4. Вычислите OMAC для структуры OPM_REQUESTED_INFORMATION, не включая член omac. Убедитесь, что OMAC соответствует значению в элементе omac .

  5. Убедитесь, что элемент cbRequestedInformationSize структуры OPM_REQUESTED_INFORMATION дает правильный размер выходных данных. Например, выходные данные для запроса OPM_GET_CONNECTOR_TYPE — это структура OPM_STANDARD_INFORMATION, поэтому значение cbRequestedInformationSize должно быть.sizeof(OPM_STANDARD_INFORMATION)

  6. Приведение элемента abRequestedInformation структуры OPM_REQUESTED_INFORMATION к правильной структуре выходных данных. Например, если запрос состояния OPM_GET_CONNECTOR_TYPE, приведение abRequestedInformation к структуре OPM_STANDARD_INFORMATION.

  7. Убедитесь, что член rnRandomNumber выходной структуры данных соответствует значению rnRandomNumber из шага 1.

  8. Проверьте элемент ulStatusFlags структуры выходных данных, как описано в разделе "Обработка отключенных выходных данных видео".

Если любой из проверка в шагах 5–8 завершается ошибкой, приложение должно перестать отображать защищенное содержимое.

Отправка команд OPM

Команды OPM используются для задания уровня защиты и других параметров в выходных данных видео. Отправка команды OPM аналогична отправке запроса состояния, за исключением отсутствия данных ответа от драйвера. Список команд см. в разделе "Команды OPM".

Чтобы отправить команду OPM, выполните следующие действия.

  1. Заполните структуру OPM_CONFIGURE_PARAMETERS, как показано в следующей таблице.

    Элемент Description
    omac Пропустите это поле сейчас.
    guidSetting ИДЕНТИФИКАТОР GUID, определяющий команду. Список команд см. в разделе "Команды OPM".
    ulSequenceNumber Порядковый номер. Для первой команды используйте начальный порядковый номер, указанный в методе IOPMVideoOutput::FinishInitialization (шаг 5 инициализации сеанса OPM).) Каждый раз, когда вы отправляете другую команду, увеличьте это число на 1.
    abParameters Массив байтов, содержащий дополнительные входные данные для команды. Формат входных данных указан в справочном разделе для каждой команды.
    cbSettingDataSize Размер допустимых данных в массиве abParameters . Содержимое остального массива не определено.

     

  2. Вычислите OMAC для блока данных, отображаемых после элемента omac, а затем задайте элемент omac этому значению.

  3. Вызов IOPMVideoOutput::Configure.

Для большинства команд существует соответствующий запрос состояния, возвращающий состояние команды. Например, команда OPM_SET_PROTECTION_LEVEL задает уровень защиты, а команда OPM_GET_VIRTUAL_PROTECTION_LEVEL получает текущий уровень защиты.

Обработка отключенных выходных данных видео

Выходные данные видео могут отключиться в любое время, чтобы предотвратить несанкционированное использование видеосодержимого. Это может произойти из-за того, что механизм защиты перестает работать, так как драйвер обнаруживает изменение или поскольку дисплей был отключен от физического соединителя. В то время как выходные данные видео отключены, видеокадры не отображаются.

Хотя защита содержимого включена, приложение должно периодически (по крайней мере каждые 2 секунды) выполнять следующие действия.

  1. Вызовите IOPMVideoOutput::GetInformation, чтобы отправить запрос OPM_GET_ACTUAL_PROTECTION_LEVEL или OPM_GET_VIRTUAL_PROTECTION_LEVEL состояния. Возвращаемые данные для обеих команд — это OPM_STANDARD_INFORMATION структура.
  2. Проверьте элемент ulInformation структуры OPM_STANDARD_INFORMATION. Этот элемент содержит флаг, указывающий, включена ли защита содержимого. Если защита содержимого отключена, немедленно остановите воспроизведение видео.
  3. Если защита содержимого включена, проверка член ulStatusFlags структуры OPM_STANDARD_INFORMATION. Если флаги не заданы, выходные данные видео работают правильно. В противном случае выходные данные видео отключены.

Для ulStatusFlags определены следующие флаги.

Флаг Description
OPM_STATUS_LINK_LOST Защита выходных данных перестала работать по какой-то причине; Например, устройство отображения может быть отложено из соединителя. Остановите воспроизведение и отключите все механизмы защиты выходных данных.
OPM_STATUS_RENEGOTIATION_REQUIRED Приложение должно повторно установить сеанс OPM. Реагируйте следующим образом.
  1. Остановите воспроизведение.
  2. Отключите все механизмы защиты.
  3. Выпуск интерфейса IOPMVideoOutput.
  4. Повторно создайте все поверхности видео.
  5. Создайте новый объект OPM и попытайтесь восстановить защиту содержимого. Если это не удается, отобразится сообщение об ошибке пользователю. Не воспроизводите больше видеоконтента.
OPM_STATUS_REVOKED_HDCP_DEVICE_ATTACHED Этот флаг применяется только при использовании HDCP и указывает на наличие отозванного устройства HDCP. Остановите воспроизведение и отключите все механизмы защиты в выходных данных видео. При установке этого флага также устанавливается флаг OPM_STATUS_LINK_LOST .
OPM_STATUS_REVOKED_HDCP_DEVICE_ATTACHED Драйвер обнаружил незаконное изменение. Остановите воспроизведение и не воспроизводите больше видео с помощью этого выходных данных видео. Также рекомендуется прекратить использование других выходных данных видео, так как система может быть скомпрометирована.

 

Использование HDCP для защиты содержимого

В этом разделе описывается, как включить защиту выходных данных HDCP с помощью OPM. Ниже приведены общие сведения о действиях, которые необходимо предпринять приложению. Подробные сведения приведены далее в этом разделе.

  1. Возможно, приложению потребуется предоставить SRM выходным данным видео. Механизм получения SRM находится за пределами область интерфейса OPM. Например, службы SRM могут быть доставлены как часть широковещательного потока.
  2. Приложение обеспечивает защиту выходных данных HDCP.
  3. Приложение воспроизводит видеоконтент. Периодически приложение опрашивает драйвер, чтобы убедиться, что HDCP включен.
  4. После завершения воспроизведения приложение отключает HDCP.

Настройка SRM

Чтобы задать SRM, выполните следующие действия.

  1. Инициализировать структуру OPM_SET_HDCP_SRM_PARAMETERS с номером версии SRM.
  2. Сохраните SRM в переменной.
  3. Отправьте команду OPM_SET_HDCP_SRM в выходные данные видео. Используйте процедуру, описанную в разделе "Отправка команд OPM".
  4. Отправьте запрос состояния OPM_GET_CURRENT_HDCP_SRM_VERSION в выходные данные видео. Используйте процедуру, описанную в разделе "Отправка запросов о состоянии OPM". Этот запрос состояния не имеет входных данных, поэтому содержимое элемента abParameters структуры OPM_GET_INFO_PARAMETERS не определено.
  5. При возвращении метода IOPMVideoOutput::GetInformation массив abRequestedInformation в структуре OPM_REQUESTED_INFORMATION содержит структуру OPM_STANDARD_INFORMATION. Элемент ulInformation этой структуры содержит номер версии текущего SRM. Это значение должно быть равно значению шага 2.

Включение HDCP

Чтобы включить HDCP, выполните следующие действия.

  1. Инициализировать структуру OPM_SET_PROTECTION_LEVEL_PARAMETERS со следующими значениями:
    • ulProtectionType = OPM_PROTECTION_TYPE_HDCP
    • ulProtectionLevel = OPM_HDCP_ON
    • Зарезервировано = 0
    • Reserved2 = 0
  2. Отправьте команду OPM_SET_PROTECTION_LEVEL. Входные данные в массиве abParameters — это структура OPM_SET_PROTECTION_LEVEL_PARAMETERS.
  3. Отправьте запрос состояния OPM_GET_VIRTUAL_PROTECTION_LEVEL, чтобы проверка, включен ли HDCP. Первые 4 байта элемента abParameters структуры OPM_GET_INFO_PARAMETERS содержат значение OPM_PROTECTION_TYPE_HDCP.

При возврате метода GetInformation массив abRequestedInformation в структуре OPM_REQUESTED_INFORMATION содержит OPM_STANDARD_INFORMATION структуру. Элемент ulInformation этой структуры содержит значение из перечисления OPM_HDCP_PROTECTION_LEVEL. Если значение равно OPM_HDCP_ON, это означает, что HDCP включен. В противном случае повторите шаги 1–2 до включения HDCP или ошибки. (Не забудьте увеличить порядковый номер и создать новое случайное число каждый раз.)

Обычно это занимает от 100 до 200 миллисекунд для включения HDCP, но может занять больше времени. Не предполагайте, что HDCP включен до тех пор, пока вы не проверили его.

Когда приложение завершит воспроизведение защищенного содержимого, отключите HDCP. Действия совпадают с включением HDCP, но на шаге 1 задайте для параметра ulProtectionLevel значение OPM_HDCP_OFF.

Примечание.

Не включите HDCP, если тип соединителя OPM_CONNECTOR_TYPE_DISPLAYPORT_EМБ EDDEDED. (См. раздел OpM Подключение or Type Flags.)

 

Диспетчер защиты выходных данных