GPU-Based защита содержимого с помощью видео D3D11
В этом разделе описываются возможности защиты видеоконтента, которые может предоставить графический драйвер.
- Введение
- Общие сведения о процессе декодирования
- Шифрование сжатых буферов видео для декодера
- Отправка команд канала, прошедших проверку подлинности
- Отправка запросов канала, прошедших проверку подлинности
- Связанные темы
Введение
На следующей схеме показано упрощенное представление о том, как защищенное видеосодержимое проходит через конвейер для отрисовки.
Примечание
Путь к защищенному носителю (PMP) не показан на этой схеме. Поток данных, показанный здесь, может происходить в рамках процесса PMP или процесса приложения.
Декодер получает зашифрованные сжатые видеоданные из внешнего источника. Предполагается, что декодер также получает криптографический ключ для расшифровки этих данных. В этом разделе не описывается обмен ключами между источником видео и декодером, но PMP определяет один из возможных механизмов. На этом этапе gpu не используется.
Для аппаратного ускорения декодирования программный декодер передает сжатое видеосодержимое в GPU. Чтобы защитить это содержимое, декодер повторно шифрует данные, как правило, с помощью AES-CTR, перед их передачей в аппаратный ускоритель. Между декодером и графическим драйвером определяется механизм обмена ключами.
Декодированные видеокадры хранятся в видеопамяти, как правило, в режиме очистки. На этом этапе кадры обрабатываются и затем отображаются. Существует два main варианта представления.
- При использовании API D3D9 кадры можно представить с помощью аппаратного наложения. Оборудование слишком не поддерживается в D3D11. Дополнительные сведения см. в разделе Поддержка аппаратного перекрытия.
- Кадры можно представить в управлении окнами рабочего стола (DWM) с помощью общей поверхности.
Последний шаг — отображение кадра на мониторе, для которого может потребоваться защита связи между графическим карта и устройством отображения. Примером защиты ссылок является High-Bandwidth Защита цифрового содержимого (HDCP). Защита ссылок настраивается с помощью диспетчера защиты выходных данных (OPM). В этом разделе не описывается OPM; Дополнительные сведения см. в разделе Использование диспетчера защиты выходных данных.
Общие сведения о процессе декодирования
Во время аппаратного ускорения декодирования программный декодер должен передавать сжатые видеоданные в графические карта. Для содержимого уровня "Премиум" эти данные, как правило, должны быть зашифрованы с использованием шифрования с симметричным ключом перед отправкой в GPU.
Чтобы зашифровать видео для декодирования, программный декодер использует следующие интерфейсы:
- ID3D11VideoDecoder. Представляет устройство декодера, также называемое ускорителем.
- ID3D11CryptoSession. Представляет криптографический сеанс, предоставляющий ключ шифрования.
- ID3D11AuthenticatedChannel. Представляет канал, прошедший проверку подлинности, который позволяет декодеру программного обеспечения связать сеанс шифрования с декодером.
Все эти интерфейсы получены с устройства Direct3D11 следующим образом:
Интерфейс | Создание |
---|---|
ID3D11VideoDecoder | Вызовите ID3D11VideoDevice::CreateVideoDecoder. Тип декодера определяется идентификатором GUID профиля. |
ID3D11CryptoSession | Вызовите ID3D11VideoDevice::CreateCryptoSession. |
ID3D11AuthenticatedChannel | Вызовите ID3D11VideoDevice::CreateAuthenticatedChannel. |
Примечание
Чтобы получить указатель на интерфейс ID3D11VideoDevice , вызовите QueryInterface в интерфейсе ID3D11Device .
Канал, прошедший проверку подлинности, предоставляет доверенный канал связи между декодером программного обеспечения и драйвером. Коммуникационный канал работает следующим образом:
- Драйвер предоставляет цепочку сертификатов X.509, корневой сертификат которой подписан корпорацией Майкрософт.
- Сертификат содержит открытый ключ RSA для драйвера.
- Программный декодер использует открытый ключ для отправки драйверу 128-разрядного ключа сеанса AES.
- Программный декодер отправляет запросы и команды в канал, прошедший проверку подлинности.
- Ключ сеанса используется для вычисления кодов проверки подлинности сообщений (MAC) для запросов и команд. Драйвер использует macs для проверки целостности данных запроса или команды, а программный декодер использует их для проверки целостности данных ответа от драйвера.
Шифрование сжатых буферов видео для декодера
Ниже приведен общий обзор процесса шифрования и декодирования.
Программный декодер получает поток зашифрованных данных из источника видео. Декодер расшифровывает этот поток.
Программный декодер согласовывает ключ сеанса с сеансом шифрования.
Программный декодер использует канал, прошедший проверку подлинности, для связывания криптографического сеанса с устройством декодера.
Программный декодер помещает сжатые данные в буферы, которые он получает от устройства декодера (ускорителя). Для защищенного содержимого программный кодировщик шифрует данные, помещаемые в буферы, используя ключ сеанса для шифрования.
Примечание
Некоторые драйверы используют ключ содержимого вместо ключа сеанса для шифрования. Ключ содержимого может меняться от одного кадра к другому.
Декодер отправляет зашифрованные сжатые буферы в ускоритель. Для AES-CTR декодер также передает вектор инициализации. Если используется ключ содержимого, декодер передает ключ содержимого, зашифрованный с помощью ключа сеанса.
Direct3D11 имеет стандартную поддержку 128-разрядных AES-CTR, но предназначен для расширения до дополнительных типов шифрования.
В следующих пяти разделах приведены более подробные действия.
- 1. Запрос возможностей защиты содержимого драйвера
- 2. Настройка канала с проверкой подлинности
- 3. Настройка сеанса шифрования
- 4. Свяжите декодер с криптографическим сеансом
1. Запрос возможностей защиты содержимого драйвера
Прежде чем пытаться применить шифрование, получите возможности защиты содержимого драйвера.
- Получите указатель на интерфейс ID3D11Device.
- Вызовите QueryInterface для интерфейса ID3D11VideoDevice .
- Вызовите ID3D11VideoDevice::GetContentProtectionCaps. Этот метод заполняет структуру D3D11_VIDEO_CONTENT_PROTECTION_CAPS возможностями защиты содержимого драйвера.
В частности, найдите следующие возможности:
- Если член Caps содержит флаг D3D11_CONTENT_PROTECTION_CAPS_SOFTWARE или D3D11_CONTENT_PROTECTION_CAPS_HARDWARE , драйвер может выполнять шифрование.
- Если член Caps содержит флаг D3D11_CONTENT_PROTECTION_CAPS_CONTENT_KEY , драйвер использует отдельный ключ содержимого для расшифровки.
- Вызовите ID3D11VideoDevice::CheckCryptoKeyExchange , чтобы определить, какие типы ключей поддерживаются драйвером для создания ключа сеанса.
Дополнительные возможности указаны в элементе Caps .
2. Настройка канала с проверкой подлинности
Следующим шагом является настройка канала, прошедшего проверку подлинности.
Вызовите ID3D11VideoDevice::CreateAuthenticatedChannel , чтобы создать канал, прошедший проверку подлинности. Для параметра ChannelType укажите тип канала, соответствующий возможностям драйвера.
- Тип канала D3D11_AUTHENTICATED_CHANNEL_DRIVER_SOFTWARE соответствует D3D11_CONTENT_PROTECTION_CAPS_SOFTWARE.
- Тип канала D3D11_AUTHENTICATED_CHANNEL_DRIVER_HARDWARE соответствует D3D11_CONTENT_PROTECTION_CAPS_HARDWARE.
Метод CreateAuthenticatedChannel возвращает указатель на интерфейс ID3D11AuthenticatedChannel .
Вызовите ID3D11AuthenticatedChannel::GetCertificateSize , чтобы получить размер сертификата X.509 драйвера. Выделите буфер требуемого размера.
Вызовите ID3D11AuthenticatedChannel::GetCertificate , чтобы получить сертификат. Метод копирует сертификат в буфер, выделенный на предыдущем шаге.
Убедитесь, что сертификат драйвера подписан корпорацией Майкрософт и не был отозван.
Получите открытый ключ из сертификата.
Создайте случайный ключ сеанса RSA. Этот ключ сеанса используется для подписывания данных, отправляемых в канал, прошедший проверку подлинности. Зашифруйте ключ сеанса с помощью открытого ключа драйвера.
Вызовите ID3D11VideoContext::NegotiateAuthenticatedChannelKeyExchange , чтобы отправить зашифрованный ключ сеанса драйверу.
Инициализируйте безопасный канал следующим образом:
- Заполните структуру D3D11_AUTHENTICATED_CONFIGURE_INITIALIZE_INPUT , как описано в документации.
- Отправьте команду D3D11_AUTHENTICATED_CONFIGURE_INITIALIZE_INPUT , вызвав ID3D11VideoContext::ConfigureAuthenticatedChannel , как описано в разделе Отправка команд канала с проверкой подлинности. Эта команда содержит начальные порядковые номера для команд и запросов, отправляемых в канал, прошедший проверку подлинности.
Проверьте тип канала, отправив запрос D3D11_AUTHENTICATED_QUERY_CHANNEL_TYPE в канал, прошедший проверку подлинности, как описано в разделе Отправка запросов канала, прошедших проверку подлинности. Убедитесь, что тип канала соответствует указанному в методе CreateAuthenticatedChannel .
3. Настройка сеанса шифрования
Затем настройте сеанс шифрования и установите ключ сеанса.
- Вызовите ID3D11VideoDevice::CreateCryptoSession , чтобы создать сеанс шифрования. Этот метод возвращает указатель на интерфейс ID3D11CryptoSession .
- Вызовите ID3D11CryptoSession::GetCertificateSize , чтобы получить размер сертификата X.509 драйвера. Выделите буфер требуемого размера.
- Вызовите ID3D11CryptoSession::GetCertificate , чтобы получить сертификат. Метод копирует сертификат в буфер, выделенный на предыдущем шаге.
- Убедитесь, что сертификат драйвера подписан корпорацией Майкрософт и не был отозван.
- Получите открытый ключ из сертификата.
- Создайте случайный ключ сеанса RSA. Это отдельный ключ сеанса от ключа сеанса канала, прошедшего проверку подлинности. Зашифруйте ключ сеанса с помощью открытого ключа драйвера.
- Вызовите ID3D11VideoContext::NegotiateCryptoSessionKeyExchange , чтобы отправить зашифрованный ключ сеанса драйверу.
- Если возможности защиты содержимого включают 3D11_CONTENT_PROTECTION_CAPS_CONTENT_KEY, создайте случайный ключ содержимого RSA. Он будет использоваться позже в процессе декодирования.
4. Свяжите декодер с криптографическим сеансом
Затем свяжите устройство декодера с устройством Direct3D11 и криптографическим сеансом следующим образом:
- Получите дескриптор для устройства Direct3D11, отправив запрос D3D11_AUTHENTICATED_QUERY_DEVICE_HANDLE в канал, прошедший проверку подлинности.
- Заполните структуру D3D11_AUTHENTICATED_CONFIGURE_CRYPTO_SESSION_INPUT следующими сведениями:
- Задайте для элемента DecodeHandle дескриптор, возвращенный из ID3D11VideoDecoder::GetDriverHandle.
- Задайте для элемента CryptoSessionHandle дескриптор, возвращенный из ID3D11CryptoSession::GetCryptoSessionHandle.
- Задайте для элемента DeviceHandle дескриптор устройства Direct3D11.
- Вызовите ID3D11VideoContext::ConfigureAuthenticatedChannel , чтобы отправить команду D3D11_AUTHENTICATED_CONFIGURE_CRYPTO_SESSION в канал, прошедший проверку подлинности.
На следующей схеме показан обмен дескрипторами:
Программный декодер теперь может использовать ключ сеанса шифрования для шифрования сжатых буферов видео. Каждый сжатый буфер будет иметь собственный вектор инициализации (IV), указанный в элементе pIVструктуры D3D11_VIDEO_DECODER_BUFFER_DESC .
Отправка команд канала, прошедших проверку подлинности
Набор команд определяется для настройки канала, прошедшего проверку подлинности, и настройки различных средств защиты содержимого. Список команд см. в разделе Команды защиты содержимого.
Чтобы отправить команду в канал, прошедший проверку подлинности, выполните следующие действия.
- Заполните структуру входных данных. Эта структура данных всегда является D3D11_AUTHENTICATED_CONFIGURE_INPUT структурой, за которой следуют дополнительные поля. Заполните структуру D3D11_AUTHENTICATED_CONFIGURE_INPUT , как показано в следующей таблице.
Член | Описание |
---|---|
omac | Пока пропустите это поле. |
ConfigureType | GUID, идентифицирующий команду. Список команд см. в разделе Команды защиты содержимого. |
hChannel | Дескриптор канала, прошедшего проверку подлинности. |
SequenceNumber | Порядковый номер. Первый порядковый номер указывается путем отправки команды D3D11_AUTHENTICATED_CONFIGURE_INITIALIZE . При каждой отправке другой команды увеличиваете это число на 1. Порядковый номер защищает от атак воспроизведения.
Примечание: Используются два отдельных порядковых номера: один для команд и один для запросов. |
- Вычислите тег OMAC для блока данных, который отображается после элемента omac входной структуры. Затем скопируйте это значение тега в элемент omac .
- Вызовите ID3D11VideoContext::ConfigureAuthenticatedChannel.
- Драйвер помещает выходные данные команды в структуру D3D11_AUTHENTICATED_CONFIGURE_OUTPUT .
- Вычислите тег OMAC для блока данных, который отображается после элемента omac выходной структуры. Сравните это со значением элемента omac . Сбой, если они не совпадают.
- Сравните значения элементов ConfigureType, hChannel и SequenceNumber в выходной структуре со значениями для этих элементов. Сбой, если они не совпадают.
- Увеличить порядковый номер для следующей команды.
Отправка запросов канала, прошедших проверку подлинности
Набор запросов определяется для получения сведений о канале, прошедшем проверку подлинности. Список запросов см. в разделе Запросы защиты содержимого.
Чтобы отправить команду в канал, прошедший проверку подлинности, выполните следующие действия.
- Заполните структуру входных данных. Эта структура данных всегда является D3D11_AUTHENTICATED_QUERY_INPUT структурой, за которой, возможно, следуют дополнительные поля. Заполните структуру D3D11_AUTHENTICATED_QUERY_INPUT , как показано в следующей таблице.
Член | Описание |
---|---|
QueryType | GUID, идентифицирующий запрос. Список запросов см. в разделе Запросы защиты содержимого. |
hChannel | Дескриптор канала, прошедшего проверку подлинности. |
SequenceNumber | Порядковый номер. Первый порядковый номер указывается путем отправки команды D3D11_AUTHENTICATED_CONFIGURE_INITIALIZE . Каждый раз, когда вы отправляете другой запрос, увеличиваете это число на 1. Порядковый номер защищает от атак воспроизведения.
Примечание: Используются два отдельных порядковых номера: один для команд и один для запросов. |
- Вызовите ID3D11VideoContext::QueryAuthenticatedChannel.
- Драйвер помещает выходные данные запроса в структуру D3D11_AUTHENTICATED_QUERY_OUTPUT . За этой структурой следуют дополнительные поля в зависимости от типа запроса.
- Вычислите тег OMAC для блока данных, который отображается после элемента omac выходной структуры. Сравните это со значением элемента omac . Сбой, если они не совпадают.
- Сравните значения элементов ConfigureType, hChannel и SequenceNumber в выходной структуре со значениями для этих элементов. Сбой, если они не совпадают.
- Увеличить порядковый номер для следующего запроса.
Связанные темы