GPU-Based Content Protection mit D3D11 Video

In diesem Thema werden Funktionen zum Schutz von Videoinhalten beschrieben, die ein Grafiktreiber bereitstellen kann.

Einführung

Das folgende Diagramm zeigt eine vereinfachte Ansicht der Art und Weise, wie geschützte Videoinhalte die zu rendernde Pipeline durchlaufen.

Ein Diagramm, das geschützte Videoinhalte zeigt.

Hinweis

Der Geschützte Medienpfad (Protected Media Path, PMP) ist in diesem Diagramm nicht dargestellt. Der hier gezeigte Datenfluss kann innerhalb eines PMP-Prozesses oder eines Anwendungsprozesses erfolgen.

Der Decoder empfängt verschlüsselte, komprimierte Videodaten aus einer externen Quelle. Es wird auch davon ausgegangen, dass der Decoder auch einen kryptografischen Schlüssel erhält, um diese Daten zu entschlüsseln. In diesem Thema wird der Schlüsselaustausch zwischen der Videoquelle und dem Decoder nicht beschrieben, aber PMP definiert einen möglichen Mechanismus. Die GPU ist in dieser Phase nicht beteiligt.

Für die hardwarebeschleunigte Decodierung übergibt der Softwaredecoder komprimierte Videoinhalte an die GPU. Um diesen Inhalt zu schützen, verschlüsselt der Decoder die Daten erneut, in der Regel mithilfe von AES-CTR, bevor er sie an die Hardwarebeschleunigung übergibt. Zwischen dem Decoder und dem Grafiktreiber wird ein Schlüsselaustauschmechanismus definiert.

Decodierte Videoframes werden im Videospeicher gespeichert, in der Regel im Klartext. An diesem Punkt werden die Frames verarbeitet und dann dargestellt. Es gibt zwei Hauptoptionen für die Präsentation.

  • Bei Verwendung der D3D9-API können Frames mithilfe einer Hardwareüberlagerung dargestellt werden. Hardware wird in D3D11 nicht übermäßig unterstützt. Weitere Informationen finden Sie unter Hardwareüberlagerungsunterstützung.
  • Frames können von der Desktopfensterverwaltung (DESKTOP Window Manage, DWM) mithilfe einer freigegebenen Oberfläche dargestellt werden.

Der letzte Schritt besteht darin, den Frame auf dem Monitor anzuzeigen, der möglicherweise einen Linkschutz zwischen der Grafikkarte und dem Anzeigegerät erfordert. Ein Beispiel für den Linkschutz ist High-Bandwidth Digital Content Protection (HDCP). Der Linkschutz wird mit dem Output Protection Manager (OPM) konfiguriert. In diesem Thema wird OPM nicht beschrieben. Weitere Informationen finden Sie unter Verwenden von Output Protection Manager.

Übersicht über den Decodierungsprozess

Während der hardwarebeschleunigten Decodierung muss der Softwaredecoder komprimierte Videodaten an die Grafikkarte übergeben. Bei Premium-Inhalten müssen diese Daten in der Regel mit verschlüsselung mit symmetrischem Schlüssel verschlüsselt werden, bevor sie an die GPU gesendet werden.

Zum Verschlüsseln des Videos für die Decodierung verwendet der Softwaredecoder die folgenden Schnittstellen:

  • ID3D11VideoDecoder. Stellt das Decodergerät dar, das auch als Zugriffstaste bezeichnet wird.
  • ID3D11CryptoSession. Stellt eine kryptografische Sitzung dar, die den Verschlüsselungsschlüssel bereitstellt.
  • ID3D11AuthenticatedChannel. Stellt einen authentifizierten Kanal dar, der es dem Softwaredecoder ermöglicht, die kryptografische Sitzung dem Decoder zuzuordnen.

Ein Diagramm, das die Direct3d9-Decodierungsschnittstellen zeigt.

Alle diese Schnittstellen werden wie folgt vom Direct3D11-Gerät abgerufen:

Schnittstelle Erstellung
ID3D11VideoDecoder Rufen Sie ID3D11VideoDevice::CreateVideoDecoder auf. Der Decodertyp wird durch eine Profil-GUID identifiziert.
ID3D11CryptoSession Rufen Sie ID3D11VideoDevice::CreateCryptoSessionauf.
ID3D11AuthenticatedChannel Rufen Sie ID3D11VideoDevice::CreateAuthenticatedChannelauf.

Hinweis

Um einen Zeiger auf die ID3D11VideoDevice-Schnittstelle abzurufen, rufen Sie QueryInterface für die ID3D11Device-Schnittstelle auf.

Der authentifizierte Kanal stellt einen vertrauenswürdigen Kommunikationskanal zwischen dem Softwaredecoder und dem Treiber bereit. Der Kommunikationskanal funktioniert wie folgt:

  • Der Treiber stellt eine X.509-Zertifikatkette bereit, deren Stammzertifikat von Microsoft signiert wurde.
  • Das Zertifikat enthält einen öffentlichen RSA-Schlüssel für den Treiber.
  • Der Softwaredecoder verwendet den öffentlichen Schlüssel, um dem Treiber einen 128-Bit-AES-Sitzungsschlüssel zu senden.
  • Der Softwaredecoder sendet Abfragen und Befehle an den authentifizierten Kanal.
  • Der Sitzungsschlüssel wird verwendet, um Nachrichtenauthentifizierungscodes (Message Authentication Codes, MACs) für die Abfragen und Befehle zu berechnen. Der Treiber verwendet die MACs, um die Integrität der Abfrage-/Befehlsdaten zu überprüfen, und der Softwaredecoder verwendet sie, um die Integrität der Antwortdaten des Treibers zu überprüfen.

Verschlüsseln komprimierter Videopuffer für den Decoder

Hier finden Sie eine allgemeine Übersicht über den Verschlüsselungs- und Decodierungsprozess:

  1. Der Softwaredecoder empfängt einen Stream verschlüsselter Daten aus der Videoquelle. Der Decoder entschlüsselt diesen Stream.

  2. Der Softwaredecoder handelt einen Sitzungsschlüssel mit der kryptografischen Sitzung aus.

  3. Der Softwaredecoder verwendet den authentifizierten Kanal, um die kryptografische Sitzung dem Decodergerät zuzuordnen.

  4. Der Softwaredecoder fügt komprimierte Daten in Puffer ein, die er vom Decodergerät (Accelerator) erhält. Bei geschützten Inhalten verschlüsselt der Softwareencoder die Daten, die in die Puffer gestellt werden, mithilfe des Sitzungsschlüssels für die Verschlüsselung.

    Hinweis

    Einige Treiber verwenden einen Inhaltsschlüssel anstelle des Sitzungsschlüssels für die Verschlüsselung. Der Inhaltsschlüssel kann sich von einem Frame zum nächsten ändern.

  5. Der Decoder sendet die verschlüsselten komprimierten Puffer an die Zugriffstaste. Bei AES-CTR übergibt der Decoder auch den Initialisierungsvektor. Wenn ein Inhaltsschlüssel verwendet wird, übergibt der Decoder den Inhaltsschlüssel, der mit dem Sitzungsschlüssel verschlüsselt wurde.

Direct3D11 verfügt über Standardunterstützung für 128-Bit-AES-CTR, ist aber für die Erweiterung auf zusätzliche Verschlüsselungstypen konzipiert.

Die nächsten fünf Abschnitte enthalten ausführlichere Schritte.

1. Abfragen der Content Protection Funktionen des Treibers

Bevor Sie versuchen, die Verschlüsselung anzuwenden, erhalten Sie die Inhaltsschutzfunktionen des Treibers.

  1. Abrufen eines Zeigers auf die ID3D11Device-Schnittstelle.
  2. Rufen Sie QueryInterface für die ID3D11VideoDevice-Schnittstelle auf.
  3. Rufen Sie ID3D11VideoDevice::GetContentProtectionCaps auf. Diese Methode füllt eine D3D11_VIDEO_CONTENT_PROTECTION_CAPS Struktur mit den Inhaltsschutzfunktionen des Treibers aus.

Suchen Sie insbesondere nach den folgenden Funktionen:

  • Wenn das Caps-Element das flag D3D11_CONTENT_PROTECTION_CAPS_SOFTWARE oder D3D11_CONTENT_PROTECTION_CAPS_HARDWARE enthält, kann der Treiber die Verschlüsselung durchführen.
  • Wenn der Caps-Member das flag D3D11_CONTENT_PROTECTION_CAPS_CONTENT_KEY enthält, verwendet der Treiber einen separaten Inhaltsschlüssel für die Entschlüsselung.
  • Rufen Sie ID3D11VideoDevice::CheckCryptoKeyExchange auf, um zu bestimmen, welche Arten von Schlüsseln der Treiber zum Generieren des Sitzungsschlüssels unterstützt.

Zusätzliche Funktionen sind im Caps-Member angegeben.

2. Konfigurieren des authentifizierten Kanals

Der nächste Schritt besteht darin, den authentifizierten Kanal zu konfigurieren.

  1. Rufen Sie ID3D11VideoDevice::CreateAuthenticatedChannel auf, um den authentifizierten Kanal zu erstellen. Geben Sie für den ChannelType-Parameter einen Kanaltyp an, der den Funktionen des Treibers entspricht.

    • Der D3D11_AUTHENTICATED_CHANNEL_DRIVER_SOFTWARE Kanaltyp entspricht D3D11_CONTENT_PROTECTION_CAPS_SOFTWARE.
    • Der D3D11_AUTHENTICATED_CHANNEL_DRIVER_HARDWARE Kanaltyp entspricht D3D11_CONTENT_PROTECTION_CAPS_HARDWARE.

    Die CreateAuthenticatedChannel-Methode gibt einen Zeiger auf die ID3D11AuthenticatedChannel-Schnittstelle zurück.

  2. Rufen Sie ID3D11AuthenticatedChannel::GetCertificateSize auf, um die Größe des X.509-Zertifikats des Treibers abzurufen. Ordnen Sie einen Puffer der erforderlichen Größe zu.

  3. Rufen Sie ID3D11AuthenticatedChannel::GetCertificate auf, um das Zertifikat abzurufen. Die -Methode kopiert das Zertifikat in den Puffer, der im vorherigen Schritt zugeordnet wurde.

  4. Vergewissern Sie sich, dass das Zertifikat des Treibers von Microsoft signiert und nicht widerrufen wurde.

  5. Abrufen des öffentlichen Schlüssels aus dem Zertifikat.

  6. Generieren Sie einen zufälligen RSA-Sitzungsschlüssel. Dieser Sitzungsschlüssel wird verwendet, um Daten zu signieren, die an den authentifizierten Kanal gesendet werden. Verschlüsseln Sie den Sitzungsschlüssel mit dem öffentlichen Schlüssel des Treibers.

  7. Rufen Sie ID3D11VideoContext::NegotiateAuthenticatedChannelKeyExchange auf, um den verschlüsselten Sitzungsschlüssel an den Treiber zu senden.

  8. Initialisieren Sie den sicheren Kanal wie folgt:

    1. Füllen Sie eine D3D11_AUTHENTICATED_CONFIGURE_INITIALIZE_INPUT Struktur aus, wie in der Dokumentation beschrieben.
    2. Senden Sie den D3D11_AUTHENTICATED_CONFIGURE_INITIALIZE_INPUT Befehl, indem Sie ID3D11VideoContext::ConfigureAuthenticatedChannel aufrufen, wie im Abschnitt Senden von Befehlenfür authentifizierte Kanäle beschrieben. Dieser Befehl enthält die Anfangssequenznummern für die Befehle und Abfragen, die an den authentifizierten Kanal gesendet werden.
  9. Überprüfen Sie den Kanaltyp, indem Sie eine D3D11_AUTHENTICATED_QUERY_CHANNEL_TYPE Abfrage an den authentifizierten Kanal senden, wie im Abschnitt Senden von Authentifizierten Kanalabfragenbeschrieben. Überprüfen Sie, ob der Kanaltyp mit dem übereinstimmt, den Sie in der CreateAuthenticatedChannel-Methode angegeben haben.

3. Konfigurieren der Kryptografiesitzung

Konfigurieren Sie als Nächstes die kryptografische Sitzung, und richten Sie den Sitzungsschlüssel ein.

  1. Rufen Sie ID3D11VideoDevice::CreateCryptoSession auf, um die kryptografische Sitzung zu erstellen. Diese Methode gibt einen Zeiger auf die ID3D11CryptoSession-Schnittstelle zurück.
  2. Rufen Sie ID3D11CryptoSession::GetCertificateSize auf, um die Größe des X.509-Zertifikats des Treibers abzurufen. Ordnen Sie einen Puffer der erforderlichen Größe zu.
  3. Rufen Sie ID3D11CryptoSession::GetCertificate auf, um das Zertifikat abzurufen. Die -Methode kopiert das Zertifikat in den Puffer, der im vorherigen Schritt zugeordnet wurde.
  4. Vergewissern Sie sich, dass das Zertifikat des Treibers von Microsoft signiert und nicht widerrufen wurde.
  5. Abrufen des öffentlichen Schlüssels aus dem Zertifikat.
  6. Generieren Sie einen zufälligen RSA-Sitzungsschlüssel. Dies ist ein separater Sitzungsschlüssel vom Sitzungsschlüssel des authentifizierten Kanals. Verschlüsseln Sie den Sitzungsschlüssel mit dem öffentlichen Schlüssel des Treibers.
  7. Rufen Sie ID3D11VideoContext::NegotiateCryptoSessionKeyExchange auf, um den verschlüsselten Sitzungsschlüssel an den Treiber zu senden.
  8. Wenn die Inhaltsschutzfunktionen 3D11_CONTENT_PROTECTION_CAPS_CONTENT_KEY enthalten, erstellen Sie einen zufälligen RSA-Inhaltsschlüssel. Dies wird später im Decodierungsprozess verwendet.

4. Zuordnen des Decoders zur Kryptografiesitzung

Ordnen Sie als Nächstes das Decodergerät wie folgt dem Direct3D11-Gerät und der kryptografischen Sitzung zu:

  1. Erhalten Sie ein Handle für das Direct3D11-Gerät, indem Sie eine D3D11_AUTHENTICATED_QUERY_DEVICE_HANDLE Abfrage an den authentifizierten Kanal senden.
  2. Füllen Sie eine D3D11_AUTHENTICATED_CONFIGURE_CRYPTO_SESSION_INPUT-Struktur mit den folgenden Informationen aus:
  3. Rufen Sie ID3D11VideoContext::ConfigureAuthenticatedChannel auf, um einen D3D11_AUTHENTICATED_CONFIGURE_CRYPTO_SESSION Befehl an den authentifizierten Kanal zu senden.

Das folgende Diagramm veranschaulicht den Austausch von Handles:

Ein Diagramm, das zeigt, wie der Dxva-Decoder der kryptografischen Sitzung zugeordnet ist.

Der Softwaredecoder kann jetzt den kryptografischen Sitzungsschlüssel verwenden, um die komprimierten Videopuffer zu verschlüsseln. Jeder komprimierte Puffer verfügt über einen eigenen Initialisierungsvektor (IV), der im pIV-Member der D3D11_VIDEO_DECODER_BUFFER_DESC-Struktur angegeben ist.

Senden von Befehlen für authentifizierte Kanäle

Eine Reihe von Befehlen wird zum Konfigurieren des authentifizierten Kanals und zum Festlegen verschiedener Inhaltsschutzfunktionen definiert. Eine Liste der Befehle finden Sie unter Content Protection Befehle.

Führen Sie die folgenden Schritte aus, um einen Befehl an den authentifizierten Kanal zu senden.

  1. Füllen Sie die Eingabedatenstruktur aus. Diese Datenstruktur ist immer eine D3D11_AUTHENTICATED_CONFIGURE_INPUT Struktur gefolgt von zusätzlichen Feldern. Füllen Sie die D3D11_AUTHENTICATED_CONFIGURE_INPUT Struktur aus, wie in der folgenden Tabelle dargestellt.
Member BESCHREIBUNG
omac Überspringen Sie dieses Feld vorerst.
ConfigureType GUID, die den Befehl identifiziert. Eine Liste der Befehle finden Sie unter Content Protection Befehle.
hChannel Das Handle für den authentifizierten Kanal.
SequenceNumber Die Sequenznummer. Die erste Sequenznummer wird durch Senden eines D3D11_AUTHENTICATED_CONFIGURE_INITIALIZE Befehls angegeben. Jedes Mal, wenn Sie einen anderen Befehl senden, erhöhen Sie diese Zahl um 1. Die Sequenznummer schützt vor Wiedergabeangriffen.
[!Note]
Es werden zwei separate Sequenznummern verwendet: eine für Befehle und eine für Abfragen.


  1. Berechnen Sie das OMAC-Tag für den Datenblock, der nach dem omac-Element der Eingabestruktur angezeigt wird. Kopieren Sie dann diesen Tagwert in das omac-Element.
  2. Rufen Sie ID3D11VideoContext::ConfigureAuthenticatedChannelauf.
  3. Der Treiber platziert die Ausgabe des Befehls in der D3D11_AUTHENTICATED_CONFIGURE_OUTPUT Struktur.
  4. Berechnen Sie das OMAC-Tag für den Datenblock, der nach dem omac-Member der Ausgabestruktur angezeigt wird. Vergleichen Sie dies mit dem Wert des omac-Elements. Fehler, wenn sie nicht übereinstimmen.
  5. Vergleichen Sie die Werte der Member ConfigureType, hChannel und SequenceNumber in der Ausgabestruktur mit den Werten für diese Member. Fehler, wenn sie nicht übereinstimmen.
  6. Erhöhen Sie die Sequenznummer für den nächsten Befehl.

Senden authentifizierter Kanalabfragen

Für das Abrufen von Informationen über den authentifizierten Kanal wird eine Reihe von Abfragen definiert. Eine Liste der Abfragen finden Sie unter Content Protection Abfragen.

Führen Sie die folgenden Schritte aus, um einen Befehl an den authentifizierten Kanal zu senden.

  1. Füllen Sie die Eingabedatenstruktur aus. Diese Datenstruktur ist immer eine D3D11_AUTHENTICATED_QUERY_INPUT Struktur, möglicherweise gefolgt von zusätzlichen Feldern. Füllen Sie die D3D11_AUTHENTICATED_QUERY_INPUT Struktur wie in der folgenden Tabelle gezeigt aus.
Member BESCHREIBUNG
QueryType GUID, die die Abfrage identifiziert. Eine Liste der Abfragen finden Sie unter Content Protection Abfragen.
hChannel Das Handle für den authentifizierten Kanal.
SequenceNumber Die Sequenznummer. Die erste Sequenznummer wird durch Senden eines D3D11_AUTHENTICATED_CONFIGURE_INITIALIZE Befehls angegeben. Jedes Mal, wenn Sie eine andere Abfrage senden, erhöhen Sie diese Zahl um 1. Die Sequenznummer schützt vor Wiedergabeangriffen.
[!Note]
Es werden zwei separate Sequenznummern verwendet: eine für Befehle und eine für Abfragen.


  1. Rufen Sie ID3D11VideoContext::QueryAuthenticatedChannel auf.
  2. Der Treiber platziert die Ausgabe der Abfrage in einer D3D11_AUTHENTICATED_QUERY_OUTPUT Struktur. Auf diese Struktur folgen je nach Abfragetyp zusätzliche Felder.
  3. Berechnen Sie das OMAC-Tag für den Datenblock, der nach dem omac-Member der Ausgabestruktur angezeigt wird. Vergleichen Sie dies mit dem Wert des omac-Members. Fehler, wenn sie nicht übereinstimmen.
  4. Vergleichen Sie die Werte der Elemente ConfigureType, hChannel und SequenceNumber in der Ausgabestruktur mit Ihren Werten für diese Member. Fehler, wenn sie nicht übereinstimmen.
  5. Erhöhen Sie die Sequenznummer für die nächste Abfrage.

Direct3D 11-Video-APIs