Dela via


GPU-Based innehållsskydd

Det här avsnittet beskriver funktioner för videoinnehållsskydd som en grafikdrivrutin kan tillhandahålla.

Införandet

Följande diagram visar en förenklad vy över hur skyddat videoinnehåll färdas genom pipelinen som ska renderas.

ett diagram som visar skyddat videoinnehåll.

Not

Den skyddade mediesökvägen (PMP) visas inte i det här diagrammet. Dataflödet som visas här kan inträffa inom en PMP-process eller i en programprocess.

Avkodaren tar emot krypterade, komprimerade videodata från en extern källa. Det antas också att avkodaren också tar emot en kryptografisk nyckel för att dekryptera dessa data. Det här avsnittet beskriver inte nyckelutbytet mellan videokällan och avkodaren, men PMP definierar en möjlig mekanism. GPU:n är inte involverad i det här skedet.

För maskinvaruaccelererad avkodning skickar programdekodaren komprimerat videoinnehåll till GPU:n. För att skydda det här innehållet krypterar avkodaren om data, vanligtvis med hjälp av AES-CTR, innan de skickas till maskinvaruacceleratorn. En nyckelutbytesmekanism definieras mellan avkodaren och grafikdrivrutinen.

Avkodade videorutor lagras i videominnet, vanligtvis i klartext. Nu bearbetas ramarna och visas sedan. Det finns två huvudsakliga alternativ för presentation.

  • Ramar kan visas med hjälp av ett maskinvaruöverlägg. Mer information finns i Support för maskinvaruöverlägg.
  • Ramar kan visas av DWM (Desktop Window Manage) med hjälp av en delad yta.

Det sista steget är att visa ramen på bildskärmen, vilket kan kräva länkskydd mellan grafikkortet och visningsenheten. Ett exempel på länkskydd är High-Bandwidth HDCP (Digital Content Protection). Länkskydd konfigureras med hjälp av Output Protection Manager (OPM). Det här avsnittet beskriver inte OPM; Mer information finns i Using Output Protection Manager.

Översikt över avkodningsprocessen

Under maskinvaruaccelererad avkodning måste programvarudekodaren skicka komprimerade videodata till grafikkortet. För premiuminnehåll måste dessa data vanligtvis krypteras med hjälp av symmetrisk nyckelkryptering innan de skickas till GPU:n.

För att kryptera videon för avkodning använder programdekodaren följande gränssnitt:

ett diagram som visar direct3d9-avkodningsgränssnitten.

Alla dessa gränssnitt hämtas från Direct3D-enheten enligt följande:

Gränssnitt Skapelse
IDirectXVideoDecoder Anropa IDirectXVideoDecoderService::CreateVideoDecoder. DXVA-avkodarens enhet identifieras av ett GUID för DXVA-profil.
IDirect3DCryptoSession9 Anropa IDirect3DDevice9Video::CreateCryptoSession.
IDirect3DAuthenticatedChannel9 Anropa IDirect3DDevice9Video::CreateAuthenticatedChannel.

Not

Om du vill få en pekare till gränssnittet IDirect3DDevice9Video anropar du QueryInterface på en D3D9Ex-enhet.

Den autentiserade kanalen tillhandahåller en betrodd kommunikationskanal mellan programdekodaren och drivrutinen. Kommunikationskanalen fungerar på följande sätt:

  • Drivrutinen tillhandahåller en X.509-certifikatkedja vars rotcertifikat är signerat av Microsoft.
  • Certifikatet innehåller en offentlig RSA-nyckel för drivrutinen.
  • Programdekodaren använder den offentliga nyckeln för att skicka drivrutinen en 128-bitars AES-sessionsnyckel.
  • Programdekodaren skickar frågor och kommandon till den autentiserade kanalen.
  • Sessionsnyckeln används för att beräkna autentiseringskoder för meddelanden (MACs) för frågor och kommandon. Drivrutinen använder MAC:erna för att verifiera integriteten för fråge-/kommandodata, och programvarudekodaren använder dem för att verifiera integriteten för svarsdata från drivrutinen.

Kryptera komprimerade videobuffertar för avkodaren

Här är en översikt på hög nivå över krypterings- och avkodningsprocessen:

  1. Programdekodaren tar emot en ström med krypterade data från videokällan. Avkodaren dekrypterar den här strömmen.

  2. Programvarudekodaren förhandlar om en sessionsnyckel med den kryptografiska sessionen.

  3. Programdekodaren använder den autentiserade kanalen för att associera den kryptografiska sessionen med DXVA-avkodarens enhet.

  4. Programvarudekodaren placerar komprimerade data i DXVA-buffertar som de får från DXVA-avkodarens enhet (accelerator). För skyddat innehåll krypterar programvarukodaren de data som placeras i DXVA-buffertarna med hjälp av sessionsnyckeln för krypteringen.

    Not

    Vissa drivrutiner använder en innehållsnyckel i stället för sessionsnyckeln för kryptering. Innehållsnyckeln kan ändras från en ram till en annan.

  5. Avkodaren skickar de krypterade komprimerade buffertarna till acceleratorn. För AES-CTR skickar avkodaren också initieringsvektorn. Om en innehållsnyckel används skickar avkodaren innehållsnyckeln, krypterad med hjälp av sessionsnyckeln.

Direct3D har standardstöd för 128-bitars AES-CTR, men är utformat för att utöka till ytterligare krypteringstyper.

De kommande fem avsnitten innehåller mer detaljerade steg.

1. Fråga efter innehållsskyddsfunktionerna i drivrutinen

Innan du försöker tillämpa kryptering hämtar du innehållsskyddsfunktionerna för drivrutinen.

  1. Hämta en pekare till Direct3D 9-enheten.
  2. Anropa QueryInterface för gränssnittet IDirect3DDevice9Video.
  3. Anropa IDirect3DDevice9Video::GetContentProtectionCaps. Den här metoden fyller i en D3DCONTENTPROTECTIONCAPS struktur med drivrutinens funktioner för innehållsskydd.

Titta särskilt efter följande funktioner:

  • Om Caps-medlemmen innehåller flaggan D3DCPCAPS_SOFTWARE eller D3DCPCAPS_HARDWARE kan drivrutinen utföra kryptering.
  • KeyExchangeType- medlem anger hur du utför nyckelutbyte för sessionsnyckeln.
  • Om Caps-medlemmen innehåller flaggan D3DCPCAPS_CONTENTKEY använder drivrutinen en separat innehållsnyckel för kryptering. Detta är viktigt när du genererar sessionsnyckeln.

Ytterligare funktioner anges i Caps medlem.

2. Konfigurera den autentiserade kanalen

Nästa steg är att konfigurera den autentiserade kanalen.

  1. Anropa IDirect3DDevice9Video::CreateAuthenticatedChannel för att skapa den autentiserade kanalen. För parametern ChannelType anger du en kanaltyp som matchar drivrutinsfunktionerna.

    • Kanaltypen D3DAUTHENTICATEDCHANNEL_DRIVER_SOFTWARE motsvarar D3DCPCAPS_SOFTWARE.
    • Kanaltypen D3DAUTHENTICATEDCHANNEL_DRIVER_HARDWARE motsvarar D3DCPCAPS_HARDWARE.

    Metoden CreateAuthenticatedChannel returnerar en pekare till gränssnittet IDirect3DAuthenticatedChannel9 tillsammans med ett handtag till kanalen. Handtaget används senare för att associera den kryptografiska sessionen med den autentiserade kanalen.

  2. Anropa IDirect3DAuthenticatedChannel9::GetCertificateSize för att hämta storleken på drivrutinens X.509-certifikat. Allokera en buffert med den storlek som krävs.

  3. Anropa IDirect3DAuthenticatedChannel9::GetCertificate för att hämta certifikatet. Metoden kopierar certifikatet till bufferten som allokerades i föregående steg.

  4. Kontrollera att drivrutinscertifikatet har signerats av Microsoft och inte har återkallats.

  5. Hämta den offentliga nyckeln från certifikatet.

  6. Generera en slumpmässig RSA-sessionsnyckel. Den här sessionsnyckeln används för att signera data som skickas till den autentiserade kanalen. Kryptera sessionsnyckeln med hjälp av drivrutinens offentliga nyckel.

  7. Anropa IDirect3DAuthenticatedChannel9::NegotiateKeyExchange för att skicka den krypterade sessionsnyckeln till drivrutinen.

  8. Initiera den säkra kanalen på följande sätt:

    1. Fyll i en D3DAUTHENTICATEDCHANNEL_CONFIGUREINITIALIZE struktur enligt beskrivningen i dokumentationen.
    2. Skicka kommandot D3DAUTHENTICATEDCONFIGURE_INITIALIZE genom att anropa IDirect3DAuthenticatedChannel9::Konfigurera enligt beskrivningen i avsnittet Skicka autentiserade kanalkommandon. Det här kommandot innehåller startsekvensnumren för de kommandon och frågor som skickas till den autentiserade kanalen.
  9. Kontrollera kanaltypen genom att skicka en D3DAUTHENTICATEDQUERY_CHANNELTYPE fråga till den autentiserade kanalen enligt beskrivningen i avsnittet Skicka autentiserade kanalfrågor. Kontrollera att kanaltypen matchar det du angav i metoden CreateAuthenticatedChannel.

3. Konfigurera den kryptografiska sessionen

Konfigurera sedan den kryptografiska sessionen och upprätta sessionsnyckeln.

  1. Anropa IDirect3DDevice9Video::CreateCryptoSession för att skapa den kryptografiska sessionen. Den här metoden returnerar en pekare till gränssnittet IDirect3DCryptoSession9 och tillsammans med ett handtag till den kryptografiska sessionen.
  2. Anropa IDirect3DCryptoSession9::GetCertificateSize för att hämta storleken på drivrutinens X.509-certifikat. Allokera en buffert med den storlek som krävs.
  3. Anropa IDirect3DCryptoSession9::GetCertificate för att hämta certifikatet. Metoden kopierar certifikatet till bufferten som allokerades i föregående steg.
  4. Kontrollera att drivrutinscertifikatet har signerats av Microsoft och inte har återkallats.
  5. Hämta den offentliga nyckeln från certifikatet.
  6. Generera en slumpmässig RSA-sessionsnyckel. Det här är en separat sessionsnyckel från den autentiserade kanalsessionsnyckeln. Kryptera sessionsnyckeln med hjälp av drivrutinens offentliga nyckel.
  7. Anropa IDirect3DCryptoSession9::NegotiateKeyExchange för att skicka den krypterade sessionsnyckeln till drivrutinen.
  8. Om innehållsskyddsfunktionerna innehåller D3DCPCAPS_CONTENTKEYskapar du en slumpmässig RSA-innehållsnyckel. Detta kommer att användas senare i avkodningsprocessen.

4. Hämta ett handtag till DXVA-avkodarens enhet

För nästa steg behöver du ett handtag till DXVA-avkodarens enhet. För att få den här handtaget fyller du i en DXVA2_DecodeExecuteParams struktur på följande sätt:

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);

Ange pExtensionData medlem i DXVA2_DecodeExecuteParams struktur till adressen för en DXVA2_DecodeExtensionData struktur.

I DXVA2_DecodeExtensionData-strukturen anger du Function member till DXVA2_DECODE_GET_DRIVER_HANDLE. Ange pPrivateOutputData till adressen för en buffert som är tillräckligt stor för att lagra ett HANDLE- värde. (I föregående exempel är den här bufferten hDecodeDeviceHandle variabel.)

Anropa sedan IDirectXVideoDecoder::Kör och skicka adressen till den DXVA2_DecodeExecuteParams strukturen. Handtaget till DXVA-avkodaren returneras i pPrivateOutputData.

5. Associera DXVA-avkodaren med den kryptografiska sessionen

Associera sedan DXVA-avkodaren med Direct3D-enheten och den kryptografiska sessionen enligt följande:

  1. Hämta ett handtag till DXVA-avkodarens enhet enligt beskrivningen i föregående avsnitt.
  2. Hämta ett handtag till Direct3D-enheten genom att skicka en D3DAUTHENTICATEDQUERY_DEVICEHANDLE fråga till den autentiserade kanalen.
  3. Fyll i en D3DAUTHENTICATEDCHANNEL_CONFIGURECRYPTOSESSION struktur med följande information:
    • Ange DXVA2DecodeHandle medlem till handtaget till DXVA-avkodarens enhet.
    • Ange CryptoSessionHandle medlem till handtaget till den kryptografiska sessionen. Den här referensen returneras av metoden IDirect3DDevice9Video::CreateCryptoSession.
    • Ange DeviceHandle- medlem till Direct3D-enhetshandtaget.
  4. Anropa IDirect3DAuthenticatedChannel9::Konfigurera för att skicka ett D3DAUTHENTICATEDCONFIGURE_CRYPTOSESSION kommando till den autentiserade kanalen.

Följande diagram illustrerar utbytet av referenser:

ett diagram som visar hur dxva-avkodaren är associerad med den kryptografiska sessionen.

Programvarudekodaren kan nu använda den kryptografiska sessionsnyckeln för att kryptera de komprimerade videobuffertarna. Varje komprimerad buffert har en egen initieringsvektor (IV) som anges i pvPVPState medlem i DXVA2_DecodeBufferDesc-strukturen.

Skicka autentiserade kanalkommandon

En uppsättning kommandon definieras för att konfigurera den autentiserade kanalen och ange olika innehållsskydd. En lista över kommandon finns i Content Protection-kommandon.

Utför följande steg för att skicka ett kommando till den autentiserade kanalen.

  1. Fyll i indatastrukturen. Den här datastrukturen är alltid en D3DAUTHENTICATEDCHANNEL_CONFIGURE_INPUT struktur följt av ytterligare fält. Fyll i den D3DAUTHENTICATEDCHANNEL_CONFIGURE_INPUT strukturen enligt följande tabell.
Medlem Beskrivning
omac Hoppa över det här fältet för tillfället.
ConfigureType GUID som identifierar kommandot. En lista över kommandon finns i Content Protection-kommandon.
hChannel Handtaget till den autentiserade kanalen.
SequenceNumber Sekvensnumret. Det första sekvensnumret anges genom att ett D3DAUTHENTICATEDCONFIGURE_INITIALIZE-kommando skickas. Varje gång du skickar ett annat kommando ökar du det här talet med 1. Sekvensnumret skyddar mot reprisattacker. Obs! Två separata sekvensnummer används, ett för kommandon och ett för frågor.
  1. Beräkna OMAC-taggen för datablocket som visas efter omac medlem i indatastrukturen. Kopiera sedan det här taggvärdet till omac- medlem.
  2. Anropa IDirect3DAuthenticatedChannel9::Konfigurera.
  3. Drivrutinen placerar utdata från kommandot i den D3DAUTHENTICATEDCHANNEL_CONFIGURE_OUTPUT strukturen.
  4. Beräkna OMAC-taggen för datablocket som visas efter omac medlem i utdatastrukturen. Jämför detta med värdet för omac medlem. Misslyckas om de inte matchar.
  5. Jämför värdena för ConfigureType, hChanneloch SequenceNumber medlemmar i utdatastrukturen mot dina värden för dessa medlemmar. Misslyckas om de inte matchar.
  6. Öka sekvensnumret för nästa kommando.

Skicka autentiserade kanalfrågor

En uppsättning frågor definieras för att hämta information om den autentiserade kanalen. En lista över frågor finns i Content Protection-frågor.

Utför följande steg för att skicka ett kommando till den autentiserade kanalen.

  1. Fyll i indatastrukturen. Den här datastrukturen är alltid en D3DAUTHENTICATEDCHANNEL_QUERY_INPUT struktur, eventuellt följt av ytterligare fält. Fyll i D3DAUTHENTICATEDCHANNEL_QUERY_INPUT struktur enligt följande tabell.
Medlem Beskrivning
QueryType GUID som identifierar frågan. En lista över frågor finns i Content Protection-frågor.
hChannel Handtaget till den autentiserade kanalen.
SequenceNumber Sekvensnumret. Det första sekvensnumret anges genom att ett D3DAUTHENTICATEDCONFIGURE_INITIALIZE-kommando skickas. Varje gång du skickar en annan fråga ökar du det här talet med 1. Sekvensnumret skyddar mot reprisattacker. Obs! Två separata sekvensnummer används, ett för kommandon och ett för frågor.
  1. Anropa IDirect3DAuthenticatedChannel9::Query.
  2. Drivrutinen placerar utdata från frågan i en D3DAUTHENTICATEDCHANNEL_QUERY_OUTPUT struktur. Den här strukturen följs av ytterligare fält, beroende på frågetyp.
  3. Beräkna OMAC-taggen för datablocket som visas efter omac medlem i utdatastrukturen. Jämför detta med värdet för omac medlem. Misslyckas om de inte matchar.
  4. Jämför värdena för ConfigureType, hChanneloch SequenceNumber medlemmar i utdatastrukturen mot dina värden för dessa medlemmar. Misslyckas om de inte matchar.
  5. Öka sekvensnumret för nästa fråga.

Direct3D 9 Video-API:er